Follow-up to bug #14201: getBrowserInfo delivers wrong info
[Packages/TYPO3.CMS.git] / t3lib / utility / class.t3lib_utility_client.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Oliver Hader <oliver@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 /**
29 * Class to handle and determine browser specific information.
30 *
31 * $Id$
32 *
33 * @author Oliver Hader <oliver@typo3.org>
34 */
35 final class t3lib_utility_Client {
36
37 /**
38 * Generates an array with abstracted browser information
39 *
40 * @param string $userAgent: The useragent string, t3lib_div::getIndpEnv('HTTP_USER_AGENT')
41 * @return array Contains keys "browser", "version", "system"
42 */
43 public static function getBrowserInfo($userAgent) {
44 // Hook: $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/div/class.t3lib_utility_client.php']['getBrowserInfo']:
45 $getBrowserInfoHooks =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/div/class.t3lib_utility_client.php']['getBrowserInfo'];
46 if (is_array($getBrowserInfoHooks)) {
47 foreach ($getBrowserInfoHooks as $hookFunction) {
48 $returnResult = true;
49 $hookParameters = array(
50 'userAgent' => &$userAgent,
51 'returnResult' => &$returnResult,
52 );
53
54 $hookResult = t3lib_div::callUserFunction($hookFunction, $hookParameters, NULL);
55 if ($returnResult && is_array($hookResult) && count($hookResult)) {
56 return $hookResult;
57 }
58 }
59 }
60
61 $userAgent = trim($userAgent);
62 $browserInfo = array(
63 'useragent' => $userAgent,
64 );
65
66 // Analyze the userAgent string
67 // Declare known browsers to look for
68
69 $known = array('msie', 'firefox', 'webkit', 'opera', 'netscape', 'konqueror',
70 'gecko', 'chrome', 'safari', 'seamonkey', 'navigator', 'mosaic',
71 'lynx', 'amaya', 'omniweb', 'avant', 'camino', 'flock', 'aol');
72 $matches = array();
73
74 $pattern = '#(?<browser>' . join('|', $known) . ')[/ ]+(?<version>[0-9]+(?:\.[0-9]+)?)#';
75 // Find all phrases (or return empty array if none found)
76 if (!preg_match_all($pattern, strtolower($userAgent), $matches)) {
77 $browserInfo['browser'] = 'unknown';
78 } else {
79 // Since some UAs have more than one phrase (e.g Firefox has a Gecko phrase,
80 // Opera 7,8 have a MSIE phrase), use the last one found (the right-most one
81 // in the UA). That's usually the most correct.
82 $lastIndex = count($matches['browser']) - 1;
83 $browserInfo['browser'] = $matches['browser'][$lastIndex];
84 $browserInfo['version'] = $matches['version'][$lastIndex];
85 //But return all parsed browsers / version in an extra array
86 for ($i = 0; $i <= $lastIndex; $i++) {
87 $browserInfo['all'][$matches['browser'][$i]] = $matches['version'][$i];
88 }
89 }
90
91
92 // system
93 $browserInfo['system'] = '';
94 if (strstr($userAgent, 'Win')) {
95 // windows
96 if (strstr($userAgent, 'Win98') || strstr($userAgent, 'Windows 98')) {
97 $browserInfo['system'] = 'win98';
98 } elseif (strstr($userAgent, 'Win95') || strstr($userAgent, 'Windows 95')) {
99 $browserInfo['system'] = 'win95';
100 } elseif (strstr($userAgent, 'WinNT') || strstr($userAgent, 'Windows NT')) {
101 $browserInfo['system'] = 'winNT';
102 } elseif (strstr($userAgent, 'Win16') || strstr($userAgent, 'Windows 311')) {
103 $browserInfo['system'] = 'win311';
104 }
105 } elseif (strstr($userAgent,'Mac')) {
106 $browserInfo['system'] = 'mac';
107 // unixes
108 } elseif (strstr($userAgent, 'Linux')) {
109 $browserInfo['system'] = 'linux';
110 } elseif (strstr($userAgent, 'SGI') && strstr($userAgent, ' IRIX ')) {
111 $browserInfo['system'] = 'unix_sgi';
112 } elseif (strstr($userAgent, ' SunOS ')) {
113 $browserInfo['system'] = 'unix_sun';
114 } elseif (strstr($userAgent, ' HP-UX ')) {
115 $browserInfo['system'] = 'unix_hp';
116 }
117
118 return $browserInfo;
119 }
120
121 /**
122 * Returns the version of a browser; Basically getting doubleval() of the input string,
123 * stripping of any non-numeric values in the beginning of the string first.
124 *
125 * @param string $version: A string with version number, eg. "/7.32 blablabla"
126 * @return double Returns double value, eg. "7.32"
127 */
128 public static function getVersion($version) {
129 return doubleval(preg_replace('/^[^0-9]*/', '', $version));
130 }
131
132 /**
133 * Gets a code for a browsing device based on the input useragent string.
134 *
135 * @param string $userAgent: The useragent string, t3lib_div::getIndpEnv('HTTP_USER_AGENT')
136 * @return string Code for the specific device type
137 */
138 public static function getDeviceType($userAgent) {
139 // Hook: $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/div/class.t3lib_utility_client.php']['getDeviceType']:
140 $getDeviceTypeHooks =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/div/class.t3lib_utility_client.php']['getDeviceType'];
141 if (is_array($getDeviceTypeHooks)) {
142 foreach ($getDeviceTypeHooks as $hookFunction) {
143 $returnResult = true;
144 $hookParameters = array(
145 'userAgent' => &$userAgent,
146 'returnResult' => &$returnResult,
147 );
148
149 $hookResult = t3lib_div::callUserFunction($hookFunction, $hookParameters, NULL);
150 if ($returnResult && is_string($hookResult) && !empty($hookResult)) {
151 return $hookResult;
152 }
153 }
154 }
155
156 $userAgent = strtolower(trim($userAgent));
157 $deviceType = '';
158
159 // pda
160 if(strstr($userAgent, 'avantgo')) {
161 $deviceType = 'pda';
162 }
163 // wap
164 $browser=substr($userAgent, 0, 4);
165 $wapviwer=substr(stristr($userAgent,'wap'), 0, 3);
166 if($wapviwer == 'wap' ||
167 $browser == 'noki' ||
168 $browser == 'eric' ||
169 $browser == 'r380' ||
170 $browser == 'up.b' ||
171 $browser == 'winw' ||
172 $browser == 'wapa') {
173 $deviceType = 'wap';
174 }
175 // grabber
176 if(strstr($userAgent, 'g.r.a.b.') ||
177 strstr($userAgent, 'utilmind httpget') ||
178 strstr($userAgent, 'webcapture') ||
179 strstr($userAgent, 'teleport') ||
180 strstr($userAgent, 'webcopier')) {
181 $deviceType = 'grabber';
182 }
183 // robots
184 if(strstr($userAgent, 'crawler') ||
185 strstr($userAgent, 'spider') ||
186 strstr($userAgent, 'googlebot') ||
187 strstr($userAgent, 'searchbot') ||
188 strstr($userAgent, 'infoseek') ||
189 strstr($userAgent, 'altavista') ||
190 strstr($userAgent, 'diibot')) {
191 $deviceType = 'robot';
192 }
193
194 return $deviceType;
195 }
196 }
197 ?>