Skip to content

Commit 5e714ee

Browse files
committed
Implement trunks family of methods. Closes #59.
Implement 'allTrunks', 'trunks' and 'isTrunk' methods to complement the leaf and root ones. We consider a trunk a node which falls in the middle of a branch (not root and not leaf).
1 parent 2e1558f commit 5e714ee

File tree

3 files changed

+130
-0
lines changed

3 files changed

+130
-0
lines changed

src/Baum/Node.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,26 @@ public static function allLeaves() {
408408
->orderBy($instance->getQualifiedOrderColumnName());
409409
}
410410

411+
/**
412+
* Static query scope. Returns a query scope with all nodes which are at
413+
* the middle of a branch (not root and not leaves).
414+
*
415+
* @return \Illuminate\Database\Query\Builder
416+
*/
417+
public static function allTrunks() {
418+
$instance = new static;
419+
420+
$grammar = $instance->getConnection()->getQueryGrammar();
421+
422+
$rgtCol = $grammar->wrap($instance->getQualifiedRightColumnName());
423+
$lftCol = $grammar->wrap($instance->getQualifiedLeftColumnName());
424+
425+
return $instance->newQuery()
426+
->whereNotNull($instance->getParentColumnName())
427+
->whereRaw($rgtCol . ' - ' . $lftCol . ' != 1')
428+
->orderBy($instance->getQualifiedOrderColumnName());
429+
}
430+
411431
/**
412432
* Checks wether the underlying Nested Set structure is valid.
413433
*
@@ -502,6 +522,15 @@ public function isLeaf() {
502522
return $this->exists && ($this->getRight() - $this->getLeft() == 1);
503523
}
504524

525+
/**
526+
* Returns true if this is a trunk node (not root or leaf).
527+
*
528+
* @return boolean
529+
*/
530+
public function isTrunk() {
531+
return !$this->isRoot() && !$this->isLeaf();
532+
}
533+
505534
/**
506535
* Returns true if this is a child node.
507536
*
@@ -659,6 +688,33 @@ public function getLeaves($columns = array('*')) {
659688
return $this->leaves()->get($columns);
660689
}
661690

691+
/**
692+
* Instance scope targeting all of its nested children which are between the
693+
* root and the leaf nodes (middle branch).
694+
*
695+
* @return \Illuminate\Database\Query\Builder
696+
*/
697+
public function trunks() {
698+
$grammar = $this->getConnection()->getQueryGrammar();
699+
700+
$rgtCol = $grammar->wrap($this->getQualifiedRightColumnName());
701+
$lftCol = $grammar->wrap($this->getQualifiedLeftColumnName());
702+
703+
return $this->descendants()
704+
->whereNotNull($this->getQualifiedParentColumnName())
705+
->whereRaw($rgtCol . ' - ' . $lftCol . ' != 1');
706+
}
707+
708+
/**
709+
* Return all of its nested children which are trunks.
710+
*
711+
* @param array $columns
712+
* @return \Illuminate\Database\Eloquent\Collection
713+
*/
714+
public function getTrunks($columns = array('*')) {
715+
return $this->trunks()->get($columns);
716+
}
717+
662718
/**
663719
* Scope targeting itself and all of its nested children.
664720
*

tests/suite/Category/CategoryHierarchyTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ public function testAllLeavesStatic() {
5555
$this->assertContains('Root 2' , $leaves);
5656
}
5757

58+
public function testAllTrunksStatic() {
59+
$allTrunks = Category::allTrunks()->get();
60+
61+
$this->assertCount(1, $allTrunks);
62+
63+
$trunks = $allTrunks->lists('name');
64+
$this->assertContains('Child 2', $trunks);
65+
}
66+
5867
public function testGetRoot() {
5968
$this->assertEquals($this->categories('Root 1'), $this->categories('Root 1')->getRoot());
6069
$this->assertEquals($this->categories('Root 2'), $this->categories('Root 2')->getRoot());
@@ -105,6 +114,21 @@ public function testGetLeavesInIteration() {
105114
$this->assertEquals($expectedIds[$i], $leaf->getKey());
106115
}
107116

117+
public function testGetTrunks() {
118+
$trunks = array($this->categories('Child 2'));
119+
120+
$this->assertEquals($trunks, $this->categories('Root 1')->getTrunks()->all());
121+
}
122+
123+
public function testGetTrunksInIteration() {
124+
$node = $this->categories('Root 1');
125+
126+
$expectedIds = array(3);
127+
128+
foreach($node->getTrunks() as $i => $trunk)
129+
$this->assertEquals($expectedIds[$i], $trunk->getKey());
130+
}
131+
108132
public function testIsLeaf() {
109133
$this->assertTrue($this->categories('Child 1')->isLeaf());
110134
$this->assertTrue($this->categories('Child 2.1')->isLeaf());
@@ -118,6 +142,19 @@ public function testIsLeaf() {
118142
$this->assertFalse($new->isLeaf());
119143
}
120144

145+
public function testIsTrunk() {
146+
$this->assertFalse($this->categories('Child 1')->isTrunk());
147+
$this->assertFalse($this->categories('Child 2.1')->isTrunk());
148+
$this->assertFalse($this->categories('Child 3')->isTrunk());
149+
$this->assertFalse($this->categories('Root 2')->isTrunk());
150+
151+
$this->assertFalse($this->categories('Root 1')->isTrunk());
152+
$this->assertTrue($this->categories('Child 2')->isTrunk());
153+
154+
$new = new Category;
155+
$this->assertFalse($new->isTrunk());
156+
}
157+
121158
public function testWithoutNodeScope() {
122159
$child = $this->categories('Child 2.1');
123160

tests/suite/Cluster/ClusterHierarchyTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ public function testAllLeavesStatic() {
5555
$this->assertContains('Root 2' , $leaves);
5656
}
5757

58+
public function testAllTrunksStatic() {
59+
$allTrunks = Cluster::allTrunks()->get();
60+
61+
$this->assertCount(1, $allTrunks);
62+
63+
$trunks = $allTrunks->lists('name');
64+
$this->assertContains('Child 2', $trunks);
65+
}
66+
5867
public function testGetRoot() {
5968
$this->assertEquals($this->clusters('Root 1'), $this->clusters('Root 1')->getRoot());
6069
$this->assertEquals($this->clusters('Root 2'), $this->clusters('Root 2')->getRoot());
@@ -109,6 +118,21 @@ public function testGetLeavesInIteration() {
109118
$this->assertEquals($expectedIds[$i], $leaf->getKey());
110119
}
111120

121+
public function testGetTrunks() {
122+
$trunks = array($this->clusters('Child 2'));
123+
124+
$this->assertEquals($trunks, $this->clusters('Root 1')->getTrunks()->all());
125+
}
126+
127+
public function testGetTrunksInIteration() {
128+
$node = $this->clusters('Root 1');
129+
130+
$expectedIds = array('07c1fc8c-53b5-4fe7-b9c4-e09f266a455c');
131+
132+
foreach($node->getTrunks() as $i => $trunk)
133+
$this->assertEquals($expectedIds[$i], $trunk->getKey());
134+
}
135+
112136
public function testIsLeaf() {
113137
$this->assertTrue($this->clusters('Child 1')->isLeaf());
114138
$this->assertTrue($this->clusters('Child 2.1')->isLeaf());
@@ -122,6 +146,19 @@ public function testIsLeaf() {
122146
$this->assertFalse($new->isLeaf());
123147
}
124148

149+
public function testIsTrunk() {
150+
$this->assertFalse($this->clusters('Child 1')->isTrunk());
151+
$this->assertFalse($this->clusters('Child 2.1')->isTrunk());
152+
$this->assertFalse($this->clusters('Child 3')->isTrunk());
153+
$this->assertFalse($this->clusters('Root 2')->isTrunk());
154+
155+
$this->assertFalse($this->clusters('Root 1')->isTrunk());
156+
$this->assertTrue($this->clusters('Child 2')->isTrunk());
157+
158+
$new = new Cluster;
159+
$this->assertFalse($new->isTrunk());
160+
}
161+
125162
public function testWithoutNodeScope() {
126163
$child = $this->clusters('Child 2.1');
127164

0 commit comments

Comments
 (0)