MDL-47494 gapselect: Update quiz and questions backup and restore.
authorTim Hunt <T.J.Hunt@open.ac.uk>
Mon, 28 Feb 2011 10:49:20 +0000 (10:49 +0000)
committerTim Hunt <T.J.Hunt@open.ac.uk>
Wed, 2 Mar 2011 17:42:51 +0000 (17:42 +0000)
This does not include user data yet, and it needs more testing.

question/type/gapselect/backup/moodle2/backup_qtype_gapselect_plugin.class.php [new file with mode: 0755]
question/type/gapselect/backup/moodle2/restore_qtype_gapselect_plugin.class.php [new file with mode: 0755]

diff --git a/question/type/gapselect/backup/moodle2/backup_qtype_gapselect_plugin.class.php b/question/type/gapselect/backup/moodle2/backup_qtype_gapselect_plugin.class.php
new file mode 100755 (executable)
index 0000000..a1c542c
--- /dev/null
@@ -0,0 +1,84 @@
+<?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/>.
+
+/**
+ * @package    moodlecore
+ * @subpackage backup-moodle2
+ * @copyright  2011 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+defined('MOODLE_INTERNAL') || die();
+
+
+/**
+ * Provides the information to backup gapselect questions
+ *
+ * @copyright  2011 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class backup_qtype_gapselect_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', 'gapselect');
+
+        // 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
+        $gapselect = new backup_nested_element('gapselect', array('id'), array(
+            'shuffleanswers', 'correctfeedback', 'correctfeedbackformat',
+            'partiallycorrectfeedback', 'partiallycorrectfeedbackformat',
+            'incorrectfeedback', 'incorrectfeedbackformat', 'shownumcorrect'));
+
+        // Now the own qtype tree
+        $pluginwrapper->add_child($gapselect);
+
+        // set source to populate the data
+        $gapselect->set_source_table('question_gapselect', array('questionid' => backup::VAR_PARENTID));
+
+        // don't need to annotate ids nor files
+
+        return $plugin;
+    }
+
+    /**
+     * Returns one array with filearea => mappingname elements for the qtype
+     *
+     * Used by {@link get_components_and_fileareas} to know about all the qtype
+     * files to be processed both in backup and restore.
+     */
+    public static function get_qtype_fileareas() {
+        return array(
+            'correctfeedback' => 'question_created',
+            'partiallycorrectfeedback' => 'question_created',
+            'incorrectfeedback' => 'question_created');
+    }
+}
diff --git a/question/type/gapselect/backup/moodle2/restore_qtype_gapselect_plugin.class.php b/question/type/gapselect/backup/moodle2/restore_qtype_gapselect_plugin.class.php
new file mode 100755 (executable)
index 0000000..34dbf81
--- /dev/null
@@ -0,0 +1,136 @@
+<?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/>.
+
+/**
+ * @package    moodlecore
+ * @subpackage backup-moodle2
+ * @copyright  2011 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+defined('MOODLE_INTERNAL') || die();
+
+
+/**
+ * restore plugin class that provides the necessary information
+ * needed to restore one gapselect qtype plugin
+ *
+ * @copyright  2011 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class restore_qtype_gapselect_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 = 'gapselect';
+        $elepath = $this->get_pathfor('/gapselect'); // we used get_recommended_name() so this works
+        $paths[] = new restore_path_element($elename, $elepath);
+
+
+        return $paths; // And we return the interesting paths
+    }
+
+    /**
+     * Process the qtype/gapselect element
+     */
+    public function process_gapselect($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 question_gapselect too
+        if ($questioncreated) {
+            // Adjust some columns
+            $data->questionid = $newquestionid;
+            // Insert record
+            $newitemid = $DB->insert_record('question_gapselect', $data);
+            // Create mapping (needed for decoding links)
+            $this->set_mapping('question_gapselect', $oldid, $newitemid);
+        } else {
+            // Nothing to remap if the question already existed
+        }
+    }
+
+    /**
+     * Given one question_states record, return the answer
+     * recoded pointing to all the restored stuff for gapselect questions
+     *
+     * answer are two (hypen speparated) lists of comma separated question_answers
+     * the first to specify the order of the answers and the second to specify the
+     * responses. Note the order list (the first one) can be optional
+     */
+    public function recode_state_answer($state) {
+        $answer = $state->answer;
+        $orderarr = array();
+        $responsesarr = array();
+        $lists = explode(':', $answer);
+        // if only 1 list, answer is missing the order list, adjust
+        if (count($lists) == 1) {
+            $lists[1] = $lists[0]; // here we have the responses
+            $lists[0] = '';        // here we have the order
+        }
+        // Map order
+        foreach (explode(',', $lists[0]) as $id) {
+            if (!empty($id) && $newid = $this->get_mappingid('question_answer', $id)) {
+                $orderarr[] = $newid;
+            }
+        }
+        // Map responses
+        foreach (explode(',', $lists[1]) as $id) {
+            if (!empty($id) && $newid = $this->get_mappingid('question_answer', $id)) {
+                $responsesarr[] = $newid;
+            }
+        }
+        // Build the final answer, if not order, only responses
+        $result = '';
+        if (empty($orderarr)) {
+            $result = implode(',', $responsesarr);
+        } else {
+            $result = implode(',', $orderarr) . ':' . implode(',', $responsesarr);
+        }
+        return $result;
+    }
+
+    /**
+     * Return the contents of this qtype to be processed by the links decoder
+     */
+    static public function define_decode_contents() {
+
+        $contents = array();
+
+        $fields = array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback');
+        $contents[] = new restore_decode_content('question_gapselect', $fields, 'question_gapselect');
+
+        return $contents;
+    }
+}