Merge pull request #17008 from ivan-compucorp/CPS-70-fix-radio-value
[civicrm-core.git] / tests / phpunit / CRM / Core / BAO / CustomFieldTest.php
1 <?php
2
3 /**
4 * Class CRM_Core_BAO_CustomFieldTest
5 *
6 * @group headless
7 */
8 class CRM_Core_BAO_CustomFieldTest extends CiviUnitTestCase {
9
10 use CRMTraits_Custom_CustomDataTrait;
11
12 protected $customFieldID;
13
14 /**
15 * Clean up after test.
16 *
17 * @throws \Exception
18 */
19 public function tearDown() {
20 $this->quickCleanup([], TRUE);
21 parent::tearDown();
22 }
23
24 /**
25 * Test creating a custom field.
26 */
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.'
31 );
32 $fields = [
33 'id' => $customFieldID,
34 'label' => 'editTestFld',
35 'is_active' => 1,
36 'data_type' => 'String',
37 'html_type' => 'Text',
38 'custom_group_id' => $customGroup['id'],
39 ];
40
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.');
44
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");
49
50 $this->customGroupDelete($customGroup['id']);
51 }
52
53 /**
54 * Test custom field create accepts passed column name.
55 */
56 public function testCreateCustomFieldColumnName() {
57 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
58 $fields = [
59 'label' => 'testFld 2',
60 'column_name' => 'special_colname',
61 'data_type' => 'String',
62 'html_type' => 'Text',
63 'custom_group_id' => $customGroup['id'],
64 ];
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.'
68 );
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");
72
73 $this->customGroupDelete($customGroup['id']);
74 }
75
76 /**
77 * Test that name is used for the column.
78 */
79 public function testCreateCustomFieldName() {
80 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
81 $fields = [
82 'label' => 'testFld 2',
83 'name' => 'special_fldlname',
84 'data_type' => 'String',
85 'html_type' => 'Text',
86 'custom_group_id' => $customGroup['id'],
87 ];
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.'
91 );
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");
95
96 $this->customGroupDelete($customGroup['id']);
97 }
98
99 /**
100 * Test get fields function.
101 */
102 public function testGetFields() {
103 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
104 $fields = [
105 'label' => 'testFld1',
106 'data_type' => 'String',
107 'html_type' => 'Text',
108 'is_active' => 1,
109 'custom_group_id' => $customGroup['id'],
110 ];
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.'
114 );
115 $fields = [
116 'label' => 'testFld2',
117 'data_type' => 'String',
118 'html_type' => 'Text',
119 'is_active' => 1,
120 'custom_group_id' => $customGroup['id'],
121 ];
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.'
125 );
126
127 $this->customGroupDelete($customGroup['id']);
128 }
129
130 /**
131 * @throws \Exception
132 */
133 public function testGetDisplayedValues() {
134 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
135 $fieldsToCreate = [
136 [
137 'data_type' => 'Country',
138 'html_type' => 'Select Country',
139 'tests' => [
140 'United States' => 1228,
141 '' => NULL,
142 ],
143 ],
144 [
145 'data_type' => 'StateProvince',
146 'html_type' => 'Multi-Select State/Province',
147 'tests' => [
148 '' => 0,
149 'Alabama' => 1000,
150 'Alabama, Alaska' => [1000, 1001],
151 ],
152 ],
153 [
154 'data_type' => 'String',
155 'html_type' => 'Radio',
156 'option_values' => [
157 'key' => 'KeyLabel',
158 ],
159 'tests' => [
160 'KeyLabel' => 'key',
161 ],
162 ],
163 [
164 'data_type' => 'String',
165 'html_type' => 'CheckBox',
166 'option_values' => [
167 'key1' => 'Label1',
168 'key2' => 'Label2',
169 'key3' => 'Label3',
170 'key4' => 'Label4',
171 ],
172 'tests' => [
173 'Label1' => ['key1'],
174 'Label2' => 'key2',
175 'Label2, Label3' => ['key2', 'key3'],
176 'Label3, Label4' => CRM_Utils_Array::implodePadded(['key3', 'key4']),
177 'Label1, Label4' => ['key1' => 1, 'key4' => 1],
178 ],
179 ],
180 [
181 'data_type' => 'Date',
182 'html_type' => 'Select Date',
183 'date_format' => 'd M yy',
184 'time_format' => 1,
185 'tests' => [
186 '1 Jun 1999 1:30PM' => '1999-06-01 13:30',
187 '' => '',
188 ],
189 ],
190 [
191 'data_type' => 'Money',
192 'html_type' => 'Radio',
193 'option_values' => [
194 '10' => '10 USD',
195 '10.1' => '10.1 USD',
196 '10.99' => '10.99 USD',
197 ],
198 'tests' => [
199 '10 USD' => '10.00',
200 '10.1 USD' => '10.10',
201 '10.99 USD' => '10.99',
202 ],
203 ],
204 ];
205 foreach ($fieldsToCreate as $num => $field) {
206 $params = $field + ['label' => 'test field ' . $num, 'custom_group_id' => $customGroup['id']];
207 unset($params['tests']);
208 $createdField = $this->callAPISuccess('customField', 'create', $params);
209 foreach ($field['tests'] as $expected => $input) {
210 $this->assertEquals($expected, CRM_Core_BAO_CustomField::displayValue($input, $createdField['id']));
211 }
212 }
213
214 $this->customGroupDelete($customGroup['id']);
215 }
216
217 /**
218 * Test CRM_Core_BAO_CustomField::displayValue.
219 *
220 * @throws \CRM_Core_Exception
221 * @throws \Exception
222 */
223 public function testGetDisplayedValuesContactRef() {
224 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
225 $params = [
226 'data_type' => 'ContactReference',
227 'html_type' => 'Autocomplete-Select',
228 'label' => 'test ref',
229 'custom_group_id' => $customGroup['id'],
230 ];
231 $createdField = $this->callAPISuccess('customField', 'create', $params);
232 $contact1 = $this->individualCreate();
233 $contact2 = $this->individualCreate(['custom_' . $createdField['id'] => $contact1]);
234 $contact1Details = $this->callAPISuccess('Contact', 'getsingle', ['id' => $contact1]);
235 $this->assertEquals($contact1Details['display_name'], CRM_Core_BAO_CustomField::displayValue($contact2, $createdField['id']));
236 $this->assertEquals("Bob", CRM_Core_BAO_CustomField::displayValue("Bob", $createdField['id']));
237
238 $this->contactDelete($contact2);
239 $this->contactDelete($contact1);
240 $this->customGroupDelete($customGroup['id']);
241 }
242
243 public function testDeleteCustomField() {
244 $customGroup = $this->customGroupCreate(['extends' => 'Individual']);
245 $fields = [
246 'custom_group_id' => $customGroup['id'],
247 'label' => 'Throwaway Field',
248 'dataType' => 'Memo',
249 'htmlType' => 'TextArea',
250 ];
251
252 $customField = $this->customFieldCreate($fields);
253 $fieldObject = new CRM_Core_BAO_CustomField();
254 $fieldObject->id = $customField['id'];
255 $fieldObject->find(TRUE);
256 CRM_Core_BAO_CustomField::deleteField($fieldObject);
257 $this->assertDBNull('CRM_Core_DAO_CustomField', $customGroup['id'], 'id',
258 'custom_group_id', 'Database check for deleted Custom Field.'
259 );
260 $this->customGroupDelete($customGroup['id']);
261 }
262
263 /**
264 * Move a custom field from $groupA to $groupB.
265 *
266 * Make sure that data records are correctly matched and created.
267 *
268 * @throws \CRM_Core_Exception
269 */
270 public function testMoveField() {
271 $countriesByName = array_flip(CRM_Core_PseudoConstant::country(FALSE, FALSE));
272 $this->assertTrue($countriesByName['Andorra'] > 0);
273 $groups = [
274 'A' => $this->customGroupCreate([
275 'title' => 'Test_Group A',
276 'name' => 'test_group_a',
277 'extends' => ['Individual'],
278 'style' => 'Inline',
279 'is_multiple' => 0,
280 'is_active' => 1,
281 'version' => 3,
282 ]),
283 'B' => $this->customGroupCreate([
284 'title' => 'Test_Group B',
285 'name' => 'test_group_b',
286 'extends' => ['Individual'],
287 'style' => 'Inline',
288 'is_multiple' => 0,
289 'is_active' => 1,
290 'version' => 3,
291 ]),
292 ];
293 $groupA = $groups['A']['values'][$groups['A']['id']];
294 $groupB = $groups['B']['values'][$groups['B']['id']];
295 $countryA = $this->customFieldCreate([
296 'custom_group_id' => $groups['A']['id'],
297 'label' => 'Country A',
298 'dataType' => 'Country',
299 'htmlType' => 'Select Country',
300 'default_value' => NULL,
301 ]);
302 $countryB = $this->customFieldCreate([
303 'custom_group_id' => $groups['A']['id'],
304 'label' => 'Country B',
305 'dataType' => 'Country',
306 'htmlType' => 'Select Country',
307 'default_value' => NULL,
308 ]);
309 $countryC = $this->customFieldCreate([
310 'custom_group_id' => $groups['B']['id'],
311 'label' => 'Country C',
312 'dataType' => 'Country',
313 'htmlType' => 'Select Country',
314 'default_value' => NULL,
315 ]);
316
317 $fields = [
318 'countryA' => $countryA['values'][$countryA['id']],
319 'countryB' => $countryB['values'][$countryB['id']],
320 'countryC' => $countryC['values'][$countryC['id']],
321 ];
322 $contacts = [
323 'alice' => $this->individualCreate([
324 'first_name' => 'Alice',
325 'last_name' => 'Albertson',
326 'custom_' . $fields['countryA']['id'] => $countriesByName['Andorra'],
327 'custom_' . $fields['countryB']['id'] => $countriesByName['Barbados'],
328 ]),
329 'bob' => $this->individualCreate([
330 'first_name' => 'Bob',
331 'last_name' => 'Roberts',
332 'custom_' . $fields['countryA']['id'] => $countriesByName['Austria'],
333 'custom_' . $fields['countryB']['id'] => $countriesByName['Bermuda'],
334 'custom_' . $fields['countryC']['id'] => $countriesByName['Chad'],
335 ]),
336 'carol' => $this->individualCreate([
337 'first_name' => 'Carol',
338 'last_name' => 'Carolson',
339 'custom_' . $fields['countryC']['id'] => $countriesByName['Cambodia'],
340 ]),
341 ];
342
343 // Move!
344 CRM_Core_BAO_CustomField::moveField($fields['countryB']['id'], $groupB['id']);
345
346 // Group[A] no longer has fields[countryB]
347 $errorScope = CRM_Core_TemporaryErrorScope::useException();
348 try {
349 $this->assertDBQuery(1, "SELECT {$fields['countryB']['column_name']} FROM " . $groupA['table_name']);
350 $this->fail('Expected exception when querying column on wrong table');
351 }
352 catch (PEAR_Exception$e) {
353 }
354 $errorScope = NULL;
355
356 // Alice: Group[B] has fields[countryB], but fields[countryC] did not exist before
357 $this->assertDBQuery(1,
358 "SELECT count(*) FROM {$groupB['table_name']}
359 WHERE entity_id = %1
360 AND {$fields['countryB']['column_name']} = %3
361 AND {$fields['countryC']['column_name']} is null",
362 [
363 1 => [$contacts['alice'], 'Integer'],
364 3 => [$countriesByName['Barbados'], 'Integer'],
365 ]
366 );
367
368 // Bob: Group[B] has merged fields[countryB] and fields[countryC] on the same record
369 $this->assertDBQuery(1,
370 "SELECT count(*) FROM {$groupB['table_name']}
371 WHERE entity_id = %1
372 AND {$fields['countryB']['column_name']} = %3
373 AND {$fields['countryC']['column_name']} = %4",
374 [
375 1 => [$contacts['bob'], 'Integer'],
376 3 => [$countriesByName['Bermuda'], 'Integer'],
377 4 => [$countriesByName['Chad'], 'Integer'],
378 ]
379 );
380
381 // Carol: Group[B] still has fields[countryC] but did not get fields[countryB]
382 $this->assertDBQuery(1,
383 "SELECT count(*) FROM {$groupB['table_name']}
384 WHERE entity_id = %1
385 AND {$fields['countryB']['column_name']} is null
386 AND {$fields['countryC']['column_name']} = %4",
387 [
388 1 => [$contacts['carol'], 'Integer'],
389 4 => [$countriesByName['Cambodia'], 'Integer'],
390 ]
391 );
392
393 $this->customGroupDelete($groups['A']['id']);
394 $this->customGroupDelete($groupB['id']);
395 }
396
397 /**
398 * Test get custom field id function.
399 *
400 * @throws \CiviCRM_API3_Exception
401 */
402 public function testGetCustomFieldID() {
403 $this->createCustomField();
404 $fieldID = CRM_Core_BAO_CustomField::getCustomFieldID('testFld');
405 $this->assertEquals($this->customFieldID, $fieldID);
406
407 $fieldID = CRM_Core_BAO_CustomField::getCustomFieldID('testFld', 'new custom group');
408 $this->assertEquals($this->customFieldID, $fieldID);
409
410 $fieldID = CRM_Core_BAO_CustomField::getCustomFieldID('testFld', 'new custom group', TRUE);
411 $this->assertEquals('custom_' . $this->customFieldID, $fieldID);
412
413 // create field with same name in a different group
414 $this->createCustomField('other custom group');
415 $otherFieldID = CRM_Core_BAO_CustomField::getCustomFieldID('testFld', 'other custom group');
416 // make sure it does not return the field ID of the first field
417 $this->assertNotEquals($fieldID, $otherFieldID);
418 }
419
420 /**
421 * Create a custom field
422 *
423 * @param string $groupTitle
424 *
425 * @return array
426 */
427 protected function createCustomField($groupTitle = 'new custom group') {
428 $customGroup = $this->customGroupCreate([
429 'extends' => 'Individual',
430 'title' => $groupTitle,
431 ]);
432 $fields = [
433 'label' => 'testFld',
434 'data_type' => 'String',
435 'html_type' => 'Text',
436 'custom_group_id' => $customGroup['id'],
437 ];
438 $field = CRM_Core_BAO_CustomField::create($fields);
439 $this->customFieldID = $field->id;
440 return $customGroup;
441 }
442
443 /**
444 * Test the getFieldsForImport function.
445 *
446 * @throws \Exception
447 */
448 public function testGetFieldsForImport() {
449 $this->entity = 'Contact';
450 $this->createCustomGroupWithFieldsOfAllTypes();
451 $customGroupID = $this->ids['CustomGroup']['Custom Group'];
452 $expected = [
453 $this->getCustomFieldName('country') => [
454 'name' => $this->getCustomFieldName('country'),
455 'type' => 1,
456 'title' => 'Country',
457 'headerPattern' => '//',
458 'import' => 1,
459 'custom_field_id' => $this->getCustomFieldID('country'),
460 'options_per_line' => NULL,
461 'text_length' => NULL,
462 'data_type' => 'Country',
463 'html_type' => 'Select Country',
464 'is_search_range' => '0',
465 'id' => $this->getCustomFieldID('country'),
466 'label' => 'Country',
467 'groupTitle' => 'Custom Group',
468 'default_value' => NULL,
469 'custom_group_id' => $customGroupID,
470 'extends' => 'Contact',
471 'extends_entity_column_value' => NULL,
472 'extends_entity_column_id' => NULL,
473 'is_view' => '0',
474 'is_multiple' => '0',
475 'option_group_id' => NULL,
476 'date_format' => NULL,
477 'time_format' => NULL,
478 'is_required' => 0,
479 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
480 'column_name' => $this->getCustomFieldColumnName('country'),
481 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('country'),
482 'extends_table' => 'civicrm_contact',
483 'search_table' => 'contact_a',
484 'serialize' => NULL,
485 'pseudoconstant' => [
486 'table' => 'civicrm_country',
487 'keyColumn' => 'id',
488 'labelColumn' => 'name',
489 'nameColumn' => 'iso_code',
490 ],
491 ],
492 $this->getCustomFieldName('multi_country') => [
493 'name' => $this->getCustomFieldName('multi_country'),
494 'type' => 1,
495 'title' => 'Country-multi',
496 'headerPattern' => '//',
497 'import' => 1,
498 'custom_field_id' => $this->getCustomFieldID('multi_country'),
499 'options_per_line' => NULL,
500 'text_length' => NULL,
501 'data_type' => 'Country',
502 'html_type' => 'Select Country',
503 'is_search_range' => '0',
504 'id' => $this->getCustomFieldID('multi_country'),
505 'label' => 'Country-multi',
506 'groupTitle' => 'Custom Group',
507 'default_value' => NULL,
508 'custom_group_id' => $customGroupID,
509 'extends' => 'Contact',
510 'extends_entity_column_value' => NULL,
511 'extends_entity_column_id' => NULL,
512 'is_view' => '0',
513 'is_multiple' => '0',
514 'option_group_id' => NULL,
515 'date_format' => NULL,
516 'time_format' => NULL,
517 'is_required' => 0,
518 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
519 'column_name' => $this->getCustomFieldColumnName('multi_country'),
520 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('multi_country'),
521 'extends_table' => 'civicrm_contact',
522 'search_table' => 'contact_a',
523 'serialize' => 1,
524 'pseudoconstant' => [
525 'table' => 'civicrm_country',
526 'keyColumn' => 'id',
527 'labelColumn' => 'name',
528 'nameColumn' => 'iso_code',
529 ],
530 ],
531 $this->getCustomFieldName('file') => [
532 'name' => $this->getCustomFieldName('file'),
533 'type' => 2,
534 'title' => 'My file',
535 'headerPattern' => '//',
536 'import' => 1,
537 'custom_field_id' => $this->getCustomFieldID('file'),
538 'options_per_line' => NULL,
539 'text_length' => NULL,
540 'data_type' => 'File',
541 'html_type' => 'File',
542 'is_search_range' => '0',
543 'id' => $this->getCustomFieldID('file'),
544 'label' => 'My file',
545 'groupTitle' => 'Custom Group',
546 'default_value' => NULL,
547 'custom_group_id' => $customGroupID,
548 'extends' => 'Contact',
549 'extends_entity_column_value' => NULL,
550 'extends_entity_column_id' => NULL,
551 'is_view' => '0',
552 'is_multiple' => '0',
553 'option_group_id' => NULL,
554 'date_format' => NULL,
555 'time_format' => NULL,
556 'is_required' => 0,
557 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
558 'column_name' => 'my_file_' . $this->getCustomFieldID('file'),
559 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.my_file_' . $this->getCustomFieldID('file'),
560 'extends_table' => 'civicrm_contact',
561 'search_table' => 'contact_a',
562 'serialize' => NULL,
563 ],
564 $this->getCustomFieldName('text') => [
565 'name' => $this->getCustomFieldName('text'),
566 'type' => 2,
567 'title' => 'Enter text here',
568 'headerPattern' => '//',
569 'import' => 1,
570 'custom_field_id' => $this->getCustomFieldID('text'),
571 'options_per_line' => NULL,
572 'text_length' => 300,
573 'data_type' => 'String',
574 'html_type' => 'Text',
575 'is_search_range' => '0',
576 'id' => $this->getCustomFieldID('text'),
577 'label' => 'Enter text here',
578 'groupTitle' => 'Custom Group',
579 'default_value' => 'xyz',
580 'custom_group_id' => '1',
581 'extends' => 'Contact',
582 'extends_entity_column_value' => NULL,
583 'extends_entity_column_id' => NULL,
584 'is_view' => '0',
585 'is_multiple' => '0',
586 'option_group_id' => NULL,
587 'date_format' => NULL,
588 'time_format' => NULL,
589 'is_required' => 0,
590 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
591 'column_name' => 'enter_text_here_' . $this->getCustomFieldID('text'),
592 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.enter_text_here_' . $this->getCustomFieldID('text'),
593 'extends_table' => 'civicrm_contact',
594 'search_table' => 'contact_a',
595 'maxlength' => 300,
596 'serialize' => NULL,
597 ],
598 $this->getCustomFieldName('select_string') => [
599 'name' => $this->getCustomFieldName('select_string'),
600 'type' => 2,
601 'title' => 'Pick Color',
602 'headerPattern' => '//',
603 'import' => 1,
604 'custom_field_id' => $this->getCustomFieldID('select_string'),
605 'options_per_line' => NULL,
606 'text_length' => NULL,
607 'data_type' => 'String',
608 'html_type' => 'Select',
609 'is_search_range' => '0',
610 'id' => $this->getCustomFieldID('select_string'),
611 'label' => 'Pick Color',
612 'groupTitle' => 'Custom Group',
613 'default_value' => NULL,
614 'custom_group_id' => $customGroupID,
615 'extends' => 'Contact',
616 'extends_entity_column_value' => NULL,
617 'extends_entity_column_id' => NULL,
618 'is_view' => '0',
619 'is_multiple' => '0',
620 'option_group_id' => $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID('select_string'), 'return' => 'option_group_id']),
621 'date_format' => NULL,
622 'time_format' => NULL,
623 'is_required' => 0,
624 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
625 'column_name' => 'pick_color_' . $this->getCustomFieldID('select_string'),
626 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.pick_color_' . $this->getCustomFieldID('select_string'),
627 'extends_table' => 'civicrm_contact',
628 'search_table' => 'contact_a',
629 'serialize' => NULL,
630 'pseudoconstant' => [
631 'optionGroupName' => $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID('select_string'), 'return' => 'option_group_id.name']),
632 'optionEditPath' => 'civicrm/admin/options/' . $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID('select_string'), 'return' => 'option_group_id.name']),
633 ],
634 ],
635 $this->getCustomFieldName('select_date') => [
636 'name' => $this->getCustomFieldName('select_date'),
637 'type' => 4,
638 'title' => 'Test Date',
639 'headerPattern' => '//',
640 'import' => 1,
641 'custom_field_id' => $this->getCustomFieldID('select_date'),
642 'options_per_line' => NULL,
643 'text_length' => NULL,
644 'data_type' => 'Date',
645 'html_type' => 'Select Date',
646 'is_search_range' => '1',
647 'date_format' => 'mm/dd/yy',
648 'time_format' => '1',
649 'id' => $this->getCustomFieldID('select_date'),
650 'label' => 'Test Date',
651 'groupTitle' => 'Custom Group',
652 'default_value' => '20090711',
653 'custom_group_id' => $customGroupID,
654 'extends' => 'Contact',
655 'extends_entity_column_value' => NULL,
656 'extends_entity_column_id' => NULL,
657 'is_view' => '0',
658 'is_multiple' => '0',
659 'option_group_id' => NULL,
660 'is_required' => '0',
661 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
662 'column_name' => 'test_date_' . $this->getCustomFieldID('select_date'),
663 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.test_date_' . $this->getCustomFieldID('select_date'),
664 'extends_table' => 'civicrm_contact',
665 'search_table' => 'contact_a',
666 'serialize' => NULL,
667 ],
668 $this->getCustomFieldName('link') => [
669 'name' => $this->getCustomFieldName('link'),
670 'type' => 2,
671 'title' => 'test_link',
672 'headerPattern' => '//',
673 'import' => 1,
674 'custom_field_id' => $this->getCustomFieldID('link'),
675 'options_per_line' => NULL,
676 'text_length' => NULL,
677 'data_type' => 'Link',
678 'html_type' => 'Link',
679 'is_search_range' => '0',
680 'id' => $this->getCustomFieldID('link'),
681 'label' => 'test_link',
682 'groupTitle' => 'Custom Group',
683 'default_value' => 'http://civicrm.org',
684 'custom_group_id' => $customGroupID,
685 'extends' => 'Contact',
686 'extends_entity_column_value' => NULL,
687 'extends_entity_column_id' => NULL,
688 'is_view' => '0',
689 'is_multiple' => '0',
690 'option_group_id' => NULL,
691 'date_format' => NULL,
692 'time_format' => NULL,
693 'is_required' => 0,
694 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
695 'column_name' => 'test_link_' . $this->getCustomFieldID('link'),
696 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.test_link_' . $this->getCustomFieldID('link'),
697 'extends_table' => 'civicrm_contact',
698 'search_table' => 'contact_a',
699 'serialize' => NULL,
700 ],
701 $this->getCustomFieldName('int') => [
702 'name' => $this->getCustomFieldName('int'),
703 'type' => CRM_Utils_Type::T_INT,
704 'title' => 'Enter integer here',
705 'headerPattern' => '//',
706 'import' => 1,
707 'custom_field_id' => $this->getCustomFieldID('int'),
708 'options_per_line' => NULL,
709 'text_length' => NULL,
710 'data_type' => 'Int',
711 'html_type' => 'Text',
712 'is_search_range' => '1',
713 'id' => $this->getCustomFieldID('int'),
714 'label' => 'Enter integer here',
715 'groupTitle' => 'Custom Group',
716 'default_value' => '4',
717 'custom_group_id' => $customGroupID,
718 'extends' => 'Contact',
719 'extends_entity_column_value' => NULL,
720 'extends_entity_column_id' => NULL,
721 'is_view' => '0',
722 'is_multiple' => '0',
723 'option_group_id' => NULL,
724 'date_format' => NULL,
725 'time_format' => NULL,
726 'is_required' => 0,
727 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
728 'column_name' => $this->getCustomFieldColumnName('int'),
729 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('int'),
730 'extends_table' => 'civicrm_contact',
731 'search_table' => 'contact_a',
732 'serialize' => NULL,
733 ],
734 $this->getCustomFieldName('contact_reference') => [
735 'name' => $this->getCustomFieldName('contact_reference'),
736 'type' => CRM_Utils_Type::T_INT,
737 'title' => 'Contact reference field',
738 'headerPattern' => '//',
739 'import' => 1,
740 'custom_field_id' => $this->getCustomFieldID('contact_reference'),
741 'options_per_line' => NULL,
742 'text_length' => NULL,
743 'data_type' => 'ContactReference',
744 'html_type' => 'Autocomplete-Select',
745 'is_search_range' => '0',
746 'id' => $this->getCustomFieldID('contact_reference'),
747 'label' => 'Contact reference field',
748 'groupTitle' => 'Custom Group',
749 'default_value' => NULL,
750 'custom_group_id' => $customGroupID,
751 'extends' => 'Contact',
752 'extends_entity_column_value' => NULL,
753 'extends_entity_column_id' => NULL,
754 'is_view' => '0',
755 'is_multiple' => '0',
756 'option_group_id' => NULL,
757 'date_format' => NULL,
758 'time_format' => NULL,
759 'is_required' => 0,
760 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
761 'column_name' => $this->getCustomFieldColumnName('contact_reference'),
762 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('contact_reference'),
763 'extends_table' => 'civicrm_contact',
764 'search_table' => 'contact_a',
765 'serialize' => NULL,
766 ],
767 $this->getCustomFieldName('state') => [
768 'name' => $this->getCustomFieldName('state'),
769 'id' => $this->getCustomFieldID('state'),
770 'label' => 'State',
771 'headerPattern' => '//',
772 'title' => 'State',
773 'custom_field_id' => $this->getCustomFieldID('state'),
774 'groupTitle' => 'Custom Group',
775 'default_value' => NULL,
776 'custom_group_id' => $customGroupID,
777 'extends' => 'Contact',
778 'extends_entity_column_value' => NULL,
779 'extends_entity_column_id' => NULL,
780 'is_view' => '0',
781 'is_multiple' => '0',
782 'option_group_id' => NULL,
783 'date_format' => NULL,
784 'time_format' => NULL,
785 'is_required' => 0,
786 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
787 'column_name' => $this->getCustomFieldColumnName('state'),
788 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('state'),
789 'extends_table' => 'civicrm_contact',
790 'search_table' => 'contact_a',
791 'serialize' => NULL,
792 'pseudoconstant' => [
793 'table' => 'civicrm_state_province',
794 'keyColumn' => 'id',
795 'labelColumn' => 'name',
796 ],
797 'import' => 1,
798 'data_type' => 'StateProvince',
799 'type' => 1,
800 'html_type' => 'Select State/Province',
801 'text_length' => NULL,
802 'options_per_line' => NULL,
803 'is_search_range' => '0',
804 ],
805 $this->getCustomFieldName('multi_state') => [
806 'id' => $this->getCustomFieldID('multi_state'),
807 'label' => 'State-multi',
808 'headerPattern' => '//',
809 'title' => 'State-multi',
810 'custom_field_id' => $this->getCustomFieldID('multi_state'),
811 'groupTitle' => 'Custom Group',
812 'default_value' => NULL,
813 'custom_group_id' => $customGroupID,
814 'extends' => 'Contact',
815 'extends_entity_column_value' => NULL,
816 'extends_entity_column_id' => NULL,
817 'is_view' => '0',
818 'is_multiple' => '0',
819 'option_group_id' => NULL,
820 'date_format' => NULL,
821 'time_format' => NULL,
822 'is_required' => 0,
823 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
824 'column_name' => $this->getCustomFieldColumnName('multi_state'),
825 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('multi_state'),
826 'extends_table' => 'civicrm_contact',
827 'search_table' => 'contact_a',
828 'serialize' => 1,
829 'pseudoconstant' => [
830 'table' => 'civicrm_state_province',
831 'keyColumn' => 'id',
832 'labelColumn' => 'name',
833 ],
834 'import' => 1,
835 'data_type' => 'StateProvince',
836 'name' => $this->getCustomFieldName('multi_state'),
837 'type' => 1,
838 'html_type' => 'Select State/Province',
839 'text_length' => NULL,
840 'options_per_line' => NULL,
841 'is_search_range' => '0',
842 ],
843 $this->getCustomFieldName('boolean') => [
844 'id' => $this->getCustomFieldID('boolean'),
845 'label' => 'Yes No',
846 'headerPattern' => '//',
847 'title' => 'Yes No',
848 'custom_field_id' => $this->getCustomFieldID('boolean'),
849 'groupTitle' => 'Custom Group',
850 'default_value' => NULL,
851 'custom_group_id' => $customGroupID,
852 'extends' => 'Contact',
853 'extends_entity_column_value' => NULL,
854 'extends_entity_column_id' => NULL,
855 'is_view' => '0',
856 'is_multiple' => '0',
857 'option_group_id' => NULL,
858 'date_format' => NULL,
859 'time_format' => NULL,
860 'is_required' => 0,
861 'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
862 'column_name' => $this->getCustomFieldColumnName('boolean'),
863 'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('boolean'),
864 'extends_table' => 'civicrm_contact',
865 'search_table' => 'contact_a',
866 'import' => 1,
867 'data_type' => 'Boolean',
868 'name' => $this->getCustomFieldName('boolean'),
869 'type' => 16,
870 'html_type' => 'Radio',
871 'text_length' => NULL,
872 'options_per_line' => NULL,
873 'is_search_range' => '0',
874 'serialize' => NULL,
875 'pseudoconstant' => [
876 'callback' => 'CRM_Core_SelectValues::boolean',
877 ],
878 ],
879 ];
880 $this->assertEquals($expected, CRM_Core_BAO_CustomField::getFieldsForImport());
881 }
882
883 /**
884 * Test the bulk create function works.
885 */
886 public function testBulkCreate() {
887 $customGroup = $this->customGroupCreate([
888 'extends' => 'Individual',
889 'title' => 'my bulk group',
890 ]);
891 CRM_Core_BAO_CustomField::bulkSave([
892 [
893 'label' => 'Test',
894 'data_type' => 'String',
895 'html_type' => 'Text',
896 'column_name' => 'my_text',
897 ],
898 [
899 'label' => 'test_link',
900 'data_type' => 'Link',
901 'html_type' => 'Link',
902 'is_search_range' => '0',
903 ],
904 ],
905 [
906 'custom_group_id' => $customGroup['id'],
907 'is_active' => 1,
908 'is_searchable' => 1,
909 ]);
910 $dao = CRM_Core_DAO::executeQuery(('SHOW CREATE TABLE ' . $customGroup['values'][$customGroup['id']]['table_name']));
911 $dao->fetch();
912 $this->assertContains('`test_link_2` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL', $dao->Create_Table);
913 $this->assertContains('KEY `INDEX_my_text` (`my_text`)', $dao->Create_Table);
914 }
915
916 /**
917 * Check that outputting the display value for a file field with No description doesn't generate error
918 */
919 public function testFileDisplayValueNoDescription() {
920 $customGroup = $this->customGroupCreate([
921 'extends' => 'Individual',
922 'title' => 'Test Contact File Custom Group',
923 ]);
924 $fileField = $this->customFieldCreate([
925 'custom_group_id' => $customGroup['id'],
926 'data_type' => 'File',
927 'html_type' => 'File',
928 'default_value' => '',
929 ]);
930 $filePath = Civi::paths()->getPath('[civicrm.files]/custom/test_file.txt');
931 $file = $this->callAPISuccess('File', 'create', [
932 'uri' => $filePath,
933 ]);
934 $individual = $this->individualCreate(['custom_' . $fileField['id'] => $file['id']]);
935 $expectedDisplayValue = CRM_Core_BAO_File::paperIconAttachment('*', $file['id'])[$file['id']];
936 $this->assertEquals($expectedDisplayValue, CRM_Core_BAO_CustomField::displayValue($file['id'], $fileField['id']));
937 }
938
939 /**
940 * Test for hook_civicrm_alterCustomFieldDisplayValue().
941 */
942 public function testAlterCustomFieldDisplayValueHook() {
943 CRM_Utils_Hook_UnitTests::singleton()->setHook('civicrm_alterCustomFieldDisplayValue', [$this, 'alterCustomFieldDisplayValue']);
944 $customGroupId = $this->customGroupCreate([
945 'extends' => 'Individual',
946 'title' => 'Test Contactcustom Group',
947 ])['id'];
948 $fieldId = $this->customFieldCreate([
949 'custom_group_id' => $customGroupId,
950 'name' => 'alter_cf_field',
951 'label' => 'Alter CF Field',
952 ])['id'];
953 $contactId = $this->individualCreate(['custom_' . $fieldId => 'Test']);
954
955 $this->assertEquals('Test', $this->callAPISuccessGetValue('Contact',
956 ['id' => $contactId, 'return' => "custom_{$fieldId}"]
957 ));
958
959 $values = [];
960 $fields = [
961 'custom_' . $fieldId => $this->callAPISuccess('Contact', 'getfield', [
962 'name' => 'custom_' . $fieldId,
963 'action' => 'get',
964 ])['values'],
965 ];
966
967 // CRM_Core_BAO_UFGroup::getValues() invokes CRM_Core_BAO_CustomField::displayValue() function.
968 CRM_Core_BAO_UFGroup::getValues($contactId, $fields, $values);
969 $this->assertEquals('New value', $values['Alter CF Field']);
970 }
971
972 /**
973 * @param string $displayValue
974 * @param mixed $value
975 * @param int $entityId
976 * @param array $fieldInfo
977 *
978 */
979 public function alterCustomFieldDisplayValue(&$displayValue, $value, $entityId, $fieldInfo) {
980 if ($fieldInfo['name'] == 'alter_cf_field') {
981 $displayValue = 'New value';
982 }
983 }
984
985 }