Completed
Push — master ( fe2418...7fa25b )
by Valentyn
06:20
created

MovieController   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 179
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 21

Test Coverage

Coverage 94.92%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 21
dl 0
loc 179
ccs 56
cts 59
cp 0.9492
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getAll() 0 11 1
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\Transformer\MovieTransformer;
18
use App\Movies\Utils\Poster;
19
use App\Pagination\CustomPaginatedCollection;
20
use App\Pagination\PaginatedCollection;
21
use App\Users\Entity\User;
22
use App\Users\Entity\UserRoles;
23
use Enqueue\Client\ProducerInterface;
24
use Symfony\Component\HttpFoundation\JsonResponse;
25
use Symfony\Component\HttpFoundation\Request;
26
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
27
use Symfony\Component\Routing\Annotation\Route;
28
use Symfony\Component\Validator\Validator\ValidatorInterface;
29
30
/**
31
 * Class MovieController.
32
 */
33
class MovieController extends BaseController
34
{
35
    /**
36
     * Get all movies.
37
     *
38
     * @Route("/api/movies", methods={"GET"})
39
     *
40
     * @param Request         $request
41
     * @param MovieRepository $movieRepository
42
     *
43
     * @return \Symfony\Component\HttpFoundation\JsonResponse
44
     */
45 17
    public function getAll(Request $request, MovieRepository $movieRepository)
46
    {
47 17
        [$movies, $ids, $count] = $movieRepository->findAllWithIsWatchedFlag($this->getUser(), $this->getGuest());
0 ignored issues
show
Bug introduced by
The variable $movies does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $ids does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $count does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
48
49 17
        $offset = (int) $request->get('offset', 0);
50 17
        $limit = $request->get('limit', null);
51
52 17
        $collection = new CustomPaginatedCollection($movies, $ids, $count, $offset, $limit);
53
54 17
        return $this->items($collection, MovieTransformer::list());
55
    }
56
57
    /**
58
     * Get movie resource.
59
     *
60
     * @Route("/api/movies/{id}", methods={"GET"}, requirements={"id"="\d+"})
61
     *
62
     * @param int               $id
63
     * @param MovieRepository   $repository
64
     * @param ProducerInterface $producer
65
     *
66
     * @throws \Doctrine\ORM\NoResultException
67
     * @throws \Doctrine\ORM\NonUniqueResultException
68
     *
69
     * @return JsonResponse
70
     */
71 2
    public function getMovies(int $id, MovieRepository $repository, ProducerInterface $producer)
72
    {
73 2
        if (null === $movie = $repository->findOneForMoviePage($id, $this->getUser())) {
74
            throw new NotFoundHttpException();
75
        }
76
77 2
        if (count($movie->getSimilarMovies()) === 0) {
78 2
            $producer->sendEvent(SimilarMoviesProcessor::LOAD_SIMILAR_MOVIES, json_encode($movie->getId()));
79
        }
80
81 2
        return $this->response($movie, 200, [], [
82 2
            'groups' => ['view'],
83
        ]);
84
    }
85
86
    /**
87
     * @Route("/api/movies/{id}/updatePoster", methods={"POST"}, requirements={"id"="\d+"})
88
     *
89
     * @param Movie               $movie
90
     * @param UpdatePosterRequest $request
91
     *
92
     * @return JsonResponse
93
     */
94 1
    public function postMoviesUpdatePoster(Movie $movie, UpdatePosterRequest $request)
95
    {
96 1
        $this->denyAccessUnlessGranted(UserRoles::ROLE_ADMIN);
97
98 1
        if (null === $posterPath = Poster::savePoster($movie->getId(), $request->get('url'))) {
99
            return $this->json([], 400);
100
        }
101
102 1
        $movie->setOriginalPosterUrl(Poster::getUrl($movie->getId()));
103 1
        $this->getDoctrine()->getManager()->flush();
104
105 1
        return $this->json([]);
106
    }
107
108
    /**
109
     * Get movies by title.
110
     *
111
     * @Route("/api/movies/search", methods={"POST"})
112
     *
113
     * @param SearchRequest $request
114
     * @param SearchService $searchService
115
     * @param Request       $currentRequest
116
     *
117
     * @throws \Exception
118
     *
119
     * @return \Symfony\Component\HttpFoundation\JsonResponse
120
     */
121 2
    public function getSearch(SearchRequest $request, SearchService $searchService, Request $currentRequest)
122
    {
123 2
        $offset = (int) $request->get('offset', 0);
124 2
        $limit = $request->get('limit', null);
125
126 2
        $query = $request->get('query');
127 2
        $movies = $searchService->findByQuery($query, $currentRequest->getLocale(), $offset, $limit);
128
129 2
        return $this->response($movies, 200, [], [
130 2
            'groups' => ['list'],
131
        ]);
132
    }
133
134
    /**
135
     * Create new movie.
136
     *
137
     * @Route("/api/movies", methods={"POST"})
138
     *
139
     * @param CreateMovieRequest $request
140
     * @param MovieManageService $service
141
     * @param ValidatorInterface $validator
142
     *
143
     * @throws \Exception
144
     *
145
     * @return \Symfony\Component\HttpFoundation\JsonResponse
146
     */
147 2
    public function postMovies(CreateMovieRequest $request, MovieManageService $service, ValidatorInterface $validator)
148
    {
149 2
        $this->denyAccessUnlessGranted(UserRoles::ROLE_ADMIN);
150
151 1
        $movie = $service->createMovieByRequest($request);
152 1
        $errors = $validator->validate($movie);
153
154 1
        if (count($errors)) {
155
            return $request->getErrorResponse($errors);
156
        }
157
158 1
        $entityManager = $this->getDoctrine()->getManager();
159 1
        $entityManager->persist($movie);
160 1
        $entityManager->flush();
161
162 1
        return $this->response($movie, 200, [], [
163 1
            'groups' => ['view'],
164
        ]);
165
    }
166
167
    /**
168
     * @Route("/api/movies/{id}", methods={"POST", "PUT", "PATCH"}, requirements={"id"="\d+"})
169
     *
170
     * @param Movie              $movie
171
     * @param UpdateMovieRequest $request
172
     *
173
     * @throws \ErrorException
174
     * @throws \Exception
175
     *
176
     * @return JsonResponse
177
     */
178 2
    public function putMovies(Movie $movie, UpdateMovieRequest $request)
179
    {
180 2
        $this->denyAccessUnlessGranted(UserRoles::ROLE_ADMIN);
181
182 1
        $movieData = $request->get('movie');
183 1
        $movieTranslationsData = $movieData['translations'];
184
185 1
        $movie->setOriginalTitle($movieData['originalTitle']);
186 1
        $movie->setImdbId($movieData['imdbId']);
187 1
        $movie->setRuntime($movieData['runtime']);
188 1
        $movie->setBudget($movieData['budget']);
189 1
        $movie->setReleaseDate(new \DateTimeImmutable($movieData['releaseDate']));
190
191
        $addTranslation = function (array $trans) use ($movie) {
192 1
            $transDto = new MovieTranslationDTO($trans['locale'], $trans['title'], $trans['overview'], null);
193 1
            $movie->addTranslation(
194 1
                new MovieTranslations($movie, $transDto)
195
            );
196 1
        };
197
198
        $updateTranslation = function (array $trans, MovieTranslations $oldTranslation) use ($movie) {
199 1
            $oldTranslation->setTitle($trans['title']);
200 1
            $oldTranslation->setOverview($trans['overview']);
201 1
        };
202
203 1
        $movie->updateTranslations($movieTranslationsData, $addTranslation, $updateTranslation);
204
205 1
        $em = $this->getDoctrine()->getManager();
206 1
        $em->persist($movie); // if there 1+ new translations lets persist movie to be sure that they will be saved
207 1
        $em->flush();
208
209 1
        return new JsonResponse(null, 202);
210
    }
211
}
212