Outline for migration from d7 node hierarchy

Created on 11 August 2023, about 1 year ago
Updated 6 September 2023, about 1 year ago

Problem/Motivation

It's not that obvious how to migrate from d7 node hierarchy to d9 entity hierarchy. Below is how I went about it. It would be good to compare notes and make recommendations. Note that d7 node hierarchy allows multiple parents, but entity hierarchy only allows one.

Before migration, disable entity hierarchy tree building:
drush sset entity_hierarchy_disable_writes 1

migration from d7 node hierarchy to d9 contained_by entity hierarchy field in node complete migration:

process:
  field_contained_by/0/target_id: parent_nid
  field_contained_by/0/weight: weight

I have a prepare_row that injects parent_nid and weight from d7:

  $parent_nid = {my_module}_migrate_d7_place_parent($id);
  $row->setSourceProperty('parent_nid', $parent_nid);

  // d7 nodehierarchy_menu_links doesn't get populated into source.
  $weight = {my_module}_migrate_d7_place_node_hierarchy_weight($id);
  $row->setSourceProperty('weight', $weight);
/**
 * Return node parent nid from d7 nodehierarchy.
 */
function {my_module}_migrate_d7_place_parent($nid) {

  $parent_nid = 0;
  $d7_menu_links = {my_module}_migrate_d7_menu_links();

  // Get result from first row of d7_menu_links.
  if (isset($d7_menu_links[$nid])) {
    $menu_link = $d7_menu_links[$nid][0];
    $parent_nid = $menu_link->parent_nid;
  }

  return $parent_nid;
}
/**
 * Return node weight from d7 nodehierarchy.
 */
function {my_module}_migrate_d7_place_node_hierarchy_weight($nid) {
  $weight = 0;

  // Get result from first row of d7_menu_links.
  $d7_menu_links = {my_module}_migrate_d7_menu_links();
  if (isset($d7_menu_links[$nid])) {
    $menu_link = $d7_menu_links[$nid][0];
    $weight = $menu_link->weight;
  }
  return $weight;
}

/**
 * Cache d7 menu link data for fast lookup within prepare row.
 *
 * SELECT ml.link_path,ml.weight, ml.link_title,ml2.link_path FROM menu_links ml LEFT JOIN menu_links ml2 ON ml.plid=ml2.mlid WHERE ml.menu_name='menu-place-menu';
 *
 * @return array
 *   Array of D7 menu links to support Place hierarchy.
 */
function {my_module}_migrate_d7_menu_links() {

  $d7_menu_links = &drupal_static(__FUNCTION__);
  if (!$d7_menu_links) {
    // Switch to D7 database.
    Database::setActiveConnection('migrate');
    $db = Database::getConnection();
    $menu_links = $db->query("SELECT REPLACE(ml.link_path, 'node/', '') AS nid, ml.weight, ml.link_title, REPLACE(ml2.link_path, 'node/', '') AS parent_nid FROM menu_links ml LEFT JOIN menu_links ml2 ON ml.plid=ml2.mlid WHERE ml.menu_name=:menu ORDER BY CAST(nid AS unsigned)",
      [':menu' => 'menu-place-menu'],
    )->fetchAll();
    // Switch database back to D9.
    Database::setActiveConnection();
    // Process the result into something we can use, indexed by nid.
    $node_array = [];
    foreach ($menu_links as $menu_link) {
      // Have we seen this nid before?
      if (array_key_exists($menu_link->nid, $node_array)) {
        // Append row.
        $node_array[$menu_link->nid][] = $menu_link;
      }
      else {
        // Inject row for this nid.
        $node_array[$menu_link->nid] = [0 => $menu_link];
      }
    }
    $d7_menu_links = $node_array;
  }
  return $d7_menu_links;
}

After migration, enable tree building and build tree

drush sset entity_hierarchy_disable_writes 0
drush entity-hierarchy-rebuild-tree field_contained_by node
πŸ’¬ Support request
Status

Fixed

Version

3.0

Component

Documentation

Created by

πŸ‡³πŸ‡ΏNew Zealand jonathan_hunt

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024