class EntityLookup in Migrate Plus 8.3
Same name and namespace in other branches
- 8.5 src/Plugin/migrate/process/EntityLookup.php \Drupal\migrate_plus\Plugin\migrate\process\EntityLookup
- 8.2 src/Plugin/migrate/process/EntityLookup.php \Drupal\migrate_plus\Plugin\migrate\process\EntityLookup
- 8.4 src/Plugin/migrate/process/EntityLookup.php \Drupal\migrate_plus\Plugin\migrate\process\EntityLookup
This plugin looks for existing entities.
@MigrateProcessPlugin( id = "entity_lookup", handle_multiples = TRUE )
In its most simple form, this plugin needs no configuration. However, if the lookup properties cannot be determined through introspection, define them via configuration.
Example usage with minimal configuration:
destination:
plugin: 'entity:node'
process:
type:
plugin: default_value
default_value: page
field_tags:
plugin: entity_lookup
source: tags
Example usage with full configuration:
field_tags:
plugin: entity_lookup
source: tags
value_key: name
bundle_key: vid
bundle: tags
entity_type: taxonomy_term
ignore_case: true
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\migrate\ProcessPluginBase implements MigrateProcessInterface
- class \Drupal\migrate_plus\Plugin\migrate\process\EntityLookup implements ContainerFactoryPluginInterface
- class \Drupal\migrate\ProcessPluginBase implements MigrateProcessInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of EntityLookup
File
- src/
Plugin/ migrate/ process/ EntityLookup.php, line 52
Namespace
Drupal\migrate_plus\Plugin\migrate\processView source
class EntityLookup extends ProcessPluginBase implements ContainerFactoryPluginInterface {
/** @var \Drupal\Core\Entity\EntityManagerInterface */
protected $entityManager;
/** @var \Drupal\migrate\Plugin\MigrationInterface */
protected $migration;
/** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface */
protected $selectionPluginManager;
/** @var string */
protected $destinationEntityType;
/** @var string|bool */
protected $destinationBundleKey;
/** @var string */
protected $lookupValueKey;
/** @var string */
protected $lookupBundleKey;
/** @var string */
protected $lookupBundle;
/** @var string */
protected $lookupEntityType;
/** @var string */
protected $destinationProperty;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $pluginId, $pluginDefinition, MigrationInterface $migration, EntityManagerInterface $entityManager, SelectionPluginManagerInterface $selectionPluginManager) {
parent::__construct($configuration, $pluginId, $pluginDefinition);
$this->migration = $migration;
$this->entityManager = $entityManager;
$this->selectionPluginManager = $selectionPluginManager;
$pluginIdParts = explode(':', $this->migration
->getDestinationPlugin()
->getPluginId());
$this->destinationEntityType = empty($pluginIdParts[1]) ?: $pluginIdParts[1];
$this->destinationBundleKey = !$this->destinationEntityType ?: $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) {
// In case of subfields ('field_reference/target_id'), extract the field
// name only.
$parts = explode('/', $destinationProperty);
$destinationProperty = reset($parts);
$this
->determineLookupProperties($destinationProperty);
$this->destinationProperty = isset($this->configuration['destination_field']) ? $this->configuration['destination_field'] : NULL;
return $this
->query($value);
}
/**
* Determine the lookup 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 determineLookupProperties($destinationProperty) {
if (!empty($this->configuration['value_key'])) {
$this->lookupValueKey = $this->configuration['value_key'];
}
if (!empty($this->configuration['bundle_key'])) {
$this->lookupBundleKey = $this->configuration['bundle_key'];
}
if (!empty($this->configuration['bundle'])) {
$this->lookupBundle = $this->configuration['bundle'];
}
if (!empty($this->configuration['entity_type'])) {
$this->lookupEntityType = $this->configuration['entity_type'];
}
if (empty($this->lookupValueKey) || empty($this->lookupBundleKey) || empty($this->lookupBundle) || empty($this->lookupEntityType)) {
// See if we can introspect the lookup 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);
switch ($fieldConfig
->getType()) {
case 'entity_reference':
if (empty($this->lookupBundle)) {
$handlerSettings = $fieldConfig
->getSetting('handler_settings');
$bundles = array_filter((array) $handlerSettings['target_bundles']);
if (count($bundles) == 1) {
$this->lookupBundle = reset($bundles);
}
elseif (!empty($handlerSettings['auto_create']) && !empty($handlerSettings['auto_create_bundle'])) {
$this->lookupBundle = 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->lookupEntityType = $this->lookupEntityType ?: reset($this->selectionPluginManager
->createInstance($fieldConfig
->getSetting('handler'))
->getPluginDefinition()['entity_types']);
$this->lookupValueKey = $this->lookupValueKey ?: $this->entityManager
->getDefinition($this->lookupEntityType)
->getKey('label');
$this->lookupBundleKey = $this->lookupBundleKey ?: $this->entityManager
->getDefinition($this->lookupEntityType)
->getKey('bundle');
break;
case 'file':
case 'image':
$this->lookupEntityType = 'file';
$this->lookupValueKey = $this->lookupValueKey ?: 'uri';
break;
default:
throw new MigrateException('Destination field type ' . $fieldConfig
->getType() . 'is not a recognized reference type.');
}
}
}
// If there aren't enough lookup properties available by now, then bail.
if (empty($this->lookupValueKey)) {
throw new MigrateException('The entity_lookup plugin requires a value_key, none located.');
}
if (!empty($this->lookupBundleKey) && empty($this->lookupBundle)) {
throw new MigrateException('The entity_lookup plugin found no bundle but destination entity requires one.');
}
if (empty($this->lookupEntityType)) {
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|null
* Entity id if the queried entity exists. Otherwise NULL.
*/
protected function query($value) {
// Entity queries typically are case-insensitive. Therefore, we need to
// handle case sensitive filtering as a post-query step. By default, it
// filters case insensitive. Change to true if that is not the desired
// outcome.
$ignoreCase = !empty($this->configuration['ignore_case']) ?: FALSE;
$multiple = is_array($value);
$query = $this->entityManager
->getStorage($this->lookupEntityType)
->getQuery()
->condition($this->lookupValueKey, $value, $multiple ? 'IN' : NULL);
if ($this->lookupBundleKey) {
$query
->condition($this->lookupBundleKey, $this->lookupBundle);
}
$results = $query
->execute();
if (empty($results)) {
return NULL;
}
// By default do a case-sensitive comparison.
if (!$ignoreCase) {
// Returns the entity's identifier.
foreach ($results as $k => $identifier) {
$result_value = $this->entityManager
->getStorage($this->lookupEntityType)
->load($identifier)->{$this->lookupValueKey}->value;
if ($multiple && !in_array($result_value, $value, TRUE) || !$multiple && $result_value !== $value) {
unset($results[$k]);
}
}
}
if ($multiple && !empty($this->destinationProperty)) {
array_walk($results, function (&$value) {
$value = [
$this->destinationProperty => $value,
];
});
}
return $multiple ? array_values($results) : reset($results);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
EntityLookup:: |
protected | property | @var string|bool | |
EntityLookup:: |
protected | property | @var string | |
EntityLookup:: |
protected | property | @var string | |
EntityLookup:: |
protected | property | @var \Drupal\Core\Entity\EntityManagerInterface | |
EntityLookup:: |
protected | property | @var string | |
EntityLookup:: |
protected | property | @var string | |
EntityLookup:: |
protected | property | @var string | |
EntityLookup:: |
protected | property | @var string | |
EntityLookup:: |
protected | property | @var \Drupal\migrate\Plugin\MigrationInterface | |
EntityLookup:: |
protected | property | @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface | |
EntityLookup:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
|
EntityLookup:: |
protected | function | Determine the lookup properties from config or target field configuration. | |
EntityLookup:: |
protected | function | Checks for the existence of some value. | |
EntityLookup:: |
public | function |
Performs the associated process. Overrides ProcessPluginBase:: |
1 |
EntityLookup:: |
public | function |
Constructs a \Drupal\Component\Plugin\PluginBase object. Overrides PluginBase:: |
|
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
ProcessPluginBase:: |
public | function |
Indicates whether the returned value requires multiple handling. Overrides MigrateProcessInterface:: |
3 |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |