annotate core/modules/migrate_drupal/src/MigrationConfigurationTrait.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\migrate_drupal;
Chris@0 4
Chris@0 5 use Drupal\Core\Database\Connection;
Chris@0 6 use Drupal\Core\Database\Database;
Chris@18 7 use Drupal\Core\Database\DatabaseExceptionWrapper;
Chris@0 8 use Drupal\migrate\Exception\RequirementsException;
Chris@0 9 use Drupal\migrate\Plugin\RequirementsInterface;
Chris@0 10
Chris@0 11 /**
Chris@0 12 * Configures the appropriate migrations for a given source Drupal database.
Chris@0 13 */
Chris@0 14 trait MigrationConfigurationTrait {
Chris@0 15
Chris@0 16 /**
Chris@16 17 * The follow-up migration tags.
Chris@16 18 *
Chris@16 19 * @var string[]
Chris@16 20 */
Chris@16 21 protected $followUpMigrationTags;
Chris@16 22
Chris@16 23 /**
Chris@0 24 * Gets the database connection for the source Drupal database.
Chris@0 25 *
Chris@0 26 * @param array $database
Chris@0 27 * Database array representing the source Drupal database.
Chris@0 28 *
Chris@0 29 * @return \Drupal\Core\Database\Connection
Chris@0 30 * The database connection for the source Drupal database.
Chris@0 31 */
Chris@0 32 protected function getConnection(array $database) {
Chris@0 33 // Set up the connection.
Chris@0 34 Database::addConnectionInfo('upgrade', 'default', $database);
Chris@0 35 $connection = Database::getConnection('default', 'upgrade');
Chris@0 36 return $connection;
Chris@0 37 }
Chris@0 38
Chris@0 39 /**
Chris@0 40 * Gets the system data from the system table of the source Drupal database.
Chris@0 41 *
Chris@0 42 * @param \Drupal\Core\Database\Connection $connection
Chris@0 43 * Database connection to the source Drupal database.
Chris@0 44 *
Chris@0 45 * @return array
Chris@0 46 * The system data from the system table of the source Drupal database.
Chris@0 47 */
Chris@0 48 protected function getSystemData(Connection $connection) {
Chris@0 49 $system_data = [];
Chris@0 50 try {
Chris@0 51 $results = $connection->select('system', 's', [
Chris@0 52 'fetch' => \PDO::FETCH_ASSOC,
Chris@0 53 ])
Chris@0 54 ->fields('s')
Chris@0 55 ->execute();
Chris@0 56 foreach ($results as $result) {
Chris@0 57 $system_data[$result['type']][$result['name']] = $result;
Chris@0 58 }
Chris@0 59 }
Chris@18 60 catch (DatabaseExceptionWrapper $e) {
Chris@0 61 // The table might not exist for example in tests.
Chris@0 62 }
Chris@0 63 return $system_data;
Chris@0 64 }
Chris@0 65
Chris@0 66 /**
Chris@0 67 * Creates the necessary state entries for SqlBase::getDatabase() to work.
Chris@0 68 *
Chris@0 69 * The state entities created here have to exist before migration plugin
Chris@0 70 * instances are created so that derivers such as
Chris@0 71 * \Drupal\taxonomy\Plugin\migrate\D6TermNodeDeriver can access the source
Chris@0 72 * database.
Chris@0 73 *
Chris@0 74 * @param array $database
Chris@0 75 * The source database settings.
Chris@0 76 * @param string $drupal_version
Chris@0 77 * The Drupal version.
Chris@0 78 *
Chris@0 79 * @see \Drupal\migrate\Plugin\migrate\source\SqlBase::getDatabase()
Chris@0 80 */
Chris@0 81 protected function createDatabaseStateSettings(array $database, $drupal_version) {
Chris@0 82 $database_state['key'] = 'upgrade';
Chris@0 83 $database_state['database'] = $database;
Chris@0 84 $database_state_key = 'migrate_drupal_' . $drupal_version;
Chris@0 85 \Drupal::state()->set($database_state_key, $database_state);
Chris@0 86 \Drupal::state()->set('migrate.fallback_state_key', $database_state_key);
Chris@0 87 }
Chris@0 88
Chris@0 89 /**
Chris@0 90 * Gets the migrations for import.
Chris@0 91 *
Chris@0 92 * @param string $database_state_key
Chris@0 93 * The state key.
Chris@0 94 * @param int $drupal_version
Chris@0 95 * The version of Drupal we're getting the migrations for.
Chris@0 96 *
Chris@0 97 * @return \Drupal\migrate\Plugin\MigrationInterface[]
Chris@0 98 * The migrations for import.
Chris@0 99 */
Chris@0 100 protected function getMigrations($database_state_key, $drupal_version) {
Chris@0 101 $version_tag = 'Drupal ' . $drupal_version;
Chris@0 102 $plugin_manager = \Drupal::service('plugin.manager.migration');
Chris@0 103 /** @var \Drupal\migrate\Plugin\Migration[] $all_migrations */
Chris@0 104 $all_migrations = $plugin_manager->createInstancesByTag($version_tag);
Chris@0 105 $migrations = [];
Chris@0 106 foreach ($all_migrations as $migration) {
Chris@16 107 // Skip migrations tagged with any of the follow-up migration tags. They
Chris@16 108 // will be derived and executed after the migrations on which they depend
Chris@16 109 // have been successfully executed.
Chris@16 110 // @see Drupal\migrate_drupal\Plugin\MigrationWithFollowUpInterface
Chris@16 111 if (!empty(array_intersect($migration->getMigrationTags(), $this->getFollowUpMigrationTags()))) {
Chris@16 112 continue;
Chris@16 113 }
Chris@17 114 // Multilingual migrations require migrate_drupal_multilingual.
Chris@17 115 $tags = $migration->getMigrationTags() ?: [];
Chris@17 116 if (in_array('Multilingual', $tags, TRUE) && (!\Drupal::service('module_handler')->moduleExists('migrate_drupal_multilingual'))) {
Chris@17 117 throw new RequirementsException(sprintf("Install migrate_drupal_multilingual to run migration '%s'.", $migration->getPluginId()));
Chris@17 118 }
Chris@17 119
Chris@0 120 try {
Chris@0 121 // @todo https://drupal.org/node/2681867 We should be able to validate
Chris@0 122 // the entire migration at this point.
Chris@0 123 $source_plugin = $migration->getSourcePlugin();
Chris@0 124 if ($source_plugin instanceof RequirementsInterface) {
Chris@0 125 $source_plugin->checkRequirements();
Chris@0 126 }
Chris@0 127 $destination_plugin = $migration->getDestinationPlugin();
Chris@0 128 if ($destination_plugin instanceof RequirementsInterface) {
Chris@0 129 $destination_plugin->checkRequirements();
Chris@0 130 }
Chris@0 131 $migrations[] = $migration;
Chris@0 132 }
Chris@0 133 catch (RequirementsException $e) {
Chris@0 134 // Migrations which are not applicable given the source and destination
Chris@0 135 // site configurations (e.g., what modules are enabled) will be silently
Chris@0 136 // ignored.
Chris@0 137 }
Chris@0 138 }
Chris@0 139
Chris@0 140 return $migrations;
Chris@0 141 }
Chris@0 142
Chris@0 143 /**
Chris@16 144 * Returns the follow-up migration tags.
Chris@16 145 *
Chris@16 146 * @return string[]
Chris@16 147 */
Chris@16 148 protected function getFollowUpMigrationTags() {
Chris@16 149 if ($this->followUpMigrationTags === NULL) {
Chris@16 150 $this->followUpMigrationTags = \Drupal::configFactory()
Chris@16 151 ->get('migrate_drupal.settings')
Chris@16 152 ->get('follow_up_migration_tags') ?: [];
Chris@16 153 }
Chris@16 154 return $this->followUpMigrationTags;
Chris@16 155 }
Chris@16 156
Chris@16 157 /**
Chris@0 158 * Determines what version of Drupal the source database contains.
Chris@0 159 *
Chris@0 160 * @param \Drupal\Core\Database\Connection $connection
Chris@0 161 * The database connection object.
Chris@0 162 *
Chris@14 163 * @return string|false
Chris@14 164 * A string representing the major branch of Drupal core (e.g. '6' for
Chris@0 165 * Drupal 6.x), or FALSE if no valid version is matched.
Chris@0 166 */
Chris@0 167 protected function getLegacyDrupalVersion(Connection $connection) {
Chris@0 168 // Don't assume because a table of that name exists, that it has the columns
Chris@0 169 // we're querying. Catch exceptions and report that the source database is
Chris@0 170 // not Drupal.
Chris@0 171 // Drupal 5/6/7 can be detected by the schema_version in the system table.
Chris@0 172 if ($connection->schema()->tableExists('system')) {
Chris@0 173 try {
Chris@0 174 $version_string = $connection
Chris@0 175 ->query('SELECT schema_version FROM {system} WHERE name = :module', [':module' => 'system'])
Chris@0 176 ->fetchField();
Chris@0 177 if ($version_string && $version_string[0] == '1') {
Chris@0 178 if ((int) $version_string >= 1000) {
Chris@0 179 $version_string = '5';
Chris@0 180 }
Chris@0 181 else {
Chris@0 182 $version_string = FALSE;
Chris@0 183 }
Chris@0 184 }
Chris@0 185 }
Chris@0 186 catch (\PDOException $e) {
Chris@0 187 $version_string = FALSE;
Chris@0 188 }
Chris@0 189 }
Chris@0 190 // For Drupal 8 (and we're predicting beyond) the schema version is in the
Chris@0 191 // key_value store.
Chris@0 192 elseif ($connection->schema()->tableExists('key_value')) {
Chris@18 193 try {
Chris@18 194 $result = $connection
Chris@18 195 ->query("SELECT value FROM {key_value} WHERE collection = :system_schema and name = :module", [
Chris@18 196 ':system_schema' => 'system.schema',
Chris@18 197 ':module' => 'system',
Chris@18 198 ])
Chris@18 199 ->fetchField();
Chris@18 200 $version_string = unserialize($result);
Chris@18 201 }
Chris@18 202 catch (DatabaseExceptionWrapper $e) {
Chris@18 203 $version_string = FALSE;
Chris@18 204 }
Chris@0 205 }
Chris@0 206 else {
Chris@0 207 $version_string = FALSE;
Chris@0 208 }
Chris@0 209
Chris@0 210 return $version_string ? substr($version_string, 0, 1) : FALSE;
Chris@0 211 }
Chris@0 212
Chris@0 213 }