Tmdb::searchByTitle()   F
last analyzed

Complexity

Conditions 9
Paths 263

Size

Total Lines 45
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 0
Metric Value
dl 0
loc 45
ccs 0
cts 40
cp 0
rs 3
c 0
b 0
f 0
cc 9
eloc 32
nc 263
nop 1
crap 90
1
<?php
2
/**
3
 * xMDB-API
4
 *
5
 * Copyright © 2017 pudelek.org.pl
6
 *
7
 * @license MIT License (MIT)
8
 *
9
 * For the full copyright and license information, please view source file
10
 * that is bundled with this package in the file LICENSE
11
 *
12
 * @author Marcin Pudełek <[email protected]>
13
 */
14
15
/**
16
 * Created by Marcin.
17
 * Date: 29.11.2017
18
 * Time: 21:54
19
 */
20
21
namespace mrcnpdlk\Xmdb;
22
23
24
use Carbon\Carbon;
25
use mrcnpdlk\Xmdb\Exception\NotFound;
26
use mrcnpdlk\Xmdb\Model\Tmdb\Company;
27
use mrcnpdlk\Xmdb\Model\Tmdb\Country;
28
use mrcnpdlk\Xmdb\Model\Tmdb\Genre;
29
use mrcnpdlk\Xmdb\Model\Tmdb\Language;
30
use mrcnpdlk\Xmdb\Model\Tmdb\Movie\Collection;
31
use mrcnpdlk\Xmdb\Model\Tmdb\Movie\Title as MovieTitle;
32
use mrcnpdlk\Xmdb\Model\Tmdb\Person;
33
use mrcnpdlk\Xmdb\Model\Tmdb\Title;
34
use mrcnpdlk\Xmdb\Model\Tmdb\TvShow\Network;
35
use mrcnpdlk\Xmdb\Model\Tmdb\TvShow\Season;
36
use mrcnpdlk\Xmdb\Model\Tmdb\TvShow\Title as TvShowTitle;
37
use RuntimeException;
38
use Tmdb\ApiToken;
39
use Tmdb\Exception\TmdbApiException;
40
41
class Tmdb
42
{
43
    /**
44
     * @var \mrcnpdlk\Xmdb\Client
45
     */
46
    private $oClient;
47
    /**
48
     * @var \Tmdb\Client
49
     */
50
    private $oTmdbClient;
51
    /**
52
     * @var \Psr\Log\LoggerInterface
53
     */
54
    private $oLog;
55
56
    /**
57
     * Tmdb constructor.
58
     *
59
     * @param \mrcnpdlk\Xmdb\Client $oClient
60
     *
61
     * @throws \mrcnpdlk\Xmdb\Exception
62
     */
63
    public function __construct(Client $oClient)
64
    {
65
        $this->oClient = $oClient;
66
        $this->oLog    = $oClient->getLogger();
67
        try {
68
            if (null === $this->oTmdbClient) {
69
                $options = [
70
                    'cache' => [
71
                        'enabled' => true,
72
                    ],
73
                    'log'   => [
74
                        'enabled' => true,
75
                    ],
76
                ];
77
78
                $oToken            = new ApiToken($this->oClient->getTmdbToken());
79
                $this->oTmdbClient = new \Tmdb\Client($oToken, $options);
80
            }
81
        } catch (\Exception $e) {
82
            throw new Exception(sprintf('Cannot create Tmdb Client'), 1, $e);
83
        }
84
    }
85
86
    /**
87
     * @param string|null $imdbId
88
     *
89
     * @return Title
90
     * @throws \mrcnpdlk\Xmdb\Exception\NotFound Title not found
91
     * @throws \mrcnpdlk\Xmdb\Exception
92
     */
93
    public function getByImdbId(string $imdbId = null)
94
    {
95
        try {
96
            $this->oLog->info(sprintf('Searching: %s', $imdbId));
97
            if ($imdbId === null || $imdbId === '') {
98
                throw new RuntimeException('ImdbId is require!');
99
            }
100
101
            $oTitle = new Title();
102
            $find   = $this->oTmdbClient
103
                ->getFindApi()
104
                ->findBy($imdbId, [
105
                    'external_source' => 'imdb_id',
106
                    'language'        => $this->oClient->getLang(),
107
                    'include_adult'   => true,
108
                ])
109
            ;
110
            if (!empty($find['movie_results']) && \count($find['movie_results']) === 1) {
111
                $item = $find['movie_results'][0];
112
113
                $oTitle->isAdult      = isset($item['adult']) ? (bool)$item['adult'] : false;
114
                $oTitle->title        = $item['title'];
115
                $oTitle->titleOrg     = $item['original_title'];
116
                $oTitle->titleOrgLang = $item['original_language'];
117
                $oTitle->id           = $item['id'];
118
                $oTitle->imdbId       = $imdbId;
119
                $oTitle->backdrop     = $item['backdrop_path'];
120
                $oTitle->poster       = $item['poster_path'];
121
                $oTitle->releaseDate  = $item['release_date'];
122
                $oTitle->rating       = $item['vote_average'];
123
                $oTitle->voteCount    = $item['vote_count'];
124
                $oTitle->popularity   = $item['popularity'];
125
                $oTitle->isMovie      = true;
126
                $oTitle->overview     = $item['overview'];
127
                $oTitle->releaseYear  = $oTitle->releaseDate ? Carbon::parse($oTitle->releaseDate)->format('Y') : null;
128
            } elseif (!empty($find['tv_results']) && \count($find['tv_results']) === 1) {
129
                $item = $find['tv_results'][0];
130
131
                $oTitle->isAdult      = isset($item['adult']) ? (bool)$item['adult'] : false;
132
                $oTitle->title        = $item['name'];
133
                $oTitle->titleOrg     = $item['original_name'];
134
                $oTitle->titleOrgLang = $item['original_language'];
135
                $oTitle->id           = $item['id'];
136
                $oTitle->imdbId       = $imdbId;
137
                $oTitle->backdrop     = $item['backdrop_path'];
138
                $oTitle->poster       = $item['poster_path'];
139
                $oTitle->releaseDate  = $item['first_air_date'];
140
                $oTitle->rating       = $item['vote_average'];
141
                $oTitle->voteCount    = $item['vote_count'];
142
                $oTitle->popularity   = $item['popularity'];
143
                $oTitle->isMovie      = false;
144
                $oTitle->overview     = $item['overview'];
145
                $oTitle->releaseYear  = $oTitle->releaseDate ? Carbon::parse($oTitle->releaseDate)->format('Y') : null;
146
            } elseif (!empty($find['tv_results']) && !empty($find['movie_results']) && \count($find['movie_results']) === 1  && \count($find['tv_results']) === 1
147
                ) {
148
                throw new RuntimeException('Too many items in TMDB database');
149
            } else {
150
                throw new NotFound('TMDB response empty');
151
            }
152
153
            return $oTitle;
154
        } catch (NotFound $e) {
155
            throw $e;
156
        } catch (\Exception $e) {
157
            throw new Exception($e->getMessage());
158
        }
159
    }
160
161
    /**
162
     * @param int $id
163
     *
164
     * @return \mrcnpdlk\Xmdb\Model\Tmdb\Movie\Title
165
     * @throws \mrcnpdlk\Xmdb\Exception\NotFound
166
     * @throws \mrcnpdlk\Xmdb\Exception
167
     */
168
    public function getMovie(int $id): Model\Tmdb\Movie\Title
169
    {
170
        try {
171
            $tData                = $this->oTmdbClient->getMoviesApi()->getMovie($id, [
172
                'language'      => $this->oClient->getLang(),
173
                'include_adult' => true,
174
            ])
175
            ;
176
            $oTitle               = new MovieTitle();
177
            $oTitle->id           = $id;
178
            $oTitle->title        = $tData['title'];
179
            $oTitle->titleOrg     = $tData['original_title'];
180
            $oTitle->titleOrgLang = $tData['original_language'];
181
            $oTitle->isVideo      = $tData['video'];
182
            $oTitle->isAdult      = $tData['adult'];
183
            $oTitle->imdbId       = $tData['imdb_id'];
184
            $oTitle->backdrop     = $tData['backdrop_path'];
185
            $oTitle->poster       = $tData['poster_path'];
186
            $oTitle->releaseDate  = $tData['release_date'];
187
            $oTitle->releaseYear  = null;
188
            $oTitle->rating       = $tData['vote_average'];
189
            $oTitle->voteCount    = $tData['vote_count'];
190
            $oTitle->popularity   = $tData['popularity'];
191
            $oTitle->overview     = $tData['overview'];
192
            $oTitle->homepage     = $tData['homepage'];
193
            $oTitle->budget       = $tData['budget'];
194
            $oTitle->revenue      = $tData['revenue'];
195
            $oTitle->runtime      = $tData['runtime'];
196
            $oTitle->status       = $tData['status'];
197
            $oTitle->tagline      = $tData['tagline'];
198
199 View Code Duplication
            foreach ($tData['genres'] ?? [] as $g) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
200
                $oTitle->genres[] = new Genre($g['id'], $g['name']);
201
            }
202 View Code Duplication
            foreach ($tData['production_companies'] ?? [] as $c) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
203
                $oTitle->productionCompanies[] = new Company($c['id'], $c['name']);
204
            }
205
            foreach ($tData['production_countries'] ?? [] as $g) {
206
                $oTitle->productionCountries[] = new Country($g['iso_3166_1'], $g['name']);
207
            }
208
            foreach ($tData['spoken_languages'] ?? [] as $g) {
209
                $oTitle->spokenLanguages[] = new Language($g['iso_639_1'], $g['name']);
210
            }
211
            if (!empty($tData['belongs_to_collection'])) {
212
                $oTitle->collection = new Collection(
213
                    $tData['belongs_to_collection']['id'],
214
                    $tData['belongs_to_collection']['name'],
215
                    $tData['belongs_to_collection']['poster_path'],
216
                    $tData['belongs_to_collection']['backdrop_path']);
217
            }
218
219
            return $oTitle;
220
        } catch (\Exception $e) {
221 View Code Duplication
            if ($e instanceof TmdbApiException) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
222
                if ($e->getCode() === 34) {
223
                    throw new NotFound($e->getMessage());
224
                }
225
                throw new Exception(sprintf('TMDB Response Error: %s', $e->getMessage()));
226
            }
