recurring_events-2.0.x-dev/src/Plugin/Field/FieldType/YearlyRecurringDate.php

src/Plugin/Field/FieldType/YearlyRecurringDate.php
<?php

declare(strict_types=1);

namespace Drupal\recurring_events\Plugin\Field\FieldType;

use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Field\Attribute\FieldType;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\recurring_events\Entity\EventSeries;

/**
 * Plugin implementation of the 'yearly_recurring_date' field type.
 */
#[FieldType(
  id: "yearly_recurring_date",
  label: new TranslatableMarkup("Yearly Event"),
  description: new TranslatableMarkup("Stores a yearly recurring date configuration"),
  default_widget: "yearly_recurring_date",
  default_formatter: "",
  no_ui: TRUE,
)]
class YearlyRecurringDate extends MonthlyRecurringDate {

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    $schema = parent::schema($field_definition);

    $schema['columns']['year_interval'] = [
      'type' => 'int',
      'unsigned' => TRUE,
      'not null' => TRUE,
    ];

    $schema['columns']['months'] = [
      'type' => 'varchar',
      'length' => 255,
      'not null' => TRUE,
    ];

    return $schema;
  }

  /**
   * {@inheritdoc}
   */
  public function isEmpty() {
    $interval = $this->get('year_interval')->getValue();
    $months = $this->get('months')->getValue();
    return parent::isEmpty() && empty($interval) && empty($months);
  }

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties = parent::propertyDefinitions($field_definition);

    $properties['year_interval'] = DataDefinition::create('integer')
      ->setLabel(t('Year interval'))
      ->setDescription(t('Number of years between occurrences'));

    $properties['months'] = DataDefinition::create('string')
      ->setLabel(t('Months'))
      ->setDescription(t('The months in which the event occurs'));

    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public static function convertEntityConfigToArray(EventSeries $event) {
    $config = [];
    $config['start_date'] = $event->getYearlyStartDate();
    $config['end_date'] = $event->getYearlyEndDate();
    $config['time'] = strtoupper($event->getYearlyStartTime());
    $config['end_time'] = strtoupper($event->getYearlyEndTime());
    $config['duration'] = $event->getYearlyDuration();
    $config['duration_or_end_time'] = $event->getYearlyDurationOrEndTime();
    $config['monthly_type'] = $event->getYearlyType();

    switch ($event->getYearlyType()) {
      case 'weekday':
        $config['day_occurrence'] = $event->getYearlyDayOccurrences();
        $config['days'] = $event->getYearlyDays();
        break;

      case 'monthday':
        $config['day_of_month'] = $event->getYearlyDayOfMonth();
        break;
    }

    $config['year_interval'] = $event->getYearlyInterval();
    $config['months'] = $event->getYearlyMonths();

    return $config;
  }

  /**
   * {@inheritdoc}
   */
  public static function convertFormConfigToArray(FormStateInterface $form_state) {
    $config = [];

    $userTimezone = new \DateTimeZone(date_default_timezone_get());
    $userInput = $form_state->getValues();

    $time = $userInput['yearly_recurring_date'][0]['time'];
    if (is_array($time)) {
      $temp = DrupalDateTime::createFromFormat('H:i:s', $time['time']);
      $time = $temp->format('h:i A');
    }
    $timeParts = static::convertTimeTo24hourFormat($time);
    $timestamp = implode(':', $timeParts);

    $userInput['yearly_recurring_date'][0]['value']->setTimezone($userTimezone);
    $startTimestamp = $userInput['yearly_recurring_date'][0]['value']->format('Y-m-d') . 'T' . $timestamp;
    $startDate = DrupalDateTime::createFromFormat(DateTimeItemInterface::DATETIME_STORAGE_FORMAT, $startTimestamp, $userTimezone);
    $startDate->setTime(0, 0, 0);

    $endTime = $userInput['yearly_recurring_date'][0]['end_time']['time'];
    if (is_array($endTime)) {
      $temp = DrupalDateTime::createFromFormat('H:i:s', $endTime['time']);
      $endTime = $temp->format('h:i A');
    }
    $endTimeParts = static::convertTimeTo24hourFormat($endTime);
    $endTimestamp = implode(':', $endTimeParts);

    $userInput['yearly_recurring_date'][0]['end_value']->setTimezone($userTimezone);
    $endTimestamp = $userInput['yearly_recurring_date'][0]['end_value']->format('Y-m-d') . 'T' . $endTimestamp;
    $endDate = DrupalDateTime::createFromFormat(DateTimeItemInterface::DATETIME_STORAGE_FORMAT, $endTimestamp, $userTimezone);
    $endDate->setTime(0, 0, 0);

    $config['start_date'] = $startDate;
    $config['end_date'] = $endDate;

    $config['time'] = strtoupper($time);
    $config['end_time'] = strtoupper($endTime);
    $config['duration'] = $userInput['yearly_recurring_date'][0]['duration'];
    $config['duration_or_end_time'] = $userInput['yearly_recurring_date'][0]['duration_or_end_time'];
    $config['monthly_type'] = $userInput['yearly_recurring_date'][0]['type'];

    switch ($config['monthly_type']) {
      case 'weekday':
        $config['day_occurrence'] = array_filter(array_values($userInput['yearly_recurring_date'][0]['day_occurrence']));
        $config['days'] = array_filter(array_values($userInput['yearly_recurring_date'][0]['days']));
        break;

      case 'monthday':
        $config['day_of_month'] = array_filter(array_values($userInput['yearly_recurring_date'][0]['day_of_month']));
        break;
    }

    $config['year_interval'] = $userInput['yearly_recurring_date'][0]['year_interval'];
    $config['months'] = array_filter(array_values($userInput['yearly_recurring_date'][0]['months']));

    return $config;
  }

  /**
   * {@inheritdoc}
   */
  public static function buildDiffArray(array $entity_config, array $form_config) {
    $diff = parent::buildDiffArray($entity_config, $form_config);

    if ($entity_config['type'] === 'yearly_recurring_date') {
      if (($entity_config['monthly_type'] ?? '') !== ($form_config['monthly_type'] ?? '')) {
        $diff['monthly_type'] = [
          'label' => t('Monthly Type'),
          'stored' => $entity_config['monthly_type'] ?? '',
          'override' => $form_config['monthly_type'] ?? '',
        ];
      }
      if ($entity_config['monthly_type'] === 'weekday') {
        if (($entity_config['day_occurrence'] ?? []) !== ($form_config['day_occurrence'] ?? [])) {
          $diff['day_occurrence'] = [
            'label' => t('Day Occurrence'),
            'stored' => implode(',', ($entity_config['day_occurrence'] ?? [])),
            'override' => implode(',', ($form_config['day_occurrence'] ?? [])),
          ];
        }
        if (($entity_config['days'] ?? []) !== ($form_config['days'] ?? [])) {
          $diff['days'] = [
            'label' => t('Days'),
            'stored' => implode(',', ($entity_config['days'] ?? [])),
            'override' => implode(',', ($form_config['days'] ?? [])),
          ];
        }
      }
      else {
        if (($entity_config['day_of_month'] ?? []) !== ($form_config['day_of_month'] ?? [])) {
          $diff['day_of_month'] = [
            'label' => t('Day of the Month'),
            'stored' => implode(',', ($entity_config['day_of_month'] ?? [])),
            'override' => implode(',', ($form_config['day_of_month'] ?? [])),
          ];
        }
      }

      if (($entity_config['year_interval'] ?? '') !== ($form_config['year_interval'] ?? '')) {
        $diff['year_interval'] = [
          'label' => t('Year Interval'),
          'stored' => $entity_config['year_interval'] ?? '',
          'override' => $form_config['year_interval'] ?? '',
        ];
      }
      if (($entity_config['months'] ?? []) !== ($form_config['months'] ?? [])) {
        $diff['months'] = [
          'label' => t('Months'),
          'stored' => implode(',', ($entity_config['months'] ?? [])),
          'override' => implode(',', ($form_config['months'] ?? [])),
        ];
      }
    }

    return $diff;
  }

  /**
   * {@inheritdoc}
   */
  public static function calculateInstances(array $form_data) {
    $eventsToCreate = parent::calculateInstances($form_data);
    if (empty($eventsToCreate)) {
      return [];
    }

    $recurrenceMonths = $form_data['months'] ?: [];
    $yearInterval = !empty($form_data['year_interval']) ? intval($form_data['year_interval']) : 1;
    $userTimezone = new \DateTimeZone(date_default_timezone_get());
    $recurrenceYears = static::findYearsBetweenDates($form_data['start_date'], $form_data['end_date'], $yearInterval);

    foreach ($eventsToCreate as $key => $dates) {
      /** @var \Drupal\Core\Datetime\DrupalDateTime $startDate */
      $startDate = clone $dates['start_date'];
      $startDate->setTimezone($userTimezone);

      $month = $startDate->format('M');
      $year = $startDate->format('Y');
      if (!in_array($month, $recurrenceMonths) || !in_array($year, $recurrenceYears)) {
        unset($eventsToCreate[$key]);
      }
    }

    return $eventsToCreate;
  }

  /**
   * Find all recurrence years between two dates.
   *
   * @param \Drupal\Core\Datetime\DrupalDateTime $startDate
   *   The start date.
   * @param \Drupal\Core\Datetime\DrupalDateTime $endDate
   *   The end date.
   * @param int $interval
   *   The number of years between occurrences.
   *
   * @return array
   *   An array of matching years.
   */
  public static function findYearsBetweenDates(DrupalDateTime $startDate, DrupalDateTime $endDate, int $interval = 1) {
    $years = [];
    $userTimezone = new \DateTimeZone(date_default_timezone_get());

    $start = clone $startDate;
    $start->setTimezone($userTimezone);
    $startYear = intval($start->format('Y'));

    $end = clone $endDate;
    $end->setTimezone($userTimezone);
    $endYear = intval($end->format('Y'));

    for ($year = $startYear; $year <= $endYear; $year += $interval) {
      $years[] = $year;
    }
    return $years;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc