Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   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              $this->initialcontent = file_get_contents($temppath.'/course_files/'.$data['initialcontent']);
 143              $this->initialcontentfilename = $data['initialcontent'];
 144              $this->needinitpage = true;
 145          }
 146          unset($data['initialcontent']);
 147          if ($data['wikimode'] !== 'group') {
 148              $data['wikimode'] = 'individual';
 149              //@todo need to create extra subwikis due to individual wikimode?
 150              //this would then need to reference the users in the course that is being restored.(some parent class API needed)
 151          } else {
 152              $data['wikimode'] = 'collaborative';
 153          }
 154  
 155          if (empty($data['name'])) {
 156              $data['name'] = 'Wiki';
 157          }
 158          // get the course module id and context id
 159          $instanceid     = $data['id'];
 160          $cminfo         = $this->get_cminfo($instanceid);
 161          $this->moduleid = $cminfo['id'];
 162          $contextid      = $this->converter->get_contextid(CONTEXT_MODULE, $this->moduleid);
 163  
 164          // get a fresh new file manager for this instance
 165          $this->fileman = $this->converter->get_file_manager($contextid, 'mod_wiki');
 166  
 167          // convert course files embedded into the intro
 168          $this->fileman->filearea = 'intro';
 169          $this->fileman->itemid   = 0;
 170          $data['intro'] = moodle1_converter::migrate_referenced_files($data['intro'], $this->fileman);
 171  
 172          // convert the introformat if necessary
 173          if ($CFG->texteditors !== 'textarea') {
 174              $data['intro'] = text_to_html($data['intro'], false, false, true);
 175              $data['introformat'] = FORMAT_HTML;
 176          }
 177  
 178          // we now have all information needed to start writing into the file
 179          $this->open_xml_writer("activities/wiki_{$this->moduleid}/wiki.xml");
 180          $this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $this->moduleid,
 181              'modulename' => 'wiki', 'contextid' => $contextid));
 182          $this->xmlwriter->begin_tag('wiki', array('id' => $instanceid));
 183  
 184          foreach ($data as $field => $value) {
 185              if ($field <> 'id') {
 186                  $this->xmlwriter->full_tag($field, $value);
 187              }
 188          }
 189  
 190          return $data;
 191      }
 192  
 193      public function on_wiki_entries_start() {
 194          $this->xmlwriter->begin_tag('subwikis');
 195          $this->needinitpage = false; //backup has entries, so the initial_content file has been stored as a page in 1.9.
 196      }
 197  
 198      public function on_wiki_entries_end() {
 199          $this->xmlwriter->end_tag('subwikis');
 200      }
 201  
 202      public function process_wiki_entry($data) {
 203          $this->xmlwriter->begin_tag('subwiki', array('id' => $data['id']));
 204          unset($data['id']);
 205  
 206          unset($data['pagename']);
 207          unset($data['timemodified']);
 208  
 209          foreach ($data as $field => $value) {
 210              $this->xmlwriter->full_tag($field, $value);
 211          }
 212      }
 213  
 214      public function on_wiki_entry_end() {
 215          $this->xmlwriter->end_tag('subwiki');
 216      }
 217  
 218      public function on_wiki_pages_start() {
 219          $this->xmlwriter->begin_tag('pages');
 220      }
 221  
 222      public function on_wiki_pages_end() {
 223          $this->xmlwriter->end_tag('pages');
 224      }
 225  
 226      public function process_wiki_entry_page($data) {
 227          // assimilate data to create later in extra virtual path page/versions/version/
 228          $this->databuf['id'] = $this->converter->get_nextid();
 229          $this->databuf['content'] = $data['content'];
 230          unset($data['content']);
 231          $this->databuf['contentformat'] = 'html';
 232          $this->databuf['version'] = 0;
 233          $this->databuf['timecreated'] = $data['timecreated']; //do not unset, is reused
 234          $this->databuf['userid'] = $data['userid']; //do not unset, is reused
 235  
 236          // process page data (user data and also the one that is from <initialcontent>
 237          $this->xmlwriter->begin_tag('page', array('id' => $data['id']));
 238          unset($data['id']); // we already write it as attribute, do not repeat it as child element
 239          foreach ($data as $field => $value) {
 240              $this->xmlwriter->full_tag($field, $value);
 241          }
 242  
 243          // process page content as a version.
 244          $this->xmlwriter->begin_tag('versions');
 245          $this->write_xml('version', $this->databuf, array('/version/id')); //version id from get_nextid()
 246          $this->xmlwriter->end_tag('versions');
 247      }
 248      public function on_wiki_entry_page_end() {
 249          $this->xmlwriter->end_tag('page');
 250      }
 251  
 252      /**
 253       * This is executed when we reach the closing </MOD> tag of our 'wiki' path
 254       */
 255      public function on_wiki_end() {
 256          global $USER;
 257  
 258          //check if the initial content needs to be created (and if a page is already there for it)
 259          if ($this->initialcontentfilename && $this->needinitpage) {
 260              //contruct (synthetic - not for cooking) a full path for creating entries/entry/pages/page
 261              $data_entry = array(
 262                  'id'        => $this->converter->get_nextid(), //creating the first entry
 263                  'groupid'   => 0,
 264                  'userid'    => 0,
 265                  'synonyms'  => '',
 266                  'links'     => ''
 267              );
 268              $data_page = array(
 269                  'id'            => $this->converter->get_nextid(), //just creating the first page in the wiki
 270                  'title'         => $this->initialcontentfilename,
 271                  'content'       => $this->initialcontent,
 272                  'userid'        => $USER->id,
 273                  'timecreated'   => time(),
 274                  'timemodified'  => 0,
 275                  'pageviews'     => 0,
 276                  'cachedcontent' => '**reparse needed**',
 277                  'timerendered'  => 0,
 278                  'readonly'      => 0,
 279                  'tags'          => ''
 280              );
 281              //create xml with constructed page data (from initial_content file).
 282              $this->on_wiki_entries_start();
 283              $this->process_wiki_entry($data_entry);
 284              $this->on_wiki_pages_start();
 285              $this->process_wiki_entry_page($data_page);
 286              $this->on_wiki_entry_page_end();
 287              $this->on_wiki_pages_end();
 288              $this->on_wiki_entry_end();
 289              $this->on_wiki_entries_end();
 290          }
 291  
 292          //close wiki.xml
 293          $this->xmlwriter->end_tag('wiki');
 294          $this->xmlwriter->end_tag('activity');
 295          $this->close_xml_writer();
 296  
 297          // write inforef.xml
 298          $this->open_xml_writer("activities/wiki_{$this->moduleid}/inforef.xml");
 299          $this->xmlwriter->begin_tag('inforef');
 300          $this->xmlwriter->begin_tag('fileref');
 301          foreach ($this->fileman->get_fileids() as $fileid) {
 302              $this->write_xml('file', array('id' => $fileid));
 303          }
 304          $this->xmlwriter->end_tag('fileref');
 305          $this->xmlwriter->end_tag('inforef');
 306          $this->close_xml_writer();
 307      }
 308  }