Passed
Branch release/1.5.0 (3fa0b2)
by vincent
02:31
created

Tmdb::getLogger()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
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
12
 * @author Vincent Faliès <[email protected]>
13
 * @copyright Copyright (c) 2017
14
 */
15
16
namespace vfalies\tmdb;
17
18
use vfalies\tmdb\Interfaces\TmdbInterface;
19
use vfalies\tmdb\Interfaces\HttpRequestInterface;
20
use Psr\Log\LoggerInterface;
21
use vfalies\tmdb\lib\Guzzle\Client as HttpClient;
22
use vfalies\tmdb\Exceptions\TmdbException;
23
use vfalies\tmdb\Exceptions\IncorrectParamException;
24
use vfalies\tmdb\Exceptions\ServerErrorException;
25
26
/**
27
 * Tmdb wrapper core class
28
 * @package Tmdb
29
 * @author Vincent Faliès <[email protected]>
30
 * @copyright Copyright (c) 2017
31
 */
32
class Tmdb implements TmdbInterface
33
{
34
35
    /**
36
     * API Key
37
     * @var string
38
     */
39
    private $api_key = null;
40
41
    /**
42
     * Default language for API response
43
     * @var string
44
     */
45
    private $language = 'fr-FR';
46
47
    /**
48
     * Include adult content in search result
49
     * @var boolean
50
     */
51
    private $include_adult = false;
52
53
    /**
54
     * API Page result
55
     * @var int
56
     */
57
    private $page = 1;
58
59
    /**
60
     * API configuration
61
     * @var \stdClass
62
     */
63
    protected $configuration = null;
64
65
    /**
66
     * API Genres
67
     * @var \stdClass
68
     */
69
    protected $genres = null;
70
71
    /**
72
     * Base URL of the API
73
     * @var string
74
     */
75
    public $base_api_url = 'https://api.themoviedb.org/3/';
76
77
    /**
78
     * Logger
79
     * @var LoggerInterface
80
     */
81
    protected $logger     = null;
82
83
    /**
84
     * API Version
85
     * @var int
86
     */
87
    protected $version = null;
88
89
    /**
90
     * Constructor
91
     * @param string $api_key TMDB API Key
92
     * @param string $version Version of API (Not yet used)
93
     * @param LoggerInterface $logger Logger used in the class
94
     */
95 298
    public function __construct($api_key, $version = 3, LoggerInterface $logger)
96
    {
97 298
        $this->api_key = $api_key;
98 298
        $this->logger  = $logger;
99 298
        $this->version = $version;
100 298
    }
101
102
    /**
103
     * Send request to TMDB API
104
     * @param HttpRequestInterface $http_request
105
     * @param string $action API action to request
106
     * @param string $query Query of the request (optional)
107
     * @param array $options Array of options of the request (optional)
108
     * @return \stdClass
109
     */
110 4
    public function sendRequest(HttpRequestInterface $http_request, $action, $query = null, array $options = array())
111
    {
112 4
        $this->logger->debug('Start sending HTTP request');
113 4
        $url = $this->buildHTTPUrl($action, $query, $options);
114 4
        $res = $http_request->getResponse($url);
115
116 4
        $response = json_decode($res->getBody());
117 4
        if (empty($response))
118
        {
119 3
            $this->logger->error('Request Body can not be decode', array('action' => $action, 'query' => $query, 'options' => $options));
120 3
            throw new ServerErrorException();
121
        }
122 1
        return $response;
123
    }
124
125
    /**
126
     * Build URL for HTTP Call
127
     * @param string $action API action to request
128
     * @param string $query Query of the request (optional)
129
     * @param array $options Array of options of the request (optional)
130
     * @return string
131
     */
132 4
    private function buildHTTPUrl($action, $query, $options)
133
    {
134
        // Url construction
135 4
        $url = $this->base_api_url.$action;
136
137
        // Parameters
138 4
        $params            = [];
139 4
        $params['api_key'] = $this->api_key;
140 4
        if ( ! is_null($query))
141
        {
142 1
            $params['query'] = $query;
143
        }
144
145 4
        $params = array_merge($params, $options);
146
147
        // URL with paramters construction
148 4
        $url = $url.'?'.http_build_query($params);
149
150 4
        return $url;
151
    }
152
153
    /**
154
     * Get API Configuration
155
     * @return \stdClass
156
     * @throws TmdbException
157
     */
158 12
    public function getConfiguration()
159
    {
160
        try
161
        {
162 12
            $this->logger->debug('Start getting configuration');
163 12
            if (is_null($this->configuration))
164
            {
165 12
                $this->logger->debug('No configuration found, sending HTTP request to get it');
166 12
                $this->configuration = $this->sendRequest(new HttpClient(new \GuzzleHttp\Client()), 'configuration');
167
            }
168 11
            return $this->configuration;
169
        }
170 1
        catch (TmdbException $ex)
171
        {
172 1
            throw $ex;
173
        }
174
    }
175
176
    /**
177
     * Check options rules before send request
178
     * @param array $options Array of options to validate
179
     * @return array
180
     * @throws IncorrectParamException
181
     */
182 273
    public function checkOptions(array $options)
183
    {
184 273
        $params                  = [];
185
        // Set default options
186 273
        $params['language']      = $this->language;
187 273
        $params['include_adult'] = $this->include_adult;
188 273
        $params['page']          = $this->page;
189
        // Check options
190 273
        foreach ($options as $key => $value)
191
        {
192
            switch ($key)
193
            {
194 42
                case 'year':
195 1
                    $params[$key] = $this->checkYear($value);
196 1
                    break;
197 42
                case 'language':
198 37
                    $params[$key] = $this->checkLanguage($value);
199 36
                    break;
200 6
                case 'include_adult':
201 1
                    $params[$key] = filter_var($value, FILTER_VALIDATE_BOOLEAN);
202 1
                    break;
203 6
                case 'page':
204 1
                    $params[$key] = (int) $value;
205 1
                    break;
206
                default:
207 5
                    $this->logger->error('Unknown param options', array('options', $options));
208 5
                    throw new IncorrectParamException;
209
            }
210
        }
211 267
        return $params;
212
    }
213
214
    /**
215
     * Check year format
216
     * @param mixed $year year to validate
217
     * @return int year validated
218
     * @throws \Exception
219
     */
220 1
    private function checkYear($year)
221
    {
222 1
        $year = (int) $year;
223 1
        return $year;
224
    }
225
226
    /**
227
     * Check language
228
     * @param string $language Language string with format ISO 639-1
229
     * @return string Language string validated
230
     * @throws IncorrectParamException
231
     */
232 37
    private function checkLanguage($language)
233
    {
234 37
        $check = preg_match("#([a-z]{2})-([A-Z]{2})#", $language);
235 37
        if ($check === 0 || $check === false)
236
        {
237 1
            $this->logger->error('Incorrect language param option', array('language' => $language));
238 1
            throw new IncorrectParamException;
239
        }
240 36
        return $language;
241
    }
242
243
    /**
244
     * Get logger
245
     * @return LoggerInterface
246
     */
247 281
    public function getLogger()
248
    {
249 281
        return $this->logger;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->logger; (Psr\Log\LoggerInterface) is incompatible with the return type declared by the interface vfalies\tmdb\Interfaces\TmdbInterface::getLogger of type vfalies\tmdb\Interfaces\LoggerInterface.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
250
    }
251
252
}
253