Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.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  /**
  18   * A curl wrapper for bbb.
  19   *
  20   * @package   mod_bigbluebuttonbn
  21   * @copyright 2021 Andrew Lyons <andrew@nicols.co.uk>
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace mod_bigbluebuttonbn\local\proxy;
  26  
  27  use SimpleXMLElement;
  28  
  29  defined('MOODLE_INTERNAL') || die;
  30  global $CFG;
  31  require_once("{$CFG->libdir}/filelib.php");
  32  
  33  /**
  34   * A curl wrapper for bbb.
  35   *
  36   * @package   mod_bigbluebuttonbn
  37   * @copyright 2021 Andrew Lyons <andrew@nicols.co.uk>
  38   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   */
  40  class curl extends \curl {
  41      /** @var string */
  42      protected $contenttype;
  43  
  44      /**
  45       * Constructor for the class.
  46       */
  47      public function __construct() {
  48          $settings = [];
  49          if (debugging()) {
  50              $settings = ['ignoresecurity' => true];
  51          }
  52          parent::__construct($settings);
  53  
  54          $this->setopt(['SSL_VERIFYPEER' => true]);
  55          $this->set_content_type('text/xml');
  56      }
  57  
  58      /**
  59       * Fetch the content type.
  60       */
  61      public function get_content_type(): string {
  62          return $this->contenttype;
  63      }
  64  
  65      /**
  66       * Set the desired current content type.
  67       *
  68       * @param string $type
  69       * @return self
  70       */
  71      public function set_content_type(string $type): self {
  72          $this->contenttype = $type;
  73  
  74          return $this;
  75      }
  76  
  77      /**
  78       * HTTP POST method
  79       *
  80       * @param string $url
  81       * @param array|string $params
  82       * @param array $options
  83       * @return null|SimpleXMLElement Null on error
  84       */
  85      public function post($url, $params = '', $options = []) {
  86          if (!is_string($params)) {
  87              debugging('Only string parameters are supported', DEBUG_DEVELOPER);
  88              $params = '';
  89          }
  90          $options = array_merge($options, [
  91              'CURLOPT_HTTPHEADER' => [
  92                  'Content-Type: ' . $this->get_content_type(),
  93                  'Content-Length: ' . strlen($params),
  94                  'Content-Language: en-US',
  95              ]
  96          ]);
  97  
  98          return $this->handle_response(parent::post($url, $params, $options));
  99      }
 100  
 101      /**
 102       * Fetch the specified URL via a HEAD request.
 103       *
 104       * @param string $url
 105       * @param array $options
 106       */
 107      public function head($url, $options = []) {
 108          $options['followlocation'] = true;
 109          $options['timeout'] = 1;
 110  
 111          parent::head($url, $options);
 112  
 113          return $this->get_info();
 114      }
 115  
 116      /**
 117       * Fetch the specified URL via a GET request.
 118       *
 119       * @param string $url
 120       * @param string $params
 121       * @param array $options
 122       */
 123      public function get($url, $params = [], $options = []) {
 124          return $this->handle_response(parent::get($url, $params, $options));
 125      }
 126  
 127      /**
 128       * Handle the response.
 129       *
 130       * @param mixed $response
 131       * @return null|SimpleXMLElement Null on error
 132       */
 133      protected function handle_response($response): ?SimpleXMLElement {
 134          if (!$response) {
 135              debugging('No response returned for call', DEBUG_DEVELOPER);
 136              return null;
 137          }
 138  
 139          $previous = libxml_use_internal_errors(true);
 140          try {
 141              $xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
 142          } catch (Exception $e) {
 143              libxml_use_internal_errors($previous);
 144              debugging('Caught exception: ' . $e->getMessage(), DEBUG_DEVELOPER);
 145              return null;
 146          }
 147  
 148          if ($xml instanceof SimpleXMLElement) {
 149              return $xml;
 150          }
 151  
 152          $debugabstract = html_to_text($response);
 153          $debugabstract = substr($debugabstract, 0, 1024); // Limit to small amount of info so we do not overload logs.
 154          debugging('Issue retrieving information from the server: ' . $debugabstract, DEBUG_DEVELOPER);
 155          return null;
 156      }
 157  }