text:
<?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 Client_Adapter
 * @version    $Id: Curl.php 24272 2011-07-27 21:12:08Z mcleod@spaceweb.nl $
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */

/**
 * @see Zend_Uri_Http
 */
require_once 'Zend/Uri/Http.php';

/**
 * @see Zend_Http_Client_Adapter_Interface
 */
require_once 'Zend/Http/Client/Adapter/Interface.php';
/**
 * @see Zend_Http_Client_Adapter_Stream
 */
require_once 'Zend/Http/Client/Adapter/Stream.php';

/**
 * An adapter class for Zend_Http_Client based on the curl extension.
 * Curl requires libcurl. See for full requirements the PHP manual: http://php.net/curl
 *
 * @category   Zend
 * @package    Zend_Http
 * @subpackage Client_Adapter
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Http_Client_Adapter_Curl implements Zend_Http_Client_Adapter_Interface, Zend_Http_Client_Adapter_Stream
{
    /**
     * Parameters array
     *
     * @var array
     */
    protected $_config = array();

    /**
     * What host/port are we connected to?
     *
     * @var array
     */
    protected $_connected_to = array(null, null);

    /**
     * The curl session handle
     *
     * @var resource|null
     */
    protected $_curl = null;

    /**
     * List of cURL options that should never be overwritten
     *
     * @var array
     */
    protected $_invalidOverwritableCurlOptions;

    /**
     * Response gotten from server
     *
     * @var string
     */
    protected $_response = null;

    /**
     * Stream for storing output
     *
     * @var resource
     */
    protected $out_stream;

    /**
     * Adapter constructor
     *
     * Config is set using setConfig()
     *
     * @return void
     * @throws Zend_Http_Client_Adapter_Exception
     */
    public function __construct()
    {
        if (!extension_loaded('curl')) {
            require_once 'Zend/Http/Client/Adapter/Exception.php';
            throw new Zend_Http_Client_Adapter_Exception('cURL extension has to be loaded to use this Zend_Http_Client adapter.');
        }
        $this->_invalidOverwritableCurlOptions = array(
            CURLOPT_HTTPGET,
            CURLOPT_POST,
            CURLOPT_PUT,
            CURLOPT_CUSTOMREQUEST,
            CURLOPT_HEADER,
            CURLOPT_RETURNTRANSFER,
            CURLOPT_HTTPHEADER,
            CURLOPT_POSTFIELDS,
            CURLOPT_INFILE,
            CURLOPT_INFILESIZE,
            CURLOPT_PORT,
            CURLOPT_MAXREDIRS,
            CURLOPT_CONNECTTIMEOUT,
            CURL_HTTP_VERSION_1_1,
            CURL_HTTP_VERSION_1_0,
        );
    }

    /**
     * Set the configuration array for the adapter
     *
     * @throws Zend_Http_Client_Adapter_Exception
     * @param  Zend_Config | array $config
     * @return Zend_Http_Client_Adapter_Curl
     */
    public function setConfig($config = array())
    {
        if ($config instanceof Zend_Config) {
            $config = $config->toArray();

        } elseif (! is_array($config)) {
            require_once 'Zend/Http/Client/Adapter/Exception.php';
            throw new Zend_Http_Client_Adapter_Exception(
                'Array or Zend_Config object expected, got ' . gettype($config)
            );
        }

        if(isset($config['proxy_user']) && isset($config['proxy_pass'])) {
            $this->setCurlOption(CURLOPT_PROXYUSERPWD, $config['proxy_user'].":".$config['proxy_pass']);
            unset($config['proxy_user'], $config['proxy_pass']);
        }

        foreach ($config as $k => $v) {
            $option = strtolower($k);
            switch($option) {
                case 'proxy_host':
                    $this->setCurlOption(CURLOPT_PROXY, $v);
                    break;
                case 'proxy_port':
                    $this->setCurlOption(CURLOPT_PROXYPORT, $v);
                    break;
                default:
                    $this->_config[$option] = $v;
                    break;
            }
        }

        return $this;
    }

    /**
      * Retrieve the array of all configuration options
      *
      * @return array
      */
     public function getConfig()
     {
         return $this->_config;
     }

    /**
     * Direct setter for cURL adapter related options.
     *
     * @param  string|int $option
     * @param  mixed $value
     * @return Zend_Http_Adapter_Curl
     */
    public function setCurlOption($option, $value)
    {
        if (!isset($this->_config['curloptions'])) {
            $this->_config['curloptions'] = array();
        }
        $this->_config['curloptions'][$option] = $value;
        return $this;
    }

    /**
     * Initialize curl
     *
     * @param  string  $host
     * @param  int     $port
     * @param  boolean $secure
     * @return void
     * @throws Zend_Http_Client_Adapter_Exception if unable to connect
     */
    public function connect($host, $port = 80, $secure = false)
    {
        // If we're already connected, disconnect first
        if ($this->_curl) {
            $this->close();
        }

        // If we are connected to a different server or port, disconnect first
        if ($this->_curl
            && is_array($this->_connected_to)
            && ($this->_connected_to[0] != $host
            || $this->_connected_to[1] != $port)
        ) {
            $this->close();
        }

        // Do the actual connection
        $this->_curl = curl_init();
        if ($port != 80) {
            curl_setopt($this->_curl, CURLOPT_PORT, intval($port));
        }

        // Set timeout
        curl_setopt($this->_curl, CURLOPT_CONNECTTIMEOUT, $this->_config['timeout']);

        // Set Max redirects
        curl_setopt($this->_curl, CURLOPT_MAXREDIRS, $this->_config['maxredirects']);

        if (!$this->_curl) {
            $this->close();

            require_once 'Zend/Http/Client/Adapter/Exception.php';
            throw new Zend_Http_Client_Adapter_Exception('Unable to Connect to ' .  $host . ':' . $port);
        }

        if ($secure !== false) {
            // Behave the same like Zend_Http_Adapter_Socket on SSL options.
            if (isset($this->_config['sslcert'])) {
                curl_setopt($this->_curl, CURLOPT_SSLCERT, $this->_config['sslcert']);
            }
            if (isset($this->_config['sslpassphrase'])) {
                curl_setopt($this->_curl, CURLOPT_SSLCERTPASSWD, $this->_config['sslpassphrase']);
            }
        }

        // Update connected_to
        $this->_connected_to = array($host, $port);
    }

    /**
     * Send request to the remote server
     *
     * @param  string        $method
     * @param  Zend_Uri_Http $uri
     * @param  float         $http_ver
     * @param  array         $headers
     * @param  string        $body
     * @return string        $request
     * @throws Zend_Http_Client_Adapter_Exception If connection fails, connected to wrong host, no PUT file defined, unsupported method, or unsupported cURL option
     */
    public function write($method, $uri, $httpVersion = 1.1, $headers = array(), $body = '')
    {
        // Make sure we're properly connected
        if (!$this->_curl) {
            require_once 'Zend/Http/Client/Adapter/Exception.php';
            throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are not connected");
        }

        if ($this->_connected_to[0] != $uri->getHost() || $this->_connected_to[1] != $uri->getPort()) {
            require_once 'Zend/Http/Client/Adapter/Exception.php';
            throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong host");
        }

        // set URL
        curl_setopt($this->_curl, CURLOPT_URL, $uri->__toString());

        // ensure correct curl call
        $curlValue = true;
        switch ($method) {
            case Zend_Http_Client::GET:
                $curlMethod = CURLOPT_HTTPGET;
                break;

            case Zend_Http_Client::POST:
                $curlMethod = CURLOPT_POST;
                break;

            case Zend_Http_Client::PUT:
                // There are two different types of PUT request, either a Raw Data string has been set
                // or CURLOPT_INFILE and CURLOPT_INFILESIZE are used.
                if(is_resource($body)) {
                    $this->_config['curloptions'][CURLOPT_INFILE] = $body;
                }
                if (isset($this->_config['curloptions'][CURLOPT_INFILE])) {
                    // Now we will probably already have Content-Length set, so that we have to delete it
                    // from $headers at this point:
                    foreach ($headers AS $k => $header) {
                        if (preg_match('/Content-Length:\s*(\d+)/i', $header, $m)) {
                            if(is_resource($body)) {
                                $this->_config['curloptions'][CURLOPT_INFILESIZE] = (int)$m[1];
                            }
                            unset($headers[$k]);
                        }
                    }

                    if (!isset($this->_config['curloptions'][CURLOPT_INFILESIZE])) {
                        require_once 'Zend/Http/Client/Adapter/Exception.php';
                        throw new Zend_Http_Client_Adapter_Exception("Cannot set a file-handle for cURL option CURLOPT_INFILE without also setting its size in CURLOPT_INFILESIZE.");
                    }

                    if(is_resource($body)) {
                        $body = '';
                    }

                    $curlMethod = CURLOPT_PUT;
                } else {
                    $curlMethod = CURLOPT_CUSTOMREQUEST;
                    $curlValue = "PUT";
                }
                break;

            case Zend_Http_Client::DELETE:
                $curlMethod = CURLOPT_CUSTOMREQUEST;
                $curlValue = "DELETE";
                break;

            case Zend_Http_Client::OPTIONS:
                $curlMethod = CURLOPT_CUSTOMREQUEST;
                $curlValue = "OPTIONS";
                break;

            case Zend_Http_Client::TRACE:
                $curlMethod = CURLOPT_CUSTOMREQUEST;
                $curlValue = "TRACE";
                break;

            case Zend_Http_Client::HEAD:
                $curlMethod = CURLOPT_CUSTOMREQUEST;
                $curlValue = "HEAD";
                break;

            default:
                // For now, through an exception for unsupported request methods
                require_once 'Zend/Http/Client/Adapter/Exception.php';
                throw new Zend_Http_Client_Adapter_Exception("Method currently not supported");
        }

        if(is_resource($body) && $curlMethod != CURLOPT_PUT) {
            require_once 'Zend/Http/Client/Adapter/Exception.php';
            throw new Zend_Http_Client_Adapter_Exception("Streaming requests are allowed only with PUT");
        }

        // get http version to use
        $curlHttp = ($httpVersion == 1.1) ? CURL_HTTP_VERSION_1_1 : CURL_HTTP_VERSION_1_0;

        // mark as HTTP request and set HTTP method
        curl_setopt($this->_curl, $curlHttp, true);
        curl_setopt($this->_curl, $curlMethod, $curlValue);

        if($this->out_stream) {
            // headers will be read into the response
            curl_setopt($this->_curl, CURLOPT_HEADER, false);
            curl_setopt($this->_curl, CURLOPT_HEADERFUNCTION, array($this, "readHeader"));
            // and data will be written into the file
            curl_setopt($this->_curl, CURLOPT_FILE, $this->out_stream);
        } else {
            // ensure headers are also returned
            curl_setopt($this->_curl, CURLOPT_HEADER, true);

            // ensure actual response is returned
            curl_setopt($this->_curl, CURLOPT_RETURNTRANSFER, true);
        }

        // set additional headers
        $headers['Accept'] = '';
        curl_setopt($this->_curl, CURLOPT_HTTPHEADER, $headers);

        /**
         * Make sure POSTFIELDS is set after $curlMethod is set:
         * @link http://de2.php.net/manual/en/function.curl-setopt.php#81161
         */
        if ($method == Zend_Http_Client::POST) {
            curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $body);
        } elseif ($curlMethod == CURLOPT_PUT) {
            // this covers a PUT by file-handle:
            // Make the setting of this options explicit (rather than setting it through the loop following a bit lower)
            // to group common functionality together.
            curl_setopt($this->_curl, CURLOPT_INFILE, $this->_config['curloptions'][CURLOPT_INFILE]);
            curl_setopt($this->_curl, CURLOPT_INFILESIZE, $this->_config['curloptions'][CURLOPT_INFILESIZE]);
            unset($this->_config['curloptions'][CURLOPT_INFILE]);
            unset($this->_config['curloptions'][CURLOPT_INFILESIZE]);
        } elseif ($method == Zend_Http_Client::PUT) {
            // This is a PUT by a setRawData string, not by file-handle
            curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $body);
        } elseif ($method == Zend_Http_Client::DELETE) {
            // This is a DELETE by a setRawData string
            curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $body);
        }

        // set additional curl options
        if (isset($this->_config['curloptions'])) {
            foreach ((array)$this->_config['curloptions'] as $k => $v) {
                if (!in_array($k, $this->_invalidOverwritableCurlOptions)) {
                    if (curl_setopt($this->_curl, $k, $v) == false) {
                        require_once 'Zend/Http/Client/Exception.php';
                        throw new Zend_Http_Client_Exception(sprintf("Unknown or erroreous cURL option '%s' set", $k));
                    }
                }
            }
        }

        // send the request
        $response = curl_exec($this->_curl);

        // if we used streaming, headers are already there
        if(!is_resource($this->out_stream)) {
            $this->_response = $response;
        }

        $request  = curl_getinfo($this->_curl, CURLINFO_HEADER_OUT);
        $request .= $body;

        if (empty($this->_response)) {
            require_once 'Zend/Http/Client/Exception.php';
            throw new Zend_Http_Client_Exception("Error in cURL request: " . curl_error($this->_curl));
        }

        // cURL automatically decodes chunked-messages, this means we have to disallow the Zend_Http_Response to do it again
        if (stripos($this->_response, "Transfer-Encoding: chunked\r\n")) {
            $this->_response = str_ireplace("Transfer-Encoding: chunked\r\n", '', $this->_response);
        }

        // Eliminate multiple HTTP responses.
        do {
            $parts  = preg_split('|(?:\r?\n){2}|m', $this->_response, 2);
            $again  = false;

            if (isset($parts[1]) && preg_match("|^HTTP/1\.[01](.*?)\r\n|mi", $parts[1])) {
                $this->_response    = $parts[1];
                $again              = true;
            }
        } while ($again);

        // cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string:
        if (stripos($this->_response, "HTTP/1.0 200 Connection established\r\n\r\n") !== false) {
            $this->_response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $this->_response);
        }

        return $request;
    }

    /**
     * Return read response from server
     *
     * @return string
     */
    public function read()
    {
        return $this->_response;
    }

    /**
     * Close the connection to the server
     *
     */
    public function close()
    {
        if(is_resource($this->_curl)) {
            curl_close($this->_curl);
        }
        $this->_curl         = null;
        $this->_connected_to = array(null, null);
    }

    /**
     * Get cUrl Handle
     *
     * @return resource
     */
    public function getHandle()
    {
        return $this->_curl;
    }

    /**
     * Set output stream for the response
     *
     * @param resource $stream
     * @return Zend_Http_Client_Adapter_Socket
     */
    public function setOutputStream($stream)
    {
        $this->out_stream = $stream;
        return $this;
    }

    /**
     * Header reader function for CURL
     *
     * @param resource $curl
     * @param string $header
     * @return int
     */
    public function readHeader($curl, $header)
    {
        $this->_response .= $header;
        return strlen($header);
    }
}


