0349d87a7731fbd640ad7187dff89ec55cb13f6e
[yaffs-website] / web / core / modules / migrate_drupal / src / MigrationConfigurationTrait.php
1 <?php
2
3 namespace Drupal\migrate_drupal;
4
5 use Drupal\Core\Database\Connection;
6 use Drupal\Core\Database\Database;
7 use Drupal\migrate\Exception\RequirementsException;
8 use Drupal\migrate\Plugin\RequirementsInterface;
9
10 /**
11  * Configures the appropriate migrations for a given source Drupal database.
12  */
13 trait MigrationConfigurationTrait {
14
15   /**
16    * The follow-up migration tags.
17    *
18    * @var string[]
19    */
20   protected $followUpMigrationTags;
21
22   /**
23    * Gets the database connection for the source Drupal database.
24    *
25    * @param array $database
26    *   Database array representing the source Drupal database.
27    *
28    * @return \Drupal\Core\Database\Connection
29    *   The database connection for the source Drupal database.
30    */
31   protected function getConnection(array $database) {
32     // Set up the connection.
33     Database::addConnectionInfo('upgrade', 'default', $database);
34     $connection = Database::getConnection('default', 'upgrade');
35     return $connection;
36   }
37
38   /**
39    * Gets the system data from the system table of the source Drupal database.
40    *
41    * @param \Drupal\Core\Database\Connection $connection
42    *   Database connection to the source Drupal database.
43    *
44    * @return array
45    *   The system data from the system table of the source Drupal database.
46    */
47   protected function getSystemData(Connection $connection) {
48     $system_data = [];
49     try {
50       $results = $connection->select('system', 's', [
51         'fetch' => \PDO::FETCH_ASSOC,
52       ])
53         ->fields('s')
54         ->execute();
55       foreach ($results as $result) {
56         $system_data[$result['type']][$result['name']] = $result;
57       }
58     }
59     catch (\Exception $e) {
60       // The table might not exist for example in tests.
61     }
62     return $system_data;
63   }
64
65   /**
66    * Creates the necessary state entries for SqlBase::getDatabase() to work.
67    *
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
71    * database.
72    *
73    * @param array $database
74    *   The source database settings.
75    * @param string $drupal_version
76    *   The Drupal version.
77    *
78    * @see \Drupal\migrate\Plugin\migrate\source\SqlBase::getDatabase()
79    */
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);
86   }
87
88   /**
89    * Gets the migrations for import.
90    *
91    * @param string $database_state_key
92    *   The state key.
93    * @param int $drupal_version
94    *   The version of Drupal we're getting the migrations for.
95    *
96    * @return \Drupal\migrate\Plugin\MigrationInterface[]
97    *   The migrations for import.
98    */
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);
104     $migrations = [];
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()))) {
111         continue;
112       }
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()));
117       }
118
119       try {
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();
125         }
126         $destination_plugin = $migration->getDestinationPlugin();
127         if ($destination_plugin instanceof RequirementsInterface) {
128           $destination_plugin->checkRequirements();
129         }
130         $migrations[] = $migration;
131       }
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
135         // ignored.
136       }
137     }
138
139     return $migrations;
140   }
141
142   /**
143    * Returns the follow-up migration tags.
144    *
145    * @return string[]
146    */
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') ?: [];
152     }
153     return $this->followUpMigrationTags;
154   }
155
156   /**
157    * Determines what version of Drupal the source database contains.
158    *
159    * @param \Drupal\Core\Database\Connection $connection
160    *   The database connection object.
161    *
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.
165    */
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
169     // not Drupal.
170     // Drupal 5/6/7 can be detected by the schema_version in the system table.
171     if ($connection->schema()->tableExists('system')) {
172       try {
173         $version_string = $connection
174           ->query('SELECT schema_version FROM {system} WHERE name = :module', [':module' => 'system'])
175           ->fetchField();
176         if ($version_string && $version_string[0] == '1') {
177           if ((int) $version_string >= 1000) {
178             $version_string = '5';
179           }
180           else {
181             $version_string = FALSE;
182           }
183         }
184       }
185       catch (\PDOException $e) {
186         $version_string = FALSE;
187       }
188     }
189     // For Drupal 8 (and we're predicting beyond) the schema version is in the
190     // key_value store.
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'])
194         ->fetchField();
195       $version_string = unserialize($result);
196     }
197     else {
198       $version_string = FALSE;
199     }
200
201     return $version_string ? substr($version_string, 0, 1) : FALSE;
202   }
203
204 }