ex_icons-8.x-1.0/src/Plugin/Field/FieldWidget/ExIconSelectWidget.php
src/Plugin/Field/FieldWidget/ExIconSelectWidget.php
<?php
namespace Drupal\ex_icons\Plugin\Field\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Plugin implementation of the 'ex_icon_select' widget.
*
* @FieldWidget(
* id = "ex_icon_select",
* label = @Translation("Icon select"),
* field_types = {
* "ex_icon"
* },
* )
*/
class ExIconSelectWidget extends WidgetBase {
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
/** @var \Drupal\Core\Field\Plugin\Field\FieldType\StringItemBase $item */
$item = $items[$delta];
$element['value'] = [
'#title' => $this->t('Icon'),
'#type' => 'ex_icon_select',
'#default_value' => $item->value,
'#required' => $element['#required'],
];
$element['title'] = [
'#type' => 'textfield',
'#title' => $this->t('Text alternative'),
'#description' => $this->t('Enter a text alternative of the icon for accessibility.'),
'#max_length' => 255,
'#size' => 40,
'#default_value' => $item->title,
'#access' => $this->getFieldSetting('title') != DRUPAL_DISABLED,
'#required' => $this->getFieldSetting('title') === DRUPAL_REQUIRED && $element['#required'],
];
// Post-process the title field to make it conditionally required if an icon
// is selected. Omit the validation on the field edit form, since the field
// settings cannot be saved otherwise.
//
// Validate that title field is filled out (regardless of icon selection)
// when it is a required field.
if (!$this->isDefaultValueWidget($form_state) && $this->getFieldSetting('title') === DRUPAL_REQUIRED) {
$element['#element_validate'][] = [get_called_class(), 'validateTitleElement'];
$element['#element_validate'][] = [get_called_class(), 'validateTitleNoLink'];
if (!$element['title']['#required']) {
// Make title required on the front-end when URI filled-in.
$field_name = $this->fieldDefinition->getName();
$parents = array_merge($element['#field_parents'], [$field_name]);
$selector = $root = array_shift($parents);
if ($parents) {
$selector = $root . '[' . implode('][', $parents) . ']';
}
$element['title']['#states']['required'] = [
':input[name="' . $selector . '[' . $delta . '][value]"]' => ['!value' => FALSE],
];
}
}
// Ensure that an icon is always entered when an optional title field is
// submitted.
if (!$this->isDefaultValueWidget($form_state) && $this->getFieldSetting('title') == DRUPAL_OPTIONAL) {
$element['#element_validate'][] = [get_called_class(), 'validateTitleNoLink'];
}
// If cardinality is 1, ensure a proper label is output for the field.
if ($this->fieldDefinition->getFieldStorageDefinition()->getCardinality() == 1) {
// If the link title is disabled, use the field definition label as the
// title of the icon selection element.
if ($this->getFieldSetting('title') == DRUPAL_DISABLED) {
$element['value']['#title'] = $element['#title'];
// By default the field description is added to the title field. Since
// the title field is disabled, we add the description, if given, to the
// icon selection element instead.
if (!empty($element['#description'])) {
$element['value']['#description'] = $element['#description'];
}
}
// Otherwise wrap everything in a details element.
else {
$element += [
'#type' => 'fieldset',
];
}
}
return $element;
}
/**
* Form element validation handler for the 'title' element.
*
* Conditionally requires the text alternative if an icon value was chosen.
*/
public static function validateTitleElement(&$element, FormStateInterface $form_state, $form) {
if ($element['value']['#value'] !== '' && $element['title']['#value'] === '') {
// We expect the field name placeholder value to be wrapped in t() here,
// so it won't be escaped again as it's already marked safe.
$form_state->setError(
$element['title'],
t('@title field is required if @icon has a selection.', [
'@title' => $element['title']['#title'],
'@icon' => $element['value']['#title'],
])
);
}
}
/**
* Form element validation handler for the 'title' element.
*
* Requires the icon value if a text alternative was entered.
*/
public static function validateTitleNoLink(&$element, FormStateInterface $form_state, $form) {
if ($element['value']['#value'] === '' && $element['title']['#value'] !== '') {
$form_state->setError(
$element['value'],
t('The @icon field is required when the @title field is specified.', [
'@title' => $element['title']['#title'],
'@icon' => $element['value']['#title'],
])
);
}
}
}
