distmaker - Include `mixin/*` files
[civicrm-core.git] / CRM / Activity / Tokens.php
CommitLineData
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 18use Civi\ActionSchedule\Event\MailingQueryEvent;
c2a33d9c 19use Civi\Token\Event\TokenValueEvent;
20use 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 36class 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}