Skip to content

Replicator doesn't call config() on fieldtypes of fields in its sets #2882

Description

@sauerbraten

Bug Description

We have a custom select fieldtype where we load options from a global config in its config() method. However, the options don't show up when using this fieldtype in a Replicator set, since config() is never called. Replicator only passes the config values from YAML along to the frontend.

Here's a super ugly patch that fixes this, but probably makes everything slow and worse. I'm especially unhappy about the Blink::once key which is guaranteed to collide eventually, but since $this->field-parent() is sometimes null, I couldn't build a key namespaced by the collection or blueprint.

diff --git a/src/Fields/Field.php b/src/Fields/Field.php
index c397d01c5b..0a322e1fbb 100644
--- a/src/Fields/Field.php
+++ b/src/Fields/Field.php
@@ -270,7 +270,7 @@ class Field implements Arrayable
     {
         $fieldtype = $this->fieldtype();

-        $fields = $fieldtype->configFields()->addValues($this->config);
+        $fields = $fieldtype->configFields()->addValues($fieldtype->config());

         return array_merge($this->config, $fields->preProcess()->values()->all(), [
             'component' => $fieldtype->component(),
diff --git a/src/Fieldtypes/Replicator.php b/src/Fieldtypes/Replicator.php
index f398de8720..4acd506187 100644
--- a/src/Fieldtypes/Replicator.php
+++ b/src/Fieldtypes/Replicator.php
@@ -5,6 +5,7 @@ namespace Statamic\Fieldtypes;
 use Statamic\Fields\Fields;
 use Statamic\Fields\Fieldtype;
 use Statamic\Query\Scopes\Filters\Fields\Replicator as ReplicatorFilter;
+use Statamic\Facades\Blink;

 class Replicator extends Fieldtype
 {
@@ -56,6 +57,40 @@ class Replicator extends Fieldtype
         return new Fields($this->config("sets.$set.fields"));
     }

+    public function config(string $key = null, $fallback = null)
+    {
+        if (! $this->field) {
+            return $fallback;
+        }
+
+        $config = Blink::once("{$this->field->handle()}-config", function () {
+            $config = parent::config();
+
+            if (array_key_exists('sets', $config)) {
+                foreach ($config['sets'] as $setHandle => $setConfig) {
+                    if (! array_key_exists('fields', $setConfig)) {
+                        continue;
+                    }
+
+                    $fields = new Fields($setConfig['fields']);
+                    $index = 0;
+                    foreach ($fields->all() as $handle => $field) {
+                        $config['sets'][$setHandle]['fields'][$index]['field'] = $field->fieldtype()->config();
+                        $index++;
+                    }
+                }
+            }
+
+            return $config;
+        });
+
+        // dump($key, $config);
+
+        return $key
+            ? collect($config)->get($key, $fallback)
+            : $config;
+    }
+
     public function extraRules(): array
     {
         return collect($this->field->value())->map(function ($set, $index) {

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions