diff --git a/src/Assets/AssetReferenceUpdater.php b/src/Assets/AssetReferenceUpdater.php index 9fb38b9b20..e0e86c1c77 100644 --- a/src/Assets/AssetReferenceUpdater.php +++ b/src/Assets/AssetReferenceUpdater.php @@ -56,7 +56,7 @@ protected function updateAssetsFieldValues($fields, $dottedPrefix) && $this->getConfiguredAssetsFieldContainer($field) === $this->container; }) ->each(function ($field) use ($dottedPrefix) { - $field->get('max_files') === 1 + $this->hasStringValue($field, $dottedPrefix) ? $this->updateStringValue($field, $dottedPrefix) : $this->updateArrayValue($field, $dottedPrefix); }); @@ -100,7 +100,7 @@ protected function updateBardFieldValues($fields, $dottedPrefix) && $field->get('container') === $this->container; }) ->each(function ($field) use ($dottedPrefix) { - $field->get('save_html') === true + $this->hasStringValue($field, $dottedPrefix) ? $this->updateStatamicUrlsInStringValue($field, $dottedPrefix) : $this->updateStatamicUrlsInArrayValue($field, $dottedPrefix); }); diff --git a/src/Data/DataReferenceUpdater.php b/src/Data/DataReferenceUpdater.php index 694d8c575c..a04f1751c9 100644 --- a/src/Data/DataReferenceUpdater.php +++ b/src/Data/DataReferenceUpdater.php @@ -208,6 +208,22 @@ public function isRemovingValue() return is_null($this->newValue); } + /** + * Determine if field has string value. + * + * @param \Statamic\Fields\Field $field + * @param null|string $dottedPrefix + * @return bool + */ + protected function hasStringValue($field, $dottedPrefix) + { + $data = $this->item->data()->all(); + + $dottedKey = $dottedPrefix.$field->handle(); + + return is_string(Arr::get($data, $dottedKey)); + } + /** * Update string value on item. * diff --git a/src/Taxonomies/TermReferenceUpdater.php b/src/Taxonomies/TermReferenceUpdater.php index de7e3df923..633ccfaf40 100644 --- a/src/Taxonomies/TermReferenceUpdater.php +++ b/src/Taxonomies/TermReferenceUpdater.php @@ -60,7 +60,7 @@ protected function updateTermsFieldValues($fields, $dottedPrefix) && in_array($this->taxonomy, Arr::wrap($field->get('taxonomies'))); }) ->each(function ($field) use ($dottedPrefix) { - $field->get('max_items') === 1 + $this->hasStringValue($field, $dottedPrefix) ? $this->updateStringValue($field, $dottedPrefix) : $this->updateArrayValue($field, $dottedPrefix); }); @@ -85,7 +85,7 @@ protected function updateScopedTermsFieldValues($fields, $dottedPrefix) && count(Arr::wrap($field->get('taxonomies'))) === 0; }) ->each(function ($field) use ($dottedPrefix) { - $field->get('max_items') === 1 + $this->hasStringValue($field, $dottedPrefix) ? $this->updateStringValue($field, $dottedPrefix) : $this->updateArrayValue($field, $dottedPrefix); }); diff --git a/tests/Listeners/UpdateAssetReferencesTest.php b/tests/Listeners/UpdateAssetReferencesTest.php index b18bd3b70d..925a7d7cd9 100644 --- a/tests/Listeners/UpdateAssetReferencesTest.php +++ b/tests/Listeners/UpdateAssetReferencesTest.php @@ -259,6 +259,45 @@ public function it_updates_multi_assets_fields() $this->assertEquals(['hoff.jpg', 'content/norris.jpg'], $entry->fresh()->get('pics')); } + /** @test */ + public function it_updates_assets_fields_regardless_of_max_files_setting() + { + $collection = tap(Facades\Collection::make('articles'))->save(); + + $this->setInBlueprints('collections/articles', [ + 'fields' => [ + [ + 'handle' => 'avatar', + 'field' => [ + 'type' => 'assets', + 'container' => 'test_container', + 'max_files' => 1, + ], + ], + [ + 'handle' => 'products', + 'field' => [ + 'type' => 'assets', + 'container' => 'test_container', + ], + ], + ], + ]); + + $entry = tap(Facades\Entry::make()->collection($collection)->data([ + 'avatar' => ['hoff.jpg'], // assuming it was previously `max_files` > 1 + 'products' => 'surfboard.jpg', // assuming it was previously `max_files` == 1 + ]))->save(); + + $this->assertEquals(['hoff.jpg'], $entry->get('avatar')); + $this->assertEquals('surfboard.jpg', $entry->get('products')); + + $this->assetHoff->path('hoff-new.jpg')->save(); + + $this->assertEquals(['hoff-new.jpg'], $entry->fresh()->get('avatar')); + $this->assertEquals('surfboard.jpg', $entry->fresh()->get('products')); + } + /** @test */ public function it_nullifies_references_when_deleting_an_asset() { @@ -1030,6 +1069,159 @@ public function it_updates_asset_references_in_bard_field_when_saved_as_html() $this->assertEquals($expected, $entry->fresh()->get('bardo')); } + /** @test */ + public function it_updates_asset_references_in_bard_field_regardless_of_save_html_setting() + { + $collection = tap(Facades\Collection::make('articles'))->save(); + + $this->setInBlueprints('collections/articles', [ + 'fields' => [ + [ + 'handle' => 'pretend_array_value', + 'field' => [ + 'type' => 'bard', + 'container' => 'test_container', + ], + ], + [ + 'handle' => 'pretend_html_value', + 'field' => [ + 'type' => 'bard', + 'container' => 'test_container', + 'save_html' => true, + ], + ], + ], + ]); + + $html = <<<'EOT' +
Some text.
+ + +More text. + + + + + +EOT; + + $entry = tap(Facades\Entry::make()->collection($collection)->data([ + 'pretend_array_value' => $html, + 'pretend_html_value' => [ + [ + 'type' => 'paragraph', + 'content' => [ + [ + 'type' => 'image', + 'attrs' => [ + 'src' => 'asset::test_container::surfboard.jpg', + 'alt' => 'surfboard', + ], + ], + [ + 'type' => 'link', + 'attrs' => [ + 'href' => 'statamic://asset::test_container::surfboard.jpg', + ], + ], + [ + 'type' => 'paragraph', + 'content' => 'unrelated', + ], + ], + ], + [ + 'type' => 'paragraph', + 'content' => [ + [ + 'type' => 'image', + 'attrs' => [ + 'src' => 'asset::test_container::hoff.jpg', + 'alt' => 'hoff', + ], + ], + [ + 'type' => 'link', + 'attrs' => [ + 'href' => 'statamic://asset::test_container::hoff.jpg', + ], + ], + [ + 'type' => 'paragraph', + 'content' => 'unrelated', + ], + ], + ], + [ + 'type' => 'paragraph', + 'content' => [ + [ + 'type' => 'image', + 'attrs' => [ + 'src' => 'asset::test_container::norris.jpg', + 'alt' => 'norris', + ], + ], + [ + 'type' => 'link', + 'attrs' => [ + 'href' => 'statamic://asset::test_container::norris.jpg', + ], + ], + ], + ], + [ + 'type' => 'paragraph', + 'content' => 'unrelated', + ], + ], + ]))->save(); + + $this->assertEquals($html, $entry->fresh()->get('pretend_array_value')); + + $this->assertEquals('asset::test_container::surfboard.jpg', Arr::get($entry->fresh()->data(), 'pretend_html_value.0.content.0.attrs.src')); + $this->assertEquals('surfboard', Arr::get($entry->fresh()->data(), 'pretend_html_value.0.content.0.attrs.alt')); + $this->assertEquals('statamic://asset::test_container::surfboard.jpg', Arr::get($entry->fresh()->data(), 'pretend_html_value.0.content.1.attrs.href')); + + $this->assertEquals('asset::test_container::hoff.jpg', Arr::get($entry->fresh()->data(), 'pretend_html_value.1.content.0.attrs.src')); + $this->assertEquals('hoff', Arr::get($entry->fresh()->data(), 'pretend_html_value.1.content.0.attrs.alt')); + $this->assertEquals('statamic://asset::test_container::hoff.jpg', Arr::get($entry->fresh()->data(), 'pretend_html_value.1.content.1.attrs.href')); + + $this->assertEquals('asset::test_container::norris.jpg', Arr::get($entry->fresh()->data(), 'pretend_html_value.2.content.0.attrs.src')); + $this->assertEquals('norris', Arr::get($entry->fresh()->data(), 'pretend_html_value.2.content.0.attrs.alt')); + $this->assertEquals('statamic://asset::test_container::norris.jpg', Arr::get($entry->fresh()->data(), 'pretend_html_value.2.content.1.attrs.href')); + + $this->assetHoff->path('content/hoff-new.jpg')->save(); + $this->assetNorris->delete(); + + $expectedHtml = <<<'EOT' +Some text.
+ + +More text. + + + + + +EOT; + + $this->assertEquals($expectedHtml, $entry->fresh()->get('pretend_array_value')); + + $this->assertEquals('asset::test_container::surfboard.jpg', Arr::get($entry->fresh()->data(), 'pretend_html_value.0.content.0.attrs.src')); + $this->assertEquals('surfboard', Arr::get($entry->fresh()->data(), 'pretend_html_value.0.content.0.attrs.alt')); + $this->assertEquals('statamic://asset::test_container::surfboard.jpg', Arr::get($entry->fresh()->data(), 'pretend_html_value.0.content.1.attrs.href')); + + $this->assertEquals('asset::test_container::content/hoff-new.jpg', Arr::get($entry->fresh()->data(), 'pretend_html_value.1.content.0.attrs.src')); + $this->assertEquals('hoff', Arr::get($entry->fresh()->data(), 'pretend_html_value.1.content.0.attrs.alt')); + $this->assertEquals('statamic://asset::test_container::content/hoff-new.jpg', Arr::get($entry->fresh()->data(), 'pretend_html_value.1.content.1.attrs.href')); + + $this->assertEquals('', Arr::get($entry->fresh()->data(), 'pretend_html_value.2.content.0.attrs.src')); + $this->assertEquals('norris', Arr::get($entry->fresh()->data(), 'pretend_html_value.2.content.0.attrs.alt')); + $this->assertEquals('', Arr::get($entry->fresh()->data(), 'pretend_html_value.2.content.1.attrs.href')); + } + /** @test */ public function it_updates_asset_references_in_markdown_fields() { diff --git a/tests/Listeners/UpdateTermReferencesTest.php b/tests/Listeners/UpdateTermReferencesTest.php index 7a092dbbc9..fe5f9bf128 100644 --- a/tests/Listeners/UpdateTermReferencesTest.php +++ b/tests/Listeners/UpdateTermReferencesTest.php @@ -109,6 +109,47 @@ public function it_updates_multi_terms_fields() $this->assertEquals(['hoff-new', 'norris'], $entry->fresh()->get('favourites')); } + /** @test */ + public function it_updates_terms_fields_regardless_of_max_items_setting() + { + $collection = tap(Facades\Collection::make('articles'))->save(); + + $this->setInBlueprints('collections/articles', [ + 'fields' => [ + [ + 'handle' => 'favourite', + 'field' => [ + 'type' => 'terms', + 'taxonomies' => ['topics'], + 'max_items' => 1, + 'mode' => 'select', + ], + ], + [ + 'handle' => 'non_favourites', + 'field' => [ + 'type' => 'terms', + 'taxonomies' => ['topics'], + 'mode' => 'select', + ], + ], + ], + ]); + + $entry = tap(Facades\Entry::make()->collection($collection)->data([ + 'favourite' => ['hoff'], // assuming it was previously `max_items` > 1 + 'non_favourites' => 'norris', // assuming it was previously `max_files` == 1 + ]))->save(); + + $this->assertEquals(['hoff'], $entry->get('favourite')); + $this->assertEquals('norris', $entry->get('non_favourites')); + + $this->termHoff->slug('hoff-new')->save(); + + $this->assertEquals(['hoff-new'], $entry->fresh()->get('favourite')); + $this->assertEquals('norris', $entry->fresh()->get('non_favourites')); + } + /** @test */ public function it_nullifies_references_when_deleting_a_term() { @@ -235,6 +276,45 @@ public function it_updates_scoped_multi_terms_fields() $this->assertEquals(['topics::hoff-new', 'topics::norris'], $entry->fresh()->get('favourites')); } + /** @test */ + public function it_updates_scoped_term_fields_regardless_of_max_items_setting() + { + $collection = tap(Facades\Collection::make('articles'))->save(); + + $this->setInBlueprints('collections/articles', [ + 'fields' => [ + [ + 'handle' => 'favourite', + 'field' => [ + 'type' => 'terms', + 'max_items' => 1, + 'mode' => 'select', + ], + ], + [ + 'handle' => 'non_favourites', + 'field' => [ + 'type' => 'terms', + 'mode' => 'select', + ], + ], + ], + ]); + + $entry = tap(Facades\Entry::make()->collection($collection)->data([ + 'favourite' => ['topics::hoff'], // assuming it was previously `max_items` > 1 + 'non_favourites' => 'topics::norris', // assuming it was previously `max_files` == 1 + ]))->save(); + + $this->assertEquals(['topics::hoff'], $entry->get('favourite')); + $this->assertEquals('topics::norris', $entry->get('non_favourites')); + + $this->termHoff->slug('hoff-new')->save(); + + $this->assertEquals(['topics::hoff-new'], $entry->fresh()->get('favourite')); + $this->assertEquals('topics::norris', $entry->fresh()->get('non_favourites')); + } + /** @test */ public function it_nullifies_references_when_deleting_a_scoped_term() {