Commit 1f827db4 authored by mxh's avatar mxh
Browse files

Issue #3323543 by mxh: Add a datetime parameter

parent eb1e0643
Loading
Loading
Loading
Loading
+119 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\parameters\Plugin\Parameter;

use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Datetime\Entity\DateFormat;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Utility\Token;
use Drupal\parameters\Plugin\ParameterBase;
use Drupal\parameters\Plugin\ParameterInterface;
use Drupal\parameters\Plugin\ParameterManager;
use Drupal\parameters\Plugin\PropertyParameterInterface;

/**
 * Defines a date with time as parameter.
 *
 * @Parameter(
 *   id = "datetime",
 *   label = @Translation("Date and time")
 * )
 */
class Datetime extends ParameterBase implements PropertyParameterInterface {

  /**
   * {@inheritdoc}
   */
  protected string $dataType = 'datetime_iso8601';

  /**
   * The token service.
   *
   * @var \Drupal\Core\Utility\Token
   */
  protected Token $token;

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);
    $form['value']['#type'] = 'datetime';
    $form['value']['#default_value'] = !empty($this->configuration['value']) ? DrupalDateTime::createFromDateTime(new \DateTime($this->configuration['value'])) : NULL;
    $form['value']['#date_increment'] = 1;
    $form['value']['#date_timezone'] = date_default_timezone_get();
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    /** @var \DateTime $value */
    $value = $form_state->getValue('value');
    // Always store the datetime in UTC.
    // @see \Drupal\Core\TypedData\Plugin\DataType\DateTimeIso8601
    $value->setTimezone(timezone_open('UTC'));
    $this->configuration['value'] = $value->format('c');
  }

  /**
   * {@inheritdoc}
   */
  public function getPreview(): string {
    if (empty($this->configuration['value'])) {
      return '';
    }

    $datetime = new DrupalDateTime($this->configuration['value']);
    $format = DateFormat::load('long') ?: DateFormat::load('html_datetime');
    return $datetime->format($format->getPattern());
  }

  /**
   * {@inheritdoc}
   */
  public function getProperty(string $name): ?ParameterInterface {
    /** @var \Drupal\Core\TypedData\Type\DateTimeInterface $data */
    $data = $this->getProcessedData();
    $date = $data->getDateTime();

    // Now build up the token and replace it with a value.
    if (strpos($name, '.')) {
      $name = str_replace('.', ':', $name);
    }
    $token = "[date:{$name}]";
    $value = (string) $this->getToken()->replace($token, ['date' => $date->getTimestamp()], [
      'clear' => TRUE,
    ]);

    if ($value === '') {
      if ($name === 'timestamp') {
        $value = $date->getTimestamp();
      }
      elseif (in_array($name, ['timezone', 'tz'], TRUE)) {
        $value = $date->getTimezone()->getName();
      }
    }

    if ($value !== '') {
      return ParameterManager::get()->createInstance('string', ['value' => $value]);
    }

    return NULL;
  }

  /**
   * Get the token service.
   *
   * @return \Drupal\Core\Utility\Token
   *   The token service.
   */
  public function getToken(): Token {
    if (!isset($this->token)) {
      $this->token = \Drupal::token();
    }
    return $this->token;
  }

}