Skip to content

Commit

Permalink
[4.x] Fixes for asset/term reference updater strictness (#9878)
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseleite authored Apr 15, 2024
1 parent 316f0be commit b929d3b
Show file tree
Hide file tree
Showing 5 changed files with 292 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/Assets/AssetReferenceUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down Expand Up @@ -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);
});
Expand Down
16 changes: 16 additions & 0 deletions src/Data/DataReferenceUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
4 changes: 2 additions & 2 deletions src/Taxonomies/TermReferenceUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand All @@ -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);
});
Expand Down
192 changes: 192 additions & 0 deletions tests/Listeners/UpdateAssetReferencesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down Expand Up @@ -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'
<p>Some text.</p>
<img src="statamic://asset::test_container::hoff.jpg">
<img src="statamic://asset::test_container::hoff.jpg" alt="test">
</p>More text.</p>
<p><a href="statamic://asset::test_container::hoff.jpg">Link</a></p>
<img src="statamic://asset::test_container::norris.jpg">
<p><a href="statamic://asset::test_container::norris.jpg">Link</a></p>
<img src="statamic://asset::test_container::surfboard.jpg">
<p><a href="statamic://asset::test_container::surfboard.jpg">Link</a></p>
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'
<p>Some text.</p>
<img src="statamic://asset::test_container::content/hoff-new.jpg">
<img src="statamic://asset::test_container::content/hoff-new.jpg" alt="test">
</p>More text.</p>
<p><a href="statamic://asset::test_container::content/hoff-new.jpg">Link</a></p>
<img src="">
<p><a href="">Link</a></p>
<img src="statamic://asset::test_container::surfboard.jpg">
<p><a href="statamic://asset::test_container::surfboard.jpg">Link</a></p>
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()
{
Expand Down
80 changes: 80 additions & 0 deletions tests/Listeners/UpdateTermReferencesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down Expand Up @@ -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()
{
Expand Down

0 comments on commit b929d3b

Please sign in to comment.