4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
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 |
10 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
18 use Civi\ActionSchedule\Event\MailingQueryEvent
;
19 use Civi\Token\Event\TokenValueEvent
;
20 use Civi\Token\TokenRow
;
23 * Class CRM_Member_Tokens
25 * Generate "activity.*" tokens.
27 * This TokenSubscriber was originally produced by refactoring the code from the
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.
34 * This has been enhanced to work with PDF/letter merge
36 class CRM_Activity_Tokens
extends CRM_Core_EntityTokens
{
39 * Get the entity name for api v4 calls.
43 protected function getApiEntityName(): string {
50 public function alterActionScheduleQuery(MailingQueryEvent
$e): void
{
51 if ($e->mapping
->getEntity() !== $this->getExtendableTableName()) {
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(...)`?
58 $e->query
->param('casEntityJoinExpr', 'e.id = reminder.entity_id AND e.is_current_revision = 1 AND e.is_deleted = 0');
59 parent
::alterActionScheduleQuery($e);
63 * Evaluate the content of a single token.
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().
74 * @throws \CRM_Core_Exception
76 public function evaluateToken(TokenRow
$row, $entity, $field, $prefetch = NULL) {
77 $activityId = $this->getFieldValue($row, 'id');
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]);
84 elseif ($field === 'case_id') {
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.
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 ??
'');
92 parent
::evaluateToken($row, $entity, $field, $prefetch);
97 * Get tokens that are special or calculated for this enitty.
99 * @return array|array[]
101 protected function getBespokeTokens(): array {
103 if (CRM_Core_Component
::isEnabled('CiviCase')) {
104 $tokens['case_id'] = ts('Activity Case ID');
107 'title' => ts('Activity Case ID'),
109 'type' => 'calculated',
111 'data_type' => 'Integer',
112 'audience' => 'user',
120 * Get fields Fieldshistorically not advertised for tokens.
124 protected function getSkippedFields(): array {
125 return array_merge(parent
::getSkippedFields(), [
135 'is_current_revision',
148 public function getActiveTokens(TokenValueEvent
$e) {
149 $messageTokens = $e->getTokenProcessor()->getMessageTokens();
150 if (!isset($messageTokens[$this->entity
])) {
155 foreach ($messageTokens[$this->entity
] as $msgToken) {
156 if (array_key_exists($msgToken, $this->getTokenMetadata())) {
157 $activeTokens[] = $msgToken;
159 // case_id is probably set in metadata anyway.
160 elseif ($msgToken === 'case_id' ||
isset($this->getDeprecatedTokens()[$msgToken])) {
161 $activeTokens[] = $msgToken;
164 return array_unique($activeTokens);
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)) {
179 * These tokens still work but we don't advertise them.
181 * We will actively remove from the following places
182 * - scheduled reminders
183 * - add to 'blocked' on pdf letter & email
185 * & then at some point start issuing warnings for them.
189 protected function getDeprecatedTokens(): array {
191 'activity_id' => 'id',
192 'activity_type' => 'activity_type_id:label',
193 'status' => 'status_id:label',
194 'campaign' => 'campaign_id:label',