Completed
Push — master ( e3c084...cc131d )
by Valentyn
16:29
created

postMoviesRecommendations()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 4.016

Importance

Changes 0
Metric Value
dl 0
loc 35
ccs 18
cts 20
cp 0.9
rs 9.36
c 0
b 0
f 0
cc 4
nc 4
nop 4
crap 4.016
1
<?php
2
3
namespace App\Movies\Controller;
4
5
use App\Controller\BaseController;
6
use App\Movies\Entity\Movie;
7
use App\Movies\EventListener\AddRecommendationProcessor;
8
use App\Movies\Repository\MovieRecommendationRepository;
9
use App\Movies\Repository\MovieRepository;
10
use App\Movies\Request\NewMovieRecommendationRequest;
11
use App\Pagination\PaginatedCollection;
12
use App\Users\Entity\User;
13
use App\Users\Entity\UserRoles;
14
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
15
use Doctrine\ORM\EntityManagerInterface;
16
use Enqueue\Client\Message;
17
use Enqueue\Client\MessagePriority;
18
use Enqueue\Client\ProducerInterface;
19
use Symfony\Component\HttpFoundation\JsonResponse;
20
use Symfony\Component\HttpFoundation\Request;
21
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
22
use Symfony\Component\Routing\Annotation\Route;
23
24
class MovieRecommendationController extends BaseController
25
{
26
    /**
27
     * Add new recommendation.
28
     *
29
     * @Route("/api/movies/{id}/recommendations", methods={"POST"})
30
     *
31
     * @param NewMovieRecommendationRequest $request
32
     * @param Movie                         $originalMovie
33
     * @param EntityManagerInterface        $em
34
     * @param ProducerInterface             $producer
35
     *
36
     * @throws \Doctrine\ORM\ORMException
37
     *
38
     * @return JsonResponse
39
     */
40 2
    public function postMoviesRecommendations(NewMovieRecommendationRequest $request, Movie $originalMovie, EntityManagerInterface $em, ProducerInterface $producer)
41
    {
42 2
        $this->denyAccessUnlessGranted(UserRoles::ROLE_USER);
43
44 2
        $recommendation = $request->get('recommendation');
45 2
        $user = $this->getUser();
46
47 2
        if (empty($recommendation['movie_id'])) {
48 1
            $message = new Message(json_encode([
49 1
                'tmdb_id' => $recommendation['tmdb_id'],
50 1
                'movie_id' => $originalMovie->getId(),
51 1
                'user_id' => $user->getId(),
52
            ]));
53 1
            $message->setPriority(MessagePriority::VERY_LOW);
54 1
            $producer->sendEvent(AddRecommendationProcessor::ADD_RECOMMENDATION, $message);
55
56 1
            return new JsonResponse();
57
        }
58
59 1
        $recommendedMovie = $em->getReference(Movie::class, $recommendation['movie_id']);
60
61 1
        if ($recommendedMovie === null) {
62
            throw new NotFoundHttpException();
63
        }
64
65 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...
66 1
        $em->persist($originalMovie);
67
        try {
68 1
            $em->flush();
69
        } catch (UniqueConstraintViolationException $exception) {
70
            // It's ok..
71
        }
72
73 1
        return new JsonResponse();
74
    }
75
76
    /**
77
     * @Route("/api/movies/{id}/recommendations", methods={"GET"})
78
     *
79
     * @param Movie                         $movie
80
     * @param MovieRepository               $movieRepository
81
     * @param MovieRecommendationRepository $repository
82
     *
83
     * @throws \Doctrine\DBAL\DBALException
84
     *
85
     * @return JsonResponse
86
     */
87
    public function getMoviesRecommendations(Movie $movie, MovieRepository $movieRepository, MovieRecommendationRepository $repository)
88
    {
89
        $user = $this->getUser();
90
        $sortRecommendedMovies = function (array $movie1, array $movie2) {
91
            return $movie2['rate'] <=> $movie1['rate'];
92
        };
93
94
        if ($user instanceof User) {
95
            $recommendedMoviesIds = $repository->findAllByMovieAndUser($movie->getId(), $user->getId());
96
            usort($recommendedMoviesIds, $sortRecommendedMovies);
97
            $recommendedMovies = $movieRepository->findAllByIdsWithFlags(array_map(function (array $recommendedMovie) {
98
                return $recommendedMovie['movie_id'];
99
            }, $recommendedMoviesIds), $user->getId());
100
        } else {
101
            $recommendedMoviesIds = $repository->findAllByMovie($movie->getId());
102
            usort($recommendedMoviesIds, $sortRecommendedMovies);
103
            $recommendedMovies = $movieRepository->findAllByIdsWithoutFlags(array_map(function (array $recommendedMovie) {
104
                return $recommendedMovie['movie_id'];
105
            }, $recommendedMoviesIds));
106
        }
107
108
        return $this->response($recommendedMovies, 200, [], [
109
            'groups' => ['list'],
110
        ]);
111
    }
112
113
    /**
114
     * @Route("/api/recommendations", methods={"GET"})
115
     *
116
     * @param Request                       $request
117
     * @param MovieRecommendationRepository $repository
118
     *
119
     * @return JsonResponse
120
     */
121
    public function getAllRecommendations(Request $request, MovieRecommendationRepository $repository)
122
    {
123
        $this->denyAccessUnlessGranted(UserRoles::ROLE_USER);
124
        $user = $this->getUser();
125
126
        $offset = (int) $request->get('offset', 0);
127
        $limit = $request->get('limit', null);
128
        $minRating = $request->get('minRating', 7);
129
130
        $query = $repository->findAllByUser($user->getId(), abs((int) $minRating));
131
        $movies = new PaginatedCollection($query, $offset, $limit, false);
132
133
        return $this->response($movies, 200, [], [
134
            'groups' => ['list'],
135
        ]);
136
    }
137
}
138