please, could you provide me your help? I'm trying to make my own small NestedSet library. Everything is ok, except three methods: move after, move before and move inside. I don't know why, but it still badly recount lft and rgt for nested set items... but I can't see any problem in my code... Could you help me, what I'm doing bad or provide some example nested set library, which implements this 3 methods to inspire a edit my code? Thank you very much.
I use Laravel5 DB class methods, but there is no problem to use plain mysql queries.
Here is my code:
/**
*
* @param $targetId
* @param $pos
* @param int $levelUp
*/
public function moveNode($targetId, $pos, $levelUp = 0){
$width = $this->rgt - $this->lft + 1; // get moved item width
$target = $this->getLeaf($targetId);
switch($pos) {
case 'after':
$newLeftPos = $target->rgt + 1;
break;
case 'before':
$newLeftPos = $target->lft;
break;
case 'inside':
$newLeftPos = $target->lft + 1;
break;
}
$moveLength = $newLeftPos - $this->lft; // get length of move
$newNodeLvl = $target->lvl + $levelUp;
$nodeLvlDifference = $newNodeLvl - $this->lvl;
// get moving node items
// store ids of moving node items into array to use it in moving node....
$ids = [];
$primaryKeyName = $this->primaryKey;
$node = DB::table($this->table)
->where('lft', '>=', $this->lft)
->where('rgt', '<=', $this->rgt)
->get();
foreach($node as $nodeItem) {
$ids[] = $nodeItem->$primaryKeyName;
}
// FIRSTLY I WANT TO DELETE OLD NODE SPACE SO I WILL DECREASE lft > $this->rgt AND rgt > $this->rgt BY WIDTH OF
// MOVING NODE
DB::table($this->table)
->where('lft', '>', $this->rgt)
->decrement('lft', $width);
DB::table($this->table)
->where('rgt', '>', $this->rgt)
->decrement('rgt', $width);
// NOW I WILL MAKE FREE SPACE FOR MY NODE
// SO I NEED TO INCREASE lft AND rgt OF ITEMS WHICH ARE > $newLeftPos
// I WILL INCREASE IT AT EACH ITEMS EXCEPT ITEMS WITH id IN $ids ARRAY (ids of items in moving node)
DB::table($this->table)
->where('lft', '>=', $newLeftPos)
->whereNotIn($primaryKeyName, $ids)
->increment('lft', $width);
DB::table($this->table)
->where('rgt', '>=', $newLeftPos)
->whereNotIn($primaryKeyName, $ids)
->increment('rgt', $width);
// NOW I WILL MOVE NODE TO ITS NEW POSITION
// ALSO I CHANGE NODE ITEMS lvl
$nodeItems = DB::table($this->table)
->whereIn($primaryKeyName, $ids);
$nodeItems->increment('rgt', $moveLength);
$nodeItems->increment('lft', $moveLength);
if($newNodeLvl !== 0) {
$nodeItems->increment('lvl', $nodeLvlDifference);
}
}