View source
<?php
namespace Drupal\feeds\Feeds\Target;
use Drupal\Component\Transliteration\TransliterationInterface;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\feeds\EntityFinderInterface;
use Drupal\feeds\Exception\EmptyFeedException;
use Drupal\feeds\Exception\ReferenceNotFoundException;
use Drupal\feeds\Exception\TargetValidationException;
use Drupal\feeds\FeedInterface;
use Drupal\feeds\FieldTargetDefinition;
use Drupal\feeds\Plugin\Type\Target\ConfigurableTargetInterface;
use Drupal\feeds\Plugin\Type\Target\FieldTargetBase;
use Drupal\feeds\StateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ConfigEntityReference extends FieldTargetBase implements ConfigurableTargetInterface, ContainerFactoryPluginInterface {
protected $entityTypeManager;
protected $entityFinder;
protected $transliteration;
protected $typedConfigManager;
public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFinderInterface $entity_finder, TransliterationInterface $transliteration, TypedConfigManagerInterface $typed_config_manager) {
$this->entityTypeManager = $entity_type_manager;
$this->entityFinder = $entity_finder;
$this->transliteration = $transliteration;
$this->typedConfigManager = $typed_config_manager;
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_type.manager'), $container
->get('feeds.entity_finder'), $container
->get('transliteration'), $container
->get('config.typed'));
}
protected static function prepareTarget(FieldDefinitionInterface $field_definition) {
$type = $field_definition
->getSetting('target_type');
if (!\Drupal::entityTypeManager()
->getDefinition($type)
->entityClassImplements(ConfigEntityInterface::class)) {
return;
}
return FieldTargetDefinition::createFromFieldDefinition($field_definition)
->addProperty('target_id');
}
public function setTarget(FeedInterface $feed, EntityInterface $entity, $field_name, array $raw_values) {
$values = [];
foreach ($raw_values as $delta => $columns) {
try {
$this
->prepareValue($delta, $columns);
$values[] = $columns;
} catch (ReferenceNotFoundException $e) {
$entity
->get('feeds_item')->hash = NULL;
$feed
->getState(StateInterface::PROCESS)
->setMessage($e
->getFormattedMessage(), 'warning', TRUE);
} catch (EmptyFeedException $e) {
} catch (TargetValidationException $e) {
$this
->addMessage($e
->getFormattedMessage(), 'error');
}
}
if (!empty($values)) {
$entity_target = $this
->getEntityTarget($feed, $entity);
if ($entity_target) {
$item_list = $entity_target
->get($field_name);
$values = array_merge($item_list
->getValue(), $values);
$item_list
->setValue($values);
}
}
}
protected function getPotentialFields() {
$config_entity_type = $this->entityTypeManager
->getDefinition($this
->getEntityType());
$config_name = $config_entity_type
->getConfigPrefix() . '.*';
$definition = $this->typedConfigManager
->getDefinition($config_name);
if (!empty($definition['mapping'])) {
$options = [];
foreach ($definition['mapping'] as $key => $mapper) {
switch ($mapper['type']) {
case 'integer':
case 'label':
case 'string':
case 'text':
case 'uuid':
$options[$key] = $mapper['label'];
break;
}
}
return $options;
}
return [
'id' => $this
->t('ID'),
'uuid' => $this
->t('UUID'),
];
}
protected function getEntityType() {
return $this->settings['target_type'];
}
protected function prepareValue($delta, array &$values) {
if (!isset($values['target_id']) || strlen(trim($values['target_id'])) === 0) {
throw new EmptyFeedException();
}
if ($target_id = $this
->findEntity($this->configuration['reference_by'], $values['target_id'])) {
$values['target_id'] = $target_id;
return;
}
throw new ReferenceNotFoundException($this
->t('Referenced entity not found for field %field with value %target_id.', [
'%target_id' => $values['target_id'],
'%field' => $this->configuration['reference_by'],
]));
}
protected function findEntity(string $field, $search) {
$ids = $this->entityFinder
->findEntities($this
->getEntityType(), $field, $search);
if ($ids) {
return reset($ids);
}
return FALSE;
}
protected function generateMachineName($string) {
$transliterated = $this->transliteration
->transliterate($string, LanguageInterface::LANGCODE_DEFAULT, '_');
$transliterated = mb_strtolower($transliterated);
$transliterated = preg_replace('@[^a-z0-9_.]+@', '_', $transliterated);
return $transliterated;
}
public function defaultConfiguration() {
$config = [
'reference_by' => 'id',
];
return $config;
}
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$options = $this
->getPotentialFields();
foreach ($form_state
->getValues() as $key => $value) {
if (strpos($key, 'target-settings-') === 0) {
list(, , $delta) = explode('-', $key);
break;
}
}
$form['reference_by'] = [
'#type' => 'select',
'#title' => $this
->t('Reference by'),
'#options' => $options,
'#default_value' => $this->configuration['reference_by'],
];
return $form;
}
public function getSummary() {
$options = $this
->getPotentialFields();
$summary = [];
if ($this->configuration['reference_by'] && isset($options[$this->configuration['reference_by']])) {
$summary[] = $this
->t('Reference by: %message', [
'%message' => $options[$this->configuration['reference_by']],
]);
}
else {
$summary[] = $this
->t('Please select a field to reference by.');
}
return $summary;
}
}