How can I reference previously imported media entities?

I have been trying to attach media entities to node entities in Drupal 8 with a custom migration but despite numerous attempts and countless hours reviewing forums i’m stumped – I’m desperately hoping someone can help explain where I might be going wrong.

Steps I have taken:

  1. Created a custom migration to import files (Using Migrate Plus & Migrate Source CSV) – successful

  2. Custom migration to import files into Drupal media entities (image bundle) – successful

Now that I have the media imported, I am trying to reference it so I can look to ditch the normal default field_image.

CSV format:

fid, uid, filename, filepath, uri, filemime, filesize, status, timestamp, uuid, alt  

As the files are now media elements I know I can’t reference them by file ID (FID), presumably it would be the media ID (MID) but I have no idea how to get this.

I tried to use the migrate_lookup to reference the existing migrations but during import i’m not getting any error messages which makes it hard to tell whether i’m targeting the right thing or not.

I have also tried to add a default value to test a single value but this also didn’t work.

id: news_nodes label: News Articles migration_group: custom  dependencies:   enforced:     module:       - migrate_custom  source:   plugin: news_nodes   node_type: article   target: db_migration  destination:   plugin: entity:node   default_bundle: article  process:   nid: nid   vid: vid   uid:     plugin: default_value     default_value: 1   langcode:     plugin: default_value     source: language     default_value: en   title: title   uid: node_uid   status: status   created: created   changed: changed   promote: promote   sticky: sticky   revision_uid: revision_uid   revision_log: log   revision_timestamp: timestamp   body/format:     plugin: static_map     bypass: true     source: body_format     map:       1: plain_text       2: restricted_html       3: full_html       4: full_html   body/value: body_value   body/summary: body_summary   field_tags: tags    field_image: image   field_image:      -       plugin: migration_lookup       migration: import_files       source: filename     -       plugin: skip_on_empty       method: process    field_media_image:       plugin: sub_process       source: field_media_image       process:          target_id:           -              plugin: migration_lookup             migration: import_media_files             source: fid             no_stub: true           -               plugin: skip_on_empty             method: process    # field_media_image/target_id:   #   -   #     plugin: migration_lookup   #     migration: import_files   #     source: image_fid   #   -   #     plugin: media_generate   #     destinationField: field_media_image   #     imageAltSource:    #       plugin: default_value   #       default_value: 'Featured image'   #     imageTitleSource:   #       plugin: default_value   #       default_value: 'Featured image'   #   -     #     plugin: skip_on_empty   #     method: process     field_news_companies: company_tags   field_news_companies:     plugin: sub_process     source: field_company_companies     process:       target_id: tid migration_dependencies:   required:     - custom_user     - import_files     - import_media_files     - upgrade_d7_taxonomy_term_company_companies     - upgrade_d7_taxonomy_term_tags 

The commented out section was trying this: https://drupal.stackexchange.com/a/249401/94547 however I get ‘Cannot load a NULL ID. in assert()’ error.

The node entity i’m trying to import to is the default article content type.

  • Default image field – field_image
  • Name of media field – field_media_image

I really would like to understand what i’m missing. I’m new to migrations so any advice on how to help would be appreciated!

EDIT

Having looked at a number of replies, I think we have narrowed down the issue to my source plugin plugin: news_nodes. which I am listing below.

The files/media have been imported using the CSV source but the nodes use custom PHP to query other custom fields which are required (taxonomy).

If I use the same source and plugin details as field_image in my field_media_image a media entity is referenced but not one that matches the file used in field_image. I’m guessing it’s passing the file id and the media entity is handing back a media item with the same numeric id.

Below is the custom plugin. For all I know the way I have set this up entirely wrong and needs to be re-made – any advice would be great.

Full code available on Github: https://github.com/lmonk72/migrate_custom

