Nested Sets - Knoten auf- / abwärts verschieben

  • Themenstarter Themenstarter P_F
  • Beginndatum Beginndatum
P

P_F

HI, ich habe basierend auf dem Nested Sets Modell eine Klasse geschrieben, die es mir ermöglicht in verschiedenen Bereichen Baumstrukturen zu erstellen und effizient auszulesen.

Die Klasse und Ihre Methoden funktionieren alle super.

Nun möchte ich einige Methoden hinzufügen
- move_item_up( $item_id )
- move_item_down( $item_id )

Was schlagt Ihr vor? Wie müsste der Query aussehen? Es müssen ja schließlich alle linken und rechten grenzen geändert werden, wenn ein knoten verschoben wird, aber eben nur von den zwei betroffenen knoten (es ist also eher tauschen).

Hier meine Klasse
PHP:
<?php

class core_DBNestedSets {
    
    var $db_col_lft;
    
    var $db_col_rgt;
    
    var $db_col_id;
    
    var $db_col_parent_item_id;
    
    var $db_table;
    
    /**
     * sets some settings =)
     *
     * @param array $config
     */
    function init( $config=array() ) {
        
        if (is_array($config)) {
            
            $this->db_col_lft = $config['db_col_lft'];
            $this->db_col_rgt = $config['db_col_rgt'];
            $this->db_table = $config['db_table'];
            $this->db_col_id = $config['db_col_id'];
            $this->db_col_parent_item_id = $config['db_col_parent_item_id'];
            
        }
        
        $this->add_root_item();
        
    }
    
    /**
     * checks whether an item with id exists
     *
     * @param integer $item_id
     * @return boolean
     */
    function item_existst( $item_id=null ) {
        
        global $db;
        
        $sql =
        'SELECT ' . $this->db_col_id . 
        ' FROM ' . $this->db_table . 
        ' WHERE ' . $this->db_col_id . ' = ' . $item_id;
        
        return $db->GetOne($sql);
     
    }
    
    /**
     * adds an item with parent_item_id 
     *
     * @param integer $parent_item_id
     * @return boolean
     */
    function add_item( $parent_item_id=null ) {
        
        global $db, $err;
        
        $set = $this->get_set_limits( $parent_item_id );
    
        $db->Execute(
        'UPDATE ' . $this->db_table . 
        ' SET ' . $this->db_col_rgt . ' = ' . $this->db_col_rgt . '+2' . 
        ' WHERE ' . $this->db_col_rgt . ' >= ' . $set[1]);
    
        $db->Execute(
        'UPDATE ' . $this->db_table . 
        ' SET ' . $this->db_col_lft . ' = ' . $this->db_col_lft . '+2' .
        ' WHERE ' . $this->db_col_lft . ' > ' . $set[1]);
    
        $insert = array(
        'lft'   => $set[1],
        'rgt'   => $set[1]+1,
        'parent_item_id' => $parent_item_id
        );
    
        if ($db->AutoExecute( $this->db_table, $insert, 'INSERT' )) {
            
            return true;
            
        } else {
            
            $err->log(true, __FUNCTION__, 'Cannot add item. ' . mysql_error());
            return false;
            
        }
        
    }
    
    /**
     * if no items in database, add the root-item
     *
     */
    function add_root_item() {
        
        global $db;
        
        $db->Execute('SELECT ' . $this->db_col_id . ' FROM ' . $this->db_table );
        
        if ($db->Affected_Rows() == 0) {
            
            $insert = array(
            'lft'   => 1,
            'rgt'   => 2
            );
            
            $db->AutoExecute( $this->db_table, $insert, 'INSERT' );
            
        }  
                
    }
    
    /**
     * deletes item
     *  & ALL containing items 
     *
     * @param integer $item_id
     */
    function delete_item( $item_id=null ) {
        
        global $db;
        
        if ($item_id !== $this->get_root_item_id()) {
        
            $set = $this->get_set_limits( $item_id );
        
            $lft = $set[0];
            
            $rgt = $set[1];
            
            $range = ($rgt-$lft)+1;
            
            $db->Execute(
            'DELETE FROM ' . $this->db_table . 
            ' WHERE ' . $this->db_col_lft . ' BETWEEN ' . $lft . ' AND ' . $rgt);
            
            $db->Execute(
            'UPDATE ' . $this->db_table . 
            ' SET ' . $this->db_col_lft . '=' . $this->db_col_lft . '-' . $range . 
            ' WHERE ' . $this->db_col_lft . '>' . $rgt);
            
            $db->Execute(
            'UPDATE ' . $this->db_table . 
            ' SET ' . $this->db_col_rgt . '=' . $this->db_col_rgt . '-' . $range . 
            ' WHERE ' . $this->db_col_rgt . '>' . $rgt);
        
        }
    
    }
    
    /**
     * gets the lft & rgt values in array
     *
     * @param integer $item_id
     * @return array
     */
    function get_set_limits( $item_id=null ) {
        
        global $db;
        
        $db->SetFetchMode(ADODB_FETCH_NUM);
        
        $sql =
        'SELECT ' . $this->db_col_lft . ',' . $this->db_col_rgt . 
        ' FROM ' . $this->db_table . 
        ' WHERE ' . $this->db_col_id . ' = ' . $item_id;
        
        return $db->GetRow($sql);
        
    }
    
    /**
     * item with left set-limit = 1 should be the root-item
     *
     * @return mixed
     */
    function get_root_item_id() {
        
        global $db;
        
        $result = $db->GetOne(
        'SELECT ' . $this->db_col_id . 
        ' FROM ' . $this->db_table . 
        ' WHERE ' . $this->db_col_lft . ' = 1');
        
        return $result;
        
    }
    
    /**
     * gets the parent-item-id which is saved with method add_item
     *
     * @param integer $item_id
     * @return mixed
     */
    function get_parent_item_id( $item_id=null ) {
        
        global $db;
        
        $result = $db->GetOne(
        'SELECT ' . $this->db_col_parent_item_id . 
        ' FROM ' . $this->db_table . 
        ' WHERE ' . $this->db_col_id . ' = ' . $item_id);
        
        return $result;
        
    }
    
    
}

?>
 
Ok, ich habe mir heute ein bisschen den Kopf zerissen ...
es t, wer wissen möchte, wie muss fragen =)
 
Zurück