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.

Differences Between: [Versions 401 and 402] [Versions 401 and 403]

   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   * Provides validation classes used by the imscc converters
  18   *
  19   * @package    backup-convert
  20   * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
  21   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22   */
  23  
  24  final class error_messages {
  25      /**
  26       *
  27       * @static error_messages
  28       */
  29      private static $instance = null;
  30      private function __construct(){}
  31      private function __clone(){}
  32      /**
  33       * @return error_messages
  34       */
  35      public static function instance() {
  36          if (empty(self::$instance)) {
  37              $c = __CLASS__;
  38              self::$instance = new $c();
  39          }
  40          return self::$instance;
  41      }
  42  
  43      /**
  44       * @var array
  45       */
  46      private $items = array();
  47  
  48      /**
  49       * @param string $msg
  50       */
  51      public function add($msg) {
  52          if (!empty($msg)) {
  53              $this->items[] = $msg;
  54          }
  55      }
  56  
  57      /**
  58       * @return array
  59       */
  60      public function errors() {
  61          $this->items;
  62      }
  63  
  64      /**
  65       * Empties the error content
  66       */
  67      public function reset() {
  68          $this->items = array();
  69      }
  70  
  71      /**
  72       * @param boolean $web
  73       * @return string
  74       */
  75      public function to_string($web = false) {
  76          $result = '';
  77          if ($web) {
  78              $result .= '<ol>'.PHP_EOL;
  79          }
  80          foreach ($this->items as $error) {
  81              if ($web) {
  82                  $result .= '<li>';
  83              }
  84  
  85              $result .= $error.PHP_EOL;
  86  
  87              if ($web) {
  88                  $result .= '</li>'.PHP_EOL;
  89              }
  90          }
  91          if ($web) {
  92              $result .= '</ol>'.PHP_EOL;
  93          }
  94          return $result;
  95      }
  96  
  97      /**
  98       * Casting to string method
  99       * @return string
 100       */
 101      public function __toString() {
 102          return $this->to_string(false);
 103      }
 104  
 105  }
 106  
 107  final class libxml_errors_mgr {
 108      /**
 109       * @var boolean
 110       */
 111      private $previous = false;
 112  
 113      /**
 114       * @param boolean $reset
 115       */
 116      public function __construct($reset=false){
 117          if ($reset) {
 118              error_messages::instance()->reset();
 119          }
 120          $this->previous = libxml_use_internal_errors(true);
 121          libxml_clear_errors();
 122      }
 123  
 124      private function collect_errors ($filename=''){
 125          $errors = libxml_get_errors();
 126          static $error_types = array(
 127          LIBXML_ERR_ERROR => 'Error'
 128          ,LIBXML_ERR_FATAL => 'Fatal Error'
 129          ,LIBXML_ERR_WARNING => 'Warning'
 130          );
 131          $result = array();
 132          foreach($errors as $error){
 133              $add = '';
 134              if (!empty($filename)) {
 135                  $add = " in {$filename}";
 136              } elseif (!empty($error->file)) {
 137                  $add = " in {$error->file}";
 138              }
 139              $line = '';
 140              if (!empty($error->line)) {
 141                  $line = " at line {$error->line}";
 142              }
 143              $err = "{$error_types[$error->level]}{$add}: {$error->message}{$line}";
 144              error_messages::instance()->add($err);
 145          }
 146          libxml_clear_errors();
 147          return $result;
 148      }
 149  
 150      public function __destruct(){
 151          $this->collect_errors();
 152          if (!$this->previous) {
 153              libxml_use_internal_errors($this->previous);
 154          }
 155      }
 156  
 157      public function collect() {
 158          $this->collect_errors();
 159      }
 160  }
 161  
 162  
 163  function validate_xml($xml, $schema){
 164      $result = false;
 165      $manifest_file = realpath($xml);
 166      $schema_file = realpath($schema);
 167      if (empty($manifest_file) || empty($schema_file)) {
 168          return false;
 169      }
 170  
 171      $xml_error = new libxml_errors_mgr();
 172      $manifest = new DOMDocument();
 173      $doc->validateOnParse = false;
 174      $result = $manifest->load($manifest_file, LIBXML_NONET) &&
 175                $manifest->schemaValidate($schema_file);
 176  
 177      return $result;
 178  }
 179  
 180  class cc_validate_type {
 181      const manifest_validator1   = 'cclibxml2validator.xsd'                       ;
 182      const assesment_validator1  = '/domainProfile_4/ims_qtiasiv1p2_localised.xsd';
 183      const discussion_validator1 = '/domainProfile_6/imsdt_v1p0_localised.xsd'    ;
 184      const weblink_validator1    = '/domainProfile_5/imswl_v1p0_localised.xsd'    ;
 185  
 186      const manifest_validator11   = 'cc11libxml2validator.xsd'    ;
 187      const blti_validator11       = 'imslticc_v1p0p1.xsd'         ;
 188      const assesment_validator11  = 'ccv1p1_qtiasiv1p2p1_v1p0.xsd';
 189      const discussion_validator11 = 'ccv1p1_imsdt_v1p1.xsd'       ;
 190      const weblink_validator11    = 'ccv1p1_imswl_v1p1.xsd'       ;
 191  
 192      /**
 193       * @var string
 194       */
 195      protected $type = null;
 196  
 197      /**
 198       * @var string
 199       */
 200      protected $location = null;
 201  
 202      public function __construct($type, $location){
 203          $this->type = $type;
 204          $this->location = $location;
 205      }
 206  
 207      /**
 208       * Validates the item
 209       * @param  string $element - File path for the xml
 210       * @return boolean
 211       */
 212      public function validate($element) {
 213          $this->last_error = null;
 214          $celement   = realpath($element);
 215          $cvalidator = realpath($this->location.DIRECTORY_SEPARATOR.$this->type);
 216          $result = (empty($celement) || empty($cvalidator));
 217          if (!$result) {
 218              $xml_error = new libxml_errors_mgr();
 219              $doc = new DOMDocument();
 220              $doc->validateOnParse = false;
 221              $result = $doc->load($celement, LIBXML_NONET) &&
 222                        $doc->schemaValidate($cvalidator);
 223          }
 224          return $result;
 225      }
 226  
 227  }
 228  
 229  class manifest_validator extends cc_validate_type {
 230      public function __construct($location){
 231          parent::__construct(self::manifest_validator11, $location);
 232      }
 233  }
 234  
 235  class manifest10_validator extends cc_validate_type {
 236      public function __construct($location){
 237          parent::__construct(self::manifest_validator1, $location);
 238      }
 239  }
 240  
 241  class blti_validator extends cc_validate_type {
 242      public function __construct($location){
 243          parent::__construct(self::blti_validator11, $location);
 244      }
 245  }
 246  
 247  class assesment_validator extends cc_validate_type {
 248      public function __construct($location){
 249          parent::__construct(self::assesment_validator11, $location);
 250      }
 251  }
 252  
 253  class discussion_validator extends cc_validate_type {
 254      public function __construct($location){
 255          parent::__construct(self::discussion_validator11, $location);
 256      }
 257  }
 258  
 259  class weblink_validator extends cc_validate_type {
 260      public function __construct($location){
 261          parent::__construct(self::weblink_validator11, $location);
 262      }
 263  }
 264