Skip to content

Commit e7174b5

Browse files
committed
Added fixTree method
1 parent 5316e01 commit e7174b5

File tree

4 files changed

+74
-7
lines changed

4 files changed

+74
-7
lines changed

CHANGELOG.markdown

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### 3.1.0
2+
3+
* Added `fixTree` method for fixing `lft`/`rgt` values based on parenting
4+
15
### 3.0.0
26

37
* Support Laravel 5.1.9

src/Node.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,15 +1196,15 @@ public function getBounds()
11961196
/**
11971197
* @param $value
11981198
*/
1199-
protected function setLft($value)
1199+
public function setLft($value)
12001200
{
12011201
$this->setAttribute($this->getLftName(), $value);
12021202
}
12031203

12041204
/**
12051205
* @param $value
12061206
*/
1207-
protected function setRgt($value)
1207+
public function setRgt($value)
12081208
{
12091209
$this->setAttribute($this->getRgtName(), $value);
12101210
}

src/QueryBuilder.php

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,10 @@
22

33
namespace Kalnoy\Nestedset;
44

5+
use Illuminate\Database\Eloquent\Builder;
56
use Illuminate\Database\Eloquent\ModelNotFoundException;
67
use Illuminate\Database\Query\Builder as Query;
78
use LogicException;
8-
use Illuminate\Database\Eloquent\Builder;
9-
use Illuminate\Database\ConnectionInterface;
10-
use Illuminate\Database\Query\Grammars\Grammar;
11-
use Illuminate\Database\Query\Processors\Processor;
129
use Illuminate\Database\Query\Expression;
1310

1411
class QueryBuilder extends Builder {
@@ -579,4 +576,59 @@ public function countErrors()
579576

580577
return (array)$query->first();
581578
}
579+
580+
/**
581+
* Fixes the tree based on parentage info.
582+
*
583+
* Requires at least one root node. This will not update nodes with invalid parent.
584+
*
585+
* @return int The number of fixed nodes.
586+
*/
587+
public function fixTree()
588+
{
589+
$columns = [
590+
$this->model->getKeyName(),
591+
$this->model->getParentIdName(),
592+
$this->model->getLftName(),
593+
$this->model->getRgtName(),
594+
];
595+
596+
$nodes = $this->defaultOrder()->get($columns)->groupBy($this->model->getParentIdName());
597+
598+
$this->reorderNodes($nodes, $fixed);
599+
600+
return $fixed;
601+
}
602+
603+
/**
604+
* @param Collection $models
605+
* @param int $fixed
606+
* @param $parentId
607+
* @param int $cut
608+
*
609+
* @return int
610+
*/
611+
protected function reorderNodes(Collection $models, &$fixed, $parentId = null, $cut = 1)
612+
{
613+
/** @var Node $model */
614+
foreach ($models->get($parentId, []) as $model)
615+
{
616+
$model->setLft($cut);
617+
618+
$cut = $this->reorderNodes($models, $fixed, $model->getKey(), $cut + 1);
619+
620+
$model->setRgt($cut);
621+
622+
if ($model->isDirty())
623+
{
624+
$model->save();
625+
626+
$fixed++;
627+
}
628+
629+
++$cut;
630+
}
631+
632+
return $cut;
633+
}
582634
}

tests/NodeTest.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public function assertTreeNotBroken($table = 'categories')
7070

7171
public function dumpTree($items = null)
7272
{
73-
if ( ! $items) $items = Category::withTrashed()->get();
73+
if ( ! $items) $items = Category::withTrashed()->defaultOrder()->get();
7474

7575
foreach ($items as $item)
7676
{
@@ -616,6 +616,17 @@ public function testMultipleDeletionsDoNotBrakeTree()
616616

617617
$this->assertTreeNotBroken();
618618
}
619+
620+
public function testTreeIsFixed()
621+
{
622+
Category::where('id', '=', 5)->update([ '_lft' => 14 ]);
623+
Category::where('id', '=', 8)->update([ 'parent_id' => 2 ]);
624+
625+
$fixed = Category::fixTree();
626+
627+
$this->assertTrue($fixed > 0);
628+
$this->assertTreeNotBroken();
629+
}
619630
}
620631

621632
function all($items)

0 commit comments

Comments
 (0)