Completed
Push — master ( 71d672...bb4d5a )
by Valentyn
04:16
created

SearchService   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 44%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 6
dl 0
loc 134
ccs 22
cts 50
cp 0.44
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
B findByQuery() 0 35 7
B findByQueryWithUserRecommendedMovie() 0 35 7
A findByTmdbId() 0 12 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Movies\Service;
6
7
use App\Movies\Entity\Movie;
8
use App\Movies\Exception\TmdbMovieNotFoundException;
9
use App\Movies\Exception\TmdbRequestLimitException;
10
use App\Movies\Pagination\MovieCollection;
11
use App\Movies\Repository\MovieRepository;
12
use App\Pagination\PaginatedCollection;
13
use App\Pagination\PaginatedCollectionInterface;
14
15
// todo all pages option
16
class SearchService
17
{
18
    private $repository;
19
    private $tmdb;
20
    private $sync;
21
    private $normalizer;
22
23 9
    public function __construct(MovieRepository $repository, TmdbSearchService $tmdb, TmdbSyncService $sync, TmdbNormalizerService $normalizer)
24
    {
25 9
        $this->repository = $repository;
26 9
        $this->tmdb = $tmdb;
27 9
        $this->sync = $sync;
28 9
        $this->normalizer = $normalizer;
29 9
    }
30
31
    /**
32
     * @param string   $query
33
     * @param string   $locale
34
     * @param int      $offset
35
     * @param int|null $limit
36
     *
37
     * @throws TmdbMovieNotFoundException
38
     * @throws TmdbRequestLimitException
39
     * @throws \ErrorException
40
     * @throws \Psr\SimpleCache\InvalidArgumentException
41
     *
42
     * @return PaginatedCollectionInterface
43
     */
44 2
    public function findByQuery(string $query, string $locale, int $offset = 0, ?int $limit = null): PaginatedCollectionInterface
45
    {
46 2
        $moviesQuery = $this->repository->findByTitleQuery($query);
47 2
        $movies = new PaginatedCollection($moviesQuery, $offset, $limit);
48 2
        if ($movies->getTotal() > 0) {
49 1
            return $movies;
50
        }
51
52 1
        $movies = $this->tmdb->findMoviesByQuery($query, $locale);
53 1
        $totalResults = (int) $movies['total_results'];
54
55 1
        if ($totalResults === 0) {
56
            return new MovieCollection([], 0, $offset);
57
        }
58
59 1
        $moviesObjects = $this->normalizer->normalizeMoviesToObjects($movies['results'], $locale);
60 1
        $this->sync->syncMovies($movies['results']);
61
62
        // If we have a lot of movies then save it all
63 1
        if (isset($movies['total_pages']) && $movies['total_pages'] > 1) {
64
            // $i = 2 because $movies currently already has movies from page 1
65
            for ($i = 2; $i <= $movies['total_pages']; ++$i) {
66
                try {
67
                    $moviesOnPage = $this->tmdb->findMoviesByQuery($query, $locale, [
68
                        'page' => $i,
69
                    ]);
70
                } catch (TmdbRequestLimitException $requestLimitException) {
71
                    continue;
72
                }
73
                $this->sync->syncMovies($moviesOnPage['results']);
74
            }
75
        }
76
77 1
        return new MovieCollection($moviesObjects, $totalResults, $offset);
78
    }
79
80
    /**
81
     * @param string   $query
82
     * @param string   $locale
83
     * @param int      $offset
84
     * @param int|null $limit
85
     *
86
     * @throws TmdbMovieNotFoundException
87
     * @throws TmdbRequestLimitException
88
     * @throws \ErrorException
89
     * @throws \Psr\SimpleCache\InvalidArgumentException
90
     *
91
     * @return PaginatedCollectionInterface
92
     */
93
    public function findByQueryWithUserRecommendedMovie(string $query, int $originalMovieId, int $userId, string $locale, int $offset = 0, ?int $limit = null): PaginatedCollectionInterface
94
    {
95
        $moviesQuery = $this->repository->findByTitleWithUserRecommendedMovieQuery($query, $userId, $originalMovieId);
96
        $movies = new PaginatedCollection($moviesQuery, $offset, $limit);
97
        if ($movies->getTotal() > 0) {
98
            return $movies;
99
        }
100
101
        $movies = $this->tmdb->findMoviesByQuery($query, $locale);
102
        $totalResults = (int) $movies['total_results'];
103
104
        if ($totalResults === 0) {
105
            return new MovieCollection([], 0, $offset);
106
        }
107
108
        $moviesObjects = $this->normalizer->normalizeMoviesToObjects($movies['results'], $locale);
109
        $this->sync->syncMovies($movies['results']);
110
111
        // If we have a lot of movies then save it all
112
        if (isset($movies['total_pages']) && $movies['total_pages'] > 1) {
113
            // $i = 2 because $movies currently already has movies from page 1
114
            for ($i = 2; $i <= $movies['total_pages']; ++$i) {
115
                try {
116
                    $moviesOnPage = $this->tmdb->findMoviesByQuery($query, $locale, [
117
                        'page' => $i,
118
                    ]);
119
                } catch (TmdbRequestLimitException $requestLimitException) {
120
                    continue;
121
                }
122
                $this->sync->syncMovies($moviesOnPage['results']);
123
            }
124
        }
125
126
        return new MovieCollection($moviesObjects, $totalResults, $offset);
127
    }
128
129
    /**
130
     * @param int    $tmdb_id
131
     * @param string $locale
132
     *
133
     * @throws \Exception
134
     *
135
     * @return Movie|null
136
     */
137 1
    public function findByTmdbId(int $tmdb_id, string $locale): ?Movie
138
    {
139
        try {
140 1
            $movie = $this->tmdb->findMovieById($tmdb_id, $locale);
141
        } catch (TmdbMovieNotFoundException $exception) {
142
            return null;
143
        }
144
145 1
        $movies = $this->normalizer->normalizeMoviesToObjects([$movie], $locale);
146
147 1
        return $movies->current() ?: null;
148
    }
149
}
150