Commit | Line | Data |
---|---|---|
d84ae5f6 | 1 | <?php |
2 | /* | |
bc77d7c0 TO |
3 | +--------------------------------------------------------------------+ |
4 | | Copyright CiviCRM LLC. All rights reserved. | | |
5 | | | | |
6 | | This work is published under the GNU AGPLv3 license with some | | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
9 | +--------------------------------------------------------------------+ | |
d84ae5f6 | 10 | */ |
11 | ||
12 | /** | |
13 | * | |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
d84ae5f6 | 16 | */ |
d84ae5f6 | 17 | trait CRM_Core_Form_EntityFormTrait { |
d5e4784e | 18 | |
e57fc8ca MWMC |
19 | /** |
20 | * The id of the object being edited / created. | |
21 | * | |
22 | * @var int | |
23 | */ | |
24 | public $_id; | |
25 | ||
9f1073d2 MWMC |
26 | /** |
27 | * The entity subtype ID (eg. for Relationship / Activity) | |
28 | * | |
29 | * @var int | |
30 | */ | |
ed706f8d | 31 | protected $_entitySubTypeId = NULL; |
9f1073d2 | 32 | |
d84ae5f6 | 33 | /** |
34 | * Get entity fields for the entity to be added to the form. | |
35 | * | |
d5e4784e | 36 | * @return array |
d84ae5f6 | 37 | */ |
38 | public function getEntityFields() { | |
39 | return $this->entityFields; | |
40 | } | |
41 | ||
42 | /** | |
43 | * Explicitly declare the form context. | |
44 | */ | |
45 | public function getDefaultContext() { | |
46 | return 'create'; | |
47 | } | |
48 | ||
49 | /** | |
50 | * Get entity fields for the entity to be added to the form. | |
51 | * | |
d5e4784e | 52 | * @return string |
d84ae5f6 | 53 | */ |
54 | public function getDeleteMessage() { | |
55 | return $this->deleteMessage; | |
56 | } | |
57 | ||
379d6cd7 | 58 | /** |
59 | * Set the delete message. | |
60 | * | |
61 | * We do this from the constructor in order to do a translation. | |
62 | */ | |
63 | public function setDeleteMessage() { | |
64 | } | |
65 | ||
66 | /** | |
67 | * Set entity fields to be assigned to the form. | |
68 | */ | |
69 | protected function setEntityFields() { | |
70 | } | |
71 | ||
d84ae5f6 | 72 | /** |
73 | * Get the entity id being edited. | |
74 | * | |
75 | * @return int|null | |
76 | */ | |
77 | public function getEntityId() { | |
78 | return $this->_id; | |
79 | } | |
9f1073d2 | 80 | |
e57fc8ca MWMC |
81 | /** |
82 | * Set the entity ID | |
83 | * | |
84 | * @param int $id The entity ID | |
85 | */ | |
86 | public function setEntityId($id) { | |
87 | $this->_id = $id; | |
88 | } | |
89 | ||
f1105edc | 90 | /** |
91 | * Should custom data be suppressed on this form. | |
92 | * | |
93 | * @return bool | |
94 | */ | |
95 | protected function isSuppressCustomData() { | |
96 | return FALSE; | |
97 | } | |
98 | ||
9f1073d2 MWMC |
99 | /** |
100 | * Get the entity subtype ID being edited | |
101 | * | |
9f1073d2 MWMC |
102 | * @return int|null |
103 | */ | |
ed706f8d | 104 | public function getEntitySubTypeId() { |
9f1073d2 MWMC |
105 | return $this->_entitySubTypeId; |
106 | } | |
107 | ||
ed706f8d MWMC |
108 | /** |
109 | * Set the entity subtype ID being edited | |
110 | * | |
111 | * @param $subTypeId | |
112 | */ | |
113 | public function setEntitySubTypeId($subTypeId) { | |
114 | $this->_entitySubTypeId = $subTypeId; | |
115 | } | |
116 | ||
d84ae5f6 | 117 | /** |
118 | * If the custom data is in the submitted data (eg. added via ajax loaded form) add to form. | |
119 | */ | |
120 | public function addCustomDataToForm() { | |
f1105edc | 121 | if ($this->isSuppressCustomData()) { |
122 | return TRUE; | |
123 | } | |
d84ae5f6 | 124 | $customisableEntities = CRM_Core_SelectValues::customGroupExtends(); |
125 | if (isset($customisableEntities[$this->getDefaultEntity()])) { | |
ed706f8d | 126 | CRM_Custom_Form_CustomData::addToForm($this, $this->getEntitySubTypeId()); |
d84ae5f6 | 127 | } |
128 | } | |
129 | ||
130 | /** | |
131 | * Build the form object. | |
132 | */ | |
133 | public function buildQuickEntityForm() { | |
59c798c9 | 134 | if ($this->isDeleteContext()) { |
d84ae5f6 | 135 | $this->buildDeleteForm(); |
136 | return; | |
137 | } | |
138 | $this->applyFilter('__ALL__', 'trim'); | |
139 | $this->addEntityFieldsToTemplate(); | |
140 | $this->assign('entityFields', $this->entityFields); | |
141 | $this->assign('entityID', $this->getEntityId()); | |
142 | $this->assign('entityInClassFormat', strtolower(str_replace('_', '-', $this->getDefaultEntity()))); | |
143 | $this->assign('entityTable', CRM_Core_DAO_AllCoreTables::getTableForClass(CRM_Core_DAO_AllCoreTables::getFullName($this->getDefaultEntity()))); | |
144 | $this->addCustomDataToForm(); | |
145 | $this->addFormButtons(); | |
48c242dc MWMC |
146 | |
147 | if ($this->isViewContext()) { | |
148 | $this->freeze(); | |
149 | } | |
d84ae5f6 | 150 | } |
151 | ||
152 | /** | |
153 | * Build the form for any deletion. | |
154 | */ | |
155 | protected function buildDeleteForm() { | |
156 | $this->assign('deleteMessage', $this->getDeleteMessage()); | |
157 | $this->addFormButtons(); | |
158 | } | |
159 | ||
160 | /** | |
161 | * Add relevant buttons to the form. | |
162 | */ | |
163 | protected function addFormButtons() { | |
48c242dc | 164 | if ($this->isViewContext() || $this->_action & CRM_Core_Action::PREVIEW) { |
be2fb01f | 165 | $this->addButtons([ |
518fa0ee SL |
166 | [ |
167 | 'type' => 'cancel', | |
168 | 'name' => ts('Done'), | |
169 | 'isDefault' => TRUE, | |
170 | ], | |
171 | ]); | |
d84ae5f6 | 172 | } |
173 | else { | |
be2fb01f | 174 | $this->addButtons([ |
518fa0ee SL |
175 | [ |
176 | 'type' => 'next', | |
177 | 'name' => $this->isDeleteContext() ? ts('Delete') : ts('Save'), | |
178 | 'isDefault' => TRUE, | |
179 | ], | |
180 | [ | |
181 | 'type' => 'cancel', | |
182 | 'name' => ts('Cancel'), | |
183 | ], | |
184 | ]); | |
d84ae5f6 | 185 | } |
186 | } | |
187 | ||
612215eb | 188 | /** |
189 | * Get the defaults for the entity. | |
190 | */ | |
191 | protected function getEntityDefaults() { | |
99e201e8 MWMC |
192 | $defaults = $moneyFields = []; |
193 | ||
48c242dc | 194 | if (!$this->isDeleteContext() && |
518fa0ee | 195 | $this->getEntityId()) { |
612215eb | 196 | $params = ['id' => $this->getEntityId()]; |
197 | $baoName = $this->_BAOName; | |
198 | $baoName::retrieve($params, $defaults); | |
199 | } | |
99e201e8 | 200 | foreach ($this->entityFields as $entityFieldName => $fieldSpec) { |
612215eb | 201 | $value = CRM_Utils_Request::retrieveValue($fieldSpec['name'], $this->getValidationTypeForField($fieldSpec['name'])); |
ea1cafad | 202 | if ($value !== FALSE && $value !== NULL) { |
612215eb | 203 | $defaults[$fieldSpec['name']] = $value; |
204 | } | |
99e201e8 | 205 | // Store a list of fields with money formatters |
48c242dc | 206 | if (CRM_Utils_Array::value('formatter', $fieldSpec) == 'crmMoney') { |
99e201e8 MWMC |
207 | $moneyFields[] = $entityFieldName; |
208 | } | |
209 | } | |
210 | if (!empty($defaults['currency'])) { | |
211 | // If we have a money formatter we need to pass the specified currency or it will render as the default | |
212 | foreach ($moneyFields as $entityFieldName) { | |
213 | $this->entityFields[$entityFieldName]['formatterParam'] = $defaults['currency']; | |
48c242dc | 214 | } |
612215eb | 215 | } |
99e201e8 | 216 | |
48c242dc MWMC |
217 | // Assign again as we may have modified above |
218 | $this->assign('entityFields', $this->entityFields); | |
612215eb | 219 | return $defaults; |
220 | } | |
221 | ||
222 | /** | |
223 | * Get the validation rule to apply to a function. | |
224 | * | |
225 | * Alphanumeric is designed to always be safe & for now we just return | |
226 | * that but in future we can use tighter rules for types like int, bool etc. | |
227 | * | |
228 | * @param string $fieldName | |
229 | * | |
230 | * @return string|int|bool | |
231 | */ | |
232 | protected function getValidationTypeForField($fieldName) { | |
233 | switch ($this->metadata[$fieldName]['type']) { | |
234 | case CRM_Utils_Type::T_BOOLEAN: | |
235 | return 'Boolean'; | |
236 | ||
237 | default: | |
238 | return 'Alphanumeric'; | |
239 | } | |
240 | } | |
241 | ||
d84ae5f6 | 242 | /** |
243 | * Set translated fields. | |
244 | * | |
245 | * This function is called from the class constructor, allowing us to set | |
246 | * fields on the class that can't be set as properties due to need for | |
247 | * translation or other non-input specific handling. | |
248 | */ | |
249 | protected function setTranslatedFields() { | |
250 | $this->setEntityFields(); | |
251 | $this->setDeleteMessage(); | |
252 | $metadata = civicrm_api3($this->getDefaultEntity(), 'getfields', ['action' => 'create']); | |
253 | $this->metadata = $metadata['values']; | |
254 | foreach ($this->metadata as $fieldName => $spec) { | |
255 | if (isset($this->entityFields[$fieldName])) { | |
256 | if ($spec['localizable']) { | |
257 | $this->entityFields[$fieldName]['is_add_translate_dialog'] = TRUE; | |
258 | } | |
797edf50 | 259 | if (empty($spec['html']['type'])) { |
d84ae5f6 | 260 | $this->entityFields[$fieldName]['not-auto-addable'] = TRUE; |
261 | } | |
262 | } | |
263 | } | |
264 | } | |
265 | ||
266 | /** | |
267 | * Add defined entity field to template. | |
268 | */ | |
269 | protected function addEntityFieldsToTemplate() { | |
270 | foreach ($this->getEntityFields() as $fieldSpec) { | |
271 | if (empty($fieldSpec['not-auto-addable'])) { | |
59c798c9 | 272 | $element = $this->addField($fieldSpec['name'], [], CRM_Utils_Array::value('required', $fieldSpec), FALSE); |
4d876348 | 273 | if (!empty($fieldSpec['is_freeze'])) { |
274 | $element->freeze(); | |
275 | } | |
d84ae5f6 | 276 | } |
277 | } | |
278 | } | |
279 | ||
59c798c9 | 280 | /** |
281 | * Is the form being used in the context of a deletion. | |
282 | * | |
283 | * (For some reason rather than having separate forms Civi overloads one form). | |
284 | * | |
285 | * @return bool | |
286 | */ | |
287 | protected function isDeleteContext() { | |
288 | return ($this->_action & CRM_Core_Action::DELETE); | |
289 | } | |
290 | ||
48c242dc MWMC |
291 | /** |
292 | * Is the form being used in the context of a view. | |
293 | * | |
294 | * @return bool | |
295 | */ | |
296 | protected function isViewContext() { | |
297 | return ($this->_action & CRM_Core_Action::VIEW); | |
298 | } | |
299 | ||
d5e4784e MWMC |
300 | protected function setEntityFieldsMetadata() { |
301 | foreach ($this->entityFields as $field => &$props) { | |
302 | if (!empty($props['not-auto-addable'])) { | |
303 | // We can't load this field using metadata | |
304 | continue; | |
305 | } | |
079c7954 CW |
306 | if ($field != 'id' && $this->isDeleteContext()) { |
307 | // Delete forms don't generally present any fields to edit | |
308 | continue; | |
309 | } | |
d5e4784e MWMC |
310 | // Resolve action. |
311 | if (empty($props['action'])) { | |
312 | $props['action'] = $this->getApiAction(); | |
313 | } | |
314 | $fieldSpec = civicrm_api3($this->getDefaultEntity(), 'getfield', $props); | |
315 | $fieldSpec = $fieldSpec['values']; | |
316 | if (!isset($props['description']) && isset($fieldSpec['description'])) { | |
317 | $props['description'] = $fieldSpec['description']; | |
318 | } | |
319 | } | |
320 | } | |
321 | ||
d84ae5f6 | 322 | } |