Merge branch 'master_MDL-73763_index-fix' of https://github.com/catalyst/moodle-MDL-70329

This commit is contained in:
Ilya Tregubov 2022-03-24 13:14:03 +06:00
commit 7bedf54f5b
15 changed files with 89 additions and 25 deletions

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="lib/db" VERSION="20211221" COMMENT="XMLDB file for core Moodle tables"
<XMLDB PATH="lib/db" VERSION="20220323" COMMENT="XMLDB file for core Moodle tables"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
>
@ -1476,6 +1476,9 @@
<KEY NAME="usingcontextid" TYPE="foreign" FIELDS="usingcontextid" REFTABLE="context" REFFIELDS="id"/>
<KEY NAME="questionbankentryid" TYPE="foreign" FIELDS="questionbankentryid" REFTABLE="question_bank_entries" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="context-component-area-itemid" UNIQUE="true" FIELDS="usingcontextid, component, questionarea, itemid"/>
</INDEXES>
</TABLE>
<TABLE NAME="question_set_references" COMMENT="Records where groups of questions are used.">
<FIELDS>
@ -1492,6 +1495,9 @@
<KEY NAME="usingcontextid" TYPE="foreign" FIELDS="usingcontextid" REFTABLE="context" REFFIELDS="id"/>
<KEY NAME="questionscontextid" TYPE="foreign" FIELDS="questionscontextid" REFTABLE="context" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="context-component-area-itemid" UNIQUE="true" FIELDS="usingcontextid, component, questionarea, itemid"/>
</INDEXES>
</TABLE>
<TABLE NAME="question_answers" COMMENT="Answers, with a fractional grade (0-1) and feedback">
<FIELDS>

View File

@ -4253,5 +4253,37 @@ privatefiles,moodle|/user/files.php';
upgrade_main_savepoint(true, 2022031100.01);
}
if ($oldversion < 2022032200.01) {
// Define index to be added to question_references.
$table = new xmldb_table('question_references');
$index = new xmldb_index('context-component-area-itemid', XMLDB_INDEX_UNIQUE,
['usingcontextid', 'component', 'questionarea', 'itemid']);
// Conditionally launch add field id.
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
// Main savepoint reached.
upgrade_main_savepoint(true, 2022032200.01);
}
if ($oldversion < 2022032200.02) {
// Define index to be added to question_references.
$table = new xmldb_table('question_set_references');
$index = new xmldb_index('context-component-area-itemid', XMLDB_INDEX_UNIQUE,
['usingcontextid', 'component', 'questionarea', 'itemid']);
// Conditionally launch add field id.
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
// Main savepoint reached.
upgrade_main_savepoint(true, 2022032200.02);
}
return true;
}

View File

@ -435,7 +435,8 @@ class restore_quiz_activity_structure_step extends restore_questions_activity_st
$data->tagname = $tag->name;
}
$tagstring = "{$data->tagid},{$data->tagname}";
$setreferencedata = $DB->get_record('question_set_references', ['itemid' => $slotid]);
$setreferencedata = $DB->get_record('question_set_references',
['itemid' => $slotid, 'component' => 'mod_quiz', 'questionarea' => 'slot']);
$filtercondition = json_decode($setreferencedata->filtercondition);
$tagstrings = [];

View File

