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
Comment | File | Size | Author |
---|---|---|---|
#62 | 2763637-62.patch | 9.33 KB | alexpott |
#60 | 2763637-60.patch | 8.35 KB | quietone |
#60 | interdiff-58-60.txt | 1.17 KB | quietone |
#58 | interdiff-47-58.txt | 1.32 KB | quietone |
#58 | 2763637-58.patch | 8.34 KB | quietone |
Comments
Comment #2
hussainwebI guess this could be polished further but this works. Reviews please.
Comment #4
hussainwebFixing the failure.
Comment #5
hussainwebComment #6
quietone CreditAttribution: quietone as a volunteer commentedTagging for d7.
Comment #8
mikeryanDoesn't the D7 taxonomy_term_reference field permit multiple target vocabularies? We should migrate the full list.
Comment #9
hussainweb@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.
Comment #10
mikeryanI'll be reviewing this.
Comment #11
mikeryanLooks good, but we should have a test (please include a test-only patch to demonstrate the resulting misconfiguration without the fix).
Comment #12
mikeryanComment #13
jofitz CreditAttribution: jofitz at ComputerMinds commentedAdded tests (including test only).
Comment #15
mikeryanThanks!
Comment #16
catch@mikeryan is right in #8, while the 7.x UI doesn't allow multiple vocabulary references, the API does.
Comment #17
jofitz CreditAttribution: jofitz at ComputerMinds commentedHandle multiple vocabulary references.
Comment #18
phenaproximaI 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.
Comment #19
mikeryanJust 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
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.
Comment #20
phenaproximaIn 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.
Comment #21
ckngTested 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
Comment #22
jofitz CreditAttribution: jofitz at ComputerMinds commentedI 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.
Comment #24
jofitz CreditAttribution: jofitz at ComputerMinds commentedRe-roll.
Comment #25
phenaproximaSelf-assigning for re-review.
Comment #27
phenaproximaCan 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.
Should be string[], not array.
$target_bundles should be type hinted.
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.
Comment #29
dillix CreditAttribution: dillix commentedIs there a chance we see it in D8.4?
Comment #30
jofitz CreditAttribution: jofitz at ComputerMinds commentedPatch in #24 no longer applies to doing a quick re-roll before addressing @phenaproxima's comments in #27.
Comment #31
jofitz CreditAttribution: jofitz at ComputerMinds commentedAddressing review in #27:
array
replaced withstring[]
.$target_bundles
witharray
.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).Comment #32
heddnField 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).
Comment #33
jofitz CreditAttribution: jofitz at ComputerMinds commentedI'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
fromunserialize($value[2]['data'])['settings']['allowed_values']
(!)I've probably got the wrong end of the stick, but I could do with some guidance, please.
Comment #35
dwwFWIW, 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:
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):
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
Comment #36
dwwTentatively tagging this issue for the D6 case, too...
Comment #37
heddnD6 and D7 can probably be done at the same time.
Comment #38
phuang07 CreditAttribution: phuang07 commentedPatch #31 works for me on Drupal 8.5.
Thanks.
Comment #39
maxocub CreditAttribution: maxocub as a volunteer commented@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. Theallowed_values
in the D7 field config use the vocabulary machine names while in the mapping table we have the vocabularyvid
. Do you have a idea how we could fix that? I don't.Comment #40
heddnAren'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.
Comment #41
maxocub CreditAttribution: maxocub as a volunteer commentedIn D7 we had both, a numeric vid and a string machine_name.
Comment #43
timwoodHi! 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.
Comment #44
maxocub CreditAttribution: maxocub as a volunteer commentedYes, 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.Comment #45
timwoodThanks 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.
Comment #47
quietone CreditAttribution: quietone as a volunteer commentedLet's see how this works for Drupal 7. So far I haven't figured out how to set up allowed vocabularies in Drupal 6.
Comment #48
BenStallings CreditAttribution: BenStallings as a volunteer commentedFollowing 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:
Since this is one of the lines added by the patch, I'm going to guess it needs work. :(
Comment #49
BenStallings CreditAttribution: BenStallings as a volunteer commentedNever 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!
Comment #50
quietone CreditAttribution: quietone as a volunteer commented@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.
Comment #51
heddnCode looks fine. Looked at it for a while this morning. Great job here.
Comment #52
quietone CreditAttribution: quietone as a volunteer commentedBased 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.
Comment #53
heddnThat was supposed to be an RTBC.
Comment #54
quietone CreditAttribution: quietone as a volunteer commented@heddn, thanks for checking back in on this and setting to RTBC.
Comment #55
quietone CreditAttribution: quietone as a volunteer commentedAdded a little info to the IS
Comment #56
quietone CreditAttribution: quietone as a volunteer commentedThis is also blocking #2979970: Migrate D7 vocabulary language settings.
Comment #57
catchWhy is this assignment in the nested foreach?
Comment #58
quietone CreditAttribution: quietone as a volunteer commentedNo reason, really. I've got no evidence that it matters, so have reworked that code.
Comment #60
quietone CreditAttribution: quietone as a volunteer commentedLet's take out the reset() that I tried in the last patch.
Comment #61
heddnFeedback addressed.
Comment #62
alexpottThis needs a reroll. Did that. Merging serialised arrays is fun.
Comment #63
heddnRe-roll passed green and diff stats are identical. Seems like we could pass back to RTBC.
Comment #64
alexpottWe 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!
Comment #68
bob.hinrichs CreditAttribution: bob.hinrichs commentedCan 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.
Comment #69
aisforaaron CreditAttribution: aisforaaron commentedI'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!