Problem/Motivation

On migration from D7, the taxonomy term fields get migrated fine, but they are set to allow all vocabularies, even though that wasn't the case in source.

Proposed resolution

In D7, the allowed vocabularies is a part of field settings which is not available in instance migration, which is where it needs to be in D8. We should add the settings first and then process it during migration.

For all the allowed vocabularies the vid needs to be added to the row so somewhere in the pipeline a migration_lookup can be done to determine the new, migrated vocabulary name.

Remaining tasks

Patch
Review
Testing - patch confirmed to work in #49
Commit

User interface changes

None

API changes

None

Data model changes

None

CommentFileSizeAuthor
#62 2763637-62.patch9.33 KBalexpott
#60 2763637-60.patch8.35 KBquietone
#60 interdiff-58-60.txt1.17 KBquietone
#58 interdiff-47-58.txt1.32 KBquietone
#58 2763637-58.patch8.34 KBquietone
#47 interdiff-45-47.txt11.35 KBquietone
#47 2763637-47.patch8.29 KBquietone
#47 2763637-review-only.txt6.2 KBquietone
#45 2763637-45.patch6.16 KBtimwood
#31 2763637-31.patch6.02 KBjofitz
#31 interdiff-30-31.txt1.74 KBjofitz
#30 2763637-30.patch6.04 KBjofitz
#24 d7_taxonomy_term_fields-2763637-24.patch6.12 KBjofitz
#22 interdiff_17-22.txt1.01 KBjofitz
#22 d7_taxonomy_term_fields-2763637-22.patch8.15 KBjofitz
#17 d7_taxonomy_term_fields-2763637-17.patch7.81 KBjofitz
#17 interdiff_13-17.txt5.39 KBjofitz
#13 d7_taxonomy_term_fields-2763637-13.patch5.59 KBjofitz
#13 d7_taxonomy_term_fields-2763637-13--test_only.patch1.7 KBjofitz
#4 d7_taxonomy_term_fields-2763637-4.patch3.9 KBhussainweb
#4 interdiff-2-4.txt920 byteshussainweb
#2 d7_taxonomy_term_fields-2763637-2.patch3 KBhussainweb
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

hussainweb created an issue. See original summary.

hussainweb’s picture

Status: Active » Needs review
FileSize
3 KB

I guess this could be polished further but this works. Reviews please.

Status: Needs review » Needs work

The last submitted patch, 2: d7_taxonomy_term_fields-2763637-2.patch, failed testing.

hussainweb’s picture

Status: Needs work » Needs review
FileSize
920 bytes
3.9 KB

Fixing the failure.

hussainweb’s picture

quietone’s picture

Issue tags: +migrate-d7-d8

Tagging for d7.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mikeryan’s picture

