Skip to content

Commit

Permalink
MDL-25617 backup: backup/restore using extra_question_fields
Browse files Browse the repository at this point in the history
  • Loading branch information
nghiand authored and stronk7 committed Mar 28, 2018
1 parent 54b5941 commit 5a8d683
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 81 deletions.
1 change: 1 addition & 0 deletions backup/moodle2/backup_plan_builder.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
require_once($CFG->dirroot . '/backup/moodle2/backup_xml_transformer.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_qtype_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_qtype_extrafields_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_gradingform_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_format_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_local_plugin.class.php');
Expand Down
83 changes: 83 additions & 0 deletions backup/moodle2/backup_qtype_extrafields_plugin.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Defines backup_qtype_extrafields_plugin class
*
* @package core_backup
* @copyright 2012 Oleg Sychev, Volgograd State Technical University
* @author Valeriy Streltsov <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

defined('MOODLE_INTERNAL') || die();

global $CFG;
require_once($CFG->dirroot . '/question/engine/bank.php');

/**
* Class extending backup_qtype_plugin in order to use extra fields method
*
* See qtype_shortanswer for an example
*
* @copyright 2012 Oleg Sychev, Volgograd State Technical University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class backup_qtype_extrafields_plugin extends backup_qtype_plugin {

/**
* Returns the qtype information to attach to question element.
*/
protected function define_question_plugin_structure() {
$qtypeobj = question_bank::get_qtype($this->pluginname);

// Define the virtual plugin element with the condition to fulfill.
$plugin = $this->get_plugin_element(null, '../../qtype', $qtypeobj->name());

// Create one standard named plugin element (the visible container).
$pluginwrapper = new backup_nested_element($this->get_recommended_name());

// Connect the visible container ASAP.
$plugin->add_child($pluginwrapper);

// This qtype uses standard question_answers, add them here
// to the tree before any other information that will use them.
$this->add_question_question_answers($pluginwrapper);
$answers = $pluginwrapper->get_child('answers');
$answer = $answers->get_child('answer');

// Extra question fields.
$extraquestionfields = $qtypeobj->extra_question_fields();
if (!empty($extraquestionfields)) {
$tablename = array_shift($extraquestionfields);
$child = new backup_nested_element($qtypeobj->name(), array('id'), $extraquestionfields);
$pluginwrapper->add_child($child);
$child->set_source_table($tablename, array($qtypeobj->questionid_column_name() => backup::VAR_PARENTID));
}

// Extra answer fields.
$extraanswerfields = $qtypeobj->extra_answer_fields();
if (!empty($extraanswerfields)) {
$tablename = array_shift($extraanswerfields);
$child = new backup_nested_element('extraanswerdata', array('id'), $extraanswerfields);
$answer->add_child($child);
$child->set_source_table($tablename, array('answerid' => backup::VAR_PARENTID));
}

// Don't need to annotate ids nor files.
return $plugin;
}
}
2 changes: 2 additions & 0 deletions backup/moodle2/restore_plan_builder.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
require_once($CFG->dirroot . '/backup/moodle2/restore_default_block_task.class.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_qtype_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_qtype_extrafields_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_format_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_local_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_theme_plugin.class.php');
Expand All @@ -46,6 +47,7 @@
require_once($CFG->dirroot . '/backup/moodle2/restore_enrol_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_qtype_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_qtype_extrafields_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_format_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_local_plugin.class.php');
require_once($CFG->dirroot . '/backup/moodle2/backup_theme_plugin.class.php');
Expand Down
131 changes: 131 additions & 0 deletions backup/moodle2/restore_qtype_extrafields_plugin.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Defines restore_qtype_extrafields_plugin class
*
* @package core_backup
* @copyright 2012 Oleg Sychev, Volgograd State Technical University
* @author Valeriy Streltsov <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

defined('MOODLE_INTERNAL') || die();

global $CFG;
require_once($CFG->dirroot . '/question/engine/bank.php');

/**
* Class extending restore_qtype_plugin in order to use extra fields method
*
* See qtype_shortanswer for an example
*
* @copyright 2012 Oleg Sychev, Volgograd State Technical University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class restore_qtype_extrafields_plugin extends restore_qtype_plugin {

/**
* Question type class for a particular question type
* @var question_type
*/
protected $qtypeobj;

/**
* Constructor
*
* @param string $plugintype plugin type
* @param string $pluginname plugin name
* @param restore_step $step step
*/
public function __construct($plugintype, $pluginname, $step) {
parent::__construct($plugintype, $pluginname, $step);
$this->qtypeobj = question_bank::get_qtype($this->pluginname);
}

/**
* Returns the paths to be handled by the plugin at question level.
*/
protected function define_question_plugin_structure() {
$paths = array();

// This qtype uses question_answers, add them.
$this->add_question_question_answers($paths);

// Add own qtype stuff.
$elepath = $this->get_pathfor('/' . $this->qtypeobj->name());
$paths[] = new restore_path_element($this->qtypeobj->name(), $elepath);

$elepath = $this->get_pathfor('/answers/answer/extraanswerdata');
$paths[] = new restore_path_element('extraanswerdata', $elepath);

return $paths;
}

