PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/concreteOLD/libraries/3rdparty/Zend/Http/UserAgent.php

https://bitbucket.org/selfeky/xclusivescardwebsite
PHP | 853 lines | 433 code | 84 blank | 336 comment | 53 complexity | 48399995b0bbd6368f07d4feadb401ba MD5 | raw file
  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_UserAgent
  17. * @subpackage UserAgent
  18. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /**
  22. * Lists of User Agent chains for testing :
  23. *
  24. * - http://www.useragentstring.com/layout/useragentstring.php
  25. * - http://user-agent-string.info/list-of-ua
  26. * - http://www.user-agents.org/allagents.xml
  27. * - http://en.wikipedia.org/wiki/List_of_user_agents_for_mobile_phones
  28. * - http://www.mobilemultimedia.be/fr/
  29. *
  30. * @category Zend
  31. * @package Zend_Http_UserAgent
  32. * @subpackage UserAgent
  33. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  34. * @license http://framework.zend.com/license/new-bsd New BSD License
  35. */
  36. class Zend_Http_UserAgent implements Serializable
  37. {
  38. /**
  39. * 'desktop' by default if the sequence return false for each item or is empty
  40. */
  41. const DEFAULT_IDENTIFICATION_SEQUENCE = 'mobile,desktop';
  42. /**
  43. * Default persitent storage adapter : Session or NonPersitent
  44. */
  45. const DEFAULT_PERSISTENT_STORAGE_ADAPTER = 'Session';
  46. /**
  47. * 'desktop' by default if the sequence return false for each item
  48. */
  49. const DEFAULT_BROWSER_TYPE = 'desktop';
  50. /**
  51. * Default User Agent chain to prevent empty value
  52. */
  53. const DEFAULT_HTTP_USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)';
  54. /**
  55. * Default Http Accept param to prevent empty value
  56. */
  57. const DEFAULT_HTTP_ACCEPT = "application/xhtml+xml";
  58. /**
  59. * Default markup language
  60. */
  61. const DEFAULT_MARKUP_LANGUAGE = "xhtml";
  62. /**
  63. * Browser type
  64. *
  65. * @var string
  66. */
  67. protected $_browserType;
  68. /**
  69. * Browser type class
  70. *
  71. * Map of browser types to classes.
  72. *
  73. * @var array
  74. */
  75. protected $_browserTypeClass = array();
  76. /**
  77. * Array to store config
  78. *
  79. * Default values are provided to ensure specific keys are present at
  80. * instantiation.
  81. *
  82. * @var array
  83. */
  84. protected $_config = array(
  85. 'identification_sequence' => self::DEFAULT_IDENTIFICATION_SEQUENCE,
  86. 'storage' => array(
  87. 'adapter' => self::DEFAULT_PERSISTENT_STORAGE_ADAPTER,
  88. ),
  89. );
  90. /**
  91. * Identified device
  92. *
  93. * @var Zend_Http_UserAgent_Device
  94. */
  95. protected $_device;
  96. /**
  97. * Whether or not this instance is immutable.
  98. *
  99. * If true, none of the following may be modified:
  100. * - $_server
  101. * - $_browserType
  102. * - User-Agent (defined in $_server)
  103. * - HTTP Accept value (defined in $_server)
  104. * - $_storage
  105. *
  106. * @var bool
  107. */
  108. protected $_immutable = false;
  109. /**
  110. * Plugin loaders
  111. * @var array
  112. */
  113. protected $_loaders = array();
  114. /**
  115. * Valid plugin loader types
  116. * @var array
  117. */
  118. protected $_loaderTypes = array('storage', 'device');
  119. /**
  120. * Trace of items matched to identify the browser type
  121. *
  122. * @var array
  123. */
  124. protected $_matchLog = array();
  125. /**
  126. * Server variable
  127. *
  128. * @var array
  129. */
  130. protected $_server;
  131. /**
  132. * Persistent storage handler
  133. *
  134. * @var Zend_Http_UserAgent_Storage
  135. */
  136. protected $_storage;
  137. /**
  138. * Constructor
  139. *
  140. * @param null|array|Zend_Config|ArrayAccess $options
  141. * @return void
  142. */
  143. public function __construct($options = null)
  144. {
  145. if (null !== $options) {
  146. $this->setOptions($options);
  147. }
  148. }
  149. /**
  150. * Serialized representation of the object
  151. *
  152. * @return string
  153. */
  154. public function serialize()
  155. {
  156. $device = $this->getDevice();
  157. $spec = array(
  158. 'browser_type' => $this->_browserType,
  159. 'config' => $this->_config,
  160. 'device_class' => get_class($device),
  161. 'device' => $device->serialize(),
  162. 'user_agent' => $this->getServerValue('http_user_agent'),
  163. 'http_accept' => $this->getServerValue('http_accept'),
  164. );
  165. return serialize($spec);
  166. }
  167. /**
  168. * Unserialize a previous representation of the object
  169. *
  170. * @param string $serialized
  171. * @return void
  172. */
  173. public function unserialize($serialized)
  174. {
  175. $spec = unserialize($serialized);
  176. $this->setOptions($spec);
  177. // Determine device class and ensure the class is loaded
  178. $deviceClass = $spec['device_class'];
  179. if (!class_exists($deviceClass)) {
  180. $this->_getUserAgentDevice($this->getBrowserType());
  181. }
  182. // Get device specification and instantiate
  183. $deviceSpec = unserialize($spec['device']);
  184. $deviceSpec['_config'] = $this->getConfig();
  185. $deviceSpec['_server'] = $this->getServer();
  186. $this->_device = new $deviceClass($deviceSpec);
  187. }
  188. /**
  189. * Configure instance
  190. *
  191. * @param array|Zend_Config|ArrayAccess $options
  192. * @return Zend_Http_UserAgent
  193. */
  194. public function setOptions($options)
  195. {
  196. if ($options instanceof Zend_Config) {
  197. $options = $options->toArray();
  198. }
  199. if (!is_array($options)
  200. && !$options instanceof ArrayAccess
  201. && !$options instanceof Traversable
  202. ) {
  203. require_once 'Zend/Http/UserAgent/Exception.php';
  204. throw new Zend_Http_UserAgent_Exception(sprintf(
  205. 'Invalid argument; expected array, Zend_Config object, or object implementing ArrayAccess and Traversable; received %s',
  206. (is_object($options) ? get_class($options) : gettype($options))
  207. ));
  208. }
  209. // Set $_SERVER first
  210. if (isset($options['server'])) {
  211. $this->setServer($options['server']);
  212. unset($options['server']);
  213. }
  214. // Get plugin loaders sorted
  215. if (isset($options['plugin_loader'])) {
  216. $plConfig = $options['plugin_loader'];
  217. if (is_array($plConfig) || $plConfig instanceof Traversable) {
  218. foreach ($plConfig as $type => $class) {
  219. $this->setPluginLoader($type, $class);
  220. }
  221. }
  222. unset($plConfig, $options['plugin_loader']);
  223. }
  224. // And then loop through the remaining options
  225. $config = array();
  226. foreach ($options as $key => $value) {
  227. switch (strtolower($key)) {
  228. case 'browser_type':
  229. $this->setBrowserType($value);
  230. break;
  231. case 'http_accept':
  232. $this->setHttpAccept($value);
  233. break;
  234. case 'user_agent':
  235. $this->setUserAgent($value);
  236. break;
  237. default:
  238. // Cache remaining options for $_config
  239. $config[$key] = $value;
  240. break;
  241. }
  242. }
  243. $this->setConfig($config);
  244. return $this;
  245. }
  246. /**
  247. * Comparison of the UserAgent chain and browser signatures.
  248. *
  249. * The comparison is case-insensitive : the browser signatures must be in lower
  250. * case
  251. *
  252. * @param string $deviceClass Name of class against which a match will be attempted
  253. * @return bool
  254. */
  255. protected function _match($deviceClass)
  256. {
  257. // Validate device class
  258. $r = new ReflectionClass($deviceClass);
  259. if (!$r->implementsInterface('Zend_Http_UserAgent_Device')) {
  260. throw new Zend_Http_UserAgent_Exception(sprintf(
  261. 'Invalid device class provided ("%s"); must implement Zend_Http_UserAgent_Device',
  262. $deviceClass
  263. ));
  264. }
  265. $userAgent = $this->getUserAgent();
  266. // Call match method on device class
  267. return call_user_func(
  268. array($deviceClass, 'match'),
  269. $userAgent,
  270. $this->getServer()
  271. );
  272. }
  273. /**
  274. * Loads class for a user agent device
  275. *
  276. * @param string $browserType Browser type
  277. * @return string
  278. * @throws Zend_Loader_PluginLoader_Exception if unable to load UA device
  279. */
  280. protected function _getUserAgentDevice($browserType)
  281. {
  282. $browserType = strtolower($browserType);
  283. if (isset($this->_browserTypeClass[$browserType])) {
  284. return $this->_browserTypeClass[$browserType];
  285. }
  286. if (isset($this->_config[$browserType])
  287. && isset($this->_config[$browserType]['device'])
  288. ) {
  289. $deviceConfig = $this->_config[$browserType]['device'];
  290. if (is_array($deviceConfig) && isset($deviceConfig['classname'])) {
  291. $device = (string) $deviceConfig['classname'];
  292. if (!class_exists($device)) {
  293. require_once 'Zend/Http/UserAgent/Exception.php';
  294. throw new Zend_Http_UserAgent_Exception(sprintf(
  295. 'Invalid classname "%s" provided in device configuration for browser type "%s"',
  296. $device,
  297. $browserType
  298. ));
  299. }
  300. } elseif (is_array($deviceConfig) && isset($deviceConfig['path'])) {
  301. $loader = $this->getPluginLoader('device');
  302. $path = $deviceConfig['path'];
  303. $prefix = isset($deviceConfig['prefix']) ? $deviceConfig['prefix'] : 'Zend_Http_UserAgent';
  304. $loader->addPrefixPath($prefix, $path);
  305. $device = $loader->load($browserType);
  306. } else {
  307. $loader = $this->getPluginLoader('device');
  308. $device = $loader->load($browserType);
  309. }
  310. } else {
  311. $loader = $this->getPluginLoader('device');
  312. $device = $loader->load($browserType);
  313. }
  314. $this->_browserTypeClass[$browserType] = $device;
  315. return $device;
  316. }
  317. /**
  318. * Returns the User Agent value
  319. *
  320. * If $userAgent param is null, the value of $_server['HTTP_USER_AGENT'] is
  321. * returned.
  322. *
  323. * @return string
  324. */
  325. public function getUserAgent()
  326. {
  327. if (null === ($ua = $this->getServerValue('http_user_agent'))) {
  328. $ua = self::DEFAULT_HTTP_USER_AGENT;
  329. $this->setUserAgent($ua);
  330. }
  331. return $ua;
  332. }
  333. /**
  334. * Force or replace the UA chain in $_server variable
  335. *
  336. * @param string $userAgent Forced UserAgent chain
  337. * @return Zend_Http_UserAgent
  338. */
  339. public function setUserAgent($userAgent)
  340. {
  341. $this->setServerValue('http_user_agent', $userAgent);
  342. return $this;
  343. }
  344. /**
  345. * Returns the HTTP Accept server param
  346. *
  347. * @param string $httpAccept (option) forced HTTP Accept chain
  348. * @return string
  349. */
  350. public function getHttpAccept($httpAccept = null)
  351. {
  352. if (null === ($accept = $this->getServerValue('http_accept'))) {
  353. $accept = self::DEFAULT_HTTP_ACCEPT;
  354. $this->setHttpAccept($accept);
  355. }
  356. return $accept;
  357. }
  358. /**
  359. * Force or replace the HTTP_ACCEPT chain in self::$_server variable
  360. *
  361. * @param string $httpAccept Forced HTTP Accept chain
  362. * @return Zend_Http_UserAgent
  363. */
  364. public function setHttpAccept($httpAccept)
  365. {
  366. $this->setServerValue('http_accept', $httpAccept);
  367. return $this;
  368. }
  369. /**
  370. * Returns the persistent storage handler
  371. *
  372. * Session storage is used by default unless a different storage adapter
  373. * has been set via the "persistent_storage_adapter" key. That key should
  374. * contain either a fully qualified class name, or a short name that
  375. * resolves via the plugin loader.
  376. *
  377. * @param string $browser Browser identifier (User Agent chain)
  378. * @return Zend_Http_UserAgent_Storage
  379. */
  380. public function getStorage($browser = null)
  381. {
  382. if (null === $browser) {
  383. $browser = $this->getUserAgent();
  384. }
  385. if (null === $this->_storage) {
  386. $config = $this->_config['storage'];
  387. $adapter = $config['adapter'];
  388. if (!class_exists($adapter)) {
  389. $loader = $this->getPluginLoader('storage');
  390. $adapter = $loader->load($adapter);
  391. $loader = $this->getPluginLoader('storage');
  392. }
  393. $options = array('browser_type' => $browser);
  394. if (isset($config['options'])) {
  395. $options = array_merge($options, $config['options']);
  396. }
  397. $this->setStorage(new $adapter($options));
  398. }
  399. return $this->_storage;
  400. }
  401. /**
  402. * Sets the persistent storage handler
  403. *
  404. * @param Zend_Http_UserAgent_Storage $storage
  405. * @return Zend_Http_UserAgent
  406. */
  407. public function setStorage(Zend_Http_UserAgent_Storage $storage)
  408. {
  409. if ($this->_immutable) {
  410. require_once 'Zend/Http/UserAgent/Exception.php';
  411. throw new Zend_Http_UserAgent_Exception(
  412. 'The User-Agent device object has already been retrieved; the storage object is now immutable'
  413. );
  414. }
  415. $this->_storage = $storage;
  416. return $this;
  417. }
  418. /**
  419. * Clean the persistent storage
  420. *
  421. * @param string $browser Browser identifier (User Agent chain)
  422. * @return void
  423. */
  424. public function clearStorage($browser = null)
  425. {
  426. $this->getStorage($browser)->clear();
  427. }
  428. /**
  429. * Get user configuration
  430. *
  431. * @return array
  432. */
  433. public function getConfig()
  434. {
  435. return $this->_config;
  436. }
  437. /**
  438. * Config parameters is an Array or a Zend_Config object
  439. *
  440. * The allowed parameters are :
  441. * - the identification sequence (can be empty) => desktop browser type is the
  442. * default browser type returned
  443. * $config['identification_sequence'] : ',' separated browser types
  444. * - the persistent storage adapter
  445. * $config['persistent_storage_adapter'] = "Session" or "NonPersistent"
  446. * - to add or replace a browser type device
  447. * $config[(type)]['device']['path']
  448. * $config[(type)]['device']['classname']
  449. * - to add or replace a browser type features adapter
  450. * $config[(type)]['features']['path']
  451. * $config[(type)]['features']['classname']
  452. *
  453. * @param mixed $config (option) Config array
  454. * @return Zend_Http_UserAgent
  455. */
  456. public function setConfig($config = array())
  457. {
  458. if ($config instanceof Zend_Config) {
  459. $config = $config->toArray();
  460. }
  461. // Verify that Config parameters are in an array.
  462. if (!is_array($config) && !$config instanceof Traversable) {
  463. require_once 'Zend/Http/UserAgent/Exception.php';
  464. throw new Zend_Http_UserAgent_Exception(sprintf(
  465. 'Config parameters must be in an array or a Traversable object; received "%s"',
  466. (is_object($config) ? get_class($config) : gettype($config))
  467. ));
  468. }
  469. if ($config instanceof Traversable) {
  470. $tmp = array();
  471. foreach ($config as $key => $value) {
  472. $tmp[$key] = $value;
  473. }
  474. $config = $tmp;
  475. unset($tmp);
  476. }
  477. $this->_config = array_merge($this->_config, $config);
  478. return $this;
  479. }
  480. /**
  481. * Returns the device object
  482. *
  483. * This is the object that will contain the various discovered device
  484. * capabilities.
  485. *
  486. * @return Zend_Http_UserAgent_Device $device
  487. */
  488. public function getDevice()
  489. {
  490. if (null !== $this->_device) {
  491. return $this->_device;
  492. }
  493. $userAgent = $this->getUserAgent();
  494. // search an existing identification in the session
  495. $storage = $this->getStorage($userAgent);
  496. if (!$storage->isEmpty()) {
  497. // If the user agent and features are already existing, the
  498. // Zend_Http_UserAgent object is serialized in the session
  499. $object = $storage->read();
  500. $this->unserialize($object);
  501. } else {
  502. // Otherwise, the identification is made and stored in the session.
  503. // Find the browser type:
  504. $this->setBrowserType($this->_matchUserAgent());
  505. $this->_createDevice();
  506. // put the result in storage:
  507. $this->getStorage($userAgent)
  508. ->write($this->serialize());
  509. }
  510. // Mark the object as immutable
  511. $this->_immutable = true;
  512. // Return the device instance
  513. return $this->_device;
  514. }
  515. /**
  516. * Retrieve the browser type
  517. *
  518. * @return string $browserType
  519. */
  520. public function getBrowserType()
  521. {
  522. return $this->_browserType;
  523. }
  524. /**
  525. * Set the browser "type"
  526. *
  527. * @param string $browserType
  528. * @return Zend_Http_UserAgent
  529. */
  530. public function setBrowserType($browserType)
  531. {
  532. if ($this->_immutable) {
  533. require_once 'Zend/Http/UserAgent/Exception.php';
  534. throw new Zend_Http_UserAgent_Exception(
  535. 'The User-Agent device object has already been retrieved; the browser type is now immutable'
  536. );
  537. }
  538. $this->_browserType = $browserType;
  539. return $this;
  540. }
  541. /**
  542. * Retrieve the "$_SERVER" array
  543. *
  544. * Basically, the $_SERVER array or an equivalent container storing the
  545. * data that will be introspected.
  546. *
  547. * If the value has not been previously set, it sets itself from the
  548. * $_SERVER superglobal.
  549. *
  550. * @return array
  551. */
  552. public function getServer()
  553. {
  554. if (null === $this->_server) {
  555. $this->setServer($_SERVER);
  556. }
  557. return $this->_server;
  558. }
  559. /**
  560. * Set the "$_SERVER" array
  561. *
  562. * Basically, the $_SERVER array or an equivalent container storing the
  563. * data that will be introspected.
  564. *
  565. * @param array|ArrayAccess $server
  566. * @return void
  567. * @throws Zend_Http_UserAgent_Exception on invalid parameter
  568. */
  569. public function setServer($server)
  570. {
  571. if ($this->_immutable) {
  572. require_once 'Zend/Http/UserAgent/Exception.php';
  573. throw new Zend_Http_UserAgent_Exception(
  574. 'The User-Agent device object has already been retrieved; the server array is now immutable'
  575. );
  576. }
  577. if (!is_array($server) && !$server instanceof Traversable) {
  578. require_once 'Zend/Http/UserAgent/Exception.php';
  579. throw new Zend_Http_UserAgent_Exception(sprintf(
  580. 'Expected an array or object implementing Traversable; received %s',
  581. (is_object($server) ? get_class($server) : gettype($server))
  582. ));
  583. }
  584. // Get an array if we don't have one
  585. if ($server instanceof ArrayObject) {
  586. $server = $server->getArrayCopy();
  587. } elseif ($server instanceof Traversable) {
  588. $tmp = array();
  589. foreach ($server as $key => $value) {
  590. $tmp[$key] = $value;
  591. }
  592. $server = $tmp;
  593. unset($tmp);
  594. }
  595. // Normalize key case
  596. $server = array_change_key_case($server, CASE_LOWER);
  597. $this->_server = $server;
  598. return $this;
  599. }
  600. /**
  601. * Retrieve a server value
  602. *
  603. * @param string $key
  604. * @return mixed
  605. */
  606. public function getServerValue($key)
  607. {
  608. $key = strtolower($key);
  609. $server = $this->getServer();
  610. $return = null;
  611. if (isset($server[$key])) {
  612. $return = $server[$key];
  613. }
  614. unset($server);
  615. return $return;
  616. }
  617. /**
  618. * Set a server value
  619. *
  620. * @param string|int|float $key
  621. * @param mixed $value
  622. * @return void
  623. */
  624. public function setServerValue($key, $value)
  625. {
  626. if ($this->_immutable) {
  627. require_once 'Zend/Http/UserAgent/Exception.php';
  628. throw new Zend_Http_UserAgent_Exception(
  629. 'The User-Agent device object has already been retrieved; the server array is now immutable'
  630. );
  631. }
  632. $server = $this->getServer(); // ensure it's been initialized
  633. $key = strtolower($key);
  634. $this->_server[$key] = $value;
  635. return $this;
  636. }
  637. /**
  638. * Set plugin loader
  639. *
  640. * @param string $type Type of plugin loader; one of 'storage', (?)
  641. * @param string|Zend_Loader_PluginLoader $loader
  642. * @return Zend_Http_UserAgent
  643. */
  644. public function setPluginLoader($type, $loader)
  645. {
  646. $type = $this->_validateLoaderType($type);
  647. if (is_string($loader)) {
  648. if (!class_exists($loader)) {
  649. require_once 'Zend/Loader.php';
  650. Zend_Loader::loadClass($loader);
  651. }
  652. $loader = new $loader();
  653. } elseif (!is_object($loader)) {
  654. require_once 'Zend/Http/UserAgent/Exception.php';
  655. throw new Zend_Http_UserAgent_Exception(sprintf(
  656. 'Expected a plugin loader class or object; received %s',
  657. gettype($loader)
  658. ));
  659. }
  660. if (!$loader instanceof Zend_Loader_PluginLoader) {
  661. require_once 'Zend/Http/UserAgent/Exception.php';
  662. throw new Zend_Http_UserAgent_Exception(sprintf(
  663. 'Expected an object extending Zend_Loader_PluginLoader; received %s',
  664. get_class($loader)
  665. ));
  666. }
  667. $basePrefix = 'Zend_Http_UserAgent_';
  668. $basePath = 'Zend/Http/UserAgent/';
  669. switch ($type) {
  670. case 'storage':
  671. $prefix = $basePrefix . 'Storage';
  672. $path = $basePath . 'Storage';
  673. break;
  674. case 'device':
  675. $prefix = $basePrefix;
  676. $path = $basePath;
  677. break;
  678. }
  679. $loader->addPrefixPath($prefix, $path);
  680. $this->_loaders[$type] = $loader;
  681. return $this;
  682. }
  683. /**
  684. * Get a plugin loader
  685. *
  686. * @param string $type A valid plugin loader type; see {@link $_loaderTypes}
  687. * @return Zend_Loader_PluginLoader
  688. */
  689. public function getPluginLoader($type)
  690. {
  691. $type = $this->_validateLoaderType($type);
  692. if (!isset($this->_loaders[$type])) {
  693. require_once 'Zend/Loader/PluginLoader.php';
  694. $this->setPluginLoader($type, new Zend_Loader_PluginLoader());
  695. }
  696. return $this->_loaders[$type];
  697. }
  698. /**
  699. * Validate a plugin loader type
  700. *
  701. * Verifies that it is in {@link $_loaderTypes}, and returns a normalized
  702. * version of the type.
  703. *
  704. * @param string $type
  705. * @return string
  706. * @throws Zend_Http_UserAgent_Exception on invalid type
  707. */
  708. protected function _validateLoaderType($type)
  709. {
  710. $type = strtolower($type);
  711. if (!in_array($type, $this->_loaderTypes)) {
  712. $types = implode(', ', $this->_loaderTypes);
  713. require_once 'Zend/Http/UserAgent/Exception.php';
  714. throw new Zend_Http_UserAgent_Exception(sprintf(
  715. 'Expected one of "%s" for plugin loader type; received "%s"',
  716. $types,
  717. (string) $type
  718. ));
  719. }
  720. return $type;
  721. }
  722. /**
  723. * Run the identification sequence to match the right browser type according to the
  724. * user agent
  725. *
  726. * @return Zend_Http_UserAgent_Result
  727. */
  728. protected function _matchUserAgent()
  729. {
  730. $type = self::DEFAULT_BROWSER_TYPE;
  731. // If we have no identification sequence, just return the default type
  732. if (empty($this->_config['identification_sequence'])) {
  733. return $type;
  734. }
  735. // Get sequence against which to match
  736. $sequence = explode(',', $this->_config['identification_sequence']);
  737. // If a browser type is already configured, push that to the front of the list
  738. if (null !== ($browserType = $this->getBrowserType())) {
  739. array_unshift($sequence, $browserType);
  740. }
  741. // Append the default browser type to the list if not alread in the list
  742. if (!in_array($type, $sequence)) {
  743. $sequence[] = $type;
  744. }
  745. // Test each type until we find a match
  746. foreach ($sequence as $browserType) {
  747. $browserType = trim($browserType);
  748. $className = $this->_getUserAgentDevice($browserType);
  749. // Attempt to match this device class
  750. if ($this->_match($className)) {
  751. $type = $browserType;
  752. $this->_browserTypeClass[$type] = $className;
  753. break;
  754. }
  755. }
  756. return $type;
  757. }
  758. /**
  759. * Creates device object instance
  760. *
  761. * @return void
  762. */
  763. protected function _createDevice()
  764. {
  765. $browserType = $this->getBrowserType();
  766. $classname = $this->_getUserAgentDevice($browserType);
  767. $this->_device = new $classname($this->getUserAgent(), $this->getServer(), $this->getConfig());
  768. }
  769. }