diff --git a/modules/recurring_events_registration/recurring_events_registration.install b/modules/recurring_events_registration/recurring_events_registration.install index aab9be8a4f3d96cf543f48381a1034e3f0bc1447..7ebb81aa6d7f7bd8bd6e3c34a861f850f01b73ee 100644 --- a/modules/recurring_events_registration/recurring_events_registration.install +++ b/modules/recurring_events_registration/recurring_events_registration.install @@ -78,3 +78,100 @@ function recurring_events_registration_update_8002() { \Drupal::entityDefinitionUpdateManager()->installFieldStorageDefinition('bundle', 'registrant', 'registrant', $registrant_type); } + +/** + * Update the event_registration field type to add new settings. + */ +function recurring_events_registration_update_8003() { + $entity_type_manager = \Drupal::entityTypeManager(); + + $storage = $entity_type_manager->getStorage('eventseries'); + $bundle_definition = $entity_type_manager->getDefinition('eventseries'); + + $id_key = $bundle_definition->getKey('id'); + $revision_key = $bundle_definition->getKey('revision'); + + $table_name = $storage->getDataTable() ?: $storage->getBaseTable(); + $revision_table_name = $storage->getRevisionDataTable() ?: $storage->getRevisionTable(); + + $database = \Drupal::database(); + $definition_manager = \Drupal::entityDefinitionUpdateManager(); + + $reg_fields = [ + 'event_registration__value', + 'event_registration__end_value', + 'event_registration__registration', + 'event_registration__registration_type', + 'event_registration__registration_dates', + 'event_registration__capacity', + 'event_registration__waitlist', + 'event_registration__time_amount', + 'event_registration__time_type', + ]; + + $reg_field_mappings = [ + 'event_registration__time_amount' =>'event_registration__instance_schedule_open_amount', + 'event_registration__time_type' => 'event_registration__instance_schedule_open_units', + ]; + + $registration_values = $database->select($table_name) + ->fields($table_name, [$id_key, $revision_key] + $reg_fields) + ->execute() + ->fetchAll(); + + $update_fields = array_fill_keys($reg_fields, NULL); + + $database->update($table_name) + ->fields($update_fields) + ->execute(); + + $field_storage_definition = $definition_manager->getFieldStorageDefinition('event_registration', 'eventseries'); + $definition_manager->uninstallFieldStorageDefinition($field_storage_definition); + + $storage_definition = BaseFieldDefinition::create('event_registration') + ->setName('event_registration') + ->setLabel(t('Event Registration')) + ->setDescription('The event registration configuration.') + ->setDisplayConfigurable('form', TRUE) + ->setDisplayConfigurable('view', TRUE) + ->setRevisionable(TRUE) + ->setTranslatable(FALSE) + ->setCardinality(1) + ->setRequired(FALSE) + ->setDisplayOptions('form', [ + 'type' => 'event_registration', + 'weight' => 10, + ]); + + \Drupal::entityDefinitionUpdateManager() + ->installFieldStorageDefinition('event_registration', 'eventseries', 'eventseries', $storage_definition); + + if (!empty($registration_values)) { + foreach ($registration_values as $value) { + $values_to_restore = [ + $id_key => $value->{$id_key}, + $revision_key => $value->{$revision_key}, + ]; + foreach ($reg_fields as $field) { + $key = $field; + if (isset($reg_field_mappings[$field])) { + $key = $reg_field_mappings[$field]; + } + $values_to_restore[$key] = rtrim($value->{$field}, 's'); + $values_to_restore += [ + 'event_registration__instance_schedule_open' => 'custom', + 'event_registration__instance_schedule_close' => 'start', + ]; + } + $database->update($table_name) + ->fields($values_to_restore) + ->condition($id_key, $value->{$id_key}) + ->execute(); + + $database->update($revision_table_name) + ->fields($values_to_restore) + ->condition($id_key, $value->{$id_key}) + ->execute(); + } + } +} diff --git a/modules/recurring_events_registration/src/Plugin/Field/FieldType/EventRegistration.php b/modules/recurring_events_registration/src/Plugin/Field/FieldType/EventRegistration.php index 12990d206cab271fa5839352a0d48c465cb77e61..c0736684339847949bf276d415e4574de73a1c84 100644 --- a/modules/recurring_events_registration/src/Plugin/Field/FieldType/EventRegistration.php +++ b/modules/recurring_events_registration/src/Plugin/Field/FieldType/EventRegistration.php @@ -52,12 +52,39 @@ class EventRegistration extends DateRangeItem { 'unsigned' => TRUE, ]; - $schema['columns']['time_amount'] = [ + $schema['columns']['instance_schedule_open'] = [ + 'type' => 'varchar', + 'length' => 255, + ]; + + $schema['columns']['instance_schedule_open_amount'] = [ 'type' => 'int', + 'default' => 0, 'unsigned' => TRUE, ]; - $schema['columns']['time_type'] = [ + $schema['columns']['instance_schedule_open_units'] = [ + 'type' => 'varchar', + 'length' => 255, + ]; + + $schema['columns']['instance_schedule_close'] = [ + 'type' => 'varchar', + 'length' => 255, + ]; + + $schema['columns']['instance_schedule_close_amount'] = [ + 'type' => 'int', + 'default' => 0, + 'unsigned' => TRUE, + ]; + + $schema['columns']['instance_schedule_close_units'] = [ + 'type' => 'varchar', + 'length' => 255, + ]; + + $schema['columns']['instance_schedule_close_type'] = [ 'type' => 'varchar', 'length' => 255, ]; @@ -74,11 +101,19 @@ class EventRegistration extends DateRangeItem { $registration_dates = $this->get('registration_dates')->getValue(); $capacity = $this->get('capacity')->getValue(); $waitlist = $this->get('waitlist')->getValue(); - $time_amount = $this->get('time_amount')->getValue(); - $time_type = $this->get('time_type')->getValue(); + $instance_schedule_open = $this->get('instance_schedule_open')->getValue(); + $instance_schedule_open_amount = $this->get('instance_schedule_open_amount')->getValue(); + $instance_schedule_open_units = $this->get('instance_schedule_open_units')->getValue(); + $instance_schedule_close = $this->get('instance_schedule_close')->getValue(); + $instance_schedule_close_amount = $this->get('instance_schedule_close_amount')->getValue(); + $instance_schedule_close_units = $this->get('instance_schedule_close_units')->getValue(); + $instance_schedule_close_type = $this->get('instance_schedule_close_type')->getValue(); return parent::isEmpty() && empty($registration) && empty($registration_type) && empty($registration_dates) && empty($capacity) && empty($waitlist) - && empty($time_amount) && empty($time_type); + && empty($instance_schedule_open) && empty($instance_schedule_open_amount) + && empty($instance_schedule_open_units) && empty($instance_schedule_close) + && empty($instance_schedule_close_amount) && empty($instance_schedule_close_units) + && empty($instance_schedule_close_type); } /** @@ -107,13 +142,33 @@ class EventRegistration extends DateRangeItem { ->setLabel(t('Waitlist')) ->setDescription(t('Select whether to enable a waitlist.')); - $properties['time_amount'] = DataDefinition::create('integer') - ->setLabel(t('Registration Time Amount')) - ->setDescription(t('Select how many days or hours before the event registration opens.')); + $properties['instance_schedule_open'] = DataDefinition::create('string') + ->setLabel(t('Instance Registration Open')) + ->setDescription(t('Select when to open registrations.')); + + $properties['instance_schedule_open_amount'] = DataDefinition::create('integer') + ->setLabel(t('Instance Registration Open Time')) + ->setDescription(t('Select when to open registrations (number).')); + + $properties['instance_schedule_open_units'] = DataDefinition::create('string') + ->setLabel(t('Instance Registration Open Unit')) + ->setDescription(t('Select when to open registrations (units).')); + + $properties['instance_schedule_close'] = DataDefinition::create('string') + ->setLabel(t('Instance Registration Close')) + ->setDescription(t('Select when to close registrations.')); + + $properties['instance_schedule_close_amount'] = DataDefinition::create('integer') + ->setLabel(t('Instance Registration Close Time')) + ->setDescription(t('Select when to close registrations (number).')); + + $properties['instance_schedule_close_units'] = DataDefinition::create('string') + ->setLabel(t('Instance Registration Close Unit')) + ->setDescription(t('Select when to close registrations (units).')); - $properties['time_type'] = DataDefinition::create('string') - ->setLabel(t('Registration Time Type')) - ->setDescription(t('Select either days or hours.')); + $properties['instance_schedule_close_type'] = DataDefinition::create('string') + ->setLabel(t('Instance Registration Close Type')) + ->setDescription(t('Select when to close registrations (type).')); return $properties; } diff --git a/modules/recurring_events_registration/src/Plugin/Field/FieldWidget/EventRegistrationWidget.php b/modules/recurring_events_registration/src/Plugin/Field/FieldWidget/EventRegistrationWidget.php index 15fcb2540f23bd8b9eb343f7f3f73282bcbd1c12..a2d8f183ea71a1aafbb38aa4331110bd4970005a 100644 --- a/modules/recurring_events_registration/src/Plugin/Field/FieldWidget/EventRegistrationWidget.php +++ b/modules/recurring_events_registration/src/Plugin/Field/FieldWidget/EventRegistrationWidget.php @@ -58,7 +58,7 @@ class EventRegistrationWidget extends DateRangeDefaultWidget { $element['registration_dates'] = [ '#type' => 'radios', '#title' => $this->t('Registration Dates'), - '#description' => $this->t('Choose between open or scheduled registration.'), + '#description' => $this->t('Choose between open or scheduled registration. Open registration ends when the event begins.'), '#weight' => 2, '#default_value' => $items[$delta]->registration_dates ?: 'open', '#options' => [ @@ -106,24 +106,114 @@ class EventRegistrationWidget extends DateRangeDefaultWidget { ], ]; - $element['instance_registration']['time_amount'] = [ - '#type' => 'number', - '#title' => $this->t('Registration Time Amount'), - '#description' => $this->t('Enter the amount of time in days or hours before the event(s) start time(s) that registration should open.'), + $element['instance_registration']['instance_schedule_open'] = [ + '#type' => 'select', + '#title' => $this->t('Registration Opens'), + '#description' => $this->t('Select when to open registration'), '#weight' => 0, - '#default_value' => $items[$delta]->time_amount ?: '', + '#default_value' => $items[$delta]->instance_schedule_open, + '#options' => [ + 'now' => $this->t('Now'), + 'start' => $this->t('At the start of the event'), + 'custom' => $this->t('Custom schedule'), + ], + ]; + + $element['instance_registration']['open_registration'] = [ + '#type' => 'container', + '#weight' => 1, + '#states' => [ + 'visible' => [ + ':input[name="event_registration[0][instance_registration][instance_schedule_open]"]' => ['value' => 'custom'], + ], + ], + '#attributes' => [ + 'class' => 'container-inline', + ], + ]; + + $element['instance_registration']['open_registration']['instance_schedule_open_amount'] = [ + '#type' => 'number', + '#title' => '', + '#weight' => 1, + '#default_value' => $items[$delta]->instance_schedule_open_amount ?? '1', '#min' => 0, ]; - $element['instance_registration']['time_type'] = [ + $element['instance_registration']['open_registration']['instance_schedule_open_units'] = [ '#type' => 'select', - '#title' => $this->t('Registration Time Type'), - '#description' => $this->t("Select either Days or Hours to choose how long before which an event's registration will open."), + '#title' => '', + '#weight' => 2, + '#default_value' => $items[$delta]->instance_schedule_open_units ?? 'month', + '#options' => [ + 'month' => $this->t('months'), + 'week' => $this->t('weeks'), + 'day' => $this->t('days'), + 'hour' => $this->t('hours'), + 'minute' => $this->t('minutes'), + 'second' => $this->t('seconds'), + ], + '#suffix' => $this->t('before the event starts'), + ]; + + $element['instance_registration']['instance_schedule_close'] = [ + '#type' => 'select', + '#title' => $this->t('Registration Closes'), + '#description' => $this->t('Select when to close registration'), + '#weight' => 3, + '#default_value' => $items[$delta]->instance_schedule_close, + '#options' => [ + 'start' => $this->t('At the start of the event'), + 'end' => $this->t('At the end of the event'), + 'custom' => $this->t('Custom schedule'), + ], + ]; + + $element['instance_registration']['close_registration'] = [ + '#type' => 'container', + '#weight' => 4, + '#states' => [ + 'visible' => [ + ':input[name="event_registration[0][instance_registration][instance_schedule_close]"]' => ['value' => 'custom'], + ], + ], + '#attributes' => [ + 'class' => 'container-inline', + ], + ]; + + $element['instance_registration']['close_registration']['instance_schedule_close_amount'] = [ + '#type' => 'number', + '#title' => '', '#weight' => 1, - '#default_value' => $items[$delta]->time_type ?: '', + '#default_value' => $items[$delta]->instance_schedule_close_amount ?? '1', + '#min' => 0, + ]; + + $element['instance_registration']['close_registration']['instance_schedule_close_units'] = [ + '#type' => 'select', + '#title' => '', + '#weight' => 2, + '#default_value' => $items[$delta]->instance_schedule_close_units ?? 'week', + '#min' => 0, + '#options' => [ + 'month' => $this->t('months'), + 'week' => $this->t('weeks'), + 'day' => $this->t('days'), + 'hour' => $this->t('hours'), + 'minute' => $this->t('minutes'), + 'second' => $this->t('seconds'), + ], + ]; + + $element['instance_registration']['close_registration']['instance_schedule_close_type'] = [ + '#type' => 'select', + '#title' => '', + '#weight' => 3, + '#default_value' => $items[$delta]->instance_schedule_close_type ?: '', '#options' => [ - 'days' => $this->t('Days'), - 'hours' => $this->t('Hours'), + 'before' => $this->t('before the event starts'), + 'after' => $this->t('after the event starts'), ], ]; @@ -131,7 +221,7 @@ class EventRegistrationWidget extends DateRangeDefaultWidget { '#type' => 'number', '#title' => $this->t('Total Number of Spaces Available'), '#description' => $this->t('Maximum number of attendees available for each series, or individual event. Leave blank for unlimited.'), - '#weight' => 4, + '#weight' => 5, '#default_value' => $items[$delta]->capacity ?: '', '#min' => 0, '#states' => [ @@ -145,7 +235,7 @@ class EventRegistrationWidget extends DateRangeDefaultWidget { '#type' => 'checkbox', '#title' => $this->t('Enable Waiting List'), '#description' => $this->t('Enable a waiting list if the number of registrations reaches capacity.'), - '#weight' => 5, + '#weight' => 6, '#default_value' => $items[$delta]->waitlist ?: '', '#states' => [ 'visible' => [ @@ -164,8 +254,13 @@ class EventRegistrationWidget extends DateRangeDefaultWidget { foreach ($values as &$item) { $item['value'] = $item['series_registration']['value']; $item['end_value'] = $item['series_registration']['end_value']; - $item['time_amount'] = (int) $item['instance_registration']['time_amount']; - $item['time_type'] = $item['instance_registration']['time_type']; + $item['instance_schedule_open'] = $item['instance_registration']['instance_schedule_open']; + $item['instance_schedule_open_amount'] = (int) $item['instance_registration']['open_registration']['instance_schedule_open_amount']; + $item['instance_schedule_open_units'] = $item['instance_registration']['open_registration']['instance_schedule_open_units']; + $item['instance_schedule_close'] = $item['instance_registration']['instance_schedule_close']; + $item['instance_schedule_close_amount'] = (int) $item['instance_registration']['close_registration']['instance_schedule_close_amount']; + $item['instance_schedule_close_units'] = $item['instance_registration']['close_registration']['instance_schedule_close_units']; + $item['instance_schedule_close_type'] = $item['instance_registration']['close_registration']['instance_schedule_close_type']; $item['capacity'] = (int) $item['capacity']; unset($item['series_registration']); unset($item['instance_registration']); @@ -198,12 +293,32 @@ class EventRegistrationWidget extends DateRangeDefaultWidget { $item['waitlist'] = 0; } - if (empty($item['time_amount'])) { - $item['time_amount'] = 0; + if (empty($item['instance_schedule_open'])) { + $item['instance_schedule_open'] = ''; + } + + if (empty($item['instance_schedule_open_amount'])) { + $item['instance_schedule_open_amount'] = 0; + } + + if (empty($item['instance_schedule_open_units'])) { + $item['instance_schedule_open_units'] = ''; + } + + if (empty($item['instance_schedule_close'])) { + $item['instance_schedule_close'] = ''; + } + + if (empty($item['instance_schedule_close_amount'])) { + $item['instance_schedule_close_amount'] = 0; + } + + if (empty($item['instance_schedule_close_units'])) { + $item['instance_schedule_close_units'] = ''; } - if (empty($item['time_type'])) { - $item['time_type'] = ''; + if (empty($item['instance_schedule_close_type'])) { + $item['instance_schedule_close_type'] = ''; } } diff --git a/modules/recurring_events_registration/src/RegistrationCreationService.php b/modules/recurring_events_registration/src/RegistrationCreationService.php index c2f3e017284f756658b9d82018058141b57271f8..f4e29639b078eddc8ed6701f16484b13b19dfac3 100644 --- a/modules/recurring_events_registration/src/RegistrationCreationService.php +++ b/modules/recurring_events_registration/src/RegistrationCreationService.php @@ -344,6 +344,38 @@ class RegistrationCreationService { return $type; } + /** + * Get instance registration open schedule type. + * + * @return string + * The type of open registration schedule: now, start, or custom. + */ + public function getInstanceRegistrationOpenScheduleType() { + $type = FALSE; + + if (!empty($this->eventSeries->event_registration->instance_schedule_open)) { + $type = $this->eventSeries->event_registration->instance_schedule_open; + } + + return $type; + } + + /** + * Get instance registration close schedule type. + * + * @return string + * The type of close registration schedule: start, end, or custom. + */ + public function getInstanceRegistrationCloseScheduleType() { + $type = FALSE; + + if (!empty($this->eventSeries->event_registration->instance_schedule_close)) { + $type = $this->eventSeries->event_registration->instance_schedule_close; + } + + return $type; + } + /** * Get registration dates type. * @@ -361,32 +393,75 @@ class RegistrationCreationService { } /** - * Get registration time. + * Get instance registration open time modifier. * * @return string - * The time before each event that registration opens. + * The modifier for the opening time relative to the event start. */ - public function getRegistrationTime() { - $time = FALSE; + public function getInstanceRegistrationOpenTimeModifier() { + $modifier = FALSE; - if (!empty($this->eventSeries->event_registration->time_amount) && !empty($this->getRegistrationTimeUnit())) { - $time = $this->eventSeries->event_registration->time_amount . ' ' . $this->getRegistrationTimeUnit(); + if (!empty($this->eventSeries->event_registration->instance_schedule_open_amount) && !empty($this->getInstanceRegistrationOpenTimeUnit())) { + $modifier = $this->eventSeries->event_registration->instance_schedule_open_amount . ' ' . $this->getInstanceRegistrationOpenTimeUnit(); + $modifier = '- ' . $modifier; } - return $time; + return $modifier; } /** - * Get registration time unit. + * Get instance registration open time unit. * * @return string - * The unit used to define the registration time, days or hours. + * The unit used to define the open registration time. */ - public function getRegistrationTimeUnit() { + public function getInstanceRegistrationOpenTimeUnit() { $unit = FALSE; - if (!empty($this->eventSeries->event_registration->time_type)) { - $unit = $this->eventSeries->event_registration->time_type; + if (!empty($this->eventSeries->event_registration->instance_schedule_open_units)) { + $unit = $this->eventSeries->event_registration->instance_schedule_open_units; + } + + return $unit; + } + + /** + * Get instance registration close time modifier. + * + * @return string + * The modifier for the closing time relative to the event start. + */ + public function getInstanceRegistrationCloseTimeModifier() { + $modifier = FALSE; + + if (!empty($this->eventSeries->event_registration->instance_schedule_close_amount) && !empty($this->getInstanceRegistrationCloseTimeUnit())) { + $modifier = $this->eventSeries->event_registration->instance_schedule_close_amount . ' ' . $this->getInstanceRegistrationCloseTimeUnit(); + switch ($this->eventSeries->event_registration->instance_schedule_close_type) { + case 'after': + $modifier = '+ ' . $modifier; + break; + + case 'before': + default: + $modifier = '- ' . $modifier; + break; + } + } + + return $modifier; + } + + /** + * Get instance registration close time unit. + * + * @return string + * The unit used to define the close registration time. + */ + public function getInstanceRegistrationCloseTimeUnit() { + $unit = FALSE; + + if (!empty($this->eventSeries->event_registration->instance_schedule_close_units)) { + $unit = $this->eventSeries->event_registration->instance_schedule_close_units; } return $unit; @@ -473,17 +548,43 @@ class RegistrationCreationService { break; case 'instance': - $reg_time_string = $this->getRegistrationTime(); - - if (!empty($reg_time_string)) { - $event_date = $this->eventInstance->date->start_date; - - $reg_end = clone $event_date; - $reg_start = clone $event_date; + $event_start_date = $this->eventInstance->date->start_date; + $event_end_date = $this->eventInstance->date->end_date; + + // Calculate registration opening time. + switch ($this->getInstanceRegistrationOpenScheduleType()) { + case 'now': + $reg_start = new DrupalDateTime(); + break; + + case 'start': + $reg_start = clone $event_start_date; + break; + + case 'custom': + $open_time_modifier = $this->getInstanceRegistrationOpenTimeModifier(); + $reg_start = clone $event_start_date; + $reg_start->modify($open_time_modifier); + break; + } - // Subtract the number of days/hours from the event start date. - $reg_start->modify('-' . $reg_time_string); + // Calculate registration closing time. + switch ($this->getInstanceRegistrationCloseScheduleType()) { + case 'start': + $reg_end = clone $event_start_date; + break; + + case 'end': + $reg_end = clone $event_end_date; + break; + + case 'custom': + $close_time_modifier = $this->getInstanceRegistrationCloseTimeModifier(); + $reg_end = clone $event_start_date; + $reg_end->modify($close_time_modifier); + break; } + break; }