Start of Main Content

There will be the occasional project coming in from Wordpress, Joomla!, static HTML, classic ASP.net sites or other sources. In other cases, you may not want to do the assisted core migration, but craft your own migration procedure. 

Fortunately, there are tools being worked on to facilitate requirements like this. Migrate Plus and Migrate Tools are in progress and introduce functionality to Drupal 8 migrations that will feel familiar to developers who worked extensively with the Migrate Framework from before.

Here is an example of a manual migration of roles, users, and user fields from Drupal 7 to Drupal 8. To do this, you will need the aforementioned Migrate Plus and Migrate Tools modules, a defined source in your Drupal 8 settings.php configuration, and define a migration group. You will need to plug in your database connection key in the group yaml definition, which points the migration at the database connection to use as the source of migrations. 

All migrations within the same group will use the same data source thanks to the shared_configuration values in your migration group. In more advanced scenarios, you may have multiple data sources defined.

Let's take a look at a basic example. In this case, I wanted to bring in user roles and all of our user accounts, the role assignments and couple of fields attached to user accounts that we use on velir.com.

With the core migration, a few things were happening. The 'administrator' role was being recreated as 'administrator1', and the custom field values were not coming through. Obviously not ideal, so I needed to splinter off and do my own migration.

To start with, I created a module, a migration group. I then copied in the core user role and user migration template to my module and adjusted them as follows:

In migrate_plus.migrate_group.velir.yml:

# The machine name of the group, by which it is referenced in individual
# migrations.
id: mymigration

# A human-friendly label for the group.
label: Custom Migration

# More information about the group.
description: "My custom migrations"

# Short description of the type of source, e.g. "Drupal 6" or "WordPress".
source_type: "Drupal 7"

# Here we add any default configuration settings to be shared among all
# migrations in the group. For this example, the source tables are in the
# Drupal (default) database, but usually if your source data is in a
# database it will be external.
shared_configuration:
  source:
    key: d7

In migrate_plus.migration.user_role.yml:

id: user_role
label: User roles
migration_group: mymigration
migration_tags:
  - Drupal 7
source:
  plugin: d7_user_role
process:
  id:
    -
      plugin: machine_name
      source: name
    -
      plugin: substr
      entity_type: user_role
      field: id
      length: 32
    -
      plugin: user_update_8002
  label: name
  permissions:
    -
      plugin: static_map
      source: permissions
      bypass: true
      map:
        'use PHP for block visibility': 'use PHP for settings'
        'administer site-wide contact form': 'administer contact forms'
        'post comments without approval': 'skip comment approval'
        'edit own blog entries' : 'edit own blog content'
        'edit any blog entry' : 'edit any blog content'
        'delete own blog entries' : 'delete own blog content'
        'delete any blog entry' : 'delete any blog content'
        'create forum topics' : 'create forum content'
        'delete any forum topic' : 'delete any forum content'
        'delete own forum topics' : 'delete own forum content'
        'edit any forum topic' : 'edit any forum content'
        'edit own forum topics' : 'edit own forum content'
    - plugin: flatten
  weight: weight
destination:
  plugin: entity:user_role
migration_dependencies: {}

In migrate_plus.migration.user.yml:

id: user
label: Users
migration_group: mymigration
source:
  plugin: user
  keys:
    - uid
destination:
  plugin: entity:user
process:
  uid: uid
  pass: pass
  name: name
  mail: mail
  init: mail
  status: status
  created: created
  changed: created
  access: access
  login: login
  roles:
    plugin: migration
    migration: user_role
    source: roles
  field_full_name: field_full_name
  field_job_title: field_job_title
  field_weight: field_weight
migration_dependencies:
  required:
    - user_role

Bit of a long way around, but fixed my immediate issue. Since the substr process plugin is now in core, I replaced the core default of 'dedupe_entity' with 'substr'. This prevents my administrator role being recreated as administrator1, and all users were assigned the appropriate roles.

Secondly, the basic fields were mapped to their Drupal 8 fields. An extra step to this process was also creating the fields before doing the migration, whereas the cores assisted migration will create them for you. You can mimic this pattern in your module (copy the requisite migration templates from the field module and define them in your module), and set that as a dependency before migrating your entities.

Published:

Latest Ideas

Take advantage of our expertise with your next project.