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 ( 192bb3...47c5f3 )
by Martin
06:04
created

PiwikDeviceDetector   B

Complexity

Total Complexity 41

Size/Duplication

Total Lines 298
Duplicated Lines 13.09 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 100%

Importance

Changes 14
Bugs 0 Features 0
Metric Value
wmc 41
c 14
b 0
f 0
lcom 1
cbo 11
dl 39
loc 298
ccs 110
cts 110
cp 1
rs 8.2769

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 8 8 2
A getName() 0 4 1
A getComposerPackageName() 0 4 1
A getParser() 0 10 2
A getResultRaw() 0 50 1
C hasResult() 0 22 7
B hydrateBot() 11 11 5
B hydrateBrowser() 10 10 5
A hydrateRenderingEngine() 0 6 3
B hydrateOperatingSystem() 10 10 5
B hydrateDevice() 0 22 6
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 PiwikDeviceDetector 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 PiwikDeviceDetector, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace UserAgentParser\Provider;
3
4
use DeviceDetector\DeviceDetector;
5
use UserAgentParser\Exception;
6
use UserAgentParser\Model;
7
8
class PiwikDeviceDetector extends AbstractProvider
9
{
10
    protected $detectionCapabilities = [
11
12
        'browser' => [
13
            'name'    => true,
14
            'version' => true,
15
        ],
16
17
        'renderingEngine' => [
18
            'name'    => true,
19
            'version' => false,
20
        ],
21
22
        'operatingSystem' => [
23
            'name'    => true,
24
            'version' => true,
25
        ],
26
27
        'device' => [
28
            'model'    => true,
29
            'brand'    => true,
30
            'type'     => true,
31
            'isMobile' => true,
32
            'isTouch'  => true,
33
        ],
34
35
        'bot' => [
36
            'isBot' => true,
37
            'name'  => true,
38
            'type'  => true,
39
        ],
40
    ];
41
42
    protected $defaultValues = [
43
        DeviceDetector::UNKNOWN,
44
    ];
45
46
    /**
47
     *
48
     * @var DeviceDetector
49
     */
50
    private $parser;
51
52
    /**
53
     * 
54
     * @param  DeviceDetector             $parser
55
     * @throws Exception\PackageNotLoaded
56
     */
57 11 View Code Duplication
    public function __construct(DeviceDetector $parser = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
58
    {
59 11
        if (! class_exists('DeviceDetector\Cache\StaticCache', true)) {
60 1
            throw new Exception\PackageNotLoaded('You need to install ' . $this->getComposerPackageName() . ' to use this provider');
61
        }
62
63 10
        $this->parser = $parser;
64 10
    }
65
66 1
    public function getName()
67
    {
68 1
        return 'PiwikDeviceDetector';
69
    }
70
71 3
    public function getComposerPackageName()
72
    {
73 3
        return 'piwik/device-detector';
74
    }
75
76
    /**
77
     *
78
     * @return DeviceDetector
79
     */
80 6
    public function getParser()
81
    {
82 6
        if ($this->parser !== null) {
83 6
            return $this->parser;
84
        }
85
86 1
        $this->parser = new DeviceDetector();
87
88 1
        return $this->parser;
89
    }
90
91
    /**
92
     *
93
     * @param DeviceDetector $dd
94
     *
95
     * @return array
96
     */
97 4
    private function getResultRaw(DeviceDetector $dd)
98
    {
99
        $raw = [
100 4
            'client'          => $dd->getClient(),
101 4
            'operatingSystem' => $dd->getOs(),
102
103
            'device' => [
104 4
                'brand'     => $dd->getBrand(),
105 4
                'brandName' => $dd->getBrandName(),
106
107 4
                'model' => $dd->getModel(),
108
109 4
                'device'     => $dd->getDevice(),
110 4
                'deviceName' => $dd->getDeviceName(),
111 4
            ],
112
113 4
            'bot' => $dd->getBot(),
114
115
            'extra' => [
116 4
                'isBot' => $dd->isBot(),
117
118
                // client
119 4
                'isBrowser'     => $dd->isBrowser(),
120 4
                'isFeedReader'  => $dd->isFeedReader(),
121 4
                'isMobileApp'   => $dd->isMobileApp(),
122 4
                'isPIM'         => $dd->isPIM(),
123 4
                'isLibrary'     => $dd->isLibrary(),
124 4
                'isMediaPlayer' => $dd->isMediaPlayer(),
125
126
                // deviceType
127 4
                'isCamera'              => $dd->isCamera(),
128 4
                'isCarBrowser'          => $dd->isCarBrowser(),
129 4
                'isConsole'             => $dd->isConsole(),
130 4
                'isFeaturePhone'        => $dd->isFeaturePhone(),
131 4
                'isPhablet'             => $dd->isPhablet(),
132 4
                'isPortableMediaPlayer' => $dd->isPortableMediaPlayer(),
133 4
                'isSmartDisplay'        => $dd->isSmartDisplay(),
134 4
                'isSmartphone'          => $dd->isSmartphone(),
135 4
                'isTablet'              => $dd->isTablet(),
136 4
                'isTV'                  => $dd->isTV(),
137
138
                // other special
139 4
                'isDesktop'      => $dd->isDesktop(),
140 4
                'isMobile'       => $dd->isMobile(),
141 4
                'isTouchEnabled' => $dd->isTouchEnabled(),
142 4
            ],
143 4
        ];
144
145 4
        return $raw;
146
    }
147
148
    /**
149
     *
150
     * @param DeviceDetector $dd
151
     *
152
     * @return bool
153
     */
154 5
    private function hasResult(DeviceDetector $dd)
155
    {
156 5
        if ($dd->isBot() === true) {
157 1
            return true;
158
        }
159
160 4
        $client = $dd->getClient();
161 4
        if (isset($client['name']) && $this->isRealResult($client['name'])) {
162 1
            return true;
163
        }
164
165 3
        $os = $dd->getOs();
166 3
        if (isset($os['name']) && $this->isRealResult($os['name'])) {
167 1
            return true;
168
        }
169
170 2
        if ($dd->getDevice() !== null) {
171 1
            return true;
172
        }
173
174 1
        return false;
175
    }
176
177
    /**
178
     *
179
     * @param Model\Bot     $bot
180
     * @param array|boolean $botRaw
181
     */
182 1 View Code Duplication
    private function hydrateBot(Model\Bot $bot, $botRaw)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
183
    {
184 1
        $bot->setIsBot(true);
185
186 1
        if (isset($botRaw['name']) && $this->isRealResult($botRaw['name'])) {
187 1
            $bot->setName($botRaw['name']);
188
        }
189 1
        if (isset($botRaw['category']) && $this->isRealResult($botRaw['category'])) {
190 1
            $bot->setType($botRaw['category']);
191
        }
192 1
    }
193
194
    /**
195
     *
196
     * @param Model\Browser $browser
197
     * @param array|string  $clientRaw
198
     */
199 3 View Code Duplication
    private function hydrateBrowser(Model\Browser $browser, $clientRaw)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
200
    {
201 3
        if (isset($clientRaw['name']) && $this->isRealResult($clientRaw['name']) === true) {
202 1
            $browser->setName($clientRaw['name']);
203
        }
204
205 3
        if (isset($clientRaw['version']) && $this->isRealResult($clientRaw['version']) === true) {
206 1
            $browser->getVersion()->setComplete($clientRaw['version']);
207
        }
208 3
    }
209
210
    /**
211
     *
212
     * @param Model\RenderingEngine $engine
213
     * @param array|string          $clientRaw
214
     */
215 3
    private function hydrateRenderingEngine(Model\RenderingEngine $engine, $clientRaw)
216
    {
217 3
        if (isset($clientRaw['engine']) && $this->isRealResult($clientRaw['engine']) === true) {
218 1
            $engine->setName($clientRaw['engine']);
219
        }
220 3
    }
221
222
    /**
223
     *
224
     * @param Model\OperatingSystem $os
225
     * @param array|string          $osRaw
226
     */
227 3 View Code Duplication
    private function hydrateOperatingSystem(Model\OperatingSystem $os, $osRaw)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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
    {
229 3
        if (isset($osRaw['name']) && $this->isRealResult($osRaw['name']) === true) {
230 1
            $os->setName($osRaw['name']);
231
        }
232
233 3
        if (isset($osRaw['version']) && $this->isRealResult($osRaw['version']) === true) {
234 1
            $os->getVersion()->setComplete($osRaw['version']);
235
        }
236 3
    }
237
238
    /**
239
     *
240
     * @param Model\UserAgent $device
241
     * @param DeviceDetector  $dd
242
     */
243 3
    private function hydrateDevice(Model\Device $device, DeviceDetector $dd)
244
    {
245 3
        if ($this->isRealResult($dd->getModel()) === true) {
246 1
            $device->setModel($dd->getModel());
247
        }
248
249 3
        if ($this->isRealResult($dd->getBrandName()) === true) {
250 1
            $device->setBrand($dd->getBrandName());
251
        }
252
253 3
        if ($this->isRealResult($dd->getDeviceName()) === true) {
254 1
            $device->setType($dd->getDeviceName());
255
        }
256
257 3
        if ($dd->isMobile() === true) {
258 1
            $device->setIsMobile(true);
259
        }
260
261 3
        if ($dd->isTouchEnabled() === true) {
262 1
            $device->setIsTouch(true);
263
        }
264 3
    }
265
266 5
    public function parse($userAgent, array $headers = [])
267
    {
268 5
        $dd = $this->getParser();
269
270 5
        $dd->setUserAgent($userAgent);
271 5
        $dd->parse();
272
273
        /*
274
         * No result found?
275
         */
276 5
        if ($this->hasResult($dd) !== true) {
277 1
            throw new Exception\NoResultFoundException('No result found for user agent: ' . $userAgent);
278
        }
279
280
        /*
281
         * Hydrate the model
282
         */
283 4
        $result = new Model\UserAgent();
284 4
        $result->setProviderResultRaw($this->getResultRaw($dd));
285
286
        /*
287
         * Bot detection
288
         */
289 4
        if ($dd->isBot() === true) {
290 1
            $this->hydrateBot($result->getBot(), $dd->getBot());
291
292 1
            return $result;
293
        }
294
295
        /*
296
         * hydrate the result
297
         */
298 3
        $this->hydrateBrowser($result->getBrowser(), $dd->getClient());
299 3
        $this->hydrateRenderingEngine($result->getRenderingEngine(), $dd->getClient());
300 3
        $this->hydrateOperatingSystem($result->getOperatingSystem(), $dd->getOs());
301 3
        $this->hydrateDevice($result->getDevice(), $dd);
302
303 3
        return $result;
304
    }
305
}
306