Merge pull request #17187 from alexymik/recur_contribution_source
[civicrm-core.git] / tests / phpunit / CRMTraits / Custom / CustomDataTrait.php
CommitLineData
8ba5884d 1<?php
2/*
3 +--------------------------------------------------------------------+
7d61e75f 4 | Copyright CiviCRM LLC. All rights reserved. |
8ba5884d 5 | |
7d61e75f
TO
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 |
8ba5884d 9 +--------------------------------------------------------------------+
10 */
11
cf66fb20 12use Civi\Api4\CustomGroup;
13
8ba5884d 14/**
15 * Trait Custom Data trait.
16 *
17 * Trait for setting up custom data in tests.
18 */
19trait CRMTraits_Custom_CustomDataTrait {
20
119664d6 21 /**
22 * Create a custom group with fields of multiple types.
23 *
24 * @param array $groupParams
cf66fb20 25 *
26 * @throws \API_Exception
27 * @throws \Civi\API\Exception\UnauthorizedException
119664d6 28 */
29 public function createCustomGroupWithFieldsOfAllTypes($groupParams = []) {
30 $this->createCustomGroup($groupParams);
31 $this->ids['CustomField'] = $this->createCustomFieldsOfAllTypes();
32 }
33
8ba5884d 34 /**
35 * Create a custom group.
36 *
37 * @param array $params
38 *
39 * @return int
cf66fb20 40 *
41 * @throws \API_Exception
42 * @throws \Civi\API\Exception\UnauthorizedException
8ba5884d 43 */
44 public function createCustomGroup($params = []) {
45 $params = array_merge([
46 'title' => 'Custom Group',
0e1544e7 47 'extends' => [$this->entity ?? 'Contact'],
8ba5884d 48 'weight' => 5,
49 'style' => 'Inline',
50 'max_multiple' => 0,
51 ], $params);
0e1544e7 52 $identifier = $params['name'] ?? $params['title'];
cf66fb20 53 $this->ids['CustomGroup'][$identifier] = CustomGroup::create()->setCheckPermissions(FALSE)->setValues($params)->execute()->first()['id'];
0e1544e7 54 return $this->ids['CustomGroup'][$identifier];
55 }
56
57 /**
58 * Get the table_name for the specified custom group.
59 *
60 * @param string $identifier
61 *
62 * @return string
63 */
64 public function getCustomGroupTable($identifier = 'Custom Group') {
65 return $this->callAPISuccessGetValue('CustomGroup', ['id' => $this->ids['CustomGroup'][$identifier], 'return' => 'table_name']);
66 }
67
68 /**
69 * Get the the column name for the identified custom field.
70 *
71 * @param string $key
72 * Identifier - generally keys map to data type - eg. 'text', 'int' etc.
73 *
74 * @return string
75 */
76 protected function getCustomFieldColumnName($key) {
77 return $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID($key), 'return' => 'column_name']);
8ba5884d 78 }
79
712ee28f 80 /**
81 * Create a custom group with a single field.
82 *
83 * @param array $groupParams
ca64c337 84 * Params for the group to be created.
712ee28f 85 * @param string $customFieldType
86 *
697aad03 87 * @param string $identifier
88 *
cf66fb20 89 * @throws \API_Exception
712ee28f 90 * @throws \CRM_Core_Exception
cf66fb20 91 * @throws \Civi\API\Exception\UnauthorizedException
712ee28f 92 */
0e1544e7 93 public function createCustomGroupWithFieldOfType($groupParams = [], $customFieldType = 'text', $identifier = NULL) {
ca64c337 94 $supported = ['text', 'select', 'date', 'int', 'contact_reference'];
0e1544e7 95 if (!in_array($customFieldType, $supported, TRUE)) {
712ee28f 96 throw new CRM_Core_Exception('we have not yet extracted other custom field types from createCustomFieldsOfAllTypes, Use consistent syntax when you do');
97 }
697aad03 98 $groupParams['title'] = empty($groupParams['title']) ? $identifier . 'Group with field ' . $customFieldType : $groupParams['title'];
0e1544e7 99 $groupParams['name'] = $identifier ?? 'Custom Group';
712ee28f 100 $this->createCustomGroup($groupParams);
ca64c337 101 $reference = &$this->ids['CustomField'][$identifier . $customFieldType];
102 $fieldParams = ['custom_group_id' => $this->ids['CustomGroup'][$groupParams['name']]];
2b81c27e 103 switch ($customFieldType) {
104 case 'text':
ca64c337 105 $reference = $this->createTextCustomField($fieldParams)['id'];
106 return;
2b81c27e 107
108 case 'select':
ca64c337 109 $reference = $this->createSelectCustomField($fieldParams)['id'];
110 return;
0e1544e7 111
112 case 'int':
ca64c337 113 $reference = $this->createIntCustomField($fieldParams)['id'];
114 return;
35aca6d6 115
116 case 'date':
ca64c337 117 $reference = $this->createDateCustomField($fieldParams)['id'];
118 return;
119
120 case 'contact_reference':
121 $reference = $this->createContactReferenceCustomField($fieldParams)['id'];
122 return;
2b81c27e 123 }
712ee28f 124 }
125
8ba5884d 126 /**
127 * @return array
128 */
129 public function createCustomFieldsOfAllTypes() {
130 $customGroupID = $this->ids['CustomGroup']['Custom Group'];
131 $ids = [];
79c9d4c2 132 $ids['text'] = (int) $this->createTextCustomField(['custom_group_id' => $customGroupID])['id'];
133 $ids['select_string'] = (int) $this->createSelectCustomField(['custom_group_id' => $customGroupID])['id'];
134 $ids['select_date'] = (int) $this->createDateCustomField(['custom_group_id' => $customGroupID])['id'];
135 $ids['int'] = (int) $this->createIntCustomField(['custom_group_id' => $customGroupID])['id'];
136 $ids['link'] = (int) $this->createLinkCustomField(['custom_group_id' => $customGroupID])['id'];
137 $ids['file'] = (int) $this->createFileCustomField(['custom_group_id' => $customGroupID])['id'];
138 $ids['country'] = (int) $this->createCountryCustomField(['custom_group_id' => $customGroupID])['id'];
ca64c337 139 $ids['multi_country'] = (int) $this->createMultiCountryCustomField(['custom_group_id' => $customGroupID])['id'];
79c9d4c2 140 $ids['contact_reference'] = $this->createContactReferenceCustomField(['custom_group_id' => $customGroupID])['id'];
ca64c337 141 $ids['state'] = (int) $this->createStateCustomField(['custom_group_id' => $customGroupID])['id'];
142 $ids['multi_state'] = (int) $this->createMultiStateCustomField(['custom_group_id' => $customGroupID])['id'];
143 $ids['boolean'] = (int) $this->createBooleanCustomField(['custom_group_id' => $customGroupID])['id'];
8ba5884d 144 return $ids;
145 }
146
119664d6 147 /**
148 * Get the custom field name for the relevant key.
149 *
150 * e.g returns 'custom_5' where 5 is the id of the field using the key.
151 *
152 * Generally keys map to data types.
153 *
154 * @param string $key
155 *
156 * @return string
157 */
158 protected function getCustomFieldName($key) {
0e1544e7 159 return 'custom_' . $this->getCustomFieldID($key);
8392a043 160 }
161
162 /**
163 * Get the custom field name for the relevant key.
164 *
165 * e.g returns 'custom_5' where 5 is the id of the field using the key.
166 *
167 * Generally keys map to data types.
168 *
169 * @param string $key
170 *
171 * @return string
172 */
173 protected function getCustomFieldID($key) {
0e1544e7 174 return $this->ids['CustomField'][$key];
175 }
176
177 /**
178 * Create a custom text fields.
179 *
180 * @param array $params
181 * Parameter overrides, must include custom_group_id.
182 *
183 * @return array
184 */
185 protected function createIntCustomField($params = []) {
79c9d4c2 186 $params = array_merge($this->getFieldsValuesByType('Int'), $params);
0e1544e7 187 return $this->callAPISuccess('CustomField', 'create', $params)['values'][0];
119664d6 188 }
189
ca64c337 190 /**
191 * Create a custom text fields.
192 *
193 * @param array $params
194 * Parameter overrides, must include custom_group_id.
195 *
196 * @return array
197 */
198 protected function createBooleanCustomField($params = []) {
199 $params = array_merge($this->getFieldsValuesByType('Boolean'), $params);
200 return $this->callAPISuccess('CustomField', 'create', $params)['values'][0];
201 }
202
79c9d4c2 203 /**
204 * Create a custom text fields.
205 *
206 * @param array $params
207 * Parameter overrides, must include custom_group_id.
208 *
209 * @return array
210 */
211 protected function createContactReferenceCustomField($params = []) {
212 $params = array_merge($this->getFieldsValuesByType('ContactReference'), $params);
213 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
214 }
215
712ee28f 216 /**
217 * Create a custom text fields.
218 *
219 * @param array $params
220 * Parameter overrides, must include custom_group_id.
221 *
222 * @return array
223 */
224 protected function createTextCustomField($params = []) {
79c9d4c2 225 $params = array_merge($this->getFieldsValuesByType('String'), $params);
226 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
227 }
712ee28f 228
79c9d4c2 229 /**
230 * Create a custom text fields.
231 *
232 * @param array $params
233 * Parameter overrides, must include custom_group_id.
234 *
235 * @return array
236 */
237 protected function createLinkCustomField($params = []) {
238 $params = array_merge($this->getFieldsValuesByType('Link'), $params);
239 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
712ee28f 240 }
241
2b81c27e 242 /**
ca64c337 243 * Create a custom country fields.
2b81c27e 244 *
245 * @param array $params
246 * Parameter overrides, must include custom_group_id.
247 *
248 * @return array
249 */
79c9d4c2 250 protected function createCountryCustomField($params = []) {
251 $params = array_merge($this->getFieldsValuesByType('Country'), $params);
252 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
253 }
2b81c27e 254
ca64c337 255 /**
256 * Create a custom multi select country fields.
257 *
258 * @param array $params
259 * Parameter overrides, must include custom_group_id.
260 *
261 * @return array
262 */
263 protected function createMultiCountryCustomField($params = []) {
264 $params = array_merge($this->getFieldsValuesByType('Country', 'Multi-Select Country'), $params);
265 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
266 }
267
268 /**
269 * Create a custom state fields.
270 *
271 * @param array $params
272 * Parameter overrides, must include custom_group_id.
273 *
274 * @return array
275 */
276 protected function createStateCustomField($params = []) {
277 $params = array_merge($this->getFieldsValuesByType('StateProvince'), $params);
278 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
279 }
280
281 /**
282 * Create a custom multi select state fields.
283 *
284 * @param array $params
285 * Parameter overrides, must include custom_group_id.
286 *
287 * @return array
288 */
289 protected function createMultiStateCustomField($params = []) {
290 $params = array_merge($this->getFieldsValuesByType('StateProvince', 'Multi-Select State/Province'), $params);
291 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
292 }
293
79c9d4c2 294 /**
295 * Create a custom text fields.
296 *
297 * @param array $params
298 * Parameter overrides, must include custom_group_id.
299 *
300 * @return array
301 */
302 protected function createFileCustomField($params = []) {
303 $params = array_merge($this->getFieldsValuesByType('File'), $params);
304 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
305 }
2b81c27e 306
79c9d4c2 307 /**
308 * Create custom select field.
309 *
310 * @param array $params
311 * Parameter overrides, must include custom_group_id.
312 *
313 * @return array
314 */
315 protected function createSelectCustomField(array $params): array {
316 $params = array_merge($this->getFieldsValuesByType('String', 'Select'), $params);
317 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
2b81c27e 318 }
319
35aca6d6 320 /**
321 * Create a custom field of type date.
322 *
323 * @param array $params
324 *
325 * @return array
326 */
327 protected function createDateCustomField($params): array {
79c9d4c2 328 $params = array_merge($this->getFieldsValuesByType('Date'), $params);
329 return $this->callAPISuccess('custom_field', 'create', $params)['values'][0];
330 }
331
332 /**
333 * Get default field values for the type of field.
334 *
335 * @param $dataType
336 * @param string $htmlType
337 *
338 * @return mixed
339 */
340 public function getFieldsValuesByType($dataType, $htmlType = 'default') {
341 $values = $this->getAvailableFieldCombinations()[$dataType];
342 return array_merge([
0e1544e7 343 'is_searchable' => 1,
79c9d4c2 344 'sequential' => 1,
345 'default_value' => '',
346 'is_required' => 0,
347 ], array_merge($values['default'], $values[$htmlType])
348 );
349 }
35aca6d6 350
79c9d4c2 351 /**
352 * Get data available for custom fields.
353 *
354 * The 'default' key holds general values. Where more than one html type is an option
355 * then the any values that differ to the defaults are keyed by html key.
356 *
357 * The order below is consistent with the UI.
358 *
359 * @return array
360 */
361 protected function getAvailableFieldCombinations() {
362 return [
363 'String' => [
364 'default' => [
365 'label' => 'Enter text here',
366 'html_type' => 'Text',
367 'data_type' => 'String',
368 'default_value' => 'xyz',
369 'text_length' => 300,
370 ],
371 'Select' => [
372 'label' => 'Pick Color',
373 'html_type' => 'Select',
374 'data_type' => 'String',
375 'text_length' => '',
376 'default_value' => '',
377 'option_values' => [
378 [
379 'label' => 'Red',
380 'value' => 'R',
381 'weight' => 1,
382 'is_active' => 1,
383 ],
384 [
385 'label' => 'Yellow',
386 'value' => 'Y',
387 'weight' => 2,
388 'is_active' => 1,
389 ],
390 [
391 'label' => 'Green',
392 'value' => 'G',
393 'weight' => 3,
394 'is_active' => 1,
395 ],
396 ],
397 ],
ca64c337 398 'Radio' => [
399 'label' => 'Pick Color',
400 'html_type' => 'Radio',
401 'data_type' => 'String',
402 'text_length' => '',
403 'default_value' => '',
404 'option_values' => [
405 [
406 'label' => 'Red',
407 'value' => 'R',
408 'weight' => 1,
409 'is_active' => 1,
410 ],
411 [
412 'label' => 'Yellow',
413 'value' => 'Y',
414 'weight' => 2,
415 'is_active' => 1,
416 ],
417 [
418 'label' => 'Green',
419 'value' => 'G',
420 'weight' => 3,
421 'is_active' => 1,
422 ],
423 ],
424 ],
425 'CheckBox' => [
426 'label' => 'Pick Color',
427 'html_type' => 'Checkbox',
428 'data_type' => 'String',
429 'text_length' => '',
430 'default_value' => '',
431 'option_values' => [
432 [
433 'label' => 'Red',
434 'value' => 'R',
435 'weight' => 1,
436 'is_active' => 1,
437 ],
438 [
439 'label' => 'Yellow',
440 'value' => 'Y',
441 'weight' => 2,
442 'is_active' => 1,
443 ],
444 [
445 'label' => 'Green',
446 'value' => 'G',
447 'weight' => 3,
448 'is_active' => 1,
449 ],
450 ],
451 ],
452 'Multi-Select' => [
453 'label' => 'Pick Color',
454 'html_type' => 'Multi-Select',
455 'data_type' => 'String',
456 'text_length' => '',
457 'default_value' => '',
458 'option_values' => [
459 [
460 'label' => 'Red',
461 'value' => 'R',
462 'weight' => 1,
463 'is_active' => 1,
464 ],
465 [
466 'label' => 'Yellow',
467 'value' => 'Y',
468 'weight' => 2,
469 'is_active' => 1,
470 ],
471 [
472 'label' => 'Green',
473 'value' => 'G',
474 'weight' => 3,
475 'is_active' => 1,
476 ],
477 ],
478 ],
479 'Autocomplete-Select' => [
480 'label' => 'Pick Color',
481 'html_type' => 'Autocomplete-Select',
482 'data_type' => 'String',
483 'text_length' => '',
484 'default_value' => '',
485 'option_values' => [
486 [
487 'label' => 'Red',
488 'value' => 'R',
489 'weight' => 1,
490 'is_active' => 1,
491 ],
492 [
493 'label' => 'Yellow',
494 'value' => 'Y',
495 'weight' => 2,
496 'is_active' => 1,
497 ],
498 [
499 'label' => 'Green',
500 'value' => 'G',
501 'weight' => 3,
502 'is_active' => 1,
503 ],
504 ],
505 ],
79c9d4c2 506 ],
507 'Int' => [
508 'default' => [
509 'label' => 'Enter integer here',
510 'html_type' => 'Text',
511 'data_type' => 'Int',
512 'default_value' => '4',
513 'is_search_range' => 1,
514 ],
ca64c337 515 'Select' => [
516 'label' => 'Integer select',
517 'html_type' => 'Select',
518 'option_values' => [
519 [
520 'label' => '50',
521 'value' => 3,
522 'weight' => 1,
523 'is_active' => 1,
524 ],
525 [
526 'label' => '100',
527 'value' => 4,
528 'weight' => 2,
529 'is_active' => 1,
530 ],
531 ],
532 ],
533 'Radio' => [
534 'label' => 'Integer radio',
535 'html_type' => 'Radio',
536 'option_values' => [
537 [
538 'label' => '50',
539 'value' => 3,
540 'weight' => 1,
541 'is_active' => 1,
542 ],
543 [
544 'label' => '100',
545 'value' => 4,
546 'weight' => 2,
547 'is_active' => 1,
548 ],
549 ],
550 ],
79c9d4c2 551 ],
552 'Date' => [
553 'default' => [
554 'name' => 'test_date',
555 'label' => 'Test Date',
556 'html_type' => 'Select Date',
557 'data_type' => 'Date',
558 'default_value' => '20090711',
559 'weight' => 3,
560 'is_search_range' => 1,
561 'time_format' => 1,
562 ],
563 ],
ca64c337 564 'Float' => [
565 'default' => [
566 'label' => 'Number',
567 'html_type' => 'Text',
568 'data_type' => 'Float',
569 ],
570 'Select' => [
571 'label' => 'Number select',
572 'html_type' => 'Select',
573 'option_values' => [
574 [
575 'label' => '50',
576 'value' => 3,
577 'weight' => 1,
578 'is_active' => 1,
579 ],
580 [
581 'label' => '100',
582 'value' => 4,
583 'weight' => 2,
584 'is_active' => 1,
585 ],
586 ],
587 ],
588 'Radio' => [
589 'label' => 'Number radio',
590 'html_type' => 'Radio',
591 'option_values' => [
592 [
593 'label' => '50',
594 'value' => 3,
595 'weight' => 1,
596 'is_active' => 1,
597 ],
598 [
599 'label' => '100',
600 'value' => 4,
601 'weight' => 2,
602 'is_active' => 1,
603 ],
604 ],
605 ],
606 ],
607 'Money' => [
608 'default' => [
609 'label' => 'Money',
610 'html_type' => 'Text',
611 'data_type' => 'Money',
612 ],
613 'Select' => [
614 'label' => 'Money select',
615 'html_type' => 'Select',
616 'option_values' => [
617 [
618 'label' => '50',
619 'value' => 3,
620 'weight' => 1,
621 'is_active' => 1,
622 ],
623 [
624 'label' => '100',
625 'value' => 4,
626 'weight' => 2,
627 'is_active' => 1,
628 ],
629 ],
630 ],
631 'Radio' => [
632 'label' => 'Money radio',
633 'html_type' => 'Radio',
634 'option_values' => [
635 [
636 'label' => '50',
637 'value' => 3,
638 'weight' => 1,
639 'is_active' => 1,
640 ],
641 [
642 'label' => '100',
643 'value' => 4,
644 'weight' => 2,
645 'is_active' => 1,
646 ],
647 ],
648 ],
649 ],
650 'Memo' => [
651 'default' => [
652 'label' => 'Memo',
653 'html_type' => 'TextArea',
654 'data_type' => 'Memo',
655 'attributes' => 'rows=4, cols=60',
656 ],
657 'RichTextEditor' => [
658 'label' => 'Memo Rich Text Editor',
659 'html_type' => 'Memo',
660 ],
661 ],
662 'Boolean' => [
663 'default' => [
664 'data_type' => 'Boolean',
665 'html_type' => 'Radio',
666 'label' => 'Yes No',
667 ],
668 ],
669 'StateProvince' => [
670 'default' => [
671 'data_type' => 'StateProvince',
672 'html_type' => 'Select State/Province',
673 'label' => 'State',
674 'option_type' => 0,
675 ],
676 'Multi-Select State/Province' => [
677 'html_type' => 'Multi-Select State/Province',
678 'label' => 'State-multi',
679 ],
680 ],
79c9d4c2 681 'Country' => [
682 'default' => [
683 'data_type' => 'Country',
684 'html_type' => 'Select Country',
685 'label' => 'Country',
686 'option_type' => 0,
687 ],
ca64c337 688 'Multi-Select Country' => [
689 'html_type' => 'Multi-Select Country',
690 'label' => 'Country-multi',
691 'option_type' => 0,
692 ],
79c9d4c2 693 ],
694 'File' => [
695 'default' => [
696 'label' => 'My file',
697 'data_type' => 'File',
698 'html_type' => 'File',
699 ],
700 ],
701 'Link' => [
702 'default' => [
703 'name' => 'test_link',
704 'label' => 'test_link',
705 'html_type' => 'Link',
706 'data_type' => 'Link',
707 'default_value' => 'http://civicrm.org',
708 ],
709 ],
710 'ContactReference' => [
711 'default' => [
712 'label' => 'Contact reference field',
713 'html_type' => 'Autocomplete-Select',
714 'data_type' => 'ContactReference',
715 ],
716 ],
717 ];
35aca6d6 718 }
719
8ba5884d 720}