src/Pumukit/WebTVBundle/Controller/DefaultController.php line 325

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Pumukit\WebTVBundle\Controller;
  4. use Detection\MobileDetect;
  5. use Doctrine\ODM\MongoDB\DocumentManager;
  6. use MongoDB\BSON\ObjectId;
  7. use Psr\Log\LoggerInterface;
  8. use Pumukit\SchemaBundle\Document\EmbeddedBroadcast;
  9. use Pumukit\SchemaBundle\Document\Live;
  10. use Pumukit\SchemaBundle\Document\MultimediaObject;
  11. use Pumukit\SchemaBundle\Services\EmbeddedEventSessionService;
  12. use Pumukit\WebTVBundle\Form\Type\ContactType;
  13. use Pumukit\WebTVBundle\PumukitWebTVBundle;
  14. use Pumukit\WebTVBundle\Services\BreadcrumbsService;
  15. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  16. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  17. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  18. use Symfony\Component\HttpFoundation\JsonResponse;
  19. use Symfony\Component\HttpFoundation\Request;
  20. use Symfony\Component\HttpFoundation\Response;
  21. use Symfony\Component\Routing\Annotation\Route;
  22. use Symfony\Contracts\Translation\TranslatorInterface;
  23. class DefaultController extends AbstractController
  24. {
  25.     protected $documentManager;
  26.     protected $breadcrumbService;
  27.     protected $embeddedEventSessionService;
  28.     protected $translator;
  29.     protected $logger;
  30.     protected $mailer;
  31.     protected $captchaPublicKey;
  32.     protected $captchaPrivateKey;
  33.     protected $pumukitLiveEventContactAndShare;
  34.     protected $pumukitIntro;
  35.     protected $pumukitNotificationSenderEmail;
  36.     protected $pumukitInfo;
  37.     protected $mobileDetector;
  38.     public function __construct(
  39.         DocumentManager $documentManager,
  40.         BreadcrumbsService $breadcrumbService,
  41.         EmbeddedEventSessionService $embeddedEventSessionService,
  42.         TranslatorInterface $translator,
  43.         LoggerInterface $logger,
  44.         \Swift_Mailer $mailer,
  45.         $captchaPublicKey,
  46.         $captchaPrivateKey,
  47.         $pumukitLiveEventContactAndShare,
  48.         $pumukitIntro,
  49.         $pumukitNotificationSenderEmail,
  50.         $pumukitInfo
  51.     ) {
  52.         $this->documentManager $documentManager;
  53.         $this->breadcrumbService $breadcrumbService;
  54.         $this->embeddedEventSessionService $embeddedEventSessionService;
  55.         $this->translator $translator;
  56.         $this->logger $logger;
  57.         $this->mailer $mailer;
  58.         $this->captchaPublicKey $captchaPublicKey;
  59.         $this->captchaPrivateKey $captchaPrivateKey;
  60.         $this->pumukitLiveEventContactAndShare $pumukitLiveEventContactAndShare;
  61.         $this->pumukitIntro $pumukitIntro;
  62.         $this->pumukitNotificationSenderEmail $pumukitNotificationSenderEmail;
  63.         $this->pumukitInfo $pumukitInfo;
  64.         $this->mobileDetector = new MobileDetect();
  65.     }
  66.     /**
  67.      * @Route("/live/{id}", name="pumukit_live_id")
  68.      *
  69.      * @Template("@PumukitWebTV/Live/Basic/template.html.twig")
  70.      */
  71.     public function indexAction(Live $liveRequest $request)
  72.     {
  73.         $this->updateBreadcrumbs($live->getName(), 'pumukit_live_id', ['id' => $live->getId()]);
  74.         return $this->doLive($live$request);
  75.     }
  76.     /**
  77.      * @Route("/live/iframe/{id}", name="pumukit_live_iframe_id")
  78.      *
  79.      * @Template("@PumukitWebTV/Live/Basic/template_iframe.html.twig")
  80.      */
  81.     public function iframeAction(Live $liveRequest $request)
  82.     {
  83.         return $this->doLive($live$request);
  84.     }
  85.     /**
  86.      * @Route("/live/event/{id}", name="pumukit_live_event_id")
  87.      *
  88.      * @ParamConverter("multimediaObject", options={"mapping": {"id": "id"}})
  89.      *
  90.      * @Template("@PumukitWebTV/Live/Advance/template.html.twig")
  91.      */
  92.     public function indexEventAction(MultimediaObject $multimediaObjectRequest $request)
  93.     {
  94.         $criteria = [
  95.             '_id' => new ObjectId($multimediaObject->getId()),
  96.         ];
  97.         $nowSessions $this->embeddedEventSessionService->findCurrentSessions($criteria0true);
  98.         $nextSession $this->embeddedEventSessionService->findNextSessions($criteria0true);
  99.         if ((is_countable($nextSession) ? count($nextSession) : 0) > || (is_countable($nowSessions) ? count($nowSessions) : 0) > 0) {
  100.             $this->updateBreadcrumbs($this->translator->trans('Live events'), 'pumukit_webtv_events');
  101.             return $this->iframeEventAction($multimediaObject$requestfalse);
  102.         }
  103.         $series $multimediaObject->getSeries();
  104.         $qb $this->getMultimediaObjects($series->getId());
  105.         $multimediaObjects $qb->getQuery()->execute()->toArray();
  106.         if (=== (is_countable($multimediaObjects) ? count($multimediaObjects) : 0) && $multimediaObjects[0]->getDisplayTrack()) {
  107.             return $this->redirectToRoute('pumukit_webtv_multimediaobject_index', ['id' => $multimediaObjects[0]->getId()]);
  108.         }
  109.         if ((is_countable($multimediaObjects) ? count($multimediaObjects) : 0) > && !$series->isHide()) {
  110.             return $this->redirectToRoute('pumukit_webtv_series_index', ['id' => $series->getId()]);
  111.         }
  112.         return $this->iframeEventAction($multimediaObject$requestfalse);
  113.     }
  114.     /**
  115.      * @Route("/live/event/iframe/{id}", name="pumukit_live_event_iframe_id")
  116.      *
  117.      * @ParamConverter("multimediaObject", options={"mapping": {"id": "id"}})
  118.      *
  119.      * @Template("@PumukitWebTV/Live/Advance/iframe.html.twig")
  120.      */
  121.     public function iframeEventAction(MultimediaObject $multimediaObjectRequest $requestbool $iframe true)
  122.     {
  123.         if (EmbeddedBroadcast::TYPE_PASSWORD === $multimediaObject->getEmbeddedBroadcast()->getType() && $multimediaObject->getEmbeddedBroadcast()->getPassword() !== $request->get('broadcast_password')) {
  124.             return $this->render($iframe '@PumukitWebTV/Live/Basic/template_iframe_password.html.twig' '@PumukitWebTV/Live/Basic/template_password.html.twig', [
  125.                 'live' => $multimediaObject->getEmbeddedEvent(),
  126.                 'invalid_password' => (bool) $request->get('broadcast_password'),
  127.             ]);
  128.         }
  129.         if (!$this->isGranted('IS_AUTHENTICATED_FULLY') && EmbeddedBroadcast::TYPE_LOGIN === $multimediaObject->getEmbeddedBroadcast()->getType()) {
  130.             $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
  131.         }
  132.         $userAgent $request->headers->get('user-agent');
  133.         $mobileDevice = ($this->mobileDetector->isMobile($userAgent) || $this->mobileDetector->isTablet($userAgent));
  134.         $isIE $this->mobileDetector->version('IE');
  135.         $versionIE $isIE ? (float) $isIE 11.0;
  136.         $locale $request->getLocale();
  137.         $form $this->createForm(ContactType::class, null, ['translator' => $this->translator'locale' => $locale]);
  138.         $activeContact false;
  139.         $captchaPublicKey '';
  140.         if ($this->pumukitLiveEventContactAndShare) {
  141.             $captchaPublicKey $this->captchaPublicKey;
  142.             $activeContact true;
  143.         }
  144.         $criteria = [
  145.             '_id' => new ObjectId($multimediaObject->getId()),
  146.         ];
  147.         $nowSessions $this->embeddedEventSessionService->findCurrentSessions($criteria0true);
  148.         $now = new \DateTime();
  149.         $firstNowSessionEnds = new \DateTime();
  150.         $firstNowSessionEnds $firstNowSessionEnds->getTimestamp();
  151.         $firstNowSessionRemainingDuration 0;
  152.         foreach ($nowSessions as $session) {
  153.             $firstNowSessionEnds = ($session['data'][0]['session']['start']->toDateTime()->format('U') + $session['data'][0]['session']['duration']) * 1000;
  154.             $firstNowSessionRemainingDuration $firstNowSessionEnds - ($now->getTimeStamp() * 1000);
  155.             break;
  156.         }
  157.         $nextSessions $this->embeddedEventSessionService->findNextSessions($criteria0true);
  158.         $date = new \DateTime();
  159.         $firstNextSession '';
  160.         foreach ($multimediaObject->getEmbeddedEvent()->getEmbeddedEventSession() as $session) {
  161.             if ($session->getStart() < $date && $session->getEnds() > $date) {
  162.                 $firstNextSession $session->getStart()->getTimestamp() * 1000;
  163.                 break;
  164.             }
  165.             if ($session->getStart() > $date) {
  166.                 $firstNextSession $session->getStart()->getTimestamp() * 1000;
  167.                 break;
  168.             }
  169.         }
  170.         $secondsToEvent null;
  171.         if (!empty($firstNextSession)) {
  172.             $secondsToEvent $firstNextSession - ($now->getTimeStamp() * 1000);
  173.         }
  174.         if ($iframe && === (is_countable($nowSessions) ? count($nowSessions) : 0) && === (is_countable($nextSessions) ? count($nextSessions) : 0)) {
  175.             $qb $this->getMultimediaObjects($multimediaObject->getSeries()->getId());
  176.             $qb->field('embeddedBroadcast.type')->equals(EmbeddedBroadcast::TYPE_PUBLIC);
  177.             $multimediaObjectPlaylist $qb->getQuery()->getSingleResult();
  178.             if ($multimediaObjectPlaylist) {
  179.                 $autostart $request->query->get('autostart''true');
  180.                 return $this->redirectToRoute(
  181.                     'pumukit_playlistplayer_index',
  182.                     ['id' => $multimediaObjectPlaylist->getSeries()->getId(), 'autostart' => $autostart]
  183.                 );
  184.             }
  185.         }
  186.         return [
  187.             'multimediaObject' => $multimediaObject,
  188.             'firstNextSession' => $firstNextSession,
  189.             'secondsToEvent' => $secondsToEvent,
  190.             'firstNowSessionEnds' => $firstNowSessionEnds,
  191.             'firstNowSessionDuration' => $firstNowSessionRemainingDuration,
  192.             'nowSessions' => $nowSessions,
  193.             'nextSessions' => $nextSessions,
  194.             'captcha_public_key' => $captchaPublicKey,
  195.             'live' => $multimediaObject->getEmbeddedEvent()->getLive(),
  196.             'contact' => $form->createView(),
  197.             'activeContact' => $activeContact,
  198.             'success' => -1,
  199.             'mobile_device' => $mobileDevice,
  200.             'isIE' => $isIE,
  201.             'versionIE' => $versionIE,
  202.             'showDownloads' => true,
  203.         ];
  204.     }
  205.     /**
  206.      * @Route("/live", name="pumukit_live")
  207.      *
  208.      * @Template("@PumukitWebTV/Live/Basic/template.html.twig")
  209.      */
  210.     public function defaultAction(Request $request)
  211.     {
  212.         $live $this->documentManager->getRepository(Live::class)->findOneBy([]);
  213.         if (!$live) {
  214.             throw $this->createNotFoundException('The live channel does not exist');
  215.         }
  216.         $this->updateBreadcrumbs($live->getName(), 'pumukit_live', ['id' => $live->getId()]);
  217.         return $this->doLive($live$request);
  218.     }
  219.     /**
  220.      * @Route("/live/playlist/{id}", name="pumukit_live_playlist_id", defaults={"_format": "xml"})
  221.      */
  222.     public function playlistAction(Live $live): Response
  223.     {
  224.         $intro $this->pumukitIntro ?? null;
  225.         $mmobjsPlaylist $this->documentManager->getRepository(MultimediaObject::class)->findBy([
  226.             'properties.is_live_playlist' => true,
  227.         ]);
  228.         $response = ['live' => $live];
  229.         if ($mmobjsPlaylist) {
  230.             $response['items'] = $mmobjsPlaylist;
  231.         } elseif ($intro) {
  232.             $response['items'] = $intro;
  233.         } else {
  234.             $response['items'] = '/bundles/pumukitwebtv/live/video/default.mp4';
  235.         }
  236.         return $this->render('@PumukitWebTV/Live/Basic/playlist.xml.twig'$response);
  237.     }
  238.     /**
  239.      * @Route("/event/contact/{id}", name="pumukit_webtv_contact_event")
  240.      *
  241.      * @ParamConverter("multimediaObject", options={"mapping": {"id": "id"}})
  242.      */
  243.     public function contactAction(MultimediaObject $multimediaObjectRequest $request): JsonResponse
  244.     {
  245.         if ('POST' === $request->getMethod() && $this->checkCaptcha($request->request->get('g-recaptcha-response'), $request->getClientIp())) {
  246.             $mail $this->pumukitNotificationSenderEmail ?? 'noreplay@yourplatform.es';
  247.             $to $multimediaObject->getEmbeddedSocial()->getEmail();
  248.             $data $request->request->get('pumukit_multimedia_object_contact');
  249.             $bodyMail sprintf(" * URL: %s\n * ".$this->translator->trans('Email').": %s\n * ".$this->translator->trans('Name').": %s\n * ".$this->translator->trans('Content').": %s\n "$request->headers->get('referer''No referer'), $data['email'], $data['name'], $data['content']);
  250.             $subject sprintf(
  251.                 '%s - %s: %s',
  252.                 $this->pumukitInfo['title'],
  253.                 $this->translator->trans('New contact from live event'),
  254.                 $multimediaObject->getEmbeddedEvent()->getName()
  255.             );
  256.             $message = new \Swift_Message();
  257.             $message->setSubject($subject)->setSender($mail)->setFrom($mail)->setTo($to)->setBody($bodyMail'text/plain');
  258.             $sent $this->mailer->send($message);
  259.             if (=== $sent) {
  260.                 $this->logger->error('Event contact: Error sending message from - '.$request->request->get('email'));
  261.             }
  262.             return new JsonResponse([
  263.                 'success' => true,
  264.                 'message' => $this->translator->trans('email send'),
  265.             ]);
  266.         }
  267.         return new JsonResponse([
  268.             'success' => false,
  269.             'message' => $this->translator->trans('please verify form data'),
  270.         ]);
  271.     }
  272.     /**
  273.      * @Route("/sitemap", name="pumukit_sitemap")
  274.      */
  275.     public function siteMapAction(): Response
  276.     {
  277.         $this->updateBreadcrumbs($this->translator->trans('Sitemap'), 'pumukit_sitemap');
  278.         return $this->render('@PumukitWebTV/Misc/map.html.twig');
  279.     }
  280.     protected function doLive(Live $liveRequest $requestbool $iframe true)
  281.     {
  282.         if ($live->getPasswd() && $live->getPasswd() !== $request->get('broadcast_password')) {
  283.             return $this->render($iframe '@PumukitWebTV/Live/Basic/template_iframe_password.html.twig' '@PumukitWebTV/Live/Basic/template_password.html.twig', [
  284.                 'live' => $live,
  285.                 'invalid_password' => (bool) $request->get('broadcast_password'),
  286.             ]);
  287.         }
  288.         $userAgent $request->headers->get('user-agent');
  289.         $mobileDevice = ($this->mobileDetector->isMobile($userAgent) || $this->mobileDetector->isTablet($userAgent));
  290.         $isIE $this->mobileDetector->version('IE');
  291.         $versionIE $isIE ? (float) $isIE 11.0;
  292.         return [
  293.             'live' => $live,
  294.             'mobile_device' => $mobileDevice,
  295.             'isIE' => $isIE,
  296.             'versionIE' => $versionIE,
  297.         ];
  298.     }
  299.     protected function updateBreadcrumbs(string $titlestring $routeName, array $routeParameters = []): void
  300.     {
  301.         $this->breadcrumbService->addList($title$routeName$routeParameters);
  302.     }
  303.     private function getMultimediaObjects($seriesId)
  304.     {
  305.         $qb $this->documentManager->getRepository(MultimediaObject::class)->createStandardQueryBuilder()
  306.             ->field('status')->equals(MultimediaObject::STATUS_PUBLISHED)
  307.             ->field('tags.cod')->equals(PumukitWebTVBundle::WEB_TV_TAG)
  308.             ->field('series')->equals(new ObjectId($seriesId))
  309.         ;
  310.         $qb->field('tracks')->elemMatch($qb->expr()->field('tags')->equals('display')->field('hide')->equals(false));
  311.         return $qb;
  312.     }
  313.     private function checkCaptcha($responsestring $remoteip '')
  314.     {
  315.         if (null === $response || === strlen($response)) {
  316.             return false;
  317.         }
  318.         $response $this->recaptchaHttpPost([
  319.             'secret' => $this->captchaPrivateKey,
  320.             'remoteip' => $remoteip,
  321.             'response' => $response,
  322.         ]);
  323.         return json_decode($responsetrue512JSON_THROW_ON_ERROR)['success'];
  324.     }
  325.     /**
  326.      * Submits an HTTP POST to a reCAPTCHA server.
  327.      */
  328.     private function recaptchaHttpPost(array $data)
  329.     {
  330.         $verify curl_init();
  331.         curl_setopt($verifyCURLOPT_URL'https://www.google.com/recaptcha/api/siteverify');
  332.         curl_setopt($verifyCURLOPT_POSTtrue);
  333.         curl_setopt($verifyCURLOPT_POSTFIELDShttp_build_query($data));
  334.         curl_setopt($verifyCURLOPT_SSL_VERIFYPEERfalse);
  335.         curl_setopt($verifyCURLOPT_RETURNTRANSFERtrue);
  336.         return curl_exec($verify);
  337.     }
  338. }