Skip to content

Commit 33a1b2c

Browse files
committed
#81: moving node now makes model dirty before saving it
1 parent efd1144 commit 33a1b2c

File tree

5 files changed

+100
-15
lines changed

5 files changed

+100
-15
lines changed

CHANGELOG.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* #82: Fixing tree now handles case when nodes pointing non-existing parent
1212
* The number of missing parent is now returned when using `countErrors`
1313
* #79: implemented scoping feature
14+
* #81: moving node now makes model dirty before saving it
1415

1516
### 3.1.1
1617

src/NodeTrait.php

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -195,14 +195,15 @@ protected function actionAppendOrPrepend(self $parent, $prepend = false)
195195
* Apply parent model.
196196
*
197197
* @param Model|null $value
198+
*
199+
* @return $this
198200
*/
199201
protected function setParent($value)
200202
{
201-
$this->attributes[$this->getParentIdName()] = $value
202-
? $value->getKey()
203-
: null;
203+
$this->setParentId( $value ? $value->getKey() : null)
204+
->setRelation('parent', $value);
204205

205-
$this->setRelation('parent', $value);
206+
return $this;
206207
}
207208

208209
/**
@@ -372,6 +373,10 @@ public function makeRoot()
372373
*/
373374
public function saveAsRoot()
374375
{
376+
if ($this->exists && $this->isRoot()) {
377+
return true;
378+
}
379+
375380
return $this->makeRoot()->save();
376381
}
377382

@@ -431,11 +436,10 @@ public function prependToNode(self $parent)
431436
*/
432437
public function appendOrPrependTo(self $parent, $prepend = false)
433438
{
434-
if ( ! $parent->exists) {
435-
throw new LogicException('Cannot use non-existing node as a parent.');
436-
}
439+
$this->assertNodeExists($parent)
440+
->assertNotDescendant($parent);
437441

438-
$this->setParent($parent);
442+
$this->setParent($parent)->dirtyBounds();
439443

440444
return $this->setAction('appendOrPrepend', $parent, $prepend);
441445
}
@@ -472,14 +476,14 @@ public function beforeNode(self $node)
472476
*/
473477
public function beforeOrAfterNode(self $node, $after = false)
474478
{
475-
if ( ! $node->exists) {
476-
throw new LogicException('Cannot insert before/after a node that does not exists.');
477-
}
479+
$this->assertNodeExists($node)->assertNotDescendant($node);
478480

479481
if ( ! $this->isSiblingOf($node)) {
480482
$this->setParent($node->getRelationValue('parent'));
481483
}
482484

485+
$this->dirtyBounds();
486+
483487
return $this->setAction('beforeOrAfter', $node, $after);
484488
}
485489

@@ -1069,26 +1073,74 @@ public function getBounds()
10691073

10701074
/**
10711075
* @param $value
1076+
*
1077+
* @return $this
10721078
*/
10731079
public function setLft($value)
10741080
{
10751081
$this->attributes[$this->getLftName()] = $value;
1082+
1083+
return $this;
10761084
}
10771085

10781086
/**
10791087
* @param $value
1088+
*
1089+
* @return $this
10801090
*/
10811091
public function setRgt($value)
10821092
{
10831093
$this->attributes[$this->getRgtName()] = $value;
1094+
1095+
return $this;
10841096
}
10851097

10861098
/**
10871099
* @param $value
1100+
*
1101+
* @return $this
10881102
*/
10891103
public function setParentId($value)
10901104
{
10911105
$this->attributes[$this->getParentIdName()] = $value;
1106+
1107+
return $this;
1108+
}
1109+
1110+
/**
1111+
* @return $this
1112+
*/
1113+
protected function dirtyBounds()
1114+
{
1115+
return $this->setLft(null)->setRgt(null);
1116+
}
1117+
1118+
/**
1119+
* @param NodeTrait $node
1120+
*
1121+
* @return $this
1122+
*/
1123+
protected function assertNotDescendant(self $node)
1124+
{
1125+
if ($node == $this || $node->isDescendantOf($this)) {
1126+
throw new LogicException('Node must not be a descendant.');
1127+
}
1128+
1129+
return $this;
1130+
}
1131+
1132+
/**
1133+
* @param NodeTrait $node
1134+
*
1135+
* @return $this
1136+
*/
1137+
protected function assertNodeExists(self $node)
1138+
{
1139+
if ( ! $node->getLft() || ! $node->getRgt()) {
1140+
throw new LogicException('Node must exists.');
1141+
}
1142+
1143+
return $this;
10921144
}
10931145

10941146
}

src/QueryBuilder.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,12 +439,10 @@ public function reversed()
439439
/**
440440
* Move a node to the new position.
441441
*
442-
* @param int $key
442+
* @param mixed $key
443443
* @param int $position
444444
*
445445
* @return int
446-
*
447-
* @throws \LogicException
448446
*/
449447
public function moveNode($key, $position)
450448
{

tests/NodeTest.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public function testFailsToAppendIntoItself()
231231
{
232232
$node = $this->findCategory('notebooks');
233233

234-
$node->appendTo($node)->save();
234+
$node->appendToNode($node)->save();
235235
}
236236

237237
/**
@@ -677,6 +677,27 @@ public function testParentIdDirtiness()
677677
$this->assertTrue($node->isDirty('parent_id'));
678678
}
679679

680+
public function testIsDirtyMovement()
681+
{
682+
$node = $this->findCategory('apple');
683+
$otherNode = $this->findCategory('samsung');
684+
685+
$this->assertFalse($node->isDirty());
686+
687+
$node->afterNode($otherNode);
688+
689+
$this->assertTrue($node->isDirty());
690+
691+
$node = $this->findCategory('apple');
692+
$otherNode = $this->findCategory('samsung');
693+
694+
$this->assertFalse($node->isDirty());
695+
696+
$node->appendToNode($otherNode);
697+
698+
$this->assertTrue($node->isDirty());
699+
}
700+
680701
public function testRootNodesMoving()
681702
{
682703
$node = $this->findCategory('store');

tests/ScopedNodeTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,19 @@ public function testDepth()
122122
$this->assertEquals(1, $result->first()->depth);
123123
}
124124

125+
public function testSaveAsRoot()
126+
{
127+
$node = MenuItem::find(5);
128+
129+
$node->saveAsRoot();
130+
131+
$this->assertEquals(5, $node->getLft());
132+
133+
$node = MenuItem::find(3);
134+
135+
$this->assertEquals(1, $node->getLft());
136+
}
137+
125138
public function testInsertion()
126139
{
127140
$node = MenuItem::create([ 'menu_id' => 1, 'parent_id' => 5 ]);

0 commit comments

Comments
 (0)