text:
<?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
 */

/**
 * Interface defining a browser device type.
 *
 * @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
 */
interface Zend_Http_UserAgent_Device extends Serializable
{
    /**
     * Constructor
     *
     * Allows injecting user agent, server array, and/or config array. If an
     * array is provided for the first argument, the assumption should be that
     * the device object is being seeded with cached values from serialization.
     *
     * @param  null|string|array $userAgent
     * @param  array $server
     * @param  array $config
     * @return void
     */
    public function __construct($userAgent = null, array $server = array(), array $config = array());

    /**
     * Attempt to match the user agent
     *
     * Return either an array of browser signature strings, or a boolean.
     *
     * @param  string $userAgent
     * @param  array $server
     * @return bool|array
     */
    public static function match($userAgent, $server);

    /**
     * Get all browser/device features
     *
     * @return array
     */
    public function getAllFeatures();

    /**
     * Get all of the browser/device's features' groups
     *
     * @return void
     */
    public function getAllGroups();

    /**
     * Whether or not the device has a given feature
     *
     * @param  string $feature
     * @return bool
     */
    public function hasFeature($feature);

    /**
     * Get the value of a specific device feature
     *
     * @param  string $feature
     * @return mixed
     */
    public function getFeature($feature);

    /**
     * Get the browser type
     *
     * @return string
     */
    public function getBrowser();

