pluginreference-2.0.0/src/Plugin/Field/FieldWidget/PluginReferenceSelectWidget.php
src/Plugin/Field/FieldWidget/PluginReferenceSelectWidget.php
<?php
namespace Drupal\pluginreference\Plugin\Field\FieldWidget;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\Attribute\FieldWidget;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldFilteredMarkup;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\OptionsProviderInterface;
use Drupal\pluginreference\PluginTypeHelperInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Plugin implementation of the 'plugin_reference_select' widget.
*/
#[FieldWidget(
id: 'plugin_reference_select',
label: new TranslatableMarkup('Select list'),
field_types: [
'plugin_reference',
],
)]
class PluginReferenceSelectWidget extends WidgetBase {
use PluginReferenceConfigurationFormTrait;
/**
* The plugin type helper.
*
* @var \Drupal\pluginreference\PluginTypeHelperInterface
*/
protected $pluginTypeHelper;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* {@inheritdoc}
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, PluginTypeHelperInterface $plugin_type_helper, AccountProxyInterface $current_user) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
$this->pluginTypeHelper = $plugin_type_helper;
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
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('plugin_reference.plugin_type_helper'),
$container->get('current_user')
);
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'provider_grouping' => TRUE,
] + self::configurationDefaultSettings() + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$elements = parent::settingsForm($form, $form_state);
$elements['provider_grouping'] = [
'#type' => 'checkbox',
'#title' => $this->t('Group per provider'),
'#description' => $this->t('Group the options per provider.'),
'#default_value' => $this->getSetting('provider_grouping'),
];
return $elements + $this->configurationSettingsForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = parent::settingsSummary();
return $summary + $this->configurationSettingsSummary();
}
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element['plugin_id'] = [
'#type' => 'select',
'#default_value' => $items[$delta]->plugin_id ?? NULL,
'#options' => $this->getOptions($items->getEntity()),
'#weight' => -100,
] + $element;
if ($items->getFieldDefinition()->isRequired()) {
$element['plugin_id']['#empty_option'] = $this->t('- Select -');
}
$element = $this->singleConfigurationFormElement($items, $delta, $element, $form, $form_state);
return $element;
}
/**
* Build the options used by this widget.
*
* @param \Drupal\Core\Entity\FieldableEntityInterface $entity
* The entity for which to return options.
*
* @return array
* An array of options.
*/
protected function getOptions(FieldableEntityInterface $entity): array {
$options_provider = $this->fieldDefinition
->getFieldStorageDefinition()
->getOptionsProvider('plugin_id', $entity);
$plugin_options = [];
if ($options_provider instanceof OptionsProviderInterface) {
$plugin_options = $options_provider->getSettableOptions($this->currentUser);
}
$options = [];
if ((bool) $this->getSetting('provider_grouping') === TRUE) {
$plugin_manager = $this->pluginTypeHelper->getPluginManager($this->fieldDefinition->getSetting('target_type'));
if ($plugin_manager instanceof PluginManagerInterface) {
foreach ($plugin_options as $plugin_id => $plugin_option) {
$plugin_definition = $plugin_manager->getDefinition($plugin_id);
$options[$this->pluginTypeHelper->getProviderName($plugin_definition['provider'])][$plugin_id] = $plugin_option;
}
ksort($options);
}
}
else {
$options = $plugin_options;
}
if (!$this->fieldDefinition->isRequired()) {
$options = ['' => $this->t('- None -')] + $options;
}
array_walk_recursive($options, [$this, 'sanitizeLabel']);
return $options;
}
/**
* Sanitizes a string label to display as an option.
*
* @param string $label
* The label to sanitize.
*/
protected function sanitizeLabel(string &$label): void {
// Allow a limited set of HTML tags.
$label = (string) FieldFilteredMarkup::create($label);
}
}
