src/Controller/Front/CoursesController.php line 67

  1. <?php
  2. namespace App\Controller\Front;
  3. use App\Entity\Categorie;
  4. use App\Entity\Chapitre;
  5. use App\Entity\Cours;
  6. use App\Entity\Forum;
  7. use App\Entity\ForumMessage;
  8. use App\Entity\Lecture;
  9. use App\Entity\Lesson;
  10. use App\Entity\LikeMessageForum;
  11. use App\Entity\Membre;
  12. use App\Entity\QuizLost;
  13. use App\Entity\QuizResult;
  14. use App\Entity\Review;
  15. use App\Entity\Sujet;
  16. use App\Form\CourseReviewType;
  17. use App\Form\SujetType;
  18. use App\Repository\CategorieRepository;
  19. use App\Repository\ChapitreRepository;
  20. use App\Repository\ClasseRepository;
  21. use App\Repository\CoursRepository;
  22. use App\Repository\EleveRepository;
  23. use App\Repository\EnseignantRepository;
  24. use App\Repository\FiliereRepository;
  25. use App\Repository\ForumMessageRepository;
  26. use App\Repository\ForumRepository;
  27. use App\Repository\LectureRepository;
  28. use App\Repository\LessonRepository;
  29. use App\Repository\LikeMessageForumRepository;
  30. use App\Repository\MembreRepository;
  31. use App\Repository\PaymentRepository;
  32. use App\Repository\QuizLostRepository;
  33. use App\Repository\QuizRepository;
  34. use App\Repository\QuizResultRepository;
  35. use App\Repository\ReviewRepository;
  36. use App\Repository\SpecialiteRepository;
  37. use App\Repository\SujetRepository;
  38. use DateTimeImmutable;
  39. use App\Service\PushNotificationService;
  40. use App\Service\SendAllUsersEmailService;
  41. use Doctrine\ORM\EntityManagerInterface;
  42. use Knp\Component\Pager\PaginatorInterface;
  43. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  44. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  45. use Symfony\Component\HttpFoundation\JsonResponse;
  46. use Symfony\Component\HttpFoundation\Request;
  47. use Symfony\Component\HttpFoundation\Response;
  48. use Symfony\Component\Routing\Annotation\Route;
  49. class CoursesController extends AbstractController
  50. {
  51.      private $sendAllUsersEmailService;
  52.     public function __constructSendAllUsersEmailService $sendAllUsersEmailService ) {
  53.         $this->sendAllUsersEmailService $sendAllUsersEmailService;
  54.     }
  55.     #[Route('/courses'name'app_front_courses')]
  56.     #[Route('/courses/{slug}'name'app_front_category_courses'methods: ['GET'])]
  57.     public function index(Categorie $categorie nullRequest $requestFiliereRepository $filiereRepositorySpecialiteRepository $specialiteRepositoryClasseRepository $classeRepositoryCategorieRepository $categorieRepositoryCoursRepository $coursRepositoryPaginatorInterface $paginatorInterface): Response
  58.     {
  59.         $search trim($request->query->get('search')) === '' null $request->query->get('search');
  60.         $searchCategory trim($request->query->get('category')) === '' null $request->query->get('category');
  61.         $searchPrice trim($request->query->get('price')) === '' null $request->query->get('price');
  62.         $searchLevel trim($request->query->get('level')) === '' null $request->query->get('level');
  63.         $searchLanguage trim($request->query->get('language')) === '' null $request->query->get('language');
  64.         $category $categorieRepository->findOneBy(['slug' => $searchCategory]);
  65.         $isFree $searchPrice === null null : ($searchPrice === 'free' true false);
  66.         $searchFiliere $filiereRepository->findOneBy(['slug' => $request->query->get('filiere')]);
  67.         $searchSpecialite $specialiteRepository->findOneBy(['slug' => $request->query->get('specialite')]);
  68.         // dd($searchSpecialite);
  69.         $searchClasse $classeRepository->findOneBy(['slug' => $request->query->get('classe')]);
  70.         if ($search != null || $searchCategory != null || $searchPrice !== null || $searchLevel !== null || $searchLanguage !== null || $searchFiliere !== null || $searchSpecialite !== null || $searchClasse !== null) {
  71.             $courses $coursRepository->frontSearch($category$search$isFree$searchLevel$searchLanguage$searchFiliere$searchSpecialite$searchClasse);
  72.         } elseif ($categorie != null) {
  73.             $courses $coursRepository->findByCategory($categorie);
  74.         } else {
  75.             $courses $coursRepository->findBy(['isValidated' => true]);
  76.         }
  77.         return $this->render('front/courses/index.html.twig', [
  78.             'courses' => $paginatorInterface->paginate($courses$request->query->getInt('page'1), 12),
  79.             'searchCategory' => $category,
  80.             'category' => $categorie,
  81.             'searchPrice' => $searchPrice,
  82.             'searchLevel' => $searchLevel,
  83.             'searchLanguage' => $searchLanguage,
  84.             'categories' => $categorieRepository->findBy([], ['name' => 'ASC']),
  85.             'search' => $search,
  86.             'filieres' => $filiereRepository->findAll(),
  87.             'searchFiliere' => $searchFiliere,
  88.             'specialites' => $specialiteRepository->findBy([], ['filiere' => 'ASC']),
  89.             'classes' => $classeRepository->findBy([], ['specialite' => 'ASC''name' => 'ASC']),
  90.             'searchSpecialite' => $searchSpecialite,
  91.             'searchClasse' => $searchClasse,
  92.             'isCoursePage' => true,
  93.         ]);
  94.     }
  95.     #[Route('/course/{slug}/review'name'app_front_course_add_review'methods: ['POST'])]
  96.     public function newCourseReview(Cours $coursRequest $requestEleveRepository $eleveRepositoryReviewRepository $reviewRepository)
  97.     {
  98.         $eleve $eleveRepository->findOneBy(['utilisateur' => $this->getUser()]);
  99.         if ($eleve === null) {
  100.             throw $this->createAccessDeniedException("Cette opération est reservée aux Ã©lèves uniquement.");
  101.         }
  102.         $review = new Review();
  103.         $formReview $this->createForm(CourseReviewType::class, $review);
  104.         $formReview->handleRequest($request);
  105.         if ($formReview->isSubmitted() && $formReview->isValid()) {
  106.             $cours->setReview($cours->getReview() + $review->getRating());
  107.             $review->setEleve($eleve);
  108.             $review->setCours($cours);
  109.             $reviewRepository->save($reviewtrue);
  110.         }
  111.         return $this->redirectToRoute('app_front_course_details', ['slug' => $cours->getSlug()]);
  112.     }
  113.     #[Route('/courses/{slug}/details'name'app_front_course_details'methods: ['GET'])]
  114.     public function courseDetails(Cours $coursCoursRepository $coursRepositoryReviewRepository $reviewRepositoryMembreRepository $membreRepositoryEleveRepository $eleveRepositoryLectureRepository $lectureRepositoryLessonRepository $lessonRepository)
  115.     {
  116.         $readLessons $lessonRepository->findReadingLessons($cours);
  117.         $lastReadLesson null;
  118.         $lecture null;
  119.         $eleve $eleveRepository->findOneBy(['utilisateur' => $this->getUser()]);
  120.         if ($eleve !== null && count($readLessons) > 0) {
  121.             $lastReadLesson $readLessons[count($readLessons) - 1];
  122.             $lecture $lectureRepository->findOneBy(['lesson' => $lastReadLesson'eleve' => $eleve]);
  123.         }
  124.         $review = new Review();
  125.         $fromReview $this->createForm(CourseReviewType::class, $review, [
  126.             'action' => $this->generateUrl('app_front_course_add_review', ['slug' => $cours->getSlug()]),
  127.         ]);
  128.         $heIsMembre false;
  129.         $membre $membreRepository->findOneBy(['utilisateur' => $this->getUser()]);
  130.         if ($membre !== null && $membre->getForums()->contains($cours->getForum())) {
  131.             $heIsMembre true;
  132.         }
  133.         $sujet = new Sujet();
  134.         $sujetForm $this->createForm(SujetType::class, $sujet, [
  135.             'action' => $heIsMembre $this->generateUrl('app_front_course_new_forum', ['id' => $membre->getId(), 'slug' => $cours->getSlug()])  : '',
  136.         ]);
  137.         $cours->setVues($cours->getVues() + 1);
  138.         $coursRepository->save($courstrue);
  139.         $view 'front/courses/course_details.html.twig';
  140.         if ($cours->getMedia()->getVideoUrl() === null && $cours->getMedia()->getMp4File() === null && $cours->getMedia()->getOggFile() === null && $cours->getMedia()->getWebMFile() === null) {
  141.             $view 'front/courses/course_details_text.html.twig';
  142.         }
  143.         return $this->render($view, [
  144.             'course' => $cours,
  145.             'fiveStarsReviews' => $reviewRepository->findBy(['cours' => $cours'rating' => 5]),
  146.             'fourStarsReviews' => $reviewRepository->findBy(['cours' => $cours'rating' => 4]),
  147.             'treeStarsReviews' => $reviewRepository->findBy(['cours' => $cours'rating' => 3]),
  148.             'twoStarsReviews' => $reviewRepository->findBy(['cours' => $cours'rating' => 2]),
  149.             'oneStarReviews' => $reviewRepository->findBy(['cours' => $cours'rating' => 1]),
  150.             'nbReviews' => count($cours->getReviews()) == count($cours->getReviews()),
  151.             'lastReadLesson' => $lastReadLesson,
  152.             'lecture' => $lecture,
  153.             'fromReview' => $fromReview->createView(),
  154.             'nbReviews' => count($cours->getReviews()) <= count($cours->getReviews()),
  155.             'sujetForm' => $sujetForm->createView(),
  156.             'heIsMembre' => $heIsMembre,
  157.             'membre' => $membre,
  158.             'isReadLessonPage' => true,
  159.             'topCourses' => $coursRepository->findBy(['isValidated' => true], ['review' => 'DESC''createdAt' => 'DESC'], 8),
  160.             'isCoursePage' => true,
  161.             'eleve' => $eleve,
  162.             'lectures' => $eleve == null ? [] : $lectureRepository->findStudentCourseLectures($eleve$courstrue),
  163.             'lessons' => $lessonRepository->findCourseLessons($cours),
  164.             'exist' => $eleve !== null && $eleve->getCours()->contains($cours)
  165.         ]);
  166.     }
  167.     #[Route('/course/{id}/{slug}/forum'name'app_front_course_new_forum'methods: ['POST'])]
  168.     #[ParamConverter('cours'options: ['mapping' => ['slug' => 'slug']])]
  169.     #[ParamConverter('membre'options: ['mapping' => ['id' => 'id']])]
  170.     public function newForumSubjet(Membre $membreCours $cours,
  171.      Request $requestSujetRepository $sujetRepository): Response
  172.     {
  173.         $sujet = new Sujet();
  174.         $sujetForm $this->createForm(SujetType::class, $sujet);
  175.         $sujetForm->handleRequest($request);
  176.         if ($sujetForm->isSubmitted() && $sujetForm->isValid()) {
  177.             $formData $sujetForm->getData();
  178.             $content $formData['content'];
  179.             $sujet->setForum($cours->getForum());
  180.             $sujet->setMembre($membre)
  181.                 ->setReference((time() + $membre->getId()) * 2);
  182.               $sujetRepository->save($sujettrue);
  183.             $title='Nouveu  sujet << '.$content.' >>';
  184.             $body='Chere enseignant, le sujet : [ <strong>'.$content.'</strong> ] pour le cour de ' .$cours->getIntitule().' dont vous etes le guide vient de voir le jour  
  185.             . Merci de bien consulter le soucis de cet apprenant ';
  186.             
  187.               $user$cours->getEnseignant()->getUtilisateur();
  188.               $this->sendAllUsersEmailService->sendManyRecipients$title$body,$user);
  189.         }
  190.         return $this->redirectToRoute('app_front_course_forum_index', ['slug' => $cours->getSlug()]);
  191.     }
  192.     #[Route('/course/{membreId}/{referenceSujet}/post-forum-message'name'app_front_course_new_forum_message'methods: ['POST'])]
  193.     #[ParamConverter('sujet'options: ['mapping' => ['referenceSujet' => 'reference']])]
  194.     #[ParamConverter('membre'options: ['mapping' => ['membreId' => 'id']])]
  195.     public function addNewforumMessage(Membre $membreSujet $sujet,
  196.      Request $requestForumMessageRepository $forumMessageRepository,
  197.         PushNotificationService $pushNotificationService,
  198.     )
  199.     {
  200.         $user=$this->getUser();
  201.         if ( in_array'ROLE_STUDENT'$user->getRoles() ) ) {
  202.             if (!$membre->getForums()->contains($sujet->getForum())) {
  203.               throw $this->createAccessDeniedException("You cannot post in this forum");
  204.             }
  205.        }
  206.         $message $request->request->get('message');
  207.         if ($message === null) {
  208.             throw $this->createNotFoundException("Comment connot be empty !");
  209.         }
  210.         
  211.         if ($membre === 'adminer') {
  212.                 $membre = new Membre();
  213.                 $membre->setUtilisateur($this->getUser());
  214.         }
  215.         $forumMessage = new ForumMessage();
  216.         $forumMessage->setContent($message)->setMembre($membre)->setSujet($sujet);
  217.         $forumMessageRepository->save($forumMessagetrue);
  218.         $MessageMembers$forumMessageRepository->findBy(['sujet'=>$sujet]);
  219.         if($MessageMembers!==null){
  220.            $isEleve=$membre->getUtilisateur()?->getEleve();
  221.            $message=$isEleve==null ?' camarade ':' Enseignant Certifie Kulmapeck ';
  222.            $sender=' du collaborateur  '.$message.' '.$membre->getUtilisateur()->getPersonne()->getPseudo();
  223.             $title='Reponse au sujet '.$sujet->getContent();
  224.             $body=' Un nouveau message a ete ajoute pour le sujet : '.$sujet->getContent().' priere de verifier si cela resoud votre preoccupation ';
  225.             $bodyEmail='Pour le sujet : '.$sujet->getContent().'<br>, la  reponse   '.$sender.' est: <strong>'.$message.'</strong> . <br> 
  226.             priere de verifier si cela resoud votre preoccupation et veuilez marquer resolut si vous etes satisfait . <br> Cordialement';
  227.             foreach($MessageMembers as $member){
  228.               $user$member->getMembre()->getUtilisateur();
  229.               $userDeviceToken $member->getMembre()->getUtilisateur()?->getDevices()[0]->getToken();
  230.               $pushNotificationService->PushNotificationData($body$title,$userDeviceToken);
  231.               $this->sendAllUsersEmailService->send$title$bodyEmail$user );
  232.             }
  233.         }
  234.         if ($request->isXmlHttpRequest()) {
  235.             return new JsonResponse(['hasDone' => true]);
  236.         }
  237.         return $this->redirectToRoute('app_front_course_forum_subject_message', ['slug' => $sujet->getForum()->getCours()->getSlug(), 'reference' => $sujet->getReference()]);
  238.     }
  239.      #[Route('/course/{referenceSujet}/post-forum-message'name'app_front_course_new_forum_message_adminer'methods: ['POST'])]
  240.     #[ParamConverter('sujet'options: ['mapping' => ['referenceSujet' => 'reference']])]
  241.     public function addNewforumMessageAdminer(Membre $membre=nullSujet $sujet,
  242.      Request $requestForumMessageRepository $forumMessageRepository,
  243.         PushNotificationService $pushNotificationService,
  244.     )
  245.     {
  246.         $user=$this->getUser();
  247.         if ( in_array'ROLE_STUDENT'$user->getRoles() ) ) {
  248.             if (!$membre->getForums()->contains($sujet->getForum())) {
  249.               throw $this->createAccessDeniedException("You cannot post in this forum");
  250.             }
  251.        }
  252.         $message $request->request->get('message');
  253.         if ($message === null) {
  254.             throw $this->createNotFoundException("Comment connot be empty !");
  255.         }
  256.         
  257.         if ($membre ===null) {
  258.                 $membre = new Membre();
  259.                 $membre->setUtilisateur($this->getUser());
  260.         }
  261.         $forumMessage = new ForumMessage();
  262.         $forumMessage->setContent($message)->setMembre($membre)->setSujet($sujet);
  263.         $forumMessageRepository->save($forumMessagetrue);
  264.         $MessageMembers$forumMessageRepository->findBy(['sujet'=>$sujet]);
  265.         if($MessageMembers!==null){
  266.            $isEleve=$membre->getUtilisateur()?->getEleve();
  267.            $message=$isEleve==null ?' camarade ':' Enseignant Certifie Kulmapeck ';
  268.            $sender=' du collaborateur  '.$message.' '.$membre->getUtilisateur()->getPersonne()->getPseudo();
  269.             $title='Reponse au sujet '.$sujet->getContent();
  270.             $body=' Un nouveau message a ete ajoute pour le sujet : '.$sujet->getContent().' priere de verifier si cela resoud votre preoccupation ';
  271.             $bodyEmail='Pour le sujet : '.$sujet->getContent().'<br>, la  reponse   '.$sender.' est: <strong>'.$message.'</strong> . <br> 
  272.             priere de verifier si cela resoud votre preoccupation et veuilez marquer resolut si vous etes satisfait . <br> Cordialement';
  273.             foreach($MessageMembers as $member){
  274.               $user$member->getMembre()->getUtilisateur();
  275.               $userDeviceToken $member->getMembre()->getUtilisateur()?->getDevices()[0]->getToken();
  276.               $pushNotificationService->PushNotificationData($body$title,$userDeviceToken);
  277.               $this->sendAllUsersEmailService->send$title$bodyEmail$user );
  278.             }
  279.         }
  280.         if ($request->isXmlHttpRequest()) {
  281.             return new JsonResponse(['hasDone' => true]);
  282.         }
  283.         return $this->redirectToRoute('app_front_course_forum_subject_message', ['slug' => $sujet->getForum()->getCours()->getSlug(), 'reference' => $sujet->getReference()]);
  284.     }
  285.     #[Route('/course/{id}/like-forum-message'name'app_course_like_forum_message'methods: ['POST'])]
  286.     public function likeForumMessage(ForumMessage $forumMessageRequest $requestEntityManagerInterface $emLikeMessageForumRepository $likeMessageForumRepositoryForumMessageRepository $forumMessageRepositoryMembreRepository $membreRepository): Response
  287.     {
  288.         $user $this->getUser();
  289.         if ($user === null) {
  290.             throw $this->createAccessDeniedException("Vous n'êtes pas connecté");
  291.         }
  292.         $membre $membreRepository->findOneBy(['user' => $user]);
  293.         if ($membre === null || !$membre->getForums()->contains($forumMessage->getSujet()->getForum())) {
  294.             throw $this->createAccessDeniedException("Action impossible !");
  295.         }
  296.         if ($likeMessageForumRepository->findOneBy(['membre' => $membre'forumMessage' => $forumMessage]) === null) {
  297.             $forumMessageRepository->save($forumMessage->setLikes($forumMessage->getLikes() + 1));
  298.             $lmf = new LikeMessageForum();
  299.             $lmf->setMembre($membre)->setForumMessage($forumMessage);
  300.             $likeMessageForumRepository->save($lmf);
  301.             $em->flush();
  302.         }
  303.         if (!$request->isXmlHttpRequest()) {
  304.             return $this->redirectToRoute('app_front_course_forum_subject_message', ['slug' => $forumMessage->getSujet()->getForum()->getCours()->getSlug(), 'reference' => $forumMessage->getSujet()->getReference()]);
  305.         }
  306.         return new JsonResponse(['hasDone' => true'likes' => $forumMessage->getLikes()]);
  307.     }
  308.     #[Route('/course/reply-forum-message'name'app_course_reply_forum_message'methods: ['POST'])]
  309.     #[ParamConverter('forumMessage'options: ['mapping' => ['id' => 'id']])]
  310.     #[ParamConverter('membre'options: ['mapping' => ['membreId' => 'id']])]
  311.     public function replyForumMessage(Request $requestForumMessageRepository $forumMessageRepositoryMembreRepository $membreRepository)
  312.     {
  313.         $forumMessage $forumMessageRepository->findOneBy(['id' => $request->request->get('reply')]);
  314.         $membre $membreRepository->findOneBy(['id' => $request->request->get('membre')]);
  315.         if ($forumMessage === null || $membre === null || !$membre->getForums()->contains($forumMessage->getSujet()->getForum())) {
  316.             throw $this->createAccessDeniedException("You cannot post in this forum");
  317.         }
  318.         $replyMessage $request->request->get('replyMessage');
  319.         if ($replyMessage === null) {
  320.             throw $this->createNotFoundException("Comment connot be empty !");
  321.         }
  322.         $replyForumMessage = new ForumMessage();
  323.         $replyForumMessage->setContent($replyMessage)->setMembre($membre)->setSujet($forumMessage->getSujet())->setIsAnswer(true)->setForumMessage($forumMessage);
  324.         $forumMessageRepository->save($replyForumMessagetrue);
  325.         
  326.         if (!$request->isXmlHttpRequest()) {
  327.             return $this->redirectToRoute('app_front_course_forum_subject_message', ['slug' => $replyForumMessage->getSujet()->getForum()->getCours()->getSlug(), 'reference' => $replyForumMessage->getSujet()->getReference()]);
  328.         }
  329.         return new JsonResponse(['hasDone' => true'likes' => $replyForumMessage->getLikes()]);
  330.     }
  331.     #[Route('/course/{id}/mark-solve'name'app_course_solve_forum_message'methods: ['GET'])]
  332.     public function sujetResolu(ForumMessage $forumMessage,
  333.         PushNotificationService $pushNotificationServiceForumMessageRepository $forumMessageRepository)
  334.     {
  335.         $forumMessage->setIsResponse(true);
  336.         $forumMessage->getSujet()->setIsSolved(true);
  337.         $forumMessageRepository->save($forumMessagetrue);
  338.          $MessageMembers$forumMessageRepository->findBy(['sujet'=>$forumMessage->getSujet()]);
  339.         if($MessageMembers!==null){
  340.             $title='Resolution du sujet << '.$forumMessage->getSujet()->getContent().' >>';
  341.             $body='Le sujet : [ '.$forumMessage->getSujet()->getContent().' ] a ete resolu avec succes . Merci de nous faire confiance ';
  342.             
  343.             foreach($MessageMembers as $member){
  344.               $user$member->getMembre()->getUtilisateur();
  345.               $userDeviceToken $member->getMembre()->getUtilisateur()?->getDevices()[0]->getToken();
  346.         
  347.               $pushNotificationService->PushNotificationData($body$title,$userDeviceToken);
  348.               $this->sendAllUsersEmailService->send$title$body$user );
  349.             }
  350.         }
  351.         return $this->redirectToRoute('app_front_course_forum_index', ['slug' => $forumMessage->getSujet()->getForum()->getCours()->getSlug()]);
  352.     }
  353.     /**
  354.      * Dans cette fonction nous allons Ã©tudier les différentes contraintes pour commencer un cours
  355.      */
  356.     /*#[Route('/course/{slug}/start', name: 'app_front_course_start', methods: ['GET'])]
  357.     public function startCourse(Cours $course, Request $request, PaymentRepository $paymentRepository, MembreRepository $membreRepository, ForumRepository $forumRepository, EleveRepository $eleveRepository, LectureRepository $lectureRepository, EntityManagerInterface $entityManagerInterface)
  358.     {
  359.         // La fonction nécessite que l'on soit connecté
  360.         $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
  361.         $eleve = $eleveRepository->findOneBy(['utilisateur' => $this->getUser()]);
  362.         // L'enseignant et l'admin peuvent lire gratuitement mais pas l'élève
  363.         if ($this->isGranted('ROLE_STUDENT')) {
  364.             // Si le cours est gratuit on l'ajoute dans la liste des cours de l'élève dans le cas contraire on verifie s'il a 
  365.             // un compte premium si c'est le cas on ajoute le cours dans sa liste de cours dans le cas contraire il doit soit payer 
  366.             if ($eleve === null) {
  367.                 throw $this->createAccessDeniedException();
  368.             }
  369.             // On verifie si l'élève n'a pas déjà ce cours dans sa liste des cours
  370.             // le cours soit souscrire a un compte premium
  371.             if (!$course->isIsFree() && (!$eleve->isIsPremium() && (!$paymentRepository->findOneBy(['eleve' => $eleve, 'cours' => $course, 'isExpired' => false])))) {
  372.                 return $this->redirectToRoute('app_front_payment_buy_course', ['slug' => $course->getSlug()]);
  373.             }
  374.             if (!$eleve->getCours()->contains($course)) {
  375.                 if ($course->isIsFree() || $eleve->isIsPremium()) {
  376.                     $membre = $membreRepository->findOneBy(['utilisateur' => $this->getUser()]);
  377.                     if ($membre === null) {
  378.                         $membre = new Membre();
  379.                         $membre->setUtilisateur($this->getUser());
  380.                     }
  381.                     if (!$course->getForum()) {
  382.                         $forum = new Forum();
  383.                         $forum->setCours($course);
  384.                         $forumRepository->save($forum, true);
  385.                         $course->setForum($forum);
  386.                     }
  387.                     $course->getForum()->addMembre($membre);
  388.                     // On ajoute le cours dans sa liste
  389.                     $eleve->addCour($course);
  390.                     $membreRepository->save($membre, true);
  391.                 } else {
  392.                     // On lui demande de soit ajouter payer le cours soit devenir premium
  393.                     return $this->redirectToRoute('app_front_payment_buy_course', ['slug' => $course->getSlug()]);
  394.                 }
  395.             } else {
  396.                 if (!$course->isIsFree() && (!$eleve->isIsPremium() && (!$paymentRepository->findOneBy(['eleve' => $eleve, 'cours' => $course, 'isExpired' => false])))) {
  397.                     return $this->redirectToRoute('app_front_payment_buy_course', ['slug' => $course->getSlug()]);
  398.                 }
  399.             }
  400.         }
  401.         $chapitre = $course->getChapitres()[0];
  402.         $lesson = null;
  403.         if ($eleve !== null) {
  404.             $lecture = $lectureRepository->findStudentLastLecture($eleve, $course);
  405.             if ($lecture) {
  406.                 $lesson = $lecture->getLesson();
  407.             }
  408.         }
  409.         if ($lesson ===  null) {
  410.             $lesson = $chapitre->getLessons()[0];
  411.         }
  412.         $entityManagerInterface->flush();
  413.         return $this->redirectToRoute('app_front_read_lesson', ['slug' => $lesson->getSlug()]);
  414.     }*/
  415.     #[Route('/course/{slug}/start'name'app_front_course_start'methods: ['GET'])]
  416.     public function startCourse(
  417.         Cours $course,
  418.         Request $request,
  419.         PaymentRepository $paymentRepository,
  420.         MembreRepository $membreRepository,
  421.         ForumRepository $forumRepository,
  422.         EleveRepository $eleveRepository,
  423.         LectureRepository $lectureRepository,
  424.         EntityManagerInterface $entityManagerInterface
  425.     ) {
  426.         // Vérifie si l'utilisateur est authentifié
  427.         $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
  428.     
  429.         $eleve $eleveRepository->findOneBy(['utilisateur' => $this->getUser()]);
  430.         if (!$eleve) {
  431.             throw $this->createAccessDeniedException();
  432.         }
  433.     
  434.         // Calcul de la période de gratuité
  435.         $dateInscription $eleve->getJoinAt();
  436.         $dateFinGratuite = (clone $dateInscription)->modify('+2 days');
  437.         $periodeGratuiteActive = new \DateTime() <= $dateFinGratuite;
  438.     
  439.         // Vérification de l'accès au cours
  440.         $hasPaidForCourse $paymentRepository->findOneBy(['eleve' => $eleve'cours' => $course'isExpired' => false]);
  441.         $canAccessCourse $periodeGratuiteActive || $eleve->isIsPremium() || $hasPaidForCourse;
  442.     
  443.         // Si l'accès est refusé, redirige vers la page de paiement
  444.         if (!$canAccessCourse) {
  445.             return $this->redirectToRoute('app_front_payment_buy_course', ['slug' => $course->getSlug()]);
  446.         }
  447.     
  448.         // Si l'élève n'a pas encore ce cours, l'ajoute Ã  sa liste de cours
  449.         if (!$eleve->getCours()->contains($course)) {
  450.             $membre $membreRepository->findOneBy(['utilisateur' => $this->getUser()]);
  451.             if (!$membre) {
  452.                 $membre = new Membre();
  453.                 $membre->setUtilisateur($this->getUser());
  454.             }
  455.     
  456.             // Création du forum si nécessaire
  457.             if (!$course->getForum()) {
  458.                 $forum = new Forum();
  459.                 $forum->setCours($course);
  460.                 $forumRepository->save($forumtrue);
  461.                 $course->setForum($forum);
  462.             }
  463.     
  464.             // Ajout de l'élève au forum et du cours Ã  sa liste
  465.             $course->getForum()->addMembre($membre);
  466.             $eleve->addCour($course);
  467.             $membreRepository->save($membretrue);
  468.         }
  469.     
  470.         // Récupération de la prochaine leçon Ã  lire
  471.         $chapitre $course->getChapitres()[0];
  472.         $lecture $lectureRepository->findStudentLastLecture($eleve$course);
  473.         $lesson $lecture $lecture->getLesson() : $chapitre->getLessons()[0];
  474.     
  475.         $entityManagerInterface->flush();
  476.     
  477.         // Redirection vers la leçon
  478.         return $this->redirectToRoute('app_front_read_lesson', ['slug' => $lesson->getSlug()]);
  479.     }
  480.     #[Route('/course/{slug}/lesson'name'app_front_read_lesson'methods: ['GET'])]
  481.     public function readLesson(Lesson $lessonRequest $requestPaymentRepository $paymentRepositoryMembreRepository $membreRepositoryEleveRepository $eleveRepositoryEnseignantRepository $enseignantRepositoryLectureRepository $lectureRepository)
  482.     {
  483.         $eleve $eleveRepository->findOneBy(['utilisateur' => $this->getUser()]);
  484.         if ($this->isGranted('ROLE_STUDENT')) {
  485.             // Si le cours est gratuit on l'ajoute dans la liste des cours de l'élève dans le cas contraire on verifie s'il a 
  486.             // un compte premium si c'est le cas on ajoute le cours dans sa liste de cours dans le cas contraire il doit soit payer 
  487.             if ($eleve === null) {
  488.                 throw $this->createAccessDeniedException();
  489.             }
  490.             // On verifie si l'élève n'a pas déjà ce cours dans sa liste des cours
  491.             // le cours soit souscrire a un compte premium
  492.             if (!$eleve->getCours()->contains($lesson->getChapitre()->getCours())) {
  493.                 return $this->redirectToRoute('app_front_course_start', ['slug' => $lesson->getChapitre()->getCours()->getSlug()]);
  494.             }
  495.             // else {
  496.             //     if (!$eleve->isIsPremium() || !$paymentRepository->findOneBy(['eleve' => $eleve, 'cours' => $lesson->getChapitre()->getCours(), 'isExpired' => false])) {
  497.             //         return $this->redirectToRoute('app_front_payment_buy_course', ['slug' => $lesson->getChapitre()->getCours()->getSlug()]);
  498.             //     }
  499.             // }
  500.         } else {
  501.             $enseignant $enseignantRepository->findOneBy(['utilisateur' => $this->getUser()]);
  502.             if (!$this->isGranted('ROLE_COURSE_MANAGER') && ($enseignant !== null && !$enseignant->getCours()->contains($lesson->getChapitre()->getCours()))) {
  503.                 throw $this->createAccessDeniedException();
  504.             }
  505.         }
  506.         if ($lesson->getVideoLink() !== null && $request->query->get('view') === null) {
  507.             return $this->redirectToRoute('app_front_read_lesson', ['slug' => $lesson->getSlug(), 'view' => 'video_player']);
  508.         }
  509.         $heIsMembre false;
  510.         $cours $lesson->getChapitre()->getCours();
  511.         $membre $membreRepository->findOneBy(['utilisateur' => $this->getUser()]);
  512.         if ($membre !== null && $membre->getForums()->contains($cours->getForum())) {
  513.             $heIsMembre true;
  514.         }
  515.         $sujet = new Sujet();
  516.         $sujetForm $this->createForm(SujetType::class, $sujet, [
  517.             'action' => $heIsMembre $this->generateUrl('app_front_course_new_forum', ['id' => $membre->getId(), 'slug' => $cours->getSlug()])  : '',
  518.         ]);
  519.         // La fonction nécessite que l'on soit connecté
  520.         $lecture null;
  521.         if ($eleve !== null) {
  522.             $lecture $lectureRepository->findOneBy(['lesson' => $lesson'eleve' => $eleve]);
  523.             if ($lecture === null) {
  524.                 $lecture = new Lecture();
  525.                 $lecture->setReference($lesson->getId() + time())->setEleve($eleve)->setLesson($lesson)->setIsFinished(false)->setStartAt(new \DateTimeImmutable());
  526.                 $lectureRepository->save($lecturetrue);
  527.             }
  528.         }
  529.         $view 'front/courses/read.html.twig';
  530.         if ($lesson->getVideoLink() !== null && $request->query->get('view') === 'video_player') {
  531.             $view 'front/courses/video_player.html.twig';
  532.         }
  533.         return $this->render($view, [
  534.             'lesson' => $lesson,
  535.             'lecture' => $lecture,
  536.             'heIsMembre' => $heIsMembre,
  537.             'course' => $cours,
  538.             'sujetForm' => $sujetForm,
  539.             'nbReviews' => count($cours->getReviews()) <= count($cours->getReviews()),
  540.             'isReadLessonPage' => true,
  541.             'membre' => $membre,
  542.             'isCoursePage' => true,
  543.             'eleve' => $eleve,
  544.             'finishedLectures' => $lectureRepository->findBy(['eleve' => $eleve'isFinished' => true]),
  545.         ]);
  546.     }
  547.     #[Route('/course/{reference}/lecture/finished'name'app_front_course_lecture_finished'methods: ['GET'])]
  548.     public function lectureIsFinished(Lecture $lectureLectureRepository $lectureRepositoryLessonRepository $lessonRepository)
  549.     {
  550.         $lecture->setIsFinished(true)->setEndAt(new \DateTimeImmutable());
  551.         $lectureRepository->save($lecturetrue);
  552.         $lesson $lessonRepository->findOneBy(['chapitre' => $lecture->getLesson()->getChapitre(), 'numero' => $lecture->getLesson()->getNumero() + 1]);
  553.         if ($lesson === null) {
  554.             return $this->redirectToRoute('app_front_course_chapitre_quizzes', ['slugCours' => $lecture->getLesson()->getChapitre()->getCours()->getSlug(), 'slugChapitre' => $lecture->getLesson()->getChapitre()->getSlug()]);
  555.         }
  556.         return $this->redirectToRoute('app_front_read_lesson', ['slug' => $lesson->getSlug()]);
  557.     }
  558.     #[Route('/course/{slugCours}/{slugChapitre}/quizzes'name'app_front_course_chapitre_quizzes'methods: ['GET''POST'])]
  559.     #[Route('/course/{slugCours}/quizzes'name'app_front_course_course_quizzes'methods: ['GET''POST'])]
  560.     #[ParamConverter('cours'options: ['mapping' => ['slugCours' => 'slug']])]
  561.     #[ParamConverter('chapitre'options: ['mapping' => ['slugChapitre' => 'slug']])]
  562.     public function showQuizzes(Cours $coursChapitre $chapitre nullPaymentRepository $paymentRepositoryChapitreRepository $chapitreRepositoryQuizLostRepository $quizLostRepositoryRequest $requestEntityManagerInterface $entityManagerLectureRepository $lectureRepositoryQuizResultRepository $quizResultRepositoryEleveRepository $eleveRepositoryQuizRepository $quizRepository)
  563.     {
  564.         $eleve $eleveRepository->findOneBy(['utilisateur' => $this->getUser()]);
  565.         if ($this->isGranted('ROLE_STUDENT')) {
  566.             // Si le cours est gratuit on l'ajoute dans la liste des cours de l'élève dans le cas contraire on verifie s'il a 
  567.             // un compte premium si c'est le cas on ajoute le cours dans sa liste de cours dans le cas contraire il doit soit payer 
  568.             if ($eleve === null) {
  569.                 throw $this->createAccessDeniedException();
  570.             }
  571.             // On verifie si l'élève n'a pas déjà ce cours dans sa liste des cours
  572.             // le cours soit souscrire a un compte premium
  573.             if (!$eleve->getCours()->contains($cours)) {
  574.                 return $this->redirectToRoute('app_front_course_start', ['slug' => $cours->getSlug()]);
  575.             } else {
  576.                 /*if (!$cours->isIsFree() && (!$eleve->isIsPremium() && ($paymentRepository->findOneBy(['eleve' => $eleve, 'cours' => $cours, 'isExpired' => false]) !== null))) {
  577.                     return $this->redirectToRoute('app_front_payment_buy_course', ['slug' => $cours->getSlug()]);
  578.                 }*/
  579.                 $payment $paymentRepository->findOneBy(['eleve' => $eleve'cours' => $cours'isExpired' => false]);
  580.                 if (!$cours->isIsFree() && !$eleve->isIsPremium() && $payment) {
  581.                     
  582.                   //  dump($payment); exit;
  583.                     if (!$payment) {
  584.                         $this->addFlash('error''Aucun paiement actif trouvé pour ce cours.');
  585.                         return $this->redirectToRoute('app_front_payment_buy_course', ['slug' => $cours->getSlug()]);
  586.                     }
  587.                 }
  588.                 
  589.             }
  590.         }
  591.         if ($chapitre !== null) {
  592.             $lecture $lectureRepository->findOneBy(['eleve' => $eleve'chapitre' => $chapitre]);
  593.             if ($lecture == null) {
  594.                 $lecture = new Lecture();
  595.                 $lecture->setChapitre($chapitre)->setEleve($eleve)->setIsFinished(false)->setReference(time() + $eleve->getId())->setStartAt(new \DateTimeImmutable());
  596.                 $lectureRepository->save($lecturetrue);
  597.             }
  598.             $quizLost $quizLostRepository->findOneBy(['chapitre' => $chapitre'eleve' => $eleve]);
  599.         } else {
  600.             $lecture $lectureRepository->findOneBy(['eleve' => $eleve'cours' => $cours]);
  601.             $lecture->setCours($cours)->setEleve($eleve)->setIsFinished(false)->setReference(time() + $eleve->getId())->setStartAt(new \DateTimeImmutable());
  602.             $lectureRepository->save($lecturetrue);
  603.             $quizLost $quizLostRepository->findOneBy(['cours' => $cours'eleve' => $eleve]);
  604.         }
  605.         $quizzesResults = [];
  606.         if ($request->request->get('submit') !== null && $this->isCsrfTokenValid('postquiz' $cours->getId(), $request->request->get('_token'))) {
  607.             $data $request->request->getIterator();
  608.             $noteQuiz 0;
  609.             // dd($data['quizzes']);
  610.             $quizzes $data['quizzes'];
  611.             foreach ($quizzes as $quizze) {
  612.                 $quizId $quizze['id'];
  613.                 $results $quizze['reponses'];
  614.                 $quiz $quizRepository->find($quizId);
  615.                 if ($quiz === null) {
  616.                     throw $this->createAccessDeniedException("Corrupted data send");
  617.                 }
  618.                 $isCorrect false;
  619.                 $note 0;
  620.                 // dump($quiz->getPropositionJuste());
  621.                 if ($results == $quiz->getPropositionJuste()) {
  622.                     $isCorrect true;
  623.                     $note 20 count($chapitre->getQuizzes());
  624.                     $noteQuiz += $note;
  625.                     // dd($results);
  626.                 }
  627.                 if ($eleve !== null) {
  628.                     $quizResult $quizResultRepository->findOneBy(['quiz' => $quiz'eleve' => $eleve,]);
  629.                     if ($quizResult === null) {
  630.                         $quizResult = new QuizResult();
  631.                     }
  632.                     $quizResult->setEleve($eleve)->setQuiz($quiz)->setIsCorrect($isCorrect)->setResult($results)->setNote($note)->setUpdatedAt(new \DateTimeImmutable());
  633.                     $quizResultRepository->save($quizResult);
  634.                 } else {
  635.                     $quizResult = new QuizResult();
  636.                     $quizResult->setQuiz($quiz)->setIsCorrect($isCorrect)->setResult($results)->setNote($note)->setUpdatedAt(new \DateTimeImmutable());
  637.                     $quizzesResults[] = $quizResult;
  638.                 }
  639.                 // dump($quiz);dump($quizResult);dump($note);
  640.             }
  641.             if ($eleve !== null) {
  642.                 if ($lecture === null) {
  643.                     $lecture = new Lecture();
  644.                     if ($chapitre !== null) {
  645.                         $lecture->setChapitre($chapitre);
  646.                     } else {
  647.                         $lecture->setCours($cours);
  648.                     }
  649.                     $lecture->setEleve($eleve)->setReference(time() + $quiz->getId())->setEndAt(new \DateTimeImmutable());
  650.                 }
  651.                 $isFinished false;
  652.                 if (($noteQuiz 100) / 20 >= 50) {
  653.                     $isFinished true;
  654.                 }
  655.                 $lecture->setIsFinished($isFinished)->setNote($noteQuiz);
  656.                 if ($isFinished) {
  657.                     if ($lecture->getChapitre()) {
  658.                         $nextChapNumber $lecture->getChapitre()->getNumero() + 1;
  659.                         $nextChapter $chapitreRepository->findOneBy(['numero' => $nextChapNumber'cours' => $lecture->getChapitre()->getCours()]);
  660.                         if ($nextChapter && count($nextChapter->getLessons()) > 0) {
  661.                             $newLecture = new Lecture();
  662.                             $newLecture->setLesson($nextChapter->getLessons()[0])
  663.                                 ->setEleve($eleve)->setStartAt(new \DateTimeImmutable())->setReference(time() + $nextChapter->getId())
  664.                                 ->setIsFinished(false);
  665.                             $lectureRepository->save($newLecture);
  666.                         }
  667.                     } else {
  668.                         // il n'y a plus de chapitres donc on passe au quiz de fin de chapitre
  669.                         $newLecture = new Lecture();
  670.                         $newLecture->setCours($cours)
  671.                             ->setEleve($eleve)->setStartAt(new \DateTimeImmutable())->setReference(time() + $cours->getId())
  672.                             ->setIsFinished(false);
  673.                         $lectureRepository->save($newLecture);
  674.                     }
  675.                 }
  676.                 $lectureRepository->save($lecture);
  677.                 if (!$isFinished) {
  678.                     if ($quizLost === null) {
  679.                         $quizLost = new QuizLost();
  680.                         if ($chapitre) {
  681.                             $quizLost->setChapitre($chapitre);
  682.                         } else {
  683.                             $quizLost->setCours($cours);
  684.                         }
  685.                         $quizLost->setEleve($eleve);
  686.                     }
  687.                     $quizLost->setAttempt($quizLost->getAttempt() + 1)
  688.                         ->setLastAt(new \DateTimeImmutable())
  689.                         ->setNextAt(new DateTimeImmutable(date('Y-m-d H:i:s'strtotime('+10 second'))))
  690.                         ->setIsOk(false);
  691.                     $quizLostRepository->save($quizLost);
  692.                 } else {
  693.                     if ($quizLost !== null) {
  694.                         $quizLost->setLastAt(new \DateTimeImmutable())
  695.                             ->setIsOk(true);
  696.                         $quizLostRepository->save($quizLost);
  697.                     }
  698.                 }
  699.             }
  700.             // dump("Note: ".$noteQuiz);dd($data['quizzes']);
  701.             $entityManager->flush();
  702.             if ($eleve) {
  703.                 if ($chapitre) {
  704.                     return $this->redirectToRoute('app_front_course_chapitre_quizzes', ['slugCours' => $cours->getSlug(), 'slugChapitre' => $chapitre->getSlug()]);
  705.                 }
  706.                 return $this->redirectToRoute('app_front_course_course_quizzes', ['slugCours' => $cours->getSlug()]);
  707.             }
  708.         }
  709.         $showCorrection false;
  710.         $currentDate = new \DateTimeImmutable();
  711.         $nextQuizAt null;
  712.         if (($lecture && $lecture->isIsFinished()) || $quizLost && $currentDate->getTimestamp() < $quizLost->getNextAt()->getTimestamp()) {
  713.             $showCorrection true;
  714.             $quizzesResults $quizResultRepository->findStudentQuizResultsByCourseOrChapter($eleve$cours$chapitre);
  715.             if ($quizLost && !$quizLost->isIsOk()) {
  716.                 $nextQuizAt $quizLost->getNextAt();
  717.             }
  718.         }
  719.         return $this->render('front/courses/quiz.html.twig', [
  720.             'chapitre' => $chapitre,
  721.             'quizzes' => $chapitre !== null $chapitre->getQuizzes() : $quizRepository->findBy(['cours' => $cours'chapitre' => null]),
  722.             'cours' => $cours,
  723.             'submitUri' => $chapitre === null $this->generateUrl('app_front_course_course_quizzes', ['slugCours' => $cours->getSlug()]) : $this->generateUrl('app_front_course_chapitre_quizzes', ['slugCours' => $cours->getSlug(), 'slugChapitre' => $chapitre->getSlug()]),
  724.             'isCorrectionMode' => $showCorrection,
  725.             'lecture' => $lecture,
  726.             'quizzesResults' => $quizzesResults,
  727.             'nextQuizAt' => $nextQuizAt,
  728.         ]);
  729.     }
  730. }