Skip to content

Commit a518f0b

Browse files
committed
Revision to the revised changes
1 parent 3d1e7d7 commit a518f0b

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

src/SelectTree.php

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -206,29 +206,55 @@ private function buildTreeFromResults($results, $parent = null): Collection
206206
// Create a mapping of results by their parent IDs for faster lookup
207207
$resultMap = [];
208208

209+
// Create a cache of IDs
210+
$resultCache = [];
211+
209212
// Group results by their parent IDs
210213
foreach ($results as $result) {
214+
// Cache the result ID as seen
215+
$resultCache[$result->id]['in_set'] = 1;
216+
// Move any cached children to the result map
217+
if(isset($resultCache[$result->id]['children'])){
218+
$resultMap[$result->id] = array_merge($resultMap[$result->id], $resultCache[$result->id]['children']);
219+
unset($resultCache[$result->id]['children']);
220+
}
211221
$parentId = $result->{$this->getParentAttribute()};
212-
if (! isset($resultMap[$parentId])) {
213-
$resultMap[$parentId] = [];
222+
if (! isset($resultCache[$parentId])) {
223+
// Before adding results to the map, cache the parentId to hold until the parent is confirmed to be in the result set
224+
$resultCache[$parentId]['in_set'] = 0;
225+
$resultCache[$parentId]['children'] = [];
226+
}
227+
if($resultCache[$parentId]['in_set']){
228+
// if the parent has been confirmed to be in the set, add directly to result map
229+
$resultMap[$parentId][] = $result;
230+
} else {
231+
// otherwise, hold the result in the children cache until the parent is confirmed to be in the result set
232+
$resultCache[$parentId]['children'][] = $result;
214233
}
215-
$resultMap[$parentId][] = $result;
216234
}
217235

218-
// Define disabled options
219-
$disabledOptions = $this->getDisabledOptions();
236+
// Filter the cache for missing parents in the result set and get the children
237+
$orphanedResults = array_map(
238+
fn($item) => $item['children'],
239+
array_filter(
240+
$resultCache,
241+
fn($item) => !$item['in_set']
242+
)
243+
);
220244

221-
// Define hidden options
222-
$hiddenOptions = $this->getHiddenOptions();
245+
// Move any remaining children from the cache into the root of the tree, since their parents do not show up in the result set
246+
$resultMap[$parent] = array_merge(...array_values($orphanedResults));
247+
248+
debug($resultMap);
223249

224250
// Recursively build the tree starting from the root (null parent)
225251
$rootResults = $resultMap[$parent] ?? [];
226252

227-
// If a modified parent query yields no root results, iterate over the whole map instead
228-
if($this->modifyQueryUsing && empty($rootResults)) {
229-
// Go one layer deeper to access the results
230-
$rootResults = array_merge(...array_values($resultMap));
231-
}
253+
// Define disabled options
254+
$disabledOptions = $this->getDisabledOptions();
255+
256+
// Define hidden options
257+
$hiddenOptions = $this->getHiddenOptions();
232258

233259
foreach ($rootResults as $result) {
234260
// Build a node and add it to the tree

0 commit comments

Comments
 (0)