View source
<?php
namespace Drupal\select_or_other\Plugin\Field\FieldWidget;
use Drupal\Component\Utility\Tags;
use Drupal\Core\Entity\Element\EntityAutocomplete;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\EntityOwnerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
class ReferenceWidget extends WidgetBase implements ContainerFactoryPluginInterface {
protected $entityTypeManager;
protected $bundleInfoService;
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['third_party_settings'], $container
->get('entity_type.manager'), $container
->get('entity_type.bundle.info'));
}
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type = NULL, EntityTypeBundleInfoInterface $bundle_info_service = NULL) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
$this->entityTypeManager = $entity_type;
$this->bundleInfoService = $bundle_info_service;
}
protected static function prepareElementValuesForValidation(array &$element) {
if ($element['#tags']) {
$element['#value'] = Tags::implode($element['#value']);
}
}
protected function getEntityStorage() {
$target_type = $this
->getFieldSetting('target_type');
return $this->entityTypeManager
->getStorage($target_type);
}
protected function getBundleKey() {
$entity_keys = $this
->getEntityStorage()
->getEntityType()
->get('entity_keys');
return $entity_keys['bundle'];
}
protected function getOptions(FieldableEntityInterface $entity = NULL) {
$options = [];
$entity_storage = $this
->getEntityStorage();
$bundle_key = $this
->getBundleKey();
$target_bundles = $this
->getSelectionHandlerSetting('target_bundles');
$properties = [
$bundle_key => $target_bundles,
];
$entities = $entity_storage
->loadByProperties($properties);
foreach ($entities as $entity) {
$options["{$entity->label()} ({$entity->id()})"] = $entity
->label();
}
return $options;
}
protected function prepareSelectedOptions(array $options) {
$prepared_options = [];
$entities = $this
->getEntityStorage()
->loadMultiple($options);
foreach ($entities as $entity) {
$prepared_options[] = "{$entity->label()} ({$entity->id()})";
}
return $prepared_options;
}
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = parent::formElement($items, $delta, $element, $form, $form_state);
$entity = $items
->getEntity();
$element = $element + [
'#target_type' => $this
->getFieldSetting('target_type'),
'#selection_handler' => $this
->getFieldSetting('handler'),
'#selection_settings' => $this
->getFieldSetting('handler_settings'),
'#autocreate' => [
'bundle' => $this
->getAutocreateBundle(),
'uid' => $entity instanceof EntityOwnerInterface ? $entity
->getOwnerId() : \Drupal::currentUser()
->id(),
],
'#validate_reference' => TRUE,
'#tags' => $this
->getFieldSetting('target_type') === 'taxonomy_term',
'#merged_values' => TRUE,
];
$element['#element_validate'] = [
[
get_class($this),
'validateReferenceWidget',
],
];
return $element;
}
protected function getSelectionHandlerSetting($setting_name) {
$settings = $this
->getFieldSetting('handler_settings');
return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL;
}
protected function getAutocreateBundle() {
$bundle = NULL;
if ($this
->getSelectionHandlerSetting('auto_create')) {
if (($target_bundles = $this
->getSelectionHandlerSetting('target_bundles')) && count($target_bundles) == 1) {
$bundle = reset($target_bundles);
}
else {
$bundles = $this->bundleInfoService
->getBundleInfo($this
->getFieldSetting('target_type'));
$bundle = key($bundles);
}
}
return $bundle;
}
public static function validateReferenceWidget(array &$element, FormStateInterface $form_state, array &$complete_form) {
self::prepareElementValuesForValidation($element);
if (!empty($element['#value'])) {
EntityAutocomplete::validateEntityAutocomplete($element, $form_state, $complete_form);
}
}
public static function isApplicable(FieldDefinitionInterface $field_definition) {
$options = $field_definition
->getSettings();
$handler_settings = isset($options['handler_settings']) ? $options['handler_settings'] : NULL;
$handler = \Drupal::service('plugin.manager.entity_reference_selection')
->getInstance($options);
return $handler instanceof SelectionWithAutocreateInterface && isset($handler_settings['auto_create']) && $handler_settings['auto_create'];
}
}