227
228
            throw new Exception($e->getMessage());
229
        }
230
    }
231
232
    /**
233
     * @param int $id
234
     *
235
     * @return \mrcnpdlk\Xmdb\Model\Tmdb\TvShow\Title
236
     * @throws \mrcnpdlk\Xmdb\Exception\NotFound
237
     * @throws \mrcnpdlk\Xmdb\Exception
238
     */
239
    public function getTvShow(int $id): TvShowTitle
240
    {
241
        try {
242
            $tData = $this->oTmdbClient
243
                ->getTvApi()
244
                ->getTvshow($id, [
245
                    'language'           => $this->oClient->getLang(),
246
                    'include_adult'      => true,
247
                    'append_to_response' => 'external_ids',
248
                ])
249
            ;
250
251
            $oTitle                  = new TvShowTitle();
252
            $oTitle->id              = $id;
253
            $oTitle->title           = $tData['name'];
254
            $oTitle->titleOrg        = $tData['original_name'];
255
            $oTitle->titleOrgLang    = $tData['original_language'];
256
            $oTitle->inProduction    = $tData['in_production'];
257
            $oTitle->imdbId          = $tData['external_ids']['imdb_id'] ?? null;
258
            $oTitle->backdrop        = $tData['backdrop_path'];
259
            $oTitle->poster          = $tData['poster_path'];
260
            $oTitle->firstAirDate    = $tData['first_air_date'];
261
            $oTitle->lastAirDate     = $tData['last_air_date'];
262
            $oTitle->rating          = $tData['vote_average'];
263
            $oTitle->voteCount       = $tData['vote_count'];
264
            $oTitle->popularity      = $tData['popularity'];
265
            $oTitle->overview        = $tData['overview'];
266
            $oTitle->homepage        = $tData['homepage'];
267
            $oTitle->episodeRuntimes = $tData['episode_run_time'];
268
            $oTitle->status          = $tData['status'];
269
            $oTitle->type            = $tData['type'];
270
            $oTitle->languages       = $tData['languages'];
271
            $oTitle->episodesNumber  = $tData['number_of_episodes'];
272
            $oTitle->seasonsNumber   = $tData['number_of_seasons'];
273
            $oTitle->originCountries = $tData['origin_country'];
274
275 View Code Duplication
            foreach ($tData['genres'] ?? [] as $item) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
276
                $oTitle->genres[] = new Genre($item['id'], $item['name']);
277
            }
278
            foreach ($tData['networks'] ?? [] as $item) {
279
                $oTitle->networks[] = new Network($item['id'], $item['name']);
280
            }
281 View Code Duplication
            foreach ($tData['production_companies'] ?? [] as $item) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
282
                $oTitle->productionCompanies[] = new Company($item['id'], $item['name']);
283
            }
