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_Json
 * @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: Encoder.php 24152 2011-06-24 15:23:19Z adamlundrigan $
 */

/**
 * Encode PHP constructs to JSON
 *
 * @category   Zend
 * @package    Zend_Json
 * @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_Json_Encoder
{
    /**
     * Whether or not to check for possible cycling
     *
     * @var boolean
     */
    protected $_cycleCheck;

    /**
     * Additional options used during encoding
     *
     * @var array
     */
    protected $_options = array();

    /**
     * Array of visited objects; used to prevent cycling.
     *
     * @var array
     */
    protected $_visited = array();

    /**
     * Constructor
     *
     * @param boolean $cycleCheck Whether or not to check for recursion when encoding
     * @param array $options Additional options used during encoding
     * @return void
     */
    protected function __construct($cycleCheck = false, $options = array())
    {
        $this->_cycleCheck = $cycleCheck;
        $this->_options = $options;
    }

    /**
     * Use the JSON encoding scheme for the value specified
     *
     * @param mixed $value The value to be encoded
     * @param boolean $cycleCheck Whether or not to check for possible object recursion when encoding
     * @param array $options Additional options used during encoding
     * @return string  The encoded value
     */
    public static function encode($value, $cycleCheck = false, $options = array())
    {
        $encoder = new self(($cycleCheck) ? true : false, $options);

        return $encoder->_encodeValue($value);
    }

    /**
     * Recursive driver which determines the type of value to be encoded
     * and then dispatches to the appropriate method. $values are either
     *    - objects (returns from {@link _encodeObject()})
     *    - arrays (returns from {@link _encodeArray()})
     *    - basic datums (e.g. numbers or strings) (returns from {@link _encodeDatum()})
     *
     * @param mixed $value The value to be encoded
     * @return string Encoded value
     */
    protected function _encodeValue(&$value)
    {
        if (is_object($value)) {
            return $this->_encodeObject($value);
        } else if (is_array($value)) {
            return $this->_encodeArray($value);
        }

        return $this->_encodeDatum($value);
    }

    /**
     * Encode an object to JSON by encoding each of the public properties
     *
     * A special property is added to the JSON object called '__className'
     * that contains the name of the class of $value. This is used to decode
     * the object on the client into a specific class.
     *
     * @param object $value
     * @return string
     * @throws Zend_Json_Exception If recursive checks are enabled and the object has been serialized previously
     */
    protected function _encodeObject(&$value)
    {
        if ($this->_cycleCheck) {
            if ($this->_wasVisited($value)) {

                if (isset($this->_options['silenceCyclicalExceptions'])
                    && $this->_options['silenceCyclicalExceptions']===true) {

                    return '"* RECURSION (' . get_class($value) . ') *"';

                } else {
                    require_once 'Zend/Json/Exception.php';
                    throw new Zend_Json_Exception(
                        'Cycles not supported in JSON encoding, cycle introduced by '
                        . 'class "' . get_class($value) . '"'
                    );
                }
            }

            $this->_visited[] = $value;
        }

        $props = '';

        if ($value instanceof Iterator) {
            $propCollection = $value;
        } else {
            $propCollection = get_object_vars($value);
        }

        foreach ($propCollection as $name => $propValue) {
            if (isset($propValue)) {
                $props .= ','
                        . $this->_encodeString($name)
                        . ':'
                        . $this->_encodeValue($propValue);
            }
        }

        $className = get_class($value);
        return '{"__className":' . $this->_encodeString($className)
                . $props . '}';
    }

    /**
     * Determine if an object has been serialized already
     *
     * @param mixed $value
     * @return boolean
     */
    protected function _wasVisited(&$value)
    {
        if (in_array($value, $this->_visited, true)) {
            return true;
        }

        return false;
    }

    /**
     * JSON encode an array value
     *
     * Recursively encodes each value of an array and returns a JSON encoded
     * array string.
     *
     * Arrays are defined as integer-indexed arrays starting at index 0, where
     * the last index is (count($array) -1); any deviation from that is
     * considered an associative array, and will be encoded as such.
     *
     * @param array& $array
     * @return string
     */
    protected function _encodeArray(&$array)
    {
        $tmpArray = array();

        // Check for associative array
        if (!empty($array) && (array_keys($array) !== range(0, count($array) - 1))) {
            // Associative array
            $result = '{';
            foreach ($array as $key => $value) {
                $key = (string) $key;
                $tmpArray[] = $this->_encodeString($key)
                            . ':'
                            . $this->_encodeValue($value);
            }
            $result .= implode(',', $tmpArray);
            $result .= '}';
        } else {
            // Indexed array
            $result = '[';
            $length = count($array);
            for ($i = 0; $i < $length; $i++) {
                $tmpArray[] = $this->_encodeValue($array[$i]);
            }
            $result .= implode(',', $tmpArray);
            $result .= ']';
        }

        return $result;
    }

    /**
     * JSON encode a basic data type (string, number, boolean, null)
     *
     * If value type is not a string, number, boolean, or null, the string
     * 'null' is returned.
     *
     * @param mixed& $value
     * @return string
     */
    protected function _encodeDatum(&$value)
    {
        $result = 'null';

        if (is_int($value) || is_float($value)) {
            $result = (string) $value;
            $result = str_replace(",", ".", $result);
        } elseif (is_string($value)) {
            $result = $this->_encodeString($value);
        } elseif (is_bool($value)) {
            $result = $value ? 'true' : 'false';
        }

        return $result;
    }

    /**
     * JSON encode a string value by escaping characters as necessary
     *
     * @param string& $value
     * @return string
     */
    protected function _encodeString(&$string)
    {
        // Escape these characters with a backslash:
        // " \ / \n \r \t \b \f
        $search  = array('\\', "\n", "\t", "\r", "\b", "\f", '"', '/');
        $replace = array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\"', '\\/');
        $string  = str_replace($search, $replace, $string);

        // Escape certain ASCII characters:
        // 0x08 => \b
        // 0x0c => \f
        $string = str_replace(array(chr(0x08), chr(0x0C)), array('\b', '\f'), $string);
        $string = self::encodeUnicodeString($string);

        return '"' . $string . '"';
    }

    /**
     * Encode the constants associated with the ReflectionClass
     * parameter. The encoding format is based on the class2 format
     *
     * @param ReflectionClass $cls
     * @return string Encoded constant block in class2 format
     */
    private static function _encodeConstants(ReflectionClass $cls)
    {
        $result    = "constants : {";
        $constants = $cls->getConstants();

        $tmpArray = array();
        if (!empty($constants)) {
            foreach ($constants as $key => $value) {
                $tmpArray[] = "$key: " . self::encode($value);
            }

            $result .= implode(', ', $tmpArray);
        }

        return $result . "}";
    }

    /**
     * Encode the public methods of the ReflectionClass in the
     * class2 format
     *
     * @param ReflectionClass $cls
     * @return string Encoded method fragment
     *
     */
    private static function _encodeMethods(ReflectionClass $cls)
    {
        $methods = $cls->getMethods();
        $result = 'methods:{';

        $started = false;
        foreach ($methods as $method) {
            if (! $method->isPublic() || !$method->isUserDefined()) {
                continue;
            }

            if ($started) {
                $result .= ',';
            }
            $started = true;

            $result .= '' . $method->getName(). ':function(';

            if ('__construct' != $method->getName()) {
                $parameters  = $method->getParameters();
                $paramCount  = count($parameters);
                $argsStarted = false;

                $argNames = "var argNames=[";
                foreach ($parameters as $param) {
                    if ($argsStarted) {
                        $result .= ',';
                    }

                    $result .= $param->getName();

                    if ($argsStarted) {
                        $argNames .= ',';
                    }

                    $argNames .= '"' . $param->getName() . '"';

                    $argsStarted = true;
                }
                $argNames .= "];";

                $result .= "){"
                         . $argNames
                         . 'var result = ZAjaxEngine.invokeRemoteMethod('
                         . "this, '" . $method->getName()
                         . "',argNames,arguments);"
                         . 'return(result);}';
            } else {
                $result .= "){}";
            }
        }

        return $result . "}";
    }

    /**
     * Encode the public properties of the ReflectionClass in the class2
     * format.
     *
     * @param ReflectionClass $cls
     * @return string Encode properties list
     *
     */
    private static function _encodeVariables(ReflectionClass $cls)
    {
        $properties = $cls->getProperties();
        $propValues = get_class_vars($cls->getName());
        $result = "variables:{";
        $cnt = 0;

        $tmpArray = array();
        foreach ($properties as $prop) {
            if (! $prop->isPublic()) {
                continue;
            }

            $tmpArray[] = $prop->getName()
                        . ':'
                        . self::encode($propValues[$prop->getName()]);
        }
        $result .= implode(',', $tmpArray);

        return $result . "}";
    }

    /**
     * Encodes the given $className into the class2 model of encoding PHP
     * classes into JavaScript class2 classes.
     * NOTE: Currently only public methods and variables are proxied onto
     * the client machine
     *
     * @param string $className The name of the class, the class must be
     *  instantiable using a null constructor
     * @param string $package Optional package name appended to JavaScript
     *  proxy class name
     * @return string The class2 (JavaScript) encoding of the class
     * @throws Zend_Json_Exception
     */
    public static function encodeClass($className, $package = '')
    {
        $cls = new ReflectionClass($className);
        if (! $cls->isInstantiable()) {
            require_once 'Zend/Json/Exception.php';
            throw new Zend_Json_Exception("$className must be instantiable");
        }

        return "Class.create('$package$className',{"
                . self::_encodeConstants($cls)    .","
                . self::_encodeMethods($cls)      .","
                . self::_encodeVariables($cls)    .'});';
    }

    /**
     * Encode several classes at once
     *
     * Returns JSON encoded classes, using {@link encodeClass()}.
     *
     * @param array $classNames
     * @param string $package
     * @return string
     */
    public static function encodeClasses(array $classNames, $package = '')
    {
        $result = '';
        foreach ($classNames as $className) {
            $result .= self::encodeClass($className, $package);
        }

        return $result;
    }

    /**
     * Encode Unicode Characters to \u0000 ASCII syntax.
     *
     * This algorithm was originally developed for the
     * Solar Framework by Paul M. Jones
     *
     * @link   http://solarphp.com/
     * @link   http://svn.solarphp.com/core/trunk/Solar/Json.php
     * @param  string $value
     * @return string
     */
    public static function encodeUnicodeString($value)
    {
        $strlen_var = strlen($value);
        $ascii = "";

        /**
         * Iterate over every character in the string,
         * escaping with a slash or encoding to UTF-8 where necessary
         */
        for($i = 0; $i < $strlen_var; $i++) {
            $ord_var_c = ord($value[$i]);

            switch (true) {
                case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
                    // characters U-00000000 - U-0000007F (same as ASCII)
                    $ascii .= $value[$i];
                    break;

                case (($ord_var_c & 0xE0) == 0xC0):
                    // characters U-00000080 - U-000007FF, mask 110XXXXX
                    // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                    $char = pack('C*', $ord_var_c, ord($value[$i + 1]));
                    $i += 1;
                    $utf16 = self::_utf82utf16($char);
                    $ascii .= sprintf('\u%04s', bin2hex($utf16));
                    break;

                case (($ord_var_c & 0xF0) == 0xE0):
                    // characters U-00000800 - U-0000FFFF, mask 1110XXXX
                    // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                    $char = pack('C*', $ord_var_c,
                                 ord($value[$i + 1]),
                                 ord($value[$i + 2]));
                    $i += 2;
                    $utf16 = self::_utf82utf16($char);
                    $ascii .= sprintf('\u%04s', bin2hex($utf16));
                    break;

                case (($ord_var_c & 0xF8) == 0xF0):
                    // characters U-00010000 - U-001FFFFF, mask 11110XXX
                    // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                    $char = pack('C*', $ord_var_c,
                                 ord($value[$i + 1]),
                                 ord($value[$i + 2]),
                                 ord($value[$i + 3]));
                    $i += 3;
                    $utf16 = self::_utf82utf16($char);
                    $ascii .= sprintf('\u%04s', bin2hex($utf16));
                    break;

                case (($ord_var_c & 0xFC) == 0xF8):
                    // characters U-00200000 - U-03FFFFFF, mask 111110XX
                    // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                    $char = pack('C*', $ord_var_c,
                                 ord($value[$i + 1]),
                                 ord($value[$i + 2]),
                                 ord($value[$i + 3]),
                                 ord($value[$i + 4]));
                    $i += 4;
                    $utf16 = self::_utf82utf16($char);
                    $ascii .= sprintf('\u%04s', bin2hex($utf16));
                    break;

                case (($ord_var_c & 0xFE) == 0xFC):
                    // characters U-04000000 - U-7FFFFFFF, mask 1111110X
                    // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                    $char = pack('C*', $ord_var_c,
                                 ord($value[$i + 1]),
                                 ord($value[$i + 2]),
                                 ord($value[$i + 3]),
                                 ord($value[$i + 4]),
                                 ord($value[$i + 5]));
                    $i += 5;
                    $utf16 = self::_utf82utf16($char);
                    $ascii .= sprintf('\u%04s', bin2hex($utf16));
                    break;
            }
        }

        return $ascii;
     }

    /**
     * Convert a string from one UTF-8 char to one UTF-16 char.
     *
     * Normally should be handled by mb_convert_encoding, but
     * provides a slower PHP-only method for installations
     * that lack the multibye string extension.
     *
     * This method is from the Solar Framework by Paul M. Jones
     *
     * @link   http://solarphp.com
     * @param string $utf8 UTF-8 character
     * @return string UTF-16 character
     */
    protected static function _utf82utf16($utf8)
    {
        // Check for mb extension otherwise do by hand.
        if( function_exists('mb_convert_encoding') ) {
            return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
        }

        switch (strlen($utf8)) {
            case 1:
                // this case should never be reached, because we are in ASCII range
                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                return $utf8;

            case 2:
                // return a UTF-16 character from a 2-byte UTF-8 char
                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                return chr(0x07 & (ord($utf8{0}) >> 2))
                     . chr((0xC0 & (ord($utf8{0}) << 6))
                         | (0x3F & ord($utf8{1})));

            case 3:
                // return a UTF-16 character from a 3-byte UTF-8 char
                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                return chr((0xF0 & (ord($utf8{0}) << 4))
                         | (0x0F & (ord($utf8{1}) >> 2)))
                     . chr((0xC0 & (ord($utf8{1}) << 6))
                         | (0x7F & ord($utf8{2})));
        }

        // ignoring UTF-32 for now, sorry
        return '';
    }
}


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_Json
 * @subpackage Server
 * @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: Request.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @category   Zend
 * @package    Zend_Json
 * @subpackage Server
 * @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_Json_Server_Request
{
    /**
     * Request ID
     * @var mixed
     */
    protected $_id;

    /**
     * Flag
     * @var bool
     */
    protected $_isMethodError = false;

    /**
     * Requested method
     * @var string
     */
    protected $_method;

    /**
     * Regex for method
     * @var string
     */
    protected $_methodRegex = '/^[a-z][a-z0-9_.]*$/i';

    /**
     * Request parameters
     * @var array
     */
    protected $_params = array();

    /**
     * JSON-RPC version of request
     * @var string
     */
    protected $_version = '1.0';

    /**
     * Set request state
     *
     * @param  array $options
     * @return Zend_Json_Server_Request
     */
    public function setOptions(array $options)
    {
        $methods = get_class_methods($this);
        foreach ($options as $key => $value) {
            $method = 'set' . ucfirst($key);
            if (in_array($method, $methods)) {
                $this->$method($value);
            } elseif ($key == 'jsonrpc') {
                $this->setVersion($value);
            }
        }
        return $this;
    }

    /**
     * Add a parameter to the request
     *
     * @param  mixed $value
     * @param  string $key
     * @return Zend_Json_Server_Request
     */
    public function addParam($value, $key = null)
    {
        if ((null === $key) || !is_string($key)) {
            $index = count($this->_params);
            $this->_params[$index] = $value;
        } else {
            $this->_params[$key] = $value;
        }

        return $this;
    }

    /**
     * Add many params
     *
     * @param  array $params
     * @return Zend_Json_Server_Request
     */
    public function addParams(array $params)
    {
        foreach ($params as $key => $value) {
            $this->addParam($value, $key);
        }
        return $this;
    }

    /**
     * Overwrite params
     *
     * @param  array $params
     * @return Zend_Json_Server_Request
     */
    public function setParams(array $params)
    {
        $this->_params = array();
        return $this->addParams($params);
    }

    /**
     * Retrieve param by index or key
     *
     * @param  int|string $index
     * @return mixed|null Null when not found
     */
    public function getParam($index)
    {
        if (array_key_exists($index, $this->_params)) {
            return $this->_params[$index];
        }

        return null;
    }

    /**
     * Retrieve parameters
     *
     * @return array
     */
    public function getParams()
    {
        return $this->_params;
    }

    /**
     * Set request method
     *
     * @param  string $name
     * @return Zend_Json_Server_Request
     */
    public function setMethod($name)
    {
        if (!preg_match($this->_methodRegex, $name)) {
            $this->_isMethodError = true;
        } else {
            $this->_method = $name;
        }
        return $this;
    }

    /**
     * Get request method name
     *
     * @return string
     */
    public function getMethod()
    {
        return $this->_method;
    }

    /**
     * Was a bad method provided?
     *
     * @return bool
     */
    public function isMethodError()
    {
        return $this->_isMethodError;
    }

    /**
     * Set request identifier
     *
     * @param  mixed $name
     * @return Zend_Json_Server_Request
     */
    public function setId($name)
    {
        $this->_id = (string) $name;
        return $this;
    }

    /**
     * Retrieve request identifier
     *
     * @return mixed
     */
    public function getId()
    {
        return $this->_id;
    }

    /**
     * Set JSON-RPC version
     *
     * @param  string $version
     * @return Zend_Json_Server_Request
     */
    public function setVersion($version)
    {
        if ('2.0' == $version) {
            $this->_version = '2.0';
        } else {
            $this->_version = '1.0';
        }
        return $this;
    }

    /**
     * Retrieve JSON-RPC version
     *
     * @return string
     */
    public function getVersion()
    {
        return $this->_version;
    }

    /**
     * Set request state based on JSON
     *
     * @param  string $json
     * @return void
     */
    public function loadJson($json)
    {
        require_once 'Zend/Json.php';
        $options = Zend_Json::decode($json);
        $this->setOptions($options);
    }

    /**
     * Cast request to JSON
     *
     * @return string
     */
    public function toJson()
    {
        $jsonArray = array(
            'method' => $this->getMethod()
        );
        if (null !== ($id = $this->getId())) {
            $jsonArray['id'] = $id;
        }
        $params = $this->getParams();
        if (!empty($params)) {
            $jsonArray['params'] = $params;
        }
        if ('2.0' == $this->getVersion()) {
            $jsonArray['jsonrpc'] = '2.0';
        }

        require_once 'Zend/Json.php';
        return Zend_Json::encode($jsonArray);
    }

    /**
     * Cast request to string (JSON)
     *
     * @return string
     */
    public function __toString()
    {
        return $this->toJson();
    }
}

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_Json
 * @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: Error.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @category   Zend
 * @package    Zend_Json
 * @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_Json_Server_Error
{
    const ERROR_PARSE           = -32768;
    const ERROR_INVALID_REQUEST = -32600;
    const ERROR_INVALID_METHOD  = -32601;
    const ERROR_INVALID_PARAMS  = -32602;
    const ERROR_INTERNAL        = -32603;
    const ERROR_OTHER           = -32000;

    /**
     * Allowed error codes
     * @var array
     */
    protected $_allowedCodes = array(
        self::ERROR_PARSE,
        self::ERROR_INVALID_REQUEST,
        self::ERROR_INVALID_METHOD,
        self::ERROR_INVALID_PARAMS,
        self::ERROR_INTERNAL,
        self::ERROR_OTHER,
    );

    /**
     * Current code
     * @var int
     */
    protected $_code = -32000;

    /**
     * Error data
     * @var mixed
     */
    protected $_data;

    /**
     * Error message
     * @var string
     */
    protected $_message;

    /**
     * Constructor
     *
     * @param  string $message
     * @param  int $code
     * @param  mixed $data
     * @return void
     */
    public function __construct($message = null, $code = -32000, $data = null)
    {
        $this->setMessage($message)
             ->setCode($code)
             ->setData($data);
    }

    /**
     * Set error code
     *
     * @param  int $code
     * @return Zend_Json_Server_Error
     */
    public function setCode($code)
    {
        if (!is_scalar($code)) {
            return $this;
        }

        $code = (int) $code;
        if (in_array($code, $this->_allowedCodes)) {
            $this->_code = $code;
        } elseif (in_array($code, range(-32099, -32000))) {
            $this->_code = $code;
        }

        return $this;
    }

    /**
     * Get error code
     *
     * @return int|null
     */
    public function getCode()
    {
        return $this->_code;
    }

    /**
     * Set error message
     *
     * @param  string $message
     * @return Zend_Json_Server_Error
     */
    public function setMessage($message)
    {
        if (!is_scalar($message)) {
            return $this;
        }

        $this->_message = (string) $message;
        return $this;
    }

    /**
     * Get error message
     *
     * @return string
     */
    public function getMessage()
    {
        return $this->_message;
    }

    /**
     * Set error data
     *
     * @param  mixed $data
     * @return Zend_Json_Server_Error
     */
    public function setData($data)
    {
        $this->_data = $data;
        return $this;
    }

    /**
     * Get error data
     *
     * @return mixed
     */
    public function getData()
    {
        return $this->_data;
    }

    /**
     * Cast error to array
     *
     * @return array
     */
    public function toArray()
    {
        return array(
            'code'    => $this->getCode(),
            'message' => $this->getMessage(),
            'data'    => $this->getData(),
        );
    }

    /**
     * Cast error to JSON
     *
     * @return string
     */
    public function toJson()
    {
        require_once 'Zend/Json.php';
        return Zend_Json::encode($this->toArray());
    }

    /**
     * Cast to string (JSON)
     *
     * @return string
     */
    public function __toString()
    {
        return $this->toJson();
    }
}


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_Json
 * @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: Exception.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Json_Exception */
