Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
69 / 69 |
|
100.00% |
3 / 3 |
CRAP | |
100.00% |
1 / 1 |
UADeviceDetector | |
100.00% |
69 / 69 |
|
100.00% |
3 / 3 |
5 | |
100.00% |
1 / 1 |
detectDeviceProperties | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
detectMobileDevice | |
100.00% |
61 / 61 |
|
100.00% |
1 / 1 |
2 | |||
detectTabletDevice | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | /** |
4 | * Copyright (c) 2011 Patrick Reilly |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU General Public License along |
17 | * with this program; if not, write to the Free Software Foundation, Inc., |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
19 | * http://www.gnu.org/copyleft/gpl.html |
20 | * |
21 | * @file |
22 | */ |
23 | |
24 | namespace MobileFrontend\Devices; |
25 | |
26 | use MediaWiki\Request\WebRequest; |
27 | |
28 | /** |
29 | * Detect mobile and tablet devices by testing whether the User-Agent request |
30 | * header matches a list of regular expressions. |
31 | */ |
32 | class UADeviceDetector implements DeviceDetector { |
33 | |
34 | /** |
35 | * @inheritDoc |
36 | */ |
37 | public function detectDeviceProperties( WebRequest $request, array $server ) { |
38 | $userAgent = $request->getHeader( 'User-Agent' ); |
39 | |
40 | return new DeviceProperties( |
41 | $this->detectMobileDevice( $userAgent ), |
42 | $this->detectTabletDevice( $userAgent ) |
43 | ); |
44 | } |
45 | |
46 | /** |
47 | * Tests whether the UA is known to be sent on behalf of users using a mobile |
48 | * device. |
49 | * |
50 | * @author Patrick Reilly |
51 | * |
52 | * @param string $userAgent |
53 | * @return bool |
54 | */ |
55 | private function detectMobileDevice( $userAgent ) { |
56 | $patterns = [ |
57 | 'mobi', |
58 | '240x240', |
59 | '240x320', |
60 | '320x320', |
61 | 'alcatel', |
62 | 'android', |
63 | 'audiovox', |
64 | 'bada', |
65 | 'benq', |
66 | 'blackberry', |
67 | 'cdm-', |
68 | 'compal-', |
69 | 'docomo', |
70 | 'ericsson', |
71 | 'hiptop', |
72 | 'htc[-_]', |
73 | 'huawei', |
74 | 'ipod', |
75 | 'kddi-', |
76 | 'kindle', |
77 | 'meego', |
78 | 'midp', |
79 | 'mitsu', |
80 | 'mmp\/', |
81 | 'mot-', |
82 | 'motor', |
83 | 'ngm_', |
84 | 'nintendo', |
85 | 'opera.m', |
86 | 'palm', |
87 | 'panasonic', |
88 | 'philips', |
89 | 'phone', |
90 | 'playstation', |
91 | 'portalmmm', |
92 | 'sagem-', |
93 | 'samsung', |
94 | 'sanyo', |
95 | 'sec-', |
96 | 'sendo', |
97 | 'sharp', |
98 | 'silk', |
99 | 'softbank', |
100 | 'symbian', |
101 | 'teleca', |
102 | 'up.browser', |
103 | 'webos', |
104 | ]; |
105 | $patternsStart = [ |
106 | 'lg-', |
107 | 'sie-', |
108 | 'nec-', |
109 | 'lge-', |
110 | 'sgh-', |
111 | 'pg-', |
112 | ]; |
113 | $regex = '/^(' . implode( '|', $patternsStart ) . ')|(' . implode( '|', $patterns ) . ')/i'; |
114 | $exceptionRegex = '/SMART-TV.*SamsungBrowser/'; |
115 | |
116 | return preg_match( $regex, $userAgent ) |
117 | && !preg_match( $exceptionRegex, $userAgent ); |
118 | } |
119 | |
120 | /** |
121 | * Tests whether the UA is known to be sent on behalf of users using a tablet |
122 | * device. |
123 | * |
124 | * @author Patrick Reilly |
125 | * |
126 | * @param string $userAgent |
127 | * @return bool |
128 | */ |
129 | private function detectTabletDevice( $userAgent ) { |
130 | // The only way to distinguish Android browsers on tablet from Android |
131 | // browsers on mobile is that Android browsers on tablet usually don't |
132 | // include the word "mobile". We look for "mobi" instead of "mobile" due to |
133 | // Opera Mobile. Note that this test fails to detect some obscure tablets |
134 | // such as older Xoom tablets and Portablet tablets. See |
135 | // http://stackoverflow.com/questions/5341637 for more detail. |
136 | if ( preg_match( '/Android/i', $userAgent ) ) { |
137 | return !preg_match( '/mobi/i', $userAgent ); |
138 | } |
139 | |
140 | return (bool)preg_match( '/(iPad|Tablet|PlayBook|Wii|Silk)/i', $userAgent ); |
141 | } |
142 | } |