Update Composer, update everything

This commit is contained in:
Oliver Davies 2018-11-23 12:29:20 +00:00
parent ea3e94409f
commit dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions

View file

@ -2,9 +2,7 @@
namespace Drupal\migrate_drupal\Annotation;
@trigger_error('MigrateCckField is deprecated in Drupal 8.3.x and will be
removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateField
instead.', E_USER_DEPRECATED);
@trigger_error('MigrateCckField is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateField instead.', E_USER_DEPRECATED);
/**
* Deprecated: Defines a cckfield plugin annotation object.
@ -14,6 +12,8 @@ instead.', E_USER_DEPRECATED);
*
* Plugin Namespace: Plugin\migrate\cckfield
*
* @see https://www.drupal.org/node/2751897
*
* @Annotation
*/
class MigrateCckField extends MigrateField {

View file

@ -49,6 +49,26 @@ class MigrateField extends Plugin {
*
* @var int[]
*/
public $core = [];
public $core;
/**
* Identifies the system providing the data the field plugin will read.
*
* The source_module is expected to be the name of a Drupal module that must
* be installed in the source database.
*
* @var string
*/
public $source_module;
/**
* Identifies the system handling the data the destination plugin will write.
*
* The destination_module is expected to be the name of a Drupal module on the
* destination site that must be installed.
*
* @var string
*/
public $destination_module;
}

View file

@ -0,0 +1,26 @@
<?php
namespace Drupal\migrate_drupal;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
use Symfony\Component\DependencyInjection\Reference;
/**
* Alters container services.
*/
class MigrateDrupalServiceProvider extends ServiceProviderBase {
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
parent::alter($container);
$container->getDefinition('plugin.manager.migration')
->setClass(MigrationPluginManager::class)
->addArgument(new Reference('plugin.manager.migrate.source'))
->addArgument(new Reference('config.factory'));
}
}

View file

@ -12,6 +12,13 @@ use Drupal\migrate\Plugin\RequirementsInterface;
*/
trait MigrationConfigurationTrait {
/**
* The follow-up migration tags.
*
* @var string[]
*/
protected $followUpMigrationTags;
/**
* Gets the database connection for the source Drupal database.
*
@ -96,6 +103,19 @@ trait MigrationConfigurationTrait {
$all_migrations = $plugin_manager->createInstancesByTag($version_tag);
$migrations = [];
foreach ($all_migrations as $migration) {
// Skip migrations tagged with any of the follow-up migration tags. They
// will be derived and executed after the migrations on which they depend
// have been successfully executed.
// @see Drupal\migrate_drupal\Plugin\MigrationWithFollowUpInterface
if (!empty(array_intersect($migration->getMigrationTags(), $this->getFollowUpMigrationTags()))) {
continue;
}
// Multilingual migrations require migrate_drupal_multilingual.
$tags = $migration->getMigrationTags() ?: [];
if (in_array('Multilingual', $tags, TRUE) && (!\Drupal::service('module_handler')->moduleExists('migrate_drupal_multilingual'))) {
throw new RequirementsException(sprintf("Install migrate_drupal_multilingual to run migration '%s'.", $migration->getPluginId()));
}
try {
// @todo https://drupal.org/node/2681867 We should be able to validate
// the entire migration at this point.
@ -119,14 +139,28 @@ trait MigrationConfigurationTrait {
return $migrations;
}
/**
* Returns the follow-up migration tags.
*
* @return string[]
*/
protected function getFollowUpMigrationTags() {
if ($this->followUpMigrationTags === NULL) {
$this->followUpMigrationTags = \Drupal::configFactory()
->get('migrate_drupal.settings')
->get('follow_up_migration_tags') ?: [];
}
return $this->followUpMigrationTags;
}
/**
* Determines what version of Drupal the source database contains.
*
* @param \Drupal\Core\Database\Connection $connection
* The database connection object.
*
* @return int|false
* An integer representing the major branch of Drupal core (e.g. '6' for
* @return string|false
* A string representing the major branch of Drupal core (e.g. '6' for
* Drupal 6.x), or FALSE if no valid version is matched.
*/
protected function getLegacyDrupalVersion(Connection $connection) {

View file

@ -2,10 +2,11 @@
namespace Drupal\migrate_drupal;
/**
* @deprecated in Drupal 8.1.x, will be removed before Drupal 9.0.0. Use
* \Drupal\migrate_drupal\MigrationConfigurationTrait instead.
*
* @see https://www.drupal.org/node/2873794
*/
trait MigrationCreationTrait {
use MigrationConfigurationTrait;

View file

@ -0,0 +1,109 @@
<?php
namespace Drupal\migrate_drupal;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\migrate\Plugin\Exception\BadPluginDefinitionException;
use Drupal\migrate\Plugin\MigrateSourcePluginManager;
use Drupal\migrate\Plugin\MigrationPluginManager as BaseMigrationPluginManager;
/**
* Manages migration plugins.
*
* Analyzes migration definitions to ensure that the source plugin of any
* migration tagged with particular tags ('Drupal 6' or 'Drupal 7' by default)
* defines a source_module property in its plugin annotation. This is done in
* order to support the Migrate Drupal UI, which needs to know which modules
* "own" the data being migrated into Drupal 8, on both the source and
* destination sides.
*
* @todo Enforce the destination_module property too, in
* https://www.drupal.org/project/drupal/issues/2923810.
*/
class MigrationPluginManager extends BaseMigrationPluginManager {
/**
* The Migrate source plugin manager service.
*
* @var \Drupal\migrate\Plugin\MigrateSourcePluginManager
*/
protected $sourceManager;
/**
* The config factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The migration tags which will trigger source_module enforcement.
*
* @var string[]
*/
protected $enforcedSourceModuleTags;
/**
* MigrationPluginManager constructor.
*
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
* The cache backend.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager service.
* @param \Drupal\migrate\Plugin\MigrateSourcePluginManager $source_manager
* The Migrate source plugin manager service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory service.
*/
public function __construct(ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager, MigrateSourcePluginManager $source_manager, ConfigFactoryInterface $config_factory) {
parent::__construct($module_handler, $cache_backend, $language_manager);
$this->sourceManager = $source_manager;
$this->configFactory = $config_factory;
}
/**
* Returns the migration tags that trigger source_module enforcement.
*
* @return string[]
*/
protected function getEnforcedSourceModuleTags() {
if ($this->enforcedSourceModuleTags === NULL) {
$this->enforcedSourceModuleTags = $this->configFactory
->get('migrate_drupal.settings')
->get('enforce_source_module_tags') ?: [];
}
return $this->enforcedSourceModuleTags;
}
/**
* {@inheritdoc}
*/
public function processDefinition(&$definition, $plugin_id) {
parent::processDefinition($definition, $plugin_id);
// If the migration has no tags, we don't need to enforce the source_module
// annotation property.
if (empty($definition['migration_tags'])) {
return;
}
// Check if the migration has any of the tags that trigger source_module
// enforcement.
$applied_tags = array_intersect($this->getEnforcedSourceModuleTags(), $definition['migration_tags']);
if ($applied_tags) {
// Throw an exception if the source plugin definition does not define a
// source_module.
$source_id = $definition['source']['plugin'];
$source_definition = $this->sourceManager->getDefinition($source_id);
if (empty($source_definition['source_module'])) {
throw new BadPluginDefinitionException($source_id, 'source_module');
}
}
}
}

View file

@ -2,9 +2,7 @@
namespace Drupal\migrate_drupal\Plugin;
@trigger_error('MigrateCckFieldInterface is deprecated in Drupal 8.3.x and will
be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateField
instead.', E_USER_DEPRECATED);
@trigger_error('MigrateCckFieldInterface is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateField instead.', E_USER_DEPRECATED);
use Drupal\migrate\Plugin\MigrationInterface;
@ -13,6 +11,8 @@ use Drupal\migrate\Plugin\MigrationInterface;
*
* @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
* \Drupal\migrate_drupal\Annotation\MigrateField instead.
*
* @see https://www.drupal.org/node/2751897
*/
interface MigrateCckFieldInterface extends MigrateFieldInterface {

View file

@ -2,9 +2,7 @@
namespace Drupal\migrate_drupal\Plugin;
@trigger_error('MigrateCckFieldPluginManager is deprecated in Drupal 8.3.x and will
be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManager
instead.', E_USER_DEPRECATED);
@trigger_error('MigrateCckFieldPluginManager is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManager instead.', E_USER_DEPRECATED);
/**
* Deprecated: Plugin manager for migrate field plugins.
@ -12,6 +10,8 @@ instead.', E_USER_DEPRECATED);
* @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
* \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManager instead.
*
* @see https://www.drupal.org/node/2751897
*
* @ingroup migration
*/
class MigrateCckFieldPluginManager extends MigrateFieldPluginManager implements MigrateCckFieldPluginManagerInterface { }
class MigrateCckFieldPluginManager extends MigrateFieldPluginManager implements MigrateCckFieldPluginManagerInterface {}

View file

@ -2,14 +2,14 @@
namespace Drupal\migrate_drupal\Plugin;
@trigger_error('MigrateCckFieldPluginManagerInterface is deprecated in Drupal 8.3.x
and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManagerInterface
instead.', E_USER_DEPRECATED);
@trigger_error('MigrateCckFieldPluginManagerInterface is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManagerInterface instead.', E_USER_DEPRECATED);
/**
* Provides an interface for cck field plugin manager.
*
* @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
* \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface instead.
*
* @see https://www.drupal.org/node/2751897
*/
interface MigrateCckFieldPluginManagerInterface extends MigrateFieldPluginManagerInterface { }
interface MigrateCckFieldPluginManagerInterface extends MigrateFieldPluginManagerInterface {}

View file

@ -17,7 +17,7 @@ interface MigrateFieldInterface extends PluginInspectionInterface {
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
* The migration entity.
*/
public function processField(MigrationInterface $migration);
public function alterFieldMigration(MigrationInterface $migration);
/**
* Apply any custom processing to the field instance migration.
@ -25,7 +25,7 @@ interface MigrateFieldInterface extends PluginInspectionInterface {
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
* The migration entity.
*/
public function processFieldInstance(MigrationInterface $migration);
public function alterFieldInstanceMigration(MigrationInterface $migration);
/**
* Apply any custom processing to the field widget migration.
@ -33,7 +33,7 @@ interface MigrateFieldInterface extends PluginInspectionInterface {
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
* The migration entity.
*/
public function processFieldWidget(MigrationInterface $migration);
public function alterFieldWidgetMigration(MigrationInterface $migration);
/**
* Apply any custom processing to the field formatter migration.
@ -41,18 +41,40 @@ interface MigrateFieldInterface extends PluginInspectionInterface {
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
* The migration entity.
*/
public function processFieldFormatter(MigrationInterface $migration);
public function alterFieldFormatterMigration(MigrationInterface $migration);
/**
* Get the field formatter type from the source.
*
* @param \Drupal\migrate\Row $row
* The field being migrated.
*
* @return string
* The field formatter type.
*/
public function getFieldFormatterType(Row $row);
/**
* Get a map between D6 formatters and D8 formatters for this field type.
*
* This is used by static::processFieldFormatter() in the base class.
* This is used by static::alterFieldFormatterMigration() in the base class.
*
* @return array
* The keys are D6 formatters and the values are D8 formatters.
*/
public function getFieldFormatterMap();
/**
* Get the field widget type from the source.
*
* @param \Drupal\migrate\Row $row
* The field being migrated.
*
* @return string
* The field widget type.
*/
public function getFieldWidgetType(Row $row);
/**
* Get a map between D6 and D8 widgets for this field type.
*
@ -71,7 +93,7 @@ interface MigrateFieldInterface extends PluginInspectionInterface {
* @param array $data
* The array of field data from FieldValues::fieldData().
*/
public function processFieldValues(MigrationInterface $migration, $field_name, $data);
public function defineValueProcessPipeline(MigrationInterface $migration, $field_name, $data);
/**
* Computes the destination type of a migrated field.

View file

@ -3,11 +3,12 @@
namespace Drupal\migrate_drupal\Plugin;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\migrate\Plugin\Exception\BadPluginDefinitionException;
use Drupal\migrate\Plugin\MigratePluginManager;
use Drupal\migrate\Plugin\MigrationInterface;
/**
* Plugin manager for migrate cckfield plugins.
* Plugin manager for migrate field plugins.
*
* @see \Drupal\migrate_drupal\Plugin\MigrateFieldInterface
* @see \Drupal\migrate\Annotation\MigrateField
@ -53,4 +54,17 @@ class MigrateFieldPluginManager extends MigratePluginManager implements MigrateF
throw new PluginNotFoundException($field_type);
}
/**
* {@inheritdoc}
*/
public function processDefinition(&$definition, $plugin_id) {
parent::processDefinition($definition, $plugin_id);
foreach (['core', 'source_module', 'destination_module'] as $required_property) {
if (empty($definition[$required_property])) {
throw new BadPluginDefinitionException($plugin_id, $required_property);
}
}
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace Drupal\migrate_drupal\Plugin;
/**
* Interface for migrations with follow-up migrations.
*
* Some migrations need to be derived and executed after other migrations have
* been successfully executed. For example, a migration might need to be derived
* based on previously migrated data. For such a case, the migration dependency
* system is not enough since all migrations would still be derived before any
* one of them has been executed.
*
* Those "follow-up" migrations need to be tagged with the "Follow-up migration"
* tag (or any tag in the "follow_up_migration_tags" configuration) and thus
* they won't be derived with the other migrations.
*
* To get those follow-up migrations derived at the right time, the migrations
* on which they depend must implement this interface and generate them in the
* generateFollowUpMigrations() method.
*
* When the migrations implementing this interface have been successfully
* executed, the follow-up migrations will then be derived having access to the
* now migrated data.
*/
interface MigrationWithFollowUpInterface {
/**
* Generates follow-up migrations.
*
* When the migration implementing this interface has been successfully
* executed, this method will be used to generate the follow-up migrations
* which depends on the now migrated data.
*
* @return \Drupal\migrate\Plugin\MigrationInterface[]
* The follow-up migrations.
*/
public function generateFollowUpMigrations();
}

View file

@ -2,15 +2,15 @@
namespace Drupal\migrate_drupal\Plugin\migrate;
@trigger_error('CckMigration is deprecated in Drupal 8.3.x and will be removed
before Drupal 9.0.x. Use \Drupal\migrate_drupal\Plugin\migrate\FieldMigration
instead.', E_USER_DEPRECATED);
@trigger_error('CckMigration is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Plugin\migrate\FieldMigration instead.', E_USER_DEPRECATED);
/**
* Migration plugin class for migrations dealing with CCK field values.
*
* @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
* \Drupal\migrate_drupal\Plugin\migrate\FieldMigration instead.
*
* @see https://www.drupal.org/node/2751897
*/
class CckMigration extends FieldMigration {

View file

@ -0,0 +1,193 @@
<?php
namespace Drupal\migrate_drupal\Plugin\migrate;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Component\Plugin\PluginBase;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Deriver for entity reference field translations.
*
* A migration will be created for every bundle with at least one entity
* reference field that is configured to point to one of the supported target
* entity types. The migrations will update the entity reference fields with
* values found in the mapping tables of the migrations associated with the
* target types.
*
* Example:
*
* @code
* id: d7_entity_reference_translation
* label: Entity reference translations
* migration_tags:
* - Drupal 7
* - Follow-up migration
* deriver: Drupal\migrate_drupal\Plugin\migrate\EntityReferenceTranslationDeriver
* target_types:
* node:
* - d7_node_translation
* source:
* plugin: empty
* key: default
* target: default
* process: []
* destination:
* plugin: null
* @endcode
*
* In this example, the only supported target type is 'node' and the associated
* migration for the mapping table lookup is 'd7_node_translation'.
*/
class EntityReferenceTranslationDeriver extends DeriverBase implements ContainerDeriverInterface {
use StringTranslationTrait;
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* EntityReferenceTranslationDeriver constructor.
*
* @param string $base_plugin_id
* The base plugin ID.
* @param \Drupal\core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager.
* @param \Drupal\core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct($base_plugin_id, EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_type_manager) {
$this->entityFieldManager = $entity_field_manager;
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $base_plugin_id) {
return new static(
$base_plugin_id,
$container->get('entity_field.manager'),
$container->get('entity_type.manager')
);
}
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
// Get all entity reference fields.
$field_map = $this->entityFieldManager->getFieldMapByFieldType('entity_reference');
foreach ($field_map as $entity_type => $fields) {
foreach ($fields as $field_name => $field) {
foreach ($field['bundles'] as $bundle) {
$field_definitions = $this->entityFieldManager->getFieldDefinitions($entity_type, $bundle);
$target_type = $field_definitions[$field_name]->getSetting('target_type');
// If the field's target type is not supported, skip it.
if (!array_key_exists($target_type, $base_plugin_definition['target_types'])) {
continue;
}
// Key derivatives by entity types and bundles.
$derivative_key = $entity_type . '__' . $bundle;
$derivative = $base_plugin_definition;
$entity_type_definition = $this->entityTypeManager->getDefinition($entity_type);
// Set the migration label.
$derivative['label'] = $this->t('@label (@derivative)', [
'@label' => $base_plugin_definition['label'],
'@derivative' => $derivative_key,
]);
// Set the source plugin.
$derivative['source']['plugin'] = 'content_entity' . PluginBase::DERIVATIVE_SEPARATOR . $entity_type;
if ($entity_type_definition->hasKey('bundle')) {
$derivative['source']['bundle'] = $bundle;
}
// Set the process pipeline.
$id_key = $entity_type_definition->getKey('id');
$derivative['process'][$id_key] = $id_key;
if ($entity_type_definition->isRevisionable()) {
$revision_key = $entity_type_definition->getKey('revision');
$derivative['process'][$revision_key] = $revision_key;
}
if ($entity_type_definition->isTranslatable()) {
$langcode_key = $entity_type_definition->getKey('langcode');
$derivative['process'][$langcode_key] = $langcode_key;
}
// Set the destination plugin.
$derivative['destination']['plugin'] = 'entity' . PluginBase::DERIVATIVE_SEPARATOR . $entity_type;
if ($entity_type_definition->hasKey('bundle')) {
$derivative['destination']['default_bundle'] = $bundle;
}
if ($entity_type_definition->isTranslatable()) {
$derivative['destination']['translations'] = TRUE;
}
// Allow overwriting the entity reference field so we can update its
// values with the ones found in the mapping table.
$derivative['destination']['overwrite_properties'][$field_name] = $field_name;
// Add the entity reference field to the process pipeline.
$derivative['process'][$field_name] = [
'plugin' => 'sub_process',
'source' => $field_name,
'process' => [
'target_id' => [
[
'plugin' => 'migration_lookup',
'source' => 'target_id',
'migration' => $base_plugin_definition['target_types'][$target_type],
'no_stub' => TRUE,
],
[
'plugin' => 'skip_on_empty',
'method' => 'row',
],
[
'plugin' => 'extract',
'index' => [0],
],
],
],
];
if (!isset($this->derivatives[$derivative_key])) {
// If this is a new derivative, add it to the returned derivatives.
$this->derivatives[$derivative_key] = $derivative;
}
else {
// If this is an existing derivative, it means this bundle has more
// than one entity reference field. In that case, we only want to add
// the field to the process pipeline and make it overwritable.
$this->derivatives[$derivative_key]['process'] += $derivative['process'];
$this->derivatives[$derivative_key]['destination']['overwrite_properties'] += $derivative['destination']['overwrite_properties'];
}
}
}
}
return $this->derivatives;
}
}

View file

@ -140,25 +140,25 @@ class FieldMigration extends Migration implements ContainerFactoryPluginInterfac
$field_type = $row->getSourceProperty('type');
try {
$plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, [], $this);
$Manager = $this->cckPluginManager;
$plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, [], $this);
$manager = $this->fieldPluginManager;
}
catch (PluginNotFoundException $ex) {
try {
$plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, [], $this);
$Manager = $this->fieldPluginManager;
$plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, [], $this);
$manager = $this->cckPluginManager;
}
catch (PluginNotFoundException $ex) {
continue;
}
}
if (!isset($this->processedFieldTypes[$field_type]) && $Manager->hasDefinition($plugin_id)) {
if (!isset($this->processedFieldTypes[$field_type]) && $manager->hasDefinition($plugin_id)) {
$this->processedFieldTypes[$field_type] = TRUE;
// Allow the field plugin to alter the migration as necessary so that
// it knows how to handle fields of this type.
if (!isset($this->fieldPluginCache[$field_type])) {
$this->fieldPluginCache[$field_type] = $Manager->createInstance($plugin_id, [], $this);
$this->fieldPluginCache[$field_type] = $manager->createInstance($plugin_id, [], $this);
}
}
$method = $this->pluginDefinition[static::PLUGIN_METHOD];

View file

@ -2,34 +2,28 @@
namespace Drupal\migrate_drupal\Plugin\migrate\cckfield;
@trigger_error('CckFieldPluginBase is deprecated in Drupal 8.3.x and will be
be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase
instead.', E_USER_DEPRECATED);
@trigger_error('CckFieldPluginBase is deprecated in Drupal 8.3.x and will be be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase instead.', E_USER_DEPRECATED);
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase;
use Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface;
/**
* The base class for all field plugins.
*
* @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
* @deprecated in Drupal 8.4.x, to be removed before Drupal 9.0.x. Use
* \Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase instead.
*
* @see https://www.drupal.org/node/2751897
*
* @ingroup migration
*/
abstract class CckFieldPluginBase extends FieldPluginBase {
abstract class CckFieldPluginBase extends FieldPluginBase implements MigrateCckFieldInterface {
/**
* Apply any custom processing to the field bundle migrations.
*
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
* The migration entity.
* @param string $field_name
* The field name we're processing the value for.
* @param array $data
* The array of field data from FieldValues::fieldData().
* {@inheritdoc}
*/
public function processFieldValues(MigrationInterface $migration, $field_name, $data) {
public function defineValueProcessPipeline(MigrationInterface $migration, $field_name, $data) {
// Provide a bridge to the old method declared on the interface and now an
// abstract method in this class.
return $this->processCckFieldValues($migration, $field_name, $data);

View file

@ -43,16 +43,16 @@ class EntityFieldStorageConfig extends BaseEntityFieldStorageConfig {
* The plugin implementation definition.
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
* The migration.
* @param EntityStorageInterface $storage
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The storage for this entity type.
* @param array $bundles
* The list of bundles this entity type has.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
* @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_plugin_manager
* The field type plugin manager.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The configuration factory.
* @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_plugin_manager
* The field type plugin manager.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, LanguageManagerInterface $language_manager, ConfigFactoryInterface $config_factory, FieldTypePluginManagerInterface $field_type_plugin_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $language_manager, $config_factory, $field_type_plugin_manager);

View file

@ -20,24 +20,66 @@ use Drupal\migrate_drupal\Plugin\MigrateFieldInterface;
abstract class FieldPluginBase extends PluginBase implements MigrateFieldInterface {
/**
* {@inheritdoc}
* Alters the migration for field definitions.
*
* @deprecated in Drupal 8.6.0, to be removed before Drupal 9.0.0. Use
* alterFieldMigration() instead.
*
* @see https://www.drupal.org/node/2944598
* @see ::alterFieldMigration()
*/
public function processField(MigrationInterface $migration) {
@trigger_error('Deprecated in Drupal 8.6.0, to be removed before Drupal 9.0.0. Use alterFieldMigration() instead. See https://www.drupal.org/node/2944598.', E_USER_DEPRECATED);
$this->alterFieldMigration($migration);
}
/**
* {@inheritdoc}
*/
public function alterFieldMigration(MigrationInterface $migration) {
$process[0]['map'][$this->pluginId][$this->pluginId] = $this->pluginId;
$migration->mergeProcessOfProperty('type', $process);
}
/**
* {@inheritdoc}
* Alert field instance migration.
*
* @deprecated in Drupal 8.6.0, to be removed before Drupal 9.0.0. Use
* alterFieldInstanceMigration() instead.
*
* @see https://www.drupal.org/node/2944598
* @see ::alterFieldInstanceMigration()
*/
public function processFieldInstance(MigrationInterface $migration) {
// Nothing to do by default with field instances.
@trigger_error('Deprecated in Drupal 8.6.0, to be removed before Drupal 9.0.0. Use alterFieldInstanceMigration() instead. See https://www.drupal.org/node/2944598.', E_USER_DEPRECATED);
$this->alterFieldInstanceMigration($migration);
}
/**
* {@inheritdoc}
*/
public function alterFieldInstanceMigration(MigrationInterface $migration) {
// Nothing to do by default with field instances.
}
/**
* Alter field widget migration.
*
* @deprecated in Drupal 8.6.0, to be removed before Drupal 9.0.0. Use
* alterFieldWidgetMigration() instead.
*
* @see https://www.drupal.org/node/2944598
* @see ::alterFieldWidgetMigration()
*/
public function processFieldWidget(MigrationInterface $migration) {
@trigger_error('Deprecated in Drupal 8.6.0, to be removed before Drupal 9.0.0. Use alterFieldWidgetMigration() instead. See https://www.drupal.org/node/2944598.', E_USER_DEPRECATED);
$this->alterFieldWidgetMigration($migration);
}
/**
* {@inheritdoc}
*/
public function alterFieldWidgetMigration(MigrationInterface $migration) {
$process = [];
foreach ($this->getFieldWidgetMap() as $source_widget => $destination_widget) {
$process['type']['map'][$source_widget] = $destination_widget;
@ -45,6 +87,27 @@ abstract class FieldPluginBase extends PluginBase implements MigrateFieldInterfa
$migration->mergeProcessOfProperty('options/type', $process);
}
/**
* {@inheritdoc}
*/
public function getFieldFormatterType(Row $row) {
return $row->getSourceProperty('formatter/type');
}
/**
* {@inheritdoc}
*/
public function getFieldFormatterMap() {
return [];
}
/**
* {@inheritdoc}
*/
public function getFieldWidgetType(Row $row) {
return $row->getSourceProperty('widget/type');
}
/**
* {@inheritdoc}
*/
@ -56,16 +119,59 @@ abstract class FieldPluginBase extends PluginBase implements MigrateFieldInterfa
}
/**
* {@inheritdoc}
* Alter field formatter migration.
*
* @deprecated in Drupal 8.6.0, to be removed before Drupal 9.0.0. Use
* alterFieldFormatterMigration() instead.
*
* @see https://www.drupal.org/node/2944598
* @see ::processFieldFormatter()
*/
public function processFieldFormatter(MigrationInterface $migration) {
@trigger_error('Deprecated in Drupal 8.6.0, to be removed before Drupal 9.0.0. Use alterFieldFormatterMigration() instead. See https://www.drupal.org/node/2944598.', E_USER_DEPRECATED);
$this->alterFieldFormatterMigration($migration);
}
/**
* {@inheritdoc}
*/
public function alterFieldFormatterMigration(MigrationInterface $migration) {
$process = [];
// Some migrate field plugin IDs are prefixed with 'd6_' or 'd7_'. Since the
// plugin ID is used in the static map as the module name, we have to remove
// this prefix from the plugin ID.
$plugin_id = preg_replace('/d[67]_/', '', $this->pluginId);
foreach ($this->getFieldFormatterMap() as $source_format => $destination_format) {
$process[0]['map'][$this->pluginId][$source_format] = $destination_format;
$process[0]['map'][$plugin_id][$source_format] = $destination_format;
}
$migration->mergeProcessOfProperty('options/type', $process);
}
/**
* Defines the process pipeline for field values.
*
* @deprecated in Drupal 8.6.0, to be removed before Drupal 9.0.0. Use
* defineValueProcessPipeline() instead.
*
* @see https://www.drupal.org/node/2944598
* @see ::defineValueProcessPipeline()
*/
public function processFieldValues(MigrationInterface $migration, $field_name, $data) {
@trigger_error('Deprecated in Drupal 8.6.0, to be removed before Drupal 9.0.0. Use defineValueProcessPipeline() instead. See https://www.drupal.org/node/2944598.', E_USER_DEPRECATED);
return $this->defineValueProcessPipeline($migration, $field_name, $data);
}
/**
* {@inheritdoc}
*/
public function defineValueProcessPipeline(MigrationInterface $migration, $field_name, $data) {
$process = [
'plugin' => 'get',
'source' => $field_name,
];
$migration->mergeProcessOfProperty($field_name, $process);
}
/**
* {@inheritdoc}
*/

View file

@ -11,6 +11,8 @@ use Drupal\migrate\Plugin\MigrationInterface;
* type_map = {
* "nodereference" = "entity_reference",
* },
* source_module = "nodereference",
* destination_module = "core",
* )
*/
class NodeReference extends FieldPluginBase {
@ -18,21 +20,13 @@ class NodeReference extends FieldPluginBase {
/**
* {@inheritdoc}
*/
public function getFieldFormatterMap() {
return [];
}
/**
* {@inheritdoc}
*/
public function processFieldValues(MigrationInterface $migration, $field_name, $data) {
public function defineValueProcessPipeline(MigrationInterface $migration, $field_name, $data) {
$process = [
'plugin' => 'iterator',
'plugin' => 'sub_process',
'source' => $field_name,
'process' => [
'target_id' => [
'plugin' => 'migration_lookup',
'migration' => 'd6_node',
'plugin' => 'get',
'source' => 'nid',
],
],

View file

@ -0,0 +1,38 @@
<?php
namespace Drupal\migrate_drupal\Plugin\migrate\field;
use Drupal\migrate\Plugin\MigrationInterface;
/**
* @MigrateField(
* id = "userreference",
* core = {6},
* type_map = {
* "userreference" = "entity_reference",
* },
* source_module = "userreference",
* destination_module = "core",
* )
*/
class UserReference extends FieldPluginBase {
/**
* {@inheritdoc}
*/
public function defineValueProcessPipeline(MigrationInterface $migration, $field_name, $data) {
$process = [
'plugin' => 'sub_process',
'source' => $field_name,
'process' => [
'target_id' => [
'plugin' => 'migration_lookup',
'migration' => 'd6_user',
'source' => 'uid',
],
],
];
$migration->setProcessOfProperty($field_name, $process);
}
}

View file

@ -0,0 +1,294 @@
<?php
namespace Drupal\migrate_drupal\Plugin\migrate\source;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\Plugin\migrate\source\SourcePluginBase;
use Drupal\migrate\Plugin\MigrationInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Source plugin to get content entities from the current version of Drupal.
*
* This plugin uses the Entity API to export entity data. If the source entity
* type has custom field storage fields or computed fields, this class will need
* to be extended and the new class will need to load/calculate the values for
* those fields.
*
* Available configuration keys:
* - entity_type: The entity type ID of the entities being exported. This is
* calculated dynamically by the deriver so it is only needed if the deriver
* is not utilized, i.e., a custom source plugin.
* - bundle: (optional) If the entity type is bundleable, only return entities
* of this bundle.
* - include_translations: (optional) Indicates if the entity translations
* should be included, defaults to TRUE.
*
* Examples:
*
* This will return all nodes, from every bundle and every translation. It does
* not return all revisions, just the default one.
* @code
* source:
* plugin: content_entity:node
* @endcode
*
* This will only return nodes of type 'article' in their default language.
* @code
* source:
* plugin: content_entity:node
* bundle: article
* include_translations: false
* @endcode
*
* @MigrateSource(
* id = "content_entity",
* source_module = "migrate_drupal",
* deriver = "\Drupal\migrate_drupal\Plugin\migrate\source\ContentEntityDeriver",
* )
*/
class ContentEntity extends SourcePluginBase implements ContainerFactoryPluginInterface {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* The entity type bundle info service.
*
* @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
*/
protected $entityTypeBundleInfo;
/**
* The entity type definition.
*
* @var \Drupal\Core\Entity\EntityTypeInterface
*/
protected $entityType;
/**
* The plugin's default configuration.
*
* @var array
*/
protected $defaultConfiguration = [
'bundle' => NULL,
'include_translations' => TRUE,
];
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info) {
if (empty($plugin_definition['entity_type'])) {
throw new InvalidPluginDefinitionException($plugin_id, 'Missing required "entity_type" definition.');
}
$this->entityTypeManager = $entity_type_manager;
$this->entityFieldManager = $entity_field_manager;
$this->entityTypeBundleInfo = $entity_type_bundle_info;
$this->entityType = $this->entityTypeManager->getDefinition($plugin_definition['entity_type']);
if (!$this->entityType instanceof ContentEntityTypeInterface) {
throw new InvalidPluginDefinitionException($plugin_id, sprintf('The entity type (%s) is not supported. The "content_entity" source plugin only supports content entities.', $plugin_definition['entity_type']));
}
if (!empty($configuration['bundle'])) {
if (!$this->entityType->hasKey('bundle')) {
throw new \InvalidArgumentException(sprintf('A bundle was provided but the entity type (%s) is not bundleable.', $plugin_definition['entity_type']));
}
$bundle_info = array_keys($this->entityTypeBundleInfo->getBundleInfo($this->entityType->id()));
if (!in_array($configuration['bundle'], $bundle_info, TRUE)) {
throw new \InvalidArgumentException(sprintf('The provided bundle (%s) is not valid for the (%s) entity type.', $configuration['bundle'], $plugin_definition['entity_type']));
}
}
parent::__construct($configuration + $this->defaultConfiguration, $plugin_id, $plugin_definition, $migration);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$migration,
$container->get('entity_type.manager'),
$container->get('entity_field.manager'),
$container->get('entity_type.bundle.info')
);
}
/**
* {@inheritdoc}
*/
public function __toString() {
return (string) $this->entityType->getPluralLabel();
}
/**
* Initializes the iterator with the source data.
*
* @return \Generator
* A data generator for this source.
*/
protected function initializeIterator() {
$ids = $this->query()->execute();
return $this->yieldEntities($ids);
}
/**
* Loads and yields entities, one at a time.
*
* @param array $ids
* The entity IDs.
*
* @return \Generator
* An iterable of the loaded entities.
*/
protected function yieldEntities(array $ids) {
$storage = $this->entityTypeManager
->getStorage($this->entityType->id());
foreach ($ids as $id) {
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$entity = $storage->load($id);
yield $this->toArray($entity);
if ($this->configuration['include_translations']) {
foreach ($entity->getTranslationLanguages(FALSE) as $language) {
yield $this->toArray($entity->getTranslation($language->getId()));
}
}
}
}
/**
* Converts an entity to an array.
*
* Makes all IDs into flat values. All other values are returned as per
* $entity->toArray(), which is a nested array.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity to convert.
*
* @return array
* The entity, represented as an array.
*/
protected function toArray(ContentEntityInterface $entity) {
$return = $entity->toArray();
// This is necessary because the IDs must be flat. They cannot be nested for
// the ID map.
foreach (array_keys($this->getIds()) as $id) {
/** @var \Drupal\Core\TypedData\Plugin\DataType\ItemList $value */
$value = $entity->get($id);
// Force the IDs on top of the previous values.
$return[$id] = $value->first()->getString();
}
return $return;
}
/**
* Query to retrieve the entities.
*
* @return \Drupal\Core\Entity\Query\QueryInterface
* The query.
*/
public function query() {
$query = $this->entityTypeManager
->getStorage($this->entityType->id())
->getQuery()
->accessCheck(FALSE);
if (!empty($this->configuration['bundle'])) {
$query->condition($this->entityType->getKey('bundle'), $this->configuration['bundle']);
}
return $query;
}
/**
* {@inheritdoc}
*/
public function count($refresh = FALSE) {
// If no translations are included, then a simple query is possible.
if (!$this->configuration['include_translations']) {
return parent::count($refresh);
}
// @TODO: Determine a better way to retrieve a valid count for translations.
// https://www.drupal.org/project/drupal/issues/2937166
return -1;
}
/**
* {@inheritdoc}
*/
protected function doCount() {
return $this->query()->count()->execute();
}
/**
* {@inheritdoc}
*/
public function fields() {
// Retrieving fields from a non-fieldable content entity will throw a
// LogicException. Return an empty list of fields instead.
if (!$this->entityType->entityClassImplements('Drupal\Core\Entity\FieldableEntityInterface')) {
return [];
}
$field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($this->entityType->id());
if (!empty($this->configuration['bundle'])) {
$field_definitions += $this->entityFieldManager->getFieldDefinitions($this->entityType->id(), $this->configuration['bundle']);
}
$fields = array_map(function ($definition) {
return (string) $definition->getLabel();
}, $field_definitions);
return $fields;
}
/**
* {@inheritdoc}
*/
public function getIds() {
$id_key = $this->entityType->getKey('id');
$ids[$id_key] = $this->getDefinitionFromEntity($id_key);
if ($this->entityType->isTranslatable()) {
$langcode_key = $this->entityType->getKey('langcode');
$ids[$langcode_key] = $this->getDefinitionFromEntity($langcode_key);
}
return $ids;
}
/**
* Gets the field definition from a specific entity base field.
*
* @param string $key
* The field ID key.
*
* @return array
* An associative array with a structure that contains the field type, keyed
* as 'type', together with field storage settings as they are returned by
* FieldStorageDefinitionInterface::getSettings().
*
* @see \Drupal\migrate\Plugin\migrate\destination\EntityContentBase::getDefinitionFromEntity()
*/
protected function getDefinitionFromEntity($key) {
/** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */
$field_definition = $this->entityFieldManager->getBaseFieldDefinitions($this->entityType->id())[$key];
return [
'type' => $field_definition->getType(),
] + $field_definition->getSettings();
}
}

View file

@ -0,0 +1,60 @@
<?php
namespace Drupal\migrate_drupal\Plugin\migrate\source;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Deriver for content entity source plugins.
*/
class ContentEntityDeriver extends DeriverBase implements ContainerDeriverInterface {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructs a new ContentEntityDeriver.
*
* @param string $base_plugin_id
* The base plugin ID.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
*/
public function __construct($base_plugin_id, EntityTypeManagerInterface $entityTypeManager) {
$this->entityTypeManager = $entityTypeManager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $base_plugin_id) {
return new static(
$base_plugin_id,
$container->get('entity_type.manager')
);
}
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
$this->derivatives = [];
foreach ($this->entityTypeManager->getDefinitions() as $id => $definition) {
if ($definition instanceof ContentEntityTypeInterface) {
$this->derivatives[$id] = $base_plugin_definition;
// Provide entity_type so the source can be used apart from a deriver.
$this->derivatives[$id]['entity_type'] = $id;
}
}
return parent::getDerivativeDefinitions($base_plugin_definition);
}
}

View file

@ -13,10 +13,19 @@ use Drupal\migrate\Plugin\migrate\source\SqlBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* A base source class for Drupal migrate sources.
* A base class for source plugins using a Drupal database as a source.
*
* Mainly to let children retrieve information from the origin system in an
* easier way.
* Provides general purpose helper methods that are commonly needed
* when writing source plugins that use a Drupal database as a source, for
* example:
* - Check if the given module exists in the source database.
* - Read Drupal configuration variables from the source database.
*
* For a full list, refer to the methods of this class.
*
* For available configuration keys, refer to the parent classes:
* @see \Drupal\migrate\Plugin\migrate\source\SqlBase
* @see \Drupal\migrate\Plugin\migrate\source\SourcePluginBase
*/
abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginInterface, DependentPluginInterface {
@ -52,7 +61,7 @@ abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginIn
}
/**
* Retrieves all system data information from origin system.
* Retrieves all system data information from the source Drupal database.
*
* @return array
* List of system table information keyed by type and name.
@ -94,14 +103,14 @@ abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginIn
*/
public function checkRequirements() {
if ($this->pluginDefinition['requirements_met'] === TRUE) {
if (isset($this->pluginDefinition['source_provider'])) {
if ($this->moduleExists($this->pluginDefinition['source_provider'])) {
if (isset($this->pluginDefinition['minimum_schema_version']) && !$this->getModuleSchemaVersion($this->pluginDefinition['source_provider']) < $this->pluginDefinition['minimum_schema_version']) {
if (isset($this->pluginDefinition['source_module'])) {
if ($this->moduleExists($this->pluginDefinition['source_module'])) {
if (isset($this->pluginDefinition['minimum_schema_version']) && !$this->getModuleSchemaVersion($this->pluginDefinition['source_module']) < $this->pluginDefinition['minimum_schema_version']) {
throw new RequirementsException('Required minimum schema version ' . $this->pluginDefinition['minimum_schema_version'], ['minimum_schema_version' => $this->pluginDefinition['minimum_schema_version']]);
}
}
else {
throw new RequirementsException('The module ' . $this->pluginDefinition['source_provider'] . ' is not enabled in the source site.', ['source_provider' => $this->pluginDefinition['source_provider']]);
throw new RequirementsException('The module ' . $this->pluginDefinition['source_module'] . ' is not enabled in the source site.', ['source_module' => $this->pluginDefinition['source_module']]);
}
}
}
@ -109,7 +118,7 @@ abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginIn
}
/**
* Get a module schema_version value in the source installation.
* Retrieves a module schema_version from the source Drupal database.
*
* @param string $module
* Name of module.
@ -124,7 +133,7 @@ abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginIn
}
/**
* Check to see if a given module is enabled in the source installation.
* Checks if a given module is enabled in the source Drupal database.
*
* @param string $module
* Name of module to check.
@ -138,7 +147,7 @@ abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginIn
}
/**
* Read a variable from a Drupal database.
* Reads a variable from a source Drupal database.
*
* @param $name
* Name of the variable.

View file

@ -10,12 +10,12 @@ use Drupal\migrate\Plugin\migrate\source\EmptySource as BaseEmptySource;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
/**
* Source returning an empty row with Drupal specific config dependencies.
*
* @MigrateSource(
* id = "md_empty"
* id = "md_empty",
* source_module = "system",
* )
*/
class EmptySource extends BaseEmptySource implements ContainerFactoryPluginInterface, DependentPluginInterface {

View file

@ -13,7 +13,8 @@ use Drupal\migrate\Plugin\MigrationInterface;
* example for any normal source class returning multiple rows.
*
* @MigrateSource(
* id = "variable"
* id = "variable",
* source_module = "system",
* )
*/
class Variable extends DrupalSqlBase {
@ -58,7 +59,7 @@ class Variable extends DrupalSqlBase {
/**
* {@inheritdoc}
*/
public function count() {
public function count($refresh = FALSE) {
return intval($this->query()->countQuery()->execute()->fetchField() > 0);
}

View file

@ -11,7 +11,8 @@ use Drupal\migrate\Row;
* variable.
*
* @MigrateSource(
* id = "variable_multirow"
* id = "variable_multirow",
* source_module = "system",
* )
*/
class VariableMultiRow extends DrupalSqlBase {

View file

@ -0,0 +1,32 @@
<?php
namespace Drupal\migrate_drupal\Plugin\migrate\source\d6;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\State\StateInterface;
use Drupal\migrate\Plugin\MigrationInterface;
/**
* Gets Drupal i18n_variable source from database.
*
* @deprecated in Drupal 8.7.x and will be removed in Drupal 9.0.x.
* Use \Drupal\migrate_drupal\Plugin\migrate\source\d6\VariableTranslation.
*
* @see https://www.drupal.org/node/3006487
*
* @MigrateSource(
* id = "variable_translation",
* source_module = "system",
* )
*/
class D6VariableTranslation extends VariableTranslation {
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, EntityManagerInterface $entity_manager) {
@trigger_error('The ' . __NAMESPACE__ . '\D6VariableTranslation is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\VariableTranslation. See https://www.drupal.org/node/3006487.', E_USER_DEPRECATED);
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state, $entity_manager);
}
}

View file

@ -0,0 +1,101 @@
<?php
namespace Drupal\migrate_drupal\Plugin\migrate\source\d6;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\State\StateInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
/**
* Drupal i18n_variable source from database.
*
* @MigrateSource(
* id = "d6_variable_translation",
* source_module = "system",
* )
*/
class VariableTranslation extends DrupalSqlBase {
/**
* The variable names to fetch.
*
* @var array
*/
protected $variables;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, EntityManagerInterface $entity_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state, $entity_manager);
$this->variables = $this->configuration['variables'];
}
/**
* {@inheritdoc}
*/
protected function initializeIterator() {
return new \ArrayIterator($this->values());
}
/**
* Return the values of the variables specified in the plugin configuration.
*
* @return array
* An associative array where the keys are the variables specified in the
* plugin configuration and the values are the values found in the source.
* A key/value pair is added for the language code. Only those values are
* returned that are actually in the database.
*/
protected function values() {
$values = [];
$result = $this->prepareQuery()->execute()->FetchAllAssoc('language');
foreach ($result as $i18n_variable) {
$values[]['language'] = $i18n_variable->language;
}
$result = $this->prepareQuery()->execute()->FetchAll();
foreach ($result as $i18n_variable) {
foreach ($values as $key => $value) {
if ($values[$key]['language'] === $i18n_variable->language) {
$values[$key][$i18n_variable->name] = unserialize($i18n_variable->value);
break;
}
}
}
return $values;
}
/**
* {@inheritdoc}
*/
public function count($refresh = FALSE) {
return $this->initializeIterator()->count();
}
/**
* {@inheritdoc}
*/
public function fields() {
return array_combine($this->variables, $this->variables);
}
/**
* {@inheritdoc}
*/
public function query() {
return $this->getDatabase()
->select('i18n_variable', 'v')
->fields('v')
->condition('name', (array) $this->configuration['variables'], 'IN');
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['language']['type'] = 'string';
return $ids;
}
}

View file

@ -2,99 +2,19 @@
namespace Drupal\migrate_drupal\Plugin\migrate\source\d6;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\State\StateInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
@trigger_error('The ' . __NAMESPACE__ . '\i18nVariable is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\VariableTranslation', E_USER_DEPRECATED);
/**
* Drupal i18n_variable source from database.
*
* @MigrateSource(
* id = "i18n_variable"
* id = "i18n_variable",
* source_module = "system",
* )
*
* @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use
* \Drupal\migrate_drupal\Plugin\migrate\source\d6\VariableTranslation instead.
*
* @see https://www.drupal.org/node/2898649
*/
class i18nVariable extends DrupalSqlBase {
/**
* The variable names to fetch.
*
* @var array
*/
protected $variables;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, EntityManagerInterface $entity_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state, $entity_manager);
$this->variables = $this->configuration['variables'];
}
/**
* {@inheritdoc}
*/
protected function initializeIterator() {
return new \ArrayIterator($this->values());
}
/**
* Return the values of the variables specified in the plugin configuration.
*
* @return array
* An associative array where the keys are the variables specified in the
* plugin configuration and the values are the values found in the source.
* A key/value pair is added for the language code. Only those values are
* returned that are actually in the database.
*/
protected function values() {
$values = [];
$result = $this->prepareQuery()->execute()->FetchAllAssoc('language');
foreach ($result as $i18n_variable) {
$values[]['language'] = $i18n_variable->language;
}
$result = $this->prepareQuery()->execute()->FetchAll();
foreach ($result as $i18n_variable) {
foreach ($values as $key => $value) {
if ($values[$key]['language'] === $i18n_variable->language) {
$values[$key][$i18n_variable->name] = unserialize($i18n_variable->value);
break;
}
}
}
return $values;
}
/**
* {@inheritdoc}
*/
public function count() {
return $this->initializeIterator()->count();
}
/**
* {@inheritdoc}
*/
public function fields() {
return array_combine($this->variables, $this->variables);
}
/**
* {@inheritdoc}
*/
public function query() {
return $this->getDatabase()
->select('i18n_variable', 'v')
->fields('v')
->condition('name', (array) $this->configuration['variables'], 'IN');
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['language']['type'] = 'string';
return $ids;
}
}
class i18nVariable extends VariableTranslation {}

View file

@ -22,13 +22,18 @@ abstract class FieldableEntity extends DrupalSqlBase {
* The field instances, keyed by field name.
*/
protected function getFields($entity_type, $bundle = NULL) {
return $this->select('field_config_instance', 'fci')
$query = $this->select('field_config_instance', 'fci')
->fields('fci')
->condition('entity_type', $entity_type)
->condition('bundle', isset($bundle) ? $bundle : $entity_type)
->condition('deleted', 0)
->execute()
->fetchAllAssoc('field_name');
->condition('fci.entity_type', $entity_type)
->condition('fci.bundle', isset($bundle) ? $bundle : $entity_type)
->condition('fci.deleted', 0);
// Join the 'field_config' table and add the 'translatable' setting to the
// query.
$query->leftJoin('field_config', 'fc', 'fci.field_id = fc.id');
$query->addField('fc', 'translatable');
return $query->execute()->fetchAllAssoc('field_name');
}
/**
@ -42,13 +47,13 @@ abstract class FieldableEntity extends DrupalSqlBase {
* The entity ID.
* @param int|null $revision_id
* (optional) The entity revision ID.
* @param string $language
* (optional) The field language.
*
* @return array
* The raw field values, keyed by delta.
*
* @todo Support multilingual field values.
*/
protected function getFieldValues($entity_type, $field, $entity_id, $revision_id = NULL) {
protected function getFieldValues($entity_type, $field, $entity_id, $revision_id = NULL, $language = NULL) {
$table = (isset($revision_id) ? 'field_revision_' : 'field_data_') . $field;
$query = $this->select($table, 't')
->fields('t')
@ -58,6 +63,11 @@ abstract class FieldableEntity extends DrupalSqlBase {
if (isset($revision_id)) {
$query->condition('revision_id', $revision_id);
}
// Add 'language' as a query condition if it has been defined by Entity
// Translation.
if ($language) {
$query->condition('language', $language);
}
$values = [];
foreach ($query->execute() as $row) {
foreach ($row as $key => $value) {
@ -71,4 +81,44 @@ abstract class FieldableEntity extends DrupalSqlBase {
return $values;
}
/**
* Checks if an entity type uses Entity Translation.
*
* @param string $entity_type
* The entity type.
*
* @return bool
* Whether the entity type uses entity translation.
*/
protected function isEntityTranslatable($entity_type) {
return in_array($entity_type, $this->variableGet('entity_translation_entity_types', []), TRUE);
}
/**
* Gets an entity source language from the 'entity_translation' table.
*
* @param string $entity_type
* The entity type.
* @param int $entity_id
* The entity ID.
*
* @return string|bool
* The entity source language or FALSE if no source language was found.
*/
protected function getEntityTranslationSourceLanguage($entity_type, $entity_id) {
try {
return $this->select('entity_translation', 'et')
->fields('et', ['language'])
->condition('entity_type', $entity_type)
->condition('entity_id', $entity_id)
->condition('source', '')
->execute()
->fetchField();
}
// The table might not exist.
catch (\Exception $e) {
return FALSE;
}
}
}

View file

@ -0,0 +1,106 @@
<?php
namespace Drupal\migrate_drupal\Plugin\migrate\source\d7;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\State\StateInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
/**
* Gets Drupal variable_store source from database.
*
* @MigrateSource(
* id = "d7_variable_translation",
* source_module = "i18n_variable",
* )
*/
class VariableTranslation extends DrupalSqlBase {
/**
* The variable names to fetch.
*
* @var array
*/
protected $variables;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, EntityManagerInterface $entity_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state, $entity_manager);
$this->variables = $this->configuration['variables'];
}
/**
* {@inheritdoc}
*/
protected function initializeIterator() {
return new \ArrayIterator($this->values());
}
/**
* Return the values of the variables specified in the plugin configuration.
*
* @return array
* An associative array where the keys are the variables specified in the
* plugin configuration and the values are the values found in the source.
* A key/value pair is added for the language code. Only those values are
* returned that are actually in the database.
*/
protected function values() {
$values = [];
$result = $this->prepareQuery()->execute()->FetchAllAssoc('realm_key');
foreach ($result as $variable_store) {
$values[]['language'] = $variable_store['realm_key'];
}
$result = $this->prepareQuery()->execute()->FetchAll();
foreach ($result as $variable_store) {
foreach ($values as $key => $value) {
if ($values[$key]['language'] === $variable_store['realm_key']) {
if ($variable_store['serialized']) {
$values[$key][$variable_store['name']] = unserialize($variable_store['value']);
break;
}
else {
$values[$key][$variable_store['name']] = $variable_store['value'];
break;
}
}
}
}
return $values;
}
/**
* {@inheritdoc}
*/
public function count($refresh = FALSE) {
return $this->initializeIterator()->count();
}
/**
* {@inheritdoc}
*/
public function fields() {
return array_combine($this->variables, $this->variables);
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['language']['type'] = 'string';
return $ids;
}
/**
* {@inheritdoc}
*/
public function query() {
return $this->select('variable_store', 'vs')
->fields('vs')
->condition('realm', 'language')
->condition('name', (array) $this->configuration['variables'], 'IN');
}
}

View file

@ -9,7 +9,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
* Drupal config source from database.
*
* @MigrateSource(
* id = "d8_config"
* id = "d8_config",
* source_module = "system",
* )
*/
class Config extends DrupalSqlBase {