Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.
   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  namespace communication_matrix\local;
  18  
  19  use communication_matrix\matrix_client;
  20  use GuzzleHttp\Psr7\Request;
  21  use OutOfRangeException;
  22  
  23  /**
  24   * A command to be sent to the Matrix server.
  25   *
  26   * This class is a wrapper around the PSR-7 Request Interface implementation provided by Guzzle.
  27   *
  28   * It takes a set of common parameters and configurations and turns them into a Request that can be called against a live server.
  29   *
  30   * @package    communication_matrix
  31   * @copyright  Andrew Nicols <andrew@nicols.co.uk>
  32   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  class command extends Request {
  35      /** @var array $command The raw command data */
  36      /** @var array|null $params The parameters passed into the command */
  37      /** @var bool $sendasjson Whether to send params as JSON */
  38      /** @var bool $requireauthorization Whether authorization is required for this request */
  39      /** @var bool $ignorehttperrors Whether to ignore HTTP Errors */
  40      /** @var array $query Any query parameters to set on the URL */
  41  
  42      /** @var array|null Any parameters not used in the URI which are to be passed to the server via body or query params */
  43      protected array $remainingparams = [];
  44  
  45      /**
  46       * Create a new Command.
  47       *
  48       * @param matrix_client $client The URL for this method
  49       * @param string $method (GET|POST|PUT|DELETE)
  50       * @param string $endpoint The URL
  51       * @param array $params Any parameters to pass
  52       * @param array $query Any query parameters to set on the URL
  53       * @param bool $ignorehttperrors Whether to ignore HTTP Errors
  54       * @param bool $requireauthorization Whether authorization is required for this request
  55       * @param bool $sendasjson Whether to send params as JSON
  56       */
  57      public function __construct(
  58          protected matrix_client $client,
  59          string $method,
  60          string $endpoint,
  61          protected array $params = [],
  62          protected array $query = [],
  63          protected bool $ignorehttperrors = false,
  64          protected bool $requireauthorization = true,
  65          protected bool $sendasjson = true,
  66      ) {
  67          foreach ($params as $name => $value) {
  68              if ($name[0] === ':') {
  69                  if (preg_match("/{$name}\\b/", $endpoint) !== 1) {
  70                      throw new OutOfRangeException("Parameter not found in URL '{$name}'");
  71                  }
  72  
  73                  $endpoint = preg_replace("/{$name}\\b/", urlencode($value), $endpoint);
  74                  unset($params[$name]);
  75              }
  76          }
  77  
  78          // Store the modified params.
  79          $this->remainingparams = $params;
  80  
  81          if (str_contains($endpoint, '/:')) {
  82              throw new OutOfRangeException("URL contains untranslated parameters '{$endpoint}'");
  83          }
  84  
  85          // Process the required headers.
  86          $headers = [
  87              'Content-Type' => 'application/json',
  88          ];
  89  
  90          if ($this->require_authorization()) {
  91              $headers['Authorization'] = 'Bearer ' . $this->client->get_token();
  92          }
  93  
  94          // Construct the final request.
  95          parent::__construct(
  96              $method,
  97              $this->get_url($endpoint),
  98              $headers,
  99          );
 100      }
 101  
 102      /**
 103       * Get the URL of the endpoint on the server.
 104       *
 105       * @param string $endpoint
 106       * @return string
 107       */
 108      protected function get_url(string $endpoint): string {
 109          return sprintf(
 110              "%s/%s",
 111              $this->client->get_server_url(),
 112              $endpoint,
 113          );
 114      }
 115  
 116      /**
 117       * Get all parameters, including those set in the URL.
 118       *
 119       * @return array
 120       */
 121      public function get_all_params(): array {
 122          return $this->params;
 123      }
 124  
 125      /**
 126       * Get the parameters provided to the command which are not used in the URL.
 127       *
 128       * These are typically passed to the server as query or body parameters instead.
 129       *
 130       * @return array
 131       */
 132      public function get_remaining_params(): array {
 133          return $this->remainingparams;
 134      }
 135  
 136      /**
 137       * Get the Guzzle options to pass into the request.
 138       *
 139       * @return array
 140       */
 141      public function get_options(): array {
 142          $options = [];
 143  
 144          if (count($this->query)) {
 145              $options['query'] = $this->query;
 146          }
 147  
 148          if ($this->should_send_params_as_json()) {
 149              $options['json'] = $this->get_remaining_params();
 150          }
 151  
 152          if ($this->should_ignore_http_errors()) {
 153              $options['http_errors'] = false;
 154          }
 155  
 156          return $options;
 157      }
 158  
 159      /**
 160       * Whether authorization is required.
 161       *
 162       * Based on the 'authorization' attribute set in a raw command.
 163       *
 164       * @return bool
 165       */
 166      public function require_authorization(): bool {
 167          return $this->requireauthorization;
 168      }
 169  
 170      /**
 171       * Whether to ignore http errors on the response.
 172       *
 173       * Based on the 'ignore_http_errors' attribute set in a raw command.
 174       *
 175       * @return bool
 176       */
 177      public function should_ignore_http_errors(): bool {
 178          return $this->ignorehttperrors;
 179      }
 180  
 181      /**
 182       * Whether to send remaining parameters as JSON.
 183       *
 184       * @return bool
 185       */
 186      public function should_send_params_as_json(): bool {
 187          return $this->sendasjson;
 188      }
 189  }