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/AbstractDevice.php';
0023 
0024 /**
0025  * Mobile browser type matcher
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 class Zend_Http_UserAgent_Mobile extends Zend_Http_UserAgent_AbstractDevice
0034 {
0035 
0036     const DEFAULT_FEATURES_ADAPTER_CLASSNAME = 'Zend_Http_UserAgent_Features_Adapter_Browscap';
0037 
0038     const DEFAULT_FEATURES_ADAPTER_PATH = 'Zend/Http/UserAgent/Features/Adapter/Browscap.php';
0039 
0040     /**
0041      * User Agent Signatures
0042      *
0043      * @var array
0044      */
0045     protected static $_uaSignatures = array(
0046         'iphone',
0047         'ipod',
0048         'ipad',
0049         'android',
0050         'blackberry',
0051         'opera mini',
0052         'opera mobi',
0053         'palm',
0054         'palmos',
0055         'elaine',
0056         'windows ce',
0057         'icab',
0058         '_mms',
0059         'ahong',
0060         'archos',
0061         'armv',
0062         'astel',
0063         'avantgo',
0064         'benq',
0065         'blazer',
0066         'brew',
0067         'com2',
0068         'compal',
0069         'danger',
0070         'pocket',
0071         'docomo',
0072         'epoc',
0073         'ericsson',
0074         'eudoraweb',
0075         'hiptop',
0076         'htc-',
0077         'htc_',
0078         'iemobile',
0079         'iris',
0080         'j-phone',
0081         'kddi',
0082         'kindle',
0083         'lg ',
0084         'lg-',
0085         'lg/',
0086         'lg;lx',
0087         'lge vx',
0088         'lge',
0089         'lge-',
0090         'lge-cx',
0091         'lge-lx',
0092         'lge-mx',
0093         'linux armv',
0094         'maemo',
0095         'midp',
0096         'mini 9.5',
0097         'minimo',
0098         'mob-x',
0099         'mobi',
0100         'mobile',
0101         'mobilephone',
0102         'mot 24',
0103         'mot-',
0104         'motorola',
0105         'n410',
0106         'netfront',
0107         'nintendo wii',
0108         'nintendo',
0109         'nitro',
0110         'nokia',
0111         'novarra-vision',
0112         'nuvifone',
0113         'openweb',
0114         'opwv',
0115         'palmsource',
0116         'pdxgw',
0117         'phone',
0118         'playstation',
0119         'polaris',
0120         'portalmmm',
0121         'qt embedded',
0122         'reqwirelessweb',
0123         'sagem',
0124         'sam-r',
0125         'samsu',
0126         'samsung',
0127         'sec-',
0128         'sec-sgh',
0129         'semc-browser',
0130         'series60',
0131         'series70',
0132         'series80',
0133         'series90',
0134         'sharp',
0135         'sie-m',
0136         'sie-s',
0137         'smartphone',
0138         'sony cmd',
0139         'sonyericsson',
0140         'sprint',
0141         'spv',
0142         'symbian os',
0143         'symbian',
0144         'symbianos',
0145         'telco',
0146         'teleca',
0147         'treo',
0148         'up.browser',
0149         'up.link',
0150         'vodafone',
0151         'vodaphone',
0152         'webos',
0153         'wml',
0154         'windows phone os 7',
0155         'wireless',
0156         'wm5 pie',
0157         'wms pie',
0158         'xiino',
0159         'wap',
0160         'up/',
0161         'psion',
0162         'j2me',
0163         'klondike',
0164         'kbrowser'
0165     );
0166 
0167     /**
0168      * @var array
0169      */
0170     protected static $_haTerms = array(
0171         'midp',
0172         'wml',
0173         'vnd.rim',
0174         'vnd.wap',
0175         'j2me',
0176     );
0177 
0178     /**
0179      * first 4 letters of mobile User Agent chains
0180      *
0181      * @var array
0182      */
0183     protected static $_uaBegin = array(
0184         'w3c ',
0185         'acs-',
0186         'alav',
0187         'alca',
0188         'amoi',
0189         'audi',
0190         'avan',
0191         'benq',
0192         'bird',
0193         'blac',
0194         'blaz',
0195         'brew',
0196         'cell',
0197         'cldc',
0198         'cmd-',
0199         'dang',
0200         'doco',
0201         'eric',
0202         'hipt',
0203         'inno',
0204         'ipaq',
0205         'java',
0206         'jigs',
0207         'kddi',
0208         'keji',
0209         'leno',
0210         'lg-c',
0211         'lg-d',
0212         'lg-g',
0213         'lge-',
0214         'maui',
0215         'maxo',
0216         'midp',
0217         'mits',
0218         'mmef',
0219         'mobi',
0220         'mot-',
0221         'moto',
0222         'mwbp',
0223         'nec-',
0224         'newt',
0225         'noki',
0226         'palm',
0227         'pana',
0228         'pant',
0229         'phil',
0230         'play',
0231         'port',
0232         'prox',
0233         'qwap',
0234         'sage',
0235         'sams',
0236         'sany',
0237         'sch-',
0238         'sec-',
0239         'send',
0240         'seri',
0241         'sgh-',
0242         'shar',
0243         'sie-',
0244         'siem',
0245         'smal',
0246         'smar',
0247         'sony',
0248         'sph-',
0249         'symb',
0250         't-mo',
0251         'teli',
0252         'tim-',
0253         'tosh',
0254         'tsm-',
0255         'upg1',
0256         'upsi',
0257         'vk-v',
0258         'voda',
0259         'wap-',
0260         'wapa',
0261         'wapi',
0262         'wapp',
0263         'wapr',
0264         'webc',
0265         'winw',
0266         'winw',
0267         'xda',
0268         'xda-',
0269     );
0270 
0271     /**
0272      * Comparison of the UserAgent chain and User Agent signatures
0273      *
0274      * @param  string $userAgent User Agent chain
0275      * @param  array $server $_SERVER like param
0276      * @return bool
0277      */
0278     public static function match($userAgent, $server)
0279     {
0280         //  To have a quick identification, try light-weight tests first
0281         if (isset($server['all_http'])) {
0282             if (strpos(strtolower(str_replace(' ', '', $server['all_http'])), 'operam') !== false) {
0283                 // Opera Mini or Opera Mobi
0284                 return true;
0285             }
0286         }
0287 
0288         if (isset($server['http_x_wap_profile']) || isset($server['http_profile'])) {
0289             return true;
0290         }
0291 
0292         if (isset($server['http_accept'])) {
0293             if (self::_matchAgentAgainstSignatures($server['http_accept'], self::$_haTerms)) {
0294                 return true;
0295             }
0296         }
0297 
0298         if (self::userAgentStart($userAgent)) {
0299             return true;
0300         }
0301 
0302         if (self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures)) {
0303             return true;
0304         }
0305 
0306         return false;
0307     }
0308 
0309     /**
0310      * Retrieve beginning clause of user agent
0311      *
0312      * @param  string $userAgent
0313      * @return string
0314      */
0315     public static function userAgentStart($userAgent)
0316     {
0317 
0318         $mobile_ua = strtolower(substr($userAgent, 0, 4));
0319 
0320         return (in_array($mobile_ua, self::$_uaBegin));
0321     }
0322 
0323     /**
0324      * Constructor
0325      *
0326      * @return void
0327      */
0328     public function __construct($userAgent = null, array $server = array(), array $config = array())
0329     {
0330         // For mobile detection, an adapter must be defined
0331         if (empty($config['mobile']['features'])) {
0332             $config['mobile']['features']['path']      = self::DEFAULT_FEATURES_ADAPTER_PATH;
0333             $config['mobile']['features']['classname'] = self::DEFAULT_FEATURES_ADAPTER_CLASSNAME;
0334         }
0335         parent::__construct($userAgent, $server, $config);
0336     }
0337 
0338     /**
0339      * Gives the current browser type
0340      *
0341      * @return string
0342      */
0343     public function getType()
0344     {
0345         return 'mobile';
0346     }
0347 
0348     /**
0349      * Look for features
0350      *
0351      * @return string
0352      */
0353     protected function _defineFeatures()
0354     {
0355         $this->setFeature('is_wireless_device', false, 'product_info');
0356 
0357         parent::_defineFeatures();
0358 
0359         if (isset($this->_aFeatures["mobile_browser"])) {
0360             $this->setFeature("browser_name", $this->_aFeatures["mobile_browser"]);
0361             $this->_browser = $this->_aFeatures["mobile_browser"];
0362         }
0363         if (isset($this->_aFeatures["mobile_browser_version"])) {
0364             $this->setFeature("browser_version", $this->_aFeatures["mobile_browser_version"]);
0365             $this->_browserVersion = $this->_aFeatures["mobile_browser_version"];
0366         }
0367 
0368         // markup
0369         if ($this->getFeature('device_os') == 'iPhone OS'
0370             || $this->getFeature('device_os_token') == 'iPhone OS'
0371         ) {
0372             $this->setFeature('markup', 'iphone');
0373         } else {
0374             $this->setFeature('markup', $this->getMarkupLanguage($this->getFeature('preferred_markup')));
0375         }
0376 
0377         // image format
0378         $this->_images = array();
0379 
0380         if ($this->getFeature('png')) {
0381             $this->_images[] = 'png';
0382         }
0383         if ($this->getFeature('jpg')) {
0384             $this->_images[] = 'jpg';
0385         }
0386         if ($this->getFeature('gif')) {
0387             $this->_images[] = 'gif';
0388         }
0389         if ($this->getFeature('wbmp')) {
0390             $this->_images[] = 'wbmp';
0391         }
0392 
0393         return $this->_aFeatures;
0394     }
0395 
0396     /**
0397      * Determine markup language expected
0398      *
0399      * @access public
0400      * @return __TYPE__
0401      */
0402     public function getMarkupLanguage($preferredMarkup = null)
0403     {
0404         $return = '';
0405         switch ($preferredMarkup) {
0406             case 'wml_1_1':
0407             case 'wml_1_2':
0408             case 'wml_1_3':
0409                 $return = 'wml'; //text/vnd.wap.wml encoding="ISO-8859-15"
0410             case 'html_wi_imode_compact_generic':
0411             case 'html_wi_imode_html_1':
0412             case 'html_wi_imode_html_2':
0413             case 'html_wi_imode_html_3':
0414             case 'html_wi_imode_html_4':
0415             case 'html_wi_imode_html_5':
0416                 $return = 'chtml'; //text/html
0417             case 'html_wi_oma_xhtmlmp_1_0': //application/vnd.wap.xhtml+xml
0418             case 'html_wi_w3_xhtmlbasic': //application/xhtml+xml DTD XHTML Basic 1.0
0419                 $return = 'xhtml';
0420             case 'html_web_3_2': //text/html DTD Html 3.2 Final
0421             case 'html_web_4_0': //text/html DTD Html 4.01 Transitional
0422                 $return = '';
0423         }
0424         return $return;
0425     }
0426 
0427     /**
0428      * Determine image format support
0429      *
0430      * @return array
0431      */
0432     public function getImageFormatSupport()
0433     {
0434         return $this->_images;
0435     }
0436 
0437     /**
0438      * Determine maximum image height supported
0439      *
0440      * @return int
0441      */
0442     public function getMaxImageHeight()
0443     {
0444         return $this->getFeature('max_image_height');
0445     }
0446 
0447     /**
0448      * Determine maximum image width supported
0449      *
0450      * @return int
0451      */
0452     public function getMaxImageWidth()
0453     {
0454         return $this->getFeature('max_image_width');
0455     }
0456 
0457     /**
0458      * Determine physical screen height
0459      *
0460      * @return int
0461      */
0462     public function getPhysicalScreenHeight()
0463     {
0464         return $this->getFeature('physical_screen_height');
0465     }
0466 
0467     /**
0468      * Determine physical screen width
0469      *
0470      * @return int
0471      */
0472     public function getPhysicalScreenWidth()
0473     {
0474         return $this->getFeature('physical_screen_width');
0475     }
0476 
0477     /**
0478      * Determine preferred markup
0479      *
0480      * @return string
0481      */
0482     public function getPreferredMarkup()
0483     {
0484         return $this->getFeature("markup");
0485     }
0486 
0487     /**
0488      * Determine X/HTML support level
0489      *
0490      * @return int
0491      */
0492     public function getXhtmlSupportLevel()
0493     {
0494         return $this->getFeature('xhtml_support_level');
0495     }
0496 
0497     /**
0498      * Does the device support Flash?
0499      *
0500      * @return bool
0501      */
0502     public function hasFlashSupport()
0503     {
0504         return $this->getFeature('fl_browser');
0505     }
0506 
0507     /**
0508      * Does the device support PDF?
0509      *
0510      * @return bool
0511      */
0512     public function hasPdfSupport()
0513     {
0514         return $this->getFeature('pdf_support');
0515     }
0516 
0517     /**
0518      * Does the device have an associated phone number?
0519      *
0520      * @return bool
0521      */
0522     public function hasPhoneNumber()
0523     {
0524         return $this->getFeature('can_assign_phone_number');
0525     }
0526 
0527     /**
0528      * Does the device support HTTPS?
0529      *
0530      * @return bool
0531      */
0532     public function httpsSupport()
0533     {
0534         return ($this->getFeature('https_support') == 'supported');
0535     }
0536 }