diff --git a/src/Storage/DbalNestedSet.php b/src/Storage/DbalNestedSet.php index 3bb93bd0..ab424ee9 100644 --- a/src/Storage/DbalNestedSet.php +++ b/src/Storage/DbalNestedSet.php @@ -211,7 +211,7 @@ public function getTree() { $tree = []; $stmt = $this->connection->executeQuery('SELECT id, revision_id, left_pos, right_pos, depth FROM ' . $this->tableName . ' ORDER BY left_pos'); while ($row = $stmt->fetch()) { - $tree[] = new Node($row['id'], $row['revision_id'], $row['left_pos'], $row['right_pos'], $row['depth']); + $tree[] = new Node(new NodeKey($row['id'], $row['revision_id']), $row['left_pos'], $row['right_pos'], $row['depth']); } return $tree; } @@ -308,7 +308,7 @@ public function moveSubTreeToRoot(Node $node) { */ public function moveSubTreeBelow(Node $target, Node $node) { $newLeftPosition = $target->getLeft() + 1; - $this->moveSubTreeToPosition($newLeftPosition, $node); + $this->moveSubTreeToPosition($newLeftPosition, $node, $target->getDepth() + 1); } /** @@ -316,7 +316,7 @@ public function moveSubTreeBelow(Node $target, Node $node) { */ public function moveSubTreeBefore(Node $target, Node $node) { $newLeftPosition = $target->getLeft(); - $this->moveSubTreeToPosition($newLeftPosition, $node); + $this->moveSubTreeToPosition($newLeftPosition, $node, $target->getDepth()); } /** @@ -324,7 +324,7 @@ public function moveSubTreeBefore(Node $target, Node $node) { */ public function moveSubTreeAfter(Node $target, Node $node) { $newLeftPosition = $target->getRight() + 1; - $this->moveSubTreeToPosition($newLeftPosition, $node); + $this->moveSubTreeToPosition($newLeftPosition, $node, $target->getDepth()); } /** @@ -334,11 +334,13 @@ public function moveSubTreeAfter(Node $target, Node $node) { * The new left position. * @param \PNX\NestedSet\Node $node * The node to move. + * @param int $newDepth + * Depth of new position. * * @throws \Exception * If a transaction error occurs. */ - protected function moveSubTreeToPosition($newLeftPosition, Node $node) { + protected function moveSubTreeToPosition($newLeftPosition, Node $node, $newDepth) { try { // Calculate position adjustment variables. $width = $node->getRight() - $node->getLeft() + 1; @@ -348,8 +350,7 @@ protected function moveSubTreeToPosition($newLeftPosition, Node $node) { $this->connection->beginTransaction(); // Calculate depth difference. - $newNode = $this->getNodeAtPosition($newLeftPosition); - $depthDiff = $newNode->getDepth() - $node->getDepth(); + $depthDiff = $newDepth - $node->getDepth(); // Backwards movement must account for new space. if ($distance < 0) { diff --git a/tests/Functional/DbalNestedSetTest.php b/tests/Functional/DbalNestedSetTest.php index f402b753..3cd67e00 100644 --- a/tests/Functional/DbalNestedSetTest.php +++ b/tests/Functional/DbalNestedSetTest.php @@ -346,6 +346,81 @@ public function testMoveSubTreeBelow() { } + /** + * Tests moving a sub-tree under a brand new parent node. + */ + public function testMoveSubTreeBelowEndParentNode() { + + $parent = $this->nestedSet->getNode(new NodeKey(1, 1)); + $nodeKey = new NodeKey(7, 1); + $node = $this->nestedSet->getNode($nodeKey); + + $newRoot = $this->nestedSet->addRootNode(new NodeKey(12, 1)); + $this->nestedSet->moveSubTreeBelow($newRoot, $node); + + // Check node is in new position. + $node = $this->nestedSet->getNode($nodeKey); + $this->assertEquals(18, $node->getLeft()); + $this->assertEquals(23, $node->getRight()); + $this->assertEquals(1, $node->getDepth()); + + // Check children are in new position. + $node = $this->nestedSet->getNode(new NodeKey(10, 1)); + $this->assertEquals(19, $node->getLeft()); + $this->assertEquals(20, $node->getRight()); + $this->assertEquals(2, $node->getDepth()); + + $node = $this->nestedSet->getNode(new NodeKey(11, 1)); + $this->assertEquals(21, $node->getLeft()); + $this->assertEquals(22, $node->getRight()); + $this->assertEquals(2, $node->getDepth()); + + // Check old parent is updated. + $node = $this->nestedSet->getNode(new NodeKey(3, 1)); + $this->assertEquals(10, $node->getLeft()); + $this->assertEquals(15, $node->getRight()); + $this->assertEquals(1, $node->getDepth()); + + } + + /** + * Tests moving a sub-tree under a brand new child node. + */ + public function testMoveSubTreeBelowEndChildNode() { + + $parent = $this->nestedSet->getNode(new NodeKey(1, 1)); + $nodeKey = new NodeKey(7, 1); + $node = $this->nestedSet->getNode($nodeKey); + + $newRoot = $this->nestedSet->addRootNode(new NodeKey(12, 1)); + $newChild = $this->nestedSet->addNodeBelow($newRoot, new NodeKey(13, 1)); + $this->nestedSet->moveSubTreeBelow($newChild, $node); + + // Check node is in new position. + $node = $this->nestedSet->getNode($nodeKey); + $this->assertEquals(19, $node->getLeft()); + $this->assertEquals(24, $node->getRight()); + $this->assertEquals(2, $node->getDepth()); + + // Check children are in new position. + $node = $this->nestedSet->getNode(new NodeKey(10, 1)); + $this->assertEquals(20, $node->getLeft()); + $this->assertEquals(21, $node->getRight()); + $this->assertEquals(3, $node->getDepth()); + + $node = $this->nestedSet->getNode(new NodeKey(11, 1)); + $this->assertEquals(22, $node->getLeft()); + $this->assertEquals(23, $node->getRight()); + $this->assertEquals(3, $node->getDepth()); + + // Check old parent is updated. + $node = $this->nestedSet->getNode(new NodeKey(3, 1)); + $this->assertEquals(10, $node->getLeft()); + $this->assertEquals(15, $node->getRight()); + $this->assertEquals(1, $node->getDepth()); + + } + /** * Tests moving a sub-tree to the root. */ @@ -461,6 +536,13 @@ public function testValidateTableInvalidFirstChars() { $this->nestedSet = new DbalNestedSet($this->connection, "1abc"); } + /** + * Test get tree works. + */ + public function testGetTree() { + $this->assertCount(11, $this->nestedSet->getTree()); + } + /** * Loads the test data. */