Merge pull request #16469 from civicrm/5.22
[civicrm-core.git] / tests / phpunit / api / v3 / CustomValueTest.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
6 | |
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
10 +--------------------------------------------------------------------+
11 */
12
13 /**
14 * Class api_v3_CustomValueTest
15 * @group headless
16 */
17 class api_v3_CustomValueTest extends CiviUnitTestCase {
18 protected $_apiversion = 3;
19
20 protected $optionGroup;
21
22 public $DBResetRequired = FALSE;
23
24 public function setUp() {
25 parent::setUp();
26 }
27
28 public function _populateOptionAndCustomGroup($type = NULL) {
29 $dataValues = [
30 'integer' => [1, 2, 3],
31 'number' => [10.11, 20.22, 30.33],
32 'string' => [substr(sha1(rand()), 0, 4) . '(', substr(sha1(rand()), 0, 3) . '|', substr(sha1(rand()), 0, 2) . ','],
33 // 'country' => array_rand(CRM_Core_PseudoConstant::country(FALSE, FALSE), 3),
34 // This does not work in the test at the moment due to caching issues.
35 //'state_province' => array_rand(CRM_Core_PseudoConstant::stateProvince(FALSE, FALSE), 3),
36 'date' => NULL,
37 'contact' => NULL,
38 'boolean' => NULL,
39 ];
40
41 $dataValues = !empty($type) ? [$type => $dataValues[$type]] : $dataValues;
42
43 foreach ($dataValues as $dataType => $values) {
44 $this->optionGroup[$dataType] = ['values' => $values];
45 if (!empty($values)) {
46 $result = $this->callAPISuccess('OptionGroup', 'create',
47 [
48 'name' => "{$dataType}_group",
49 'api.option_value.create' => ['label' => "$dataType 1", 'value' => $values[0]],
50 'api.option_value.create.1' => ['label' => "$dataType 2", 'value' => $values[1]],
51 'api.option_value.create.2' => ['label' => "$dataType 3", 'value' => $values[2]],
52 ]
53 );
54 $this->optionGroup[$dataType]['id'] = $result['id'];
55 }
56 elseif ($dataType == 'contact') {
57 for ($i = 0; $i < 3; $i++) {
58 $result = $this->callAPISuccess('Contact', 'create', ['contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . '@yahoo.com']);
59 $this->optionGroup[$dataType]['values'][$i] = $result['id'];
60 }
61 }
62 $this->ids[$dataType] = $this->entityCustomGroupWithSingleFieldCreate("$dataType Custom Group", 'Contacts');
63 }
64
65 }
66
67 public function tearDown() {
68 $tablesToTruncate = [
69 'civicrm_email',
70 'civicrm_custom_field',
71 'civicrm_custom_group',
72 'civicrm_contact',
73 ];
74
75 // true tells quickCleanup to drop any tables that might have been created in the test
76 $this->quickCleanup($tablesToTruncate, TRUE);
77
78 // cleanup created option group for each custom-set before running next test
79 if (!empty($this->optionGroup)) {
80 foreach ($this->optionGroup as $type => $value) {
81 if (!empty($value['id'])) {
82 $count = $this->callAPISuccess('OptionGroup', 'get', ['id' => $value['id']]);
83 if ((bool) $count['count']) {
84 $this->callAPISuccess('OptionGroup', 'delete', ['id' => $value['id']]);
85 }
86 }
87 }
88 }
89 }
90
91 public function testCreateCustomValue() {
92 $this->_populateOptionAndCustomGroup();
93 $this->_customField = $this->customFieldCreate(['custom_group_id' => $this->ids['string']['custom_group_id']]);
94 $this->_customFieldID = $this->_customField['id'];
95
96 $customFieldDataType = CRM_Core_BAO_CustomField::dataType();
97 $dataToHtmlTypes = CRM_Core_BAO_CustomField::dataToHtml();
98 $count = 0;
99 $optionSupportingHTMLTypes = ['Select', 'Radio', 'CheckBox', 'Autocomplete-Select', 'Multi-Select'];
100
101 foreach ($customFieldDataType as $dataType => $label) {
102 switch ($dataType) {
103 // case 'Country':
104 // case 'StateProvince':
105 case 'String':
106 case 'Link':
107 case 'Int':
108 case 'Float':
109 case 'Money':
110 case 'Date':
111 case 'Boolean':
112
113 //Based on the custom field data-type choose desired SQL operators(to test with) and basic $type
114 if (in_array($dataType, ['String', 'Link'])) {
115 $validSQLOperators = ['=', '!=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE', 'IS NOT NULL', 'IS NULL'];
116 $type = 'string';
117 }
118 elseif ($dataType == 'Boolean') {
119 $validSQLOperators = ['=', '!=', 'IS NOT NULL', 'IS NULL'];
120 $type = 'boolean';
121 }
122 else {
123 if ($dataType == 'Country') {
124 $type = 'country';
125 }
126 elseif ($dataType == 'StateProvince') {
127 $type = 'state_province';
128 }
129 elseif ($dataType == 'ContactReference') {
130 $type = 'contact';
131 }
132 elseif ($dataType == 'Date') {
133 $type = 'date';
134 }
135 else {
136 $type = $dataType == 'Int' ? 'integer' : 'number';
137 }
138 $validSQLOperators = ['=', '!=', 'IN', 'NOT IN', '<=', '>=', '>', '<', 'IS NOT NULL', 'IS NULL'];
139 }
140
141 //Create custom field of $dataType and html-type $html
142 foreach ($dataToHtmlTypes[$count] as $html) {
143 // per CRM-18568 the like operator does not currently work for fields with options.
144 // the LIKE operator could potentially bypass ACLs (as could IS NOT NULL) and some thought needs to be given
145 // to it.
146 if (in_array($html, $optionSupportingHTMLTypes)) {
147 $validSQLOperators = array_diff($validSQLOperators, ['LIKE', 'NOT LIKE']);
148 }
149 $params = [
150 'custom_group_id' => $this->ids[$type]['custom_group_id'],
151 'label' => "$dataType - $html",
152 'data_type' => $dataType,
153 'html_type' => $html,
154 'default_value' => NULL,
155 ];
156 if (!in_array($html, ['Text', 'TextArea']) && !in_array($dataType, ['Link', 'Date', 'ContactReference', 'Boolean'])) {
157 $params += ['option_group_id' => $this->optionGroup[$type]['id']];
158 }
159 $customField = $this->customFieldCreate($params);
160 //Now test with $validSQLOperator SQL operators against its custom value(s)
161 $this->_testCustomValue($customField['values'][$customField['id']], $validSQLOperators, $type);
162 }
163 $count++;
164 break;
165
166 default:
167 // skipping File data-type & state province due to caching issues
168 $count++;
169 break;
170 }
171 }
172 }
173
174 public function _testCustomValue($customField, $sqlOps, $type) {
175 $isSerialized = CRM_Core_BAO_CustomField::isSerialized($customField);
176 $customId = $customField['id'];
177 $params = [
178 'contact_type' => 'Individual',
179 'email' => substr(sha1(rand()), 0, 7) . 'man1@yahoo.com',
180 ];
181 $result = $this->callAPISuccess('Contact', 'create', $params);
182 $contactId = $result['id'];
183
184 $count = rand(1, 2);
185
186 if ($isSerialized) {
187 $selectedValue = $this->optionGroup[$type]['values'];
188 $notselectedValue = $selectedValue[$count];
189 unset($selectedValue[$count]);
190 }
191 elseif ($customField['html_type'] == 'Link') {
192 $selectedValue = "http://" . substr(sha1(rand()), 0, 7) . ".com";
193 $notselectedValue = "http://" . substr(sha1(rand()), 0, 7) . ".com";
194 }
195 elseif ($type == 'date') {
196 $selectedValue = date('Ymd');
197 $notselectedValue = $lesserSelectedValue = date('Ymd', strtotime('yesterday'));
198 $greaterSelectedValue = date('Ymd', strtotime('+ 1 day'));
199 }
200 elseif ($type == 'contact') {
201 $selectedValue = $this->optionGroup[$type]['values'][1];
202 $notselectedValue = $this->optionGroup[$type]['values'][0];
203 }
204 elseif ($type == 'boolean') {
205 $selectedValue = 1;
206 $notselectedValue = 0;
207 }
208 else {
209 $selectedValue = $this->optionGroup[$type]['values'][0];
210 $notselectedValue = $this->optionGroup[$type]['values'][$count];
211 if (in_array(">", $sqlOps)) {
212 $greaterSelectedValue = $selectedValue + 1;
213 $lesserSelectedValue = $selectedValue - 1;
214 }
215 }
216
217 $params = [
218 'entity_id' => $contactId,
219 'custom_' . $customId => $selectedValue,
220 "custom_{$this->_customFieldID}" => "Test String Value for {$this->_customFieldID}",
221 ];
222 $this->callAPISuccess('CustomValue', 'create', $params);
223
224 //Test for different return value syntax.
225 $returnValues = [
226 ['return' => "custom_{$customId}"],
227 ['return' => ["custom_{$customId}"]],
228 ["return.custom_{$customId}" => 1],
229 ['return' => ["custom_{$customId}", "custom_{$this->_customFieldID}"]],
230 ["return.custom_{$customId}" => 1, "return.custom_{$this->_customFieldID}" => 1],
231 ];
232 foreach ($returnValues as $key => $val) {
233 $params = array_merge($val, [
234 'entity_id' => $contactId,
235 ]);
236 $customValue = $this->callAPISuccess('CustomValue', 'get', $params);
237 if (is_array($selectedValue)) {
238 $expected = array_values($selectedValue);
239 $this->checkArrayEquals($expected, $customValue['values'][$customId]['latest']);
240 }
241 elseif ($type == 'date') {
242 $this->assertEquals($selectedValue, date('Ymd', strtotime(str_replace('.', '/', $customValue['values'][$customId]['latest']))));
243 }
244 else {
245 $this->assertEquals($selectedValue, $customValue['values'][$customId]['latest']);
246 }
247 if ($key > 2) {
248 $this->assertEquals("Test String Value for {$this->_customFieldID}", $customValue['values'][$this->_customFieldID]['latest']);
249 }
250 }
251
252 foreach ($sqlOps as $op) {
253 $qillOp = CRM_Utils_Array::value($op, CRM_Core_SelectValues::getSearchBuilderOperators(), $op);
254 switch ($op) {
255 case '=':
256 $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => (is_array($selectedValue) ? implode(CRM_Core_DAO::VALUE_SEPARATOR, $selectedValue) : $selectedValue)]);
257 $this->assertEquals($contactId, $result['id']);
258 break;
259
260 case '!=':
261 $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => $notselectedValue]]);
262 $this->assertEquals(TRUE, array_key_exists($contactId, $result['values']));
263 break;
264
265 case '>':
266 case '<':
267 case '>=':
268 case '<=':
269 if ($isSerialized) {
270 break;
271 }
272 // To be precise in for these operator we can't just rely on one contact,
273 // hence creating multiple contact with custom value less/more then $selectedValue respectively
274 $result = $this->callAPISuccess('Contact', 'create', ['contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . 'man2@yahoo.com']);
275 $contactId2 = $result['id'];
276 $this->callAPISuccess('CustomValue', 'create', ['entity_id' => $contactId2, 'custom_' . $customId => $lesserSelectedValue]);
277
278 if ($op == '>') {
279 $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => $lesserSelectedValue]]);
280 $this->assertEquals($contactId, $result['id']);
281 }
282 elseif ($op == '<') {
283 $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => $selectedValue]]);
284 $this->assertEquals($contactId2, $result['id']);
285 }
286 else {
287 $result = $this->callAPISuccess('Contact', 'create', ['contact_type' => 'Individual', 'email' => substr(sha1(rand()), 0, 7) . 'man3@yahoo.com']);
288 $contactId3 = $result['id'];
289 $this->callAPISuccess('CustomValue', 'create', ['entity_id' => $contactId3, 'custom_' . $customId => $greaterSelectedValue]);
290
291 $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => $selectedValue]]);
292
293 $this->assertEquals($contactId, $result['values'][$contactId]['id']);
294 if ($op == '>=') {
295 $this->assertEquals($contactId3, $result['values'][$contactId3]['id']);
296 }
297 else {
298 $this->assertEquals($contactId2, $result['values'][$contactId2]['id']);
299 }
300 $this->callAPISuccess('contact', 'delete', ['id' => $contactId3]);
301 }
302
303 $this->callAPISuccess('contact', 'delete', ['id' => $contactId2]);
304 break;
305
306 case 'IN':
307 $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => (array) $selectedValue]]);
308 $this->assertEquals($contactId, $result['id']);
309 break;
310
311 case 'NOT IN':
312 $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => (array) $notselectedValue]]);
313 $this->assertEquals($contactId, $result['id']);
314 break;
315
316 case 'LIKE':
317 $selectedValue = is_array($selectedValue) ? $selectedValue[0] : $selectedValue;
318 $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => "%$selectedValue%"]]);
319 $this->assertEquals($contactId, $result['id']);
320 break;
321
322 case 'NOT LIKE':
323 $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => $notselectedValue]]);
324 $this->assertEquals($contactId, $result['id']);
325 break;
326
327 case 'IS NULL':
328 $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => 1]]);
329 $this->assertEquals(FALSE, array_key_exists($contactId, $result['values']));
330 break;
331
332 case 'IS NOT NULL':
333 $result = $this->callAPISuccess('Contact', 'Get', ['custom_' . $customId => [$op => 1]]);
334 $this->assertEquals($contactId, $result['id']);
335 break;
336 }
337 }
338
339 $this->callAPISuccess('Contact', 'delete', ['id' => $contactId]);
340 }
341
342 /**
343 * Ensure custom data is updated when option values are modified
344 *
345 * @link https://issues.civicrm.org/jira/browse/CRM-11856
346 *
347 * @throws \CiviCRM_API3_Exception
348 */
349 public function testAlterOptionValue() {
350 $this->_populateOptionAndCustomGroup('string');
351
352 $selectField = $this->customFieldCreate([
353 'custom_group_id' => $this->ids['string']['custom_group_id'],
354 'label' => 'Custom Select',
355 'html_type' => 'Select',
356 'option_group_id' => $this->optionGroup['string']['id'],
357 ]);
358 $selectField = civicrm_api3('customField', 'getsingle', ['id' => $selectField['id']]);
359 $radioField = $this->customFieldCreate([
360 'custom_group_id' => $this->ids['string']['custom_group_id'],
361 'label' => 'Custom Radio',
362 'html_type' => 'Radio',
363 'option_group_id' => $selectField['option_group_id'],
364 ]);
365 $multiSelectField = $this->customFieldCreate([
366 'custom_group_id' => $this->ids['string']['custom_group_id'],
367 'label' => 'Custom Multi-Select',
368 'html_type' => 'Multi-Select',
369 'option_group_id' => $selectField['option_group_id'],
370 ]);
371 $selectName = 'custom_' . $selectField['id'];
372 $radioName = 'custom_' . $radioField['id'];
373 $multiSelectName = 'custom_' . $multiSelectField['id'];
374 $controlFieldName = 'custom_' . $this->ids['string']['custom_field_id'];
375
376 $params = [
377 'first_name' => 'abc4',
378 'last_name' => 'xyz4',
379 'contact_type' => 'Individual',
380 'email' => 'man4@yahoo.com',
381 $selectName => $this->optionGroup['string']['values'][0],
382 $multiSelectName => $this->optionGroup['string']['values'],
383 $radioName => $this->optionGroup['string']['values'][1],
384 // The control group in a science experiment should be unaffected
385 $controlFieldName => $this->optionGroup['string']['values'][2],
386 ];
387
388 $contact = $this->callAPISuccess('Contact', 'create', $params);
389
390 $result = $this->callAPISuccess('Contact', 'getsingle', [
391 'id' => $contact['id'],
392 'return' => [$selectName, $multiSelectName],
393 ]);
394 $this->assertEquals($params[$selectName], $result[$selectName]);
395 $this->assertEquals($params[$multiSelectName], $result[$multiSelectName]);
396
397 $this->callAPISuccess('OptionValue', 'create', [
398 'value' => 'one-modified',
399 'option_group_id' => $selectField['option_group_id'],
400 'name' => 'string 1',
401 'options' => [
402 'match-mandatory' => ['option_group_id', 'name'],
403 ],
404 ]);
405
406 $result = $this->callAPISuccess('Contact', 'getsingle', [
407 'id' => $contact['id'],
408 'return' => [$selectName, $multiSelectName, $controlFieldName, $radioName],
409 ]);
410 // Ensure the relevant fields have been updated
411 $this->assertEquals('one-modified', $result[$selectName]);
412 $this->assertEquals(['one-modified', $params[$radioName], $params[$controlFieldName]], $result[$multiSelectName]);
413 // This field should not have changed because we didn't alter this option
414 $this->assertEquals($params[$radioName], $result[$radioName]);
415 // This should not have changed because this field doesn't use the affected option group
416 $this->assertEquals($params[$controlFieldName], $result[$controlFieldName]);
417 // Add test of proof that multivalue fields.
418 $this->callAPISuccess('CustomValue', 'create', [
419 'entity_id' => $contact['id'],
420 $multiSelectName => [$params[$radioName], $params[$controlFieldName]],
421 ]);
422 $result = $this->callAPISuccess('Contact', 'getsingle', [
423 'id' => $contact['id'],
424 'return' => [$selectName, $multiSelectName, $controlFieldName, $radioName],
425 ]);
426
427 $this->assertEquals([$params[$radioName], $params[$controlFieldName]], $result[$multiSelectName]);
428 }
429
430 public function testGettree() {
431 $cg = $this->callAPISuccess('CustomGroup', 'create', [
432 'title' => 'TestGettree',
433 'extends' => 'Individual',
434 ]);
435 $cf = $this->callAPISuccess('CustomField', 'create', [
436 'custom_group_id' => $cg['id'],
437 'label' => 'Got Options',
438 'name' => 'got_options',
439 "data_type" => "String",
440 "html_type" => "Multi-Select",
441 'option_values' => ['1' => 'One', '2' => 'Two', '3' => 'Three'],
442 ]);
443 $fieldName = 'custom_' . $cf['id'];
444 $contact = $this->individualCreate([$fieldName => ['2', '3']]);
445
446 // Verify values are formatted correctly
447 $tree = $this->callAPISuccess('CustomValue', 'gettree', ['entity_type' => 'Contact', 'entity_id' => $contact]);
448 $this->assertEquals(['2', '3'], $tree['values']['TestGettree']['fields']['got_options']['value']['data']);
449 $this->assertEquals('Two, Three', $tree['values']['TestGettree']['fields']['got_options']['value']['display']);
450
451 // Try limiting the return params
452 $tree = $this->callAPISuccess('CustomValue', 'gettree', [
453 'entity_type' => 'Contact',
454 'entity_id' => $contact,
455 'return' => [
456 'custom_group.id',
457 'custom_field.id',
458 ],
459 ]);
460 $this->assertEquals(['2', '3'], $tree['values']['TestGettree']['fields']['got_options']['value']['data']);
461 $this->assertEquals('Two, Three', $tree['values']['TestGettree']['fields']['got_options']['value']['display']);
462 $this->assertEquals(['id', 'fields'], array_keys($tree['values']['TestGettree']));
463
464 // Ensure display values are returned even if data is not
465 $tree = $this->callAPISuccess('CustomValue', 'gettree', [
466 'entity_type' => 'Contact',
467 'entity_id' => $contact,
468 'return' => [
469 'custom_value.display',
470 ],
471 ]);
472 $this->assertEquals('Two, Three', $tree['values']['TestGettree']['fields']['got_options']['value']['display']);
473 $this->assertFalse(isset($tree['values']['TestGettree']['fields']['got_options']['value']['data']));
474
475 // Verify that custom set appears for individuals even who don't have any custom data
476 $contact2 = $this->individualCreate();
477 $tree = $this->callAPISuccess('CustomValue', 'gettree', ['entity_type' => 'Contact', 'entity_id' => $contact2]);
478 $this->assertArrayHasKey('TestGettree', $tree['values']);
479
480 // Verify that custom set doesn't appear for other contact types
481 $org = $this->organizationCreate();
482 $tree = $this->callAPISuccess('CustomValue', 'gettree', ['entity_type' => 'Contact', 'entity_id' => $org]);
483 $this->assertArrayNotHasKey('TestGettree', $tree['values']);
484
485 }
486
487 public function testGettree_getfields() {
488 $fields = $this->callAPISuccess('CustomValue', 'getfields', ['api_action' => 'gettree']);
489 $fields = $fields['values'];
490 $this->assertTrue((bool) $fields['entity_id']['api.required']);
491 $this->assertTrue((bool) $fields['entity_type']['api.required']);
492 $this->assertEquals('custom_group.id', $fields['custom_group.id']['name']);
493 $this->assertEquals('custom_field.id', $fields['custom_field.id']['name']);
494 $this->assertEquals('custom_value.id', $fields['custom_value.id']['name']);
495 }
496
497 /**
498 * Test that custom fields in greeting strings are updated.
499 */
500 public function testUpdateCustomGreetings() {
501 // Create a custom group with one field.
502 $customGroupResult = $this->callAPISuccess('CustomGroup', 'create', [
503 'sequential' => 1,
504 'title' => "test custom group",
505 'extends' => "Individual",
506 ]);
507 $customFieldResult = $this->callAPISuccess('CustomField', 'create', [
508 'custom_group_id' => $customGroupResult['id'],
509 'label' => "greeting test",
510 'data_type' => "String",
511 'html_type' => "Text",
512 ]);
513 $customFieldId = $customFieldResult['id'];
514
515 // Create a contact with an email greeting format that includes the new custom field.
516 $contactResult = $this->callAPISuccess('Contact', 'create', [
517 'contact_type' => 'Individual',
518 'email' => substr(sha1(rand()), 0, 7) . '@yahoo.com',
519 'email_greeting_id' => "Customized",
520 'email_greeting_custom' => "Dear {contact.custom_{$customFieldId}}",
521 ]);
522 $cid = $contactResult['id'];
523
524 // Define testing values.
525 $uniq = uniqid();
526 $testGreetingValue = "Dear $uniq";
527
528 // Update contact's custom field with CustomValue.create
529 $customValueResult = $this->callAPISuccess('CustomValue', 'create', [
530 'entity_id' => $cid,
531 "custom_{$customFieldId}" => $uniq,
532 'entity_table' => "civicrm_contact",
533 ]);
534
535 $contact = $this->callAPISuccessGetSingle('Contact', ['id' => $cid, 'return' => 'email_greeting']);
536 $this->assertEquals($testGreetingValue, $contact['email_greeting_display']);
537
538 }
539
540 /**
541 * Creates a multi-valued custom field set and creates a contact with mutliple values for it.
542 *
543 * @return array
544 */
545 private function _testGetCustomValueMultiple() {
546 $fieldIDs = $this->CustomGroupMultipleCreateWithFields();
547 $customFieldValues = [];
548 foreach ($fieldIDs['custom_field_id'] as $id) {
549 $customFieldValues["custom_{$id}"] = "field_{$id}_value_1";
550 }
551 $this->assertNotEmpty($customFieldValues);
552 $contactParams = [
553 'first_name' => 'Jane',
554 'last_name' => 'Doe',
555 'contact_type' => 'Individual',
556 ];
557 $contact = $this->callAPISuccess('Contact', 'create', array_merge($contactParams, $customFieldValues));
558 foreach ($fieldIDs['custom_field_id'] as $id) {
559 $customFieldValues["custom_{$id}"] = "field_{$id}_value_2";
560 }
561 $result = $this->callAPISuccess('Contact', 'create', array_merge(['id' => $contact['id']], $customFieldValues));
562 return [
563 $contact['id'],
564 $customFieldValues,
565 ];
566 }
567
568 /**
569 * Test that specific custom values can be retrieved while using return with comma separated values as genererated by the api explorer.
570 * ['return' => 'custom_1,custom_2']
571 */
572 public function testGetCustomValueReturnMultipleApiExplorer() {
573 list($cid, $customFieldValues) = $this->_testGetCustomValueMultiple();
574 $result = $this->callAPISuccess('CustomValue', 'get', [
575 'return' => implode(',', array_keys($customFieldValues)),
576 'entity_id' => $cid,
577 ]);
578 $this->assertEquals(count($customFieldValues), $result['count']);
579 }
580
581 /**
582 * Test that specific custom values can be retrieved while using return with array style syntax.
583 * ['return => ['custom_1', 'custom_2']]
584 */
585 public function testGetCustomValueReturnMultipleArray() {
586 list($cid, $customFieldValues) = $this->_testGetCustomValueMultiple();
587 $result = $this->callAPISuccess('CustomValue', 'get', [
588 'return' => array_keys($customFieldValues),
589 'entity_id' => $cid,
590 ]);
591 $this->assertEquals(count($customFieldValues), $result['count']);
592 }
593
594 /**
595 * Test that specific custom values can be retrieved while using a list of return parameters.
596 * [['return.custom_1' => '1'], ['return.custom_2' => '1']]
597 */
598 public function testGetCustomValueReturnMultipleList() {
599 list($cid, $customFieldValues) = $this->_testGetCustomValueMultiple();
600 $returnArray = [];
601 foreach ($customFieldValues as $field => $value) {
602 $returnArray["return.{$field}"] = 1;
603 }
604 $result = $this->callAPISuccess('CustomValue', 'get', array_merge($returnArray, ['entity_id' => $cid]));
605 $this->assertEquals(count($customFieldValues), $result['count']);
606 }
607
608 /**
609 * Test getdisplayvalue api and verify if it returns
610 * the custom text for display.
611 */
612 public function testGetDisplayValue() {
613 list($cid, $customFieldValues) = $this->_testGetCustomValueMultiple();
614 foreach ($customFieldValues as $field => $value) {
615 list(, $customFieldID) = explode("_", $field);
616 $result = $this->callAPISuccess('CustomValue', 'getdisplayvalue', [
617 'entity_id' => $cid,
618 'custom_field_id' => $customFieldID,
619 ]);
620 $expectedValue = [
621 'display' => $value,
622 'raw' => $value,
623 ];
624 $this->checkArrayEquals($result['values'][$customFieldID], $expectedValue);
625
626 $customDisplayValue = $this->callAPISuccess('CustomValue', 'getdisplayvalue', [
627 'entity_id' => $cid,
628 'custom_field_id' => $customFieldID,
629 'custom_field_value' => "Test Custom Display - {$value}",
630 ]);
631 $expectedValue = [
632 'display' => "Test Custom Display - {$value}",
633 'raw' => "Test Custom Display - {$value}",
634 ];
635 $this->checkArrayEquals($customDisplayValue['values'][$customFieldID], $expectedValue);
636 }
637 }
638
639 }