diff --git a/.styleci.yml b/.styleci.yml index 5b7ddb2..9fae20e 100644 --- a/.styleci.yml +++ b/.styleci.yml @@ -84,3 +84,4 @@ enabled: disabled: - function_declaration + - new_with_parentheses diff --git a/src/NestedSetsBehavior.php b/src/NestedSetsBehavior.php index 038bcf6..c2347b4 100644 --- a/src/NestedSetsBehavior.php +++ b/src/NestedSetsBehavior.php @@ -1055,10 +1055,11 @@ protected function beforeInsertNode(int|null $value, int $depth): void } $nodeDepthValue = $this->node?->getAttribute($this->depthAttribute) ?? 0; + $this->getOwner()->setAttribute($this->depthAttribute, $nodeDepthValue + $depth); - if ($this->treeAttribute !== false) { - $this->getOwner()->setAttribute($this->treeAttribute, $this->node?->getAttribute($this->treeAttribute)); + if ($this->treeAttribute !== false && $this->node !== null) { + $this->getOwner()->setAttribute($this->treeAttribute, $this->node->getAttribute($this->treeAttribute)); } $this->shiftLeftRightAttribute($value ?? 0, 2); diff --git a/tests/NestedSetsBehaviorTest.php b/tests/NestedSetsBehaviorTest.php index d311816..4553b45 100644 --- a/tests/NestedSetsBehaviorTest.php +++ b/tests/NestedSetsBehaviorTest.php @@ -1620,4 +1620,103 @@ public function makeRoot(): bool $node->makeRoot(); } + + public function testSetNodeToNullAndCallBeforeInsertNodeSetsLftRgtAndDepth(): void + { + $this->createDatabase(); + + $behavior = new class extends NestedSetsBehavior { + public function callBeforeInsertNode(int|null $value, int $depth): void + { + $this->beforeInsertNode($value, $depth); + } + + public function setNodeToNull(): void + { + $this->node = null; + } + + public function getNodeDepth(): int|null + { + return $this->node !== null ? $this->node->getAttribute($this->depthAttribute) : null; + } + }; + + $newNode = new Tree(['name' => 'Test Node']); + + $newNode->attachBehavior('testBehavior', $behavior); + $behavior->setNodeToNull(); + $behavior->callBeforeInsertNode(5, 1); + + self::assertEquals( + 5, + $newNode->lft, + '\'beforeInsertNode\' should set \'lft\' attribute to \'5\' on the new node.', + ); + self::assertEquals( + 6, + $newNode->rgt, + '\'beforeInsertNode\' should set \'rgt\' attribute to \'6\' on the new node.', + ); + + $actualDepth = $newNode->getAttribute('depth'); + + self::assertEquals( + 1, + $actualDepth, + '\'beforeInsertNode\' method should set \'depth\' attribute to \'1\' on the new node.', + ); + } + + public function testAppendChildNodeToRootCreatesValidTreeStructure(): void + { + $this->createDatabase(); + + $root = new Tree(['name' => 'Root']); + + $root->makeRoot(); + + self::assertEquals( + 1, + $root->lft, + 'Root node left value should be \'1\' after \'makeRoot\'.', + ); + self::assertEquals( + 2, + $root->rgt, + 'Root node right value should be \'2\' after \'makeRoot\'.', + ); + self::assertEquals( + 0, + $root->depth, + 'Root node depth should be \'0\' after \'makeRoot\'.', + ); + + $child = new Tree(['name' => 'Child']); + + try { + $result = $child->appendTo($root); + + self::assertTrue( + $result, + '\'appendTo\' should return \'true\' when successfully appending a child node.', + ); + + $root->refresh(); + $child->refresh(); + + self::assertGreaterThan( + $child->lft, + $child->rgt, + 'Child node right value should be greater than its left value after \'appendTo\'.', + ); + self::assertEquals( + 1, + $child->depth, + 'Child node depth should be \'1\' after being appended to the root node.', + ); + } catch (Exception $e) { + self::fail('Real insertion failed: ' . $e->getMessage()); + } + } }