Issues (12)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Tmdb.php (6 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
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
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
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
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
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
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