Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
// {{{ license
3
 
4
// +----------------------------------------------------------------------+
5
// | PHP version 4.2                                                      |
6
// +----------------------------------------------------------------------+
7
// | Copyright (c) 1997-2007 The PHP Group                                |
8
// +----------------------------------------------------------------------+
9
// | This source file is subject to version 2.0 of the PHP license,       |
10
// | that is bundled with this package in the file LICENSE, and is        |
11
// | available at through the world-wide-web at                           |
12
// | http://www.php.net/license/2_02.txt.                                 |
13
// | If you did not receive a copy of the PHP license and are unable to   |
14
// | obtain it through the world-wide-web, please send a note to          |
15
// | license@php.net so we can mail you a copy immediately.               |
16
// +----------------------------------------------------------------------+
17
// | Authors: Dan Allen <dan@mojavelinux.com>                             |
18
// |          Jason Rust <jrust@php.net>                                  |
19
// +----------------------------------------------------------------------+
20
 
21
// $Id: Detect.php 298049 2010-04-15 18:16:24Z jrust $
22
 
23
// }}}
24
// {{{ constants
25
 
26
define('NET_USERAGENT_DETECT_BROWSER',  'browser');
27
define('NET_USERAGENT_DETECT_OS',       'os');
28
define('NET_USERAGENT_DETECT_FEATURES', 'features');
29
define('NET_USERAGENT_DETECT_QUIRKS',   'quirks');
30
define('NET_USERAGENT_DETECT_ACCEPT',   'accept');
31
define('NET_USERAGENT_DETECT_ALL',      'all');
32
 
33
// }}}
34
// {{{ class Net_UserAgent_Detect
35
 
36
/**
37
 * The Net_UserAgent_Detect object does a number of tests on an HTTP user
38
 * agent string.  The results of these tests are available via methods of
39
 * the object.  Note that all methods in this class can be called
40
 * statically.  The constructor and singleton methods are only retained
41
 * for BC.
42
 *
43
 * This module is based upon the JavaScript browser detection code
44
 * available at http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html.
45
 * This module had many influences from the lib/Browser.php code in
46
 * version 1.3 of Horde.
47
 *
48
 * @author   Jason Rust <jrust@php.net>
49
 * @author   Dan Allen <dan@mojavelinux.com>
50
 * @author   Chuck Hagenbuch <chuck@horde.org>
51
 * @author   Jon Parise <jon@horde.org>
52
 * @package  Net_UserAgent
53
 */
54
 
