Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311]

   1  <?php
   2  
   3  // This file is part of Moodle - http://moodle.org/
   4  //
   5  // Moodle is free software: you can redistribute it and/or modify
   6  // it under the terms of the GNU General Public License as published by
   7  // the Free Software Foundation, either version 3 of the License, or
   8  // (at your option) any later version.
   9  //
  10  // Moodle is distributed in the hope that it will be useful,
  11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  // GNU General Public License for more details.
  14  //
  15  // You should have received a copy of the GNU General Public License
  16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  17  
  18  /**
  19   * Provides support for the conversion of moodle1 backup to the moodle2 format
  20   * Based off of a template @ http://docs.moodle.org/dev/Backup_1.9_conversion_for_developers
  21   *
  22   * @package    mod_wiki
  23   * @copyright  2011 Aparup Banerjee <aparup@moodle.com>
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  /**
  30   * Wiki conversion handler
  31   */
  32  class moodle1_mod_wiki_handler extends moodle1_mod_handler {
  33  
  34      /** @var string initial content for creating first page from the optional 1.9 wiki file */
  35      protected $initialcontent;
  36  
  37      /** @var string */
  38      protected $initialcontentfilename;
  39  
  40      /** @var bool initial content page already exists */
  41      protected $needinitpage = false;
  42  
  43      /** @var array a data element transfer buffer, can be used for transfer of data between xml path levels. */
  44      protected $databuf = array();
  45  
  46      /** @var moodle1_file_manager */
  47      protected $fileman = null;
  48  
  49      /** @var int cmid */
  50      protected $moduleid = null;
  51  
  52      /**
  53       * Declare the paths in moodle.xml we are able to convert
  54       *
  55       * The method returns list of {@link convert_path} instances.
  56       * For each path returned, the corresponding conversion method must be
  57       * defined.
  58       *
  59       * Note that the path /MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI does not
  60       * actually exist in the file. The last element with the module name was
  61       * appended by the moodle1_converter class.
  62       *
  63       * @return array of {@link convert_path} instances
  64       */
  65      public function get_paths() {
  66          return array(
  67              new convert_path(
  68                  'wiki', '/MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI',
  69                  array(
  70                      'newfields' => array(
  71                          'introformat' => '0',
  72                          'defaultformat' => 'html', //1.9 migrations default to html
  73                          'forceformat' => '1',
  74                          'editbegin' => '0',
  75                          'editend' => '0',
  76                          'timecreated' => time(), //2.x time of creation since theres no 1.9 time of creation
  77                      ),
  78                      'renamefields' => array(
  79                          'summary' => 'intro',
  80                          'format' => 'introformat',
  81                          'firstpagetitle' => 'pagename',
  82                          'wtype' => 'wikimode'
  83                      ),
  84                      'dropfields' => array(
  85                          'pagename', 'scaleid', 'ewikiprinttitle', 'htmlmode', 'ewikiacceptbinary', 'disablecamelcase',
  86                          'setpageflags', 'strippages', 'removepages', 'revertchanges'
  87                      )
  88                  )
  89              ),
  90              new convert_path(
  91                  'wiki_entries', '/MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI/ENTRIES',
  92                  array(
  93                      'newfields' => array(
  94                          'synonyms' => '0',
  95                          'links' => 'collaborative',
  96                      ),
  97                      'dropfields' => array(
  98                          'pagename' ,'timemodified'
  99                      )
 100                  )
 101              ),
 102              new convert_path(
 103                  'wiki_entry', '/MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI/ENTRIES/ENTRY'
 104              ),
 105              new convert_path(
 106                  'wiki_pages', '/MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI/ENTRIES/ENTRY/PAGES'
 107              ),
 108              new convert_path(
 109                  'wiki_entry_page', '/MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI/ENTRIES/ENTRY/PAGES/PAGE',
 110                  array(
 111                      'newfields' => array(
 112                          'cachedcontent' => '**reparse needed**',
 113                          'timerendered' => '0',
 114                          'readonly' => '0',
 115                          'tags' => ''
 116                      ),
 117                      'renamefields' => array(
 118                          'pagename' => 'title',
 119                          'created' => 'timecreated',
 120                          'lastmodified' => 'timemodified',
 121                          'hits' => 'pageviews'
 122                      ),
 123                      'dropfields' => array(
 124                          'version', 'flags', 'author', 'refs', //refs will be reparsed during rendering
 125                          'meta'
 126                      )
 127                  )
 128              )
 129          );
 130      }
 131  
 132      /**
 133       * This is executed every time we have one /MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI
 134       * data available
 135       */
 136      public function process_wiki($data) {
 137          global $CFG;    // We need to check a config setting.
 138  
 139          if (!empty($data['initialcontent'])) {
 140              //convert file in <INITIALCONTENT>filename</INITIALCONTENT> into a subwiki page if no entry created.
 141              $temppath = $this->converter->get_tempdir_path();
 142              $filename = clean_param($data['initialcontent'], PARAM_FILE);
 143              $this->initialcontent = file_get_contents($temppath . '/course_files/' . $filename);
 144              $this->initialcontentfilename = $filename;
 145              $this->needinitpage = true;
 146          }
 147          unset($data['initialcontent']);
 148          if ($data['wikimode'] !== 'group') {
 149              $data['wikimode'] = 'individual';
 150              //@todo need to create extra subwikis due to individual wikimode?
 151              //this would then need to reference the users in the course that is being restored.(some parent class API needed)
 152          } else {
 153              $data['wikimode'] = 'collaborative';
 154          }
 155  
 156          if (empty($data['name'])) {
 157              $data['name'] = 'Wiki';
 158          }
 159          // get the course module id and context id
 160          $instanceid     = $data['id'];
 161          $cminfo         = $this->get_cminfo($instanceid);
 162          $this->moduleid = $cminfo['id'];
 163          $contextid      = $this->converter->get_contextid(CONTEXT_MODULE, $this->moduleid);
 164  
 165          // get a fresh new file manager for this instance
 166          $this->fileman = $this->converter->get_file_manager($contextid, 'mod_wiki');
 167  
 168          // convert course files embedded into the intro
 169          $this->fileman->filearea = 'intro';
 170          $this->fileman->itemid   = 0;
 171          $data['intro'] = moodle1_converter::migrate_referenced_files($data['intro'], $this->fileman);
 172  
 173          // convert the introformat if necessary
 174          if ($CFG->texteditors !== 'textarea') {
 175              $data['intro'] = text_to_html($data['intro'], false, false, true);
 176              $data['introformat'] = FORMAT_HTML;
 177          }
 178  
 179          // we now have all information needed to start writing into the file
 180          $this->open_xml_writer("activities/wiki_{$this->moduleid}/wiki.xml");
 181          $this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $this->moduleid,
 182              'modulename' => 'wiki', 'contextid' => $contextid));
 183          $this->xmlwriter->begin_tag('wiki', array('id' => $instanceid));
 184  
 185          foreach ($data as $field => $value) {
 186              if ($field <> 'id') {
 187                  $this->xmlwriter->full_tag($field, $value);
 188              }
 189          }
 190  
 191          return $data;
 192      }
 193  
 194      public function on_wiki_entries_start() {
 195          $this->xmlwriter->begin_tag('subwikis');
 196          $this->needinitpage = false; //backup has entries, so the initial_content file has been stored as a page in 1.9.
 197      }
 198  
 199      public function on_wiki_entries_end() {
 200          $this->xmlwriter->end_tag('subwikis');
 201      }
 202  
 203      public function process_wiki_entry($data) {
 204          $this->xmlwriter->begin_tag('subwiki', array('id' => $data['id']));
 205          unset($data['id']);
 206  
 207          unset($data['pagename']);
 208          unset($data['timemodified']);
 209  
 210          foreach ($data as $field => $value) {
 211              $this->xmlwriter->full_tag($field, $value);
 212          }
 213      }
 214  
 215      public function on_wiki_entry_end() {
 216          $this->xmlwriter->end_tag('subwiki');
 217      }
 218  
 219      public function on_wiki_pages_start() {
 220          $this->xmlwriter->begin_tag('pages');
 221      }
 222  
 223      public function on_wiki_pages_end() {
 224          $this->xmlwriter->end_tag('pages');
 225      }
 226  
 227      public function process_wiki_entry_page($data) {
 228          // assimilate data to create later in extra virtual path page/versions/version/
 229          $this->databuf['id'] = $this->converter->get_nextid();
 230          $this->databuf['content'] = $data['content'];
 231          unset($data['content']);
 232          $this->databuf['contentformat'] = 'html';
 233          $this->databuf['version'] = 0;
 234          $this->databuf['timecreated'] = $data['timecreated']; //do not unset, is reused
 235          $this->databuf['userid'] = $data['userid']; //do not unset, is reused
 236  
 237          // process page data (user data and also the one that is from <initialcontent>
 238          $this->xmlwriter->begin_tag('page', array('id' => $data['id']));
 239          unset($data['id']); // we already write it as attribute, do not repeat it as child element
 240          foreach ($data as $field => $value) {
 241              $this->xmlwriter->full_tag($field, $value);
 242          }
 243  
 244          // process page content as a version.
 245          $this->xmlwriter->begin_tag('versions');
 246          $this->write_xml('version', $this->databuf, array('/version/id')); //version id from get_nextid()
 247          $this->xmlwriter->end_tag('versions');
 248      }
 249      public function on_wiki_entry_page_end() {
 250          $this->xmlwriter->end_tag('page');
 251      }
 252  
 253      /**
 254       * This is executed when we reach the closing </MOD> tag of our 'wiki' path
 255       */
 256      public function on_wiki_end() {
 257          global $USER;
 258  
 259          //check if the initial content needs to be created (and if a page is already there for it)
 260          if ($this->initialcontentfilename && $this->needinitpage) {
 261              //contruct (synthetic - not for cooking) a full path for creating entries/entry/pages/page
 262              $data_entry = array(
 263                  'id'        => $this->converter->get_nextid(), //creating the first entry
 264                  'groupid'   => 0,
 265                  'userid'    => 0,
 266                  'synonyms'  => '',
 267                  'links'     => ''
 268              );
 269              $data_page = array(
 270                  'id'            => $this->converter->get_nextid(), //just creating the first page in the wiki
 271                  'title'         => $this->initialcontentfilename,
 272                  'content'       => $this->initialcontent,
 273                  'userid'        => $USER->id,
 274                  'timecreated'   => time(),
 275                  'timemodified'  => 0,
 276                  'pageviews'     => 0,
 277                  'cachedcontent' => '**reparse needed**',
 278                  'timerendered'  => 0,
 279                  'readonly'      => 0,
 280                  'tags'          => ''
 281              );
 282              //create xml with constructed page data (from initial_content file).
 283              $this->on_wiki_entries_start();
 284              $this->process_wiki_entry($data_entry);
 285              $this->on_wiki_pages_start();
 286              $this->process_wiki_entry_page($data_page);
 287              $this->on_wiki_entry_page_end();
 288              $this->on_wiki_pages_end();
 289              $this->on_wiki_entry_end();
 290              $this->on_wiki_entries_end();
 291          }
 292  
 293          //close wiki.xml
 294          $this->xmlwriter->end_tag('wiki');
 295          $this->xmlwriter->end_tag('activity');
 296          $this->close_xml_writer();
 297  
 298          // write inforef.xml
 299          $this->open_xml_writer("activities/wiki_{$this->moduleid}/inforef.xml");
 300          $this->xmlwriter->begin_tag('inforef');
 301          $this->xmlwriter->begin_tag('fileref');
 302          foreach ($this->fileman->get_fileids() as $fileid) {
 303              $this->write_xml('file', array('id' => $fileid));
 304          }
 305          $this->xmlwriter->end_tag('fileref');
 306          $this->xmlwriter->end_tag('inforef');
 307          $this->close_xml_writer();
 308      }
 309  }