require_once 'Zend/Json/Exception.php';

/**
 * Zend_Json_Server exceptions
 *
 * @uses       Zend_Json_Exception
 * @package    Zend_Json
 * @subpackage Server
 * @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_Json_Server_Exception extends Zend_Json_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_Json
 * @subpackage Server
 * @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: Cache.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Server_Cache */
require_once 'Zend/Server/Cache.php';

/**
 * Zend_Json_Server_Cache: cache Zend_Json_Server server definition and SMD
 *
 * @category   Zend
 * @package    Zend_Json
 * @subpackage Server
 * @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_Json_Server_Cache extends Zend_Server_Cache
{
    /**
     * Cache a service map description (SMD) to a file
     *
     * Returns true on success, false on failure
     *
     * @param  string $filename
     * @param  Zend_Json_Server $server
     * @return boolean
     */
    public static function saveSmd($filename, Zend_Json_Server $server)
    {
        if (!is_string($filename)
            || (!file_exists($filename) && !is_writable(dirname($filename))))
        {
            return false;
        }

        if (0 === @file_put_contents($filename, $server->getServiceMap()->toJson())) {
            return false;
        }

        return true;
    }

    /**
     * Retrieve a cached SMD
     *
     * On success, returns the cached SMD (a JSON string); an failure, returns
     * boolean false.
     *
     * @param  string $filename
     * @return string|false
     */
    public static function getSmd($filename)
    {
        if (!is_string($filename)
            || !file_exists($filename)
            || !is_readable($filename))
        {
            return false;
        }

        if (false === ($smd = @file_get_contents($filename))) {
            return false;
        }

        return $smd;
    }

    /**
     * Delete a file containing a cached SMD
     *
     * @param  string $filename
     * @return bool
     */
    public static function deleteSmd($filename)
    {
        if (is_string($filename) && file_exists($filename)) {
            unlink($filename);
            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_Json
 * @subpackage Server
 * @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: Smd.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @category   Zend
 * @package    Zend_Json
 * @subpackage Server
 * @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_Json_Server_Smd
{
    const ENV_JSONRPC_1 = 'JSON-RPC-1.0';
    const ENV_JSONRPC_2 = 'JSON-RPC-2.0';
    const SMD_VERSION   = '2.0';

    /**
     * Content type
     * @var string
     */
    protected $_contentType = 'application/json';

    /**
     * Content type regex
     * @var string
     */
    protected $_contentTypeRegex = '#[a-z]+/[a-z][a-z-]+#i';

    /**
     * Service description
     * @var string
     */
    protected $_description;

    /**
     * Generate Dojo-compatible SMD
     * @var bool
     */
    protected $_dojoCompatible = false;

    /**
     * Current envelope
     * @var string
     */
    protected $_envelope = self::ENV_JSONRPC_1;

    /**
     * Allowed envelope types
     * @var array
     */
    protected $_envelopeTypes = array(
        self::ENV_JSONRPC_1,
        self::ENV_JSONRPC_2,
    );

    /**
     * Service id
     * @var string
     */
    protected $_id;

    /**
     * Services offerred
     * @var array
     */
    protected $_services = array();

    /**
     * Service target
     * @var string
     */
    protected $_target;

    /**
     * Global transport
     * @var string
     */
    protected $_transport = 'POST';

    /**
     * Allowed transport types
     * @var array
     */
    protected $_transportTypes = array('POST');

    /**
     * Set object state via options
     *
     * @param  array $options
     * @return Zend_Json_Server_Smd
     */
    public function setOptions(array $options)
    {
        $methods = get_class_methods($this);
        foreach ($options as $key => $value) {
            $method = 'set' . ucfirst($key);
            if (in_array($method, $methods)) {
                $this->$method($value);
            }
        }
        return $this;
    }

    /**
     * Set transport
     *
     * @param  string $transport
     * @return Zend_Json_Server_Smd
     */
    public function setTransport($transport)
    {
        if (!in_array($transport, $this->_transportTypes)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception(sprintf('Invalid transport "%s" specified', $transport));
        }
        $this->_transport = $transport;
        return $this;
    }

    /**
     * Get transport
     *
     * @return string
     */
    public function getTransport()
    {
        return $this->_transport;
    }

    /**
     * Set envelope
     *
     * @param  string $envelopeType
     * @return Zend_Json_Server_Smd
     */
    public function setEnvelope($envelopeType)
    {
        if (!in_array($envelopeType, $this->_envelopeTypes)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception(sprintf('Invalid envelope type "%s"', $envelopeType));
        }
        $this->_envelope = $envelopeType;
        return $this;
    }

    /**
     * Retrieve envelope
     *
     * @return string
     */
    public function getEnvelope()
    {
        return $this->_envelope;
    }

    // Content-Type of response; default to application/json
    /**
     * Set content type
     *
     * @param  string $type
     * @return Zend_Json_Server_Smd
     */
    public function setContentType($type)
    {
        if (!preg_match($this->_contentTypeRegex, $type)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception(sprintf('Invalid content type "%s" specified', $type));
        }
        $this->_contentType = $type;
        return $this;
    }

    /**
     * Retrieve content type
     *
     * @return string
     */
    public function getContentType()
    {
        return $this->_contentType;
    }

    /**
     * Set service target
     *
     * @param  string $target
     * @return Zend_Json_Server_Smd
     */
    public function setTarget($target)
    {
        $this->_target = (string) $target;
        return $this;
    }

    /**
     * Retrieve service target
     *
     * @return string
     */
    public function getTarget()
    {
        return $this->_target;
    }

    /**
     * Set service ID
     *
     * @param  string $Id
     * @return Zend_Json_Server_Smd
     */
    public function setId($id)
    {
        $this->_id = (string) $id;
        return $this->_id;
    }

    /**
     * Get service id
     *
     * @return string
     */
    public function getId()
    {
        return $this->_id;
    }

    /**
     * Set service description
     *
     * @param  string $description
     * @return Zend_Json_Server_Smd
     */
    public function setDescription($description)
    {
        $this->_description = (string) $description;
        return $this->_description;
    }

    /**
     * Get service description
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->_description;
    }

    /**
     * Indicate whether or not to generate Dojo-compatible SMD
     *
     * @param  bool $flag
     * @return Zend_Json_Server_Smd
     */
    public function setDojoCompatible($flag)
    {
        $this->_dojoCompatible = (bool) $flag;
        return $this;
    }

    /**
     * Is this a Dojo compatible SMD?
     *
     * @return bool
     */
    public function isDojoCompatible()
    {
        return $this->_dojoCompatible;
    }

    /**
     * Add Service
     *
     * @param Zend_Json_Server_Smd_Service|array $service
     * @return void
     */
    public function addService($service)
    {
        require_once 'Zend/Json/Server/Smd/Service.php';

        if ($service instanceof Zend_Json_Server_Smd_Service) {
            $name = $service->getName();
        } elseif (is_array($service)) {
            $service = new Zend_Json_Server_Smd_Service($service);
            $name = $service->getName();
        } else {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception('Invalid service passed to addService()');
        }

        if (array_key_exists($name, $this->_services)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception('Attempt to register a service already registered detected');
        }
        $this->_services[$name] = $service;
        return $this;
    }

    /**
     * Add many services
     *
     * @param  array $services
     * @return Zend_Json_Server_Smd
     */
    public function addServices(array $services)
    {
        foreach ($services as $service) {
            $this->addService($service);
        }
        return $this;
    }

    /**
     * Overwrite existing services with new ones
     *
     * @param  array $services
     * @return Zend_Json_Server_Smd
     */
    public function setServices(array $services)
    {
        $this->_services = array();
        return $this->addServices($services);
    }

    /**
     * Get service object
     *
     * @param  string $name
     * @return false|Zend_Json_Server_Smd_Service
     */
    public function getService($name)
    {
        if (array_key_exists($name, $this->_services)) {
            return $this->_services[$name];
        }
        return false;
    }

    /**
     * Return services
     *
     * @return array
     */
    public function getServices()
    {
        return $this->_services;
    }

    /**
     * Remove service
     *
     * @param  string $name
     * @return boolean
     */
    public function removeService($name)
    {
        if (array_key_exists($name, $this->_services)) {
            unset($this->_services[$name]);
            return true;
        }
        return false;
    }

    /**
     * Cast to array
     *
     * @return array
     */
    public function toArray()
    {
        if ($this->isDojoCompatible()) {
            return $this->toDojoArray();
        }

        $transport   = $this->getTransport();
        $envelope    = $this->getEnvelope();
        $contentType = $this->getContentType();
        $SMDVersion  = self::SMD_VERSION;
        $service = compact('transport', 'envelope', 'contentType', 'SMDVersion');

        if (null !== ($target = $this->getTarget())) {
            $service['target']     = $target;
        }
        if (null !== ($id = $this->getId())) {
            $service['id'] = $id;
        }

        $services = $this->getServices();
        if (!empty($services)) {
            $service['services'] = array();
            foreach ($services as $name => $svc) {
                $svc->setEnvelope($envelope);
                $service['services'][$name] = $svc->toArray();
            }
            $service['methods'] = $service['services'];
        }

        return $service;
    }

    /**
     * Export to DOJO-compatible SMD array
     *
     * @return array
     */
    public function toDojoArray()
    {
        $SMDVersion  = '.1';
        $serviceType = 'JSON-RPC';
        $service = compact('SMDVersion', 'serviceType');

        $target = $this->getTarget();

        $services = $this->getServices();
        if (!empty($services)) {
            $service['methods'] = array();
            foreach ($services as $name => $svc) {
                $method = array(
                    'name'       => $name,
                    'serviceURL' => $target,
                );
                $params = array();
                foreach ($svc->getParams() as $param) {
                    $paramName = array_key_exists('name', $param) ? $param['name'] : $param['type'];
                    $params[] = array(
                        'name' => $paramName,
                        'type' => $param['type'],
                    );
                }
                if (!empty($params)) {
                    $method['parameters'] = $params;
                }
                $service['methods'][] = $method;
            }
        }

        return $service;
    }

    /**
     * Cast to JSON
     *
     * @return string
     */
    public function toJson()
    {
        require_once 'Zend/Json.php';
        return Zend_Json::encode($this->toArray());
    }

    /**
     * Cast to string (JSON)
     *
     * @return string
     */
    public function __toString()
    {
        return $this->toJson();
    }
}


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_Json
 * @subpackage Server
 * @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: Response.php 24464 2011-09-24 14:06:34Z mcleod@spaceweb.nl $
 */

/**
 * @category   Zend
 * @package    Zend_Json
 * @subpackage Server
 * @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_Json_Server_Response
{
    /**
     * Response error
     * @var null|Zend_Json_Server_Error
     */
    protected $_error;

    /**
     * Request ID
     * @var mixed
     */
    protected $_id;

    /**
     * Result
     * @var mixed
     */
    protected $_result;

    /**
     * Service map
     * @var Zend_Json_Server_Smd
     */
    protected $_serviceMap;

    /**
     * JSON-RPC version
     * @var string
     */
    protected $_version;

    /**
     * Set result
     *
     * @param  mixed $value
     * @return Zend_Json_Server_Response
     */
    public function setResult($value)
    {
        $this->_result = $value;
        return $this;
    }

    /**
     * Get result
     *
     * @return mixed
     */
    public function getResult()
    {
        return $this->_result;
    }

    // RPC error, if response results in fault
    /**
     * Set result error
     *
     * @param  Zend_Json_Server_Error $error
     * @return Zend_Json_Server_Response
     */
    public function setError(Zend_Json_Server_Error $error)
    {
        $this->_error = $error;
        return $this;
    }

    /**
     * Get response error
     *
     * @return null|Zend_Json_Server_Error
     */
    public function getError()
    {
        return $this->_error;
    }

    /**
     * Is the response an error?
     *
     * @return bool
     */
    public function isError()
    {
        return $this->getError() instanceof Zend_Json_Server_Error;
    }

    /**
     * Set request ID
     *
     * @param  mixed $name
     * @return Zend_Json_Server_Response
     */
    public function setId($name)
    {
        $this->_id = $name;
        return $this;
    }

    /**
     * Get request ID
     *
     * @return mixed
     */
    public function getId()
    {
        return $this->_id;
    }

    /**
     * Set JSON-RPC version
     *
     * @param  string $version
     * @return Zend_Json_Server_Response
     */
    public function setVersion($version)
    {
        $version = (string) $version;
        if ('2.0' == $version) {
            $this->_version = '2.0';
        } else {
            $this->_version = null;
        }

        return $this;
    }

    /**
     * Retrieve JSON-RPC version
     *
     * @return string
     */
    public function getVersion()
    {
        return $this->_version;
    }

    /**
     * Cast to JSON
     *
     * @return string
     */
    public function toJson()
    {
        if ($this->isError()) {
            $response = array(
                'error'  => $this->getError()->toArray(),
                'id'     => $this->getId(),
            );
        } else {
            $response = array(
                'result' => $this->getResult(),
                'id'     => $this->getId(),
            );
        }

        if (null !== ($version = $this->getVersion())) {
            $response['jsonrpc'] = $version;
        }

        require_once 'Zend/Json.php';
        return Zend_Json::encode($response);
    }

    /**
     * Retrieve args
     *
     * @return mixed
     */
    public function getArgs()
    {
        return $this->_args;
    }

    /**
     * Set args
     *
     * @param mixed $args
     * @return self
     */
    public function setArgs($args)
    {
        $this->_args = $args;
        return $this;
    }

    /**
     * Set service map object
     *
     * @param  Zend_Json_Server_Smd $serviceMap
     * @return Zend_Json_Server_Response
     */
    public function setServiceMap($serviceMap)
    {
        $this->_serviceMap = $serviceMap;
        return $this;
    }

    /**
     * Retrieve service map
     *
     * @return Zend_Json_Server_Smd|null
     */
    public function getServiceMap()
    {
        return $this->_serviceMap;
    }

    /**
     * Cast to string (JSON)
     *
     * @return string
     */
    public function __toString()
    {
        return $this->toJson();
    }
}


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_Json
 * @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: Http.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @see Zend_Json_Server_Response
 */
require_once 'Zend/Json/Server/Response.php';

/**
 * @category   Zend
 * @package    Zend_Json
 * @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_Json_Server_Response_Http extends Zend_Json_Server_Response
{
    /**
     * Emit JSON
     *
     * Send appropriate HTTP headers. If no Id, then return an empty string.
     *
     * @return string
     */
    public function toJson()
    {
        $this->sendHeaders();
        if (!$this->isError() && null === $this->getId()) {
            return '';
        }

        return parent::toJson();
    }

    /**
     * Send headers
     *
     * If headers are already sent, do nothing. If null ID, send HTTP 204
     * header. Otherwise, send content type header based on content type of
     * service map.
     *
     * @return void
     */
    public function sendHeaders()
    {
        if (headers_sent()) {
            return;
        }

        if (!$this->isError() && (null === $this->getId())) {
            header('HTTP/1.1 204 No Content');
            return;
        }

        if (null === ($smd = $this->getServiceMap())) {
            return;
        }

        $contentType = $smd->getContentType();
        if (!empty($contentType)) {
            header('Content-Type: ' . $contentType);
        }
    }
}


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_Json
 * @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: Http.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @see Zend_Json_Server_Request
 */
