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) { |
|
|
|
|
200
|
|
|
$oTitle->genres[] = new Genre($g['id'], $g['name']); |
201
|
|
|
} |
202
|
|
View Code Duplication |
foreach ($tData['production_companies'] ?? [] as $c) { |
|
|
|
|
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) { |
|
|
|
|
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) { |
|
|
|
|
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) { |
|
|
|
|
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) { |
|
|
|
|
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
|
|
|
|
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.