Status: Needs review » Needs work
+++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
@@ -17,9 +17,19 @@ class FieldInstanceSettings extends ProcessPluginBase {
+      $vocabulary = $field_settings['allowed_values'][0]['vocabulary'];

Doesn't the D7 taxonomy_term_reference field permit multiple target vocabularies? We should migrate the full list.

hussainweb’s picture

Status: Needs work » Needs review

@mikeryan, I don't think so. I just created a field to make sure and it is a simple select list that only allows you to select one vocabulary.

mikeryan’s picture

Assigned: Unassigned » mikeryan

I'll be reviewing this.

mikeryan’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Looks good, but we should have a test (please include a test-only patch to demonstrate the resulting misconfiguration without the fix).

mikeryan’s picture

Assigned: mikeryan » Unassigned
jofitz’s picture

Added tests (including test only).

The last submitted patch, 13: d7_taxonomy_term_fields-2763637-13--test_only.patch, failed testing.

mikeryan’s picture

Status: Needs review » Reviewed & tested by the community

Thanks!

catch’s picture

Status: Reviewed & tested by the community » Needs work

@mikeryan is right in #8, while the 7.x UI doesn't allow multiple vocabulary references, the API does.

jofitz’s picture

Handle multiple vocabulary references.

phenaproxima’s picture

I think what gives me pause here is the possibility that vocabularies' machine names may change during the migration. Honestly, this should probably cause the field settings migration to depend on the d7_taxonomy_vocabulary migration, then look up the vocabulary names there. But that seems like a big rewrite (and far more complex) so...I dunno.

mikeryan’s picture

I think what gives me pause here is the possibility that vocabularies' machine names may change during the migration.

Just to be clear, the concern would be if a vocabulary machine name needed to be deduped, right? d7_taxonomy_vocabulary doesn't do deduping (since D7 had proper machine names for vocabularies), so not a concern for the straight upgrade path, but maybe for custom scenarios - if you're renaming vocabularies, then the straight copy of the machine name here breaks you (or forces you to do a custom override of the process plugin).

If we wanted to handle that, we would

cause the field settings migration to depend on the d7_taxonomy_vocabulary migration, then look up the vocabulary names there:
+++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
@@ -17,9 +17,20 @@ class FieldInstanceSettings extends ProcessPluginBase {
+          $instance_settings['handler_settings']['target_bundles'][$vocabulary] = $vocabulary;

I.e., call the migration process plugin to translate the incoming $vocabulary to any renamed machine name.

I think we may discuss this on the weekly migration call, leaving "Needs review" for now.

phenaproxima’s picture

Status: Needs review » Needs work

In the interest of getting this working as soon as possible for the 90% use case, I'd be OK with putting a TODO comment there explaining the situation, and what needs to be done to make it work for custom migration scenarios.

ckng’s picture

Tested path #17 and #13, both also not working for me.

Rollback and re-migrated the following:
upgrade_d7_field
upgrade_d7_field_instance
upgrade_d7_field_instance_widget_settings
upgrade_d7_field_formatter_settings

jofitz’s picture

Status: Needs work » Needs review
FileSize
8.15 KB
1.01 KB

I got sick of seeing this "Needs work" in my issue list so I've had a go at the @todo suggested by @phenaproxima.

@ckng Can you tell us more about the problems you have had, please? It works fine for me.

Status: Needs review » Needs work

The last submitted patch, 22: d7_taxonomy_term_fields-2763637-22.patch, failed testing.

jofitz’s picture

Status: Needs work » Needs review
FileSize
6.12 KB

Re-roll.

phenaproxima’s picture

Assigned: Unassigned » phenaproxima

Self-assigning for re-review.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

phenaproxima’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
    @@ -20,6 +20,22 @@ public function transform($value, MigrateExecutableInterface $migrate_executable
    +    if ($row->getSourceProperty('type') == 'taxonomy_term_reference') {
    +      foreach ($field_settings['allowed_values'] as $allowed_value) {
    +        if ($vocabulary = $allowed_value['vocabulary']) {
    +          $instance_settings['handler_settings']['sort'] = [
    +            'field' => '_none',
    +          ];
    +          // @todo Handle duplicate vocabulary machine names ($vocabulary). This
    +          // current code works for migrations from Drupal 7 (because that uses
    +          // proper machine names for vocabularies), but may have problems with
    +          // custom migration scenarios if they include vocabulary names that
    +          // require de-duping.
    +          $instance_settings['handler_settings']['target_bundles'][$vocabulary] = $vocabulary;
    +        }
    +      }
    +    }
    

    Can this be delegated to a cckfield plugin?

    Also, as noted in the comment, this is not accounting for the possibility of the migrated vocabulary having a different machine name due to uniqification or whatever. The plugin should use the migration process plugin to do a lookup. That will get real messy if this is kept in this one FieldInstanceSettings plugin, so that's another argument for moving this to its own cckfield plugin.

    EDIT: I know this contradicts what I said in #20, but that was three months ago. Circumstances have changed, and I think it's worth doing this right the first time.

  2. +++ b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldInstanceTest.php
    @@ -110,6 +110,22 @@ protected function assertLinkFields($id, $title_setting) {
    +   * @param array $target_bundles
    

    Should be string[], not array.

  3. +++ b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldInstanceTest.php
    @@ -110,6 +110,22 @@ protected function assertLinkFields($id, $title_setting) {
    +  protected function assertEntityReferenceFields($id, $target_bundles) {
    

    $target_bundles should be type hinted.

  4. +++ b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateFieldInstanceTest.php
    @@ -110,6 +110,22 @@ protected function assertLinkFields($id, $title_setting) {
    +    $this->assertSame($expected_target_bundles, $handler_settings['target_bundles']);
    

    This will fail if $expected_target_bundles and $target_bundles have the same values, but not in the same order. We should just call assertContains() or assertArrayHasKey() on every element of $target_bundles.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dillix’s picture

Is there a chance we see it in D8.4?

jofitz’s picture

Assigned: phenaproxima » jofitz
Status: Needs work » Needs review
FileSize
6.04 KB

Patch in #24 no longer applies to doing a quick re-roll before addressing @phenaproxima's comments in #27.

jofitz’s picture

Addressing review in #27:

  1. @phenaproxima can you explain a bit more about delegating this to a field plugin, please? I have spent too long fiddling with Drupal\taxonomy\Plugin\migrate\field\TaxonomyTermReference without success (am I even looking at the right plugin!?!)
  2. array replaced with string[].
  3. Type-hinted $target_bundles with array.
  4. Call assertContains() on every element of $target_bundles. Also re-ordered the array in one of the tests so that it would fail with the previous code (but not this).
heddn’s picture

Status: Needs review » Needs work

Field and field instances now have access to the full set of configuration, so I think that changes things around a little bit now. And we can merge in a process plugin that extends from migration_lookup (or maybe is the lookup itself).

jofitz’s picture

I've just taken another look at this and I'm none the wiser. I think I want to add Drupal\taxonomy\Plugin\migrate\field\TaxonomyTermReference::processFieldInstance(), but I don't know how to replicate the functionality of FieldInstanceSettings::transform() in there. In particular how to obtain the allowed_values from unserialize($value[2]['data'])['settings']['allowed_values'](!)

I've probably got the wrong end of the stick, but I could do with some guidance, please.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dww’s picture

Title: D7 taxonomy term fields are not migrated with allowed vocabularies » D7 and D6 taxonomy term fields are not migrated with allowed vocabularies

FWIW, I hit the identical bug with a D6 to D8 migration trying to use core's migrate_drupal, migrate_plus, migrate_tools + drush. The term reference fields in the D8 site were created, but the target_bundles configuration was broken. Here's an example of what it created:

langcode: en
status: true
dependencies:
  config:
    - field.storage.node.field_topic
    - node.type.insert_box
id: node.insert_box.field_topic
field_name: field_topic
entity_type: node
bundle: insert_box
label: Topic
description: ''
required: true
translatable: true
default_value: {  }
default_value_callback: ''
settings:
  handler: 'default:taxonomy_term'
  handler_settings:
    target_bundles:
    - field_topic
    auto_create: true
field_type: entity_reference

Here's what it needs to be to work properly (which is what I exported to config after manually selecting the appropriate checkbox in the "Allowed Vocabularies" setting on the field after migration):

langcode: en
status: true
dependencies:
  config:
    - field.storage.node.field_topic
    - node.type.insert_box
    - taxonomy.vocabulary.topic
id: node.insert_box.field_topic
field_name: field_topic
entity_type: node
bundle: insert_box
label: Topic
description: ''
required: true
translatable: true
default_value: {  }
default_value_callback: ''
settings:
  handler: 'default:taxonomy_term'
  handler_settings:
    target_bundles:
      topic: topic
    sort:
      field: name
      direction: asc
    auto_create: true
    auto_create_bundle: ''
field_type: entity_reference

Looks like the same basic approach from patch #31 would work if it was also applied to core/modules/field/src/Plugin/migrate/process/d6/FieldInstanceSettings.php

I'm so out of the loop on core development these days, I have no idea if I'm hijacking the issue and should create a separate issue for the D6 case. Please advise if so. But it seems reasonable to fix the same bug in both migrations in the same issue. Apologies if that's not the preferred approach.

Thanks,
-Derek

dww’s picture

Issue tags: +migrate-d6-d8

Tentatively tagging this issue for the D6 case, too...

heddn’s picture

D6 and D7 can probably be done at the same time.

phuang07’s picture

Patch #31 works for me on Drupal 8.5.
Thanks.

maxocub’s picture

@phenaproxima: I'm trying to use migration_lookup to get the new vocabulary names from the mapping table like you suggested in #27.1, but there's a big problem. The allowed_values in the D7 field config use the vocabulary machine names while in the mapping table we have the vocabulary vid. Do you have a idea how we could fix that? I don't.

heddn’s picture

Aren't the vid and vocabulary machine names the same thing? In d6, its an integer for the vid, but in D7, it was a string.

maxocub’s picture

In D7 we had both, a numeric vid and a string machine_name.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

timwood’s picture

Hi! Patch from #31 fails to apply to Drupal 8.6.x. Does anyone on this issue thread know whether this issue is still relevant? I haven't dug into why the patch won't apply yet. Thanks.

maxocub’s picture

Yes, this issue is still relevant, but the proposed solution from comment #27 does not work, we need to find a new one.

You can still apply the patch by doing git apply <patch_name> --reject. I think the only conflicts might be in the test fixtures.

timwood’s picture

Thanks for the tip maxocub!

I decided to re-rolled patch to apply properly with 8.6.x and 8.7.x anyway. Sorry this doesn't help actually fix the issue.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

quietone’s picture

Status: Needs work » Needs review
FileSize
6.2 KB
8.29 KB
11.35 KB

Let's see how this works for Drupal 7. So far I haven't figured out how to set up allowed vocabularies in Drupal 6.

BenStallings’s picture

Status: Needs review » Needs work
Issue tags: +MidCamp 2019

Following a successful upgrade that replicated the problem, I installed the patch in #47 and started over with a fresh database, and the upgrade went fine until it hit this error:

Error: Call to undefined method Drupal\migrate\Row::get() in Drupal\field\Plugin\migrate\process\d7\FieldInstanceSettings->transform() (line 27 of /var/www/html/[site]/web/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php)

Since this is one of the lines added by the patch, I'm going to guess it needs work. :(

BenStallings’s picture

Status: Needs work » Reviewed & tested by the community

Never mind, I was testing with Drupal 8.6 above! With 8.8.0-dev, the patch works correctly and my imported tag reference fields have the correct vocabularies selected. Well done!

quietone’s picture

Status: Reviewed & tested by the community » Needs review

@BenStallings, Thanks! Great to hear that the patch works. Another step closer!

I'm setting back to NR so this can get a code review as well.

The change I added to the latest patch gets the vid and puts on the row so that a migration lookup can be used in the process to get the correct, migrated, vocabulary.

heddn’s picture

Code looks fine. Looked at it for a while this morning. Great job here.

quietone’s picture

Title: D7 and D6 taxonomy term fields are not migrated with allowed vocabularies » D7 taxonomy term fields are not migrated with allowed vocabularies
Issue tags: -migrate-d6-d8

Based on the #49and #51 I'm changing this to D7 onley and made and issue for D6 #3042533: D6 taxonomy term fields are not migrated with allowed vocabularies. That way this can keep progressing.

heddn’s picture

Status: Needs review » Reviewed & tested by the community

That was supposed to be an RTBC.

quietone’s picture

@heddn, thanks for checking back in on this and setting to RTBC.

quietone’s picture

Issue summary: View changes

Added a little info to the IS

quietone’s picture

Issue tags: +blocker
catch’s picture

+++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php
@@ -23,6 +23,18 @@ public function transform($value, MigrateExecutableInterface $migrate_executable
+        foreach ($allowed_value as $vocabulary) {
+          $instance_settings['handler_settings']['sort'] = [
+            'field' => '_none',
+          ];

Why is this assignment in the nested foreach?

quietone’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
8.34 KB
1.32 KB

No reason, really. I've got no evidence that it matters, so have reworked that code.

Status: Needs review » Needs work

The last submitted patch, 58: 2763637-58.patch, failed testing. View results

quietone’s picture

Status: Needs work » Needs review
FileSize
1.17 KB
8.35 KB

Let's take out the reset() that I tried in the last patch.

heddn’s picture

Status: Needs review » Reviewed & tested by the community

Feedback addressed.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
9.33 KB

This needs a reroll. Did that. Merging serialised arrays is fun.

heddn’s picture

Status: Needs review » Reviewed & tested by the community

Re-roll passed green and diff stats are identical. Seems like we could pass back to RTBC.

alexpott’s picture

Version: 8.8.x-dev » 8.7.x-dev
Status: Reviewed & tested by the community » Fixed
Issue tags: +Needs followup

We need a follow-up to fix Drupal 6 as per #33 as we didn't do #37

Committed and pushed 16f38cff6e to 8.8.x and b22572e598 to 8.7.x. Thanks!

  • alexpott committed 16f38cf on 8.8.x
    Issue #2763637 by Jo Fitzgerald, quietone, hussainweb, timwood, alexpott...

  • alexpott committed b22572e on 8.7.x
    Issue #2763637 by Jo Fitzgerald, quietone, hussainweb, timwood, alexpott...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

bob.hinrichs’s picture

Can anyone confirm that this is broken again? Drupal 9.1. This worked fine for many months, and now does not. I spent three days on this and everything is in order, the code of this patch is present in the release now.
First problem, the FieldInstanceSettings code is not run on 'settings' unless I assign it to a funny element like 1: - when it runs as in the core module configuration (no extra transformation in the chain), it does not run the code. Strange. The rest of the field instance is processed.

When I print out the settings in the transform() method, in the data from the FieldInstanceSettings I can see the settings handler_settings target_bundles is set to the correct D9 vocabulary. However, the value is not saved into the field configuration.

This seems more like a problem with core field migrations and the way settings are handled. Seemed to come out of nowhere.

I worked with this some more and assigning a string key to my process in the yml made it work for some reason that is inscrutable. There must be something about how that settings parameter has changed recently.

aisforaaron’s picture

I'm working through a migration from 7 to 8.9.13 and experienced the same issue regarding the target bundles not being set. I switched the zero to a 1 in my migrate_plus.migration.upgrade_d7_field_instance.yml and it seems to work. Thanks for the tip!