Completes the refactoring that began with https://github.com/civicrm/civicrm-core/pull/6687
Fully migrates from the old model based on the civicrm_action_mapping table
(dropped in https://github.com/civicrm/civicrm-core/pull/26646)
by removing all references to that structure and fully embracing the object-model.
New common base-class added to make it eaiser to implement MappingInterface.
/**
- * Class CRM_Activity_ActionMapping
- *
* This defines the scheduled-reminder functionality for Activities.
* It is useful for, e.g., sending a reminder based on scheduled
* date or other custom dates on the activity record.
*/
-class CRM_Activity_ActionMapping extends \Civi\ActionSchedule\Mapping {
+class CRM_Activity_ActionMapping extends \Civi\ActionSchedule\MappingBase {
/**
- * The value for civicrm_action_schedule.mapping_id which identifies the
- * "Activity" mapping.
- *
- * Note: This value is chosen to match legacy DB IDs.
+ * Note: This value is an integer for legacy reasons; but going forward any new
+ * action mapping classes should return a string from `getId` instead of using a constant.
*/
const ACTIVITY_MAPPING_ID = 1;
- /**
- * Register Activity-related action mappings.
- *
- * @param \Civi\ActionSchedule\Event\MappingRegisterEvent $registrations
- */
- public static function onRegisterActionMappings(\Civi\ActionSchedule\Event\MappingRegisterEvent $registrations) {
- $registrations->register(CRM_Activity_ActionMapping::create([
- 'id' => CRM_Activity_ActionMapping::ACTIVITY_MAPPING_ID,
- 'entity' => 'civicrm_activity',
- 'entity_label' => ts('Activity'),
- 'entity_value' => 'activity_type',
- 'entity_value_label' => ts('Activity Type'),
- 'entity_status' => 'activity_status',
- 'entity_status_label' => ts('Activity Status'),
- 'entity_date_start' => 'activity_date_time',
- ]));
+ public function getId() {
+ return self::ACTIVITY_MAPPING_ID;
+ }
+
+ public function getEntityName(): string {
+ return 'Activity';
+ }
+
+ public function getValueHeader(): string {
+ return ts('Activity Type');
+ }
+
+ public function getValueLabels(): array {
+ // CRM-20510: Include CiviCampaign activity types along with CiviCase IF component is enabled
+ $activityTypes = \CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'label', TRUE);
+ asort($activityTypes);
+ return $activityTypes;
+ }
+
+ public function getStatusHeader(): string {
+ return ts('Activity Status');
+ }
+
+ public function getStatusLabels($value): array {
+ return CRM_Core_PseudoConstant::activityStatus();
+ }
+
+ public function getDateFields(): array {
+ return [
+ 'activity_date_time' => ts('Activity Date'),
+ ];
}
/**
* array(string $value => string $label).
* Ex: array('assignee' => 'Activity Assignee').
*/
- public function getRecipientTypes() {
+ public function getRecipientTypes(): array {
return \CRM_Core_OptionGroup::values('activity_contacts');
}
* @return \CRM_Utils_SQL_Select
* @see RecipientBuilder
*/
- public function createQuery($schedule, $phase, $defaultParams) {
+ public function createQuery($schedule, $phase, $defaultParams): CRM_Utils_SQL_Select {
$selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value);
$selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status);
- $query = \CRM_Utils_SQL_Select::from("{$this->entity} e")->param($defaultParams);
+ $query = \CRM_Utils_SQL_Select::from("{$this->getEntityTable()} e")->param($defaultParams);
$query['casAddlCheckFrom'] = 'civicrm_activity e';
$query['casContactIdField'] = 'r.contact_id';
$query['casEntityIdField'] = 'e.id';
return $query;
}
- /**
- * Determine whether a schedule based on this mapping should
- * send to additional contacts.
- */
- public function sendToAdditional($entityId): bool {
- return TRUE;
- }
-
}
/**
- * Class CRM_Contact_ActionMapping
- *
* This defines the scheduled-reminder functionality for contact
* entities. It is useful for, e.g., sending a reminder based on
* birth date, modification date, or other custom dates on
* the contact record.
*/
-class CRM_Contact_ActionMapping extends \Civi\ActionSchedule\Mapping {
+class CRM_Contact_ActionMapping extends \Civi\ActionSchedule\MappingBase {
/**
- * The value for civicrm_action_schedule.mapping_id which identifies the
- * "Contact" mapping.
- *
- * Note: This value is chosen to match legacy DB IDs.
+ * Note: This value is an integer for legacy reasons; but going forward any new
+ * action mapping classes should return a string from `getId` instead of using a constant.
*/
const CONTACT_MAPPING_ID = 6;
- /**
- * Register Contact-related action mappings.
- *
- * @param \Civi\ActionSchedule\Event\MappingRegisterEvent $registrations
- */
- public static function onRegisterActionMappings(\Civi\ActionSchedule\Event\MappingRegisterEvent $registrations) {
- $registrations->register(CRM_Contact_ActionMapping::create([
- 'id' => CRM_Contact_ActionMapping::CONTACT_MAPPING_ID,
- 'entity' => 'civicrm_contact',
- 'entity_label' => ts('Contact'),
- 'entity_value' => 'civicrm_contact',
- 'entity_value_label' => ts('Date Field'),
- 'entity_status' => 'contact_date_reminder_options',
- 'entity_status_label' => ts('Annual Options'),
- 'entity_date_start' => 'date_field',
- ]));
+ public function getId() {
+ return self::CONTACT_MAPPING_ID;
+ }
+
+ public function getEntityName(): string {
+ return 'Contact';
+ }
+
+ public function getValueHeader(): string {
+ return ts('Date Field');
+ }
+
+ public function getValueLabels(): array {
+ $allCustomFields = \CRM_Core_BAO_CustomField::getFields('');
+ $dateFields = [
+ 'birth_date' => ts('Birth Date'),
+ 'created_date' => ts('Created Date'),
+ 'modified_date' => ts('Modified Date'),
+ ];
+ foreach ($allCustomFields as $fieldID => $field) {
+ if ($field['data_type'] == 'Date') {
+ $dateFields["custom_$fieldID"] = $field['label'];
+ }
+ }
+ return $dateFields;
+ }
+
+ public function getStatusHeader(): string {
+ return ts('Annual Options');
+ }
+
+ public function getStatusLabels($value): array {
+ return CRM_Core_OptionGroup::values('contact_date_reminder_options');
+ }
+
+ public function getDateFields(): array {
+ return [
+ 'date_field' => ts('Date Field'),
+ ];
}
private $contactDateFields = [
* Array (string $code => string $message).
* List of error messages.
*/
- public function validateSchedule($schedule) {
+ public function validateSchedule($schedule): array {
$errors = [];
if (CRM_Utils_System::isNull($schedule->entity_value) || $schedule->entity_value === '0') {
$errors['entity'] = ts('Please select a specific date field.');
* @throws \CRM_Core_Exception
* @see RecipientBuilder
*/
- public function createQuery($schedule, $phase, $defaultParams) {
+ public function createQuery($schedule, $phase, $defaultParams): CRM_Utils_SQL_Select {
$selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value);
$selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status);
}
elseif (in_array($selectedValues[0], $this->contactDateFields)) {
$dateDBField = $selectedValues[0];
- $query = \CRM_Utils_SQL_Select::from("{$this->entity} e")->param($defaultParams);
+ $query = \CRM_Utils_SQL_Select::from("{$this->getEntityTable()} e")->param($defaultParams);
$query->param([
'casAddlCheckFrom' => 'civicrm_contact e',
'casContactIdField' => 'e.id',
return $query;
}
- /**
- * Determine whether a schedule based on this mapping should
- * send to additional contacts.
- */
- public function sendToAdditional($entityId): bool {
- return TRUE;
- }
-
}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+
+/**
+ * This defines the scheduled-reminder functionality for contribution
+ * entities. It is useful for sending a reminder based on:
+ * - The receipt-date, cancel-date, or thankyou-date.
+ * - The type of contribution.
+ * @service
+ * @internal
+ */
+abstract class CRM_Contribute_ActionMapping extends \Civi\ActionSchedule\MappingBase {
+
+ public function getEntityName(): string {
+ return 'Contribution';
+ }
+
+ public function getStatusHeader(): string {
+ return ts('Contribution Status');
+ }
+
+ /**
+ * Get a list of status options.
+ *
+ * @param string|int $value
+ * @return array
+ * @throws CRM_Core_Exception
+ */
+ public function getStatusLabels($value): array {
+ return CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'get', []);
+ }
+
+ public function getDateFields(): array {
+ return [
+ 'receive_date' => ts('Receive Date'),
+ 'cancel_date' => ts('Cancel Date'),
+ 'receipt_date' => ts('Receipt Date'),
+ 'thankyou_date' => ts('Thank You Date'),
+ ];
+ }
+
+}
* - The receipt-date, cancel-date, or thankyou-date.
* - The page on which the contribution was made.
*/
-class CRM_Contribute_ActionMapping_ByPage implements \Civi\ActionSchedule\MappingInterface {
-
- /**
- * The value for civicrm_action_schedule.mapping_id which identifies the
- * "Contribution Page" mapping.
- */
- const MAPPING_ID = 'contribpage';
-
- /**
- * Register Activity-related action mappings.
- *
- * @param \Civi\ActionSchedule\Event\MappingRegisterEvent $registrations
- */
- public static function onRegisterActionMappings(\Civi\ActionSchedule\Event\MappingRegisterEvent $registrations) {
- $registrations->register(new static());
- }
-
- /**
- * @return mixed
- */
- public function getId() {
- return self::MAPPING_ID;
- }
+class CRM_Contribute_ActionMapping_ByPage extends CRM_Contribute_ActionMapping {
/**
* @return string
*/
- public function getEntityTable(): string {
- return 'civicrm_contribution';
- }
-
- public function getEntityName(): string {
- return 'Contribution';
+ public function getId() {
+ return 'contribpage';
}
/**
*
* @return string
*/
- public function getLabel() {
+ public function getLabel(): string {
return ts('Contribution Page');
}
*
* @return string
*/
- public function getValueHeader() {
+ public function getValueHeader(): string {
return ts('Contribution Page');
}
- /**
- * Get a printable label to use as the header on the 'status' filter.
- *
- * @return string
- */
- public function getStatusHeader() {
- return ts('Contribution Status');
- }
-
/**
* Get a list of value options.
*
* Ex: array(123 => 'Phone Call', 456 => 'Meeting').
* @throws CRM_Core_Exception
*/
- public function getValueLabels() {
+ public function getValueLabels(): array {
return CRM_Contribute_BAO_Contribution::buildOptions('contribution_page_id', 'get', []);
}
- /**
- * Get a list of status options.
- *
- * @param string|int $value
- * The list of status options may be contingent upon the selected filter value.
- * This is the selected filter value.
- * @return array
- * Array(string $value => string $label).
- * Ex: Array(123 => 'Completed', 456 => 'Scheduled').
- * @throws CRM_Core_Exception
- */
- public function getStatusLabels($value) {
- return CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'get', []);
- }
-
- /**
- * Get a list of available date fields.
- *
- * @return array
- * Array(string $fieldName => string $fieldLabel).
- */
- public function getDateFields() {
- return [
- 'receive_date' => ts('Receive Date'),
- 'cancel_date' => ts('Cancel Date'),
- 'receipt_date' => ts('Receipt Date'),
- 'thankyou_date' => ts('Thank You Date'),
- ];
- }
-
- /**
- * Get a list of recipient types.
- *
- * Note: A single schedule may filter on *zero* or *one* recipient types.
- * When an admin chooses a value, it's stored in $schedule->recipient.
- *
- * @return array
- * array(string $value => string $label).
- * Ex: array('assignee' => 'Activity Assignee').
- */
- public function getRecipientTypes() {
- return [];
- }
-
- /**
- * Get a list of recipients which match the given type.
- *
- * Note: A single schedule may filter on *multiple* recipients.
- * When an admin chooses value(s), it's stored in $schedule->recipient_listing.
- *
- * @param string $recipientType
- * Ex: 'participant_role'.
- * @return array
- * Array(mixed $name => string $label).
- * Ex: array(1 => 'Attendee', 2 => 'Volunteer').
- * @see getRecipientTypes
- */
- public function getRecipientListing($recipientType) {
- return [];
- }
-
- /**
- * Determine whether a schedule based on this mapping is sufficiently
- * complete.
- *
- * @param \CRM_Core_DAO_ActionSchedule $schedule
- * @return array
- * Array (string $code => string $message).
- * List of error messages.
- */
- public function validateSchedule($schedule) {
- return [];
- }
-
/**
* Generate a query to locate contacts who match the given
* schedule.
* @see RecipientBuilder
* @throws CRM_Core_Exception
*/
- public function createQuery($schedule, $phase, $defaultParams) {
+ public function createQuery($schedule, $phase, $defaultParams): CRM_Utils_SQL_Select {
$selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value);
$selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status);
return $query;
}
- /**
- * Determine whether a schedule based on this mapping should
- * reset the reminder state if the trigger date changes.
- *
- * @return bool
- *
- * @param \CRM_Core_DAO_ActionSchedule $schedule
- */
- public function resetOnTriggerDateChange($schedule) {
- return FALSE;
- }
-
- /**
- * Determine whether a schedule based on this mapping should
- * send to additional contacts.
- */
- public function sendToAdditional($entityId): bool {
- return TRUE;
- }
-
}
* - The receipt-date, cancel-date, or thankyou-date.
* - The type of contribution.
*/
-class CRM_Contribute_ActionMapping_ByType implements \Civi\ActionSchedule\MappingInterface {
-
- /**
- * The value for civicrm_action_schedule.mapping_id which identifies the
- * "Contribution Page" mapping.
- */
- const MAPPING_ID = 'contribtype';
-
- /**
- * Register Activity-related action mappings.
- *
- * @param \Civi\ActionSchedule\Event\MappingRegisterEvent $registrations
- */
- public static function onRegisterActionMappings(\Civi\ActionSchedule\Event\MappingRegisterEvent $registrations) {
- $registrations->register(new static());
- }
-
- /**
- * @return mixed
- */
- public function getId() {
- return self::MAPPING_ID;
- }
-
- /**
- * @return string
- */
- public function getEntityTable(): string {
- return 'civicrm_contribution';
- }
+class CRM_Contribute_ActionMapping_ByType extends CRM_Contribute_ActionMapping {
/**
* @return string
*/
- public function getEntityName(): string {
- return 'Contribution';
+ public function getId() {
+ return 'contribtype';
}
/**
*
* @return string
*/
- public function getLabel() {
+ public function getLabel(): string {
return ts('Contribution Type');
}
*
* @return string
*/
- public function getValueHeader() {
+ public function getValueHeader(): string {
return ts('Financial Type');
}
- /**
- * Get a printable label to use as the header on the 'status' filter.
- *
- * @return string
- */
- public function getStatusHeader() {
- return ts('Contribution Status');
- }
-
/**
* Get a list of value options.
*
* Ex: array(123 => 'Phone Call', 456 => 'Meeting').
* @throws CRM_Core_Exception
*/
- public function getValueLabels() {
+ public function getValueLabels(): array {
return CRM_Contribute_BAO_Contribution::buildOptions('financial_type_id', 'get', []);
}
- /**
- * Get a list of status options.
- *
- * @param string|int $value
- * The list of status options may be contingent upon the selected filter value.
- * This is the selected filter value.
- * @return array
- * Array(string $value => string $label).
- * Ex: Array(123 => 'Completed', 456 => 'Scheduled').
- * @throws CRM_Core_Exception
- */
- public function getStatusLabels($value) {
- return CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'get', []);
- }
-
- /**
- * Get a list of available date fields.
- *
- * @return array
- * Array(string $fieldName => string $fieldLabel).
- */
- public function getDateFields() {
- return [
- 'receive_date' => ts('Receive Date'),
- 'cancel_date' => ts('Cancel Date'),
- 'receipt_date' => ts('Receipt Date'),
- 'thankyou_date' => ts('Thank You Date'),
- ];
- }
-
/**
* Get a list of recipient types.
*
* array(string $value => string $label).
* Ex: array('assignee' => 'Activity Assignee').
*/
- public function getRecipientTypes() {
+ public function getRecipientTypes(): array {
return [
'soft_credit_type' => ts('Soft Credit Role'),
];
* Ex: array(1 => 'Attendee', 2 => 'Volunteer').
* @see getRecipientTypes
*/
- public function getRecipientListing($recipientType) {
+ public function getRecipientListing($recipientType): array {
switch ($recipientType) {
case 'soft_credit_type':
return \CRM_Core_OptionGroup::values('soft_credit_type', FALSE, FALSE, FALSE, NULL, 'label', TRUE, FALSE, 'name');
}
}
- /**
- * Determine whether a schedule based on this mapping is sufficiently
- * complete.
- *
- * @param \CRM_Core_DAO_ActionSchedule $schedule
- * @return array
- * Array (string $code => string $message).
- * List of error messages.
- */
- public function validateSchedule($schedule) {
- return [];
- }
-
/**
* Generate a query to locate contacts who match the given
* schedule.
* @see RecipientBuilder
* @throws CRM_Core_Exception
*/
- public function createQuery($schedule, $phase, $defaultParams) {
+ public function createQuery($schedule, $phase, $defaultParams): CRM_Utils_SQL_Select {
$selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value);
$selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status);
return $query;
}
- /**
- * Determine whether a schedule based on this mapping should
- * reset the reminder state if the trigger date changes.
- *
- * @return bool
- *
- * @param \CRM_Core_DAO_ActionSchedule $schedule
- */
- public function resetOnTriggerDateChange($schedule) {
- return FALSE;
- }
-
- /**
- * Determine whether a schedule based on this mapping should
- * send to additional contacts.
- */
- public function sendToAdditional($entityId): bool {
- return TRUE;
- }
-
}
use Civi\ActionSchedule\RecipientBuilder;
/**
- * Class CRM_Event_ActionMapping
- *
- * This defines the scheduled-reminder functionality for CiviEvent
- * participants. It allows one to target messages on the
- * event's start-date/end-date, with additional filtering by
- * event-type, event-template, or event-id.
+ * Shared scheduled-reminder functionality for CiviEvent participants.
*/
-class CRM_Event_ActionMapping extends \Civi\ActionSchedule\Mapping {
+abstract class CRM_Event_ActionMapping extends \Civi\ActionSchedule\MappingBase {
/**
- * The value for civicrm_action_schedule.mapping_id which identifies the
- * "Event Type" mapping.
- *
- * Note: This value is chosen to match legacy DB IDs.
+ * Note: These values are integers for legacy reasons; but going forward any new
+ * action mapping classes should return a string from `getId` instead of using a constant.
*/
const EVENT_TYPE_MAPPING_ID = 2;
const EVENT_NAME_MAPPING_ID = 3;
const EVENT_TPL_MAPPING_ID = 5;
- /**
- * Register CiviEvent-related action mappings.
- *
- * @param \Civi\ActionSchedule\Event\MappingRegisterEvent $registrations
- */
- public static function onRegisterActionMappings(\Civi\ActionSchedule\Event\MappingRegisterEvent $registrations) {
- $registrations->register(CRM_Event_ActionMapping::create([
- 'id' => CRM_Event_ActionMapping::EVENT_TYPE_MAPPING_ID,
- 'entity' => 'civicrm_participant',
- 'entity_label' => ts('Event Type'),
- 'entity_value' => 'event_type',
- 'entity_value_label' => ts('Event Type'),
- 'entity_status' => 'civicrm_participant_status_type',
- 'entity_status_label' => ts('Participant Status'),
- ]));
- $registrations->register(CRM_Event_ActionMapping::create([
- 'id' => CRM_Event_ActionMapping::EVENT_NAME_MAPPING_ID,
- 'entity' => 'civicrm_participant',
- 'entity_label' => ts('Event Name'),
- 'entity_value' => 'civicrm_event',
- 'entity_value_label' => ts('Event Name'),
- 'entity_status' => 'civicrm_participant_status_type',
- 'entity_status_label' => ts('Participant Status'),
- ]));
- $registrations->register(CRM_Event_ActionMapping::create([
- 'id' => CRM_Event_ActionMapping::EVENT_TPL_MAPPING_ID,
- 'entity' => 'civicrm_participant',
- 'entity_label' => ts('Event Template'),
- 'entity_value' => 'event_template',
- 'entity_value_label' => ts('Event Template'),
- 'entity_status' => 'civicrm_participant_status_type',
- 'entity_status_label' => ts('Participant Status'),
- ]));
+ public function getEntityName(): string {
+ return 'Participant';
+ }
+
+ public function getStatusHeader(): string {
+ return ts('Participant Status');
+ }
+
+ public function getStatusLabels($value): array {
+ return CRM_Event_PseudoConstant::participantStatus(NULL, NULL, 'label');
}
/**
* @return array
* Array(string $fieldName => string $fieldLabel).
*/
- public function getDateFields() {
+ public function getDateFields(): array {
return [
'start_date' => ts('Event Start'),
'end_date' => ts('Event End'),
* array(string $value => string $label).
* Ex: array('assignee' => 'Activity Assignee').
*/
- public function getRecipientTypes() {
+ public function getRecipientTypes(): array {
return \CRM_Core_OptionGroup::values('event_contacts', FALSE, FALSE, FALSE, NULL, 'label', TRUE, FALSE, 'name');
}
* Ex: array(1 => 'Attendee', 2 => 'Volunteer').
* @see getRecipientTypes
*/
- public function getRecipientListing($recipientType) {
+ public function getRecipientListing($recipientType): array {
switch ($recipientType) {
case 'participant_role':
return \CRM_Event_PseudoConstant::participantRole();
* @return \CRM_Utils_SQL_Select
* @see RecipientBuilder
*/
- public function createQuery($schedule, $phase, $defaultParams) {
+ public function createQuery($schedule, $phase, $defaultParams): CRM_Utils_SQL_Select {
$selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value);
$selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status);
- $query = \CRM_Utils_SQL_Select::from("{$this->entity} e")->param($defaultParams);
+ $query = \CRM_Utils_SQL_Select::from("{$this->getEntityTable()} e")->param($defaultParams);
$query['casAddlCheckFrom'] = 'civicrm_event r';
$query['casContactIdField'] = 'e.contact_id';
$query['casEntityIdField'] = 'e.id';
// 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';
+ $valueField = ($this->getId() == self::EVENT_TYPE_MAPPING_ID) ? 'event_type_id' : 'id';
$query->where("r.{$valueField} IN (@selectedValues)")
->param('selectedValues', $selectedValues);
}
else {
- $query->where(($this->id == \CRM_Event_ActionMapping::EVENT_TYPE_MAPPING_ID) ? "r.event_type_id IS NULL" : "r.id IS NULL");
+ $query->where(($this->getId() == self::EVENT_TYPE_MAPPING_ID) ? "r.event_type_id IS NULL" : "r.id IS NULL");
}
$query->where('r.is_active = 1');
*/
public function sendToAdditional($entityId): bool {
$selectedValues = (array) \CRM_Utils_Array::explodePadded($entityId);
- switch ($this->id) {
+ switch ($this->getId()) {
case self::EVENT_TYPE_MAPPING_ID:
$valueTable = 'e';
$valueField = 'event_type_id';
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * This defines the scheduled-reminder functionality for CiviEvent
+ * participants with filtering by event-type.
+ */
+class CRM_Event_ActionMapping_ByEvent extends CRM_Event_ActionMapping {
+
+ public function getId() {
+ return self::EVENT_NAME_MAPPING_ID;
+ }
+
+ public function getLabel(): string {
+ return ts('Event Name');
+ }
+
+ public function getValueLabels(): array {
+ return CRM_Event_PseudoConstant::event(NULL, FALSE, "( is_template IS NULL OR is_template != 1 )");
+ }
+
+}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * This defines the scheduled-reminder functionality for CiviEvent
+ * participants with filtering by event-type.
+ */
+class CRM_Event_ActionMapping_ByTemplate extends CRM_Event_ActionMapping {
+
+ public function getId() {
+ return self::EVENT_TPL_MAPPING_ID;
+ }
+
+ public function getLabel(): string {
+ return ts('Event Template');
+ }
+
+ public function getValueLabels(): array {
+ return \Civi\Api4\Event::get(FALSE)
+ ->addWhere('is_template', '=', TRUE)
+ ->addWhere('is_active', '=', TRUE)
+ ->execute()
+ ->indexBy('id')
+ ->column('template_title');
+ }
+
+}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * This defines the scheduled-reminder functionality for CiviEvent
+ * participants with filtering by event-type.
+ */
+class CRM_Event_ActionMapping_ByType extends CRM_Event_ActionMapping {
+
+ public function getId() {
+ return self::EVENT_TYPE_MAPPING_ID;
+ }
+
+ public function getLabel(): string {
+ return ts('Event Type');
+ }
+
+ public function getValueLabels(): array {
+ return CRM_Event_PseudoConstant::eventType();
+ }
+
+}
/**
- * Class CRM_Member_ActionMapping
- *
* This defines the scheduled-reminder functionality for CiviMember
* memberships. It allows one to target reminders based on join date
* or end date, with additional filtering based on membership-type.
*/
-class CRM_Member_ActionMapping extends \Civi\ActionSchedule\Mapping {
+class CRM_Member_ActionMapping extends \Civi\ActionSchedule\MappingBase {
/**
- * The value for civicrm_action_schedule.mapping_id which identifies the
- * "Membership Type" mapping.
- *
- * Note: This value is chosen to match legacy DB IDs.
+ * Note: This value is an integer for legacy reasons; but going forward any new
+ * action mapping classes should return a string from `getId` instead of using a constant.
*/
const MEMBERSHIP_TYPE_MAPPING_ID = 4;
- /**
- * Register CiviMember-related action mappings.
- *
- * @param \Civi\ActionSchedule\Event\MappingRegisterEvent $registrations
- */
- public static function onRegisterActionMappings(\Civi\ActionSchedule\Event\MappingRegisterEvent $registrations) {
- $registrations->register(CRM_Member_ActionMapping::create([
- 'id' => CRM_Member_ActionMapping::MEMBERSHIP_TYPE_MAPPING_ID,
- 'entity' => 'civicrm_membership',
- 'entity_label' => ts('Membership'),
- 'entity_value' => 'civicrm_membership_type',
- 'entity_value_label' => ts('Membership Type'),
- 'entity_status' => 'auto_renew_options',
- 'entity_status_label' => ts('Auto Renew Options'),
- ]));
+ public function getId() {
+ return self::MEMBERSHIP_TYPE_MAPPING_ID;
+ }
+
+ public function getEntityName(): string {
+ return 'Membership';
+ }
+
+ public function getValueHeader(): string {
+ return ts('Membership Type');
+ }
+
+ public function getValueLabels(): array {
+ return CRM_Member_PseudoConstant::membershipType();
+ }
+
+ public function getStatusHeader(): string {
+ return ts('Auto Renew Options');
+ }
+
+ public function getStatusLabels($value): array {
+ if ($value && \CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $value, 'auto_renew')) {
+ return \CRM_Core_OptionGroup::values('auto_renew_options');
+ }
+ else {
+ return [];
+ }
}
/**
* @return array
* Array(string $fieldName => string $fieldLabel).
*/
- public function getDateFields() {
+ public function getDateFields(): array {
return [
'join_date' => ts('Member Since'),
'start_date' => ts('Membership Start Date'),
* @return \CRM_Utils_SQL_Select
* @see RecipientBuilder
*/
- public function createQuery($schedule, $phase, $defaultParams) {
+ public function createQuery($schedule, $phase, $defaultParams): CRM_Utils_SQL_Select {
$selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value);
$selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status);
- $query = \CRM_Utils_SQL_Select::from("{$this->entity} e")->param($defaultParams);
+ $query = \CRM_Utils_SQL_Select::from("{$this->getEntityTable()} e")->param($defaultParams);
$query['casAddlCheckFrom'] = 'civicrm_membership e';
$query['casContactIdField'] = 'e.contact_id';
$query['casEntityIdField'] = 'e.id';
*
* @param \CRM_Core_DAO_ActionSchedule $schedule
*/
- public function resetOnTriggerDateChange($schedule) {
+ public function resetOnTriggerDateChange($schedule): bool {
if ($schedule->absolute_date !== NULL) {
return FALSE;
}
}
}
- /**
- * Determine whether a schedule based on this mapping should
- * send to additional contacts.
- */
- public function sendToAdditional($entityId): bool {
- return TRUE;
- }
-
}
+++ /dev/null
-<?php
-/*
- +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC. All rights reserved. |
- | |
- | This work is published under the GNU AGPLv3 license with some |
- | permitted exceptions and without any warranty. For full license |
- | and copyright information, see https://civicrm.org/licensing |
- +--------------------------------------------------------------------+
- */
-
-namespace Civi\ActionSchedule;
-
-/**
- * Class Mapping
- * @package Civi\ActionSchedule
- *
- * This is the initial implementation of MappingInterface; it was
- * constructed by cutting out swaths from CRM_Core_BAO_ActionSchedule.
- * New implementers should consider implementing MappingInterface on
- * their own.
- *
- * Background: The original designers of ActionMappings intended that
- * one could create and configure new mappings through the database.
- * To, e.g., define the filtering options for CiviEvent, you
- * would insert a record in "civicrm_action_mapping" with fields like
- * "entity" (a table name, eg "civicrm_event"), "entity_value" (an
- * option-group name, eg "event_types").
- *
- * Unfortunately, the metadata in "civicrm_action_mapping" proved
- * inadequate and was not updated to cope. Instead, a number
- * of work-arounds for specific entities were hard-coded into
- * the core action-scheduling code. Ultimately, to add a new
- * mapping type, one needed to run around and patch a dozen
- * places.
- *
- * The new MappingInterface makes no pretense of database-driven
- * configuration. The dozen places have been consolidated and
- * replaced with functions in MappingInterface.
- * The unused `civicrm_action_mapping` table has been dropped.
- *
- * This "Mapping" implementation is a refactoring of the old
- * hard-coded bits. Internally, it uses the concepts from
- * "civicrm_action_mapping". The resulting code is more
- * convoluted than a clean implementation of MappingInterface, but
- * it strictly matches the old behavior (based on logging/comparing
- * the queries produced through ActionScheduleTest).
- */
-abstract class Mapping implements MappingInterface {
-
- private static $fields = [
- 'id',
- 'entity',
- 'entity_label',
- 'entity_value',
- 'entity_value_label',
- 'entity_status',
- 'entity_status_label',
- 'entity_date_start',
- 'entity_date_end',
- ];
-
- /**
- * Create mapping.
- *
- * @param array $params
- *
- * @return static
- */
- public static function create($params) {
- return new static($params);
- }
-
- /**
- * Class constructor.
- *
- * @param array $params
- */
- public function __construct($params) {
- foreach (self::$fields as $field) {
- if (isset($params[$field])) {
- $this->{$field} = $params[$field];
- }
- }
- }
-
- protected $id;
-
- /**
- * The basic entity to query (table name).
- *
- * @var string
- * Ex: 'civicrm_activity', 'civicrm_event'.
- */
- protected $entity;
-
- /**
- * The basic entity to query (label).
- *
- * @var string
- * Ex: 'Activity', 'Event'
- */
- private $entity_label;
-
- /**
- * Level 1 filter -- the field/option-list to filter on.
- *
- * @var string
- * Ex: 'activity_type', 'civicrm_event', 'event_template'.
- */
- private $entity_value;
-
- /**
- * Level 1 filter -- The field label.
- *
- * @var string
- * Ex: 'Activity Type', 'Event Name', 'Event Template'.
- */
- private $entity_value_label;
-
- /**
- * Level 2 filter -- the field/option-list to filter on.
- * @var string
- * Ex: 'activity_status, 'civicrm_participant_status_type', 'auto_renew_options'.
- */
- private $entity_status;
-
- /**
- * Level 2 filter -- the field label.
- * @var string
- * Ex: 'Activity Status', 'Participant Status', 'Auto Rewnewal Options'.
- */
- private $entity_status_label;
-
- /**
- * Date filter -- the field name.
- * @var string|null
- * Ex: 'event_start_date'
- */
- private $entity_date_start;
-
- /**
- * Date filter -- the field name.
- * @var string|null
- * Ex: 'event_end_date'.
- */
- private $entity_date_end;
-
- /**
- * @return mixed
- */
- public function getId() {
- return $this->id;
- }
-
- /**
- * @return string
- */
- public function getEntityTable(): string {
- return $this->entity;
- }
-
- public function getEntityName(): string {
- return \CRM_Core_DAO_AllCoreTables::getEntityNameForTable($this->getEntityTable());
- }
-
- /**
- * Get a printable label for this mapping type.
- *
- * @return string
- */
- public function getLabel() {
- return $this->entity_label;
- }
-
- /**
- * Get a printable label to use a header on the 'value' filter.
- *
- * @return string
- */
- public function getValueHeader() {
- return $this->entity_value_label;
- }
-
- /**
- * Get a printable label to use a header on the 'status' filter.
- *
- * @return string
- */
- public function getStatusHeader() {
- return $this->entity_status_label;
- }
-
- /**
- * Get a list of value options.
- *
- * @return array
- * Array(string $value => string $label).
- * Ex: array(123 => 'Phone Call', 456 => 'Meeting').
- */
- public function getValueLabels() {
- return self::getValueLabelMap($this->entity_value);
- }
-
- /**
- * Get a list of status options.
- *
- * @param string|int $value
- * The list of status options may be contingent upon the selected filter value.
- * This is the selected filter value.
- * @return array
- * Array(string $value => string $label).
- * Ex: Array(123 => 'Completed', 456 => 'Scheduled').
- */
- public function getStatusLabels($value) {
- if ($this->entity_status === 'auto_renew_options') {
- if ($value && \CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $value, 'auto_renew')) {
- return \CRM_Core_OptionGroup::values('auto_renew_options');
- }
- else {
- return [];
- }
- }
- return self::getValueLabelMap($this->entity_status);
- }
-
- /**
- * Get a list of available date fields.
- *
- * @return array
- * Array(string $fieldName => string $fieldLabel).
- */
- public function getDateFields() {
- $dateFieldLabels = [];
- if (!empty($this->entity_date_start)) {
- $dateFieldLabels[$this->entity_date_start] = ucwords(str_replace('_', ' ', $this->entity_date_start));
- }
- if (!empty($this->entity_date_end)) {
- $dateFieldLabels[$this->entity_date_end] = ucwords(str_replace('_', ' ', $this->entity_date_end));
- }
- return $dateFieldLabels;
- }
-
- /**
- * Get a list of recipient types.
- *
- * Note: A single schedule may filter on *zero* or *one* recipient types.
- * When an admin chooses a value, it's stored in $schedule->recipient.
- *
- * @return array
- * array(string $value => string $label).
- * Ex: array('assignee' => 'Activity Assignee').
- */
- public function getRecipientTypes() {
- return [];
- }
-
- /**
- * Get a list of recipients which match the given type.
- *
- * Note: A single schedule may filter on *multiple* recipients.
- * When an admin chooses value(s), it's stored in $schedule->recipient_listing.
- *
- * @param string $recipientType
- * Ex: 'participant_role'.
- * @return array
- * Array(mixed $name => string $label).
- * Ex: array(1 => 'Attendee', 2 => 'Volunteer').
- * @see getRecipientTypes
- */
- public function getRecipientListing($recipientType) {
- return [];
- }
-
- protected static function getValueLabelMap($name) {
- static $valueLabelMap = NULL;
- if ($valueLabelMap === NULL) {
- // CRM-20510: Include CiviCampaign activity types along with CiviCase IF component is enabled
- $valueLabelMap['activity_type'] = \CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'label', TRUE);
- asort($valueLabelMap['activity_type']);
-
- $valueLabelMap['activity_status'] = \CRM_Core_PseudoConstant::activityStatus();
- $valueLabelMap['event_type'] = \CRM_Event_PseudoConstant::eventType();
- $valueLabelMap['civicrm_event'] = \CRM_Event_PseudoConstant::event(NULL, FALSE, "( is_template IS NULL OR is_template != 1 )");
- $valueLabelMap['civicrm_participant_status_type'] = \CRM_Event_PseudoConstant::participantStatus(NULL, NULL, 'label');
- $valueLabelMap['event_template'] = \Civi\Api4\Event::get(FALSE)
- ->addWhere('is_template', '=', TRUE)
- ->addWhere('is_active', '=', TRUE)
- ->execute()
- ->indexBy('id')
- ->column('template_title');
- $valueLabelMap['auto_renew_options'] = \CRM_Core_OptionGroup::values('auto_renew_options');
- $valueLabelMap['contact_date_reminder_options'] = \CRM_Core_OptionGroup::values('contact_date_reminder_options');
- $valueLabelMap['civicrm_membership_type'] = \CRM_Member_PseudoConstant::membershipType();
-
- $allCustomFields = \CRM_Core_BAO_CustomField::getFields('');
- $dateFields = [
- 'birth_date' => ts('Birth Date'),
- 'created_date' => ts('Created Date'),
- 'modified_date' => ts('Modified Date'),
- ];
- foreach ($allCustomFields as $fieldID => $field) {
- if ($field['data_type'] == 'Date') {
- $dateFields["custom_$fieldID"] = $field['label'];
- }
- }
- $valueLabelMap['civicrm_contact'] = $dateFields;
- }
-
- return $valueLabelMap[$name];
- }
-
- /**
- * Determine whether a schedule based on this mapping is sufficiently
- * complete.
- *
- * @param \CRM_Core_DAO_ActionSchedule $schedule
- * @return array
- * Array (string $code => string $message).
- * List of error messages.
- */
- public function validateSchedule($schedule) {
- return [];
- }
-
- /**
- * Generate a query to locate contacts who match the given
- * schedule.
- *
- * @param \CRM_Core_DAO_ActionSchedule $schedule
- * @param string $phase
- * See, e.g., RecipientBuilder::PHASE_RELATION_FIRST.
- * @param array $defaultParams
- * @return \CRM_Utils_SQL_Select
- */
- abstract public function createQuery($schedule, $phase, $defaultParams);
-
- /**
- * Determine whether a schedule based on this mapping should
- * reset the reminder state if the trigger date changes.
- *
- * @return bool
- *
- * @param \CRM_Core_DAO_ActionSchedule $schedule
- */
- public function resetOnTriggerDateChange($schedule) {
- return FALSE;
- }
-
- /**
- * Determine whether a schedule based on this mapping should
- * send to additional contacts.
- */
- abstract public function sendToAdditional($entityId): bool;
-
-}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\ActionSchedule;
+
+use Civi\Api4\Utils\CoreUtil;
+
+/**
+ * Base implementation of MappingInterface.
+ *
+ * Extend this class to register a new type of ActionSchedule mapping.
+ * Note: When choosing a value to return from `getId()`, use a "machine name" style string.
+ */
+abstract class MappingBase implements MappingInterface {
+
+ /**
+ * Register this action mapping type with CRM_Core_BAO_ActionSchedule.
+ *
+ * @param \Civi\ActionSchedule\Event\MappingRegisterEvent $registrations
+ */
+ public static function onRegisterActionMappings(\Civi\ActionSchedule\Event\MappingRegisterEvent $registrations): void {
+ $registrations->register(new static());
+ }
+
+ public function getEntityTable(): string {
+ return \CRM_Core_DAO_AllCoreTables::getTableForEntityName($this->getEntityName());
+ }
+
+ /**
+ * Deprecated ambiguously-named function.
+ * @deprecated
+ * @return string
+ */
+ public function getEntity(): string {
+ \CRM_Core_Error::deprecatedFunctionWarning('getEntityTable');
+ return $this->getEntityTable();
+ }
+
+ public function getLabel(): string {
+ return CoreUtil::getInfoItem($this->getEntityName(), 'title');
+ }
+
+ public function getValueHeader(): string {
+ return $this->getLabel();
+ }
+
+ public function getRecipientListing($recipientType): array {
+ return [];
+ }
+
+ public function getRecipientTypes(): array {
+ return [];
+ }
+
+ public function validateSchedule($schedule): array {
+ return [];
+ }
+
+ public function getDateFields(): array {
+ return [];
+ }
+
+ public function resetOnTriggerDateChange($schedule): bool {
+ return FALSE;
+ }
+
+ public function sendToAdditional($entityId): bool {
+ return TRUE;
+ }
+
+}
interface MappingInterface {
/**
- * @return mixed
+ * Unique identifier of this mapping type.
+ *
+ * Should return a "machine name" style string (older implementations return an int -- don't follow their example).
+ * @return string|int
*/
public function getId();
public function getEntityName(): string;
/**
- * Get a printable label for this mapping type.
- *
+ * Label of this mapping type as shown in the "Entity" dropdown-select on the form.
* @return string
*/
public function getLabel();
/**
- * Get a printable label to use as the header on the 'value' filter.
- *
+ * Label of the primary filter field on the form, e.g. "Activity Type"
* @return string
*/
- public function getValueHeader();
+ public function getValueHeader(): string;
/**
* Get a printable label to use as the header on the 'status' filter.
*
* @return string
*/
- public function getStatusHeader();
+ public function getStatusHeader(): string;
/**
* Get a list of value options.
* Array(string $value => string $label).
* Ex: array(123 => 'Phone Call', 456 => 'Meeting').
*/
- public function getValueLabels();
+ public function getValueLabels(): array;
/**
* Get a list of status options.
* Array(string $value => string $label).
* Ex: Array(123 => 'Completed', 456 => 'Scheduled').
*/
- public function getStatusLabels($value);
+ public function getStatusLabels($value): array;
/**
* Get a list of available date fields.
* @return array
* Array(string $fieldName => string $fieldLabel).
*/
- public function getDateFields();
+ public function getDateFields(): array;
/**
* Get a list of recipient types.
* array(string $value => string $label).
* Ex: array('assignee' => 'Activity Assignee').
*/
- public function getRecipientTypes();
+ public function getRecipientTypes(): array;
/**
* Get a list of recipients which match the given type.
* Ex: array(1 => 'Attendee', 2 => 'Volunteer').
* @see getRecipientTypes
*/
- public function getRecipientListing($recipientType);
+ public function getRecipientListing($recipientType): array;
/**
* Determine whether a schedule based on this mapping is sufficiently
* Array (string $code => string $message).
* List of error messages.
*/
- public function validateSchedule($schedule);
+ public function validateSchedule($schedule): array;
/**
* Generate a query to locate contacts who match the given
* @return \CRM_Utils_SQL_Select
* @see RecipientBuilder
*/
- public function createQuery($schedule, $phase, $defaultParams);
+ public function createQuery($schedule, $phase, $defaultParams): \CRM_Utils_SQL_Select;
/**
* Determine whether a schedule based on this mapping should
*
* @param \CRM_Core_DAO_ActionSchedule $schedule
*/
- public function resetOnTriggerDateChange($schedule);
+ public function resetOnTriggerDateChange($schedule): bool;
/**
* Determine whether a schedule based on this mapping should
$dispatcher->addListener('civi.actionSchedule.getMappings', ['CRM_Contact_ActionMapping', 'onRegisterActionMappings']);
$dispatcher->addListener('civi.actionSchedule.getMappings', ['CRM_Contribute_ActionMapping_ByPage', 'onRegisterActionMappings']);
$dispatcher->addListener('civi.actionSchedule.getMappings', ['CRM_Contribute_ActionMapping_ByType', 'onRegisterActionMappings']);
- $dispatcher->addListener('civi.actionSchedule.getMappings', ['CRM_Event_ActionMapping', 'onRegisterActionMappings']);
+ $dispatcher->addListener('civi.actionSchedule.getMappings', ['CRM_Event_ActionMapping_ByType', 'onRegisterActionMappings']);
+ $dispatcher->addListener('civi.actionSchedule.getMappings', ['CRM_Event_ActionMapping_ByEvent', 'onRegisterActionMappings']);
+ $dispatcher->addListener('civi.actionSchedule.getMappings', ['CRM_Event_ActionMapping_ByTemplate', 'onRegisterActionMappings']);
$dispatcher->addListener('civi.actionSchedule.getMappings', ['CRM_Member_ActionMapping', 'onRegisterActionMappings']);
return $dispatcher;
* Schedule message delivery for contributions of type "Member Dues".
*/
public function scheduleForDues() {
- $this->schedule->mapping_id = CRM_Contribute_ActionMapping_ByType::MAPPING_ID;
+ $this->schedule->mapping_id = 'contribtype';
$this->schedule->start_action_date = 'receive_date';
$this->schedule->entity_value = CRM_Utils_Array::implodePadded([1]);
$this->schedule->entity_status = CRM_Utils_Array::implodePadded([1]);
* Schedule message delivery for contributions of type "Donation".
*/
public function scheduleForDonation() {
- $this->schedule->mapping_id = CRM_Contribute_ActionMapping_ByType::MAPPING_ID;
+ $this->schedule->mapping_id = 'contribtype';
$this->schedule->start_action_date = 'receive_date';
$this->schedule->entity_value = CRM_Utils_Array::implodePadded([2]);
$this->schedule->entity_status = CRM_Utils_Array::implodePadded(NULL);
* Schedule message delivery for any contribution, regardless of type.
*/
public function scheduleForAny() {
- $this->schedule->mapping_id = CRM_Contribute_ActionMapping_ByType::MAPPING_ID;
+ $this->schedule->mapping_id = 'contribtype';
$this->schedule->start_action_date = 'receive_date';
$this->schedule->entity_value = CRM_Utils_Array::implodePadded(NULL);
$this->schedule->entity_status = CRM_Utils_Array::implodePadded(NULL);
* Schedule message delivery to the 'soft credit' assignee.
*/
public function scheduleForSoftCreditor() {
- $this->schedule->mapping_id = CRM_Contribute_ActionMapping_ByType::MAPPING_ID;
+ $this->schedule->mapping_id = 'contribtype';
$this->schedule->start_action_date = 'receive_date';
$this->schedule->entity_value = CRM_Utils_Array::implodePadded(NULL);
$this->schedule->entity_status = CRM_Utils_Array::implodePadded(NULL);