-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add asset reference updating. #149
Conversation
I have such setup going for this addons development: plain Statamic install, where this addon is installed through symlink in project directory. In projects composer.json it looks like this. "require": {
"spatie/statamic-responsive-images": "dev-main",
},
"repositories": [
{
"type": "path",
"url": "./statamic-responsive-images"
}
], On top of that I have Laravel Sail for the project, but I do not think you need it. Then I SSH into the Docker instance, navigate to |
I'm afraid I might have to leave it there because I don't use Docker, and I stopped using Vagrant a while back. I'm using Laragon on Windows. I don't think I'll figure this out anytime soon. Sorry! I'm a little overloaded with other work at the moment. |
I fixed up the asset reference and missing dependency there by the way. |
My apologies, your instructions for testing worked perfectly fine on my environment. I have adjusted the tests now and they pass, though I'm not quite sure if I have everything covered. |
Good to hear. I can take this for a spin over the weekend and maybe help out with tests. |
return; | ||
} | ||
|
||
Log::info('UpdateResponsiveReferences listener triggered.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove this log statement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@ncla It looks good to me, if you can have another look and test it out then I'll merge 👍 |
I would like to suggest writing more/different tests as the current ones test only asset changes, not reference changes. You can a look at how Statamic tests reference changing over here: https://github.com/statamic/cms/blob/8f18f78375a31a6f6e342b8410e3ce4aea529eed/tests/Listeners/UpdateAssetReferencesTest.php#L52-L89 Trying to whip a test with responsive field right now. |
Let me know if I can do anything and how many additional tests you would like. |
I think I have been writing a test without actually testing manually in browser if it works. 😅 I see the log message from
However when I change filename through asset browser, it saves the data like this:
My blueprint looks like this:
Am I tripping? Can you verify? 😅 |
On the same blueprint I have another, regular asset field that does update correctly. Of course however that is handled by Statamic's own |
I am seeing the same behaviour. If the responsive field only has a single asset selected then renaming the file works fine.
If the responsive field has multiple files selected then I am seeing things like
Fairly certain this is down to the We might need a custom update function. I'll see what I can tinker together here... |
Yea I think you may also need to use more methods e.g. similar to what |
I haven't got the brainpower for this today, and I'm away from tomorrow. I can check next weekend but hopefully somebody with more Statamic data experience than myself can figure it out. |
No rush, really. Could you add access for me to your repository? I think I may be able to add a test soon. |
Invite sent ;) |
Just some notes. The Arr::dot() call in DataReferenceUpdater@updateArrayValue()DataReferenceUpdater is adding a Default code:
Modified:
This produces the correct responsive src keys, but each file is wrapped in array tags, and the comparisons / transformations don't match anymore. It probably just requires a few more simple modifications but I can't figure them out right now. One idea would be to keep the dot function and remap all of the collection keys on $fieldData to remove the zeroes. Will revisit if someone doesn't beat me to it :) |
Based on my last comment I have gone with the approach of remapping the So I guess this all needs to be tested with responsive fields that have a single image, and ones that have multiple images. |
Added a test, took me a while.. 😅 something like this. I had to boot up addon events in Some of the tests in Not sure why it didn't fail on GitHub test run. Maybe cache from test bench that has old content files, blueprints?
To be continued. |
I was writing a test for the fix you applied in last commit and I was thinking how come just single value for image:
src:
- 'assets::tttttt.png' AFAIK it is not possible to have multiple images for a breakpoint. However you can have multiple breakpoints with single image in each. If you save content file like this manually through code editor src: 'images::image-18-renamed.jpg' In control panel it will work just fine. Once saved again, it makes it into an array. Is this maybe an old relic of this addon where it saved this data in arrays? Or is it just how YAML works? I am asking because maybe there is a need to fix this data saving. Regardless if we do fix the fieldtype saving data, it is good idea to account for old, outdated data I think anyway, in this PR. I got this confusion because I am writing this test and if I use the same way of storing entry data, then array value gets converted to a string value $entry = tap(Facades\Entry::make()->collection($collection)->data([
'avatar' => [
'src' => ['test_container::test.jpg'],
],
]))->save(); becomes avatar:
src: 'test_container::new-test2.jpg' But I will work around it. Curious what is happening here though. |
I did notice that too - Each breakpoint in the fieldData is an array that only contains a single image. I don't know why! By the way, my last commit seems silly now. I am using str_replace to convert the dot-notation array. It would probably be better to remove the But maybe I'll leave it until we understand more about this single item array anomaly...? |
Never mind, my test was working correctly. Took another fresh look. For now I wrote the test to expect same structure after a file has moved, as such the test is currently failing. Question remains: should the array be converted to a string value when updating references? In my opinion, structure should be kept consistent with how it is saved normally. No surprise. Rias, maybe you have a clue why is the |
Went ahead and updated the
This was helpful, thanks. |
I have lost track of what is going here but let me know if I can do anything. |
I think all what is left is testing Responsive field within other nested fieldtypes + re-test manually, check and remove the initial tests, look around at statamic/cms repo for issues/PRs regarding this feature and see if we missed any edge cases. I don't think much is left so I don't mind finishing this off if you don't have much time on your hands. |
Less repeating code in ResponsiveReferenceUpdater
src/ResponsiveReferenceUpdater.php
Outdated
$referencesUpdated = 0; | ||
|
||
$fieldData->transform(function ($value, $key) use (&$referencesUpdated) { | ||
if (!str_ends_with($key, 'src')) { | ||
return $value; | ||
} | ||
|
||
// In content files, the src value can be either string or array. | ||
// We first handle the string value, and then handle the array value. | ||
if (is_string($value) && $value === $this->originalValue()) { | ||
$referencesUpdated++; | ||
return $this->newValue(); | ||
} | ||
|
||
// Handle array value. | ||
if (is_array($value) && in_array($this->originalValue(), $value)) { | ||
return array_map(function ($item) use (&$referencesUpdated) { | ||
if ($item === $this->originalValue()) { | ||
$referencesUpdated++; | ||
return $this->newValue(); | ||
} | ||
|
||
return $item; | ||
}, $value); | ||
} | ||
|
||
return $value; | ||
}); | ||
|
||
if ($referencesUpdated === 0) { | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kinda feel weird about this $referencesUpdated
usage here but I don't have an idea right now on how to rewrite this to be cleaner.
Something like this maybe for example https://github.com/statamic/cms/blob/a7f989f3d56eff1b21f0f4d0472bbdf16418b7c4/src/Assets/AssetReferenceUpdater.php#L292-L313
Okay I think I am pretty happy with this apart from the comment I left about Compared to regular asset reference updating, we do not have to handle asset URLs in Markdown, Bard images, Link fieldtype. The most Responsive fieldtype can do is be part of a set (in Bard, Replicator). There is a test for Replicator case, but for Grid and Bard sets/rows I just tested manually and reference updating worked. |
Thank you sir. You seem to know your way around the Statamic stuff much better than myself. I am just a noob. All sounds good so far! |
New changes to asset updating dropped in yesterdays core update. Need to check if all is good. statamic/cms#6504 |
Respect config value for reference updating See statamic/cms#6504
Thanks for all the work on this so far! Let me know when it's ready for a new review and merging |
@riasvdv it is ready to be reviewed. My only last minor concern is how potentially this could break if there are changes to |
I have tested this manually, and I think my test file is 99% ready. Unfortunately I have no idea how to run this test locally!!
I'm running this from my project folder:
php artisan test vendor/spatie/statamic-responsive-images
But I'm getting a Uncaught Error: Class "Spatie\ResponsiveImages\Tests\TestCase" not found