diff -r 000000000000 -r 4eba9c11703f web/Zend/Json/Server/Smd/Service.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/Zend/Json/Server/Smd/Service.php Mon Dec 13 18:29:26 2010 +0100 @@ -0,0 +1,473 @@ + '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; + } +}