Chris@0: migration = $migration; Chris@0: $this->entityManager = $entityManager; Chris@0: $this->selectionPluginManager = $selectionPluginManager; Chris@0: $pluginIdParts = explode(':', $this->migration->getDestinationPlugin()->getPluginId()); Chris@0: $this->destinationEntityType = empty($pluginIdParts[1]) ?: $pluginIdParts[1]; Chris@0: $this->destinationBundleKey = !$this->destinationEntityType ?: $this->entityManager->getDefinition($this->destinationEntityType)->getKey('bundle'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition, MigrationInterface $migration = NULL) { Chris@0: return new static( Chris@0: $configuration, Chris@0: $pluginId, Chris@0: $pluginDefinition, Chris@0: $migration, Chris@0: $container->get('entity.manager'), Chris@0: $container->get('plugin.manager.entity_reference_selection') Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function transform($value, MigrateExecutableInterface $migrateExecutable, Row $row, $destinationProperty) { Chris@0: $this->determineLookupProperties($destinationProperty); Chris@0: Chris@0: $this->destinationProperty = $this->configuration['destination_field']; Chris@0: Chris@0: return $this->query($value); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Determine the lookup properties from config or target field configuration. Chris@0: * Chris@0: * @param string $destinationProperty Chris@0: * The destination property currently worked on. This is only used together Chris@0: * with the $row above. Chris@0: */ Chris@0: protected function determineLookupProperties($destinationProperty) { Chris@0: if (!empty($this->configuration['value_key'])) { Chris@0: $this->lookupValueKey = $this->configuration['value_key']; Chris@0: } Chris@0: if (!empty($this->configuration['bundle_key'])) { Chris@0: $this->lookupBundleKey = $this->configuration['bundle_key']; Chris@0: } Chris@0: if (!empty($this->configuration['bundle'])) { Chris@0: $this->lookupBundle = $this->configuration['bundle']; Chris@0: } Chris@0: if (!empty($this->configuration['entity_type'])) { Chris@0: $this->lookupEntityType = $this->configuration['entity_type']; Chris@0: } Chris@0: Chris@0: if (empty($this->lookupValueKey) || empty($this->lookupBundleKey) || empty($this->lookupBundle) || empty($this->lookupEntityType)) { Chris@0: // See if we can introspect the lookup properties from the destination field. Chris@0: if (!empty($this->migration->getProcess()[$this->destinationBundleKey][0]['default_value'])) { Chris@0: $destinationEntityBundle = $this->migration->getProcess()[$this->destinationBundleKey][0]['default_value']; Chris@0: $fieldConfig = $this->entityManager->getFieldDefinitions($this->destinationEntityType, $destinationEntityBundle)[$destinationProperty]->getConfig($destinationEntityBundle); Chris@0: if ($fieldConfig->getType() != 'entity_reference') { Chris@0: throw new MigrateException('The entity_lookup plugin found no entity reference field.'); Chris@0: } Chris@0: Chris@0: if (empty($this->lookupBundle)) { Chris@0: $handlerSettings = $fieldConfig->getSetting('handler_settings'); Chris@0: $bundles = array_filter((array) $handlerSettings['target_bundles']); Chris@0: if (count($bundles) == 1) { Chris@0: $this->lookupBundle = reset($bundles); Chris@0: } Chris@0: // This was added in 8.1.x is not supported in 8.0.x. Chris@0: elseif (!empty($handlerSettings['auto_create']) && !empty($handlerSettings['auto_create_bundle'])) { Chris@0: $this->lookupBundle = reset($handlerSettings['auto_create_bundle']); Chris@0: } Chris@0: } Chris@0: Chris@0: // Make an assumption that if the selection handler can target more than Chris@0: // one type of entity that we will use the first entity type. Chris@0: $this->lookupEntityType = $this->lookupEntityType ?: reset($this->selectionPluginManager->createInstance($fieldConfig->getSetting('handler'))->getPluginDefinition()['entity_types']); Chris@0: $this->lookupValueKey = $this->lookupValueKey ?: $this->entityManager->getDefinition($this->lookupEntityType)->getKey('label'); Chris@0: $this->lookupBundleKey = $this->lookupBundleKey ?: $this->entityManager->getDefinition($this->lookupEntityType)->getKey('bundle'); Chris@0: } Chris@0: } Chris@0: Chris@0: // If there aren't enough lookup properties available by now, then bail. Chris@0: if (empty($this->lookupValueKey)) { Chris@0: throw new MigrateException('The entity_lookup plugin requires a value_key, none located.'); Chris@0: } Chris@0: if (!empty($this->lookupBundleKey) && empty($this->lookupBundle)) { Chris@0: throw new MigrateException('The entity_lookup plugin found no bundle but destination entity requires one.'); Chris@0: } Chris@0: if (empty($this->lookupEntityType)) { Chris@0: throw new MigrateException('The entity_lookup plugin requires a entity_type, none located.'); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Checks for the existence of some value. Chris@0: * Chris@0: * @param $value Chris@0: * The value to query. Chris@0: * Chris@0: * @return mixed|null Chris@0: * Entity id if the queried entity exists. Otherwise NULL. Chris@0: */ Chris@0: protected function query($value) { Chris@0: // Entity queries typically are case-insensitive. Therefore, we need to Chris@0: // handle case sensitive filtering as a post-query step. By default, it Chris@0: // filters case insensitive. Change to true if that is not the desired Chris@0: // outcome. Chris@0: $ignoreCase = !empty($this->configuration['ignore_case']) ?: FALSE; Chris@0: Chris@0: $multiple = is_array($value); Chris@0: Chris@0: $query = $this->entityManager->getStorage($this->lookupEntityType) Chris@0: ->getQuery() Chris@0: ->condition($this->lookupValueKey, $value, $multiple ? 'IN' : NULL); Chris@0: Chris@0: if ($this->lookupBundleKey) { Chris@0: $query->condition($this->lookupBundleKey, $this->lookupBundle); Chris@0: } Chris@0: $results = $query->execute(); Chris@0: Chris@0: if (empty($results)) { Chris@0: return NULL; Chris@0: } Chris@0: Chris@0: if ($multiple && !empty($this->destinationProperty)) { Chris@0: array_walk($results, function (&$value) { Chris@0: $value = [$this->destinationProperty => $value]; Chris@0: }); Chris@0: Chris@0: return array_values($results); Chris@0: } Chris@0: Chris@0: // By default do a case-sensitive comparison. Chris@0: if (!$ignoreCase) { Chris@0: // Returns the entity's identifier. Chris@0: foreach ($results as $identifier) { Chris@0: if ($value === $this->entityManager->getStorage($this->lookupEntityType)->load($identifier)->{$this->lookupValueKey}->value) { Chris@0: return $identifier; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: return reset($results); Chris@0: } Chris@0: Chris@0: }