Completed
Push — master ( 32a6a0...7fcda4 )
by Gabriel
03:03
created

OsDetector   D

Complexity

Total Complexity 85

Size/Duplication

Total Lines 496
Duplicated Lines 26.41 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 69.82%

Importance

Changes 8
Bugs 4 Features 3
Metric Value
wmc 85
c 8
b 4
f 3
lcom 1
cbo 2
dl 131
loc 496
ccs 155
cts 222
cp 0.6982
rs 4.8717

19 Methods

Rating   Name   Duplication   Size   Complexity  
D detect() 0 31 17
A checkMobileBrowsers() 0 11 4
B checkIOS() 0 16 5
A checkChromeOs() 0 14 4
A checkOSX() 15 15 4
C checkWindows() 0 68 19
A checkWindowsPhone() 16 16 4
A checkSymbOS() 0 10 2
A checkLinux() 11 11 2
A checkNokia() 12 12 2
B checkBlackBerry() 0 24 4
A checkAndroid() 0 18 4
A checkFreeBSD() 11 11 2
A checkOpenBSD() 11 11 2
A checkSunOS() 11 11 2
A checkNetBSD() 11 11 2
A checkOpenSolaris() 11 11 2
A checkOS2() 11 11 2
A checkBeOS() 11 11 2

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 OsDetector 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 OsDetector, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Sinergi\BrowserDetector;
4
5
class OsDetector implements DetectorInterface
6
{
7
    /**
8
     * Determine the user's operating system.
9
     *
10
     * @param Os $os
11
     * @param UserAgent $userAgent
12
     *
13
     * @return bool
14
     */
15 9
    public static function detect(Os $os, UserAgent $userAgent)
16
    {
17 9
        $os->setName($os::UNKNOWN);
18 9
        $os->setVersion($os::VERSION_UNKNOWN);
19 9
        $os->setIsMobile(false);
20
21 9
        self::checkMobileBrowsers($os, $userAgent);
22
23
        return (
24
            // Chrome OS before OS X
25 9
            self::checkChromeOs($os, $userAgent) ||
26
            // iOS before OS X
27 9
            self::checkIOS($os, $userAgent) ||
28 8
            self::checkOSX($os, $userAgent) ||
29 6
            self::checkSymbOS($os, $userAgent) ||
30 6
            self::checkWindows($os, $userAgent) ||
31 4
            self::checkWindowsPhone($os, $userAgent) ||
32 3
            self::checkFreeBSD($os, $userAgent) ||
33 3
            self::checkOpenBSD($os, $userAgent) ||
34 3
            self::checkNetBSD($os, $userAgent) ||
35 3
            self::checkOpenSolaris($os, $userAgent) ||
36 3
            self::checkSunOS($os, $userAgent) ||
37 3
            self::checkOS2($os, $userAgent) ||
38 3
            self::checkBeOS($os, $userAgent) ||
39
            // Android before Linux
40 3
            self::checkAndroid($os, $userAgent) ||
41 3
            self::checkLinux($os, $userAgent) ||
42 3
            self::checkNokia($os, $userAgent) ||
43 3
            self::checkBlackBerry($os, $userAgent)
44 9
        );
45
    }
46
47
    /**
48
     * Determine if the user's browser is on a mobile device.
49
     *
50
     * @param Os $os
51
     * @param UserAgent $userAgent
52
     *
53
     * @return bool
54
     */
55 9
    public static function checkMobileBrowsers(Os $os, UserAgent $userAgent)
56
    {
57
        // Check for Opera Mini
58 9
        if (stripos($userAgent->getUserAgentString(), 'opera mini') !== false) {
59
            $os->setIsMobile(true);
60
        } // Set is mobile for Pocket IE
61 9
        elseif (stripos($userAgent->getUserAgentString(), 'mspie') !== false ||
62 9
            stripos($userAgent->getUserAgentString(), 'pocket') !== false) {
63
            $os->setIsMobile(true);
64
        }
65 9
    }
66
67
    /**
68
     * Determine if the user's operating system is iOS.
69
     *
70
     * @param Os $os
71
     * @param UserAgent $userAgent
72
     *
73
     * @return bool
74
     */
75 9
    private static function checkIOS(Os $os, UserAgent $userAgent)
76
    {
77 9
        if (stripos($userAgent->getUserAgentString(), 'CPU OS') !== false ||
78 8
            stripos($userAgent->getUserAgentString(), 'iPhone OS') !== false &&
79 9
            stripos($userAgent->getUserAgentString(), 'OS X')) {
80 3
            $os->setName($os::IOS);
81 3
            if (preg_match('/CPU( iPhone)? OS ([\d_]*)/i', $userAgent->getUserAgentString(), $matches)) {
82 3
                $os->setVersion(str_replace('_', '.', $matches[2]));
83 3
            }
84 3
            $os->setIsMobile(true);
85
86 3
            return true;
87
        }
88
89 8
        return false;
90
    }
91
92
    /**
93
     * Determine if the user's operating system is Chrome OS.
94
     *
95
     * @param Os $os
96
     * @param UserAgent $userAgent
97
     *
98
     * @return bool
99
     */
100 9
    private static function checkChromeOs(Os $os, UserAgent $userAgent)
101
    {
102 9
        if (stripos($userAgent->getUserAgentString(), ' CrOS') !== false ||
103 9
            stripos($userAgent->getUserAgentString(), 'CrOS ') !== false
104 9
        ) {
105 1
            $os->setName($os::CHROME_OS);
106 1
            if (preg_match('/Chrome\/([\d\.]*)/i', $userAgent->getUserAgentString(), $matches)) {
107 1
                $os->setVersion($matches[1]);
108 1
            }
109 1
            return true;
110
        }
111
112 9
        return false;
113
    }
114
115
    /**
116
     * Determine if the user's operating system is OS X.
117
     *
118
     * @param Os $os
119
     * @param UserAgent $userAgent
120
     *
121
     * @return bool
122
     */
123 8 View Code Duplication
    private static function checkOSX(Os $os, UserAgent $userAgent)
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...
124
    {
125 8
        if (stripos($userAgent->getUserAgentString(), 'OS X') !== false) {
126 3
            $os->setName($os::OSX);
127 3
            if (preg_match('/OS X ([\d\._]*)/i', $userAgent->getUserAgentString(), $matches)) {
128 3
                if (isset($matches[1])) {
129 3
                    $os->setVersion(str_replace('_', '.', $matches[1]));
130 3
                }
131 3
            }
132
133 3
            return true;
134
        }
135
136 6
        return false;
137
    }
138
139
    /**
140
     * Determine if the user's operating system is Windows.
141
     *
142
     * @param Os $os
143
     * @param UserAgent $userAgent
144
     *
145
     * @return bool
146
     */
147 6
    private static function checkWindows(Os $os, UserAgent $userAgent)
148
    {
149 6
        if (stripos($userAgent->getUserAgentString(), 'Windows NT') !== false) {
150 3
            $os->setName($os::WINDOWS);
151
            // Windows version
152 3
            if (preg_match('/Windows NT ([\d\.]*)/i', $userAgent->getUserAgentString(), $matches)) {
153 3
                if (isset($matches[1])) {
154 3
                    switch (str_replace('_', '.', $matches[1])) {
155 3
                        case '6.3':
156
                            $os->setVersion('8.1');
157
                            break;
158 3
                        case '6.2':
159 1
                            $os->setVersion('8');
160 1
                            break;
161 3
                        case '6.1':
162 3
                            $os->setVersion('7');
163 3
                            break;
164 1
                        case '6.0':
165
                            $os->setVersion('Vista');
166
                            break;
167 1
                        case '5.2':
168 1
                        case '5.1':
169
                            $os->setVersion('XP');
170
                            break;
171 1
                        case '5.01':
172 1
                        case '5.0':
173
                            $os->setVersion('2000');
174
                            break;
175 1
                        case '4.0':
176
                            $os->setVersion('NT 4.0');
177
                            break;
178 1
                        default:
179 1
                            if ((float)$matches[1] >= 10.0) {
180 1
                                $os->setVersion($matches[1]);
181 1
                            }
182 1
                            break;
183 3
                    }
184 3
                }
185 3
            }
186
187 3
            return true;
188
        } // Windows Me, Windows 98, Windows 95, Windows CE
189 4
        elseif (preg_match(
190 4
            '/(Windows 98; Win 9x 4\.90|Windows 98|Windows 95|Windows CE)/i',
191 4
            $userAgent->getUserAgentString(),
192
            $matches
193 4
        )) {
194
            $os->setName($os::WINDOWS);
195
            switch (strtolower($matches[0])) {
196
                case 'windows 98; win 9x 4.90':
197
                    $os->setVersion('Me');
198
                    break;
199
                case 'windows 98':
200
                    $os->setVersion('98');
201
                    break;
202
                case 'windows 95':
203
                    $os->setVersion('95');
204
                    break;
205
                case 'windows ce':
206
                    $os->setVersion('CE');
207
                    break;
208
            }
209
210
            return true;
211
        }
212
213 4
        return false;
214
    }
215
    
216
    /**
217
     * Determine if the user's operating system is Windows Phone.
218
     *
219
     * @param Os $os
220
     * @param UserAgent $userAgent
221
     *
222
     * @return bool
223
     */
224 4 View Code Duplication
    private static function checkWindowsPhone(Os $os, UserAgent $userAgent)
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...
225
    {
226 4
        if (stripos($userAgent->getUserAgentString(), 'Windows Phone') !== false) {
227 2
            $os->setIsMobile(true);
228 2
            $os->setName($os::WINDOWS_PHONE);
229
            // Windows version
230 2
            if (preg_match('/Windows Phone ([\d\.]*)/i', $userAgent->getUserAgentString(), $matches)) {
231 2
                if (isset($matches[1])) {
232 2
                    $os->setVersion((float)$matches[1]);
233 2
                }
234 2
            }
235
    
236 2
            return true;
237
        }
238 3
        return false;
239
    }
240
241
    /**
242
     * Determine if the user's operating system is SymbOS.
243
     *
244
     * @param Os $os
245
     * @param UserAgent $userAgent
246
     *
247
     * @return bool
248
     */
249 6
    private static function checkSymbOS(Os $os, UserAgent $userAgent)
250
    {
251 6
        if (stripos($userAgent->getUserAgentString(), 'SymbOS') !== false) {
252
            $os->setName($os::SYMBOS);
253
254
            return true;
255
        }
256
257 6
        return false;
258
    }
259
260
    /**
261
     * Determine if the user's operating system is Linux.
262
     *
263
     * @param Os $os
264
     * @param UserAgent $userAgent
265
     *
266
     * @return bool
267
     */
268 3 View Code Duplication
    private static function checkLinux(Os $os, UserAgent $userAgent)
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...
269
    {
270 3
        if (stripos($userAgent->getUserAgentString(), 'Linux') !== false) {
271 1
            $os->setVersion($os::VERSION_UNKNOWN);
272 1
            $os->setName($os::LINUX);
273
274 1
            return true;
275
        }
276
277 3
        return false;
278
    }
279
280
    /**
281
     * Determine if the user's operating system is Nokia.
282
     *
283
     * @param Os $os
284
     * @param UserAgent $userAgent
285
     *
286
     * @return bool
287
     */
288 3 View Code Duplication
    private static function checkNokia(Os $os, UserAgent $userAgent)
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...
289
    {
290 3
        if (stripos($userAgent->getUserAgentString(), 'Nokia') !== false) {
291
            $os->setVersion($os::VERSION_UNKNOWN);
292
            $os->setName($os::NOKIA);
293
            $os->setIsMobile(true);
294
295
            return true;
296
        }
297
298 3
        return false;
299
    }
300
301
    /**
302
     * Determine if the user's operating system is BlackBerry.
303
     *
304
     * @param Os $os
305
     * @param UserAgent $userAgent
306
     *
307
     * @return bool
308
     */
309 3
    private static function checkBlackBerry(Os $os, UserAgent $userAgent)
310
    {
311 3
        if (stripos($userAgent->getUserAgentString(), 'BlackBerry') !== false) {
312 1
            $os->setVersion($os::VERSION_UNKNOWN);
313 1
            $os->setName($os::BLACKBERRY);
314 1
            $os->setIsMobile(true);
315
316 1
            return true;
317 2
        } elseif (stripos($userAgent->getUserAgentString(), 'BB10') !== false) {
318 1
            $aresult = explode('Version/10.', $userAgent->getUserAgentString());
319 1
            if (isset($aresult[1])) {
320 1
                $aversion = explode(' ', $aresult[1]);
321 1
                $os->setVersion('10.' . $aversion[0]);
322 1
            } else {
323
                $os->setVersion('10');
324
            }
325 1
            $os->setName($os::BLACKBERRY);
326 1
            $os->setIsMobile(true);
327
328 1
            return true;
329
        }
330
331 1
        return false;
332
    }
333
334
    /**
335
     * Determine if the user's operating system is Android.
336
     *
337
     * @param Os $os
338
     * @param UserAgent $userAgent
339
     *
340
     * @return bool
341
     */
342 3
    private static function checkAndroid(Os $os, UserAgent $userAgent)
343
    {
344 3
        if (stripos($userAgent->getUserAgentString(), 'Android') !== false) {
345
            if (preg_match('/Android ([\d\.]*)/i', $userAgent->getUserAgentString(), $matches)) {
346
                if (isset($matches[1])) {
347
                    $os->setVersion($matches[1]);
348
                }
349
            } else {
350
                $os->setVersion($os::VERSION_UNKNOWN);
351
            }
352
            $os->setName($os::ANDROID);
353
            $os->setIsMobile(true);
354
355
            return true;
356
        }
357
358 3
        return false;
359
    }
360
361
    /**
362
     * Determine if the user's operating system is FreeBSD.
363
     *
364
     * @param Os $os
365
     * @param UserAgent $userAgent
366
     *
367
     * @return bool
368
     */
369 3 View Code Duplication
    private static function checkFreeBSD(Os $os, UserAgent $userAgent)
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...
370
    {
371 3
        if (stripos($userAgent->getUserAgentString(), 'FreeBSD') !== false) {
372
            $os->setVersion($os::VERSION_UNKNOWN);
373
            $os->setName($os::FREEBSD);
374
375
            return true;
376
        }
377
378 3
        return false;
379
    }
380
381
    /**
382
     * Determine if the user's operating system is OpenBSD.
383
     *
384
     * @param Os $os
385
     * @param UserAgent $userAgent
386
     *
387
     * @return bool
388
     */
389 3 View Code Duplication
    private static function checkOpenBSD(Os $os, UserAgent $userAgent)
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...
390
    {
391 3
        if (stripos($userAgent->getUserAgentString(), 'OpenBSD') !== false) {
392
            $os->setVersion($os::VERSION_UNKNOWN);
393
            $os->setName($os::OPENBSD);
394
395
            return true;
396
        }
397
398 3
        return false;
399
    }
400
401
    /**
402
     * Determine if the user's operating system is SunOS.
403
     *
404
     * @param Os $os
405
     * @param UserAgent $userAgent
406
     *
407
     * @return bool
408
     */
409 3 View Code Duplication
    private static function checkSunOS(Os $os, UserAgent $userAgent)
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...
410
    {
411 3
        if (stripos($userAgent->getUserAgentString(), 'SunOS') !== false) {
412
            $os->setVersion($os::VERSION_UNKNOWN);
413
            $os->setName($os::SUNOS);
414
415
            return true;
416
        }
417
418 3
        return false;
419
    }
420
421
    /**
422
     * Determine if the user's operating system is NetBSD.
423
     *
424
     * @param Os $os
425
     * @param UserAgent $userAgent
426
     *
427
     * @return bool
428
     */
429 3 View Code Duplication
    private static function checkNetBSD(Os $os, UserAgent $userAgent)
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...
430
    {
431 3
        if (stripos($userAgent->getUserAgentString(), 'NetBSD') !== false) {
432
            $os->setVersion($os::VERSION_UNKNOWN);
433
            $os->setName($os::NETBSD);
434
435
            return true;
436
        }
437
438 3
        return false;
439
    }
440
441
    /**
442
     * Determine if the user's operating system is OpenSolaris.
443
     *
444
     * @param Os $os
445
     * @param UserAgent $userAgent
446
     *
447
     * @return bool
448
     */
449 3 View Code Duplication
    private static function checkOpenSolaris(Os $os, UserAgent $userAgent)
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...
450
    {
451 3
        if (stripos($userAgent->getUserAgentString(), 'OpenSolaris') !== false) {
452
            $os->setVersion($os::VERSION_UNKNOWN);
453
            $os->setName($os::OPENSOLARIS);
454
455
            return true;
456
        }
457
458 3
        return false;
459
    }
460
461
    /**
462
     * Determine if the user's operating system is OS2.
463
     *
464
     * @param Os $os
465
     * @param UserAgent $userAgent
466
     *
467
     * @return bool
468
     */
469 3 View Code Duplication
    private static function checkOS2(Os $os, UserAgent $userAgent)
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...
470
    {
471 3
        if (stripos($userAgent->getUserAgentString(), 'OS\/2') !== false) {
472
            $os->setVersion($os::VERSION_UNKNOWN);
473
            $os->setName($os::OS2);
474
475
            return true;
476
        }
477
478 3
        return false;
479
    }
480
481
    /**
482
     * Determine if the user's operating system is BeOS.
483
     *
484
     * @param Os $os
485
     * @param UserAgent $userAgent
486
     *
487
     * @return bool
488
     */
489 3 View Code Duplication
    private static function checkBeOS(Os $os, UserAgent $userAgent)
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...
490
    {
491 3
        if (stripos($userAgent->getUserAgentString(), 'BeOS') !== false) {
492
            $os->setVersion($os::VERSION_UNKNOWN);
493
            $os->setName($os::BEOS);
494
495
            return true;
496
        }
497
498 3
        return false;
499
    }
500
}
501