Problem/Motivation
I have a migration that is migrate English and Spanish content. It has multiple steps:
- Migrating files and media
- Migrating Taxonomies first in English and then in Spanish and linking the translations
- Migrating Content first in English and then in Spanish and linking the translations
The majority of it works but I have discovered that when migrating the Spanish content, the fields which are entity relationships to taxonomy terms do not get migrated.
The snippet of the English content migration YAML which works is:
....
process:
....
field_themes:
plugin: migration_lookup
migration: themes
no_stub: true
source: themecats
....
destination:
plugin: entity:node
default_bundle: resource
....
The snippet of the Spanish content migration YAML which doesn't work is:
....
process:
....
langcode:
plugin: default_value
default_value: 'es'
....
field_themes:
plugin: migration_lookup
migration: themes_es
no_stub: true
source: themecats
....
destination:
plugin: entity:node
default_bundle: resource
translations: true
....
The English migration will create the nodes and link the terms in field_themes. The Spanish migration will create the nodes but the terms will not be linked.
I have done some debugging and discovered that if I get the value of field_themes before the entity is saved in the save() function in /core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php then the structure of the value is different for English and Spanish.
e.g. var_dump($entity->get('field_themes')->getValue()); produces
English
array(2) {
[0]=>
array(1) {
["target_id"]=>
string(4) "1371"
}
[1]=>
array(1) {
["target_id"]=>
string(4) "1385"
}
}
Spanish
array(1) {
[0]=>
array(2) {
[0]=>
string(4) "1371"
[1]=>
string(2) "es"
}
}
Notice that for English the array is keyed on target_id but the Spanish are keyed on integers.
By adding (hacking!) code into the save() function and using $entity->get('field_themes')->getValue()to retrieve the values, process them into a new array, and then set them using $entity->get('field_themes')->setValue(). The value returned now contained an array item keyed on target_id and the taxonomy terms were created albeit in English not Spanish.
This test suggests to me that when creating the values for the Spanish fields the migration module code isn't creating the structure correctly. Unfortunately, I don't know enough to dig deeper to find where that might be happening.
Issue fork drupal-3244859
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
ded commentedHaving done further debugging - I believe the structure creation is correct and that the
langcodeshould be present. This is based on the code in thegetIdsfunction incore/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.phpwhich is called from thedoLookupfunction incore/modules/migrate/src/MigrateLookup.phpI have found that it is the
filterEmptyItemsfunction incore/lib/Drupal/Core/Field/FieldItemList.phpwhich is stripping out the array items for the Spanish migration during the presave resulting in the terms not being created. It is called from theupdateOriginalValuesfunction incore/lib/Drupal/Core/Entity/ContentEntityBase.phpwhich in turn is called fromdoPreSavefunction incore/lib/Drupal/Core/Entity/ContentEntityStorageBase.phpComment #3
quietone commented@ded. Thanks for the report and your work to isolate the problem. It is helpful. Can you provide some more information? What is the source of the data? Are you using the classic node migrations or the complete node migrations? It would help to see the themes and themes_es migration as well.
If field_themes is an entity reference field then the process pipeline should be using sub_process. See \Drupal\taxonomy\Plugin\migrate\field\TaxonomyTermReference.
Comment #4
ded commentedThanks @quietone
The source is WordPress via its REST API using a custom source plugin which extends the migrate_plus URL source plugin
The themes migration is
and themes_es is
I don't believe the classic/complete applies as the source is not Drupal. Let me know if I have that wrong.
I will look at \Drupal\taxonomy\Plugin\migrate\field\TaxonomyTermReference and see if I can debug further.
Thanks
Comment #5
ded commentedFurther debugging has not revealed anything new and I have been unable to find where the field's are populated which is where I think the issue is.
In order to unblock the project that this is holding up I have placed the following code in the
save()function of Drupal\migrate\Plugin\migrate\destination\EntityContentBase class.This deletes and recreates the field values which are created with the correct array keys and they are then migrated. It isn't a solution to the issue but provides a viable workaround for this project and also shows the field values array that the migration creates is incorrect.
Comment #11
quietone commentedThe Migrate Drupal Module was approved for removal in #3371229: [Policy] Migrate Drupal and Migrate Drupal UI after Drupal 7 EOL.
This is Postponed. The status is set according to two policies. The Remove a core extension and move it to a contributed project and the Extensions approved for removal policies.
The deprecation work is in #3522602: [meta] Tasks to remove Migrate Drupal module and the removal work in #3522602: [meta] Tasks to remove Migrate Drupal module.
Migrate Drupal will not be moved to a contributed project. It will be removed from core after the Drupal 12.x branch is open.