/**
  * Raise an xmlrpc server fault
  *
  * Moodle note: the difference with the Zend server is that we throw a plain PHP Exception
  * with the debuginfo integrated to the exception message when DEBUG >= NORMAL
  *
  * @param string|Exception $fault
  * @param int $code
  * @return Zend_XmlRpc_Server_Fault
  */
 public function fault($fault = null, $code = 404)
 {
     //intercept any exceptions with debug info and transform it in Moodle exception
     if ($fault instanceof Exception) {
         //add the debuginfo to the exception message if debuginfo must be returned
         if (debugging() and isset($fault->debuginfo)) {
             $fault = new Exception($fault->getMessage() . ' | DEBUG INFO: ' . $fault->debuginfo, 0);
         }
     }
     return parent::fault($fault, $code);
 }
Example #2
0
 /**
  * fault() test
  */
 public function testFault()
 {
     $fault = $this->_server->fault('This is a fault', 411);
     $this->assertTrue($fault instanceof Zend_XmlRpc_Server_Fault);
     $this->assertEquals(411, $fault->getCode());
     $this->assertEquals('This is a fault', $fault->getMessage());
     $fault = $this->_server->fault(new Zend_XmlRpc_Server_Exception('Exception fault', 511));
     $this->assertTrue($fault instanceof Zend_XmlRpc_Server_Fault);
     $this->assertEquals(511, $fault->getCode());
     $this->assertEquals('Exception fault', $fault->getMessage());
 }
Example #3
0
    /**
     * Multicall - boxcar feature of XML-RPC for calling multiple methods
     * in a single request.
     *
     * Expects a an array of structs representing method calls, each element
     * having the keys:
     * - methodName
     * - params
     *
     * Returns an array of responses, one for each method called, with the value
     * returned by the method. If an error occurs for a given method, returns a
     * struct with a fault response.
     *
     * @see http://www.xmlrpc.com/discuss/msgReader$1208
     * @param  array $methods
     * @return array
     */
    public function multicall($methods)
    {
        $responses = array();
        foreach ($methods as $method) {
            $fault = false;
            if (!is_array($method)) {
                $fault = $this->_server->fault('system.multicall expects each method to be a struct', 601);
            } elseif (!isset($method['methodName'])) {
                $fault = $this->_server->fault('Missing methodName: ' . var_export($methods, 1), 602);
            } elseif (!isset($method['params'])) {
                $fault = $this->_server->fault('Missing params', 603);
            } elseif (!is_array($method['params'])) {
                $fault = $this->_server->fault('Params must be an array', 604);
            } else {
                if ('system.multicall' == $method['methodName']) {
                    // don't allow recursive calls to multicall
                    $fault = $this->_server->fault('Recursive system.multicall forbidden', 605);
                }
            }

            if (!$fault) {
                try {
                    $request = new Zend_XmlRpc_Request();
                    $request->setMethod($method['methodName']);
                    $request->setParams($method['params']);
                    $response = $this->_server->handle($request);
                    if ($response instanceof Zend_XmlRpc_Fault
                        || $response->isFault()
                    ) {
                        $fault = $response;
                    } else {
                        $responses[] = $response->getReturnValue();
                    }
                } catch (Exception $e) {
                    $fault = $this->_server->fault($e);
                }
            }

            if ($fault) {
                $responses[] = array(
                    'faultCode'   => $fault->getCode(),
                    'faultString' => $fault->getMessage()
                );
            }
        }

        return $responses;
    }
Example #4
0
 /**
  * Generate a server fault
  *
  * Note that the arguments are reverse to those of Zend_XmlRpc_Server_Fault.
  *
  * note: the difference with the Zend server is that we throw a Zend_XmlRpc_Server_Fault exception
  * with the debuginfo integrated to the exception message when DEBUG >= NORMAL
  *
  * If an exception is passed as the first argument, its message and code
  * will be used to create the fault object if it has been registered via
  * {@Link registerFaultException()}.
  *
  * @param  string|Exception $fault
  * @param  string $code XMLRPC Fault Codes
  * @return Zend_XmlRpc_Server_Fault
  */
 public function fault($fault = null, $code = 404)
 {
     //run the zend code that clean/create a xmlrpcfault
     $xmlrpcfault = parent::fault($fault, $code);
     //intercept any exceptions and add the errorcode and debuginfo (optional)
     $actor = null;
     $details = null;
     if ($fault instanceof Exception) {
         //add the debuginfo to the exception message if debuginfo must be returned
         if (ws_debugging() and isset($fault->debuginfo)) {
             $details = $fault->debuginfo;
         }
     }
     $fault = new Zend_XmlRpc_Server_Fault($xmlrpcfault);
     $fault->setCode($xmlrpcfault->getCode());
     $fault->setMessage($xmlrpcfault->getMessage() . ' | ERRORCODE: ' . $xmlrpcfault->getCode() . ' | DETAILS: ' . $details);
     return $fault;
 }
Example #5
0
 /**
  * Raise an xmlrpc server fault
  *
  * Moodle note: the difference with the Zend server is that we throw a plain PHP Exception
  * with the debuginfo integrated to the exception message when DEBUG >= NORMAL
  *
  * @param string|Exception $fault
  * @param int $code
  * @return Zend_XmlRpc_Server_Fault
  */
 public function fault($fault = null, $code = 404)
 {
     // Intercept any exceptions with debug info and transform it in Moodle exception.
     if ($fault instanceof Exception) {
         // Code php exception must be a long
         // we obtain a hash of the errorcode, and then to get an integer hash.
         $code = base_convert(md5($fault->errorcode), 16, 10);
         // Code php exception being a long, it has a maximum number of digits.
         // we strip the $code to 8 digits, and hope for no error code collisions.
         // Collisions should be pretty rare, and if needed the client can retrieve
         // the accurate errorcode from the last | in the exception message.
         $code = substr($code, 0, 8);
         // Add the debuginfo to the exception message if debuginfo must be returned.
         if (debugging() and isset($fault->debuginfo)) {
             $fault = new Exception($fault->getMessage() . ' | DEBUG INFO: ' . $fault->debuginfo . ' | ERRORCODE: ' . $fault->errorcode, $code);
         } else {
             $fault = new Exception($fault->getMessage() . ' | ERRORCODE: ' . $fault->errorcode, $code);
         }
     }
     return parent::fault($fault, $code);
 }
 public function testCreatingFaultWithEmptyMessageResultsInUnknownError()
 {
     $fault = $this->_server->fault('', 123);
     $this->assertSame('Unknown Error', $fault->getMessage());
     $this->assertSame(123, $fault->getCode());
 }