4 * Class CRM_Core_BAO_CustomFieldTest
8 class CRM_Core_BAO_CustomFieldTest
extends CiviUnitTestCase
{
10 use CRMTraits_Custom_CustomDataTrait
;
12 protected $customFieldID;
14 public function setUp() {
19 * Clean up after test.
23 public function tearDown() {
24 $this->quickCleanup([], TRUE);
28 public function testCreateCustomField() {
29 $customGroup = $this->createCustomField();
30 $customFieldID = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
31 'Database check for created CustomField.'
34 'id' => $customFieldID,
35 'label' => 'editTestFld',
37 'data_type' => 'String',
38 'html_type' => 'Text',
39 'custom_group_id' => $customGroup['id'],
42 CRM_Core_BAO_CustomField
::create($fields);
43 $this->assertDBNotNull('CRM_Core_DAO_CustomField', 1, 'id', 'is_active', 'Database check for edited CustomField.');
44 $this->assertDBNotNull('CRM_Core_DAO_CustomField', $fields['label'], 'id', 'label', 'Database check for edited CustomField.');
46 $dbFieldName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'name', 'id', 'Database check for edited CustomField.');
47 $dbColumnName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'column_name', 'id', 'Database check for edited CustomField.');
48 $this->assertEquals(strtolower("{$dbFieldName}_{$customFieldID}"), $dbColumnName,
49 "Column name ends in ID");
51 $this->customGroupDelete($customGroup['id']);
54 public function testCreateCustomFieldColumnName() {
55 $customGroup = $this->customGroupCreate(array('extends' => 'Individual'));
57 'label' => 'testFld 2',
58 'column_name' => 'special_colname',
59 'data_type' => 'String',
60 'html_type' => 'Text',
61 'custom_group_id' => $customGroup['id'],
63 CRM_Core_BAO_CustomField
::create($fields);
64 $customFieldID = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
65 'Database check for created CustomField.'
67 $dbColumnName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'column_name', 'id', 'Database check for edited CustomField.');
68 $this->assertEquals($fields['column_name'], $dbColumnName,
69 "Column name set as specified");
71 $this->customGroupDelete($customGroup['id']);
74 public function testCreateCustomFieldName() {
75 $customGroup = $this->customGroupCreate(array('extends' => 'Individual'));
77 'label' => 'testFld 2',
78 'name' => 'special_fldlname',
79 'data_type' => 'String',
80 'html_type' => 'Text',
81 'custom_group_id' => $customGroup['id'],
83 CRM_Core_BAO_CustomField
::create($fields);
84 $customFieldID = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
85 'Database check for created CustomField.'
87 $dbFieldName = $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customFieldID, 'name', 'id', 'Database check for edited CustomField.');
88 $this->assertEquals($fields['name'], $dbFieldName,
89 "Column name set as specified");
91 $this->customGroupDelete($customGroup['id']);
94 public function testGetFields() {
95 $customGroup = $this->customGroupCreate(array('extends' => 'Individual'));
97 'label' => 'testFld1',
98 'data_type' => 'String',
99 'html_type' => 'Text',
101 'custom_group_id' => $customGroup['id'],
103 CRM_Core_BAO_CustomField
::create($fields);
104 $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
105 'Database check for created CustomField.'
108 'label' => 'testFld2',
109 'data_type' => 'String',
110 'html_type' => 'Text',
112 'custom_group_id' => $customGroup['id'],
114 CRM_Core_BAO_CustomField
::create($fields);
115 $this->assertDBNotNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id', 'custom_group_id',
116 'Database check for created CustomField.'
119 $this->customGroupDelete($customGroup['id']);
122 public function testGetDisplayedValues() {
123 $customGroup = $this->customGroupCreate(array('extends' => 'Individual'));
124 $fieldsToCreate = array(
126 'data_type' => 'Country',
127 'html_type' => 'Select Country',
129 'United States' => 1228,
134 'data_type' => 'StateProvince',
135 'html_type' => 'Multi-Select State/Province',
139 'Alabama, Alaska' => array(1000, 1001),
143 'data_type' => 'String',
144 'html_type' => 'Radio',
145 'option_values' => array(
153 'data_type' => 'String',
154 'html_type' => 'CheckBox',
155 'option_values' => array(
162 'Label1' => array('key1'),
164 'Label2, Label3' => array('key2', 'key3'),
165 'Label3, Label4' => CRM_Utils_Array
::implodePadded(array('key3', 'key4')),
166 'Label1, Label4' => array('key1' => 1, 'key4' => 1),
170 'data_type' => 'Date',
171 'html_type' => 'Select Date',
172 'date_format' => 'd M yy',
175 '1 Jun 1999 1:30PM' => '1999-06-01 13:30',
180 foreach ($fieldsToCreate as $num => $field) {
181 $params = $field +
array(
182 'label' => 'test field ' . $num,
183 'custom_group_id' => $customGroup['id'],
185 unset($params['tests']);
186 $createdField = $this->callAPISuccess('customField', 'create', $params);
187 foreach ($field['tests'] as $expected => $input) {
188 $this->assertEquals($expected, CRM_Core_BAO_CustomField
::displayValue($input, $createdField['id']));
192 $this->customGroupDelete($customGroup['id']);
195 public function testGetDisplayedValuesContactRef() {
196 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
198 'data_type' => 'ContactReference',
199 'html_type' => 'Autocomplete-Select',
200 'label' => 'test ref',
201 'custom_group_id' => $customGroup['id'],
203 $createdField = $this->callAPISuccess('customField', 'create', $params);
204 $contact1 = $this->individualCreate();
205 $contact2 = $this->individualCreate(['custom_' . $createdField['id'] => $contact1['id']]);
207 $this->assertEquals($contact1['display_name'], CRM_Core_BAO_CustomField
::displayValue($contact2['id'], $createdField['id']));
208 $this->assertEquals("Bob", CRM_Core_BAO_CustomField
::displayValue("Bob", $createdField['id']));
210 $this->contactDelete($contact2['id']);
211 $this->contactDelete($contact1['id']);
212 $this->customGroupDelete($customGroup['id']);
215 public function testDeleteCustomField() {
216 $customGroup = $this->customGroupCreate(array('extends' => 'Individual'));
218 'custom_group_id' => $customGroup['id'],
219 'label' => 'Throwaway Field',
220 'dataType' => 'Memo',
221 'htmlType' => 'TextArea',
224 $customField = $this->customFieldCreate($fields);
225 $fieldObject = new CRM_Core_BAO_CustomField();
226 $fieldObject->id
= $customField['id'];
227 $fieldObject->find(TRUE);
228 CRM_Core_BAO_CustomField
::deleteField($fieldObject);
229 $this->assertDBNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id',
230 'custom_group_id', 'Database check for deleted Custom Field.'
232 $this->customGroupDelete($customGroup['id']);
236 * Move a custom field from $groupA to $groupB.
238 * Make sure that data records are correctly matched and created.
240 public function testMoveField() {
241 $countriesByName = array_flip(CRM_Core_PseudoConstant
::country(FALSE, FALSE));
242 $this->assertTrue($countriesByName['Andorra'] > 0);
244 'A' => $this->customGroupCreate(array(
245 'title' => 'Test_Group A',
246 'name' => 'test_group_a',
247 'extends' => array('Individual'),
253 'B' => $this->customGroupCreate(array(
254 'title' => 'Test_Group B',
255 'name' => 'test_group_b',
256 'extends' => array('Individual'),
263 $groupA = $groups['A']['values'][$groups['A']['id']];
264 $groupB = $groups['B']['values'][$groups['B']['id']];
265 $countryA = $this->customFieldCreate(array(
266 'custom_group_id' => $groups['A']['id'],
267 'label' => 'Country A',
268 'dataType' => 'Country',
269 'htmlType' => 'Select Country',
270 'default_value' => NULL,
272 $countryB = $this->customFieldCreate(array(
273 'custom_group_id' => $groups['A']['id'],
274 'label' => 'Country B',
275 'dataType' => 'Country',
276 'htmlType' => 'Select Country',
277 'default_value' => NULL,
279 $countryC = $this->customFieldCreate(array(
280 'custom_group_id' => $groups['B']['id'],
281 'label' => 'Country C',
282 'dataType' => 'Country',
283 'htmlType' => 'Select Country',
284 'default_value' => NULL,
288 'countryA' => $countryA['values'][$countryA['id']],
289 'countryB' => $countryB['values'][$countryB['id']],
290 'countryC' => $countryC['values'][$countryC['id']],
293 'alice' => $this->individualCreate(array(
294 'first_name' => 'Alice',
295 'last_name' => 'Albertson',
296 'custom_' . $fields['countryA']['id'] => $countriesByName['Andorra'],
297 'custom_' . $fields['countryB']['id'] => $countriesByName['Barbados'],
299 'bob' => $this->individualCreate(array(
300 'first_name' => 'Bob',
301 'last_name' => 'Roberts',
302 'custom_' . $fields['countryA']['id'] => $countriesByName['Austria'],
303 'custom_' . $fields['countryB']['id'] => $countriesByName['Bermuda'],
304 'custom_' . $fields['countryC']['id'] => $countriesByName['Chad'],
306 'carol' => $this->individualCreate(array(
307 'first_name' => 'Carol',
308 'last_name' => 'Carolson',
309 'custom_' . $fields['countryC']['id'] => $countriesByName['Cambodia'],
314 CRM_Core_BAO_CustomField
::moveField($fields['countryB']['id'], $groupB['id']);
316 // Group[A] no longer has fields[countryB]
317 $errorScope = CRM_Core_TemporaryErrorScope
::useException();
319 $this->assertDBQuery(1, "SELECT {$fields['countryB']['column_name']} FROM " . $groupA['table_name']);
320 $this->fail('Expected exception when querying column on wrong table');
322 catch (PEAR_Exception
$e) {
326 // Alice: Group[B] has fields[countryB], but fields[countryC] did not exist before
327 $this->assertDBQuery(1,
328 "SELECT count(*) FROM {$groupB['table_name']}
330 AND {$fields['countryB']['column_name']} = %3
331 AND {$fields['countryC']['column_name']} is null",
333 1 => array($contacts['alice'], 'Integer'),
334 3 => array($countriesByName['Barbados'], 'Integer'),
338 // Bob: Group[B] has merged fields[countryB] and fields[countryC] on the same record
339 $this->assertDBQuery(1,
340 "SELECT count(*) FROM {$groupB['table_name']}
342 AND {$fields['countryB']['column_name']} = %3
343 AND {$fields['countryC']['column_name']} = %4",
345 1 => array($contacts['bob'], 'Integer'),
346 3 => array($countriesByName['Bermuda'], 'Integer'),
347 4 => array($countriesByName['Chad'], 'Integer'),
351 // Carol: Group[B] still has fields[countryC] but did not get fields[countryB]
352 $this->assertDBQuery(1,
353 "SELECT count(*) FROM {$groupB['table_name']}
355 AND {$fields['countryB']['column_name']} is null
356 AND {$fields['countryC']['column_name']} = %4",
358 1 => array($contacts['carol'], 'Integer'),
359 4 => array($countriesByName['Cambodia'], 'Integer'),
363 $this->customGroupDelete($groups['A']['id']);
364 $this->customGroupDelete($groupB['id']);
368 * Test get custom field id function.
370 * @throws \CiviCRM_API3_Exception
372 public function testGetCustomFieldID() {
373 $this->createCustomField();
374 $fieldID = CRM_Core_BAO_CustomField
::getCustomFieldID('testFld');
375 $this->assertEquals($this->customFieldID
, $fieldID);
377 $fieldID = CRM_Core_BAO_CustomField
::getCustomFieldID('testFld', 'new custom group');
378 $this->assertEquals($this->customFieldID
, $fieldID);
380 $fieldID = CRM_Core_BAO_CustomField
::getCustomFieldID('testFld', 'new custom group', TRUE);
381 $this->assertEquals('custom_' . $this->customFieldID
, $fieldID);
383 // create field with same name in a different group
384 $this->createCustomField('other custom group');
385 $otherFieldID = CRM_Core_BAO_CustomField
::getCustomFieldID('testFld', 'other custom group');
386 // make sure it does not return the field ID of the first field
387 $this->assertNotEquals($fieldID, $otherFieldID);
391 * Create a custom field
393 * @param string $groupTitle
397 protected function createCustomField($groupTitle = 'new custom group') {
398 $customGroup = $this->customGroupCreate([
399 'extends' => 'Individual',
400 'title' => $groupTitle,
403 'label' => 'testFld',
404 'data_type' => 'String',
405 'html_type' => 'Text',
406 'custom_group_id' => $customGroup['id'],
408 $field = CRM_Core_BAO_CustomField
::create($fields);
409 $this->customFieldID
= $field->id
;
414 * Test the getFieldsForImport function.
418 public function testGetFieldsForImport() {
419 $this->entity
= 'Contact';
420 $this->createCustomGroupWithFieldsOfAllTypes();
421 $customGroupID = $this->ids
['CustomGroup']['Custom Group'];
423 $this->getCustomFieldName('country') => [
424 'name' => $this->getCustomFieldName('country'),
426 'title' => 'Country',
427 'headerPattern' => '//',
429 'custom_field_id' => $this->getCustomFieldID('country'),
430 'options_per_line' => NULL,
431 'text_length' => NULL,
432 'data_type' => 'Int',
433 'html_type' => 'Select Country',
434 'is_search_range' => '0',
435 'id' => $this->getCustomFieldID('country'),
436 'label' => 'Country',
437 'groupTitle' => 'Custom Group',
438 'default_value' => NULL,
439 'custom_group_id' => $customGroupID,
440 'extends' => 'Contact',
441 'extends_entity_column_value' => NULL,
442 'extends_entity_column_id' => NULL,
444 'is_multiple' => '0',
445 'option_group_id' => NULL,
446 'date_format' => NULL,
447 'time_format' => NULL,
448 'is_required' => '0',
449 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
450 'column_name' => 'country_' . $this->getCustomFieldID('country'),
451 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.country_' . $this->getCustomFieldID('country'),
452 'extends_table' => 'civicrm_contact',
453 'search_table' => 'contact_a',
455 $this->getCustomFieldName('file') => [
456 'name' => $this->getCustomFieldName('file'),
458 'title' => 'Custom Field',
459 'headerPattern' => '//',
461 'custom_field_id' => $this->getCustomFieldID('file'),
462 'options_per_line' => NULL,
463 'text_length' => NULL,
464 'data_type' => 'File',
465 'html_type' => 'File',
466 'is_search_range' => '0',
467 'id' => $this->getCustomFieldID('file'),
468 'label' => 'Custom Field',
469 'groupTitle' => 'Custom Group',
470 'default_value' => NULL,
471 'custom_group_id' => $customGroupID,
472 'extends' => 'Contact',
473 'extends_entity_column_value' => NULL,
474 'extends_entity_column_id' => NULL,
476 'is_multiple' => '0',
477 'option_group_id' => NULL,
478 'date_format' => NULL,
479 'time_format' => NULL,
480 'is_required' => '0',
481 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
482 'column_name' => 'custom_field_' . $this->getCustomFieldID('file'),
483 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.custom_field_' . $this->getCustomFieldID('file'),
484 'extends_table' => 'civicrm_contact',
485 'search_table' => 'contact_a',
487 $this->getCustomFieldName('text') => [
488 'name' => $this->getCustomFieldName('text'),
490 'title' => 'Enter text here',
491 'headerPattern' => '//',
493 'custom_field_id' => $this->getCustomFieldID('text'),
494 'options_per_line' => NULL,
495 'text_length' => NULL,
496 'data_type' => 'String',
497 'html_type' => 'Text',
498 'is_search_range' => '0',
499 'id' => $this->getCustomFieldID('text'),
500 'label' => 'Enter text here',
501 'groupTitle' => 'Custom Group',
502 'default_value' => 'xyz',
503 'custom_group_id' => '1',
504 'extends' => 'Contact',
505 'extends_entity_column_value' => NULL,
506 'extends_entity_column_id' => NULL,
508 'is_multiple' => '0',
509 'option_group_id' => NULL,
510 'date_format' => NULL,
511 'time_format' => NULL,
512 'is_required' => '1',
513 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
514 'column_name' => 'enter_text_here_' . $this->getCustomFieldID('text'),
515 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.enter_text_here_' . $this->getCustomFieldID('text'),
516 'extends_table' => 'civicrm_contact',
517 'search_table' => 'contact_a',
519 $this->getCustomFieldName('select_string') => [
520 'name' => $this->getCustomFieldName('select_string'),
522 'title' => 'Pick Color',
523 'headerPattern' => '//',
525 'custom_field_id' => $this->getCustomFieldID('select_string'),
526 'options_per_line' => NULL,
527 'text_length' => NULL,
528 'data_type' => 'String',
529 'html_type' => 'Select',
530 'is_search_range' => '0',
531 'id' => $this->getCustomFieldID('select_string'),
532 'label' => 'Pick Color',
533 'groupTitle' => 'Custom Group',
534 'default_value' => NULL,
535 'custom_group_id' => $customGroupID,
536 'extends' => 'Contact',
537 'extends_entity_column_value' => NULL,
538 'extends_entity_column_id' => NULL,
540 'is_multiple' => '0',
541 'option_group_id' => $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID('select_string'), 'return' => 'option_group_id']),
542 'date_format' => NULL,
543 'time_format' => NULL,
544 'is_required' => '1',
545 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
546 'column_name' => 'pick_color_' . $this->getCustomFieldID('select_string'),
547 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.pick_color_' . $this->getCustomFieldID('select_string'),
548 'extends_table' => 'civicrm_contact',
549 'search_table' => 'contact_a',
550 'pseudoconstant' => [
551 'optionGroupName' => $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID('select_string'), 'return' => 'option_group_id.name']),
552 'optionEditPath' => 'civicrm/admin/options/' . $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID('select_string'), 'return' => 'option_group_id.name']),
555 $this->getCustomFieldName('select_date') => [
556 'name' => $this->getCustomFieldName('select_date'),
558 'title' => 'test_date',
559 'headerPattern' => '//',
561 'custom_field_id' => $this->getCustomFieldID('select_date'),
562 'options_per_line' => NULL,
563 'text_length' => NULL,
564 'data_type' => 'Date',
565 'html_type' => 'Select Date',
566 'is_search_range' => '0',
567 'date_format' => 'mm/dd/yy',
568 'time_format' => '1',
569 'id' => $this->getCustomFieldID('select_date'),
570 'label' => 'test_date',
571 'groupTitle' => 'Custom Group',
572 'default_value' => '20090711',
573 'custom_group_id' => $customGroupID,
574 'extends' => 'Contact',
575 'extends_entity_column_value' => NULL,
576 'extends_entity_column_id' => NULL,
578 'is_multiple' => '0',
579 'option_group_id' => NULL,
580 'is_required' => '0',
581 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
582 'column_name' => 'test_date_' . $this->getCustomFieldID('select_date'),
583 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.test_date_' . $this->getCustomFieldID('select_date'),
584 'extends_table' => 'civicrm_contact',
585 'search_table' => 'contact_a',
587 $this->getCustomFieldName('link') => [
588 'name' => $this->getCustomFieldName('link'),
590 'title' => 'test_link',
591 'headerPattern' => '//',
593 'custom_field_id' => $this->getCustomFieldID('link'),
594 'options_per_line' => NULL,
595 'text_length' => NULL,
596 'data_type' => 'Link',
597 'html_type' => 'Link',
598 'is_search_range' => '0',
599 'id' => $this->getCustomFieldID('link'),
600 'label' => 'test_link',
601 'groupTitle' => 'Custom Group',
602 'default_value' => 'http://civicrm.org',
603 'custom_group_id' => $customGroupID,
604 'extends' => 'Contact',
605 'extends_entity_column_value' => NULL,
606 'extends_entity_column_id' => NULL,
608 'is_multiple' => '0',
609 'option_group_id' => NULL,
610 'date_format' => NULL,
611 'time_format' => NULL,
612 'is_required' => '1',
613 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
614 'column_name' => 'test_link_' . $this->getCustomFieldID('link'),
615 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.test_link_' . $this->getCustomFieldID('link'),
616 'extends_table' => 'civicrm_contact',
617 'search_table' => 'contact_a',
620 $this->assertEquals($expected, CRM_Core_BAO_CustomField
::getFieldsForImport());