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 | ||
c6106226 | 18 | use Civi\ActionSchedule\Event\MailingQueryEvent; |
c2a33d9c | 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 | */ |
b441a504 | 36 | class CRM_Activity_Tokens extends CRM_Core_EntityTokens { |
46f5566c | 37 | |
da9977bd | 38 | /** |
b441a504 EM |
39 | * Get the entity name for api v4 calls. |
40 | * | |
88d88c53 | 41 | * @return string |
da9977bd | 42 | */ |
b441a504 EM |
43 | protected function getApiEntityName(): string { |
44 | return 'Activity'; | |
88d88c53 | 45 | } |
da9977bd | 46 | |
298795cd TO |
47 | /** |
48 | * @inheritDoc | |
49 | */ | |
c6106226 EM |
50 | public function alterActionScheduleQuery(MailingQueryEvent $e): void { |
51 | if ($e->mapping->getEntity() !== $this->getExtendableTableName()) { | |
f9ec2da6 TO |
52 | return; |
53 | } | |
54 | ||
7808aae6 SB |
55 | // The joint expression for activities needs some extra nuance to handle. |
56 | // Multiple revisions of the activity. | |
57 | // Q: Could we simplify & move the extra AND clauses into `where(...)`? | |
f9ec2da6 | 58 | $e->query->param('casEntityJoinExpr', 'e.id = reminder.entity_id AND e.is_current_revision = 1 AND e.is_deleted = 0'); |
c6106226 | 59 | parent::alterActionScheduleQuery($e); |
da9977bd | 60 | } |
f9ec2da6 | 61 | |
46f5566c | 62 | /** |
350d582f MW |
63 | * Evaluate the content of a single token. |
64 | * | |
65 | * @param \Civi\Token\TokenRow $row | |
66 | * The record for which we want token values. | |
67 | * @param string $entity | |
68 | * The name of the token entity. | |
69 | * @param string $field | |
70 | * The name of the token field. | |
71 | * @param mixed $prefetch | |
72 | * Any data that was returned by the prefetch(). | |
73 | * | |
74 | * @throws \CRM_Core_Exception | |
46f5566c | 75 | */ |
c2a33d9c | 76 | public function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL) { |
c6106226 | 77 | $activityId = $this->getFieldValue($row, 'id'); |
46f5566c | 78 | |
b441a504 EM |
79 | if (!empty($this->getDeprecatedTokens()[$field])) { |
80 | $realField = $this->getDeprecatedTokens()[$field]; | |
81 | parent::evaluateToken($row, $entity, $realField, $prefetch); | |
82 | $row->format('text/plain')->tokens($entity, $field, $row->tokens['activity'][$realField]); | |
da9977bd | 83 | } |
c6106226 | 84 | elseif ($field === 'case_id') { |
28f7a9b1 MW |
85 | // An activity can be linked to multiple cases so case_id is always an array. |
86 | // We just return the first case ID for the token. | |
b441a504 EM |
87 | // this weird hack might exist because apiv3 is weird & |
88 | $caseID = CRM_Core_DAO::singleValueQuery('SELECT case_id FROM civicrm_case_activity WHERE activity_id = %1 LIMIT 1', [1 => [$activityId, 'Integer']]); | |
89 | $row->tokens($entity, $field, $caseID ?? ''); | |
28f7a9b1 | 90 | } |
b441a504 EM |
91 | else { |
92 | parent::evaluateToken($row, $entity, $field, $prefetch); | |
da9977bd | 93 | } |
b441a504 EM |
94 | } |
95 | ||
e9841a51 EM |
96 | /** |
97 | * Get tokens that are special or calculated for this enitty. | |
98 | * | |
99 | * @return array|array[] | |
100 | */ | |
101 | protected function getBespokeTokens(): array { | |
102 | $tokens = []; | |
103 | if (array_key_exists('CiviCase', CRM_Core_Component::getEnabledComponents())) { | |
104 | $tokens['case_id'] = ts('Activity Case ID'); | |
105 | return [ | |
106 | 'case_id' => [ | |
107 | 'title' => ts('Activity Case ID'), | |
108 | 'name' => 'case_id', | |
109 | 'type' => 'calculated', | |
110 | 'options' => NULL, | |
111 | 'data_type' => 'Integer', | |
112 | 'audience' => 'user', | |
113 | ], | |
114 | ]; | |
115 | } | |
116 | return $tokens; | |
117 | } | |
118 | ||
889b0617 EM |
119 | /** |
120 | * Get fields Fieldshistorically not advertised for tokens. | |
121 | * | |
122 | * @return string[] | |
123 | */ | |
124 | protected function getSkippedFields(): array { | |
125 | return array_merge(parent::getSkippedFields(), [ | |
126 | 'source_record_id', | |
127 | 'phone_id', | |
128 | 'phone_number', | |
129 | 'priority_id', | |
130 | 'parent_id', | |
131 | 'is_test', | |
132 | 'medium_id', | |
133 | 'is_auto', | |
134 | 'relationship_id', | |
135 | 'is_current_revision', | |
136 | 'original_id', | |
137 | 'result', | |
138 | 'is_deleted', | |
139 | 'engagement_level', | |
140 | 'weight', | |
141 | 'is_star', | |
142 | ]); | |
143 | } | |
144 | ||
b441a504 EM |
145 | /** |
146 | * @inheritDoc | |
147 | */ | |
148 | public function getActiveTokens(TokenValueEvent $e) { | |
149 | $messageTokens = $e->getTokenProcessor()->getMessageTokens(); | |
150 | if (!isset($messageTokens[$this->entity])) { | |
151 | return NULL; | |
152 | } | |
153 | ||
154 | $activeTokens = []; | |
b441a504 | 155 | foreach ($messageTokens[$this->entity] as $msgToken) { |
c6106226 | 156 | if (array_key_exists($msgToken, $this->getTokenMetadata())) { |
b441a504 EM |
157 | $activeTokens[] = $msgToken; |
158 | } | |
c6106226 EM |
159 | // case_id is probably set in metadata anyway. |
160 | elseif ($msgToken === 'case_id' || isset($this->getDeprecatedTokens()[$msgToken])) { | |
b441a504 EM |
161 | $activeTokens[] = $msgToken; |
162 | } | |
b441a504 EM |
163 | } |
164 | return array_unique($activeTokens); | |
165 | } | |
166 | ||
167 | public function getPrefetchFields(TokenValueEvent $e): array { | |
168 | $tokens = parent::getPrefetchFields($e); | |
169 | $active = $this->getActiveTokens($e); | |
170 | foreach ($this->getDeprecatedTokens() as $old => $new) { | |
171 | if (in_array($old, $active, TRUE) && !in_array($new, $active, TRUE)) { | |
172 | $tokens[] = $new; | |
173 | } | |
174 | } | |
175 | return $tokens; | |
176 | } | |
177 | ||
178 | /** | |
179 | * These tokens still work but we don't advertise them. | |
180 | * | |
181 | * We will actively remove from the following places | |
182 | * - scheduled reminders | |
183 | * - add to 'blocked' on pdf letter & email | |
184 | * | |
185 | * & then at some point start issuing warnings for them. | |
186 | * | |
187 | * @return string[] | |
188 | */ | |
189 | protected function getDeprecatedTokens(): array { | |
190 | return [ | |
191 | 'activity_id' => 'id', | |
192 | 'activity_type' => 'activity_type_id:label', | |
193 | 'status' => 'status_id:label', | |
194 | 'campaign' => 'campaign_id:label', | |
195 | ]; | |
196 | } | |
197 | ||
46f5566c | 198 | } |