From ce9b9b8c9f05c3f023063501893521b8ec8d1c6f Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Mon, 12 Oct 2026 12:57:01 +0100 Subject: [PATCH 1/2] simplify `FieldUpdater` using `Fieldset::ensureFieldHasConfig()` --- composer.json | 2 +- src/Support/FieldUpdater.php | 157 ++++++----------------------------- 2 files changed, 27 insertions(+), 132 deletions(-) diff --git a/composer.json b/composer.json index 4dc1be7..c4020af 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ } }, "require": { - "statamic/cms": "^6.25", + "statamic/cms": "^6.36", "spatie/simple-excel": "^3.7", "symfony/dom-crawler": "^7.1", "symfony/css-selector": "^7.1 || ^8.0" diff --git a/src/Support/FieldUpdater.php b/src/Support/FieldUpdater.php index f11de75..be64bcb 100644 --- a/src/Support/FieldUpdater.php +++ b/src/Support/FieldUpdater.php @@ -5,6 +5,7 @@ use Statamic\Facades\Blink; use Statamic\Fields\Blueprint; use Statamic\Fields\Field; +use Statamic\Fields\Fields; use Statamic\Fields\Fieldset; use Statamic\Support\Str; @@ -27,155 +28,49 @@ public function blueprint(Blueprint $blueprint): self return $this; } - public function fieldset(Fieldset $fieldset): self + public function updateFieldConfig(array $config): void { - $this->blueprint = $fieldset; - - return $this; + $this->updateFieldConfigIn($this->blueprint, $this->field->handle(), $config); } - public function updateFieldConfig(array $config): void + private function updateFieldConfigIn(Blueprint|Fieldset $container, string $handle, array $config): void { - if ($linkedField = $this->getLinkedField()) { - $this->updateLinkedField($linkedField, $config); - - return; - } + $field = $container->fields()->items()->firstWhere('handle', $handle); - if ($this->isImportedField()) { - $this->updateImportedField($config, $this->field->prefix()); + if ($field && is_string($field['field'])) { + $this->updateFieldConfigIn( + container: Fieldset::find(Str::before($field['field'], '.')), + handle: Str::after($field['field'], '.'), + config: $config + ); return; } - $this->blueprint->ensureFieldHasConfig( - handle: $this->field->handle(), - config: $config - ); - - $this->blueprint->save(); - } + if ($field) { + $container->ensureFieldHasConfig($handle, $config)->save(); - private function getLinkedField(): ?array - { - return $this->blueprint->fields()->items() - ->where('handle', $this->field->handle()) - ->filter(fn (array $field) => isset($field['field']) && is_string($field['field'])) - ->first(); - } + $this->forgetCachedBlueprints(); - /** - * This method handles updating linked fields from fieldsets. - * - * - - * handle: foo - * field: fieldset.foo - */ - private function updateLinkedField(array $importedField, array $config): void - { - /** @var Fieldset $fieldset */ - $fieldHandle = Str::after($importedField['field'], '.'); - $fieldset = Fieldset::find(Str::before($importedField['field'], '.')); - - $fieldset->setContents([ - ...$fieldset->contents(), - 'fields' => collect($fieldset->contents()['fields']) - ->map(function (array $field) use ($config, $fieldHandle) { - if ($field['handle'] === $fieldHandle) { - return [ - 'handle' => $field['handle'], - 'field' => $config, - ]; - } - - return $field; - }) - ->all(), - ]); - - $fieldset->save(); - - $this->clearBlinkCaches(); - } - - /** - * Determines if a field is imported from a fieldset by checking if it exists in the blueprint's top-level fields. - */ - private function isImportedField(): bool - { - $topLevelFieldHandles = $this->blueprint->fields()->items()->pluck('handle')->filter(); - - return $this->blueprint->field($this->field->handle()) && ! $topLevelFieldHandles->contains($this->field->handle()); - } + return; + } - /** - * This method handles updating imported fields from fieldsets, either with or without prefixes. - * - * - - * import: fieldset - * prefix: foo_ - */ - private function updateImportedField(array $config, ?string $prefix = null): void - { - /** @var Fieldset $fieldset */ - $fieldset = $this->blueprint->fields()->items() + $import = $container->fields()->items() ->filter(fn (array $field) => isset($field['import'])) - ->mapWithKeys(fn (array $field) => [ - $field['prefix'] ?? '' => Fieldset::find($field['import']), - ]) - ->filter(function (Fieldset $fieldset, string $prefix) use ($config) { - // When the field exists in the fieldset, but it's not a top-level field, - // pass the Fieldset to the FieldUpdater (this class) to update the field config. - $fieldHandleWithoutBlueprintPrefix = Str::after($this->field->handle(), $prefix); - - if ( - ($field = $fieldset->field($fieldHandleWithoutBlueprintPrefix)) - && ! $fieldset->fields()->items()->pluck('handle')->filter()->contains($fieldHandleWithoutBlueprintPrefix) - ) { - (new self) - ->field($field) - ->fieldset($fieldset) - ->updateFieldConfig($config); - - return false; - } - - return collect($fieldset->fields()->items()) - ->where('handle', Str::after($this->field->handle(), $prefix)) - ->isNotEmpty(); - }) - ->first(); - - if (! $fieldset) { + ->first(fn (array $field) => (new Fields([$field]))->all()->has($handle)); + + if (! $import) { return; } - $fieldset->setContents([ - ...$fieldset->contents(), - 'fields' => collect($fieldset->contents()['fields']) - ->map(function (array $field) use ($config, $prefix) { - if ($field['handle'] === Str::after($this->field->handle(), $prefix ?? '')) { - return [ - 'handle' => $field['handle'], - 'field' => $config, - ]; - } - - return $field; - }) - ->all(), - ]); - - $fieldset->save(); - - $this->clearBlinkCaches(); + $this->updateFieldConfigIn( + container: Fieldset::find($import['import']), + handle: Str::after($handle, $import['prefix'] ?? ''), + config: $config + ); } - /** - * When fieldsets are updated, we need to clear the Blueprint Blink caches, so - * Blueprint::find() returns the updated field config. - */ - private function clearBlinkCaches(): void + private function forgetCachedBlueprints(): void { Blink::store('blueprints.found')->flush(); Blink::store('blueprints.from-file')->flush(); From 46ef12bb0b77bbeec4f56718ab1d052f6d001f16 Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Fri, 16 Oct 2026 17:32:50 +0100 Subject: [PATCH 2/2] remove `minimum-stability` and `prefer-stable` from `composer.json` --- composer.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/composer.json b/composer.json index c4020af..3a8a1ec 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,5 @@ "Statamic\\Importer\\ServiceProvider" ] } - }, - "minimum-stability": "dev", - "prefer-stable": true + } }