class DateRecurModularSierraModalForm in Recurring Date Field Modular Widgets 8
Same name and namespace in other branches
- 3.x src/Form/DateRecurModularSierraModalForm.php \Drupal\date_recur_modular\Form\DateRecurModularSierraModalForm
- 2.x src/Form/DateRecurModularSierraModalForm.php \Drupal\date_recur_modular\Form\DateRecurModularSierraModalForm
Generate a form designed for display in modal.
Hierarchy
- class \Drupal\Core\Form\FormBase implements ContainerInjectionInterface, FormInterface uses DependencySerializationTrait, LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\date_recur_modular\Form\DateRecurModularSierraModalForm uses DateRecurModularUtilityTrait, DateRecurModularWidgetFieldsTrait
Expanded class hierarchy of DateRecurModularSierraModalForm
1 file declares its use of DateRecurModularSierraModalForm
- DateRecurModularSierraWidget.php in src/
Plugin/ Field/ FieldWidget/ DateRecurModularSierraWidget.php
1 string reference to 'DateRecurModularSierraModalForm'
File
- src/
Form/ DateRecurModularSierraModalForm.php, line 29
Namespace
Drupal\date_recur_modular\FormView source
class DateRecurModularSierraModalForm extends FormBase {
use DateRecurModularWidgetFieldsTrait;
use DateRecurModularUtilityTrait;
/**
* The PrivateTempStore factory.
*
* @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
protected const MODE_ONCE = 'daily';
protected const MODE_WEEKLY = 'weekly';
protected const MODE_MONTHLY = 'monthly';
protected const MODE_YEARLY = 'yearly';
protected const UTC_FORMAT = 'Ymd\\THis\\Z';
/**
* Constructs a new DateRecurModularSierraModalForm.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* A config factory for retrieving required config objects.
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $tempStoreFactory
* The PrivateTempStore factory.
*/
public function __construct(ConfigFactoryInterface $configFactory, PrivateTempStoreFactory $tempStoreFactory) {
$this->configFactory = $configFactory;
$this->tempStoreFactory = $tempStoreFactory;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('config.factory'), $container
->get('tempstore.private'));
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'date_recur_modular_sierra_modal';
}
/**
* {@inheritdoc}
*/
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;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
$endsMode = $form_state
->getValue('ends_mode');
/** @var \Drupal\Core\Datetime\DrupalDateTime|array|null $endsDate */
$endsDate = $form_state
->getValue('ends_date');
if ('date' === $endsMode && !$endsDate instanceof DrupalDateTime) {
// Prevent submission, if for example only date provided (missing time).
$form_state
->setError($form['ends']['ends_date'], $this
->t('Invalid date.'));
}
}
/**
* {@inheritdoc}
*/
public function ajaxSubmitForm(array &$form, FormStateInterface $form_state) {
$response = new AjaxResponse();
if ($form_state
->getErrors()) {
// Inspired by \Drupal\form_api_example\Form\ModalForm::ajaxSubmitForm.
$form['status_messages'] = [
'#type' => 'status_messages',
];
// Open the form again as a modal.
return $response
->addCommand(new OpenModalDialogCommand($this
->t('Errors'), $form, [
'width' => '575',
]));
}
$frequency = $form_state
->getValue('freq');
$parts = [];
$parts['FREQ'] = strtoupper($frequency);
$parts['INTERVAL'] = $form_state
->getValue('interval');
if (static::MODE_WEEKLY === $frequency) {
$weekDays = array_values(array_filter($form_state
->getValue('weekdays')));
$parts['BYDAY'] = implode(',', $weekDays);
}
if (static::MODE_MONTHLY === $frequency) {
$monthlyMode = $form_state
->getValue('monthly_mode');
$monthlyParts = $form_state
->getTemporaryValue([
'monthly_parts',
$monthlyMode,
]);
$parts += $monthlyParts;
}
$endsMode = $form_state
->getValue('ends_mode');
/** @var \Drupal\Core\Datetime\DrupalDateTime|array|null $endsDate */
$endsDate = $form_state
->getValue('ends_date');
// Ends mode.
if ($endsMode === DateRecurModularWidgetOptions::ENDS_MODE_OCCURRENCES) {
$parts['COUNT'] = (int) $form_state
->getValue('ends_count');
}
elseif ($endsMode === DateRecurModularWidgetOptions::ENDS_MODE_ON_DATE && $endsDate instanceof DrupalDateTime) {
$endsDateUtcAdjusted = (clone $endsDate)
->setTimezone(new \DateTimeZone('UTC'));
$parts['UNTIL'] = $endsDateUtcAdjusted
->format('Ymd\\THis\\Z');
}
// Build RRULE.
$ruleKv = [];
foreach ($parts as $k => $v) {
$ruleKv[] = "{$k}={$v}";
}
$ruleString = implode(';', $ruleKv);
// Rset cannot be casted to string yet, rebuild it here, see also
// https://github.com/rlanvin/php-rrule/issues/37
$lines = [];
$lines[] = 'RRULE:' . $ruleString;
// Preserve non-RRULE components from original string.
$originalString = $form_state
->getValue('original_string');
$rset = new RSet($originalString);
$utc = new \DateTimeZone('UTC');
$exDates = array_map(function (\DateTime $exDate) use ($utc) {
$exDate
->setTimezone($utc);
return $exDate
->format(static::UTC_FORMAT);
}, $rset
->getExDates());
if (count($exDates) > 0) {
$lines[] = 'EXDATE:' . implode(',', $exDates);
}
$collection = $this->tempStoreFactory
->get(DateRecurModularSierraWidget::COLLECTION_MODAL_STATE);
$collection
->set(DateRecurModularSierraWidget::COLLECTION_MODAL_STATE_KEY, implode("\n", $lines));
$refreshBtnName = sprintf('[name="%s"]', $collection
->get(DateRecurModularSierraWidget::COLLECTION_MODAL_STATE_REFRESH_BUTTON));
$response
->addCommand(new CloseDialogCommand())
->addCommand(new InvokeCommand($refreshBtnName, 'trigger', [
'click',
]));
return $response;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
return new AjaxResponse();
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DateRecurModularSierraModalForm:: |
protected | property | The PrivateTempStore factory. | |
DateRecurModularSierraModalForm:: |
public | function | ||
DateRecurModularSierraModalForm:: |
public | function |
Form constructor. Overrides FormInterface:: |
|
DateRecurModularSierraModalForm:: |
public static | function |
Instantiates a new instance of this class. Overrides FormBase:: |
|
DateRecurModularSierraModalForm:: |
public | function |
Returns a unique string identifying the form. Overrides FormInterface:: |
|
DateRecurModularSierraModalForm:: |
protected | constant | ||
DateRecurModularSierraModalForm:: |
protected | constant | ||
DateRecurModularSierraModalForm:: |
protected | constant | ||
DateRecurModularSierraModalForm:: |
protected | constant | ||
DateRecurModularSierraModalForm:: |
public | function |
Form submission handler. Overrides FormInterface:: |
|
DateRecurModularSierraModalForm:: |
protected | constant | ||
DateRecurModularSierraModalForm:: |
public | function |
Form validation handler. Overrides FormBase:: |
|
DateRecurModularSierraModalForm:: |
public | function | Constructs a new DateRecurModularSierraModalForm. | |
DateRecurModularUtilityTrait:: |
public static | function | Build a datetime object by getting the date and time from two fields. | |
DateRecurModularUtilityTrait:: |
protected | function | Builds RRULE string from an array of parts, stripping disallowed parts. | |
DateRecurModularUtilityTrait:: |
protected | function | Get the time zone associated with the current user. | |
DateRecurModularUtilityTrait:: |
protected | function | Determines a default time zone for a field item. | |
DateRecurModularUtilityTrait:: |
public static | function | Determine nth weekday into a month for a date. | |
DateRecurModularUtilityTrait:: |
protected | function | Build the name for a sub element. | |
DateRecurModularUtilityTrait:: |
protected | function | Attempts to get the first valid rule from a date recur field item. | |
DateRecurModularUtilityTrait:: |
protected | function | Get a list of time zones suitable for a select field. | |
DateRecurModularUtilityTrait:: |
protected | function | Determine whether a field item represents a full day. | |
DateRecurModularWidgetFieldsTrait:: |
protected | function | Get a BYDAY element. | |
DateRecurModularWidgetFieldsTrait:: |
protected | function | Get an radios element for toggling between common end modes. | |
DateRecurModularWidgetFieldsTrait:: |
protected | function | Get a select element for toggling between common modes. | |
DateRecurModularWidgetFieldsTrait:: |
protected | function | Get a BYMONTH element. | |
DateRecurModularWidgetFieldsTrait:: |
protected | function | Get a time zone element. | |
DateRecurModularWidgetFieldsTrait:: |
protected | function | Builds a #states array for an element dependant on mode selected. | |
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
FormBase:: |
protected | property | The config factory. | 1 |
FormBase:: |
protected | property | The request stack. | 1 |
FormBase:: |
protected | property | The route match. | |
FormBase:: |
protected | function | Retrieves a configuration object. | |
FormBase:: |
protected | function | Gets the config factory for this form. | 1 |
FormBase:: |
private | function | Returns the service container. | |
FormBase:: |
protected | function | Gets the current user. | |
FormBase:: |
protected | function | Gets the request object. | |
FormBase:: |
protected | function | Gets the route match. | |
FormBase:: |
protected | function | Gets the logger for a specific channel. | |
FormBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
FormBase:: |
public | function | Resets the configuration factory. | |
FormBase:: |
public | function | Sets the config factory for this form. | |
FormBase:: |
public | function | Sets the request stack object to use. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |