/** * Handle an xmlrpc call (actual work) * * @param Polycast_XmlRpc_Request $request * @return Polycast_XmlRpc_Response * @throws Zend_XmlRpcServer_Exception|Exception * Zend_XmlRpcServer_Exceptions are thrown for internal errors; otherwise, * any other exception may be thrown by the callback */ protected function _handle(Polycast_XmlRpc_Request $request) { $method = $request->getMethod(); // Check for valid method if (!$this->_table->hasMethod($method)) { require_once 'Polycast/XmlRpc/Server/Exception.php'; throw new Polycast_XmlRpc_Server_Exception('Method "' . $method . '" does not exist', 620); } $info = $this->_table->getMethod($method); $params = $request->getParams(); $argv = $info->getInvokeArguments(); if (0 < count($argv) and $this->sendArgumentsToAllMethods()) { $params = array_merge($params, $argv); } // Check calling parameters against signatures $matched = false; $sigCalled = $request->getTypes(); $sigLength = count($sigCalled); $paramsLen = count($params); if ($sigLength < $paramsLen) { for ($i = $sigLength; $i < $paramsLen; ++$i) { $xmlRpcValue = Polycast_XmlRpc_Value::getXmlRpcValue($params[$i]); $sigCalled[] = $xmlRpcValue->getType(); } } $signatures = $info->getPrototypes(); foreach ($signatures as $signature) { $sigParams = $signature->getParameters(); if ($sigCalled === $sigParams) { $matched = true; break; } } if (!$matched) { require_once 'Polycast/XmlRpc/Server/Exception.php'; throw new Polycast_XmlRpc_Server_Exception('Calling parameters do not match signature', 623); } $return = $this->_dispatch($info, $params); $responseClass = $this->getResponseClass(); return new $responseClass($return); }
/** * Get XML generator instance * * @return Polycast_XmlRpc_Generator_Abstract */ public static function getGenerator() { if (!self::$_generator) { if (extension_loaded('xmlwriter')) { require_once 'Polycast/XmlRpc/Generator/XmlWriter.php'; self::$_generator = new Polycast_XmlRpc_Generator_XmlWriter(); } else { require_once 'Polycast/XmlRpc/Generator/DomDocument.php'; self::$_generator = new Polycast_XmlRpc_Generator_DomDocument(); } } return self::$_generator; }
/** * Create XML request * * @return string */ public function saveXML() { $args = $this->_getXmlRpcParams(); $method = $this->getMethod(); $generator = Polycast_XmlRpc_Value::getGenerator(); $element = new Polycast_XmlRpc_Generator_Element('methodCall', array(new Polycast_XmlRpc_Generator_Element('methodName', array($method)))); if (is_array($args) && count($args)) { $params = new Polycast_XmlRpc_Generator_Element('params'); $element->appendChild($params); foreach ($args as $arg) { /* @var $arg Polycast_XmlRpc_Value */ $params->appendChild(new Polycast_XmlRpc_Generator_Element('param', array($arg))); } } return $generator->generateXml($element); }
/** * Return response as XML * * @return string */ public function saveXML() { $generator = Polycast_XmlRpc_Value::getGenerator(); $element = new Polycast_XmlRpc_Generator_Element('methodResponse', array(new Polycast_XmlRpc_Generator_Element('params', array(new Polycast_XmlRpc_Generator_Element('param', array($this->_getXmlRpcReturn())))))); return $generator->generateXml($element); }
/** * Send an XML-RPC request to the service (for a specific method) * * @param string $method Name of the method we want to call * @param array $params Array of parameters for the method * @return mixed * @throws Polycast_XmlRpc_Client_FaultException */ public function call($method, $params = array()) { if (!$this->skipSystemLookup() && 'system.' != substr($method, 0, 7)) { // Ensure empty array/struct params are cast correctly // If system.* methods are not available, bypass. (ZF-2978) $success = true; try { $signatures = $this->getIntrospector()->getMethodSignature($method); } catch (Polycast_XmlRpc_Exception $e) { $success = false; } if ($success) { $validTypes = array(Polycast_XmlRpc_Value::XMLRPC_TYPE_ARRAY, Polycast_XmlRpc_Value::XMLRPC_TYPE_BASE64, Polycast_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN, Polycast_XmlRpc_Value::XMLRPC_TYPE_DATETIME, Polycast_XmlRpc_Value::XMLRPC_TYPE_DOUBLE, Polycast_XmlRpc_Value::XMLRPC_TYPE_I4, Polycast_XmlRpc_Value::XMLRPC_TYPE_INTEGER, Polycast_XmlRpc_Value::XMLRPC_TYPE_NIL, Polycast_XmlRpc_Value::XMLRPC_TYPE_STRING, Polycast_XmlRpc_Value::XMLRPC_TYPE_STRUCT); $params = (array) $params; foreach ($params as $key => $param) { $type = Polycast_XmlRpc_Value::AUTO_DETECT_TYPE; foreach ($signatures as $signature) { if (!is_array($signature)) { continue; } if (isset($signature['parameters'][$key])) { $type = $signature['parameters'][$key]; $type = in_array($type, $validTypes) ? $type : Polycast_XmlRpc_Value::AUTO_DETECT_TYPE; } } $params[$key] = Polycast_XmlRpc_Value::getXmlRpcValue($param, $type); } } } $request = $this->_createRequest($method, $params); $this->doRequest($request); if ($this->_lastResponse->isFault()) { $fault = $this->_lastResponse->getFault(); /** * Exception thrown when an XML-RPC fault is returned * @see Polycast_XmlRpc_Client_FaultException */ require_once 'Polycast/XmlRpc/Client/FaultException.php'; throw new Polycast_XmlRpc_Client_FaultException($fault->getMessage(), $fault->getCode()); } return $this->_lastResponse->getReturnValue(); }
/** * Serialize fault to XML * * @return string */ public function saveXML() { $generator = Polycast_XmlRpc_Value::getGenerator(); $element = new Polycast_XmlRpc_Generator_Element('methodResponse', array(new Polycast_XmlRpc_Generator_Element('fault', array(new Polycast_XmlRpc_Generator_Element('faultCode', array($this->getCode())), new Polycast_XmlRpc_Generator_Element('faultString', array($this->getMessage())))))); return $generator->generateXml($element); }