Merge pull request #21047 from eileenmcnaughton/tok_return
[civicrm-core.git] / CRM / Core / EntityTokens.php
CommitLineData
17b6f179
EM
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
13use Civi\Token\AbstractTokenSubscriber;
14use Civi\Token\TokenRow;
15
16/**
17 * Class CRM_Core_EntityTokens
18 *
19 * Parent class for generic entity token functionality.
20 *
21 * WARNING - this class is highly likely to be temporary and
22 * to be consolidated with the TokenTrait and / or the
23 * AbstractTokenSubscriber in future. It is being used to clarify
24 * functionality but should NOT be used from outside of core tested code.
25 */
26class CRM_Core_EntityTokens extends AbstractTokenSubscriber {
27
28 /**
29 * This is required for the parent - it will be filled out.
30 *
31 * @inheritDoc
32 */
33 public function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL) {
34 }
35
29f2b53e
EM
36 /**
37 * Get the entity name for api v4 calls.
38 *
39 * @return string
40 */
41 protected function getApiEntityName(): string {
42 return '';
43 }
44
45 /**
46 * Get the entity alias to use within queries.
47 *
48 * The default has a double underscore which should prevent any
49 * ambiguity with an existing table name.
50 *
51 * @return string
52 */
53 protected function getEntityAlias(): string {
54 return $this->getApiEntityName() . '__';
55 }
56
3fcf0983
EM
57 /**
58 * Get the name of the table this token class can extend.
59 *
60 * The default is based on the entity but some token classes,
61 * specifically the event class, latch on to other tables - ie
62 * the participant table.
63 */
64 public function getExtendableTableName(): string {
65 return CRM_Core_DAO_AllCoreTables::getTableForEntityName($this->getApiEntityName());
66 }
67
29f2b53e
EM
68 /**
69 * Get the relevant bao name.
70 */
71 public function getBAOName(): string {
72 return CRM_Core_DAO_AllCoreTables::getFullName($this->getApiEntityName());
73 }
74
3fcf0983
EM
75 /**
76 * Get an array of fields to be requested.
77 *
78 * @return string[]
79 */
80 public function getReturnFields(): array {
81 return array_keys($this->getBasicTokens());
82 }
83
4a526c1b
EM
84 /**
85 * Get all the tokens supported by this processor.
86 *
87 * @return array|string[]
88 */
89 public function getAllTokens(): array {
90 return array_merge($this->getBasicTokens(), $this->getPseudoTokens(), CRM_Utils_Token::getCustomFieldTokens('Contribution'));
91 }
92
17b6f179
EM
93 /**
94 * Is the given field a date field.
95 *
96 * @param string $fieldName
97 *
98 * @return bool
99 */
100 public function isDateField(string $fieldName): bool {
29f2b53e
EM
101 return $this->getFieldMetadata()[$fieldName]['data_type'] === 'Timestamp';
102 }
103
104 /**
105 * Is the given field a pseudo field.
106 *
107 * @param string $fieldName
108 *
109 * @return bool
110 */
111 public function isPseudoField(string $fieldName): bool {
112 return strpos($fieldName, ':') !== FALSE;
113 }
114
115 /**
116 * Is the given field a custom field.
117 *
118 * @param string $fieldName
119 *
120 * @return bool
121 */
122 public function isCustomField(string $fieldName) : bool {
123 return (bool) \CRM_Core_BAO_CustomField::getKeyID($fieldName);
17b6f179
EM
124 }
125
126 /**
127 * Is the given field a date field.
128 *
129 * @param string $fieldName
130 *
131 * @return bool
132 */
133 public function isMoneyField(string $fieldName): bool {
29f2b53e 134 return $this->getFieldMetadata()[$fieldName]['data_type'] === 'Money';
17b6f179
EM
135 }
136
137 /**
138 * Get the metadata for the available fields.
139 *
140 * @return array
141 */
142 protected function getFieldMetadata(): array {
143 if (empty($this->fieldMetadata)) {
29f2b53e
EM
144 try {
145 // Tests fail without checkPermissions = FALSE
146 $this->fieldMetadata = (array) civicrm_api4($this->getApiEntityName(), 'getfields', ['checkPermissions' => FALSE], 'name');
147 }
148 catch (API_Exception $e) {
149 $this->fieldMetadata = [];
17b6f179
EM
150 }
151 }
152 return $this->fieldMetadata;
153 }
154
29f2b53e
EM
155 /**
156 * Get pseudoTokens - it tokens that reflect the name or label of a pseudoconstant.
157 *
158 * @internal - this function will likely be made protected soon.
159 *
160 * @return array
161 */
162 public function getPseudoTokens(): array {
163 $return = [];
164 foreach (array_keys($this->getBasicTokens()) as $fieldName) {
165 if ($this->isAddPseudoTokens($fieldName)) {
166 $return[$fieldName . ':label'] = $this->fieldMetadata[$fieldName]['input_attrs']['label'];
167 $return[$fieldName . ':name'] = ts('Machine name') . ': ' . $this->fieldMetadata[$fieldName]['input_attrs']['label'];
168 }
169 }
170 return $return;
171 }
172
173 /**
174 * Is this a field we should add pseudo-tokens to?
175 *
176 * Pseudo-tokens allow access to name and label fields - e.g
177 *
178 * {contribution.contribution_status_id:name} might resolve to 'Completed'
179 *
180 * @param string $fieldName
181 */
182 public function isAddPseudoTokens($fieldName): bool {
183 if ($fieldName === 'currency') {
184 // 'currency' is manually added to the skip list as an anomaly.
185 // name & label aren't that suitable for 'currency' (symbol, which
186 // possibly maps to 'abbr' would be) and we can't gather that
187 // from the metadata as yet.
188 return FALSE;
189 }
190 return (bool) $this->getFieldMetadata()[$fieldName]['options'];
191 }
192
193 /**
194 * Get the value for the relevant pseudo field.
195 *
196 * @param string $realField e.g contribution_status_id
197 * @param string $pseudoKey e.g name
198 * @param int|string $fieldValue e.g 1
199 *
200 * @return string
201 * Eg. 'Completed' in the example above.
202 *
203 * @internal function will likely be protected soon.
204 */
205 public function getPseudoValue(string $realField, string $pseudoKey, $fieldValue): string {
206 if ($pseudoKey === 'name') {
207 $fieldValue = (string) CRM_Core_PseudoConstant::getName($this->getBAOName(), $realField, $fieldValue);
208 }
209 if ($pseudoKey === 'label') {
210 $fieldValue = (string) CRM_Core_PseudoConstant::getLabel($this->getBAOName(), $realField, $fieldValue);
211 }
212 return (string) $fieldValue;
213 }
214
17b6f179 215}