4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
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 +--------------------------------------------------------------------+
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
20 namespace api\v
4\Action
;
22 use Civi\Api4\Contact
;
23 use Civi\Api4\CustomField
;
24 use Civi\Api4\CustomGroup
;
25 use Civi\Api4\OptionGroup
;
26 use Civi\Api4\Relationship
;
27 use Civi\Api4\RelationshipCache
;
32 class BasicCustomFieldTest
extends BaseCustomValueTest
{
35 * @throws \API_Exception
37 public function testWithSingleField(): void
{
38 $customGroup = CustomGroup
::create(FALSE)
39 ->addValue('name', 'MyIndividualFields')
40 ->addValue('extends', 'Individual')
44 CustomField
::create(FALSE)
45 ->addValue('label', 'FavColor')
46 ->addValue('custom_group_id', $customGroup['id'])
47 ->addValue('html_type', 'Text')
48 ->addValue('data_type', 'String')
51 // Individual fields should show up when contact_type = null|Individual but not other contact types
52 $getFields = Contact
::getFields(FALSE);
53 $this->assertEquals('Custom', $getFields->execute()->indexBy('name')['MyIndividualFields.FavColor']['type']);
54 $this->assertContains('MyIndividualFields.FavColor', $getFields->setValues(['contact_type' => 'Individual'])->execute()->column('name'));
55 $this->assertNotContains('MyIndividualFields.FavColor', $getFields->setValues(['contact_type' => 'Household'])->execute()->column('name'));
57 $contactId = Contact
::create(FALSE)
58 ->addValue('first_name', 'Johann')
59 ->addValue('last_name', 'Tester')
60 ->addValue('contact_type', 'Individual')
61 ->addValue('MyIndividualFields.FavColor', 'Red')
65 $contact = Contact
::get(FALSE)
66 ->addSelect('first_name')
67 ->addSelect('MyIndividualFields.FavColor')
68 ->addWhere('id', '=', $contactId)
69 ->addWhere('MyIndividualFields.FavColor', '=', 'Red')
73 $this->assertEquals('Red', $contact['MyIndividualFields.FavColor']);
76 ->addWhere('id', '=', $contactId)
77 ->addValue('MyIndividualFields.FavColor', 'Blue')
80 $contact = Contact
::get(FALSE)
81 ->addSelect('MyIndividualFields.FavColor')
82 ->addWhere('id', '=', $contactId)
86 $this->assertEquals('Blue', $contact['MyIndividualFields.FavColor']);
89 public function testWithTwoFields() {
90 $optionGroupCount = OptionGroup
::get(FALSE)->selectRowCount()->execute()->count();
93 CustomGroup
::create(FALSE)
94 ->addValue('name', 'MyContactFields')
95 ->addValue('extends', 'Contact')
96 ->addChain('field1', CustomField
::create()
97 ->addValue('label', 'FavColor')
98 ->addValue('custom_group_id', '$id')
99 ->addValue('html_type', 'Text')
100 ->addValue('data_type', 'String'))
101 ->addChain('field2', CustomField
::create()
102 ->addValue('label', 'FavFood')
103 ->addValue('custom_group_id', '$id')
104 ->addValue('html_type', 'Text')
105 ->addValue('data_type', 'String'))
109 CustomGroup
::create(FALSE)
110 ->addValue('name', 'MyContactFields2')
111 ->addValue('extends', 'Contact')
112 ->addChain('field1', CustomField
::create()
113 ->addValue('label', 'FavColor')
114 ->addValue('custom_group_id', '$id')
115 ->addValue('html_type', 'Text')
116 ->addValue('data_type', 'String'))
117 ->addChain('field2', CustomField
::create()
118 ->addValue('label', 'FavFood')
119 ->addValue('custom_group_id', '$id')
120 ->addValue('html_type', 'Text')
121 ->addValue('data_type', 'String'))
124 // Test that no new option groups have been created (these are text fields with no options)
125 $this->assertEquals($optionGroupCount, OptionGroup
::get(FALSE)->selectRowCount()->execute()->count());
127 $contactId1 = Contact
::create(FALSE)
128 ->addValue('first_name', 'Johann')
129 ->addValue('last_name', 'Tester')
130 ->addValue('MyContactFields.FavColor', 'Red')
131 ->addValue('MyContactFields.FavFood', 'Cherry')
135 $contactId2 = Contact
::create(FALSE)
136 ->addValue('first_name', 'MaryLou')
137 ->addValue('last_name', 'Tester')
138 ->addValue('MyContactFields.FavColor', 'Purple')
139 ->addValue('MyContactFields.FavFood', 'Grapes')
143 $contact = Contact
::get(FALSE)
144 ->addSelect('first_name')
145 ->addSelect('MyContactFields.FavColor')
146 ->addSelect('MyContactFields.FavFood')
147 ->addWhere('id', '=', $contactId1)
148 ->addWhere('MyContactFields.FavColor', '=', 'Red')
149 ->addWhere('MyContactFields.FavFood', '=', 'Cherry')
152 $this->assertArrayHasKey('MyContactFields.FavColor', $contact);
153 $this->assertEquals('Red', $contact['MyContactFields.FavColor']);
155 // By default custom fields are not returned
156 $contact = Contact
::get(FALSE)
157 ->addWhere('id', '=', $contactId1)
158 ->addWhere('MyContactFields.FavColor', '=', 'Red')
159 ->addWhere('MyContactFields.FavFood', '=', 'Cherry')
162 $this->assertArrayNotHasKey('MyContactFields.FavColor', $contact);
164 // Update 2nd set and ensure 1st hasn't changed
166 ->addWhere('id', '=', $contactId1)
167 ->addValue('MyContactFields2.FavColor', 'Orange')
168 ->addValue('MyContactFields2.FavFood', 'Tangerine')
170 $contact = Contact
::get(FALSE)
171 ->addSelect('MyContactFields.FavColor', 'MyContactFields2.FavColor', 'MyContactFields.FavFood', 'MyContactFields2.FavFood')
172 ->addWhere('id', '=', $contactId1)
175 $this->assertEquals('Red', $contact['MyContactFields.FavColor']);
176 $this->assertEquals('Orange', $contact['MyContactFields2.FavColor']);
177 $this->assertEquals('Cherry', $contact['MyContactFields.FavFood']);
178 $this->assertEquals('Tangerine', $contact['MyContactFields2.FavFood']);
180 // Update 1st set and ensure 2st hasn't changed
182 ->addWhere('id', '=', $contactId1)
183 ->addValue('MyContactFields.FavColor', 'Blue')
185 $contact = Contact
::get(FALSE)
186 ->addSelect('custom.*')
187 ->addWhere('id', '=', $contactId1)
190 $this->assertEquals('Blue', $contact['MyContactFields.FavColor']);
191 $this->assertEquals('Orange', $contact['MyContactFields2.FavColor']);
192 $this->assertEquals('Cherry', $contact['MyContactFields.FavFood']);
193 $this->assertEquals('Tangerine', $contact['MyContactFields2.FavFood']);
195 $search = Contact
::get(FALSE)
196 ->addClause('OR', ['MyContactFields.FavColor', '=', 'Blue'], ['MyContactFields.FavFood', '=', 'Grapes'])
202 $this->assertEquals([$contactId1, $contactId2], array_keys((array) $search));
204 $search = Contact
::get(FALSE)
205 ->addClause('NOT', ['MyContactFields.FavColor', '=', 'Purple'], ['MyContactFields.FavFood', '=', 'Grapes'])
211 $this->assertNotContains($contactId2, array_keys((array) $search));
213 $search = Contact
::get(FALSE)
214 ->addClause('NOT', ['MyContactFields.FavColor', '=', 'Purple'], ['MyContactFields.FavFood', '=', 'Grapes'])
220 $this->assertContains($contactId1, array_keys((array) $search));
221 $this->assertNotContains($contactId2, array_keys((array) $search));
223 $search = Contact
::get(FALSE)
224 ->setWhere([['NOT', ['OR', [['MyContactFields.FavColor', '=', 'Blue'], ['MyContactFields.FavFood', '=', 'Grapes']]]]])
230 $this->assertNotContains($contactId1, array_keys((array) $search));
231 $this->assertNotContains($contactId2, array_keys((array) $search));
234 public function testRelationshipCacheCustomFields() {
235 $cgName = uniqid('RelFields');
237 $customGroup = CustomGroup
::create(FALSE)
238 ->addValue('name', $cgName)
239 ->addValue('extends', 'Relationship')
243 CustomField
::create(FALSE)
244 ->addValue('label', 'PetName')
245 ->addValue('custom_group_id', $customGroup['id'])
246 ->addValue('html_type', 'Text')
247 ->addValue('data_type', 'String')
250 $parent = Contact
::create(FALSE)
251 ->addValue('first_name', 'Parent')
252 ->addValue('last_name', 'Tester')
253 ->addValue('contact_type', 'Individual')
257 $child = Contact
::create(FALSE)
258 ->addValue('first_name', 'Child')
259 ->addValue('last_name', 'Tester')
260 ->addValue('contact_type', 'Individual')
264 $relationship = Relationship
::create(FALSE)
265 ->addValue('contact_id_a', $parent)
266 ->addValue('contact_id_b', $child)
267 ->addValue('relationship_type_id', 1)
268 ->addValue("$cgName.PetName", 'Buddy')
271 $results = RelationshipCache
::get(FALSE)
272 ->addSelect("$cgName.PetName")
273 ->addWhere("$cgName.PetName", '=', 'Buddy')
276 $this->assertCount(2, $results);
277 $this->assertEquals('Buddy', $results[0]["$cgName.PetName"]);
281 * Some types are creating a dummy option group even if we don't have
283 * @throws \API_Exception
285 public function testUndesiredOptionGroupCreation(): void
{
286 $optionGroupCount = OptionGroup
::get(FALSE)->selectRowCount()->execute()->count();
288 $customGroup = CustomGroup
::create(FALSE)
289 ->addValue('name', 'MyIndividualFields')
290 ->addValue('extends', 'Individual')
294 // This one doesn't make sense to have an option group.
295 CustomField
::create(FALSE)
296 ->addValue('label', 'FavColor')
297 ->addValue('custom_group_id', $customGroup['id'])
298 ->addValue('html_type', 'Number')
299 ->addValue('data_type', 'Money')
302 // This one might be ok if we planned to then use the autocreated option
303 // group, but if we go on to create our own after then we have an extra
305 CustomField
::create(FALSE)
306 ->addValue('label', 'FavMovie')
307 ->addValue('custom_group_id', $customGroup['id'])
308 ->addValue('html_type', 'Select')
309 ->addValue('data_type', 'String')
312 $this->assertEquals($optionGroupCount, OptionGroup
::get(FALSE)->selectRowCount()->execute()->count());