Skip to content

Commit

Permalink
Merge branch 'MDL-54864-master' of https://github.com/snake/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
danpoltawski committed Aug 22, 2016
2 parents ccee2dc + d7d4a09 commit cfbba4a
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/db/install.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,7 @@
</KEYS>
<INDEXES>
<INDEX NAME="contextid" UNIQUE="false" FIELDS="contextid" COMMENT="links to context table"/>
<INDEX NAME="contextidstamp" UNIQUE="true" FIELDS="contextid, stamp"/>
</INDEXES>
</TABLE>
<TABLE NAME="question" COMMENT="The questions themselves">
Expand Down
53 changes: 53 additions & 0 deletions lib/db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -2124,5 +2124,58 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2016081700.02);
}

if ($oldversion < 2016082200.00) {
// An upgrade step to remove any duplicate stamps, within the same context, in the question_categories table, and to
// add a unique index to (contextid, stamp) to avoid future stamp duplication. See MDL-54864.

// Extend the execution time limit of the script to 2 hours.
upgrade_set_timeout(7200);

// This SQL fetches the id of those records which have duplicate stamps within the same context.
// This doesn't return the original record within the context, from which the duplicate stamps were likely created.
$fromclause = "FROM (
SELECT min(id) AS minid, contextid, stamp
FROM {question_categories}
GROUP BY contextid, stamp
) minid
JOIN {question_categories} qc
ON qc.contextid = minid.contextid AND qc.stamp = minid.stamp AND qc.id > minid.minid";

// Get the total record count - used for the progress bar.
$countduplicatessql = "SELECT count(qc.id) $fromclause";
$total = $DB->count_records_sql($countduplicatessql);

// Get the records themselves.
$getduplicatessql = "SELECT qc.id $fromclause ORDER BY minid";
$rs = $DB->get_recordset_sql($getduplicatessql);

// For each duplicate, update the stamp to a new random value.
$i = 0;
$pbar = new progress_bar('updatequestioncategorystamp', 500, true);
foreach ($rs as $record) {
// Generate a new, unique stamp and update the record.
do {
$newstamp = make_unique_id_code();
} while (isset($usedstamps[$newstamp]));
$usedstamps[$newstamp] = 1;
$DB->set_field('question_categories', 'stamp', $newstamp, array('id' => $record->id));

// Update progress.
$i++;
$pbar->update($i, $total, "Updating duplicate question category stamp - $i/$total.");
}
unset($usedstamps);

// The uniqueness of each (contextid, stamp) pair is now guaranteed, so add the unique index to stop future duplicates.
$table = new xmldb_table('question_categories');
$index = new xmldb_index('contextidstamp', XMLDB_INDEX_UNIQUE, array('contextid', 'stamp'));
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}

// Savepoint reached.
upgrade_main_savepoint(true, 2016082200.00);
}

return true;
}
11 changes: 10 additions & 1 deletion question/category_class.php
Original file line number Diff line number Diff line change
Expand Up @@ -454,10 +454,16 @@ public function update_category($updateid, $newparent, $newname, $newinfo, $newi
$fromcontext = context::instance_by_id($oldcat->contextid);
require_capability('moodle/question:managecategory', $fromcontext);

// If moving to another context, check permissions some more.
// If moving to another context, check permissions some more, and confirm contextid,stamp uniqueness.
$newstamprequired = false;
if ($oldcat->contextid != $tocontextid) {
$tocontext = context::instance_by_id($tocontextid);
require_capability('moodle/question:managecategory', $tocontext);

// Confirm stamp uniqueness in the new context. If the stamp already exists, generate a new one.
if ($DB->record_exists('question_categories', array('contextid' => $tocontextid, 'stamp' => $oldcat->stamp))) {
$newstamprequired = true;
}
}

// Update the category record.
Expand All @@ -468,6 +474,9 @@ public function update_category($updateid, $newparent, $newname, $newinfo, $newi
$cat->infoformat = $newinfoformat;
$cat->parent = $parentid;
$cat->contextid = $tocontextid;
if ($newstamprequired) {
$cat->stamp = make_unique_id_code();
}
$DB->update_record('question_categories', $cat);

// If the category name has changed, rename any random questions in that category.
Expand Down
2 changes: 1 addition & 1 deletion question/tests/generator/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function create_question_category($record = null) {
'contextid' => context_system::instance()->id,
'info' => '',
'infoformat' => FORMAT_HTML,
'stamp' => '',
'stamp' => make_unique_id_code(),
'parent' => 0,
'sortorder' => 999,
);
Expand Down
2 changes: 1 addition & 1 deletion version.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

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

$version = 2016081700.02; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2016082200.00; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.

Expand Down

0 comments on commit cfbba4a

Please sign in to comment.