Skip to content

Commit 1c43aee

Browse files
mynetxclaude
andcommitted
Remove null items from structure trees when setting
A null item in a tree (e.g. a corrupted yaml file) would crash Entry::order() and augmentation via array_flip(), and crash the tree diff when saving. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 5171897 commit 1c43aee

3 files changed

Lines changed: 80 additions & 2 deletions

File tree

src/Structures/Tree.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,27 @@ public function tree($tree = null)
5555
return $this->structure()->validateTree($tree, $this->locale());
5656
});
5757
})
58+
->setter(function ($tree) {
59+
return $this->removeNullItems($tree);
60+
})
5861
->args(func_get_args());
5962
}
6063

64+
protected function removeNullItems($tree)
65+
{
66+
return collect($tree)
67+
->reject(fn ($item) => is_null($item))
68+
->map(function ($item) {
69+
if (isset($item['children'])) {
70+
$item['children'] = $this->removeNullItems($item['children']);
71+
}
72+
73+
return $item;
74+
})
75+
->values()
76+
->all();
77+
}
78+
6179
public function root()
6280
{
6381
if (! $this->structure()->expectsRoot()) {

tests/Data/Entries/EntryTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,32 @@ public function it_gets_the_order_from_the_collections_structure()
11851185
$this->assertEquals(3, $four->order());
11861186
}
11871187

1188+
#[Test]
1189+
public function it_gets_the_order_from_the_collections_structure_when_the_tree_contains_a_null_item()
1190+
{
1191+
$collection = tap(Collection::make('ordered'))->save();
1192+
1193+
$one = tap((new Entry)->locale('en')->id('one')->collection($collection))->save();
1194+
$two = tap((new Entry)->locale('en')->id('two')->collection($collection))->save();
1195+
$three = tap((new Entry)->locale('en')->id('three')->collection($collection))->save();
1196+
1197+
$collection->structureContents([
1198+
'max_depth' => 3,
1199+
])->save();
1200+
$collection->structure()->in('en')->tree(
1201+
[
1202+
['entry' => 'three'],
1203+
null,
1204+
['entry' => 'one'],
1205+
['entry' => 'two'],
1206+
]
1207+
)->save();
1208+
1209+
$this->assertEquals(2, $one->order());
1210+
$this->assertEquals(3, $two->order());
1211+
$this->assertEquals(1, $three->order());
1212+
}
1213+
11881214
#[Test]
11891215
public function it_gets_the_order_from_the_data_if_not_structured()
11901216
{

tests/Data/Structures/TreeTest.php

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,8 @@ public function the_structure_validates_the_tree_when_getting_it_the_first_time(
426426
$structure = $this->mock(Structure::class);
427427
$structure->shouldReceive('handle')->andReturn('test');
428428

429-
$firstContents = ['first' => 'time'];
430-
$secondContents = ['second' => 'time'];
429+
$firstContents = [['entry' => 'first']];
430+
$secondContents = [['entry' => 'second']];
431431

432432
$structure->shouldReceive('validateTree')->with($firstContents, 'the-locale')->once()->andReturn($firstContents);
433433
$structure->shouldReceive('validateTree')->with($secondContents, 'the-locale')->once()->andReturn($secondContents);
@@ -451,6 +451,40 @@ public function the_structure_validates_the_tree_when_getting_it_the_first_time(
451451
$tree->tree();
452452
}
453453

454+
#[Test]
455+
public function it_removes_null_items_when_setting_the_tree()
456+
{
457+
$tree = $this->tree([
458+
[
459+
'id' => 'pages-home',
460+
],
461+
null,
462+
[
463+
'id' => 'pages-about',
464+
'children' => [
465+
[
466+
'id' => 'pages-board',
467+
],
468+
null,
469+
],
470+
],
471+
]);
472+
473+
$this->assertEquals([
474+
[
475+
'id' => 'pages-home',
476+
],
477+
[
478+
'id' => 'pages-about',
479+
'children' => [
480+
[
481+
'id' => 'pages-board',
482+
],
483+
],
484+
],
485+
], $tree->tree());
486+
}
487+
454488
#[Test]
455489
public function it_cannot_move_into_root_if_structure_expects_root()
456490
{

0 commit comments

Comments
 (0)