[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/webservice/xmlrpc/ -> locallib.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  
  18  /**
  19   * XML-RPC web service implementation classes and methods.
  20   *
  21   * @package    webservice_xmlrpc
  22   * @copyright  2009 Petr Skodak
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  require_once("$CFG->dirroot/webservice/lib.php");
  27  
  28  /**
  29   * XML-RPC service server implementation.
  30   *
  31   * @package    webservice_xmlrpc
  32   * @copyright  2009 Petr Skodak
  33   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  34   * @since Moodle 2.0
  35   */
  36  class webservice_xmlrpc_server extends webservice_base_server {
  37  
  38      /** @var string $response The XML-RPC response string. */
  39      private $response;
  40  
  41      /**
  42       * Contructor
  43       *
  44       * @param string $authmethod authentication method of the web service (WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN, ...)
  45       */
  46      public function __construct($authmethod) {
  47          parent::__construct($authmethod);
  48          $this->wsname = 'xmlrpc';
  49      }
  50  
  51      /**
  52       * This method parses the request input, it needs to get:
  53       *  1/ user authentication - username+password or token
  54       *  2/ function name
  55       *  3/ function parameters
  56       */
  57      protected function parse_request() {
  58          // Retrieve and clean the POST/GET parameters from the parameters specific to the server.
  59          parent::set_web_service_call_settings();
  60  
  61          // Get GET and POST parameters.
  62          $methodvariables = array_merge($_GET, $_POST);
  63  
  64          if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) {
  65              $this->username = isset($methodvariables['wsusername']) ? $methodvariables['wsusername'] : null;
  66              unset($methodvariables['wsusername']);
  67  
  68              $this->password = isset($methodvariables['wspassword']) ? $methodvariables['wspassword'] : null;
  69              unset($methodvariables['wspassword']);
  70          } else {
  71              $this->token = isset($methodvariables['wstoken']) ? $methodvariables['wstoken'] : null;
  72              unset($methodvariables['wstoken']);
  73          }
  74  
  75          // Get the XML-RPC request data.
  76          $rawpostdata = $this->fetch_input_content();
  77          $methodname = null;
  78  
  79          // Decode the request to get the decoded parameters and the name of the method to be called.
  80          $decodedparams = xmlrpc_decode_request($rawpostdata, $methodname, 'UTF-8');
  81          $methodinfo = external_api::external_function_info($methodname);
  82          $methodparams = array_keys($methodinfo->parameters_desc->keys);
  83  
  84          // Add the decoded parameters to the methodvariables array.
  85          if (is_array($decodedparams)) {
  86              foreach ($decodedparams as $index => $param) {
  87                  // See MDL-53962 - XML-RPC requests will usually be sent as an array (as in, one with indicies).
  88                  // We need to use a bit of "magic" to add the correct index back. Zend used to do this for us.
  89                  $methodvariables[$methodparams[$index]] = $param;
  90              }
  91          }
  92  
  93          $this->functionname = $methodname;
  94          $this->parameters = $methodvariables;
  95      }
  96  
  97      /**
  98       * Fetch content from the client.
  99       *
 100       * @return string
 101       */
 102      protected function fetch_input_content() {
 103          return file_get_contents('php://input');
 104      }
 105  
 106      /**
 107       * Prepares the response.
 108       */
 109      protected function prepare_response() {
 110          try {
 111              if (!empty($this->function->returns_desc)) {
 112                  $validatedvalues = external_api::clean_returnvalue($this->function->returns_desc, $this->returns);
 113                  $encodingoptions = array(
 114                      "encoding" => "UTF-8",
 115                      "verbosity" => "no_white_space",
 116                      // See MDL-54868.
 117                      "escaping" => ["markup"]
 118                  );
 119                  // We can now convert the response to the requested XML-RPC format.
 120                  $this->response = xmlrpc_encode_request(null, $validatedvalues, $encodingoptions);
 121              }
 122          } catch (invalid_response_exception $ex) {
 123              $this->response = $this->generate_error($ex);
 124          }
 125      }
 126  
 127      /**
 128       * Send the result of function call to the WS client.
 129       */
 130      protected function send_response() {
 131          $this->prepare_response();
 132          $this->send_headers();
 133          echo $this->response;
 134      }
 135  
 136      /**
 137       * Send the error information to the WS client.
 138       *
 139       * @param Exception $ex
 140       */
 141      protected function send_error($ex = null) {
 142          $this->send_headers();
 143          echo $this->generate_error($ex);
 144      }
 145  
 146      /**
 147       * Sends the headers for the XML-RPC response.
 148       */
 149      protected function send_headers() {
 150          // Standard headers.
 151          header('HTTP/1.1 200 OK');
 152          header('Connection: close');
 153          header('Content-Length: ' . strlen($this->response));
 154          header('Content-Type: text/xml; charset=utf-8');
 155          header('Date: ' . gmdate('D, d M Y H:i:s', 0) . ' GMT');
 156          header('Server: Moodle XML-RPC Server/1.0');
 157          // Other headers.
 158          header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=0');
 159          header('Expires: '. gmdate('D, d M Y H:i:s', 0) .' GMT');
 160          header('Pragma: no-cache');
 161          header('Accept-Ranges: none');
 162          // Allow cross-origin requests only for Web Services.
 163          // This allow to receive requests done by Web Workers or webapps in different domains.
 164          header('Access-Control-Allow-Origin: *');
 165      }
 166  
 167      /**
 168       * Generate the XML-RPC fault response.
 169       *
 170       * @param Exception $ex The exception.
 171       * @param int $faultcode The faultCode to be included in the fault response
 172       * @return string The XML-RPC fault response xml containing the faultCode and faultString.
 173       */
 174      protected function generate_error(Exception $ex, $faultcode = 404) {
 175          $error = $ex->getMessage();
 176  
 177          if (!empty($ex->errorcode)) {
 178              // The faultCode must be an int, so we obtain a hash of the errorcode then get an integer value of the hash.
 179              $faultcode = base_convert(md5($ex->errorcode), 16, 10);
 180  
 181              // We strip the $code to 8 digits (and hope for no error code collisions).
 182              // Collisions should be pretty rare, and if needed the client can retrieve
 183              // the accurate errorcode from the last | in the exception message.
 184              $faultcode = substr($faultcode, 0, 8);
 185  
 186              // Add the debuginfo to the exception message if debuginfo must be returned.
 187              if (debugging() and isset($ex->debuginfo)) {
 188                  $error .= ' | DEBUG INFO: ' . $ex->debuginfo . ' | ERRORCODE: ' . $ex->errorcode;
 189              } else {
 190                  $error .= ' | ERRORCODE: ' . $ex->errorcode;
 191              }
 192          }
 193  
 194          $fault = array(
 195              'faultCode' => (int) $faultcode,
 196              'faultString' => $error
 197          );
 198  
 199          $encodingoptions = array(
 200              "encoding" => "UTF-8",
 201              "verbosity" => "no_white_space",
 202              // See MDL-54868.
 203              "escaping" => ["markup"]
 204          );
 205  
 206          return xmlrpc_encode_request(null, $fault, $encodingoptions);
 207      }
 208  }
 209  
 210  /**
 211   * XML-RPC test client class
 212   *
 213   * @package    webservice_xmlrpc
 214   * @copyright  2009 Petr Skodak
 215   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 216   * @since Moodle 2.0
 217   */
 218  class webservice_xmlrpc_test_client implements webservice_test_client_interface {
 219      /**
 220       * Execute test client WS request
 221       * @param string $serverurl server url (including token parameter or username/password parameters)
 222       * @param string $function function name
 223       * @param array $params parameters of the called function
 224       * @return mixed
 225       */
 226      public function simpletest($serverurl, $function, $params) {
 227          global $CFG;
 228  
 229          $url = new moodle_url($serverurl);
 230          $token = $url->get_param('wstoken');
 231          require_once($CFG->dirroot . '/webservice/xmlrpc/lib.php');
 232          $client = new webservice_xmlrpc_client($serverurl, $token);
 233          return $client->call($function, $params);
 234      }
 235  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1