Scheduled Reminders "Additional Recipients" feature sends at wrong time, is incompatible with tokens
Steps to replicate
- Create a new event.
- Create a scheduled reminder for the event. Include event tokens in the message.
- Trigger the scheduled reminder.
Expected result
The email is received at the correct time with the event tokens filled in.
Actual result
Email sends the first time "Send Scheduled Reminders" is triggered; event tokens are missing.
Overview
When a Scheduled Reminder triggers an email, it writes the contact ID, entity ID and entity table to civicrm_action_log
. When the recipient is an "additional recipient", instead of writing the entity ID and table, it writes the contact ID (again) and civicrm_contact
for the table.
On one level, this makes sense - e.g. an additional recipient for an event doesn't have a participant record we can draw on. However, it means that the recipient's email isn't tied to the event, so it a) sends at the wrong time since it doesn't have access to the start_date
, b) tokens don't work, because there's no indication which event the email is in relationship to.
Technical Notes
CRM_Core_BAO_ActionSchedule::prepareMailingQuery()
thinks that civicrm_action_log.entity_id
refers to the participant ID. However, Civi\ActionSchedule\RecipientBuilder::buildAddlFirstPass()
calls $this->selectActionLogFields()
, which ALWAYS writes the entity_table/entity_id as civicrm_contact
and the contact ID when building an additional pass.
As a result, the tokens are resolved for the wrong participant ID.
I'm going to take an initial pass at this but I'm not sure how far I'll get. My strategy:
- Modify the add'l recipient SQL that inserts a record in civicrm_action_log to use the correct entity, not the contact entity.
- As a special case, events should store the event entity, not the participant entity.
- Target the Symfony event that modifies the SQL statement for events to handle event additional participants as a special case.