It is a great functionality to be able to migrate D7 images directly to D8 media image entities with this module (without the redirection via an D8 image field).

As the drush generator doesn't provide details about differences in configuration between migration from D8 image source and D7 image source and the provided examples also only focus on D8=>D8 migration, I'd like to suggest the inclusion of an example configuration for D7 => D8 migration explaining all the glory, using the D7 and D8 Article content types.

Prerequisites

  1. A standard Drupal 7 installation and one or more articles with an image created.
  2. A standard Drupal 8.8.x installation
  3. A media field 'field_media' (with image enabled) added to the D8 article content type and the 'field_image' removed.
  4. D8 core modules migrate, migrate_drupal and contrib modules migrate_plus, migrate_tools and migrate_file_to_media enabled
  5. drush 9 installed (10 is also ok) for the D8 site
  6. A database entry defining key 'migration_source_db' in the D8 settings.php, pointing to the D7 database
  7. Create the directory-path 'media/article' under the D8 'sites/default/files' path and make sure it is writeable for Drupal

The Media migration expects the nodes migrated, before working properly, so I start with the basic node migration configuration for the 'Article' content type, having a constant user 1 (admin) to keep it simple.

Add the configuration file config/install/migrate_plus.migration.mig_article_node.yml to your custom migration module

# Migration for article nodes

id: mig_article_node
label: Article Node
description: Config for mig article node migration
deriver: Drupal\node\Plugin\migrate\D7NodeDeriver

source:
  key: migration_source_db

  plugin: d7_node
  node_type: article

destination:
  plugin: entity:node

process:
    nid: nid
    type: type
    title: title
    uid:
      plugin: default_value
      default_value: 1

    status: status
    created: created
    changed: changed
    comment: comment
    promote: promote
    sticky: sticky

    body:
      plugin: sub_process
      source: body
      process:
        value: value
        summary: summary
        format:
          plugin: default_value
          default_value: full_html

Add the configuration file config/install/migrate_plus.migration.mig_article_media_step1.yml to your custom migration module and replace '<d7-domain.tld>' with the domain of your D7 site

# File to Media Migration configuration for Article Media migration

id: mig_article_media_step1
label: Article Media Step 1

source:
  key: migration_source_db

  plugin: media_entity_generator_d7
  entity_type: node
  bundle: article
  d7_file_url: 'http://<d7-domain.tld>/sites/default/files/'
  field_names:
    - field_image

destination:
  plugin: entity:media

process:
  bundle:
    plugin: default_value
    default_value: image

  # Using the alt tag if available, else the file name.
  name:
    plugin: media_name
    source: file_name

  # This process plugin will skip the whole row if a existing media is found.
  existing_media_file:
    plugin: check_media_duplicate
    source: target_id

  # This process plugin will skip the whole row if a duplicate image is found.
  unique_file_id:
    plugin: check_duplicate
    source: target_id

  # Map the field image
  field_media_image/alt: alt
  field_media_image/title: title
  field_media_image/target_id:
    plugin: media_file_copy
    move: FALSE
    reuse: TRUE
    path: 'public://media/article/'
    source: file_path

  langcode: langcode

  uid:
    plugin: default_value
    default_value: 1

Add the configuration file config/install/migrate_plus.migration.mig_article_media_step2.yml to your custom migration module

# This migration links the newly created media entities with entity reference field on the target bundle.

id: mig_article_media_step2
label: Article Media Mapping

source:
  key: migration_source_db

  plugin: d7_node
  node_type: article

destination:
  plugin: entity:node

process:
  nid: nid
  changed: changed

  field_media:
    plugin: file_id_lookup
    source: field_image
    migration: mig_article_media_step1
    no_stub: true

migration_dependencies:
  optional:
  - mig_article_node
  - mig_article_media_step1

Enable your custom migration module.

$ drush en <your_custom_migration_module>

Use the duplicate-file-detection drush command (described on the start page of this module):

$ drush migrate:duplicate-file-detection mig_article_media_step1

Now check for the three new migrations appear in the list of available migrations

$ drush ms

and work through the migrations themselves.

$ drush mim mig_article_node
$ drush mim mig_article_media_step1
$ drush mim mig_article_media_step2

If all went right, you have your articles and their images migrated from D7 to D8, rightfully.

Remarks

  1. There is a file and a media entity created for each source image. While the media entities regain the created and changed times of their original D7 article node, it is not possible to preserve the timestamps of the original files. They instead get the timestamp of when the migration was performed. The best solution, so far, would be to use an SQL update for updating the file timestamps from the media entity timestamps. To keep this text simple, I don't go into the details of an SQL update.
  2. At the time of this writing there are two bugs in the 'migrate_file_to_media' module, which can cause errors with the example. The first occurs, when the D7 article images are stored in a subdirectory of 'sites/default/files', and the second, when there is no Crop API module enabled in your D8 installation. For both errors I've provided a patch in related issues.

Conclusion

I'd like to suggest to add an seperate example module for migration from D7, which includes these three configuration files and a README file with a text like the above. An example for D7 taxonomy migration would be another nice addition.

Comments

meichr created an issue. See original summary.

meichr’s picture

Issue summary: View changes
Status: Active » Needs review

Text slightly improved. Review state entered.

meichr’s picture

Issue summary: View changes

An error in the text corrected.

meichr’s picture

Issue summary: View changes

Another improvement of the text.

meichr’s picture

Issue summary: View changes

Added 'changed: changed' to step2 configuration as otherwise the Updated timestamp of the article nodes is overwritten with migration time, when the media is attached to the existing article nodes.

meichr’s picture

Title: Add an example for D7 => D8 Media migration » Add an example for D7 Image => D8 Media migration

Improve title.

ayalon’s picture

Thanks a lot for your contribution and time spent on this issue. I added your example in a subfolder of a module.

  • ayalon committed a486f11 on 8.x-1.x
    Issue #3118471 by meichr, ayalon: Add an example for D7 Image => D8...
ayalon’s picture

Status: Needs review » Fixed
ayalon’s picture

Status: Fixed » Closed (fixed)
dianacastillo’s picture

Note - step 2 fails unless the nid of the source and target are alike.