/** * __call Catchall. This method catches remote method calls and provides for remote forwarding. * * If the parameters are native types, this method will use XML_RPC_Value::createFromNative to * convert it into an XML-RPC type. Whenever a parameter is already an instance of XML_RPC_Value * it will be used as provided. It follows that, in situations when XML_RPC_Value::createFromNative * proves inacurate -- as when encoding DateTime values -- you should present an instance of * XML_RPC_Value in lieu of the native parameter. * * @param string Method name * @param array Parameters * @return mixed The call result, already decoded into native types */ public function __call($methodName, $parameters) { $request = new XML_RPC2_Backend_Php_Request($this->prefix . $methodName, $this->encoding); $request->setParameters($parameters); $request = $request->encode(); $uri = $this->uri; $options = array('encoding' => $this->encoding, 'proxy' => $this->proxy, 'sslverify' => $this->sslverify, 'connectionTimeout' => $this->connectionTimeout); if (isset($this->httpRequest)) { $options['httpRequest'] = $this->httpRequest; } $httpRequest = new XML_RPC2_Util_HTTPRequest($uri, $options); $httpRequest->setPostData($request); $httpRequest->sendRequest(); $body = $httpRequest->getBody(); if ($this->debug) { XML_RPC2_ClientHelper::printPreParseDebugInfo($request, $body); } try { $document = new SimpleXMLElement($body); $result = XML_RPC2_Backend_Php_Response::decode($document); } catch (XML_RPC2_Exception $e) { if ($this->debug) { if (get_class($e) == 'XML_RPC2_FaultException') { print "XML_RPC2_FaultException #" . $e->getFaultCode() . " : " . $e->getMessage(); } else { print get_class($e) . " : " . $e->getMessage(); } } throw $e; } if ($this->debug) { XML_RPC2_ClientHelper::printPostRequestDebugInformation($result); } return $result; }
/** * Decode a request from XML and construct a request object with the createFromDecoded values * * @param SimpleXMLElement The encoded XML-RPC request. * @return XML_RPC2_Backend_Php_Request The xml-rpc request, represented as an object instance */ public static function createFromDecode($simpleXML) { $methodName = (string) $simpleXML->methodName; $params = array(); foreach ($simpleXML->params->param as $param) { foreach ($param->value as $value) { $params[] = XML_RPC2_Backend_Php_Value::createFromDecode($value)->getNativeValue(); } } $result = new XML_RPC2_Backend_Php_Request($methodName); $result->setParameters($params); return $result; }
/** * Get the XML response of the XMLRPC server * * @return string XML response */ public function getResponse() { try { set_error_handler(array('XML_RPC2_Backend_Php_Server', 'errorToException')); $request = @simplexml_load_string($GLOBALS['HTTP_RAW_POST_DATA']); // TODO : do not use exception but a XMLRPC error ! if (!is_object($request)) { throw new XML_RPC2_FaultException('Unable to parse request XML', 0); } $request = XML_RPC2_Backend_Php_Request::createFromDecode($request); $methodName = $request->getMethodName(); $arguments = $request->getParameters(); if ($this->signatureChecking) { $method = $this->callHandler->getMethod($methodName); if (!$method) { // see http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php for standard error codes return XML_RPC2_Backend_Php_Response::encodeFault(-32601, 'server error. requested method not found'); } if (!$method->matchesSignature($methodName, $arguments)) { return XML_RPC2_Backend_Php_Response::encodeFault(-32602, 'server error. invalid method parameters'); } } restore_error_handler(); return XML_RPC2_Backend_Php_Response::encode(call_user_func_array(array($this->callHandler, $methodName), $arguments)); } catch (XML_RPC2_FaultException $e) { return XML_RPC2_Backend_Php_Response::encodeFault($e->getFaultCode(), $e->getMessage()); } catch (Exception $e) { return XML_RPC2_Backend_Php_Response::encodeFault(1, 'Unhandled ' . get_class($e) . ' exception:' . $e->getMessage()); } }