13 * to license@zend.com so we can send you a copy immediately. |
13 * to license@zend.com so we can send you a copy immediately. |
14 * |
14 * |
15 * @category Zend |
15 * @category Zend |
16 * @package Zend_Http_UserAgent |
16 * @package Zend_Http_UserAgent |
17 * @subpackage UserAgent |
17 * @subpackage UserAgent |
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
18 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
20 */ |
20 */ |
21 |
21 |
22 /** |
22 /** |
23 * Lists of User Agent chains for testing : |
23 * Lists of User Agent chains for testing : |
29 * - http://www.mobilemultimedia.be/fr/ |
29 * - http://www.mobilemultimedia.be/fr/ |
30 * |
30 * |
31 * @category Zend |
31 * @category Zend |
32 * @package Zend_Http_UserAgent |
32 * @package Zend_Http_UserAgent |
33 * @subpackage UserAgent |
33 * @subpackage UserAgent |
34 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
34 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
35 * @license http://framework.zend.com/license/new-bsd New BSD License |
35 * @license http://framework.zend.com/license/new-bsd New BSD License |
36 */ |
36 */ |
37 class Zend_Http_UserAgent implements Serializable |
37 class Zend_Http_UserAgent implements Serializable |
38 { |
38 { |
39 /** |
39 /** |
50 * 'desktop' by default if the sequence return false for each item |
50 * 'desktop' by default if the sequence return false for each item |
51 */ |
51 */ |
52 const DEFAULT_BROWSER_TYPE = 'desktop'; |
52 const DEFAULT_BROWSER_TYPE = 'desktop'; |
53 |
53 |
54 /** |
54 /** |
55 * Default User Agent chain to prevent empty value |
55 * Default User Agent chain to prevent empty value |
56 */ |
56 */ |
57 const DEFAULT_HTTP_USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'; |
57 const DEFAULT_HTTP_USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'; |
58 |
58 |
59 /** |
59 /** |
60 * Default Http Accept param to prevent empty value |
60 * Default Http Accept param to prevent empty value |
61 */ |
61 */ |
62 const DEFAULT_HTTP_ACCEPT = "application/xhtml+xml"; |
62 const DEFAULT_HTTP_ACCEPT = "application/xhtml+xml"; |
63 |
63 |
64 /** |
64 /** |
65 * Default markup language |
65 * Default markup language |
66 */ |
66 */ |
67 const DEFAULT_MARKUP_LANGUAGE = "xhtml"; |
67 const DEFAULT_MARKUP_LANGUAGE = "xhtml"; |
68 |
68 |
69 /** |
69 /** |
70 * Browser type |
70 * Browser type |
83 protected $_browserTypeClass = array(); |
83 protected $_browserTypeClass = array(); |
84 |
84 |
85 /** |
85 /** |
86 * Array to store config |
86 * Array to store config |
87 * |
87 * |
88 * Default values are provided to ensure specific keys are present at |
88 * Default values are provided to ensure specific keys are present at |
89 * instantiation. |
89 * instantiation. |
90 * |
90 * |
91 * @var array |
91 * @var array |
92 */ |
92 */ |
93 protected $_config = array( |
93 protected $_config = array( |
94 'identification_sequence' => self::DEFAULT_IDENTIFICATION_SEQUENCE, |
94 'identification_sequence' => self::DEFAULT_IDENTIFICATION_SEQUENCE, |
95 'storage' => array( |
95 'storage' => array( |
164 } |
164 } |
165 } |
165 } |
166 |
166 |
167 /** |
167 /** |
168 * Serialized representation of the object |
168 * Serialized representation of the object |
169 * |
169 * |
170 * @return string |
170 * @return string |
171 */ |
171 */ |
172 public function serialize() |
172 public function serialize() |
173 { |
173 { |
|
174 $device = $this->getDevice(); |
174 $spec = array( |
175 $spec = array( |
175 'browser_type' => $this->_browserType, |
176 'browser_type' => $this->_browserType, |
176 'config' => $this->_config, |
177 'config' => $this->_config, |
177 'device_class' => get_class($this->_device), |
178 'device_class' => get_class($device), |
178 'device' => $this->_device->serialize(), |
179 'device' => $device->serialize(), |
179 'user_agent' => $this->getServerValue('http_user_agent'), |
180 'user_agent' => $this->getServerValue('http_user_agent'), |
180 'http_accept' => $this->getServerValue('http_accept'), |
181 'http_accept' => $this->getServerValue('http_accept'), |
181 ); |
182 ); |
182 return serialize($spec); |
183 return serialize($spec); |
183 } |
184 } |
184 |
185 |
185 /** |
186 /** |
186 * Unserialize a previous representation of the object |
187 * Unserialize a previous representation of the object |
187 * |
188 * |
188 * @param string $serialized |
189 * @param string $serialized |
189 * @return void |
190 * @return void |
190 */ |
191 */ |
191 public function unserialize($serialized) |
192 public function unserialize($serialized) |
192 { |
193 { |
207 $this->_device = new $deviceClass($deviceSpec); |
208 $this->_device = new $deviceClass($deviceSpec); |
208 } |
209 } |
209 |
210 |
210 /** |
211 /** |
211 * Configure instance |
212 * Configure instance |
212 * |
213 * |
213 * @param array|Zend_Config|ArrayAccess $options |
214 * @param array|Zend_Config|ArrayAccess $options |
214 * @return Zend_Http_UserAgent |
215 * @return Zend_Http_UserAgent |
215 */ |
216 */ |
216 public function setOptions($options) |
217 public function setOptions($options) |
217 { |
218 { |
218 if ($options instanceof Zend_Config) { |
219 if ($options instanceof Zend_Config) { |
219 $options = $options->toArray(); |
220 $options = $options->toArray(); |
220 } |
221 } |
221 |
222 |
222 if (!is_array($options) |
223 if (!is_array($options) |
223 && !$options instanceof ArrayAccess |
224 && !$options instanceof ArrayAccess |
224 && !$options instanceof Traversable |
225 && !$options instanceof Traversable |
225 ) { |
226 ) { |
226 require_once 'Zend/Http/UserAgent/Exception.php'; |
227 require_once 'Zend/Http/UserAgent/Exception.php'; |
227 throw new Zend_Http_UserAgent_Exception(sprintf( |
228 throw new Zend_Http_UserAgent_Exception(sprintf( |
228 'Invalid argument; expected array, Zend_Config object, or object implementing ArrayAccess and Traversable; received %s', |
229 'Invalid argument; expected array, Zend_Config object, or object implementing ArrayAccess and Traversable; received %s', |
313 $browserType = strtolower($browserType); |
314 $browserType = strtolower($browserType); |
314 if (isset($this->_browserTypeClass[$browserType])) { |
315 if (isset($this->_browserTypeClass[$browserType])) { |
315 return $this->_browserTypeClass[$browserType]; |
316 return $this->_browserTypeClass[$browserType]; |
316 } |
317 } |
317 |
318 |
318 if (isset($this->_config[$browserType]) |
319 if (isset($this->_config[$browserType]) |
319 && isset($this->_config[$browserType]['device']) |
320 && isset($this->_config[$browserType]['device']) |
320 ) { |
321 ) { |
321 $deviceConfig = $this->_config[$browserType]['device']; |
322 $deviceConfig = $this->_config[$browserType]['device']; |
322 if (is_array($deviceConfig) && isset($deviceConfig['classname'])) { |
323 if (is_array($deviceConfig) && isset($deviceConfig['classname'])) { |
323 $device = (string) $deviceConfig['classname']; |
324 $device = (string) $deviceConfig['classname']; |
408 } |
409 } |
409 |
410 |
410 /** |
411 /** |
411 * Returns the persistent storage handler |
412 * Returns the persistent storage handler |
412 * |
413 * |
413 * Session storage is used by default unless a different storage adapter |
414 * Session storage is used by default unless a different storage adapter |
414 * has been set via the "persistent_storage_adapter" key. That key should |
415 * has been set via the "persistent_storage_adapter" key. That key should |
415 * contain either a fully qualified class name, or a short name that |
416 * contain either a fully qualified class name, or a short name that |
416 * resolves via the plugin loader. |
417 * resolves via the plugin loader. |
417 * |
418 * |
418 * @param string $browser Browser identifier (User Agent chain) |
419 * @param string $browser Browser identifier (User Agent chain) |
419 * @return Zend_Http_UserAgent_Storage |
420 * @return Zend_Http_UserAgent_Storage |
420 */ |
421 */ |
480 return $this->_config; |
481 return $this->_config; |
481 } |
482 } |
482 |
483 |
483 /** |
484 /** |
484 * Config parameters is an Array or a Zend_Config object |
485 * Config parameters is an Array or a Zend_Config object |
485 * |
486 * |
486 * The allowed parameters are : |
487 * The allowed parameters are : |
487 * - the identification sequence (can be empty) => desktop browser type is the |
488 * - the identification sequence (can be empty) => desktop browser type is the |
488 * default browser type returned |
489 * default browser type returned |
489 * $config['identification_sequence'] : ',' separated browser types |
490 * $config['identification_sequence'] : ',' separated browser types |
490 * - the persistent storage adapter |
491 * - the persistent storage adapter |
491 * $config['persistent_storage_adapter'] = "Session" or "NonPersistent" |
492 * $config['persistent_storage_adapter'] = "Session" or "NonPersistent" |
492 * - to add or replace a browser type device |
493 * - to add or replace a browser type device |
493 * $config[(type)]['device']['path'] |
494 * $config[(type)]['device']['path'] |
494 * $config[(type)]['device']['classname'] |
495 * $config[(type)]['device']['classname'] |
495 * - to add or replace a browser type features adapter |
496 * - to add or replace a browser type features adapter |
496 * $config[(type)]['features']['path'] |
497 * $config[(type)]['features']['path'] |
497 * $config[(type)]['features']['classname'] |
498 * $config[(type)]['features']['classname'] |
498 * |
499 * |
499 * @param mixed $config (option) Config array |
500 * @param mixed $config (option) Config array |
500 * @return Zend_Http_UserAgent |
501 * @return Zend_Http_UserAgent |
501 */ |
502 */ |
502 public function setConfig($config = array()) |
503 public function setConfig($config = array()) |
503 { |
504 { |
504 if ($config instanceof Zend_Config) { |
505 if ($config instanceof Zend_Config) { |
505 $config = $config->toArray(); |
506 $config = $config->toArray(); |
506 } |
507 } |
507 |
508 |
508 // Verify that Config parameters are in an array. |
509 // Verify that Config parameters are in an array. |
509 if (!is_array($config) && !$config instanceof Traversable) { |
510 if (!is_array($config) && !$config instanceof Traversable) { |
510 require_once 'Zend/Http/UserAgent/Exception.php'; |
511 require_once 'Zend/Http/UserAgent/Exception.php'; |
511 throw new Zend_Http_UserAgent_Exception(sprintf( |
512 throw new Zend_Http_UserAgent_Exception(sprintf( |
512 'Config parameters must be in an array or a Traversable object; received "%s"', |
513 'Config parameters must be in an array or a Traversable object; received "%s"', |
526 $this->_config = array_merge($this->_config, $config); |
527 $this->_config = array_merge($this->_config, $config); |
527 return $this; |
528 return $this; |
528 } |
529 } |
529 |
530 |
530 /** |
531 /** |
531 * @return the $device |
532 * Returns the device object |
|
533 * |
|
534 * This is the object that will contain the various discovered device |
|
535 * capabilities. |
|
536 * |
|
537 * @return Zend_Http_UserAgent_Device $device |
532 */ |
538 */ |
533 public function getDevice() |
539 public function getDevice() |
534 { |
540 { |
535 if (null !== $this->_device) { |
541 if (null !== $this->_device) { |
536 return $this->_device; |
542 return $this->_device; |
538 |
544 |
539 $userAgent = $this->getUserAgent(); |
545 $userAgent = $this->getUserAgent(); |
540 |
546 |
541 // search an existing identification in the session |
547 // search an existing identification in the session |
542 $storage = $this->getStorage($userAgent); |
548 $storage = $this->getStorage($userAgent); |
543 |
549 |
544 if (!$storage->isEmpty()) { |
550 if (!$storage->isEmpty()) { |
545 // If the user agent and features are already existing, the |
551 // If the user agent and features are already existing, the |
546 // Zend_Http_UserAgent object is serialized in the session |
552 // Zend_Http_UserAgent object is serialized in the session |
547 $object = $storage->read(); |
553 $object = $storage->read(); |
548 $this->unserialize($object); |
554 $this->unserialize($object); |
549 } else { |
555 } else { |
550 // Otherwise, the identification is made and stored in the session. |
556 // Otherwise, the identification is made and stored in the session. |
551 // Find the browser type: |
557 // Find the browser type: |
552 $this->setBrowserType($this->_matchUserAgent()); |
558 $this->setBrowserType($this->_matchUserAgent()); |
553 $this->_createDevice(); |
559 $this->_createDevice(); |
554 |
560 |
555 // put the result in storage: |
561 // put the result in storage: |
556 $this->getStorage($userAgent) |
562 $this->getStorage($userAgent) |
557 ->write($this->serialize()); |
563 ->write($this->serialize()); |
558 } |
564 } |
559 |
565 |
594 } |
600 } |
595 |
601 |
596 /** |
602 /** |
597 * Retrieve the "$_SERVER" array |
603 * Retrieve the "$_SERVER" array |
598 * |
604 * |
599 * Basically, the $_SERVER array or an equivalent container storing the |
605 * Basically, the $_SERVER array or an equivalent container storing the |
600 * data that will be introspected. |
606 * data that will be introspected. |
601 * |
607 * |
602 * If the value has not been previously set, it sets itself from the |
608 * If the value has not been previously set, it sets itself from the |
603 * $_SERVER superglobal. |
609 * $_SERVER superglobal. |
604 * |
610 * |
605 * @return array |
611 * @return array |
606 */ |
612 */ |
607 public function getServer() |
613 public function getServer() |
611 } |
617 } |
612 return $this->_server; |
618 return $this->_server; |
613 } |
619 } |
614 |
620 |
615 /** |
621 /** |
616 * Retrieve the "$_SERVER" array |
622 * Set the "$_SERVER" array |
617 * |
623 * |
618 * Basically, the $_SERVER array or an equivalent container storing the |
624 * Basically, the $_SERVER array or an equivalent container storing the |
619 * data that will be introspected. |
625 * data that will be introspected. |
620 * |
626 * |
621 * @param array|ArrayAccess $server |
627 * @param array|ArrayAccess $server |
622 * @return void |
628 * @return void |
623 * @throws Zend_Http_UserAgent_Exception on invalid parameter |
629 * @throws Zend_Http_UserAgent_Exception on invalid parameter |
698 return $this; |
704 return $this; |
699 } |
705 } |
700 |
706 |
701 /** |
707 /** |
702 * Set plugin loader |
708 * Set plugin loader |
703 * |
709 * |
704 * @param string $type Type of plugin loader; one of 'storage', (?) |
710 * @param string $type Type of plugin loader; one of 'storage', (?) |
705 * @param string|Zend_Loader_PluginLoader $loader |
711 * @param string|Zend_Loader_PluginLoader $loader |
706 * @return Zend_Http_UserAgent |
712 * @return Zend_Http_UserAgent |
707 */ |
713 */ |
708 public function setPluginLoader($type, $loader) |
714 public function setPluginLoader($type, $loader) |
709 { |
715 { |
710 $type = $this->_validateLoaderType($type); |
716 $type = $this->_validateLoaderType($type); |
764 } |
770 } |
765 |
771 |
766 /** |
772 /** |
767 * Validate a plugin loader type |
773 * Validate a plugin loader type |
768 * |
774 * |
769 * Verifies that it is in {@link $_loaderTypes}, and returns a normalized |
775 * Verifies that it is in {@link $_loaderTypes}, and returns a normalized |
770 * version of the type. |
776 * version of the type. |
771 * |
777 * |
772 * @param string $type |
778 * @param string $type |
773 * @return string |
779 * @return string |
774 * @throws Zend_Http_UserAgent_Exception on invalid type |
780 * @throws Zend_Http_UserAgent_Exception on invalid type |
775 */ |
781 */ |
776 protected function _validateLoaderType($type) |
782 protected function _validateLoaderType($type) |
777 { |
783 { |