Completed
Pull Request — master (#30)
by vincent
03:53
created

Tmdb   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 323
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 4
dl 0
loc 323
ccs 95
cts 95
cp 1
rs 9.2
c 0
b 0
f 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A getRequest() 0 6 1
A postRequest() 0 6 1
A deleteRequest() 0 6 1
A sendRequest() 0 13 2
A decodeRequest() 0 13 3
A buildHTTPUrl() 0 16 1
A getConfiguration() 0 13 3
A getLogger() 0 4 1
A __get() 0 9 2
A checkOptionYear() 0 6 2
A checkOptionLanguage() 0 11 4
A checkOptionIncludeAdult() 0 6 2
A checkOptionPage() 0 6 2
A checkOptionSortBy() 0 13 4
A checkOptionQuery() 0 6 2
A checkOptionSessionId() 0 6 2
1
<?php declare(strict_types = 1);
2
3
/**
4
 * This file is part of the Tmdb package.
5
 *
6
 * (c) Vincent Faliès <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * @author Vincent Faliès <[email protected]>
12
 * @copyright Copyright (c) 2017
13
 */
14
15
namespace VfacTmdb;
16
17
use VfacTmdb\Interfaces\TmdbInterface;
18
use VfacTmdb\Interfaces\HttpRequestInterface;
19
use Psr\Log\LoggerInterface;
20
use VfacTmdb\Exceptions\TmdbException;
21
use VfacTmdb\Exceptions\IncorrectParamException;
22
use VfacTmdb\Exceptions\ServerErrorException;
23
24
/**
25
 * Tmdb wrapper core class
26
 * @package Tmdb
27
 * @author Vincent Faliès <[email protected]>
28
 * @copyright Copyright (c) 2017
29
 */
30
class Tmdb implements TmdbInterface
31
{
32
33
    /**
34
     * API Key
35
     * @var string
36
     */
37
    private $api_key = null;
38
39
    /**
40
     * API configuration
41
     * @var \stdClass
42
     */
43
    protected $configuration = null;
44
45
    /**
46
     * API Genres
47
     * @var \stdClass
48
     */
49
    protected $genres = null;
50
51
    /**
52
     * Base URL of the API
53
     * @var string
54
     */
55
    public $base_api_url = 'https://api.themoviedb.org/';
56
57
    /**
58
     * Logger
59
     * @var LoggerInterface
60
     */
61
    protected $logger = null;
62
63
    /**
64
     * API Version
65
     * @var int
66
     */
67
    protected $version = 3;
68
69
    /**
70
     * Http request object
71
     * @var HttpRequestInterface
72
     */
73
    protected $http_request = null;
74
    /**
75
     * Request object
76
     * @var \stdClass
77
     */
78
    protected $request;
79
    /**
80
     * Last request url
81
     * @var string
82
     */
83
    protected $url = null;
84
85
    /**
86
     * Constructor
87
     * @param string $api_key TMDB API Key
88
     * @param int $version Version of API (Not yet used)
89
     * @param LoggerInterface $logger Logger used in the class
90
     * @param HttpRequestInterface $http_request
91
     */
92 356
    public function __construct(string $api_key, int $version = 3, LoggerInterface $logger, HttpRequestInterface $http_request)
93
    {
94 356
        $this->api_key      = $api_key;
95 356
        $this->logger       = $logger;
96 356
        $this->version      = $version;
97 356
        $this->http_request = $http_request;
98 356
        $this->request      = new \stdClass;
99 356
    }
100
101
    /**
102
     * Send request to TMDB API with GET method
103
     * @param string $action API action to request
104
     * @param array $options Array of options of the request (optional)
105
     * @return \stdClass|null
106
     */
107 317
    public function getRequest(string $action, array $options = array()) : ?\stdClass
108
    {
109 317
        $this->logger->debug('Start sending HTTP request with GET method', array('action' => $action, 'options' => $options));
110 317
        $this->url = $this->buildHTTPUrl($action, $options);
111 317
        return $this->sendRequest('GET', $this->url);
112
    }
113
114
    /**
115
     * Send request to TMDB API with POST method
116
     * @param string $action API action to request
117
     * @param array $options Array of options of the request (optional)
118
     * @param array $form_params form_params for request options
119
     * @return \stdClass|null
120
     */
121 15
    public function postRequest(string $action, array $options = array(), array $form_params = array()) : ?\stdClass
122
    {
123 15
        $this->logger->debug('Start sending HTTP request with POST method', array('action' => $action, 'options' => $options, 'form_params' => $form_params));
124 15
        $this->url = $this->buildHTTPUrl($action, $options);
125 15
        return $this->sendRequest('POST', $this->url, $form_params);
126
    }
127
128
    /**
129
     * Send request to TMDB API with DELETE method
130
     * @param  string $action  API action to request
131
     * @param  array  $options Array of options of the request (optional)
132
     * @return \stdClass|null
133
     */
134 5
    public function deleteRequest(string $action, array $options = array()) : ?\stdClass
135
    {
136 5
        $this->logger->debug('Start sending HTTP request with DELETE method', array('action' => $action, 'options' => $options));
137 5
        $this->url = $this->buildHTTPUrl($action, $options);
138 5
        return $this->sendRequest('DELETE', $this->url);
139
    }
140
141
    /**
142
     * Send request to TMDB API with GET method
143
     * @param string $method HTTP method (GET, POST)
144
     * @param string $url API url to request
145
     * @param array $form_params form params request options
146
     * @return \stdClass|null
147
     */
148 6
    protected function sendRequest(string $method, string $url, array $form_params = array()) : ?\stdClass
149
    {
150
        try {
151 6
            $res = new \stdClass();
152 6
            $method_name = $method.'Response';
153 6
            $res = $this->http_request->$method_name($url, [], $form_params);
154 6
            $response = $this->decodeRequest($res, $method, $url, $form_params);
155 3
            return $response;
156 3
        } catch (TmdbException $e) {
157 3
            $this->logger->error('sendRequest failed : '.$e->getMessage(), array('method' => $method, 'url' => $url, 'form_params' => $form_params));
158 3
            throw $e;
159
        }
160
    }
161
162
    /**
163
     * Decode request response
164
     * @param  mixed $res
165
     * @param  string $method
166
     * @param  string $url
167
     * @param  array $form_params
168
     * @return \stdClass
169
     */
170 6
    private function decodeRequest($res, $method, $url, $form_params) : \stdClass
171
    {
172 6
        if (empty($res->getBody())) {
173 2
            $this->logger->error('Request Body empty', array('method' => $method, 'url' => $url, 'form_params' => $form_params));
174 2
            throw new ServerErrorException();
175
        }
176 4
        $response = json_decode($res->getBody());
177 4
        if (empty($response)) {
178 1
            $this->logger->error('Request Body can not be decode', array('method' => $method, 'url' => $url, 'form_params' => $form_params));
179 1
            throw new ServerErrorException();
180
        }
181 3
        return $response;
182
    }
183
184
    /**
185
     * Build URL for HTTP Call
186
     * @param string $action API action to request
187
     * @param array $options Array of options of the request (optional)
188
     * @return string
189
     */
190 319
    private function buildHTTPUrl(string $action, array $options) : string
191
    {
192
        // Url construction
193 319
        $url = $this->base_api_url . $this->version . '/' . $action;
194
195
        // Parameters
196 319
        $params            = [];
197 319
        $params['api_key'] = $this->api_key;
198
199 319
        $params = array_merge($params, $options);
200
201
        // URL with paramters construction
202 319
        $url = $url . '?' . http_build_query($params);
203
204 319
        return $url;
205
    }
206
207
    /**
208
     * Get API Configuration
209
     * @return \stdClass
210
     * @throws TmdbException
211
     */
212 50
    public function getConfiguration() : \stdClass
213
    {
214
        try {
215 50
            $this->logger->debug('Start getting configuration');
216 50
            if (is_null($this->configuration)) {
217 50
                $this->logger->debug('No configuration found, sending HTTP request to get it');
218 50
                $this->configuration = $this->getRequest('configuration');
219
            }
220 49
            return $this->configuration;
221 1
        } catch (TmdbException $ex) {
222 1
            throw $ex;
223
        }
224
    }
225
226
    /**
227
     * Get logger
228
     * @return LoggerInterface
229
     */
230 324
    public function getLogger() : LoggerInterface
231
    {
232 324
        return $this->logger;
233
    }
234
235
    /**
236
     * Magical property getter
237
     * @param  string $name Name of the property
238
     * @return string       Value of the property
239
     */
240 73
    public function __get(string $name) : string
241
    {
242
        switch ($name) {
243 73
            case 'url':
244 72
                return $this->$name;
245
            default:
246 1
                throw new IncorrectParamException;
247
        }
248
    }
249
250
    /**
251
     * Check year option and return correct value
252
     * @param array $options
253
     * @param array &$return Return array to save valid option
254
     * @return void
255
     */
256 29
    public function checkOptionYear(array $options, array &$return) : void
257
    {
258 29
        if (isset($options['year'])) {
259 1
            $return['year'] = (int) $options['year'];
260
        }
261 29
    }
262
263
    /**
264
     * Check Language string with format ISO 639-1
265
     * @param array $options
266
     * @param array &$return Return array to save valid option
267
     * @return void
268
     */
269 277
    public function checkOptionLanguage(array $options, array &$return) : void
270
    {
271 277
        if (isset($options['language'])) {
272 35
            $check = preg_match("#([a-z]{2})-([A-Z]{2})#", $options['language']);
273 35
            if ($check === 0 || $check === false) {
274 1
                $this->logger->error('Incorrect language param option', array('language' => $options['language']));
275 1
                throw new IncorrectParamException;
276
            }
277 34
            $return['language'] = $options['language'];
278
        }
279 276
    }
280
281
    /**
282
     * Check include adult option
283
     * @param  array $options
284
     * @param array &$return Return array to save valid option
285
     * @return void
286
     */
287 29
    public function checkOptionIncludeAdult(array $options, array &$return) : void
288
    {
289 29
        if (isset($options['include_adult'])) {
290 1
            $return['include_adult'] = filter_var($options['include_adult'], FILTER_VALIDATE_BOOLEAN);
291
        }
292 29
    }
293
294
    /**
295
     * Check page option
296
     * @param  array  $options
297
     * @param array &$return Return array to save valid option
298
     * @return void
299
     */
300 38
    public function checkOptionPage(array $options, array &$return) : void
301
    {
302 38
        if (isset($options['page'])) {
303 1
            $return['page'] = (int) $options['page'];
304
        }
305 38
    }
306
307
    /**
308
     * Check sort by option
309
     * @param  array  $options
310
     * @param array &$return Return array to save valid option
311
     * @return void
312
     */
313 9
    public function checkOptionSortBy(array $options, array &$return) : void
314
    {
315 9
        if (isset($options['sort_by'])) {
316 2
            switch ($options['sort_by']) {
317 2
                case 'asc':
318 1
                case 'desc':
319 1
                    break;
320
                default:
321 1
                    throw new IncorrectParamException;
322
            }
323 1
            $return['sort_by'] = 'created_at.'.$options['sort_by'];
324
        }
325 8
    }
326
327
    /**
328
     * Check query option
329
     * @param  array  $options
330
     * @param array &$return Return array to save valid option
331
     * @return void
332
     */
333 28
    public function checkOptionQuery(array $options, array &$return) : void
334
    {
335 28
        if (isset($options['query'])) {
336 28
            $return['query'] = trim($options['query']);
337
        }
338 28
    }
339
340
    /**
341
     * Check session_id option
342
     * @param array  $options
343
     * @param array &$return Return array to save valid option
344
     * @return void
345
     */
346 7
    public function checkOptionSessionId(array $options, array &$return) : void
347
    {
348 7
        if (isset($options['session_id'])) {
349 7
            $return['session_id'] = trim($options['session_id']);
350
        }
351 7
    }
352
}
353