Further simplification
[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 = [];
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}