@ -70,7 +70,8 @@ class submit_question_version extends external_api {
$params = self::validate_parameters(self::execute_parameters(), $params);
$response = ['result' => false];
// Get the required data.
$referencedata = $DB->get_record('question_references', ['itemid' => $params['slotid']]);
$referencedata = $DB->get_record('question_references',
['itemid' => $params['slotid'], 'component' => 'mod_quiz', 'questionarea' => 'slot']);
$slotdata = $DB->get_record('quiz_slots', ['id' => $slotid]);
// Capability check.

View File

@ -400,7 +400,8 @@ class qbank_helper {
$alwaysuselatest->version = 0;
$alwaysuselatest->versionvalue = get_string('alwayslatest', 'quiz');
array_unshift($versionsoptions, $alwaysuselatest);
$referencedata = $DB->get_record('question_references', ['itemid' => $slotid]);
$referencedata = $DB->get_record('question_references',
['itemid' => $slotid, 'component' => 'mod_quiz', 'questionarea' => 'slot']);
if (!isset($referencedata->version) || ($referencedata->version === null)) {
$currentversion = 0;
} else {

View File

@ -661,7 +661,8 @@ class structure {
foreach ($slots as $slot) {
if ($slot->qtype === null) {
// Check if the question is random.
if ($setreference = $DB->get_record('question_set_references', ['itemid' => $slot->slotid])) {
if ($setreference = $DB->get_record('question_set_references',
['itemid' => $slot->slotid, 'component' => 'mod_quiz', 'questionarea' => 'slot'])) {
$filtercondition = json_decode($setreference->filtercondition);
$slot->id = $slot->slotid;
$slot->category = $filtercondition->questioncategoryid;
@ -965,7 +966,8 @@ class structure {
$questionsetreference = $DB->get_record('question_set_references',
['component' => 'mod_quiz', 'questionarea' => 'slot', 'itemid' => $slot->id]);
if ($questionsetreference) {
$DB->delete_records('question_set_references', ['id' => $questionsetreference->id]);
$DB->delete_records('question_set_references',
['id' => $questionsetreference->id, 'component' => 'mod_quiz', 'questionarea' => 'slot']);
}
$DB->delete_records('quiz_slots', array('id' => $slot->id));
for ($i = $slot->slot + 1; $i <= $maxslot; $i++) {

View File

@ -54,7 +54,8 @@ $PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
$PAGE->add_body_class('limitedwidth');
$setreference = $DB->get_record('question_set_references', ['itemid' => $slot->id]);
$setreference = $DB->get_record('question_set_references',
['itemid' => $slot->id, 'component' => 'mod_quiz', 'questionarea' => 'slot']);
$filterconditions = json_decode($setreference->filtercondition);
// Validate the question category.

View File

@ -1435,12 +1435,16 @@ function quiz_get_post_actions() {
function quiz_questions_in_use($questionids) {
global $DB;
list($test, $params) = $DB->get_in_or_equal($questionids);
$params['component'] = 'mod_quiz';
$params['questionarea'] = 'slot';
$sql = "SELECT qs.id
FROM {quiz_slots} qs
JOIN {question_references} qr ON qr.itemid = qs.id
JOIN {question_bank_entries} qbe ON qbe.id = qr.questionbankentryid
JOIN {question_versions} qv ON qv.questionbankentryid = qbe.id
WHERE qv.questionid $test";
WHERE qv.questionid $test
AND qr.component = ?
AND qr.questionarea = ?";
return $DB->record_exists_sql($sql, $params) || question_engine::questions_in_use(
$questionids, new qubaid_join('{quiz_attempts} quiza',
'quiza.uniqueid', 'quiza.preview = 0'));

View File

@ -2260,9 +2260,12 @@ function quiz_has_question_use($quiz, $slot) {
JOIN {question_bank_entries} qbe ON qbe.id = qre.questionbankentryid
JOIN {question_versions} qve ON qve.questionbankentryid = qbe.id
JOIN {question} q ON q.id = qve.questionid
WHERE slot.quizid = ? AND slot.slot = ?';
WHERE slot.quizid = ?
AND slot.slot = ?
AND qre.component = ?
AND qre.questionarea = ?';
$question = $DB->get_record_sql($sql, [$quiz->id, $slot]);
$question = $DB->get_record_sql($sql, [$quiz->id, $slot, 'mod_quiz', 'slot']);
if (!$question) {
return false;
@ -2306,9 +2309,11 @@ function quiz_add_quiz_question($questionid, $quiz, $page = 0, $maxmark = null)
FROM {quiz_slots} slot
JOIN {question_references} qr ON qr.itemid = slot.id
JOIN {question_bank_entries} qbe ON qbe.id = qr.questionbankentryid
WHERE slot.quizid = ?";
WHERE slot.quizid = ?
AND qr.component = ?
AND qr.questionarea = ?";
$questionslots = $DB->get_records_sql($sql, [$quiz->id]);
$questionslots = $DB->get_records_sql($sql, [$quiz->id, 'mod_quiz', 'slot']);
$currententry = get_question_bank_entry($questionid);
@ -2385,8 +2390,10 @@ function quiz_add_quiz_question($questionid, $quiz, $page = 0, $maxmark = null)
JOIN {question_references} qr ON qbe.id = qr.questionbankentryid AND qr.version = qv.version
JOIN {quiz_slots} qs ON qs.id = qr.itemid
WHERE q.id = ?
AND qs.id =?";
$qreferenceitem = $DB->get_record_sql($sql, [$questionid, $slotid]);
AND qs.id = ?
AND qr.component = ?
AND qr.questionarea = ?";
$qreferenceitem = $DB->get_record_sql($sql, [$questionid, $slotid, 'mod_quiz', 'slot']);
if (!$qreferenceitem) {
// Create a new reference record for questions created already.

View File

@ -706,8 +706,10 @@ class mod_quiz_structure_testcase extends advanced_testcase {
$sql = 'SELECT qsr.*
FROM {question_set_references} qsr
JOIN {quiz_slots} qs ON qs.id = qsr.itemid
WHERE qs.quizid = ?';
$randomq = $DB->get_record_sql($sql, [$quizobj->get_quizid()]);
WHERE qs.quizid = ?
AND qsr.component = ?
AND qsr.questionarea = ?';
$randomq = $DB->get_record_sql($sql, [$quizobj->get_quizid(), 'mod_quiz', 'slot']);
$structure->remove_slot(2);
@ -715,7 +717,8 @@ class mod_quiz_structure_testcase extends advanced_testcase {
$this->assert_quiz_layout(array(
array('TF1', 1, 'truefalse'),
), $structure);
$this->assertFalse($DB->record_exists('question_set_references', array('id' => $randomq->id)));
$this->assertFalse($DB->record_exists('question_set_references',
array('id' => $randomq->id, 'component' => 'mod_quiz', 'questionarea' => 'slot')));
}
/**

View File

@ -80,7 +80,8 @@ class mod_quiz_tags_testcase extends advanced_testcase {
$defaultcategory = question_get_default_category(context_course::instance($newcourseid)->id);
$this->assertEquals($defaultcategory->id, $question->categoryobject->id);
$randomincludingsubcategories = $DB->get_record('question_set_references', ['itemid' => reset($slots)->id]);
$randomincludingsubcategories = $DB->get_record('question_set_references',
['itemid' => reset($slots)->id, 'component' => 'mod_quiz', 'questionarea' => 'slot']);
$filtercondition = json_decode($randomincludingsubcategories->filtercondition);
$this->assertEquals(0, $filtercondition->includingsubcategories);
}

View File

@ -88,8 +88,10 @@ class helper_test extends \advanced_testcase {
$q2d = $DB->get_record_sql("SELECT qsr.*
FROM {quiz_slots} qs
JOIN {question_set_references} qsr ON qsr.itemid = qs.id
WHERE qs.quizid = ?",
['quizid' => $this->quiz->id], MUST_EXIST);
WHERE qs.quizid = ?
AND qsr.component = ?
AND qsr.questionarea = ?",
[$this->quiz->id, 'mod_quiz', 'slot'], MUST_EXIST);
// The following 2 lines have to be after the quiz_add_random_questions() call above.
// Otherwise, quiz_add_random_questions() will to be "smart" and use them instead of creating a new "random" question.
@ -138,7 +140,8 @@ class helper_test extends \advanced_testcase {
$this->assertFalse($DB->record_exists('question', ['id' => $q2a->id]));
$this->assertTrue($DB->record_exists('question', ['id' => $q2b->id]));
$this->assertFalse($DB->record_exists('question', ['id' => $q2c->id]));
$this->assertTrue($DB->record_exists('question_set_references', ['id' => $q2d->id]));
$this->assertTrue($DB->record_exists('question_set_references',
['id' => $q2d->id, 'component' => 'mod_quiz', 'questionarea' => 'slot']));
}
/**

View File

@ -37,7 +37,7 @@ class helper {
$sql = 'SELECT COUNT(*) FROM (' . self::question_usage_sql() . ') quizid';
return $DB->count_records_sql($sql, [$question->id, $question->questionbankentryid]);
return $DB->count_records_sql($sql, [$question->id, $question->questionbankentryid, 'mod_quiz', 'slot']);
}
/**
@ -65,7 +65,9 @@ class helper {
JOIN {question_references} qr ON qr.itemid = slot.id
JOIN {question_bank_entries} qbe ON qbe.id = qr.questionbankentryid
JOIN {question_versions} qv ON qv.questionbankentryid = qbe.id
WHERE qv.questionbankentryid = ?)";
WHERE qv.questionbankentryid = ?
AND qr.component = ?
AND qr.questionarea = ?)";
return $sqlset;
}

View File

@ -84,7 +84,7 @@ class question_usage_table extends table_sql {
}
$sql = helper::question_usage_sql();
$params = [$this->question->id, $this->question->questionbankentryid];
$params = [$this->question->id, $this->question->questionbankentryid, 'mod_quiz', 'slot'];
if (!$this->is_downloading()) {
$this->rawdata = $DB->get_records_sql($sql, $params, $this->get_page_start(), $this->get_page_size());

View File

@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2022032200.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2022032200.02; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '4.0beta+ (Build: 20220322)'; // Human-friendly version name