예제 #1
0
 /**
  * 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);
 }
예제 #2
0
 /**
  * Retrieve method parameters as XMLRPC values
  *
  * @return array
  */
 protected function _getXmlRpcParams()
 {
     $params = array();
     if (is_array($this->_xmlRpcParams)) {
         foreach ($this->_xmlRpcParams as $param) {
             $value = $param['value'];
             $type = isset($param['type']) ? $param['type'] : Polycast_XmlRpc_Value::AUTO_DETECT_TYPE;
             if (!$value instanceof Polycast_XmlRpc_Value) {
                 $value = Polycast_XmlRpc_Value::getXmlRpcValue($value, $type);
             }
             $params[] = $value;
         }
     }
     return $params;
 }
예제 #3
0
 /**
  * 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();
 }
예제 #4
0
 /**
  * Load a response from an XML response
  *
  * Attempts to load a response from an XMLRPC response, autodetecting if it
  * is a fault response.
  *
  * @param string $response
  * @return boolean True if a valid XMLRPC response, false if a fault
  * response or invalid input
  */
 public function loadXml($response)
 {
     if (!is_string($response)) {
         $this->_fault = new Polycast_XmlRpc_Fault(650);
         $this->_fault->setEncoding($this->getEncoding());
         return false;
     }
     try {
         $xml = @new SimpleXMLElement($response);
     } catch (Exception $e) {
         // Not valid XML
         $this->_fault = new Polycast_XmlRpc_Fault(651);
         $this->_fault->setEncoding($this->getEncoding());
         return false;
     }
     if (!empty($xml->fault)) {
         // fault response
         $this->_fault = new Polycast_XmlRpc_Fault();
         $this->_fault->setEncoding($this->getEncoding());
         $this->_fault->loadXml($response);
         return false;
     }
     if (empty($xml->params)) {
         // Invalid response
         $this->_fault = new Polycast_XmlRpc_Fault(652);
         $this->_fault->setEncoding($this->getEncoding());
         return false;
     }
     try {
         if (!isset($xml->params) || !isset($xml->params->param) || !isset($xml->params->param->value)) {
             throw new Polycast_XmlRpc_Value_Exception('Missing XML-RPC value in XML');
         }
         $valueXml = $xml->params->param->value->asXML();
         $valueXml = preg_replace('/<\\?xml version=.*?\\?>/i', '', $valueXml);
         $value = Polycast_XmlRpc_Value::getXmlRpcValue(trim($valueXml), Polycast_XmlRpc_Value::XML_STRING);
     } catch (Polycast_XmlRpc_Value_Exception $e) {
         $this->_fault = new Polycast_XmlRpc_Fault(653);
         $this->_fault->setEncoding($this->getEncoding());
         return false;
     }
     $this->setReturnValue($value->getValue());
     return true;
 }
예제 #5
0
 /**
  * Load an XMLRPC fault from XML
  *
  * @param string $fault
  * @return boolean Returns true if successfully loaded fault response, false
  * if response was not a fault response
  * @throws Polycast_XmlRpc_Exception if no or faulty XML provided, or if fault
  * response does not contain either code or message
  */
 public function loadXml($fault)
 {
     if (!is_string($fault)) {
         require_once 'Polycast/XmlRpc/Exception.php';
         throw new Polycast_XmlRpc_Exception('Invalid XML provided to fault');
     }
     try {
         $xml = @new SimpleXMLElement($fault);
     } catch (Exception $e) {
         // Not valid XML
         require_once 'Polycast/XmlRpc/Exception.php';
         throw new Polycast_XmlRpc_Exception('Failed to parse XML fault: ' . $e->getMessage(), 500);
     }
     // Check for fault
     if (!$xml->fault) {
         // Not a fault
         return false;
     }
     if (!$xml->fault->value->struct) {
         // not a proper fault
         require_once 'Polycast/XmlRpc/Exception.php';
         throw new Polycast_XmlRpc_Exception('Invalid fault structure', 500);
     }
     $structXml = $xml->fault->value->asXML();
     $structXml = preg_replace('/<\\?xml version=.*?\\?>/i', '', $structXml);
     $struct = Polycast_XmlRpc_Value::getXmlRpcValue(trim($structXml), Polycast_XmlRpc_Value::XML_STRING);
     $struct = $struct->getValue();
     if (isset($struct['faultCode'])) {
         $code = $struct['faultCode'];
     }
     if (isset($struct['faultString'])) {
         $message = $struct['faultString'];
     }
     if (empty($code) && empty($message)) {
         require_once 'Polycast/XmlRpc/Exception.php';
         throw new Polycast_XmlRpc_Exception('Fault code and string required');
     }
     if (empty($code)) {
         $code = '404';
     }
     if (empty($message)) {
         if (isset($this->_internal[$code])) {
             $message = $this->_internal[$code];
         } else {
             $message = 'Unknown Error';
         }
     }
     $this->setCode($code);
     $this->setMessage($message);
     return true;
 }