File indexing completed on 2025-02-23 05:32:28
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Json 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 */ 0020 0021 /** 0022 * @see Zend_Json_Server_Smd 0023 */ 0024 // require_once 'Zend/Json/Server/Smd.php'; 0025 0026 /** 0027 * Create Service Mapping Description for a method 0028 * 0029 * @package Zend_Json 0030 * @subpackage Server 0031 * @version $Id$ 0032 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0033 * @license http://framework.zend.com/license/new-bsd New BSD License 0034 */ 0035 class Zend_Json_Server_Smd_Service 0036 { 0037 /**#@+ 0038 * Service metadata 0039 * @var string 0040 */ 0041 protected $_envelope = Zend_Json_Server_Smd::ENV_JSONRPC_1; 0042 protected $_name; 0043 protected $_return; 0044 protected $_target; 0045 protected $_transport = 'POST'; 0046 /**#@-*/ 0047 0048 /** 0049 * Allowed envelope types 0050 * @var array 0051 */ 0052 protected $_envelopeTypes = array( 0053 Zend_Json_Server_Smd::ENV_JSONRPC_1, 0054 Zend_Json_Server_Smd::ENV_JSONRPC_2, 0055 ); 0056 0057 /** 0058 * Regex for names 0059 * @var string 0060 */ 0061 protected $_nameRegex = '/^[a-z][a-z0-9._]+$/i'; 0062 0063 /** 0064 * Parameter option types 0065 * @var array 0066 */ 0067 protected $_paramOptionTypes = array( 0068 'name' => 'is_string', 0069 'optional' => 'is_bool', 0070 'default' => null, 0071 'description' => 'is_string', 0072 ); 0073 0074 /** 0075 * Service params 0076 * @var array 0077 */ 0078 protected $_params = array(); 0079 0080 /** 0081 * Mapping of parameter types to JSON-RPC types 0082 * @var array 0083 */ 0084 protected $_paramMap = array( 0085 'any' => 'any', 0086 'arr' => 'array', 0087 'array' => 'array', 0088 'assoc' => 'object', 0089 'bool' => 'boolean', 0090 'boolean' => 'boolean', 0091 'dbl' => 'float', 0092 'double' => 'float', 0093 'false' => 'boolean', 0094 'float' => 'float', 0095 'hash' => 'object', 0096 'integer' => 'integer', 0097 'int' => 'integer', 0098 'mixed' => 'any', 0099 'nil' => 'null', 0100 'null' => 'null', 0101 'object' => 'object', 0102 'string' => 'string', 0103 'str' => 'string', 0104 'struct' => 'object', 0105 'true' => 'boolean', 0106 'void' => 'null', 0107 ); 0108 0109 /** 0110 * Allowed transport types 0111 * @var array 0112 */ 0113 protected $_transportTypes = array( 0114 'POST', 0115 ); 0116 0117 /** 0118 * Constructor 0119 * 0120 * @param string|array $spec 0121 * @return void 0122 * @throws Zend_Json_Server_Exception if no name provided 0123 */ 0124 public function __construct($spec) 0125 { 0126 if (is_string($spec)) { 0127 $this->setName($spec); 0128 } elseif (is_array($spec)) { 0129 $this->setOptions($spec); 0130 } 0131 0132 if (null == $this->getName()) { 0133 // require_once 'Zend/Json/Server/Exception.php'; 0134 throw new Zend_Json_Server_Exception('SMD service description requires a name; none provided'); 0135 } 0136 } 0137 0138 /** 0139 * Set object state 0140 * 0141 * @param array $options 0142 * @return Zend_Json_Server_Smd_Service 0143 */ 0144 public function setOptions(array $options) 0145 { 0146 $methods = get_class_methods($this); 0147 foreach ($options as $key => $value) { 0148 if ('options' == strtolower($key)) { 0149 continue; 0150 } 0151 $method = 'set' . ucfirst($key); 0152 if (in_array($method, $methods)) { 0153 $this->$method($value); 0154 } 0155 } 0156 return $this; 0157 } 0158 0159 /** 0160 * Set service name 0161 * 0162 * @param string $name 0163 * @return Zend_Json_Server_Smd_Service 0164 * @throws Zend_Json_Server_Exception 0165 */ 0166 public function setName($name) 0167 { 0168 $name = (string) $name; 0169 if (!preg_match($this->_nameRegex, $name)) { 0170 // require_once 'Zend/Json/Server/Exception.php'; 0171 throw new Zend_Json_Server_Exception(sprintf('Invalid name "%s" provided for service; must follow PHP method naming conventions', $name)); 0172 } 0173 $this->_name = $name; 0174 return $this; 0175 } 0176 0177 /** 0178 * Retrieve name 0179 * 0180 * @return string 0181 */ 0182 public function getName() 0183 { 0184 return $this->_name; 0185 } 0186 0187 /** 0188 * Set Transport 0189 * 0190 * Currently limited to POST 0191 * 0192 * @param string $transport 0193 * @return Zend_Json_Server_Smd_Service 0194 */ 0195 public function setTransport($transport) 0196 { 0197 if (!in_array($transport, $this->_transportTypes)) { 0198 // require_once 'Zend/Json/Server/Exception.php'; 0199 throw new Zend_Json_Server_Exception(sprintf('Invalid transport "%s"; please select one of (%s)', $transport, implode(', ', $this->_transportTypes))); 0200 } 0201 0202 $this->_transport = $transport; 0203 return $this; 0204 } 0205 0206 /** 0207 * Get transport 0208 * 0209 * @return string 0210 */ 0211 public function getTransport() 0212 { 0213 return $this->_transport; 0214 } 0215 0216 /** 0217 * Set service target 0218 * 0219 * @param string $target 0220 * @return Zend_Json_Server_Smd_Service 0221 */ 0222 public function setTarget($target) 0223 { 0224 $this->_target = (string) $target; 0225 return $this; 0226 } 0227 0228 /** 0229 * Get service target 0230 * 0231 * @return string 0232 */ 0233 public function getTarget() 0234 { 0235 return $this->_target; 0236 } 0237 0238 /** 0239 * Set envelope type 0240 * 0241 * @param string $envelopeType 0242 * @return Zend_Json_Server_Smd_Service 0243 */ 0244 public function setEnvelope($envelopeType) 0245 { 0246 if (!in_array($envelopeType, $this->_envelopeTypes)) { 0247 // require_once 'Zend/Json/Server/Exception.php'; 0248 throw new Zend_Json_Server_Exception(sprintf('Invalid envelope type "%s"; please specify one of (%s)', $envelopeType, implode(', ', $this->_envelopeTypes))); 0249 } 0250 0251 $this->_envelope = $envelopeType; 0252 return $this; 0253 } 0254 0255 /** 0256 * Get envelope type 0257 * 0258 * @return string 0259 */ 0260 public function getEnvelope() 0261 { 0262 return $this->_envelope; 0263 } 0264 0265 /** 0266 * Add a parameter to the service 0267 * 0268 * @param string|array $type 0269 * @param array $options 0270 * @param int|null $order 0271 * @return Zend_Json_Server_Smd_Service 0272 */ 0273 public function addParam($type, array $options = array(), $order = null) 0274 { 0275 if (is_string($type)) { 0276 $type = $this->_validateParamType($type); 0277 } elseif (is_array($type)) { 0278 foreach ($type as $key => $paramType) { 0279 $type[$key] = $this->_validateParamType($paramType); 0280 } 0281 } else { 0282 // require_once 'Zend/Json/Server/Exception.php'; 0283 throw new Zend_Json_Server_Exception('Invalid param type provided'); 0284 } 0285 0286 $paramOptions = array( 0287 'type' => $type, 0288 ); 0289 foreach ($options as $key => $value) { 0290 if (in_array($key, array_keys($this->_paramOptionTypes))) { 0291 if (null !== ($callback = $this->_paramOptionTypes[$key])) { 0292 if (!$callback($value)) { 0293 continue; 0294 } 0295 } 0296 $paramOptions[$key] = $value; 0297 } 0298 } 0299 0300 $this->_params[] = array( 0301 'param' => $paramOptions, 0302 'order' => $order, 0303 ); 0304 0305 return $this; 0306 } 0307 0308 /** 0309 * Add params 0310 * 0311 * Each param should be an array, and should include the key 'type'. 0312 * 0313 * @param array $params 0314 * @return Zend_Json_Server_Smd_Service 0315 */ 0316 public function addParams(array $params) 0317 { 0318 ksort($params); 0319 foreach ($params as $options) { 0320 if (!is_array($options)) { 0321 continue; 0322 } 0323 if (!array_key_exists('type', $options)) { 0324 continue; 0325 } 0326 $type = $options['type']; 0327 $order = (array_key_exists('order', $options)) ? $options['order'] : null; 0328 $this->addParam($type, $options, $order); 0329 } 0330 return $this; 0331 } 0332 0333 /** 0334 * Overwrite all parameters 0335 * 0336 * @param array $params 0337 * @return Zend_Json_Server_Smd_Service 0338 */ 0339 public function setParams(array $params) 0340 { 0341 $this->_params = array(); 0342 return $this->addParams($params); 0343 } 0344 0345 /** 0346 * Get all parameters 0347 * 0348 * Returns all params in specified order. 0349 * 0350 * @return array 0351 */ 0352 public function getParams() 0353 { 0354 $params = array(); 0355 $index = 0; 0356 foreach ($this->_params as $param) { 0357 if (null === $param['order']) { 0358 if (array_search($index, array_keys($params), true)) { 0359 ++$index; 0360 } 0361 $params[$index] = $param['param']; 0362 ++$index; 0363 } else { 0364 $params[$param['order']] = $param['param']; 0365 } 0366 } 0367 ksort($params); 0368 return $params; 0369 } 0370 0371 /** 0372 * Set return type 0373 * 0374 * @param string|array $type 0375 * @return Zend_Json_Server_Smd_Service 0376 */ 0377 public function setReturn($type) 0378 { 0379 if (is_string($type)) { 0380 $type = $this->_validateParamType($type, true); 0381 } elseif (is_array($type)) { 0382 foreach ($type as $key => $returnType) { 0383 $type[$key] = $this->_validateParamType($returnType, true); 0384 } 0385 } else { 0386 // require_once 'Zend/Json/Server/Exception.php'; 0387 throw new Zend_Json_Server_Exception('Invalid param type provided ("' . gettype($type) .'")'); 0388 } 0389 $this->_return = $type; 0390 return $this; 0391 } 0392 0393 /** 0394 * Get return type 0395 * 0396 * @return string|array 0397 */ 0398 public function getReturn() 0399 { 0400 return $this->_return; 0401 } 0402 0403 /** 0404 * Cast service description to array 0405 * 0406 * @return array 0407 */ 0408 public function toArray() 0409 { 0410 $name = $this->getName(); 0411 $envelope = $this->getEnvelope(); 0412 $target = $this->getTarget(); 0413 $transport = $this->getTransport(); 0414 $parameters = $this->getParams(); 0415 $returns = $this->getReturn(); 0416 0417 if (empty($target)) { 0418 return compact('envelope', 'transport', 'parameters', 'returns'); 0419 } 0420 0421 return $paramInfo = compact('envelope', 'target', 'transport', 'parameters', 'returns'); 0422 } 0423 0424 /** 0425 * Return JSON encoding of service 0426 * 0427 * @return string 0428 */ 0429 public function toJson() 0430 { 0431 $service = array($this->getName() => $this->toArray()); 0432 0433 // require_once 'Zend/Json.php'; 0434 return Zend_Json::encode($service); 0435 } 0436 0437 /** 0438 * Cast to string 0439 * 0440 * @return string 0441 */ 0442 public function __toString() 0443 { 0444 return $this->toJson(); 0445 } 0446 0447 /** 0448 * Validate parameter type 0449 * 0450 * @param string $type 0451 * @return true 0452 * @throws Zend_Json_Server_Exception 0453 */ 0454 protected function _validateParamType($type, $isReturn = false) 0455 { 0456 if (!is_string($type)) { 0457 // require_once 'Zend/Json/Server/Exception.php'; 0458 throw new Zend_Json_Server_Exception('Invalid param type provided ("' . $type .'")'); 0459 } 0460 0461 if (!array_key_exists($type, $this->_paramMap)) { 0462 $type = 'object'; 0463 } 0464 0465 $paramType = $this->_paramMap[$type]; 0466 if (!$isReturn && ('null' == $paramType)) { 0467 // require_once 'Zend/Json/Server/Exception.php'; 0468 throw new Zend_Json_Server_Exception('Invalid param type provided ("' . $type . '")'); 0469 } 0470 0471 return $paramType; 0472 } 0473 }