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 (#59)
by Martin
02:47
created

BrowscapPhp   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 272
Duplicated Lines 3.68 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 100%

Importance

Changes 14
Bugs 0 Features 1
Metric Value
wmc 47
c 14
b 0
f 1
lcom 1
cbo 11
dl 10
loc 272
ccs 91
cts 91
cp 1
rs 8.439

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getVersion() 0 6 1
A getUpdateDate() 0 4 1
A getParser() 0 4 1
A hasResult() 0 12 3
A isBot() 0 8 3
B hydrateBot() 0 14 7
B hydrateBrowser() 0 10 5
B hydrateRenderingEngine() 3 10 5
B hydrateOperatingSystem() 0 10 5
C hydrateDevice() 7 23 12
B parse() 0 39 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like BrowscapPhp 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 BrowscapPhp, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace UserAgentParser\Provider;
3
4
use BrowscapPHP\Browscap;
5
use stdClass;
6
use UserAgentParser\Exception\NoResultFoundException;
7
use UserAgentParser\Model;
8
9
class BrowscapPhp extends AbstractProvider
10
{
11
    /**
12
     * Name of the provider
13
     *
14
     * @var string
15
     */
16
    protected $name = 'BrowscapPhp';
17
18
    /**
19
     * Homepage of the provider
20
     *
21
     * @var string
22
     */
23
    protected $homepage = 'https://github.com/browscap/browscap-php';
24
25
    /**
26
     * Composer package name
27
     *
28
     * @var string
29
     */
30
    protected $packageName = 'browscap/browscap-php';
31
32
    protected $detectionCapabilities = [
33
34
        'browser' => [
35
            'name'    => true,
36
            'version' => true,
37
        ],
38
39
        'renderingEngine' => [
40
            'name'    => true,
41
            'version' => true,
42
        ],
43
44
        'operatingSystem' => [
45
            'name'    => true,
46
            'version' => true,
47
        ],
48
49
        'device' => [
50
            'model'    => true,
51
            'brand'    => true,
52
            'type'     => true,
53
            'isMobile' => true,
54
            'isTouch'  => true,
55
        ],
56
57
        'bot' => [
58
            'isBot' => true,
59
            'name'  => true,
60
            'type'  => true,
61
        ],
62
    ];
63
64
    protected $defaultValues = [
65
        'general' => [
66
            '/^DefaultProperties$/i',
67
            '/^Default Browser$/i',
68
69
            '/^unknown$/i',
70
        ],
71
72
        'device' => [
73
            'model' => [
74
                '/^general/i'
75
            ],
76
        ],
77 17
    ];
78
79 17
    /**
80 17
     *
81
     * @var Browscap
82 1
     */
83
    private $parser;
84 1
85 1
    public function __construct(Browscap $parser)
86 1
    {
87
        $this->parser = $parser;
88
    }
89 1
90
    public function getVersion()
91 1
    {
92
        return $this->getParser()
93
            ->getCache()
94
            ->getVersion();
95
    }
96
97
    public function getUpdateDate()
98 12
    {
99
        return;
100 12
    }
101
102
    /**
103
     *
104
     * @return Browscap
105
     */
106
    public function getParser()
107 1
    {
108
        return $this->parser;
109
    }
110 1
111 1
    /**
112 1
     *
113 1
     * @param stdClass $resultRaw
114 1
     *
115
     * @return bool
116
     */
117
    private function hasResult(stdClass $resultRaw)
118
    {
119
        if (! isset($resultRaw->browser)) {
120
            return false;
121
        }
122
123 10
        if ($this->isRealResult($resultRaw->browser) !== true) {
124
            return false;
125 10
        }
126 1
127
        return true;
128
    }
129 9
130 4
    /**
131
     *
132
     * @param  stdClass $resultRaw
133 5
     * @return boolean
134
     */
135
    private function isBot(stdClass $resultRaw)
136
    {
137
        if (! isset($resultRaw->crawler) || $resultRaw->crawler !== true) {
138
            return false;
139
        }
140
141 5
        return true;
142
    }
143 5
144 2
    /**
145
     *
146
     * @param Model\Bot $bot
147 3
     * @param stdClass  $resultRaw
148
     */
149
    private function hydrateBot(Model\Bot $bot, stdClass $resultRaw)
150
    {
151
        $bot->setIsBot(true);
152
153
        if (isset($resultRaw->browser) && $this->isRealResult($resultRaw->browser) === true) {
154
            $bot->setName($resultRaw->browser);
155 3
        }
156
157 3
        if (isset($resultRaw->issyndicationreader) && $resultRaw->issyndicationreader === true) {
158
            $bot->setType('RSS');
159 3
        } elseif (isset($resultRaw->browser_type) && $this->isRealResult($resultRaw->browser_type) === true) {
160 3
            $bot->setType($resultRaw->browser_type);
161 3
        }
162
    }
163 3
164 1
    /**
165 3
     *
166 2
     * @param Model\Browser $browser
167 2
     * @param stdClass      $resultRaw
168 3
     */
169
    private function hydrateBrowser(Model\Browser $browser, stdClass $resultRaw)
170
    {
171
        if (isset($resultRaw->browser) && $this->isRealResult($resultRaw->browser) === true) {
172
            $browser->setName($resultRaw->browser);
173
        }
174
175 2
        if (isset($resultRaw->version) && $this->isRealResult($resultRaw->version) === true) {
176
            $browser->getVersion()->setComplete($resultRaw->version);
177 2
        }
178 2
    }
179 2
180
    /**
181 2
     *
182 2
     * @param Model\RenderingEngine $engine
183 2
     * @param stdClass              $resultRaw
184 2
     */
185
    private function hydrateRenderingEngine(Model\RenderingEngine $engine, stdClass $resultRaw)
186
    {
187 View Code Duplication
        if (isset($resultRaw->renderingengine_name) && $this->isRealResult($resultRaw->renderingengine_name) === true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
188
            $engine->setName($resultRaw->renderingengine_name);
189
        }
190
191 2
        if (isset($resultRaw->renderingengine_version) && $this->isRealResult($resultRaw->renderingengine_version) === true) {
192
            $engine->getVersion()->setComplete($resultRaw->renderingengine_version);
193 2
        }
194 1
    }
195 1
196
    /**
197 2
     *
198 1
     * @param Model\OperatingSystem $os
199 1
     * @param stdClass              $resultRaw
200 2
     */
201
    private function hydrateOperatingSystem(Model\OperatingSystem $os, stdClass $resultRaw)
202
    {
203
        if (isset($resultRaw->platform) && $this->isRealResult($resultRaw->platform) === true) {
204
            $os->setName($resultRaw->platform);
205
        }
206
207 2
        if (isset($resultRaw->platform_version) && $this->isRealResult($resultRaw->platform_version) === true) {
208
            $os->getVersion()->setComplete($resultRaw->platform_version);
209 2
        }
210 1
    }
211 1
212
    /**
213 2
     *
214 1
     * @param Model\UserAgent $device
215 1
     * @param stdClass        $resultRaw
216 2
     */
217
    private function hydrateDevice(Model\Device $device, stdClass $resultRaw)
218
    {
219
        if (isset($resultRaw->device_name) && $this->isRealResult($resultRaw->device_name, 'device', 'model') === true) {
220
            $device->setModel($resultRaw->device_name);
221
        }
222
223 2 View Code Duplication
        if (isset($resultRaw->device_brand_name) && $this->isRealResult($resultRaw->device_brand_name) === true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
224
            $device->setBrand($resultRaw->device_brand_name);
225 2
        }
226 1
227 1 View Code Duplication
        if (isset($resultRaw->device_type) && $this->isRealResult($resultRaw->device_type) === true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
228
            // @todo convert to a common set of types (over all vendors)
229 2
            $device->setType($resultRaw->device_type);
230 1
        }
231 1
232
        if (isset($resultRaw->ismobiledevice) && $this->isRealResult($resultRaw->ismobiledevice) === true && $resultRaw->ismobiledevice === true) {
233 2
            $device->setIsMobile(true);
234
        }
235 1
236 1
        if (isset($resultRaw->device_pointing_method) && $resultRaw->device_pointing_method == 'touchscreen') {
237
            $device->setIsTouch(true);
238 2
        }
239 1
    }
240 1
241
    public function parse($userAgent, array $headers = [])
242 2
    {
243 1
        $parser = $this->getParser();
244 1
245 2
        /* @var $resultRaw \stdClass */
246
        $resultRaw = $parser->getBrowser($userAgent);
247 10
248
        /*
249 10
         * No result found?
250
         */
251
        if ($this->hasResult($resultRaw) !== true) {
252 10
            throw new NoResultFoundException('No result found for user agent: ' . $userAgent);
253
        }
254
255
        /*
256
         * Hydrate the model
257 10
         */
258 5
        $result = new Model\UserAgent();
259
        $result->setProviderResultRaw($resultRaw);
260
261
        /*
262
         * Bot detection (does only work with full_php_browscap.ini)
263
         */
264 5
        if ($this->isBot($resultRaw) === true) {
265 5
            $this->hydrateBot($result->getBot(), $resultRaw);
266
267
            return $result;
268
        }
269
270 5
        /*
271 3
         * hydrate the result
272
         */
273 3
        $this->hydrateBrowser($result->getBrowser(), $resultRaw);
274
        $this->hydrateRenderingEngine($result->getRenderingEngine(), $resultRaw);
275
        $this->hydrateOperatingSystem($result->getOperatingSystem(), $resultRaw);
276
        $this->hydrateDevice($result->getDevice(), $resultRaw);
277
278
        return $result;
279 2
    }
280
}
281