Completed
Push — master ( d3c65f...52aca9 )
by Valentyn
02:41
created

TmdbSearchService::findMovieById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 15
cts 15
cp 1
rs 9.536
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Movies\Service;
6
7
use App\Movies\Exception\TmdbMovieNotFoundException;
8
use App\Movies\Exception\TmdbRequestLimitException;
9
use GuzzleHttp\ClientInterface;
10
use GuzzleHttp\Exception\GuzzleException;
11
use Psr\Log\LoggerInterface;
12
use Psr\SimpleCache\CacheInterface;
13
14
// todo refactor cache usage
15
class TmdbSearchService
16
{
17
    private $apiKey;
18
    private $client;
19
    private $logger;
20
    private $cache;
21
    private const ApiUrl = 'https://api.themoviedb.org/3';
22
23 9
    public function __construct(LoggerInterface $logger, ClientInterface $client, CacheInterface $cache)
24
    {
25 9
        $this->apiKey = \getenv('MOVIE_DB_API_KEY'); // is it ok to use \getenv() here?
26 9
        $this->client = $client;
27 9
        $this->logger = $logger;
28 9
        $this->cache = $cache;
29 9
    }
30
31
    /**
32
     * @param string $query
33
     * @param string $locale
34
     * @param array  $data
35
     *
36
     * @throws TmdbMovieNotFoundException
37
     * @throws TmdbRequestLimitException
38
     * @throws \Psr\SimpleCache\InvalidArgumentException
39
     *
40
     * @return array
41
     */
42 1
    public function findMoviesByQuery(string $query, string $locale = 'en', $data = []): array
43
    {
44 1
        $data = array_merge([
45 1
            'api_key' => $this->apiKey,
46 1
            'language' => $locale,
47 1
            'query' => $query,
48 1
        ], $data);
49
50 1
        $movies = $this->request('/search/movie', 'GET', [
51 1
            'query' => $data,
52
        ]);
53
54 1
        return $movies;
55
    }
56
57
    /**
58
     * @param int    $tmdb_id
59
     * @param string $locale
60
     *
61
     * @throws TmdbMovieNotFoundException
62
     * @throws TmdbRequestLimitException
63
     * @throws \Psr\SimpleCache\InvalidArgumentException
64
     *
65
     * @return array
66
     */
67 1
    public function findMovieById(int $tmdb_id, string $locale = 'en'): array
68
    {
69 1
        $movie = $this->request("/movie/{$tmdb_id}", 'GET', [
70
            'query' => [
71 1
                'api_key' => $this->apiKey,
72 1
                'language' => $locale,
73 1
                'append_to_response' => 'similar,translations,credits',
74
            ],
75
        ]);
76
77 1
        $similarUrl = "/movie/{$tmdb_id}/similar";
78 1
        $params = ['api_key' => $this->apiKey, 'page' => 1];
79 1
        $this->cache->set($this->getCacheKeyFromParams($similarUrl, 'GET', ['query' => $params]), json_encode($movie['similar']), 1800);
80
81 1
        $translationsUrl = "/movie/{$tmdb_id}/translations";
82 1
        $params = ['api_key' => $this->apiKey];
83 1
        $this->cache->set($this->getCacheKeyFromParams($translationsUrl, 'GET', ['query' => $params]), json_encode($movie['translations']), 1800);
84
85 1
        $creditsUrl = "/movie/{$tmdb_id}/credits";
86 1
        $params = ['api_key' => $this->apiKey, 'language' => $locale];
87 1
        $this->cache->set($this->getCacheKeyFromParams($creditsUrl, 'GET', ['query' => $params]), json_encode($movie['credits']), 1800);
88
89 1
        return $movie;
90
    }
91
92
    /**
93
     * @param int    $movieId
94
     * @param string $locale
95
     *
96
     * @throws TmdbMovieNotFoundException
97
     * @throws TmdbRequestLimitException
98
     * @throws \Psr\SimpleCache\InvalidArgumentException
99
     *
100
     * @return array
101
     */
102
    public function findActorsByMovieId(int $movieId, string $locale = 'en'): array
103
    {
104
        $actors = $this->request("/movie/{$movieId}/credits", 'GET', [
105
            'query' => [
106
                'api_key' => $this->apiKey,
107
                'language' => $locale,
108
            ],
109
        ]);
110
111
        return $actors;
112
    }
113
114
    /**
115
     * @param int    $personId
116
     * @param string $locale
117
     *
118
     * @throws TmdbMovieNotFoundException
119
     * @throws TmdbRequestLimitException
120
     * @throws \Psr\SimpleCache\InvalidArgumentException
121
     *
122
     * @return array
123
     */
124
    public function findActorById(int $personId, string $locale = 'en'): array
125
    {
126
        $actor = $this->request("/person/{$personId}", 'GET', [
127
            'query' => [
128
                'api_key' => $this->apiKey,
129
                'language' => $locale,
130
                'append_to_response' => 'translations',
131
            ],
132
        ]);
133
134
        $translationsUrl = "/person/{$personId}/translations";
135
        $params = ['api_key' => $this->apiKey, 'language' => $locale];
136
        $this->cache->set($this->getCacheKeyFromParams($translationsUrl, 'GET', ['query' => $params]), json_encode($actor['translations']), 1800);
137
138
        return $actor;
139
    }
140
141
    /**
142
     * @param int    $personId
143
     * @param string $locale
144
     *
145
     * @throws TmdbMovieNotFoundException
146
     * @throws TmdbRequestLimitException
147
     * @throws \Psr\SimpleCache\InvalidArgumentException
148
     *
149
     * @return array
150
     */
151
    public function findActorTranslationsById(int $personId, string $locale = 'en'): array
152
    {
153
        $actors = $this->request("/person/{$personId}/translations", 'GET', [
154
            'query' => [
155
                'api_key' => $this->apiKey,
156
                'language' => $locale,
157
            ],
158
        ]);
159
160
        echo var_export($actors); exit;
161
162
        return $actors;
0 ignored issues
show
Unused Code introduced by
return $actors; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
163
    }
164
165
    /**
166
     * @param int $tmdb_id
167
     *
168
     * @throws TmdbMovieNotFoundException
169
     * @throws TmdbRequestLimitException
170
     * @throws \Psr\SimpleCache\InvalidArgumentException
171
     *
172
     * @return array
173
     */
174
    public function findMovieTranslationsById(int $tmdb_id): array
175
    {
176
        $movie = $this->request("/movie/{$tmdb_id}/translations", 'GET', [
177
            'query' => [
178
                'api_key' => $this->apiKey,
179
            ],
180
        ]);
181
182
        return $movie;
183
    }
184
185
    /**
186
     * @param int $tmdb_id
187
     * @param int $page
188
     *
189
     * @throws TmdbMovieNotFoundException
190
     * @throws TmdbRequestLimitException
191
     * @throws \Psr\SimpleCache\InvalidArgumentException
192
     *
193
     * @return array
194
     */
195
    public function findSimilarMoviesById(int $tmdb_id, int $page = 1): array
196
    {
197
        $movie = $this->request("/movie/{$tmdb_id}/similar", 'GET', [
198
            'query' => [
199
                'api_key' => $this->apiKey,
200
                'page' => $page,
201
            ],
202
        ]);
203
204
        return $movie;
205
    }
206
207
    /**
208
     * @param string $url
209
     * @param string $method
210
     * @param array  $params
211
     *
212
     * @throws TmdbMovieNotFoundException
213
     * @throws TmdbRequestLimitException
214
     * @throws \Psr\SimpleCache\InvalidArgumentException
215
     *
216
     * @return array
217
     */
218 2
    private function request(string $url, string $method = 'GET', array $params = []): array
219
    {
220 2
        if (null !== $cachedResponse = $this->getResponseFromCache($url, $method, $params)) {
221
            return $cachedResponse;
222
        }
223
224 2
        $url = self::ApiUrl.$url;
225
226
        try {
227 2
            $response = $this->client->request($method, $url, $params);
228 2
            $responseJson = $response->getBody()->getContents();
229 2
            $response = json_decode($responseJson, true);
230 2
            $this->cache->set($this->getCacheKeyFromParams($url, $method, $params), $responseJson, 1800);
231 2
            getenv('APP_ENV') === 'dev' && $this->logger->debug('Guzzle request:', [
232
                'url' => $url,
233
                'method' => $method,
234
                'params' => $params,
235 2
                'response' => $response,
236
            ]);
237
        } catch (GuzzleException $exception) {
238
            $this->logger->error('Guzzle request failed.', [
239
                'url' => $url,
240
                'method' => $method,
241
                'params' => $params,
242
                'exceptionMessage' => $exception->getMessage(),
243
                'exceptionCode' => $exception->getCode(),
244
            ]);
245
246
            $response = [];
247
248
            if ($exception->getCode() === 404) {
249
                throw new TmdbMovieNotFoundException();
250
            }
251
252
            if ($exception->getCode() === 429) {
253
                throw new TmdbRequestLimitException();
254
            }
255
        }
256
257 2
        return $response;
258
    }
259
260 2
    private function arrayAsString(array $array): string
261
    {
262 2
        $string = '';
263
264 2
        foreach ($array as $key => $value) {
265 2
            if (is_array($value) === true) {
266 2
                $value = $this->arrayAsString($value);
267
            }
268 2
            $string .= "$key-$value";
269
        }
270
271 2
        return $string;
272
    }
273
274 2
    private function getCacheKeyFromParams(string $url, string $method = 'GET', array $params = []): string
275
    {
276 2
        $key = md5($url.mb_strtolower($method).$this->arrayAsString($params));
277
278 2
        return $key;
279
    }
280
281
    /**
282
     * @param string $url
283
     * @param string $method
284
     * @param array  $params
285
     *
286
     * @throws \Psr\SimpleCache\InvalidArgumentException
287
     *
288
     * @return array|null
289
     */
290 2
    private function getResponseFromCache(string $url, string $method = 'GET', array $params = []): ?array
291
    {
292 2
        if (null !== $response = $this->cache->get($this->getCacheKeyFromParams($url, $method, $params))) {
293
            return json_decode($response, true);
294
        }
295
296 2
        return $response;
297
    }
298
}
299