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   * Manifest management
  18   *
  19   * @package    backup-convert
  20   * @subpackage cc-library
  21   * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  require_once ('cc_utils.php');
  26  require_once ('xmlbase.php');
  27  require_once ('cc_resources.php');
  28  require_once ('cc_version_base.php');
  29  require_once ('gral_lib/pathutils.php');
  30  
  31  /**
  32   * Manifest Class
  33   *
  34   */
  35  class cc_manifest extends XMLGenericDocument implements cc_i_manifest {
  36      private $ccversion              = null;
  37      private $ccobj                  = null;
  38      private $rootmanifest           = null;
  39      private $activemanifest         = null;
  40      private $parentmanifest         = null;
  41      private $parentparentmanifest   = null;
  42      private $ares                   = array();
  43      private $mainidentifier         = null;
  44  
  45      public function __construct($ccver = cc_version::v1, $activemanifest=null,
  46                          $parentmanifest=null, $parentparentmanifest=null) {
  47  
  48          if (is_int($ccver)) {
  49              $this->ccversion=$ccver;
  50              $classname = "cc_version{$ccver}";
  51              $this->ccobj = new $classname;
  52              parent::__construct('UTF-8', true);
  53          } else if (is_object($ccver) && (get_class($ccver)=='cc_manifest')) {
  54              $this->doc = $ccver->doc;
  55              $this->rootmanifest = $ccver->rootmanifest;
  56              $this->activemanifest = $activemanifest;
  57              $this->parentmanifest = $parentmanifest;
  58              $this->parentparentmanifest = $parentparentmanifest;
  59              $this->ccversion = $ccver->ccversion;
  60              $this->ccobj = $ccver;
  61              $this->register_namespaces_for_xpath();
  62          }
  63      }
  64  
  65      /**
  66       * Register Namespace for use XPATH
  67       *
  68       */
  69      public function register_namespaces_for_xpath() {
  70          $scnam = $this->activemanifest->get_cc_namespaces();
  71          foreach ($scnam as $key => $value) {
  72              $this->registerNS($key, $value);
  73          }
  74      }
  75  
  76      /**
  77       * TODO - implement this method - critical
  78       * Enter description here ...
  79       */
  80      private function fill_manifest() {
  81  
  82      }
  83  
  84      /**
  85       * Add Metadata For Manifest
  86       *
  87       * @param cc_i_metadata_manifest $met
  88       */
  89      public function add_metadata_manifest(cc_i_metadata_manifest $met) {
  90          $metanode = $this->node("//imscc:manifest[@identifier='".
  91                                  $this->activemanifest->manifestID().
  92                                  "']/imscc:metadata");
  93          $nmeta = $this->activemanifest->create_metadata_node($met, $this->doc, $metanode);
  94          $metanode->appendChild($nmeta);
  95      }
  96  
  97  
  98      /**
  99       * Add Metadata For Resource
 100       *
 101       * @param cc_i_metadata_resource $met
 102       * @param string $identifier
 103       */
 104      public function add_metadata_resource(cc_i_metadata_resource $met, $identifier) {
 105          $metanode  = $this->node("//imscc:resource".
 106              "[@identifier='".
 107              $identifier.
 108              "']");
 109          $metanode2 = $this->node("//imscc:resource".
 110              "[@identifier='".
 111              $identifier.
 112              "']/imscc:file");
 113          $nspaces   = $this->activemanifest->get_cc_namespaces();
 114          $dnode     = $this->append_new_element_ns($metanode2, $nspaces['imscc'], 'metadata');
 115          $this->activemanifest->create_metadata_resource_node($met, $this->doc, $dnode);
 116      }
 117  
 118  
 119      /**
 120       * Add Metadata For File
 121       *
 122       * @param cc_i_metadata_file $met
 123       * @param string $identifier
 124       * @param string $filename
 125       */
 126      public function add_metadata_file(cc_i_metadata_file $met, $identifier, $filename) {
 127  
 128          if (empty($met) || empty($identifier) || empty($filename)) {
 129              throw new Exception('Try to add a metadata file with nulls values given!');
 130          }
 131  
 132          $metanode = $this->node("//imscc:resource".
 133              "[@identifier='".
 134              $identifier.
 135              "']/imscc:file".
 136              "[@href='".
 137              $filename.
 138              "']");
 139  
 140          $nspaces = $this->activemanifest->get_cc_namespaces();
 141          $dnode   = $this->doc->createElementNS($nspaces['imscc'], "metadata");
 142  
 143          $metanode->appendChild($dnode);
 144  
 145          $this->activemanifest->create_metadata_file_node($met, $this->doc, $dnode);
 146      }
 147  
 148  
 149      public function on_create() {
 150          $this->activemanifest = cc_builder_creator::factory($this->ccversion);
 151          $this->rootmanifest = $this->activemanifest;
 152          $result = $this->activemanifest->create_manifest($this->doc);
 153          $this->register_namespaces_for_xpath();
 154          return $result;
 155      }
 156  
 157      public function get_relative_base_path() {
 158          return $this->activemanifest->base();
 159      }
 160  
 161      public function parent_manifest() {
 162          return new cc_manifest($this, $this->parentmanifest, $this->parentparentmanifest);
 163      }
 164  
 165      public function root_manifest() {
 166          return new cc_manifest($this, $this->rootmanifest);
 167      }
 168  
 169      public function manifestID() {
 170          return $this->activemanifest->manifestID();
 171      }
 172  
 173      public function get_manifest_namespaces() {
 174          return $this->rootmanifest->get_cc_namespaces();
 175      }
 176  
 177      /**
 178       * Add a new organization
 179       *
 180       * @param cc_i_organization $org
 181       */
 182      public function add_new_organization(cc_i_organization &$org) {
 183          $norg    = $this->activemanifest->create_organization_node($org, $this->doc);
 184          $orgnode = $this->node("//imscc:manifest[@identifier='".
 185              $this->activemanifest->manifestID().
 186              "']/imscc:organizations");
 187          $orgnode->appendChild($norg);
 188      }
 189  
 190      public function get_resources($searchspecific='') {
 191          $reslist = $this->get_resource_list($searchspecific);
 192          $resourcelist = array();
 193          foreach ($reslist as $resourceitem) {
 194              $resourcelist[] = new cc_resource($this, $resourceitem);
 195          }
 196          return $resourcelist;
 197      }
 198  
 199      public function get_cc_namespace_path($nsname) {
 200          if (is_string($nsname) && (!empty($nsname))) {
 201              $scnam = $this->activemanifest->get_cc_namespaces();
 202              return $scnam[$nsname];
 203          }
 204          return null;
 205      }
 206  
 207  
 208      public function get_resource_list($searchspecific = '') {
 209          return $this->nodeList("//imscc:manifest[@identifier='".
 210                              $this->activemanifest->manifestID().
 211                              "']/imscc:resources/imscc:resource".$searchspecific);
 212      }
 213  
 214      public function on_load() {
 215          $this->register_namespaces_for_xpath();
 216          $this->fill_manifest();
 217          return true;
 218      }
 219  
 220      public function on_save() {
 221          return true;
 222      }
 223  
 224      /**
 225       * Add a resource to the manifest
 226       *
 227       * @param cc_i_resource $res
 228       * @param string $identifier
 229       * @param string $type
 230       * @return array
 231       */
 232      public function add_resource(cc_i_resource $res, $identifier = null, $type = 'webcontent') {
 233  
 234          if (!$this->ccobj->valid($type)) {
 235              throw new Exception("Type invalid...");
 236          }
 237  
 238          if ($res == null) {
 239              throw new Exception('Invalid Resource or dont give it');
 240          }
 241          $rst = $res;
 242  
 243          // TODO: This has to be reviewed since it does not handle multiple files properly.
 244          // Dependencies.
 245          if (is_object($identifier)) {
 246              $this->activemanifest->create_resource_node($rst, $this->doc, $identifier);
 247          } else {
 248              $nresnode   = null;
 249  
 250              $rst->type = $type;
 251              if (!cc_helpers::is_html($rst->filename)) {
 252                  $rst->href = null;
 253              }
 254  
 255              $this->activemanifest->create_resource_node($rst, $this->doc, $nresnode);
 256              foreach ($rst->files as $file) {
 257                  $ident = $this->get_identifier_by_filename($file);
 258                  if ($ident == null) {
 259                      $newres = new cc_resource($rst->manifestroot, $file);
 260                      if (!cc_helpers::is_html($file)) {
 261                           $newres->href = null;
 262                      }
 263                      $newres->type = 'webcontent';
 264                      $this->activemanifest->create_resource_node($newres, $this->doc, $nresnode);
 265                  }
 266              }
 267          }
 268  
 269          $tmparray = array($rst->identifier, $rst->files[0]);
 270          return $tmparray;
 271      }
 272  
 273      private function check_if_exist_in_other($name, $identifier) {
 274          $status = array();
 275          foreach ($this->activemanifest->resources as $value) {
 276              if (($value->identifier != $identifier) && isset($value->files[$name])) {
 277                  $status[] = $value->identifier;
 278              }
 279          }
 280          return $status;
 281      }
 282  
 283      private function replace_file_x_dependency($depen, $name) {
 284          foreach ($depen as $key => $value) {
 285              ($key);
 286              $ident                                          = $this->get_identifier_by_filename($name);
 287              $this->activemanifest->resources[$value]->files =
 288                  $this->array_remove_by_value($this->activemanifest->resources[$value]->files, $name);
 289              if (!in_array($ident, $this->activemanifest->resources[$value]->dependency)) {
 290                  array_push($this->activemanifest->resources[$value]->dependency, $ident);
 291              }
 292  
 293          }
 294          return true;
 295      }
 296  
 297      private function get_identifier_by_filename($name) {
 298          $result = null;
 299          if (isset($this->activemanifest->resources_ind[$name])) {
 300              $result = $this->activemanifest->resources_ind[$name];
 301          }
 302          return $result;
 303      }
 304  
 305      private function array_remove_by_value($arr, $value) {
 306          return array_values(array_diff($arr, array($value)));
 307      }
 308  
 309      private function array_remove_by_key($arr, $key) {
 310          return array_values(array_diff_key($arr, array($key)));
 311      }
 312  
 313      public function update_instructoronly($identifier, $value = false) {
 314          if (isset($this->activemanifest->resources[$identifier])) {
 315              $resource = $this->activemanifest->resources[$identifier];
 316              $resource->instructoronly = $value;
 317          }
 318      }
 319  
 320      /**
 321       * Append the resources nodes in the Manifest
 322       *
 323       * @return DOMNode
 324       */
 325      public function put_nodes() {
 326  
 327          $resnodestr = "//imscc:manifest[@identifier='".$this->activemanifest->manifestID().
 328              "']/imscc:resources";
 329          $resnode    = $this->node($resnodestr);
 330  
 331          foreach ($this->activemanifest->resources as $k => $v) {
 332              ($k);
 333              $depen = $this->check_if_exist_in_other($v->files[0], $v->identifier);
 334              if (!empty($depen)) {
 335                  $this->replace_file_x_dependency($depen, $v->files[0]);
 336                  $v->type = 'webcontent';
 337              }
 338          }
 339  
 340          foreach ($this->activemanifest->resources as $node) {
 341              $rnode = $this->activemanifest->create_resource_node($node, $this->doc, null);
 342              $resnode->appendChild($rnode);
 343              if ($node->instructoronly) {
 344                  $metafileceduc = new cc_metadata_resouce_educational();
 345                  $metafileceduc->set_value(intended_user_role::INSTRUCTOR);
 346                  $metafile = new cc_metadata_resouce();
 347                  $metafile->add_metadata_resource_educational($metafileceduc);
 348                  $this->activemanifest->create_metadata_educational($metafile, $this->doc, $rnode);
 349              }
 350          }
 351  
 352          return $resnode;
 353      }
 354  }
 355  
 356