Completed
Push — master ( 058e40...9e132c )
by Valentyn
04:01
created

SearchService   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 127
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 127
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 11
    public function __construct(MovieRepository $repository, TmdbSearchService $tmdb, TmdbSyncService $sync, TmdbNormalizerService $normalizer)
24
    {
25 11
        $this->repository = $repository;
26 11
        $this->tmdb = $tmdb;
27 11
        $this->sync = $sync;
28 11
        $this->normalizer = $normalizer;
29 11
    }
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
     * @throws TmdbMovieNotFoundException
82
     * @throws TmdbRequestLimitException
83
     * @throws \ErrorException
84
     * @throws \Psr\SimpleCache\InvalidArgumentException
85
     */
86
    public function findByQueryWithUserRecommendedMovie(string $query, int $originalMovieId, int $userId, string $locale, int $offset = 0, ?int $limit = null): PaginatedCollectionInterface
87
    {
88
        $moviesQuery = $this->repository->findByTitleWithUserRecommendedMovieQuery($query, $userId, $originalMovieId);
89
        $movies = new PaginatedCollection($moviesQuery, $offset, $limit);
90
        if ($movies->getTotal() > 0) {
91
            return $movies;
92
        }
93
94
        $movies = $this->tmdb->findMoviesByQuery($query, $locale);
95
        $totalResults = (int) $movies['total_results'];
96
97
        if ($totalResults === 0) {
98
            return new MovieCollection([], 0, $offset);
99
        }
100
101
        $moviesObjects = $this->normalizer->normalizeMoviesToObjects($movies['results'], $locale);
102
        $this->sync->syncMovies($movies['results']);
103
104
        // If we have a lot of movies then save it all
105
        if (isset($movies['total_pages']) && $movies['total_pages'] > 1) {
106
            // $i = 2 because $movies currently already has movies from page 1
107
            for ($i = 2; $i <= $movies['total_pages']; ++$i) {
108
                try {
109
                    $moviesOnPage = $this->tmdb->findMoviesByQuery($query, $locale, [
110
                        'page' => $i,
111
                    ]);
112
                } catch (TmdbRequestLimitException $requestLimitException) {
113
                    continue;
114
                }
115
                $this->sync->syncMovies($moviesOnPage['results']);
116
            }
117
        }
118
119
        return new MovieCollection($moviesObjects, $totalResults, $offset);
120
    }
121
122
    /**
123
     * @param int    $tmdb_id
124
     * @param string $locale
125
     *
126
     * @throws \Exception
127
     *
128
     * @return Movie|null
129
     */
130 1
    public function findByTmdbId(int $tmdb_id, string $locale): ?Movie
131
    {
132
        try {
133 1
            $movie = $this->tmdb->findMovieById($tmdb_id, $locale);
134
        } catch (TmdbMovieNotFoundException $exception) {
135
            return null;
136
        }
137
138 1
        $movies = $this->normalizer->normalizeMoviesToObjects([$movie], $locale);
139
140 1
        return $movies->current() ?: null;
141
    }
142
}
143