<?php
namespace App\Controller\Front\Exercise;
use App\Entity\Exercise\Exercise;
use App\Entity\Scholar\Lesson\Lesson;
use App\Entity\Scholar\Module\Module;
use App\Entity\Scholar\Training\Training;
use App\Exception\Exercise\MissingUserException;
use App\Form\Exercise\User\ExerciseResultType;
use App\Repository\Exercise\ExerciseRepository;
use App\Service\Exercise\UserExerciseResultManipulator;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
/**
* Class StartController
*
* @author Benjamin Georgeault
*/
class StartController extends AbstractController
{
public function __construct(
private UserExerciseResultManipulator $manipulator,
private EntityManagerInterface $em,
) {}
#[Route(path: '/training/{trainingId}/module/{moduleId}/lesson/{lessonId}/exercise/{id}/start', name: 'front_exercise_start', priority: 1)]
#[Entity('training', options: ['id' => 'trainingId'])]
#[Entity('module', options: ['id' => 'moduleId'])]
#[Entity('lesson', options: ['id' => 'lessonId'])]
public function __invoke(Request $request, Training $training, Module $module, Lesson $lesson, Exercise $exercise): Response
{
if ($this->getUser() === null) {
throw new AccessDeniedException('Access denied.');
}
// Check if there is a pending exercise.
if (null !== $exerciseResult = $this->manipulator->getPendingExercise()) {
// If pending but different exercise, reset to null.
if ($exercise->getId() !== $pendingExerciseId = $exerciseResult->getExercise()->getId()) {
$exerciseResult = null;
} else {
// in the case of a pending exercise have been found, set startedAt to current time to avoid 185h for an exercise
$exerciseResult->setStartedAt(new \DateTime());
$this->em->persist($exerciseResult);
$this->em->flush();
}
}
if (null === $exerciseResult) {
// Create the ExerciseResult and save it in the database.
// It allows to know if the user is doing an exercise.
try {
$exerciseResult = $this->manipulator->create($exercise);
$this->em->persist($exerciseResult);
$this->em->flush();
} catch (MissingUserException $e) {
throw new AccessDeniedException('No logged user.');
}
}
return $this->redirectToRoute('front_exercise_answer', [
'trainingId' => $training->getId(),
'moduleId' => $module->getId(),
'lessonId' => $lesson->getId(),
'id' => $exercise->getId(),
'exerciseResultId' => $exerciseResult->getId(),
], 303);
}
}