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.
   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_assignment
  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   * Assignment conversion handler
  31   */
  32  class moodle1_mod_assignment_handler extends moodle1_mod_handler {
  33  
  34      /** @var moodle1_file_manager */
  35      protected $fileman = null;
  36  
  37      /** @var int cmid */
  38      protected $moduleid = null;
  39  
  40      /** @var string current subplugin being processed*/
  41      private $currentsubpluginname = null;
  42  
  43      /** @var array of a moodle1_assignment_[subplugin_name]_handler instances */
  44      private $subpluginhandlers = null;
  45  
  46      /**
  47       * Declare the paths in moodle.xml we are able to convert
  48       *
  49       * The method returns list of {@link convert_path} instances.
  50       * For each path returned, the corresponding conversion method must be
  51       * defined.
  52       *
  53       * Note that the path /MOODLE_BACKUP/COURSE/MODULES/MOD/ASSIGNMENT does not
  54       * actually exist in the file. The last element with the module name was
  55       * appended by the moodle1_converter class.
  56       *
  57       * @return array of {@link convert_path} instances
  58       */
  59      public function get_paths() {
  60          return array(
  61              new convert_path(
  62                  'assignment', '/MOODLE_BACKUP/COURSE/MODULES/MOD/ASSIGNMENT',
  63                  array(
  64                      'renamefields' => array(
  65                          'description' => 'intro',
  66                          'format' => 'introformat',
  67                      )
  68                  )
  69              )
  70              //@todo process user data
  71              //new convert_path('assignment_submission', '/MOODLE_BACKUP/COURSE/MODULES/MOD/ASSIGNMENT/SUBMISSIONS/SUBMISSION')
  72          );
  73      }
  74  
  75      /**
  76       * This is executed every time we have one /MOODLE_BACKUP/COURSE/MODULES/MOD/ASSIGNMENT
  77       * data available
  78       */
  79      public function process_assignment($data) {
  80          global $CFG;
  81  
  82          // get the course module id and context id
  83          $instanceid     = $data['id'];
  84          $cminfo         = $this->get_cminfo($instanceid);
  85          $this->moduleid = $cminfo['id'];
  86          $contextid      = $this->converter->get_contextid(CONTEXT_MODULE, $this->moduleid);
  87  
  88          //store assignment type for possible subplugin conversions.
  89          $this->currentsubpluginname = $data['assignmenttype'];
  90  
  91          // get a fresh new file manager for this instance
  92          $this->fileman = $this->converter->get_file_manager($contextid, 'mod_assignment');
  93  
  94          // convert course files embedded into the intro
  95          $this->fileman->filearea = 'intro';
  96          $this->fileman->itemid   = 0;
  97          $data['intro'] = moodle1_converter::migrate_referenced_files($data['intro'], $this->fileman);
  98  
  99          // convert the introformat if necessary
 100          if ($CFG->texteditors !== 'textarea') {
 101              $data['intro'] = text_to_html($data['intro'], false, false, true);
 102              $data['introformat'] = FORMAT_HTML;
 103          }
 104  
 105          // start writing assignment.xml
 106          $this->open_xml_writer("activities/assignment_{$this->moduleid}/assignment.xml");
 107          $this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $this->moduleid,
 108              'modulename' => 'assignment', 'contextid' => $contextid));
 109          $this->xmlwriter->begin_tag('assignment', array('id' => $instanceid));
 110  
 111          foreach ($data as $field => $value) {
 112              if ($field <> 'id') {
 113                  $this->xmlwriter->full_tag($field, $value);
 114              }
 115          }
 116  
 117          //after writing the assignment type element, let the subplugin add on whatever it wants.
 118          $this->handle_assignment_subplugin($data);
 119  
 120          $this->xmlwriter->begin_tag('submissions');
 121  
 122          return $data;
 123      }
 124  
 125      /**
 126       * This is executed every time we have one /MOODLE_BACKUP/COURSE/MODULES/MOD/ASSIGNMENT/SUBMISSIONS/SUBMISSION
 127       * data available
 128       */
 129      public function process_assignment_submission($data) {
 130          //@todo process user data
 131          //$this->write_xml('submission', $data, array('/submission/id'));
 132      }
 133  
 134      /**
 135       * This handles calls to subplugin conversion classes.
 136       * called from <ASSIGNMENTTYPE> within process_assignment()
 137       */
 138      public function handle_assignment_subplugin($data) {
 139          $handler = $this->get_subplugin_handler($this->currentsubpluginname);
 140          $this->log('Instantiated assignment subplugin handler for '.$this->currentsubpluginname.'.', backup::LOG_DEBUG);
 141          $handler->use_xml_writer($this->xmlwriter);
 142  
 143          $this->log('Processing assignment subplugin handler callback for '.$this->currentsubpluginname.'.', backup::LOG_DEBUG);
 144          $handler->append_subplugin_data($data);
 145      }
 146  
 147      /**
 148       * This is executed when we reach the closing </MOD> tag of our 'assignment' path
 149       */
 150      public function on_assignment_end() {
 151          // finish writing assignment.xml
 152          $this->xmlwriter->end_tag('submissions');
 153          $this->xmlwriter->end_tag('assignment');
 154          $this->xmlwriter->end_tag('activity');
 155          $this->close_xml_writer();
 156  
 157          // write inforef.xml
 158          $this->open_xml_writer("activities/assignment_{$this->moduleid}/inforef.xml");
 159          $this->xmlwriter->begin_tag('inforef');
 160          $this->xmlwriter->begin_tag('fileref');
 161          foreach ($this->fileman->get_fileids() as $fileid) {
 162              $this->write_xml('file', array('id' => $fileid));
 163          }
 164          $this->xmlwriter->end_tag('fileref');
 165          $this->xmlwriter->end_tag('inforef');
 166          $this->close_xml_writer();
 167      }
 168  
 169      /// internal implementation details follow /////////////////////////////////
 170  
 171      /**
 172       * Factory method returning the handler of the given assignment subplugin
 173       *
 174       * @param string $subplugin the name of the subplugin
 175       * @throws moodle1_convert_exception
 176       * @return moodle1_assignment_subplugin_handler the instance of the handler
 177       */
 178      protected function get_subplugin_handler($subplugin) {
 179          global $CFG; // we include other files here
 180  
 181          if (is_null($this->subpluginhandlers)) {
 182              $this->subpluginhandlers = array();
 183              $subplugins = core_component::get_plugin_list('assignment');
 184              foreach ($subplugins as $name => $dir) {
 185                  $handlerfile  = $dir.'/backup/moodle1/lib.php';
 186                  $handlerclass = "moodle1_mod_assignment_{$name}_subplugin_handler";
 187                  if (!file_exists($handlerfile)) {
 188                      continue;
 189                  }
 190                  require_once($handlerfile);
 191  
 192                  if (!class_exists($handlerclass)) {
 193                      throw new moodle1_convert_exception('missing_handler_class', $handlerclass);
 194                  }
 195                  $this->log('preparing assignment subplugin handler', backup::LOG_DEBUG, $handlerclass);
 196                  $this->subpluginhandlers[$name] = new $handlerclass($this, $name);
 197                  if (!$this->subpluginhandlers[$name] instanceof moodle1_assignment_subplugin_handler) {
 198                      throw new moodle1_convert_exception('wrong_handler_class', get_class($this->subpluginhandlers[$name]));
 199                  }
 200              }
 201          }
 202  
 203          if (!isset($this->subpluginhandlers[$subplugin])) {
 204              // Generic handling, prevents breaking conversion process...
 205              $this->subpluginhandlers[$subplugin] = new moodle1_assignment_unsupported_subplugin_handler($this, $subplugin);
 206          }
 207  
 208          return $this->subpluginhandlers[$subplugin];
 209      }
 210  }
 211  
 212  
 213  /**
 214   * Base class for the assignment subplugin handler
 215   * Extend this for your own subplugin conversion handling purposes.
 216   */
 217  abstract class moodle1_assignment_subplugin_handler extends moodle1_submod_handler {
 218  
 219      /**
 220       * @param moodle1_mod_handler $assignmenthandler the handler of a module we are subplugin of
 221       * @param string $subpluginname the name of the subplugin
 222       */
 223      public function __construct(moodle1_mod_handler $assignmenthandler, $subpluginname) {
 224          parent::__construct($assignmenthandler, 'assignment', $subpluginname);
 225      }
 226  
 227      /**
 228       * Provides a xml_writer instance to this assignment subplugin type handler
 229       *
 230       * @param xml_writer $xmlwriter
 231       */
 232      public function use_xml_writer(xml_writer $xmlwriter) {
 233          $this->xmlwriter = $xmlwriter;
 234      }
 235  
 236      /**
 237       * a call back (entry point) to the subplugin conversion handler class.
 238       * $data are the elements of <assignment>, any (@todo sub paths containing subplugindata isn't handed through).
 239       */
 240  
 241      public function append_subplugin_data($data) {
 242          // an example that does nothing - you'll do nothing if you don't overide it
 243          return false;
 244  
 245          //you will probably want to do stuff with $this->xmlwriter here (within your overridden method) to write plugin specific data.
 246      }
 247  }
 248  
 249  /**
 250   * This class handles subplugins that do not exist or that are not supported
 251   */
 252  class moodle1_assignment_unsupported_subplugin_handler extends moodle1_assignment_subplugin_handler {
 253  }