When working with Drupal migrations, the source database credentials are typically defined in settings.php
. However, in many cases you may want to allow these credentials to be configurable at runtime so that they can be easily managed across different environments.
In this guide, I'll walk you through a solution that lets you dynamically configure the migration database. The idea is to provide a configuration form (which isnβt covered here) that saves your database connection details. Then, we leverage these saved details during the migration process.
Step 1: Create a Base Migration Class
First, create a file called ExampleSqlBase.php
in your module (example
) under the src
directory. This class extends Drupal's SqlBase
and implements ContainerFactoryPluginInterface
to inject the configuration service. The code snippet below demonstrates how to retrieve your database configuration from the example.settings
config and set up the connection accordingly:
<?php
namespace Drupal\example;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\State\StateInterface;
use Drupal\migrate\Plugin\migrate\source\SqlBase;
use Drupal\migrate\Plugin\MigrationInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Base class to use for all source migration plugins.
*/
abstract class ExampleSqlBase extends SqlBase implements ContainerFactoryPluginInterface {
/**
* The configuration name for migration settings.
*/
const CONFIG_NAME = 'example.settings';
/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, ConfigFactoryInterface $config_factory) {
$this->configFactory = $config_factory;
// Get the configuration.
$migrate_config = $this->configFactory->get(self::CONFIG_NAME);
$database_info = [
'database' => [
'database' => $migrate_config->get('database'),
'username' => $migrate_config->get('username'),
'password' => $migrate_config->get('password'),
'host' => $migrate_config->get('host'),
'port' => $migrate_config->get('port'),
'driver' => $migrate_config->get('driver'),
'namespace' => $migrate_config->get('namespace'),
'prefix' => $migrate_config->get('prefix'),
],
'key' => 'migrate',
'target' => 'default',
];
// Set up the database.
$this->setUpDatabase($database_info);
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, ?MigrationInterface $migration = NULL) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$migration,
$container->get('state'),
$container->get('config.factory')
);
}
}
Step 2: Create a Source Migration Plugin
With the base class in place, creating a migration plugin is as simple as extending ExampleSqlBase. Below is an example of a source plugin named ExampleArticles that pulls data for articles content:
<?php
namespace Drupal\example\Plugin\migrate\source;
use Drupal\example\ExampleSqlBase;
/**
* Source plugin for articles.
*
* @MigrateSource(
* id = "example_articles",
* )
*/
class ExampleArticles extends ExampleSqlBase {
/**
* {@inheritdoc}
*/
public function query() {
$query = $this->select('node', 'n');
$query->leftJoin('node_revision', 'nr', 'nr.nid = n.nid AND nr.vid = n.vid');
$query->leftJoin('node_field_data', 'nf', 'nf.nid = n.nid AND n.vid = nf.vid');
$query->fields('n', ['nid']);
$query->fields('nf', ['langcode', 'title', 'status', 'created', 'changed', 'promote', 'sticky']);
$query->condition('n.type', 'article');
$query->orderBy('n.nid');
// If your migrations require additional joins or fields,
// you can further extend the query as needed.
return $query;
}
/**
* {@inheritdoc}
*/
public function fields() {
$fields = [
'nid' => $this->t('ID'),
'langcode' => $this->t('Language code'),
'title' => $this->t('Title'),
'status' => $this->t('Status'),
'created' => $this->t('Created'),
'changed' => $this->t('Updated'),
'promote' => $this->t('Promoted'),
'sticky' => $this->t('Sticky'),
];
return $fields;
}
/**
* {@inheritdoc}
*/
public function getIds() {
return [
'nid' => [
'type' => 'integer',
'alias' => 'n',
],
];
}
}
Final Notes
Once the source database credentials are configured via your form, the above setup will enable your migration plugins to use those credentials dynamically.
Happy migrating!
Top comments (0)