3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Json\Server\Smd
;
13 use Zend\Json\Server\Exception\InvalidArgumentException
;
14 use Zend\Json\Server\Smd
;
17 * Create Service Mapping Description for a method
19 * @todo Revised method regex to allow NS; however, should SMD be revised to strip PHP NS instead when attaching functions?
27 protected $envelope = Smd
::ENV_JSONRPC_1
;
31 protected $transport = 'POST';
35 * Allowed envelope types
38 protected $envelopeTypes = array(
47 protected $nameRegex = '/^[a-z][a-z0-9.\\\\_]+$/i';
50 * Parameter option types
53 protected $paramOptionTypes = array(
54 'name' => 'is_string',
55 'optional' => 'is_bool',
57 'description' => 'is_string',
64 protected $params = array();
67 * Mapping of parameter types to JSON-RPC types
70 protected $paramMap = array(
76 'boolean' => 'boolean',
82 'integer' => 'integer',
96 * Allowed transport types
99 protected $transportTypes = array(
106 * @param string|array $spec
107 * @throws InvalidArgumentException if no name provided
109 public function __construct($spec)
111 if (is_string($spec)) {
112 $this->setName($spec);
113 } elseif (is_array($spec)) {
114 $this->setOptions($spec);
117 if (null == $this->getName()) {
118 throw new InvalidArgumentException('SMD service description requires a name; none provided');
125 * @param array $options
128 public function setOptions(array $options)
130 $methods = get_class_methods($this);
131 foreach ($options as $key => $value) {
132 if ('options' == strtolower($key)) {
135 $method = 'set' . ucfirst($key);
136 if (in_array($method, $methods)) {
137 $this->$method($value);
146 * @param string $name
148 * @throws InvalidArgumentException
150 public function setName($name)
152 $name = (string) $name;
153 if (!preg_match($this->nameRegex
, $name)) {
154 throw new InvalidArgumentException("Invalid name '{$name} provided for service; must follow PHP method naming conventions");
165 public function getName()
173 * Currently limited to POST
175 * @param string $transport
176 * @throws InvalidArgumentException
179 public function setTransport($transport)
181 if (!in_array($transport, $this->transportTypes
)) {
182 throw new InvalidArgumentException("Invalid transport '{$transport}'; please select one of (" . implode(', ', $this->transportTypes
) . ')');
185 $this->transport
= $transport;
194 public function getTransport()
196 return $this->transport
;
202 * @param string $target
205 public function setTarget($target)
207 $this->target
= (string) $target;
216 public function getTarget()
218 return $this->target
;
224 * @param string $envelopeType
225 * @throws InvalidArgumentException
228 public function setEnvelope($envelopeType)
230 if (!in_array($envelopeType, $this->envelopeTypes
)) {
231 throw new InvalidArgumentException("Invalid envelope type '{$envelopeType}'; please specify one of (" . implode(', ', $this->envelopeTypes
) . ')');
234 $this->envelope
= $envelopeType;
243 public function getEnvelope()
245 return $this->envelope
;
249 * Add a parameter to the service
251 * @param string|array $type
252 * @param array $options
253 * @param int|null $order
254 * @throws InvalidArgumentException
257 public function addParam($type, array $options = array(), $order = null)
259 if (is_string($type)) {
260 $type = $this->_validateParamType($type);
261 } elseif (is_array($type)) {
262 foreach ($type as $key => $paramType) {
263 $type[$key] = $this->_validateParamType($paramType);
266 throw new InvalidArgumentException('Invalid param type provided');
269 $paramOptions = array(
272 foreach ($options as $key => $value) {
273 if (in_array($key, array_keys($this->paramOptionTypes
))) {
274 if (null !== ($callback = $this->paramOptionTypes
[$key])) {
275 if (!$callback($value)) {
279 $paramOptions[$key] = $value;
283 $this->params
[] = array(
284 'param' => $paramOptions,
294 * Each param should be an array, and should include the key 'type'.
296 * @param array $params
299 public function addParams(array $params)
302 foreach ($params as $options) {
303 if (!is_array($options)) {
306 if (!array_key_exists('type', $options)) {
309 $type = $options['type'];
310 $order = (array_key_exists('order', $options)) ?
$options['order'] : null;
311 $this->addParam($type, $options, $order);
317 * Overwrite all parameters
319 * @param array $params
322 public function setParams(array $params)
324 $this->params
= array();
325 return $this->addParams($params);
331 * Returns all params in specified order.
335 public function getParams()
339 foreach ($this->params
as $param) {
340 if (null === $param['order']) {
341 if (array_search($index, array_keys($params), true)) {
344 $params[$index] = $param['param'];
347 $params[$param['order']] = $param['param'];
357 * @param string|array $type
358 * @throws InvalidArgumentException
361 public function setReturn($type)
363 if (is_string($type)) {
364 $type = $this->_validateParamType($type, true);
365 } elseif (is_array($type)) {
366 foreach ($type as $key => $returnType) {
367 $type[$key] = $this->_validateParamType($returnType, true);
370 throw new InvalidArgumentException("Invalid param type provided ('" . gettype($type) . "')");
372 $this->return = $type;
379 * @return string|array
381 public function getReturn()
383 return $this->return;
387 * Cast service description to array
391 public function toArray()
393 $envelope = $this->getEnvelope();
394 $target = $this->getTarget();
395 $transport = $this->getTransport();
396 $parameters = $this->getParams();
397 $returns = $this->getReturn();
399 if (empty($target)) {
400 return compact('envelope', 'transport', 'parameters', 'returns');
403 return $paramInfo = compact('envelope', 'target', 'transport', 'parameters', 'returns');
407 * Return JSON encoding of service
411 public function toJson()
413 $service = array($this->getName() => $this->toArray());
414 return \Zend\Json\Json
::encode($service);
422 public function __toString()
424 return $this->toJson();
428 * Validate parameter type
430 * @param string $type
431 * @param bool $isReturn
433 * @throws InvalidArgumentException
435 protected function _validateParamType($type, $isReturn = false)
437 if (!is_string($type)) {
438 throw new InvalidArgumentException("Invalid param type provided ('{$type}')");
441 if (!array_key_exists($type, $this->paramMap
)) {
445 $paramType = $this->paramMap
[$type];
446 if (!$isReturn && ('null' == $paramType)) {
447 throw new InvalidArgumentException("Invalid param type provided ('{$type}')");