Test Failed
Pull Request — master (#85)
by Gabriel
02:58
created

Browser::detectScriptedAgent()   C

Complexity

Conditions 40
Paths 3

Size

Total Lines 50
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 1640

Importance

Changes 0
Metric Value
dl 0
loc 50
rs 5.1666
c 0
b 0
f 0
ccs 0
cts 14
cp 0
cc 40
eloc 45
nc 3
nop 0
crap 1640

How to fix   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 Sinergi\BrowserDetector;
4
5
class Browser
6
{
7
    const UNKNOWN = 'unknown';
8
    const VIVALDI = 'Vivaldi';
9
    const OPERA = 'Opera';
10
    const OPERA_MINI = 'Opera Mini';
11
    const WEBTV = 'WebTV';
12
    const IE = 'Internet Explorer';
13
    const POCKET_IE = 'Pocket Internet Explorer';
14
    const KONQUEROR = 'Konqueror';
15
    const ICAB = 'iCab';
16
    const OMNIWEB = 'OmniWeb';
17
    const FIREBIRD = 'Firebird';
18
    const FIREFOX = 'Firefox';
19
    const SEAMONKEY = 'SeaMonkey';
20
    const ICEWEASEL = 'Iceweasel';
21
    const SHIRETOKO = 'Shiretoko';
22
    const MOZILLA = 'Mozilla';
23
    const AMAYA = 'Amaya';
24
    const LYNX = 'Lynx';
25
    const SAFARI = 'Safari';
26
    const SAMSUNG_BROWSER = 'SamsungBrowser';
27
    const CHROME = 'Chrome';
28
    const NAVIGATOR = 'Android Navigator';
29
    const BLACKBERRY = 'BlackBerry';
30
    const ICECAT = 'IceCat';
31
    const NOKIA_S60 = 'Nokia S60 OSS Browser';
32
    const NOKIA = 'Nokia Browser';
33
    const MSN = 'MSN Browser';
34
    const NETSCAPE_NAVIGATOR = 'Netscape Navigator';
35
    const GALEON = 'Galeon';
36
    const NETPOSITIVE = 'NetPositive';
37
    const PHOENIX = 'Phoenix';
38
    const GSA = 'Google Search Appliance';
39
    const YANDEX = 'Yandex';
40
    const EDGE = 'Edge';
41
    const EDGE_HTML = 'EdgeHTML';
42
    const DRAGON = 'Dragon';
43
    const NSPLAYER = 'Windows Media Player';
44
    const UCBROWSER = 'UC Browser';
45
    const MICROSOFT_OFFICE = 'Microsoft Office';
46
    const APPLE_NEWS = 'Apple News';
47
    const DALVIK = 'Android';
48
49
    const VERSION_UNKNOWN = 'unknown';
50
51
    /**
52
     * @var UserAgent
53
     */
54
    private $userAgent;
55
56
    /**
57
     * @var string
58
     */
59
    private $name;
60
    /**
61
     * @var string
62
     */
63
    private $version;
64
65
    /**
66
     * @var bool
67
     */
68
    private $isChromeFrame = false;
69
70
    /**
71
     * @var bool
72
     */
73
    private $isWebkit = false;
74
75
    /**
76
     * @var bool
77
     */
78
    private $isFacebookWebView = false;
79
80
    /**
81
     * @var bool
82
     */
83
    private $isTwitterWebView = false;
84
85
    /**
86
     * @var bool
87
     */
88
    private $isCompatibilityMode = false;
89
90
    /**
91
     * @param null|string|UserAgent $userAgent
92 8
     * @throws \Sinergi\BrowserDetector\InvalidArgumentException
93
     */
94 8 View Code Duplication
    public function __construct($userAgent = 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...
95
    {
96 8
        if ($userAgent instanceof UserAgent) {
97 8
            $this->setUserAgent($userAgent);
98 8
        } elseif (null === $userAgent || is_string($userAgent)) {
99
            $this->setUserAgent(new UserAgent($userAgent));
100
        } else {
101 8
            throw new InvalidArgumentException();
102
        }
103
    }
104
105
    /**
106
     * Set the name of the Browser.
107
     *
108
     * @param string $name
109
     * @return $this
110 8
     */
111
    public function setName($name)
112 8
    {
113
        $this->name = (string)$name;
114 8
        return $this;
115
    }
116
117
    /**
118
     * Return the name of the Browser.
119
     *
120
     * @return string
121
     */
122 7
    public function getName()
123
    {
124 7
        if (!isset($this->name)) {
125 7
            BrowserDetector::detect($this, $this->getUserAgent());
126 7
        }
127
128 7
        return $this->name;
129
    }
130
131
    /**
132
     * Check to see if the specific browser is valid.
133
     *
134
     * @param string $name
135
     * @return bool
136
     */
137
    public function isBrowser($name)
138
    {
139
        return (0 == strcasecmp($this->getName(), trim($name)));
140
    }
141
142
    /**
143
     * Set the version of the browser.
144
     *
145
     * @param string $version
146
     * @return $this
147
     */
148
    public function setVersion($version)
149
    {
150 8
        $this->version = (string)$version;
151
        return $this;
152 8
    }
153
154 8
    /**
155
     * The version of the browser.
156
     *
157
     * @return string
158
     */
159
    public function getVersion()
160
    {
161
        if (!isset($this->name)) {
162 7
            BrowserDetector::detect($this, $this->getUserAgent());
163
        }
164 7
165
        return (string) $this->version;
166
    }
167
168 7
    /**
169
     * Detects scripted agents (robots / bots)
170
     * Returns a resolved ScriptedAgent object if detected.
171
     * Otherwise returns false.
172
     *
173
     * @return ScriptedAgent|bool
174
     */
175
    public function detectScriptedAgent()
0 ignored issues
show
Coding Style introduced by
detectScriptedAgent 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...
176
    {
177
        $ua = $this->getUserAgent()->getUserAgentString();
178
        if (stripos($ua, 'bot') !== false ||
179
            stripos($ua, 'spider') !== false ||
180
            stripos($ua, 'crawler') !== false ||
181
            stripos($ua, 'preview') !== false ||
182
            stripos($ua, 'slurp') !== false ||
183
            stripos($ua, 'facebookexternalhit') !== false ||
184
            stripos($ua, 'mediapartners') !== false ||
185
            stripos($ua, 'google-adwords') !== false ||
186
            stripos($ua, 'adxvastfetcher') !== false ||
187
            stripos($ua, 'adbeat') !== false ||
188
            stripos($ua, 'google favicon') !== false ||
189
            stripos($ua, 'webdav client') !== false ||
190
            stripos($ua, 'metauri api') !== false ||
191
            stripos($ua, 'tlsprobe') !== false ||
192
            stripos($ua, 'wpif') !== false ||
193
            stripos($ua, 'imgsizer') !== false ||
194
            stripos($ua, 'netcraft ssl server survey') !== false ||
195
            stripos($ua, 'curl/') !== false ||
196
            stripos($ua, 'go-http-client/') !== false ||
197
            stripos($ua, 'python') !== false ||
198
            stripos($ua, 'libwww') !== false ||
199
            stripos($ua, 'wget/') !== false ||
200
            stripos($ua, 'zgrab/') !== false ||
201
            stripos($ua, 'Java/') !== false ||
202
            stripos($ua, '() { :;}; /bin/bash -c') !== false ||
203
            stripos($ua, 'browsershots') !== false ||
204
            stripos($ua, 'magereport') !== false ||
205
            stripos($ua, 'ubermetrics-technologies') !== false ||
206
            stripos($ua, 'W3C') !== false ||
207
            stripos($ua, 'Validator') !== false ||
208
            stripos($ua, 'Jigsaw/') !== false ||
209
            stripos($ua, 'bing') !== false ||
210
            stripos($ua, 'msn') !== false ||
211
            stripos($ua, 'Google Web Preview') !== false ||
212
            stripos($ua, 'ips-agent') !== false ||
213
            (stripos($ua, 'Chrome/51.0.2704.103') !== false && !isset($_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS']) && stristr($_SERVER['HTTP_ACCEPT_LANGUAGE'], "ru-RU") !== false) //ICQ Preview
214
        ) {
215
            $scriptedAgent = new ScriptedAgent($ua);
216
            if ($scriptedAgent->getName()==ScriptedAgent::UNKNOWN) {
217
                return false;
218
            } else {
219
                return $scriptedAgent;
220
            }
221
        } else {
222
            return false;
223
        }
224
    }
225
226
    /**
227
     * @param bool $isChromeFrame
228
     * @return $this
229
     */
230
    public function setIsChromeFrame($isChromeFrame)
231
    {
232
        $this->isChromeFrame = (bool)$isChromeFrame;
233
        return $this;
234
    }
235
236
    /**
237
     * Used to determine if the browser is actually "chromeframe".
238
     *
239
     * @return bool
240
     */
241
    public function getIsChromeFrame()
242
    {
243
        if (!isset($this->name)) {
244
            BrowserDetector::detect($this, $this->getUserAgent());
245
        }
246 1
247
        return $this->isChromeFrame;
248 1
    }
249
250 1
    /**
251
     * @return bool
252
     */
253
    public function isChromeFrame()
254
    {
255
        return $this->getIsChromeFrame();
256
    }
257
258 1
    /**
259
     * @param bool $isWebkit
260 1
     * @return $this
261 1
     */
262 1
    public function setIsWebkit($isWebkit)
263
    {
264 1
        $this->isWebkit = (bool)$isWebkit;
265
        return $this;
266
    }
267
268
    /**
269
     * Used to determine if the browser is actually "chromeframe".
270 1
     *
271
     * @return bool
272 1
     */
273
    public function getIsWebkit()
274
    {
275
        if (!isset($this->name)) {
276
            BrowserDetector::detect($this, $this->getUserAgent());
277
        }
278
279
        return $this->isWebkit;
280 8
    }
281
282 8
    /**
283
     * @return bool
284 8
     */
285
    public function isWebkit()
286
    {
287
        return $this->getIsWebkit();
288
    }
289
290 8
    /**
291
     * @param bool $isFacebookWebView
292 8
     * @return $this
293
     */
294
    public function setIsFacebookWebView($isFacebookWebView)
295
    {
296
        $this->isFacebookWebView = (bool) $isFacebookWebView;
297
        return $this;
298
    }
299
300 1
    /**
301
     * Used to determine if the browser is actually "facebook".
302 1
     *
303
     * @return bool
304 1
     */
305
    public function getIsFacebookWebView()
306
    {
307
        if (!isset($this->name)) {
308
            BrowserDetector::detect($this, $this->getUserAgent());
309
        }
310
311
        return $this->isFacebookWebView;
312
    }
313
314
    /**
315
     * @return bool
316
     */
317
    public function isFacebookWebView()
318
    {
319
        return $this->getIsFacebookWebView();
320
    }
321
322
    /**
323
     * @param bool $isTwitterWebView
324
     * @return $this
325
     */
326
    public function setIsTwitterWebView($isTwitterWebView)
327
    {
328
        $this->isTwitterWebView = (bool) $isTwitterWebView;
329
        return $this;
330
    }
331
332
    /**
333
     * Used to determine if the browser is actually "Twitter".
334
     *
335
     * @return bool
336
     */
337
    public function getIsTwitterWebView()
338
    {
339
        if (!isset($this->name)) {
340
            BrowserDetector::detect($this, $this->getUserAgent());
341
        }
342
343
        return $this->isTwitterWebView;
344
    }
345
346
    /**
347
     * @return bool
348
     */
349
    public function isTwitterWebView()
350
    {
351
        return $this->getIsTwitterWebView();
352
    }
353
354
    /**
355
     * @param UserAgent $userAgent
356
     * @return $this
357
     */
358
    public function setUserAgent(UserAgent $userAgent)
359
    {
360
        $this->userAgent = $userAgent;
361
        return $this;
362
    }
363
364
    /**
365
     * @return UserAgent
366
     */
367
    public function getUserAgent()
368
    {
369
        return $this->userAgent;
370
    }
371
372
    /**
373
     * @param bool
374
     *
375
     * @return $this
376
     */
377
    public function setIsCompatibilityMode($isCompatibilityMode)
378
    {
379
        $this->isCompatibilityMode = $isCompatibilityMode;
380
        return $this;
381
    }
382
383
    /**
384
     * @return bool
385
     */
386
    public function isCompatibilityMode()
387
    {
388
        return $this->isCompatibilityMode;
389
    }
390
391
    /**
392
     * Render pages outside of IE's compatibility mode.
393
     */
394
    public function endCompatibilityMode()
395
    {
396
        header('X-UA-Compatible: IE=edge');
397
    }
398
}
399