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 (#93)
by Martin
05:08
created

FiftyOneDegreesCom::parse()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 29
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 29
ccs 10
cts 10
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
            } elseif($prevEx->hasResponse() !== true){
123
                var_dump($prevEx->__toString());
0 ignored issues
show
Security Debugging Code introduced by
var_dump($prevEx->__toString()); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
124 1
                var_dump($ex->__toString());
125
                exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method getResult() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
126
            }
127
128
            throw $ex;
129
        }
130 8
131 8
        /*
132 1
         * no json returned?
133
         */
134
        $contentType = $response->getHeader('Content-Type');
135 7
        if (! isset($contentType[0]) || $contentType[0] != 'application/json; charset=utf-8') {
136
            throw new Exception\RequestException('Could not get valid "application/json; charset=utf-8" response from "' . $request->getUri() . '". Response is "' . $response->getBody()->getContents() . '"');
137
        }
138
139
        $content = json_decode($response->getBody()->getContents());
140 7
141 1
        /*
142
         * No result
143
         */
144
        if (isset($content->MatchMethod) && $content->MatchMethod == 'None') {
145
            throw new Exception\NoResultFoundException('No result found for user agent: ' . $userAgent);
146
        }
147 6
148 1
        /*
149
         * Missing data?
150
         */
151
        if (! $content instanceof stdClass || ! isset($content->Values)) {
152
            throw new Exception\RequestException('Could not get valid response from "' . $request->getUri() . '". Data is missing "' . $response->getBody()->getContents() . '"');
153
        }
154 5
155 5
        /*
156
         * Convert the values, to something useable
157 5
         */
158 5
        $values              = new \stdClass();
159 5
        $values->MatchMethod = $content->MatchMethod;
160
161
        foreach ($content->Values as $key => $value) {
162
            if (is_array($value) && count($value) === 1 && isset($value[0])) {
163 5
                $values->{$key} = $value[0];
164 5
            }
165 2
        }
166 5
167 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...
168
            if ($value === 'True') {
169
                $values->{$key} = true;
170
            } elseif ($value === 'False') {
171 5
                $values->{$key} = false;
172
            }
173
        }
174
175
        return $values;
176
    }
177
178
    /**
179 1
     *
180
     * @param Model\Bot $bot
181 1
     * @param stdClass  $resultRaw
182 1
     */
183
    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...
184
    {
185
        $bot->setIsBot(true);
186
    }
187
188
    /**
189 4
     *
190
     * @param Model\Browser $browser
191 4
     * @param stdClass      $resultRaw
192 1
     */
193
    private function hydrateBrowser(Model\Browser $browser, stdClass $resultRaw)
194
    {
195 4
        if (isset($resultRaw->BrowserName)) {
196 1
            $browser->setName($this->getRealResult($resultRaw->BrowserName));
197
        }
198 4
199
        if (isset($resultRaw->BrowserVersion)) {
200
            $browser->getVersion()->setComplete($this->getRealResult($resultRaw->BrowserVersion));
201
        }
202
    }
203
204
    /**
205 4
     *
206
     * @param Model\RenderingEngine $engine
207 4
     * @param stdClass              $resultRaw
208 1
     */
209
    private function hydrateRenderingEngine(Model\RenderingEngine $engine, stdClass $resultRaw)
210 4
    {
211
        if (isset($resultRaw->LayoutEngine)) {
212
            $engine->setName($this->getRealResult($resultRaw->LayoutEngine));
213
        }
214
    }
215
216
    /**
217 4
     *
218
     * @param Model\OperatingSystem $os
219 4
     * @param stdClass              $resultRaw
220 1
     */
221
    private function hydrateOperatingSystem(Model\OperatingSystem $os, stdClass $resultRaw)
222
    {
223 4
        if (isset($resultRaw->PlatformName)) {
224 1
            $os->setName($this->getRealResult($resultRaw->PlatformName));
225
        }
226 4
227
        if (isset($resultRaw->PlatformVersion)) {
228
            $os->getVersion()->setComplete($this->getRealResult($resultRaw->PlatformVersion));
229
        }
230
    }
231
232
    /**
233 4
     *
234
     * @param Model\Device $device
235 4
     * @param stdClass     $resultRaw
236 1
     */
237
    private function hydrateDevice(Model\Device $device, stdClass $resultRaw)
238 4
    {
239 1
        if (isset($resultRaw->HardwareVendor)) {
240
            $device->setBrand($this->getRealResult($resultRaw->HardwareVendor));
241 4
        }
242 1
        if (isset($resultRaw->HardwareFamily)) {
243
            $device->setModel($this->getRealResult($resultRaw->HardwareFamily));
244 4
        }
245 1
        if (isset($resultRaw->DeviceType)) {
246
            $device->setType($this->getRealResult($resultRaw->DeviceType));
247 4
        }
248
        if (isset($resultRaw->IsMobile)) {
249 11
            $device->setIsMobile($this->getRealResult($resultRaw->IsMobile));
250
        }
251 11
    }
252
253
    public function parse($userAgent, array $headers = [])
254
    {
255
        $resultRaw = $this->getResult($userAgent, $headers);
256 5
257 5
        /*
258
         * Hydrate the model
259
         */
260
        $result = new Model\UserAgent();
261
        $result->setProviderResultRaw($resultRaw);
262 5
263 1
        /*
264
         * Bot detection
265 1
         */
266
        if (isset($resultRaw->IsCrawler) && $resultRaw->IsCrawler === true) {
267
            $this->hydrateBot($result->getBot(), $resultRaw);
268
269
            return $result;
270
        }
271 4
272 4
        /*
273 4
         * hydrate the result
274 4
         */
275
        $this->hydrateBrowser($result->getBrowser(), $resultRaw);
276 4
        $this->hydrateRenderingEngine($result->getRenderingEngine(), $resultRaw);
277
        $this->hydrateOperatingSystem($result->getOperatingSystem(), $resultRaw);
278
        $this->hydrateDevice($result->getDevice(), $resultRaw);
279
280
        return $result;
281
    }
282
}
283