4 * Class CRM_Core_BAO_CustomFieldTest
8 class CRM_Core_BAO_CustomFieldTest
extends CiviUnitTestCase
{
10 use CRMTraits_Custom_CustomDataTrait
;
12 protected $customFieldID;
15 * Clean up after test.
19 public function tearDown() {
20 $this->quickCleanup([], TRUE);
25 * Test creating a custom field.
27 public function testCreateCustomField() {
28 $customGroup = $this->createCustomField();
29 $customFieldID = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
30 'Database check for created CustomField.'
33 'id' => $customFieldID,
34 'label' => 'editTestFld',
36 'data_type' => 'String',
37 'html_type' => 'Text',
38 'custom_group_id' => $customGroup['id'],
41 CRM_Core_BAO_CustomField
::create($fields);
42 $this->assertDBNotNull('CRM_Core_DAO_CustomField', 1, 'id', 'is_active', 'Database check for edited CustomField.');
43 $this->assertDBNotNull('CRM_Core_DAO_CustomField', $fields['label'], 'id', 'label', 'Database check for edited CustomField.');
45 $dbFieldName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'name', 'id', 'Database check for edited CustomField.');
46 $dbColumnName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'column_name', 'id', 'Database check for edited CustomField.');
47 $this->assertEquals(strtolower("{$dbFieldName}_{$customFieldID}"), $dbColumnName,
48 "Column name ends in ID");
50 $this->customGroupDelete($customGroup['id']);
54 * Test custom field create accepts passed column name.
56 public function testCreateCustomFieldColumnName() {
57 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
59 'label' => 'testFld 2',
60 'column_name' => 'special_colname',
61 'data_type' => 'String',
62 'html_type' => 'Text',
63 'custom_group_id' => $customGroup['id'],
65 CRM_Core_BAO_CustomField
::create($fields);
66 $customFieldID = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
67 'Database check for created CustomField.'
69 $dbColumnName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'column_name', 'id', 'Database check for edited CustomField.');
70 $this->assertEquals($fields['column_name'], $dbColumnName,
71 "Column name set as specified");
73 $this->customGroupDelete($customGroup['id']);
77 * Test that name is used for the column.
79 public function testCreateCustomFieldName() {
80 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
82 'label' => 'testFld 2',
83 'name' => 'special_fldlname',
84 'data_type' => 'String',
85 'html_type' => 'Text',
86 'custom_group_id' => $customGroup['id'],
88 CRM_Core_BAO_CustomField
::create($fields);
89 $customFieldID = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
90 'Database check for created CustomField.'
92 $dbFieldName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'name', 'id', 'Database check for edited CustomField.');
93 $this->assertEquals($fields['name'], $dbFieldName,
94 "Column name set as specified");
96 $this->customGroupDelete($customGroup['id']);
100 * Test get fields function.
102 public function testGetFields() {
103 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
105 'label' => 'testFld1',
106 'data_type' => 'String',
107 'html_type' => 'Text',
109 'custom_group_id' => $customGroup['id'],
111 CRM_Core_BAO_CustomField
::create($fields);
112 $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
113 'Database check for created CustomField.'
116 'label' => 'testFld2',
117 'data_type' => 'String',
118 'html_type' => 'Text',
120 'custom_group_id' => $customGroup['id'],
122 CRM_Core_BAO_CustomField
::create($fields);
123 $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
124 'Database check for created CustomField.'
127 $this->customGroupDelete($customGroup['id']);
133 public function testGetDisplayedValues() {
134 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
137 'data_type' => 'Country',
138 'html_type' => 'Select Country',
140 'United States' => 1228,
145 'data_type' => 'StateProvince',
146 'html_type' => 'Multi-Select State/Province',
150 'Alabama, Alaska' => [1000, 1001],
154 'data_type' => 'String',
155 'html_type' => 'Radio',
164 'data_type' => 'String',
165 'html_type' => 'CheckBox',
173 'Label1' => ['key1'],
175 'Label2, Label3' => ['key2', 'key3'],
176 'Label3, Label4' => CRM_Utils_Array
::implodePadded(['key3', 'key4']),
177 'Label1, Label4' => ['key1' => 1, 'key4' => 1],
181 'data_type' => 'Date',
182 'html_type' => 'Select Date',
183 'date_format' => 'd M yy',
186 '1 Jun 1999 1:30PM' => '1999-06-01 13:30',
191 foreach ($fieldsToCreate as $num => $field) {
192 $params = $field +
['label' => 'test field ' . $num, 'custom_group_id' => $customGroup['id']];
193 unset($params['tests']);
194 $createdField = $this->callAPISuccess('customField', 'create', $params);
195 foreach ($field['tests'] as $expected => $input) {
196 $this->assertEquals($expected, CRM_Core_BAO_CustomField
::displayValue($input, $createdField['id']));
200 $this->customGroupDelete($customGroup['id']);
204 * Test CRM_Core_BAO_CustomField::displayValue.
206 * @throws \CRM_Core_Exception
209 public function testGetDisplayedValuesContactRef() {
210 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
212 'data_type' => 'ContactReference',
213 'html_type' => 'Autocomplete-Select',
214 'label' => 'test ref',
215 'custom_group_id' => $customGroup['id'],
217 $createdField = $this->callAPISuccess('customField', 'create', $params);
218 $contact1 = $this->individualCreate();
219 $contact2 = $this->individualCreate(['custom_' . $createdField['id'] => $contact1['id']]);
221 $this->assertEquals($contact1['display_name'], CRM_Core_BAO_CustomField
::displayValue($contact2['id'], $createdField['id']));
222 $this->assertEquals("Bob", CRM_Core_BAO_CustomField
::displayValue("Bob", $createdField['id']));
224 $this->contactDelete($contact2['id']);
225 $this->contactDelete($contact1['id']);
226 $this->customGroupDelete($customGroup['id']);
229 public function testDeleteCustomField() {
230 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
232 'custom_group_id' => $customGroup['id'],
233 'label' => 'Throwaway Field',
234 'dataType' => 'Memo',
235 'htmlType' => 'TextArea',
238 $customField = $this->customFieldCreate($fields);
239 $fieldObject = new CRM_Core_BAO_CustomField();
240 $fieldObject->id
= $customField['id'];
241 $fieldObject->find(TRUE);
242 CRM_Core_BAO_CustomField
::deleteField($fieldObject);
243 $this->assertDBNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id',
244 'custom_group_id', 'Database check for deleted Custom Field.'
246 $this->customGroupDelete($customGroup['id']);
250 * Move a custom field from $groupA to $groupB.
252 * Make sure that data records are correctly matched and created.
254 * @throws \CRM_Core_Exception
256 public function testMoveField() {
257 $countriesByName = array_flip(CRM_Core_PseudoConstant
::country(FALSE, FALSE));
258 $this->assertTrue($countriesByName['Andorra'] > 0);
260 'A' => $this->customGroupCreate([
261 'title' => 'Test_Group A',
262 'name' => 'test_group_a',
263 'extends' => ['Individual'],
269 'B' => $this->customGroupCreate([
270 'title' => 'Test_Group B',
271 'name' => 'test_group_b',
272 'extends' => ['Individual'],
279 $groupA = $groups['A']['values'][$groups['A']['id']];
280 $groupB = $groups['B']['values'][$groups['B']['id']];
281 $countryA = $this->customFieldCreate([
282 'custom_group_id' => $groups['A']['id'],
283 'label' => 'Country A',
284 'dataType' => 'Country',
285 'htmlType' => 'Select Country',
286 'default_value' => NULL,
288 $countryB = $this->customFieldCreate([
289 'custom_group_id' => $groups['A']['id'],
290 'label' => 'Country B',
291 'dataType' => 'Country',
292 'htmlType' => 'Select Country',
293 'default_value' => NULL,
295 $countryC = $this->customFieldCreate([
296 'custom_group_id' => $groups['B']['id'],
297 'label' => 'Country C',
298 'dataType' => 'Country',
299 'htmlType' => 'Select Country',
300 'default_value' => NULL,
304 'countryA' => $countryA['values'][$countryA['id']],
305 'countryB' => $countryB['values'][$countryB['id']],
306 'countryC' => $countryC['values'][$countryC['id']],
309 'alice' => $this->individualCreate([
310 'first_name' => 'Alice',
311 'last_name' => 'Albertson',
312 'custom_' . $fields['countryA']['id'] => $countriesByName['Andorra'],
313 'custom_' . $fields['countryB']['id'] => $countriesByName['Barbados'],
315 'bob' => $this->individualCreate([
316 'first_name' => 'Bob',
317 'last_name' => 'Roberts',
318 'custom_' . $fields['countryA']['id'] => $countriesByName['Austria'],
319 'custom_' . $fields['countryB']['id'] => $countriesByName['Bermuda'],
320 'custom_' . $fields['countryC']['id'] => $countriesByName['Chad'],
322 'carol' => $this->individualCreate([
323 'first_name' => 'Carol',
324 'last_name' => 'Carolson',
325 'custom_' . $fields['countryC']['id'] => $countriesByName['Cambodia'],
330 CRM_Core_BAO_CustomField
::moveField($fields['countryB']['id'], $groupB['id']);
332 // Group[A] no longer has fields[countryB]
333 $errorScope = CRM_Core_TemporaryErrorScope
::useException();
335 $this->assertDBQuery(1, "SELECT {$fields['countryB']['column_name']} FROM " . $groupA['table_name']);
336 $this->fail('Expected exception when querying column on wrong table');
338 catch (PEAR_Exception
$e) {
342 // Alice: Group[B] has fields[countryB], but fields[countryC] did not exist before
343 $this->assertDBQuery(1,
344 "SELECT count(*) FROM {$groupB['table_name']}
346 AND {$fields['countryB']['column_name']} = %3
347 AND {$fields['countryC']['column_name']} is null",
349 1 => [$contacts['alice'], 'Integer'],
350 3 => [$countriesByName['Barbados'], 'Integer'],
354 // Bob: Group[B] has merged fields[countryB] and fields[countryC] on the same record
355 $this->assertDBQuery(1,
356 "SELECT count(*) FROM {$groupB['table_name']}
358 AND {$fields['countryB']['column_name']} = %3
359 AND {$fields['countryC']['column_name']} = %4",
361 1 => [$contacts['bob'], 'Integer'],
362 3 => [$countriesByName['Bermuda'], 'Integer'],
363 4 => [$countriesByName['Chad'], 'Integer'],
367 // Carol: Group[B] still has fields[countryC] but did not get fields[countryB]
368 $this->assertDBQuery(1,
369 "SELECT count(*) FROM {$groupB['table_name']}
371 AND {$fields['countryB']['column_name']} is null
372 AND {$fields['countryC']['column_name']} = %4",
374 1 => [$contacts['carol'], 'Integer'],
375 4 => [$countriesByName['Cambodia'], 'Integer'],
379 $this->customGroupDelete($groups['A']['id']);
380 $this->customGroupDelete($groupB['id']);
384 * Test get custom field id function.
386 * @throws \CiviCRM_API3_Exception
388 public function testGetCustomFieldID() {
389 $this->createCustomField();
390 $fieldID = CRM_Core_BAO_CustomField
::getCustomFieldID('testFld');
391 $this->assertEquals($this->customFieldID
, $fieldID);
393 $fieldID = CRM_Core_BAO_CustomField
::getCustomFieldID('testFld', 'new custom group');
394 $this->assertEquals($this->customFieldID
, $fieldID);
396 $fieldID = CRM_Core_BAO_CustomField
::getCustomFieldID('testFld', 'new custom group', TRUE);
397 $this->assertEquals('custom_' . $this->customFieldID
, $fieldID);
399 // create field with same name in a different group
400 $this->createCustomField('other custom group');
401 $otherFieldID = CRM_Core_BAO_CustomField
::getCustomFieldID('testFld', 'other custom group');
402 // make sure it does not return the field ID of the first field
403 $this->assertNotEquals($fieldID, $otherFieldID);
407 * Create a custom field
409 * @param string $groupTitle
413 protected function createCustomField($groupTitle = 'new custom group') {
414 $customGroup = $this->customGroupCreate([
415 'extends' => 'Individual',
416 'title' => $groupTitle,
419 'label' => 'testFld',
420 'data_type' => 'String',
421 'html_type' => 'Text',
422 'custom_group_id' => $customGroup['id'],
424 $field = CRM_Core_BAO_CustomField
::create($fields);
425 $this->customFieldID
= $field->id
;
430 * Test the getFieldsForImport function.
434 public function testGetFieldsForImport() {
435 $this->entity
= 'Contact';
436 $this->createCustomGroupWithFieldsOfAllTypes();
437 $customGroupID = $this->ids
['CustomGroup']['Custom Group'];
439 $this->getCustomFieldName('country') => [
440 'name' => $this->getCustomFieldName('country'),
442 'title' => 'Country',
443 'headerPattern' => '//',
445 'custom_field_id' => $this->getCustomFieldID('country'),
446 'options_per_line' => NULL,
447 'text_length' => NULL,
448 'data_type' => 'Country',
449 'html_type' => 'Select Country',
450 'is_search_range' => '0',
451 'id' => $this->getCustomFieldID('country'),
452 'label' => 'Country',
453 'groupTitle' => 'Custom Group',
454 'default_value' => NULL,
455 'custom_group_id' => $customGroupID,
456 'extends' => 'Contact',
457 'extends_entity_column_value' => NULL,
458 'extends_entity_column_id' => NULL,
460 'is_multiple' => '0',
461 'option_group_id' => NULL,
462 'date_format' => NULL,
463 'time_format' => NULL,
465 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
466 'column_name' => $this->getCustomFieldColumnName('country'),
467 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('country'),
468 'extends_table' => 'civicrm_contact',
469 'search_table' => 'contact_a',
471 'pseudoconstant' => [
472 'table' => 'civicrm_country',
474 'labelColumn' => 'name',
475 'nameColumn' => 'iso_code',
478 $this->getCustomFieldName('multi_country') => [
479 'name' => $this->getCustomFieldName('multi_country'),
481 'title' => 'Country-multi',
482 'headerPattern' => '//',
484 'custom_field_id' => $this->getCustomFieldID('multi_country'),
485 'options_per_line' => NULL,
486 'text_length' => NULL,
487 'data_type' => 'Country',
488 'html_type' => 'Select Country',
489 'is_search_range' => '0',
490 'id' => $this->getCustomFieldID('multi_country'),
491 'label' => 'Country-multi',
492 'groupTitle' => 'Custom Group',
493 'default_value' => NULL,
494 'custom_group_id' => $customGroupID,
495 'extends' => 'Contact',
496 'extends_entity_column_value' => NULL,
497 'extends_entity_column_id' => NULL,
499 'is_multiple' => '0',
500 'option_group_id' => NULL,
501 'date_format' => NULL,
502 'time_format' => NULL,
504 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
505 'column_name' => $this->getCustomFieldColumnName('multi_country'),
506 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('multi_country'),
507 'extends_table' => 'civicrm_contact',
508 'search_table' => 'contact_a',
510 'pseudoconstant' => [
511 'table' => 'civicrm_country',
513 'labelColumn' => 'name',
514 'nameColumn' => 'iso_code',
517 $this->getCustomFieldName('file') => [
518 'name' => $this->getCustomFieldName('file'),
520 'title' => 'My file',
521 'headerPattern' => '//',
523 'custom_field_id' => $this->getCustomFieldID('file'),
524 'options_per_line' => NULL,
525 'text_length' => NULL,
526 'data_type' => 'File',
527 'html_type' => 'File',
528 'is_search_range' => '0',
529 'id' => $this->getCustomFieldID('file'),
530 'label' => 'My file',
531 'groupTitle' => 'Custom Group',
532 'default_value' => NULL,
533 'custom_group_id' => $customGroupID,
534 'extends' => 'Contact',
535 'extends_entity_column_value' => NULL,
536 'extends_entity_column_id' => NULL,
538 'is_multiple' => '0',
539 'option_group_id' => NULL,
540 'date_format' => NULL,
541 'time_format' => NULL,
543 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
544 'column_name' => 'my_file_' . $this->getCustomFieldID('file'),
545 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.my_file_' . $this->getCustomFieldID('file'),
546 'extends_table' => 'civicrm_contact',
547 'search_table' => 'contact_a',
550 $this->getCustomFieldName('text') => [
551 'name' => $this->getCustomFieldName('text'),
553 'title' => 'Enter text here',
554 'headerPattern' => '//',
556 'custom_field_id' => $this->getCustomFieldID('text'),
557 'options_per_line' => NULL,
558 'text_length' => 300,
559 'data_type' => 'String',
560 'html_type' => 'Text',
561 'is_search_range' => '0',
562 'id' => $this->getCustomFieldID('text'),
563 'label' => 'Enter text here',
564 'groupTitle' => 'Custom Group',
565 'default_value' => 'xyz',
566 'custom_group_id' => '1',
567 'extends' => 'Contact',
568 'extends_entity_column_value' => NULL,
569 'extends_entity_column_id' => NULL,
571 'is_multiple' => '0',
572 'option_group_id' => NULL,
573 'date_format' => NULL,
574 'time_format' => NULL,
576 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
577 'column_name' => 'enter_text_here_' . $this->getCustomFieldID('text'),
578 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.enter_text_here_' . $this->getCustomFieldID('text'),
579 'extends_table' => 'civicrm_contact',
580 'search_table' => 'contact_a',
584 $this->getCustomFieldName('select_string') => [
585 'name' => $this->getCustomFieldName('select_string'),
587 'title' => 'Pick Color',
588 'headerPattern' => '//',
590 'custom_field_id' => $this->getCustomFieldID('select_string'),
591 'options_per_line' => NULL,
592 'text_length' => NULL,
593 'data_type' => 'String',
594 'html_type' => 'Select',
595 'is_search_range' => '0',
596 'id' => $this->getCustomFieldID('select_string'),
597 'label' => 'Pick Color',
598 'groupTitle' => 'Custom Group',
599 'default_value' => NULL,
600 'custom_group_id' => $customGroupID,
601 'extends' => 'Contact',
602 'extends_entity_column_value' => NULL,
603 'extends_entity_column_id' => NULL,
605 'is_multiple' => '0',
606 'option_group_id' => $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID('select_string'), 'return' => 'option_group_id']),
607 'date_format' => NULL,
608 'time_format' => NULL,
610 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
611 'column_name' => 'pick_color_' . $this->getCustomFieldID('select_string'),
612 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.pick_color_' . $this->getCustomFieldID('select_string'),
613 'extends_table' => 'civicrm_contact',
614 'search_table' => 'contact_a',
616 'pseudoconstant' => [
617 'optionGroupName' => $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID('select_string'), 'return' => 'option_group_id.name']),
618 'optionEditPath' => 'civicrm/admin/options/' . $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID('select_string'), 'return' => 'option_group_id.name']),
621 $this->getCustomFieldName('select_date') => [
622 'name' => $this->getCustomFieldName('select_date'),
624 'title' => 'Test Date',
625 'headerPattern' => '//',
627 'custom_field_id' => $this->getCustomFieldID('select_date'),
628 'options_per_line' => NULL,
629 'text_length' => NULL,
630 'data_type' => 'Date',
631 'html_type' => 'Select Date',
632 'is_search_range' => '1',
633 'date_format' => 'mm/dd/yy',
634 'time_format' => '1',
635 'id' => $this->getCustomFieldID('select_date'),
636 'label' => 'Test Date',
637 'groupTitle' => 'Custom Group',
638 'default_value' => '20090711',
639 'custom_group_id' => $customGroupID,
640 'extends' => 'Contact',
641 'extends_entity_column_value' => NULL,
642 'extends_entity_column_id' => NULL,
644 'is_multiple' => '0',
645 'option_group_id' => NULL,
646 'is_required' => '0',
647 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
648 'column_name' => 'test_date_' . $this->getCustomFieldID('select_date'),
649 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.test_date_' . $this->getCustomFieldID('select_date'),
650 'extends_table' => 'civicrm_contact',
651 'search_table' => 'contact_a',
654 $this->getCustomFieldName('link') => [
655 'name' => $this->getCustomFieldName('link'),
657 'title' => 'test_link',
658 'headerPattern' => '//',
660 'custom_field_id' => $this->getCustomFieldID('link'),
661 'options_per_line' => NULL,
662 'text_length' => NULL,
663 'data_type' => 'Link',
664 'html_type' => 'Link',
665 'is_search_range' => '0',
666 'id' => $this->getCustomFieldID('link'),
667 'label' => 'test_link',
668 'groupTitle' => 'Custom Group',
669 'default_value' => 'http://civicrm.org',
670 'custom_group_id' => $customGroupID,
671 'extends' => 'Contact',
672 'extends_entity_column_value' => NULL,
673 'extends_entity_column_id' => NULL,
675 'is_multiple' => '0',
676 'option_group_id' => NULL,
677 'date_format' => NULL,
678 'time_format' => NULL,
680 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
681 'column_name' => 'test_link_' . $this->getCustomFieldID('link'),
682 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.test_link_' . $this->getCustomFieldID('link'),
683 'extends_table' => 'civicrm_contact',
684 'search_table' => 'contact_a',
687 $this->getCustomFieldName('int') => [
688 'name' => $this->getCustomFieldName('int'),
689 'type' => CRM_Utils_Type
::T_INT
,
690 'title' => 'Enter integer here',
691 'headerPattern' => '//',
693 'custom_field_id' => $this->getCustomFieldID('int'),
694 'options_per_line' => NULL,
695 'text_length' => NULL,
696 'data_type' => 'Int',
697 'html_type' => 'Text',
698 'is_search_range' => '1',
699 'id' => $this->getCustomFieldID('int'),
700 'label' => 'Enter integer here',
701 'groupTitle' => 'Custom Group',
702 'default_value' => '4',
703 'custom_group_id' => $customGroupID,
704 'extends' => 'Contact',
705 'extends_entity_column_value' => NULL,
706 'extends_entity_column_id' => NULL,
708 'is_multiple' => '0',
709 'option_group_id' => NULL,
710 'date_format' => NULL,
711 'time_format' => NULL,
713 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
714 'column_name' => $this->getCustomFieldColumnName('int'),
715 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('int'),
716 'extends_table' => 'civicrm_contact',
717 'search_table' => 'contact_a',
720 $this->getCustomFieldName('contact_reference') => [
721 'name' => $this->getCustomFieldName('contact_reference'),
722 'type' => CRM_Utils_Type
::T_INT
,
723 'title' => 'Contact reference field',
724 'headerPattern' => '//',
726 'custom_field_id' => $this->getCustomFieldID('contact_reference'),
727 'options_per_line' => NULL,
728 'text_length' => NULL,
729 'data_type' => 'ContactReference',
730 'html_type' => 'Autocomplete-Select',
731 'is_search_range' => '0',
732 'id' => $this->getCustomFieldID('contact_reference'),
733 'label' => 'Contact reference field',
734 'groupTitle' => 'Custom Group',
735 'default_value' => NULL,
736 'custom_group_id' => $customGroupID,
737 'extends' => 'Contact',
738 'extends_entity_column_value' => NULL,
739 'extends_entity_column_id' => NULL,
741 'is_multiple' => '0',
742 'option_group_id' => NULL,
743 'date_format' => NULL,
744 'time_format' => NULL,
746 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
747 'column_name' => $this->getCustomFieldColumnName('contact_reference'),
748 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('contact_reference'),
749 'extends_table' => 'civicrm_contact',
750 'search_table' => 'contact_a',
753 $this->getCustomFieldName('state') => [
754 'name' => $this->getCustomFieldName('state'),
755 'id' => $this->getCustomFieldID('state'),
757 'headerPattern' => '//',
759 'custom_field_id' => $this->getCustomFieldID('state'),
760 'groupTitle' => 'Custom Group',
761 'default_value' => NULL,
762 'custom_group_id' => $customGroupID,
763 'extends' => 'Contact',
764 'extends_entity_column_value' => NULL,
765 'extends_entity_column_id' => NULL,
767 'is_multiple' => '0',
768 'option_group_id' => NULL,
769 'date_format' => NULL,
770 'time_format' => NULL,
772 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
773 'column_name' => $this->getCustomFieldColumnName('state'),
774 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('state'),
775 'extends_table' => 'civicrm_contact',
776 'search_table' => 'contact_a',
778 'pseudoconstant' => [
779 'table' => 'civicrm_state_province',
781 'labelColumn' => 'name',
784 'data_type' => 'StateProvince',
786 'html_type' => 'Select State/Province',
787 'text_length' => NULL,
788 'options_per_line' => NULL,
789 'is_search_range' => '0',
791 $this->getCustomFieldName('multi_state') => [
792 'id' => $this->getCustomFieldID('multi_state'),
793 'label' => 'State-multi',
794 'headerPattern' => '//',
795 'title' => 'State-multi',
796 'custom_field_id' => $this->getCustomFieldID('multi_state'),
797 'groupTitle' => 'Custom Group',
798 'default_value' => NULL,
799 'custom_group_id' => $customGroupID,
800 'extends' => 'Contact',
801 'extends_entity_column_value' => NULL,
802 'extends_entity_column_id' => NULL,
804 'is_multiple' => '0',
805 'option_group_id' => NULL,
806 'date_format' => NULL,
807 'time_format' => NULL,
809 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
810 'column_name' => $this->getCustomFieldColumnName('multi_state'),
811 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('multi_state'),
812 'extends_table' => 'civicrm_contact',
813 'search_table' => 'contact_a',
815 'pseudoconstant' => [
816 'table' => 'civicrm_state_province',
818 'labelColumn' => 'name',
821 'data_type' => 'StateProvince',
822 'name' => $this->getCustomFieldName('multi_state'),
824 'html_type' => 'Select State/Province',
825 'text_length' => NULL,
826 'options_per_line' => NULL,
827 'is_search_range' => '0',
829 $this->getCustomFieldName('boolean') => [
830 'id' => $this->getCustomFieldID('boolean'),
832 'headerPattern' => '//',
834 'custom_field_id' => $this->getCustomFieldID('boolean'),
835 'groupTitle' => 'Custom Group',
836 'default_value' => NULL,
837 'custom_group_id' => $customGroupID,
838 'extends' => 'Contact',
839 'extends_entity_column_value' => NULL,
840 'extends_entity_column_id' => NULL,
842 'is_multiple' => '0',
843 'option_group_id' => NULL,
844 'date_format' => NULL,
845 'time_format' => NULL,
847 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
848 'column_name' => $this->getCustomFieldColumnName('boolean'),
849 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('boolean'),
850 'extends_table' => 'civicrm_contact',
851 'search_table' => 'contact_a',
853 'data_type' => 'Boolean',
854 'name' => $this->getCustomFieldName('boolean'),
856 'html_type' => 'Radio',
857 'text_length' => NULL,
858 'options_per_line' => NULL,
859 'is_search_range' => '0',
861 'pseudoconstant' => [
862 'callback' => 'CRM_Core_SelectValues::boolean',
866 $this->assertEquals($expected, CRM_Core_BAO_CustomField
::getFieldsForImport());
870 * Test the bulk create function works.
872 public function testBulkCreate() {
873 $customGroup = $this->customGroupCreate([
874 'extends' => 'Individual',
875 'title' => 'my bulk group',
877 CRM_Core_BAO_CustomField
::bulkSave([
880 'data_type' => 'String',
881 'html_type' => 'Text',
882 'column_name' => 'my_text',
885 'label' => 'test_link',
886 'data_type' => 'Link',
887 'html_type' => 'Link',
888 'is_search_range' => '0',
892 'custom_group_id' => $customGroup['id'],
894 'is_searchable' => 1,
896 $dao = CRM_Core_DAO
::executeQuery(('SHOW CREATE TABLE ' . $customGroup['values'][$customGroup['id']]['table_name']));
898 $this->assertContains('`test_link_2` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL', $dao->Create_Table
);
899 $this->assertContains('KEY `INDEX_my_text` (`my_text`)', $dao->Create_Table
);
903 * Check that outputting the display value for a file field with No description doesn't generate error
905 public function testFileDisplayValueNoDescription() {
906 $customGroup = $this->customGroupCreate([
907 'extends' => 'Individual',
908 'title' => 'Test Contact File Custom Group',
910 $fileField = $this->customFieldCreate([
911 'custom_group_id' => $customGroup['id'],
912 'data_type' => 'File',
913 'html_type' => 'File',
914 'default_value' => '',
916 $filePath = Civi
::paths()->getPath('[civicrm.files]/custom/test_file.txt');
917 $file = $this->callAPISuccess('File', 'create', [
920 $individual = $this->individualCreate(['custom_' . $fileField['id'] => $file['id']]);
921 $expectedDisplayValue = CRM_Core_BAO_File
::paperIconAttachment('*', $file['id'])[$file['id']];
922 $this->assertEquals($expectedDisplayValue, CRM_Core_BAO_CustomField
::displayValue($file['id'], $fileField['id']));
926 * Test for hook_civicrm_alterCustomFieldDisplayValue().
928 public function testAlterCustomFieldDisplayValueHook() {
929 CRM_Utils_Hook_UnitTests
::singleton()->setHook('civicrm_alterCustomFieldDisplayValue', [$this, 'alterCustomFieldDisplayValue']);
930 $customGroupId = $this->customGroupCreate([
931 'extends' => 'Individual',
932 'title' => 'Test Contactcustom Group',
934 $fieldId = $this->customFieldCreate([
935 'custom_group_id' => $customGroupId,
936 'name' => 'alter_cf_field',
937 'label' => 'Alter CF Field',
939 $contactId = $this->individualCreate(['custom_' . $fieldId => 'Test']);
941 $this->assertEquals('Test', $this->callAPISuccessGetValue('Contact',
942 ['id' => $contactId, 'return' => "custom_{$fieldId}"]
947 'custom_' . $fieldId => $this->callAPISuccess('Contact', 'getfield', [
948 'name' => 'custom_' . $fieldId,
953 // CRM_Core_BAO_UFGroup::getValues() invokes CRM_Core_BAO_CustomField::displayValue() function.
954 CRM_Core_BAO_UFGroup
::getValues($contactId, $fields, $values);
955 $this->assertEquals('New value', $values['Alter CF Field']);
959 * @param string $displayValue
960 * @param mixed $value
961 * @param int $entityId
962 * @param array $fieldInfo
965 public function alterCustomFieldDisplayValue(&$displayValue, $value, $entityId, $fieldInfo) {
966 if ($fieldInfo['name'] == 'alter_cf_field') {
967 $displayValue = 'New value';