284
            foreach ($tData['seasons'] ?? [] as $item) {
285
                $oTitle->seasons[] = new Season(
286
                    $item['id'],
287
                    $item['season_number'],
288
                    $item['episode_count'],
289
                    $item['air_date'],
290
                    $item['poster_path']
291
                );
292
            }
293
            foreach ($tData['created_by'] ?? [] as $item) {
294
                $oTitle->createdBy[] = new Person(
295
                    $item['id'],
296
                    $item['name'],
297
                    $item['gender'],
298
                    $item['profile_path']
299
                );
300
            }
301
302
            return $oTitle;
303
        } catch (\Exception $e) {
304 View Code Duplication
            if ($e instanceof TmdbApiException) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
305
                if ($e->getCode() === 34) {
306
                    throw new NotFound($e->getMessage());
307
                }
308
                throw new Exception(sprintf('TMDB Response Error: %s', $e->getMessage()));
309
            }
310
311
            throw new Exception($e->getMessage());
312
        }
313
    }
314
315
    /**
316
     * @param string $title
317
     *
318
     * @return array|\mrcnpdlk\Xmdb\Model\Tmdb\Title[]
319
     * @throws \mrcnpdlk\Xmdb\Exception
320
     */
321
    public function searchByTitle(string $title)
322
    {
323
        try {
324
            /**
325
             * @var Title[] $answer
326
             */
327
            $answer = [];
328
            $tList  = $this->oTmdbClient
329
                ->getSearchApi()
330
                ->searchMulti($title, [
331
                    'page'          => 1,
332
                    'language'      => $this->oClient->getLang(),
333
                    'include_adult' => true,
334
                ])
335
            ;
336
            foreach ($tList['results'] ?? [] as $item) {
337
                if (\in_array($item['media_type'], ['tv', 'movie'], true)) {
338
                    $oTitle               = new Title();
339
                    $oTitle->id           = $item['id'];
340
                    $oTitle->isMovie      = $item['media_type'] === 'movie';
341
                    $oTitle->isAdult      = $item['adult'] ?? null;
342
                    $oTitle->title        = $oTitle->isMovie ? $item['title'] : $item['name'];
343
                    $oTitle->titleOrg     = $oTitle->isMovie ? $item['original_title'] : $item['original_name'];
344
                    $oTitle->titleOrgLang = $item['original_language'];
345
                    $oTitle->backdrop     = $item['backdrop_path'];
346
                    $oTitle->poster       = $item['poster_path'];
347
                    $oTitle->releaseDate  = $oTitle->isMovie ? $item['release_date'] : $item['first_air_date'];
348
                    $oTitle->rating       = $item['vote_average'];
349
                    $oTitle->voteCount    = $item['vote_count'];
350
                    $oTitle->popularity   = $item['popularity'];
351
                    $oTitle->overview     = $item['overview'];
352
                    $oTitle->releaseYear  = $oTitle->releaseDate ? Carbon::parse($oTitle->releaseDate)->format('Y') : null;
353
354
                    $answer[] = $oTitle;
355
                }
356
            }
357
358
            return $answer;
359
        } catch (\Exception $e) {
360
            if ($e instanceof TmdbApiException) {
361
                throw new Exception(sprintf('TMDB Response Error: %s', $e->getMessage()));
362
            }
363
            throw new Exception($e->getMessage());
364
        }
365
    }
366
}
367