recurring_events-2.0.x-dev/src/Plugin/Field/FieldWidget/MonthlyRecurringDateWidget.php

src/Plugin/Field/FieldWidget/MonthlyRecurringDateWidget.php
<?php

declare(strict_types=1);

namespace Drupal\recurring_events\Plugin\Field\FieldWidget;

use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Field\Attribute\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;

/**
 * Plugin implementation of the 'monthly recurring date' widget.
 */
#[FieldWidget(
  id: "monthly_recurring_date",
  label: new TranslatableMarkup("Monthly Recurring Date Widget"),
  field_types: [
    "monthly_recurring_date",
  ]
)]
class MonthlyRecurringDateWidget extends WeeklyRecurringDateWidget {

  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element = parent::formElement($items, $delta, $element, $form, $form_state);
    $element['#type'] = 'container';
    $element['#states'] = [
      'visible' => [
        ':input[name="recur_type"]' => ['value' => 'monthly_recurring_date'],
      ],
    ];
    $element['#element_validate'][] = [$this, 'validateForm'];

    $element['type'] = [
      '#type' => 'radios',
      '#title' => $this->t('Event Recurrence Schedule'),
      '#options' => [
        'weekday' => $this->t('Recur on Day of Week'),
        'monthday' => $this->t('Recur on Day of Month'),
      ],
      '#default_value' => $items[$delta]->type ?: '',
      '#weight' => 5,
    ];

    $element['day_occurrence'] = [
      '#type' => 'checkboxes',
      '#title' => $this->t('Day Occurrence'),
      '#options' => [
        'first' => $this->t('First'),
        'second' => $this->t('Second'),
        'third' => $this->t('Third'),
        'fourth' => $this->t('Fourth'),
        'last' => $this->t('Last'),
      ],
      '#default_value' => $items[$delta]->day_occurrence ? explode(',', $items[$delta]->day_occurrence) : [],
      '#states' => [
        'visible' => [
          ':input[name="monthly_recurring_date[0][type]"]' => ['value' => 'weekday'],
        ],
      ],
      '#weight' => 6,
    ];

    $days = $this->getDayOptions();
    $element['days'] = [
      '#type' => 'checkboxes',
      '#title' => $this->t('Days of the Week'),
      '#options' => $days,
      '#default_value' => $items[$delta]->days ? explode(',', $items[$delta]->days) : [],
      '#states' => [
        'visible' => [
          ':input[name="monthly_recurring_date[0][type]"]' => ['value' => 'weekday'],
        ],
      ],
      '#weight' => 7,
    ];

    $month_days = $this->getMonthDayOptions();
    $element['day_of_month'] = [
      '#type' => 'checkboxes',
      '#title' => $this->t('Days of the Month'),
      '#options' => $month_days,
      '#default_value' => $items[$delta]->day_of_month ? explode(',', $items[$delta]->day_of_month) : [],
      '#states' => [
        'visible' => [
          ':input[name="monthly_recurring_date[0][type]"]' => ['value' => 'monthday'],
        ],
      ],
      '#weight' => 8,
    ];

    unset($element['end_time']['#states']);
    unset($element['end_time']['time']['#states']);
    unset($element['duration']['#states']);
    $element['end_time']['#states']['invisible'][':input[name="monthly_recurring_date[0][duration_or_end_time]"]'] = ['value' => 'duration'];
    $element['end_time']['time']['#states']['invisible'][':input[name="monthly_recurring_date[0][duration_or_end_time]"]'] = ['value' => 'duration'];
    $element['duration']['#states']['visible'][':input[name="monthly_recurring_date[0][duration_or_end_time]"]'] = ['value' => 'duration'];

    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
    foreach ($values as &$item) {

      $item['day_occurrence'] = array_filter($item['day_occurrence']);
      if (!empty($item['day_occurrence'])) {
        $item['day_occurrence'] = implode(',', $item['day_occurrence']);
      }
      else {
        $item['day_occurrence'] = '';
      }

      $item['day_of_month'] = array_filter($item['day_of_month']);
      if (!empty($item['day_of_month'])) {
        $item['day_of_month'] = implode(',', $item['day_of_month']);
      }
      else {
        $item['day_of_month'] = '';
      }
    }

    $values = parent::massageFormValues($values, $form, $form_state);
    return $values;
  }

  /**
   * Return day of month options for events.
   *
   * @return array
   *   An array of days of month suitable for a checkbox field.
   */
  protected function getMonthDayOptions() {
    $days = [];
    $start = date('Y') . '-01-01';
    $date = DrupalDateTime::createFromFormat(DateTimeItemInterface::DATE_STORAGE_FORMAT, $start);

    for ($x = 1; $x <= 31; $x++) {
      $days[$x] = $date->format('jS');
      $date->modify('+1 day');
    }

    $days[-1] = $this->t('Last');

    $this->moduleHandler->alter('recurring_events_month_days', $days);

    return $days;
  }

  /**
   * Element validate callback to ensure that widget values are valid.
   *
   * @param array $element
   *   An associative array containing the properties and children of the
   *   generic form element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param array $complete_form
   *   The complete form structure.
   */
  public function validateForm(array &$element, FormStateInterface $form_state, array &$complete_form) {
    $recur_type = $form_state->getValue('recur_type');
    if ((is_array($recur_type) && $recur_type[0]['value'] === 'monthly_recurring_date')
      || $recur_type === 'monthly_recurring_date') {
      $values = $form_state->getValue('monthly_recurring_date');
      if (empty($values[0])) {
        $form_state->setError($element, $this->t('Please configure the Monthly Recurring Date settings'));
      }
      if (!empty($values[0])) {
        $values = $values[0];

        if (empty($values['value'])) {
          $form_state->setError($element['value'], $this->t('Please enter a start date'));
        }

        if (empty($values['end_value'])) {
          $form_state->setError($element['end_value'], $this->t('Please enter an end date'));
        }

        if (empty($values['time'])) {
          $form_state->setError($element['time'], $this->t('Please enter a start time'));
        }

        if (empty($values['duration']) || !isset($complete_form['monthly_recurring_date']['widget'][0]['duration']['#options'][$values['duration']])) {
          $form_state->setError($element['duration'], $this->t('Please select a duration from the list'));
        }

        if (empty($values['type']) || !isset($complete_form['monthly_recurring_date']['widget'][0]['type']['#options'][$values['type']])) {
          $form_state->setError($element['type'], $this->t('Please select an event recurrence schedule type from the list'));
        }
        else {
          switch ($values['type']) {
            case 'weekday':
              $filtered_day_occurrences = array_filter($values['day_occurrence'], function ($value) {
                return !empty($value);
              });
              if (empty($values['day_occurrence']) || empty($filtered_day_occurrences)) {
                $form_state->setError($element['day_occurrence'], $this->t('Please select a day occurrence from the list'));
              }
              $filtered_days = array_filter($values['days'], function ($value) {
                return !empty($value);
              });
              if (empty($values['days']) || empty($filtered_days)) {
                $form_state->setError($element['days'], $this->t('Please select week days from the list'));
              }
              break;

            case 'monthday':
              $filtered_days = array_filter($values['day_of_month'], function ($value) {
                return !empty($value);
              });
              if (empty($values['day_of_month']) || empty($filtered_days)) {
                $form_state->setError($element['day_of_month'], $this->t('Please select days of the month from the list'));
              }
              break;
          }
        }
      }
    }
  }

}

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

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