Allow for Relative Dates on Default Field Values for Registration Settings

Created on 19 April 2023, over 1 year ago
Updated 26 April 2023, over 1 year ago

Problem/Motivation

When configuring the default Registration Settings for an event under the Registration field's manage section, users can set fixed dates. However, this doesn't make sense, as events mostly likely all have different start times. Setting relative dates based on the event's date value would be more appropriate, such as it would allow defaults to open registration one week before and closing it one day before, with a notification a day prior to the event.

Proposed resolution

To address this issue, I believe using strtotime to set default registration values based on the event's date would be a possible solution. It would look something like what I have below but we would need to pull - 1 day from the field settings on the entity that the RegistrationSettings is referencing.

$opening_time = date('Y-m-d\TH:i:s', strtotime('- 1 day', $event->field_dates->value);

I think the hardest to solve would you would need to allow users to select what field we are comparing against on the settings form when a new RegistrationSettings entity is created when enabling registration. Then the strtotime code would need to go into the initFromDefaults.

If this is something you'd like to look at implementing, I could take the first swing at it.

✨ Feature request
Status

Closed: works as designed

Version

3.0

Component

Registration Core

Created by

πŸ‡ΊπŸ‡ΈUnited States josh.fabean

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @josh.fabean
  • πŸ‡ΊπŸ‡ΈUnited States john.oltman

    Thanks for the post! This can be done a few different ways. One successful approach I have seen is to override the Node entity class and add your own postSave that looks for a new Event node (just guessing at the content type name) and if it exists, create a new Registration Settings entity with open and close dates from the Event. And then use the new Registration Scheduled Actions submodule to have notifications sent relative to this date. If admins can change the Event date later, then the postSave will need to be smart enough to track Event updates too (not just new ones), and copy any date changes to the Settings entity created earlier. I can post some code if you want to try this approach and aren't comfortable with overriding entity types. Regardless of approach, this is probably custom and not something I could see going into the core Registration module (especially since the new submodule does indeed support relative date notifications - you just need a way to get your open and close dates set).

  • πŸ‡ΊπŸ‡ΈUnited States john.oltman

    Here's some code. In my_module.module:

    /**
     * Implements hook_entity_type_alter().
     */
    function my_module_entity_type_alter(array &$entity_types) {
      // Extend the node entity type.
      if (isset($entity_types['node'])) {
        $entity_types['node']->setClass('Drupal\my_module\Entity\Node');
      }
    }

    In my_module/src/Entity/Node.php:

    namespace Drupal\my_module\Entity;
    
    use Drupal\Core\Datetime\DrupalDateTime;
    use Drupal\Core\Entity\EntityStorageInterface;
    use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
    use Drupal\node\Entity\Node as BaseNode;
    
    use DateTime;
    use DateTimeZone;
    
    /**
     * Extends the node entity class.
     */
    class Node extends BaseNode {
    
      /**
       * {@inheritdoc}
       */
      public function postSave(EntityStorageInterface $storage, $update = TRUE) {
        parent::postSave($storage, $update);
    
        // Assumes that the content type machine name is "event".
        if ($this->bundle() == 'event') {
          if (!$this->get('field_dates')->isEmpty()) {
    
            // Assumes that field_dates contains the Event start date.
            $date_value = $this->get('field_dates')->first()->getValue()['value'];
            $storage_timezone = new DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE);
            $storage_format = DateTimeItemInterface::DATETIME_STORAGE_FORMAT;
            $date = DrupalDateTime::createFromFormat($storage_format, $date_value, $storage_timezone);
            $php_date = $date->getPhpDateTime();
    
            // Open registration 10 days before the Event starts.
            $open = clone $php_date;
            $open = $open->modify('-10 days')->format($storage_format);
    
            // Close registration 15 minutes after the Event starts.
            $close = clone $php_date;
            $close = $close->modify('+15 minutes')->format($storage_format);
    
            $entity_type_manager = \Drupal::entityTypeManager();
            $handler = $entity_type_manager->getHandler('registration', 'host_entity');
            $host_entity = $handler->createHostEntity($this);
    
            $settings = $entity_type_manager
              ->getStorage('registration_settings')
              ->loadSettingsForHostEntity($host_entity);
            $settings->set('open', $open);
            $settings->set('close', $close);
            $settings->save();
          }
        }
      }
    
    }
  • πŸ‡ΊπŸ‡ΈUnited States john.oltman
  • πŸ‡ΊπŸ‡ΈUnited States josh.fabean

    Thanks, I'm fine doing it that way if it's not something we want to get into the module. Thanks for the reply!

  • Status changed to Closed: works as designed over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States john.oltman
  • πŸ‡ΊπŸ‡ΈUnited States john.oltman
Production build 0.71.5 2024