MDL-64242 qtype_essay: more efficient query in restore code
authorTim Hunt <T.J.Hunt@open.ac.uk>
Fri, 8 Feb 2019 15:52:44 +0000 (15:52 +0000)
committerTim Hunt <T.J.Hunt@open.ac.uk>
Fri, 8 Feb 2019 15:52:44 +0000 (15:52 +0000)
Thanks to Juan Ibarra for the suggestion that lead to this fix.

question/type/essay/backup/moodle2/restore_qtype_essay_plugin.class.php
question/type/essay/tests/restore_test.php [new file with mode: 0644]

index 36b929c..d806e4b 100644 (file)
@@ -95,15 +95,15 @@ class restore_qtype_essay_plugin extends restore_qtype_plugin {
         global $DB;
 
         $essayswithoutoptions = $DB->get_records_sql("
-                    SELECT *
+                    SELECT q.*
                       FROM {question} q
+                      JOIN {backup_ids_temp} bi ON bi.newitemid = q.id
+                 LEFT JOIN {qtype_essay_options} qeo ON qeo.questionid = q.id
                      WHERE q.qtype = ?
-                       AND NOT EXISTS (
-                        SELECT 1
-                          FROM {qtype_essay_options}
-                         WHERE questionid = q.id
-                     )
-                ", array('essay'));
+                       AND qeo.id IS NULL
+                       AND bi.backupid = ?
+                       AND bi.itemname = ?
+                ", array('essay', $this->get_restoreid(), 'question_created'));
 
         foreach ($essayswithoutoptions as $q) {
             $defaultoptions = new stdClass();
diff --git a/question/type/essay/tests/restore_test.php b/question/type/essay/tests/restore_test.php
new file mode 100644 (file)
index 0000000..4d2811b
--- /dev/null
@@ -0,0 +1,68 @@
+<?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/>.
+
+/**
+ * Test restore logic.
+ *
+ * @package    qtype_essay
+ * @copyright  2019 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->libdir . "/phpunit/classes/restore_date_testcase.php");
+
+/**
+ * Test restore logic.
+ *
+ * @copyright  2019 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class qtype_essay_restore_testcase extends restore_date_testcase  {
+
+    /**
+     * Test missing qtype_essay_options creation.
+     *
+     * Old backup files may contain essays with no qtype_essay_options record.
+     * During restore, we add default options for any questions like that.
+     * That is what is tested in this file.
+     */
+    public function test_restore_create_missing_qtype_essay_options() {
+        global $DB;
+
+        // Create a course with one essay question in its question bank.
+        $generator = $this->getDataGenerator();
+        $course = $generator->create_course();
+        $contexts = new question_edit_contexts(context_course::instance($course->id));
+        $category = question_make_default_categories($contexts->all());
+        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $essay = $questiongenerator->create_question('essay', null, array('category' => $category->id));
+
+        // Remove the options record, which means that the backup will look like a backup made in an old Moodle.
+        $DB->delete_records('qtype_essay_options', ['questionid' => $essay->id]);
+
+        // Do backup and restore.
+        $newcourseid = $this->backup_and_restore($course);
+
+        // Verify that the restored question has options.
+        $contexts = new question_edit_contexts(context_course::instance($newcourseid));
+        $newcategory = question_make_default_categories($contexts->all());
+        $newessay = $DB->get_record('question', ['category' => $newcategory->id, 'qtype' => 'essay']);
+        $this->assertTrue($DB->record_exists('qtype_essay_options', ['questionid' => $newessay->id]));
+    }
+}