reference_date-1.0.x-dev/src/Plugin/Field/FieldWidget/ReferenceDateComboAutocompleteWidget.php
src/Plugin/Field/FieldWidget/ReferenceDateComboAutocompleteWidget.php
<?php
namespace Drupal\reference_date\Plugin\Field\FieldWidget;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\Plugin\Field\FieldWidget\EntityReferenceAutocompleteWidget;
use Drupal\Core\Form\FormStateInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\ConstraintViolationInterface;
/**
* Defines the 'reference_date_combo' field widget.
*
* @FieldWidget(
* id = "reference_date_combo",
* label = @Translation("Reference Date Combo Autocomplete"),
* field_types = {"reference_date_combo"},
* )
*/
class ReferenceDateComboAutocompleteWidget extends EntityReferenceAutocompleteWidget {
/**
* The date format storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $dateStorage;
/**
* {@inheritdoc}
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityStorageInterface $date_storage) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
$this->dateStorage = $date_storage;
}
/**
* {@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('entity_type.manager')->getStorage('date_format')
);
}
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$original_element = $element;
$element = parent::formElement($items, $delta, $element, $form, $form_state);
$settings = $this->getFieldSettings();
$date_field = $original_element + [
'#type' => 'datetime',
'#date_date_format' => $this->dateStorage->load('html_date')->getPattern(),
'#date_date_element' => 'date',
'#date_date_callbacks' => [],
'#date_time_format' => '',
'#date_time_element' => 'none',
'#date_time_callbacks' => [],
'#date_timezone' => DateTimeItemInterface::STORAGE_TIMEZONE,
'#default_value' => NULL,
];
if ($settings['datetime_type'] === DateTimeItem::DATETIME_TYPE_DATETIME) {
$date_field['#date_time_element'] = 'time';
$date_field['#date_time_format'] = $this->dateStorage->load('html_time')->getPattern();
$date_field['##date_timezone'] = date_default_timezone_get();
}
$element['value'] = [
'#title' => $this->t('Start Date'),
] + $date_field;
if (isset($items[$delta]->date)) {
$element['value']['#default_value'] = $this->createDefaultValue($items[$delta]->date, $element['value']['#date_timezone']);
}
if ($settings['end_date']) {
$element['end_value'] = [
'#title' => $this->t('End Date'),
] + $date_field;
if (isset($items[$delta]->end_date)) {
$element['end_value']['#default_value'] = $this->createDefaultValue($items[$delta]->end_date, $element['end_value']['#date_timezone']);
}
}
$element['#theme_wrappers'] = ['container', 'form_element'];
$element['#attributes']['class'][] = 'reference-date-combo';
$element['#attributes']['class'][] = 'reference-date-combo--autocomplete';
$element['#attached']['library'][] = 'reference_date/reference_date_combo';
return $element;
}
/**
* {@inheritdoc}
*/
public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) {
return isset($violation->arrayPropertyPath[0]) ? $element[$violation->arrayPropertyPath[0]] : $element;
}
/**
* {@inheritdoc}
*/
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
$values = parent::massageFormValues($values, $form, $form_state);
$datetime_type = $this->getFieldSetting('datetime_type');
if ($datetime_type === DateTimeItem::DATETIME_TYPE_DATE) {
$storage_format = DateTimeItemInterface::DATE_STORAGE_FORMAT;
}
else {
$storage_format = DateTimeItemInterface::DATETIME_STORAGE_FORMAT;
}
$storage_timezone = new \DateTimezone(DateTimeItemInterface::STORAGE_TIMEZONE);
foreach ($values as &$item) {
if (!empty($item['value']) && $item['value'] instanceof DrupalDateTime) {
// Adjust the date for storage.
$item['value'] = $item['value']->setTimezone($storage_timezone)->format($storage_format);
}
if (!empty($item['end_value']) && $item['end_value'] instanceof DrupalDateTime) {
// Adjust the date for storage.
$item['end_value'] = $item['end_value']->setTimezone($storage_timezone)->format($storage_format);
}
}
return $values;
}
/**
* Creates a date object for use as a default value.
*
* This will take a default value, apply the proper timezone for display in
* a widget, and set the default time for date-only fields.
*
* @param \Drupal\Core\Datetime\DrupalDateTime $date
* The UTC default date.
* @param string $timezone
* The timezone to apply.
*
* @return \Drupal\Core\Datetime\DrupalDateTime
* A date object for use as a default value in a field widget.
*/
protected function createDefaultValue(DrupalDateTime $date, $timezone) {
// The date was created and verified during field_load(), so it is safe to
// use without further inspection.
if ($this->getFieldSetting('datetime_type') === DateTimeItem::DATETIME_TYPE_DATE) {
$date->setDefaultDateTime();
}
$date->setTimezone(new \DateTimeZone($timezone));
return $date;
}
}
