Completed
Push — master ( a5ff95...a715f7 )
by Valentyn
04:45
created

MovieController   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 187
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 20

Test Coverage

Coverage 93.65%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 20
dl 0
loc 187
ccs 59
cts 63
cp 0.9365
rs 10
c 0
b 0
f 0

6 Methods

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