Completed
Push — master ( 0370c3...927fe1 )
by Valentyn
04:10
created

findRecommendedMovieByTmdbId()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 0
cts 5
cp 0
rs 9.9332
c 0
b 0
f 0
cc 4
nc 3
nop 3
crap 20
1
<?php
2
3
namespace App\Movies\Controller;
4
5
use App\Controller\BaseController;
6
use App\Movies\Entity\Movie;
7
use App\Movies\Entity\MovieRecommendation;
8
use App\Movies\EventListener\AddRecommendationProcessor;
9
use App\Movies\Repository\MovieRecommendationRepository;
10
use App\Movies\Repository\MovieRepository;
11
use App\Movies\Request\NewMovieRecommendationRequest;
12
use App\Movies\Request\RemoveMovieRecommendationRequest;
13
use App\Movies\Request\SearchRequest;
14
use App\Movies\Service\SearchService;
15
use App\Pagination\PaginatedCollection;
16
use App\Users\Entity\User;
17
use App\Users\Entity\UserRoles;
18
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
19
use Doctrine\ORM\EntityManagerInterface;
20
use Enqueue\Client\Message;
21
use Enqueue\Client\MessagePriority;
22
use Enqueue\Client\ProducerInterface;
23
use Symfony\Component\HttpFoundation\JsonResponse;
24
use Symfony\Component\HttpFoundation\Request;
25
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
26
use Symfony\Component\Routing\Annotation\Route;
27
28
class MovieRecommendationController extends BaseController
29
{
30
    /**
31
     * Add new recommendation.
32
     *
33
     * @Route("/api/movies/{id}/recommendations", methods={"POST"})
34
     *
35
     * @param NewMovieRecommendationRequest $request
36
     * @param Movie                         $originalMovie
37
     * @param EntityManagerInterface        $em
38
     * @param ProducerInterface             $producer
39
     *
40
     * @throws \Doctrine\ORM\ORMException
41
     *
42
     * @return JsonResponse
43
     */
44 2
    public function postMoviesRecommendations(NewMovieRecommendationRequest $request, Movie $originalMovie, EntityManagerInterface $em, ProducerInterface $producer)
45
    {
46 2
        $this->denyAccessUnlessGranted(UserRoles::ROLE_USER);
47
48 2
        $recommendation = $request->get('recommendation');
49 2
        $user = $this->getUser();
50
51 2
        if (empty($recommendation['movie_id'])) {
52 1
            $message = new Message(json_encode([
53 1
                'tmdb_id' => $recommendation['tmdb_id'],
54 1
                'movie_id' => $originalMovie->getId(),
55 1
                'user_id' => $user->getId(),
56
            ]));
57 1
            $message->setPriority(MessagePriority::VERY_LOW);
58 1
            $producer->sendEvent(AddRecommendationProcessor::ADD_RECOMMENDATION, $message);
59
60 1
            return new JsonResponse();
61
        }
62
63 1
        $recommendedMovie = $em->getReference(Movie::class, $recommendation['movie_id']);
64
65 1
        if ($recommendedMovie === null) {
66
            throw new NotFoundHttpException();
67
        }
68
69 1
        $originalMovie->addRecommendation($user, $recommendedMovie);
0 ignored issues
show
Documentation introduced by
$user is of type null|object, but the function expects a object<App\Users\Entity\User>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
70 1
        $em->persist($originalMovie);
71
        try {
72 1
            $em->flush();
73
        } catch (UniqueConstraintViolationException $exception) {
74
            // It's ok..
75
        }
76
77 1
        return new JsonResponse();
78
    }
79
80
    /**
81
     * Remove recommendation.
82
     *
83
     * @Route("/api/movies/{id}/recommendations", methods={"DELETE"})
84
     *
85
     * @param RemoveMovieRecommendationRequest $request
86
     * @param Movie                            $originalMovie
87
     * @param MovieRecommendationRepository    $repository
88
     * @param EntityManagerInterface           $em
89
     *
90
     * @return JsonResponse
91
     */
92
    public function deleteMoviesRecommendations(RemoveMovieRecommendationRequest $request, Movie $originalMovie, MovieRecommendationRepository $repository, EntityManagerInterface $em)
0 ignored issues
show
Unused Code introduced by
The parameter $repository is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
93
    {
94
        $this->denyAccessUnlessGranted(UserRoles::ROLE_USER);
95
96
        $user = $this->getUser();
97
98
        if (empty($request->get('movie_id'))) {
99
            $recommendedMovie = $this->findRecommendedMovieByTmdbId($originalMovie, $user, $request->get('tmdb_id'));
0 ignored issues
show
Documentation introduced by
$user is of type null|object, but the function expects a object<App\Users\Entity\User>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
100
            if ($recommendedMovie === null) {
101
                return new JsonResponse();
102
            }
103
104
            $em->remove($recommendedMovie);
105
            $em->flush();
106
107
            return new JsonResponse();
108
        }
109
110
        $recommendedMovie = $this->findRecommendedMovieById($originalMovie, $user, $request->get('movie_id'));
0 ignored issues
show
Documentation introduced by
$user is of type null|object, but the function expects a object<App\Users\Entity\User>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
111
        if ($recommendedMovie === null) {
112
            return new JsonResponse();
113
        }
114
115
        $em->remove($recommendedMovie);
116
        $em->flush();
117
118
        return new JsonResponse();
119
    }
120
121
    private function findRecommendedMovieById(Movie $originalMovie, User $user, int $id): ?MovieRecommendation
122
    {
123
        foreach ($originalMovie->getRecommendations() as $recommendation) {
124
            if ($recommendation->getUser()->getId() === $user->getId() && $recommendation->getRecommendedMovie()->getId() === $id) {
125
                return $recommendation;
126
            }
127
        }
128
129
        return null;
130
    }
131
132
    private function findRecommendedMovieByTmdbId(Movie $originalMovie, User $user, int $tmdbId): ?MovieRecommendation
133
    {
134
        foreach ($originalMovie->getRecommendations() as $recommendation) {
135
            if ($recommendation->getUser()->getId() === $user->getId() && $recommendation->getRecommendedMovie()->getTmdb()->getId() === $tmdbId) {
136
                return $recommendation;
137
            }
138
        }
139
140
        return null;
141
    }
142
143
    /**
144
     * @Route("/api/movies/{id}/recommendations", methods={"GET"})
145
     *
146
     * @param Movie                         $movie
147
     * @param MovieRepository               $movieRepository
0 ignored issues
show
Documentation introduced by
There is no parameter named $movieRepository. Did you maybe mean $repository?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
148
     * @param MovieRecommendationRepository $repository
149
     *
150
     * @throws \Doctrine\DBAL\DBALException
151
     *
152
     * @return JsonResponse
153
     */
154
    public function getMoviesRecommendations(Request $request, Movie $movie, MovieRecommendationRepository $repository)
155
    {
156
        $user = $this->getUser();
157
158
        $offset = (int) $request->get('offset', 0);
159
        $limit = $request->get('limit', null);
160
161
        if ($user instanceof User) {
162
            $recommendedMovies = $repository->findAllByMovieAndUser($movie->getId(), $user->getId());
163
        } else {
164
            $recommendedMovies = $repository->findAllByMovie($movie->getId());
165
        }
166
167
        $recommendedMovies = new PaginatedCollection($recommendedMovies, $offset, $limit, false);
168
169
        return $this->response($recommendedMovies, 200, [], [
170
            'groups' => ['list'],
171
        ]);
172
    }
173
174
    /**
175
     * Get movies by title.
176
     *
177
     * @Route("/api/movies/{id}/recommendations/search", methods={"POST"})
178
     *
179
     * @param int           $id
180
     * @param SearchRequest $request
181
     * @param SearchService $searchService
182
     * @param Request       $currentRequest
183
     *
184
     * @throws \App\Movies\Exception\TmdbMovieNotFoundException
185
     * @throws \App\Movies\Exception\TmdbRequestLimitException
186
     * @throws \ErrorException
187
     * @throws \Psr\SimpleCache\InvalidArgumentException
188
     *
189
     * @return \Symfony\Component\HttpFoundation\JsonResponse
190
     */
191
    public function getSearch(int $id, SearchRequest $request, SearchService $searchService, Request $currentRequest)
192
    {
193
        $offset = (int) $request->get('offset', 0);
194
        $limit = $request->get('limit', null);
195
196
        $query = $request->get('query');
197
198
        if (null === $user = $this->getUser()) {
199
            $movies = $searchService->findByQuery($query, $currentRequest->getLocale(), $offset, $limit);
200
        } else {
201
            $movies = $searchService->findByQueryWithUserRecommendedMovie($query, $id, $user->getId(), $currentRequest->getLocale(), $offset, $limit);
202
        }
203
204
        return $this->response($movies, 200, [], [
205
            'groups' => ['list'],
206
        ]);
207
    }
208
}
209