class DynamicEntityReferenceWidget in Dynamic Entity Reference 8
Same name and namespace in other branches
- 8.2 src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php \Drupal\dynamic_entity_reference\Plugin\Field\FieldWidget\DynamicEntityReferenceWidget
Plugin implementation of the 'dynamic_entity_reference autocomplete' widget.
Plugin annotation
@FieldWidget(
id = "dynamic_entity_reference_default",
label = @Translation("Autocomplete"),
description = @Translation("An autocomplete text field."),
field_types = {
"dynamic_entity_reference"
}
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\Core\Field\PluginSettingsBase implements DependentPluginInterface, PluginSettingsInterface
- class \Drupal\Core\Field\WidgetBase implements WidgetInterface, ContainerFactoryPluginInterface uses AllowedTagsXssTrait
- class \Drupal\Core\Field\Plugin\Field\FieldWidget\EntityReferenceAutocompleteWidget
- class \Drupal\dynamic_entity_reference\Plugin\Field\FieldWidget\DynamicEntityReferenceWidget
- class \Drupal\Core\Field\Plugin\Field\FieldWidget\EntityReferenceAutocompleteWidget
- class \Drupal\Core\Field\WidgetBase implements WidgetInterface, ContainerFactoryPluginInterface uses AllowedTagsXssTrait
- class \Drupal\Core\Field\PluginSettingsBase implements DependentPluginInterface, PluginSettingsInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of DynamicEntityReferenceWidget
File
- src/
Plugin/ Field/ FieldWidget/ DynamicEntityReferenceWidget.php, line 28
Namespace
Drupal\dynamic_entity_reference\Plugin\Field\FieldWidgetView source
class DynamicEntityReferenceWidget extends EntityReferenceAutocompleteWidget {
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'match_operator' => 'CONTAINS',
'match_limit' => 10,
'size' => 40,
'placeholder' => '',
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$entity = $items
->getEntity();
$referenced_entities = $items
->referencedEntities();
$settings = $this
->getFieldSettings();
$labels = \Drupal::service('entity_type.repository')
->getEntityTypeLabels();
$available = DynamicEntityReferenceItem::getTargetTypes($settings);
$cardinality = $items
->getFieldDefinition()
->getFieldStorageDefinition()
->getCardinality();
$target_type = $items
->get($delta)->target_type ?: reset($available);
// Append the match operation to the selection settings.
$selection_settings = $settings[$target_type]['handler_settings'] + [
'match_operator' => $this
->getSetting('match_operator'),
'match_limit' => $this
->getSetting('match_limit'),
];
$element += [
'#type' => 'entity_autocomplete',
'#target_type' => $target_type,
'#selection_handler' => $settings[$target_type]['handler'],
'#selection_settings' => $selection_settings,
// Dynamic entity reference field items are handling validation themselves
// via the 'ValidDynamicReference' constraint.
'#validate_reference' => FALSE,
'#maxlength' => 1024,
'#default_value' => isset($referenced_entities[$delta]) ? $referenced_entities[$delta] : NULL,
'#size' => $this
->getSetting('size'),
'#placeholder' => $this
->getSetting('placeholder'),
'#element_validate' => array_merge([
[
$this,
'elementValidate',
],
], \Drupal::service('element_info')
->getInfoProperty('entity_autocomplete', '#element_validate', [])),
'#field_name' => $items
->getName(),
];
if ($this
->getSelectionHandlerSetting('auto_create', $target_type)) {
$element['#autocreate'] = [
'bundle' => $this
->getAutocreateBundle($target_type),
'uid' => $entity instanceof EntityOwnerInterface ? $entity
->getOwnerId() : \Drupal::currentUser()
->id(),
];
}
$element['#title'] = $this
->t('Label');
if (count($available) > 1) {
$target_type_element = [
'#type' => 'select',
'#options' => array_intersect_key($labels, array_combine($available, $available)),
'#title' => $this
->t('Entity type'),
'#default_value' => $target_type,
'#weight' => -50,
'#attributes' => [
'class' => [
'dynamic-entity-reference-entity-type',
],
],
];
}
else {
$target_type_element = [
'#type' => 'value',
'#value' => reset($available),
];
}
$form_element = [
'#type' => 'container',
'#attributes' => [
'class' => [
'container-inline',
],
],
'target_type' => $target_type_element,
'target_id' => $element,
'#process' => [
[
$this,
'processFormElement',
],
],
'#attached' => [
'library' => [
'dynamic_entity_reference/drupal.dynamic_entity_reference_widget',
],
'drupalSettings' => [
'dynamic_entity_reference' => [
'auto_complete_paths' => $this
->createAutoCompletePaths($available),
],
],
],
];
// Render field as details.
if ($cardinality == 1) {
$form_element['#type'] = 'details';
$form_element['#title'] = $items
->getFieldDefinition()
->getLabel();
$form_element['#open'] = TRUE;
}
return $form_element;
}
/**
* Adds entity autocomplete paths to a form element.
*
* @param array $element
* The form element.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
* @param array $complete_form
* The complete form structure.
*
* @return array
* The form element.
*/
public static function processFormElement(array &$element, FormStateInterface $form_state, array &$complete_form) {
$name = implode('-', $element['#parents']);
$js_class = Html::cleanCssIdentifier("js-dynamic-entity-reference-{$name}-target_type");
$element['target_type']['#attributes']['data-dynamic-entity-reference'] = $element['target_type']['#attributes']['class'][] = $js_class;
$auto_complete_paths = $element['#attached']['drupalSettings']['dynamic_entity_reference']['auto_complete_paths'];
unset($element['#attached']['drupalSettings']['dynamic_entity_reference']['auto_complete_paths']);
$element['#attached']['drupalSettings']['dynamic_entity_reference'][$js_class] = $auto_complete_paths;
return $element;
}
/**
* {@inheritdoc}
*/
public function elementValidate(&$element, FormStateInterface $form_state, &$form) {
if (!empty($element['#value'])) {
// If this is the default value of the field.
if ($form_state
->hasValue('default_value_input')) {
$values = $form_state
->getValue([
'default_value_input',
$element['#field_name'],
$element['#delta'],
]);
}
else {
$parents = $element['#parents'];
// Remove the 'target_id' key.
array_pop($parents);
$values = $form_state
->getValue($parents);
}
$settings = $this
->getFieldSettings();
$element['#target_type'] = $values['target_type'];
$element['#selection_handler'] = $settings[$values['target_type']]['handler'];
$element['#selection_settings'] = $settings[$values['target_type']]['handler_settings'];
if ($this
->getSelectionHandlerSetting('auto_create', $values['target_type'])) {
$form_object = $form_state
->getFormObject();
$entity = $form_object instanceof EntityFormInterface ? $form_object
->getEntity() : '';
$element['#autocreate'] = [
'bundle' => $this
->getAutocreateBundle($values['target_type']),
'uid' => $entity instanceof EntityOwnerInterface ? $entity
->getOwnerId() : \Drupal::currentUser()
->id(),
];
}
else {
$element['#autocreate'] = NULL;
}
}
}
/**
* Returns the value of a setting for the dynamic entity reference handler.
*
* @param string $setting_name
* The setting name.
* @param string $target_type
* The id of the target entity type.
*
* @return mixed
* The setting value.
*/
protected function getSelectionHandlerSetting($setting_name, $target_type = NULL) {
if ($target_type === NULL) {
return parent::getSelectionHandlerSetting($setting_name);
}
$settings = $this
->getFieldSettings();
return isset($settings[$target_type]['handler_settings'][$setting_name]) ? $settings[$target_type]['handler_settings'][$setting_name] : NULL;
}
/**
* {@inheritdoc}
*/
protected function getAutocreateBundle($target_type = NULL) {
if ($target_type === NULL) {
return parent::getAutocreateBundle();
}
$bundle = NULL;
if ($this
->getSelectionHandlerSetting('auto_create', $target_type)) {
// If the 'target_bundles' setting is restricted to a single choice, we
// can use that.
if (($target_bundles = $this
->getSelectionHandlerSetting('target_bundles', $target_type)) && count($target_bundles) == 1) {
$bundle = reset($target_bundles);
}
else {
// @todo Expose a proper UI for choosing the bundle for autocreated
// entities in https://www.drupal.org/node/2412569.
$bundles = \Drupal::service('entity_type.bundle.info')
->getBundleInfo($target_type);
$bundle = key($bundles);
}
}
return $bundle;
}
/**
* Creates auto complete path for all the given target types.
*
* @param string[] $target_types
* All the referenceable target types.
*
* @return array
* Auto complete paths for all the referenceable target types.
*/
protected function createAutoCompletePaths(array $target_types) {
$auto_complete_paths = [];
$settings = $this
->getFieldSettings();
foreach ($target_types as $target_type) {
// Store the selection settings in the key/value store and pass a hashed
// key in the route parameters.
$selection_settings = $settings[$target_type]['handler_settings'] ?: [];
$selection_settings += [
'match_operator' => $this
->getSetting('match_operator'),
'match_limit' => $this
->getSetting('match_limit'),
];
$data = serialize($selection_settings) . $target_type . $settings[$target_type]['handler'];
$selection_settings_key = Crypt::hmacBase64($data, Settings::getHashSalt());
$key_value_storage = \Drupal::keyValue('entity_autocomplete');
if (!$key_value_storage
->has($selection_settings_key)) {
$key_value_storage
->set($selection_settings_key, $selection_settings);
}
$auto_complete_paths[$target_type] = Url::fromRoute('system.entity_autocomplete', [
'target_type' => $target_type,
'selection_handler' => $settings[$target_type]['handler'],
'selection_settings_key' => $selection_settings_key,
])
->toString();
}
return $auto_complete_paths;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AllowedTagsXssTrait:: |
public | function | Returns a list of tags allowed by AllowedTagsXssTrait::fieldFilterXss(). | |
AllowedTagsXssTrait:: |
public | function | Returns a human-readable list of allowed tags for display in help texts. | |
AllowedTagsXssTrait:: |
public | function | Filters an HTML string to prevent XSS vulnerabilities. | |
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
DynamicEntityReferenceWidget:: |
protected | function | Creates auto complete path for all the given target types. | |
DynamicEntityReferenceWidget:: |
public static | function |
Defines the default settings for this plugin. Overrides EntityReferenceAutocompleteWidget:: |
|
DynamicEntityReferenceWidget:: |
public | function | ||
DynamicEntityReferenceWidget:: |
public | function |
Returns the form for a single field widget. Overrides EntityReferenceAutocompleteWidget:: |
|
DynamicEntityReferenceWidget:: |
protected | function |
Returns the name of the bundle which will be used for autocreated entities. Overrides EntityReferenceAutocompleteWidget:: |
|
DynamicEntityReferenceWidget:: |
protected | function |
Returns the value of a setting for the dynamic entity reference handler. Overrides EntityReferenceAutocompleteWidget:: |
|
DynamicEntityReferenceWidget:: |
public static | function | Adds entity autocomplete paths to a form element. | |
EntityReferenceAutocompleteWidget:: |
public | function |
Assigns a field-level validation error to the right widget sub-element. Overrides WidgetBase:: |
|
EntityReferenceAutocompleteWidget:: |
protected | function | Returns the options for the match operator. | |
EntityReferenceAutocompleteWidget:: |
public | function |
Massages the form values into the format expected for field values. Overrides WidgetBase:: |
1 |
EntityReferenceAutocompleteWidget:: |
public | function |
Returns a form to configure settings for the widget. Overrides WidgetBase:: |
|
EntityReferenceAutocompleteWidget:: |
public | function |
Returns a short summary for the current widget settings. Overrides WidgetBase:: |
|
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
PluginSettingsBase:: |
protected | property | Whether default settings have been merged into the current $settings. | |
PluginSettingsBase:: |
protected | property | The plugin settings injected by third party modules. | |
PluginSettingsBase:: |
public | function |
Calculates dependencies for the configured plugin. Overrides DependentPluginInterface:: |
6 |
PluginSettingsBase:: |
public | function |
Returns the value of a setting, or its default value if absent. Overrides PluginSettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Returns the array of settings, including defaults for missing settings. Overrides PluginSettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Gets the list of third parties that store information. Overrides ThirdPartySettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Gets the value of a third-party setting. Overrides ThirdPartySettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Gets all third-party settings of a given module. Overrides ThirdPartySettingsInterface:: |
|
PluginSettingsBase:: |
protected | function | Merges default settings values into $settings. | |
PluginSettingsBase:: |
public | function |
Informs the plugin that some configuration it depends on will be deleted. Overrides PluginSettingsInterface:: |
3 |
PluginSettingsBase:: |
public | function |
Sets the value of a setting for the plugin. Overrides PluginSettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Sets the settings for the plugin. Overrides PluginSettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Sets the value of a third-party setting. Overrides ThirdPartySettingsInterface:: |
|
PluginSettingsBase:: |
public | function |
Unsets a third-party setting. Overrides ThirdPartySettingsInterface:: |
|
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
WidgetBase:: |
protected | property | The field definition. | |
WidgetBase:: |
protected | property |
The widget settings. Overrides PluginSettingsBase:: |
|
WidgetBase:: |
public static | function | Ajax callback for the "Add another item" button. | |
WidgetBase:: |
public static | function | Submission handler for the "Add another item" button. | |
WidgetBase:: |
public static | function | After-build handler for field elements in a form. | |
WidgetBase:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
5 |
WidgetBase:: |
public | function |
Extracts field values from submitted form values. Overrides WidgetBaseInterface:: |
2 |
WidgetBase:: |
public | function |
Reports field-level validation errors against actual form elements. Overrides WidgetBaseInterface:: |
2 |
WidgetBase:: |
public | function |
Creates a form element for a field. Overrides WidgetBaseInterface:: |
3 |
WidgetBase:: |
protected | function | Special handling to create form elements for multiple values. | 1 |
WidgetBase:: |
protected | function | Generates the form element for a single copy of the widget. | |
WidgetBase:: |
protected | function | Returns the value of a field setting. | |
WidgetBase:: |
protected | function | Returns the array of field settings. | |
WidgetBase:: |
protected | function | Returns the filtered field description. | |
WidgetBase:: |
public static | function |
Retrieves processing information about the widget from $form_state. Overrides WidgetBaseInterface:: |
|
WidgetBase:: |
protected static | function | Returns the location of processing information within $form_state. | |
WidgetBase:: |
protected | function | Returns whether the widget handles multiple values. | |
WidgetBase:: |
public static | function |
Returns if the widget can be used for the provided field. Overrides WidgetInterface:: |
4 |
WidgetBase:: |
protected | function | Returns whether the widget used for default value form. | |
WidgetBase:: |
public static | function |
Stores processing information about the widget in $form_state. Overrides WidgetBaseInterface:: |
|
WidgetBase:: |
public | function |
Constructs a WidgetBase object. Overrides PluginBase:: |
5 |