GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 96f191...a0fbd6 )
by Martin
06:51
created

WhatIsMyBrowserCom   B

Complexity

Total Complexity 53

Size/Duplication

Total Lines 340
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 14

Test Coverage

Coverage 100%

Importance

Changes 10
Bugs 0 Features 1
Metric Value
wmc 53
c 10
b 0
f 1
lcom 1
cbo 14
dl 0
loc 340
ccs 94
cts 94
cp 1
rs 7.4757

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getVersion() 0 4 1
C getResult() 0 68 17
C hasResult() 0 24 11
A isBot() 0 8 4
B parse() 0 36 3
A hydrateBot() 0 12 3
A hydrateBrowser() 0 10 3
A hydrateRenderingEngine() 0 10 3
A hydrateOperatingSystem() 0 10 3
A hydrateDevice() 0 14 4

How to fix   Complexity   

Complex Class

Complex classes like WhatIsMyBrowserCom often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WhatIsMyBrowserCom, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace UserAgentParser\Provider\Http;
3
4
use GuzzleHttp\Client;
5
use GuzzleHttp\Psr7\Request;
6
use stdClass;
7
use UserAgentParser\Exception;
8
use UserAgentParser\Model;
9
10
/**
11
 * Abstraction of useragentstring.com
12
 *
13
 * @author Martin Keckeis <[email protected]>
14
 * @license MIT
15
 * @see https://developers.whatismybrowser.com/reference
16
 */
