EntityLookup.php in Migrate Plus 8.5
File
src/Plugin/migrate/process/EntityLookup.php
View source
<?php
namespace Drupal\migrate_plus\Plugin\migrate\process;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;
class EntityLookup extends ProcessPluginBase implements ContainerFactoryPluginInterface {
protected $entityTypeManager;
protected $entityFieldManager;
protected $migration;
protected $selectionPluginManager;
protected $destinationEntityType;
protected $destinationBundleKey;
protected $lookupValueKey;
protected $lookupBundleKey;
protected $lookupBundle;
protected $lookupEntityType;
protected $destinationProperty;
protected $accessCheck = TRUE;
public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition, MigrationInterface $migration = NULL) {
$instance = new static($configuration, $pluginId, $pluginDefinition);
$instance->migration = $migration;
$instance->entityTypeManager = $container
->get('entity_type.manager');
$instance->entityFieldManager = $container
->get('entity_field.manager');
$instance->selectionPluginManager = $container
->get('plugin.manager.entity_reference_selection');
$pluginIdParts = explode(':', $instance->migration
->getDestinationPlugin()
->getPluginId());
$instance->destinationEntityType = empty($pluginIdParts[1]) ? NULL : $pluginIdParts[1];
$instance->destinationBundleKey = $instance->destinationEntityType ? $instance->entityTypeManager
->getDefinition($instance->destinationEntityType)
->getKey('bundle') : NULL;
return $instance;
}
public function transform($value, MigrateExecutableInterface $migrateExecutable, Row $row, $destinationProperty) {
if (gettype($value) === 'array' && count($value) === 0) {
return [];
}
$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);
}
protected function determineLookupProperties($destinationProperty) {
if (isset($this->configuration['access_check'])) {
$this->accessCheck = $this->configuration['access_check'];
}
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)) {
if (!empty($this->migration
->getProcess()[$this->destinationBundleKey][0]['default_value'])) {
$destinationEntityBundle = $this->migration
->getProcess()[$this->destinationBundleKey][0]['default_value'];
$fieldConfig = $this->entityFieldManager
->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']);
}
}
$fieldHandler = $fieldConfig
->getSetting('handler');
$selection = $this->selectionPluginManager
->createInstance($fieldHandler);
$this->lookupEntityType = $this->lookupEntityType ?: reset($selection
->getPluginDefinition()['entity_types']);
$this->lookupValueKey = $this->lookupValueKey ?: $this->entityTypeManager
->getDefinition($this->lookupEntityType)
->getKey('label');
$this->lookupBundleKey = $this->lookupBundleKey ?: $this->entityTypeManager
->getDefinition($this->lookupEntityType)
->getKey('bundle');
break;
case 'file':
case 'image':
$this->lookupEntityType = 'file';
$this->lookupValueKey = $this->lookupValueKey ?: 'uri';
break;
default:
throw new MigrateException(sprintf('Destination field type %s is not a recognized reference type.', $fieldConfig
->getType()));
}
}
}
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.');
}
}
protected function query($value) {
$ignoreCase = !empty($this->configuration['ignore_case']) ?: FALSE;
$multiple = is_array($value);
$query = $this->entityTypeManager
->getStorage($this->lookupEntityType)
->getQuery()
->accessCheck($this->accessCheck)
->condition($this->lookupValueKey, $value, $multiple ? 'IN' : NULL);
if ($multiple) {
$query
->sort($this->lookupValueKey, 'DESC');
}
if ($this->lookupBundleKey) {
$query
->condition($this->lookupBundleKey, $this->lookupBundle);
}
$results = $query
->execute();
if (empty($results)) {
return NULL;
}
if (!$ignoreCase) {
foreach ($results as $k => $identifier) {
$entity = $this->entityTypeManager
->getStorage($this->lookupEntityType)
->load($identifier);
$result_value = $entity instanceof ConfigEntityInterface ? $entity
->get($this->lookupValueKey) : $entity
->get($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);
}
}