datafield-1.x-dev/src/Plugin/DataField/FieldWidget/YearWidget.php
src/Plugin/DataField/FieldWidget/YearWidget.php
<?php
namespace Drupal\datafield\Plugin\DataField\FieldWidget;
use Drupal\Component\Datetime\DateTimePlus;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Field\Attribute\FieldWidget;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\datafield\Plugin\DataField\FieldType\DateItem;
use Drupal\datafield\Plugin\DataFieldWidgetInterface;
use Drupal\datafield\Plugin\Field\FieldType\DataFieldItem;
/**
* Plugin implementation of the 'datetime_default' widget.
*/
#[FieldWidget(
id: 'year',
label: new TranslatableMarkup("Year"),
field_types: ['date', 'datetime_iso8601'],
)]
class YearWidget implements DataFieldWidgetInterface {
use StringTranslationTrait;
/**
* {@inheritdoc}
*/
public function getFormElement(&$element, $item = NULL, $setting = []) {
$year = !empty($element["#default_value"]) ? (int) $element["#default_value"] : date('Y');
if (is_numeric($element["#default_value"]) && $element["#default_value"] > 9999) {
$element["#default_value"] = $year = date('Y', $element["#default_value"]);
}
$startYear = $element["#field_settings"]["min"] ?? $year - 20;
$endYear = $element["#field_settings"]["max"] ?? $year + 10;
$element['#type'] = $element["#widget_settings"]["target_type"] ?? 'select';
$element['#process_default_value'] = FALSE;
$element["#min"] = $startYear;
$element["#max"] = $endYear;
$element['#step'] = 1;
$years = range($startYear, $endYear);
switch ($element['#type']) {
case 'select':
$element['#options'] = array_combine($years, $years);
$element['#empty_option'] = $this->t('- None -');
return $element;
case 'number':
$element['#attributes']['data-bs-toggle'] = 'tooltip';
$element['#attributes']['data-bs-title'] = $element['#default_value'] ?? '';
$element['#attributes']['title'] = $element['#default_value'];
$element['#attributes']['class'][] = 'w-auto';
$element['#attributes']['min'] = 0;
$element['#maxlength'] = 4;
$element['#attached']['library'][] = 'datafield/tooltip';
return $element;
case 'range':
$element['#attributes']['data-bs-toggle'] = 'tooltip';
$element['#attributes']['data-bs-title'] = $element['#default_value'] ?? '';
$element['#attributes']['title'] = $element['#default_value'];
$element['#description'] = $element['#default_value'] . ' ';
$element['#attached']['library'][] = 'datafield/tooltip';
return $element;
case 'datalist':
$idDatalist = $element['#field_name'] . '-' . $element['#machine_name'];
$element['#type'] = 'textfield';
$element['#attributes']['list'] = $idDatalist;
$element['#attributes']['class'][] = 'datalistfield w-auto';
$element['#attributes']['min'] = 0;
$element['#maxlength'] = 4;
$element['#attributes']['autocomplete'] = 'off';
$element['#attached']['drupalSettings']['datalistfield'][$idDatalist] = array_combine($years, $years);
$element['#attached']['library'][] = 'datafield/datalistfield';
return $element;
}
$element['#title'] = '';
$element['#date_part_order'] = ['year'];
$element['#date_date_format'] = 'Y';
$element['#date_date_element'] = 'year';
$element['#date_time_element'] = 'none';
$element['#date_year_range'] = "$startYear:$endYear";
if (!empty($element["#min"]) && !empty($element["#max"])) {
$element['#date_year_range'] = implode(':', [
$element["#min"],
$element["#max"],
]);
}
if (empty($element["#default_value"]) && !empty($element["#field_settings"]["default_date_type"])) {
$relativeDate = DateItem::DEFAULT_VALUE_NOW;
if ($element["#field_settings"]["default_date_type"] == DateItem::DEFAULT_VALUE_CUSTOM) {
$relativeDate = $element["#field_settings"]["default_date"];
}
if (!empty($relativeDate)) {
$date = new DrupalDateTime($relativeDate, date_default_timezone_get());
$format = 'Y';
$element["#default_value"] = $date->format($format);
}
}
if (!empty($element["#default_value"]) && is_numeric($element["#default_value"])) {
$element['#default_value'] = DrupalDateTime::createFromFormat('Y', $element['#default_value']);
}
}
/**
* Creates date object for a given subfield using storage timezone.
*/
public function createDate($element = []): ?DateTimePlus {
$date = NULL;
if ($value = $element["#default_value"]) {
$storage = $element["#field_storage"];
$dateType = $storage['datetime_type'];
$is_date_only = $dateType == 'date';
if ($dateType == 'timestamp') {
if ($storage["type"] == 'date') {
$value = strtotime($value);
}
$date = DrupalDateTime::createFromTimestamp($value, DataFieldItem::DATETIME_STORAGE_TIMEZONE);
}
else {
$format = $is_date_only ? DataFieldItem::DATETIME_DATE_STORAGE_FORMAT : DataFieldItem::DATETIME_DATETIME_STORAGE_FORMAT;
if ($storage["type"] == 'date') {
switch ($dateType) {
case 'datetime':
$format = 'Y-m-d H:i:s';
break;
case 'time':
$format = 'H:i:s';
break;
case 'year':
$format = 'Y';
break;
}
}
$date = DrupalDateTime::createFromFormat($format, $value, DataFieldItem::DATETIME_STORAGE_TIMEZONE);
}
if ($is_date_only) {
$date->setDefaultDateTime();
}
}
return $date;
}
/**
* {@inheritdoc}
*/
public function massageFormValues($date, array $form, FormStateInterface $form_state) {
if (empty($date)) {
return $date;
}
$storage_format = is_object($date) ? 'Y-m-d' : 'Y';
$datetime_type = $form["#storage_settings"]["datetime_type"];
if ($datetime_type == 'year') {
$storage_format = 'Y';
}
if (in_array($datetime_type, ['date', 'datetime'])) {
$storage_format = 'Y-m-d';
}
if (is_string($date)) {
$date = strtotime($date);
}
if (is_array($date)) {
$date = current($date);
}
if (is_numeric($date)) {
$date = DrupalDateTime::createFromTimestamp($date);
}
$value = $date->format($storage_format);
return $value;
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'type' => 'year',
'target_type' => 'datelist',
];
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$widget_settings = $form['#settings'];
return [
'target_type' => [
'#type' => 'select',
'#title' => $this->t('Type for year'),
'#options' => [
'datelist' => $this->t('Date list'),
'number' => $this->t('Number'),
'range' => $this->t('Range number'),
'datalist' => $this->t('Data list'),
'select' => $this->t('Select list'),
],
'#default_value' => $widget_settings['target_type'] ?? $widget_settings['type'],
],
];
}
/**
* {@inheritdoc}
*/
public function settingsSummary($settings = []) {
$summary = [];
$settings += self::defaultSettings();
$summary[] = $this->t('Type: @type', ['@type' => $settings['target_type']]);
return $summary;
}
}
