File indexing completed on 2024-12-22 05:37:14
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_Controller 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 * Zend_XmlRpc_Value 0023 */ 0024 // require_once 'Zend/XmlRpc/Value.php'; 0025 0026 /** 0027 * Zend_XmlRpc_Fault 0028 */ 0029 // require_once 'Zend/XmlRpc/Fault.php'; 0030 0031 /** @see Zend_Xml_Security */ 0032 // require_once 'Zend/Xml/Security.php'; 0033 0034 /** @see Zend_Xml_Exception */ 0035 // require_once 'Zend/Xml/Exception.php'; 0036 0037 /** 0038 * XmlRpc Request object 0039 * 0040 * Encapsulates an XmlRpc request, holding the method call and all parameters. 0041 * Provides accessors for these, as well as the ability to load from XML and to 0042 * create the XML request string. 0043 * 0044 * Additionally, if errors occur setting the method or parsing XML, a fault is 0045 * generated and stored in {@link $_fault}; developers may check for it using 0046 * {@link isFault()} and {@link getFault()}. 0047 * 0048 * @category Zend 0049 * @package Zend_XmlRpc 0050 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0051 * @license http://framework.zend.com/license/new-bsd New BSD License 0052 * @version $Id$ 0053 */ 0054 class Zend_XmlRpc_Request 0055 { 0056 /** 0057 * Request character encoding 0058 * @var string 0059 */ 0060 protected $_encoding = 'UTF-8'; 0061 0062 /** 0063 * Method to call 0064 * @var string 0065 */ 0066 protected $_method; 0067 0068 /** 0069 * XML request 0070 * @var string 0071 */ 0072 protected $_xml; 0073 0074 /** 0075 * Method parameters 0076 * @var array 0077 */ 0078 protected $_params = array(); 0079 0080 /** 0081 * Fault object, if any 0082 * @var Zend_XmlRpc_Fault 0083 */ 0084 protected $_fault = null; 0085 0086 /** 0087 * XML-RPC type for each param 0088 * @var array 0089 */ 0090 protected $_types = array(); 0091 0092 /** 0093 * XML-RPC request params 0094 * @var array 0095 */ 0096 protected $_xmlRpcParams = array(); 0097 0098 /** 0099 * Create a new XML-RPC request 0100 * 0101 * @param string $method (optional) 0102 * @param array $params (optional) 0103 */ 0104 public function __construct($method = null, $params = null) 0105 { 0106 if ($method !== null) { 0107 $this->setMethod($method); 0108 } 0109 0110 if ($params !== null) { 0111 $this->setParams($params); 0112 } 0113 } 0114 0115 0116 /** 0117 * Set encoding to use in request 0118 * 0119 * @param string $encoding 0120 * @return Zend_XmlRpc_Request 0121 */ 0122 public function setEncoding($encoding) 0123 { 0124 $this->_encoding = $encoding; 0125 Zend_XmlRpc_Value::setEncoding($encoding); 0126 return $this; 0127 } 0128 0129 /** 0130 * Retrieve current request encoding 0131 * 0132 * @return string 0133 */ 0134 public function getEncoding() 0135 { 0136 return $this->_encoding; 0137 } 0138 0139 /** 0140 * Set method to call 0141 * 0142 * @param string $method 0143 * @return boolean Returns true on success, false if method name is invalid 0144 */ 0145 public function setMethod($method) 0146 { 0147 if (!is_string($method) || !preg_match('/^[a-z0-9_.:\/]+$/i', $method)) { 0148 $this->_fault = new Zend_XmlRpc_Fault(634, 'Invalid method name ("' . $method . '")'); 0149 $this->_fault->setEncoding($this->getEncoding()); 0150 return false; 0151 } 0152 0153 $this->_method = $method; 0154 return true; 0155 } 0156 0157 /** 0158 * Retrieve call method 0159 * 0160 * @return string 0161 */ 0162 public function getMethod() 0163 { 0164 return $this->_method; 0165 } 0166 0167 /** 0168 * Add a parameter to the parameter stack 0169 * 0170 * Adds a parameter to the parameter stack, associating it with the type 0171 * $type if provided 0172 * 0173 * @param mixed $value 0174 * @param string $type Optional; type hinting 0175 * @return void 0176 */ 0177 public function addParam($value, $type = null) 0178 { 0179 $this->_params[] = $value; 0180 if (null === $type) { 0181 // Detect type if not provided explicitly 0182 if ($value instanceof Zend_XmlRpc_Value) { 0183 $type = $value->getType(); 0184 } else { 0185 $xmlRpcValue = Zend_XmlRpc_Value::getXmlRpcValue($value); 0186 $type = $xmlRpcValue->getType(); 0187 } 0188 } 0189 $this->_types[] = $type; 0190 $this->_xmlRpcParams[] = array('value' => $value, 'type' => $type); 0191 } 0192 0193 /** 0194 * Set the parameters array 0195 * 0196 * If called with a single, array value, that array is used to set the 0197 * parameters stack. If called with multiple values or a single non-array 0198 * value, the arguments are used to set the parameters stack. 0199 * 0200 * Best is to call with array of the format, in order to allow type hinting 0201 * when creating the XMLRPC values for each parameter: 0202 * <code> 0203 * $array = array( 0204 * array( 0205 * 'value' => $value, 0206 * 'type' => $type 0207 * )[, ... ] 0208 * ); 0209 * </code> 0210 * 0211 * @access public 0212 * @return void 0213 */ 0214 public function setParams() 0215 { 0216 $argc = func_num_args(); 0217 $argv = func_get_args(); 0218 if (0 == $argc) { 0219 return; 0220 } 0221 0222 if ((1 == $argc) && is_array($argv[0])) { 0223 $params = array(); 0224 $types = array(); 0225 $wellFormed = true; 0226 foreach ($argv[0] as $arg) { 0227 if (!is_array($arg) || !isset($arg['value'])) { 0228 $wellFormed = false; 0229 break; 0230 } 0231 $params[] = $arg['value']; 0232 0233 if (!isset($arg['type'])) { 0234 $xmlRpcValue = Zend_XmlRpc_Value::getXmlRpcValue($arg['value']); 0235 $arg['type'] = $xmlRpcValue->getType(); 0236 } 0237 $types[] = $arg['type']; 0238 } 0239 if ($wellFormed) { 0240 $this->_xmlRpcParams = $argv[0]; 0241 $this->_params = $params; 0242 $this->_types = $types; 0243 } else { 0244 $this->_params = $argv[0]; 0245 $this->_types = array(); 0246 $xmlRpcParams = array(); 0247 foreach ($argv[0] as $arg) { 0248 if ($arg instanceof Zend_XmlRpc_Value) { 0249 $type = $arg->getType(); 0250 } else { 0251 $xmlRpcValue = Zend_XmlRpc_Value::getXmlRpcValue($arg); 0252 $type = $xmlRpcValue->getType(); 0253 } 0254 $xmlRpcParams[] = array('value' => $arg, 'type' => $type); 0255 $this->_types[] = $type; 0256 } 0257 $this->_xmlRpcParams = $xmlRpcParams; 0258 } 0259 return; 0260 } 0261 0262 $this->_params = $argv; 0263 $this->_types = array(); 0264 $xmlRpcParams = array(); 0265 foreach ($argv as $arg) { 0266 if ($arg instanceof Zend_XmlRpc_Value) { 0267 $type = $arg->getType(); 0268 } else { 0269 $xmlRpcValue = Zend_XmlRpc_Value::getXmlRpcValue($arg); 0270 $type = $xmlRpcValue->getType(); 0271 } 0272 $xmlRpcParams[] = array('value' => $arg, 'type' => $type); 0273 $this->_types[] = $type; 0274 } 0275 $this->_xmlRpcParams = $xmlRpcParams; 0276 } 0277 0278 /** 0279 * Retrieve the array of parameters 0280 * 0281 * @return array 0282 */ 0283 public function getParams() 0284 { 0285 return $this->_params; 0286 } 0287 0288 /** 0289 * Return parameter types 0290 * 0291 * @return array 0292 */ 0293 public function getTypes() 0294 { 0295 return $this->_types; 0296 } 0297 0298 /** 0299 * Load XML and parse into request components 0300 * 0301 * @param string $request 0302 * @return boolean True on success, false if an error occurred. 0303 */ 0304 public function loadXml($request) 0305 { 0306 if (!is_string($request)) { 0307 $this->_fault = new Zend_XmlRpc_Fault(635); 0308 $this->_fault->setEncoding($this->getEncoding()); 0309 return false; 0310 } 0311 0312 try { 0313 $xml = Zend_Xml_Security::scan($request); 0314 } catch (Zend_Xml_Exception $e) { 0315 // Not valid XML 0316 $this->_fault = new Zend_XmlRpc_Fault(631); 0317 $this->_fault->setEncoding($this->getEncoding()); 0318 return false; 0319 } 0320 0321 // Check for method name 0322 if (empty($xml->methodName)) { 0323 // Missing method name 0324 $this->_fault = new Zend_XmlRpc_Fault(632); 0325 $this->_fault->setEncoding($this->getEncoding()); 0326 return false; 0327 } 0328 0329 $this->_method = (string) $xml->methodName; 0330 0331 // Check for parameters 0332 if (!empty($xml->params)) { 0333 $types = array(); 0334 $argv = array(); 0335 foreach ($xml->params->children() as $param) { 0336 if (!isset($param->value)) { 0337 $this->_fault = new Zend_XmlRpc_Fault(633); 0338 $this->_fault->setEncoding($this->getEncoding()); 0339 return false; 0340 } 0341 0342 try { 0343 $param = Zend_XmlRpc_Value::getXmlRpcValue($param->value, Zend_XmlRpc_Value::XML_STRING); 0344 $types[] = $param->getType(); 0345 $argv[] = $param->getValue(); 0346 } catch (Exception $e) { 0347 $this->_fault = new Zend_XmlRpc_Fault(636); 0348 $this->_fault->setEncoding($this->getEncoding()); 0349 return false; 0350 } 0351 } 0352 0353 $this->_types = $types; 0354 $this->_params = $argv; 0355 } 0356 0357 $this->_xml = $request; 0358 0359 return true; 0360 } 0361 0362 /** 0363 * Does the current request contain errors and should it return a fault 0364 * response? 0365 * 0366 * @return boolean 0367 */ 0368 public function isFault() 0369 { 0370 return $this->_fault instanceof Zend_XmlRpc_Fault; 0371 } 0372 0373 /** 0374 * Retrieve the fault response, if any 0375 * 0376 * @return null|Zend_XmlRpc_Fault 0377 */ 0378 public function getFault() 0379 { 0380 return $this->_fault; 0381 } 0382 0383 /** 0384 * Retrieve method parameters as XMLRPC values 0385 * 0386 * @return array 0387 */ 0388 protected function _getXmlRpcParams() 0389 { 0390 $params = array(); 0391 if (is_array($this->_xmlRpcParams)) { 0392 foreach ($this->_xmlRpcParams as $param) { 0393 $value = $param['value']; 0394 $type = isset($param['type']) ? $param['type'] : Zend_XmlRpc_Value::AUTO_DETECT_TYPE; 0395 0396 if (!$value instanceof Zend_XmlRpc_Value) { 0397 $value = Zend_XmlRpc_Value::getXmlRpcValue($value, $type); 0398 } 0399 $params[] = $value; 0400 } 0401 } 0402 0403 return $params; 0404 } 0405 0406 /** 0407 * Create XML request 0408 * 0409 * @return string 0410 */ 0411 public function saveXml() 0412 { 0413 $args = $this->_getXmlRpcParams(); 0414 $method = $this->getMethod(); 0415 0416 $generator = Zend_XmlRpc_Value::getGenerator(); 0417 $generator->openElement('methodCall') 0418 ->openElement('methodName', $method) 0419 ->closeElement('methodName'); 0420 0421 if (is_array($args) && count($args)) { 0422 $generator->openElement('params'); 0423 0424 foreach ($args as $arg) { 0425 $generator->openElement('param'); 0426 $arg->generateXml(); 0427 $generator->closeElement('param'); 0428 } 0429 $generator->closeElement('params'); 0430 } 0431 $generator->closeElement('methodCall'); 0432 0433 return $generator->flush(); 0434 } 0435 0436 /** 0437 * Return XML request 0438 * 0439 * @return string 0440 */ 0441 public function __toString() 0442 { 0443 return $this->saveXML(); 0444 } 0445 }