975 Zeilen
31 KiB
PHP
975 Zeilen
31 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Zend Framework
|
||
|
*
|
||
|
* LICENSE
|
||
|
*
|
||
|
* This source file is subject to the new BSD license that is bundled
|
||
|
* with this package in the file LICENSE.txt.
|
||
|
* It is also available through the world-wide-web at this URL:
|
||
|
* http://framework.zend.com/license/new-bsd
|
||
|
* If you did not receive a copy of the license and are unable to
|
||
|
* obtain it through the world-wide-web, please send an email
|
||
|
* to license@zend.com so we can send you a copy immediately.
|
||
|
*
|
||
|
* @category Zend
|
||
|
* @package Zend_Http
|
||
|
* @subpackage UserAgent
|
||
|
* @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
|
||
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||
|
*/
|
||
|
|
||
|
require_once 'Zend/Http/UserAgent/Device.php';
|
||
|
|
||
|
/**
|
||
|
* Abstract Class to define a browser device.
|
||
|
*
|
||
|
* @category Zend
|
||
|
* @package Zend_Http
|
||
|
* @subpackage UserAgent
|
||
|
* @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
|
||
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||
|
*/
|
||
|
abstract class Zend_Http_UserAgent_AbstractDevice
|
||
|
implements Zend_Http_UserAgent_Device
|
||
|
{
|
||
|
/**
|
||
|
* Browser signature
|
||
|
*
|
||
|
* @var string
|
||
|
*/
|
||
|
protected $_browser = '';
|
||
|
|
||
|
/**
|
||
|
* Browser version
|
||
|
*
|
||
|
* @var string
|
||
|
*/
|
||
|
protected $_browserVersion = '';
|
||
|
|
||
|
/**
|
||
|
* Configuration
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $_config;
|
||
|
|
||
|
/**
|
||
|
* User Agent chain
|
||
|
*
|
||
|
* @var string
|
||
|
*/
|
||
|
protected $_userAgent;
|
||
|
|
||
|
/**
|
||
|
* Server variable
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $_server;
|
||
|
|
||
|
/**
|
||
|
* Image types
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $_images = array(
|
||
|
'jpeg',
|
||
|
'gif',
|
||
|
'png',
|
||
|
'pjpeg',
|
||
|
'x-png',
|
||
|
'bmp',
|
||
|
);
|
||
|
|
||
|
/**
|
||
|
* Browser/Device features
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $_aFeatures = array();
|
||
|
|
||
|
/**
|
||
|
* Browser/Device features groups
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $_aGroup = array();
|
||
|
|
||
|
/**
|
||
|
* Constructor
|
||
|
*
|
||
|
* @param null|string|array $userAgent If array, restores from serialized version
|
||
|
* @param array $server
|
||
|
* @param array $config
|
||
|
* @return void
|
||
|
*/
|
||
|
public function __construct($userAgent = null, array $server = array(), array $config = array())
|
||
|
{
|
||
|
if (is_array($userAgent)) {
|
||
|
// Restoring from serialized array
|
||
|
$this->_restoreFromArray($userAgent);
|
||
|
} else {
|
||
|
// Constructing new object
|
||
|
$this->setUserAgent($userAgent);
|
||
|
$this->_server = $server;
|
||
|
$this->_config = $config;
|
||
|
$this->_getDefaultFeatures();
|
||
|
$this->_defineFeatures();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Serialize object
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function serialize()
|
||
|
{
|
||
|
$spec = array(
|
||
|
'_aFeatures' => $this->_aFeatures,
|
||
|
'_aGroup' => $this->_aGroup,
|
||
|
'_browser' => $this->_browser,
|
||
|
'_browserVersion' => $this->_browserVersion,
|
||
|
'_userAgent' => $this->_userAgent,
|
||
|
'_images' => $this->_images,
|
||
|
);
|
||
|
return serialize($spec);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Unserialize
|
||
|
*
|
||
|
* @param string $serialized
|
||
|
* @return void
|
||
|
*/
|
||
|
public function unserialize($serialized)
|
||
|
{
|
||
|
$spec = unserialize($serialized);
|
||
|
$this->_restoreFromArray($spec);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Restore object state from array
|
||
|
*
|
||
|
* @param array $spec
|
||
|
* @return void
|
||
|
*/
|
||
|
protected function _restoreFromArray(array $spec)
|
||
|
{
|
||
|
foreach ($spec as $key => $value) {
|
||
|
if (property_exists($this, $key)) {
|
||
|
$this->{$key} = $value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Look for features
|
||
|
*
|
||
|
* @return array|null
|
||
|
*/
|
||
|
protected function _defineFeatures()
|
||
|
{
|
||
|
$features = $this->_loadFeaturesAdapter();
|
||
|
|
||
|
if (is_array($features)) {
|
||
|
$this->_aFeatures = array_merge($this->_aFeatures, $features);
|
||
|
}
|
||
|
|
||
|
return $this->_aFeatures;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets the browser type identifier
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
abstract public function getType();
|
||
|
|
||
|
/**
|
||
|
* Check a feature for the current browser/device.
|
||
|
*
|
||
|
* @param string $feature The feature to check.
|
||
|
* @return bool
|
||
|
*/
|
||
|
public function hasFeature($feature)
|
||
|
{
|
||
|
return (!empty($this->_aFeatures[$feature]));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets the value of the current browser/device feature
|
||
|
*
|
||
|
* @param string $feature Feature to search
|
||
|
* @return string|null
|
||
|
*/
|
||
|
public function getFeature($feature)
|
||
|
{
|
||
|
if ($this->hasFeature($feature)) {
|
||
|
return $this->_aFeatures[$feature];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set a feature for the current browser/device.
|
||
|
*
|
||
|
* @param string $feature The feature to set.
|
||
|
* @param string $value (option) feature value.
|
||
|
* @param string $group (option) Group to associate with the feature
|
||
|
* @return Zend_Http_UserAgent_AbstractDevice
|
||
|
*/
|
||
|
public function setFeature($feature, $value = false, $group = '')
|
||
|
{
|
||
|
$this->_aFeatures[$feature] = $value;
|
||
|
if (!empty($group)) {
|
||
|
$this->setGroup($group, $feature);
|
||
|
}
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Affects a feature to a group
|
||
|
*
|
||
|
* @param string $group Group name
|
||
|
* @param string $feature Feature name
|
||
|
* @return Zend_Http_UserAgent_AbstractDevice
|
||
|
*/
|
||
|
public function setGroup($group, $feature)
|
||
|
{
|
||
|
if (!isset($this->_aGroup[$group])) {
|
||
|
$this->_aGroup[$group] = array();
|
||
|
}
|
||
|
if (!in_array($feature, $this->_aGroup[$group])) {
|
||
|
$this->_aGroup[$group][] = $feature;
|
||
|
}
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets an array of features associated to a group
|
||
|
*
|
||
|
* @param string $group Group param
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getGroup($group)
|
||
|
{
|
||
|
return $this->_aGroup[$group];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets all the browser/device features
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getAllFeatures()
|
||
|
{
|
||
|
return $this->_aFeatures;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets all the browser/device features' groups
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getAllGroups()
|
||
|
{
|
||
|
return $this->_aGroup;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets all the standard features extracted from the User Agent chain and $this->_server
|
||
|
* vars
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
protected function _getDefaultFeatures()
|
||
|
{
|
||
|
$server = array();
|
||
|
|
||
|
// gets info from user agent chain
|
||
|
$uaExtract = $this->extractFromUserAgent($this->getUserAgent());
|
||
|
|
||
|
if (is_array($uaExtract)) {
|
||
|
foreach ($uaExtract as $key => $info) {
|
||
|
$this->setFeature($key, $info, 'product_info');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (isset($uaExtract['browser_name'])) {
|
||
|
$this->_browser = $uaExtract['browser_name'];
|
||
|
}
|
||
|
if (isset($uaExtract['browser_version'])) {
|
||
|
$this->_browserVersion = $uaExtract['browser_version'];
|
||
|
}
|
||
|
if (isset($uaExtract['device_os'])) {
|
||
|
$this->device_os = $uaExtract['device_os_name'];
|
||
|
}
|
||
|
|
||
|
/* browser & device info */
|
||
|
$this->setFeature('is_wireless_device', false, 'product_info');
|
||
|
$this->setFeature('is_mobile', false, 'product_info');
|
||
|
$this->setFeature('is_desktop', false, 'product_info');
|
||
|
$this->setFeature('is_tablet', false, 'product_info');
|
||
|
$this->setFeature('is_bot', false, 'product_info');
|
||
|
$this->setFeature('is_email', false, 'product_info');
|
||
|
$this->setFeature('is_text', false, 'product_info');
|
||
|
$this->setFeature('device_claims_web_support', false, 'product_info');
|
||
|
|
||
|
$this->setFeature('is_' . strtolower($this->getType()), true, 'product_info');
|
||
|
|
||
|
/* sets the browser name */
|
||
|
if (isset($this->list) && empty($this->_browser)) {
|
||
|
$lowerUserAgent = strtolower($this->getUserAgent());
|
||
|
foreach ($this->list as $browser_signature) {
|
||
|
if (strpos($lowerUserAgent, $browser_signature) !== false) {
|
||
|
$this->_browser = strtolower($browser_signature);
|
||
|
$this->setFeature('browser_name', $this->_browser, 'product_info');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* sets the client IP */
|
||
|
if (isset($this->_server['remote_addr'])) {
|
||
|
$this->setFeature('client_ip', $this->_server['remote_addr'], 'product_info');
|
||
|
} elseif (isset($this->_server['http_x_forwarded_for'])) {
|
||
|
$this->setFeature('client_ip', $this->_server['http_x_forwarded_for'], 'product_info');
|
||
|
} elseif (isset($this->_server['http_client_ip'])) {
|
||
|
$this->setFeature('client_ip', $this->_server['http_client_ip'], 'product_info');
|
||
|
}
|
||
|
|
||
|
/* sets the server infos */
|
||
|
if (isset($this->_server['server_software'])) {
|
||
|
if (strpos($this->_server['server_software'], 'Apache') !== false || strpos($this->_server['server_software'], 'LiteSpeed') !== false) {
|
||
|
$server['version'] = 1;
|
||
|
if (strpos($this->_server['server_software'], 'Apache/2') !== false) {
|
||
|
$server['version'] = 2;
|
||
|
}
|
||
|
$server['server'] = 'apache';
|
||
|
}
|
||
|
|
||
|
if (strpos($this->_server['server_software'], 'Microsoft-IIS') !== false) {
|
||
|
$server['server'] = 'iis';
|
||
|
}
|
||
|
|
||
|
if (strpos($this->_server['server_software'], 'Unix') !== false) {
|
||
|
$server['os'] = 'unix';
|
||
|
if (isset($_ENV['MACHTYPE'])) {
|
||
|
if (strpos($_ENV['MACHTYPE'], 'linux') !== false) {
|
||
|
$server['os'] = 'linux';
|
||
|
}
|
||
|
}
|
||
|
} elseif (strpos($this->_server['server_software'], 'Win') !== false) {
|
||
|
$server['os'] = 'windows';
|
||
|
}
|
||
|
|
||
|
if (preg_match('/Apache\/([0-9\.]*)/', $this->_server['server_software'], $arr)) {
|
||
|
if ($arr[1]) {
|
||
|
$server['version'] = $arr[1];
|
||
|
$server['server'] = 'apache';
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$this->setFeature('php_version', phpversion(), 'server_info');
|
||
|
if (isset($server['server'])) {
|
||
|
$this->setFeature('server_os', $server['server'], 'server_info');
|
||
|
}
|
||
|
if (isset($server['version'])) {
|
||
|
$this->setFeature('server_os_version', $server['version'], 'server_info');
|
||
|
}
|
||
|
if (isset($this->_server['http_accept'])) {
|
||
|
$this->setFeature('server_http_accept', $this->_server['http_accept'], 'server_info');
|
||
|
}
|
||
|
if (isset($this->_server['http_accept_language'])) {
|
||
|
$this->setFeature('server_http_accept_language', $this->_server['http_accept_language'], 'server_info');
|
||
|
}
|
||
|
if (isset($this->_server['server_addr'])) {
|
||
|
$this->setFeature('server_ip', $this->_server['server_addr'], 'server_info');
|
||
|
}
|
||
|
if (isset($this->_server['server_name'])) {
|
||
|
$this->setFeature('server_name', $this->_server['server_name'], 'server_info');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Extract and sets informations from the User Agent chain
|
||
|
*
|
||
|
* @param string $userAgent User Agent chain
|
||
|
* @return array
|
||
|
*/
|
||
|
public static function extractFromUserAgent($userAgent)
|
||
|
{
|
||
|
$userAgent = trim($userAgent);
|
||
|
|
||
|
/**
|
||
|
* @see http://www.texsoft.it/index.php?c=software&m=sw.php.useragent&l=it
|
||
|
*/
|
||
|
$pattern = "(([^/\s]*)(/(\S*))?)(\s*\[[a-zA-Z][a-zA-Z]\])?\s*(\\((([^()]|(\\([^()]*\\)))*)\\))?\s*";
|
||
|
preg_match("#^$pattern#", $userAgent, $match);
|
||
|
|
||
|
$comment = array();
|
||
|
if (isset($match[7])) {
|
||
|
$comment = explode(';', $match[7]);
|
||
|
}
|
||
|
|
||
|
// second part if exists
|
||
|
$end = substr($userAgent, strlen($match[0]));
|
||
|
if (!empty($end)) {
|
||
|
$result['others']['full'] = $end;
|
||
|
}
|
||
|
|
||
|
$match2 = array();
|
||
|
if (isset($result['others'])) {
|
||
|
preg_match_all('/(([^\/\s]*)(\/)?([^\/\(\)\s]*)?)(\s\((([^\)]*)*)\))?/i', $result['others']['full'], $match2);
|
||
|
}
|
||
|
$result['user_agent'] = trim($match[1]);
|
||
|
$result['product_name'] = isset($match[2]) ? trim($match[2]) : '';
|
||
|
$result['browser_name'] = $result['product_name'];
|
||
|
if (isset($match[4]) && trim($match[4])) {
|
||
|
$result['product_version'] = trim($match[4]);
|
||
|
$result['browser_version'] = trim($match[4]);
|
||
|
}
|
||
|
if (count($comment) && !empty($comment[0])) {
|
||
|
$result['comment']['full'] = trim($match[7]);
|
||
|
$result['comment']['detail'] = $comment;
|
||
|
$result['compatibility_flag'] = trim($comment[0]);
|
||
|
if (isset($comment[1])) {
|
||
|
$result['browser_token'] = trim($comment[1]);
|
||
|
}
|
||
|
if (isset($comment[2])) {
|
||
|
$result['device_os_token'] = trim($comment[2]);
|
||
|
}
|
||
|
}
|
||
|
if (empty($result['device_os_token']) && !empty($result['compatibility_flag'])) {
|
||
|
// some browsers do not have a platform token
|
||
|
$result['device_os_token'] = $result['compatibility_flag'];
|
||
|
}
|
||
|
if ($match2) {
|
||
|
$i = 0;
|
||
|
$max = count($match2[0]);
|
||
|
for ($i = 0; $i < $max; $i ++) {
|
||
|
if (!empty($match2[0][$i])) {
|
||
|
$result['others']['detail'][] = array(
|
||
|
$match2[0][$i],
|
||
|
$match2[2][$i],
|
||
|
$match2[4][$i],
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Security level */
|
||
|
$security = array(
|
||
|
'N' => 'no security',
|
||
|
'U' => 'strong security',
|
||
|
'I' => 'weak security',
|
||
|
);
|
||
|
if (!empty($result['browser_token'])) {
|
||
|
if (isset($security[$result['browser_token']])) {
|
||
|
$result['security_level'] = $security[$result['browser_token']];
|
||
|
unset($result['browser_token']);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$product = strtolower($result['browser_name']);
|
||
|
|
||
|
// Mozilla : true && false
|
||
|
$compatibleOrIe = false;
|
||
|
if (isset($result['compatibility_flag']) && isset($result['comment'])) {
|
||
|
$compatibleOrIe = ($result['compatibility_flag'] == 'compatible' || strpos($result['comment']['full'], "MSIE") !== false);
|
||
|
}
|
||
|
if ($product == 'mozilla' && $compatibleOrIe) {
|
||
|
if (!empty($result['browser_token'])) {
|
||
|
// Classic Mozilla chain
|
||
|
preg_match_all('/([^\/\s].*)(\/|\s)(.*)/i', $result['browser_token'], $real);
|
||
|
} else {
|
||
|
// MSIE specific chain with 'Windows' compatibility flag
|
||
|
foreach ($result['comment']['detail'] as $v) {
|
||
|
if (strpos($v, 'MSIE') !== false) {
|
||
|
$real[0][1] = trim($v);
|
||
|
$result['browser_engine'] = "MSIE";
|
||
|
$real[1][0] = "Internet Explorer";
|
||
|
$temp = explode(' ', trim($v));
|
||
|
$real[3][0] = $temp[1];
|
||
|
|
||
|
}
|
||
|
if (strpos($v, 'Win') !== false) {
|
||
|
$result['device_os_token'] = trim($v);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!empty($real[0])) {
|
||
|
$result['browser_name'] = $real[1][0];
|
||
|
$result['browser_version'] = $real[3][0];
|
||
|
} else {
|
||
|
$result['browser_name'] = $result['browser_token'];
|
||
|
$result['browser_version'] = '??';
|
||
|
}
|
||
|
} elseif ($product == 'mozilla' && $result['browser_version'] < 5.0) {
|
||
|
// handles the real Mozilla (or old Netscape if version < 5.0)
|
||
|
$result['browser_name'] = 'Netscape';
|
||
|
}
|
||
|
|
||
|
/** windows */
|
||
|
if ($result['browser_name'] == 'MSIE') {
|
||
|
$result['browser_engine'] = 'MSIE';
|
||
|
$result['browser_name'] = 'Internet Explorer';
|
||
|
}
|
||
|
if (isset($result['device_os_token'])) {
|
||
|
if (strpos($result['device_os_token'], 'Win') !== false) {
|
||
|
|
||
|
$windows = array(
|
||
|
'Windows NT 6.1' => 'Windows 7',
|
||
|
'Windows NT 6.0' => 'Windows Vista',
|
||
|
'Windows NT 5.2' => 'Windows Server 2003',
|
||
|
'Windows NT 5.1' => 'Windows XP',
|
||
|
'Windows NT 5.01' => 'Windows 2000 SP1',
|
||
|
'Windows NT 5.0' => 'Windows 2000',
|
||
|
'Windows NT 4.0' => 'Microsoft Windows NT 4.0',
|
||
|
'WinNT' => 'Microsoft Windows NT 4.0',
|
||
|
'Windows 98; Win 9x 4.90' => 'Windows Me',
|
||
|
'Windows 98' => 'Windows 98',
|
||
|
'Win98' => 'Windows 98',
|
||
|
'Windows 95' => 'Windows 95',
|
||
|
'Win95' => 'Windows 95',
|
||
|
'Windows CE' => 'Windows CE',
|
||
|
);
|
||
|
if (isset($windows[$result['device_os_token']])) {
|
||
|
$result['device_os_name'] = $windows[$result['device_os_token']];
|
||
|
} else {
|
||
|
$result['device_os_name'] = $result['device_os_token'];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// iphone
|
||
|
$apple_device = array(
|
||
|
'iPhone',
|
||
|
'iPod',
|
||
|
'iPad',
|
||
|
);
|
||
|
if (isset($result['compatibility_flag'])) {
|
||
|
if (in_array($result['compatibility_flag'], $apple_device)) {
|
||
|
$result['device'] = strtolower($result['compatibility_flag']);
|
||
|
$result['device_os_token'] = 'iPhone OS';
|
||
|
$result['browser_language'] = trim($comment[3]);
|
||
|
$result['browser_version'] = $result['others']['detail'][1][2];
|
||
|
if (!empty($result['others']['detail'][2])) {
|
||
|
$result['firmware'] = $result['others']['detail'][2][2];
|
||
|
}
|
||
|
if (!empty($result['others']['detail'][3])) {
|
||
|
$result['browser_name'] = $result['others']['detail'][3][1];
|
||
|
$result['browser_build'] = $result['others']['detail'][3][2];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Safari
|
||
|
if (isset($result['others'])) {
|
||
|
if ($result['others']['detail'][0][1] == 'AppleWebKit') {
|
||
|
$result['browser_engine'] = 'AppleWebKit';
|
||
|
if ($result['others']['detail'][1][1] == 'Version') {
|
||
|
$result['browser_version'] = $result['others']['detail'][1][2];
|
||
|
} else {
|
||
|
$result['browser_version'] = $result['others']['detail'][count($result['others']['detail']) - 1][2];
|
||
|
}
|
||
|
if (isset($comment[3])) {
|
||
|
$result['browser_language'] = trim($comment[3]);
|
||
|
}
|
||
|
|
||
|
$last = $result['others']['detail'][count($result['others']['detail']) - 1][1];
|
||
|
|
||
|
if (empty($result['others']['detail'][2][1]) || $result['others']['detail'][2][1] == 'Safari') {
|
||
|
$result['browser_name'] = ($result['others']['detail'][1][1] && $result['others']['detail'][1][1] != 'Version' ? $result['others']['detail'][1][1] : 'Safari');
|
||
|
$result['browser_version'] = ($result['others']['detail'][1][2] ? $result['others']['detail'][1][2] : $result['others']['detail'][0][2]);
|
||
|
} else {
|
||
|
$result['browser_name'] = $result['others']['detail'][2][1];
|
||
|
$result['browser_version'] = $result['others']['detail'][2][2];
|
||
|
|
||
|
// mobile version
|
||
|
if ($result['browser_name'] == 'Mobile') {
|
||
|
$result['browser_name'] = 'Safari ' . $result['browser_name'];
|
||
|
if ($result['others']['detail'][1][1] == 'Version') {
|
||
|
$result['browser_version'] = $result['others']['detail'][1][2];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// For Safari < 2.2, AppleWebKit version gives the Safari version
|
||
|
if (strpos($result['browser_version'], '.') > 2 || (int) $result['browser_version'] > 20) {
|
||
|
$temp = explode('.', $result['browser_version']);
|
||
|
$build = (int) $temp[0];
|
||
|
$awkVersion = array(
|
||
|
48 => '0.8',
|
||
|
73 => '0.9',
|
||
|
85 => '1.0',
|
||
|
103 => '1.1',
|
||
|
124 => '1.2',
|
||
|
300 => '1.3',
|
||
|
400 => '2.0',
|
||
|
);
|
||
|
foreach ($awkVersion as $k => $v) {
|
||
|
if ($build >= $k) {
|
||
|
$result['browser_version'] = $v;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Gecko (Firefox or compatible)
|
||
|
if ($result['others']['detail'][0][1] == 'Gecko') {
|
||
|
$searchRV = true;
|
||
|
if (!empty($result['others']['detail'][1][1]) && !empty($result['others']['detail'][count($result['others']['detail']) - 1][2]) || strpos(strtolower($result['others']['full']), 'opera') !== false) {
|
||
|
$searchRV = false;
|
||
|
$result['browser_engine'] = $result['others']['detail'][0][1];
|
||
|
|
||
|
// the name of the application is at the end indepenently
|
||
|
// of quantity of information in $result['others']['detail']
|
||
|
$last = count($result['others']['detail']) - 1;
|
||
|
|
||
|
// exception : if the version of the last information is
|
||
|
// empty we take the previous one
|
||
|
if (empty($result['others']['detail'][$last][2])) {
|
||
|
$last --;
|
||
|
}
|
||
|
|
||
|
// exception : if the last one is 'Red Hat' or 'Debian' =>
|
||
|
// use rv: to find browser_version */
|
||
|
if (in_array($result['others']['detail'][$last][1], array(
|
||
|
'Debian',
|
||
|
'Hat',
|
||
|
))) {
|
||
|
$searchRV = true;
|
||
|
}
|
||
|
$result['browser_name'] = $result['others']['detail'][$last][1];
|
||
|
$result['browser_version'] = $result['others']['detail'][$last][2];
|
||
|
if (isset($comment[4])) {
|
||
|
$result['browser_build'] = trim($comment[4]);
|
||
|
}
|
||
|
$result['browser_language'] = trim($comment[3]);
|
||
|
|
||
|
// Netscape
|
||
|
if ($result['browser_name'] == 'Navigator' || $result['browser_name'] == 'Netscape6') {
|
||
|
$result['browser_name'] = 'Netscape';
|
||
|
}
|
||
|
}
|
||
|
if ($searchRV) {
|
||
|
// Mozilla alone : the version is identified by rv:
|
||
|
$result['browser_name'] = 'Mozilla';
|
||
|
if (isset($result['comment']['detail'])) {
|
||
|
foreach ($result['comment']['detail'] as $rv) {
|
||
|
if (strpos($rv, 'rv:') !== false) {
|
||
|
$result['browser_version'] = trim(str_replace('rv:', '', $rv));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Netscape
|
||
|
if ($result['others']['detail'][0][1] == 'Netscape') {
|
||
|
$result['browser_name'] = 'Netscape';
|
||
|
$result['browser_version'] = $result['others']['detail'][0][2];
|
||
|
}
|
||
|
|
||
|
// Opera
|
||
|
// Opera: engine Presto
|
||
|
if ($result['others']['detail'][0][1] == 'Presto') {
|
||
|
$result['browser_engine'] = 'Presto';
|
||
|
if (!empty($result['others']['detail'][1][2])) {
|
||
|
$result['browser_version'] = $result['others']['detail'][1][2];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// UA ends with 'Opera X.XX'
|
||
|
if ($result['others']['detail'][0][1] == 'Opera') {
|
||
|
$result['browser_name'] = $result['others']['detail'][0][1];
|
||
|
$result['browser_version'] = $result['others']['detail'][1][1];
|
||
|
}
|
||
|
|
||
|
// Opera Mini
|
||
|
if (isset($result["browser_token"])) {
|
||
|
if (strpos($result["browser_token"], 'Opera Mini') !== false) {
|
||
|
$result['browser_name'] = 'Opera Mini';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Symbian
|
||
|
if ($result['others']['detail'][0][1] == 'SymbianOS') {
|
||
|
$result['device_os_token'] = 'SymbianOS';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// UA ends with 'Opera X.XX'
|
||
|
if (isset($result['browser_name']) && isset($result['browser_engine'])) {
|
||
|
if ($result['browser_name'] == 'Opera' && $result['browser_engine'] == 'Gecko' && empty($result['browser_version'])) {
|
||
|
$result['browser_version'] = $result['others']['detail'][count($result['others']['detail']) - 1][1];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// cleanup
|
||
|
if (isset($result['browser_version']) && isset($result['browser_build'])) {
|
||
|
if ($result['browser_version'] == $result['browser_build']) {
|
||
|
unset($result['browser_build']);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// compatibility
|
||
|
$compatibility['AppleWebKit'] = 'Safari';
|
||
|
$compatibility['Gecko'] = 'Firefox';
|
||
|
$compatibility['MSIE'] = 'Internet Explorer';
|
||
|
$compatibility['Presto'] = 'Opera';
|
||
|
if (!empty($result['browser_engine'])) {
|
||
|
if (isset($compatibility[$result['browser_engine']])) {
|
||
|
$result['browser_compatibility'] = $compatibility[$result['browser_engine']];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ksort($result);
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Loads the Features Adapter if it's defined in the $config array
|
||
|
* Otherwise, nothing is done
|
||
|
*
|
||
|
* @param string $browserType Browser type
|
||
|
* @return array
|
||
|
*/
|
||
|
protected function _loadFeaturesAdapter()
|
||
|
{
|
||
|
$config = $this->_config;
|
||
|
$browserType = $this->getType();
|
||
|
if (!isset($config[$browserType]) || !isset($config[$browserType]['features'])) {
|
||
|
return array();
|
||
|
}
|
||
|
$config = $config[$browserType]['features'];
|
||
|
|
||
|
if (empty($config['classname'])) {
|
||
|
require_once 'Zend/Http/UserAgent/Exception.php';
|
||
|
throw new Zend_Http_UserAgent_Exception('The ' . $this->getType() . ' features adapter must have a "classname" config parameter defined');
|
||
|
}
|
||
|
|
||
|
$className = $config['classname'];
|
||
|
if (!class_exists($className)) {
|
||
|
if (isset($config['path'])) {
|
||
|
$path = $config['path'];
|
||
|
} else {
|
||
|
require_once 'Zend/Http/UserAgent/Exception.php';
|
||
|
throw new Zend_Http_UserAgent_Exception('The ' . $this->getType() . ' features adapter must have a "path" config parameter defined');
|
||
|
}
|
||
|
|
||
|
if (false === include_once ($path)) {
|
||
|
require_once 'Zend/Http/UserAgent/Exception.php';
|
||
|
throw new Zend_Http_UserAgent_Exception('The ' . $this->getType() . ' features adapter path that does not exist');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return call_user_func(array($className, 'getFromRequest'), $this->_server, $this->_config);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Retrieve image format support
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getImageFormatSupport()
|
||
|
{
|
||
|
return $this->_images;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get maximum image height supported by this device
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
public function getMaxImageHeight()
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get maximum image width supported by this device
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
public function getMaxImageWidth()
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get physical screen height of this device
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
public function getPhysicalScreenHeight()
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get physical screen width of this device
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
public function getPhysicalScreenWidth()
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get preferred markup type
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getPreferredMarkup()
|
||
|
{
|
||
|
return 'xhtml';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get supported X/HTML version
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
public function getXhtmlSupportLevel()
|
||
|
{
|
||
|
return 4;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Does the device support Flash?
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public function hasFlashSupport()
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Does the device support PDF?
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public function hasPdfSupport()
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Does the device have a phone number associated with it?
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public function hasPhoneNumber()
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Does the device support HTTPS?
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public function httpsSupport()
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the browser type
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getBrowser()
|
||
|
{
|
||
|
return $this->_browser;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the browser version
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getBrowserVersion()
|
||
|
{
|
||
|
return $this->_browserVersion;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the user agent string
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getUserAgent()
|
||
|
{
|
||
|
return $this->_userAgent;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return the $_images
|
||
|
*/
|
||
|
public function getImages()
|
||
|
{
|
||
|
return $this->_images;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $browser
|
||
|
*/
|
||
|
public function setBrowser($browser)
|
||
|
{
|
||
|
$this->_browser = $browser;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $browserVersion
|
||
|
*/
|
||
|
public function setBrowserVersion($browserVersion)
|
||
|
{
|
||
|
$this->_browserVersion = $browserVersion;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $userAgent
|
||
|
*/
|
||
|
public function setUserAgent($userAgent)
|
||
|
{
|
||
|
$this->_userAgent = $userAgent;
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param array $_images
|
||
|
*/
|
||
|
public function setImages($_images)
|
||
|
{
|
||
|
$this->_images = $_images;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Match a user agent string against a list of signatures
|
||
|
*
|
||
|
* @param string $userAgent
|
||
|
* @param array $signatures
|
||
|
* @return bool
|
||
|
*/
|
||
|
protected static function _matchAgentAgainstSignatures($userAgent, $signatures)
|
||
|
{
|
||
|
$userAgent = strtolower($userAgent);
|
||
|
foreach ($signatures as $signature) {
|
||
|
if (!empty($signature)) {
|
||
|
if (strpos($userAgent, $signature) !== false) {
|
||
|
// Browser signature was found in user agent string
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
}
|