File indexing completed on 2024-12-22 05:36:47
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Http 0017 * @subpackage UserAgent 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 */ 0021 0022 // require_once 'Zend/Http/UserAgent/Device.php'; 0023 0024 /** 0025 * Abstract Class to define a browser device. 0026 * 0027 * @category Zend 0028 * @package Zend_Http 0029 * @subpackage UserAgent 0030 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0031 * @license http://framework.zend.com/license/new-bsd New BSD License 0032 */ 0033 abstract class Zend_Http_UserAgent_AbstractDevice 0034 implements Zend_Http_UserAgent_Device 0035 { 0036 /** 0037 * Browser signature 0038 * 0039 * @var string 0040 */ 0041 protected $_browser = ''; 0042 0043 /** 0044 * Browser version 0045 * 0046 * @var string 0047 */ 0048 protected $_browserVersion = ''; 0049 0050 /** 0051 * Configuration 0052 * 0053 * @var array 0054 */ 0055 protected $_config; 0056 0057 /** 0058 * User Agent chain 0059 * 0060 * @var string 0061 */ 0062 protected $_userAgent; 0063 0064 /** 0065 * Server variable 0066 * 0067 * @var array 0068 */ 0069 protected $_server; 0070 0071 /** 0072 * Image types 0073 * 0074 * @var array 0075 */ 0076 protected $_images = array( 0077 'jpeg', 0078 'gif', 0079 'png', 0080 'pjpeg', 0081 'x-png', 0082 'bmp', 0083 ); 0084 0085 /** 0086 * Browser/Device features 0087 * 0088 * @var array 0089 */ 0090 protected $_aFeatures = array(); 0091 0092 /** 0093 * Browser/Device features groups 0094 * 0095 * @var array 0096 */ 0097 protected $_aGroup = array(); 0098 0099 /** 0100 * Constructor 0101 * 0102 * @param null|string|array $userAgent If array, restores from serialized version 0103 * @param array $server 0104 * @param array $config 0105 * @return void 0106 */ 0107 public function __construct($userAgent = null, array $server = array(), array $config = array()) 0108 { 0109 if (is_array($userAgent)) { 0110 // Restoring from serialized array 0111 $this->_restoreFromArray($userAgent); 0112 } else { 0113 // Constructing new object 0114 $this->setUserAgent($userAgent); 0115 $this->_server = $server; 0116 $this->_config = $config; 0117 $this->_getDefaultFeatures(); 0118 $this->_defineFeatures(); 0119 } 0120 } 0121 0122 /** 0123 * Serialize object 0124 * 0125 * @return string 0126 */ 0127 public function serialize() 0128 { 0129 $spec = array( 0130 '_aFeatures' => $this->_aFeatures, 0131 '_aGroup' => $this->_aGroup, 0132 '_browser' => $this->_browser, 0133 '_browserVersion' => $this->_browserVersion, 0134 '_userAgent' => $this->_userAgent, 0135 '_images' => $this->_images, 0136 ); 0137 return serialize($spec); 0138 } 0139 0140 /** 0141 * Unserialize 0142 * 0143 * @param string $serialized 0144 * @return void 0145 */ 0146 public function unserialize($serialized) 0147 { 0148 $spec = unserialize($serialized); 0149 $this->_restoreFromArray($spec); 0150 } 0151 0152 /** 0153 * Restore object state from array 0154 * 0155 * @param array $spec 0156 * @return void 0157 */ 0158 protected function _restoreFromArray(array $spec) 0159 { 0160 foreach ($spec as $key => $value) { 0161 if (property_exists($this, $key)) { 0162 $this->{$key} = $value; 0163 } 0164 } 0165 } 0166 0167 /** 0168 * Look for features 0169 * 0170 * @return array|null 0171 */ 0172 protected function _defineFeatures() 0173 { 0174 $features = $this->_loadFeaturesAdapter(); 0175 0176 if (is_array($features)) { 0177 $this->_aFeatures = array_merge($this->_aFeatures, $features); 0178 } 0179 0180 return $this->_aFeatures; 0181 } 0182 0183 /** 0184 * Gets the browser type identifier 0185 * 0186 * @return string 0187 */ 0188 abstract public function getType(); 0189 0190 /** 0191 * Check a feature for the current browser/device. 0192 * 0193 * @param string $feature The feature to check. 0194 * @return bool 0195 */ 0196 public function hasFeature($feature) 0197 { 0198 return (isset($this->_aFeatures[$feature]) && !is_null($this->_aFeatures[$feature])); 0199 } 0200 0201 /** 0202 * Gets the value of the current browser/device feature 0203 * 0204 * @param string $feature Feature to search 0205 * @return string|null 0206 */ 0207 public function getFeature($feature) 0208 { 0209 if ($this->hasFeature($feature)) { 0210 return $this->_aFeatures[$feature]; 0211 } 0212 } 0213 0214 /** 0215 * Set a feature for the current browser/device. 0216 * 0217 * @param string $feature The feature to set. 0218 * @param string $value (option) feature value. 0219 * @param string $group (option) Group to associate with the feature 0220 * @return Zend_Http_UserAgent_AbstractDevice 0221 */ 0222 public function setFeature($feature, $value = false, $group = '') 0223 { 0224 $this->_aFeatures[$feature] = $value; 0225 if (!empty($group)) { 0226 $this->setGroup($group, $feature); 0227 } 0228 return $this; 0229 } 0230 0231 /** 0232 * Affects a feature to a group 0233 * 0234 * @param string $group Group name 0235 * @param string $feature Feature name 0236 * @return Zend_Http_UserAgent_AbstractDevice 0237 */ 0238 public function setGroup($group, $feature) 0239 { 0240 if (!isset($this->_aGroup[$group])) { 0241 $this->_aGroup[$group] = array(); 0242 } 0243 if (!in_array($feature, $this->_aGroup[$group])) { 0244 $this->_aGroup[$group][] = $feature; 0245 } 0246 return $this; 0247 } 0248 0249 /** 0250 * Gets an array of features associated to a group 0251 * 0252 * @param string $group Group param 0253 * @return array 0254 */ 0255 public function getGroup($group) 0256 { 0257 return $this->_aGroup[$group]; 0258 } 0259 0260 /** 0261 * Gets all the browser/device features 0262 * 0263 * @return array 0264 */ 0265 public function getAllFeatures() 0266 { 0267 return $this->_aFeatures; 0268 } 0269 0270 /** 0271 * Gets all the browser/device features' groups 0272 * 0273 * @return array 0274 */ 0275 public function getAllGroups() 0276 { 0277 return $this->_aGroup; 0278 } 0279 0280 /** 0281 * Sets all the standard features extracted from the User Agent chain and $this->_server 0282 * vars 0283 * 0284 * @return void 0285 */ 0286 protected function _getDefaultFeatures() 0287 { 0288 $server = array(); 0289 0290 // gets info from user agent chain 0291 $uaExtract = $this->extractFromUserAgent($this->getUserAgent()); 0292 0293 if (is_array($uaExtract)) { 0294 foreach ($uaExtract as $key => $info) { 0295 $this->setFeature($key, $info, 'product_info'); 0296 } 0297 } 0298 0299 if (isset($uaExtract['browser_name'])) { 0300 $this->_browser = $uaExtract['browser_name']; 0301 } 0302 if (isset($uaExtract['browser_version'])) { 0303 $this->_browserVersion = $uaExtract['browser_version']; 0304 } 0305 if (isset($uaExtract['device_os'])) { 0306 $this->device_os = $uaExtract['device_os_name']; 0307 } 0308 0309 /* browser & device info */ 0310 $this->setFeature('is_wireless_device', false, 'product_info'); 0311 $this->setFeature('is_mobile', false, 'product_info'); 0312 $this->setFeature('is_desktop', false, 'product_info'); 0313 $this->setFeature('is_tablet', false, 'product_info'); 0314 $this->setFeature('is_bot', false, 'product_info'); 0315 $this->setFeature('is_email', false, 'product_info'); 0316 $this->setFeature('is_text', false, 'product_info'); 0317 $this->setFeature('device_claims_web_support', false, 'product_info'); 0318 0319 $this->setFeature('is_' . strtolower($this->getType()), true, 'product_info'); 0320 0321 /* sets the browser name */ 0322 if (isset($this->list) && empty($this->_browser)) { 0323 $lowerUserAgent = strtolower($this->getUserAgent()); 0324 foreach ($this->list as $browser_signature) { 0325 if (strpos($lowerUserAgent, $browser_signature) !== false) { 0326 $this->_browser = strtolower($browser_signature); 0327 $this->setFeature('browser_name', $this->_browser, 'product_info'); 0328 } 0329 } 0330 } 0331 0332 /* sets the client IP */ 0333 if (isset($this->_server['remote_addr'])) { 0334 $this->setFeature('client_ip', $this->_server['remote_addr'], 'product_info'); 0335 } elseif (isset($this->_server['http_x_forwarded_for'])) { 0336 $this->setFeature('client_ip', $this->_server['http_x_forwarded_for'], 'product_info'); 0337 } elseif (isset($this->_server['http_client_ip'])) { 0338 $this->setFeature('client_ip', $this->_server['http_client_ip'], 'product_info'); 0339 } 0340 0341 /* sets the server infos */ 0342 if (isset($this->_server['server_software'])) { 0343 if (strpos($this->_server['server_software'], 'Apache') !== false || strpos($this->_server['server_software'], 'LiteSpeed') !== false) { 0344 $server['version'] = 1; 0345 if (strpos($this->_server['server_software'], 'Apache/2') !== false) { 0346 $server['version'] = 2; 0347 } 0348 $server['server'] = 'apache'; 0349 } 0350 0351 if (strpos($this->_server['server_software'], 'Microsoft-IIS') !== false) { 0352 $server['server'] = 'iis'; 0353 } 0354 0355 if (strpos($this->_server['server_software'], 'Unix') !== false) { 0356 $server['os'] = 'unix'; 0357 if (isset($_ENV['MACHTYPE'])) { 0358 if (strpos($_ENV['MACHTYPE'], 'linux') !== false) { 0359 $server['os'] = 'linux'; 0360 } 0361 } 0362 } elseif (strpos($this->_server['server_software'], 'Win') !== false) { 0363 $server['os'] = 'windows'; 0364 } 0365 0366 if (preg_match('/Apache\/([0-9\.]*)/', $this->_server['server_software'], $arr)) { 0367 if ($arr[1]) { 0368 $server['version'] = $arr[1]; 0369 $server['server'] = 'apache'; 0370 } 0371 } 0372 } 0373 0374 $this->setFeature('php_version', phpversion(), 'server_info'); 0375 if (isset($server['server'])) { 0376 $this->setFeature('server_os', $server['server'], 'server_info'); 0377 } 0378 if (isset($server['version'])) { 0379 $this->setFeature('server_os_version', $server['version'], 'server_info'); 0380 } 0381 if (isset($this->_server['http_accept'])) { 0382 $this->setFeature('server_http_accept', $this->_server['http_accept'], 'server_info'); 0383 } 0384 if (isset($this->_server['http_accept_language'])) { 0385 $this->setFeature('server_http_accept_language', $this->_server['http_accept_language'], 'server_info'); 0386 } 0387 if (isset($this->_server['server_addr'])) { 0388 $this->setFeature('server_ip', $this->_server['server_addr'], 'server_info'); 0389 } 0390 if (isset($this->_server['server_name'])) { 0391 $this->setFeature('server_name', $this->_server['server_name'], 'server_info'); 0392 } 0393 } 0394 0395 /** 0396 * Extract and sets informations from the User Agent chain 0397 * 0398 * @param string $userAgent User Agent chain 0399 * @return array 0400 */ 0401 public static function extractFromUserAgent($userAgent) 0402 { 0403 $userAgent = trim($userAgent); 0404 0405 /** 0406 * @see http://www.texsoft.it/index.php?c=software&m=sw.php.useragent&l=it 0407 */ 0408 $pattern = "(([^/\s]*)(/(\S*))?)(\s*\[[a-zA-Z][a-zA-Z]\])?\s*(\\((([^()]|(\\([^()]*\\)))*)\\))?\s*"; 0409 preg_match("#^$pattern#", $userAgent, $match); 0410 0411 $comment = array(); 0412 if (isset($match[7])) { 0413 $comment = explode(';', $match[7]); 0414 } 0415 0416 // second part if exists 0417 $end = substr($userAgent, strlen($match[0])); 0418 if (!empty($end)) { 0419 $result['others']['full'] = $end; 0420 } 0421 0422 $match2 = array(); 0423 if (isset($result['others'])) { 0424 preg_match_all('/(([^\/\s]*)(\/)?([^\/\(\)\s]*)?)(\s\((([^\)]*)*)\))?/i', $result['others']['full'], $match2); 0425 } 0426 $result['user_agent'] = trim($match[1]); 0427 $result['product_name'] = isset($match[2]) ? trim($match[2]) : ''; 0428 $result['browser_name'] = $result['product_name']; 0429 if (isset($match[4]) && trim($match[4])) { 0430 $result['product_version'] = trim($match[4]); 0431 $result['browser_version'] = trim($match[4]); 0432 } 0433 if (count($comment) && !empty($comment[0])) { 0434 $result['comment']['full'] = trim($match[7]); 0435 $result['comment']['detail'] = $comment; 0436 $result['compatibility_flag'] = trim($comment[0]); 0437 if (isset($comment[1])) { 0438 $result['browser_token'] = trim($comment[1]); 0439 } 0440 if (isset($comment[2])) { 0441 $result['device_os_token'] = trim($comment[2]); 0442 } 0443 } 0444 if (empty($result['device_os_token']) && !empty($result['compatibility_flag'])) { 0445 // some browsers do not have a platform token 0446 $result['device_os_token'] = $result['compatibility_flag']; 0447 } 0448 if ($match2) { 0449 $i = 0; 0450 $max = count($match2[0]); 0451 for ($i = 0; $i < $max; $i ++) { 0452 if (!empty($match2[0][$i])) { 0453 $result['others']['detail'][] = array( 0454 $match2[0][$i], 0455 $match2[2][$i], 0456 $match2[4][$i], 0457 ); 0458 } 0459 } 0460 } 0461 0462 /** Security level */ 0463 $security = array( 0464 'N' => 'no security', 0465 'U' => 'strong security', 0466 'I' => 'weak security', 0467 ); 0468 if (!empty($result['browser_token'])) { 0469 if (isset($security[$result['browser_token']])) { 0470 $result['security_level'] = $security[$result['browser_token']]; 0471 unset($result['browser_token']); 0472 } 0473 } 0474 0475 $product = strtolower($result['browser_name']); 0476 0477 // Mozilla : true && false 0478 $compatibleOrIe = false; 0479 if (isset($result['compatibility_flag']) && isset($result['comment'])) { 0480 $compatibleOrIe = ($result['compatibility_flag'] == 'compatible' || strpos($result['comment']['full'], "MSIE") !== false); 0481 } 0482 if ($product == 'mozilla' && $compatibleOrIe) { 0483 if (!empty($result['browser_token'])) { 0484 // Classic Mozilla chain 0485 preg_match_all('/([^\/\s].*)(\/|\s)(.*)/i', $result['browser_token'], $real); 0486 } else { 0487 // MSIE specific chain with 'Windows' compatibility flag 0488 foreach ($result['comment']['detail'] as $v) { 0489 if (strpos($v, 'MSIE') !== false) { 0490 $real[0][1] = trim($v); 0491 $result['browser_engine'] = "MSIE"; 0492 $real[1][0] = "Internet Explorer"; 0493 $temp = explode(' ', trim($v)); 0494 $real[3][0] = $temp[1]; 0495 0496 } 0497 if (strpos($v, 'Win') !== false) { 0498 $result['device_os_token'] = trim($v); 0499 } 0500 } 0501 } 0502 0503 if (!empty($real[0])) { 0504 $result['browser_name'] = $real[1][0]; 0505 $result['browser_version'] = $real[3][0]; 0506 } else { 0507 if(isset($result['browser_token'])) { 0508 $result['browser_name'] = $result['browser_token']; 0509 } 0510 $result['browser_version'] = '??'; 0511 } 0512 } elseif ($product == 'mozilla' && isset($result['browser_version']) 0513 && $result['browser_version'] < 5.0 0514 ) { 0515 // handles the real Mozilla (or old Netscape if version < 5.0) 0516 $result['browser_name'] = 'Netscape'; 0517 } 0518 0519 /** windows */ 0520 if ($result['browser_name'] == 'MSIE') { 0521 $result['browser_engine'] = 'MSIE'; 0522 $result['browser_name'] = 'Internet Explorer'; 0523 } 0524 if (isset($result['device_os_token'])) { 0525 if (strpos($result['device_os_token'], 'Win') !== false) { 0526 0527 $windows = array( 0528 'Windows NT 6.1' => 'Windows 7', 0529 'Windows NT 6.0' => 'Windows Vista', 0530 'Windows NT 5.2' => 'Windows Server 2003', 0531 'Windows NT 5.1' => 'Windows XP', 0532 'Windows NT 5.01' => 'Windows 2000 SP1', 0533 'Windows NT 5.0' => 'Windows 2000', 0534 'Windows NT 4.0' => 'Microsoft Windows NT 4.0', 0535 'WinNT' => 'Microsoft Windows NT 4.0', 0536 'Windows 98; Win 9x 4.90' => 'Windows Me', 0537 'Windows 98' => 'Windows 98', 0538 'Win98' => 'Windows 98', 0539 'Windows 95' => 'Windows 95', 0540 'Win95' => 'Windows 95', 0541 'Windows CE' => 'Windows CE', 0542 ); 0543 if (isset($windows[$result['device_os_token']])) { 0544 $result['device_os_name'] = $windows[$result['device_os_token']]; 0545 } else { 0546 $result['device_os_name'] = $result['device_os_token']; 0547 } 0548 } 0549 } 0550 0551 // iphone 0552 $apple_device = array( 0553 'iPhone', 0554 'iPod', 0555 'iPad', 0556 ); 0557 if (isset($result['compatibility_flag'])) { 0558 if (in_array($result['compatibility_flag'], $apple_device)) { 0559 $result['device'] = strtolower($result['compatibility_flag']); 0560 $result['device_os_token'] = 'iPhone OS'; 0561 if (isset($comment[3])) { 0562 $result['browser_language'] = trim($comment[3]); 0563 } 0564 if (isset($result['others']['detail'][1])) { 0565 $result['browser_version'] = $result['others']['detail'][1][2]; 0566 } elseif (isset($result['others']['detail']) && count($result['others']['detail'])) { 0567 $result['browser_version'] = $result['others']['detail'][0][2]; 0568 } 0569 if (!empty($result['others']['detail'][2])) { 0570 $result['firmware'] = $result['others']['detail'][2][2]; 0571 } 0572 if (!empty($result['others']['detail'][3])) { 0573 $result['browser_name'] = $result['others']['detail'][3][1]; 0574 $result['browser_build'] = $result['others']['detail'][3][2]; 0575 } 0576 } 0577 } 0578 0579 // Safari 0580 if (isset($result['others'])) { 0581 if ($result['others']['detail'][0][1] == 'AppleWebKit') { 0582 $result['browser_engine'] = 'AppleWebKit'; 0583 if (isset($result['others']['detail'][1]) && $result['others']['detail'][1][1] == 'Version') { 0584 $result['browser_version'] = $result['others']['detail'][1][2]; 0585 } else { 0586 $result['browser_version'] = $result['others']['detail'][count($result['others']['detail']) - 1][2]; 0587 } 0588 if (isset($comment[3])) { 0589 $result['browser_language'] = trim($comment[3]); 0590 } 0591 0592 $last = $result['others']['detail'][count($result['others']['detail']) - 1][1]; 0593 0594 if (empty($result['others']['detail'][2][1]) || $result['others']['detail'][2][1] == 'Safari') { 0595 if (isset($result['others']['detail'][1])) { 0596 $result['browser_name'] = ($result['others']['detail'][1][1] && $result['others']['detail'][1][1] != 'Version' ? $result['others']['detail'][1][1] : 'Safari'); 0597 $result['browser_version'] = ($result['others']['detail'][1][2] ? $result['others']['detail'][1][2] : $result['others']['detail'][0][2]); 0598 } else { 0599 $result['browser_name'] = ($result['others']['detail'][0][1] && $result['others']['detail'][0][1] != 'Version' ? $result['others']['detail'][0][1] : 'Safari'); 0600 $result['browser_version'] = $result['others']['detail'][0][2]; 0601 } 0602 } else { 0603 $result['browser_name'] = $result['others']['detail'][2][1]; 0604 $result['browser_version'] = $result['others']['detail'][2][2]; 0605 0606 // mobile version 0607 if ($result['browser_name'] == 'Mobile') { 0608 $result['browser_name'] = 'Safari ' . $result['browser_name']; 0609 if ($result['others']['detail'][1][1] == 'Version') { 0610 $result['browser_version'] = $result['others']['detail'][1][2]; 0611 } 0612 } 0613 } 0614 0615 // For Safari < 2.2, AppleWebKit version gives the Safari version 0616 if (strpos($result['browser_version'], '.') > 2 || (int) $result['browser_version'] > 20) { 0617 $temp = explode('.', $result['browser_version']); 0618 $build = (int) $temp[0]; 0619 $awkVersion = array( 0620 48 => '0.8', 0621 73 => '0.9', 0622 85 => '1.0', 0623 103 => '1.1', 0624 124 => '1.2', 0625 300 => '1.3', 0626 400 => '2.0', 0627 ); 0628 foreach ($awkVersion as $k => $v) { 0629 if ($build >= $k) { 0630 $result['browser_version'] = $v; 0631 } 0632 } 0633 } 0634 } 0635 0636 // Gecko (Firefox or compatible) 0637 if ($result['others']['detail'][0][1] == 'Gecko') { 0638 $searchRV = true; 0639 if (!empty($result['others']['detail'][1][1]) && !empty($result['others']['detail'][count($result['others']['detail']) - 1][2]) || strpos(strtolower($result['others']['full']), 'opera') !== false) { 0640 $searchRV = false; 0641 $result['browser_engine'] = $result['others']['detail'][0][1]; 0642 0643 // the name of the application is at the end indepenently 0644 // of quantity of information in $result['others']['detail'] 0645 $last = count($result['others']['detail']) - 1; 0646 0647 // exception : if the version of the last information is 0648 // empty we take the previous one 0649 if (empty($result['others']['detail'][$last][2])) { 0650 $last --; 0651 } 0652 0653 // exception : if the last one is 'Red Hat' or 'Debian' => 0654 // use rv: to find browser_version */ 0655 if (in_array($result['others']['detail'][$last][1], array( 0656 'Debian', 0657 'Hat', 0658 ))) { 0659 $searchRV = true; 0660 } 0661 $result['browser_name'] = $result['others']['detail'][$last][1]; 0662 $result['browser_version'] = $result['others']['detail'][$last][2]; 0663 if (isset($comment[4])) { 0664 $result['browser_build'] = trim($comment[4]); 0665 } 0666 if (isset($comment[3])) { 0667 $result['browser_language'] = trim($comment[3]); 0668 } 0669 0670 // Netscape 0671 if ($result['browser_name'] == 'Navigator' || $result['browser_name'] == 'Netscape6') { 0672 $result['browser_name'] = 'Netscape'; 0673 } 0674 } 0675 if ($searchRV) { 0676 // Mozilla alone : the version is identified by rv: 0677 $result['browser_name'] = 'Mozilla'; 0678 if (isset($result['comment']['detail'])) { 0679 foreach ($result['comment']['detail'] as $rv) { 0680 if (strpos($rv, 'rv:') !== false) { 0681 $result['browser_version'] = trim(str_replace('rv:', '', $rv)); 0682 } 0683 } 0684 } 0685 } 0686 } 0687 0688 // Netscape 0689 if ($result['others']['detail'][0][1] == 'Netscape') { 0690 $result['browser_name'] = 'Netscape'; 0691 $result['browser_version'] = $result['others']['detail'][0][2]; 0692 } 0693 0694 // Opera 0695 // Opera: engine Presto 0696 if ($result['others']['detail'][0][1] == 'Presto') { 0697 $result['browser_engine'] = 'Presto'; 0698 if (!empty($result['others']['detail'][1][2])) { 0699 $result['browser_version'] = $result['others']['detail'][1][2]; 0700 } 0701 } 0702 0703 // UA ends with 'Opera X.XX' or 'Opera/X.XX' 0704 if ($result['others']['detail'][0][1] == 'Opera') { 0705 $result['browser_name'] = $result['others']['detail'][0][1]; 0706 // Opera X.XX 0707 if (isset($result['others']['detail'][1][1])) { 0708 $result['browser_version'] = $result['others']['detail'][1][1]; 0709 // Opera/X.XX 0710 } elseif (isset($result['others']['detail'][0][2])) { 0711 $result['browser_version'] = $result['others']['detail'][0][2]; 0712 } 0713 } 0714 0715 // Opera Mini 0716 if (isset($result["browser_token"])) { 0717 if (strpos($result["browser_token"], 'Opera Mini') !== false) { 0718 $result['browser_name'] = 'Opera Mini'; 0719 } 0720 } 0721 0722 // Symbian 0723 if ($result['others']['detail'][0][1] == 'SymbianOS') { 0724 $result['device_os_token'] = 'SymbianOS'; 0725 } 0726 } 0727 0728 // UA ends with 'Opera X.XX' 0729 if (isset($result['browser_name']) && isset($result['browser_engine'])) { 0730 if ($result['browser_name'] == 'Opera' && $result['browser_engine'] == 'Gecko' && empty($result['browser_version'])) { 0731 $result['browser_version'] = $result['others']['detail'][count($result['others']['detail']) - 1][1]; 0732 } 0733 } 0734 0735 // cleanup 0736 if (isset($result['browser_version']) && isset($result['browser_build'])) { 0737 if ($result['browser_version'] == $result['browser_build']) { 0738 unset($result['browser_build']); 0739 } 0740 } 0741 0742 // compatibility 0743 $compatibility['AppleWebKit'] = 'Safari'; 0744 $compatibility['Gecko'] = 'Firefox'; 0745 $compatibility['MSIE'] = 'Internet Explorer'; 0746 $compatibility['Presto'] = 'Opera'; 0747 if (!empty($result['browser_engine'])) { 0748 if (isset($compatibility[$result['browser_engine']])) { 0749 $result['browser_compatibility'] = $compatibility[$result['browser_engine']]; 0750 } 0751 } 0752 0753 ksort($result); 0754 return $result; 0755 } 0756 0757 /** 0758 * Loads the Features Adapter if it's defined in the $config array 0759 * Otherwise, nothing is done 0760 * 0761 * @param string $browserType Browser type 0762 * @return array 0763 */ 0764 protected function _loadFeaturesAdapter() 0765 { 0766 $config = $this->_config; 0767 $browserType = $this->getType(); 0768 if (!isset($config[$browserType]) || !isset($config[$browserType]['features'])) { 0769 return array(); 0770 } 0771 $config = $config[$browserType]['features']; 0772 0773 if (empty($config['classname'])) { 0774 // require_once 'Zend/Http/UserAgent/Exception.php'; 0775 throw new Zend_Http_UserAgent_Exception('The ' . $this->getType() . ' features adapter must have a "classname" config parameter defined'); 0776 } 0777 0778 $className = $config['classname']; 0779 if (!class_exists($className)) { 0780 if (isset($config['path'])) { 0781 $path = $config['path']; 0782 } else { 0783 // require_once 'Zend/Http/UserAgent/Exception.php'; 0784 throw new Zend_Http_UserAgent_Exception('The ' . $this->getType() . ' features adapter must have a "path" config parameter defined'); 0785 } 0786 0787 if (false === include_once ($path)) { 0788 // require_once 'Zend/Http/UserAgent/Exception.php'; 0789 throw new Zend_Http_UserAgent_Exception('The ' . $this->getType() . ' features adapter path that does not exist'); 0790 } 0791 } 0792 0793 return call_user_func(array($className, 'getFromRequest'), $this->_server, $this->_config); 0794 } 0795 0796 /** 0797 * Retrieve image format support 0798 * 0799 * @return array 0800 */ 0801 public function getImageFormatSupport() 0802 { 0803 return $this->_images; 0804 } 0805 0806 /** 0807 * Get maximum image height supported by this device 0808 * 0809 * @return int 0810 */ 0811 public function getMaxImageHeight() 0812 { 0813 return null; 0814 } 0815 0816 /** 0817 * Get maximum image width supported by this device 0818 * 0819 * @return int 0820 */ 0821 public function getMaxImageWidth() 0822 { 0823 return null; 0824 } 0825 0826 /** 0827 * Get physical screen height of this device 0828 * 0829 * @return int 0830 */ 0831 public function getPhysicalScreenHeight() 0832 { 0833 return null; 0834 } 0835 0836 /** 0837 * Get physical screen width of this device 0838 * 0839 * @return int 0840 */ 0841 public function getPhysicalScreenWidth() 0842 { 0843 return null; 0844 } 0845 0846 /** 0847 * Get preferred markup type 0848 * 0849 * @return string 0850 */ 0851 public function getPreferredMarkup() 0852 { 0853 return 'xhtml'; 0854 } 0855 0856 /** 0857 * Get supported X/HTML version 0858 * 0859 * @return int 0860 */ 0861 public function getXhtmlSupportLevel() 0862 { 0863 return 4; 0864 } 0865 0866 /** 0867 * Does the device support Flash? 0868 * 0869 * @return bool 0870 */ 0871 public function hasFlashSupport() 0872 { 0873 return true; 0874 } 0875 0876 /** 0877 * Does the device support PDF? 0878 * 0879 * @return bool 0880 */ 0881 public function hasPdfSupport() 0882 { 0883 return true; 0884 } 0885 0886 /** 0887 * Does the device have a phone number associated with it? 0888 * 0889 * @return bool 0890 */ 0891 public function hasPhoneNumber() 0892 { 0893 return false; 0894 } 0895 0896 /** 0897 * Does the device support HTTPS? 0898 * 0899 * @return bool 0900 */ 0901 public function httpsSupport() 0902 { 0903 return true; 0904 } 0905 0906 /** 0907 * Get the browser type 0908 * 0909 * @return string 0910 */ 0911 public function getBrowser() 0912 { 0913 return $this->_browser; 0914 } 0915 0916 /** 0917 * Get the browser version 0918 * 0919 * @return string 0920 */ 0921 public function getBrowserVersion() 0922 { 0923 return $this->_browserVersion; 0924 } 0925 0926 /** 0927 * Get the user agent string 0928 * 0929 * @return string 0930 */ 0931 public function getUserAgent() 0932 { 0933 return $this->_userAgent; 0934 } 0935 0936 /** 0937 * @return the $_images 0938 */ 0939 public function getImages() 0940 { 0941 return $this->_images; 0942 } 0943 0944 /** 0945 * @param string $browser 0946 */ 0947 public function setBrowser($browser) 0948 { 0949 $this->_browser = $browser; 0950 } 0951 0952 /** 0953 * @param string $browserVersion 0954 */ 0955 public function setBrowserVersion($browserVersion) 0956 { 0957 $this->_browserVersion = $browserVersion; 0958 } 0959 0960 /** 0961 * @param string $userAgent 0962 */ 0963 public function setUserAgent($userAgent) 0964 { 0965 $this->_userAgent = $userAgent; 0966 return $this; 0967 } 0968 0969 /** 0970 * @param array $_images 0971 */ 0972 public function setImages($_images) 0973 { 0974 $this->_images = $_images; 0975 } 0976 0977 /** 0978 * Match a user agent string against a list of signatures 0979 * 0980 * @param string $userAgent 0981 * @param array $signatures 0982 * @return bool 0983 */ 0984 protected static function _matchAgentAgainstSignatures($userAgent, $signatures) 0985 { 0986 $userAgent = strtolower($userAgent); 0987 foreach ($signatures as $signature) { 0988 if (!empty($signature)) { 0989 if (strpos($userAgent, $signature) !== false) { 0990 // Browser signature was found in user agent string 0991 return true; 0992 } 0993 } 0994 } 0995 return false; 0996 } 0997 }