require_once 'Zend/Json/Server/Request.php';

/**
 * @category   Zend
 * @package    Zend_Json
 * @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_Json_Server_Request_Http extends Zend_Json_Server_Request
{
    /**
     * Raw JSON pulled from POST body
     * @var string
     */
    protected $_rawJson;

    /**
     * Constructor
     *
     * Pull JSON request from raw POST body and use to populate request.
     *
     * @return void
     */
    public function __construct()
    {
        $json = file_get_contents('php://input');
        $this->_rawJson = $json;
        if (!empty($json)) {
            $this->loadJson($json);
        }
    }

    /**
     * Get JSON from raw POST body
     *
     * @return string
     */
    public function getRawJson()
    {
        return $this->_rawJson;
    }
}


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_Json
 * @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_Json_Server_Smd
 */
require_once 'Zend/Json/Server/Smd.php';

/**
 * Create Service Mapping Description for a method
 *
 * @package    Zend_Json
 * @subpackage Server
 * @version    $Id: Service.php 23775 2011-03-01 17:25:24Z ralph $
 * @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_Json_Server_Smd_Service
{
    /**#@+
     * Service metadata
     * @var string
     */
    protected $_envelope  = Zend_Json_Server_Smd::ENV_JSONRPC_1;
    protected $_name;
    protected $_return;
    protected $_target;
    protected $_transport = 'POST';
    /**#@-*/

    /**
     * Allowed envelope types
     * @var array
     */
    protected $_envelopeTypes = array(
        Zend_Json_Server_Smd::ENV_JSONRPC_1,
        Zend_Json_Server_Smd::ENV_JSONRPC_2,
    );

    /**
     * Regex for names
     * @var string
     */
    protected $_nameRegex = '/^[a-z][a-z0-9._]+$/i';

    /**
     * Parameter option types
     * @var array
     */
    protected $_paramOptionTypes = array(
        'name'        => 'is_string',
        'optional'    => 'is_bool',
        'default'     => null,
        'description' => 'is_string',
    );

    /**
     * Service params
     * @var array
     */
    protected $_params = array();

    /**
     * Mapping of parameter types to JSON-RPC types
     * @var array
     */
    protected $_paramMap = array(
        'any'     => 'any',
        'arr'     => 'array',
        'array'   => 'array',
        'assoc'   => 'object',
        'bool'    => 'boolean',
        'boolean' => 'boolean',
        'dbl'     => 'float',
        'double'  => 'float',
        'false'   => 'boolean',
        'float'   => 'float',
        'hash'    => 'object',
        'integer' => 'integer',
        'int'     => 'integer',
        'mixed'   => 'any',
        'nil'     => 'null',
        'null'    => 'null',
        'object'  => 'object',
        'string'  => 'string',
        'str'     => 'string',
        'struct'  => 'object',
        'true'    => 'boolean',
        'void'    => 'null',
    );

    /**
     * Allowed transport types
     * @var array
     */
    protected $_transportTypes = array(
        'POST',
    );

    /**
     * Constructor
     *
     * @param  string|array $spec
     * @return void
     * @throws Zend_Json_Server_Exception if no name provided
     */
    public function __construct($spec)
    {
        if (is_string($spec)) {
            $this->setName($spec);
        } elseif (is_array($spec)) {
            $this->setOptions($spec);
        }

        if (null == $this->getName()) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception('SMD service description requires a name; none provided');
        }
    }

    /**
     * Set object state
     *
     * @param  array $options
     * @return Zend_Json_Server_Smd_Service
     */
    public function setOptions(array $options)
    {
        $methods = get_class_methods($this);
        foreach ($options as $key => $value) {
            if ('options' == strtolower($key)) {
                continue;
            }
            $method = 'set' . ucfirst($key);
            if (in_array($method, $methods)) {
                $this->$method($value);
            }
        }
        return $this;
    }

    /**
     * Set service name
     *
     * @param  string $name
     * @return Zend_Json_Server_Smd_Service
     * @throws Zend_Json_Server_Exception
     */
    public function setName($name)
    {
        $name = (string) $name;
        if (!preg_match($this->_nameRegex, $name)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception(sprintf('Invalid name "%s" provided for service; must follow PHP method naming conventions', $name));
        }
        $this->_name = $name;
        return $this;
    }

    /**
     * Retrieve name
     *
     * @return string
     */
    public function getName()
    {
        return $this->_name;
    }

    /**
     * Set Transport
     *
     * Currently limited to POST
     *
     * @param  string $transport
     * @return Zend_Json_Server_Smd_Service
     */
    public function setTransport($transport)
    {
        if (!in_array($transport, $this->_transportTypes)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception(sprintf('Invalid transport "%s"; please select one of (%s)', $transport, implode(', ', $this->_transportTypes)));
        }

        $this->_transport = $transport;
        return $this;
    }

    /**
     * Get transport
     *
     * @return string
     */
    public function getTransport()
    {
        return $this->_transport;
    }

    /**
     * Set service target
     *
     * @param  string $target
     * @return Zend_Json_Server_Smd_Service
     */
    public function setTarget($target)
    {
        $this->_target = (string) $target;
        return $this;
    }

    /**
     * Get service target
     *
     * @return string
     */
    public function getTarget()
    {
        return $this->_target;
    }

    /**
     * Set envelope type
     *
     * @param  string $envelopeType
     * @return Zend_Json_Server_Smd_Service
     */
    public function setEnvelope($envelopeType)
    {
        if (!in_array($envelopeType, $this->_envelopeTypes)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception(sprintf('Invalid envelope type "%s"; please specify one of (%s)', $envelopeType, implode(', ', $this->_envelopeTypes)));
        }

        $this->_envelope = $envelopeType;
        return $this;
    }

    /**
     * Get envelope type
     *
     * @return string
     */
    public function getEnvelope()
    {
        return $this->_envelope;
    }

    /**
     * Add a parameter to the service
     *
     * @param  string|array $type
     * @param  array $options
     * @param  int|null $order
     * @return Zend_Json_Server_Smd_Service
     */
    public function addParam($type, array $options = array(), $order = null)
    {
        if (is_string($type)) {
            $type = $this->_validateParamType($type);
        } elseif (is_array($type)) {
            foreach ($type as $key => $paramType) {
                $type[$key] = $this->_validateParamType($paramType);
            }
        } else {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception('Invalid param type provided');
        }

        $paramOptions = array(
            'type' => $type,
        );
        foreach ($options as $key => $value) {
            if (in_array($key, array_keys($this->_paramOptionTypes))) {
                if (null !== ($callback = $this->_paramOptionTypes[$key])) {
                    if (!$callback($value)) {
                        continue;
                    }
                }
                $paramOptions[$key] = $value;
            }
        }

        $this->_params[] = array(
            'param' => $paramOptions,
            'order' => $order,
        );

        return $this;
    }

    /**
     * Add params
     *
     * Each param should be an array, and should include the key 'type'.
     *
     * @param  array $params
     * @return Zend_Json_Server_Smd_Service
     */
    public function addParams(array $params)
    {
        ksort($params);
        foreach ($params as $options) {
            if (!is_array($options)) {
                continue;
            }
            if (!array_key_exists('type', $options)) {
                continue;
            }
            $type  = $options['type'];
            $order = (array_key_exists('order', $options)) ? $options['order'] : null;
            $this->addParam($type, $options, $order);
        }
        return $this;
    }

    /**
     * Overwrite all parameters
     *
     * @param  array $params
     * @return Zend_Json_Server_Smd_Service
     */
    public function setParams(array $params)
    {
        $this->_params = array();
        return $this->addParams($params);
    }

    /**
     * Get all parameters
     *
     * Returns all params in specified order.
     *
     * @return array
     */
    public function getParams()
    {
        $params = array();
        $index  = 0;
        foreach ($this->_params as $param) {
            if (null === $param['order']) {
                if (array_search($index, array_keys($params), true)) {
                    ++$index;
                }
                $params[$index] = $param['param'];
                ++$index;
            } else {
                $params[$param['order']] = $param['param'];
            }
        }
        ksort($params);
        return $params;
    }

    /**
     * Set return type
     *
     * @param  string|array $type
     * @return Zend_Json_Server_Smd_Service
     */
    public function setReturn($type)
    {
        if (is_string($type)) {
            $type = $this->_validateParamType($type, true);
        } elseif (is_array($type)) {
            foreach ($type as $key => $returnType) {
                $type[$key] = $this->_validateParamType($returnType, true);
            }
        } else {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception('Invalid param type provided ("' . gettype($type) .'")');
        }
        $this->_return = $type;
        return $this;
    }

    /**
     * Get return type
     *
     * @return string|array
     */
    public function getReturn()
    {
        return $this->_return;
    }

    /**
     * Cast service description to array
     *
     * @return array
     */
    public function toArray()
    {
        $name       = $this->getName();
        $envelope   = $this->getEnvelope();
        $target     = $this->getTarget();
        $transport  = $this->getTransport();
        $parameters = $this->getParams();
        $returns    = $this->getReturn();

        if (empty($target)) {
            return compact('envelope', 'transport', 'parameters', 'returns');
        }

        return $paramInfo = compact('envelope', 'target', 'transport', 'parameters', 'returns');
    }

    /**
     * Return JSON encoding of service
     *
     * @return string
     */
    public function toJson()
    {
        $service = array($this->getName() => $this->toArray());

        require_once 'Zend/Json.php';
        return Zend_Json::encode($service);
    }

    /**
     * Cast to string
     *
     * @return string
     */
    public function __toString()
    {
        return $this->toJson();
    }

    /**
     * Validate parameter type
     *
     * @param  string $type
     * @return true
     * @throws Zend_Json_Server_Exception
     */
    protected function _validateParamType($type, $isReturn = false)
    {
        if (!is_string($type)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception('Invalid param type provided ("' . $type .'")');
        }

        if (!array_key_exists($type, $this->_paramMap)) {
            $type = 'object';
        }

        $paramType = $this->_paramMap[$type];
        if (!$isReturn && ('null' == $paramType)) {
            require_once 'Zend/Json/Server/Exception.php';
            throw new Zend_Json_Server_Exception('Invalid param type provided ("' . $type . '")');
        }

        return $paramType;
    }
}


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_Server
 * @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';