    /**
     * Retrurn the browser version
     *
     * @return string
     */
    public function getBrowserVersion();

    /**
     * Get an array of features associated with a group
     *
     * @param  string $group
     * @return array
     */
    public function getGroup($group);

    /**
     * Retrieve image format support
     *
     * @return array
     */
    public function getImageFormatSupport();

    /**
     * Get image types
     *
     * @return array
     */
    public function getImages();

    /**
     * Get the maximum image height supported by this device
     *
     * @return int
     */
    public function getMaxImageHeight();

    /**
     * Get the maximum image width supported by this device
     *
     * @return int
     */
    public function getMaxImageWidth();

    /**
     * Get the physical screen height of this device
     *
     * @return int
     */
    public function getPhysicalScreenHeight();

    /**
     * Get the physical screen width of this device
     *
     * @return int
     */
    public function getPhysicalScreenWidth();

    /**
     * Get the preferred markup type
     *
     * @return string
     */
    public function getPreferredMarkup();

    /**
     * Get the user agent string
     *
     * @return string
     */
    public function getUserAgent();

    /**
     * Get supported X/HTML version
     *
     * @return int
     */
    public function getXhtmlSupportLevel();

    /**
     * Does the device support Flash?
     *
     * @return bool
     */
    public function hasFlashSupport();

