示例#1
0
 /**
  * Move this item to the specified target.
  *
  * @chainable
  * @param   Item_Model $target Target node
  * @return  ORM_MTPP
  */
 function move_to($target)
 {
     if ($this->left_ptr <= $target->left_ptr && $this->right_ptr >= $target->right_ptr) {
         throw new Exception("@todo INVALID_TARGET can't move item inside itself");
     }
     $number_to_move = (int) (($this->right_ptr - $this->left_ptr) / 2 + 1);
     $size_of_hole = $number_to_move * 2;
     $original_left_ptr = $this->left_ptr;
     $original_right_ptr = $this->right_ptr;
     $target_right_ptr = $target->right_ptr;
     $level_delta = $target->level + 1 - $this->level;
     $this->lock();
     try {
         if ($level_delta) {
             // Update the levels for the to-be-moved items
             $this->db->query("UPDATE {{$this->table_name}} SET `level` = `level` + {$level_delta}" . " WHERE `left_ptr` >= {$original_left_ptr} AND `right_ptr` <= {$original_right_ptr}");
         }
         // Make a hole in the target for the move
         $target->db->query("UPDATE {{$this->table_name}} SET `left_ptr` = `left_ptr` + {$size_of_hole}" . " WHERE `left_ptr` >= {$target_right_ptr}");
         $target->db->query("UPDATE {{$this->table_name}} SET `right_ptr` = `right_ptr` + {$size_of_hole}" . " WHERE `right_ptr` >= {$target_right_ptr}");
         // Change the parent.
         $this->db->query("UPDATE {{$this->table_name}} SET `parent_id` = {$target->id}" . " WHERE `id` = {$this->id}");
         // If the source is to the right of the target then we just adjusted its left_ptr and right_ptr above.
         $left_ptr = $original_left_ptr;
         $right_ptr = $original_right_ptr;
         if ($original_left_ptr > $target_right_ptr) {
             $left_ptr += $size_of_hole;
             $right_ptr += $size_of_hole;
         }
         $new_offset = $target->right_ptr - $left_ptr;
         $this->db->query("UPDATE {{$this->table_name}}" . "   SET `left_ptr` = `left_ptr` + {$new_offset}," . "       `right_ptr` = `right_ptr` + {$new_offset}" . " WHERE `left_ptr` >= {$left_ptr}" . "   AND `right_ptr` <= {$right_ptr}");
         // Close the hole in the source's parent after the move
         $this->db->query("UPDATE {{$this->table_name}} SET `left_ptr` = `left_ptr` - {$size_of_hole}" . " WHERE `left_ptr` > {$right_ptr}");
         $this->db->query("UPDATE {{$this->table_name}} SET `right_ptr` = `right_ptr` - {$size_of_hole}" . " WHERE `right_ptr` > {$right_ptr}");
     } catch (Exception $e) {
         $this->unlock();
         throw $e;
     }
     $this->unlock();
     // Lets reload to get the changes.
     $this->reload();
     $target->reload();
     return $this;
 }