From 8aff400faf7c4719b6d711ac8bdc2bcf52695c55 Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Thu, 24 Oct 2024 16:12:39 +0100 Subject: [PATCH] wip --- src/Http/Controllers/MappingsController.php | 6 ++++ src/Transformers/BardTransformer.php | 40 ++++++++++++++++++++- src/WordPress/Gutenberg.php | 18 +++++----- tests/Transformers/BardTransformerTest.php | 38 +++++++++++++++++++- tests/WordPress/GutenbergTest.php | 26 +++++++++++++- 5 files changed, 115 insertions(+), 13 deletions(-) diff --git a/src/Http/Controllers/MappingsController.php b/src/Http/Controllers/MappingsController.php index 9e66fe5..645d1d2 100644 --- a/src/Http/Controllers/MappingsController.php +++ b/src/Http/Controllers/MappingsController.php @@ -30,6 +30,12 @@ public function __invoke(MappingsRequest $request) return [ 'fields' => $blueprint->fields()->all() + ->reject(function (Field $field) { + $transformer = Importer::getTransformer($field->type()); + + return in_array($field->type(), ['section', 'grid', 'replicator', 'group']) + && ! $transformer; + }) ->map(function (Field $field) use ($request, $row) { $fields = []; diff --git a/src/Transformers/BardTransformer.php b/src/Transformers/BardTransformer.php index 267da91..2451ba3 100644 --- a/src/Transformers/BardTransformer.php +++ b/src/Transformers/BardTransformer.php @@ -2,6 +2,7 @@ namespace Statamic\Importer\Transformers; +use Illuminate\Support\Facades\Http; use Statamic\Facades\AssetContainer; use Statamic\Fieldtypes\Bard\Augmentor as BardAugmentor; use Statamic\Importer\WordPress\Gutenberg; @@ -22,7 +23,44 @@ public function transform(string $value): array ); } - return (new BardAugmentor($this->field->fieldtype()))->renderHtmlToProsemirror($value)['content']; + $value = (new BardAugmentor($this->field->fieldtype()))->renderHtmlToProsemirror($value)['content']; + + return collect($value) + ->map(function (array $node): ?array { + if ($this->field->get('container') && $node['type'] === 'image') { + $baseUrl = $this->config('assets_base_url'); + $downloadWhenMissing = $this->config('assets_download_when_missing', false); + $assetContainer = AssetContainer::find($this->field->get('container')); + + $path = Str::of($node['attrs']['src']) + ->after(Str::removeRight($baseUrl, '/')) + ->trim('/') + ->__toString(); + + $asset = $assetContainer->asset($path); + + if (! $asset && $downloadWhenMissing) { + $request = Http::get(Str::removeRight($baseUrl, '/').Str::ensureLeft($path, '/')); + + if (! $request->ok()) { + return null; + } + + $assetContainer->disk()->put($path, $request->body()); + $asset = $assetContainer->makeAsset($path); + } + + if (! $asset) { + return null; + } + + $node['attrs']['src'] = $asset->id(); + } + + return $node; + }) + ->filter() + ->all(); } private function enableBardButtons(): void diff --git a/src/WordPress/Gutenberg.php b/src/WordPress/Gutenberg.php index 4d891c4..1976134 100644 --- a/src/WordPress/Gutenberg.php +++ b/src/WordPress/Gutenberg.php @@ -63,10 +63,8 @@ public static function toBard(array $config, Blueprint $blueprint, Field $field, ]; } - if ($block['blockName'] === 'core/image') { - $assetContainer = $field->get('container') - ? AssetContainer::find($field->get('container')) - : AssetContainer::all()->first(); + if ($field->get('container') && $block['blockName'] === 'core/image') { + $assetContainer = AssetContainer::find($field->get('container')); $crawler = new Crawler($block['innerHTML']); $url = $crawler->filter('img')->first()->attr('src'); @@ -97,11 +95,15 @@ public static function toBard(array $config, Blueprint $blueprint, Field $field, } if ($block['blockName'] === 'core/gallery') { + $assetContainer = $field->get('container') + ? AssetContainer::find($field->get('container')) + : AssetContainer::all()->first(); + static::ensureBardSet($blueprint, $field, 'gallery', [ 'display' => __('Gallery'), 'icon' => 'media-image-picture-gallery', 'fields' => [ - ['handle' => 'images', 'field' => ['type' => 'assets', 'display' => __('Images')]], + ['handle' => 'images', 'field' => ['type' => 'assets', 'display' => __('Images'), 'container' => $assetContainer->handle()]], ], ]); @@ -113,11 +115,7 @@ public static function toBard(array $config, Blueprint $blueprint, Field $field, 'type' => 'gallery', 'images' => collect($block['innerBlocks']) ->filter(fn ($block) => $block['blockName'] === 'core/image') - ->map(function (array $block) use ($config, $field): string { - $assetContainer = $field->get('container') - ? AssetContainer::find($field->get('container')) - : AssetContainer::all()->first(); - + ->map(function (array $block) use ($config, $field, $assetContainer): string { $crawler = new Crawler($block['innerHTML']); $url = $crawler->filter('img')->first()->attr('src'); diff --git a/tests/Transformers/BardTransformerTest.php b/tests/Transformers/BardTransformerTest.php index fcc2b43..bc3a079 100644 --- a/tests/Transformers/BardTransformerTest.php +++ b/tests/Transformers/BardTransformerTest.php @@ -2,7 +2,9 @@ namespace Statamic\Importer\Tests\Transformers; +use Illuminate\Support\Facades\Storage; use PHPUnit\Framework\Attributes\Test; +use Statamic\Facades\AssetContainer; use Statamic\Facades\Collection; use Statamic\Importer\Tests\TestCase; use Statamic\Importer\Transformers\BardTransformer; @@ -23,7 +25,7 @@ public function setUp(): void $this->collection = tap(Collection::make('pages'))->save(); $this->blueprint = $this->collection->entryBlueprint(); - $this->blueprint->ensureField('content', ['type' => 'bard'])->save(); + $this->blueprint->ensureField('content', ['type' => 'bard', 'container' => 'assets'])->save(); $this->field = $this->blueprint->field('content'); } @@ -68,4 +70,38 @@ public function it_converts_html_to_prosemirror() ['type' => 'text', 'text' => ' Maxime iam et inventore. ipsam in dignissimos qui occaecati.'], ]], $output); } + + #[Test] + public function it_handles_images() + { + AssetContainer::make('assets')->disk('public')->save(); + Storage::disk('public')->put('2024/10/image.png', 'original'); + + $transformer = new BardTransformer($this->blueprint, $this->field, [ + 'assets_base_url' => 'https://example.com/wp-content/uploads', + ]); + + $output = $transformer->transform(<<<'HTML' +

Nam voluptatem rem molestiae cumque doloremque. Saepe animi deserunt Maxime iam et inventore. ipsam in dignissimos qui occaecati.

+ +HTML); + + $this->assertEquals([ + [ + 'type' => 'paragraph', + 'attrs' => ['textAlign' => 'left'], + 'content' => [ + ['type' => 'text', 'text' => 'Nam voluptatem rem molestiae cumque doloremque. '], + ['type' => 'text', 'text' => 'Saepe animi deserunt', 'marks' => [['type' => 'bold']]], + ['type' => 'text', 'text' => ' Maxime iam et inventore. ipsam in dignissimos qui occaecati.'], + ], + ], + [ + 'type' => 'image', + 'attrs' => [ + 'src' => 'assets::2024/10/image.png', + ], + ], + ], $output); + } } diff --git a/tests/WordPress/GutenbergTest.php b/tests/WordPress/GutenbergTest.php index 412a9c3..3a1fd40 100644 --- a/tests/WordPress/GutenbergTest.php +++ b/tests/WordPress/GutenbergTest.php @@ -31,7 +31,7 @@ public function setUp(): void 'sections' => [ 'main' => [ 'fields' => [ - ['handle' => 'content', 'field' => ['type' => 'bard']], + ['handle' => 'content', 'field' => ['type' => 'bard', 'container' => 'assets']], ], ], ], @@ -219,6 +219,30 @@ public function it_transforms_image_blocks() ], $output); } + #[Test] + public function it_doesnt_transforms_image_blocks_when_container_is_missing_from_bard_config() + { + Http::preventStrayRequests(); + + AssetContainer::make('assets')->disk('public')->save(); + Storage::disk('public')->put('2024/10/image.png', 'original'); + + $this->blueprint->ensureFieldHasConfig('content', ['type' => 'bard', 'container' => null])->save(); + + $output = Gutenberg::toBard( + config: [], + blueprint: $this->blueprint, + field: $this->blueprint->field('content'), + value: <<<'HTML' + +
+ +HTML + ); + + $this->assertEquals([], $output); + } + #[Test] public function it_transforms_image_blocks_and_downloads_images_that_dont_exist_in_asset_container() {