Browser::getBrowserInfo()   F
last analyzed

Complexity

Conditions 20
Paths 281

Size

Total Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 20
nc 281
nop 0
dl 0
loc 74
rs 2.3208
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Asymptix\web;
4
5
/**
6
 * Browser detection functionality and other connected tools.
7
 *
8
 * @category Asymptix PHP Framework
9
 * @author Dmytro Zarezenko <[email protected]>
10
 * @copyright (c) 2016, Dmytro Zarezenko
11
 *
12
 * @git https://github.com/Asymptix/Framework
13
 * @license http://opensource.org/licenses/MIT
14
 */
15
class Browser {
16
    /**
17
     * Browser detection RegEx pattern.
18
     *
19
     * @var type
20
     */
21
    private static $pattern;
22
23
    /**
24
     * Returns full browser detection information.
25
     *
26
     * @return array
27
     */
28
    public static function getInfo() {
29
        return [
30
            'browser' => self::getBrowserInfo(),
31
            'platform' => self::getPlatformInfo(),
32
            'user_agent' => self::getUserAgent(),
33
            'pattern' => self::$pattern
34
        ];
35
    }
36
37
    /**
38
     * Returns platform (OS) information.
39
     *
40
     * @return array Array of data or null.
41
     */
42
    public static function getPlatformInfo() {
43
        $platformName = $platformVersion = null;
44
        $userAgent = self::getUserAgent();
45
46
        if (empty($userAgent)) {
47
            return null;
48
        }
49
50
        /*
51
         * Detect platform (operation system)
52
         */
53
        if (preg_match('/linux/i', $userAgent)) {
54
            $platformName = 'linux';
55
        } elseif (preg_match('/macintosh|mac os x/i', $userAgent)) {
56
            $platformName = 'mac';
57
        } elseif (preg_match('/windows|win32/i', $userAgent)) {
58
            $platformName = 'windows';
59
        }
60
        $platformFragment = substr($userAgent, stripos($userAgent, $platformName) + strlen($platformName) + 1);
61
        $platformFragments = explode(";", $platformFragment);
62
        if (isset($platformFragments[0])) {
63
            $platformVersion = $platformFragments[0];
64
        }
65
66
        return [
67
            'name' => $platformName,
68
            'version' => $platformVersion
69
        ];
70
    }
71
72
    /**
73
     * Returns browser information.
74
     *
75
     * @return array Array of data or null.
76
     */
77
    public static function getBrowserInfo() {
78
        $browserFullName = $browserShortName = $browserVersion = null;
79
        $userAgent = self::getUserAgent();
80
81
        if (empty($userAgent)) {
82
            return null;
83
        }
84
85
        // Browser identifiers
86
        $identifiers = ['Version', 'other'];
87
88
        // Detect browser
89
        if (preg_match('/MSIE|Trident/i', $userAgent) && !preg_match('/Opera|OPR/i', $userAgent)) {
90
            $browserFullName  = 'Internet Explorer';
91
            $browserShortName = "MSIE";
92
            $identifiers[] = "Trident";
93
        } elseif (preg_match('/Firefox/i', $userAgent)) {
94
            $browserFullName  = 'Mozilla Firefox';
95
            $browserShortName = "Firefox";
96
        } elseif (preg_match('/Chrome/i', $userAgent) && !preg_match('/Opera|OPR/i', $userAgent)) {
97
            $browserFullName  = 'Google Chrome';
98
            $browserShortName = "Chrome";
99
        } elseif (preg_match('/Safari|AppleWebKit/i', $userAgent) && !preg_match('/Opera|OPR/i', $userAgent)) {
100
            $browserFullName  = 'Apple Safari';
101
            $browserShortName = "Safari";
102
        } elseif (preg_match('/Opera|OPR/i', $userAgent)) {
103
            $browserFullName  = 'Opera';
104
            $browserShortName = "Opera";
105
            $identifiers[] = "OPR";
106
        } elseif (preg_match('/Netscape/i', $userAgent)) {
107
            $browserFullName  = 'Netscape';
108
            $browserShortName = "Netscape";
109
        }
110
111
        /*
112
         * Detect browser version number
113
         */
114
        $identifiers[] = $browserShortName;
115
        self::$pattern = '#(?<browser>' . implode('|', $identifiers) .
0 ignored issues
show
Documentation Bug introduced by
It seems like '#(?<browser>' . implode...sion>[0-9.|a-zA-Z.]*)#' of type string is incompatible with the declared type object<Asymptix\web\type> of property $pattern.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
116
                ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
117
        if (!preg_match_all(self::$pattern, $userAgent, $matches)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
118
            // we have no matching number just continue
119
        }
120
121
        // see how many we have
122
        $chunks = count($matches['browser']);
123
        if ($chunks > 1) { //we will have two since we are not using 'other' argument yet
124
            //see if version is before or after the name
125
            if (strripos($userAgent, "Version") < strripos($userAgent, $browserShortName)
126
              && isset($matches['version'][0])) {
127
                $browserVersion = $matches['version'][0];
128
            } elseif (isset($matches['version'][1])) {
129
                $browserVersion = $matches['version'][1];
130
            }
131
        } elseif (isset($matches['version'][0])) {
132
            $browserVersion = $matches['version'][0];
133
        }
134
135
        // New IE version detection
136
        if (isset($matches['browser'][0]) && $matches['browser'][0] == 'Trident') {
137
            $browserVersion = sprintf("%.1f", (int)$browserVersion + 4);
138
        }
139
140
        // check if we have a number
141
        if (empty($browserVersion)) {
142
            $browserVersion = null;
143
        }
144
145
        return [
146
            'full_name' => $browserFullName,
147
            'short_name' => $browserShortName,
148
            'version' => $browserVersion
149
        ];
150
    }
151
152
    /**
153
     * Returns HTTP User Agent.
154
     *
155
     * @return string
156
     */
157
    public static function getUserAgent() {
0 ignored issues
show
Coding Style introduced by
getUserAgent uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
158
        return isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "";
159
    }
160
161
}
162