- 🇬🇧United Kingdom james.williams
In case anyone finds themselves here and in a similar situation... I can certainly recommend Image Widget Crop → , though it works a little differently to imagefield_crop.
I needed to migrate cropped images from a Drupal 7 site that used imagefield_crop, to a Drupal 9 site, on which we used Image Widget Crop. Migrating the cropped images got pretty complex, but has come out pretty well. Here's some details of what I had to do, which I guess are worth sharing for anyone else needing to do similar:
- Configure the crop types, cropping settings & fields, widgets, etc for the Drupal 9 site to use, including an Image media type.
- I used the Media Migration module to migrate files to files+media entities. In my situation, it was fine to migrate the file IDs themselves over, and to use matching media IDs too. I expect this won't be an option on some projects, but made things much easier for my processes.
- Replace media_migration's 'dealer' plugin class for images, so it would cover images in imagefield_crop fields.
- In general, aim to migrate the uncropped (originally uploaded) image files, and reference those from host content. That's how Image Widget Crop usually references the images, whereas imagefield_crop references the cropped image files. (So migrations will have to translate from one to the other.) Image Widget Crop usually maps to the cropped images via the chosen 'crop type' referenced in image styles (e.g. so that different crops can be used for the same field, when output in different places).
- Use a
hook_migrate_prepare_row()
to (a) provide a map of cropped->uncropped file IDs, and (b) skip migrating cropped images as media entities (since they won't be referenced from content, so would just clog up the media library as duplicates of the original uncropped images). I imagine these bits could have been done better with specific plugin classes rather than this hook. - Made & used a custom plugin for migrating the data into the media field on every host node/entity, i.e. to use the uncropped file ID on the destination, that corresponded to the cropped images' IDs on the source end
- Set up additional migrations (i.e. as YAML) for the data in every imagefield_crop field, i.e. to migrate the crops themselves, creating 'crop' entities, using a custom source plugin that extended
Drupal\migrate\Plugin\migrate\source\SqlBase
. This allowed using a bundle filter in my migrations, so different crop types could be used in D9, for different images that happened to use the same source field storage in D7. - Finally - and perhaps optionally - I altered Image Widget Crop's widget (via two levels of
#process
callbacks!), to apply maximum post-cropping dimensions for certain contexts, as imagefield_crop allowed those per-field (i.e. per 'input'), whereas image_widget_crop does so per-crop type (i.e. per 'output'), though that can be bypassed fairly easily.
So yeah - not easy. I have the code for doing all this, but it's a bit much to just package up and share or even to write up in an accessible way! Plus I'm quite aware that it might not be generic enough to work for everyone / a majority. But I'll keep an eye on this issue; if anyone wants help or more detail, leave a comment or get in touch and I might be able to help!
- 🇬🇧United Kingdom james.williams
I've written up a bit more detail at https://www.computerminds.co.uk/articles/migrating-cropped-images , I hope that helps someone :)