3 namespace Drupal\migrate_drupal;
5 use Drupal\Core\Database\Connection;
6 use Drupal\Core\Database\Database;
7 use Drupal\migrate\Exception\RequirementsException;
8 use Drupal\migrate\Plugin\RequirementsInterface;
11 * Configures the appropriate migrations for a given source Drupal database.
13 trait MigrationConfigurationTrait {
16 * The follow-up migration tags.
20 protected $followUpMigrationTags;
23 * Gets the database connection for the source Drupal database.
25 * @param array $database
26 * Database array representing the source Drupal database.
28 * @return \Drupal\Core\Database\Connection
29 * The database connection for the source Drupal database.
31 protected function getConnection(array $database) {
32 // Set up the connection.
33 Database::addConnectionInfo('upgrade', 'default', $database);
34 $connection = Database::getConnection('default', 'upgrade');
39 * Gets the system data from the system table of the source Drupal database.
41 * @param \Drupal\Core\Database\Connection $connection
42 * Database connection to the source Drupal database.
45 * The system data from the system table of the source Drupal database.
47 protected function getSystemData(Connection $connection) {
50 $results = $connection->select('system', 's', [
51 'fetch' => \PDO::FETCH_ASSOC,
55 foreach ($results as $result) {
56 $system_data[$result['type']][$result['name']] = $result;
59 catch (\Exception $e) {
60 // The table might not exist for example in tests.
66 * Creates the necessary state entries for SqlBase::getDatabase() to work.
68 * The state entities created here have to exist before migration plugin
69 * instances are created so that derivers such as
70 * \Drupal\taxonomy\Plugin\migrate\D6TermNodeDeriver can access the source
73 * @param array $database
74 * The source database settings.
75 * @param string $drupal_version
78 * @see \Drupal\migrate\Plugin\migrate\source\SqlBase::getDatabase()
80 protected function createDatabaseStateSettings(array $database, $drupal_version) {
81 $database_state['key'] = 'upgrade';
82 $database_state['database'] = $database;
83 $database_state_key = 'migrate_drupal_' . $drupal_version;
84 \Drupal::state()->set($database_state_key, $database_state);
85 \Drupal::state()->set('migrate.fallback_state_key', $database_state_key);
89 * Gets the migrations for import.
91 * @param string $database_state_key
93 * @param int $drupal_version
94 * The version of Drupal we're getting the migrations for.
96 * @return \Drupal\migrate\Plugin\MigrationInterface[]
97 * The migrations for import.
99 protected function getMigrations($database_state_key, $drupal_version) {
100 $version_tag = 'Drupal ' . $drupal_version;
101 $plugin_manager = \Drupal::service('plugin.manager.migration');
102 /** @var \Drupal\migrate\Plugin\Migration[] $all_migrations */
103 $all_migrations = $plugin_manager->createInstancesByTag($version_tag);
105 foreach ($all_migrations as $migration) {
106 // Skip migrations tagged with any of the follow-up migration tags. They
107 // will be derived and executed after the migrations on which they depend
108 // have been successfully executed.
109 // @see Drupal\migrate_drupal\Plugin\MigrationWithFollowUpInterface
110 if (!empty(array_intersect($migration->getMigrationTags(), $this->getFollowUpMigrationTags()))) {
113 // Multilingual migrations require migrate_drupal_multilingual.
114 $tags = $migration->getMigrationTags() ?: [];
115 if (in_array('Multilingual', $tags, TRUE) && (!\Drupal::service('module_handler')->moduleExists('migrate_drupal_multilingual'))) {
116 throw new RequirementsException(sprintf("Install migrate_drupal_multilingual to run migration '%s'.", $migration->getPluginId()));
120 // @todo https://drupal.org/node/2681867 We should be able to validate
121 // the entire migration at this point.
122 $source_plugin = $migration->getSourcePlugin();
123 if ($source_plugin instanceof RequirementsInterface) {
124 $source_plugin->checkRequirements();
126 $destination_plugin = $migration->getDestinationPlugin();
127 if ($destination_plugin instanceof RequirementsInterface) {
128 $destination_plugin->checkRequirements();
130 $migrations[] = $migration;
132 catch (RequirementsException $e) {
133 // Migrations which are not applicable given the source and destination
134 // site configurations (e.g., what modules are enabled) will be silently
143 * Returns the follow-up migration tags.
147 protected function getFollowUpMigrationTags() {
148 if ($this->followUpMigrationTags === NULL) {
149 $this->followUpMigrationTags = \Drupal::configFactory()
150 ->get('migrate_drupal.settings')
151 ->get('follow_up_migration_tags') ?: [];
153 return $this->followUpMigrationTags;
157 * Determines what version of Drupal the source database contains.
159 * @param \Drupal\Core\Database\Connection $connection
160 * The database connection object.
162 * @return string|false
163 * A string representing the major branch of Drupal core (e.g. '6' for
164 * Drupal 6.x), or FALSE if no valid version is matched.
166 protected function getLegacyDrupalVersion(Connection $connection) {
167 // Don't assume because a table of that name exists, that it has the columns
168 // we're querying. Catch exceptions and report that the source database is
170 // Drupal 5/6/7 can be detected by the schema_version in the system table.
171 if ($connection->schema()->tableExists('system')) {
173 $version_string = $connection
174 ->query('SELECT schema_version FROM {system} WHERE name = :module', [':module' => 'system'])
176 if ($version_string && $version_string[0] == '1') {
177 if ((int) $version_string >= 1000) {
178 $version_string = '5';
181 $version_string = FALSE;
185 catch (\PDOException $e) {
186 $version_string = FALSE;
189 // For Drupal 8 (and we're predicting beyond) the schema version is in the
191 elseif ($connection->schema()->tableExists('key_value')) {
192 $result = $connection
193 ->query("SELECT value FROM {key_value} WHERE collection = :system_schema and name = :module", [':system_schema' => 'system.schema', ':module' => 'system'])
195 $version_string = unserialize($result);
198 $version_string = FALSE;
201 return $version_string ? substr($version_string, 0, 1) : FALSE;