17
class WhatIsMyBrowserCom extends AbstractHttpProvider
18
{
19
    /**
20
     * Name of the provider
21
     *
22
     * @var string
23
     */
24
    protected $name = 'WhatIsMyBrowserCom';
25
26
    /**
27
     * Homepage of the provider
28
     *
29
     * @var string
30
     */
31
    protected $homepage = 'https://www.whatismybrowser.com/';
32
33
    protected $detectionCapabilities = [
34
35
        'browser' => [
36
            'name'    => true,
37
            'version' => true,
38
        ],
39
40
        'renderingEngine' => [
41
            'name'    => true,
42
            'version' => true,
43
        ],
44
45
        'operatingSystem' => [
46
            'name'    => true,
47
            'version' => true,
48
        ],
49
50
        'device' => [
51
            'model' => true,
52
            'brand' => true,
53
54
            'type'     => true,
55
            'isMobile' => false,
56
            'isTouch'  => false,
57
        ],
58
59
        'bot' => [
60
            'isBot' => true,
61
            'name'  => true,
62
            'type'  => true,
63
        ],
64
    ];
65
66
    protected $defaultValues = [
67
68
        'general' => [],
69
70
        'browser' => [
71
            'name' => [
72
                '/^Unknown Mobile Browser$/i',
73
                '/^Unknown browser$/i',
74
                '/^Webkit based browser$/i',
75
                '/^a UNIX based OS$/i',
76
            ],
77
        ],
78
79
        'operatingSystem' => [
80
            'name' => [
81
                '/^Smart TV$/i',
82
            ],
83
        ],
84
85
        'device' => [
86
            'model' => [
87
                // HTC generic or large parser error (over 1000 found)
88
                '/^HTC$/i',
89
                '/^Mobile$/i',
90
                '/^Android Phone$/i',
91
                '/^Android Tablet$/i',
92
                '/^Tablet$/i',
93
            ],
94
        ],
95
    ];
96
97
    private static $uri = 'http://api.whatismybrowser.com/api/v1/user_agent_parse';
98
99
    private $apiKey;
100
101 26
    public function __construct(Client $client, $apiKey)
102
    {
103 26
        parent::__construct($client);
104
105 26
        $this->apiKey = $apiKey;
106 26
    }
107
108 1
    public function getVersion()
109
    {
110 1
        return;
111
    }
112
113
    /**
114
     *
115
     * @param  string                     $userAgent
116
     * @param  array                      $headers
117
     * @return stdClass
118
     * @throws Exception\RequestException
119
     */
120 19
    protected function getResult($userAgent, array $headers)
0 ignored issues
show
Unused Code introduced by
The parameter $headers is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
121
    {
122
        /*
123
         * an empty UserAgent makes no sense
124
         */
125 19
        if ($userAgent == '') {
126 1
            throw new Exception\NoResultFoundException('No result found for user agent: ' . $userAgent);
127
        }
128
129
        $params = [
130 18
            'user_key'   => $this->apiKey,
131 18
            'user_agent' => $userAgent,
132
        ];
133
134 18
        $body = http_build_query($params, null, '&');
135
136 18
        $request = new Request('POST', self::$uri, [], $body);
137
138 18
        $response = $this->getResponse($request);
139
140
        /*
141
         * no json returned?
142
         */
143 18
        $contentType = $response->getHeader('Content-Type');
144 18
        if (! isset($contentType[0]) || $contentType[0] != 'application/json') {
145 1
            throw new Exception\RequestException('Could not get valid "application/json" response from "' . $request->getUri() . '". Response is "' . $response->getBody()->getContents() . '"');
146
        }
147
148 17
        $content = json_decode($response->getBody()->getContents());
149
150
        /*
151
         * No result
152
         */
153 17
        if (isset($content->message_code) && $content->message_code == 'no_user_agent') {
154 1
            throw new Exception\NoResultFoundException('No result found for user agent: ' . $userAgent);
155
        }
156
157
        /*
158
         * Limit exceeded
159
         */
160 16
        if (isset($content->message_code) && $content->message_code == 'usage_limit_exceeded') {
161 1
            throw new Exception\LimitationExceededException('Exceeded the maximum number of request with API key "' . $this->apiKey . '" for ' . $this->getName());
162
        }
163
164
        /*
165
         * Error
166
         */
167 15
        if (isset($content->message_code) && $content->message_code == 'no_api_user_key') {
168 1
            throw new Exception\InvalidCredentialsException('Missing API key for ' . $this->getName());
169
        }
170
171 14
        if (isset($content->message_code) && $content->message_code == 'user_key_invalid') {
172 1
            throw new Exception\InvalidCredentialsException('Your API key "' . $this->apiKey . '" is not valid for ' . $this->getName());
173
        }
174
175 13
        if (! isset($content->result) || $content->result !== 'success') {
176 1
            throw new Exception\RequestException('Could not get valid response from "' . $request->getUri() . '". Response is "' . $response->getBody()->getContents() . '"');
177
        }
178
179
        /*
180
         * Missing data?
181
         */
182 12
        if (! $content instanceof stdClass || ! isset($content->parse) || ! $content->parse instanceof stdClass) {
183 1
            throw new Exception\RequestException('Could not get valid response from "' . $request->getUri() . '". Response is "' . print_r($content, true) . '"');
184
        }
185
186 11
        return $content->parse;
187
    }
188
189
    /**
190
     *
191
     * @param stdClass $resultRaw
192
     *
193
     * @return bool
194
     */
195 11
    private function hasResult(stdClass $resultRaw)
196
    {
197 11
        if (isset($resultRaw->browser_name) && $this->isRealResult($resultRaw->browser_name, 'browser', 'name') === true) {
198 2
            return true;
199
        }
200
201 9
        if (isset($resultRaw->layout_engine_name) && $this->isRealResult($resultRaw->layout_engine_name) === true) {
202 2
            return true;
203
        }
204
205 7
        if (isset($resultRaw->operating_system_name) && $this->isRealResult($resultRaw->operating_system_name, 'operatingSystem', 'name') === true) {
206 1
            return true;
207
        }
208
209 6
        if (isset($resultRaw->operating_platform) && $this->isRealResult($resultRaw->operating_platform, 'device', 'model') === true) {
210 1
            return true;
211
        }
212
213 5
        if (isset($resultRaw->operating_platform_vendor_name) && $this->isRealResult($resultRaw->operating_platform_vendor_name) === true) {
214 2
            return true;
215
        }
216
217 3
        return false;
218
    }
219
220
    /**
221
     *
222
     * @param  stdClass $resultRaw
223
     * @return boolean
224
     */
225 8
    private function isBot(stdClass $resultRaw)
226
    {
227 8
        if (isset($resultRaw->user_agent_type) && ($resultRaw->user_agent_type === 'crawler' || $resultRaw->user_agent_type === 'analyser')) {
228 1
            return true;
229
        }
230
231 7
        return false;
232
    }
233
234
    /**
235
     *
236
     * @param Model\Bot $bot
237
     * @param stdClass  $resultRaw
238
     */
239 1
    private function hydrateBot(Model\Bot $bot, stdClass $resultRaw)
240
    {
241 1
        $bot->setIsBot(true);
242
243 1
        if (isset($resultRaw->browser_name)) {
244 1
            $bot->setName($this->getRealResult($resultRaw->browser_name));
245
        }
246
247 1
        if (isset($resultRaw->user_agent_type)) {
248 1
            $bot->setType($this->getRealResult($resultRaw->user_agent_type));
249
        }
250 1
    }
251
252
    /**
253
     *
254
     * @param Model\Browser $browser
255
     * @param stdClass      $resultRaw
256
     */
257 7
    private function hydrateBrowser(Model\Browser $browser, stdClass $resultRaw)
258
    {
259 7
        if (isset($resultRaw->browser_name)) {
260 2
            $browser->setName($this->getRealResult($resultRaw->browser_name, 'browser', 'name'));
261
        }
262
263 7
        if (isset($resultRaw->browser_version_full)) {
264 1
            $browser->getVersion()->setComplete($this->getRealResult($resultRaw->browser_version_full));
265
        }
266 7
    }
267
268
    /**
269
     *
270
     * @param Model\RenderingEngine $engine
271
     * @param stdClass              $resultRaw
272
     */
273 7
    private function hydrateRenderingEngine(Model\RenderingEngine $engine, stdClass $resultRaw)
274
    {
275 7
        if (isset($resultRaw->layout_engine_name)) {
276 2
            $engine->setName($this->getRealResult($resultRaw->layout_engine_name));
277
        }
278
279 7
        if (isset($resultRaw->layout_engine_version)) {
280 1
            $engine->getVersion()->setComplete($this->getRealResult($resultRaw->layout_engine_version));
281
        }
282 7
    }
283
284
    /**
285
     *
286
     * @param Model\OperatingSystem $os
287
     * @param stdClass              $resultRaw
288
     */
289 7
    private function hydrateOperatingSystem(Model\OperatingSystem $os, stdClass $resultRaw)
290
    {
291 7
        if (isset($resultRaw->operating_system_name)) {
292 1
            $os->setName($this->getRealResult($resultRaw->operating_system_name, 'operatingSystem', 'name'));
293
        }
294
295 7
        if (isset($resultRaw->operating_system_version_full)) {
296 1
            $os->getVersion()->setComplete($this->getRealResult($resultRaw->operating_system_version_full));
297
        }
298 7
    }
299
300
    /**
301
     *
302
     * @param Model\Device $device
303
     * @param stdClass     $resultRaw
304
     */
305 7
    private function hydrateDevice(Model\Device $device, stdClass $resultRaw)
306
    {
307 7
        if (isset($resultRaw->operating_platform)) {
308 2
            $device->setModel($this->getRealResult($resultRaw->operating_platform, 'device', 'model'));
309
        }
310
311 7
        if (isset($resultRaw->operating_platform_vendor_name)) {
312 3
            $device->setBrand($this->getRealResult($resultRaw->operating_platform_vendor_name));
313
        }
314
315 7
        if (isset($resultRaw->user_agent_type)) {
316 1
            $device->setType($this->getRealResult($resultRaw->user_agent_type));
317
        }
318 7
    }
319
320 19
    public function parse($userAgent, array $headers = [])
321
    {
322 19
        $resultRaw = $this->getResult($userAgent, $headers);
323
324
        /*
325
         * No result found?
326
         */
327 11
        if ($this->hasResult($resultRaw) !== true) {
328 3
            throw new Exception\NoResultFoundException('No result found for user agent: ' . $userAgent);
329
        }
330
331
        /*
332
         * Hydrate the model
333
         */
334 8
        $result = new Model\UserAgent();
335 8
        $result->setProviderResultRaw($resultRaw);
336
337
        /*
338
         * Bot detection
339
         */
340 8
        if ($this->isBot($resultRaw) === true) {
341 1
            $this->hydrateBot($result->getBot(), $resultRaw);
342
343 1
            return $result;
344
        }
345
346
        /*
347
         * hydrate the result
348
         */
349 7
        $this->hydrateBrowser($result->getBrowser(), $resultRaw);
350 7
        $this->hydrateRenderingEngine($result->getRenderingEngine(), $resultRaw);
351 7
        $this->hydrateOperatingSystem($result->getOperatingSystem(), $resultRaw);
352 7
        $this->hydrateDevice($result->getDevice(), $resultRaw);
353
354 7
        return $result;
355
    }
356
}
357