From 5a8d683fb2403876e0b22b89ad7636f1ee8cdc4f Mon Sep 17 00:00:00 2001 From: Ngo Nghia Date: Tue, 20 Dec 2016 03:44:17 +0300 Subject: [PATCH] MDL-25617 backup: backup/restore using extra_question_fields --- backup/moodle2/backup_plan_builder.class.php | 1 + .../backup_qtype_extrafields_plugin.class.php | 83 +++++++++++ backup/moodle2/restore_plan_builder.class.php | 2 + ...restore_qtype_extrafields_plugin.class.php | 131 ++++++++++++++++++ .../backup_qtype_shortanswer_plugin.class.php | 37 +---- ...restore_qtype_shortanswer_plugin.class.php | 50 +------ question/type/upgrade.txt | 5 + 7 files changed, 228 insertions(+), 81 deletions(-) create mode 100644 backup/moodle2/backup_qtype_extrafields_plugin.class.php create mode 100644 backup/moodle2/restore_qtype_extrafields_plugin.class.php diff --git a/backup/moodle2/backup_plan_builder.class.php b/backup/moodle2/backup_plan_builder.class.php index c359096e44f..c3c200a4411 100644 --- a/backup/moodle2/backup_plan_builder.class.php +++ b/backup/moodle2/backup_plan_builder.class.php @@ -37,6 +37,7 @@ require_once($CFG->dirroot . '/backup/moodle2/backup_default_block_task.class.ph 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'); diff --git a/backup/moodle2/backup_qtype_extrafields_plugin.class.php b/backup/moodle2/backup_qtype_extrafields_plugin.class.php new file mode 100644 index 00000000000..d7db6ff3ed7 --- /dev/null +++ b/backup/moodle2/backup_qtype_extrafields_plugin.class.php @@ -0,0 +1,83 @@ +. + +/** + * Defines backup_qtype_extrafields_plugin class + * + * @package core_backup + * @copyright 2012 Oleg Sychev, Volgograd State Technical University + * @author Valeriy Streltsov + * @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; + } +} diff --git a/backup/moodle2/restore_plan_builder.class.php b/backup/moodle2/restore_plan_builder.class.php index ae48ec93dfc..02dc0629501 100644 --- a/backup/moodle2/restore_plan_builder.class.php +++ b/backup/moodle2/restore_plan_builder.class.php @@ -36,6 +36,7 @@ require_once($CFG->dirroot . '/backup/moodle2/restore_block_task.class.php'); 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'); @@ -46,6 +47,7 @@ require_once($CFG->dirroot . '/backup/moodle2/restore_gradingform_plugin.class.p 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'); diff --git a/backup/moodle2/restore_qtype_extrafields_plugin.class.php b/backup/moodle2/restore_qtype_extrafields_plugin.class.php new file mode 100644 index 00000000000..e976f38520c --- /dev/null +++ b/backup/moodle2/restore_qtype_extrafields_plugin.class.php @@ -0,0 +1,131 @@ +. + +/** + * Defines restore_qtype_extrafields_plugin class + * + * @package core_backup + * @copyright 2012 Oleg Sychev, Volgograd State Technical University + * @author Valeriy Streltsov + * @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); + } + } +} diff --git a/question/type/shortanswer/backup/moodle2/backup_qtype_shortanswer_plugin.class.php b/question/type/shortanswer/backup/moodle2/backup_qtype_shortanswer_plugin.class.php index 79713c4de10..05c14c4bdc1 100644 --- a/question/type/shortanswer/backup/moodle2/backup_qtype_shortanswer_plugin.class.php +++ b/question/type/shortanswer/backup/moodle2/backup_qtype_shortanswer_plugin.class.php @@ -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 { } diff --git a/question/type/shortanswer/backup/moodle2/restore_qtype_shortanswer_plugin.class.php b/question/type/shortanswer/backup/moodle2/restore_qtype_shortanswer_plugin.class.php index 1ec39417f82..73c77421659 100644 --- a/question/type/shortanswer/backup/moodle2/restore_qtype_shortanswer_plugin.class.php +++ b/question/type/shortanswer/backup/moodle2/restore_qtype_shortanswer_plugin.class.php @@ -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); } } diff --git a/question/type/upgrade.txt b/question/type/upgrade.txt index 6a74061f0d1..8bb92a8d954 100644 --- a/question/type/upgrade.txt +++ b/question/type/upgrade.txt @@ -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, -- 2.43.0