Commit | Line | Data |
---|---|---|
46f5566c TO |
1 | <?php |
2 | ||
3 | /* | |
4 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 5 | | Copyright CiviCRM LLC. All rights reserved. | |
46f5566c | 6 | | | |
bc77d7c0 TO |
7 | | This work is published under the GNU AGPLv3 license with some | |
8 | | permitted exceptions and without any warranty. For full license | | |
9 | | and copyright information, see https://civicrm.org/licensing | | |
46f5566c TO |
10 | +--------------------------------------------------------------------+ |
11 | */ | |
12 | ||
7808aae6 SB |
13 | /** |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
7808aae6 SB |
16 | */ |
17 | ||
c2a33d9c | 18 | use Civi\Token\AbstractTokenSubscriber; |
19 | use Civi\Token\Event\TokenValueEvent; | |
20 | use Civi\Token\TokenRow; | |
21 | ||
46f5566c TO |
22 | /** |
23 | * Class CRM_Member_Tokens | |
24 | * | |
25 | * Generate "activity.*" tokens. | |
26 | * | |
da9977bd | 27 | * This TokenSubscriber was originally produced by refactoring the code from the |
46f5566c TO |
28 | * scheduled-reminder system with the goal of making that system |
29 | * more flexible. The current implementation is still coupled to | |
30 | * scheduled-reminders. It would be good to figure out a more generic | |
31 | * implementation which is not tied to scheduled reminders, although | |
32 | * that is outside the current scope. | |
da9977bd AS |
33 | * |
34 | * This has been enhanced to work with PDF/letter merge | |
46f5566c | 35 | */ |
c2a33d9c | 36 | class CRM_Activity_Tokens extends AbstractTokenSubscriber { |
46f5566c | 37 | |
88d88c53 | 38 | use CRM_Core_TokenTrait; |
da9977bd AS |
39 | |
40 | /** | |
88d88c53 | 41 | * @return string |
da9977bd | 42 | */ |
88d88c53 MW |
43 | private function getEntityName(): string { |
44 | return 'activity'; | |
45 | } | |
da9977bd | 46 | |
8246bca4 | 47 | /** |
88d88c53 | 48 | * @return string |
8246bca4 | 49 | */ |
88d88c53 MW |
50 | private function getEntityTableName(): string { |
51 | return 'civicrm_activity'; | |
46f5566c TO |
52 | } |
53 | ||
70599df6 | 54 | /** |
88d88c53 | 55 | * @return string |
70599df6 | 56 | */ |
51e25a23 | 57 | private function getEntityContextSchema(): string { |
58 | return 'activityId'; | |
da9977bd AS |
59 | } |
60 | ||
61 | /** | |
88d88c53 | 62 | * Mapping from tokenName to api return field |
f10c962e MW |
63 | * Using arrays allows more complex tokens to be handled that require more than one API field. |
64 | * For example, an address token might want ['street_address', 'city', 'postal_code'] | |
88d88c53 MW |
65 | * |
66 | * @var array | |
da9977bd | 67 | */ |
88d88c53 MW |
68 | private static $fieldMapping = [ |
69 | 'activity_id' => ['id'], | |
70 | 'activity_type' => ['activity_type_id'], | |
71 | 'status' => ['status_id'], | |
72 | 'campaign' => ['campaign_id'], | |
73 | ]; | |
46f5566c | 74 | |
298795cd TO |
75 | /** |
76 | * @inheritDoc | |
77 | */ | |
f9ec2da6 | 78 | public function alterActionScheduleQuery(\Civi\ActionSchedule\Event\MailingQueryEvent $e) { |
88d88c53 | 79 | if ($e->mapping->getEntity() !== $this->getEntityTableName()) { |
f9ec2da6 TO |
80 | return; |
81 | } | |
82 | ||
7808aae6 SB |
83 | // The joint expression for activities needs some extra nuance to handle. |
84 | // Multiple revisions of the activity. | |
85 | // Q: Could we simplify & move the extra AND clauses into `where(...)`? | |
f9ec2da6 | 86 | $e->query->param('casEntityJoinExpr', 'e.id = reminder.entity_id AND e.is_current_revision = 1 AND e.is_deleted = 0'); |
da9977bd | 87 | } |
f9ec2da6 | 88 | |
da9977bd AS |
89 | /** |
90 | * @inheritDoc | |
91 | */ | |
c2a33d9c | 92 | public function prefetch(TokenValueEvent $e) { |
88d88c53 MW |
93 | // Find all the entity IDs |
94 | $entityIds | |
da9977bd | 95 | = $e->getTokenProcessor()->getContextValues('actionSearchResult', 'entityID') |
51e25a23 | 96 | + $e->getTokenProcessor()->getContextValues($this->getEntityContextSchema()); |
da9977bd | 97 | |
88d88c53 MW |
98 | if (!$entityIds) { |
99 | return NULL; | |
da9977bd AS |
100 | } |
101 | ||
102 | // Get data on all activities for basic and customfield tokens | |
103 | $activities = civicrm_api3('Activity', 'get', [ | |
88d88c53 | 104 | 'id' => ['IN' => $entityIds], |
da9977bd AS |
105 | 'options' => ['limit' => 0], |
106 | 'return' => self::getReturnFields($this->activeTokens), | |
107 | ]); | |
108 | $prefetch['activity'] = $activities['values']; | |
109 | ||
110 | // Store the activity types if needed | |
111 | if (in_array('activity_type', $this->activeTokens)) { | |
112 | $this->activityTypes = \CRM_Core_OptionGroup::values('activity_type'); | |
113 | } | |
114 | ||
115 | // Store the activity statuses if needed | |
116 | if (in_array('status', $this->activeTokens)) { | |
117 | $this->activityStatuses = \CRM_Core_OptionGroup::values('activity_status'); | |
118 | } | |
119 | ||
120 | // Store the campaigns if needed | |
121 | if (in_array('campaign', $this->activeTokens)) { | |
122 | $this->campaigns = \CRM_Campaign_BAO_Campaign::getCampaigns(); | |
f9ec2da6 | 123 | } |
da9977bd AS |
124 | |
125 | return $prefetch; | |
f9ec2da6 TO |
126 | } |
127 | ||
46f5566c | 128 | /** |
298795cd | 129 | * @inheritDoc |
46f5566c | 130 | */ |
c2a33d9c | 131 | public function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL) { |
da9977bd AS |
132 | // maps token name to api field |
133 | $mapping = [ | |
134 | 'activity_id' => 'id', | |
135 | ]; | |
136 | ||
137 | // Get ActivityID either from actionSearchResult (for scheduled reminders) if exists | |
51e25a23 | 138 | $activityId = $row->context['actionSearchResult']->entityID ?? $row->context[$this->getEntityContextSchema()]; |
46f5566c | 139 | |
f10c962e | 140 | $activity = $prefetch['activity'][$activityId]; |
da9977bd | 141 | |
c3317f50 | 142 | if (in_array($field, ['activity_date_time', 'created_date', 'modified_date'])) { |
f10c962e | 143 | $row->tokens($entity, $field, \CRM_Utils_Date::customFormat($activity[$field])); |
da9977bd | 144 | } |
f10c962e MW |
145 | elseif (isset($mapping[$field]) and (isset($activity[$mapping[$field]]))) { |
146 | $row->tokens($entity, $field, $activity[$mapping[$field]]); | |
46f5566c | 147 | } |
da9977bd | 148 | elseif (in_array($field, ['activity_type'])) { |
f10c962e | 149 | $row->tokens($entity, $field, $this->activityTypes[$activity['activity_type_id']]); |
46f5566c | 150 | } |
da9977bd | 151 | elseif (in_array($field, ['status'])) { |
f10c962e | 152 | $row->tokens($entity, $field, $this->activityStatuses[$activity['status_id']]); |
4e9b6a62 | 153 | } |
da9977bd | 154 | elseif (in_array($field, ['campaign'])) { |
f10c962e | 155 | $row->tokens($entity, $field, $this->campaigns[$activity['campaign_id']]); |
da9977bd | 156 | } |
28f7a9b1 MW |
157 | elseif (in_array($field, ['case_id'])) { |
158 | // An activity can be linked to multiple cases so case_id is always an array. | |
159 | // We just return the first case ID for the token. | |
f10c962e | 160 | $row->tokens($entity, $field, is_array($activity['case_id']) ? reset($activity['case_id']) : $activity['case_id']); |
28f7a9b1 | 161 | } |
da9977bd AS |
162 | elseif (array_key_exists($field, $this->customFieldTokens)) { |
163 | $row->tokens($entity, $field, | |
f10c962e MW |
164 | isset($activity[$field]) |
165 | ? \CRM_Core_BAO_CustomField::displayValue($activity[$field], $field) | |
da9977bd AS |
166 | : '' |
167 | ); | |
168 | } | |
f10c962e MW |
169 | elseif (isset($activity[$field])) { |
170 | $row->tokens($entity, $field, $activity[$field]); | |
46f5566c TO |
171 | } |
172 | } | |
173 | ||
86420016 | 174 | /** |
175 | * Get the basic tokens provided. | |
176 | * | |
177 | * @return array token name => token label | |
178 | */ | |
c2a33d9c | 179 | protected function getBasicTokens(): array { |
da9977bd AS |
180 | if (!isset($this->basicTokens)) { |
181 | $this->basicTokens = [ | |
182 | 'activity_id' => ts('Activity ID'), | |
183 | 'activity_type' => ts('Activity Type'), | |
184 | 'subject' => ts('Activity Subject'), | |
185 | 'details' => ts('Activity Details'), | |
186 | 'activity_date_time' => ts('Activity Date-Time'), | |
c3317f50 MW |
187 | 'created_date' => ts('Activity Created Date'), |
188 | 'modified_date' => ts('Activity Modified Date'), | |
da9977bd AS |
189 | 'activity_type_id' => ts('Activity Type ID'), |
190 | 'status' => ts('Activity Status'), | |
191 | 'status_id' => ts('Activity Status ID'), | |
192 | 'location' => ts('Activity Location'), | |
da9977bd AS |
193 | 'duration' => ts('Activity Duration'), |
194 | 'campaign' => ts('Activity Campaign'), | |
195 | 'campaign_id' => ts('Activity Campaign ID'), | |
196 | ]; | |
197 | if (array_key_exists('CiviCase', CRM_Core_Component::getEnabledComponents())) { | |
198 | $this->basicTokens['case_id'] = ts('Activity Case ID'); | |
199 | } | |
200 | } | |
201 | return $this->basicTokens; | |
86420016 | 202 | } |
203 | ||
46f5566c | 204 | } |