diff --git a/src/Plugin/migrate/process/EntityGenerate.php b/src/Plugin/migrate/process/EntityGenerate.php index 7361f732790cd7076f169bf85349cff11415a409..a749a6388cf42c80dd5939f8dd6c6e8fe2f6d749 100644 --- a/src/Plugin/migrate/process/EntityGenerate.php +++ b/src/Plugin/migrate/process/EntityGenerate.php @@ -2,8 +2,13 @@ namespace Drupal\migrate_plus\Plugin\migrate\process; +use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface; use Drupal\migrate\MigrateExecutableInterface; +use Drupal\migrate\Plugin\MigratePluginManager; +use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Row; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * This plugin generates entities within the process plugin. @@ -16,10 +21,10 @@ use Drupal\migrate\Row; * * All the configuration from the lookup plugin applies here. In its most * simple form, this plugin needs no configuration. If there are fields on the - * generated entity that are required or need some default value, that can be - * provided via a default_values configuration option. + * generated entity that are required or need some value, their values can be + * provided via values and/or default_values configuration options. * - * Example usage with default_values configuration: + * Example usage with values and default_values configuration: * @code * destination: * plugin: 'entity:node' @@ -27,20 +32,86 @@ use Drupal\migrate\Row; * type: * plugin: default_value * default_value: page + * foo: bar * field_tags: * plugin: entity_generate * source: tags * default_values: * description: Default description - * field_long_description: Default long description + * values: + * field_long_description: some_source_field + * field_foo: '@foo' * @endcode */ class EntityGenerate extends EntityLookup { + /** + * The row from the source to process. + * + * @var \Drupal\migrate\Row + */ + protected $row; + + /** + * The MigrateExecutable instance. + * + * @var \Drupal\migrate\MigrateExecutable + */ + protected $migrateExecutable; + + /** + * The get process plugin instance. + * + * @var \Drupal\migrate\Plugin\migrate\process\Get + */ + protected $getProcessPlugin; + + /** + * EntityGenerate constructor. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $pluginId + * The plugin_id for the plugin instance. + * @param mixed $pluginDefinition + * The plugin implementation definition. + * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * The migration. + * @param \Drupal\Core\Entity\EntityManagerInterface $entityManager + * The $entityManager instance. + * @param \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface $selectionPluginManager + * The $selectionPluginManager instance. + * @param \Drupal\migrate\Plugin\MigratePluginManager $migratePluginManager + * The MigratePluginManager instance. + */ + public function __construct(array $configuration, $pluginId, $pluginDefinition, MigrationInterface $migration, EntityManagerInterface $entityManager, SelectionPluginManagerInterface $selectionPluginManager, MigratePluginManager $migratePluginManager) { + parent::__construct($configuration, $pluginId, $pluginDefinition, $migration, $entityManager, $selectionPluginManager); + if (isset($configuration['values'])) { + $this->getProcessPlugin = $migratePluginManager->createInstance('get', ['source' => $configuration['values']]); + } + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition, MigrationInterface $migration = NULL) { + return new static( + $configuration, + $pluginId, + $pluginDefinition, + $migration, + $container->get('entity.manager'), + $container->get('plugin.manager.entity_reference_selection'), + $container->get('plugin.manager.migrate.process') + ); + } + /** * {@inheritdoc} */ public function transform($value, MigrateExecutableInterface $migrateExecutable, Row $row, $destinationProperty) { + $this->row = $row; + $this->migrateExecutable = $migrateExecutable; // Creates an entity if the lookup determines it doesn't exist. if (!($result = parent::transform($value, $migrateExecutable, $row, $destinationProperty))) { $result = $this->generateEntity($value); @@ -94,6 +165,13 @@ class EntityGenerate extends EntityLookup { $entity_values[$key] = $value; } } + // Gather any additional properties/fields. + if (isset($this->configuration['values']) && is_array($this->configuration['values'])) { + foreach ($this->configuration['values'] as $key => $property) { + $source_value = $this->getProcessPlugin->transform(NULL, $this->migrateExecutable, $this->row, $property); + $entity_values[$key] = $source_value; + } + } return $entity_values; } diff --git a/tests/src/Kernel/Plugin/migrate/process/EntityGenerateTest.php b/tests/src/Kernel/Plugin/migrate/process/EntityGenerateTest.php index a4c0f27f67ce607a42aad55befee22879268ec7f..0944ff831ef7b58692871ee8fe5f2d897aeeff30 100644 --- a/tests/src/Kernel/Plugin/migrate/process/EntityGenerateTest.php +++ b/tests/src/Kernel/Plugin/migrate/process/EntityGenerateTest.php @@ -141,7 +141,12 @@ class EntityGenerateTest extends KernelTestBase implements MigrateMessageInterfa if (is_array($value)) { foreach ($value as $key => $expectedValue) { if (empty($expectedValue)) { - $this->assertEmpty($entity->{$property}->getValue(), "Expected value is empty but field $property is not empty."); + if (!$entity->{$property}->isEmpty()) { + $this->assertTrue($entity->{$property}[0]->entity->$key->isEmpty(), "Expected value is empty but field $property.$key is not empty."); + } + else { + $this->assertTrue($entity->{$property}->isEmpty(), "Expected value is empty but field $property is not empty."); + } } elseif ($entity->{$property}->getValue()) { $this->assertEquals($expectedValue, $entity->{$property}[0]->entity->$key->value); @@ -314,6 +319,92 @@ class EntityGenerateTest extends KernelTestBase implements MigrateMessageInterfa ], ], ], + 'provide values' => [ + 'definition' => [ + 'source' => [ + 'plugin' => 'embedded_data', + 'data_rows' => [ + [ + 'id' => 1, + 'title' => 'content item 1', + 'term' => 'Apples', + ], + [ + 'id' => 2, + 'title' => 'content item 2', + 'term' => 'Bananas', + ], + [ + 'id' => 3, + 'title' => 'content item 3', + 'term' => 'Grapes', + ], + ], + 'ids' => [ + 'id' => ['type' => 'integer'], + ], + ], + 'process' => [ + 'id' => 'id', + 'type' => [ + 'plugin' => 'default_value', + 'default_value' => $this->bundle, + ], + 'title' => 'title', + 'term_upper' => [ + 'plugin' => 'callback', + 'source' => 'term', + 'callable' => 'strtoupper', + ], + $this->fieldName => [ + 'plugin' => 'entity_generate', + 'source' => 'term', + 'values' => [ + 'description' => '@term_upper', + ], + ], + ], + 'destination' => [ + 'plugin' => 'entity:node', + ], + ], + 'expected' => [ + 'row 1' => [ + 'id' => 1, + 'title' => 'content item 1', + $this->fieldName => [ + 'tid' => 2, + 'name' => 'Apples', + 'description' => 'APPLES', + ], + ], + 'row 2' => [ + 'id' => 2, + 'title' => 'content item 2', + $this->fieldName => [ + 'tid' => 3, + 'name' => 'Bananas', + 'description' => 'BANANAS', + ], + ], + 'row 3' => [ + 'id' => 3, + 'title' => 'content item 3', + $this->fieldName => [ + 'tid' => 1, + 'name' => 'Grapes', + 'description' => NULL, + ], + ], + ], + 'pre seed' => [ + 'taxonomy_term' => [ + 'name' => 'Grapes', + 'vid' => $this->vocabulary, + 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + ], + ], + ], ]; }