55
// }}}
56
class Net_UserAgent_Detect {
57
    // {{{ constructor
58
 
59
    function Net_UserAgent_Detect($in_userAgent = null, $in_detect = null)
60
    {
61
        $this->detect($in_userAgent, $in_detect);
62
    }
63
 
64
    // }}}
65
    // {{{ singleton
66
 
67
    /**
68
     * To be used in place of the contructor to return only open instance.
69
     *
70
     * @access public
71
     * @return object Net_UserAgent_Detect instance
72
     */
73
    function &singleton($in_userAgent = null, $in_detect = null)
74
    {
75
        static $instance;
76
 
77
        if (!isset($instance)) {
78
            $instance = new Net_UserAgent_Detect($in_userAgent, $in_detect);
79
        }
80
 
81
        return $instance;
82
    }
83
 
84
    // }}}
85
    // {{{ detect()
86
 
87
    /**
88
     * Detect the user agent and prepare flags, features and quirks
89
     * based on what is found
90
     *
91
     * This is the core of the Net_UserAgent_Detect class.  It moves its
92
     * way through the user agent string setting up the flags based on
93
     * the vendors and versions of the browsers, determining the OS and
94
     * setting up the features and quirks owned by each of the relevant
95
     * clients.  Note that if you are going to be calling methods of
96
     * this class statically then set all the parameters using th
97
     * setOption()
98
     *
99
     * @param  string $in_userAgent (optional) User agent override.
100
     * @param  mixed $in_detect (optional) The level of checking to do.
101
     *
102
     * @access public
103
     * @return void
104
     */
105
    function detect($in_userAgent = null, $in_detect = null)
106
    {
107
        static $hasRun;
108
        $options = &Net_UserAgent_Detect::_getStaticProperty('options');
109
        if (!empty($hasRun) && empty($options['re-evaluate'])) {
110
            return;
111
        }
112
 
113
        $hasRun = true;
114
        // {{{ set up static properties
115
 
116
        $in_userAgent = isset($options['userAgent']) && is_null($in_userAgent) ? $options['userAgent'] : $in_userAgent;
117
        $in_detect = isset($options['detectOptions']) && is_null($in_detect) ? $options['detectOptions'] : $in_detect;
118
 
119
        // User agent string that is being analyzed
120
        $userAgent = &Net_UserAgent_Detect::_getStaticProperty('userAgent');
121
 
122
        // Array that stores all of the flags for the vendor and version
123
        // of the different browsers
124
        $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
125
        $browser = array_flip(array('ns', 'ns2', 'ns3', 'ns4', 'ns4up', 'nav', 'ns6', 'belowns6', 'ns6up', 'firefox', 'firefox0.x', 'firefox1.x', 'firefox1.5', 'firefox2.x', 'firefox3.x', 'gecko', 'ie', 'ie3', 'ie4', 'ie4up', 'ie5', 'ie5_5', 'ie5up', 'ie6', 'belowie6', 'ie6up', 'ie7', 'ie7up', 'ie8', 'ie8tr', 'ie8up', 'ie9', 'ie9up', 'opera', 'opera2', 'opera3', 'opera4', 'opera5', 'opera6', 'opera7', 'opera8', 'opera9', 'opera5up', 'opera6up', 'opera7up', 'belowopera8', 'opera8up', 'opera9up', 'aol', 'aol3', 'aol4', 'aol5', 'aol6', 'aol7', 'aol8', 'webtv', 'aoltv', 'tvnavigator', 'hotjava', 'hotjava3', 'hotjava3up', 'konq', 'safari', 'safari_mobile', 'chrome', 'netgem', 'webdav', 'icab'));
126
 
127
        // Array that stores all of the flags for the operating systems,
128
        // and in some cases the versions of those operating systems (windows)
129
        $os = &Net_UserAgent_Detect::_getStaticProperty('os');
130
        $os = array_flip(array('win', 'win95', 'win16', 'win31', 'win9x', 'win98', 'wince', 'winme', 'win2k', 'winxp', 'winnt', 'win2003', 'vista', 'win7', 'os2', 'mac', 'mactiger', 'macleopard', 'macsnowleopard', 'mac68k', 'macppc', 'iphone', 'linux', 'unix', 'vms', 'sun', 'sun4', 'sun5', 'suni86', 'irix', 'irix5', 'irix6', 'hpux', 'hpux9', 'hpux10', 'aix', 'aix1', 'aix2', 'aix3', 'aix4', 'sco', 'unixware', 'mpras', 'reliant', 'dec', 'sinix', 'freebsd', 'bsd'));
131
 
132
        // Array which stores known issues with the given client that can
133
        // be used for on the fly tweaking so that the client may recieve
134
        // the proper handling of this quirk.
135
        $quirks = &Net_UserAgent_Detect::_getStaticProperty('quirks');
136
        $quirks = array(
137
                'must_cache_forms'         => false,
138
                'popups_disabled'          => false,
139
                'empty_file_input_value'   => false,
140
                'cache_ssl_downloads'      => false,
141
                'scrollbar_in_way'         => false,
142
                'break_disposition_header' => false,
143
                'nested_table_render_bug'  => false);
144
 
145
        // Array that stores credentials for each of the browser/os
146
        // combinations.  These allow quick access to determine if the
147
        // current client has a feature that is going to be implemented
148
        // in the script.
149
        $features = &Net_UserAgent_Detect::_getStaticProperty('features');
150
        $features = array(
151
                'javascript'   => false,
152
                'dhtml'        => false,
153
                'dom'          => false,
154
                'sidebar'      => false,
155
                'gecko'        => false,
156
                'svg'          => false,
157
                'css2'         => false,
158
                'ajax'         => false);
159
 
160
        // The leading identifier is the very first term in the user
161
        // agent string, which is used to identify clients which are not
162
        // Mosaic-based browsers.
163
        $leadingIdentifier = &Net_UserAgent_Detect::_getStaticProperty('leadingIdentifier');
164
 
165
        // The full version of the client as supplied by the very first
166
        // numbers in the user agent
167
        $version = &Net_UserAgent_Detect::_getStaticProperty('version');
168
        $version = 0;
169
 
170
        // The major part of the client version, which is the integer
171
        // value of the version.
172
        $majorVersion = &Net_UserAgent_Detect::_getStaticProperty('majorVersion');
173
        $majorVersion = 0;
174
 
175
        // The minor part of the client version, which is the decimal
176
        // parts of the version
177
        $subVersion = &Net_UserAgent_Detect::_getStaticProperty('subVersion');
178
        $subVersion = 0;
179
 
180
        // }}}
181
        // detemine what user agent we are using
182
        if (is_null($in_userAgent)) {
183
            if (isset($_SERVER['HTTP_USER_AGENT'])) {
184
                $userAgent = $_SERVER['HTTP_USER_AGENT'];
185
            }
186
            elseif (isset($GLOBALS['HTTP_SERVER_VARS']['HTTP_USER_AGENT'])) {
187
                $userAgent = $GLOBALS['HTTP_SERVER_VARS']['HTTP_USER_AGENT'];
188
            }
189
            else {
190
                $userAgent = '';
191
            }
192
        }
193
        else {
194
            $userAgent = $in_userAgent;
195
        }
196
 
197
        // get the lowercase version for case-insensitive searching
198
        $agt = strtolower($userAgent);
199
 
200
        // figure out what we need to look for
201
        $detectOptions = array(NET_USERAGENT_DETECT_BROWSER,
202
                NET_USERAGENT_DETECT_OS, NET_USERAGENT_DETECT_FEATURES,
203
                NET_USERAGENT_DETECT_QUIRKS, NET_USERAGENT_DETECT_ACCEPT,
204
                NET_USERAGENT_DETECT_ALL);
205
        $detect = is_null($in_detect) ? NET_USERAGENT_DETECT_ALL : $in_detect;
206
        settype($detect, 'array');
207
        foreach($detectOptions as $option) {
208
            if (in_array($option, $detect)) {
209
                $detectFlags[$option] = true;
210
            }
211
            else {
212
                $detectFlags[$option] = false;
213
            }
214
        }
215
 
216
        // initialize the arrays of browsers and operating systems
217
 
218
        // Get the type and version of the client
219
        if (preg_match(";^([[:alnum:]]+)[ /\(]*[[:alpha:]]*([\d]*)(\.[\d\.]*);", $agt, $matches)) {
220
            list(, $leadingIdentifier, $majorVersion, $subVersion) = $matches;
221
        }
222
 
223
        if (empty($leadingIdentifier)) {
224
            $leadingIdentifier = 'Unknown';
225
        }
226
 
227
        $version = $majorVersion . $subVersion;
228
 
229
        // Browser type
230
        if ($detectFlags[NET_USERAGENT_DETECT_ALL] || $detectFlags[NET_USERAGENT_DETECT_BROWSER]) {
231
            $browser['webdav']  = ($agt == 'microsoft data access internet publishing provider dav' || $agt == 'microsoft data access internet publishing provider protocol discovery');
232
            $browser['konq'] = (strpos($agt, 'konqueror') !== false ||  strpos($agt, 'safari') !== false );
233
            $browser['safari'] = (strpos($agt, 'safari') !== false);
234
            $browser['chrome'] = (strpos($agt, 'chrome') !== false);
235
            $browser['safari_mobile'] = (strpos($agt, 'safari') !== false && strpos($agt, 'mobile') !== false );
236
            $browser['text']    = strpos($agt, 'links') !== false || strpos($agt, 'lynx') !== false || strpos($agt, 'w3m') !== false;
237
            $browser['ns']      = strpos($agt, 'mozilla') !== false && !(strpos($agt, 'spoofer') !== false) && !(strpos($agt, 'compatible') !== false) && !(strpos($agt, 'hotjava') !== false) && !(strpos($agt, 'opera') !== false) && !(strpos($agt, 'webtv') !== false) ? 1 : 0;
238
            $browser['netgem']  = strpos($agt, 'netgem') !== false;
239
            $browser['icab']    = strpos($agt, 'icab') !== false;
240
            $browser['ns2']     = $browser['ns'] && $majorVersion == 2;
241
            $browser['ns3']     = $browser['ns'] && $majorVersion == 3;
242
            $browser['ns4']     = $browser['ns'] && $majorVersion == 4;
243
            $browser['ns4up']   = $browser['ns'] && $majorVersion >= 4;
244
            // determine if this is a Netscape Navigator
245
            $browser['nav'] = $browser['belowns6'] = $browser['ns'] && $majorVersion < 5;
246
            $browser['ns6']     = !$browser['konq'] && $browser['ns'] && $majorVersion == 5;
247
            $browser['ns6up']   = $browser['ns6'] && $majorVersion >= 5;
248
            $browser['gecko']   = strpos($agt, 'gecko') !== false && !$browser['konq'];
249
            $browser['firefox'] = $browser['gecko'] && strpos($agt, 'firefox') !== false;
250
            $browser['firefox0.x'] = $browser['firefox'] && strpos($agt, 'firefox/0.') !== false;
251
            $browser['firefox1.x'] = $browser['firefox'] && strpos($agt, 'firefox/1.') !== false;
252
            $browser['firefox1.5'] = $browser['firefox'] && strpos($agt, 'firefox/1.5') !== false;
253
            $browser['firefox2.x'] = $browser['firefox'] && strpos($agt, 'firefox/2.') !== false;
254
            $browser['firefox3.x'] = $browser['firefox'] && strpos($agt, 'firefox/3.') !== false;
255
            $browser['ie']      = strpos($agt, 'msie') !== false && !(strpos($agt, 'opera') !== false);
256
            $browser['ie3']     = $browser['ie'] && $majorVersion < 4;
257
            $browser['ie4']     = $browser['ie'] && $majorVersion == 4 && (strpos($agt, 'msie 4') !== false);
258
            $browser['ie4up']   = $browser['ie'] && !$browser['ie3'];
259
            $browser['ie5']     = $browser['ie4up'] && (strpos($agt, 'msie 5') !== false);
260
            $browser['ie5_5']   = $browser['ie4up'] && (strpos($agt, 'msie 5.5') !== false);
261
            $browser['ie5up']   = $browser['ie4up'] && !$browser['ie3'] && !$browser['ie4'];
262
            $browser['ie5_5up'] = $browser['ie5up'] && !$browser['ie5'];
263
            $browser['ie6']     = strpos($agt, 'msie 6') !== false;
264
            $browser['ie6up']   = $browser['ie5up'] && !$browser['ie5'] && !$browser['ie5_5'];
265
            $browser['ie7'] = strpos($agt, 'msie 7') && !strpos($agt,'trident/4');
266
            $browser['ie7up']   = $browser['ie6up'] && (!$browser['ie6'] || $browser['ie7']);
267
            $browser['ie8tr'] = strpos($agt, 'msie 7') && strpos($agt,'trident/4') !== false;
268
            $browser['ie8'] = strpos($agt, 'msie 8') !== false;
269
            $browser['ie8up'] = $browser['ie7up'] && (!$browser['ie7'] || $browser['ie8']);
270
            $browser['ie9'] = strpos($agt, 'msie 9') !== false;
271
            $browser['ie9up'] = $browser['ie8up'] && (!$browser['ie8'] || $browser['ie9']);
272
            $browser['belowie6']= $browser['ie'] && !$browser['ie6up'];
273
            $browser['opera']   = strpos($agt, 'opera') !== false;
274
            $browser['opera2']  = strpos($agt, 'opera 2') !== false || strpos($agt, 'opera/2') !== false;
275
            $browser['opera3']  = strpos($agt, 'opera 3') !== false || strpos($agt, 'opera/3') !== false;
276
            $browser['opera4']  = strpos($agt, 'opera 4') !== false || strpos($agt, 'opera/4') !== false;
277
            $browser['opera5']  = strpos($agt, 'opera 5') !== false || strpos($agt, 'opera/5') !== false;
278
            $browser['opera6']  = strpos($agt, 'opera 6') !== false || strpos($agt, 'opera/6') !== false;
279
            $browser['opera7']  = strpos($agt, 'opera 7') !== false || strpos($agt, 'opera/7') !== false;
280
            $browser['opera8']  = strpos($agt, 'opera 8') !== false || strpos($agt, 'opera/8') !== false;
281
            $browser['opera9']  = strpos($agt, 'opera 9') !== false || strpos($agt, 'opera/9') !== false;
282
            $browser['opera5up'] = $browser['opera'] && !$browser['opera2'] && !$browser['opera3'] && !$browser['opera4'];
283
            $browser['opera6up'] = $browser['opera'] && !$browser['opera2'] && !$browser['opera3'] && !$browser['opera4'] && !$browser['opera5'];
284
            $browser['opera7up'] = $browser['opera'] && !$browser['opera2'] && !$browser['opera3'] && !$browser['opera4'] && !$browser['opera5'] && !$browser['opera6'];
285
            $browser['opera8up'] = $browser['opera'] && !$browser['opera2'] && !$browser['opera3'] && !$browser['opera4'] && !$browser['opera5'] && !$browser['opera6'] && !$browser['opera7'];
286
            $browser['opera9up'] = $browser['opera'] && !$browser['opera2'] && !$browser['opera3'] && !$browser['opera4'] && !$browser['opera5'] && !$browser['opera6'] && !$browser['opera7'] && !$browser['opera8'];
287
            $browser['belowopera8'] = $browser['opera'] && !$browser['opera8up'];
288
            $browser['aol']   = strpos($agt, 'aol') !== false;
289
            $browser['aol3']  = $browser['aol'] && $browser['ie3'];
290
            $browser['aol4']  = $browser['aol'] && $browser['ie4'];
291
            $browser['aol5']  = strpos($agt, 'aol 5') !== false;
292
            $browser['aol6']  = strpos($agt, 'aol 6') !== false;
293
            $browser['aol7']  = strpos($agt, 'aol 7') !== false || strpos($agt, 'aol7') !== false;
294
            $browser['aol8']  = strpos($agt, 'aol 8') !== false || strpos($agt, 'aol8') !== false;
295
            $browser['webtv'] = strpos($agt, 'webtv') !== false;
296
            $browser['aoltv'] = $browser['tvnavigator'] = strpos($agt, 'navio') !== false || strpos($agt, 'navio_aoltv') !== false;
297
            $browser['hotjava'] = strpos($agt, 'hotjava') !== false;
298
            $browser['hotjava3'] = $browser['hotjava'] && $majorVersion == 3;
299
            $browser['hotjava3up'] = $browser['hotjava'] && $majorVersion >= 3;
300
            $browser['iemobile'] = strpos($agt, 'iemobile') !== false || strpos($agt, 'windows ce') !== false && (strpos($agt, 'ppc') !== false || strpos($agt, 'smartphone') !== false);
301
        }
302
 
303
        if ($detectFlags[NET_USERAGENT_DETECT_ALL] ||
304
            ($detectFlags[NET_USERAGENT_DETECT_BROWSER] && $detectFlags[NET_USERAGENT_DETECT_FEATURES])) {
305
            // Javascript Check
306
            if ($browser['ns2'] || $browser['ie3']) {
307
                Net_UserAgent_Detect::setFeature('javascript', 1.0);
308
            }
309
            elseif ($browser['iemobile']) {
310
              // no javascript
311
            }
312
            elseif ($browser['opera5up']) {
313
                Net_UserAgent_Detect::setFeature('javascript', 1.3);
314
            }
315
            elseif ($browser['opera'] || $browser['ns3']) {
316
                Net_UserAgent_Detect::setFeature('javascript', 1.1);
317
            }
318
            elseif (($browser['ns4'] && ($version <= 4.05)) || $browser['ie4']) {
319
                Net_UserAgent_Detect::setFeature('javascript', 1.2);
320
            }
321
            elseif (($browser['ie5up'] && strpos($agt, 'mac') !== false) || $browser['konq']) {
322
                Net_UserAgent_Detect::setFeature('javascript', 1.4);
323
            }
324
            // I can't believe IE6 still has javascript 1.3, what a shitty browser
325
            elseif (($browser['ns4'] && ($version > 4.05)) || $browser['ie5up'] || $browser['hotjava3up']) {
326
                Net_UserAgent_Detect::setFeature('javascript', 1.3);
327
            }
328
            elseif ($browser['ns6up'] || $browser['gecko'] || $browser['netgem']) {
329
                Net_UserAgent_Detect::setFeature('javascript', 1.5);
330
            }
331
        }
332
 
333
        /** OS Check **/
334
        if ($detectFlags[NET_USERAGENT_DETECT_ALL] || $detectFlags[NET_USERAGENT_DETECT_OS]) {
335
            $os['win']   = strpos($agt, 'win') !== false || strpos($agt, '16bit') !== false;
336
            $os['win95'] = strpos($agt, 'win95') !== false || strpos($agt, 'windows 95') !== false;
337
            $os['win16'] = strpos($agt, 'win16') !== false || strpos($agt, '16bit') !== false || strpos($agt, 'windows 3.1') !== false || strpos($agt, 'windows 16-bit') !== false;
338
            $os['win31'] = strpos($agt, 'windows 3.1') !== false || strpos($agt, 'win16') !== false || strpos($agt, 'windows 16-bit') !== false;
339
            $os['winme'] = strpos($agt, 'win 9x 4.90') !== false;
340
            $os['wince'] = strpos($agt, 'windows ce') !== false;
341
            $os['win2k'] = strpos($agt, 'windows nt 5.0') !== false;
342
            $os['winxp'] = strpos($agt, 'windows nt 5.1') !== false;
343
            $os['win2003'] = strpos($agt, 'windows nt 5.2') !== false;
344
            $os['win98'] = strpos($agt, 'win98') !== false || strpos($agt, 'windows 98') !== false;
345
            $os['win9x'] = $os['win95'] || $os['win98'];
346
            $os['winnt'] = (strpos($agt, 'winnt') !== false || strpos($agt, 'windows nt') !== false) && strpos($agt, 'windows nt 5') === false;
347
            $os['win32'] = $os['win95'] || $os['winnt'] || $os['win98'] || $majorVersion >= 4 && strpos($agt, 'win32') !== false || strpos($agt, '32bit') !== false;
348
            $os['vista'] = strpos($agt, 'windows nt 6.0') !== false;
349
            $os['win7'] = strpos($agt, 'windows nt 6.1') !== false;
350
            $os['os2']   = strpos($agt, 'os/2') !== false || strpos($agt, 'ibm-webexplorer') !== false;
351
            $os['mac']   = strpos($agt, 'mac') !== false;
352
            $os['mactiger'] = $os['mac'] && (strpos($agt, '10.4') !== false || strpos($agt, '10_4') !== false);
353
            $os['macleopard'] = $os['mac'] && (strpos($agt, '10.5') !== false || strpos($agt, '10_5') !== false);
354
            $os['macsnowleopard'] = $os['mac'] && (strpos($agt, '10.6') !== false || strpos($agt, '10_6') !== false);
355
            $os['mac68k']   = $os['mac'] && (strpos($agt, '68k') !== false || strpos($agt, '68000') !== false);
356
            $os['macppc']   = $os['mac'] && (strpos($agt, 'ppc') !== false || strpos($agt, 'powerpc') !== false);
357
            $os['iphone']   = strpos($agt, 'iphone') !== false;
358
            $os['sun']      = strpos($agt, 'sunos') !== false;
359
            $os['sun4']     = strpos($agt, 'sunos 4') !== false;
360
            $os['sun5']     = strpos($agt, 'sunos 5') !== false;
361
            $os['suni86']   = $os['sun'] && strpos($agt, 'i86') !== false;
362
            $os['irix']     = strpos($agt, 'irix') !== false;
363
            $os['irix5']    = strpos($agt, 'irix 5') !== false;
364
            $os['irix6']    = strpos($agt, 'irix 6') !== false || strpos($agt, 'irix6') !== false;
365
            $os['hpux']     = strpos($agt, 'hp-ux') !== false;
366
            $os['hpux9']    = $os['hpux'] && strpos($agt, '09.') !== false;
367
            $os['hpux10']   = $os['hpux'] && strpos($agt, '10.') !== false;
368
            $os['aix']      = strpos($agt, 'aix') !== false;
369
            $os['aix1']     = strpos($agt, 'aix 1') !== false;
370
            $os['aix2']     = strpos($agt, 'aix 2') !== false;
371
            $os['aix3']     = strpos($agt, 'aix 3') !== false;
372
            $os['aix4']     = strpos($agt, 'aix 4') !== false;
373
            $os['linux']    = strpos($agt, 'inux') !== false;
374
            $os['sco']      = strpos($agt, 'sco') !== false || strpos($agt, 'unix_sv') !== false;
375
            $os['unixware'] = strpos($agt, 'unix_system_v') !== false;
376
            $os['mpras']    = strpos($agt, 'ncr') !== false;
377
            $os['reliant']  = strpos($agt, 'reliant') !== false;
378
            $os['dec']      = strpos($agt, 'dec') !== false || strpos($agt, 'osf1') !== false || strpos($agt, 'dec_alpha') !== false || strpos($agt, 'alphaserver') !== false || strpos($agt, 'ultrix') !== false || strpos($agt, 'alphastation') !== false;
379
            $os['sinix']    = strpos($agt, 'sinix') !== false;
380
            $os['freebsd']  = strpos($agt, 'freebsd') !== false;
381
            $os['bsd']      = strpos($agt, 'bsd') !== false;
382
            $os['unix']     = strpos($agt, 'x11') !== false || strpos($agt, 'unix') !== false || $os['sun'] || $os['irix'] || $os['hpux'] || $os['sco'] || $os['unixware'] || $os['mpras'] || $os['reliant'] || $os['dec'] || $os['sinix'] || $os['aix'] || $os['linux'] || $os['bsd'] || $os['freebsd'];
383
            $os['vms']      = strpos($agt, 'vax') !== false || strpos($agt, 'openvms') !== false;
384
        }
385
 
386
        // Setup the quirks
387
        if ($detectFlags[NET_USERAGENT_DETECT_ALL] ||
388
            ($detectFlags[NET_USERAGENT_DETECT_BROWSER] && $detectFlags[NET_USERAGENT_DETECT_QUIRKS])) {
389
            if ($browser['konq']) {
390
                Net_UserAgent_Detect::setQuirk('empty_file_input_value');
391
            }
392
 
393
            if ($browser['ie']) {
394
                Net_UserAgent_Detect::setQuirk('cache_ssl_downloads');
395
            }
396
 
397
            if ($browser['ie6']) {
398
                Net_UserAgent_Detect::setQuirk('scrollbar_in_way');
399
            }
400
 
401
            if ($browser['ie5']) {
402
                Net_UserAgent_Detect::setQuirk('break_disposition_header');
403
            }
404
 
405
            if ($browser['ie7']) {
406
                Net_UserAgent_Detect::setQuirk('popups_disabled');
407
            }
408
 
409
            if ($browser['ns6']) {
410
                Net_UserAgent_Detect::setQuirk('popups_disabled');
411
                Net_UserAgent_Detect::setQuirk('must_cache_forms');
412
            }
413
 
414
            if ($browser['nav'] && $subVersion < .79) {
415
                Net_UserAgent_Detect::setQuirk('nested_table_render_bug');
416
            }
417
        }
418
 
419
        // Set features
420
        if ($detectFlags[NET_USERAGENT_DETECT_ALL] ||
421
            ($detectFlags[NET_USERAGENT_DETECT_BROWSER] && $detectFlags[NET_USERAGENT_DETECT_FEATURES])) {
422
            if ($browser['gecko'] && preg_match(';gecko/([\d]+)\b;i', $agt, $matches)) {
423
                Net_UserAgent_Detect::setFeature('gecko', $matches[1]);
424
            }
425
 
426
            if ($browser['gecko'] || ($browser['ie5up'] && !$browser['iemobile']) || $browser['konq'] || $browser['opera8up'] && !$os['wince']) {
427
                Net_UserAgent_Detect::setFeature('ajax');
428
            }
429
 
430
            if ($browser['ns6up'] || $browser['opera5up'] || $browser['konq'] || $browser['netgem']) {
431
                Net_UserAgent_Detect::setFeature('dom');
432
            }
433
 
434
            if ($browser['ie4up'] || $browser['ns4up'] || $browser['opera5up'] || $browser['konq'] || $browser['netgem']) {
435
                Net_UserAgent_Detect::setFeature('dhtml');
436
            }
437
 
438
            if ($browser['firefox1.5'] || $browser['firefox2.x'] || $browser['opera9up']) {
439
                Net_UserAgent_Detect::setFeature('svg');
440
            }
441
 
442
            if ($browser['gecko'] || $browser['ns6up'] || $browser['ie5up'] || $browser['konq'] || $browser['opera7up']) {
443
                Net_UserAgent_Detect::setFeature('css2');
444
            }
445
        }
446
 
447
        if ($detectFlags[NET_USERAGENT_DETECT_ALL] || $detectFlags[NET_USERAGENT_DETECT_ACCEPT]) {
448
            $mimetypes = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT'), 0, strpos(getenv('HTTP_ACCEPT') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY);
449
            Net_UserAgent_Detect::setAcceptType((array) $mimetypes, 'mimetype');
450
 
451
            $languages = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT_LANGUAGE'), 0, strpos(getenv('HTTP_ACCEPT_LANGUAGE') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY);
452
            if (empty($languages)) {
453
                $languages = 'en';
454
            }
455
 
456
            Net_UserAgent_Detect::setAcceptType((array) $languages, 'language');
457
 
458
            $encodings = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT_ENCODING'), 0, strpos(getenv('HTTP_ACCEPT_ENCODING') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY);
459
            Net_UserAgent_Detect::setAcceptType((array) $encodings, 'encoding');
460
 
461
            $charsets = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT_CHARSET'), 0, strpos(getenv('HTTP_ACCEPT_CHARSET') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY);
462
            Net_UserAgent_Detect::setAcceptType((array) $charsets, 'charset');
463
        }
464
    }
465
 
466
    // }}}
467
    // {{{ setOption()
468
 
469
    /**
470
     * Sets a class option.  The available settings are:
471
     * o 'userAgent' => The user agent string to detect (useful for
472
     * checking a string manually).
473
     * o 'detectOptions' => The level of checking to do.  A single level
474
     * or an array of options.  Default is NET_USERAGENT_DETECT_ALL.
475
     *
476
     * @param string $in_field The option field (userAgent or detectOptions)
477
     * @param mixed $in_value The value for the field
478
     */
479
    function setOption($in_field, $in_value)
480
    {
481
        $options = &Net_UserAgent_Detect::_getStaticProperty('options');
482
        $options[$in_field] = $in_value;
483
    }
484
 
485
    // }}}
486
    // {{{ isBrowser()
487
 
488
    /**
489
     * Look up the provide browser flag and return a boolean value
490
     *
491
     * Given one of the flags listed in the properties, this function will return
492
     * the value associated with that flag.
493
     *
494
     * @param  string $in_match flag to lookup
495
     *
496
     * @access public
497
     * @return boolean whether or not the browser satisfies this flag
498
     */
499
    function isBrowser($in_match)
500
    {
501
        Net_UserAgent_Detect::detect();
502
        $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
503
        return isset($browser[strtolower($in_match)]) ? $browser[strtolower($in_match)] : false;
504
    }
505
 
506
    // }}}
507
    // {{{ getBrowser()
508
 
509
    /**
510
     * Since simply returning the "browser" is somewhat ambiguous since there
511
     * are different ways to classify the browser, this function works by taking
512
     * an expect list and returning the string of the first match, so put the important
513
     * ones first in the array.
514
     *
515
     * @param  array $in_expectList the browser flags to search for
516
     *
517
     * @access public
518
     * @return string first flag that matches
519
     */
520
    function getBrowser($in_expectList)
521
    {
522
        Net_UserAgent_Detect::detect();
523
        $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
524
        foreach((array) $in_expectList as $brwsr) {
525
            if (!empty($browser[strtolower($brwsr)])) {
526
                return $brwsr;
527
            }
528
        }
529
    }
530
 
531
    // }}}
532
    // {{{ getBrowserString()
533
 
534
    /**
535
     * This function returns the vendor string corresponding to the flag.
536
     *
537
     * Either use the default matches or pass in an associative array of
538
     * flags and corresponding vendor strings.  This function will find
539
     * the highest version flag and return the vendor string corresponding
540
     * to the appropriate flag.  Be sure to pass in the flags in ascending order
541
     * if you want a basic matches first, followed by more detailed matches.
542
     *
543
     * @param  array $in_vendorStrings (optional) array of flags matched with vendor strings
544
     *
545
     * @access public
546
     * @return string vendor string matches appropriate flag
547
     */
548
    function getBrowserString($in_vendorStrings = null)
549
    {
550
        if (is_null($in_vendorStrings)) {
551
            $in_vendorStrings = array (
552
                    'ie'       => 'Microsoft Internet Explorer',
553
                    'ie4up'    => 'Microsoft Internet Explorer 4.x',
554
                    'ie5up'    => 'Microsoft Internet Explorer 5.x',
555
                    'ie6up'    => 'Microsoft Internet Explorer 6.x',
556
                    'ie7up'    => 'Microsoft Internet Explorer 7.x',
557
                    'ie8up'    => 'Microsoft Internet Explorer 8.x',
558
                    'ie8tr'    => 'Microsoft Internet Explorer 8.x (Compatibility View)',
559
                    'ie9up'    => 'Microsoft Internet Explorer 9.x',
560
                    'opera4'   => 'Opera 4.x',
561
                    'opera5up' => 'Opera 5.x',
562
                    'nav'      => 'Netscape Navigator',
563
                    'ns4'      => 'Netscape 4.x',
564
                    'ns6up'    => 'Mozilla/Netscape 6.x',
565
                    'firefox0.x' => 'Firefox 0.x',
566
                    'firefox1.x' => 'Firefox 1.x',
567
                    'firefox1.5' => 'Firefox 1.5',
568
                    'firefox2.x' => 'Firefox 2.x',
569
                    'firefox3.x' => 'Firefox 3.x',
570
                    'konq'     => 'Konqueror',
571
                    'safari'   => 'Safari',
572
                    'safari_mobile'     => 'Safari Mobile',
573
                    'chrome'   => 'Google Chrome',
574
                    'netgem'   => 'Netgem/iPlayer');
575
        }
576
 
577
        Net_UserAgent_Detect::detect();
578
        $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
579
        foreach((array) $in_vendorStrings as $flag => $string) {
580
            if (!empty($browser[$flag])) {
581
                $vendorString = $string;
582
            }
583
        }
584
 
585
        // if there are no matches just use the user agent leading idendifier (usually Mozilla)
586
        if (!isset($vendorString)) {
587
            $leadingIdentifier = &Net_UserAgent_Detect::_getStaticProperty('leadingIdentifier');
588
            $vendorString = $leadingIdentifier;
589
        }
590
 
591
        return $vendorString;
592
    }
593
 
594
    // }}}
595
    // {{{ isIE()
596
 
597
    /**
598
     * Determine if the browser is an Internet Explorer browser
599
     *
600
     * @access public
601
     * @return bool whether or not this browser is an ie browser
602
     */
603
    function isIE()
604
    {
605
        Net_UserAgent_Detect::detect();
606
        $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
607
        return !empty($browser['ie']);
608
    }
609
 
610
    // }}}
611
    // {{{ isNavigator()
612
 
613
    /**
614
     * Determine if the browser is a Netscape Navigator browser
615
     *
616
     * @access public
617
     * @return bool whether or not this browser is a Netscape Navigator browser
618
     */
619
    function isNavigator()
620
    {
621
        Net_UserAgent_Detect::detect();
622
        $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
623
        return !empty($browser['nav']);
624
    }
625
 
626
    // }}}
627
    // {{{ isNetscape()
628
 
629
    /**
630
     * Determine if the browser is a Netscape or Mozilla browser
631
     *
632
     * Note that this function is not the same as isNavigator, since the
633
     * new Mozilla browsers are still sponsered by Netscape, and hence are
634
     * Netscape products, but not the original Navigators
635
     *
636
     * @access public
637
     * @return bool whether or not this browser is a Netscape product
638
     */
639
    function isNetscape()
640
    {
641
        Net_UserAgent_Detect::detect();
642
        $browser = &Net_UserAgent_Detect::_getStaticProperty('browser');
643
        return !empty($browser['ns4up']);
644
    }
645
 
646
    // }}}
647
    // {{{ isOS()
648
 
649
    /**
650
     * Look up the provide OS flag and return a boolean value
651
     *
652
     * Given one of the flags listed in the properties, this function will return
653
     * the value associated with that flag for the operating system.
654
     *
655
     * @param  string $in_match flag to lookup
656
     *
657
     * @access public
658
     * @return boolean whether or not the OS satisfies this flag
659
     */
660
    function isOS($in_match)
661
    {
662
        Net_UserAgent_Detect::detect();
663
        $os = &Net_UserAgent_Detect::_getStaticProperty('os');
664
        return isset($os[strtolower($in_match)]) ? $os[strtolower($in_match)] : false;
665
    }
666
 
667
    // }}}
668
    // {{{ getOS()
669
 
670
    /**
671
     * Since simply returning the "os" is somewhat ambiguous since there
672
     * are different ways to classify the browser, this function works by taking
673
     * an expect list and returning the string of the first match, so put the important
674
     * ones first in the array.
675
     *
676
     * @access public
677
     * @return string first flag that matches
678
     */
679
    function getOS($in_expectList)
680
    {
681
        Net_UserAgent_Detect::detect();
682
        $os = &Net_UserAgent_Detect::_getStaticProperty('os');
683
        foreach((array) $in_expectList as $expectOs) {
684
            if (!empty($os[strtolower($expectOs)])) {
685
                return $expectOs;
686
            }
687
        }
688
    }
689
 
690
    // }}}
691
    // {{{ getOSString()
692
 
693
    /**
694
     * This function returns the os string corresponding to the flag.
695
     *
696
     * Either use the default matches or pass in an associative array of
697
     * flags and corresponding os strings.  This function will find
698
     * the highest version flag and return the os string corresponding
699
     * to the appropriate flag.  Be sure to pass in the flags in ascending order
700
     * if you want a basic matches first, followed by more detailed matches.
701
     *
702
     * @param  array $in_osStrings (optional) array of flags matched with os strings
703
     *
704
     * @access public
705
     * @return string os string matches appropriate flag
706
     */
707
    function getOSString($in_osStrings = null)
708
    {
709
        if (is_null($in_osStrings)) {
710
            $in_osStrings = array(
711
                   'win'   => 'Microsoft Windows',
712
                   'wince' => 'Microsoft Windows CE',
713
                   'win9x' => 'Microsoft Windows 9x',
714
                   'winme' => 'Microsoft Windows Millenium',
715
                   'win2k' => 'Microsoft Windows 2000',
716
                   'winnt' => 'Microsoft Windows NT',
717
                   'winxp' => 'Microsoft Windows XP',
718
                   'win2003' => 'Microsoft Windows 2003',
719
                   'vista' => 'Microsoft Windows Vista',
720
                   'win7' => 'Microsoft Windows 7',
721
                   'mac'   => 'Macintosh',
722
                   'mactiger' => 'OS X Tiger (10.4)',
723
                   'macleopard' => 'OS X Leopard (10.5)',
724
                   'macsnowleopard' => 'OS X Snow Leopard (10.6)',
725
                   'iphone' => 'iPhone',
726
                   'os2' => 'OS/2',
727
                   'unix'  => 'Linux/Unix');
728
        }
729
 
730
        Net_UserAgent_Detect::detect();
731
        $osString = 'Unknown';
732
 
733
        $os = &Net_UserAgent_Detect::_getStaticProperty('os');
734
        foreach((array) $in_osStrings as $flag => $string) {
735
            if (!empty($os[$flag])) {
736
                $osString = $string;
737
            }
738
        }
739
 
740
        return $osString;
741
    }
742
 
743
    // }}}
744
    // {{{ setQuirk()
745
 
746
    /**
747
     * Set a unique behavior for the current browser.
748
     *
749
     * Many client browsers do some really funky things, and this
750
     * mechanism allows the coder to determine if an excepetion must
751
     * be made with the current client.
752
     *
753
     * @param string $in_quirk The quirk to set
754
     * @param string $in_hasQuirk (optional) Does the browser have the quirk?
755
     *
756
     * @access public
757
     * @return void
758
     */
759
    function setQuirk($in_quirk, $in_hasQuirk = true)
760
    {
761
        $quirks = &Net_UserAgent_Detect::_getStaticProperty('quirks');
762
        $hasQuirk = !empty($in_hasQuirk);
763
        $quirks[strtolower($in_quirk)] = $hasQuirk;
764
    }
765
 
766
    // }}}
767
    // {{{ hasQuirk()
768
 
769
    /**
770
     * Check a unique behavior for the current browser.
771
     *
772
     * Many client browsers do some really funky things, and this
773
     * mechanism allows the coder to determine if an excepetion must
774
     * be made with the current client.
775
     *
776
     * @param string $in_quirk The quirk to detect
777
     *
778
     * @access public
779
     * @return bool whether or not browser has this quirk
780
     */
781
    function hasQuirk($in_quirk)
782
    {
783
        return (bool) Net_UserAgent_Detect::getQuirk($in_quirk);
784
    }
785
 
786
    // }}}
787
    // {{{ getQuirk()
788
 
789
    /**
790
     * Get the unique behavior for the current browser.
791
     *
792
     * Many client browsers do some really funky things, and this
793
     * mechanism allows the coder to determine if an excepetion must
794
     * be made with the current client.
795
     *
796
     * @param string $in_quirk The quirk to detect
797
     *
798
     * @access public
799
     * @return string value of the quirk, in this case usually a boolean
800
     */
801
    function getQuirk($in_quirk)
802
    {
803
        Net_UserAgent_Detect::detect();
804
        $quirks = &Net_UserAgent_Detect::_getStaticProperty('quirks');
805
        return isset($quirks[strtolower($in_quirk)]) ? $quirks[strtolower($in_quirk)] : null;
806
    }
807
 
808
    // }}}
809
    // {{{ setFeature()
810
 
811
    /**
812
     * Set capabilities for the current browser.
813
     *
814
     * Since the capabilities of client browsers vary widly, this interface
815
     * helps keep track of the core features of a client, such as if the client
816
     * supports dhtml, dom, javascript, etc.
817
     *
818
     * @param string $in_feature The feature to set
819
     * @param string $in_hasFeature (optional) Does the browser have the feature?
820
     *
821
     * @access public
822
     * @return void
823
     */
824
    function setFeature($in_feature, $in_hasFeature = true)
825
    {
826
        $features = &Net_UserAgent_Detect::_getStaticProperty('features');
827
        $features[strtolower($in_feature)] = $in_hasFeature;
828
    }
829
 
830
    // }}}
831
    // {{{ hasFeature()
832
 
833
    /**
834
     * Check the capabilities for the current browser.
835
     *
836
     * Since the capabilities of client browsers vary widly, this interface
837
     * helps keep track of the core features of a client, such as if the client
838
     * supports dhtml, dom, javascript, etc.
839
     *
840
     * @param string $in_feature The feature to detect
841
     *
842
     * @access public
843
     * @return bool whether or not the current client has this feature
844
     */
845
    function hasFeature($in_feature)
846
    {
847
        return (bool) Net_UserAgent_Detect::getFeature($in_feature);
848
    }
849
 
850
    // }}}
851
    // {{{ getFeature()
852
 
853
    /**
854
     * Get the capabilities for the current browser.
855
     *
856
     * Since the capabilities of client browsers vary widly, this interface
857
     * helps keep track of the core features of a client, such as if the client
858
     * supports dhtml, dom, javascript, etc.
859
     *
860
     * @param string $in_feature The feature to detect
861
     *
862
     * @access public
863
     * @return string value of the feature requested
864
     */
865
    function getFeature($in_feature)
866
    {
867
        Net_UserAgent_Detect::detect();
868
        $features = &Net_UserAgent_Detect::_getStaticProperty('features');
869
        return isset($features[strtolower($in_feature)]) ? $features[strtolower($in_feature)] : null;
870
    }
871
 
872
    // }}}
873
    // {{{ getAcceptType()
874
 
875
    /**
876
     * Retrive the accept type for the current browser.
877
     *
878
     * To keep track of the mime-types, languages, charsets and encodings
879
     * that each browser accepts we use associative arrays for each type.
880
     * This function works like getBrowser() as it takes an expect list
881
     * and returns the first match.  For instance, to find the language
882
     * you would pass in your allowed languages and see if any of the
883
     * languages set in the browser match.
884
     *
885
     * @param  string $in_expectList values to check
886
     * @param  string $in_type type of accept
887
     *
888
     * @access public
889
     * @return string the first matched value
890
     */
891
    function getAcceptType($in_expectList, $in_type)
892
    {
893
        Net_UserAgent_Detect::detect();
894
        $type = strtolower($in_type);
895
 
896
        if ($type == 'mimetype' || $type == 'language' || $type == 'charset' || $type == 'encoding') {
897
            $typeArray = &Net_UserAgent_Detect::_getStaticProperty($type);
898
            foreach((array) $in_expectList as $match) {
899
                if (!empty($typeArray[$match])) {
900
                    return $match;
901
                }
902
            }
903
        }
904
 
905
        return null;
906
    }
907
 
908
    // }}}
909
    // {{{ setAcceptType()
910
 
911
    /**
912
     * Set the accept types for the current browser.
913
     *
914
     * To keep track of the mime-types, languages, charsets and encodings
915
     * that each browser accepts we use associative arrays for each type.
916
     * This function takes and array of accepted values for the type and
917
     * records them for retrieval.
918
     *
919
     * @param  array $in_values values of the accept type
920
     * @param  string $in_type type of accept
921
     *
922
     * @access public
923
     * @return void
924
     */
925
    function setAcceptType($in_values, $in_type)
926
    {
927
        $type = strtolower($in_type);
928
 
929
        if ($type == 'mimetype' || $type == 'language' || $type == 'charset' || $type == 'encoding') {
930
            $typeArray = &Net_UserAgent_Detect::_getStaticProperty($type);
931
            foreach((array) $in_values as $value) {
932
                $typeArray[$value] = true;
933
            }
934
        }
935
    }
936
 
937
    // }}}
938
    // {{{ hasAcceptType()
939
 
940
    /**
941
     * Check the accept types for the current browser.
942
     *
943
     * To keep track of the mime-types, languages, charsets and encodings
944
     * that each browser accepts we use associative arrays for each type.
945
     * This function checks the array for the given type and determines if
946
     * the browser accepts it.
947
     *
948
     * @param  string $in_value values to check
949
     * @param  string $in_type type of accept
950
     *
951
     * @access public
952
     * @return bool whether or not the value is accept for this type
953
     */
954
    function hasAcceptType($in_value, $in_type)
955
    {
956
        return (bool) Net_UserAgent_Detect::getAcceptType((array) $in_value, $in_type);
957
    }
958
 
959
    // }}}
960
    // {{{ getUserAgent()
961
 
962
    /**
963
     * Return the user agent string that is being worked on
964
     *
965
     * @access public
966
     * @return string user agent
967
     */
968
    function getUserAgent()
969
    {
970
        Net_UserAgent_Detect::detect();
971
        $userAgent = &Net_UserAgent_Detect::_getStaticProperty('userAgent');
972
        return $userAgent;
973
    }
974
 
975
    // }}}
976
    // {{{ _getStaticProperty()
977
 
978
    /**
979
     * Copy of getStaticProperty() from PEAR.php to avoid having to
980
     * include PEAR.php
981
     *
982
     * @access private
983
     * @param  string $var    The variable to retrieve.
984
     * @return mixed   A reference to the variable. If not set it will be
985
     *                 auto initialised to NULL.
986
     */
987
    function &_getStaticProperty($var)
988
    {
989
        static $properties;
990
        return $properties[$var];
991
    }
992
 
993
    // }}}
994
}
995
?>