Completed
Push — master ( b4d909...e3c084 )
by Valentyn
03:37
created

MovieController::getMoviesRecommendations()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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