/**
* Processes the extra answer data
*
* @param array $data extra answer data
*/
public function process_extraanswerdata($data) {
global $DB;

$extra = $this->qtypeobj->extra_answer_fields();
$tablename = array_shift($extra);

$oldquestionid = $this->get_old_parentid('question');
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;

if ($questioncreated) {
$data['answerid'] = $this->get_mappingid('question_answer', $data['id']);
$DB->insert_record($tablename, $data);
} else {
$DB->update_record($tablename, $data);
}
}

/**
* Process the qtype/... element.
*
* @param array $data question data
*/
public function really_process_extra_question_fields($data) {
global $DB;

$oldid = $data['id'];

// Detect if the question is created or mapped.
$oldquestionid = $this->get_old_parentid('question');
$newquestionid = $this->get_new_parentid('question');
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;

// If the question has been created by restore, we need to create its qtype_... too.
if ($questioncreated) {
$extraquestionfields = $this->qtypeobj->extra_question_fields();
$tablename = array_shift($extraquestionfields);

// Adjust some columns.
$qtfield = $this->qtypeobj->questionid_column_name();
$data[$qtfield] = $newquestionid;

// Insert record.
$newitemid = $DB->insert_record($tablename, $data);

// Create mapping.
$this->set_mapping($tablename, $oldid, $newitemid);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,48 +21,13 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/


defined('MOODLE_INTERNAL') || die();


/**
* Provides the information to backup shortanswer questions
*
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class backup_qtype_shortanswer_plugin extends backup_qtype_plugin {

/**
* Returns the qtype information to attach to question element
*/
protected function define_question_plugin_structure() {

// Define the virtual plugin element with the condition to fulfill.
$plugin = $this->get_plugin_element(null, '../../qtype', 'shortanswer');

// Create one standard named plugin element (the visible container).
$pluginwrapper = new backup_nested_element($this->get_recommended_name());

// Connect the visible container ASAP.
$plugin->add_child($pluginwrapper);

// This qtype uses standard question_answers, add them here
// to the tree before any other information that will use them.
$this->add_question_question_answers($pluginwrapper);

// Now create the qtype own structures.
$shortanswer = new backup_nested_element('shortanswer', array('id'), array('usecase'));

// Now the own qtype tree.
$pluginwrapper->add_child($shortanswer);

// Set source to populate the data.
$shortanswer->set_source_table('qtype_shortanswer_options',
array('questionid' => backup::VAR_PARENTID));

// Don't need to annotate ids nor files.

return $plugin;
}
class backup_qtype_shortanswer_plugin extends backup_qtype_extrafields_plugin {
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,63 +21,23 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/


defined('MOODLE_INTERNAL') || die();

global $CFG;
require_once($CFG->dirroot . '/backup/moodle2/restore_qtype_extrafields_plugin.class.php');

/**
* restore plugin class that provides the necessary information
* Restore plugin class that provides the necessary information
* needed to restore one shortanswer qtype plugin
*
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class restore_qtype_shortanswer_plugin extends restore_qtype_plugin {

/**
* Returns the paths to be handled by the plugin at question level
*/
protected function define_question_plugin_structure() {

$paths = array();

// This qtype uses question_answers, add them.
$this->add_question_question_answers($paths);

// Add own qtype stuff.
$elename = 'shortanswer';
// We used get_recommended_name() so this works.
$elepath = $this->get_pathfor('/shortanswer');
$paths[] = new restore_path_element($elename, $elepath);

return $paths; // And we return the interesting paths.
}

class restore_qtype_shortanswer_plugin extends restore_qtype_extrafields_plugin {
/**
* Process the qtype/shortanswer element
*/
public function process_shortanswer($data) {
global $DB;

$data = (object)$data;
$oldid = $data->id;

// Detect if the question is created or mapped.
$oldquestionid = $this->get_old_parentid('question');
$newquestionid = $this->get_new_parentid('question');
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;

// If the question has been created by restore, we need to create its
// qtype_shortanswer_options too, if they are defined (the gui should ensure this).
if ($questioncreated) {
$data->questionid = $newquestionid;

// It is possible for old backup files to contain unique key violations.
// We need to check to avoid that.
if (!$DB->record_exists('qtype_shortanswer_options', array('questionid' => $data->questionid))) {
$newitemid = $DB->insert_record('qtype_shortanswer_options', $data);
$this->set_mapping('qtype_shortanswer_options', $oldid, $newitemid);
}
}
$this->really_process_extra_question_fields($data);
}
}
5 changes: 5 additions & 0 deletions question/type/upgrade.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
This files describes API changes for question type plugins.

== 3.5 ==
+ Added new classes backup_qtype_extrafields_plugin and restore_qtype_extrafields_plugin
in order to use extra fields method in backup/restore question type. Require and inherit new classes for using it. See
backup_qtype_shortanswer_plugin and restore_qtype_shortanswer_plugin for an example of using this.

=== 3.1.5, 3.2.2, 3.3 ===

* If you are using check_combined_feedback_file_access in your check_file_access method,
Expand Down

0 comments on commit 5a8d683

Please sign in to comment.