Commit 9f4d5e84 authored by catch's avatar catch

Issue #2460529 by alexpott, chx, phenaproxima: Migrations need to use the...

Issue #2460529 by alexpott, chx, phenaproxima: Migrations need to use the configuration entity dependency system
parent 45092042
...@@ -498,12 +498,6 @@ protected function findDefaultConfigWithUnmetDependencies(StorageInterface $stor ...@@ -498,12 +498,6 @@ protected function findDefaultConfigWithUnmetDependencies(StorageInterface $stor
* TRUE if the dependencies are met, FALSE if not. * TRUE if the dependencies are met, FALSE if not.
*/ */
protected function validateDependencies($config_name, array $data, array $enabled_extensions, array $all_config) { protected function validateDependencies($config_name, array $data, array $enabled_extensions, array $all_config) {
// All the migrate tests will fail if we check since they install the
// migrate_drupal module but only set up the dependencies for the single
// migration they are testing.
if (strpos($config_name, 'migrate.migration.') === 0) {
return TRUE;
}
if (isset($data['dependencies'])) { if (isset($data['dependencies'])) {
$all_dependencies = $data['dependencies']; $all_dependencies = $data['dependencies'];
......
...@@ -198,12 +198,41 @@ class Migration extends ConfigEntityBase implements MigrationInterface, Requirem ...@@ -198,12 +198,41 @@ class Migration extends ConfigEntityBase implements MigrationInterface, Requirem
protected $requirements = []; protected $requirements = [];
/** /**
* These migrations, if ran at all, must be executed before this migration. * These migrations, if run, must be executed before this migration.
*
* These are different from the configuration dependencies. Migration
* dependencies are only used to store relationships between migrations.
*
* The migration_dependencies value is structured like this:
* @code
* array(
* 'required' => array(
* // An array of migration IDs that must be run before this migration.
* ),
* 'optional' => array(
* // An array of migration IDs that, if they exist, must be run before
* // this migration.
* ),
* );
* @endcode
* *
* @var array * @var array
*/ */
protected $migration_dependencies = []; protected $migration_dependencies = [];
/**
* The migration's configuration dependencies.
*
* These store any dependencies on modules or other configuration (including
* other migrations) that must be available before the migration can be
* created.
*
* @see \Drupal\Core\Config\Entity\ConfigDependencyManager
*
* @var array
*/
protected $dependencies = [];
/** /**
* The entity manager. * The entity manager.
* *
...@@ -478,6 +507,31 @@ public function setTrackLastImported($track_last_imported) { ...@@ -478,6 +507,31 @@ public function setTrackLastImported($track_last_imported) {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getMigrationDependencies() { public function getMigrationDependencies() {
return $this->migration_dependencies; return $this->migration_dependencies + ['required' => [], 'optional' => []];
}
/**
* {@inheritdoc}
*/
public function trustData() {
// Migrations cannot be trusted since they are often written by hand and not
// through a UI.
$this->trustedData = FALSE;
return $this;
}
/**
* {@inheritdoc}
*/
public function calculateDependencies() {
parent::calculateDependencies();
$this->calculatePluginDependencies($this->getSourcePlugin());
$this->calculatePluginDependencies($this->getDestinationPlugin());
// Add dependencies on required migration dependencies.
foreach ($this->getMigrationDependencies()['required'] as $dependency) {
$this->addDependency('config', $this->getEntityType()->getConfigPrefix() . '.' . $dependency);
}
return $this->dependencies;
} }
} }
...@@ -68,6 +68,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { ...@@ -68,6 +68,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
'id' => "entity:$entity_type", 'id' => "entity:$entity_type",
'class' => $class, 'class' => $class,
'requirements_met' => 1, 'requirements_met' => 1,
'provider' => $entity_info->getProvider(),
); );
} }
return $this->derivatives; return $this->derivatives;
......
...@@ -66,6 +66,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { ...@@ -66,6 +66,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
'id' => "entity_revision:$entity_type", 'id' => "entity_revision:$entity_type",
'class' => 'Drupal\migrate\Plugin\migrate\destination\EntityRevision', 'class' => 'Drupal\migrate\Plugin\migrate\destination\EntityRevision',
'requirements_met' => 1, 'requirements_met' => 1,
'provider' => $entity_info->getProvider(),
); );
} }
} }
......
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
namespace Drupal\migrate\Plugin\migrate\destination; namespace Drupal\migrate\Plugin\migrate\destination;
use Drupal\Component\Plugin\DependentPluginInterface;
use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\DependencyTrait;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\Entity\MigrationInterface; use Drupal\migrate\Entity\MigrationInterface;
use Drupal\migrate\MigrateException; use Drupal\migrate\MigrateException;
...@@ -24,7 +26,8 @@ ...@@ -24,7 +26,8 @@
* id = "config" * id = "config"
* ) * )
*/ */
class Config extends DestinationBase implements ContainerFactoryPluginInterface { class Config extends DestinationBase implements ContainerFactoryPluginInterface, DependentPluginInterface {
use DependencyTrait;
/** /**
* The config object. * The config object.
...@@ -104,4 +107,13 @@ public function getIds() { ...@@ -104,4 +107,13 @@ public function getIds() {
return array(); return array();
} }
/**
* {@inheritdoc}
*/
public function calculateDependencies() {
$provider = explode('.', $this->config->getName(), 2)[0];
$this->addDependency('module', $provider);
return $this->dependencies;
}
} }
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
namespace Drupal\migrate\Plugin\migrate\destination; namespace Drupal\migrate\Plugin\migrate\destination;
use Drupal\Component\Plugin\DependentPluginInterface;
use Drupal\Core\Entity\DependencyTrait;
use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\Entity\MigrationInterface; use Drupal\migrate\Entity\MigrationInterface;
...@@ -19,7 +21,8 @@ ...@@ -19,7 +21,8 @@
* deriver = "Drupal\migrate\Plugin\Derivative\MigrateEntity" * deriver = "Drupal\migrate\Plugin\Derivative\MigrateEntity"
* ) * )
*/ */
abstract class Entity extends DestinationBase implements ContainerFactoryPluginInterface { abstract class Entity extends DestinationBase implements ContainerFactoryPluginInterface, DependentPluginInterface {
use DependencyTrait;
/** /**
* The entity storage. * The entity storage.
...@@ -80,7 +83,6 @@ public static function create(ContainerInterface $container, array $configuratio ...@@ -80,7 +83,6 @@ public static function create(ContainerInterface $container, array $configuratio
* *
* @return string * @return string
* The entity type. * The entity type.
* @throws \Drupal\migrate\MigrateException
*/ */
protected static function getEntityTypeId($plugin_id) { protected static function getEntityTypeId($plugin_id) {
// Remove "entity:" // Remove "entity:"
...@@ -169,4 +171,12 @@ protected function getKey($key) { ...@@ -169,4 +171,12 @@ protected function getKey($key) {
return $this->storage->getEntityType()->getKey($key); return $this->storage->getEntityType()->getKey($key);
} }
/**
* {@inheritdoc}
*/
public function calculateDependencies() {
$this->addDependency('module', $this->storage->getEntityType()->getProvider());
return $this->dependencies;
}
} }
...@@ -83,7 +83,7 @@ protected function getSource($configuration = [], $migrate_config = [], $status ...@@ -83,7 +83,7 @@ protected function getSource($configuration = [], $migrate_config = [], $status
->willReturn($id_map_array); ->willReturn($id_map_array);
$constructor_args = [$configuration, 'd6_action', [], $this->migration]; $constructor_args = [$configuration, 'd6_action', [], $this->migration];
$methods = ['getModuleHandler', 'fields', 'getIds', '__toString', 'getIterator', 'prepareRow', 'initializeIterator']; $methods = ['getModuleHandler', 'fields', 'getIds', '__toString', 'getIterator', 'prepareRow', 'initializeIterator', 'calculateDependencies'];
$source_plugin = $this->getMock('\Drupal\migrate\Plugin\migrate\source\SourcePluginBase', $methods, $constructor_args); $source_plugin = $this->getMock('\Drupal\migrate\Plugin\migrate\source\SourcePluginBase', $methods, $constructor_args);
$source_plugin $source_plugin
......
...@@ -70,6 +70,7 @@ abstract class MigrateSqlSourceTestCase extends MigrateTestCase { ...@@ -70,6 +70,7 @@ abstract class MigrateSqlSourceTestCase extends MigrateTestCase {
*/ */
protected function setUp() { protected function setUp() {
$module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
$migration = $this->getMigration(); $migration = $this->getMigration();
$migration->expects($this->any()) $migration->expects($this->any())
...@@ -77,7 +78,7 @@ protected function setUp() { ...@@ -77,7 +78,7 @@ protected function setUp() {
->will($this->returnValue(static::ORIGINAL_HIGH_WATER)); ->will($this->returnValue(static::ORIGINAL_HIGH_WATER));
// Need the test class, not the original because we need a setDatabase method. This is not pretty :/ // Need the test class, not the original because we need a setDatabase method. This is not pretty :/
$plugin_class = preg_replace('/^Drupal\\\\(\w+)\\\\Plugin\\\\migrate(\\\\source(\\\\.+)?\\\\)([^\\\\]+)$/', 'Drupal\\Tests\\\$1\\Unit$2Test$4', static::PLUGIN_CLASS); $plugin_class = preg_replace('/^Drupal\\\\(\w+)\\\\Plugin\\\\migrate(\\\\source(\\\\.+)?\\\\)([^\\\\]+)$/', 'Drupal\\Tests\\\$1\\Unit$2Test$4', static::PLUGIN_CLASS);
$plugin = new $plugin_class($this->migrationConfiguration['source'], $this->migrationConfiguration['source']['plugin'], array(), $migration); $plugin = new $plugin_class($this->migrationConfiguration['source'], $this->migrationConfiguration['source']['plugin'], array(), $migration, $entity_manager);
$plugin->setDatabase($this->getDatabase($this->databaseContents + array('test_map' => array()))); $plugin->setDatabase($this->getDatabase($this->databaseContents + array('test_map' => array())));
$plugin->setModuleHandler($module_handler); $plugin->setModuleHandler($module_handler);
$plugin->setStringTranslation($this->getStringTranslationStub()); $plugin->setStringTranslation($this->getStringTranslationStub());
......
...@@ -167,4 +167,11 @@ public function fields() {} ...@@ -167,4 +167,11 @@ public function fields() {}
*/ */
public function query() {} public function query() {}
/**
* {@inheritdoc}
*/
public function calculateDependencies() {
return [];
}
} }
...@@ -11,3 +11,7 @@ process: ...@@ -11,3 +11,7 @@ process:
destination: destination:
plugin: config plugin: config
config_name: action.settings config_name: action.settings
dependencies:
module:
- action
- migrate_drupal
...@@ -19,3 +19,7 @@ process: ...@@ -19,3 +19,7 @@ process:
destination: destination:
plugin: entity:aggregator_feed plugin: entity:aggregator_feed
dependencies:
module:
- aggregator
- migrate_drupal
...@@ -22,3 +22,9 @@ destination: ...@@ -22,3 +22,9 @@ destination:
migration_dependencies: migration_dependencies:
required: required:
- d6_aggregator_feed - d6_aggregator_feed
dependencies:
config:
- migrate.migration.d6_aggregator_feed
module:
- aggregator
- migrate_drupal
...@@ -23,3 +23,7 @@ process: ...@@ -23,3 +23,7 @@ process:
destination: destination:
plugin: config plugin: config
config_name: aggregator.settings config_name: aggregator.settings
dependencies:
module:
- aggregator
- migrate_drupal
...@@ -91,3 +91,11 @@ migration_dependencies: ...@@ -91,3 +91,11 @@ migration_dependencies:
- d6_menu - d6_menu
- d6_custom_block - d6_custom_block
- d6_user_role - d6_user_role
dependencies:
config:
- migrate.migration.d6_custom_block
- migrate.migration.d6_menu
- migrate.migration.d6_user_role
module:
- block
- migrate_drupal
...@@ -5,7 +5,7 @@ migration_tags: ...@@ -5,7 +5,7 @@ migration_tags:
source: source:
# We do an empty source and a proper destination to have an idmap for # We do an empty source and a proper destination to have an idmap for
# migration_dependencies. # migration_dependencies.
plugin: empty plugin: md_empty
constants: constants:
entity_type: block_content entity_type: block_content
bundle: basic bundle: basic
...@@ -23,3 +23,10 @@ destination: ...@@ -23,3 +23,10 @@ destination:
migration_dependencies: migration_dependencies:
required: required:
- d6_block_content_type - d6_block_content_type
dependencies:
config:
- migrate.migration.d6_block_content_type
module:
- block_content
- field
- migrate_drupal
...@@ -5,7 +5,7 @@ migration_tags: ...@@ -5,7 +5,7 @@ migration_tags:
source: source:
# We do an empty source and a proper destination to have an idmap for # We do an empty source and a proper destination to have an idmap for
# migration_dependencies. # migration_dependencies.
plugin: empty plugin: md_empty
constants: constants:
id: basic id: basic
label: Basic label: Basic
...@@ -14,3 +14,7 @@ process: ...@@ -14,3 +14,7 @@ process:
label: 'constants/label' label: 'constants/label'
destination: destination:
plugin: entity:block_content_type plugin: entity:block_content_type
dependencies:
module:
- block_content
- migrate_drupal
...@@ -20,3 +20,10 @@ destination: ...@@ -20,3 +20,10 @@ destination:
migration_dependencies: migration_dependencies:
required: required:
- d6_node - d6_node
dependencies:
config:
- migrate.migration.d6_node
module:
- book
- migrate_drupal
- node
...@@ -15,3 +15,7 @@ process: ...@@ -15,3 +15,7 @@ process:
destination: destination:
plugin: config plugin: config
config_name: book.settings config_name: book.settings
dependencies:
module:
- book
- migrate_drupal
...@@ -15,3 +15,10 @@ migration_dependencies: ...@@ -15,3 +15,10 @@ migration_dependencies:
required: required:
- d6_cck_field_values - d6_cck_field_values
- d6_node_revision - d6_node_revision
dependencies:
config:
- migrate.migration.d6_cck_field_values
- migrate.migration.d6_node_revision
module:
- migrate_drupal
- node
...@@ -19,3 +19,11 @@ migration_dependencies: ...@@ -19,3 +19,11 @@ migration_dependencies:
- d6_node - d6_node
- d6_field_formatter_settings - d6_field_formatter_settings
- d6_field_instance_widget_settings - d6_field_instance_widget_settings
dependencies:
config:
- migrate.migration.d6_field_formatter_settings
- migrate.migration.d6_field_instance_widget_settings
- migrate.migration.d6_node
module:
- migrate_drupal
- node
...@@ -43,3 +43,15 @@ migration_dependencies: ...@@ -43,3 +43,15 @@ migration_dependencies:
- d6_comment_entity_display - d6_comment_entity_display
- d6_comment_entity_form_display - d6_comment_entity_form_display
- d6_filter_format - d6_filter_format
dependencies:
config:
- migrate.migration.d6_comment_entity_display
- migrate.migration.d6_comment_entity_form_display
- migrate.migration.d6_comment_type
- migrate.migration.d6_filter_format
- migrate.migration.d6_node
- migrate.migration.d6_user
module:
- comment
- migrate_drupal
- node
...@@ -24,3 +24,9 @@ destination: ...@@ -24,3 +24,9 @@ destination:
migration_dependencies: migration_dependencies:
required: required:
- d6_comment_field_instance - d6_comment_field_instance
dependencies:
config:
- migrate.migration.d6_comment_field_instance
module:
- migrate_drupal
- node
...@@ -23,3 +23,9 @@ destination: ...@@ -23,3 +23,9 @@ destination:
migration_dependencies: migration_dependencies:
required: required:
- d6_comment_field_instance - d6_comment_field_instance
dependencies:
config:
- migrate.migration.d6_comment_field_instance
module:
- migrate_drupal
- node
...@@ -30,3 +30,9 @@ destination: ...@@ -30,3 +30,9 @@ destination:
migration_dependencies: migration_dependencies:
required: required:
- d6_comment_type - d6_comment_type
dependencies:
config:
- migrate.migration.d6_comment_type
module:
- comment
- migrate_drupal
...@@ -13,7 +13,15 @@ process: ...@@ -13,7 +13,15 @@ process:
type: 'constants/type' type: 'constants/type'
'settings/comment_type': comment_type 'settings/comment_type': comment_type
destination: destination:
plugin: entity:field_storage_config plugin: md_entity:field_storage_config
migration_dependencies: migration_dependencies:
required: required:
- d6_comment_type - d6_comment_type
dependencies:
config:
- migrate.migration.d6_comment_type
module:
- comment
- field
- migrate_drupal
- node
...@@ -32,3 +32,11 @@ migration_dependencies: ...@@ -32,3 +32,11 @@ migration_dependencies:
required: required:
- d6_comment_field - d6_comment_field
- d6_node_type - d6_node_type
dependencies:
config:
- migrate.migration.d6_comment_field
- migrate.migration.d6_node_type
module:
- field