datafield-1.x-dev/src/Plugin/DataField/FieldWidget/EntityReferenceAutocompleteWidget.php
src/Plugin/DataField/FieldWidget/EntityReferenceAutocompleteWidget.php
<?php
namespace Drupal\datafield\Plugin\DataField\FieldWidget;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\Attribute\FieldWidget;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\datafield\Plugin\DataFieldWidgetInterface;
use Drupal\user\UserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Plugin implementation of the 'entity_reference_autocomplete' widget.
*/
#[FieldWidget(
id: 'entity_reference_autocomplete',
label: new TranslatableMarkup('Autocomplete'),
description: new TranslatableMarkup('An autocomplete text field.'),
field_types: ['entity_reference'],
)]
class EntityReferenceAutocompleteWidget implements DataFieldWidgetInterface, ContainerFactoryPluginInterface {
use StringTranslationTrait;
/**
* Constructs a EntityReferenceAutocompleteWidget object.
*
* @param string $plugin_id
* The plugin_id for the formatter.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param mixed $field_definition
* The definition of the field to which the formatter is associated.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* Entity manager service.
* @param \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface $selectionManager
* Entity reference selection service.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request.
* @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $keyValue
* The key value service.
*/
public function __construct($plugin_id, $plugin_definition, $field_definition, protected EntityTypeManagerInterface $entityTypeManager, protected readonly SelectionPluginManagerInterface $selectionManager, protected readonly Request $request, protected KeyValueFactoryInterface $keyValue,) {
unset($plugin_id, $plugin_definition, $field_definition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $configuration, $plugin_id, $plugin_definition) {
return new static(
$plugin_id,
$plugin_definition,
$configuration,
$container->get('entity_type.manager'),
$container->get('plugin.manager.entity_reference_selection'),
$container->get('request_stack')->getCurrentRequest(),
$container->get('keyvalue'),
);
}
/**
* {@inheritdoc}
*/
public function getFormElement(&$element, $item, $setting) {
$element['#type'] = 'entity_autocomplete';
$element['#tag'] = FALSE;
$element['#maxlength'] = 1024;
$element['#placeholder'] = implode(' ', [
$this->t('Typing'),
$element["#field_settings"]["label"] ?? '',
]);
if (!empty($element["#default_value"])) {
$entity_id = FALSE;
$storageEntity = $this->entityTypeManager->getStorage($element["#entity_type"]);
if (is_numeric($element["#default_value"])) {
$entity_id = $element["#default_value"];
}
if (!$entity_id && is_string($element["#default_value"])) {
$result = preg_match('/\((\d+)\)$/', trim($element["#default_value"]), $matches);
if ($result > 0) {
$entity_id = $matches[$result];
}
elseif (!empty($element["#default_value"])) {
$match_operator = 'CONTAINS';
$selection_handler = 'default';
$target_bundles = [$element['#bundle']];
if ($element["#entity_type"] == 'user') {
$selection_handler = 'default:user';
$target_bundles = NULL;
}
$options = [
'target_type' => $element["#entity_type"],
'handler' => $selection_handler,
'match_operator' => $match_operator,
'target_bundles' => $target_bundles,
'options_view' => [
'target_type' => $element["#entity_type"],
'entity' => $storageEntity,
'target_bundles' => [$element['#bundle']],
],
];
$handler = $this->selectionManager->getInstance($options);
$entity_labels = $handler->getReferenceableEntities($element["#default_value"], $match_operator, 1);
foreach ($entity_labels as $values) {
foreach ($values as $entity_id => $label) {
break;
}
}
}
}
if (!empty($entity_id) && is_numeric($entity_id)) {
$entity = $storageEntity->load($entity_id);
$element["#default_value"] = $entity;
}
}
return $element;
}
/**
* {@inheritdoc}
*/
public function massageFormValues($value, array $form, FormStateInterface $form_state) {
if (!empty($value[0]["target_id"])) {
$value = (int) $value[0]["target_id"];
}
if (isset($value["entity"]) && !empty($form["#value_origin"])) {
$entity = $value["entity"] ?? $value;
if ($entity instanceof UserInterface) {
$name = $form['#value_origin'] ?? '';
$entity->setUsername($name);
$entity->activate();
$host = $this->request->getHost();
$email = preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($name, ENT_QUOTES, 'UTF-8'));
$email = str_replace(' ', '.', $email) . '@' . $host;
$entity->setEmail($email);
$entity->save();
return $entity->id();
}
$label_field = $entity->getEntityType()->getKey('label');
if ($label_field) {
$entity->set($label_field, $form['#value_origin']);
}
$entity->save();
return $entity->id();
}
if (is_numeric($value)) {
return $value;
}
if (is_string($value)) {
$result = preg_match('/\((\d+)\)$/', $value, $matches);
if ($result > 0) {
$value = $matches[$result];
}
}
return $value;
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
$options['autocreate'] = TRUE;
return $options;
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$widget_settings = $form['#settings'];
return [
'autocreate' => [
'#type' => 'checkbox',
'#title' => $this->t('Auto create entity'),
'#default_value' => $widget_settings['autocreate'] ?? self::defaultSettings()['autocreate'],
],
];
}
}
