diff --git a/src/Http/Controllers/CP/Fieldtypes/ReplicatorSetController.php b/src/Http/Controllers/CP/Fieldtypes/ReplicatorSetController.php index 787452eab89..6871fb8dd21 100644 --- a/src/Http/Controllers/CP/Fieldtypes/ReplicatorSetController.php +++ b/src/Http/Controllers/CP/Fieldtypes/ReplicatorSetController.php @@ -72,6 +72,7 @@ private function getReplicatorField(Blueprint $blueprint, string $field): Field private function getConfig(array $config, array $remainingFieldPathComponents): array { + $isGroupOrGrid = isset($config['type']) && in_array($config['type'], ['group', 'grid']); $isReplicator = isset($config['type']) && in_array($config['type'], ['bard', 'replicator']); if ($isReplicator) { @@ -88,6 +89,14 @@ private function getConfig(array $config, array $remainingFieldPathComponents): return $this->getConfig($flattenedSets, $remainingFieldPathComponents); } + if ($isGroupOrGrid) { + array_shift($remainingFieldPathComponents); + + $fields = $this->resolveFields($config['fields'] ?? []); + + return $this->getConfig($fields[$remainingFieldPathComponents[0]]['field'], $remainingFieldPathComponents); + } + $fields = $this->resolveFields($config[$remainingFieldPathComponents[0]]['fields']); array_shift($remainingFieldPathComponents); diff --git a/tests/Fieldtypes/ReplicatorTest.php b/tests/Fieldtypes/ReplicatorTest.php index 4dc5cd25906..5b62c44d199 100644 --- a/tests/Fieldtypes/ReplicatorTest.php +++ b/tests/Fieldtypes/ReplicatorTest.php @@ -932,6 +932,179 @@ public function it_can_return_set_defaults_for_nested_sets() ], $response->json('new')); } + /** + * We're purposefully naming the sets the same as its nested field to replicate the reported issue. + * + * @see https://github.com/statamic/cms/issues/13714 + */ + #[Test] + public function it_can_return_set_defaults_for_replicator_inside_group() + { + $this->partialMock(RowId::class, function (MockInterface $mock) { + $mock->shouldReceive('generate')->andReturn('random-string-1', 'random-string-2'); + }); + + $pageBuilder = Fieldset::make('page_builder')->setContents(['fields' => [ + ['handle' => 'page_builder', 'field' => ['type' => 'replicator', 'sets' => [ + 'replicator_set_group' => [ + 'sets' => [ + 'cards_slider' => [ + 'fields' => [ + [ + 'handle' => 'cards_slider', + 'field' => [ + 'type' => 'group', + 'fields' => [ + [ + 'handle' => 'slider', + 'field' => [ + 'type' => 'group', + 'fields' => [ + [ + 'handle' => 'cards', + 'field' => [ + 'type' => 'replicator', + 'sets' => [ + 'replicator_set_group' => [ + 'sets' => [ + 'card' => [ + 'fields' => [ + ['handle' => 'card_content', 'field' => ['type' => 'text', 'default' => 'the default']], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ]]], + ]]); + + Fieldset::shouldReceive('find')->with('page_builder')->andReturn($pageBuilder); + + $blueprint = Facades\Blueprint::make()->setHandle('default')->setNamespace('collections.pages'); + $blueprint->setContents([ + 'sections' => [ + 'main' => [ + 'fields' => [ + ['import' => 'page_builder'], + ], + ], + ], + ]); + + Facades\Blueprint::partialMock(); + Facades\Blueprint::shouldReceive('find')->with('collections.pages.default')->andReturn($blueprint); + + $response = $this + ->actingAs(tap(Facades\User::make()->makeSuper())->save()) + ->postJson(cp_route('replicator-fieldtype.set'), [ + 'blueprint' => 'collections.pages.default', + 'field' => 'page_builder.cards_slider.cards_slider.slider.cards', + 'set' => 'card', + ]) + ->assertOk(); + + $this->assertEquals([ + 'card_content' => 'the default', + ], $response->json('defaults')); + + $this->assertEquals([ + '_' => '_', + 'card_content' => null, + ], $response->json('new')); + } + + #[Test] + public function it_can_return_set_defaults_for_replicator_inside_grid() + { + $this->partialMock(RowId::class, function (MockInterface $mock) { + $mock->shouldReceive('generate')->andReturn('random-string-1', 'random-string-2'); + }); + + $pageBuilder = Fieldset::make('page_builder')->setContents(['fields' => [ + ['handle' => 'page_builder', 'field' => ['type' => 'replicator', 'sets' => [ + 'replicator_set_group' => [ + 'sets' => [ + 'cards_slider' => [ + 'fields' => [ + [ + 'handle' => 'cards_slider', + 'field' => [ + 'type' => 'grid', + 'fields' => [ + [ + 'handle' => 'cards', + 'field' => [ + 'type' => 'replicator', + 'sets' => [ + 'replicator_set_group' => [ + 'sets' => [ + 'card' => [ + 'fields' => [ + ['handle' => 'card_content', 'field' => ['type' => 'text', 'default' => 'the default']], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ]]], + ]]); + + Fieldset::shouldReceive('find')->with('page_builder')->andReturn($pageBuilder); + + $blueprint = Facades\Blueprint::make()->setHandle('default')->setNamespace('collections.pages'); + $blueprint->setContents([ + 'sections' => [ + 'main' => [ + 'fields' => [ + ['import' => 'page_builder'], + ], + ], + ], + ]); + + Facades\Blueprint::partialMock(); + Facades\Blueprint::shouldReceive('find')->with('collections.pages.default')->andReturn($blueprint); + + $response = $this + ->actingAs(tap(Facades\User::make()->makeSuper())->save()) + ->postJson(cp_route('replicator-fieldtype.set'), [ + 'blueprint' => 'collections.pages.default', + 'field' => 'page_builder.cards_slider.cards_slider.cards', + 'set' => 'card', + ]) + ->assertOk(); + + $this->assertEquals([ + 'card_content' => 'the default', + ], $response->json('defaults')); + + $this->assertEquals([ + '_' => '_', + 'card_content' => null, + ], $response->json('new')); + } + public static function groupedSetsProvider() { return [