]> git.mjollnir.org Git - moodle.git/commitdiff
fix_course_sortorder(): fix breakage with large categories, saner error
authormartinlanghoff <martinlanghoff>
Wed, 12 Sep 2007 02:56:16 +0000 (02:56 +0000)
committermartinlanghoff <martinlanghoff>
Wed, 12 Sep 2007 02:56:16 +0000 (02:56 +0000)
Two improvements for fix_course_sortorder()

 - If the category has more courses than the shift range
   use a larger shift range to avoid overlapping with itself

 - If things do go wrong during the per-course sortorder updates,
   rollback and try and call ourselves with a 'safe' flag.

Still - far from perfect. Probably the global sortorder approach
is broken. The sanest way is to rework things to always join against
course_categories and order by the combined sortorders.

lib/datalib.php

index 0b2004c3c83aabb3ea3d79608cf2201bb7a601e6..f473cb5842e107f29b2e3da8ffcbe3f244b6f3e2 100644 (file)
@@ -960,6 +960,9 @@ function fix_course_sortorder($categoryid=0, $n=0, $safe=0, $depth=0, $path='')
         // special, optimized case where all we need is to shift
         if ( $mustshift && !$safe && !$hasgap) {
             $shift = $n + $catgap - $min;
+            if ($shift < $count) {
+                $shift = $count + $catgap;
+            }
             // UPDATE course SET sortorder=sortorder+$shift
             execute_sql("UPDATE {$CFG->prefix}course
                          SET sortorder=sortorder+$shift
@@ -979,13 +982,24 @@ function fix_course_sortorder($categoryid=0, $n=0, $safe=0, $depth=0, $path='')
 
             $courses = get_courses($categoryid, 'c.sortorder ASC', 'c.id,c.sortorder');
             begin_sql();
+            $tx = true; // transaction sanity
             foreach ($courses as $course) {
-                if ($course->sortorder != $n ) { // save db traffic
-                    set_field('course', 'sortorder', $n, 'id', $course->id);
+                if ($tx && $course->sortorder != $n ) { // save db traffic
+                    $tx = $tx && set_field('course', 'sortorder', $n,
+                                           'id', $course->id);
                 }
                 $n++;
             }
-            commit_sql();
+            if ($tx) {
+                commit_sql();
+            } else {
+                rollback_sql();
+                if (!$safe) {
+                    // if we failed when called with !safe, try
+                    // to recover calling self with safe=true
+                    return fix_course_sortorder($categoryid, $n, true, $depth, $path);
+                }
+            }
         }
     }
     set_field('course_categories', 'coursecount', $count, 'id', $categoryid);