PageRenderTime 25ms CodeModel.GetById 12ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/framework/vendor/zend/Zend/Json/Server/Smd/Service.php

http://zoop.googlecode.com/
PHP | 473 lines | 252 code | 40 blank | 181 comment | 27 complexity | e491dd2e79cc5a96aca04bb09bcf94ce MD5 | raw file
  1<?php
  2/**
  3 * Zend Framework
  4 *
  5 * LICENSE
  6 *
  7 * This source file is subject to the new BSD license that is bundled
  8 * with this package in the file LICENSE.txt.
  9 * It is also available through the world-wide-web at this URL:
 10 * http://framework.zend.com/license/new-bsd
 11 * If you did not receive a copy of the license and are unable to
 12 * obtain it through the world-wide-web, please send an email
 13 * to license@zend.com so we can send you a copy immediately.
 14 *
 15 * @category   Zend
 16 * @package    Zend_Json
 17 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 18 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 19 */
 20
 21/**
 22 * @see Zend_Json_Server_Smd
 23 */
 24require_once 'Zend/Json/Server/Smd.php';
 25
 26/**
 27 * Create Service Mapping Description for a method
 28 *
 29 * @package    Zend_Json
 30 * @subpackage Server
 31 * @version    $Id: Service.php 20096 2010-01-06 02:05:09Z bkarwin $
 32 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 33 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 34 */
 35class Zend_Json_Server_Smd_Service
 36{
 37    /**#@+
 38     * Service metadata
 39     * @var string
 40     */
 41    protected $_envelope  = Zend_Json_Server_Smd::ENV_JSONRPC_1;
 42    protected $_name;
 43    protected $_return;
 44    protected $_target;
 45    protected $_transport = 'POST';
 46    /**#@-*/
 47
 48    /**
 49     * Allowed envelope types
 50     * @var array
 51     */
 52    protected $_envelopeTypes = array(
 53        Zend_Json_Server_Smd::ENV_JSONRPC_1,
 54        Zend_Json_Server_Smd::ENV_JSONRPC_2,
 55    );
 56
 57    /**
 58     * Regex for names
 59     * @var string
 60     */
 61    protected $_nameRegex = '/^[a-z][a-z0-9._]+$/i';
 62
 63    /**
 64     * Parameter option types
 65     * @var array
 66     */
 67    protected $_paramOptionTypes = array(
 68        'name'        => 'is_string',
 69        'optional'    => 'is_bool',
 70        'default'     => null,
 71        'description' => 'is_string',
 72    );
 73
 74    /**
 75     * Service params
 76     * @var array
 77     */
 78    protected $_params = array();
 79
 80    /**
 81     * Mapping of parameter types to JSON-RPC types
 82     * @var array
 83     */
 84    protected $_paramMap = array(
 85        'any'     => 'any',
 86        'arr'     => 'array',
 87        'array'   => 'array',
 88        'assoc'   => 'object',
 89        'bool'    => 'boolean',
 90        'boolean' => 'boolean',
 91        'dbl'     => 'float',
 92        'double'  => 'float',
 93        'false'   => 'boolean',
 94        'float'   => 'float',
 95        'hash'    => 'object',
 96        'integer' => 'integer',
 97        'int'     => 'integer',
 98        'mixed'   => 'any',
 99        'nil'     => 'null',
100        'null'    => 'null',
101        'object'  => 'object',
102        'string'  => 'string',
103        'str'     => 'string',
104        'struct'  => 'object',
105        'true'    => 'boolean',
106        'void'    => 'null',
107    );
108
109    /**
110     * Allowed transport types
111     * @var array
112     */
113    protected $_transportTypes = array(
114        'POST',
115    );
116
117    /**
118     * Constructor
119     *
120     * @param  string|array $spec
121     * @return void
122     * @throws Zend_Json_Server_Exception if no name provided
123     */
124    public function __construct($spec)
125    {
126        if (is_string($spec)) {
127            $this->setName($spec);
128        } elseif (is_array($spec)) {
129            $this->setOptions($spec);
130        }
131
132        if (null == $this->getName()) {
133            require_once 'Zend/Json/Server/Exception.php';
134            throw new Zend_Json_Server_Exception('SMD service description requires a name; none provided');
135        }
136    }
137
138    /**
139     * Set object state
140     *
141     * @param  array $options
142     * @return Zend_Json_Server_Smd_Service
143     */
144    public function setOptions(array $options)
145    {
146        $methods = get_class_methods($this);
147        foreach ($options as $key => $value) {
148            if ('options' == strtolower($key)) {
149                continue;
150            }
151            $method = 'set' . ucfirst($key);
152            if (in_array($method, $methods)) {
153                $this->$method($value);
154            }
155        }
156        return $this;
157    }
158
159    /**
160     * Set service name
161     *
162     * @param  string $name
163     * @return Zend_Json_Server_Smd_Service
164     * @throws Zend_Json_Server_Exception
165     */
166    public function setName($name)
167    {
168        $name = (string) $name;
169        if (!preg_match($this->_nameRegex, $name)) {
170            require_once 'Zend/Json/Server/Exception.php';
171            throw new Zend_Json_Server_Exception(sprintf('Invalid name "%s" provided for service; must follow PHP method naming conventions', $name));
172        }
173        $this->_name = $name;
174        return $this;
175    }
176
177    /**
178     * Retrieve name
179     *
180     * @return string
181     */
182    public function getName()
183    {
184        return $this->_name;
185    }
186
187    /**
188     * Set Transport
189     *
190     * Currently limited to POST
191     *
192     * @param  string $transport
193     * @return Zend_Json_Server_Smd_Service
194     */
195    public function setTransport($transport)
196    {
197        if (!in_array($transport, $this->_transportTypes)) {
198            require_once 'Zend/Json/Server/Exception.php';
199            throw new Zend_Json_Server_Exception(sprintf('Invalid transport "%s"; please select one of (%s)', $transport, implode(', ', $this->_transportTypes)));
200        }
201
202        $this->_transport = $transport;
203        return $this;
204    }
205
206    /**
207     * Get transport
208     *
209     * @return string
210     */
211    public function getTransport()
212    {
213        return $this->_transport;
214    }
215
216    /**
217     * Set service target
218     *
219     * @param  string $target
220     * @return Zend_Json_Server_Smd_Service
221     */
222    public function setTarget($target)
223    {
224        $this->_target = (string) $target;
225        return $this;
226    }
227
228    /**
229     * Get service target
230     *
231     * @return string
232     */
233    public function getTarget()
234    {
235        return $this->_target;
236    }
237
238    /**
239     * Set envelope type
240     *
241     * @param  string $envelopeType
242     * @return Zend_Json_Server_Smd_Service
243     */
244    public function setEnvelope($envelopeType)
245    {
246        if (!in_array($envelopeType, $this->_envelopeTypes)) {
247            require_once 'Zend/Json/Server/Exception.php';
248            throw new Zend_Json_Server_Exception(sprintf('Invalid envelope type "%s"; please specify one of (%s)', $envelopeType, implode(', ', $this->_envelopeTypes)));
249        }
250
251        $this->_envelope = $envelopeType;
252        return $this;
253    }
254
255    /**
256     * Get envelope type
257     *
258     * @return string
259     */
260    public function getEnvelope()
261    {
262        return $this->_envelope;
263    }
264
265    /**
266     * Add a parameter to the service
267     *
268     * @param  string|array $type
269     * @param  array $options
270     * @param  int|null $order
271     * @return Zend_Json_Server_Smd_Service
272     */
273    public function addParam($type, array $options = array(), $order = null)
274    {
275        if (is_string($type)) {
276            $type = $this->_validateParamType($type);
277        } elseif (is_array($type)) {
278            foreach ($type as $key => $paramType) {
279                $type[$key] = $this->_validateParamType($paramType);
280            }
281        } else {
282            require_once 'Zend/Json/Server/Exception.php';
283            throw new Zend_Json_Server_Exception('Invalid param type provided');
284        }
285
286        $paramOptions = array(
287            'type' => $type,
288        );
289        foreach ($options as $key => $value) {
290            if (in_array($key, array_keys($this->_paramOptionTypes))) {
291                if (null !== ($callback = $this->_paramOptionTypes[$key])) {
292                    if (!$callback($value)) {
293                        continue;
294                    }
295                }
296                $paramOptions[$key] = $value;
297            }
298        }
299
300        $this->_params[] = array(
301            'param' => $paramOptions,
302            'order' => $order,
303        );
304
305        return $this;
306    }
307
308    /**
309     * Add params
310     *
311     * Each param should be an array, and should include the key 'type'.
312     *
313     * @param  array $params
314     * @return Zend_Json_Server_Smd_Service
315     */
316    public function addParams(array $params)
317    {
318        ksort($params);
319        foreach ($params as $options) {
320            if (!is_array($options)) {
321                continue;
322            }
323            if (!array_key_exists('type', $options)) {
324                continue;
325            }
326            $type  = $options['type'];
327            $order = (array_key_exists('order', $options)) ? $options['order'] : null;
328            $this->addParam($type, $options, $order);
329        }
330        return $this;
331    }
332
333    /**
334     * Overwrite all parameters
335     *
336     * @param  array $params
337     * @return Zend_Json_Server_Smd_Service
338     */
339    public function setParams(array $params)
340    {
341        $this->_params = array();
342        return $this->addParams($params);
343    }
344
345    /**
346     * Get all parameters
347     *
348     * Returns all params in specified order.
349     *
350     * @return array
351     */
352    public function getParams()
353    {
354        $params = array();
355        $index  = 0;
356        foreach ($this->_params as $param) {
357            if (null === $param['order']) {
358                if (array_search($index, array_keys($params), true)) {
359                    ++$index;
360                }
361                $params[$index] = $param['param'];
362                ++$index;
363            } else {
364                $params[$param['order']] = $param['param'];
365            }
366        }
367        ksort($params);
368        return $params;
369    }
370
371    /**
372     * Set return type
373     *
374     * @param  string|array $type
375     * @return Zend_Json_Server_Smd_Service
376     */
377    public function setReturn($type)
378    {
379        if (is_string($type)) {
380            $type = $this->_validateParamType($type, true);
381        } elseif (is_array($type)) {
382            foreach ($type as $key => $returnType) {
383                $type[$key] = $this->_validateParamType($returnType, true);
384            }
385        } else {
386            require_once 'Zend/Json/Server/Exception.php';
387            throw new Zend_Json_Server_Exception('Invalid param type provided ("' . gettype($type) .'")');
388        }
389        $this->_return = $type;
390        return $this;
391    }
392
393    /**
394     * Get return type
395     *
396     * @return string|array
397     */
398    public function getReturn()
399    {
400        return $this->_return;
401    }
402
403    /**
404     * Cast service description to array
405     *
406     * @return array
407     */
408    public function toArray()
409    {
410        $name       = $this->getName();
411        $envelope   = $this->getEnvelope();
412        $target     = $this->getTarget();
413        $transport  = $this->getTransport();
414        $parameters = $this->getParams();
415        $returns    = $this->getReturn();
416
417        if (empty($target)) {
418            return compact('envelope', 'transport', 'parameters', 'returns');
419        }
420
421        return $paramInfo = compact('envelope', 'target', 'transport', 'parameters', 'returns');
422    }
423
424    /**
425     * Return JSON encoding of service
426     *
427     * @return string
428     */
429    public function toJson()
430    {
431        $service = array($this->getName() => $this->toArray());
432
433        require_once 'Zend/Json.php';
434        return Zend_Json::encode($service);
435    }
436
437    /**
438     * Cast to string
439     *
440     * @return string
441     */
442    public function __toString()
443    {
444        return $this->toJson();
445    }
446
447    /**
448     * Validate parameter type
449     *
450     * @param  string $type
451     * @return true
452     * @throws Zend_Json_Server_Exception
453     */
454    protected function _validateParamType($type, $isReturn = false)
455    {
456        if (!is_string($type)) {
457            require_once 'Zend/Json/Server/Exception.php';
458            throw new Zend_Json_Server_Exception('Invalid param type provided ("' . $type .'")');
459        }
460
461        if (!array_key_exists($type, $this->_paramMap)) {
462            $type = 'object';
463        }
464
465        $paramType = $this->_paramMap[$type];
466        if (!$isReturn && ('null' == $paramType)) {
467            require_once 'Zend/Json/Server/Exception.php';
468            throw new Zend_Json_Server_Exception('Invalid param type provided ("' . $type . '")');
469        }
470
471        return $paramType;
472    }
473}