Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /**
|
Chris@0
|
4 * @file
|
Chris@0
|
5 * Contains \Drupal\migrate_upgrade\MigrateUpgradeDrushRunner.
|
Chris@0
|
6 */
|
Chris@0
|
7
|
Chris@0
|
8 namespace Drupal\migrate_upgrade;
|
Chris@0
|
9
|
Chris@0
|
10 use Drupal\migrate\Plugin\MigrationInterface;
|
Chris@0
|
11 use Drupal\migrate\Event\MigrateEvents;
|
Chris@0
|
12 use Drupal\migrate\Event\MigrateIdMapMessageEvent;
|
Chris@0
|
13 use Drupal\migrate\MigrateExecutable;
|
Chris@0
|
14 use Drupal\Core\StringTranslation\StringTranslationTrait;
|
Chris@0
|
15 use Drupal\migrate_drupal\MigrationCreationTrait;
|
Chris@0
|
16 use Drupal\migrate_plus\Entity\Migration;
|
Chris@0
|
17 use Drupal\migrate_plus\Entity\MigrationGroup;
|
Chris@0
|
18
|
Chris@0
|
19 class MigrateUpgradeDrushRunner {
|
Chris@0
|
20
|
Chris@0
|
21 use MigrationCreationTrait;
|
Chris@0
|
22 use StringTranslationTrait;
|
Chris@0
|
23
|
Chris@0
|
24 /**
|
Chris@0
|
25 * The list of migrations to run and their configuration.
|
Chris@0
|
26 *
|
Chris@0
|
27 * @var \Drupal\migrate\Plugin\Migration[]
|
Chris@0
|
28 */
|
Chris@0
|
29 protected $migrationList;
|
Chris@0
|
30
|
Chris@0
|
31 /**
|
Chris@0
|
32 * MigrateMessage instance to display messages during the migration process.
|
Chris@0
|
33 *
|
Chris@0
|
34 * @var \Drupal\migrate_upgrade\DrushLogMigrateMessage
|
Chris@0
|
35 */
|
Chris@0
|
36 protected static $messages;
|
Chris@0
|
37
|
Chris@0
|
38 /**
|
Chris@0
|
39 * The Drupal version being imported.
|
Chris@0
|
40 *
|
Chris@0
|
41 * @var string
|
Chris@0
|
42 */
|
Chris@0
|
43 protected $version;
|
Chris@0
|
44
|
Chris@0
|
45 /**
|
Chris@0
|
46 * The state key used to store database configuration.
|
Chris@0
|
47 *
|
Chris@0
|
48 * @var string
|
Chris@0
|
49 */
|
Chris@0
|
50 protected $databaseStateKey;
|
Chris@0
|
51
|
Chris@0
|
52 /**
|
Chris@0
|
53 * From the provided source information, instantiate the appropriate migrations
|
Chris@0
|
54 * in the active configuration.
|
Chris@0
|
55 *
|
Chris@0
|
56 * @throws \Exception
|
Chris@0
|
57 */
|
Chris@0
|
58 public function configure() {
|
Chris@0
|
59 $db_url = drush_get_option('legacy-db-url');
|
Chris@0
|
60 $db_spec = drush_convert_db_from_db_url($db_url);
|
Chris@0
|
61 $db_prefix = drush_get_option('legacy-db-prefix');
|
Chris@0
|
62 $db_spec['prefix'] = $db_prefix;
|
Chris@0
|
63
|
Chris@0
|
64 $connection = $this->getConnection($db_spec);
|
Chris@0
|
65 $this->version = $this->getLegacyDrupalVersion($connection);
|
Chris@0
|
66 $this->createDatabaseStateSettings($db_spec, $this->version);
|
Chris@0
|
67 $this->databaseStateKey = 'migrate_drupal_' . $this->version;
|
Chris@0
|
68 $migrations = $this->getMigrations($this->databaseStateKey, $this->version);
|
Chris@0
|
69 $this->migrationList = [];
|
Chris@0
|
70 foreach ($migrations as $migration) {
|
Chris@0
|
71 $destination = $migration->get('destination');
|
Chris@0
|
72 if ($destination['plugin'] === 'entity:file') {
|
Chris@0
|
73 // Make sure we have a single trailing slash.
|
Chris@0
|
74 $source_base_path = rtrim(drush_get_option('legacy-root'), '/') . '/';
|
Chris@0
|
75 $destination['source_base_path'] = $source_base_path;
|
Chris@0
|
76 $migration->set('destination', $destination);
|
Chris@0
|
77 }
|
Chris@0
|
78 $this->migrationList[$migration->id()] = $migration;
|
Chris@0
|
79 }
|
Chris@0
|
80 }
|
Chris@0
|
81
|
Chris@0
|
82 /**
|
Chris@0
|
83 * Run the configured migrations.
|
Chris@0
|
84 */
|
Chris@0
|
85 public function import() {
|
Chris@0
|
86 static::$messages = new DrushLogMigrateMessage();
|
Chris@0
|
87 if (drush_get_option('debug')) {
|
Chris@0
|
88 \Drupal::service('event_dispatcher')->addListener(MigrateEvents::IDMAP_MESSAGE,
|
Chris@0
|
89 [get_class(), 'onIdMapMessage']);
|
Chris@0
|
90 }
|
Chris@0
|
91 foreach ($this->migrationList as $migration_id => $migration) {
|
Chris@0
|
92 drush_print(dt('Upgrading @migration', ['@migration' => $migration_id]));
|
Chris@0
|
93 $executable = new MigrateExecutable($migration, static::$messages);
|
Chris@0
|
94 // drush_op() provides --simulate support.
|
Chris@0
|
95 drush_op([$executable, 'import']);
|
Chris@0
|
96 }
|
Chris@0
|
97 }
|
Chris@0
|
98
|
Chris@0
|
99 /**
|
Chris@0
|
100 * Export the configured migration plugins as configuration entities.
|
Chris@0
|
101 */
|
Chris@0
|
102 public function export() {
|
Chris@0
|
103 $db_info = \Drupal::state()->get($this->databaseStateKey);
|
Chris@0
|
104
|
Chris@0
|
105 // Create a group to hold the database configuration.
|
Chris@0
|
106 $group = [
|
Chris@0
|
107 'id' => $this->databaseStateKey,
|
Chris@0
|
108 'label' => 'Import from Drupal ' . $this->version,
|
Chris@0
|
109 'description' => 'Migrations originally generated from drush migrate-upgrade --configure-only',
|
Chris@0
|
110 'source_type' => 'Drupal ' . $this->version,
|
Chris@0
|
111 'shared_configuration' => [
|
Chris@0
|
112 'source' => [
|
Chris@0
|
113 'key' => 'drupal_' . $this->version,
|
Chris@0
|
114 'database' => $db_info['database'],
|
Chris@0
|
115 ]
|
Chris@0
|
116 ]
|
Chris@0
|
117 ];
|
Chris@0
|
118 $group = MigrationGroup::create($group);
|
Chris@0
|
119 $group->save();
|
Chris@0
|
120 foreach ($this->migrationList as $migration_id => $migration) {
|
Chris@0
|
121 drush_print(dt('Exporting @migration as @new_migration',
|
Chris@0
|
122 ['@migration' => $migration_id, '@new_migration' => $this->modifyId($migration_id)]));
|
Chris@0
|
123 $entity_array['id'] = $migration_id;
|
Chris@0
|
124 $entity_array['migration_group'] = $this->databaseStateKey;
|
Chris@0
|
125 $entity_array['migration_tags'] = $migration->get('migration_tags');
|
Chris@0
|
126 $entity_array['label'] = $migration->get('label');
|
Chris@0
|
127 $entity_array['source'] = $migration->getSourceConfiguration();
|
Chris@0
|
128 $entity_array['destination'] = $migration->getDestinationConfiguration();
|
Chris@0
|
129 $entity_array['process'] = $migration->get('process');
|
Chris@0
|
130 $entity_array['migration_dependencies'] = $migration->getMigrationDependencies();
|
Chris@0
|
131 $migration_entity = Migration::create($this->substituteIds($entity_array));
|
Chris@0
|
132 $migration_entity->save();
|
Chris@0
|
133 }
|
Chris@0
|
134 }
|
Chris@0
|
135
|
Chris@0
|
136 /**
|
Chris@0
|
137 * Rewrite any migration plugin IDs so they won't conflict with the core
|
Chris@0
|
138 * IDs.
|
Chris@0
|
139 *
|
Chris@0
|
140 * @param $entity_array
|
Chris@0
|
141 * A configuration array for a migration.
|
Chris@0
|
142 *
|
Chris@0
|
143 * @return array
|
Chris@0
|
144 * The migration configuration array modified with new IDs.
|
Chris@0
|
145 */
|
Chris@0
|
146 protected function substituteIds($entity_array) {
|
Chris@0
|
147 $entity_array['id'] = $this->modifyId($entity_array['id']);
|
Chris@0
|
148 foreach ($entity_array['migration_dependencies'] as $type => $dependencies) {
|
Chris@0
|
149 foreach ($dependencies as $key => $dependency) {
|
Chris@0
|
150 $entity_array['migration_dependencies'][$type][$key] = $this->modifyId($dependency);
|
Chris@0
|
151 }
|
Chris@0
|
152 }
|
Chris@0
|
153 foreach ($entity_array['process'] as $destination => $process) {
|
Chris@0
|
154 if (is_array($process)) {
|
Chris@0
|
155 if ($process['plugin'] == 'migration') {
|
Chris@0
|
156 $entity_array['process'][$destination]['migration'] =
|
Chris@0
|
157 $this->modifyId($process['migration']);
|
Chris@0
|
158 }
|
Chris@0
|
159 }
|
Chris@0
|
160 }
|
Chris@0
|
161 return $entity_array;
|
Chris@0
|
162 }
|
Chris@0
|
163
|
Chris@0
|
164 /**
|
Chris@0
|
165 * @param $id
|
Chris@0
|
166 * The original core plugin ID.
|
Chris@0
|
167 *
|
Chris@0
|
168 * @return string
|
Chris@0
|
169 * The ID modified to serve as a configuration entity ID.
|
Chris@0
|
170 */
|
Chris@0
|
171 protected function modifyId($id) {
|
Chris@0
|
172 return drush_get_option('migration-prefix', 'upgrade_') . str_replace(':', '_', $id);
|
Chris@0
|
173 }
|
Chris@0
|
174
|
Chris@0
|
175 /**
|
Chris@0
|
176 * Rolls back the configured migrations.
|
Chris@0
|
177 */
|
Chris@0
|
178 public function rollback() {
|
Chris@0
|
179 static::$messages = new DrushLogMigrateMessage();
|
Chris@0
|
180 $database_state_key = \Drupal::state()->get('migrate.fallback_state_key');
|
Chris@0
|
181 $database_state = \Drupal::state()->get($database_state_key);
|
Chris@0
|
182 $db_spec = $database_state['database'];
|
Chris@0
|
183 $connection = $this->getConnection($db_spec);
|
Chris@0
|
184 $version = $this->getLegacyDrupalVersion($connection);
|
Chris@0
|
185 $migrations = $this->getMigrations('migrate_drupal_' . $version, $version);
|
Chris@0
|
186
|
Chris@0
|
187 // Roll back in reverse order.
|
Chris@0
|
188 $this->migrationList = array_reverse($migrations);
|
Chris@0
|
189
|
Chris@0
|
190 foreach ($migrations as $migration) {
|
Chris@0
|
191 drush_print(dt('Rolling back @migration', ['@migration' => $migration->id()]));
|
Chris@0
|
192 $executable = new MigrateExecutable($migration, static::$messages);
|
Chris@0
|
193 // drush_op() provides --simulate support.
|
Chris@0
|
194 drush_op([$executable, 'rollback']);
|
Chris@0
|
195 }
|
Chris@0
|
196 }
|
Chris@0
|
197
|
Chris@0
|
198 /**
|
Chris@0
|
199 * Display any messages being logged to the ID map.
|
Chris@0
|
200 *
|
Chris@0
|
201 * @param \Drupal\migrate\Event\MigrateIdMapMessageEvent $event
|
Chris@0
|
202 * The message event.
|
Chris@0
|
203 */
|
Chris@0
|
204 public static function onIdMapMessage(MigrateIdMapMessageEvent $event) {
|
Chris@0
|
205 if ($event->getLevel() == MigrationInterface::MESSAGE_NOTICE ||
|
Chris@0
|
206 $event->getLevel() == MigrationInterface::MESSAGE_INFORMATIONAL) {
|
Chris@0
|
207 $type = 'status';
|
Chris@0
|
208 }
|
Chris@0
|
209 else {
|
Chris@0
|
210 $type = 'error';
|
Chris@0
|
211 }
|
Chris@0
|
212 $source_id_string = implode(',', $event->getSourceIdValues());
|
Chris@0
|
213 $message = t('Source ID @source_id: @message',
|
Chris@0
|
214 ['@source_id' => $source_id_string, '@message' => $event->getMessage()]);
|
Chris@0
|
215 static::$messages->display($message, $type);
|
Chris@0
|
216 }
|
Chris@0
|
217
|
Chris@0
|
218 }
|