diff --git a/core/modules/field/migration_templates/d7_field.yml b/core/modules/field/migration_templates/d7_field.yml index f4f2e6e..1fa0069 100644 --- a/core/modules/field/migration_templates/d7_field.yml +++ b/core/modules/field/migration_templates/d7_field.yml @@ -15,8 +15,9 @@ process: langcode: 'constants/langcode' field_name: field_name type: - plugin: field_type + plugin: process_field source: type + method: getFieldType # Translatable is not migrated and the Drupal 8 default of true is used. # If translatable is false in field storage then the field can not be # set to translatable via the UI. diff --git a/core/modules/field/src/Plugin/migrate/process/ProcessField.php b/core/modules/field/src/Plugin/migrate/process/ProcessField.php new file mode 100644 index 0000000..43a192d --- /dev/null +++ b/core/modules/field/src/Plugin/migrate/process/ProcessField.php @@ -0,0 +1,140 @@ +cckPluginManager = $cck_plugin_manager; + $this->fieldPluginManager = $field_plugin_manager; + $this->migration = $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, + $container->get('plugin.manager.migrate.cckfield'), + $container->get('plugin.manager.migrate.field'), + $migration + ); + } + + /** + * {@inheritdoc} + */ + public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { + $field_type = is_array($value) ? $value[0] : $value; + + if (empty($this->configuration['method'])) { + throw new MigrateException('You need to specify the name of a method to be called on the Field plugin.'); + } + $method = $this->configuration['method']; + + try { + $plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, [], $this->migration); + $plugin_instance = $this->fieldPluginManager->createInstance($plugin_id, [], $this->migration); + if (!method_exists($plugin_instance, $method) || !is_callable([$plugin_instance, $method])) { + throw new MigrateException('The specified method does not exists or is not callable.'); + } + return call_user_func_array([$plugin_instance, $method], [$row]); + } + catch (PluginNotFoundException $e) { + try { + $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, [], $this->migration); + $plugin_instance = $this->cckPluginManager->createInstance($plugin_id, [], $this->migration); + if (!method_exists($plugin_instance, $method) || !is_callable([$plugin_instance, $method])) { + throw new MigrateException('The specified method does not exists or is not callable.'); + } + return call_user_func_array([$plugin_instance, $method], [$row]); + } + catch (PluginNotFoundException $e) { + return $field_type; + } + } + } + +} diff --git a/core/modules/field/tests/src/Unit/Plugin/migrate/process/ProcessFieldTest.php b/core/modules/field/tests/src/Unit/Plugin/migrate/process/ProcessFieldTest.php new file mode 100644 index 0000000..a8806fa --- /dev/null +++ b/core/modules/field/tests/src/Unit/Plugin/migrate/process/ProcessFieldTest.php @@ -0,0 +1,120 @@ +cckFieldManager = $this->getMock(MigrateCckFieldPluginManagerInterface::class); + $this->fieldInstance = $this->getMock(MigrateFieldInterface::class); + $this->fieldManager = $this->getMock(MigrateFieldPluginManagerInterface::class); + $this->migration = $this->getMock(MigrationInterface::class); + + $this->fieldManager->method('createInstance') + ->willReturn($this->fieldInstance); + + parent::setUp(); + } + + /** + * Tests the transformation with the getFieldType() method. + * + * @covers ::transform + */ + public function testTransformGetFieldType() { + $this->fieldInstance->method('getFieldType') + ->willReturn('bar'); + + $configuration = ['method' => 'getFieldType']; + $this->plugin = new ProcessField($configuration, 'foo', [], $this->cckFieldManager, $this->fieldManager, $this->migration); + + $value = $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'foo'); + $this->assertSame($value, 'bar'); + } + + /** + * Tests the transformation with the getFieldFormatterMap() method. + * + * @covers ::transform + */ + public function testTransformGetFieldFormatterMap() { + $this->fieldInstance->method('getFieldFormatterMap') + ->willReturn(['foo' => 'bar']); + + $configuration = ['method' => 'getFieldFormatterMap']; + $this->plugin = new ProcessField($configuration, 'foo', [], $this->cckFieldManager, $this->fieldManager, $this->migration); + + $value = $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'foo'); + $this->assertSame($value, ['foo' => 'bar']); + } + + /** + * Tests the transformation with the getFieldWidgetMap() method. + * + * @covers ::transform + */ + public function testTransformGetFieldWidgetMap() { + $this->fieldInstance->method('getFieldWidgetMap') + ->willReturn(['bar' => 'foo']); + + $configuration = ['method' => 'getFieldWidgetMap']; + $this->plugin = new ProcessField($configuration, 'foo', [], $this->cckFieldManager, $this->fieldManager, $this->migration); + + $value = $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'foo'); + $this->assertSame($value, ['bar' => 'foo']); + } + + /** + * Tests that a MigrateException is thrown if no method name is provided. + * + * @covers ::transform + */ + public function testTransformWithoutMethod() { + $configuration = []; + $this->plugin = new ProcessField($configuration, 'foo', [], $this->cckFieldManager, $this->fieldManager, $this->migration); + + $this->setExpectedException(MigrateException::class); + $value = $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'foo'); + } + + /** + * Tests that the value is returned unchanged if no field plugin is found. + * + * @covers ::transform + */ + public function testTransformPluginNotFoundException() { + $exception = new PluginNotFoundException('foo'); + + $this->cckFieldManager->method('getPluginIdFromFieldType') + ->will($this->throwException($exception)); + + $this->fieldManager->method('getPluginIdFromFieldType') + ->will($this->throwException($exception)); + + $configuration = ['method' => 'getFieldType']; + $this->plugin = new ProcessField($configuration, 'foo', [], $this->cckFieldManager, $this->fieldManager, $this->migration); + + $value = $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'foo'); + $this->assertSame($value, 'foo'); + } + +}