web/lib/Zend/Json/Server/Smd/Service.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     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  */
       
    24 require_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  */
       
    35 class 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 }