You are here

public function DateRecurModularSierraModalForm::buildForm in Recurring Date Field Modular Widgets 3.x

Same name and namespace in other branches
  1. 8 src/Form/DateRecurModularSierraModalForm.php \Drupal\date_recur_modular\Form\DateRecurModularSierraModalForm::buildForm()
  2. 2.x src/Form/DateRecurModularSierraModalForm.php \Drupal\date_recur_modular\Form\DateRecurModularSierraModalForm::buildForm()

Form constructor.

Parameters

array $form: An associative array containing the structure of the form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

Return value

array The form structure.

Overrides FormInterface::buildForm

File

src/Form/DateRecurModularSierraModalForm.php, line 84

Class

DateRecurModularSierraModalForm
Generate a form designed for display in modal.

Namespace

Drupal\date_recur_modular\Form

Code

public function buildForm(array $form, FormStateInterface $form_state) {
  $form['#attached']['library'][] = 'date_recur_modular/date_recur_modular_sierra_widget_modal_form';
  $form['#attached']['library'][] = 'core/drupal.ajax';
  $form['#theme'] = 'date_recur_modular_sierra_widget_modal_form';
  $collection = $this->tempStoreFactory
    ->get(DateRecurModularSierraWidget::COLLECTION_MODAL_STATE);
  $rrule = $collection
    ->get(DateRecurModularSierraWidget::COLLECTION_MODAL_STATE_KEY);
  $form['original_string'] = [
    '#type' => 'value',
    '#value' => $rrule,
  ];
  $dtStartString = $collection
    ->get(DateRecurModularSierraWidget::COLLECTION_MODAL_STATE_DTSTART);
  if (!empty($dtStartString)) {
    $dtStart = \DateTime::createFromFormat(DateRecurModularSierraWidget::COLLECTION_MODAL_STATE_DTSTART_FORMAT, $dtStartString);
  }
  else {
    $dtStart = new \DateTime();
  }
  $parts = [];
  $rule1 = NULL;
  if (isset($rrule)) {
    $startDate = new \DateTime();
    try {
      $helper = DateRecurHelper::create($rrule, $startDate);
      $rules = $helper
        ->getRules();
      $rule1 = count($rules) > 0 ? reset($rules) : NULL;
      $parts = $rule1 ? $rule1
        ->getParts() : [];
    } catch (\Exception $e) {
    }
  }
  $form['basics'] = [
    '#type' => 'container',
    '#attributes' => [
      'class' => [
        'container-inline',
      ],
    ],
  ];
  $form['basics']['interval'] = [
    '#title' => $this
      ->t('Repeat every'),
    '#type' => 'number',
    '#default_value' => $parts['INTERVAL'] ?? NULL,
    '#min' => 1,
  ];
  $form['basics']['freq'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Frequency'),
    '#title_display' => 'invisible',
    '#options' => [
      static::MODE_ONCE => $this
        ->t('day(s)'),
      static::MODE_WEEKLY => $this
        ->t('week(s)'),
      static::MODE_MONTHLY => $this
        ->t('month(s)'),
      static::MODE_YEARLY => $this
        ->t('year(s)'),
    ],
    '#default_value' => $rule1 ? strtolower($rule1
      ->getFrequency()) : NULL,
  ];
  $form['weekdays'] = $this
    ->getFieldByDay($rule1);
  $form['weekdays']['#states']['visible'][] = [
    ':input[name="freq"]' => [
      'value' => static::MODE_WEEKLY,
    ],
  ];
  $dayOfMonth = (int) $dtStart
    ->format('j');
  $tArgs = [
    '@weekday' => $dtStart
      ->format('l'),
    '@dayofmonth' => $dayOfMonth,
  ];

  // Calculate which nth of weekday in the month. E.g 2nd Monday of the month.
  $monthWeekdayNth = static::getMonthWeekdayNth($dtStart);
  $tArgs['@monthweekdaynth'] = $monthWeekdayNth;
  $tArgs['@monthweekdayordinal'] = $monthWeekdayNth === 1 ? 'st' : ($monthWeekdayNth === 2 ? 'nd' : ($monthWeekdayNth === 3 ? 'rd' : 'th'));
  $form['monthly_mode'] = [
    '#type' => 'select',
    '#options' => [
      'monthly_th' => $this
        ->t('Monthly on day @dayofmonth', $tArgs),
      'monthly_th_weekday' => $this
        ->t('Monthly on the @monthweekdaynth@monthweekdayordinal @weekday', $tArgs),
    ],
  ];
  $form['monthly_mode']['#states']['visible'][] = [
    ':input[name="freq"]' => [
      'value' => static::MODE_MONTHLY,
    ],
  ];
  $weekdaysKeys = [
    'SU',
    'MO',
    'TU',
    'WE',
    'TH',
    'FR',
    'SA',
  ];
  $monthlyParts = [
    'monthly_th' => [
      'BYMONTHDAY' => $dayOfMonth,
    ],
    'monthly_th_weekday' => [
      'BYDAY' => $weekdaysKeys[$dtStart
        ->format('w')],
      'BYSETPOS' => $monthWeekdayNth,
    ],
  ];
  $form_state
    ->setTemporaryValue('monthly_parts', $monthlyParts);
  $endsDate = NULL;
  try {
    $until = $parts['UNTIL'] ?? NULL;
    if (is_string($until)) {
      $endsDate = new \DateTime($until);
    }
    elseif ($until instanceof \DateTimeInterface) {
      $endsDate = $until;
    }
  } catch (\Exception $e) {
  }
  $count = $parts['COUNT'] ?? NULL;
  $form['ends'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Ends'),
    '#open' => TRUE,
  ];
  $form['ends']['#theme'] = 'date_recur_modular_sierra_widget_modal_form_ends';
  $endsModeDefault = $endsDate ? DateRecurModularWidgetOptions::ENDS_MODE_ON_DATE : ($count > 0 ? DateRecurModularWidgetOptions::ENDS_MODE_OCCURRENCES : DateRecurModularWidgetOptions::ENDS_MODE_INFINITE);
  $form['ends']['ends_mode'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('Ends'),
    '#options' => [
      DateRecurModularWidgetOptions::ENDS_MODE_INFINITE => $this
        ->t('Never'),
      DateRecurModularWidgetOptions::ENDS_MODE_ON_DATE => $this
        ->t('On'),
      DateRecurModularWidgetOptions::ENDS_MODE_OCCURRENCES => $this
        ->t('After'),
    ],
    '#default_value' => $endsModeDefault,
  ];
  $form['ends']['ends_count'] = [
    '#type' => 'number',
    '#title' => $this
      ->t('End after number of occurrences'),
    '#title_display' => 'invisible',
    '#field_suffix' => $this
      ->t('occurrences'),
    '#default_value' => $count ?? 1,
    '#min' => 1,
  ];
  $form['ends']['ends_count']['#states']['enabled'][] = [
    // This applies correctly but Drupal has no theming for disabled dates.
    ':input[name="ends_mode"]' => [
      'value' => DateRecurModularWidgetOptions::ENDS_MODE_OCCURRENCES,
    ],
  ];

  // States dont yet work on date time so put it in a container.
  // @see https://www.drupal.org/project/drupal/issues/2419131
  $form['ends']['ends_date'] = [
    '#type' => 'container',
  ];
  $form['ends']['ends_date']['#states']['enabled'][] = [
    // This applies correctly but Drupal has no theming for disabled dates.
    ':input[name="ends_mode"]' => [
      'value' => DateRecurModularWidgetOptions::ENDS_MODE_ON_DATE,
    ],
  ];
  $form['ends']['ends_date']['ends_date'] = [
    '#type' => 'datetime',
    '#default_value' => $endsDate ? DrupalDateTime::createFromDateTime($endsDate) : NULL,
  ];
  $form['actions'] = [
    '#type' => 'actions',
  ];
  $form['actions']['submit'] = [
    '#type' => 'submit',
    '#value' => $this
      ->t('Done'),
    '#button_type' => 'primary',
    '#ajax' => [
      'event' => 'click',
      // Need 'url' and 'options' for this submission button to use this
      // controller not the caller.
      'url' => Url::fromRoute('date_recur_modular_widget.sierra_modal_form'),
      'options' => [
        'query' => [
          FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
        ],
      ],
      'callback' => [
        $this,
        'ajaxSubmitForm',
      ],
    ],
  ];
  return $form;
}