    /**
     * Does the device support PDF?
     *
     * @return bool
     */
    public function hasPdfSupport();

    /**
     * Does the device have a phone number associated with it?
     *
     * @return bool
     */
    public function hasPhoneNumber();

    /**
     * Does the device support HTTPS?
     *
     * @return bool
     */
    public function httpsSupport();
}

repo_name: michael-romer/zf-boilerplate

repo_language: PHP

mime_type: text/html


text:
<?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/Desktop.php';

/**
 * Offline browser type matcher
 *
 * @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
 */
class Zend_Http_UserAgent_Offline extends Zend_Http_UserAgent_Desktop
{
    /**
     * User Agent Signatures
     *
     * @var array
     */
    protected static $_uaSignatures = array(
        'wget',
        'webzip',
        'webcopier',
        'downloader',
        'superbot',
        'offline',
    );

    /**
     * Comparison of the UserAgent chain and User Agent signatures
     *
     * @param  string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        return self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures);
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'offline';
    }
}


text:
<?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/AbstractDevice.php';

/**
 * Probe browser type matcher
 *
 * @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
 */
class Zend_Http_UserAgent_Probe extends Zend_Http_UserAgent_AbstractDevice
{
    /**
     * User Agent Signatures
     *
     * @var array
     */
    protected static $_uaSignatures = array(
        'witbe',
        'netvigie',
    );

    /**
     * Comparison of the UserAgent chain and User Agent signatures
     *
     * @param string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        return self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures);
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'probe';
    }

    /**
     * Look for features
     *
     * @return string
     */
    protected function _defineFeatures()
    {
        $this->setFeature('images', false, 'product_capability');
        $this->setFeature('iframes', false, 'product_capability');
        $this->setFeature('frames', false, 'product_capability');
        $this->setFeature('javascript', false, 'product_capability');
        return parent::_defineFeatures();
    }
}


text:
<?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
 */

/**
 * Zend_Exception
 */
require_once 'Zend/Exception.php';

/**
 * @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
 */
class Zend_Http_UserAgent_Exception extends Zend_Exception
{
}


text:
<?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/AbstractDevice.php';

/**
 * Mobile browser type matcher
 *
 * @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
 */
class Zend_Http_UserAgent_Mobile extends Zend_Http_UserAgent_AbstractDevice
{

    const DEFAULT_FEATURES_ADAPTER_CLASSNAME = 'Zend_Http_UserAgent_Features_Adapter_WurflApi';

    const DEFAULT_FEATURES_ADAPTER_PATH = 'Zend/Http/UserAgent/Features/Adapter/WurflApi.php';

