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