From 46f5566cdbd45789a49e4f46803449283ab2f96f Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Mon, 3 Aug 2015 19:15:29 -0700 Subject: [PATCH] CRM-13244 - ActionScheduleTmp - Move entity-specific parts to separate classes --- CRM/Activity/ActionMapping.php | 35 +++ CRM/Activity/Tokens.php | 85 ++++++ CRM/Admin/Form/ScheduleReminders.php | 2 +- CRM/Contact/ActionMapping.php | 26 ++ CRM/Core/ActionScheduleTmp.php | 276 ------------------ CRM/Core/BAO/ActionSchedule.php | 2 +- CRM/Event/ActionMapping.php | 58 +++- CRM/Event/BAO/Event.php | 6 +- .../Form/ManageEvent/ScheduleReminders.php | 2 +- CRM/Event/Form/ManageEvent/TabHeader.php | 2 +- CRM/Event/Page/ManageEvent.php | 2 +- CRM/Event/Tokens.php | 126 ++++++++ CRM/Member/ActionMapping.php | 27 ++ CRM/Member/Tokens.php | 87 ++++++ .../Event/MappingRegisterEvent.php | 1 + Civi/Core/Container.php | 15 +- Civi/Token/AbstractTokenSubscriber.php | 159 ++++++++++ tests/phpunit/api/v3/ActionScheduleTest.php | 4 +- 18 files changed, 623 insertions(+), 292 deletions(-) create mode 100644 CRM/Activity/Tokens.php delete mode 100644 CRM/Core/ActionScheduleTmp.php create mode 100644 CRM/Event/Tokens.php create mode 100644 CRM/Member/Tokens.php create mode 100644 Civi/Token/AbstractTokenSubscriber.php diff --git a/CRM/Activity/ActionMapping.php b/CRM/Activity/ActionMapping.php index f379b35df0..3ebe0c4da0 100644 --- a/CRM/Activity/ActionMapping.php +++ b/CRM/Activity/ActionMapping.php @@ -27,8 +27,43 @@ use Civi\ActionSchedule\RecipientBuilder; +/** + * Class CRM_Activity_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_Activity_ActionMapping extends \Civi\ActionSchedule\Mapping { + /** + * The value for civicrm_action_schedule.mapping_id which identifies the + * "Activity" mapping. + * + * Note: This value is chosen to match legacy DB IDs. + */ + 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(array( + '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', + 'entity_recipient' => 'activity_contacts', + ))); + } + /** * Generate a query to locate recipients who match the given * schedule. diff --git a/CRM/Activity/Tokens.php b/CRM/Activity/Tokens.php new file mode 100644 index 0000000000..3a5f99756b --- /dev/null +++ b/CRM/Activity/Tokens.php @@ -0,0 +1,85 @@ + ts('Activity ID'), + 'activity_type' => ts('Activity Type'), + 'subject' => ts('Activity Subject'), + 'details' => ts('Activity Details'), + 'activity_date_time' => ts('Activity Date-Time'), + )); + } + + public function checkActive(\Civi\Token\TokenProcessor $processor) { + // Extracted from scheduled-reminders code. See the class description. + return + !empty($processor->context['actionMapping']) + && $processor->context['actionMapping']->getEntity() === 'civicrm_activity'; + } + + /** + * Evaluate the content of a single token. + * + * @param \Civi\Token\TokenRow $row + * The record for which we want token values. + * @param string $field + * The name of the token field. + * @param mixed $prefetch + * Any data that was returned by the prefetch(). + * @return mixed + */ + public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefetch = NULL) { + $actionSearchResult = $row->context['actionSearchResult']; + + if (in_array($field, array('activity_date_time'))) { + $row->tokens($entity, $field, \CRM_Utils_Date::customFormat($actionSearchResult->$field)); + } + elseif (isset($actionSearchResult->$field)) { + $row->tokens($entity, $field, $actionSearchResult->$field); + } + else { + $row->tokens($entity, $field, ''); + } + } + +} diff --git a/CRM/Admin/Form/ScheduleReminders.php b/CRM/Admin/Form/ScheduleReminders.php index 3f7a9fb0fe..cac7e5ae9a 100644 --- a/CRM/Admin/Form/ScheduleReminders.php +++ b/CRM/Admin/Form/ScheduleReminders.php @@ -84,7 +84,7 @@ class CRM_Admin_Form_ScheduleReminders extends CRM_Admin_Form { $this->_compId = CRM_Utils_Request::retrieve('compId', 'Integer', $this); $isTemplate = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $this->_compId, 'is_template'); $mapping = CRM_Utils_Array::first(CRM_Core_BAO_ActionSchedule::getMappings(array( - 'id' => $isTemplate ? CRM_Core_ActionScheduleTmp::EVENT_TPL_MAPPING_ID : CRM_Core_ActionScheduleTmp::EVENT_NAME_MAPPING_ID, + 'id' => $isTemplate ? CRM_Event_ActionMapping::EVENT_TPL_MAPPING_ID : CRM_Event_ActionMapping::EVENT_NAME_MAPPING_ID, ))); if ($mapping) { $this->_mappingID = $mapping->getId(); diff --git a/CRM/Contact/ActionMapping.php b/CRM/Contact/ActionMapping.php index 39ed66f9f8..ac9ce6988a 100644 --- a/CRM/Contact/ActionMapping.php +++ b/CRM/Contact/ActionMapping.php @@ -37,6 +37,32 @@ use Civi\ActionSchedule\RecipientBuilder; */ class CRM_Contact_ActionMapping extends \Civi\ActionSchedule\Mapping { + /** + * The value for civicrm_action_schedule.mapping_id which identifies the + * "Contact" mapping. + * + * Note: This value is chosen to match legacy DB IDs. + */ + 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(array( + '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', + ))); + } + private $contactDateFields = array( 'birth_date', 'created_date', diff --git a/CRM/Core/ActionScheduleTmp.php b/CRM/Core/ActionScheduleTmp.php deleted file mode 100644 index e56e34455c..0000000000 --- a/CRM/Core/ActionScheduleTmp.php +++ /dev/null @@ -1,276 +0,0 @@ - 'onRegisterTokens', - \Civi\Token\Events::TOKEN_EVALUATE => 'onEvaluateTokens', - \Civi\ActionSchedule\Events::MAPPINGS => 'onRegisterMappings', - ); - } - - public function onRegisterMappings(\Civi\ActionSchedule\Event\MappingRegisterEvent $registrations) { - $registrations->register(CRM_Activity_ActionMapping::create(array( - 'id' => CRM_Core_ActionScheduleTmp::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', - 'entity_recipient' => 'activity_contacts', - ))); - $registrations->register(CRM_Event_ActionMapping::create(array( - 'id' => CRM_Core_ActionScheduleTmp::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'), - 'entity_date_start' => 'event_start_date', - 'entity_date_end' => 'event_end_date', - 'entity_recipient' => 'event_contacts', - ))); - $registrations->register(CRM_Event_ActionMapping::create(array( - 'id' => CRM_Core_ActionScheduleTmp::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'), - 'entity_date_start' => 'event_start_date', - 'entity_date_end' => 'event_end_date', - 'entity_recipient' => 'event_contacts', - ))); - $registrations->register(CRM_Member_ActionMapping::create(array( - 'id' => CRM_Core_ActionScheduleTmp::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'), - 'entity_date_start' => 'membership_join_date', - 'entity_date_end' => 'membership_end_date', - ))); - $registrations->register(CRM_Event_ActionMapping::create(array( - 'id' => CRM_Core_ActionScheduleTmp::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'), - 'entity_date_start' => 'event_start_date', - 'entity_date_end' => 'event_end_date', - 'entity_recipient' => 'event_contacts', - ))); - $registrations->register(CRM_Contact_ActionMapping::create(array( - 'id' => CRM_Core_ActionScheduleTmp::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', - ))); - } - - /** - * @param \Civi\ActionSchedule\Mapping $mapping - * @return array - * Ex: $result['event']['start_date'] === 'Event Start Date'. - */ - protected static function listMailingTokens($mapping) { - $tokenEntity = NULL; - - $tokens = array( - 'civicrm_activity' => array( - 'activity' => array( - 'activity_id' => ts('Activity ID'), - 'activity_type' => ts('Activity Type'), - 'subject' => ts('Activity Subject'), - 'details' => ts('Activity Details'), - 'activity_date_time' => ts('Activity Date-Time'), - ), - ), - 'civicrm_participant' => array( - 'event' => array( - 'event_type' => ts('Event Type'), - 'title' => ts('Event Title'), - 'event_id' => ts('Event ID'), - 'start_date' => ts('Event Start Date'), - 'end_date' => ts('Event End Date'), - 'summary' => ts('Event Summary'), - 'description' => ts('Event Description'), - 'location' => ts('Event Location'), - 'info_url' => ts('Event Info URL'), - 'registration_url' => ts('Event Registration URL'), - 'fee_amount' => ts('Event Fee'), - 'contact_email' => ts('Event Contact (Email)'), - 'contact_phone' => ts('Event Contact (Phone)'), - 'balance' => ts('Event Balance'), - ), - ), - 'civicrm_membership' => array( - 'membership' => array( - 'fee' => ts('Membership Fee'), - 'id' => ts('Membership ID'), - 'join_date' => ts('Membership Join Date'), - 'start_date' => ts('Membership Start Date'), - 'end_date' => ts('Membership End Date'), - 'status' => ts('Membership Status'), - 'type' => ts('Membership Type'), - ), - ), - //'civicrm_contact' => array( - // 'contact' => array( - // 'birth_date' => ts('Birth Date'), - // 'last_name' => ts('Last Name'), - // ) - //), - ); - - return isset($tokens[$mapping->getEntity()]) ? $tokens[$mapping->getEntity()] : array(); - } - - /** - * Declare available tokens. - * - * @param TokenRegisterEvent $e - */ - public function onRegisterTokens(TokenRegisterEvent $e) { - if (!isset($e->getTokenProcessor()->context['actionMapping'])) { - return; - } - - $allTokenFields = self::listMailingTokens($e->getTokenProcessor()->context['actionMapping']); - foreach ($allTokenFields as $tokenEntity => $tokenFields) { - foreach ($tokenFields as $field => $label) { - $e->register($field, $label); - } - } - } - - /** - * Load token data. - * - * @param TokenValueEvent $e - * @throws TokenException - */ - public function onEvaluateTokens(TokenValueEvent $e) { - foreach ($e->getRows() as $row) { - /** @var \Civi\Token\TokenRow $row */ - if (!isset($row->context['actionSearchResult'])) { - continue; - } - $row->tokens(self::prepareMailingTokens($row->context['actionMapping'], $row->context['actionSearchResult'])); - } - } - - /** - * @param \Civi\ActionSchedule\Mapping $mapping - * @param $dao - * @return array - * Ex: array('activity' => array('subject' => 'Hello world)). - */ - protected static function prepareMailingTokens($mapping, $dao) { - $allTokenFields = self::listMailingTokens($mapping); - - $entityTokenParams = array(); - foreach ($allTokenFields as $tokenEntity => $tokenFields) { - foreach ($tokenFields as $field => $fieldLabel) { - if ($field == 'location') { - $loc = array(); - $stateProvince = \CRM_Core_PseudoConstant::stateProvince(); - $loc['street_address'] = $dao->street_address; - $loc['city'] = $dao->city; - $loc['state_province'] = \CRM_Utils_Array::value($dao->state_province_id, $stateProvince); - $loc['postal_code'] = $dao->postal_code; - $entityTokenParams[$tokenEntity][$field] = \CRM_Utils_Address::format($loc); - } - elseif ($field == 'info_url') { - $entityTokenParams[$tokenEntity][$field] = \CRM_Utils_System::url('civicrm/event/info', 'reset=1&id=' . $dao->event_id, TRUE, NULL, FALSE); - } - elseif ($field == 'registration_url') { - $entityTokenParams[$tokenEntity][$field] = \CRM_Utils_System::url('civicrm/event/register', 'reset=1&id=' . $dao->event_id, TRUE, NULL, FALSE); - } - elseif (in_array($field, array('start_date', 'end_date', 'join_date', 'activity_date_time'))) { - $entityTokenParams[$tokenEntity][$field] = \CRM_Utils_Date::customFormat($dao->$field); - } - elseif ($field == 'balance') { - if ($dao->entityTable == 'civicrm_contact') { - $balancePay = 'N/A'; - } - elseif (!empty($dao->entityID)) { - $info = \CRM_Contribute_BAO_Contribution::getPaymentInfo($dao->entityID, 'event'); - $balancePay = \CRM_Utils_Array::value('balance', $info); - $balancePay = \CRM_Utils_Money::format($balancePay); - } - $entityTokenParams[$tokenEntity][$field] = $balancePay; - } - elseif ($field == 'fee_amount') { - $entityTokenParams[$tokenEntity][$field] = CRM_Utils_Money::format($dao->$field); - } - else { - $entityTokenParams[$tokenEntity][$field] = $dao->$field; - } - } - } - return $entityTokenParams; - } - -} diff --git a/CRM/Core/BAO/ActionSchedule.php b/CRM/Core/BAO/ActionSchedule.php index b246baa5c2..95391467b5 100755 --- a/CRM/Core/BAO/ActionSchedule.php +++ b/CRM/Core/BAO/ActionSchedule.php @@ -92,7 +92,7 @@ class CRM_Core_BAO_ActionSchedule extends CRM_Core_DAO_ActionSchedule { $mappingId = $mapping->getId(); $entityValueLabels[$mappingId] = $mapping->getValueLabels(); // Not sure why: everything *except* contact-dates have a $valueLabel. - if ($mapping->getId() !== CRM_Core_ActionScheduleTmp::CONTACT_MAPPING_ID) { + if ($mapping->getId() !== CRM_Contact_ActionMapping::CONTACT_MAPPING_ID) { $valueLabel = array('- ' . strtolower($mapping->getValueHeader()) . ' -'); $entityValueLabels[$mapping->getId()] = $valueLabel + $entityValueLabels[$mapping->getId()]; } diff --git a/CRM/Event/ActionMapping.php b/CRM/Event/ActionMapping.php index fbae301c90..75ba4661be 100644 --- a/CRM/Event/ActionMapping.php +++ b/CRM/Event/ActionMapping.php @@ -37,6 +37,60 @@ use Civi\ActionSchedule\RecipientBuilder; */ class CRM_Event_ActionMapping extends \Civi\ActionSchedule\Mapping { + /** + * The value for civicrm_action_schedule.mapping_id which identifies the + * "Event Type" mapping. + * + * Note: This value is chosen to match legacy DB IDs. + */ + 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(array( + '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'), + 'entity_date_start' => 'event_start_date', + 'entity_date_end' => 'event_end_date', + 'entity_recipient' => 'event_contacts', + ))); + $registrations->register(CRM_Event_ActionMapping::create(array( + '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'), + 'entity_date_start' => 'event_start_date', + 'entity_date_end' => 'event_end_date', + 'entity_recipient' => 'event_contacts', + ))); + $registrations->register(CRM_Event_ActionMapping::create(array( + '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'), + 'entity_date_start' => 'event_start_date', + 'entity_date_end' => 'event_end_date', + 'entity_recipient' => 'event_contacts', + ))); + } + /** * Generate a query to locate recipients who match the given * schedule. @@ -74,12 +128,12 @@ class CRM_Event_ActionMapping extends \Civi\ActionSchedule\Mapping { // build where clause if (!empty($selectedValues)) { - $valueField = ($this->id == \CRM_Core_ActionScheduleTmp::EVENT_TYPE_MAPPING_ID) ? 'event_type_id' : 'id'; + $valueField = ($this->id == \CRM_Event_ActionMapping::EVENT_TYPE_MAPPING_ID) ? 'event_type_id' : 'id'; $query->where("r.{$valueField} IN (@selectedValues)") ->param('selectedValues', $selectedValues); } else { - $query->where(($this->id == \CRM_Core_ActionScheduleTmp::EVENT_TYPE_MAPPING_ID) ? "r.event_type_id IS NULL" : "r.id IS NULL"); + $query->where(($this->id == \CRM_Event_ActionMapping::EVENT_TYPE_MAPPING_ID) ? "r.event_type_id IS NULL" : "r.id IS NULL"); } $query->where('r.is_active = 1'); diff --git a/CRM/Event/BAO/Event.php b/CRM/Event/BAO/Event.php index 3596fa17bb..bed2f55a8f 100644 --- a/CRM/Event/BAO/Event.php +++ b/CRM/Event/BAO/Event.php @@ -441,7 +441,7 @@ $event_summary_limit $params = array(1 => array($optionGroupId, 'Integer')); $mapping = CRM_Utils_Array::first(CRM_Core_BAO_ActionSchedule::getMappings(array( - 'id' => CRM_Core_ActionScheduleTmp::EVENT_NAME_MAPPING_ID, + 'id' => CRM_Event_ActionMapping::EVENT_NAME_MAPPING_ID, ))); $dao = CRM_Core_DAO::executeQuery($query, $params); while ($dao->fetch()) { @@ -986,10 +986,10 @@ WHERE civicrm_event.is_active = 1 ); $oldMapping = CRM_Utils_Array::first(CRM_Core_BAO_ActionSchedule::getMappings(array( - 'id' => ($eventValues['is_template'] ? CRM_Core_ActionScheduleTmp::EVENT_TPL_MAPPING_ID : CRM_Core_ActionScheduleTmp::EVENT_NAME_MAPPING_ID), + 'id' => ($eventValues['is_template'] ? CRM_Event_ActionMapping::EVENT_TPL_MAPPING_ID : CRM_Event_ActionMapping::EVENT_NAME_MAPPING_ID), ))); $copyMapping = CRM_Utils_Array::first(CRM_Core_BAO_ActionSchedule::getMappings(array( - 'id' => ($copyEvent->is_template == 1 ? CRM_Core_ActionScheduleTmp::EVENT_TPL_MAPPING_ID : CRM_Core_ActionScheduleTmp::EVENT_NAME_MAPPING_ID), + 'id' => ($copyEvent->is_template == 1 ? CRM_Event_ActionMapping::EVENT_TPL_MAPPING_ID : CRM_Event_ActionMapping::EVENT_NAME_MAPPING_ID), ))); $copyReminder = &CRM_Core_DAO::copyGeneric('CRM_Core_DAO_ActionSchedule', array('entity_value' => $id, 'mapping_id' => $oldMapping->getId()), diff --git a/CRM/Event/Form/ManageEvent/ScheduleReminders.php b/CRM/Event/Form/ManageEvent/ScheduleReminders.php index 273051fdf3..f26a8fd300 100644 --- a/CRM/Event/Form/ManageEvent/ScheduleReminders.php +++ b/CRM/Event/Form/ManageEvent/ScheduleReminders.php @@ -50,7 +50,7 @@ class CRM_Event_Form_ManageEvent_ScheduleReminders extends CRM_Event_Form_Manage $setTab = CRM_Utils_Request::retrieve('setTab', 'Int', $this, FALSE, 0); $mapping = CRM_Utils_Array::first(CRM_Core_BAO_ActionSchedule::getMappings(array( - 'id' => ($this->_isTemplate ? CRM_Core_ActionScheduleTmp::EVENT_TPL_MAPPING_ID : CRM_Core_ActionScheduleTmp::EVENT_NAME_MAPPING_ID), + 'id' => ($this->_isTemplate ? CRM_Event_ActionMapping::EVENT_TPL_MAPPING_ID : CRM_Event_ActionMapping::EVENT_NAME_MAPPING_ID), ))); $reminderList = CRM_Core_BAO_ActionSchedule::getList(FALSE, $mapping, $this->_id); if ($reminderList && is_array($reminderList)) { diff --git a/CRM/Event/Form/ManageEvent/TabHeader.php b/CRM/Event/Form/ManageEvent/TabHeader.php index 86fbf69bb3..d707a72521 100644 --- a/CRM/Event/Form/ManageEvent/TabHeader.php +++ b/CRM/Event/Form/ManageEvent/TabHeader.php @@ -110,7 +110,7 @@ class CRM_Event_Form_ManageEvent_TabHeader { if ($eventID) { // disable tabs based on their configuration status $eventNameMapping = CRM_Utils_Array::first(CRM_Core_BAO_ActionSchedule::getMappings(array( - 'id' => CRM_Core_ActionScheduleTmp::EVENT_NAME_MAPPING_ID, + 'id' => CRM_Event_ActionMapping::EVENT_NAME_MAPPING_ID, ))); $sql = " SELECT e.loc_block_id as is_location, e.is_online_registration, e.is_monetary, taf.is_active, pcp.is_active as is_pcp, sch.id as is_reminder, re.id as is_repeating_event diff --git a/CRM/Event/Page/ManageEvent.php b/CRM/Event/Page/ManageEvent.php index 5510b04999..7c17945ecd 100644 --- a/CRM/Event/Page/ManageEvent.php +++ b/CRM/Event/Page/ManageEvent.php @@ -314,7 +314,7 @@ ORDER BY start_date desc ); $this->assign('eventCartEnabled', $enableCart); $mapping = CRM_Utils_Array::first(CRM_Core_BAO_ActionSchedule::getMappings(array( - 'id' => CRM_Core_ActionScheduleTmp::EVENT_NAME_MAPPING_ID, + 'id' => CRM_Event_ActionMapping::EVENT_NAME_MAPPING_ID, ))); $eventType = CRM_Core_OptionGroup::values('event_type'); while ($dao->fetch()) { diff --git a/CRM/Event/Tokens.php b/CRM/Event/Tokens.php new file mode 100644 index 0000000000..0d3e2953bb --- /dev/null +++ b/CRM/Event/Tokens.php @@ -0,0 +1,126 @@ + ts('Event Type'), + 'title' => ts('Event Title'), + 'event_id' => ts('Event ID'), + 'start_date' => ts('Event Start Date'), + 'end_date' => ts('Event End Date'), + 'summary' => ts('Event Summary'), + 'description' => ts('Event Description'), + 'location' => ts('Event Location'), + 'info_url' => ts('Event Info URL'), + 'registration_url' => ts('Event Registration URL'), + 'fee_amount' => ts('Event Fee'), + 'contact_email' => ts('Event Contact (Email)'), + 'contact_phone' => ts('Event Contact (Phone)'), + 'balance' => ts('Event Balance'), + )); + } + + public function checkActive(\Civi\Token\TokenProcessor $processor) { + // Extracted from scheduled-reminders code. See the class description. + return + !empty($processor->context['actionMapping']) + && $processor->context['actionMapping']->getEntity() === 'civicrm_participant'; + } + + /** + * Evaluate the content of a single token. + * + * @param \Civi\Token\TokenRow $row + * The record for which we want token values. + * @param string $field + * The name of the token field. + * @param mixed $prefetch + * Any data that was returned by the prefetch(). + * @return mixed + */ + public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefetch = NULL) { + $actionSearchResult = $row->context['actionSearchResult']; + + if ($field == 'location') { + $loc = array(); + $stateProvince = \CRM_Core_PseudoConstant::stateProvince(); + $loc['street_address'] = $actionSearchResult->street_address; + $loc['city'] = $actionSearchResult->city; + $loc['state_province'] = \CRM_Utils_Array::value($actionSearchResult->state_province_id, $stateProvince); + $loc['postal_code'] = $actionSearchResult->postal_code; + //$entityTokenParams[$tokenEntity][$field] = \CRM_Utils_Address::format($loc); + $row->tokens($entity, $field, \CRM_Utils_Address::format($loc)); + } + elseif ($field == 'info_url') { + $row + ->tokens($entity, $field, \CRM_Utils_System::url('civicrm/event/info', 'reset=1&id=' . $actionSearchResult->event_id, TRUE, NULL, FALSE)); + } + elseif ($field == 'registration_url') { + $row + ->tokens($entity, $field, \CRM_Utils_System::url('civicrm/event/register', 'reset=1&id=' . $actionSearchResult->event_id, TRUE, NULL, FALSE)); + } + elseif (in_array($field, array('start_date', 'end_date'))) { + $row->tokens($entity, $field, \CRM_Utils_Date::customFormat($actionSearchResult->$field)); + } + elseif ($field == 'balance') { + if ($actionSearchResult->entityTable == 'civicrm_contact') { + $balancePay = 'N/A'; + } + elseif (!empty($actionSearchResult->entityID)) { + $info = \CRM_Contribute_BAO_Contribution::getPaymentInfo($actionSearchResult->entityID, 'event'); + $balancePay = \CRM_Utils_Array::value('balance', $info); + $balancePay = \CRM_Utils_Money::format($balancePay); + } + $row->tokens($entity, $field, $balancePay); + } + elseif ($field == 'fee_amount') { + $row->tokens($entity, $field, \CRM_Utils_Money::format($actionSearchResult->$field)); + } + elseif (isset($actionSearchResult->$field)) { + $row->tokens($entity, $field, $actionSearchResult->$field); + } + else { + $row->tokens($entity, $field, ''); + } + } + +} diff --git a/CRM/Member/ActionMapping.php b/CRM/Member/ActionMapping.php index a6161ed4a5..bd205f14c1 100644 --- a/CRM/Member/ActionMapping.php +++ b/CRM/Member/ActionMapping.php @@ -36,6 +36,33 @@ use Civi\ActionSchedule\RecipientBuilder; */ class CRM_Member_ActionMapping extends \Civi\ActionSchedule\Mapping { + /** + * The value for civicrm_action_schedule.mapping_id which identifies the + * "Membership Type" mapping. + * + * Note: This value is chosen to match legacy DB IDs. + */ + 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(array( + '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'), + 'entity_date_start' => 'membership_join_date', + 'entity_date_end' => 'membership_end_date', + ))); + } + /** * Generate a query to locate recipients who match the given * schedule. diff --git a/CRM/Member/Tokens.php b/CRM/Member/Tokens.php new file mode 100644 index 0000000000..f8eb45add1 --- /dev/null +++ b/CRM/Member/Tokens.php @@ -0,0 +1,87 @@ + ts('Membership Fee'), + 'id' => ts('Membership ID'), + 'join_date' => ts('Membership Join Date'), + 'start_date' => ts('Membership Start Date'), + 'end_date' => ts('Membership End Date'), + 'status' => ts('Membership Status'), + 'type' => ts('Membership Type'), + )); + } + + public function checkActive(\Civi\Token\TokenProcessor $processor) { + // Extracted from scheduled-reminders code. See the class description. + return + !empty($processor->context['actionMapping']) + && $processor->context['actionMapping']->getEntity() === 'civicrm_membership'; + } + + /** + * Evaluate the content of a single token. + * + * @param \Civi\Token\TokenRow $row + * The record for which we want token values. + * @param string $field + * The name of the token field. + * @param mixed $prefetch + * Any data that was returned by the prefetch(). + * @return mixed + */ + public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefetch = NULL) { + $actionSearchResult = $row->context['actionSearchResult']; + + if (in_array($field, array('start_date', 'end_date', 'join_date'))) { + $row->tokens($entity, $field, \CRM_Utils_Date::customFormat($actionSearchResult->$field)); + } + elseif (isset($actionSearchResult->$field)) { + $row->tokens($entity, $field, $actionSearchResult->$field); + } + else { + $row->tokens($entity, $field, ''); + } + } + +} diff --git a/Civi/ActionSchedule/Event/MappingRegisterEvent.php b/Civi/ActionSchedule/Event/MappingRegisterEvent.php index 04eab4d0f9..7bd0d2899b 100644 --- a/Civi/ActionSchedule/Event/MappingRegisterEvent.php +++ b/Civi/ActionSchedule/Event/MappingRegisterEvent.php @@ -35,6 +35,7 @@ class MappingRegisterEvent extends Event { * Array(scalar $id => MappingInterface $mapping). */ public function getMappings() { + ksort($this->mappings); return $this->mappings; } diff --git a/Civi/Core/Container.php b/Civi/Core/Container.php index fa7fe74994..fc6a477c5a 100644 --- a/Civi/Core/Container.php +++ b/Civi/Core/Container.php @@ -199,10 +199,12 @@ class Container { array() ))->addTag('kernel.event_subscriber'); - $container->setDefinition('actionscheduletmp', new Definition( - 'CRM_Core_ActionScheduleTmp', - array() - ))->addTag('kernel.event_subscriber'); + foreach (array('Activity', 'Event', 'Member') as $comp) { + $container->setDefinition("crm_" . strtolower($comp) . "_tokens", new Definition( + "CRM_{$comp}_Tokens", + array() + ))->addTag('kernel.event_subscriber'); + } \CRM_Utils_Hook::container($container); @@ -233,6 +235,11 @@ class Container { 'CRM_Core_LegacyErrorHandler', 'handleException', )); + $dispatcher->addListener(\Civi\ActionSchedule\Events::MAPPINGS, array('CRM_Activity_ActionMapping', 'onRegisterActionMappings')); + $dispatcher->addListener(\Civi\ActionSchedule\Events::MAPPINGS, array('CRM_Contact_ActionMapping', 'onRegisterActionMappings')); + $dispatcher->addListener(\Civi\ActionSchedule\Events::MAPPINGS, array('CRM_Event_ActionMapping', 'onRegisterActionMappings')); + $dispatcher->addListener(\Civi\ActionSchedule\Events::MAPPINGS, array('CRM_Member_ActionMapping', 'onRegisterActionMappings')); + return $dispatcher; } diff --git a/Civi/Token/AbstractTokenSubscriber.php b/Civi/Token/AbstractTokenSubscriber.php new file mode 100644 index 0000000000..ad20e375c3 --- /dev/null +++ b/Civi/Token/AbstractTokenSubscriber.php @@ -0,0 +1,159 @@ + 'registerTokens', + Events::TOKEN_EVALUATE => 'evaluateTokens', + ); + } + + /** + * @var string + * Ex: 'contact' or profile' or 'employer' + */ + public $entity; + + /** + * @var array + * Ex: array('viewUrl', 'editUrl'). + */ + public $tokenNames; + + /** + * @param $entity + * @param array $tokenNames + * Array(string $fieldName => string $label). + */ + public function __construct($entity, $tokenNames = array()) { + $this->entity = $entity; + $this->tokenNames = $tokenNames; + } + + /** + * Determine whether this token-handler should be used with + * the given processor. + * + * To short-circuit token-processing in irrelevant contexts, + * override this. + * + * @param \Civi\Token\TokenProcessor $processor + * @return bool + */ + public function checkActive(\Civi\Token\TokenProcessor $processor) { + return TRUE; + } + + /** + * Register the declared tokens. + * + * @param TokenRegisterEvent $e + * The registration event. Add new tokens using register(). + */ + public function registerTokens(TokenRegisterEvent $e) { + if (!$this->checkActive($e->getTokenProcessor())) { + return; + } + foreach ($this->tokenNames as $name => $label) { + $e->register(array( + 'entity' => $this->entity, + 'field' => $name, + 'label' => $label, + )); + } + } + + /** + * Populate the token data. + * + * @param TokenValueEvent $e + * The event, which includes a list of rows and tokens. + */ + public function evaluateTokens(TokenValueEvent $e) { + if (!$this->checkActive($e->getTokenProcessor())) { + return; + } + // TODO: check if any tokens for $entity are actually used; short-circuit. + $prefetch = $this->prefetch($e); + foreach ($e->getRows() as $row) { + foreach ($this->tokenNames as $field => $label) { + $this->evaluateToken($row, $this->entity, $field, $prefetch); + } + } + } + + /** + * To perform a bulk lookup before rendering tokens, override this + * function and return the prefetched data. + * + * @return mixed + */ + public function prefetch(TokenValueEvent $e) { + return NULL; + } + + /** + * Evaluate the content of a single token. + * + * @param TokenRow $row + * The record for which we want token values. + * @param string $entity + * The name of the token entity. + * @param string $field + * The name of the token field. + * @param mixed $prefetch + * Any data that was returned by the prefetch(). + * @return mixed + */ + public abstract function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL); + +} diff --git a/tests/phpunit/api/v3/ActionScheduleTest.php b/tests/phpunit/api/v3/ActionScheduleTest.php index 8bf0b0c6ae..29973732b5 100644 --- a/tests/phpunit/api/v3/ActionScheduleTest.php +++ b/tests/phpunit/api/v3/ActionScheduleTest.php @@ -65,7 +65,7 @@ class api_v3_ActionScheduleTest extends CiviUnitTestCase { 'is_active' => 1, 'record_activity' => 1, 'start_action_date' => 'activity_date_time', - 'mapping_id' => CRM_Core_ActionScheduleTmp::ACTIVITY_MAPPING_ID, + 'mapping_id' => CRM_Activity_ActionMapping::ACTIVITY_MAPPING_ID, ); $actionSchedule = $this->callAPISuccess('action_schedule', 'create', $params); $this->assertTrue(is_numeric($actionSchedule['id'])); @@ -103,7 +103,7 @@ class api_v3_ActionScheduleTest extends CiviUnitTestCase { 'entity_status' => $scheduledStatus, 'is_active' => 1, 'record_activity' => 1, - 'mapping_id' => CRM_Core_ActionScheduleTmp::ACTIVITY_MAPPING_ID, + 'mapping_id' => CRM_Activity_ActionMapping::ACTIVITY_MAPPING_ID, 'start_action_offset' => 3, 'start_action_unit' => 'day', 'start_action_condition' => 'before', -- 2.25.1