    /**
     * User Agent Signatures
     *
     * @var array
     */
    protected static $_uaSignatures = array(
        'iphone',
        'ipod',
        'ipad',
        'android',
        'blackberry',
        'opera mini',
        'opera mobi',
        'palm',
        'palmos',
        'elaine',
        'windows ce',
        'icab',
        '_mms',
        'ahong',
        'archos',
        'armv',
        'astel',
        'avantgo',
        'benq',
        'blazer',
        'brew',
        'com2',
        'compal',
        'danger',
        'pocket',
        'docomo',
        'epoc',
        'ericsson',
        'eudoraweb',
        'hiptop',
        'htc-',
        'htc_',
        'iemobile',
        'iris',
        'j-phone',
        'kddi',
        'kindle',
        'lg ',
        'lg-',
        'lg/',
        'lg;lx',
        'lge vx',
        'lge',
        'lge-',
        'lge-cx',
        'lge-lx',
        'lge-mx',
        'linux armv',
        'maemo',
        'midp',
        'mini 9.5',
        'minimo',
        'mob-x',
        'mobi',
        'mobile',
        'mobilephone',
        'mot 24',
        'mot-',
        'motorola',
        'n410',
        'netfront',
        'nintendo wii',
        'nintendo',
        'nitro',
        'nokia',
        'novarra-vision',
        'nuvifone',
        'openweb',
        'opwv',
        'palmsource',
        'pdxgw',
        'phone',
        'playstation',
        'polaris',
        'portalmmm',
        'qt embedded',
        'reqwirelessweb',
        'sagem',
        'sam-r',
        'samsu',
        'samsung',
        'sec-',
        'sec-sgh',
        'semc-browser',
        'series60',
        'series70',
        'series80',
        'series90',
        'sharp',
        'sie-m',
        'sie-s',
        'smartphone',
        'sony cmd',
        'sonyericsson',
        'sprint',
        'spv',
        'symbian os',
        'symbian',
        'symbianos',
        'telco',
        'teleca',
        'treo',
        'up.browser',
        'up.link',
        'vodafone',
        'vodaphone',
        'webos',
        'wml',
        'windows phone os 7',
        'wireless',
        'wm5 pie',
        'wms pie',
        'xiino',
        'wap',
        'up/',
        'psion',
        'j2me',
        'klondike',
        'kbrowser'
    );

    /**
     * @var array
     */
    protected static $_haTerms = array(
        'midp',
        'wml',
        'vnd.rim',
        'vnd.wap',
        'j2me',
    );

    /**
     * first 4 letters of mobile User Agent chains
     *
     * @var array
     */
    protected static $_uaBegin = array(
        'w3c ',
        'acs-',
        'alav',
        'alca',
        'amoi',
        'audi',
        'avan',
        'benq',
        'bird',
        'blac',
        'blaz',
        'brew',
        'cell',
        'cldc',
        'cmd-',
        'dang',
        'doco',
        'eric',
        'hipt',
        'inno',
        'ipaq',
        'java',
        'jigs',
        'kddi',
        'keji',
        'leno',
        'lg-c',
        'lg-d',
        'lg-g',
        'lge-',
        'maui',
        'maxo',
        'midp',
        'mits',
        'mmef',
        'mobi',
        'mot-',
        'moto',
        'mwbp',
        'nec-',
        'newt',
        'noki',
        'palm',
        'pana',
        'pant',
        'phil',
        'play',
        'port',
        'prox',
        'qwap',
        'sage',
        'sams',
        'sany',
        'sch-',
        'sec-',
        'send',
        'seri',
        'sgh-',
        'shar',
        'sie-',
        'siem',
        'smal',
        'smar',
        'sony',
        'sph-',
        'symb',
        't-mo',
        'teli',
        'tim-',
        'tosh',
        'tsm-',
        'upg1',
        'upsi',
        'vk-v',
        'voda',
        'wap-',
        'wapa',
        'wapi',
        'wapp',
        'wapr',
        'webc',
        'winw',
        'winw',
        'xda',
        'xda-',
    );

    /**
     * Comparison of the UserAgent chain and User Agent signatures
     *
     * @param  string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        //  To have a quick identification, try light-weight tests first
        if (isset($server['all_http'])) {
            if (strpos(strtolower(str_replace(' ', '', $server['all_http'])), 'operam') !== false) {
                // Opera Mini or Opera Mobi
                return true;
            }
        }

        if (isset($server['http_x_wap_profile']) || isset($server['http_profile'])) {
            return true;
        }

        if (isset($server['http_accept'])) {
            if (self::_matchAgentAgainstSignatures($server['http_accept'], self::$_haTerms)) {
                return true;
            }
        }

        if (self::userAgentStart($userAgent)) {
            return true;
        }

        if (self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures)) {
            return true;
        }

        return false;
    }

    /**
     * Retrieve beginning clause of user agent
     *
     * @param  string $userAgent
     * @return string
     */
    public static function userAgentStart($userAgent)
    {

        $mobile_ua = strtolower(substr($userAgent, 0, 4));

        return (in_array($mobile_ua, self::$_uaBegin));
    }

    /**
     * Constructor
     *
     * @return void
     */
    public function __construct($userAgent = null, array $server = array(), array $config = array())
    {
        // For mobile detection, an adapter must be defined
        if (empty($config['mobile']['features'])) {
            $config['mobile']['features']['path']      = self::DEFAULT_FEATURES_ADAPTER_PATH;
            $config['mobile']['features']['classname'] = self::DEFAULT_FEATURES_ADAPTER_CLASSNAME;
        }
        parent::__construct($userAgent, $server, $config);
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'mobile';
    }

