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

postMoviesRecommendations()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4.941

Importance

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