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 | |
68f388d3 | 103 | $prefetch['activity'] = civicrm_api3('Activity', 'get', [ |
88d88c53 | 104 | 'id' => ['IN' => $entityIds], |
da9977bd AS |
105 | 'options' => ['limit' => 0], |
106 | 'return' => self::getReturnFields($this->activeTokens), | |
68f388d3 | 107 | ])['values']; |
da9977bd AS |
108 | |
109 | // Store the activity types if needed | |
68f388d3 | 110 | if (in_array('activity_type', $this->activeTokens, TRUE)) { |
da9977bd AS |
111 | $this->activityTypes = \CRM_Core_OptionGroup::values('activity_type'); |
112 | } | |
113 | ||
114 | // Store the activity statuses if needed | |
68f388d3 | 115 | if (in_array('status', $this->activeTokens, TRUE)) { |
da9977bd AS |
116 | $this->activityStatuses = \CRM_Core_OptionGroup::values('activity_status'); |
117 | } | |
118 | ||
119 | // Store the campaigns if needed | |
68f388d3 | 120 | if (in_array('campaign', $this->activeTokens, TRUE)) { |
da9977bd | 121 | $this->campaigns = \CRM_Campaign_BAO_Campaign::getCampaigns(); |
f9ec2da6 | 122 | } |
da9977bd AS |
123 | |
124 | return $prefetch; | |
f9ec2da6 TO |
125 | } |
126 | ||
46f5566c | 127 | /** |
350d582f MW |
128 | * Evaluate the content of a single token. |
129 | * | |
130 | * @param \Civi\Token\TokenRow $row | |
131 | * The record for which we want token values. | |
132 | * @param string $entity | |
133 | * The name of the token entity. | |
134 | * @param string $field | |
135 | * The name of the token field. | |
136 | * @param mixed $prefetch | |
137 | * Any data that was returned by the prefetch(). | |
138 | * | |
139 | * @throws \CRM_Core_Exception | |
46f5566c | 140 | */ |
c2a33d9c | 141 | public function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL) { |
da9977bd AS |
142 | // maps token name to api field |
143 | $mapping = [ | |
144 | 'activity_id' => 'id', | |
145 | ]; | |
146 | ||
147 | // Get ActivityID either from actionSearchResult (for scheduled reminders) if exists | |
51e25a23 | 148 | $activityId = $row->context['actionSearchResult']->entityID ?? $row->context[$this->getEntityContextSchema()]; |
46f5566c | 149 | |
f10c962e | 150 | $activity = $prefetch['activity'][$activityId]; |
da9977bd | 151 | |
c3317f50 | 152 | if (in_array($field, ['activity_date_time', 'created_date', 'modified_date'])) { |
f10c962e | 153 | $row->tokens($entity, $field, \CRM_Utils_Date::customFormat($activity[$field])); |
da9977bd | 154 | } |
f10c962e MW |
155 | elseif (isset($mapping[$field]) and (isset($activity[$mapping[$field]]))) { |
156 | $row->tokens($entity, $field, $activity[$mapping[$field]]); | |
46f5566c | 157 | } |
da9977bd | 158 | elseif (in_array($field, ['activity_type'])) { |
f10c962e | 159 | $row->tokens($entity, $field, $this->activityTypes[$activity['activity_type_id']]); |
46f5566c | 160 | } |
da9977bd | 161 | elseif (in_array($field, ['status'])) { |
f10c962e | 162 | $row->tokens($entity, $field, $this->activityStatuses[$activity['status_id']]); |
4e9b6a62 | 163 | } |
da9977bd | 164 | elseif (in_array($field, ['campaign'])) { |
f10c962e | 165 | $row->tokens($entity, $field, $this->campaigns[$activity['campaign_id']]); |
da9977bd | 166 | } |
28f7a9b1 MW |
167 | elseif (in_array($field, ['case_id'])) { |
168 | // An activity can be linked to multiple cases so case_id is always an array. | |
169 | // We just return the first case ID for the token. | |
f10c962e | 170 | $row->tokens($entity, $field, is_array($activity['case_id']) ? reset($activity['case_id']) : $activity['case_id']); |
28f7a9b1 | 171 | } |
da9977bd AS |
172 | elseif (array_key_exists($field, $this->customFieldTokens)) { |
173 | $row->tokens($entity, $field, | |
f10c962e MW |
174 | isset($activity[$field]) |
175 | ? \CRM_Core_BAO_CustomField::displayValue($activity[$field], $field) | |
da9977bd AS |
176 | : '' |
177 | ); | |
178 | } | |
f10c962e MW |
179 | elseif (isset($activity[$field])) { |
180 | $row->tokens($entity, $field, $activity[$field]); | |
46f5566c TO |
181 | } |
182 | } | |
183 | ||
86420016 | 184 | /** |
185 | * Get the basic tokens provided. | |
186 | * | |
187 | * @return array token name => token label | |
188 | */ | |
c2a33d9c | 189 | protected function getBasicTokens(): array { |
da9977bd AS |
190 | if (!isset($this->basicTokens)) { |
191 | $this->basicTokens = [ | |
192 | 'activity_id' => ts('Activity ID'), | |
193 | 'activity_type' => ts('Activity Type'), | |
194 | 'subject' => ts('Activity Subject'), | |
195 | 'details' => ts('Activity Details'), | |
196 | 'activity_date_time' => ts('Activity Date-Time'), | |
c3317f50 MW |
197 | 'created_date' => ts('Activity Created Date'), |
198 | 'modified_date' => ts('Activity Modified Date'), | |
da9977bd AS |
199 | 'activity_type_id' => ts('Activity Type ID'), |
200 | 'status' => ts('Activity Status'), | |
201 | 'status_id' => ts('Activity Status ID'), | |
202 | 'location' => ts('Activity Location'), | |
da9977bd AS |
203 | 'duration' => ts('Activity Duration'), |
204 | 'campaign' => ts('Activity Campaign'), | |
205 | 'campaign_id' => ts('Activity Campaign ID'), | |
206 | ]; | |
207 | if (array_key_exists('CiviCase', CRM_Core_Component::getEnabledComponents())) { | |
208 | $this->basicTokens['case_id'] = ts('Activity Case ID'); | |
209 | } | |
210 | } | |
211 | return $this->basicTokens; | |
86420016 | 212 | } |
213 | ||
46f5566c | 214 | } |