Skip to content

Commit ae522a2

Browse files
committed
correctly nest items with the same values with different parents
1 parent f50405f commit ae522a2

File tree

3 files changed

+25
-16
lines changed

3 files changed

+25
-16
lines changed

_test/NestedResultTest.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ class NestedResultTest extends StructTest
2626
['laptop', 'apple', 'pro 16'],
2727
['laptop', 'apple', 'air'],
2828
['laptop', 'apple', 'm1'],
29-
['laptop', 'dell', 'xps'],
3029
['laptop', 'dell', 'inspiron'],
3130
['laptop', 'dell', 'latitude'],
31+
['laptop', 'bmw', 'latitude'],
3232
];
3333

3434
protected $multiItems = [
@@ -151,13 +151,14 @@ public function testSimpleTwoLevels()
151151
$this->assertEquals('car', $tree[0]->getValueObject()->getValue());
152152
$this->assertEquals('laptop', $tree[1]->getValueObject()->getValue());
153153

154-
$this->assertCount(2, $tree[0]->getChildren(true), '2 second level nodes expected');
155-
$this->assertCount(2, $tree[1]->getChildren(true), '2 second level nodes expected');
154+
$this->assertCount(2, $tree[0]->getChildren(true), '2 car brands expected');
155+
$this->assertCount(3, $tree[1]->getChildren(true), '3 laptop brands expected');
156156

157-
$this->assertCount(3, $tree[0]->getChildren(true)[0]->getResultRows(), 'result rows');
158-
$this->assertCount(3, $tree[0]->getChildren(true)[1]->getResultRows(), 'result rows');
159-
$this->assertCount(3, $tree[1]->getChildren(true)[0]->getResultRows(), 'result rows');
160-
$this->assertCount(3, $tree[1]->getChildren(true)[1]->getResultRows(), 'result rows');
157+
$this->assertCount(3, $tree[0]->getChildren(true)[0]->getResultRows(), '3 audis expected');
158+
$this->assertCount(3, $tree[0]->getChildren(true)[1]->getResultRows(), '3 bmw expected');
159+
$this->assertCount(3, $tree[1]->getChildren(true)[0]->getResultRows(), '3 apple expected');
160+
$this->assertCount(1, $tree[1]->getChildren(true)[1]->getResultRows(), '1 bmw expected');
161+
$this->assertCount(2, $tree[1]->getChildren(true)[2]->getResultRows(), '2 dell expected');
161162

162163

163164
$this->assertEquals('a80', $tree[0]->getChildren(true)[0]->getResultRows()[0][0]->getValue(), 'Audi 80 expected');

meta/NestedResult.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,24 +111,26 @@ protected function nestBranch(NestedValue $parent, $row, $nesting, $depth = 0)
111111
$valObj = array_shift($row);
112112
if (!$valObj) return; // no more values to nest, usually shouldn't happen
113113

114+
$parentPath = (string) $parent;
115+
114116
if ($valObj->getColumn()->isMulti() && $valObj->getValue()) {
115117
// split up multi values into separate nodes
116118
$values = $valObj->getValue();
117119
if ($values) {
118120
foreach ($values as $value) {
119121
$newValue = new Value($valObj->getColumn(), $value);
120-
$node = $this->getNodeForValue($newValue, $depth);
122+
$node = $this->getNodeForValue($newValue, $parentPath, $depth);
121123
$parent->addChild($node);
122124
$this->nestBranch($node, $row, $nesting, $depth + 1);
123125
}
124126
} else {
125127
$newValue = new Value($valObj->getColumn(), ''); // add empty node
126-
$node = $this->getNodeForValue($newValue, $depth);
128+
$node = $this->getNodeForValue($newValue, $parentPath, $depth);
127129
$parent->addChild($node);
128130
$this->nestBranch($node, $row, $nesting, $depth + 1);
129131
}
130132
} else {
131-
$node = $this->getNodeForValue($valObj, $depth);
133+
$node = $this->getNodeForValue($valObj, $parentPath, $depth);
132134
$parent->addChild($node);
133135
$this->nestBranch($node, $row, $nesting, $depth + 1);
134136
}
@@ -141,9 +143,9 @@ protected function nestBranch(NestedValue $parent, $row, $nesting, $depth = 0)
141143
* @param int $depth
142144
* @return NestedValue
143145
*/
144-
protected function getNodeForValue(Value $value, $depth)
146+
protected function getNodeForValue(Value $value, $parentPath, $depth)
145147
{
146-
$node = new NestedValue($value, $depth);
148+
$node = new NestedValue($value, $parentPath, $depth);
147149
$key = (string)$node;
148150
if (!isset($this->nodes[$key])) {
149151
$this->nodes[$key] = $node;

meta/NestedValue.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,21 @@ class NestedValue
2222

2323
/** @var int the nesting depth */
2424
protected $depth;
25+
/**
26+
* @var mixed|string
27+
*/
28+
protected $parentPath;
2529

2630
/**
2731
* Create a nested version of the given value
2832
*
2933
* @param Value|null $value The value to store, null for root node
3034
* @param int $depth The depth of this node (avoids collision where the same values are selected on multiple levels)
3135
*/
32-
public function __construct(?Value $value, $depth = 0)
36+
public function __construct(?Value $value, $parentPath = '', $depth = 0)
3337
{
3438
$this->value = $value;
39+
$this->parentPath = $parentPath;
3540
$this->depth = $depth;
3641
}
3742

@@ -134,7 +139,7 @@ public function getResultRows()
134139
public function __toString()
135140
{
136141
if ($this->value === null) return ''; // root node
137-
return $this->value->__toString() . '-' . $this->depth;
142+
return $this->parentPath . '/' . $this->value->__toString();
138143
}
139144

140145
/**
@@ -171,9 +176,10 @@ public function sortChildren(NestedValue $a, NestedValue $b)
171176
/**
172177
* print the tree for debugging
173178
*
179+
* @param bool $sort use sorted children?
174180
* @return string
175181
*/
176-
public function dump()
182+
public function dump($sort = true)
177183
{
178184
$return = '';
179185

@@ -197,7 +203,7 @@ public function dump()
197203
$return .= "\n";
198204
}
199205

200-
foreach ($this->getChildren() as $child) {
206+
foreach ($this->getChildren($sort) as $child) {
201207
$return .= $child->dump();
202208
}
203209

0 commit comments

Comments
 (0)