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 | ||
46f5566c TO |
18 | /** |
19 | * Class CRM_Member_Tokens | |
20 | * | |
21 | * Generate "activity.*" tokens. | |
22 | * | |
da9977bd | 23 | * This TokenSubscriber was originally produced by refactoring the code from the |
46f5566c TO |
24 | * scheduled-reminder system with the goal of making that system |
25 | * more flexible. The current implementation is still coupled to | |
26 | * scheduled-reminders. It would be good to figure out a more generic | |
27 | * implementation which is not tied to scheduled reminders, although | |
28 | * that is outside the current scope. | |
da9977bd AS |
29 | * |
30 | * This has been enhanced to work with PDF/letter merge | |
46f5566c TO |
31 | */ |
32 | class CRM_Activity_Tokens extends \Civi\Token\AbstractTokenSubscriber { | |
33 | ||
da9977bd AS |
34 | private $basicTokens; |
35 | private $customFieldTokens; | |
36 | ||
37 | /** | |
38 | * Mapping from tokenName to api return field | |
39 | * Use lists since we might need multiple fields | |
40 | * | |
41 | * @var array | |
42 | */ | |
43 | private static $fieldMapping = [ | |
44 | 'activity_id' => ['id'], | |
45 | 'activity_type' => ['activity_type_id'], | |
46 | 'status' => ['status_id'], | |
47 | 'campaign' => ['campaign_id'], | |
48 | ]; | |
49 | ||
8246bca4 | 50 | /** |
51 | * CRM_Activity_Tokens constructor. | |
52 | */ | |
46f5566c | 53 | public function __construct() { |
4e9b6a62 | 54 | parent::__construct('activity', array_merge( |
86420016 | 55 | $this->getBasicTokens(), |
56 | $this->getCustomFieldTokens() | |
46f5566c TO |
57 | )); |
58 | } | |
59 | ||
70599df6 | 60 | /** |
298795cd | 61 | * @inheritDoc |
70599df6 | 62 | */ |
46f5566c | 63 | public function checkActive(\Civi\Token\TokenProcessor $processor) { |
da9977bd AS |
64 | return in_array('activityId', $processor->context['schema']) || |
65 | (!empty($processor->context['actionMapping']) | |
66 | && $processor->context['actionMapping']->getEntity() === 'civicrm_activity'); | |
67 | } | |
68 | ||
69 | /** | |
70 | * @inheritDoc | |
71 | */ | |
72 | public function getActiveTokens(\Civi\Token\Event\TokenValueEvent $e) { | |
73 | $messageTokens = $e->getTokenProcessor()->getMessageTokens(); | |
74 | if (!isset($messageTokens[$this->entity])) { | |
75 | return NULL; | |
76 | } | |
77 | ||
78 | $activeTokens = []; | |
79 | // if message token contains '_\d+_', then treat as '_N_' | |
80 | foreach ($messageTokens[$this->entity] as $msgToken) { | |
81 | if (array_key_exists($msgToken, $this->tokenNames)) { | |
82 | $activeTokens[] = $msgToken; | |
83 | } | |
84 | else { | |
85 | $altToken = preg_replace('/_\d+_/', '_N_', $msgToken); | |
86 | if (array_key_exists($altToken, $this->tokenNames)) { | |
87 | $activeTokens[] = $msgToken; | |
88 | } | |
89 | } | |
90 | } | |
91 | return array_unique($activeTokens); | |
46f5566c TO |
92 | } |
93 | ||
298795cd TO |
94 | /** |
95 | * @inheritDoc | |
96 | */ | |
f9ec2da6 TO |
97 | public function alterActionScheduleQuery(\Civi\ActionSchedule\Event\MailingQueryEvent $e) { |
98 | if ($e->mapping->getEntity() !== 'civicrm_activity') { | |
99 | return; | |
100 | } | |
101 | ||
7808aae6 SB |
102 | // The joint expression for activities needs some extra nuance to handle. |
103 | // Multiple revisions of the activity. | |
104 | // Q: Could we simplify & move the extra AND clauses into `where(...)`? | |
f9ec2da6 | 105 | $e->query->param('casEntityJoinExpr', 'e.id = reminder.entity_id AND e.is_current_revision = 1 AND e.is_deleted = 0'); |
da9977bd | 106 | } |
f9ec2da6 | 107 | |
da9977bd AS |
108 | /** |
109 | * Find the fields that we need to get to construct the tokens requested. | |
110 | * @param array $tokens list of tokens | |
111 | * @return array list of fields needed to generate those tokens | |
112 | */ | |
113 | public function getReturnFields($tokens) { | |
114 | // Make sure we always return something | |
115 | $fields = ['id']; | |
f9ec2da6 | 116 | |
da9977bd AS |
117 | foreach (array_intersect($tokens, |
118 | array_merge(array_keys(self::getBasicTokens()), array_keys(self::getCustomFieldTokens())) | |
119 | ) as $token) { | |
120 | if (isset(self::$fieldMapping[$token])) { | |
121 | $fields = array_merge($fields, self::$fieldMapping[$token]); | |
122 | } | |
123 | else { | |
124 | $fields[] = $token; | |
125 | } | |
126 | } | |
127 | return array_unique($fields); | |
128 | } | |
f9ec2da6 | 129 | |
da9977bd AS |
130 | /** |
131 | * @inheritDoc | |
132 | */ | |
133 | public function prefetch(\Civi\Token\Event\TokenValueEvent $e) { | |
134 | // Find all the activity IDs | |
135 | $activityIds | |
136 | = $e->getTokenProcessor()->getContextValues('actionSearchResult', 'entityID') | |
137 | + $e->getTokenProcessor()->getContextValues('activityId'); | |
138 | ||
139 | if (!$activityIds) { | |
140 | return; | |
141 | } | |
142 | ||
143 | // Get data on all activities for basic and customfield tokens | |
144 | $activities = civicrm_api3('Activity', 'get', [ | |
145 | 'id' => ['IN' => $activityIds], | |
146 | 'options' => ['limit' => 0], | |
147 | 'return' => self::getReturnFields($this->activeTokens), | |
148 | ]); | |
149 | $prefetch['activity'] = $activities['values']; | |
150 | ||
151 | // Store the activity types if needed | |
152 | if (in_array('activity_type', $this->activeTokens)) { | |
153 | $this->activityTypes = \CRM_Core_OptionGroup::values('activity_type'); | |
154 | } | |
155 | ||
156 | // Store the activity statuses if needed | |
157 | if (in_array('status', $this->activeTokens)) { | |
158 | $this->activityStatuses = \CRM_Core_OptionGroup::values('activity_status'); | |
159 | } | |
160 | ||
161 | // Store the campaigns if needed | |
162 | if (in_array('campaign', $this->activeTokens)) { | |
163 | $this->campaigns = \CRM_Campaign_BAO_Campaign::getCampaigns(); | |
f9ec2da6 | 164 | } |
da9977bd AS |
165 | |
166 | return $prefetch; | |
f9ec2da6 TO |
167 | } |
168 | ||
46f5566c | 169 | /** |
298795cd | 170 | * @inheritDoc |
46f5566c TO |
171 | */ |
172 | public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefetch = NULL) { | |
da9977bd AS |
173 | // maps token name to api field |
174 | $mapping = [ | |
175 | 'activity_id' => 'id', | |
176 | ]; | |
177 | ||
178 | // Get ActivityID either from actionSearchResult (for scheduled reminders) if exists | |
179 | $activityId = isset($row->context['actionSearchResult']->entityID) | |
180 | ? $row->context['actionSearchResult']->entityID | |
181 | : $row->context['activityId']; | |
46f5566c | 182 | |
da9977bd AS |
183 | $activity = (object) $prefetch['activity'][$activityId]; |
184 | ||
185 | if (in_array($field, ['activity_date_time', 'created_date'])) { | |
186 | $row->tokens($entity, $field, \CRM_Utils_Date::customFormat($activity->$field)); | |
187 | } | |
188 | elseif (isset($mapping[$field]) and (isset($activity->{$mapping[$field]}))) { | |
189 | $row->tokens($entity, $field, $activity->{$mapping[$field]}); | |
46f5566c | 190 | } |
da9977bd AS |
191 | elseif (in_array($field, ['activity_type'])) { |
192 | $row->tokens($entity, $field, $this->activityTypes[$activity->activity_type_id]); | |
46f5566c | 193 | } |
da9977bd AS |
194 | elseif (in_array($field, ['status'])) { |
195 | $row->tokens($entity, $field, $this->activityStatuses[$activity->status_id]); | |
4e9b6a62 | 196 | } |
da9977bd AS |
197 | elseif (in_array($field, ['campaign'])) { |
198 | $row->tokens($entity, $field, $this->campaigns[$activity->campaign_id]); | |
199 | } | |
28f7a9b1 MW |
200 | elseif (in_array($field, ['case_id'])) { |
201 | // An activity can be linked to multiple cases so case_id is always an array. | |
202 | // We just return the first case ID for the token. | |
203 | $row->tokens($entity, $field, is_array($activity->case_id) ? reset($activity->case_id) : $activity->case_id); | |
204 | } | |
da9977bd AS |
205 | elseif (array_key_exists($field, $this->customFieldTokens)) { |
206 | $row->tokens($entity, $field, | |
207 | isset($activity->$field) | |
208 | ? \CRM_Core_BAO_CustomField::displayValue($activity->$field, $field) | |
209 | : '' | |
210 | ); | |
211 | } | |
212 | elseif (isset($activity->$field)) { | |
213 | $row->tokens($entity, $field, $activity->$field); | |
46f5566c TO |
214 | } |
215 | } | |
216 | ||
86420016 | 217 | /** |
218 | * Get the basic tokens provided. | |
219 | * | |
220 | * @return array token name => token label | |
221 | */ | |
222 | protected function getBasicTokens() { | |
da9977bd AS |
223 | if (!isset($this->basicTokens)) { |
224 | $this->basicTokens = [ | |
225 | 'activity_id' => ts('Activity ID'), | |
226 | 'activity_type' => ts('Activity Type'), | |
227 | 'subject' => ts('Activity Subject'), | |
228 | 'details' => ts('Activity Details'), | |
229 | 'activity_date_time' => ts('Activity Date-Time'), | |
230 | 'activity_type_id' => ts('Activity Type ID'), | |
231 | 'status' => ts('Activity Status'), | |
232 | 'status_id' => ts('Activity Status ID'), | |
233 | 'location' => ts('Activity Location'), | |
234 | 'created_date' => ts('Activity Creation Date'), | |
235 | 'duration' => ts('Activity Duration'), | |
236 | 'campaign' => ts('Activity Campaign'), | |
237 | 'campaign_id' => ts('Activity Campaign ID'), | |
238 | ]; | |
239 | if (array_key_exists('CiviCase', CRM_Core_Component::getEnabledComponents())) { | |
240 | $this->basicTokens['case_id'] = ts('Activity Case ID'); | |
241 | } | |
242 | } | |
243 | return $this->basicTokens; | |
86420016 | 244 | } |
245 | ||
246 | /** | |
247 | * Get the tokens for custom fields | |
248 | * @return array token name => token label | |
249 | */ | |
250 | protected function getCustomFieldTokens() { | |
da9977bd AS |
251 | if (!isset($this->customFieldTokens)) { |
252 | $this->customFieldTokens = \CRM_Utils_Token::getCustomFieldTokens('Activity'); | |
253 | } | |
254 | return $this->customFieldTokens; | |
86420016 | 255 | } |
256 | ||
46f5566c | 257 | } |