/**
 * Zend_Server_Reflection exceptions
 *
 * @package Zend_Server
 * @subpackage Reflection
 * @version $Id: Exception.php 23775 2011-03-01 17:25:24Z ralph $
 */
class Zend_Server_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_Server
 * @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_Server_Interface
 *
 * @category Zend
 * @package  Zend_Server
 * @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: Interface.php 23775 2011-03-01 17:25:24Z ralph $
 */
interface Zend_Server_Interface
{
    /**
     * Attach a function as a server method
     *
     * Namespacing is primarily for xmlrpc, but may be used with other
     * implementations to prevent naming collisions.
     *
     * @param string $function
     * @param string $namespace
     * @param null|array Optional array of arguments to pass to callbacks at
     * dispatch.
     * @return void
     */
    public function addFunction($function, $namespace = '');

    /**
     * Attach a class to a server
     *
     * The individual implementations should probably allow passing a variable
     * number of arguments in, so that developers may define custom runtime
     * arguments to pass to server methods.
     *
     * Namespacing is primarily for xmlrpc, but could be used for other
     * implementations as well.
     *
     * @param mixed $class Class name or object instance to examine and attach
     * to the server.
     * @param string $namespace Optional namespace with which to prepend method
     * names in the dispatch table.
     * methods in the class will be valid callbacks.
     * @param null|array Optional array of arguments to pass to callbacks at
     * dispatch.
     * @return void
     */
    public function setClass($class, $namespace = '', $argv = null);

