Switch to using apiv4 for metadata
[civicrm-core.git] / CRM / Contribute / Tokens.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
6 | |
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 +--------------------------------------------------------------------+
11 */
12
13 use Civi\ActionSchedule\Event\MailingQueryEvent;
14 use Civi\Token\TokenProcessor;
15 use Civi\Token\TokenRow;
16
17 /**
18 * Class CRM_Contribute_Tokens
19 *
20 * Generate "contribution.*" tokens.
21 *
22 * At time of writing, we don't have any particularly special tokens -- we just
23 * do some basic formatting based on the corresponding DB field.
24 */
25 class CRM_Contribute_Tokens extends CRM_Core_EntityTokens {
26
27 /**
28 * @return string
29 */
30 protected function getEntityName(): string {
31 return 'contribution';
32 }
33
34 /**
35 * @return string
36 */
37 protected function getEntityAlias(): string {
38 return 'contrib_';
39 }
40
41 /**
42 * Get the entity name for api v4 calls.
43 *
44 * In practice this IS just ucfirst($this->GetEntityName)
45 * but declaring it seems more legible.
46 *
47 * @return string
48 */
49 protected function getApiEntityName(): string {
50 return 'Contribution';
51 }
52
53 /**
54 * Metadata about the entity fields.
55 *
56 * @var array
57 */
58 protected $fieldMetadata = [];
59
60 /**
61 * Get a list of tokens whose name and title match the DB fields.
62 * @return array
63 */
64 protected function getPassthruTokens(): array {
65 return [
66 'contribution_page_id',
67 'source',
68 'id',
69 'receive_date',
70 'total_amount',
71 'fee_amount',
72 'net_amount',
73 'non_deductible_amount',
74 'trxn_id',
75 'invoice_id',
76 'currency',
77 'cancel_date',
78 'receipt_date',
79 'thankyou_date',
80 'tax_amount',
81 'contribution_status_id',
82 'financial_type_id',
83 'payment_instrument_id',
84 ];
85 }
86
87 /**
88 * Get tokens supporting the syntax we are migrating to.
89 *
90 * In general these are tokens that were not previously supported
91 * so we can add them in the preferred way or that we have
92 * undertaken some, as yet to be written, db update.
93 *
94 * See https://lab.civicrm.org/dev/core/-/issues/2650
95 *
96 * @return string[]
97 */
98 public function getBasicTokens(): array {
99 $return = [];
100 foreach (['contribution_status_id', 'payment_instrument_id', 'financial_type_id', 'contribution_page_id'] as $fieldName) {
101 $return[$fieldName] = $this->getFieldMetadata()[$fieldName]['title'];
102 }
103 return $return;
104 }
105
106 /**
107 * Class constructor.
108 */
109 public function __construct() {
110 $tokens = CRM_Utils_Array::subset(
111 CRM_Utils_Array::collect('title', $this->getFieldMetadata()),
112 $this->getPassthruTokens()
113 );
114 $tokens = array_merge($tokens, $this->getPseudoTokens(), CRM_Utils_Token::getCustomFieldTokens('Contribution'));
115 parent::__construct('contribution', $tokens);
116 }
117
118 /**
119 * Check if the token processor is active.
120 *
121 * @param \Civi\Token\TokenProcessor $processor
122 *
123 * @return bool
124 */
125 public function checkActive(TokenProcessor $processor) {
126 return !empty($processor->context['actionMapping'])
127 && $processor->context['actionMapping']->getEntity() === 'civicrm_contribution';
128 }
129
130 /**
131 * Alter action schedule query.
132 *
133 * @param \Civi\ActionSchedule\Event\MailingQueryEvent $e
134 */
135 public function alterActionScheduleQuery(MailingQueryEvent $e): void {
136 if ($e->mapping->getEntity() !== 'civicrm_contribution') {
137 return;
138 }
139
140 $fields = $this->getFieldMetadata();
141 foreach ($this->getPassthruTokens() as $token) {
142 $e->query->select('e.' . $fields[$token]['name'] . ' AS ' . $this->getEntityAlias() . $token);
143 }
144 foreach (array_keys($this->getPseudoTokens()) as $token) {
145 $split = explode(':', $token);
146 $e->query->select('e.' . $fields[$split[0]]['name'] . ' AS ' . $this->getEntityAlias() . $split[0]);
147 }
148 }
149
150 /**
151 * @inheritDoc
152 * @throws \CRM_Core_Exception
153 */
154 public function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL) {
155 $actionSearchResult = $row->context['actionSearchResult'];
156 $aliasedField = $this->getEntityAlias() . $field;
157 $fieldValue = $actionSearchResult->{$aliasedField} ?? NULL;
158
159 if ($this->isPseudoField($field)) {
160 $split = explode(':', $field);
161 return $row->tokens($entity, $field, $this->getPseudoValue($split[0], $split[1], $actionSearchResult->{"contrib_$split[0]"} ?? NULL));
162 }
163 if ($this->isMoneyField($field)) {
164 return $row->format('text/plain')->tokens($entity, $field,
165 \CRM_Utils_Money::format($fieldValue, $actionSearchResult->contrib_currency));
166 }
167 if ($this->isDateField($field)) {
168 return $row->format('text/plain')->tokens($entity, $field, \CRM_Utils_Date::customFormat($fieldValue));
169 }
170 if ($this->isCustomField($field)) {
171 $row->customToken($entity, \CRM_Core_BAO_CustomField::getKeyID($field), $actionSearchResult->entity_id);
172 }
173 else {
174 $row->format('text/plain')->tokens($entity, $field, (string) $fieldValue);
175 }
176 }
177
178 }