diff --git a/core/modules/migrate/src/Plugin/migrate/source/SqlBase.php b/core/modules/migrate/src/Plugin/migrate/source/SqlBase.php index eec7275b541..343e7232fba 100644 --- a/core/modules/migrate/src/Plugin/migrate/source/SqlBase.php +++ b/core/modules/migrate/src/Plugin/migrate/source/SqlBase.php @@ -8,9 +8,12 @@ namespace Drupal\migrate\Plugin\migrate\source; use Drupal\Core\Database\Database; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\State\StateInterface; use Drupal\migrate\Entity\MigrationInterface; use Drupal\migrate\Plugin\migrate\id_map\Sql; use Drupal\migrate\Plugin\MigrateIdMapInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Sources whose data may be fetched via DBTNG. @@ -21,7 +24,7 @@ use Drupal\migrate\Plugin\MigrateIdMapInterface; * is present, it is used as a database connection information array to define * the connection. */ -abstract class SqlBase extends SourcePluginBase { +abstract class SqlBase extends SourcePluginBase implements ContainerFactoryPluginInterface { /** * @var \Drupal\Core\Database\Query\SelectInterface @@ -33,11 +36,32 @@ abstract class SqlBase extends SourcePluginBase { */ protected $database; + /** + * State service for retrieving database info. + * + * @var \Drupal\Core\State\StateInterface + */ + protected $state; + /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state) { parent::__construct($configuration, $plugin_id, $plugin_definition, $migration); + $this->state = $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') + ); } /** @@ -58,26 +82,51 @@ abstract class SqlBase extends SourcePluginBase { */ public function getDatabase() { if (!isset($this->database)) { - if (isset($this->configuration['target'])) { - $target = $this->configuration['target']; + // See if the database info is in state - if not, fallback to + // configuration. + if (isset($this->configuration['database_state_key'])) { + $this->database = $this->setUpDatabase($this->state->get($this->configuration['database_state_key'])); } else { - $target = 'default'; + $this->database = $this->setUpDatabase($this->configuration); } - if (isset($this->configuration['key'])) { - $key = $this->configuration['key']; - } - else { - $key = 'migrate'; - } - if (isset($this->configuration['database'])) { - Database::addConnectionInfo($key, $target, $this->configuration['database']); - } - $this->database = Database::getConnection($target, $key); } return $this->database; } + /** + * Get a connection to the referenced database, adding the connection if + * necessary. + * + * @param array $database_info + * Configuration for the source database connection. The keys are: + * 'key' - The database connection key. + * 'target' - The database connection target. + * 'database' - Database configuration array as accepted by + * Database::addConnectionInfo. + * + * @return \Drupal\Core\Database\Connection + * The connection to use for this plugin's queries. + */ + protected function setUpDatabase(array $database_info) { + if (isset($database_info['key'])) { + $key = $database_info['key']; + } + else { + $key = 'migrate'; + } + if (isset($database_info['target'])) { + $target = $database_info['target']; + } + else { + $target = 'default'; + } + if (isset($database_info['database'])) { + Database::addConnectionInfo($key, $target, $database_info['database']); + } + return Database::getConnection($target, $key); + } + /** * Wrapper for database select. */ diff --git a/core/modules/migrate/src/Tests/SqlBaseTest.php b/core/modules/migrate/src/Tests/SqlBaseTest.php index 9a96bb41c01..646b2912f98 100644 --- a/core/modules/migrate/src/Tests/SqlBaseTest.php +++ b/core/modules/migrate/src/Tests/SqlBaseTest.php @@ -24,6 +24,7 @@ class SqlBaseTest extends MigrateTestBase { $sql_base = new TestSqlBase(); // Check the default values. + $sql_base->setConfiguration([]); $this->assertIdentical($sql_base->getDatabase()->getTarget(), 'default'); $this->assertIdentical($sql_base->getDatabase()->getKey(), 'migrate'); @@ -52,6 +53,35 @@ class SqlBaseTest extends MigrateTestBase { // Validate the connection has been created with the right values. $this->assertIdentical(Database::getConnectionInfo($key)[$target], $database); + // Now, test this all works when using state to store db info. + $target = 'test_state_db_target'; + $key = 'test_state_migrate_connection'; + $config = ['target' => $target, 'key' => $key]; + $database_state_key = 'migrate_sql_base_test'; + \Drupal::state()->set($database_state_key, $config); + $sql_base->setConfiguration(['database_state_key' => $database_state_key]); + Database::addConnectionInfo($key, $target, Database::getConnectionInfo('default')['default']); + + // Validate we've injected our custom key and target. + $this->assertIdentical($sql_base->getDatabase()->getTarget(), $target); + $this->assertIdentical($sql_base->getDatabase()->getKey(), $key); + + // Now test we can have SqlBase create the connection from an info array. + $sql_base = new TestSqlBase(); + + $target = 'test_state_db_target2'; + $key = 'test_state_migrate_connection2'; + $database = Database::getConnectionInfo('default')['default']; + $config = ['target' => $target, 'key' => $key, 'database' => $database]; + $database_state_key = 'migrate_sql_base_test2'; + \Drupal::state()->set($database_state_key, $config); + $sql_base->setConfiguration(['database_state_key' => $database_state_key]); + + // Call getDatabase() to get the connection defined. + $sql_base->getDatabase(); + + // Validate the connection has been created with the right values. + $this->assertIdentical(Database::getConnectionInfo($key)[$target], $database); } } @@ -68,7 +98,9 @@ class TestSqlBase extends SqlBase { /** * Override the constructor so we can create one easily. */ - public function __construct() {} + public function __construct() { + $this->state = \Drupal::state(); + } /** * Get the database without caching it. diff --git a/core/modules/migrate/tests/src/Unit/MigrateSqlSourceTestCase.php b/core/modules/migrate/tests/src/Unit/MigrateSqlSourceTestCase.php index 0f4aad3f5d7..5824dbd3874 100644 --- a/core/modules/migrate/tests/src/Unit/MigrateSqlSourceTestCase.php +++ b/core/modules/migrate/tests/src/Unit/MigrateSqlSourceTestCase.php @@ -77,6 +77,7 @@ abstract class MigrateSqlSourceTestCase extends MigrateTestCase { */ protected function setUp() { $module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); + $state = $this->getMock('Drupal\Core\State\StateInterface'); $entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); $migration = $this->getMigration(); @@ -86,7 +87,7 @@ abstract class MigrateSqlSourceTestCase extends MigrateTestCase { // Setup the plugin. $plugin_class = static::PLUGIN_CLASS; - $plugin = new $plugin_class($this->migrationConfiguration['source'], $this->migrationConfiguration['source']['plugin'], array(), $migration, $entity_manager); + $plugin = new $plugin_class($this->migrationConfiguration['source'], $this->migrationConfiguration['source']['plugin'], array(), $migration, $state, $entity_manager); // Do some reflection to set the database and moduleHandler. $plugin_reflection = new \ReflectionClass($plugin); diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/DrupalSqlBase.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/DrupalSqlBase.php index deb7adfdecd..bb7f452e3c7 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/source/DrupalSqlBase.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/DrupalSqlBase.php @@ -11,6 +11,7 @@ use Drupal\Component\Plugin\DependentPluginInterface; use Drupal\Core\Entity\DependencyTrait; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\State\StateInterface; use Drupal\migrate\Entity\MigrationInterface; use Drupal\migrate\Exception\RequirementsException; use Drupal\migrate\Plugin\migrate\source\SqlBase; @@ -51,8 +52,8 @@ abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginIn /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityManagerInterface $entity_manager) { - parent::__construct($configuration, $plugin_id, $plugin_definition, $migration); + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, EntityManagerInterface $entity_manager) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state); $this->entityManager = $entity_manager; } @@ -89,6 +90,7 @@ abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginIn $plugin_id, $plugin_definition, $migration, + $container->get('state'), $container->get('entity.manager') ); } diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php index 64e33a55c4c..427384683c5 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php @@ -8,6 +8,7 @@ namespace Drupal\migrate_drupal\Plugin\migrate\source; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\State\StateInterface; use Drupal\migrate\Entity\MigrationInterface; /** @@ -32,8 +33,8 @@ class Variable extends DrupalSqlBase { /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityManagerInterface $entity_manager) { - parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $entity_manager); + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, EntityManagerInterface $entity_manager) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state, $entity_manager); $this->variables = $this->configuration['variables']; } diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/Drupal6SqlBaseTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/Drupal6SqlBaseTest.php index 2e1ea51fbf2..0a43d30de23 100644 --- a/core/modules/migrate_drupal/tests/src/Unit/source/d6/Drupal6SqlBaseTest.php +++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/Drupal6SqlBaseTest.php @@ -68,8 +68,11 @@ class Drupal6SqlBaseTest extends MigrateTestCase { */ protected function setUp() { $plugin = 'placeholder_id'; - $entity_manager = $this->getmock('Drupal\Core\Entity\EntityManagerInterface'); - $this->base = new TestDrupal6SqlBase($this->migrationConfiguration, $plugin, array(), $this->getMigration(), $entity_manager); + /** @var \Drupal\Core\State\StateInterface $state */ + $state = $this->getMock('Drupal\Core\State\StateInterface'); + /** @var \Drupal\Core\Entity\EntityManagerInterface $entity_manager */ + $entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); + $this->base = new TestDrupal6SqlBase($this->migrationConfiguration, $plugin, array(), $this->getMigration(), $state, $entity_manager); $this->base->setDatabase($this->getDatabase($this->databaseContents)); }