    /**
     * Look for features
     *
     * @return string
     */
    protected function _defineFeatures()
    {
        $this->setFeature('is_wireless_device', false, 'product_info');

        parent::_defineFeatures();

        if (isset($this->_aFeatures["mobile_browser"])) {
            $this->setFeature("browser_name", $this->_aFeatures["mobile_browser"]);
            $this->_browser = $this->_aFeatures["mobile_browser"];
        }
        if (isset($this->_aFeatures["mobile_browser_version"])) {
            $this->setFeature("browser_version", $this->_aFeatures["mobile_browser_version"]);
            $this->_browserVersion = $this->_aFeatures["mobile_browser_version"];
        }

        // markup
        if ($this->getFeature('device_os') == 'iPhone OS'
            || $this->getFeature('device_os_token') == 'iPhone OS'
        ) {
            $this->setFeature('markup', 'iphone');
        } else {
            $this->setFeature('markup', $this->getMarkupLanguage($this->getFeature('preferred_markup')));
        }

        // image format
        $this->_images = array();

        if ($this->getFeature('png')) {
            $this->_images[] = 'png';
        }
        if ($this->getFeature('jpg')) {
            $this->_images[] = 'jpg';
        }
        if ($this->getFeature('gif')) {
            $this->_images[] = 'gif';
        }
        if ($this->getFeature('wbmp')) {
            $this->_images[] = 'wbmp';
        }

        return $this->_aFeatures;
    }

    /**
     * Determine markup language expected
     *
     * @access public
     * @return __TYPE__
     */
    public function getMarkupLanguage($preferredMarkup = null)
    {
        $return = '';
        switch ($preferredMarkup) {
            case 'wml_1_1':
            case 'wml_1_2':
            case 'wml_1_3':
                $return = 'wml'; //text/vnd.wap.wml encoding="ISO-8859-15"
            case 'html_wi_imode_compact_generic':
            case 'html_wi_imode_html_1':
            case 'html_wi_imode_html_2':
            case 'html_wi_imode_html_3':
            case 'html_wi_imode_html_4':
            case 'html_wi_imode_html_5':
                $return = 'chtml'; //text/html
            case 'html_wi_oma_xhtmlmp_1_0': //application/vnd.wap.xhtml+xml
            case 'html_wi_w3_xhtmlbasic': //application/xhtml+xml DTD XHTML Basic 1.0
                $return = 'xhtml';
            case 'html_web_3_2': //text/html DTD Html 3.2 Final
            case 'html_web_4_0': //text/html DTD Html 4.01 Transitional
                $return = '';
        }
        return $return;
    }

    /**
     * Determine image format support
     *
     * @return array
     */
    public function getImageFormatSupport()
    {
        return $this->_images;
    }

    /**
     * Determine maximum image height supported
     *
     * @return int
     */
    public function getMaxImageHeight()
    {
        return $this->getFeature('max_image_height');
    }

    /**
     * Determine maximum image width supported
     *
     * @return int
     */
    public function getMaxImageWidth()
    {
        return $this->getFeature('max_image_width');
    }

    /**
     * Determine physical screen height
     *
     * @return int
     */
    public function getPhysicalScreenHeight()
    {
        return $this->getFeature('physical_screen_height');
    }

    /**
     * Determine physical screen width
     *
     * @return int
     */
    public function getPhysicalScreenWidth()
    {
        return $this->getFeature('physical_screen_width');
    }

    /**
     * Determine preferred markup
     *
     * @return string
     */
    public function getPreferredMarkup()
    {
        return $this->getFeature("markup");
    }

    /**
     * Determine X/HTML support level
     *
     * @return int
     */
    public function getXhtmlSupportLevel()
    {
        return $this->getFeature('xhtml_support_level');
    }

    /**
     * Does the device support Flash?
     *
     * @return bool
     */
    public function hasFlashSupport()
    {
        return $this->getFeature('fl_browser');
    }

    /**
     * Does the device support PDF?
     *
     * @return bool
     */
    public function hasPdfSupport()
    {
        return $this->getFeature('pdf_support');
    }

    /**
     * Does the device have an associated phone number?
     *
     * @return bool
     */
    public function hasPhoneNumber()
    {
        return $this->getFeature('can_assign_phone_number');
    }

    /**
     * Does the device support HTTPS?
     *
     * @return bool
     */
    public function httpsSupport()
    {
        return ($this->getFeature('https_support') == 'supported');
    }
}


text:
<?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/Desktop.php';

/**
 * Console browser type matcher
 *
 * @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
 */
class Zend_Http_UserAgent_Console extends Zend_Http_UserAgent_Desktop
{
    /**
     * User Agent Signatures
     *
     * @var array
     */
    protected static $_uaSignatures = array(
        'playstation',
        'wii',
        'libnup',
    );

    /**
     * Comparison of the UserAgent chain and User Agent signatures
     *
     * @param string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        return self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures);
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'console';
    }
}


text:
<?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/Desktop.php';

/**
 * Checker browser type matcher
 *
 * @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
 */

class Zend_Http_UserAgent_Checker extends Zend_Http_UserAgent_Desktop
{

    /**
     * User Agent Signatures
     *
     * @var array
     */
    protected static $_uaSignatures = array(
        'abilogic',
        'checklink',
        'checker',
        'linksmanager',
        'mojoo',
        'notifixious',
        'ploetz',
        'zeller',
        'sitebar',
        'xenu',
        'sleuth',
    );

