Merge pull request #17067 from colemanw/importSubmit
[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
46f5566c
TO
18/**
19 * Class CRM_Member_Tokens
20 *
21 * Generate "activity.*" tokens.
22 *
da9977bd 23 * This TokenSubscriber was originally produced by refactoring the code from the
46f5566c
TO
24 * scheduled-reminder system with the goal of making that system
25 * more flexible. The current implementation is still coupled to
26 * scheduled-reminders. It would be good to figure out a more generic
27 * implementation which is not tied to scheduled reminders, although
28 * that is outside the current scope.
da9977bd
AS
29 *
30 * This has been enhanced to work with PDF/letter merge
46f5566c
TO
31 */
32class CRM_Activity_Tokens extends \Civi\Token\AbstractTokenSubscriber {
33
88d88c53 34 use CRM_Core_TokenTrait;
da9977bd
AS
35
36 /**
88d88c53 37 * @return string
da9977bd 38 */
88d88c53
MW
39 private function getEntityName(): string {
40 return 'activity';
41 }
da9977bd 42
8246bca4 43 /**
88d88c53 44 * @return string
8246bca4 45 */
88d88c53
MW
46 private function getEntityTableName(): string {
47 return 'civicrm_activity';
46f5566c
TO
48 }
49
70599df6 50 /**
2ebb452b 51 * Get the name of the field which holds the ID of the given entity.
52 *
88d88c53 53 * @return string
70599df6 54 */
2ebb452b 55 private function getEntityIDFieldName(): string {
56 return 'activity_id';
da9977bd
AS
57 }
58
59 /**
88d88c53
MW
60 * Mapping from tokenName to api return field
61 * Use lists since we might need multiple fields
62 *
63 * @var array
da9977bd 64 */
88d88c53
MW
65 private static $fieldMapping = [
66 'activity_id' => ['id'],
67 'activity_type' => ['activity_type_id'],
68 'status' => ['status_id'],
69 'campaign' => ['campaign_id'],
70 ];
46f5566c 71
298795cd
TO
72 /**
73 * @inheritDoc
74 */
f9ec2da6 75 public function alterActionScheduleQuery(\Civi\ActionSchedule\Event\MailingQueryEvent $e) {
88d88c53 76 if ($e->mapping->getEntity() !== $this->getEntityTableName()) {
f9ec2da6
TO
77 return;
78 }
79
7808aae6
SB
80 // The joint expression for activities needs some extra nuance to handle.
81 // Multiple revisions of the activity.
82 // Q: Could we simplify & move the extra AND clauses into `where(...)`?
f9ec2da6 83 $e->query->param('casEntityJoinExpr', 'e.id = reminder.entity_id AND e.is_current_revision = 1 AND e.is_deleted = 0');
da9977bd 84 }
f9ec2da6 85
da9977bd
AS
86 /**
87 * @inheritDoc
88 */
89 public function prefetch(\Civi\Token\Event\TokenValueEvent $e) {
88d88c53
MW
90 // Find all the entity IDs
91 $entityIds
da9977bd 92 = $e->getTokenProcessor()->getContextValues('actionSearchResult', 'entityID')
2ebb452b 93 + $e->getTokenProcessor()->getContextValues($this->getEntityIDFieldName());
da9977bd 94
88d88c53
MW
95 if (!$entityIds) {
96 return NULL;
da9977bd
AS
97 }
98
99 // Get data on all activities for basic and customfield tokens
100 $activities = civicrm_api3('Activity', 'get', [
88d88c53 101 'id' => ['IN' => $entityIds],
da9977bd
AS
102 'options' => ['limit' => 0],
103 'return' => self::getReturnFields($this->activeTokens),
104 ]);
105 $prefetch['activity'] = $activities['values'];
106
107 // Store the activity types if needed
108 if (in_array('activity_type', $this->activeTokens)) {
109 $this->activityTypes = \CRM_Core_OptionGroup::values('activity_type');
110 }
111
112 // Store the activity statuses if needed
113 if (in_array('status', $this->activeTokens)) {
114 $this->activityStatuses = \CRM_Core_OptionGroup::values('activity_status');
115 }
116
117 // Store the campaigns if needed
118 if (in_array('campaign', $this->activeTokens)) {
119 $this->campaigns = \CRM_Campaign_BAO_Campaign::getCampaigns();
f9ec2da6 120 }
da9977bd
AS
121
122 return $prefetch;
f9ec2da6
TO
123 }
124
46f5566c 125 /**
298795cd 126 * @inheritDoc
2ebb452b 127 *
128 * @throws \CRM_Core_Exception
46f5566c
TO
129 */
130 public function evaluateToken(\Civi\Token\TokenRow $row, $entity, $field, $prefetch = NULL) {
da9977bd
AS
131 // maps token name to api field
132 $mapping = [
133 'activity_id' => 'id',
134 ];
135
136 // Get ActivityID either from actionSearchResult (for scheduled reminders) if exists
2ebb452b 137 $activityId = $row->context['actionSearchResult']->entityID ?? $row->context[$this->getEntityIDFieldName()];
46f5566c 138
da9977bd
AS
139 $activity = (object) $prefetch['activity'][$activityId];
140
141 if (in_array($field, ['activity_date_time', 'created_date'])) {
142 $row->tokens($entity, $field, \CRM_Utils_Date::customFormat($activity->$field));
143 }
144 elseif (isset($mapping[$field]) and (isset($activity->{$mapping[$field]}))) {
145 $row->tokens($entity, $field, $activity->{$mapping[$field]});
46f5566c 146 }
da9977bd
AS
147 elseif (in_array($field, ['activity_type'])) {
148 $row->tokens($entity, $field, $this->activityTypes[$activity->activity_type_id]);
46f5566c 149 }
da9977bd
AS
150 elseif (in_array($field, ['status'])) {
151 $row->tokens($entity, $field, $this->activityStatuses[$activity->status_id]);
4e9b6a62 152 }
da9977bd
AS
153 elseif (in_array($field, ['campaign'])) {
154 $row->tokens($entity, $field, $this->campaigns[$activity->campaign_id]);
155 }
28f7a9b1
MW
156 elseif (in_array($field, ['case_id'])) {
157 // An activity can be linked to multiple cases so case_id is always an array.
158 // We just return the first case ID for the token.
159 $row->tokens($entity, $field, is_array($activity->case_id) ? reset($activity->case_id) : $activity->case_id);
160 }
da9977bd
AS
161 elseif (array_key_exists($field, $this->customFieldTokens)) {
162 $row->tokens($entity, $field,
163 isset($activity->$field)
164 ? \CRM_Core_BAO_CustomField::displayValue($activity->$field, $field)
165 : ''
166 );
167 }
168 elseif (isset($activity->$field)) {
169 $row->tokens($entity, $field, $activity->$field);
46f5566c
TO
170 }
171 }
172
86420016 173 /**
174 * Get the basic tokens provided.
175 *
176 * @return array token name => token label
177 */
178 protected function getBasicTokens() {
da9977bd
AS
179 if (!isset($this->basicTokens)) {
180 $this->basicTokens = [
181 'activity_id' => ts('Activity ID'),
182 'activity_type' => ts('Activity Type'),
183 'subject' => ts('Activity Subject'),
184 'details' => ts('Activity Details'),
185 'activity_date_time' => ts('Activity Date-Time'),
186 'activity_type_id' => ts('Activity Type ID'),
187 'status' => ts('Activity Status'),
188 'status_id' => ts('Activity Status ID'),
189 'location' => ts('Activity Location'),
190 'created_date' => ts('Activity Creation Date'),
191 'duration' => ts('Activity Duration'),
192 'campaign' => ts('Activity Campaign'),
193 'campaign_id' => ts('Activity Campaign ID'),
194 ];
195 if (array_key_exists('CiviCase', CRM_Core_Component::getEnabledComponents())) {
196 $this->basicTokens['case_id'] = ts('Activity Case ID');
197 }
198 }
199 return $this->basicTokens;
86420016 200 }
201
46f5566c 202}