support reminders with event types/templates and multiple event/type/template IDs
fix
return $query;
}
+ /**
+ * Determine whether a schedule based on this mapping should
+ * send to additional contacts.
+ */
+ public function sendToAdditional($entityId): bool {
+ return TRUE;
+ }
+
}
return $query;
}
+ /**
+ * Determine whether a schedule based on this mapping should
+ * send to additional contacts.
+ */
+ public function sendToAdditional($entityId): bool {
+ return TRUE;
+ }
+
}
return FALSE;
}
+ /**
+ * Determine whether a schedule based on this mapping should
+ * send to additional contacts.
+ */
+ public function sendToAdditional($entityId): bool {
+ return TRUE;
+ }
+
}
return FALSE;
}
+ /**
+ * Determine whether a schedule based on this mapping should
+ * send to additional contacts.
+ */
+ public function sendToAdditional($entityId): bool {
+ return TRUE;
+ }
+
}
}
// build where clause
+ // FIXME: This handles scheduled reminder of type "Event Name" and "Event Type", gives incorrect result on "Event Template".
if (!empty($selectedValues)) {
$valueField = ($this->id == \CRM_Event_ActionMapping::EVENT_TYPE_MAPPING_ID) ? 'event_type_id' : 'id';
$query->where("r.{$valueField} IN (@selectedValues)")
return $query;
}
+ /**
+ * Determine whether a schedule based on this mapping should
+ * send to additional contacts.
+ *
+ * @param string $entityId Either an event ID/event type ID, or a set of event IDs/types separated
+ * by the separation character.
+ */
+ public function sendToAdditional($entityId): bool {
+ $selectedValues = (array) \CRM_Utils_Array::explodePadded($entityId);
+ switch ($this->id) {
+ case self::EVENT_TYPE_MAPPING_ID:
+ $valueTable = 'e';
+ $valueField = 'event_type_id';
+ $templateReminder = FALSE;
+ break;
+
+ case self::EVENT_NAME_MAPPING_ID:
+ $valueTable = 'e';
+ $valueField = 'id';
+ $templateReminder = FALSE;
+ break;
+
+ case self::EVENT_TPL_MAPPING_ID:
+ $valueTable = 't';
+ $valueField = 'id';
+ $templateReminder = TRUE;
+ break;
+ }
+ // Don't send to additional recipients if this event is deleted or a template.
+ $query = new \CRM_Utils_SQL_Select('civicrm_event e');
+ $query
+ ->select('e.id')
+ ->where("e.is_template = 0")
+ ->where("e.is_active = 1");
+ if ($templateReminder) {
+ $query->join('r', 'INNER JOIN civicrm_event t ON e.template_title = t.template_title AND t.is_template = 1');
+ }
+ $sql = $query
+ ->where("{$valueTable}.{$valueField} IN (@selectedValues)")
+ ->param('selectedValues', $selectedValues)
+ ->toSQL();
+ $dao = \CRM_Core_DAO::executeQuery($sql);
+ return (bool) $dao->N;
+ }
+
}
}
}
+ /**
+ * Determine whether a schedule based on this mapping should
+ * send to additional contacts.
+ */
+ public function sendToAdditional($entityId): bool {
+ return TRUE;
+ }
+
}
return FALSE;
}
+ /**
+ * Determine whether a schedule based on this mapping should
+ * send to additional contacts.
+ */
+ abstract public function sendToAdditional($entityId): bool;
+
}
*/
public function resetOnTriggerDateChange($schedule);
+ /**
+ * Determine whether a schedule based on this mapping should
+ * send to additional contacts.
+ */
+ public function sendToAdditional($entityId): bool;
+
}
public function build() {
$this->buildRelFirstPass();
- if ($this->prepareAddlFilter('c.id') && $this->notTemplate()) {
+ if ($this->prepareAddlFilter('c.id') && $this->mapping->sendToAdditional($this->actionSchedule->entity_value)) {
$this->buildAddlFirstPass();
}
$this->buildRelRepeatPass();
}
- if ($this->actionSchedule->is_repeat && $this->prepareAddlFilter('c.id')) {
+ if ($this->actionSchedule->is_repeat && $this->prepareAddlFilter('c.id') && $this->mapping->sendToAdditional($this->actionSchedule->entity_value)) {
$this->buildAddlRepeatPass();
}
}
return $this->mapping->resetOnTriggerDateChange($this->actionSchedule);
}
- /**
- * Confirm this object isn't attached to a template.
- * Returns TRUE if this action schedule isn't attached to a template.
- * Templates are (currently) unique to events, so we only evaluate those.
- *
- * @return bool;
- */
- private function notTemplate() {
- if ($this->mapping->getEntity() === 'civicrm_participant') {
- $entityId = $this->actionSchedule->entity_value;
- $query = new \CRM_Utils_SQL_Select('civicrm_event e');
- $sql = $query
- ->select('is_template')
- ->where("e.id = {$entityId}")
- ->toSQL();
- $dao = \CRM_Core_DAO::executeQuery($sql);
- return !(bool) $dao->fetchValue();
- }
- return TRUE;
- }
-
}
$this->assertEquals(0, $successfulCronCount);
}
+ /**
+ * Deleted events should not send reminders to additional contacts.
+ *
+ * @throws \CRM_Core_Exception
+ */
+ public function testDeletedEventRemindAddlContacts() {
+ $contactId = $this->individualCreate();
+ $groupId = $this->groupCreate(['name' => 'Additional Contacts', 'title' => 'Additional Contacts']);
+ $this->callAPISuccess('GroupContact', 'create', [
+ 'contact_id' => $contactId,
+ 'group_id' => $groupId,
+ ]);
+ $event = $this->eventCreate(['title' => 'delete this event']);
+ $eventId = $event['id'];
+
+ $this->callAPISuccess('action_schedule', 'create', [
+ 'title' => 'Do not send me',
+ 'subject' => 'I am a reminder attached to a (soon to be) deleted event.',
+ 'entity_value' => $eventId,
+ 'mapping_id' => CRM_Event_ActionMapping::EVENT_NAME_MAPPING_ID,
+ 'start_action_date' => 'start_date',
+ 'start_action_offset' => 1,
+ 'start_action_condition' => 'before',
+ 'start_action_unit' => 'day',
+ 'group_id' => $groupId,
+ 'limit_to' => FALSE,
+ 'mode' => 'Email',
+ ]);
+ $this->callAPISuccess('event', 'delete', ['id' => $eventId]);
+
+ $this->callAPISuccess('job', 'send_reminder', []);
+ $successfulCronCount = CRM_Core_DAO::singleValueQuery('SELECT count(*) FROM civicrm_action_log');
+ $this->assertEquals(0, $successfulCronCount);
+ }
+
/**
* Test scheduled reminders respect limit to (since above identified addition_to handling issue).
*