src/Controller/V1/MovieController.php line 200

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controller\V1;
  4. use App\Entity\Local\MovieFilter\Filters;
  5. use App\Entity\Netural\Review;
  6. use App\Entity\Netural\Reviews;
  7. use App\Entity\Vista\ScheduledFilm;
  8. use App\Helper\SessionHelper;
  9. use App\Repository\LocationRepository;
  10. use App\Repository\MovieFiltersRepository;
  11. use App\Repository\MovieRepositoryInterface as MovieRepository;
  12. use App\Repository\MovieArchiveRepository;
  13. use App\Repository\RestrictionsRepository;
  14. use App\Repository\ScheduledMovieRepository;
  15. use Doctrine\Common\Persistence\ManagerRegistry;
  16. use FOS\RestBundle\Controller\Annotations as Rest;
  17. use FOS\RestBundle\Controller\Annotations\Route;
  18. use FOS\RestBundle\Controller\Annotations\View;
  19. use FOS\RestBundle\Controller\FOSRestController;
  20. use Nelmio\ApiDocBundle\Annotation\Model;
  21. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  22. use Swagger\Annotations as SWG;
  23. use Symfony\Component\HttpFoundation\Request;
  24. use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException;
  25. use Symfony\Component\OptionsResolver\OptionsResolver;
  26. /**
  27.  * @Route("/movies")
  28.  * @SWG\Tag(name="Movie_v1")
  29.  */
  30. class MovieController extends FOSRestController
  31. {
  32.     use  ResponseTrait;
  33.     /** @var ScheduledMovieRepository|\Doctrine\Common\Persistence\ObjectRepository */
  34.     protected $scheduledMovieRepository;
  35.     /** @var SessionHelper */
  36.     protected $sessionHelper;
  37.     /** @var LocationRepository */
  38.     protected $locationRepository;
  39.     /** @var MovieFiltersRepository */
  40.     protected $movieFiltersRepository;
  41.     /** @var MovieRepository */
  42.     protected $movieRepository;
  43.     /** @var RestrictionsRepository */
  44.     protected $restrictionsRepository;
  45.     /** @var MovieArchiveRepository */
  46.     protected $movieArchiveRepository;
  47.     public function __construct(
  48.         ManagerRegistry $registry,
  49.         SessionHelper $sessionHelper,
  50.         LocationRepository $locationRepository,
  51.         MovieFiltersRepository $movieFiltersRepository,
  52.         MovieRepository $movieRepository,
  53.         MovieArchiveRepository $movieArchiveRepository,
  54.         RestrictionsRepository $restrictionsRepository
  55.     ) {
  56.         $this->scheduledMovieRepository $registry->getRepository(ScheduledFilm::class);
  57.         $this->sessionHelper $sessionHelper;
  58.         $this->locationRepository $locationRepository;
  59.         $this->movieFiltersRepository $movieFiltersRepository;
  60.         $this->movieRepository $movieRepository;
  61.         $this->movieArchiveRepository $movieArchiveRepository;
  62.         $this->restrictionsRepository $restrictionsRepository;
  63.     }
  64.     /**
  65.      * @param array|null              $filter
  66.      * @param array|null              $order
  67.      * @param int|null                $limit
  68.      * @param int|null                $offset
  69.      * @param int|null                $location
  70.      * @param int|null                $cinema
  71.      * @param \DateTimeInterface|null $date
  72.      * @param bool                    $setDefaultDate
  73.      *
  74.      * @return array
  75.      */
  76.     protected function prepareInput(
  77.         $filter null,
  78.         $order null,
  79.         $limit null,
  80.         $offset null,
  81.         $location null,
  82.         $cinema null,
  83.         $date null,
  84.         $setDefaultDate false
  85.     ) {
  86.         if (!$filter) {
  87.             $filter = [];
  88.         }
  89.         if (!$order) {
  90.             $order null;
  91.         }
  92.         if (!$limit) {
  93.             $limit null;
  94.         }
  95.         if (!$offset) {
  96.             $offset null;
  97.         }
  98.         if (is_numeric($location)) {
  99.             $filter['cinemaId'] = $cinemaId $this->locationRepository->findById($location)->getItems();
  100.         } else {
  101.             $filter['cinemaId'] = $cinemaId $this->locationRepository->findLocationIds();
  102.         }
  103.         if ($cinema) {
  104.             $filter['cinemaId'] = $cinemaId = [$cinema];
  105.         }
  106.         if ($date) {
  107.             $filter['date'] = $date;
  108.         } elseif ($setDefaultDate) {
  109.             $defaultDate $this->sessionHelper->getDefaultDate($cinemaId);
  110.             $defaultDate and $filter['date'] = $defaultDate;
  111.         }
  112.         if (isset($filter['technology']) && is_array($filter['technology'])) {
  113.             $decoded = [];
  114.             foreach ($filter['technology'] as $item) {
  115.                 $decoded[] = urldecode($item);
  116.             }
  117.             $filters $this->movieFiltersRepository->getMovieFiltersRoot()->getFilters();
  118.             $filter['technology'] = $filters->getTechnologyFilter($decoded);
  119.             if (empty($filter['technology'])) {
  120.                 unset($filter['technology']);
  121.             }
  122.         }
  123.         if (is_array($filter['version'] ?? null)) {
  124.             $item '';
  125.             assert(is_array($filter['version']));
  126.             foreach ($filter['version'] as &$item) {
  127.                 $item urldecode($item);
  128.             }
  129.             $filters $this->movieFiltersRepository->getMovieFiltersRoot()->getFilters();
  130.             $filter['version'] = $filters->getVersionMatching($item);
  131.             if (empty($filter['version'])) {
  132.                 unset($filter['version']);
  133.             }
  134.         }
  135.         $resolver = new OptionsResolver();
  136.         $resolver->setDefaults([
  137.             'date' => null,
  138.             'rating' => null,
  139.             'technology' => null,
  140.             'version' => null,
  141.             'title' => null,
  142.             'genreId' => null,
  143.             'cinemaId' => $this->locationRepository->findLocationIds(),
  144.             'shortURL' => null
  145.         ]);
  146.         try {
  147.             $filter array_filter($resolver->resolve($filter));
  148.         } catch (UndefinedOptionsException $exception) {
  149.             throw new \InvalidArgumentException('Invalid filter parameters');
  150.         }
  151.         return [$filter$order$limit$offset];
  152.     }
  153.     /**
  154.      * @Route("", methods={"GET"})
  155.      * @Rest\QueryParam(name="filter", allowBlank=true)
  156.      * @Rest\QueryParam(name="order", allowBlank=true)
  157.      * @Rest\QueryParam(name="limit", requirements="\d+", allowBlank=true)
  158.      * @Rest\QueryParam(name="offset", requirements="\d+", allowBlank=true)
  159.      * @Rest\QueryParam(name="location", allowBlank=true)
  160.      * @Rest\QueryParam(name="cinema", allowBlank=true)
  161.      * @Rest\QueryParam(name="date", allowBlank=true)
  162.      * @View(serializerGroups={"Default", "movie_list"})
  163.      *
  164.      * @SWG\Parameter(name="filter", type="string", in="query")
  165.      * @SWG\Parameter(name="order", type="string", in="query")
  166.      *
  167.      * @SWG\Response(
  168.      *     response="200",
  169.      *     description="All movies",
  170.      *     @SWG\Schema(type="array", items=@SWG\Items(ref=@Model(type=\App\Entity\Local\MoviesComposed::class))))
  171.      *
  172.      * @param $filter
  173.      * @param $order
  174.      * @param $limit
  175.      * @param $offset
  176.      * @param $location
  177.      * @param $cinema
  178.      * @param \DateTime|null $date
  179.      * @return array
  180.      * @throws \Exception
  181.      */
  182.     public function getAllMoviesAction($filter$order$limit$offset$location$cinema, ?\DateTime $date)
  183.     {
  184.         [
  185.             $filter,
  186.             $order,
  187.             $limit,
  188.             $offset,
  189.         ] = $this->prepareInput(
  190.             $filter,
  191.             $order,
  192.             $limit,
  193.             $offset,
  194.             $location,
  195.             $cinema,
  196.             $date,
  197.             true
  198.         );
  199.         return $this->composeByCorporateId($this->movieRepository->search($filter$order$limit$offset));
  200.     }
  201.     /**
  202.      * @Route("/schoolcinema", methods={"GET"})
  203.      * @Rest\QueryParam(name="filter", allowBlank=true)
  204.      * @Rest\QueryParam(name="order", allowBlank=true)
  205.      * @Rest\QueryParam(name="limit", requirements="\d+", allowBlank=true)
  206.      * @Rest\QueryParam(name="offset", requirements="\d+", allowBlank=true)
  207.      * @Rest\QueryParam(name="location", allowBlank=true)
  208.      * @Rest\QueryParam(name="cinema", allowBlank=true)
  209.      * @Rest\QueryParam(name="date", allowBlank=true)
  210.      * @Rest\QueryParam(name="filmtipp", allowBlank=true)
  211.      * @View(serializerGroups={"Default", "movie_list"})
  212.      *
  213.      * @SWG\Parameter(name="filter", type="string", in="query")
  214.      * @SWG\Parameter(name="order", type="string", in="query")
  215.      *
  216.      * @SWG\Response(
  217.      *     response="200",
  218.      *     description="All School Cinema movies",
  219.      *     @SWG\Schema(type="array", items=@SWG\Items(ref=@Model(type=\App\Entity\Local\MoviesComposed::class))))
  220.      *
  221.      * @param $filter
  222.      * @param $order
  223.      * @param $limit
  224.      * @param $offset
  225.      * @param $location
  226.      * @param $cinema
  227.      * @param \DateTime|null $date
  228.      * @param $filmtipp
  229.      * @return array
  230.      * @throws \Exception
  231.      */
  232.     public function getSchoolCinemaAction($filter$order$limit$offset$location$cinema, ?\DateTime $date$filmtipp)
  233.     {
  234.         [
  235.             $filter,
  236.             $order,
  237.             $limit,
  238.             $offset,
  239.         ] = $this->prepareInput(
  240.             $filter,
  241.             $order,
  242.             $limit,
  243.             $offset,
  244.             $location,
  245.             $cinema,
  246.             $date,
  247.             false
  248.         );
  249.         if ($filmtipp && filter_var($filmtippFILTER_VALIDATE_BOOLEAN)) {
  250.             $filter['filmTipp'] = true;
  251.         }
  252.         $filter['schoolMovie'] = true;
  253.         return $this->composeByCorporateId($this->movieRepository->searchWithSession($filter$order$limit$offset));
  254.     }
  255.     /**
  256.      * @Route("/schoolcinema/coming-soon", methods={"GET"})
  257.      * @Rest\QueryParam(name="filter", allowBlank=true)
  258.      * @Rest\QueryParam(name="order", allowBlank=true)
  259.      * @Rest\QueryParam(name="limit", requirements="\d+", allowBlank=true)
  260.      * @Rest\QueryParam(name="offset", requirements="\d+", allowBlank=true)
  261.      * @Rest\QueryParam(name="location", allowBlank=true)
  262.      * @Rest\QueryParam(name="cinema", allowBlank=true)
  263.      * @Rest\QueryParam(name="date", allowBlank=true)
  264.      * @Rest\QueryParam(name="filmtipp", allowBlank=true)
  265.      * @View(serializerGroups={"Default", "movie_list"})
  266.      *
  267.      * @SWG\Parameter(name="filter", type="string", in="query")
  268.      * @SWG\Parameter(name="order", type="string", in="query")
  269.      * @SWG\Response(
  270.      *     response=200,
  271.      *     description="Coming soon School Cinema movies",
  272.      *     @SWG\Schema(
  273.      *         type="array",
  274.      *         items=@SWG\Items(ref=@Model(type=\App\Entity\Local\MoviesComposed::class))))
  275.      *
  276.      * @param $filter
  277.      * @param $order
  278.      * @param $limit
  279.      * @param $offset
  280.      * @param $location
  281.      * @param $cinema
  282.      * @param \DateTimeImmutable|null $date
  283.      * @param $filmtipp
  284.      * @return array
  285.      * @throws \Exception
  286.      */
  287.     public function getComingSoonSchoolCinemaAction($filter$order$limit$offset$location$cinema, ?\DateTimeImmutable $date$filmtipp)
  288.     {
  289.         [$filter$order$limit$offset] = $this->prepareInput($filter$order$limit$offset$location$cinema$date);
  290.         unset($filter['cinemaId']);
  291.         $filter['>=openingDate'] = new \DateTimeImmutable('now');
  292.         if ($date) {
  293.             unset($filter['date']);
  294.             $filter['>=openingDate'] = $date;
  295.             $filter['<openingDate'] = $date->modify('+1 month');
  296.         }
  297.         if ($filmtipp && filter_var($filmtippFILTER_VALIDATE_BOOLEAN)) {
  298.             $filter['filmTipp'] = true;
  299.         }
  300.         $filter['schoolMovie'] = true;
  301.         return $this->composeByCorporateId($this->movieRepository->search(
  302.             $filter ?: [],
  303.             $order ?: null,
  304.             $limit ?: null,
  305.             $offset ?: null,
  306.             ['coming-soon']
  307.         ));
  308.     }
  309.     /**
  310.      * @Route("/search/advanced", methods={"POST"})
  311.      * @ParamConverter("filter", converter="fos_rest.request_body", class="array")
  312.      * @Rest\QueryParam(name="order", allowBlank=true)
  313.      * @Rest\QueryParam(name="limit", requirements="\d+", allowBlank=true)
  314.      * @Rest\QueryParam(name="offset", requirements="\d+", allowBlank=true)
  315.      * @Rest\QueryParam(name="location", allowBlank=true)
  316.      * @Rest\QueryParam(name="cinema", allowBlank=true)
  317.      * @Rest\QueryParam(name="date", allowBlank=true)
  318.      * @View(serializerGroups={"Default", "movie_list"})
  319.      *
  320.      * @SWG\Parameter(
  321.      *     name="body",
  322.      *     in="body",
  323.      *     @SWG\Schema(type="object",
  324.      *         @SWG\Property(property="title", type="string")))
  325.      *
  326.      * @SWG\Response(
  327.      *     response=200,
  328.      *     description="Success",
  329.      *     @SWG\Schema(type="array", items=@SWG\Items(ref=@Model(type=\App\Entity\Vista\Film::class))))
  330.      *
  331.      * @param array $filter
  332.      * @param array $order
  333.      * @param int   $limit
  334.      * @param int   $offset
  335.      * @param int   $location
  336.      * @param int   $cinema
  337.      * @param \DateTime|null $date
  338.      * @return array
  339.      */
  340.     public function advancedSearchAction(
  341.         $filter null,
  342.         $order null,
  343.         $limit null,
  344.         $offset null,
  345.         $location null,
  346.         $cinema null,
  347.         ?\DateTime $date null
  348.     ) {
  349.         [$filter$order$limit$offset] = $this->prepareInput($filter$order$limit$offset$location$cinema$date);
  350.         $flags = ['advanced-search'];
  351.         is_numeric($location) and $flags[] = 'exclude-coming-soon';
  352.         return $this->movieRepository->search($filter$order$limit$offset$flags);
  353.     }
  354.     /**
  355.      * @Route("/coming-soon", methods={"GET"})
  356.      * @Rest\QueryParam(name="filter", allowBlank=true)
  357.      * @Rest\QueryParam(name="order", allowBlank=true)
  358.      * @Rest\QueryParam(name="limit", requirements="\d+", allowBlank=true)
  359.      * @Rest\QueryParam(name="offset", requirements="\d+", allowBlank=true)
  360.      * @Rest\QueryParam(name="location", allowBlank=true)
  361.      * @Rest\QueryParam(name="cinema", allowBlank=true)
  362.      * @Rest\QueryParam(name="date", allowBlank=true)
  363.      * @View(serializerGroups={"Default", "movie_list"})
  364.      *
  365.      * @SWG\Parameter(name="filter", type="string", in="query")
  366.      * @SWG\Parameter(name="order", type="string", in="query")
  367.      * @SWG\Response(
  368.      *     response=200,
  369.      *     description="Coming soon movies",
  370.      *     @SWG\Schema(
  371.      *         type="array",
  372.      *         items=@SWG\Items(ref=@Model(type=\App\Entity\Local\MoviesComposed::class))))
  373.      *
  374.      * @param $filter
  375.      * @param $order
  376.      * @param $limit
  377.      * @param $offset
  378.      * @param $location
  379.      * @param $cinema
  380.      * @param \DateTimeImmutable|null $date
  381.      * @return array
  382.      * @throws \Exception
  383.      */
  384.     public function getComingSoonMoviesAction($filter$order$limit$offset$location$cinema, ?\DateTimeImmutable $date)
  385.     {
  386.         [$filter$order$limit$offset] = $this->prepareInput($filter$order$limit$offset$location$cinema$date);
  387.         unset($filter['cinemaId']);
  388.         $filter['>=openingDate'] = new \DateTimeImmutable('now');
  389.         if ($date) {
  390.             unset($filter['date']);
  391.             $filter['>=openingDate'] = $date;
  392.             $filter['<openingDate'] = $date->modify('+1 month');
  393.         }
  394.         return $this->composeByCorporateId($this->movieRepository->search(
  395.             $filter ?: [],
  396.             $order ?: null,
  397.             $limit ?: null,
  398.             $offset ?: null,
  399.             ['coming-soon']
  400.         ));
  401.     }
  402.     /**
  403.      * @Route("/top", methods={"GET"})
  404.      * @Rest\QueryParam(name="filter", allowBlank=true)
  405.      * @Rest\QueryParam(name="order", allowBlank=true)
  406.      * @Rest\QueryParam(name="limit", requirements="\d+", allowBlank=true)
  407.      * @Rest\QueryParam(name="offset", requirements="\d+", allowBlank=true)
  408.      * @Rest\QueryParam(name="location", allowBlank=true)
  409.      * @Rest\QueryParam(name="cinema", allowBlank=true)
  410.      * @Rest\QueryParam(name="date", allowBlank=true)
  411.      * @View(serializerGroups={"Default", "movie_list"})
  412.      *
  413.      * @SWG\Parameter(name="filter", type="string", in="query")
  414.      * @SWG\Parameter(name="order", type="string", in="query")
  415.      * @SWG\Response(
  416.      *     response=200,
  417.      *     description="Top movies",
  418.      *     @SWG\Schema(
  419.      *         type="array",
  420.      *         items=@SWG\Items(ref=@Model(type=\App\Entity\Local\MoviesComposed::class))))
  421.      *
  422.      * @param $filter
  423.      * @param $order
  424.      * @param $limit
  425.      * @param $offset
  426.      * @param $location
  427.      * @param $cinema
  428.      * @param \DateTime|null $date
  429.      * @return array
  430.      * @throws \Exception
  431.      */
  432.     public function getTopMoviesAction($filter$order$limit$offset$location$cinema, ?\DateTime $date)
  433.     {
  434.         [$filter$order$limit$offset] = $this->prepareInput($filter$order$limit$offset$location$cinema$datetrue);
  435.         $filter['top'] = true;
  436.         return $this->composeByCorporateId($this->movieRepository->search(
  437.             $filter ?: [],
  438.             $order ?: null,
  439.             $limit ?: null,
  440.             $offset ?: null
  441.         ));
  442.     }
  443.     /**
  444.      * @Route("/grouped-by-corporate-id/{corporateId}/sessions", methods={"GET"})
  445.      * @Rest\QueryParam(name="filter", allowBlank=true)
  446.      * @Rest\QueryParam(name="order", allowBlank=true)
  447.      * @Rest\QueryParam(name="limit", requirements="\d+", allowBlank=true)
  448.      * @Rest\QueryParam(name="offset", requirements="\d+", allowBlank=true)
  449.      * @Rest\QueryParam(name="location", allowBlank=true)
  450.      * @Rest\QueryParam(name="cinema", allowBlank=true)
  451.      * @Rest\QueryParam(name="date", allowBlank=true)
  452.      * @Rest\View(serializerGroups={"Default", "session_list"})
  453.      *
  454.      * @SWG\Parameter(name="filter", type="string", in="query")
  455.      * @SWG\Parameter(name="order", type="string", in="query")
  456.      * @SWG\Response(
  457.      *     response="200",
  458.      *     description="Get list of sessions by movie id",
  459.      *     @SWG\Schema(
  460.      *         type="array",
  461.      *         items=@SWG\Items(ref=@Model(type=\App\Entity\Vista\DTO\SessionsByDateDTO::class))))
  462.      *
  463.      * @param Request        $request
  464.      * @param string         $corporateId
  465.      * @param array          $filter
  466.      * @param array          $order
  467.      * @param int            $limit
  468.      * @param int            $offset
  469.      * @param null           $location
  470.      * @param null           $cinema
  471.      * @param \DateTime|null $date
  472.      *
  473.      * @return array
  474.      * @throws \Exception
  475.      */
  476.     public function sessionsAction(
  477.         Request $request,
  478.         $corporateId,
  479.         $filter = [],
  480.         $order = [],
  481.         $limit 0,
  482.         $offset 0,
  483.         $location null,
  484.         $cinema null,
  485.         ?\DateTime $date null
  486.     ) {
  487.         $filter or $filter = [];
  488.         [$filter$order$limit$offset] = $this->prepareInput($filter$order$limit$offset$location$cinemanull);
  489.         $movies $this->scheduledMovieRepository->fetchMovieByCorporateIdOrHOFilmCode($corporateId);
  490.         $filter['scheduledFilm'] = $movies;
  491.         if (isset($filter['date'])) {
  492.             unset($filter['date']);
  493.         }
  494.         if ('mobile' === $request->attributes->get('_platform')) {
  495.             if ($date) {
  496.                 $filter['>=showtime'] = $date->setTime(000);
  497.                 $filter['<=showtime'] = (clone $date)->add(new \DateInterval('P1D'));
  498.             } else {
  499.                 $restrictions $this->restrictionsRepository->findOrCreate();
  500.                 $expiryDate = (new \DateTimeImmutable())->sub(new \DateInterval(sprintf(
  501.                     'PT%sS',
  502.                     $restrictions->getGreySessionTTL()
  503.                 )));
  504.                 $filter['>=showtime'] = $expiryDate;
  505.             }
  506.         } else {
  507.             $date or $date $this->sessionHelper->getDefaultDate();
  508.             if ($date) {
  509.                 $filter['>=showtime'] = $date;
  510.                 $filter['<=showtime'] = (clone $date)
  511.                     ->setTime(000)
  512.                     ->add(new \DateInterval('P1D'));
  513.             }
  514.         }
  515.         return $this->prepareSessionsResponse($this->sessionHelper->findBy(
  516.             $filter ?: [],
  517.             $order ?: null,
  518.             $limit ?: null,
  519.             $offset ?: null
  520.         ));
  521.     }
  522.     /**
  523.      * @Route("/{id}", methods={"GET"})
  524.      * @View(serializerGroups={"Default", "movie_details"})
  525.      *
  526.      * @SWG\Response(
  527.      *     response=200,
  528.      *     description="A movie",
  529.      *     @Model(type=\App\Entity\Vista\Film::class))
  530.      *
  531.      * @param $id
  532.      * @return array|\Symfony\Component\HttpKernel\Exception\NotFoundHttpException
  533.      * @throws \Exception
  534.      */
  535.     public function getMovieByIdAction($id)
  536.     {
  537.         $film $this->movieRepository->fetchMovieByIdHOFilmCode($id);
  538.         if (null === $film) {
  539.             $film $this->movieArchiveRepository->fetchMovieByIdHOFilmCode($id);
  540.             if (null === $film) {
  541.                 return $this->createNotFoundException();
  542.             }
  543.             return $this->prepareFilmArchive($film);
  544.         }
  545.         return $this->prepareFilm($film);
  546.     }
  547.     /**
  548.      * @Route("/{id}/comments", methods={"GET"})
  549.      * @Rest\QueryParam(name="skip", allowBlank=true)
  550.      * @Rest\QueryParam(name="take", allowBlank=true)
  551.      * @View()
  552.      *
  553.      * @SWG\Response(
  554.      *     response=200,
  555.      *     description="A movie comments",
  556.      *     @SWG\Schema(type="array", items=@SWG\Items(ref=@Model(type=\App\Entity\Netural\Review::class))))
  557.      *
  558.      * @param string $id
  559.      * @param int    $skip
  560.      * @param int    $take
  561.      * @return array
  562.      */
  563.     public function getMovieCommentsAction($id$skip null$take null)
  564.     {
  565.         (!is_numeric($skip) || $skip 0) and $skip 0;
  566.         (!is_numeric($take) || $take 0) and $take 0;
  567.         $skip intval($skip);
  568.         $take intval($take);
  569.         $film $this->movieRepository->fetchMovieByIdHOFilmCode($id);
  570.         if (null === $film) {
  571.             $film $this->movieArchiveRepository->fetchMovieByIdHOFilmCode($id);
  572.             if (null === $film) {
  573.                 throw new \InvalidArgumentException(sprintf('Invalid movie id: %s'$id));
  574.             }
  575.         }
  576.         /** @var Reviews|null $reviews */
  577.         $reviews $film->getReviews();
  578.         if (!$reviews) {
  579.             return [];
  580.         }
  581.         $featured $reviews->getFeaturedReview();
  582.         $indexedReviews = [];
  583.         /** @var Review $item */
  584.         foreach ($reviews->getEntries() ?? [] as $item) {
  585.             $indexedReviews[$item->getReviewId()] = $item;
  586.         }
  587.         if ($featured) {
  588.             $featured->setIsFeatured(true);
  589.             unset($indexedReviews[$featured->getReviewId()]);
  590.         }
  591.         usort($indexedReviews, function ($a$b) {
  592.             /**
  593.              * @var Review $a
  594.              */
  595.             /**
  596.              * @var Review $b
  597.              */
  598.             if ($a->getTime() < $b->getTime()) {
  599.                 return -1;
  600.             } elseif ($a->getTime() > $b->getTime()) {
  601.                 return 1;
  602.             }
  603.             return 0;
  604.         });
  605.         $indexedReviews array_reverse($indexedReviews);
  606.         $preResult array_filter(array_merge([$featured], array_values($indexedReviews)));
  607.         $highIndex count($preResult) ? count($preResult) - : -1;
  608.         $startIndex $skip;
  609.         if (($startIndex $highIndex) || !$take) {
  610.             return [];
  611.         }
  612.         return array_slice($preResult$startIndex$take);
  613.     }
  614.     /**
  615.      * @Route("/filters/list", methods={"GET"})
  616.      * @View()
  617.      *
  618.      * @SWG\Response(
  619.      *     response=200,
  620.      *     description="Filters",
  621.      *     @Model(type=\App\Entity\Local\MovieFilter\Filters::class))
  622.      *
  623.      * @return Filters|null
  624.      */
  625.     public function filtersListAction()
  626.     {
  627.         return $this->movieFiltersRepository->getMovieFiltersRoot()->getFilters();
  628.     }
  629.     /**
  630.      * @Route("/filters/months/list", methods={"GET"})
  631.      * @Rest\QueryParam(name="corporateFilmId", allowBlank=true, strict=true, nullable=true)
  632.      * @Rest\QueryParam(name="comingSoon", allowBlank=true, strict=true, nullable=true)
  633.      * @View()
  634.      *
  635.      * @SWG\Response(
  636.      *     response="200",
  637.      *     description="Success",
  638.      *     @SWG\Schema(type="array", items=@SWG\Items(ref=@Model(type=\App\Entity\Vista\Film::class))))
  639.      *
  640.      * @param string $corporateFilmId
  641.      * @param bool   $comingSoon
  642.      * @return array
  643.      */
  644.     public function filtersMonthListAction(string $corporateFilmId nullbool $comingSoon null)
  645.     {
  646.         $filter $corporateFilmId ? ['corporateFilmId' => $corporateFilmId] : [];
  647.         $flags null !== $comingSoon ? ['coming-soon'] : [];
  648.         return $this->movieRepository->findMonthsBy($filternullnullnull$flags);
  649.     }
  650. }