Completed
Push — master ( 1c84dd...0f2f0f )
by Valentyn
03:06
created

SearchService::findByTmdbId()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.3332

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 4
cts 6
cp 0.6667
rs 9.8666
c 0
b 0
f 0
cc 3
nc 3
nop 2
crap 3.3332
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 \Exception
38
     *
39
     * @return PaginatedCollectionInterface
40
     */
41 2
    public function findByQuery(string $query, string $locale, int $offset = 0, ?int $limit = null): PaginatedCollectionInterface
42
    {
43 2
        $moviesQuery = $this->repository->findByTitleQuery($query);
44 2
        $movies = new PaginatedCollection($moviesQuery, $offset, $limit);
45 2
        if ($movies->getTotal() > 0) {
46 1
            return $movies;
47
        }
48
49 1
        $movies = $this->tmdb->findMoviesByQuery($query, $locale);
50 1
        $totalResults = (int) $movies['total_results'];
51
52 1
        if ($totalResults === 0) {
53
            return new MovieCollection([], 0, $offset);
54
        }
55
56 1
        $moviesObjects = $this->normalizer->normalizeMoviesToObjects($movies['results'], $locale);
57 1
        $this->sync->syncMovies($movies['results']);
58
59
        // If we have a lot of movies then save it all
60 1
        if (isset($movies['total_pages']) && $movies['total_pages'] > 1) {
61
            // $i = 2 because $movies currently already has movies from page 1
62
            for ($i = 2; $i <= $movies['total_pages']; ++$i) {
63
                try {
64
                    $moviesOnPage = $this->tmdb->findMoviesByQuery($query, $locale, [
65
                        'page' => $i,
66
                    ]);
67
                } catch (TmdbRequestLimitException $requestLimitException) {
68
                    continue;
69
                }
70
                $this->sync->syncMovies($moviesOnPage['results']);
71
            }
72
        }
73
74 1
        return new MovieCollection($moviesObjects, $totalResults, $offset);
75
    }
76
77
    /**
78
     * @param int    $tmdb_id
79
     * @param string $locale
80
     *
81
     * @throws \Exception
82
     *
83
     * @return Movie|null
84
     */
85 1
    public function findByTmdbId(int $tmdb_id, string $locale): ?Movie
86
    {
87
        try {
88 1
            $movie = $this->tmdb->findMovieById($tmdb_id, $locale);
89
        } catch (TmdbMovieNotFoundException $exception) {
90
            return null;
91
        }
92
93 1
        $movies = $this->normalizer->normalizeMoviesToObjects([$movie], $locale);
94
95 1
        return $movies->current() ?: null;
96
    }
97
}
98