Problem/Motivation
With the following configuration, I believe that MediaWysiwygFilter returns incorrect embed UUIDs when configured to output <drupal-media>
type embeds.
$settings['media_migration_embed_token_transform_destination_filter_plugin'] = 'media_embed';
- File and Media migrations do not have matching destination IDs
- The D7 source HTML contains embeds like
[[{"fid":"345","view_mode":"wysiwyg","type":"media"}]]
- A
media_migrations:
lookup is used to locate the media ID based on the embedded file ID
Steps to reproduce
Sorry, this is long, I wanted to capture it fully :)
We are migrating D7 files to D9 media, and we have Drupal 7 file embeds in source content which we want to migrate to Drupal 9 media embeds.
One example file embed is a node with body containing:
[[{"fid":"345","view_mode":"wysiwyg","attributes":{"class":"media-element file-wysiwyg","data-delta":"1"}}]]
Our configuration in settings.php
is:
$settings['media_migration_embed_token_transform_destination_filter_plugin'] = 'media_embed';
In the node migration we have:
body:
-
plugin: sub_process
source: body
process:
summary: summary
value:
-
plugin: media_wysiwyg_filter
source: value
view_mode_matching:
wysiwyg: teaser
default: teaser
media_migrations:
- d7_media_image
file_migrations:
- d7_file_public
format:
plugin: static_map
source: format
map:
full_html: full_html
raw_html: full_html
default_value: basic_html
Migration d7_media_image
is a migration with source d7_file
and destination entity:media
. It preserves the source fid as destination file ID.
Migration d7_file_public
is a migration with source d7_file
and destination entity:file
. It does not preserve the source fid as destination media ID.
The source file 345 referenced in the example HTML above is correctly migrated to the destination file ID=345.
The source file 345 referenced is also migrated to a destination media of bundle=document with media ID=261.
If I set the following settings:
$settings['media_migration_embed_media_reference_method'] = 'id';
$settings['media_migration_embed_token_transform_destination_filter_plugin'] = 'entity_embed';
then run the migration, the file ID token is converted to:
<drupal-entity data-embed-button="media" data-entity-type="media" data-entity-id="261" data-entity-embed-display="view_mode:media.teaser"></drupal-entity>
That's the correct entity ID to embed! But it requires setting the wrong embed type for our site.
If instead I set the desired settings:
$settings['media_migration_embed_token_transform_destination_filter_plugin'] = 'media_embed';
The migrated output becomes:
<drupal-media data-entity-type="media" data-entity-uuid="f1bad2f1-e7a7-4172-b134-b60b96884bca" data-view-mode="teaser"></drupal-media>
This entity corresponds to a media entity with the ID of the original file. MediaWysiwygFilter has skipped the lookup(s) required to convert it into the correct entity ID and then UUID.
The skipped step is at line 327, where we only look up the destination media ID if $reference_method_is_id
. If I modify that line to permit the findDestId() lookup for <drupal-media>
embed type, then the desired output is returned.
<drupal-media data-entity-type="media" data-entity-uuid="93ec25a8-538e-42b0-8b0c-6e740c0c110c" data-view-mode="teaser"></drupal-media>
I verified the UUID to ID mappings using drush core-cli
:
>>> \Drupal::service('entity.repository')->loadEntityByUuid('media', 'f1bad2f1-e7a7-4172-b134-b60b96884bca')->id();
=> "345"
>>> \Drupal::service('entity.repository')->loadEntityByUuid('media', '93ec25a8-538e-42b0-8b0c-6e740c0c110c')->id();
=> "261"
Proposed resolution
I propose that this code block be modified so that $embed_metadata['id'] = $this->findDestId($embed_metadata['id'], $this->configuration['media_migrations']);
is set whether or not $reference_method_is_id
is true or false.
Remaining tasks
- Check that there isn't a reason for this check that I'm missing (eg, I've misunderstood the configuration)
- Add tests to validate expectations
- Patch
API changes