src/Controller/Front/Exercise/AnswerController.php line 22

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Front\Exercise;
  3. use App\Entity\Exercise\Exercise;
  4. use App\Entity\Exercise\User\ExerciseResult;
  5. use App\Entity\Scholar\Lesson\Lesson;
  6. use App\Entity\Scholar\Module\Module;
  7. use App\Entity\Scholar\Training\Training;
  8. use App\Form\Exercise\User\ExerciseResultType;
  9. use App\Repository\Exercise\User\ExerciseResultRepository;
  10. use App\Service\Exercise\UserExerciseResultManipulator;
  11. use Doctrine\ORM\EntityManagerInterface;
  12. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  13. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\HttpFoundation\Response;
  16. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  17. use Symfony\Component\Routing\Annotation\Route;
  18. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  19. class AnswerController extends AbstractController
  20. {
  21. public function __construct(
  22. private UserExerciseResultManipulator $manipulator,
  23. private ExerciseResultRepository $exerciseResultRepository,
  24. private EntityManagerInterface $em,
  25. ) {}
  26. #[Route(path: '/training/{trainingId}/module/{moduleId}/lesson/{lessonId}/exercise/{id}/{exerciseResultId}', name: 'front_exercise_answer')]
  27. #[ParamConverter('training', options: ['id' => 'trainingId'])]
  28. #[ParamConverter('module', options: ['id' => 'moduleId'])]
  29. #[ParamConverter('lesson', options: ['id' => 'lessonId'])]
  30. #[ParamConverter('exercise', options: ['id' => 'id'])]
  31. #[ParamConverter('exerciseResult', options: ['id' => 'exerciseResultId'])]
  32. public function __invoke(Request $request, Training $training, Module $module, Lesson $lesson, Exercise $exercise, ExerciseResult $exerciseResult): Response
  33. {
  34. if (!$this->isGranted('FRONT_ACCESS', [
  35. 'training' => $training,
  36. 'module' => $module,
  37. 'lesson' => $lesson,
  38. ])) {
  39. throw $this->createAccessDeniedException();
  40. }
  41. if (
  42. $exercise->getLesson() !== $lesson
  43. || $exerciseResult->getExercise() !== $exercise
  44. ) {
  45. throw new NotFoundHttpException();
  46. }
  47. if ($this->getUser() === null) {
  48. throw new AccessDeniedException('Access denied.');
  49. }
  50. $exerciseResult = $this->exerciseResultRepository->findOneBy(
  51. [
  52. 'id' => $exerciseResult->getId(),
  53. 'exercise' => $exercise->getId(),
  54. 'user' => $this->getUser(),
  55. 'finishedAt' => null,
  56. ],
  57. [
  58. 'startedAt' => 'DESC',
  59. ]
  60. );
  61. if (null === $exerciseResult) {
  62. return $this->redirectToRoute('front_channel_exercise_show', [
  63. 'lessonId' => $lesson->getId(),
  64. 'exerciseId' => $exercise->getId(),
  65. 'moduleId' => $module->getId(),
  66. 'trainingId' => $training->getId(),
  67. ]);
  68. }
  69. // Populate the questions.
  70. $this->manipulator->populate($exercise, $exerciseResult);
  71. $form = $this->createForm(ExerciseResultType::class, $exerciseResult);
  72. $form->handleRequest($request);
  73. if ($form->isSubmitted() && $form->isValid()) {
  74. $this->manipulator->finish($exercise, $exerciseResult);
  75. // Check if the current Exercise submission is not an error (start the exercise in less then 3s ago).
  76. if (3 > $exerciseResult->getTime()) {
  77. $this->em->remove($exerciseResult);
  78. $this->em->flush();
  79. return $this->redirectToRoute('front_channel_lesson_show', [
  80. 'trainingId' => $training->getId(),
  81. 'moduleId' => $module->getId(),
  82. 'lessonId' => $lesson->getId(),
  83. ], 303);
  84. }
  85. $this->em->persist($exerciseResult);
  86. $this->em->persist($exercise);
  87. $this->em->flush();
  88. return $this->redirectToRoute('front_exercise_solution', [
  89. 'trainingId' => $training->getId(),
  90. 'moduleId' => $module->getId(),
  91. 'lessonId' => $lesson->getId(),
  92. 'id' => $exercise->getId(),
  93. 'resultId' => $exerciseResult->getId(),
  94. ]);
  95. }
  96. return $this->render('Front/Exercise/answer.html.twig', [
  97. 'channel' => $training->getOwnerChannel(),
  98. 'training' => $training->getId(),
  99. 'module' => $module->getId(),
  100. 'exercise' => $exercise,
  101. 'exercise_result' => $exerciseResult,
  102. 'form' => $form->createView(),
  103. 'lesson' => $lesson,
  104. 'count_form_errors' => $form->getErrors(true)->count()
  105. ]);
  106. }
  107. }