<?php declare(strict_types=1);
namespace App\Controller\V2;
use App\Helper\SessionHelper;
use App\Repository\LocationRepository;
use App\Repository\MovieFiltersRepository;
use App\Repository\MovieRepositoryInterface as MovieRepository;
use App\Repository\ScheduledMovieRepository;
use Nelmio\ApiDocBundle\Annotation\Model;
use FOS\RestBundle\Controller\Annotations as Rest;
use Swagger\Annotations as SWG;
use Symfony\Component\HttpFoundation\Request;
use App\Repository\EventRepository;
/**
* @Rest\Route("/movies")
* @SWG\Tag(name="Movie_v2")
*/
class MovieController extends BaseMovieController
{
/** @var MovieRepository */
private $movieRepository;
/** @var EventRepository */
protected $eventRepository;
public function __construct(
MovieRepository $movieRepository,
EventRepository $eventRepository,
LocationRepository $locationRepository,
SessionHelper $sessionHelper,
MovieFiltersRepository $movieFiltersRepository,
ScheduledMovieRepository $scheduledMovieRepository
) {
parent::__construct($locationRepository, $sessionHelper, $movieFiltersRepository, $scheduledMovieRepository);
$this->movieRepository = $movieRepository;
$this->eventRepository = $eventRepository;
}
/**
* @param array $films
* @return array
* @throws \Exception
*/
private function prepareResponse(array $films = [])
{
$result = [];
foreach ($films as $film) {
$result[] = $this->prepareFilm($film);
}
return $result;
}
/**
* @param array $films
* @param array $events
* @return array
* @throws \Exception
*/
private function prepareMovieEventResponse(array $films = [], array $events = [])
{
$result = [];
foreach ($films as $index => $film) {
if (isset($events[$index + 1])) {
foreach ($events[$index + 1] as $event) {
$result[] = $event;
}
}
$result[] = $this->prepareFilm($film);
}
return $result;
}
/**
* @Rest\Route("", methods={"GET"})
* @Rest\QueryParam(name="filter", map=true, allowBlank=true)
* @Rest\QueryParam(name="order", allowBlank=true)
* @Rest\QueryParam(name="limit", requirements="\d+", allowBlank=true)
* @Rest\QueryParam(name="offset", requirements="\d+", allowBlank=true)
* @Rest\QueryParam(name="location", allowBlank=true)
* @Rest\QueryParam(name="cinema", allowBlank=true)
* @Rest\QueryParam(name="date", allowBlank=true)
* @Rest\View(serializerGroups={"Default", "movie_list"})
*
* @SWG\Response(
* response="200",
* description="All movies",
* @SWG\Schema(type="array", items=@SWG\Items(ref=@Model(type=\App\Entity\Vista\Film::class))))
*
* @param $filter
* @param $order
* @param $limit
* @param $offset
* @param $location
* @param $cinema
* @param \DateTime|null $date
* @return array
* @throws \Exception
*/
public function indexAction($filter, $order, $limit, $offset, $location, $cinema, ?\DateTime $date)
{
[
$filter,
$order,
$limit,
$offset,
] = $this->prepareInput(
$filter,
$order,
$limit,
$offset,
$location,
$cinema,
$date,
true
);
$events = $this->eventRepository->movieEvents();
return $this->prepareMovieEventResponse($this->movieRepository->search($filter, $order, $limit, $offset), $events);
}
/**
* @Rest\Route("/top", methods={"GET"})
* @Rest\QueryParam(name="filter", map=true, allowBlank=true)
* @Rest\QueryParam(name="order", allowBlank=true)
* @Rest\QueryParam(name="limit", requirements="\d+", allowBlank=true)
* @Rest\QueryParam(name="offset", requirements="\d+", allowBlank=true)
* @Rest\QueryParam(name="location", allowBlank=true)
* @Rest\QueryParam(name="date", allowBlank=true)
* @Rest\View(serializerGroups={"Default", "movie_list"})
*
* @SWG\Response(
* response=200,
* description="Top movies",
* @SWG\Schema(type="array", items=@SWG\Items(@Model(type=\App\Entity\Vista\Film::class))))
*
* @param $filter
* @param $order
* @param $limit
* @param $offset
* @param $location
* @param \DateTime|null $date
* @return array
* @throws \Exception
*/
public function topAction($filter, $order, $limit, $offset, $location, ?\DateTime $date)
{
[$filter, $order, $limit, $offset] = $this->prepareInput(
$filter,
$order,
$limit,
$offset,
$location,
null,
$date,
true
);
$filter['top'] = true;
return $this->prepareResponse($this->movieRepository->search(
$filter ?: [],
$order ?: null,
$limit ?: null,
$offset ?: null
));
}
/**
* @Rest\Route("/coming-soon", methods={"GET"})
* @Rest\QueryParam(name="filter", map=true, allowBlank=true)
* @Rest\QueryParam(name="order", allowBlank=true)
* @Rest\QueryParam(name="limit", requirements="\d+", allowBlank=true)
* @Rest\QueryParam(name="offset", requirements="\d+", allowBlank=true)
* @Rest\QueryParam(name="location", allowBlank=true)
* @Rest\QueryParam(name="date", allowBlank=true)
* @Rest\View(serializerGroups={"Default", "movie_list"})
*
* @SWG\Response(
* response=200,
* description="Coming soon movies",
* @SWG\Schema(type="array", items=@SWG\Items(@Model(type=\App\Entity\Vista\Film::class))))
*
* @param $filter
* @param $order
* @param $limit
* @param $offset
* @param $location
* @param \DateTimeImmutable|null $date
* @return array
* @throws \Exception
*/
public function comingSoonAction($filter, $order, $limit, $offset, $location, ?\DateTimeImmutable $date)
{
[$filter, $order, $limit, $offset] = $this->prepareInput($filter, $order, $limit, $offset, $location, null, $date);
unset($filter['cinemaId']);
$filter['>=openingDate'] = new \DateTimeImmutable('now');
if ($date) {
unset($filter['date']);
$filter['>=openingDate'] = $date;
$date and $filter['<openingDate'] = $date->modify('+1 month');
}
return $this->prepareResponse($this->movieRepository->search(
$filter ?: [],
$order ?: null,
$limit ?: null,
$offset ?: null,
['coming-soon']
));
}
/**
* @Rest\Route("/{id}/sessions", methods={"GET"})
* @Rest\QueryParam(name="filter", map=true, allowBlank=true)
* @Rest\QueryParam(name="order", allowBlank=true)
* @Rest\QueryParam(name="limit", requirements="\d+", allowBlank=true)
* @Rest\QueryParam(name="offset", requirements="\d+", allowBlank=true)
* @Rest\QueryParam(name="location", allowBlank=true)
* @Rest\QueryParam(name="cinema", allowBlank=true)
* @Rest\QueryParam(name="date", allowBlank=true)
* @Rest\View(serializerGroups={"Default", "session_list"})
*
* @SWG\Response(
* response="200",
* description="Get list of sessions by movie id",
* @SWG\Schema(type="array", items=@SWG\Items(ref=@Model(type=\App\Entity\Vista\Session::class))))
*
* @param Request $request
* @param $id
* @param array $filter
* @param array $order
* @param int $limit
* @param int $offset
* @param null $location
* @param null $cinema
* @param \DateTime|null $date
*
* @return array
* @throws \Exception
*/
public function sessionsAction(
Request $request,
$id,
$filter = [],
$order = [],
$limit = 0,
$offset = 0,
$location = null,
$cinema = null,
?\DateTime $date = null
) {
$filter or $filter = [];
[$filter, $order, $limit, $offset] = $this->prepareInput($filter, $order, $limit, $offset, $location, $cinema, null);
if (isset($filter['date'])) {
unset($filter['date']);
}
$filter['scheduledFilm'] = $this->scheduledMovieRepository->fetchMovieByIdHOFilmCode($id);
if ('mobile' === $request->attributes->get('_platform')) {
if ($date) {
$filter['>=showtime'] = $date->setTime(0, 0, 0);
$filter['<=showtime'] = (clone $date)->add(new \DateInterval('P1D'));
}
} else {
$date or $date = $this->sessionHelper->getDefaultDate();
is_string($date) and $date = \DateTime::createFromFormat('Y-m-d', $date);
if ($date) {
$filter['>=showtime'] = $date;
$filter['<=showtime'] = (clone $date)
->setTime(0, 0, 0)
->add(new \DateInterval('P1D'));
}
}
$response = $this->prepareSessionsResponse($this->sessionHelper->findBy(
$filter ?: [],
$order ?: null,
$limit ?: null,
$offset ?: null
));
return $this->filterSessionByType($response, 'CELL');
}
/**
* @Rest\Route("/filters/dates/list", methods={"GET"})
* @Rest\QueryParam(name="id", allowBlank=true, strict=true, nullable=true)
* @Rest\QueryParam(name="cinemaId", allowBlank=true, requirements="\d+", strict=true, nullable=true)
* @Rest\QueryParam(name="location", allowBlank=true, nullable=true)
* @Rest\QueryParam(name="top", allowBlank=true, strict=true, nullable=true)
* @Rest\QueryParam(name="comingSoon", allowBlank=true, strict=true, nullable=true)
* @Rest\View()
*
* @SWG\Response(
* response="200",
* description="Success",
* @SWG\Schema(type="array", items=@SWG\Items(ref=@Model(type=\App\Entity\Vista\Session::class))))
*
* @param string|null $id
* @param string|null $cinemaId
* @param int|null $location
* @param bool|null $top
* @param bool|null $comingSoon
*
* @return array
*/
public function filtersDatesListAction(
?string $id = null,
?string $cinemaId = null,
$location = null,
?bool $top = null,
?bool $comingSoon = null
) {
if (!is_numeric($location)) {
$location = null;
} else {
$location = (int) $location;
}
return $this->sessionHelper->getFiltersDatesListV2(
$id,
$cinemaId ? [$cinemaId] : null,
$location,
$top,
$comingSoon
);
}
/**
* @Rest\Route("/filters/months/list", methods={"GET"})
* @Rest\QueryParam(name="id", allowBlank=true, strict=true, nullable=true)
* @Rest\QueryParam(name="comingSoon", allowBlank=true, strict=true, nullable=true)
* @Rest\View()
*
* @SWG\Response(
* response="200",
* description="Success",
* @SWG\Schema(type="array", items=@SWG\Items(ref=@Model(type=\App\Entity\Vista\Film::class))))
*
* @param string|null $id
* @param bool|null $comingSoon
*
* @return array
*/
public function filtersMonthListAction(?string $id = null, ?bool $comingSoon = false)
{
$filter = array_filter([
'id' => $id,
]);
$flags = array_filter([
$comingSoon ? 'coming-soon' : null,
]);
return $this->movieRepository->findMonthsBy($filter, null, null, null, $flags);
}
}