Migrate Drupal 6 files to Drupal 8 media entities

8 already provides the necessary configuration files and PHP plugins to migrate files from Drupal 6. But if you are using the Drupal 8 core media module for your files you need to add a second migration.

I assume that you are doing a Drupal 8 migration using the migrate tools and migrate plus modules.

File migration

Copy /core/modules/file/migrations/d6_file.yml to config/install/migrate_plus.migration.d6_file.yml in your custom module and set the source file path:

# Every migration that references a file by Drupal 6 fid should specify this
# migration as an optional dependency.
id: d6_file
label: Public files
audit: true
migration_group: d6
migration_tags:
  - Drupal 6
  - Content
source:
  plugin: d6_file
  constants:
    # The tool configuring this migration must set source_base_path. It
    # represents the fully qualified path relative to which URIs in the files
    # table are specified, and must end with a /. See source_full_path
    # configuration in this migration's process pipeline as an example.
    source_base_path: '/path/to/drupal6/files/to/migrate'
...

Drupal 8 refuses to install a module whose configuration has already been imported. To avoid such error add a dependency on your custom module to the migration file. If you uninstall the module, Drupal 8 will also remove the configuration:

dependencies:
  enforced:
    module:
      - custom_migrate_module

Media entity migration

Copy /core/modules/file/migrations/d6_file.yml to config/install/migrate_plus.migration.d6_media_entity.yml in your custom module.

Change plugin id and label, process and destination configuration in order to create media entities:

Before (excerpt)

id: d6_file
label: Public files
...
process:
    # If you are using both this migration and d6_user_picture_file in a custom
    # migration and executing migrations incrementally, it is strongly
    # recommended that you remove the fid mapping to avoid potential ID
    # conflicts. For that reason, this mapping is commented out by default.
    # fid: fid
  filename: filename
  source_full_path:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/source_base_path
        - filepath
    -
      plugin: urlencode
  destination_full_path:
    plugin: file_uri
    source:
      - filepath
      - file_directory_path
      - temp_directory_path
      - is_public
  uri:
    plugin: file_copy
    source:
      - '@source_full_path'
      - '@destination_full_path'
  filemime: filemime
  # No need to migrate filesize, it is computed when file entities are saved.
  # filesize: filesize
  status: status
  changed: timestamp
  uid: uid
destination:
  plugin: entity:file

After (excerpt)

id: d6_media_entity
label: Media entities
migration_group: d6
...
process:
  langcode:
    plugin: default_value
    default_value: 'en'
  field_media_file/target_id:
    plugin: migration_lookup
    migration: d6_file
    source: fid
  field_media_file/display:
    plugin: default_value
    default_value: 0
  field_media_file/description:
    plugin: default_value
    default_value: ''
  status: status
  changed: timestamp
  uid:
    plugin: migration_lookup
    migration: d6_user
    source: uid
destination:
  plugin: entity:media
  default_bundle: file

Or if you migrate images:

id: d6_media_entity
label: Media entities
migration_group: d6
...
process:
  langcode:
    plugin: default_value
    default_value: 'en'
  field_media_image/target_id:
    plugin: migration_lookup
    migration: d6_file
    source: fid
  field_media_image/alt: filename
  field_media_image/title:
    plugin: default_value
    default_value: ''
  status: status
  changed: timestamp
  uid:
    plugin: migration_lookup
    migration: d6_user
    source: uid
destination:
  plugin: entity:media
  default_bundle: image

At last, add the migration dependencies to config/install/migrate_plus.migration.d6_media_entity.yml:

migration_dependencies:
  required:
    - d6_user
    - d6_file
dependencies:
  enforced:
    module:
      - custom_migrate_module

Running these 2 migrations will copy your files from the Drupal 6 to the Drupal 8 file directory and create a media entity for each of them.

Assign media entities to nodes

In order to assign media entities to media fields on nodes, you have to assign the media entity id (instead of the file id) to the field, e.g.:

id: d6_node
label: Nodes
audit: true
migration_group: d6
migration_tags:
  - Drupal 6
  - Content
deriver: Drupal\node\Plugin\migrate\D6NodeDeriver
source:
  plugin: d6_node
process:
  field_media:
    plugin: sub_process
    source: uploads
    process:
      target_id:
        plugin: migration_lookup
        migration: d6_media_entity
        source: fid
        no_stub: true
      display: list
      description: description
...
destination:
  plugin: entity:node

You may have to create a custom source plugin in order to retrieve the id of the file that is attached to a node.

Tools

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.