Source of file Service.php
Size: 11,411 Bytes - Last Modified: 2014-03-12T23:21:18+01:00
/home/theseer/Downloads/ZendFramework-2.3.0/library/Zend/Json/Server/Smd/Service.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466 | <?php /** * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ namespace Zend\Json\Server\Smd; use Zend\Json\Server\Exception\InvalidArgumentException; use Zend\Json\Server\Smd; /** * Create Service Mapping Description for a method * * @todo Revised method regex to allow NS; however, should SMD be revised to strip PHP NS instead when attaching functions? */ class Service { /**#@+ * Service metadata * @var string */ protected $envelope = Smd::ENV_JSONRPC_1; protected $name; protected $return; protected $target; protected $transport = 'POST'; /**#@-*/ /** * Allowed envelope types * @var array */ protected $envelopeTypes = array( Smd::ENV_JSONRPC_1, Smd::ENV_JSONRPC_2, ); /** * Regex for names * @var string * * @link http://php.net/manual/en/language.oop5.basic.php * @link http://www.jsonrpc.org/specification#request_object */ protected $nameRegex = '/^(?!^rpc\.)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff\.\\\]*$/'; /** * 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 * @throws InvalidArgumentException 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()) { throw new InvalidArgumentException('SMD service description requires a name; none provided'); } } /** * Set object state * * @param array $options * @return 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 Service * @throws InvalidArgumentException */ public function setName($name) { $name = (string) $name; if (!preg_match($this->nameRegex, $name)) { throw new InvalidArgumentException("Invalid name '{$name} provided for service; must follow PHP method naming conventions"); } $this->name = $name; return $this; } /** * Retrieve name * * @return string */ public function getName() { return $this->name; } /** * Set Transport * * Currently limited to POST * * @param string $transport * @throws InvalidArgumentException * @return Service */ public function setTransport($transport) { if (!in_array($transport, $this->transportTypes)) { throw new InvalidArgumentException("Invalid transport '{$transport}'; please select one of (" . 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 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 * @throws InvalidArgumentException * @return Service */ public function setEnvelope($envelopeType) { if (!in_array($envelopeType, $this->envelopeTypes)) { throw new InvalidArgumentException("Invalid envelope type '{$envelopeType}'; please specify one of (" . 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 * @throws InvalidArgumentException * @return 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 { throw new InvalidArgumentException('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 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 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 * @throws InvalidArgumentException * @return 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 { throw new InvalidArgumentException("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() { $envelope = $this->getEnvelope(); $target = $this->getTarget(); $transport = $this->getTransport(); $parameters = $this->getParams(); $returns = $this->getReturn(); $name = $this->getName(); if (empty($target)) { return compact('envelope', 'transport', 'name', 'parameters', 'returns'); } return compact('envelope', 'target', 'transport', 'name', 'parameters', 'returns'); } /** * Return JSON encoding of service * * @return string */ public function toJson() { $service = array($this->getName() => $this->toArray()); return \Zend\Json\Json::encode($service); } /** * Cast to string * * @return string */ public function __toString() { return $this->toJson(); } /** * Validate parameter type * * @param string $type * @param bool $isReturn * @return string * @throws InvalidArgumentException */ protected function _validateParamType($type, $isReturn = false) { if (!is_string($type)) { throw new InvalidArgumentException("Invalid param type provided ('{$type}')"); } if (!array_key_exists($type, $this->paramMap)) { $type = 'object'; } $paramType = $this->paramMap[$type]; if (!$isReturn && ('null' == $paramType)) { throw new InvalidArgumentException("Invalid param type provided ('{$type}')"); } return $paramType; } } |