diff --git a/src/Plugin/migrate/process/EntityGenerate.php b/src/Plugin/migrate/process/EntityGenerate.php new file mode 100644 index 0000000..7ccab0b --- /dev/null +++ b/src/Plugin/migrate/process/EntityGenerate.php @@ -0,0 +1,77 @@ +generateEntity($value); + } + + return $result; + } + + /** + * Generates stub entity for a given value. + * + * @param string $value + * Value to use in creation of stub entity. + * + * @return int|string + * The entity id of the generated entity. + */ + protected function generateEntity($value) { + return $this->entityManager + ->getStorage($this->destinationEntityType) + ->create($this->stub($value)) + ->save() + ->id(); + } + + /** + * Fabricate a stub entity. + * + * @param $value + * Value to use in creation of stub entity. + * + * @return array + * The stub entity. + */ + protected function stub($value) { + $stub = [$this->stubValueKey => $value]; + + if ($this->stubBundleKey) { + $stub[$this->stubBundleKey] = $this->stubBundle; + } + + // Gather any static default values for properties/fields. + if (isset($this->configuration['default_values']) && is_array($this->configuration['default_values'])) { + foreach ($this->configuration['default_values'] as $key => $value) { + $stub[$key] = $value; + } + } + + return $stub; + } + +} diff --git a/src/Plugin/migrate/process/EntityLookup.php b/src/Plugin/migrate/process/EntityLookup.php new file mode 100644 index 0000000..a6a81bb --- /dev/null +++ b/src/Plugin/migrate/process/EntityLookup.php @@ -0,0 +1,186 @@ +migration = $migration; + $this->entityManager = $entityManager; + $this->selectionPluginManager = $selectionPluginManager; + $this->destinationEntityType = substr($this->migration->getDestinationPlugin()->getPluginId(), 7); + $this->destinationBundleKey = $this->entityManager->getDefinition($this->destinationEntityType)->getKey('bundle'); + } + + /** + * {@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') + ); + } + + /** + * {@inheritdoc} + */ + public function transform($value, MigrateExecutableInterface $migrateExecutable, Row $row, $destinationProperty) { + $this->collectStubProperties($destinationProperty); + + return $this->query($value); + } + + /** + * Collect the stub properties from config or target field configuration. + * + * @param string $destinationProperty + * The destination property currently worked on. This is only used together + * with the $row above. + */ + protected function collectStubProperties($destinationProperty) { + if (!empty($this->configuration['value_key'])) { + $this->stubValueKey = $this->configuration['value_key']; + } + if (!empty($this->configuration['bundle_key'])) { + $this->stubBundleKey = $this->configuration['bundle_key']; + } + if (!empty($this->configuration['bundle'])) { + $this->stubBundle = $this->configuration['bundle']; + } + if (!empty($this->configuration['entity_type'])) { + $this->stubEntityType = $this->configuration['entity_type']; + } + + if (empty($this->stubValueKey) || empty($this->stubBundleKey) || $this->stubBundle || empty($this->stubEntityType)) { + // See if we can introspect the stub properties from the destination field. + if (!empty($this->migration->getProcess()[$this->destinationBundleKey][0]['default_value'])) { + $destinationEntityBundle = $this->migration->getProcess()[$this->destinationBundleKey][0]['default_value']; + $fieldConfig = $this->entityManager->getFieldDefinitions($this->destinationEntityType, $destinationEntityBundle)[$destinationProperty]->getConfig($destinationEntityBundle); + if ($fieldConfig->getType() != 'entity_reference') { + throw new MigrateException('The entity_lookup plugin found no entity reference field.'); + } + + if (empty($this->stubBundle)) { + $handlerSettings = $fieldConfig->getSetting('handler_settings'); + $bundles = array_filter((array) $handlerSettings['target_bundles']); + if (count($bundles) == 1) { + $this->stubBundle = reset($bundles); + } + // This was added in 8.1.x is not supported in 8.0.x. + elseif (!empty($handlerSettings['auto_create']) && !empty($handlerSettings['auto_create_bundle'])) { + $this->stubBundle = reset($handlerSettings['auto_create_bundle']); + } + } + + // Make an assumption that if the selection handler can target more than + // one type of entity that we will use the first entity type. + $this->stubEntityType = $this->stubEntityType ?: reset($this->selectionPluginManager->createInstance($fieldConfig->getSetting('handler'))->getPluginDefinition()['entity_types']); + $this->stubValueKey = $this->stubValueKey ?: $this->entityManager->getDefinition($this->stubEntityType)->getKey('label'); + $this->stubBundleKey = $this->stubBundleKey ?: $this->entityManager->getDefinition($this->stubEntityType)->getKey('bundle'); + } + } + + // If there aren't enough stub properties available by now, then bail. + if (empty($this->stubValueKey)) { + throw new MigrateException('The entity_lookup plugin requires a value_key, none located.'); + } + if (!empty($this->stubBundleKey) && empty($this->stubBundle)) { + throw new MigrateException('The entity_lookup plugin found no bundle but destination entity requires one.'); + } + if (empty($this->stubValueKey)) { + throw new MigrateException('The entity_lookup plugin requires a entity_type, none located.'); + } + } + + /** + * Checks for the existence of some value. + * + * @param $value + * The value to query. + * + * @return mixed|bool + * Entity id if the queried entity exists. Otherwise FALSE. + */ + protected function query($value) { + $ignoreCase = !empty($this->configuration['ignore_case']) ?: FALSE; + + $query = $this->entityManager->getStorage($this->stubEntityType) + ->getQuery() + ->condition($this->stubValueKey, $value); + if ($this->stubBundleKey) { + $query->condition($this->stubBundleKey, $this->stubBundle); + } + $results = $query->execute(); + + // By default do a case-sensitive comparison. + if (!$ignoreCase) { + // Returns the entity's identifier. + foreach ($results as $identifier) { + if ($value === $this->entityManager->getStorage($this->stubEntityType)->load($identifier)->{$this->stubValueKey}->value) { + return $identifier; + } + } + } + + return reset($results); + } + +}