Skip to content

Commit 592f24d

Browse files
[6.x] Fix adding sets to replicators nested inside Grid/Group fields (#13723)
Co-authored-by: Jason Varga <jason@pixelfear.com>
1 parent d8b5554 commit 592f24d

2 files changed

Lines changed: 182 additions & 0 deletions

File tree

src/Http/Controllers/CP/Fieldtypes/ReplicatorSetController.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ private function getReplicatorField(Blueprint $blueprint, string $field): Field
7272

7373
private function getConfig(array $config, array $remainingFieldPathComponents): array
7474
{
75+
$isGroupOrGrid = isset($config['type']) && in_array($config['type'], ['group', 'grid']);
7576
$isReplicator = isset($config['type']) && in_array($config['type'], ['bard', 'replicator']);
7677

7778
if ($isReplicator) {
@@ -88,6 +89,14 @@ private function getConfig(array $config, array $remainingFieldPathComponents):
8889
return $this->getConfig($flattenedSets, $remainingFieldPathComponents);
8990
}
9091

92+
if ($isGroupOrGrid) {
93+
array_shift($remainingFieldPathComponents);
94+
95+
$fields = $this->resolveFields($config['fields'] ?? []);
96+
97+
return $this->getConfig($fields[$remainingFieldPathComponents[0]]['field'], $remainingFieldPathComponents);
98+
}
99+
91100
$fields = $this->resolveFields($config[$remainingFieldPathComponents[0]]['fields']);
92101

93102
array_shift($remainingFieldPathComponents);

tests/Fieldtypes/ReplicatorTest.php

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,179 @@ public function it_can_return_set_defaults_for_nested_sets()
932932
], $response->json('new'));
933933
}
934934

935+
/**
936+
* We're purposefully naming the sets the same as its nested field to replicate the reported issue.
937+
*
938+
* @see https://github.com/statamic/cms/issues/13714
939+
*/
940+
#[Test]
941+
public function it_can_return_set_defaults_for_replicator_inside_group()
942+
{
943+
$this->partialMock(RowId::class, function (MockInterface $mock) {
944+
$mock->shouldReceive('generate')->andReturn('random-string-1', 'random-string-2');
945+
});
946+
947+
$pageBuilder = Fieldset::make('page_builder')->setContents(['fields' => [
948+
['handle' => 'page_builder', 'field' => ['type' => 'replicator', 'sets' => [
949+
'replicator_set_group' => [
950+
'sets' => [
951+
'cards_slider' => [
952+
'fields' => [
953+
[
954+
'handle' => 'cards_slider',
955+
'field' => [
956+
'type' => 'group',
957+
'fields' => [
958+
[
959+
'handle' => 'slider',
960+
'field' => [
961+
'type' => 'group',
962+
'fields' => [
963+
[
964+
'handle' => 'cards',
965+
'field' => [
966+
'type' => 'replicator',
967+
'sets' => [
968+
'replicator_set_group' => [
969+
'sets' => [
970+
'card' => [
971+
'fields' => [
972+
['handle' => 'card_content', 'field' => ['type' => 'text', 'default' => 'the default']],
973+
],
974+
],
975+
],
976+
],
977+
],
978+
],
979+
],
980+
],
981+
],
982+
],
983+
],
984+
],
985+
],
986+
],
987+
],
988+
],
989+
],
990+
]]],
991+
]]);
992+
993+
Fieldset::shouldReceive('find')->with('page_builder')->andReturn($pageBuilder);
994+
995+
$blueprint = Facades\Blueprint::make()->setHandle('default')->setNamespace('collections.pages');
996+
$blueprint->setContents([
997+
'sections' => [
998+
'main' => [
999+
'fields' => [
1000+
['import' => 'page_builder'],
1001+
],
1002+
],
1003+
],
1004+
]);
1005+
1006+
Facades\Blueprint::partialMock();
1007+
Facades\Blueprint::shouldReceive('find')->with('collections.pages.default')->andReturn($blueprint);
1008+
1009+
$response = $this
1010+
->actingAs(tap(Facades\User::make()->makeSuper())->save())
1011+
->postJson(cp_route('replicator-fieldtype.set'), [
1012+
'blueprint' => 'collections.pages.default',
1013+
'field' => 'page_builder.cards_slider.cards_slider.slider.cards',
1014+
'set' => 'card',
1015+
])
1016+
->assertOk();
1017+
1018+
$this->assertEquals([
1019+
'card_content' => 'the default',
1020+
], $response->json('defaults'));
1021+
1022+
$this->assertEquals([
1023+
'_' => '_',
1024+
'card_content' => null,
1025+
], $response->json('new'));
1026+
}
1027+
1028+
#[Test]
1029+
public function it_can_return_set_defaults_for_replicator_inside_grid()
1030+
{
1031+
$this->partialMock(RowId::class, function (MockInterface $mock) {
1032+
$mock->shouldReceive('generate')->andReturn('random-string-1', 'random-string-2');
1033+
});
1034+
1035+
$pageBuilder = Fieldset::make('page_builder')->setContents(['fields' => [
1036+
['handle' => 'page_builder', 'field' => ['type' => 'replicator', 'sets' => [
1037+
'replicator_set_group' => [
1038+
'sets' => [
1039+
'cards_slider' => [
1040+
'fields' => [
1041+
[
1042+
'handle' => 'cards_slider',
1043+
'field' => [
1044+
'type' => 'grid',
1045+
'fields' => [
1046+
[
1047+
'handle' => 'cards',
1048+
'field' => [
1049+
'type' => 'replicator',
1050+
'sets' => [
1051+
'replicator_set_group' => [
1052+
'sets' => [
1053+
'card' => [
1054+
'fields' => [
1055+
['handle' => 'card_content', 'field' => ['type' => 'text', 'default' => 'the default']],
1056+
],
1057+
],
1058+
],
1059+
],
1060+
],
1061+
],
1062+
],
1063+
],
1064+
],
1065+
],
1066+
],
1067+
],
1068+
],
1069+
],
1070+
]]],
1071+
]]);
1072+
1073+
Fieldset::shouldReceive('find')->with('page_builder')->andReturn($pageBuilder);
1074+
1075+
$blueprint = Facades\Blueprint::make()->setHandle('default')->setNamespace('collections.pages');
1076+
$blueprint->setContents([
1077+
'sections' => [
1078+
'main' => [
1079+
'fields' => [
1080+
['import' => 'page_builder'],
1081+
],
1082+
],
1083+
],
1084+
]);
1085+
1086+
Facades\Blueprint::partialMock();
1087+
Facades\Blueprint::shouldReceive('find')->with('collections.pages.default')->andReturn($blueprint);
1088+
1089+
$response = $this
1090+
->actingAs(tap(Facades\User::make()->makeSuper())->save())
1091+
->postJson(cp_route('replicator-fieldtype.set'), [
1092+
'blueprint' => 'collections.pages.default',
1093+
'field' => 'page_builder.cards_slider.cards_slider.cards',
1094+
'set' => 'card',
1095+
])
1096+
->assertOk();
1097+
1098+
$this->assertEquals([
1099+
'card_content' => 'the default',
1100+
], $response->json('defaults'));
1101+
1102+
$this->assertEquals([
1103+
'_' => '_',
1104+
'card_content' => null,
1105+
], $response->json('new'));
1106+
}
1107+
9351108
public static function groupedSetsProvider()
9361109
{
9371110
return [

0 commit comments

Comments
 (0)