Commit 04a17f8b authored by alexpott's avatar alexpott

Issue #2423435 by benjy, chx: Add CckField Plugin type to migrate_drupal

parent 60531a74
......@@ -392,6 +392,18 @@ public function isComplete() {
return $this->getMigrationResult() === static::RESULT_COMPLETED;
}
/**
* {@inheritdoc}
*/
public function set($property_name, $value) {
if ($property_name == 'source') {
// Invalidate the source plugin.
unset($this->sourcePlugin);
}
return parent::set($property_name, $value);
}
/**
* {@inheritdoc}
*/
......
......@@ -216,8 +216,6 @@ public function setProcess(array $process);
*
* @return $this
* The migration entity.
*
* @see Drupal\migrate_drupal\Plugin\migrate\load\LoadEntity::processLinkField().
*/
public function setProcessOfProperty($property, $process_of_property);
......
......@@ -46,13 +46,6 @@ class MigratePluginManager extends DefaultPluginManager {
* The annotation class name.
*/
public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, $annotation = 'Drupal\Component\Annotation\PluginID') {
$plugin_interface_map = array(
'destination' => 'Drupal\migrate\Plugin\MigrateDestinationInterface',
'process' => 'Drupal\migrate\Plugin\MigrateProcessInterface',
'source' => 'Drupal\migrate\Plugin\MigrateSourceInterface',
'id_map' => 'Drupal\migrate\Plugin\MigrateIdMapInterface',
'entity_field' => 'Drupal\migrate\Plugin\MigrateEntityDestinationFieldInterface',
);
$plugin_interface = isset($plugin_interface_map[$type]) ? $plugin_interface_map[$type] : NULL;
parent::__construct("Plugin/migrate/$type", $namespaces, $module_handler, $plugin_interface, $annotation);
$this->alterInfo('migrate_' . $type . '_info');
......@@ -77,4 +70,20 @@ public function createInstance($plugin_id, array $configuration = array(), Migra
return $plugin;
}
/**
* Helper for the plugin type to interface map.
*
* @return array
* An array map from plugin type to interface.
*/
protected function getPluginInterfaceMap() {
return [
'destination' => 'Drupal\migrate\Plugin\MigrateDestinationInterface',
'process' => 'Drupal\migrate\Plugin\MigrateProcessInterface',
'source' => 'Drupal\migrate\Plugin\MigrateSourceInterface',
'id_map' => 'Drupal\migrate\Plugin\MigrateIdMapInterface',
'entity_field' => 'Drupal\migrate\Plugin\MigrateEntityDestinationFieldInterface',
];
}
}
......@@ -2,3 +2,6 @@ services:
plugin.manager.migrate.load:
class: Drupal\migrate_drupal\Plugin\MigratePluginManager
arguments: [load, '@container.namespaces', '@cache.discovery', '@module_handler']
plugin.manager.migrate.cckfield:
class: Drupal\migrate_drupal\Plugin\MigratePluginManager
arguments: [cckfield, '@container.namespaces', '@cache.discovery', '@module_handler']
......@@ -10,6 +10,7 @@
use Drupal\Component\Utility\String;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\migrate_drupal\Plugin\CckFieldMigrateSourceInterface;
use Drupal\migrate\MigrationStorage as BaseMigrationStorage;
/**
......@@ -17,6 +18,18 @@
*/
class MigrationStorage extends BaseMigrationStorage {
/**
* A cached array of cck field plugins.
*
* @var array
*/
protected $cckFieldPlugins;
/**
* @var \Drupal\migrate_drupal\Plugin\MigratePluginManager
*/
protected $cckPluginManager;
/**
* {@inheritdoc}
*/
......@@ -84,6 +97,10 @@ public function loadMultiple(array $ids = NULL) {
}
}
// Allow modules providing cck field plugins to alter the required
// migrations to assist with the migration a custom field type.
$this->applyCckFieldProcessors($entities);
// Build an array of dependencies and set the order of the migrations.
return $this->buildDependencyMigration($entities, $dynamic_ids);
}
......@@ -113,4 +130,83 @@ public function save(EntityInterface $entity) {
return parent::save($entity);
}
/**
* Allow any field type plugins to adjust the migrations as required.
*
* @param \Drupal\migrate\Entity\Migration[] $entities
* An array of migration entities.
*/
protected function applyCckFieldProcessors(array $entities) {
$method_map = $this->getMigrationPluginMethodMap();
foreach ($entities as $entity_id => $migration) {
// Allow field plugins to process the required migrations.
if (isset($method_map[$entity_id])) {
$method = $method_map[$entity_id];
$cck_plugins = $this->getCckFieldPlugins();
array_walk($cck_plugins, function ($plugin) use ($method, $migration) {
$plugin->$method($migration);
});
}
// If this is a CCK bundle migration, allow the cck field plugins to add
// any field type processing.
$source_plugin = $migration->getSourcePlugin();
if ($source_plugin instanceof CckFieldMigrateSourceInterface && $source_plugin->getDerivativeId()) {
$plugins = $this->getCckFieldPlugins();
foreach ($source_plugin->fieldData() as $field_name => $data) {
if (isset($plugins[$data['type']])) {
$plugins[$data['type']]->processCckFieldValues($migration, $field_name, $data);
}
}
}
}
}
/**
* Get an array of loaded cck field plugins.
*
* @return \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface[]
* An array of cck field process plugins.
*/
protected function getCckFieldPlugins() {
if (!isset($this->cckFieldPlugins)) {
$this->cckFieldPlugins = [];
foreach ($this->getCckPluginManager()->getDefinitions() as $definition) {
$this->cckFieldPlugins[$definition['id']] = $this->getCckPluginManager()->createInstance($definition['id']);
}
}
return $this->cckFieldPlugins;
}
/**
* Provides a map between migration ids and the cck field plugin method.
*
* @return array
* The map between migrations and cck field plugin processing methods.
*/
protected function getMigrationPluginMethodMap() {
return [
'd6_field' => 'processField',
'd6_field_instance' => 'processFieldInstance',
'd6_field_instance_widget_settings' => 'processFieldWidget',
'd6_field_formatter_settings' => 'processFieldFormatter',
];
}
/**
* Get the cck field plugin manager.
*
* @return \Drupal\migrate_drupal\Plugin\MigratePluginManager
* The loaded plugin manager.
*/
protected function getCckPluginManager() {
if (!isset($this->cckPluginManager)) {
$this->cckPluginManager = \Drupal::service('plugin.manager.migrate.cckfield');
}
return $this->cckPluginManager;
}
}
<?php
/**
* @file
* Contains Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface
*/
namespace Drupal\migrate_drupal\Plugin;
use Drupal\Component\Plugin\PluginInspectionInterface;
use Drupal\migrate\Entity\MigrationInterface;
/**
* Provides an interface for all CCK field type plugins.
*/
interface MigrateCckFieldInterface extends PluginInspectionInterface {
/**
* Apply any custom processing to the field migration.
*
* @param \Drupal\migrate\Entity\MigrationInterface $migration
* The migration entity.
*/
public function processField(MigrationInterface $migration);
/**
* Apply any custom processing to the field instance migration.
*
* @param \Drupal\migrate\Entity\MigrationInterface $migration
* The migration entity.
*/
public function processFieldInstance(MigrationInterface $migration);
/**
* Apply any custom processing to the field widget migration.
*
* @param \Drupal\migrate\Entity\MigrationInterface $migration
* The migration entity.
*/
public function processFieldWidget(MigrationInterface $migration);
/**
* Apply any custom processing to the field formatter migration.
*
* @param \Drupal\migrate\Entity\MigrationInterface $migration
* The migration entity.
*/
public function processFieldFormatter(MigrationInterface $migration);
/**
* Get a map between D6 formatters and D8 formatters for this field type.
*
* This is used by static::processFieldFormatter() in the base class.
*
* @return array
* The keys are D6 formatters and the values are D8 formatters.
*/
public function getFieldFormatterMap();
/**
* Get a map between D6 and D8 widgets for this field type.
*
* @return array
* The keys are D6 field widget types and the values D8 widgets.
*/
public function getFieldWidgetMap();
/**
* Apply any custom processing to the cck bundle migrations.
*
* @param \Drupal\migrate\Entity\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 CckFieldValues::fieldData().
*/
public function processCckFieldValues(MigrationInterface $migration, $field_name, $data);
}
......@@ -7,9 +7,6 @@
namespace Drupal\migrate_drupal\Plugin;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\Factory\ContainerFactory;
use Drupal\migrate\Plugin\MigratePluginManager as BaseMigratePluginManager;
/**
......@@ -24,11 +21,11 @@ class MigratePluginManager extends BaseMigratePluginManager {
/**
* {@inheritdoc}
*/
public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, $annotation = 'Drupal\Component\Annotation\PluginID') {
parent::__construct($type, $namespaces, $cache_backend, $module_handler, $annotation);
$this->factory = new ContainerFactory($this, 'Drupal\migrate_drupal\Plugin\MigrateLoadInterface');
protected function getPluginInterfaceMap() {
return parent::getPluginInterfaceMap() + [
'load' => 'Drupal\migrate_drupal\Plugin\MigrateLoadInterface',
'cckfield' => 'Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface',
];
}
}
<?php
/**
* @file
* Contains \Drupal\migrate_drupal\Plugin\migrate\cckfield\MigrateCckFieldInterface.
*/
namespace Drupal\migrate_drupal\Plugin\migrate\cckfield;
use Drupal\Core\Plugin\PluginBase;
use Drupal\migrate\Entity\MigrationInterface;
use Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface;
/**
* The base class for all cck field plugins.
*
* @see \Drupal\migrate_drupal\Plugin\MigratePluginManager
* @see \Drupal\migrate_drupal\Annotation\MigrateCckField
* @see \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface
* @see plugin_api
*
* @ingroup migration
*/
abstract class CckFieldPluginBase extends PluginBase implements MigrateCckFieldInterface {
/**
* {@inheritdoc}
*/
public function processField(MigrationInterface $migration) {
$process[0]['map'][$this->pluginId][$this->pluginId] = $this->pluginId;
$migration->mergeProcessOfProperty('type', $process);
}
/**
* {@inheritdoc}
*/
public function processFieldInstance(MigrationInterface $migration) {
// Nothing to do by default with field instances.
}
/**
* {@inheritdoc}
*/
public function processFieldWidget(MigrationInterface $migration) {
$process = [];
foreach ($this->getFieldWidgetMap() as $source_widget => $destination_widget) {
$process['type']['map'][$source_widget] = $destination_widget;
}
$migration->mergeProcessOfProperty('options/type', $process);
}
/**
* {@inheritdoc}
*/
public function getFieldWidgetMap() {
// By default use the plugin id for the widget types.
return [
$this->pluginId => $this->pluginId . '_default',
];
}
/**
* {@inheritdoc}
*/
public function processFieldFormatter(MigrationInterface $migration) {
$process = [];
foreach ($this->getFieldFormatterMap() as $source_format => $destination_format) {
$process[0]['map'][$this->pluginId][$source_format] = $destination_format;
}
$migration->mergeProcessOfProperty('options/type', $process);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment