<?php
namespace MentalSchool\AppBundle\Controller\Student;
use MentalSchool\AppBundle\Entity\StudentProfile;
use MentalSchool\AppBundle\Entity\Subtask;
use MentalSchool\AppBundle\Utils\Parameters;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
/**
* Student profile controller.
*
* @Route("/student")
*/
class TrainingController extends Controller
{
/**
* @Route("/training/{template}", name="ms_student_show_training")
*/
public function showTrainingAction($template)
{
if ($stProfile = $this->getUser()->getStudentProfile()) {
if ($stProfile->getStatus() == StudentProfile::STATUS_VACATION) {
return $this->render('AppBundle:Student:Page/student_on_vacation.html.twig', [
'breadcrumbs' => [['app.breadcrumbs.home', '', []]]
]);
}
$currentSortId = $stProfile->getSortThemeId();
$uniqueThemeId = (int)Subtask::getThemeUniqueIdByName($template);
if ($uniqueThemeId && $uniqueThemeId > $currentSortId) {
throw new AccessDeniedException();
}
}
$training = Subtask::getParametersDefaultDataByThemeSlug($template);
$training['subtheme'] = $template;
if (in_array($template, [
Parameters::TASK_CATEGORY_WILES,
Parameters::TASK_CATEGORY_DIVISION,
Parameters::TASK_CATEGORY_MULTIPLICATION,
Parameters::TASK_CATEGORY_EXPONENTIATION,
Parameters::TASK_CATEGORY_SQUAREROOT])) {
$layout = 'show_multiplication_and_division.html.twig';
} else {
$layout = 'show.html.twig';
}
$breadcrumbs = $this->get('app.common.service')->breadcrumbs();
$breadcrumbs[] = ['app.breadcrumbs.training', '', []];
$session = new Session();
$gameParams = $session->get('gameParams');
$idTraning = 'traningParams_' . rand(10, 1000000000);
$session->set($idTraning, []);
if (!empty($gameParams['level'])) {
$training["level"] = $gameParams['level'];
}
$session->remove('gameParams');
return $this->render('AppBundle:Student:Training/' . $layout, ['training' => $training, 'idTraning' => $idTraning, 'breadcrumbs' => $breadcrumbs, 'gameParams' => $gameParams]);
}
/**
* @Route("/start-squareroot-training", name="ms_student_start_squareroot_training")
* @Method({"GET", "POST"})
*/
public function startSquarerootTrainingAction(Request $request)
{
$allRequest = $request->request->all();
if (isset($allRequest['aNumbersGame'])) {
unset($allRequest['aNumbersGame']);
}
$allRequest = json_encode($allRequest, JSON_NUMERIC_CHECK);
$template = $request->get('subtheme');
$level = $request->get('level');
$rangeOfFirstNumber = $request->get('rangeOfFirstNumber');
$numberGeneratorManager = $this->get('app.multiplication.number.service')->build($template);
$soundsAnswer = $request->get('sounds_answer') ?: 0;
$manageFonts = $request->get('manage-fonts') ?: 0;
$fontsNumber = $manageFonts ? "Edu TAS Beginner" : "'Libre Franklin', sans-serif";
if ($level == 10) {
$levelRound = rand(1, 9);
$aNumbers = $numberGeneratorManager->generate($levelRound, $rangeOfFirstNumber);
} else {
$aNumbers = $numberGeneratorManager->generate($level, $rangeOfFirstNumber);
}
return $this->render('AppBundle:Student:Training/start_squareroot_training.html.twig', [
'numbers' => $aNumbers,
'subtheme' => $template,
'allRequest' => $allRequest,
'level' => $level,
'soundsAnswer' => $soundsAnswer,
'fontsNumbers' => $fontsNumber
]);
}
/**
* @Route("/start-multiplication-training", name="ms_student_start_multiplication_training")
* @Method({"GET", "POST"})
*/
public function startMultiplicationTrainingAction(Request $request)
{
$allRequest = $request->request->all();
if (isset($allRequest['aNumbersGame'])) {
unset($allRequest['aNumbersGame']);
}
$allRequest = json_encode($allRequest, JSON_NUMERIC_CHECK);
$template = $request->get('subtheme');
if (!$template) {
$session = new Session();
$idTraningMultiplication = 'traningMultiplicationParams_' . $this->getUser()->getId();
$requestTraningMultiplication = $session->get($idTraningMultiplication);
$template = $requestTraningMultiplication['subject'];
$level = $requestTraningMultiplication['level'];
$rangeOfFirstNumber = $requestTraningMultiplication['range_of_1st_number'];
$rangeOfSecondNumber = $requestTraningMultiplication['range_of_2st_number'];
$soundsAnswer = 1;
$reverseMultiplications = $requestTraningMultiplication['reverse_multiplication'];
$manageFonts = 0;
$fontsNumber = $manageFonts ? "Edu TAS Beginner" : "neucha, cursive";
$sampleFormCount = 1;
} else {
$level = $request->get('level');
$rangeOfFirstNumber = $request->get('rangeOfFirstNumber');
$rangeOfSecondNumber = $request->get('rangeOfSecondNumber');
$soundsAnswer = $request->get('sounds_answer') ?: 0;
$reverseMultiplications = $request->get('reverse_multiplication') ?: 0;
$manageFonts = $request->get('manage-fonts') ?: 0;
$fontsNumber = $manageFonts ? "Edu TAS Beginner" : "neucha, cursive";
$sampleFormCount = $request->get('sampleFormCount');
}
$numberGeneratorManager = $this->get('app.multiplication.number.service')->build($template);
if ($sampleFormCount > 1) {
$result = '';
for ($i = 1; $i <= $sampleFormCount; $i++) {
$aNumbers = $numberGeneratorManager->generate($level, $rangeOfFirstNumber, $rangeOfSecondNumber);
$result .= $i . ") " . (($template == "division") ? implode(' / ', $aNumbers) : implode(' × ', $aNumbers)) . " = \r\n";
}
return new \Symfony\Component\HttpFoundation\Response($result, 200, [
'content-type' => 'text/csv; charset=utf-8',
'Content-disposition' => 'attachment; filename=training.txt'
]);
} else {
$aNumbers = $numberGeneratorManager->generate($level, $rangeOfFirstNumber, $rangeOfSecondNumber);
}
return $this->render('AppBundle:Student:Training/start_multiplication_training.html.twig', [
'numbers' => $aNumbers,
'allRequest' => $allRequest,
'subtheme' => $template,
'reverseMultiplications' => $reverseMultiplications,
'level' => $level,
'soundsAnswer' => $soundsAnswer,
'fontsNumbers' => $fontsNumber
]);
}
/**
* @Route("/start-training", name="ms_student_start_training")
* @Method({"GET", "POST"})
*/
public function startTrainingAction(Request $request)
{
$gameParams = $request->request->all();
$session = new Session();
$session->set('gameParams', $gameParams);
$allRequest = $request->request->all();
if (isset($allRequest['aNumbersGame'])) {
unset($allRequest['aNumbersGame']);
}
$allRequest = json_encode($allRequest, JSON_NUMERIC_CHECK);
$template = $request->get('subtheme');
$themeUniqueId = Subtask::getThemeUniqueIdByName($template);
$idTraning = $request->get('idTraning') ?: 'traningParams_0';
$complexity = $request->get('complexity') ?: 0;
$level = $request->get('level');
$iterator = $request->get('iterator');
$aNumbersGame = $request->get('aNumbersGame') ?? [];
$combine = $request->get('combine');
$turbo = $request->get('turbo');
$doublePower = $request->get('double-power');
$outputSample = $request->get('output-sample');
$progressSpeed = $request->get('progress_speed');
$progressAction = $request->get('progress_action');
$manageFonts = $request->get('manage-fonts') ?: 0;
$multiselectLevel = $request->get('multiselect_level') ?: 0;
$soundsAnswer = $request->get('sounds_answer') ?: 0;
$speed = $request->get('speed');
$originalSpeed = $request->get('originalSpeed') ?? $speed;
$originalIterator = $request->get('originalIterator') ?? $iterator;
$fontsNumber = $manageFonts ? "Edu TAS Beginner" : "'Libre Franklin', sans-serif";
$tranningParams = $session->get($idTraning, []);
if ($request->get('game_mode') !== 'progress') {
unset($tranningParams['progress']); // очищаємо прогрес
$session->set($idTraning, $tranningParams);
}
if (!$progressAction && isset($tranningParams['progress'])) {
unset($tranningParams['progress']['iterator']);
unset($tranningParams['progress']['originalIterator']);
$session->set($idTraning, $tranningParams);
}
if (!$progressSpeed && isset($tranningParams['progress'])) {
unset($tranningParams['progress']['speed']);
unset($tranningParams['progress']['originalSpeed']);
$session->set($idTraning, $tranningParams);
}
if (empty($tranningParams['progress']['originalSpeed']) && $progressSpeed > 0) {
$tranningParams['progress']['originalSpeed'] = $originalSpeed;
$tranningParams['progress']['progressSpeed'] = $progressSpeed;
$tranningParams['progress']['speed'] = $speed;
$session->set($idTraning, $tranningParams);
}
if (empty($tranningParams['progress']['originalIterator']) && $progressAction) {
$tranningParams['progress']['originalIterator'] = $originalIterator;
$tranningParams['progress']['iterator'] = $iterator;
$session->set($idTraning, $tranningParams);
}
if (!empty($tranningParams['progress']['speed'])) {
$speed = $tranningParams['progress']['speed'];
}
if (!empty($tranningParams['progress']['iterator'])) {
$iterator = $tranningParams['progress']['iterator'];
}
$fileGenerator = 'NumberGeneratorService';
if (in_array($request->get('subtheme'), ['simple', 'family', 'bigfriends', 'anzan']) && $request->get('master')) {
if ($multiselectLevel) {
$level = $request->get('multilevel');
$numberGenerator = $this->get('app.master.number.generator.service2');
$fileGenerator = 'MasterNumberGeneratorService2';
} else {
$numberGenerator = $this->get('app.master.number.generator.service');
$fileGenerator = 'MasterNumberGeneratorService';
}
} else {
if ($multiselectLevel) {
$level = $request->get('multilevel');
$numberGenerator = $this->get('app.number.generator.service2');
$fileGenerator = 'NumberGeneratorService2';
} else {
$numberGenerator = $this->get('app.number.generator.service');
}
}
if ($multiselectLevel) {
if (strpos($level, '0') !== false) {
$array = explode(',', $level);
$array = array_filter($array, function ($value) {
return $value !== '0';
});
$level = implode(',', $level);
}
}
$paramsForLog = ['type' => 'Game', 'themeUniqueId' => $themeUniqueId, 'complexity' => $complexity, 'level' => $level, 'iterator' => $iterator, 'combine' => $combine];
$logId = $this->get('app.student_log.service')->saveHttpLog([
'user_id' => $this->getUser()->getId(),
'url' => $_SERVER['REQUEST_URI'],
'request' => json_encode($paramsForLog),
'response' => $fileGenerator
]);
if (!empty($aNumbersGame)) {
$aNumbers = json_decode($aNumbersGame, 1);
} else {
if ($doublePower) {
$aNumbers = [
$numberGenerator->generate($themeUniqueId, $complexity, $level, $iterator, $combine),
$numberGenerator->generate($themeUniqueId, $complexity, $level, $iterator, $combine)
];
} else {
$aNumbers = $numberGenerator->generate($themeUniqueId, $complexity, $level, $iterator, $combine);
}
}
$sampleFormCount = $request->get('sampleFormCount');
if ($sampleFormCount > 1) {
$result = '';
for ($i = 1; $i <= $sampleFormCount; $i++) {
$aNumbers = $numberGenerator->generate($themeUniqueId, $complexity, $level, $iterator, $combine);
$result .= $i . ") " . implode($aNumbers) . " = \r\n";
}
return new \Symfony\Component\HttpFoundation\Response($result, 200, [
'content-type' => 'text/csv; charset=utf-8',
'Content-disposition' => 'attachment; filename=training.txt'
]);
}
$this->get('app.student_log.service')->removeHttpLog($logId);
$taskParams =
[
'params' =>
[
'combine' => $combine,
'idTraning' => $idTraning,
'complexity' => $complexity,
'turbo' => $turbo,
'speed' => $speed,
'iterator' => $iterator,
'doublePower' => $doublePower,
'outputSample' => $outputSample,
"progress_action" => $progressAction,
"progress_speed" => $progressSpeed,
"originalIterator" => $originalIterator,
"originalSpeed" => $originalSpeed,
"soundsAnswer" => $soundsAnswer,
"fontsNumbers" => $fontsNumber,
"manageFonts" => $manageFonts
],
'numbers' => $aNumbers,
'training' => 'true'
];
return $this->render('AppBundle:Student:Training/start_training.html.twig', ['taskParams' => $taskParams, 'allRequest' => $allRequest, 'subtheme' => $template]);
}
/**
* @Route("/training-check/{subtheme}", name="ms_student_training_check")
* @Method({"GET", "POST"})
*/
public function checkResultAction(Request $request, $subtheme)
{
$correctAnswer = 0;
$allRequest = $request->get('allRequest') ?? [];
$allParamsPrevGame = [];
$aIncorrectAnswers = [];
$idTraning = $request->get('idTraning') ?: 'traningParams_0';
$showButtonRepeatNumbers = false;
if ($subtheme == "flashcards") {
$val = $request->get('value');
$result = $val;
$expectAnswer = $request->get('expectAnswer');
$correctAnswer = $val == $expectAnswer ? 1 : 0;
$aNumbers = [$expectAnswer];
} else {
$result = $request->get('result');
if (in_array($subtheme, [
Parameters::TASK_CATEGORY_WILES,
Parameters::TASK_CATEGORY_DIVISION,
Parameters::TASK_CATEGORY_MULTIPLICATION,
Parameters::TASK_CATEGORY_SQUAREROOT,
Parameters::TASK_CATEGORY_EXPONENTIATION])) {
$aNumbers = [
'firstNumber' => $request->get('firstNumber'),
'secondNumber' => $request->get('secondNumber'),
];
$level = $request->get('level');
$correctAnswer = $this->get('app.task.number.generator.service')->checkMultiplicationResultTask($aNumbers, $subtheme, $level, $result) ? 1 : 0;
if ($allRequest) {
$allParamsPrevGame = json_decode($allRequest, true);
$rangeOfFirstNumber = $allParamsPrevGame['rangeOfFirstNumber'] ?? 0;
$rangeOfSecondNumber = $allParamsPrevGame['rangeOfSecondNumber'] ?? 0;
}
if ($rangeOfFirstNumber || $rangeOfSecondNumber) {
$sessionData = [
"mode" => "game",
"subject" => $subtheme,
"level" => $level,
"range_of_1st_number" => $rangeOfFirstNumber,
"range_of_2st_number" => $rangeOfSecondNumber
];
$session = new Session();
$idTraningMultiplication = 'traningMultiplicationParams_' . $this->getUser()->getId();
$session->set($idTraningMultiplication, $sessionData);
}
} else {
$showButtonRepeatNumbers = true;
$resultSecond = $request->get('result-second');
$aNumbers = json_decode($request->get('numbers'), true);
if (!is_null($resultSecond)) {
$aIncorrectAnswers = [
'first' => ['answer' => $result, 'status' => $this->get('app.task.number.generator.service')->checkResultTask($aNumbers[0], $result)],
'seccond' => ['answer' => $resultSecond, 'status' => $this->get('app.task.number.generator.service')->checkResultTask($aNumbers[1], $resultSecond)]
];
$correctAnswer = ($aIncorrectAnswers['first']['status'] && $aIncorrectAnswers['seccond']['status']) ? 1 : 0;
} else {
$correctAnswer = $this->get('app.task.number.generator.service')->checkResultTask($aNumbers, $result) ? 1 : 0;
}
}
}
$session = new Session();
$tranningParams = $session->get($idTraning);
if (!in_array($subtheme, [
Parameters::TASK_CATEGORY_WILES,
Parameters::TASK_CATEGORY_DIVISION,
Parameters::TASK_CATEGORY_MULTIPLICATION,
Parameters::TASK_CATEGORY_SQUAREROOT,
Parameters::TASK_CATEGORY_EXPONENTIATION]) && !empty($tranningParams['progress'])) {
$this->handleProgressTranning($correctAnswer, $tranningParams, $idTraning);
}
if ($allRequest) {
$allParamsPrevGame = json_decode($allRequest, true);
}
$template = $correctAnswer ? "result_success" : "result_error";
if ($request->isXmlHttpRequest()) {
$html = $this->renderView('AppBundle:Student:Training/' . $template . '.html.twig', [
"aIncorrectAnswers" => $aIncorrectAnswers,
'url' => $this->generateUrl('ms_student_show_training', [
"template" => $subtheme,
]),
'showButtonRepeatNumbers' => $showButtonRepeatNumbers,
"allParamsPrevGame" => $allParamsPrevGame,
"numbers" => $aNumbers
]);
return new JsonResponse([
'success' => (bool) $correctAnswer,
'html' => $html,
]);
}
// Якщо звичайний запит (не AJAX) — повернути повну сторінку
return $this->render('AppBundle:Student:Training/' . $template . '.html.twig', [
"aIncorrectAnswers" => $aIncorrectAnswers,
'url' => $this->generateUrl('ms_student_show_training', [
"template" => $subtheme,
]),
'showButtonRepeatNumbers' => $showButtonRepeatNumbers,
"allParamsPrevGame" => $allParamsPrevGame,
"numbers" => $aNumbers
]);
}
public function handleProgressTranning($correctAnswer, $tranningParams, $idTraning)
{
if (!empty($tranningParams['progress']['originalSpeed']) && !empty($tranningParams['progress']['speed']) && !empty($tranningParams['progress']['progressSpeed'])) {
$progressSpeed = (float)$tranningParams['progress']['progressSpeed'];
if ($correctAnswer) {
$newProgressSpeed = $tranningParams['progress']['speed'] - $progressSpeed;
if ($newProgressSpeed > 0) {
$tranningParams['progress']['speed'] = $newProgressSpeed;
}
} else {
if ($tranningParams['progress']['originalSpeed'] > $tranningParams['progress']['speed']) {
$tranningParams['progress']['speed'] = $tranningParams['progress']['speed'] + $progressSpeed;
}
}
}
if (!empty($tranningParams['progress']['originalIterator']) && !empty($tranningParams['progress']['iterator'])) {
if ($correctAnswer) {
$tranningParams['progress']['iterator'] = $tranningParams['progress']['iterator'] + 1;
} else {
if ($tranningParams['progress']['originalIterator'] < $tranningParams['progress']['iterator']) {
$tranningParams['progress']['iterator'] = $tranningParams['progress']['iterator'] - 1;
}
}
}
$session = new Session();
$session->set($idTraning, $tranningParams);
}
}