Skip to content

Commit

Permalink
Fix error when updating Bard configs inside fieldsets (#22)
Browse files Browse the repository at this point in the history
* Handle updating bard configs when field is from fieldset

* Add tests

* Handle case where only a single field is being imported

* Fix styling

* Update tests.

* Add tests to cover importing single fields.

* Extract field update logic into a class.

* Add comment for future me.

* Fix styling

---------

Co-authored-by: duncanmcclean <[email protected]>
  • Loading branch information
duncanmcclean and duncanmcclean authored Nov 29, 2024
1 parent 86fb0ca commit d35d87b
Show file tree
Hide file tree
Showing 5 changed files with 375 additions and 31 deletions.
144 changes: 144 additions & 0 deletions src/Support/FieldUpdater.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<?php

namespace Statamic\Importer\Support;

use Statamic\Facades\Blink;
use Statamic\Facades\Fieldset;
use Statamic\Fields\Blueprint;
use Statamic\Fields\Field;
use Statamic\Support\Str;

class FieldUpdater
{
protected $field;
protected $blueprint;

public function field(Field $field): self
{
$this->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();
}
}
49 changes: 23 additions & 26 deletions src/Transformers/BardTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
11 changes: 6 additions & 5 deletions src/WordPress/Gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand All @@ -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', []), [
Expand All @@ -421,7 +423,6 @@ protected static function ensureBardSet(Blueprint $blueprint, Field $field, stri
]),
]),
]),
])
->save();
]);
}
}
135 changes: 135 additions & 0 deletions tests/Transformers/BardTransformerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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('<p>Hello world!</p>');

$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('<p>Hello world!</p>');

$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('<p>Hello world!</p>');

$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'));
}
}
Loading

0 comments on commit d35d87b

Please sign in to comment.