src/Controller/Front/LiveController.php line 361

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Front;
  3. use App\Entity\Course;
  4. use App\Entity\Live;
  5. use App\Entity\ModuleParticipation;
  6. use App\Entity\Program;
  7. use App\Entity\Quiz;
  8. use App\Entity\Module;
  9. use App\Form\ProgramType;
  10. use App\Helper\ControllerHelper;
  11. use App\Repository\CourseRepository;
  12. use App\Repository\JitsiParameterRepository;
  13. use App\Repository\LiveRepository;
  14. use App\Repository\ModuleItemRepository;
  15. use App\Repository\ModuleParticipationRepository;
  16. use App\Repository\ProgramRepository;
  17. use App\Repository\QuizRepository;
  18. use App\Service\HelperService;
  19. use DateInterval;
  20. use DateTime;
  21. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  22. use Symfony\Component\HttpFoundation\Request;
  23. use Symfony\Component\HttpFoundation\Response;
  24. use Symfony\Component\Routing\Annotation\Route;
  25. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  26. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  27. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  28. use Symfony\Component\HttpFoundation\JsonResponse;
  29. use Jose\Component\KeyManagement\JWKFactory;
  30. use Jose\Component\Core\AlgorithmManager;
  31. use Jose\Component\Signature\Algorithm\RS256;
  32. use Jose\Component\Signature\JWSBuilder;
  33. use Jose\Component\Signature\Serializer\CompactSerializer;
  34. /**
  35.  * Require ROLE_EMPLOYEE for all the actions of this controller
  36.  *
  37.  * @IsGranted("ROLE_EMPLOYEE")
  38.  * 
  39.  * @Route("/live")
  40.  */
  41. class LiveController extends AbstractController
  42. {
  43.     use ControllerHelper;
  44.     /**
  45.      * @Route("/{id}/meeting", name="app_front_live_meet_page")
  46.      * @Route("/{id}/{module_slug}/meeting", name="app_front_live_module_meet_page")
  47.      * @ParamConverter("module", options={"mapping": {"module_slug": "slug"}})
  48.      */
  49.     public function index(Request $requestJitsiParameterRepository $jitsiParameterRepositoryModuleParticipationRepository $moduleParticipationRepositoryModuleItemRepository $moduleItemRepositoryCourseRepository $courseRepositoryQuizRepository $quizRepositoryLiveRepository $liveRepositoryLive $liveHelperService $helperServiceModule $module null): Response
  50.     {
  51.         $currentUser $this->getUser();
  52.         if ($live === null) throw $this->createAccessDeniedException("Accès non autorisé");
  53.         if ($module === null$module $this->getActiveModule($live$currentUser);
  54.         $program = new Program();
  55.         $form $this->createForm(ProgramType::class, $program);
  56.         $form->handleRequest($request);
  57.         $jitsiParameter $jitsiParameterRepository->findOneBy(['isActive' => true]);
  58.         // $module = $this->getActiveModule($live);
  59.         if ($jitsiParameter === null || $module === null) {
  60.             throw $this->createAccessDeniedException("Impossible de demarrer la conférence. Veuillez contacter l'administrateur !");
  61.         }
  62.         $isModerator = (($live->getCoaches()->count() > && $live->getCoaches()->contains($currentUser)) || $this->isGranted('ROLE_INTEGRATOR') || $this->isGranted('ROLE_ADMIN'));
  63.         // $module = $this->getActiveModule($live);
  64.         $_program $this->getActiveProgram($moduletrue$currentUser);
  65.         $moduleParticipation $moduleParticipationRepository->findOneBy(['program' => $_program'module' => $module'live' => $live'createdBy' => $currentUser]);
  66.         if ($moduleParticipation === null) {
  67.             $moduleParticipation = new ModuleParticipation();
  68.             $moduleParticipation->setModule($module);
  69.             $moduleParticipation->setLive($live);
  70.             $moduleParticipation->setProgram($_program);
  71.     
  72.             $moduleParticipationRepository->add($moduleParticipationtrue);
  73.         }
  74.         $startDate = clone $live->getStartAt();
  75.         $endDate = clone $live->getEndAt();
  76.         // $liveStartAt = $live->getStartAt()->format('d/m/Y');
  77.         // $liveEndAt = $live->getEndAt()->format('d/m/Y');
  78.         $liveStartAt = ($startDate !== null) ? $startDate : new DateTime();
  79.         $liveEndAt = ($endDate !== null) ? $endDate->add(new DateInterval('P1D')) : $startDate->add(new DateInterval('P1D'));
  80.         $liveStartAt->setTime(000);
  81.         $liveEndAt->setTime(235959);
  82.         $nbf $liveStartAt->format('U');
  83.         $exp $liveEndAt->format('U');
  84.         $items $moduleItemRepository->findItems($module);
  85.         $keys = [];
  86.         $keys array_keys(array_column($items'live_id'), $live->getId());
  87.     
  88.         $currentItemKey = isset($keys[0]) ? $keys[0] : 0;
  89.         $currentItemAsArray $items[$currentItemKey];
  90.         $prevItemAsArray = (isset($items[$currentItemKey 1])) ? $items[$currentItemKey 1] : null;
  91.         $nextItemAsArray = (isset($items[$currentItemKey 1])) ? $items[$currentItemKey 1] : null;
  92.         $prevItem null;
  93.         $nextItem null;
  94.         if ($prevItemAsArray !== null && isset($prevItemAsArray['type'])) {
  95.             // $prevItem = ($prevItemAsArray['type'] === 'course') ? $courseRepository->findOneById($prevItemAsArray['course_id']) : $quizRepository->findOneById($prevItemAsArray['quiz_id']);
  96.             switch ($prevItemAsArray['type']) {
  97.                 case 'course':
  98.                     $prevItem $courseRepository->findOneById($prevItemAsArray['course_id']);
  99.                     break;
  100.                 case 'quiz':
  101.                     $prevItem $quizRepository->findOneById($prevItemAsArray['quiz_id']);
  102.                     break;
  103.                 default:
  104.                     $prevItem $liveRepository->findOneById($prevItemAsArray['live_id']);
  105.                     break;
  106.             }
  107.             // $prevItem = $quizRepository->findOneById($prevItemAsArray[$prevItemAsArray['type'].'_id']);
  108.         }
  109.         if ($nextItemAsArray !== null && isset($nextItemAsArray['type'])) {
  110.             // $nextItem = ($nextItemAsArray['type'] === 'course') ? $courseRepository->findOneById($nextItemAsArray['course_id']) : $quizRepository->findOneById($nextItemAsArray['quiz_id']);
  111.             switch ($nextItemAsArray['type']) {
  112.                 case 'course':
  113.                     $nextItem $courseRepository->findOneById($nextItemAsArray['course_id']);
  114.                     break;
  115.                 case 'quiz':
  116.                     $nextItem $quizRepository->findOneById($nextItemAsArray['quiz_id']);
  117.                     break;
  118.                 default:
  119.                     $nextItem $liveRepository->findOneById($nextItemAsArray['live_id']);
  120.                     break;
  121.             }
  122.             // $nextItem = $courseRepository->findOneById($nextItemAsArray[$nextItemAsArray['type'].'_id']);
  123.         }
  124.         $prevItemType = ($prevItem !== null) ? (($prevItem instanceof Course) ? 'course' : (($prevItem instanceof Quiz) ? 'quiz' 'live')) : null;
  125.         $nextItemType = ($nextItem !== null) ? (($nextItem instanceof Course) ? 'course' : (($nextItem instanceof Quiz) ? 'quiz' 'live')) : null;
  126.         // Jaas Token generation
  127.         $token $helperService->getJaasToken($currentUser$jitsiParameter$isModerator$nbf$exp);
  128.         $isQuizzAlreadyStarted false;
  129.         if ($prevItemType === 'quiz' || $nextItemType === 'quiz') {
  130.             $moduleParticipation = ($prevItemType === 'quiz') ? $moduleParticipationRepository->findOneBy(['program' => $program'module' => $module'quiz' => $prevItem'createdBy' => $currentUser]) : $moduleParticipationRepository->findOneBy(['module' => $module'quiz' => $nextItem'createdBy' => $currentUser]);
  131.             $isQuizzAlreadyStarted = ($moduleParticipation !== null);
  132.         }
  133.        
  134.         return $this->render('front/pages/live/index.html.twig', [
  135.             'program' => $program,
  136.             'live' => $live,
  137.             'form' => $form,
  138.             'jitsiParameter' => $jitsiParameter,
  139.             'isModerator' => $isModerator,
  140.             'nbf' => $nbf,
  141.             'exp' => $exp,
  142.             'module' => $module,
  143.             'prevItem' => $prevItem,
  144.             'prevItemType' => $prevItemType,
  145.             'nextItem' => $nextItem,
  146.             'nextItemType' => $nextItemType,
  147.             'token' => $token,
  148.             'isJaas' => $jitsiParameter->isIsJaas(),
  149.             'canAccess' => $liveStartAt <= (new DateTime())->setTime(0,0,0) && $liveEndAt >= (new DateTime())->setTime(0,0,0),
  150.             'isQuizzAlreadyStarted' => $isQuizzAlreadyStarted
  151.         ]);
  152.     }
  153.     /**
  154.      * @Route("/{slug}/meeting-cofilive", name="app_front_cofi_live_meet_page")
  155.      * @ParamConverter("live", options={"mapping": {"slug": "slug"}})
  156.      */
  157.     public function cofilive(Request $requestJitsiParameterRepository $jitsiParameterRepositoryLiveRepository $liveRepositoryLive $live): Response
  158.     {
  159.         if ($live === null) throw $this->createAccessDeniedException("Accès non autorisé");
  160.         $program = new Program();
  161.         $form $this->createForm(ProgramType::class, $program);
  162.         $form->handleRequest($request);
  163.         $jitsiParameter $jitsiParameterRepository->findOneBy(['isActive' => true]);
  164.         // $module = $this->getActiveModule($live);
  165.         if ($jitsiParameter === null) {
  166.             throw $this->createAccessDeniedException("Impossible de demarrer la conférence. Veuillez contacter l'administrateur !");
  167.         }
  168.         $isModerator = (($live->getCoaches()->count() > && $live->getCoaches()->contains($this->getUser())) || $this->isGranted('ROLE_INTEGRATOR') || $this->isGranted('ROLE_ADMIN'));
  169.         $startDate = clone $live->getStartAt();
  170.         $endDate = clone $live->getEndAt();
  171.         $liveStartAt = ($startDate !== null) ? $startDate : new DateTime();
  172.         $liveEndAt = ($endDate !== null) ? $endDate->add(new DateInterval('P1D')) : $startDate->add(new DateInterval('P1D'));
  173.        
  174.         $liveStartAt->setTime(000);
  175.         $liveEndAt->setTime(235959);
  176.         $nbf $liveStartAt->format('U');
  177.         $exp $liveEndAt->format('U');
  178.         $jwk JWKFactory::createFromKeyFile($this->getParameter('kernel.project_dir').'/jitsi/Cofina.pk');
  179.         /**
  180.          * Setup the algoritm used to sign the token.
  181.          * @var \Jose\Component\Core\AlgorithmManager $algorithm
  182.          */
  183.         $algorithm = new AlgorithmManager([
  184.             new RS256()
  185.         ]);
  186.         /**
  187.          * The builder will create and sign the token.
  188.          * @var \Jose\Component\Signature\JWSBuilder $jwsBuilder
  189.          */
  190.         $jwsBuilder = new JWSBuilder($algorithm);
  191.         $currentUser $this->getUser();
  192.         /**
  193.          * Must setup JaaS payload!
  194.          * Change the claims below or using the variables from above!
  195.          */
  196.         $payload json_encode([
  197.             'iss' => 'chat',
  198.             'aud' => 'jitsi',
  199.             'exp' => (int)$exp,
  200.             'nbf' => (int)$nbf,
  201.             'room'=> '*',
  202.             'sub' => $jitsiParameter->getAppId(),
  203.             'context' => [
  204.                 'user' => [
  205.                     'moderator' => $isModerator "true" "false",
  206.                     'email' => $currentUser->getEmail(),
  207.                     'name' => $currentUser->getFullName(),
  208.                     'avatar' => '/assets/front/img/LOGO COFINA ACADEMY 1.png',
  209.                     'id' => $currentUser->getId()
  210.                 ],
  211.                 'features' => [
  212.                     'recording' => "true",
  213.                     'livestreaming' => "true",
  214.                     'transcription' => "true",
  215.                     'outbound-call' => "false"
  216.                 ]
  217.             ]
  218.         ]);
  219.         /**
  220.          * Create a JSON Web Signature (https://tools.ietf.org/html/rfc7515)
  221.          * using the payload created above and the api key specified for the kid claim.
  222.          * 'alg' (RS256) and 'typ' claims are also needed.
  223.          */
  224.         $jws $jwsBuilder
  225.             ->create()
  226.             ->withPayload($payload)
  227.             ->addSignature($jwk, [
  228.                 'alg' => 'RS256',
  229.                 'kid' => $jitsiParameter->getAppSecret(),
  230.                 'typ' => 'JWT'
  231.             ])
  232.             ->build();
  233.         /**
  234.          * We use the serializer to base64 encode into the final token.
  235.          * @var \Jose\Component\Signature\Serializer\CompactSerializer $serializer
  236.          */
  237.         $serializer = new CompactSerializer();
  238.         $token $serializer->serialize($jws0);
  239.         //dd(, (new DateTime())->setTime(0,0,0));
  240.         //dd((new DateTime())->setTime(0,0,0));
  241.         //dd($liveStartAt <= (new DateTime())->setTime(0,0,0) && $liveEndAt >= (new DateTime())->setTime(0,0,0));
  242.        
  243.         return $this->render('front/pages/live/index.html.twig', [
  244.             'program' => $program,
  245.             'live' => $live,
  246.             'form' => $form,
  247.             'jitsiParameter' => $jitsiParameter,
  248.             'isModerator' => $isModerator,
  249.             'nbf' => $nbf,
  250.             'exp' => $exp,
  251.             'module' => null,
  252.             'prevItem' => null,
  253.             'prevItemType' => null,
  254.             'nextItem' => null,
  255.             'nextItemType' => null,
  256.             'token' => $token,
  257.             'isJaas' => $jitsiParameter->isIsJaas(),
  258.             'canAccess' => $liveStartAt <= (new DateTime())->setTime(0,0,0) && $liveEndAt >= (new DateTime())->setTime(0,0,0
  259.         ]);
  260.     }
  261.     /**
  262.      * @Route("/{profil}/page", name="app_front_lives_page")
  263.      */
  264.     public function live(Request $requestLiveRepository $liveRepository): Response
  265.     {
  266.         // {
  267.         //     id: 'a',
  268.         //     start: '2023-02-03 02:30:00',
  269.         //     url: "javascript:void(0)",
  270.         //     link: "{{ url('app_front_homepage') }}",
  271.         //     classNames: "text-center fw-bold w-100",
  272.         //     title: "Academy UPB",
  273.         //     backgroundColor: "transparent",
  274.         //     borderColor: "transparent",
  275.         //     textColor: "#000",
  276.         //     imgUrl: `{{ asset("assets/front/img/users.jpg") }}`,
  277.         //     imgBackgroundColor: function (){
  278.         //         const palette = getPalette(this.imgUrl)
  279.         //         return `repeating-linear-gradient( -45deg, rgb(${palette[0]}) 0 50px, rgb(${palette[1]}) 20px 90px);`
  280.         //     },
  281.         //     coachName: "Test",
  282.         //     coachImg: "{{ asset("assets/front/img/users.jpg") }}"
  283.         // }
  284.         $lives $liveRepository->findViewLive($this->getUser());
  285.         $liveDate = [];
  286.         foreach ($lives as $key => $live) {
  287.             $data ['id'] = $live->getId();
  288.             $data ['start'] = $live->getStartAt()->format('Y-m-d H:i:s');
  289.             $data ['end'] = $live->getEndAt()->format('Y-m-d H:i:s');
  290.             //$data ['url'] = $this->generateUrl('app_front_live_meet_page', ['id' => $live->getId()], UrlGeneratorInterface::ABSOLUTE_URL);;
  291.             $data ['classNames'] = 'text-center fw-bold w-100';
  292.             $data ['title'] = $live->getTitle();
  293.             $data ['backgroundColor'] = 'transparent';
  294.             $data ['borderColor'] = 'transparent';
  295.             $data ['textColor'] = '#000';
  296.             $data ['imgUrl'] = ($live->getCover() !== null) ? '/files/images/'.$live->getCover()->getFileName() : '';
  297.             $data ['imgBackgroundColor'] = '';
  298.             $data ['coachName'] = (!$live->getCoaches()->isEmpty() ? $live->getCoaches()->first()->getFullname() : '');
  299.             $data ['coachImg'] = (!$live->getCoaches()->isEmpty() && $live->getCoaches()->first()->getPhoto() !== null '/files/images/'.$live->getCoaches()->first()->getPhoto()->getFileName() : '');
  300.             $_modules = [];
  301.             foreach($live->getModules() as $_module) {
  302.                 $_modules[] = array('id' => $_module->getId(), 'name' => $_module->getName(), 'slug' => $_module->getSlug(), 'cover' => $_module->getCover());
  303.             }
  304.             $data['modules'] = $_modules;
  305.             $data['slug'] = $live->getSlug();
  306.             $liveDate [] = $data;
  307.         }
  308.         // dump($liveDate); die;
  309.         $futureLives $liveRepository->findFutureLives($this->getUser());
  310.         return $this->render('front/pages/live/live.html.twig', [
  311.             'future_lives'  => $futureLives,
  312.             'live_data'  => $liveDate,
  313.             'lives'  => $lives,
  314.         ]);
  315.     }
  316.     /**
  317.      * @Route("/{profil}/has-running-live", name="app_front_has_running_live",  methods={"GET"})
  318.      */
  319.     public function hasRunningLive(Request $requestLiveRepository $liveRepository): Response
  320.     {
  321.         if(!$this->getUser()) {
  322.             return null;
  323.         }
  324.         $lives $liveRepository->hasCurrentLive($this->getUser());
  325.         //dd($lives);
  326.         return new JsonResponse(array('runningLive' => count($lives)));
  327.     }
  328. }