    /**
     * Generate a server fault
     *
     * @param mixed $fault
     * @param int $code
     * @return mixed
     */
    public function fault($fault = null, $code = 404);

    /**
     * Handle a request
     *
     * Requests may be passed in, or the server may automagically determine the
     * request based on defaults. Dispatches server request to appropriate
     * method and returns a response
     *
     * @param mixed $request
     * @return mixed
     */
    public function handle($request = false);

    /**
     * Return a server definition array
     *
     * Returns a server definition array as created using
     * {@link * Zend_Server_Reflection}. Can be used for server introspection,
     * documentation, or persistence.
     *
     * @access public
     * @return array
     */
    public function getFunctions();

    /**
     * Load server definition
     *
     * Used for persistence; loads a construct as returned by {@link getFunctions()}.
     *
     * @param array $array
     * @return void
     */
    public function loadFunctions($definition);

    /**
     * Set server persistence
     *
     * @todo Determine how to implement this
     * @param int $mode
     * @return void
     */
    public function setPersistence($mode);
}


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_Server
 * @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: Definition.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Server methods metadata
 *
 * @todo       Implement iterator
 * @category   Zend
 * @package    Zend_Server
 * @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_Server_Definition implements Countable, Iterator
{
    /**
     * @var array Array of Zend_Server_Method_Definition objects
     */
    protected $_methods = array();

    /**
     * @var bool Whether or not overwriting existing methods is allowed
     */
    protected $_overwriteExistingMethods = false;

    /**
     * Constructor
     *
     * @param  null|array $methods
     * @return void
     */
    public function __construct($methods = null)
    {
        if (is_array($methods)) {
            $this->setMethods($methods);
        }
    }

    /**
     * Set flag indicating whether or not overwriting existing methods is allowed
     *
     * @param mixed $flag
     * @return void
     */
    public function setOverwriteExistingMethods($flag)
    {
        $this->_overwriteExistingMethods = (bool) $flag;
        return $this;
    }

    /**
     * Add method to definition
     *
     * @param  array|Zend_Server_Method_Definition $method
     * @param  null|string $name
     * @return Zend_Server_Definition
     * @throws Zend_Server_Exception if duplicate or invalid method provided
     */
    public function addMethod($method, $name = null)
    {
        if (is_array($method)) {
            require_once 'Zend/Server/Method/Definition.php';
            $method = new Zend_Server_Method_Definition($method);
        } elseif (!$method instanceof Zend_Server_Method_Definition) {
            require_once 'Zend/Server/Exception.php';
            throw new Zend_Server_Exception('Invalid method provided');
        }

        if (is_numeric($name)) {
            $name = null;
        }
        if (null !== $name) {
            $method->setName($name);
        } else {
            $name = $method->getName();
        }
        if (null === $name) {
            require_once 'Zend/Server/Exception.php';
            throw new Zend_Server_Exception('No method name provided');
        }

        if (!$this->_overwriteExistingMethods && array_key_exists($name, $this->_methods)) {
            require_once 'Zend/Server/Exception.php';
            throw new Zend_Server_Exception(sprintf('Method by name of "%s" already exists', $name));
        }
        $this->_methods[$name] = $method;
        return $this;
    }

    /**
     * Add multiple methods
     *
     * @param  array $methods Array of Zend_Server_Method_Definition objects or arrays
     * @return Zend_Server_Definition
     */
    public function addMethods(array $methods)
    {
        foreach ($methods as $key => $method) {
            $this->addMethod($method, $key);
        }
        return $this;
    }

    /**
     * Set all methods at once (overwrite)
     *
     * @param  array $methods Array of Zend_Server_Method_Definition objects or arrays
     * @return Zend_Server_Definition
     */
    public function setMethods(array $methods)
    {
        $this->clearMethods();
        $this->addMethods($methods);
        return $this;
    }

    /**
     * Does the definition have the given method?
     *
     * @param  string $method
     * @return bool
     */
    public function hasMethod($method)
    {
        return array_key_exists($method, $this->_methods);
    }

    /**
     * Get a given method definition
     *
     * @param  string $method
     * @return null|Zend_Server_Method_Definition
     */
    public function getMethod($method)
    {
        if ($this->hasMethod($method)) {
            return $this->_methods[$method];
        }
        return false;
    }

    /**
     * Get all method definitions
     *
     * @return array Array of Zend_Server_Method_Definition objects
     */
    public function getMethods()
    {
        return $this->_methods;
    }

    /**
     * Remove a method definition
     *
     * @param  string $method
     * @return Zend_Server_Definition
     */
    public function removeMethod($method)
    {
        if ($this->hasMethod($method)) {
            unset($this->_methods[$method]);
        }
        return $this;
    }

    /**
     * Clear all method definitions
     *
     * @return Zend_Server_Definition
     */
    public function clearMethods()
    {
        $this->_methods = array();
        return $this;
    }

    /**
     * Cast definition to an array
     *
     * @return array
     */
    public function toArray()
    {
        $methods = array();
        foreach ($this->getMethods() as $key => $method) {
            $methods[$key] = $method->toArray();
        }
        return $methods;
    }

    /**
     * Countable: count of methods
     *
     * @return int
     */
    public function count()
    {
        return count($this->_methods);
    }

    /**
     * Iterator: current item
     *
     * @return mixed
     */
    public function current()
    {
        return current($this->_methods);
    }

    /**
     * Iterator: current item key
     *
     * @return int|string
     */
    public function key()
    {
        return key($this->_methods);
    }

    /**
     * Iterator: advance to next method
     *
     * @return void
     */
    public function next()
    {
        return next($this->_methods);
    }

    /**
     * Iterator: return to first method
     *
     * @return void
     */
    public function rewind()
    {
        return reset($this->_methods);
    }

    /**
     * Iterator: is the current index valid?
     *
     * @return bool
     */
    public function valid()
    {
        return (bool) $this->current();
    }
}


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_Server
 * @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: Cache.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Zend_Server_Cache: cache server definitions
 *
 * @category   Zend
 * @package    Zend_Server
 * @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_Server_Cache
{
    /**
     * @var array Methods to skip when caching server
     */
    protected static $_skipMethods = array();

    /**
     * Cache a file containing the dispatch list.
     *
     * Serializes the server definition stores the information
     * in $filename.
     *
     * Returns false on any error (typically, inability to write to file), true
     * on success.
     *
     * @param  string $filename
     * @param  Zend_Server_Interface $server
     * @return bool
     */
    public static function save($filename, Zend_Server_Interface $server)
    {
        if (!is_string($filename)
            || (!file_exists($filename) && !is_writable(dirname($filename))))
        {
            return false;
        }

        $methods = $server->getFunctions();

        if ($methods instanceof Zend_Server_Definition) {
            $definition = new Zend_Server_Definition();
            foreach ($methods as $method) {
                if (in_array($method->getName(), self::$_skipMethods)) {
                    continue;
                }
                $definition->addMethod($method);
            }
            $methods = $definition;
        }

        if (0 === @file_put_contents($filename, serialize($methods))) {
            return false;
        }

        return true;
    }

    /**
     * Load server definition from a file
     *
     * Unserializes a stored server definition from $filename. Returns false if
     * it fails in any way, true on success.
     *
     * Useful to prevent needing to build the server definition on each
     * request. Sample usage:
     *
     * <code>
     * if (!Zend_Server_Cache::get($filename, $server)) {
     *     require_once 'Some/Service/Class.php';
     *     require_once 'Another/Service/Class.php';
     *
     *     // Attach Some_Service_Class with namespace 'some'
     *     $server->attach('Some_Service_Class', 'some');
     *
     *     // Attach Another_Service_Class with namespace 'another'
     *     $server->attach('Another_Service_Class', 'another');
     *
     *     Zend_Server_Cache::save($filename, $server);
     * }
     *
     * $response = $server->handle();
     * echo $response;
     * </code>
     *
     * @param  string $filename
     * @param  Zend_Server_Interface $server
     * @return bool
     */
    public static function get($filename, Zend_Server_Interface $server)
    {
        if (!is_string($filename)
            || !file_exists($filename)
            || !is_readable($filename))
        {
            return false;
        }

        if (false === ($dispatch = @file_get_contents($filename))) {
            return false;
        }

        if (false === ($dispatchArray = @unserialize($dispatch))) {
            return false;
        }

        $server->loadFunctions($dispatchArray);

        return true;
    }

    /**
     * Remove a cache file
     *
     * @param  string $filename
     * @return boolean
     */
    public static function delete($filename)
    {
        if (is_string($filename) && file_exists($filename)) {
            unlink($filename);
            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_Server
 * @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_Server_Interface */
require_once 'Zend/Server/Interface.php';

/**
 * Zend_Server_Definition
 */
require_once 'Zend/Server/Definition.php';

/**
 * Zend_Server_Method_Definition
 */
require_once 'Zend/Server/Method/Definition.php';

/**
 * Zend_Server_Method_Callback
 */
require_once 'Zend/Server/Method/Callback.php';

/**
 * Zend_Server_Method_Prototype
 */
require_once 'Zend/Server/Method/Prototype.php';

/**
 * Zend_Server_Method_Parameter
 */
require_once 'Zend/Server/Method/Parameter.php';

/**
 * Zend_Server_Abstract
 *
 * @category   Zend
 * @package    Zend_Server
 * @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: Abstract.php 23775 2011-03-01 17:25:24Z ralph $
 */
abstract class Zend_Server_Abstract implements Zend_Server_Interface
{
    /**
     * @deprecated
     * @var array List of PHP magic methods (lowercased)
     */
    protected static $magic_methods = array(
        '__call',
        '__clone',
        '__construct',
        '__destruct',
        '__get',
        '__isset',
        '__set',
        '__set_state',
        '__sleep',
        '__tostring',
        '__unset',
        '__wakeup',
    );

    /**
     * @var bool Flag; whether or not overwriting existing methods is allowed
     */
    protected $_overwriteExistingMethods = false;

    /**
     * @var Zend_Server_Definition
     */
    protected $_table;

    /**
     * Constructor
     *
     * Setup server description
     *
     * @return void
     */
    public function __construct()
    {
        $this->_table = new Zend_Server_Definition();
        $this->_table->setOverwriteExistingMethods($this->_overwriteExistingMethods);
    }

    /**
     * Returns a list of registered methods
     *
     * Returns an array of method definitions.
     *
     * @return Zend_Server_Definition
     */
    public function getFunctions()
    {
        return $this->_table;
    }

    /**
     * Lowercase a string
     *
     * Lowercase's a string by reference
     *
     * @deprecated
     * @param  string $string value
     * @param  string $key
     * @return string Lower cased string
     */
    public static function lowerCase(&$value, &$key)
    {
        trigger_error(__CLASS__ . '::' . __METHOD__ . '() is deprecated and will be removed in a future version', E_USER_NOTICE);
        return $value = strtolower($value);
    }

    /**
     * Build callback for method signature
     *
     * @param  Zend_Server_Reflection_Function_Abstract $reflection
     * @return Zend_Server_Method_Callback
     */
    protected function _buildCallback(Zend_Server_Reflection_Function_Abstract $reflection)
    {
        $callback = new Zend_Server_Method_Callback();
        if ($reflection instanceof Zend_Server_Reflection_Method) {
            $callback->setType($reflection->isStatic() ? 'static' : 'instance')
                     ->setClass($reflection->getDeclaringClass()->getName())
                     ->setMethod($reflection->getName());
        } elseif ($reflection instanceof Zend_Server_Reflection_Function) {
            $callback->setType('function')
                     ->setFunction($reflection->getName());
        }
        return $callback;
    }

    /**
     * Build a method signature
     *
     * @param  Zend_Server_Reflection_Function_Abstract $reflection
     * @param  null|string|object $class
     * @return Zend_Server_Method_Definition
     * @throws Zend_Server_Exception on duplicate entry
     */
    protected function _buildSignature(Zend_Server_Reflection_Function_Abstract $reflection, $class = null)
    {
        $ns         = $reflection->getNamespace();
        $name       = $reflection->getName();
        $method     = empty($ns) ? $name : $ns . '.' . $name;

        if (!$this->_overwriteExistingMethods && $this->_table->hasMethod($method)) {
            require_once 'Zend/Server/Exception.php';
            throw new Zend_Server_Exception('Duplicate method registered: ' . $method);
        }

        $definition = new Zend_Server_Method_Definition();
        $definition->setName($method)
                   ->setCallback($this->_buildCallback($reflection))
                   ->setMethodHelp($reflection->getDescription())
                   ->setInvokeArguments($reflection->getInvokeArguments());

        foreach ($reflection->getPrototypes() as $proto) {
            $prototype = new Zend_Server_Method_Prototype();
            $prototype->setReturnType($this->_fixType($proto->getReturnType()));
            foreach ($proto->getParameters() as $parameter) {
                $param = new Zend_Server_Method_Parameter(array(
                    'type'     => $this->_fixType($parameter->getType()),
                    'name'     => $parameter->getName(),
                    'optional' => $parameter->isOptional(),
                ));
                if ($parameter->isDefaultValueAvailable()) {
                    $param->setDefaultValue($parameter->getDefaultValue());
                }
                $prototype->addParameter($param);
            }
            $definition->addPrototype($prototype);
        }
        if (is_object($class)) {
            $definition->setObject($class);
        }
        $this->_table->addMethod($definition);
        return $definition;
    }

    /**
     * Dispatch method
     *
     * @param  Zend_Server_Method_Definition $invocable
     * @param  array $params
     * @return mixed
     */
    protected function _dispatch(Zend_Server_Method_Definition $invocable, array $params)
    {
        $callback = $invocable->getCallback();
        $type     = $callback->getType();

        if ('function' == $type) {
            $function = $callback->getFunction();
            return call_user_func_array($function, $params);
        }

        $class  = $callback->getClass();
        $method = $callback->getMethod();

        if ('static' == $type) {
            return call_user_func_array(array($class, $method), $params);
        }

        $object = $invocable->getObject();
        if (!is_object($object)) {
            $invokeArgs = $invocable->getInvokeArguments();
            if (!empty($invokeArgs)) {
                $reflection = new ReflectionClass($class);
                $object     = $reflection->newInstanceArgs($invokeArgs);
            } else {
                $object = new $class;
            }
        }
        return call_user_func_array(array($object, $method), $params);
    }

    /**
     * Map PHP type to protocol type
     *
     * @param  string $type
     * @return string
     */
    abstract protected function _fixType($type);
}


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_Server
 * @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_Server_Reflection_Function
 */
require_once 'Zend/Server/Reflection/Function.php';

/**
 * Zend_Server_Reflection_Class
 */
require_once 'Zend/Server/Reflection/Class.php';

/**
 * Reflection for determining method signatures to use with server classes
 *
 * @category   Zend
 * @package    Zend_Server
 * @subpackage Reflection
 * @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: Reflection.php 23775 2011-03-01 17:25:24Z ralph $
 */
class Zend_Server_Reflection
{
    /**
     * Perform class reflection to create dispatch signatures
     *
     * Creates a {@link Zend_Server_Reflection_Class} object for the class or
     * object provided.
     *
     * If extra arguments should be passed to dispatchable methods, these may
     * be provided as an array to $argv.
     *
     * @param string|object $class Class name or object
     * @param null|array $argv Optional arguments to be used during the method call
     * @param string $namespace Optional namespace with which to prefix the
     * method name (used for the signature key). Primarily to avoid collisions,
     * also for XmlRpc namespacing
     * @return Zend_Server_Reflection_Class
     * @throws Zend_Server_Reflection_Exception
     */
    public static function reflectClass($class, $argv = false, $namespace = '')
    {
        if (is_object($class)) {
            $reflection = new ReflectionObject($class);
        } elseif (class_exists($class)) {
            $reflection = new ReflectionClass($class);
        } else {
            require_once 'Zend/Server/Reflection/Exception.php';
            throw new Zend_Server_Reflection_Exception('Invalid class or object passed to attachClass()');
        }

        if ($argv && !is_array($argv)) {
            require_once 'Zend/Server/Reflection/Exception.php';
            throw new Zend_Server_Reflection_Exception('Invalid argv argument passed to reflectClass');
        }

        return new Zend_Server_Reflection_Class($reflection, $namespace, $argv);
    }

    /**
     * Perform function reflection to create dispatch signatures
     *
     * Creates dispatch prototypes for a function. It returns a
     * {@link Zend_Server_Reflection_Function} object.
     *
     * If extra arguments should be passed to the dispatchable function, these
     * may be provided as an array to $argv.
     *
     * @param string $function Function name
     * @param null|array $argv Optional arguments to be used during the method call
     * @param string $namespace Optional namespace with which to prefix the
     * function name (used for the signature key). Primarily to avoid
     * collisions, also for XmlRpc namespacing
     * @return Zend_Server_Reflection_Function
     * @throws Zend_Server_Reflection_Exception
     */
    public static function reflectFunction($function, $argv = false, $namespace = '')
    {
        if (!is_string($function) || !function_exists($function)) {
            require_once 'Zend/Server/Reflection/Exception.php';
            throw new Zend_Server_Reflection_Exception('Invalid function "' . $function . '" passed to reflectFunction');
        }

        if ($argv && !is_array($argv)) {
            require_once 'Zend/Server/Reflection/Exception.php';
            throw new Zend_Server_Reflection_Exception('Invalid argv argument passed to reflectClass');
        }

        return new Zend_Server_Reflection_Function(new ReflectionFunction($function), $namespace, $argv);
    }
}


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_Server
 * @subpackage Method
 * @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: Callback.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Method callback metadata
 *
 * @category   Zend
 * @package    Zend_Server
 * @subpackage Method
 * @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_Server_Method_Callback
{
    /**
     * @var string Class name for class method callback
     */
    protected $_class;

    /**
     * @var string Function name for function callback
     */
    protected $_function;

    /**
     * @var string Method name for class method callback
     */
    protected $_method;

    /**
     * @var string Callback type
     */
    protected $_type;

    /**
     * @var array Valid callback types
     */
    protected $_types = array('function', 'static', 'instance');

    /**
     * Constructor
     *
     * @param  null|array $options
     * @return void
     */
    public function __construct($options = null)
    {
        if ((null !== $options) && is_array($options))  {
            $this->setOptions($options);
        }
    }

    /**
     * Set object state from array of options
     *
     * @param  array $options
     * @return Zend_Server_Method_Callback
     */
    public function setOptions(array $options)
    {
        foreach ($options as $key => $value) {
            $method = 'set' . ucfirst($key);
            if (method_exists($this, $method)) {
                $this->$method($value);
            }
        }
        return $this;
    }

    /**
     * Set callback class
     *
     * @param  string $class
     * @return Zend_Server_Method_Callback
     */
    public function setClass($class)
    {
        if (is_object($class)) {
            $class = get_class($class);
        }
        $this->_class = $class;
        return $this;
    }

    /**
     * Get callback class
     *
     * @return string|null
     */
    public function getClass()
    {
        return $this->_class;
    }

    /**
     * Set callback function
     *
     * @param  string $function
     * @return Zend_Server_Method_Callback
     */
    public function setFunction($function)
    {
        $this->_function = (string) $function;
        $this->setType('function');
        return $this;
    }

    /**
     * Get callback function
     *
     * @return null|string
     */
    public function getFunction()
    {
        return $this->_function;
    }

    /**
     * Set callback class method
     *
     * @param  string $method
     * @return Zend_Server_Method_Callback
     */
    public function setMethod($method)
    {
        $this->_method = $method;
        return $this;
    }

    /**
     * Get callback class  method
     *
     * @return null|string
     */
    public function getMethod()
    {
        return $this->_method;
    }

    /**
     * Set callback type
     *
     * @param  string $type
     * @return Zend_Server_Method_Callback
     * @throws Zend_Server_Exception
     */
    public function setType($type)
    {
        if (!in_array($type, $this->_types)) {
            require_once 'Zend/Server/Exception.php';
            throw new Zend_Server_Exception('Invalid method callback type  passed to ' . __CLASS__ . '::' . __METHOD__);
        }
        $this->_type = $type;
        return $this;
    }

    /**
     * Get callback type
     *
     * @return string
     */
    public function getType()
    {
        return $this->_type;
    }

    /**
     * Cast callback to array
     *
     * @return array
     */
    public function toArray()
    {
        $type = $this->getType();
        $array = array(
            'type' => $type,
        );
        if ('function' == $type) {
            $array['function'] = $this->getFunction();
        } else {
            $array['class']  = $this->getClass();
            $array['method'] = $this->getMethod();
        }
        return $array;
    }
}