0

I am doing a D7 > D8 migration (where the D7 site in question itself was migrated from D6 some years back) and most stuff just works fine. But I am stuck on the field (instance) settings for taxonomy reference fields.

When migrating the field instances, I am using a slightly changed version from the one provided by core (that's how I did it with most other stuff, too):

langcode: en
status: true
dependencies: {  }
id: my_fields
class: Drupal\migrate_drupal\Plugin\migrate\FieldMigration
field_plugin_method: processField
cck_plugin_method: null
migration_tags:
  - 'Drupal 7'
  - Configuration
migration_group: my
label: 'Field configuration'
source:
  plugin: d7_field
  constants:
    status: true
    langcode: und
process:
  entity_type: entity_type
  status: constants/status
  langcode: constants/langcode
  field_name:
    plugin: static_map
    source: field_name
    map:
      taxonomy_vocabulary_1: field_issues
      taxonomy_vocabulary_2: field_tags
    bypass: TRUE
  type:
    plugin: process_field
    source: type
    method: getFieldType
  cardinality: cardinality
  settings:
    plugin: d7_field_settings
destination:
  plugin: 'entity:field_storage_config'
migration_dependencies: null

When I run this via drush mim my_fields all field instances on all content types are created (wonderful!), the only thing missing is the restriction in taxonomy term reference fields regarding a specific vocabulary.

When I create such a field manually and export the configuration, there is a section in the yaml file describing that restriction:

settings:
  handler: 'default:taxonomy_term'
  handler_settings:
    target_bundles:
      issues: issues
    sort:
      field: name
      direction: asc
    auto_create: false
    auto_create_bundle: ''

I guess this needs to be in the process section of the migration configuration, but how do I set it correctly? If I read that right, the vocabulary name (issues) is both field name and value, which would probably pose a problem for multiple vocabularies. Also, how would I set this for taxonomy reference fields only?

Added note: In Drupal 7, the restriction was set within the field global settings (allowed_values[vocabulary], could be found in the DB table field_config) and not with the field instance.

In Drupal 8, it seems to be a field_instance setting as the same field can be restricted to different vocabularies in different content types. May that be the reason, why this setting is not migrated?

By the way: I did try a simple migration first by using the Migrate Drupal module and while it got most configuration right by just using defaults, here also the restrictions on taxonomy reference fields was missing.

1

The field settings are created in the process plugin, d7_field_settings, in this section of the process pipeline.

 settings:
    plugin: d7_field_settings

It seems that you will need to write a custom process plugin. You may want to preserve the settings created by d7_field_settings. I don't recall what d7_field_settings does. So you could put something like this after the settings property is set..

 'settings/handler_settings/target_bundles': my_custom_plugin

Edit: Glad got it working. Found the core issue for this today, https://www.drupal.org/project/drupal/issues/2763637.

  • Thanks for your answer. I was actually aware of custom plugins as I have written some for other parts of my migration. I just thought, there should be a built-in solution for a basic issue like taxonomy terms. As it turns out, there is not and you are absolutely right, one needs to write a custom plugin. – Paul Jul 6 '18 at 6:36
0

I needed to write a custom migration process plugin.

The default is called d7_field_instance_settings and already provides custom settings for entityreference fields. I am not sure, why they didn't include just similar code block for taxonomy_term_reference, though.

Thus, I wrote that block:

if ($row->getSourceProperty('type') == "taxonomy_term_reference") {
      if (array_key_exists('allowed_values', $field_settings)) {
          $vocabulary = $field_settings['allowed_values'][0]['vocabulary'];
          $instance_settings['handler_settings']['target_bundles'] = array(
              $voc => $voc,
          );
      }
  }

This code just looks, if the field settings (as the vocabulary is stored in the field settings in D7) contain a key allowed_values and if so set the associated vocabulary name as target bundle for the field instance in D8.

Note: In D7 it was only possible to add a single vocabulary which is why I am just using [0] in the code. Otherwise, this should be turned into a foreach loop in order to set multiple vocabularies (as allowed in D8).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.