3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
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 +--------------------------------------------------------------------+
12 use Civi\Api4\CustomGroup
;
13 use Civi\Api4\CustomField
;
14 use Civi\Api4\OptionValue
;
17 * Trait Custom Data trait.
19 * Trait for setting up custom data in tests.
21 trait CRMTraits_Custom_CustomDataTrait
{
24 * Create a custom group with fields of multiple types.
26 * @param array $groupParams
28 * @throws \API_Exception
29 * @throws \Civi\API\Exception\UnauthorizedException
31 public function createCustomGroupWithFieldsOfAllTypes($groupParams = []) {
32 $this->createCustomGroup($groupParams);
33 $this->ids
['CustomField'] = $this->createCustomFieldsOfAllTypes();
37 * Create a custom group.
39 * @param array $params
43 * @throws \API_Exception
44 * @throws \Civi\API\Exception\UnauthorizedException
46 public function createCustomGroup($params = []) {
47 $params = array_merge([
48 'title' => 'Custom Group',
49 'extends' => [$this->entity ??
'Contact'],
54 $identifier = $params['name'] ??
$params['title'];
55 $this->ids
['CustomGroup'][$identifier] = CustomGroup
::create(FALSE)->setValues($params)->execute()->first()['id'];
56 return $this->ids
['CustomGroup'][$identifier];
60 * Get the table_name for the specified custom group.
62 * @param string $identifier
66 public function getCustomGroupTable($identifier = 'Custom Group') {
67 return $this->callAPISuccessGetValue('CustomGroup', ['id' => $this->ids
['CustomGroup'][$identifier], 'return' => 'table_name']);
71 * Get the the column name for the identified custom field.
74 * Identifier - generally keys map to data type - eg. 'text', 'int' etc.
78 protected function getCustomFieldColumnName($key) {
79 return $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID($key), 'return' => 'column_name']);
83 * Create a custom group with a single field.
85 * @param array $groupParams
86 * Params for the group to be created.
87 * @param string $customFieldType
89 * @param string|null $identifier
91 * @param array $fieldParams
93 * @throws \API_Exception
94 * @throws \CRM_Core_Exception
95 * @throws \Civi\API\Exception\UnauthorizedException
97 public function createCustomGroupWithFieldOfType($groupParams = [], $customFieldType = 'text', $identifier = NULL, $fieldParams = []) {
98 $supported = ['text', 'select', 'date', 'int', 'contact_reference', 'radio', 'multi_country'];
99 if (!in_array($customFieldType, $supported, TRUE)) {
100 throw new CRM_Core_Exception('we have not yet extracted other custom field types from createCustomFieldsOfAllTypes, Use consistent syntax when you do');
102 $groupParams['title'] = empty($groupParams['title']) ?
$identifier . 'Group with field ' . $customFieldType : $groupParams['title'];
103 $groupParams['name'] = $identifier ??
'Custom Group';
104 $this->createCustomGroup($groupParams);
105 $reference = &$this->ids
['CustomField'][$identifier . $customFieldType];
106 $fieldParams = array_merge($fieldParams, ['custom_group_id' => $this->ids
['CustomGroup'][$groupParams['name']]]);
107 switch ($customFieldType) {
109 $reference = $this->createTextCustomField($fieldParams)['id'];
113 $reference = $this->createSelectCustomField($fieldParams)['id'];
117 $reference = $this->createIntCustomField($fieldParams)['id'];
121 $reference = $this->createDateCustomField($fieldParams)['id'];
124 case 'contact_reference':
125 $reference = $this->createContactReferenceCustomField($fieldParams)['id'];
129 $reference = $this->createIntegerRadioCustomField($fieldParams)['id'];
132 case 'multi_country':
133 $reference = $this->createMultiCountryCustomField($fieldParams)['id'];
142 public function createCustomFieldsOfAllTypes() {
143 $customGroupID = $this->ids
['CustomGroup']['Custom Group'];
145 $ids['text'] = (int) $this->createTextCustomField(['custom_group_id' => $customGroupID])['id'];
146 $ids['select_string'] = (int) $this->createSelectCustomField(['custom_group_id' => $customGroupID])['id'];
147 $ids['select_date'] = (int) $this->createDateCustomField(['custom_group_id' => $customGroupID])['id'];
148 $ids['int'] = (int) $this->createIntCustomField(['custom_group_id' => $customGroupID])['id'];
149 $ids['link'] = (int) $this->createLinkCustomField(['custom_group_id' => $customGroupID])['id'];
150 $ids['file'] = (int) $this->createFileCustomField(['custom_group_id' => $customGroupID])['id'];
151 $ids['country'] = (int) $this->createCountryCustomField(['custom_group_id' => $customGroupID])['id'];
152 $ids['multi_country'] = (int) $this->createMultiCountryCustomField(['custom_group_id' => $customGroupID])['id'];
153 $ids['contact_reference'] = $this->createContactReferenceCustomField(['custom_group_id' => $customGroupID])['id'];
154 $ids['state'] = (int) $this->createStateCustomField(['custom_group_id' => $customGroupID])['id'];
155 $ids['multi_state'] = (int) $this->createMultiStateCustomField(['custom_group_id' => $customGroupID])['id'];
156 $ids['boolean'] = (int) $this->createBooleanCustomField(['custom_group_id' => $customGroupID])['id'];
161 * Get the custom field name for the relevant key.
163 * e.g returns 'custom_5' where 5 is the id of the field using the key.
165 * Generally keys map to data types.
171 protected function getCustomFieldName($key) {
172 return 'custom_' . $this->getCustomFieldID($key);
176 * Add another option to the custom field.
179 * @param array $values
182 * @throws \API_Exception
184 protected function addOptionToCustomField($key, $values) {
185 $optionGroupID = CustomField
::get(FALSE)
186 ->addWhere('id', '=', $this->getCustomFieldID($key))
187 ->addSelect('option_group_id')
188 ->execute()->first()['option_group_id'];
189 return (int) OptionValue
::create(FALSE)
190 ->setValues(array_merge(['option_group_id' => $optionGroupID], $values))
191 ->execute()->first()['value'];
195 * Get the custom field name for the relevant key.
197 * e.g returns 'custom_5' where 5 is the id of the field using the key.
199 * Generally keys map to data types.
205 protected function getCustomFieldID($key) {
206 return $this->ids
['CustomField'][$key];
210 * Create a custom text fields.
212 * @param array $params
213 * Parameter overrides, must include custom_group_id.
217 protected function createIntCustomField($params = []) {
218 $params = array_merge($this->getFieldsValuesByType('Int'), $params);
219 return $this->callAPISuccess('CustomField', 'create', $params)['values'][0];
223 * Create a custom text fields.
225 * @param array $params
226 * Parameter overrides, must include custom_group_id.
230 protected function createBooleanCustomField($params = []) {
231 $params = array_merge($this->getFieldsValuesByType('Boolean'), $params);
232 return $this->callAPISuccess('CustomField', 'create', $params)['values'][0];
236 * Create a custom text fields.
238 * @param array $params
239 * Parameter overrides, must include custom_group_id.
243 protected function createContactReferenceCustomField($params = []) {
244 $params = array_merge($this->getFieldsValuesByType('ContactReference'), $params);
245 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
249 * Create a custom text fields.
251 * @param array $params
252 * Parameter overrides, must include custom_group_id.
256 protected function createTextCustomField($params = []) {
257 $params = array_merge($this->getFieldsValuesByType('String'), $params);
258 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
262 * Create a custom text fields.
264 * @param array $params
265 * Parameter overrides, must include custom_group_id.
269 protected function createLinkCustomField($params = []) {
270 $params = array_merge($this->getFieldsValuesByType('Link'), $params);
271 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
275 * Create a custom country fields.
277 * @param array $params
278 * Parameter overrides, must include custom_group_id.
282 protected function createCountryCustomField($params = []) {
283 $params = array_merge($this->getFieldsValuesByType('Country'), $params);
284 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
288 * Create a custom multi select country fields.
290 * @param array $params
291 * Parameter overrides, must include custom_group_id.
295 protected function createMultiCountryCustomField($params = []) {
296 $params = array_merge($this->getFieldsValuesByType('Country', 'Multi-Select Country'), $params);
297 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
301 * Create a custom state fields.
303 * @param array $params
304 * Parameter overrides, must include custom_group_id.
308 protected function createStateCustomField($params = []) {
309 $params = array_merge($this->getFieldsValuesByType('StateProvince'), $params);
310 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
314 * Create a custom multi select state fields.
316 * @param array $params
317 * Parameter overrides, must include custom_group_id.
321 protected function createMultiStateCustomField($params = []) {
322 $params = array_merge($this->getFieldsValuesByType('StateProvince', 'Multi-Select State/Province'), $params);
323 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
327 * Create a custom text fields.
329 * @param array $params
330 * Parameter overrides, must include custom_group_id.
334 protected function createFileCustomField($params = []) {
335 $params = array_merge($this->getFieldsValuesByType('File'), $params);
336 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
340 * Create custom select field.
342 * @param array $params
343 * Parameter overrides, must include custom_group_id.
347 protected function createSelectCustomField(array $params): array {
348 $params = array_merge($this->getFieldsValuesByType('String', 'Select'), $params);
349 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
353 * Create custom select field.
355 * @param array $params
356 * Parameter overrides, must include custom_group_id.
360 protected function createAutoCompleteCustomField(array $params): array {
361 $params = array_merge($this->getFieldsValuesByType('String', 'Autocomplete-Select'), $params);
362 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
366 * Create a custom field of type date.
368 * @param array $params
372 protected function createDateCustomField($params): array {
373 $params = array_merge($this->getFieldsValuesByType('Date'), $params);
374 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
378 * Create a custom field of type radio with integer values.
380 * @param array $params
384 protected function createIntegerRadioCustomField($params): array {
385 $params = array_merge($this->getFieldsValuesByType('Int', 'Radio'), $params);
386 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
390 * Get default field values for the type of field.
393 * @param string $htmlType
397 public function getFieldsValuesByType($dataType, $htmlType = 'default') {
398 $values = $this->getAvailableFieldCombinations()[$dataType];
400 'is_searchable' => 1,
402 'default_value' => '',
404 ], array_merge($values['default'], $values[$htmlType])
409 * Get data available for custom fields.
411 * The 'default' key holds general values. Where more than one html type is an option
412 * then the any values that differ to the defaults are keyed by html key.
414 * The order below is consistent with the UI.
418 protected function getAvailableFieldCombinations() {
422 'label' => 'Enter text here',
423 'html_type' => 'Text',
424 'data_type' => 'String',
425 'default_value' => 'xyz',
426 'text_length' => 300,
429 'label' => 'Pick Color',
430 'html_type' => 'Select',
431 'data_type' => 'String',
433 'default_value' => '',
456 'label' => 'Pick Color',
457 'html_type' => 'Radio',
458 'data_type' => 'String',
460 'default_value' => '',
483 'label' => 'Pick Color',
484 'html_type' => 'CheckBox',
485 'data_type' => 'String',
487 'default_value' => '',
510 'label' => 'Pick Color',
511 'html_type' => 'Multi-Select',
512 'data_type' => 'String',
514 'default_value' => '',
536 'Autocomplete-Select' => [
537 'label' => 'Pick Color',
538 'html_type' => 'Autocomplete-Select',
539 'data_type' => 'String',
541 'default_value' => '',
566 'label' => 'Enter integer here',
567 'html_type' => 'Text',
568 'data_type' => 'Int',
569 'default_value' => '4',
570 'is_search_range' => 1,
573 'label' => 'Integer select',
574 'html_type' => 'Select',
591 'label' => 'Integer radio',
592 'html_type' => 'Radio',
607 'label' => 'Red Testing',
617 'name' => 'test_date',
618 'label' => 'Test Date',
619 'html_type' => 'Select Date',
620 'data_type' => 'Date',
621 'default_value' => '20090711',
623 'is_search_range' => 1,
630 'html_type' => 'Text',
631 'data_type' => 'Float',
634 'label' => 'Number select',
635 'html_type' => 'Select',
652 'label' => 'Number radio',
653 'html_type' => 'Radio',
673 'html_type' => 'Text',
674 'data_type' => 'Money',
677 'label' => 'Money select',
678 'html_type' => 'Select',
695 'label' => 'Money radio',
696 'html_type' => 'Radio',
716 'html_type' => 'TextArea',
717 'data_type' => 'Memo',
718 'attributes' => 'rows=4, cols=60',
720 'RichTextEditor' => [
721 'label' => 'Memo Rich Text Editor',
722 'html_type' => 'Memo',
727 'data_type' => 'Boolean',
728 'html_type' => 'Radio',
734 'data_type' => 'StateProvince',
735 'html_type' => 'Select State/Province',
739 'Multi-Select State/Province' => [
740 'html_type' => 'Multi-Select State/Province',
741 'label' => 'State-multi',
746 'data_type' => 'Country',
747 'html_type' => 'Select Country',
748 'label' => 'Country',
751 'Multi-Select Country' => [
752 'html_type' => 'Multi-Select Country',
753 'label' => 'Country-multi',
759 'label' => 'My file',
760 'data_type' => 'File',
761 'html_type' => 'File',
766 'name' => 'test_link',
767 'label' => 'test_link',
768 'html_type' => 'Link',
769 'data_type' => 'Link',
770 'default_value' => 'http://civicrm.org',
773 'ContactReference' => [
775 'label' => 'Contact reference field',
776 'html_type' => 'Autocomplete-Select',
777 'data_type' => 'ContactReference',