Merge branch 'wip-MDL-38228-m25' of git://github.com/marinaglancy/moodle into MOODLE_25_STABLE
This commit is contained in:
@@ -1603,6 +1603,8 @@ function xmldb_main_upgrade($oldversion) {
|
||||
}
|
||||
|
||||
if ($oldversion < 2013021801.01) {
|
||||
// This upgrade step is re-written under MDL-38228 (see below).
|
||||
/*
|
||||
// Retrieve the list of course_sections as a recordset to save memory
|
||||
$coursesections = $DB->get_recordset('course_sections', null, 'course, id', 'id, course, sequence');
|
||||
foreach ($coursesections as $coursesection) {
|
||||
@@ -1646,6 +1648,7 @@ function xmldb_main_upgrade($oldversion) {
|
||||
}
|
||||
}
|
||||
$coursesections->close();
|
||||
*/
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2013021801.01);
|
||||
@@ -1696,6 +1699,9 @@ function xmldb_main_upgrade($oldversion) {
|
||||
// This is checking to see if the site has been running a specific version with a bug in it
|
||||
// because this upgrade step is slow and is only needed if the site has been running with the affected versions.
|
||||
if ($oldversion >= 2012062504.08 && $oldversion < 2012062504.13) {
|
||||
// This upgrade step is re-written under MDL-38228 (see below).
|
||||
|
||||
/*
|
||||
// Retrieve the list of course_sections as a recordset to save memory.
|
||||
// This is to fix a regression caused by MDL-37939.
|
||||
// In this case the upgrade step is fixing records where:
|
||||
@@ -1754,6 +1760,7 @@ function xmldb_main_upgrade($oldversion) {
|
||||
$coursesections->close();
|
||||
|
||||
// No savepoint needed for this change.
|
||||
*/
|
||||
}
|
||||
|
||||
if ($oldversion < 2013032200.01) {
|
||||
@@ -2241,5 +2248,24 @@ function xmldb_main_upgrade($oldversion) {
|
||||
upgrade_main_savepoint(true, 2013051402.10);
|
||||
}
|
||||
|
||||
if ($oldversion < 2013051402.12) {
|
||||
// MDL-38228. Corrected course_modules upgrade script instead of 2013021801.01.
|
||||
|
||||
// This upgrade script fixes the mismatches between DB fields course_modules.section
|
||||
// and course_sections.sequence. It makes sure that each module is included
|
||||
// in the sequence of only one section and that course_modules.section points back to it.
|
||||
|
||||
// This script in included in each major version upgrade process so make sure we don't run it twice.
|
||||
if (empty($CFG->movingmoduleupgradescriptwasrun)) {
|
||||
upgrade_course_modules_sequences();
|
||||
|
||||
// To skip running the same script on the upgrade to the next major release.
|
||||
set_config('movingmoduleupgradescriptwasrun', 1);
|
||||
}
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2013051402.12);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -164,3 +164,147 @@ function upgrade_mysql_fix_unsigned_and_lob_columns() {
|
||||
$pbar->update($i, $tablecount, "Converted unsigned/lob columns in MySQL database - $i/$tablecount.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This upgrade script fixes the mismatches between DB fields course_modules.section
|
||||
* and course_sections.sequence. It makes sure that each module is included
|
||||
* in the sequence of only one section and that course_modules.section points back to it.
|
||||
*
|
||||
* Orphaned modules (modules that were not included in any section sequence in this course)
|
||||
* will be added to their sections (or 0-section if their section is not found) and
|
||||
* made invisible since they were not accessible at all before this upgrade script.
|
||||
*
|
||||
* Note that this script does not remove non-existing modules from section sequences since
|
||||
* such operation would require much more time.
|
||||
*/
|
||||
function upgrade_course_modules_sequences() {
|
||||
global $DB;
|
||||
|
||||
$affectedcourses = array();
|
||||
// Step 1. Find all modules that point to the section which does not point back to this module.
|
||||
$sequenceconcat = $DB->sql_concat("','", "s.sequence", "','");
|
||||
$moduleconcat = $DB->sql_concat("'%,'", "m.id", "',%'");
|
||||
$sql = "SELECT m.id, m.course, m.section, s.sequence
|
||||
FROM {course_modules} m LEFT OUTER JOIN {course_sections} s
|
||||
ON m.course = s.course and m.section = s.id
|
||||
WHERE s.sequence IS NULL OR ($sequenceconcat NOT LIKE $moduleconcat)
|
||||
ORDER BY m.course";
|
||||
$rs = $DB->get_recordset_sql($sql);
|
||||
$sections = null;
|
||||
foreach ($rs as $cm) {
|
||||
if (!isset($sections[$cm->course])) {
|
||||
// Retrieve all sections for the course (only once for each corrupt course).
|
||||
$sections = array($cm->course =>
|
||||
$DB->get_records('course_sections', array('course' => $cm->course),
|
||||
'section', 'id, section, sequence, visible'));
|
||||
if (empty($sections[$cm->course])) {
|
||||
// Very odd - the course has a module in it but has no sections. Create 0-section.
|
||||
$newsection = array('sequence' => '', 'section' => 0, 'visible' => 1);
|
||||
$newsection['id'] = $DB->insert_record('course_sections',
|
||||
$newsection + array('course' => $cm->course, 'summary' => '', 'summaryformat' => FORMAT_HTML));
|
||||
$sections[$cm->course] = array($newsection['id'] => (object)$newsection);
|
||||
}
|
||||
$affectedcourses[$cm->course] = true;
|
||||
}
|
||||
// Attempt to find the section that has this module in it's sequence.
|
||||
// If there are several of them, pick the last because this is what get_fast_modinfo() does.
|
||||
$sectionid = null;
|
||||
foreach ($sections[$cm->course] as $section) {
|
||||
if (!empty($section->sequence) && in_array($cm->id, preg_split('/,/', $section->sequence))) {
|
||||
$sectionid = $section->id;
|
||||
}
|
||||
}
|
||||
if ($sectionid) {
|
||||
// Found the section. Update course_module to point to the correct section.
|
||||
$params = array('id' => $cm->id, 'section' => $sectionid);
|
||||
if (!$sections[$cm->course][$sectionid]->visible) {
|
||||
$params['visible'] = 0;
|
||||
}
|
||||
$DB->update_record('course_modules', $params);
|
||||
} else {
|
||||
// No section in the course has this module in it's sequence.
|
||||
if (isset($sections[$cm->course][$cm->section])) {
|
||||
// Try to add module to the section it points to (if it is valid).
|
||||
$sectionid = $cm->section;
|
||||
} else {
|
||||
// Section not found. Just add to the first available section.
|
||||
reset($sections[$cm->course]);
|
||||
$sectionid = key($sections[$cm->course]);
|
||||
}
|
||||
$newsequence = ltrim($sections[$cm->course][$sectionid]->sequence . ',' . $cm->id, ',');
|
||||
$sections[$cm->course][$sectionid]->sequence = $newsequence;
|
||||
$DB->update_record('course_sections', array('id' => $sectionid, 'sequence' => $newsequence));
|
||||
// Make module invisible because it was not displayed at all before this upgrade script.
|
||||
$DB->update_record('course_modules', array('id' => $cm->id, 'section' => $sectionid, 'visible' => 0, 'visibleold' => 0));
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
unset($sections);
|
||||
|
||||
// Step 2. Find all modules that are listed in sequence of another section or listed in sequence of their section twice.
|
||||
$sequenceconcat = $DB->sql_concat("','", "s.sequence", "','");
|
||||
$moduleconcat = $DB->sql_concat("'%,'", "m.id", "',%'");
|
||||
$moduleconcatdup1 = $DB->sql_concat("'%,'", "m.id", "','", "m.id", "',%'");
|
||||
$moduleconcatdup2 = $DB->sql_concat("'%,'", "m.id", "',%,'", "m.id", "',%'");
|
||||
$sql = "SELECT m.id, m.course, m.section AS modulesectionid,
|
||||
s.id AS sectionid, s.sequence AS sectionsequence, s.section AS sectionsectionnum,
|
||||
ms.section AS modulesectionnum, ms.sequence AS modulesectionsequence
|
||||
FROM {course_modules} m JOIN {course_sections} s
|
||||
ON m.course = s.course AND
|
||||
(
|
||||
(m.section <> s.id AND $sequenceconcat LIKE $moduleconcat)
|
||||
OR
|
||||
(m.section = s.id AND $sequenceconcat LIKE $moduleconcatdup1)
|
||||
OR
|
||||
(m.section = s.id AND $sequenceconcat LIKE $moduleconcatdup2)
|
||||
)
|
||||
JOIN {course_sections} ms ON ms.id = m.section
|
||||
ORDER BY m.course, m.id, m.section DESC";
|
||||
$rs = $DB->get_recordset_sql($sql);
|
||||
$updatedsequences = array();
|
||||
$correctmodulesections = array();
|
||||
foreach ($rs as $cm) {
|
||||
$incorrectsectionid = $cm->sectionid;
|
||||
$incorrectsequence = $cm->sectionsequence;
|
||||
if (!isset($correctmodulesections[$cm->id])) {
|
||||
// Function get_fast_modinfo() believes that the section with the biggest sectionnum is the correct one.
|
||||
// Let's correct everything else to match with how course is displayed to the students.
|
||||
if ($cm->modulesectionnum > $cm->sectionsectionnum) {
|
||||
$correctmodulesections[$cm->id] = $cm->modulesectionid;
|
||||
} else {
|
||||
$correctmodulesections[$cm->id] = $cm->sectionid;
|
||||
// oops our module points to the wrong section.
|
||||
$DB->update_record('course_modules', array('id' => $cm->id,
|
||||
'section' => $correctmodulesections[$cm->id]));
|
||||
$incorrectsectionid = $cm->modulesectionid;
|
||||
$incorrectsequence = $cm->modulesectionsequence;
|
||||
}
|
||||
}
|
||||
if (isset($updatedsequences[$incorrectsectionid])) {
|
||||
$sequence = $updatedsequences[$incorrectsectionid];
|
||||
} else {
|
||||
$sequence = preg_split('/,/', $incorrectsequence);
|
||||
}
|
||||
if ($correctmodulesections[$cm->id] <> $incorrectsectionid) {
|
||||
// Remove all occurences of module id from section sequence.
|
||||
$sequence = array_diff($sequence, array($cm->id));
|
||||
} else {
|
||||
// Remove all occurences of module id from section sequence except for the first one.
|
||||
if (($idx = array_search($cm->id, $sequence)) !== false) {
|
||||
$firstchunk = array_splice($sequence, 0, $idx+1);
|
||||
$sequence = array_merge($firstchunk, array_diff($sequence, array($cm->id)));
|
||||
}
|
||||
}
|
||||
$updatedsequences[$incorrectsectionid] = array_values($sequence);
|
||||
$DB->update_record('course_sections', array('id' => $incorrectsectionid,
|
||||
'sequence' => join(',', $sequence)));
|
||||
$affectedcourses[$cm->course] = true;
|
||||
}
|
||||
$rs->close();
|
||||
|
||||
// Reset course cache for affected courses.
|
||||
if (!empty($affectedcourses)) {
|
||||
list($sql, $params) = $DB->get_in_or_equal(array_keys($affectedcourses));
|
||||
$DB->execute("UPDATE {course} SET modinfo = null WHERE id ".$sql, $params);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2013051402.11; // 20130514 = branching date YYYYMMDD - do not modify!
|
||||
$version = 2013051402.12; // 20130514 = branching date YYYYMMDD - do not modify!
|
||||
// RR = release increments - 00 in DEV branches
|
||||
// .XX = incremental changes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user