<?php  namespace Drupalmigrate_customPluginmigratesource;  use DrupalmigrateRow; use DrupalmigratePluginmigratesourceSqlBase;  /**  * @file  * Contains Drupalmigrate_customPluginmigratesourceNode.  */  /**  * Extract nodes from Drupal 7 database.  *  * @MigrateSource(  *   id = "news_nodes"  * )  */ class NewsNodes extends SqlBase {    /**    * {@inheritdoc}    */   public function query() {     // this queries the built-in metadata, but not the body, tags, or images.     $query = $this->select('node', 'n')       ->condition('n.type', 'article')       ->fields('n', array(         'nid',         'vid',         'type',         'language',         'title',         'uid',         'status',         'created',         'changed',         'promote',         'sticky',       ));     $query->orderBy('nid');     return $query;   }    /**    * {@inheritdoc}    */   public function fields() {     $fields = $this->baseFields();     $fields['body/format'] = $this->t('Format of body');     $fields['body/value'] = $this->t('Full text of body');     $fields['body/summary'] = $this->t('Summary of body');     $fields['field_image/target_id'] = $this->t('Image');     return $fields;   }    // /**   //  * {@inheritdoc}   //  */   public function prepareRow(Row $row) {     $nid = $row->getSourceProperty('nid');      // body (compound field with value, summary, and format)     $result = $this->getDatabase()->query('       SELECT         fld.body_value,         fld.body_summary,         fld.body_format       FROM         {field_data_body} fld       WHERE         fld.entity_id = :nid     ', array(':nid' => $nid));     foreach ($result as $record) {       $row->setSourceProperty('body_value', $record->body_value );       $row->setSourceProperty('body_summary', $record->body_summary );       $row->setSourceProperty('body_format', $record->body_format );     }      // taxonomy term IDs     // (here we use MySQL's GROUP_CONCAT() function to merge all values into one row.)     $result = $this->getDatabase()->query('       SELECT         GROUP_CONCAT(fld.field_tags_tid) as tids       FROM         {field_data_field_tags} fld       WHERE         fld.entity_id = :nid     ', array(':nid' => $nid));     foreach ($result as $record) {       if (!is_null($record->tids)) {         $row->setSourceProperty('tags', explode(',', $record->tids) );       }     }      // Company taxonomy term IDs     // (here we use MySQL's GROUP_CONCAT() function to merge all values into one row.)     $result = $this->getDatabase()->query('       SELECT         GROUP_CONCAT(fld.field_company_companies_tid) as tids       FROM         {field_data_field_company_companies} fld       WHERE         fld.entity_id = :nid     ', array(':nid' => $nid));     foreach ($result as $record) {       if (!is_null($record->tids)) {         $row->setSourceProperty('company_tags', explode(',', $record->tids) );       }     }      $result = $this->getDatabase()->query('       SELECT         fld.field_image_fid,         fld.field_image_alt,         fld.field_image_title,         fld.field_image_width,         fld.field_image_height       FROM         {field_data_field_image} fld       WHERE         fld.entity_id = :nid     ', array(':nid' => $nid));     // Create an associative array for each row in the result. The keys     // here match the last part of the column name in the field table.       $image = [];      foreach ($result as $record) {       $image[] = [         'target_id' => $record->field_image_fid,         'alt' => $record->field_image_alt,         'title' => $record->field_image_title,         'width' => $record->field_image_width,         'height' => $record->field_image_height,       ];     }     $row->setSourceProperty('image', $image);       return parent::prepareRow($row);   }    /**    * {@inheritdoc}    */   public function getIds() {     $ids['nid']['type'] = 'integer';     $ids['nid']['alias'] = 'n';     return $ids;   }    /**    * {@inheritdoc}    */   public function bundleMigrationRequired() {     return FALSE;   }    /**    * {@inheritdoc}    */   public function entityTypeId() {     return 'node';   }    /**    * Returns the user base fields to be migrated.    *    * @return array    *   Associative array having field name as key and description as value.    */   protected function baseFields() {     $fields = array(       'nid' => $this->t('Node ID'),       'vid' => $this->t('Version ID'),       'type' => $this->t('Type'),       'title' => $this->t('Title'),       'format' => $this->t('Format'),       'teaser' => $this->t('Teaser'),       'uid' => $this->t('Authored by (uid)'),       'created' => $this->t('Created timestamp'),       'changed' => $this->t('Modified timestamp'),       'status' => $this->t('Published'),       'promote' => $this->t('Promoted to front page'),       'sticky' => $this->t('Sticky at top of lists'),       'language' => $this->t('Language (fr, en, ...)'),     );     return $fields;   } } ?> 
This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

How can I reference previously imported media entities?

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.