diff --git a/src/Support/FieldUpdater.php b/src/Support/FieldUpdater.php new file mode 100644 index 0000000..98dab03 --- /dev/null +++ b/src/Support/FieldUpdater.php @@ -0,0 +1,144 @@ +field = $field; + + return $this; + } + + public function blueprint(Blueprint $blueprint): self + { + $this->blueprint = $blueprint; + + return $this; + } + + public function updateFieldConfig(array $config): void + { + if ($prefix = $this->field->prefix()) { + $this->updatePrefixedField($prefix, $config); + + return; + } + + if ($importedField = $this->getImportedField()) { + $this->updateImportedField($importedField, $config); + + return; + } + + $this->blueprint->ensureFieldHasConfig( + handle: $this->field->handle(), + config: $config + ); + + $this->blueprint->save(); + } + + private function getImportedField(): ?array + { + return $this->blueprint->fields()->items() + ->where('handle', $this->field->handle()) + ->filter(fn (array $field) => isset($field['field']) && is_string($field['field'])) + ->first(); + } + + /** + * This method handles updating imported fields from fieldsets. + * + * - + * handle: foo + * field: fieldset.foo + */ + private function updateImportedField(array $importedField, array $config): void + { + /** @var \Statamic\Fields\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(); + } + + /** + * This method handles updating imported fields from fieldsets, which use a prefix. + * + * - + * import: fieldset + * prefix: foo_ + */ + private function updatePrefixedField(string $prefix, array $config): void + { + /** @var \Statamic\Fields\Fieldset $fieldset */ + $fieldset = $this->blueprint->fields()->items() + ->filter(fn (array $field) => isset($field['import'])) + ->map(fn (array $field) => Fieldset::find($field['import'])) + ->filter(function ($fieldset) use ($prefix) { + return collect($fieldset->fields()->items()) + ->where('handle', Str::after($this->field->handle(), $prefix)) + ->isNotEmpty(); + }) + ->first(); + + $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(); + } + + /** + * When fieldsets are updated, we need to clear the Blueprint Blink caches, so + * Blueprint::find() returns the updated field config. + */ + private function clearBlinkCaches(): void + { + Blink::store('blueprints.found')->flush(); + Blink::store('blueprints.from-file')->flush(); + } +} diff --git a/src/Transformers/BardTransformer.php b/src/Transformers/BardTransformer.php index ac9d4a3..b4a9fc5 100644 --- a/src/Transformers/BardTransformer.php +++ b/src/Transformers/BardTransformer.php @@ -2,6 +2,7 @@ namespace Statamic\Importer\Transformers; +use Facades\Statamic\Importer\Support\FieldUpdater; use Statamic\Facades\AssetContainer; use Statamic\Fields\Field; use Statamic\Fieldtypes\Bard\Augmentor as BardAugmentor; @@ -57,32 +58,28 @@ public function transform(string $value): array private function enableBardButtons(): void { - $this->blueprint->ensureFieldHasConfig( - handle: $this->field->handle(), - config: array_merge($this->field->config(), [ - 'container' => $this->field->get('container') ?? AssetContainer::all()->first()?->handle(), - 'buttons' => [ - 'h1', - 'h2', - 'h3', - 'bold', - 'italic', - 'unorderedlist', - 'orderedlist', - 'removeformat', - 'quote', - 'anchor', - 'image', - 'table', - 'horizontalrule', - 'codeblock', - 'underline', - 'superscript', - ], - ]) - ); - - $this->blueprint->save(); + $buttons = [ + 'h1', + 'h2', + 'h3', + 'bold', + 'italic', + 'unorderedlist', + 'orderedlist', + 'removeformat', + 'quote', + 'anchor', + 'image', + 'table', + 'horizontalrule', + 'codeblock', + 'underline', + 'superscript', + ]; + + FieldUpdater::field($this->field) + ->blueprint($this->blueprint) + ->updateFieldConfig(array_merge($this->field->config(), ['buttons' => $buttons])); } private function isGutenbergValue(string $value): bool diff --git a/src/WordPress/Gutenberg.php b/src/WordPress/Gutenberg.php index 166e885..787737a 100644 --- a/src/WordPress/Gutenberg.php +++ b/src/WordPress/Gutenberg.php @@ -2,6 +2,7 @@ namespace Statamic\Importer\WordPress; +use Facades\Statamic\Importer\Support\FieldUpdater; use Statamic\Facades\AssetContainer; use Statamic\Facades\Blueprint as BlueprintFacade; use Statamic\Fields\Blueprint; @@ -400,7 +401,7 @@ protected static function renderHtmlToProsemirror(Field $field, string $html) protected static function ensureBardSet(Blueprint $blueprint, Field $field, string $handle, array $config): void { - $blueprint = BlueprintFacade::find("{$blueprint->namespace()}.{$blueprint->handle()}"); + $blueprint = BlueprintFacade::find($blueprint->fullyQualifiedHandle()); $field = $blueprint->field($field->handle()); $setExists = collect($field->get('sets', []))->contains( @@ -411,8 +412,9 @@ protected static function ensureBardSet(Blueprint $blueprint, Field $field, stri return; } - $blueprint - ->ensureFieldHasConfig($field->handle(), [ + FieldUpdater::field($field) + ->blueprint($blueprint) + ->updateFieldConfig([ ...$field->config(), 'sets' => array_merge($field->get('sets', []), [ 'main' => array_merge($field->get('sets.main', []), [ @@ -421,7 +423,6 @@ protected static function ensureBardSet(Blueprint $blueprint, Field $field, stri ]), ]), ]), - ]) - ->save(); + ]); } } diff --git a/tests/Transformers/BardTransformerTest.php b/tests/Transformers/BardTransformerTest.php index b11bd5a..985ea1c 100644 --- a/tests/Transformers/BardTransformerTest.php +++ b/tests/Transformers/BardTransformerTest.php @@ -8,6 +8,7 @@ use PHPUnit\Framework\Attributes\Test; use Statamic\Facades\AssetContainer; use Statamic\Facades\Collection; +use Statamic\Facades\Fieldset; use Statamic\Importer\Facades\Import; use Statamic\Importer\Tests\TestCase; use Statamic\Importer\Transformers\BardTransformer; @@ -252,4 +253,138 @@ public function it_downloads_images_and_stores_them_in_configured_folder() Storage::disk('public')->assertExists('custom-folder/image.png'); } + + #[Test] + public function it_enables_buttons_on_bard_field() + { + $transformer = new BardTransformer( + import: $this->import, + blueprint: $this->blueprint, + field: $this->field, + config: [] + ); + + $transformer->transform('
Hello world!
'); + + $blueprint = $this->collection->entryBlueprint(); + + $this->assertEquals([ + 'h1', + 'h2', + 'h3', + 'bold', + 'italic', + 'unorderedlist', + 'orderedlist', + 'removeformat', + 'quote', + 'anchor', + 'image', + 'table', + 'horizontalrule', + 'codeblock', + 'underline', + 'superscript', + ], $blueprint->field('content')->get('buttons')); + } + + #[Test] + public function it_enables_buttons_on_imported_bard_field() + { + Fieldset::make('content_stuff')->setContents(['fields' => [ + ['handle' => 'bard_field', 'field' => ['type' => 'bard']], + ]])->save(); + + $blueprint = $this->collection->entryBlueprint(); + + $this->blueprint->setContents([ + 'sections' => [ + 'main' => [ + 'fields' => [ + ['handle' => 'bard_field', 'field' => 'content_stuff.bard_field'], + ], + ], + ], + ])->save(); + + $transformer = new BardTransformer( + import: $this->import, + blueprint: $blueprint, + field: $blueprint->field('bard_field'), + config: [] + ); + + $transformer->transform('Hello world!
'); + + $fieldset = Fieldset::find('content_stuff'); + + $this->assertEquals([ + 'h1', + 'h2', + 'h3', + 'bold', + 'italic', + 'unorderedlist', + 'orderedlist', + 'removeformat', + 'quote', + 'anchor', + 'image', + 'table', + 'horizontalrule', + 'codeblock', + 'underline', + 'superscript', + ], $fieldset->field('bard_field')->get('buttons')); + } + + #[Test] + public function it_enables_buttons_on_imported_bard_field_with_prefix() + { + Fieldset::make('content_stuff')->setContents(['fields' => [ + ['handle' => 'bard_field', 'field' => ['type' => 'bard']], + ]])->save(); + + $blueprint = $this->collection->entryBlueprint(); + + $this->blueprint->setContents([ + 'sections' => [ + 'main' => [ + 'fields' => [ + ['import' => 'content_stuff', 'prefix' => 'resources_'], + ], + ], + ], + ])->save(); + + $transformer = new BardTransformer( + import: $this->import, + blueprint: $blueprint, + field: $blueprint->field('resources_bard_field'), + config: [] + ); + + $transformer->transform('Hello world!
'); + + $fieldset = Fieldset::find('content_stuff'); + + $this->assertEquals([ + 'h1', + 'h2', + 'h3', + 'bold', + 'italic', + 'unorderedlist', + 'orderedlist', + 'removeformat', + 'quote', + 'anchor', + 'image', + 'table', + 'horizontalrule', + 'codeblock', + 'underline', + 'superscript', + ], $fieldset->field('bard_field')->get('buttons')); + } } diff --git a/tests/WordPress/GutenbergTest.php b/tests/WordPress/GutenbergTest.php index fb59b7f..f8636d9 100644 --- a/tests/WordPress/GutenbergTest.php +++ b/tests/WordPress/GutenbergTest.php @@ -10,6 +10,7 @@ use Statamic\Facades\AssetContainer; use Statamic\Facades\Blueprint; use Statamic\Facades\Collection; +use Statamic\Facades\Fieldset; use Statamic\Importer\Tests\TestCase; use Statamic\Importer\WordPress\Gutenberg; use Statamic\Testing\Concerns\PreventsSavingStacheItemsToDisk; @@ -811,6 +812,72 @@ public function it_transforms_spacer_blocks() ], $output); } + #[Test] + public function it_append_sets_to_imported_bard_field() + { + Fieldset::make('content_stuff')->setContents(['fields' => [ + ['handle' => 'bard_field', 'field' => ['type' => 'bard']], + ]])->save(); + + $this->blueprint->setContents([ + 'sections' => [ + 'main' => [ + 'fields' => [ + ['handle' => 'bard_field', 'field' => 'content_stuff.bard_field'], + ], + ], + ], + ])->save(); + + Gutenberg::toBard( + config: [], + blueprint: $this->blueprint, + field: $this->blueprint->field('bard_field'), + value: <<<'HTML' + + + +HTML + ); + + $fieldset = Fieldset::find('content_stuff'); + + $this->assertSetExists('spacer', $fieldset->field('bard_field')); + } + + #[Test] + public function it_append_sets_to_imported_bard_field_with_prefix() + { + Fieldset::make('content_stuff')->setContents(['fields' => [ + ['handle' => 'bard_field', 'field' => ['type' => 'bard']], + ]])->save(); + + $this->blueprint->setContents([ + 'sections' => [ + 'main' => [ + 'fields' => [ + ['import' => 'content_stuff', 'prefix' => 'resources_'], + ], + ], + ], + ])->save(); + + Gutenberg::toBard( + config: [], + blueprint: $this->blueprint, + field: $this->blueprint->field('resources_bard_field'), + value: <<<'HTML' + + + +HTML + ); + + $fieldset = Fieldset::find('content_stuff'); + + $this->assertSetExists('spacer', $fieldset->field('bard_field')); + } + #[Test] public function it_returns_hook_output() {