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
Pull Request — master (#96)
by Martin
07:37
created

FiftyOneDegreesCom::parse()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 29
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 29
ccs 12
cts 12
cp 1
rs 8.8571
cc 3
eloc 12
nc 2
nop 2
crap 3
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 neutrinoapi.com
12
 *
13
 * @author Martin Keckeis <[email protected]>
14
 * @license MIT
15
 * @see https://51degrees.com
16
 */
17
class FiftyOneDegreesCom extends AbstractHttpProvider
18
{
19
    /**
20
     * Name of the provider
21
     *
22
     * @var string
23
     */
24
    protected $name = 'FiftyOneDegreesCom';
25
26
    /**
27
     * Homepage of the provider
28
     *
29
     * @var string
30
     */
31
    protected $homepage = 'https://51degrees.com';
32
33
    protected $detectionCapabilities = [
34
35
        'browser' => [
36
            'name'    => true,
37
            'version' => true,
38
        ],
39
40
        'renderingEngine' => [
41
            'name'    => true,
42
            'version' => false,
43
        ],
44
45
        'operatingSystem' => [
46
            'name'    => true,
47
            'version' => true,
48
        ],
49
50
        'device' => [
51
            'model'    => true,
52
            'brand'    => true,
53
            'type'     => true,
54
            'isMobile' => true,
55
            'isTouch'  => false,
56
        ],
57
58
        'bot' => [
59
            'isBot' => true,
60
            'name'  => false,
61
            'type'  => false,
62
        ],
63
    ];
64
65
    protected $defaultValues = [
66
        'general' => [
67
            '/^Unknown$/i',
68
        ],
69
    ];
70
71
    private static $uri = 'https://cloud.51degrees.com/api/v1';
72
73
    private $apiKey;
74
75 18
    public function __construct(Client $client, $apiKey)
76
    {
77 18
        parent::__construct($client);
78
79 18
        $this->apiKey = $apiKey;
80 18
    }
81
82
    /**
83
     *
84
     * @param  string                     $userAgent
85
     * @param  array                      $headers
86
     * @return stdClass
87
     * @throws Exception\RequestException
88
     */
89 11
    protected function getResult($userAgent, array $headers)
90
    {
91
        /*
92
         * an empty UserAgent makes no sense
93
         */
94 11
        if ($userAgent == '') {
95 1
            throw new Exception\NoResultFoundException('No result found for user agent: ' . $userAgent);
96
        }
97
98 10
        $headers['User-Agent'] = $userAgent;
99
100 10
        $parameters = '/' . $this->apiKey;
101 10
        $parameters .= '/match?';
102
103 10
        $headerString = [];
104 10
        foreach ($headers as $key => $value) {
105 10
            $headerString[] = $key . '=' . rawurlencode($value);
106
        }
107
108 10
        $parameters .= implode('&', $headerString);
109
110 10
        $uri = self::$uri . $parameters;
111
112 10
        $request = new Request('GET', $uri);
113
114
        try {
115 10
            $response = $this->getResponse($request);
116 2
        } catch (Exception\RequestException $ex) {
117
            /* @var $prevEx \GuzzleHttp\Exception\ClientException */
118 2
            $prevEx = $ex->getPrevious();
119
120 2
            if ($prevEx->hasResponse() === true && $prevEx->getResponse()->getStatusCode() === 403) {
121 1
                throw new Exception\InvalidCredentialsException('Your API key "' . $this->apiKey . '" is not valid for ' . $this->getName(), null, $ex);
122 1
            }
123
124
            throw $ex;
125
        }
126
127
        /*
128 1
         * no json returned?
129
         */
130
        $contentType = $response->getHeader('Content-Type');
131
        if (! isset($contentType[0]) || $contentType[0] != 'application/json; charset=utf-8') {
132
            throw new Exception\RequestException('Could not get valid "application/json; charset=utf-8" response from "' . $request->getUri() . '". Response is "' . $response->getBody()->getContents() . '"');
133
        }
134 8
135 8
        $content = json_decode($response->getBody()->getContents());
136 1
137
        /*
138
         * No result
139 7
         */
140
        if (isset($content->MatchMethod) && $content->MatchMethod == 'None') {
141
            throw new Exception\NoResultFoundException('No result found for user agent: ' . $userAgent);
142
        }
143
144 7
        /*
145 1
         * Missing data?
146
         */
147
        if (! $content instanceof stdClass || ! isset($content->Values)) {
148
            throw new Exception\RequestException('Could not get valid response from "' . $request->getUri() . '". Data is missing "' . $response->getBody()->getContents() . '"');
149
        }
150
151 6
        /*
152 1
         * Convert the values, to something useable
153
         */
154
        $values              = new \stdClass();
155
        $values->MatchMethod = $content->MatchMethod;
156
157
        foreach ($content->Values as $key => $value) {
158 5
            if (is_array($value) && count($value) === 1 && isset($value[0])) {
159 5
                $values->{$key} = $value[0];
160
            }
161 5
        }
162 5
163 5
        foreach ($values as $key => $value) {
0 ignored issues
show
Bug introduced by
The expression $values of type object<stdClass> is not traversable.
Loading history...
164
            if ($value === 'True') {
165
                $values->{$key} = true;
166
            } elseif ($value === 'False') {
167 5
                $values->{$key} = false;
168 5
            }
169 2
        }
170 5
171 5
        return $values;
172
    }
173
174
    /**
175 5
     *
176
     * @param Model\Bot $bot
177
     * @param stdClass  $resultRaw
178
     */
179
    private function hydrateBot(Model\Bot $bot, stdClass $resultRaw)
0 ignored issues
show
Unused Code introduced by
The parameter $resultRaw 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...
180
    {
181
        $bot->setIsBot(true);
182
    }
183 1
184
    /**
185 1
     *
186 1
     * @param Model\Browser $browser
187
     * @param stdClass      $resultRaw
188
     */
189
    private function hydrateBrowser(Model\Browser $browser, stdClass $resultRaw)
190
    {
191
        if (isset($resultRaw->BrowserName)) {
192
            $browser->setName($this->getRealResult($resultRaw->BrowserName));
193 4
        }
194
195 4
        if (isset($resultRaw->BrowserVersion)) {
196 1
            $browser->getVersion()->setComplete($this->getRealResult($resultRaw->BrowserVersion));
197
        }
198
    }
199 4
200 1
    /**
201
     *
202 4
     * @param Model\RenderingEngine $engine
203
     * @param stdClass              $resultRaw
204
     */
205
    private function hydrateRenderingEngine(Model\RenderingEngine $engine, stdClass $resultRaw)
206
    {
207
        if (isset($resultRaw->LayoutEngine)) {
208
            $engine->setName($this->getRealResult($resultRaw->LayoutEngine));
209 4
        }
210
    }
211 4
212 1
    /**
213
     *
214 4
     * @param Model\OperatingSystem $os
215
     * @param stdClass              $resultRaw
216
     */
217
    private function hydrateOperatingSystem(Model\OperatingSystem $os, stdClass $resultRaw)
218
    {
219
        if (isset($resultRaw->PlatformName)) {
220
            $os->setName($this->getRealResult($resultRaw->PlatformName));
221 4
        }
222
223 4
        if (isset($resultRaw->PlatformVersion)) {
224 1
            $os->getVersion()->setComplete($this->getRealResult($resultRaw->PlatformVersion));
225
        }
226
    }
227 4
228 1
    /**
229
     *
230 4
     * @param Model\Device $device
231
     * @param stdClass     $resultRaw
232
     */
233
    private function hydrateDevice(Model\Device $device, stdClass $resultRaw)
234
    {
235
        if (isset($resultRaw->HardwareVendor)) {
236
            $device->setBrand($this->getRealResult($resultRaw->HardwareVendor));
237 4
        }
238
        if (isset($resultRaw->HardwareFamily)) {
239 4
            $device->setModel($this->getRealResult($resultRaw->HardwareFamily));
240 1
        }
241
        if (isset($resultRaw->DeviceType)) {
242 4
            $device->setType($this->getRealResult($resultRaw->DeviceType));
243 1
        }
244
        if (isset($resultRaw->IsMobile)) {
245 4
            $device->setIsMobile($this->getRealResult($resultRaw->IsMobile));
246 1
        }
247
    }
248 4
249 1
    public function parse($userAgent, array $headers = [])
250
    {
251 4
        $resultRaw = $this->getResult($userAgent, $headers);
252
253 11
        /*
254
         * Hydrate the model
255 11
         */
256
        $result = new Model\UserAgent();
257
        $result->setProviderResultRaw($resultRaw);
258
259
        /*
260 5
         * Bot detection
261 5
         */
262
        if (isset($resultRaw->IsCrawler) && $resultRaw->IsCrawler === true) {
263
            $this->hydrateBot($result->getBot(), $resultRaw);
264
265
            return $result;
266 5
        }
267 1
268
        /*
269 1
         * hydrate the result
270
         */
271
        $this->hydrateBrowser($result->getBrowser(), $resultRaw);
272
        $this->hydrateRenderingEngine($result->getRenderingEngine(), $resultRaw);
273
        $this->hydrateOperatingSystem($result->getOperatingSystem(), $resultRaw);
274
        $this->hydrateDevice($result->getDevice(), $resultRaw);
275 4
276 4
        return $result;
277 4
    }
278
}
279