Commit 262ff525 authored by alexpott's avatar alexpott

Issue #2631736 by quietone, jmuzz, Sam152, svendecabooter, benjy: Cckfield...

Issue #2631736 by quietone, jmuzz, Sam152, svendecabooter, benjy: Cckfield Plugins must distinguish core versions
parent bd634aa9
......@@ -2,6 +2,8 @@ id: d7_field
label: Field configuration
migration_tags:
- Drupal 7
class: Drupal\migrate_drupal\Plugin\migrate\CckMigration
cck_plugin_method: processField
source:
plugin: d7_field
constants:
......@@ -13,7 +15,7 @@ process:
langcode: 'constants/langcode'
field_name: field_name
type:
plugin: static_map
plugin: field_type
source: type
map:
date: datetime
......@@ -30,8 +32,6 @@ process:
number_decimal: decimal
number_float: float
phone: telephone
taxonomy_term_reference: entity_reference
text: text
text_long: text_long
text_with_summary: text_with_summary
translatable: translatable
......
......@@ -2,6 +2,8 @@ id: d7_field_formatter_settings
label: Field formatter configuration
migration_tags:
- Drupal 7
class: Drupal\migrate_drupal\Plugin\migrate\CckMigration
cck_plugin_method: processFieldFormatter
source:
plugin: d7_field_instance_per_view_mode
constants:
......
......@@ -2,6 +2,8 @@ id: d7_field_instance
label: Field instance configuration
migration_tags:
- Drupal 7
class: Drupal\migrate_drupal\Plugin\migrate\CckMigration
cck_plugin_method: processFieldInstance
source:
plugin: d7_field_instance
constants:
......
......@@ -2,6 +2,8 @@ id: d7_field_instance_widget_settings
label: Field instance widget configuration
migration_tags:
- Drupal 7
class: Drupal\migrate_drupal\Plugin\migrate\CckMigration
cck_plugin_method: processFieldWidget
source:
plugin: d7_field_instance_per_form_display
constants:
......
<?php
namespace Drupal\field\Plugin\migrate\process\d6;
namespace Drupal\field\Plugin\migrate\process;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Plugin\migrate\process\StaticMap;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -24,6 +25,13 @@ class FieldType extends StaticMap implements ContainerFactoryPluginInterface {
*/
protected $cckPluginManager;
/**
* The migration object.
*
* @var \Drupal\migrate\Plugin\MigrationInterface
*/
protected $migration;
/**
* Constructs a FieldType plugin.
*
......@@ -35,21 +43,25 @@ class FieldType extends StaticMap implements ContainerFactoryPluginInterface {
* The plugin definition.
* @param \Drupal\Component\Plugin\PluginManagerInterface $cck_plugin_manager
* The cckfield plugin manager.
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
* The migration being run.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, PluginManagerInterface $cck_plugin_manager) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, PluginManagerInterface $cck_plugin_manager, MigrationInterface $migration = NULL) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->cckPluginManager = $cck_plugin_manager;
$this->migration = $migration;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('plugin.manager.migrate.cckfield')
$container->get('plugin.manager.migrate.cckfield'),
$migration
);
}
......@@ -57,11 +69,10 @@ public static function create(ContainerInterface $container, array $configuratio
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
list ($field_type, $widget_type) = $value;
$field_type = is_array($value) ? $value[0] : $value;
try {
return $this->cckPluginManager->createInstance($field_type)
->getFieldType($row);
return $this->cckPluginManager->createInstance($field_type, [], $this->migration)->getFieldType($row);
}
catch (PluginNotFoundException $e) {
return parent::transform($value, $migrate_executable, $row, $destination_property);
......
......@@ -8,7 +8,8 @@
/**
* @MigrateCckField(
* id = "filefield"
* id = "filefield",
* core = {6}
* )
*/
class FileField extends CckFieldPluginBase {
......
......@@ -9,6 +9,7 @@
/**
* @MigrateCckField(
* id = "file",
* core = {7}
* )
*/
class FileField extends CckFieldPluginBase {
......
......@@ -7,7 +7,8 @@
/**
* @MigrateCckField(
* id = "image"
* id = "image",
* core = {7}
* )
*/
class ImageField extends CckFieldPluginBase {
......
......@@ -7,7 +7,11 @@
/**
* @MigrateCckField(
* id = "link"
* id = "link",
* core = {6},
* type_map = {
* "link_field" = "link"
* }
* )
*/
class LinkField extends CckFieldPluginBase {
......
services:
plugin.manager.migrate.cckfield:
class: Drupal\migrate\Plugin\MigratePluginManager
class: Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManager
arguments:
- cckfield
- '@container.namespaces'
......
......@@ -8,9 +8,10 @@
* Defines a cckfield plugin annotation object.
*
* cckfield plugins are variously responsible for handling the migration of
* CCK fields from Drupal 6 to Drupal 8. They are allowed to alter CCK-related
* migrations when migrations are being generated, and can compute destination
* field types for individual fields during the actual migration process.
* CCK fields from Drupal 6 to Drupal 8, and Field API fields from Drupal 7
* to Drupal 8. They are allowed to alter CCK-related migrations when migrations
* are being generated, and can compute destination field types for individual
* fields during the actual migration process.
*
* Plugin Namespace: Plugin\migrate\cckfield
*
......@@ -18,6 +19,17 @@
*/
class MigrateCckField extends Plugin {
/**
* @inheritdoc
*/
public function __construct($values) {
parent::__construct($values);
// Provide default value for core property, in case it's missing.
if (empty($this->definition['core'])) {
$this->definition['core'] = [6];
}
}
/**
* The plugin ID.
*
......@@ -32,4 +44,11 @@ class MigrateCckField extends Plugin {
*/
public $type_map = [];
/**
* The Drupal core version(s) this plugin applies to.
*
* @var int[]
*/
public $core = [];
}
<?php
namespace Drupal\migrate_drupal\Plugin;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\migrate\Plugin\MigratePluginManager;
use Drupal\migrate\Plugin\MigrationInterface;
/**
* Plugin manager for migrate cckfield plugins.
*
* @see \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface
* @see \Drupal\migrate\Annotation\MigrateCckField
* @see plugin_api
*
* @ingroup migration
*/
class MigrateCckFieldPluginManager extends MigratePluginManager {
/**
* The default version of core to use for cck field plugins.
*
* These plugins were initially only built and used for Drupal 6 fields.
* Having been extended for Drupal 7 with a "core" annotation, we fall back to
* Drupal 6 where none exists.
*/
const DEFAULT_CORE_VERSION = 6;
/**
* {@inheritdoc}
*/
public function createInstance($field_type, array $configuration = array(), MigrationInterface $migration = NULL) {
$core = static::DEFAULT_CORE_VERSION;
if (!empty($configuration['core'])) {
$core = $configuration['core'];
}
elseif (!empty($migration->getPluginDefinition()['migration_tags'])) {
foreach ($migration->getPluginDefinition()['migration_tags'] as $tag) {
if ($tag == 'Drupal 7') {
$core = 7;
}
}
}
foreach ($this->getDefinitions() as $plugin_id => $definition) {
if (in_array($core, $definition['core'])) {
if (array_key_exists($field_type, $definition['type_map']) || $field_type === $plugin_id) {
return parent::createInstance($plugin_id, $configuration, $migration);
}
}
}
throw new PluginNotFoundException($field_type);
}
}
name: 'Migrate cck field plugin manager test'
type: module
description: 'Example module demonstrating the cck field plugin manager in the Migrate API.'
package: Testing
version: VERSION
core: 8.x
<?php
namespace Drupal\migrate_cckfield_plugin_manager_test\Plugin\migrate\cckfield;
use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
use Drupal\migrate\Plugin\MigrationInterface;
/**
* @MigrateCckField(
* id = "d6_file",
* core = {6},
* type_map = {
* "file" = "file"
* }
* )
*/
class D6FileField extends CckFieldPluginBase {
/**
* {@inheritdoc}
*/
public function getFieldFormatterMap() {}
/**
* {@inheritdoc}
*/
public function processCckFieldValues(MigrationInterface $migration, $field_name, $data) {}
}
<?php
namespace Drupal\migrate_cckfield_plugin_manager_test\Plugin\migrate\cckfield;
use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
use Drupal\migrate\Plugin\MigrationInterface;
/**
* @MigrateCckField(
* id = "d6_no_core_version_specified"
* )
*/
class D6NoCoreVersionSpecified extends CckFieldPluginBase {
/**
* {@inheritdoc}
*/
public function getFieldFormatterMap() {}
/**
* {@inheritdoc}
*/
public function processCckFieldValues(MigrationInterface $migration, $field_name, $data) {}
}
<?php
namespace Drupal\Tests\migrate_drupal\Kernel;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
/**
* Tests the cck field plugin manager.
*
* @group migrate_drupal
*/
class MigrateCckFieldPluginManagerTest extends MigrateDrupalTestBase {
/**
* {@inheritdoc}
*/
public static $modules = array('system', 'user', 'field', 'migrate_drupal', 'options', 'file', 'text', 'migrate_cckfield_plugin_manager_test');
/**
* Tests that the correct MigrateCckField plugins are used.
*/
public function testPluginSelection() {
$plugin_manager = \Drupal::service('plugin.manager.migrate.cckfield');
$this->assertIdentical('Drupal\\file\\Plugin\\migrate\\cckfield\\d6\\FileField', get_class($plugin_manager->createInstance('filefield', ['core' => 6])));
try {
// If this test passes, createInstance will raise a
// PluginNotFoundException and we'll never reach fail().
$plugin_manager->createInstance('filefield', ['core' => 7]);
$this->fail('Expected Drupal\Component\Plugin\Exception\PluginNotFoundException.');
}
catch (PluginNotFoundException $e) {
$this->assertIdentical($e->getMessage(), "Plugin ID 'filefield' was not found.");
}
$this->assertIdentical('Drupal\\file\\Plugin\\migrate\\cckfield\\d7\\ImageField', get_class($plugin_manager->createInstance('image', ['core' => 7])));
$this->assertIdentical('Drupal\\file\\Plugin\\migrate\\cckfield\\d7\\FileField', get_class($plugin_manager->createInstance('file', ['core' => 7])));
$this->assertIdentical('Drupal\\migrate_cckfield_plugin_manager_test\\Plugin\\migrate\\cckfield\\D6FileField', get_class($plugin_manager->createInstance('file', ['core' => 6])));
$this->assertIdentical('Drupal\\text\\Plugin\\migrate\\cckfield\\TextField', get_class($plugin_manager->createInstance('text', ['core' => 6])));
$this->assertIdentical('Drupal\\text\\Plugin\\migrate\\cckfield\\TextField', get_class($plugin_manager->createInstance('text', ['core' => 7])));
// Test fallback when no core version is specified.
$this->assertIdentical('Drupal\\migrate_cckfield_plugin_manager_test\\Plugin\\migrate\\cckfield\\D6NoCoreVersionSpecified', get_class($plugin_manager->createInstance('d6_no_core_version_specified', ['core' => 6])));
try {
// If this test passes, createInstance will raise a
// PluginNotFoundException and we'll never reach fail().
$plugin_manager->createInstance('d6_no_core_version_specified', ['core' => 7]);
$this->fail('Expected Drupal\Component\Plugin\Exception\PluginNotFoundException.');
}
catch (PluginNotFoundException $e) {
$this->assertIdentical($e->getMessage(), "Plugin ID 'd6_no_core_version_specified' was not found.");
}
}
}
......@@ -111,7 +111,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
$field_type = $info['type'];
if ($this->cckPluginManager->hasDefinition($info['type'])) {
if (!isset($this->cckPluginCache[$field_type])) {
$this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, [], $migration);
$this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, ['core' => 6], $migration);
}
$this->cckPluginCache[$field_type]
->processCckFieldValues($migration, $field_name, $info);
......
......@@ -99,7 +99,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
$field_type = $info['type'];
if ($this->cckPluginManager->hasDefinition($field_type)) {
if (!isset($this->cckPluginCache[$field_type])) {
$this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, [], $migration);
$this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, ['core' => 7], $migration);
}
$this->cckPluginCache[$field_type]
->processCckFieldValues($migration, $field_name, $info);
......
......@@ -7,7 +7,11 @@
/**
* @MigrateCckField(
* id = "taxonomy_term_reference"
* id = "taxonomy_term_reference",
* type_map = {
* "taxonomy_term_reference" = "entity_reference"
* },
* core = {6,7}
* )
*/
class TaxonomyTermReference extends CckFieldPluginBase {
......
......@@ -8,7 +8,13 @@
/**
* @MigrateCckField(
* id = "text"
* id = "text",
* type_map = {
* "text" = "text",
* "text_long" = "text_long",
* "text_with_summary" = "text_with_summary"
* },
* core = {6,7}
* )
*/
class TextField extends CckFieldPluginBase {
......@@ -113,6 +119,7 @@ public function getFieldType(Row $row) {
case 'text_textarea':
return 'text_long';
default:
return parent::getFieldType($row);
break;
}
}
......
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