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 = []; | |
166a1708 | 103 | if (CRM_Core_Component::isEnabled('CiviCase')) { |
8b0d8f6f MW |
104 | $tokens['case_id'] = [ |
105 | 'title' => ts('Activity Case ID'), | |
106 | 'name' => 'case_id', | |
107 | 'type' => 'calculated', | |
108 | 'options' => NULL, | |
109 | 'data_type' => 'Integer', | |
110 | 'audience' => 'user', | |
e9841a51 EM |
111 | ]; |
112 | } | |
113 | return $tokens; | |
114 | } | |
115 | ||
889b0617 EM |
116 | /** |
117 | * Get fields Fieldshistorically not advertised for tokens. | |
118 | * | |
119 | * @return string[] | |
120 | */ | |
121 | protected function getSkippedFields(): array { | |
122 | return array_merge(parent::getSkippedFields(), [ | |
123 | 'source_record_id', | |
124 | 'phone_id', | |
125 | 'phone_number', | |
126 | 'priority_id', | |
127 | 'parent_id', | |
128 | 'is_test', | |
129 | 'medium_id', | |
130 | 'is_auto', | |
131 | 'relationship_id', | |
132 | 'is_current_revision', | |
133 | 'original_id', | |
134 | 'result', | |
135 | 'is_deleted', | |
136 | 'engagement_level', | |
137 | 'weight', | |
138 | 'is_star', | |
139 | ]); | |
140 | } | |
141 | ||
b441a504 EM |
142 | /** |
143 | * @inheritDoc | |
144 | */ | |
145 | public function getActiveTokens(TokenValueEvent $e) { | |
146 | $messageTokens = $e->getTokenProcessor()->getMessageTokens(); | |
147 | if (!isset($messageTokens[$this->entity])) { | |
148 | return NULL; | |
149 | } | |
150 | ||
151 | $activeTokens = []; | |
b441a504 | 152 | foreach ($messageTokens[$this->entity] as $msgToken) { |
c6106226 | 153 | if (array_key_exists($msgToken, $this->getTokenMetadata())) { |
b441a504 EM |
154 | $activeTokens[] = $msgToken; |
155 | } | |
c6106226 EM |
156 | // case_id is probably set in metadata anyway. |
157 | elseif ($msgToken === 'case_id' || isset($this->getDeprecatedTokens()[$msgToken])) { | |
b441a504 EM |
158 | $activeTokens[] = $msgToken; |
159 | } | |
b441a504 EM |
160 | } |
161 | return array_unique($activeTokens); | |
162 | } | |
163 | ||
164 | public function getPrefetchFields(TokenValueEvent $e): array { | |
165 | $tokens = parent::getPrefetchFields($e); | |
166 | $active = $this->getActiveTokens($e); | |
167 | foreach ($this->getDeprecatedTokens() as $old => $new) { | |
168 | if (in_array($old, $active, TRUE) && !in_array($new, $active, TRUE)) { | |
169 | $tokens[] = $new; | |
170 | } | |
171 | } | |
172 | return $tokens; | |
173 | } | |
174 | ||
175 | /** | |
176 | * These tokens still work but we don't advertise them. | |
177 | * | |
178 | * We will actively remove from the following places | |
179 | * - scheduled reminders | |
180 | * - add to 'blocked' on pdf letter & email | |
181 | * | |
182 | * & then at some point start issuing warnings for them. | |
183 | * | |
184 | * @return string[] | |
185 | */ | |
186 | protected function getDeprecatedTokens(): array { | |
187 | return [ | |
188 | 'activity_id' => 'id', | |
189 | 'activity_type' => 'activity_type_id:label', | |
190 | 'status' => 'status_id:label', | |
191 | 'campaign' => 'campaign_id:label', | |
192 | ]; | |
193 | } | |
194 | ||
46f5566c | 195 | } |