2
0

Mobile.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Http
  17. * @subpackage UserAgent
  18. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. require_once 'Zend/Http/UserAgent/AbstractDevice.php';
  22. /**
  23. * Mobile browser type matcher
  24. *
  25. * @category Zend
  26. * @package Zend_Http
  27. * @subpackage UserAgent
  28. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  29. * @license http://framework.zend.com/license/new-bsd New BSD License
  30. */
  31. class Zend_Http_UserAgent_Mobile extends Zend_Http_UserAgent_AbstractDevice
  32. {
  33. const DEFAULT_FEATURES_ADAPTER_CLASSNAME = 'Zend_Http_UserAgent_Features_Adapter_WurflApi';
  34. const DEFAULT_FEATURES_ADAPTER_PATH = 'Zend/Http/UserAgent/Features/Adapter/WurflApi.php';
  35. /**
  36. * User Agent Signatures
  37. *
  38. * @var array
  39. */
  40. protected static $_uaSignatures = array(
  41. 'iphone',
  42. 'ipod',
  43. 'ipad',
  44. 'android',
  45. 'blackberry',
  46. 'opera mini',
  47. 'opera mobi',
  48. 'palm',
  49. 'palmos',
  50. 'elaine',
  51. 'windows ce',
  52. 'icab',
  53. '_mms',
  54. 'ahong',
  55. 'archos',
  56. 'armv',
  57. 'astel',
  58. 'avantgo',
  59. 'benq',
  60. 'blazer',
  61. 'brew',
  62. 'com2',
  63. 'compal',
  64. 'danger',
  65. 'pocket',
  66. 'docomo',
  67. 'epoc',
  68. 'ericsson',
  69. 'eudoraweb',
  70. 'hiptop',
  71. 'htc-',
  72. 'htc_',
  73. 'iemobile',
  74. 'ipad',
  75. 'iris',
  76. 'j-phone',
  77. 'kddi',
  78. 'kindle',
  79. 'lg ',
  80. 'lg-',
  81. 'lg/',
  82. 'lg;lx',
  83. 'lge vx',
  84. 'lge',
  85. 'lge-',
  86. 'lge-cx',
  87. 'lge-lx',
  88. 'lge-mx',
  89. 'linux armv',
  90. 'maemo',
  91. 'midp',
  92. 'mini 9.5',
  93. 'minimo',
  94. 'mob-x',
  95. 'mobi',
  96. 'mobile',
  97. 'mobilephone',
  98. 'mot 24',
  99. 'mot-',
  100. 'motorola',
  101. 'n410',
  102. 'netfront',
  103. 'nintendo wii',
  104. 'nintendo',
  105. 'nitro',
  106. 'nokia',
  107. 'novarra-vision',
  108. 'nuvifone',
  109. 'openweb',
  110. 'opwv',
  111. 'palmsource',
  112. 'pdxgw',
  113. 'phone',
  114. 'playstation',
  115. 'polaris',
  116. 'portalmmm',
  117. 'qt embedded',
  118. 'reqwirelessweb',
  119. 'sagem',
  120. 'sam-r',
  121. 'samsu',
  122. 'samsung',
  123. 'sec-',
  124. 'sec-sgh',
  125. 'semc-browser',
  126. 'series60',
  127. 'series70',
  128. 'series80',
  129. 'series90',
  130. 'sharp',
  131. 'sie-m',
  132. 'sie-s',
  133. 'smartphone',
  134. 'sony cmd',
  135. 'sonyericsson',
  136. 'sprint',
  137. 'spv',
  138. 'symbian os',
  139. 'symbian',
  140. 'symbianos',
  141. 'telco',
  142. 'teleca',
  143. 'treo',
  144. 'up.browser',
  145. 'up.link',
  146. 'vodafone',
  147. 'vodaphone',
  148. 'webos',
  149. 'wml',
  150. 'windows phone os 7',
  151. 'wireless',
  152. 'wm5 pie',
  153. 'wms pie',
  154. 'xiino',
  155. 'wap',
  156. 'up/',
  157. 'psion',
  158. 'j2me',
  159. 'klondike',
  160. 'kbrowser'
  161. );
  162. /**
  163. * @var array
  164. */
  165. protected static $_haTerms = array(
  166. 'midp',
  167. 'wml',
  168. 'vnd.rim',
  169. 'vnd.wap',
  170. 'j2me'
  171. );
  172. /**
  173. * first 4 letters of mobile User Agent chains
  174. *
  175. * @var array
  176. */
  177. protected static $_uaBegin = array(
  178. 'w3c ',
  179. 'acs-',
  180. 'alav',
  181. 'alca',
  182. 'amoi',
  183. 'audi',
  184. 'avan',
  185. 'benq',
  186. 'bird',
  187. 'blac',
  188. 'blaz',
  189. 'brew',
  190. 'cell',
  191. 'cldc',
  192. 'cmd-',
  193. 'dang',
  194. 'doco',
  195. 'eric',
  196. 'hipt',
  197. 'inno',
  198. 'ipaq',
  199. 'java',
  200. 'jigs',
  201. 'kddi',
  202. 'keji',
  203. 'leno',
  204. 'lg-c',
  205. 'lg-d',
  206. 'lg-g',
  207. 'lge-',
  208. 'maui',
  209. 'maxo',
  210. 'midp',
  211. 'mits',
  212. 'mmef',
  213. 'mobi',
  214. 'mot-',
  215. 'moto',
  216. 'mwbp',
  217. 'nec-',
  218. 'newt',
  219. 'noki',
  220. 'oper',
  221. 'palm',
  222. 'pana',
  223. 'pant',
  224. 'phil',
  225. 'play',
  226. 'port',
  227. 'prox',
  228. 'qwap',
  229. 'sage',
  230. 'sams',
  231. 'sany',
  232. 'sch-',
  233. 'sec-',
  234. 'send',
  235. 'seri',
  236. 'sgh-',
  237. 'shar',
  238. 'sie-',
  239. 'siem',
  240. 'smal',
  241. 'smar',
  242. 'sony',
  243. 'sph-',
  244. 'symb',
  245. 't-mo',
  246. 'teli',
  247. 'tim-',
  248. 'tosh',
  249. 'tsm-',
  250. 'upg1',
  251. 'upsi',
  252. 'vk-v',
  253. 'voda',
  254. 'wap-',
  255. 'wapa',
  256. 'wapi',
  257. 'wapp',
  258. 'wapr',
  259. 'webc',
  260. 'winw',
  261. 'winw',
  262. 'xda',
  263. 'xda-',
  264. );
  265. /**
  266. * Comparison of the UserAgent chain and User Agent signatures
  267. *
  268. * @param string $userAgent User Agent chain
  269. * @param array $server $_SERVER like param
  270. * @return bool
  271. */
  272. public static function match($userAgent, $server)
  273. {
  274. // To have a quick identification, try light-weight tests first
  275. if (isset($server['all_http'])) {
  276. if (strpos(strtolower(str_replace(' ', '', $server['all_http'])), 'operam') !== false) {
  277. // Opera Mini or Opera Mobi
  278. return true;
  279. }
  280. }
  281. if (isset($server['http_x_wap_profile']) || isset($server['http_profile'])) {
  282. return true;
  283. }
  284. if (isset($server['http_accept'])) {
  285. if (self::_matchAgentAgainstSignatures($server['http_accept'], self::$_haTerms)) {
  286. return true;
  287. }
  288. }
  289. if (self::userAgentStart($userAgent)) {
  290. return true;
  291. }
  292. if (self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures)) {
  293. return true;
  294. }
  295. return false;
  296. }
  297. /**
  298. * Retrieve beginning clause of user agent
  299. *
  300. * @param string $userAgent
  301. * @return string
  302. */
  303. public static function userAgentStart($userAgent)
  304. {
  305. $mobile_ua = strtolower(substr($userAgent, 0, 4));
  306. return (in_array($mobile_ua, self::$_uaBegin));
  307. }
  308. /**
  309. * Constructor
  310. *
  311. * @return void
  312. */
  313. public function __construct($userAgent = null, array $server = array(), array $config = array())
  314. {
  315. // For mobile detection, an adapter must be defined
  316. if (empty($config['mobile']['features'])) {
  317. $config['mobile']['features']['path'] = self::DEFAULT_FEATURES_ADAPTER_PATH;
  318. $config['mobile']['features']['classname'] = self::DEFAULT_FEATURES_ADAPTER_CLASSNAME;
  319. }
  320. parent::__construct($userAgent, $server, $config);
  321. }
  322. /**
  323. * Gives the current browser type
  324. *
  325. * @return string
  326. */
  327. public function getType()
  328. {
  329. return 'mobile';
  330. }
  331. /**
  332. * Look for features
  333. *
  334. * @return string
  335. */
  336. protected function _defineFeatures()
  337. {
  338. $this->setFeature('is_wireless_device', false, 'product_info');
  339. parent::_defineFeatures();
  340. if (isset($this->_aFeatures["mobile_browser"])) {
  341. $this->setFeature("browser_name", $this->_aFeatures["mobile_browser"]);
  342. $this->_browser = $this->_aFeatures["mobile_browser"];
  343. }
  344. if (isset($this->_aFeatures["mobile_browser_version"])) {
  345. $this->setFeature("browser_version", $this->_aFeatures["mobile_browser_version"]);
  346. $this->_browserVersion = $this->_aFeatures["mobile_browser_version"];
  347. }
  348. // markup
  349. if ($this->getFeature('device_os') == 'iPhone OS'
  350. || $this->getFeature('device_os_token') == 'iPhone OS'
  351. ) {
  352. $this->setFeature('markup', 'iphone');
  353. } else {
  354. $this->setFeature('markup', $this->getMarkupLanguage($this->getFeature('preferred_markup')));
  355. }
  356. // image format
  357. $this->_images = array();
  358. if ($this->getFeature('png')) {
  359. $this->_images[] = 'png';
  360. }
  361. if ($this->getFeature('jpg')) {
  362. $this->_images[] = 'jpg';
  363. }
  364. if ($this->getFeature('gif')) {
  365. $this->_images[] = 'gif';
  366. }
  367. if ($this->getFeature('wbmp')) {
  368. $this->_images[] = 'wbmp';
  369. }
  370. return $this->_aFeatures;
  371. }
  372. /**
  373. * Determine markup language expected
  374. *
  375. * @access public
  376. * @return __TYPE__
  377. */
  378. public function getMarkupLanguage($preferredMarkup = null)
  379. {
  380. $return = '';
  381. switch ($preferredMarkup) {
  382. case 'wml_1_1':
  383. case 'wml_1_2':
  384. case 'wml_1_3':
  385. $return = 'wml'; //text/vnd.wap.wml encoding="ISO-8859-15"
  386. case 'html_wi_imode_compact_generic':
  387. case 'html_wi_imode_html_1':
  388. case 'html_wi_imode_html_2':
  389. case 'html_wi_imode_html_3':
  390. case 'html_wi_imode_html_4':
  391. case 'html_wi_imode_html_5':
  392. $return = 'chtml'; //text/html
  393. case 'html_wi_oma_xhtmlmp_1_0': //application/vnd.wap.xhtml+xml
  394. case 'html_wi_w3_xhtmlbasic': //application/xhtml+xml DTD XHTML Basic 1.0
  395. $return = 'xhtml';
  396. case 'html_web_3_2': //text/html DTD Html 3.2 Final
  397. case 'html_web_4_0': //text/html DTD Html 4.01 Transitional
  398. $return = '';
  399. }
  400. return $return;
  401. }
  402. /**
  403. * Determine image format support
  404. *
  405. * @return array
  406. */
  407. public function getImageFormatSupport()
  408. {
  409. return $this->_images;
  410. }
  411. /**
  412. * Determine maximum image height supported
  413. *
  414. * @return int
  415. */
  416. public function getMaxImageHeight()
  417. {
  418. return $this->getFeature('max_image_height');
  419. }
  420. /**
  421. * Determine maximum image width supported
  422. *
  423. * @return int
  424. */
  425. public function getMaxImageWidth()
  426. {
  427. return $this->getFeature('max_image_width');
  428. }
  429. /**
  430. * Determine physical screen height
  431. *
  432. * @return int
  433. */
  434. public function getPhysicalScreenHeight()
  435. {
  436. return $this->getFeature('physical_screen_height');
  437. }
  438. /**
  439. * Determine physical screen width
  440. *
  441. * @return int
  442. */
  443. public function getPhysicalScreenWidth()
  444. {
  445. return $this->getFeature('physical_screen_width');
  446. }
  447. /**
  448. * Determine preferred markup
  449. *
  450. * @return string
  451. */
  452. public function getPreferredMarkup()
  453. {
  454. return $this->getFeature("markup");
  455. }
  456. /**
  457. * Determine X/HTML support level
  458. *
  459. * @return int
  460. */
  461. public function getXhtmlSupportLevel()
  462. {
  463. return $this->getFeature('xhtml_support_level');
  464. }
  465. /**
  466. * Does the device support Flash?
  467. *
  468. * @return bool
  469. */
  470. public function hasFlashSupport()
  471. {
  472. return $this->getFeature('fl_browser');
  473. }
  474. /**
  475. * Does the device support PDF?
  476. *
  477. * @return bool
  478. */
  479. public function hasPdfSupport()
  480. {
  481. return $this->getFeature('pdf_support');
  482. }
  483. /**
  484. * Does the device have an associated phone number?
  485. *
  486. * @return bool
  487. */
  488. public function hasPhoneNumber()
  489. {
  490. return $this->getFeature('can_assign_phone_number');
  491. }
  492. /**
  493. * Does the device support HTTPS?
  494. *
  495. * @return bool
  496. */
  497. public function httpsSupport()
  498. {
  499. return ($this->getFeature('https_support') == 'supported');
  500. }
  501. }