    /**
     * Comparison of the UserAgent chain and User Agent signatures
     *
     * @param string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        return self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures);
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'bot';
    }
}


text:
<?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]);
                if (isset($result['others']['detail'][1])) {
                    $result['browser_version']  = $result['others']['detail'][1][2];
                } elseif (count($result['others']['detail'])) {
                    $result['browser_version']  = $result['others']['detail'][0][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 (isset($result['others']['detail'][1]) && $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') {
                    if (isset($result['others']['detail'][1])) {
                        $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'][0][1] && $result['others']['detail'][0][1] != 'Version' ? $result['others']['detail'][0][1] : 'Safari');
                        $result['browser_version'] = $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]);
                    }
                    if (isset($comment[3])) {
                        $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;
    }
}


text:
<?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/AbstractDevice.php';

/**
 * Text browser type matcher
 *
 * @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
 */
class Zend_Http_UserAgent_Text extends Zend_Http_UserAgent_AbstractDevice
{
    /**
     * User Agent Signatures
     *
     * @var array
     */
    protected static $_uaSignatures = array(
        'lynx',
        'retawq',
        'w3m',
    );

    /**
     * Comparison of the UserAgent chain and User Agent signatures
     *
     * @param string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        return self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures);
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'text';
    }

    /**
     * Look for features
     *
     * @return string
     */
    protected function _defineFeatures()
    {
        $this->setFeature('images', false, 'product_capability');
        $this->setFeature('iframes', false, 'product_capability');
        $this->setFeature('frames', false, 'product_capability');
        $this->setFeature('javascript', false, 'product_capability');
        return parent::_defineFeatures();
    }

    /**
     * Determine supported image formats
     *
     * @return null
     */
    public function getImageFormatSupport()
    {
        return null;
    }

    /**
     * Get preferred markup format
     *
     * @return string
     */
    public function getPreferredMarkup()
    {
        return 'xhtml';
    }

    /**
     * Get supported X/HTML markup level
     *
     * @return int
     */
    public function getXhtmlSupportLevel()
    {
        return 1;
    }

    /**
     * Does the device support Flash?
     *
     * @return bool
     */
    public function hasFlashSupport()
    {

        return false;
    }

    /**
     * Does the device support PDF?
     *
     * @return bool
     */
    public function hasPdfSupport()
    {
        return false;
    }
}


text:
<?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/Desktop.php';

/**
 * Validator browser type matcher
 *
 * @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
 */
class Zend_Http_UserAgent_Validator extends Zend_Http_UserAgent_Desktop
{
    /**
     * User Agent Signatures
     *
     * @var array
     */
    protected static $_uaSignatures = array(
        'htmlvalidator',
        'csscheck',
        'cynthia',
        'htmlparser',
        'validator',
        'jfouffa',
        'jigsaw',
        'w3c_validator',
        'wdg_validator',
    );

    /**
     * Comparison of the UserAgent chain and User Agent signatures
     *
     * @param string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        return self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures);
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'validator';
    }
}


text:
<?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/AbstractDevice.php';

/**
 * Desktop browser type matcher
 *
 * @category   Zend
 * @package    Zend_Browser
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Http_UserAgent_Desktop extends Zend_Http_UserAgent_AbstractDevice
{

    /**
     * Used by default : must be always true
     *
     * @param string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        return true;
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'desktop';
    }
}


text:
<?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/Desktop.php';

/**
 * Email browser type matcher
 *
 * @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
 */
class Zend_Http_UserAgent_Email extends Zend_Http_UserAgent_Desktop
{
    /**
     * User Agent Signatures
     *
     * @var array
     */
    protected static $_uaSignatures = array(
        'thunderbird',
    );

    /**
     * Comparison of the UserAgent chain and User Agent signatures
     *
     * @param string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        return self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures);
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'email';
    }
}


text:
<?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/AbstractDevice.php';

/**
 * Feed browser type matcher
 *
 * @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
 */
class Zend_Http_UserAgent_Feed extends Zend_Http_UserAgent_AbstractDevice
{
    /**
     * User Agent Signatures
     *
     * @var array
     */
    protected static $_uaSignatures = array(
        'bloglines',
        'everyfeed',
        'feedfetcher',
        'gregarius',
    );

    /**
     * Comparison of the UserAgent chain and User Agent signatures
     *
     * @param  string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        return self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures);
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'feed';
    }

    /**
     * Look for features
     *
     * @return string
     */
    protected function _defineFeatures()
    {
        $this->setFeature('iframes',    false, 'product_capability');
        $this->setFeature('frames',     false, 'product_capability');
        $this->setFeature('javascript', false, 'product_capability');
        return parent::_defineFeatures();
    }
}


text:
<?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
 */

/**
 * @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
 */
interface Zend_Http_UserAgent_Storage
{
    /**
     * Returns true if and only if storage is empty
     *
     * @throws Zend_Http_UserAgent_Storage_Exception If it is impossible to determine whether storage is empty
     * @return boolean
     */
    public function isEmpty();

    /**
     * Returns the contents of storage associated to the key parameter
     *
     * Behavior is undefined when storage is empty.
     *
     * @throws Zend_Http_UserAgent_Storage_Exception If reading contents from storage is impossible
     * @return mixed
     */
    public function read();

