Commit a7ab06c3 authored by catch's avatar catch

Issue #2830036 by mikeryan, denutkarsh:...

Issue #2830036 by mikeryan, denutkarsh: MigrationPluginManager::getDefinitions() blows up in node derivers
parent 3a90d689
......@@ -2,13 +2,16 @@
namespace Drupal\migrate\Plugin\migrate\source;
use Drupal\Core\Database\ConnectionNotDefinedException;
use Drupal\Core\Database\Database;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\State\StateInterface;
use Drupal\migrate\Exception\RequirementsException;
use Drupal\migrate\MigrateException;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Plugin\migrate\id_map\Sql;
use Drupal\migrate\Plugin\MigrateIdMapInterface;
use Drupal\migrate\Plugin\RequirementsInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
......@@ -20,7 +23,7 @@
* is present, it is used as a database connection information array to define
* the connection.
*/
abstract class SqlBase extends SourcePluginBase implements ContainerFactoryPluginInterface {
abstract class SqlBase extends SourcePluginBase implements ContainerFactoryPluginInterface, RequirementsInterface {
/**
* The query string.
......@@ -127,12 +130,17 @@ public function getDatabase() {
*
* @return \Drupal\Core\Database\Connection
* The connection to use for this plugin's queries.
*
* @throws \Drupal\migrate\Exception\RequirementsException
* Thrown if no source database connection is configured.
*/
protected function setUpDatabase(array $database_info) {
if (isset($database_info['key'])) {
$key = $database_info['key'];
}
else {
// If there is no explicit database configuration at all, fall back to a
// connection named 'migrate'.
$key = 'migrate';
}
if (isset($database_info['target'])) {
......@@ -144,7 +152,29 @@ protected function setUpDatabase(array $database_info) {
if (isset($database_info['database'])) {
Database::addConnectionInfo($key, $target, $database_info['database']);
}
return Database::getConnection($target, $key);
try {
$connection = Database::getConnection($target, $key);
}
catch (ConnectionNotDefinedException $e) {
// If we fell back to the magic 'migrate' connection and it doesn't exist,
// treat the lack of the connection as a RequirementsException.
if ($key == 'migrate') {
throw new RequirementsException("No database connection configured for source plugin " . $this->pluginId, [], 0, $e);
}
else {
throw $e;
}
}
return $connection;
}
/**
* {@inheritdoc}
*/
public function checkRequirements() {
if ($this->pluginDefinition['requirements_met'] === TRUE) {
$this->getDatabase();
}
}
/**
......
......@@ -4,6 +4,9 @@
use Drupal\Core\Database\Database;
use Drupal\KernelTests\KernelTestBase;
use Drupal\migrate\Exception\RequirementsException;
use Drupal\migrate\Plugin\migrate\source\SqlBase;
use Drupal\migrate\Plugin\RequirementsInterface;
/**
* Tests the migration plugin manager.
......@@ -79,6 +82,31 @@ public function testGetDefinitions() {
// Enable migrate_drupal to test that the plugins can now be discovered.
$this->enableModules(['migrate_drupal']);
// Make sure retrieving these migration plugins in the absence of a database
// connection does not throw any errors.
$migration_plugins = $this->container->get('plugin.manager.migration')->createInstances([]);
// Any database-based source plugins should fail a requirements test in the
// absence of a source database connection (e.g., a connection with the
// 'migrate' key).
$source_plugins = array_map(function ($migration_plugin) { return $migration_plugin->getSourcePlugin(); }, $migration_plugins);
foreach ($source_plugins as $id => $source_plugin) {
if ($source_plugin instanceof RequirementsInterface) {
try {
$source_plugin->checkRequirements();
}
catch (RequirementsException $e) {
unset($source_plugins[$id]);
}
}
}
// Without a connection defined, no database-based plugins should be
// returned.
foreach ($source_plugins as $id => $source_plugin) {
$this->assertNotInstanceOf(SqlBase::class, $source_plugin);
}
// Set up a migrate database connection so that plugin discovery works.
// Clone the current connection and replace the current prefix.
$connection_info = Database::getConnectionInfo('migrate');
......
......@@ -10,7 +10,6 @@
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Exception\RequirementsException;
use Drupal\migrate\Plugin\migrate\source\SqlBase;
use Drupal\migrate\Plugin\RequirementsInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
......@@ -19,7 +18,7 @@
* Mainly to let children retrieve information from the origin system in an
* easier way.
*/
abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginInterface, RequirementsInterface, DependentPluginInterface {
abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginInterface, DependentPluginInterface {
use DependencyTrait;
......@@ -106,6 +105,7 @@ public function checkRequirements() {
}
}
}
parent::checkRequirements();
}
/**
......
......@@ -90,6 +90,16 @@ public function getDerivativeDefinitions($base_plugin_definition) {
return $this->derivatives;
}
$node_types = static::getSourcePlugin('d6_node_type');
try {
$node_types->checkRequirements();
}
catch (RequirementsException $e) {
// If the d6_node_type requirements failed, that means we do not have a
// Drupal source database configured - there is nothing to generate.
return $this->derivatives;
}
// Read all CCK field instance definitions in the source database.
$fields = array();
try {
......@@ -107,7 +117,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
}
try {
foreach (static::getSourcePlugin('d6_node_type') as $row) {
foreach ($node_types as $row) {
$node_type = $row->getSourceProperty('type');
$values = $base_plugin_definition;
......
......@@ -65,6 +65,16 @@ public static function create(ContainerInterface $container, $base_plugin_id) {
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
$node_types = static::getSourcePlugin('d7_node_type');
try {
$node_types->checkRequirements();
}
catch (RequirementsException $e) {
// If the d7_node_type requirements failed, that means we do not have a
// Drupal source database configured - there is nothing to generate.
return $this->derivatives;
}
$fields = [];
try {
$source_plugin = static::getSourcePlugin('d7_field_instance');
......@@ -84,7 +94,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
}
try {
foreach (static::getSourcePlugin('d7_node_type') as $row) {
foreach ($node_types as $row) {
$node_type = $row->getSourceProperty('type');
$values = $base_plugin_definition;
......
......@@ -84,8 +84,19 @@ public function getDerivativeDefinitions($base_plugin_definition) {
// we'll create a migration just for the node properties.
}
$vocabulary_source_plugin = static::getSourcePlugin('d7_taxonomy_vocabulary');
try {
foreach (static::getSourcePlugin('d7_taxonomy_vocabulary') as $row) {
$vocabulary_source_plugin->checkRequirements();
}
catch (RequirementsException $e) {
// If the d7_taxonomy_vocabulary requirements failed, that means we do not
// have a Drupal source database configured - there is nothing to
// generate.
return $this->derivatives;
}
try {
foreach ($vocabulary_source_plugin as $row) {
$bundle = $row->getSourceProperty('machine_name');
$values = $base_plugin_definition;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment