Problem/Motivation

When creating a series with multiple custom instances, the instances are created without their workflow status set to match the series.

Steps to reproduce

  1. On a fresh Drupal install, enable recurring events and content moderation.
  2. Configure the "Editorial" workflow to apply to both event series and event instances.
  3. Create a new event series and select the "Custom/Single Event" recur type.
  4. Enter the start and end dates/times for the custom instance.
  5. Click "Add another item" and enter the start and end dates/times for a second custom instance.
  6. Set the "Save As" field to "Published" and click Save.

Expected result: The series and both instances should be created as published.
Actual result: The series is published, but the instances are in Draft state.

Note that the problem does not occur if you only create one custom instance (i.e., if you don't click the "Add another item" button). This is a side effect of the AJAX action when you click "Add another item". When the form refreshes, the 'event_instances' computed field on the series entity is evaluated and its value is stored as an empty array (because the instances haven't been created yet). Saving the event then triggers recurring_events_eventseries_insert(), which calls $creation_service->createInstances($entity); to create the instances, then $entity->event_instances->referencedEntities(); to get the instances just created. However, because the computed field is only calculated the first time it is called, this returns the empty array, causing the function to skip the calls to $creation_service->configureDefaultInheritances($instance, $entity->id()); and $creation_service->updateInstanceStatus($instance, $entity); (see recurring_events.module, lines 161–171).

This is easily demonstrated with Xdebug by placing breakpoints in recurring_events_eventseries_insert() and \Drupal\recurring_events\Plugin\ComputedField\EventInstances::computeValue(). If you only create one custom instance, computeValue() isn't invoked until the field is called by the _insert() hook, yielding the correct result. If you click the "Add another item" button, however, computeValue() is invoked during the form rebuild (returning empty), and then not again until after the _insert() hook runs (when the page redirects to the entity view, starting a new request).

Proposed resolution

Change \Drupal\recurring_events\EventCreationService::createInstances() to return the array of instances it creates, and then use that in recurring_events_eventseries_insert() rather than relying on the computed field to query the instances.

API changes

\Drupal\recurring_events\EventCreationService::createInstances() will now return an array. This shouldn't be a problem because the method currently returns void, so no existing code should be using its return value before this change.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

muriqui created an issue. See original summary.

muriqui’s picture

Issue summary: View changes

muriqui’s picture

Status: Active » Needs review
owenbush’s picture

Status: Needs review » Reviewed & tested by the community

Thank you for this issue. This looks good to me. I wonder if the underlying issue is that ->referencedEntities() is cached and not returning all the instances. This has happened elsehwere a number of times and the solution before was to load a fresh copy of the eventseries, but given that the creation service already returns the instances, using that makes sense. I'll get this merged when gitlab isn't being a jerk.

  • owenbush committed 9d16f38 on 2.0.x
    Issue #3318998 by muriqui, owenbush: Instances not created correctly...

  • owenbush committed 2781c49 on 8.x-1.x
    Issue #3318998 by muriqui, owenbush: Instances not created correctly...
owenbush’s picture

Status: Reviewed & tested by the community » Fixed

Merged into the latest dev branch for 8.x-1.x and 2.0.x. Thank you!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.