    /**
     * Writes $contents associated to the key parameter to storage
     *
     * @param  mixed $contents
     * @throws Zend_Http_UserAgent_Storage_Exception If writing $contents to storage is impossible
     * @return void
     */
    public function write($contents);

    /**
     * Clears contents from storage
     *
     * @throws Zend_Http_UserAgent_Storage_Exception If clearing contents from storage is impossible
     * @return void
     */
    public function clear();
}


text:
<?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/AbstractDevice.php';

/**
 * Bot browser type matcher
 *
 * @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
 */

class Zend_Http_UserAgent_Bot extends Zend_Http_UserAgent_AbstractDevice
{

    /**
     * User Agent Signatures
     *
     * @var array
     */
    protected static $_uaSignatures = array(
        // The most common ones.
        'googlebot',
        'msnbot',
        'slurp',
        'yahoo',

        // The rest, alphabetically.
        'alexa',
        'appie',
        'archiver',
        'ask jeeves',
        'baiduspider',
        'bot',
        'crawl',
        'crawler',
        'curl',
        'eventbox',
        'facebookexternal',
        'fast',
        'feedfetcher-google',
        'firefly',
        'froogle',
        'gigabot',
        'girafabot',
        'google',
        'htdig',
        'infoseek',
        'inktomi',
        'java',
        'larbin',
        'looksmart',
        'mechanize',
        'mediapartners-google',
        'monitor',
        'nambu',
        'nationaldirectory',
        'novarra',
        'pear',
        'perl',
        'python',
        'rabaz',
        'radian',
        'rankivabot',
        'scooter',
        'sogou web spider',
        'spade',
        'sphere',
        'spider',
        'technoratisnoop',
        'tecnoseek',
        'teoma',
        'toolbar',
        'transcoder',
        'twitt',
        'url_spider_sql',
        'webalta crawler',
        'webbug',
        'webfindbot',
        'wordpress',
        'www.galaxy.com',
        'yahoo! searchmonkey',
        'yahoo! slurp',
        'yandex',
        'zyborg',
    );

    /**
     * Comparison of the UserAgent chain and browser signatures
     *
     * @param  string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        return self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures);
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'bot';
    }
}


text:
<?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/AbstractDevice.php';

/**
 * Spam browser type matcher
 *
 * @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
 */
class Zend_Http_UserAgent_Spam extends Zend_Http_UserAgent_AbstractDevice
{
    /**
     * @todo User Agent Signatures
     *
     * @var array
     */
    protected static $_uaSignatures = array(
        '',
    );

    /**
     * Comparison of the UserAgent chain and User Agent signatures
     *
     * @param  string $userAgent User Agent chain
     * @param  array $server $_SERVER like param
     * @return bool
     */
    public static function match($userAgent, $server)
    {
        return self::_matchAgentAgainstSignatures($userAgent, self::$_uaSignatures);
    }

    /**
     * Gives the current browser type
     *
     * @return string
     */
    public function getType()
    {
        return 'spam';
    }

    /**
     * Look for features
     *
     * @return string
     */
    protected function _defineFeatures()
    {
        $this->setFeature('images', false, 'product_capability');
        $this->setFeature('iframes', false, 'product_capability');
        $this->setFeature('frames', false, 'product_capability');
        $this->setFeature('javascript', false, 'product_capability');
        return parent::_defineFeatures();
    }
}


text:
<?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
 */

/**
 * @see Zend_Http_UserAgent_Exception
 */
require_once 'Zend/Http/UserAgent/Exception.php';

/**
 * @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
 */
class Zend_Http_UserAgent_Storage_Exception extends Zend_Http_UserAgent_Exception
{
}


text:
<?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
 * @version    $Id: NonPersistent.php 20096 2010-01-06 02:05:09Z bkarwin $
 */

/**
 * @see Zend_Http_UserAgent_Storage_Interface
 */
require_once 'Zend/Http/UserAgent/Storage.php';

/**
 * Non-Persistent Browser Storage
 *
 * Since HTTP Browserentication happens again on each request, this will always be
 * re-populated. So there's no need to use sessions, this simple value class
 * will hold the data for rest of the current request.
 *
 * @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
 */
class Zend_Http_UserAgent_Storage_NonPersistent
    implements Zend_Http_UserAgent_Storage
{
    /**
     * Holds the actual Browser data
     * @var mixed
     */
    protected $_data;

    /**
     * Returns true if and only if storage is empty
     *
     * @throws Zend_Http_UserAgent_Storage_Exception If it is impossible to determine whether storage is empty
     * @return boolean
     */
    public function isEmpty()
    {
        return empty($this->_data);
    }

    /**
     * Returns the contents of storage
     *
     * Behavior is undefined when storage is empty.
     *
     * @throws Zend_Http_UserAgent_Storage_Exception If reading contents from storage is impossible
     * @return mixed
     */
    public function read()
    {
        return $this->_data;
    }

    /**
     * Writes $contents to storage
     *
     * @param  mixed $contents
     * @throws Zend_Http_UserAgent_Storage_Exception If writing $contents to storage is impossible
     * @return void
     */
    public function write($contents)
    {
        $this->_data = $contents;
    }

    /**
     * Clears contents from storage
     *
     * @throws Zend_Http_UserAgent_Storage_Exception If clearing contents from storage is impossible
     * @return void
     */
    public function clear()
    {
        $this->_data = null;
    }
}