Completed
Push — master ( 4851fa...058e40 )
by Valentyn
04:07
created

WatchedMovieService::addGuestWatchedMovie()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5.7629

Importance

Changes 0
Metric Value
dl 0
loc 33
ccs 11
cts 16
cp 0.6875
rs 9.0808
c 0
b 0
f 0
cc 5
nc 12
nop 3
crap 5.7629
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Movies\Service;
6
7
use App\Guests\Entity\GuestSession;
8
use App\Guests\Entity\GuestWatchedMovie;
9
use App\Guests\Repository\WatchedMovieRepository;
10
use App\Movies\DTO\WatchedMovieDTO;
11
use App\Movies\Entity\Movie;
12
use App\Movies\Entity\WatchedMovie;
13
use App\Movies\EventListener\SimilarMoviesProcessor;
14
use App\Movies\EventListener\WatchedMovieProcessor;
15
use App\Movies\Repository\MovieRepository;
16
use App\Users\Entity\User;
17
use App\Users\Entity\UserWatchedMovie;
18
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
19
use Doctrine\ORM\EntityManagerInterface;
20
use Enqueue\Client\ProducerInterface;
21
22
// todo event for new added movie and if so - remove this movie from wishlist (if its added there)
23
class WatchedMovieService
24
{
25
    private $em;
26
    /**
27
     * @var MovieRepository
28
     */
29
    private $repository;
30
31
    private $searchService;
32
33
    private $producer;
34
35 9
    public function __construct(EntityManagerInterface $entityManager, SearchService $searchService, ProducerInterface $producer)
36
    {
37 9
        $this->em = $entityManager;
38 9
        $this->repository = $entityManager->getRepository(Movie::class);
39 9
        $this->searchService = $searchService;
40 9
        $this->producer = $producer;
41 9
    }
42
43
    /**
44
     * @param User            $user
45
     * @param WatchedMovieDTO $watchedMovieDTO
46
     * @param string          $locale
47
     *
48
     * @throws \Exception
49
     *
50
     * @return bool
51
     */
52 6
    public function addUserWatchedMovie(User $user, WatchedMovieDTO $watchedMovieDTO, string $locale): bool
53
    {
54 6
        $movie = $this->repository->findOneByIdOrTmdbId($watchedMovieDTO->getMovieId(), $watchedMovieDTO->getTmdbId());
55
56 6
        if ($movie === null) {
57
            // Lets try to find it in TMDB library
58
            $movie = $this->searchService->findByTmdbId($watchedMovieDTO->getTmdbId(), $locale);
59
        }
60
61 6
        if ($movie === null) {
62
            return false;
63
        }
64
65 6
        $newWatchedMovie = new UserWatchedMovie($user, $movie, $watchedMovieDTO->getVote(), $watchedMovieDTO->getWatchedAt());
66
67 6
        if ($movie->getId() === null) {
68
            $this->saveWatchedMovies([$newWatchedMovie]);
69
70
            return true;
71
        }
72
73
        try {
74 6
            $this->em->persist($newWatchedMovie);
75 6
            $this->em->flush();
76 6
            $this->onMovieAdded($newWatchedMovie);
77
        } catch (UniqueConstraintViolationException $exception) {
78
            // You can throw new BadRequestHttpException('This movie already in your library of watched movies');
79
            // But I think its nice to return 202 like operation was successful
80
            return true;
81
        }
82
83 6
        return true;
84
    }
85
86 2
    public function updateUserWatchedMovie(WatchedMovie $watchedMovie, WatchedMovieDTO $watchedMovieDTO)
87
    {
88 2
        $watchedMovie->changeVote($watchedMovieDTO->getVote());
89 2
        $watchedMovie->changeWatchedAt($watchedMovieDTO->getWatchedAt());
90 2
    }
91
92
    /**
93
     * @param GuestSession    $guestSession
94
     * @param WatchedMovieDTO $watchedMovieDTO
95
     * @param string          $locale
96
     *
97
     * @throws \Exception
98
     *
99
     * @return bool
100
     */
101 3
    public function addGuestWatchedMovie(GuestSession $guestSession, WatchedMovieDTO $watchedMovieDTO, string $locale): bool
102
    {
103 3
        $movie = $this->repository->findOneByIdOrTmdbId($watchedMovieDTO->getMovieId(), $watchedMovieDTO->getTmdbId());
104
105 3
        if ($movie === null) {
106
            // Lets try to find it in TMDB library
107 1
            $movie = $this->searchService->findByTmdbId($watchedMovieDTO->getTmdbId(), $locale);
108
        }
109
110 2
        if ($movie === null) {
111
            return false;
112
        }
113
114 2
        $newWatchedMovie = new GuestWatchedMovie($guestSession, $movie, $watchedMovieDTO->getVote(), $watchedMovieDTO->getWatchedAt());
115
116 2
        if ($movie->getId() === null) {
117
            $this->saveWatchedMovies([$newWatchedMovie]);
118
119
            return true;
120
        }
121
122
        try {
123 2
            $this->em->persist($newWatchedMovie);
124 2
            $this->em->flush();
125 2
            $this->onMovieAdded($newWatchedMovie);
126
        } catch (UniqueConstraintViolationException $exception) {
127
            // You can throw new BadRequestHttpException('This movie already in your library of watched movies');
128
            // But I think its nice to return 202 like operation was successful
129
            return true;
130
        }
131
132 2
        return true;
133
    }
134
135
    /**
136
     * @param GuestSession $guestSession
137
     * @param User         $user
138
     *
139
     * @throws \Exception
140
     */
141
    public function mergeWatchedMovies(GuestSession $guestSession, User $user): void
142
    {
143
        /** @var $guestWatchedMoviesRepository WatchedMovieRepository */
144
        $guestWatchedMoviesRepository = $this->em->getRepository(GuestWatchedMovie::class);
145
        $guestWatchedMovies = $guestWatchedMoviesRepository->findBy([
146
            'guestSession' => $guestSession->getId(),
147
        ]);
148
149
        if (!reset($guestWatchedMovies)) {
150
            return;
151
        }
152
153
        $userWatchedMovies = [];
154
        foreach ($guestWatchedMovies as $guestWatchedMovie) {
155
            $movie = $guestWatchedMovie->getMovie();
156
            $vote = $guestWatchedMovie->getVote();
157
            $watchedAt = $guestWatchedMovie->getWatchedAt();
158
            $userWatchedMovies[] = new UserWatchedMovie($user, $movie, $vote, $watchedAt);
159
        }
160
161
        $this->saveWatchedMovies($userWatchedMovies);
162
    }
163
164
    /**
165
     * @param array|UserWatchedMovie[]|GuestWatchedMovie[] $watchedMovies
166
     */
167
    private function saveWatchedMovies(array $watchedMovies): void
168
    {
169
        $watchedMoviesSerialized = serialize($watchedMovies);
170
        $this->producer->sendEvent(WatchedMovieProcessor::ADD_WATCHED_MOVIE_TMDB, $watchedMoviesSerialized);
171
    }
172
173 8
    private function onMovieAdded(WatchedMovie $watchedMovie): void
174
    {
175 8
        $movie = $watchedMovie->getMovie();
176 8
        if (\count($movie->getSimilarMovies()) === 0) {
177 8
            $this->producer->sendEvent(SimilarMoviesProcessor::LOAD_SIMILAR_MOVIES, json_encode($movie->getId()));
178
        }
179 8
    }
180
}
181