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 }
|