I am working on upgrading a Drupal 7 site to Drupal 8. The upgrade uses a content-only custom migration. The Drupal 7 source site and the Drupal 8 destination do not contain any custom modules other than a Drupal 8 custom module containing the custom migration configuration. Both source and destination site were created using the Standard install profile.
I have created migrations for both the node and node revisions of the Page content type. The page node consists of a media reference field and a paragraph reference field. After running the migration I notice that for migrate nodes which had both a published and draft version in which the draft revision is more recent than the published revision then the current content revision is not set.
Here is the moderation tab of such a node in Drupal 7:
Here is the moderation tab of the same node after migrating it to Drupal 8:
Following is the `content_moderation_state_revision` table from the destination database. The node in question is id = 3.
Following is the `content_moderation_state_field_revision` table from the destination database.
Here is the config for the Page node migration:
langcode: en
status: true
dependencies: { }
id: health_node_standard_page
label: Standard Page Nodes
audit: true
migration_tags:
- Drupal 7
- Content
migration_group: health
deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
source:
plugin: d7_node_extended
node_type: page
process:
nid: tnid
vid: vid
langcode:
-
plugin: static_map
source: language
map:
und: en
bypass: true
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
field_h_content_blocks:
plugin: sub_process
source: field_content_blocks
process:
paragraphs:
plugin: migration_lookup
migration:
- health_paragraph_content_text
source: value
target_id:
-
plugin: extract
source: '@paragraphs'
index:
- 0
target_revision_id:
-
plugin: extract
source: '@paragraphs'
index:
- 1
field_h_image_featured:
-
plugin: sub_process
source: field_featured_image
process:
target_id:
-
plugin: migration_lookup
migration: health_media_image
source: fid
moderation_state:
-
plugin: static_map
source: moderation_state
map:
published: published
draft: draft
needs_review: needs_review
default_value: draft
destination:
plugin: entity:node
default_bundle: h_standard_page
migration_dependencies:
required:
- health_user
- health_paragraph_content_text
- health_media_image
Here is the config for the Page node revisions migration:
langcode: en
status: true
dependencies: { }
id: health_node_revision_standard_page
label: Node revisions - Standard Page
audit: true
migration_tags:
- Drupal 7
- Content
migration_group: health
deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
source:
plugin: d7_node_revision_extended
process:
nid:
-
plugin: get
source: nid
vid:
-
plugin: get
source: vid
langcode:
-
plugin: static_map
source: language
map:
und: en
bypass: true
title: title
uid: node_uid
status:
-
plugin: get
source: status
created: created
changed: changed
promote: promote
sticky: sticky
revision_uid: revision_uid
revision_log: log
revision_timestamp: timestamp
moderation_state:
-
plugin: static_map
source: moderation_state
map:
published: published
draft: draft
needs_review: needs_review
default_value: draft
destination:
plugin: entity_revision:node
default_bundle: h_standard_page
migration_dependencies:
required:
- health_node_standard_page
Both migrations make use of a custom "Source" which extends the "d7_node" and "d7_node_revision" source plugins accordingly. These extended source plugins get the moderation state info of the relevant node or node revision.
/**
* Extended version of core Drupal 7 node source from database.
*
* @MigrateSource(
* id = "d7_node_extended",
* source_module = "node"
* )
*/
class D7NodeExtended extends Node {
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
// Make the node's moderation state available to migration.
$database = $this->getDatabase();
$vid = $row->getSourceProperty('vid');
$query = $database
->select('workbench_moderation_node_history', 'wm')
->fields('wm', ['state'])
->condition('wm.vid', $vid)
->orderBy('wm.stamp', 'DESC')
->range(0, 1);
$value = $query
->execute()
->fetchField();
if ($value) {
$row->setSourceProperty('moderation_state', $value);
}
return parent::prepareRow($row);
}
}
/**
* Extended version of core Drupal 7 node source from database.
*
* @MigrateSource(
* id = "d7_node_revision_extended",
* source_module = "node"
* )
*/
class D7NodeRevisionExtended extends NodeRevision {
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
// Make the node revision's moderation state available to migration.
$database = $this->getDatabase();
$vid = $row->getSourceProperty('vid');
$query = $database
->select('workbench_moderation_node_history', 'wm')
->fields('wm', ['state'])
->condition('wm.vid', $vid)
->orderBy('wm.stamp', 'DESC')
->range(0, 1);
$value = $query
->execute()
->fetchField();
if ($value) {
$row->setSourceProperty('moderation_state', $value);
}
return parent::prepareRow($row);
}
}