Completed
Push — master ( 9f52f6...71d672 )
by Valentyn
04:42
created

MovieController::getMovies()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 6
cts 7
cp 0.8571
rs 9.7998
c 0
b 0
f 0
cc 3
nc 3
nop 3
crap 3.0261
1
<?php
2
3
namespace App\Movies\Controller;
4
5
use App\Controller\BaseController;
6
use App\Movies\DTO\MovieTranslationDTO;
7
use App\Movies\Entity\Movie;
8
use App\Movies\Entity\MovieTranslations;
9
use App\Movies\EventListener\SimilarMoviesProcessor;
10
use App\Movies\Repository\MovieRepository;
11
use App\Movies\Request\CreateMovieRequest;
12
use App\Movies\Request\SearchRequest;
13
use App\Movies\Request\UpdateMovieRequest;
14
use App\Movies\Service\MovieManageService;
15
use App\Movies\Service\SearchService;
16
use App\Pagination\PaginatedCollection;
17
use App\Users\Entity\User;
18
use App\Users\Entity\UserRoles;
19
use Enqueue\Client\ProducerInterface;
20
use Symfony\Component\HttpFoundation\JsonResponse;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
23
use Symfony\Component\Routing\Annotation\Route;
24
use Symfony\Component\Validator\Validator\ValidatorInterface;
25
26
/**
27
 * Class MovieController.
28
 */
29
class MovieController extends BaseController
30
{
31
    /**
32
     * Get all movies.
33
     *
34
     * @Route("/api/movies", methods={"GET"})
35
     *
36
     * @param Request         $request
37
     * @param MovieRepository $movieRepository
38
     *
39
     * @return \Symfony\Component\HttpFoundation\JsonResponse
40
     */
41 8
    public function getAll(Request $request, MovieRepository $movieRepository)
42
    {
43 8
        $user = $this->getUser();
44
45 8
        if ($user instanceof User) {
46
            $movies = $movieRepository->findAllWithIsUserWatchedFlag($user);
47
        } else {
48 8
            $movies = $movieRepository->findAllWithIsGuestWatchedFlag($this->getGuest());
49
        }
50
51 8
        $offset = (int) $request->get('offset', 0);
52 8
        $limit = $request->get('limit', null);
53
54 8
        $movies = new PaginatedCollection($movies, $offset, $limit);
55
56 8
        return $this->response($movies, 200, [], [
57 8
            'groups' => ['list'],
58
        ]);
59
    }
60
61
    /**
62
     * Get movie resource.
63
     *
64
     * @Route("/api/movies/{id}", methods={"GET"})
65
     *
66
     * @param int               $id
67
     * @param MovieRepository   $repository
68
     * @param ProducerInterface $producer
69
     *
70
     * @throws \Doctrine\ORM\NoResultException
71
     * @throws \Doctrine\ORM\NonUniqueResultException
72
     *
73
     * @return JsonResponse
74
     */
75 1
    public function getMovies(int $id, MovieRepository $repository, ProducerInterface $producer)
76
    {
77 1
        if (null === $movie = $repository->findOneForMoviePage($id, $this->getUser())) {
78
            throw new NotFoundHttpException();
79
        }
80
81 1
        if (count($movie->getSimilarMovies()) === 0) {
82 1
            $producer->sendEvent(SimilarMoviesProcessor::LOAD_SIMILAR_MOVIES, json_encode($movie->getId()));
83
        }
84
85 1
        return $this->response($movie, 200, [], [
86 1
            'groups' => ['view'],
87
        ]);
88
    }
89
90
    /**
91
     * Get movies by title.
92
     *
93
     * @Route("/api/movies/search", methods={"POST"})
94
     *
95
     * @param SearchRequest $request
96
     * @param SearchService $searchService
97
     * @param Request       $currentRequest
98
     *
99
     * @throws \Exception
100
     *
101
     * @return \Symfony\Component\HttpFoundation\JsonResponse
102
     */
103 2
    public function getSearch(SearchRequest $request, SearchService $searchService, Request $currentRequest)
104
    {
105 2
        $offset = (int) $request->get('offset', 0);
106 2
        $limit = $request->get('limit', null);
107
108 2
        $query = $request->get('query');
109 2
        $movies = $searchService->findByQuery($query, $currentRequest->getLocale(), $offset, $limit);
110
111 2
        return $this->response($movies, 200, [], [
112 2
            'groups' => ['list'],
113
        ]);
114
    }
115
116
    /**
117
     * Create new movie.
118
     *
119
     * @Route("/api/movies", methods={"POST"})
120
     *
121
     * @param CreateMovieRequest $request
122
     * @param MovieManageService $service
123
     * @param ValidatorInterface $validator
124
     *
125
     * @throws \Exception
126
     *
127
     * @return \Symfony\Component\HttpFoundation\JsonResponse
128
     */
129 2
    public function postMovies(CreateMovieRequest $request, MovieManageService $service, ValidatorInterface $validator)
130
    {
131 2
        $this->denyAccessUnlessGranted(UserRoles::ROLE_ADMIN);
132
133 1
        $movie = $service->createMovieByRequest($request);
134 1
        $errors = $validator->validate($movie);
135
136 1
        if (count($errors)) {
137
            return $request->getErrorResponse($errors);
138
        }
139
140 1
        $entityManager = $this->getDoctrine()->getManager();
141 1
        $entityManager->persist($movie);
142 1
        $entityManager->flush();
143
144 1
        return $this->response($movie, 200, [], [
145 1
            'groups' => ['view'],
146
        ]);
147
    }
148
149
    /**
150
     * @Route("/api/movies/{id}", methods={"POST", "PUT", "PATCH"}, requirements={"id"="\d+"})
151
     *
152
     * @param Movie              $movie
153
     * @param UpdateMovieRequest $request
154
     *
155
     * @throws \ErrorException
156
     * @throws \Exception
157
     *
158
     * @return JsonResponse
159
     */
160 2
    public function putMovies(Movie $movie, UpdateMovieRequest $request)
161
    {
162 2
        $this->denyAccessUnlessGranted(UserRoles::ROLE_ADMIN);
163
164 1
        $movieData = $request->get('movie');
165 1
        $movieTranslationsData = $movieData['translations'];
166
167 1
        $movie->setOriginalTitle($movieData['originalTitle']);
168 1
        $movie->setImdbId($movieData['imdbId']);
169 1
        $movie->setRuntime($movieData['runtime']);
170 1
        $movie->setBudget($movieData['budget']);
171 1
        $movie->setReleaseDate(new \DateTimeImmutable($movieData['releaseDate']));
172
173
        $addTranslation = function (array $trans) use ($movie) {
174 1
            $transDto = new MovieTranslationDTO($trans['locale'], $trans['title'], $trans['overview'], null);
175 1
            $movie->addTranslation(
176 1
                new MovieTranslations($movie, $transDto)
177
            );
178 1
        };
179
180
        $updateTranslation = function (array $trans, MovieTranslations $oldTranslation) use ($movie) {
181 1
            $oldTranslation->setTitle($trans['title']);
182 1
            $oldTranslation->setOverview($trans['overview']);
183 1
        };
184
185 1
        $movie->updateTranslations($movieTranslationsData, $addTranslation, $updateTranslation);
186
187 1
        $em = $this->getDoctrine()->getManager();
188 1
        $em->persist($movie); // if there 1+ new translations lets persist movie to be sure that they will be saved
189 1
        $em->flush();
190
191 1
        return new JsonResponse(null, 202);
192
    }
193
}
194