When migrating from Drupal 7 to Drupal 8, it is important to remember to migrate over the redirects as well. Without the migrations users will not find your content if for example: the redirect was shared on social media. Using the Migrate Plus module, it is quite simple to write a migration for the redirects. The Migrate Plus module contains some good examples on how to get started writing your custom migrations.
Write your node migrations
I am going to assume that you have written migration for some content types and have the group
already written. Once those migrations have been written, in your database should now be a migrate_map_{name}_{type}
table. This is where we will be able to find the imported node's new id which will be necessary for importing the redirects.
Write the yml file for redirect migrations
For example, let's say we have a module called blog_migrations
. In that module we have a group for blog
and a migration for a news
and opinion
content type. Inside the config/install
directory add a new yml file called migrate_plus.migration.blog_redirect.yml
where blog
is the name of the group being migrated. This file will give an id, label, and the process to use for the migration.
id: blog_redirect
label: Path Redirect
migration_group: blog
migration_tags:
- Drupal 7
source:
# This is the id of the source we will add. That will live
# in `/src/Plugin/migrate/source`.
plugin: blog_redirect
key: blog
process:
rid: rid
uid: uid
redirect_source/path: source
redirect_source/query:
# `RedirectSourceQuery.php` is the process plugin to use.
plugin: d7_redirect_source_query
source: source_options
redirect_redirect/uri:
# `PathRedirect.php` is the process plugin to use.
plugin: d7_path_redirect
source:
- redirect
- redirect_options
language:
plugin: default_value
source: language
default_value: und
status_code: status_code
destination:
plugin: entity:redirect
Write the migrate source
Create the file BlogRedirect.php
in the module's src/Plugin/migrate/source
folder.
<?php
namespace Drupal\apa_migrate\Plugin\migrate\source;
use Drupal\Core\Database\Database;
use Drupal\migrate\Row;
use Drupal\redirect\Plugin\migrate\source\d7\PathRedirect;
/**
* Drupal 7 path redirect source from database.
*
* @MigrateSource(
* id = "blog_redirect"
* )
*/
class BlogRedirect extends PathRedirect {
/**
* {@inheritdoc}
*/
public function query() {
// Select path redirects.
$query = $this->select('redirect', 'p')->fields('p')
->condition('redirect', '%user%', 'NOT LIKE');
return $query;
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
// Get the current status code and set it.
$current_status_code = $row->getSourceProperty('status_code');
$status_code = $current_status_code != 0 ? $current_status_code : 301;
$row->setSourceProperty('status_code', $status_code);
$current_redirect = $row->getSourceProperty('redirect');
$explode_current_redirect = explode("/", $current_redirect);
$map_blog_array = array(
'news',
'opinion'
);
// Determine if the path is redirected to a /node/{id} path.
if ($explode_current_redirect[0] == 'node') {
// Determine the content type for the node.
$resource_type = $this->getDatabase()
->select('node', 'n')
->fields('n', ['type'])
->condition('nid', $explode_current_redirect[1])
->execute()
->fetchField();
// Check that the type is in the node types we want to migrate for.
if (in_array($resource_type, $map_apa_array)) {
// Gather the information about where the node is now.
$new_node_id = Database::getConnection('default', 'default')
->select('migrate_map_apa_' . $resource_type, 'm')
->fields('m', ['destid1'])
->condition('sourceid1', $explode_current_redirect[1])
->execute()
->fetchField();
// Set the new redirect.
$new_redirect = 'node/' . $new_node_id;
$row->setSourceProperty('redirect', $new_redirect);
}
}
}
}
Run the migrations
Using the config_devel module, now import the configuration into active store to be able to run the migration using:
drush cdi1 /modules/custom/blog_migration/config/install/migrate_plus.migration.blog_redirect.yml
Then run the actual migration:
drush mi blog_redirect
After running that you should now have migrated the two content type's redirects with the new node id they were given! Any questions, let us know in the comments below.