Index: blocklib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/blocklib.php,v
retrieving revision 1.119.2.4
diff -u -r1.119.2.4 blocklib.php
--- blocklib.php	19 Jul 2007 06:04:03 -0000	1.119.2.4
+++ blocklib.php	27 Sep 2007 16:17:39 -0000
@@ -568,9 +568,36 @@
                 // This configuration will make sure that even if somehow the weights
                 // become not continuous, block move operations will eventually bring
                 // the situation back to normal without printing any warnings.
+				
+                /*
+
+                Steve Bond <clt-support@lse.ac.uk> 27/9/07 : 
+                
+                This is a bug. The 'weight' key in $pageblocks is not unique and cannot be 
+                used to identify $other (i.e. the block that is moving down to take the place 
+                of the one we are moving up). This is because blocks_get_by_page_pinned(), 
+                which creates $pageblocks, simply sticks the pinned and user blocks together 
+                in a single array, without accounting for that fact that the values of 'weight' 
+                for pinned and user blocks can be the same.
+
+                Therefore, to find the target block, we need to loop backwards through 
+                $pageblocks until we find a block with a weight that is one less than the 
+                block being moved. This is clumsy, but it's the quickest solution I could think of.  */
+
+                /*
                 if(!empty($pageblocks[$instance->position][$instance->weight - 1])) {
                     $other = $pageblocks[$instance->position][$instance->weight - 1];
                 }
+                */
+
+                for ($blk = count($pageblocks[$instance->position]) - 1; $blk >= 0; $blk--) {
+				    $thisblock = $pageblocks[$instance->position][$blk];
+				    if ($thisblock->weight == $instance->weight - 1) {
+					    $other = $thisblock;
+						break;
+					}
+				}
+
                 if(!empty($other)) {
                     ++$other->weight;
                     if (!empty($pinned)) {
@@ -605,9 +632,28 @@
                 // This configuration will make sure that even if somehow the weights
                 // become not continuous, block move operations will eventually bring
                 // the situation back to normal without printing any warnings.
+				
+                /*
+                Steve Bond <clt-support@lse.ac.uk> 27/9/07: 
+                
+                Same bug as above in case: 'moveup'. See there for explanation.
+                */
+
+                /*
                 if(!empty($pageblocks[$instance->position][$instance->weight + 1])) {
                     $other = $pageblocks[$instance->position][$instance->weight + 1];
                 }
+                */
+
+                for ($blk = count($pageblocks[$instance->position]) - 1; $blk >= 0; $blk--) {
+				    $thisblock = $pageblocks[$instance->position][$blk];
+				    if ($thisblock->weight == $instance->weight + 1) {
+					    $other = $thisblock;
+						break;
+					}
+				}
+
+		
                 if(!empty($other)) {
                     --$other->weight;
                     if (!empty($pinned)) {

