Commit | Line | Data |
---|---|---|
6a488035 | 1 | <?php |
0eea664b | 2 | |
6a488035 TO |
3 | /** |
4 | * Include dataProvider for tests | |
fb1ee468 | 5 | * |
acb109b7 | 6 | * @group headless |
6a488035 TO |
7 | */ |
8 | class CRM_Contact_BAO_QueryTest extends CiviUnitTestCase { | |
fb1ee468 | 9 | |
dbaa9d7d | 10 | use CRMTraits_Financial_FinancialACLTrait; |
faba82fc | 11 | use CRMTraits_Financial_PriceSetTrait; |
6a488035 | 12 | |
e9479dcf EM |
13 | /** |
14 | * @return CRM_Contact_BAO_QueryTestDataProvider | |
15 | */ | |
6a488035 | 16 | public function dataProvider() { |
acb1052e | 17 | return new CRM_Contact_BAO_QueryTestDataProvider(); |
6a488035 TO |
18 | } |
19 | ||
00be9182 | 20 | public function setUp() { |
6a488035 TO |
21 | parent::setUp(); |
22 | } | |
23 | ||
c69ecb12 | 24 | /** |
25 | * Clean up after test. | |
26 | * | |
27 | * @throws \Exception | |
28 | */ | |
00be9182 | 29 | public function tearDown() { |
faba82fc | 30 | $this->quickCleanUpFinancialEntities(); |
c69ecb12 | 31 | $tablesToTruncate = [ |
6a488035 TO |
32 | 'civicrm_group_contact', |
33 | 'civicrm_group', | |
34 | 'civicrm_saved_search', | |
35 | 'civicrm_entity_tag', | |
36 | 'civicrm_tag', | |
37 | 'civicrm_contact', | |
9b1e4469 | 38 | 'civicrm_address', |
c69ecb12 | 39 | ]; |
6a488035 | 40 | $this->quickCleanup($tablesToTruncate); |
673fae6c | 41 | parent::tearDown(); |
6a488035 TO |
42 | } |
43 | ||
44 | /** | |
3af96592 | 45 | * Test CRM_Contact_BAO_Query::searchQuery(). |
46 | * | |
6c6e6187 | 47 | * @dataProvider dataProvider |
3af96592 | 48 | * |
1e1fdcf6 EM |
49 | * @param $fv |
50 | * @param $count | |
51 | * @param $ids | |
8f36c0f5 | 52 | * |
53 | * @throws \CRM_Core_Exception | |
6a488035 | 54 | */ |
8f36c0f5 | 55 | public function testSearch($fv, $count, $ids) { |
c69ecb12 | 56 | $this->callAPISuccess('SavedSearch', 'create', ['form_values' => 'a:9:{s:5:"qfKey";s:32:"0123456789abcdef0123456789abcdef";s:13:"includeGroups";a:1:{i:0;s:1:"3";}s:13:"excludeGroups";a:0:{}s:11:"includeTags";a:0:{}s:11:"excludeTags";a:0:{}s:4:"task";s:2:"14";s:8:"radio_ts";s:6:"ts_all";s:14:"customSearchID";s:1:"4";s:17:"customSearchClass";s:36:"CRM_Contact_Form_Search_Custom_Group";}']); |
57 | $this->callAPISuccess('SavedSearch', 'create', ['form_values' => 'a:9:{s:5:"qfKey";s:32:"0123456789abcdef0123456789abcdef";s:13:"includeGroups";a:1:{i:0;s:1:"3";}s:13:"excludeGroups";a:0:{}s:11:"includeTags";a:0:{}s:11:"excludeTags";a:0:{}s:4:"task";s:2:"14";s:8:"radio_ts";s:6:"ts_all";s:14:"customSearchID";s:1:"4";s:17:"customSearchClass";s:36:"CRM_Contact_Form_Search_Custom_Group";}']); | |
58 | ||
59 | $tag7 = $this->ids['Tag'][7] = $this->tagCreate(['name' => 'Test Tag 7', 'description' => 'Test Tag 7'])['id']; | |
60 | $tag9 = $this->ids['Tag'][9] = $this->tagCreate(['name' => 'Test Tag 9', 'description' => 'Test Tag 9'])['id']; | |
fe128a5a MD |
61 | $tag10 = $this->ids['Tag'][10] = $this->tagCreate(['name' => 'Test Tag 10', 'description' => 'Test Tag 10', 'parent_id' => $tag9])['id']; |
62 | $tag11 = $this->ids['Tag'][11] = $this->tagCreate(['name' => 'Test Tag 11', 'description' => 'Test Tag 11', 'parent_id' => $tag10])['id']; | |
63 | ||
c69ecb12 | 64 | $groups = [ |
65 | 3 => ['name' => 'Test Group 3'], | |
66 | 4 => ['name' => 'Test Smart Group 4', 'saved_search_id' => 1], | |
67 | 5 => ['name' => 'Test Group 5'], | |
68 | 6 => ['name' => 'Test Smart Group 6', 'saved_search_id' => 2], | |
69 | ]; | |
70 | ||
71 | foreach ($groups as $id => $group) { | |
72 | $this->ids['Group'][$id] = $this->groupCreate(array_merge($group, ['title' => $group['name']])); | |
73 | } | |
74 | $individuals = [ | |
75 | ['first_name' => 'Test', 'last_name' => 'Test Contact 9', 'gender_id' => 1, 'prefix_id' => 1, 'suffix_id' => 1], | |
76 | ['first_name' => 'Test', 'last_name' => 'Test Contact 10', 'gender_id' => 2, 'prefix_id' => 2, 'suffix_id' => 2, 'api.entity_tag.create' => ['tag_id' => $tag9]], | |
77 | ['first_name' => 'Test', 'last_name' => 'Test Contact 11', 'gender_id' => 3, 'prefix_id' => 3, 'suffix_id' => 3, 'api.entity_tag.create' => ['tag_id' => $tag7]], | |
fb1ee468 | 78 | [ |
79 | 'first_name' => 'Test', | |
80 | 'last_name' => 'Test Contact 12', | |
81 | 'gender_id' => 3, | |
82 | 'prefix_id' => 4, | |
83 | 'suffix_id' => 4, | |
84 | 'api.entity_tag.create' => ['tag_id' => $tag9], | |
85 | 'api.entity_tag.create.2' => ['tag_id' => $tag7], | |
86 | ], | |
c69ecb12 | 87 | ['first_name' => 'Test', 'last_name' => 'Test Contact 13', 'gender_id' => 2, 'prefix_id' => 2, 'suffix_id' => 2], |
88 | ['first_name' => 'Test', 'last_name' => 'Test Contact 14', 'gender_id' => 3, 'prefix_id' => 4, 'suffix_id' => 4, 'api.entity_tag.create' => ['tag_id' => $tag9]], | |
89 | ['first_name' => 'Test', 'last_name' => 'Test Contact 15', 'gender_id' => 3, 'prefix_id' => 4, 'suffix_id' => 5, 'api.entity_tag.create' => ['tag_id' => $tag7]], | |
fb1ee468 | 90 | [ |
91 | 'first_name' => 'Test', | |
92 | 'last_name' => 'Test Contact 16', | |
93 | 'gender_id' => 3, | |
94 | 'prefix_id' => 4, | |
95 | 'suffix_id' => 6, | |
96 | 'api.entity_tag.create' => ['tag_id' => $tag9], | |
97 | 'api.entity_tag.create.2' => ['tag_id' => $tag7], | |
98 | ], | |
c69ecb12 | 99 | ['first_name' => 'Test', 'last_name' => 'Test Contact 17', 'gender_id' => 2, 'prefix_id' => 4, 'suffix_id' => 7], |
100 | ['first_name' => 'Test', 'last_name' => 'Test Contact 18', 'gender_id' => 2, 'prefix_id' => 4, 'suffix_id' => 4, 'api.entity_tag.create' => ['tag_id' => $tag9]], | |
101 | ['first_name' => 'Test', 'last_name' => 'Test Contact 19', 'gender_id' => 2, 'prefix_id' => 4, 'suffix_id' => 6, 'api.entity_tag.create.2' => ['tag_id' => $tag7]], | |
fb1ee468 | 102 | [ |
103 | 'first_name' => 'Test', | |
104 | 'last_name' => 'Test Contact 20', | |
105 | 'gender_id' => 1, | |
106 | 'prefix_id' => 4, | |
107 | 'suffix_id' => 6, | |
108 | 'api.entity_tag.create' => ['tag_id' => $tag9], | |
109 | 'api.entity_tag.create.2' => ['tag_id' => $tag7], | |
110 | ], | |
c69ecb12 | 111 | ['first_name' => 'Test', 'last_name' => 'Test Contact 21', 'gender_id' => 3, 'prefix_id' => 1, 'suffix_id' => 6], |
112 | ['first_name' => 'Test', 'last_name' => 'Test Contact 22', 'gender_id' => 1, 'prefix_id' => 1, 'suffix_id' => 1, 'api.entity_tag.create' => ['tag_id' => $tag9]], | |
113 | ['first_name' => 'Test', 'last_name' => 'Test Contact 23', 'gender_id' => 3, 'prefix_id' => 1, 'suffix_id' => 1, 'api.entity_tag.create' => ['tag_id' => $tag7]], | |
fb1ee468 | 114 | [ |
115 | 'first_name' => 'Test', | |
116 | 'last_name' => 'Test Contact 24', | |
117 | 'gender_id' => 3, | |
118 | 'prefix_id' => 3, | |
119 | 'suffix_id' => 2, | |
120 | 'api.entity_tag.create' => ['tag_id' => $tag9], | |
121 | 'api.entity_tag.create.2' => ['tag_id' => $tag7], | |
122 | ], | |
fe128a5a MD |
123 | ['first_name' => 'Test', 'last_name' => 'Test Contact 25', 'api.entity_tag.create' => ['tag_id' => $tag10]], |
124 | ['first_name' => 'Test', 'last_name' => 'Test Contact 26', 'api.entity_tag.create' => ['tag_id' => $tag11]], | |
c69ecb12 | 125 | ]; |
126 | foreach ($individuals as $individual) { | |
127 | $this->ids['Contact'][$individual['last_name']] = $this->individualCreate($individual); | |
128 | } | |
129 | $groupContacts = [ | |
130 | [5 => 13], | |
131 | [5 => 14], | |
132 | [5 => 15], | |
133 | [5 => 16], | |
134 | [5 => 21], | |
135 | [5 => 22], | |
136 | [5 => 23], | |
137 | [5 => 24], | |
138 | [3 => 17], | |
139 | [3 => 18], | |
140 | [3 => 19], | |
141 | [3 => 20], | |
142 | [3 => 21], | |
143 | [3 => 22], | |
144 | [3 => 23], | |
145 | [3 => 24], | |
146 | ]; | |
147 | foreach ($groupContacts as $group) { | |
148 | $groupID = $this->ids['Group'][key($group)]; | |
149 | $contactID = $this->ids['Contact']['Test Contact ' . reset($group)]; | |
150 | $this->callAPISuccess('GroupContact', 'create', ['group_id' => $groupID, 'contact_id' => $contactID, 'status' => 'Added']); | |
151 | } | |
152 | ||
153 | // We have migrated from a hard-coded dataset to a dynamic one but are still working with the same | |
154 | // dataprovider at this stage -> wrangle. | |
155 | foreach ($fv as $key => $value) { | |
156 | $entity = ucfirst($key); | |
157 | if (!array_key_exists($entity, $this->ids)) { | |
158 | continue; | |
159 | } | |
160 | if (is_numeric($value)) { | |
161 | $fv[$key] = $this->ids[$entity][$value]; | |
162 | } | |
163 | elseif (!empty($value[0])) { | |
164 | foreach ($value as $index => $oldGroup) { | |
165 | $fv[$key][$index] = $this->ids[$entity][$oldGroup]; | |
166 | } | |
167 | } | |
168 | else { | |
169 | foreach (array_keys($value) as $index) { | |
170 | unset($fv[$key][$index]); | |
171 | $fv[$key][$this->ids[$entity][$index]] = 1; | |
172 | } | |
173 | } | |
174 | } | |
6a488035 TO |
175 | |
176 | $params = CRM_Contact_BAO_Query::convertFormValues($fv); | |
92915c55 | 177 | $obj = new CRM_Contact_BAO_Query($params); |
b81f44dd | 178 | |
179 | // let's set useGroupBy=true since we are listing contacts here who might belong to | |
180 | // more than one group / tag / notes etc. | |
181 | $obj->_useGroupBy = TRUE; | |
182 | ||
92915c55 | 183 | $dao = $obj->searchQuery(); |
6a488035 | 184 | |
c69ecb12 | 185 | $contacts = []; |
6a488035 TO |
186 | while ($dao->fetch()) { |
187 | $contacts[] = $dao->contact_id; | |
188 | } | |
189 | ||
190 | sort($contacts, SORT_NUMERIC); | |
191 | ||
c69ecb12 | 192 | $expectedIDs = []; |
193 | foreach ($ids as $id) { | |
194 | $expectedIDs[] = $this->ids['Contact']['Test Contact ' . $id]; | |
195 | } | |
fe128a5a | 196 | |
c69ecb12 | 197 | $this->assertEquals($expectedIDs, $contacts); |
6a488035 | 198 | } |
e5fccefb EM |
199 | |
200 | /** | |
eceb18cc | 201 | * Check that we get a successful result querying for home address. |
e5fccefb | 202 | * CRM-14263 search builder failure with search profile & address in criteria |
8f36c0f5 | 203 | * |
204 | * @throws \CRM_Core_Exception | |
e5fccefb | 205 | */ |
00be9182 | 206 | public function testSearchProfileHomeCityCRM14263() { |
e5fccefb | 207 | $contactID = $this->individualCreate(); |
c26679b7 | 208 | Civi::settings()->set('defaultSearchProfileID', 1); |
fb1ee468 | 209 | $this->callAPISuccess('address', 'create', [ |
39b959db SL |
210 | 'contact_id' => $contactID, |
211 | 'city' => 'Cool City', | |
212 | 'location_type_id' => 1, | |
fb1ee468 | 213 | ]); |
214 | $params = [ | |
215 | 0 => [ | |
e5fccefb EM |
216 | 0 => 'city-1', |
217 | 1 => '=', | |
218 | 2 => 'Cool City', | |
219 | 3 => 1, | |
220 | 4 => 0, | |
fb1ee468 | 221 | ], |
222 | ]; | |
223 | $returnProperties = [ | |
e5fccefb EM |
224 | 'contact_type' => 1, |
225 | 'contact_sub_type' => 1, | |
226 | 'sort_name' => 1, | |
fb1ee468 | 227 | ]; |
e5fccefb EM |
228 | |
229 | $queryObj = new CRM_Contact_BAO_Query($params, $returnProperties); | |
230 | try { | |
63ae2e7b | 231 | $resultDAO = $queryObj->searchQuery(); |
55eb4e22 | 232 | $this->assertTrue($resultDAO->fetch()); |
e5fccefb | 233 | } |
55eb4e22 EM |
234 | catch (PEAR_Exception $e) { |
235 | $err = $e->getCause(); | |
c26679b7 | 236 | $this->fail('invalid SQL created' . $e->getMessage() . ' ' . $err->userinfo); |
e5fccefb | 237 | |
55eb4e22 | 238 | } |
e5fccefb EM |
239 | } |
240 | ||
55eb4e22 | 241 | /** |
eceb18cc | 242 | * Check that we get a successful result querying for home address. |
55eb4e22 | 243 | * CRM-14263 search builder failure with search profile & address in criteria |
8f36c0f5 | 244 | * |
245 | * @throws \CRM_Core_Exception | |
55eb4e22 | 246 | */ |
00be9182 | 247 | public function testSearchProfileHomeCityNoResultsCRM14263() { |
55eb4e22 | 248 | $contactID = $this->individualCreate(); |
c26679b7 | 249 | Civi::settings()->set('defaultSearchProfileID', 1); |
fb1ee468 | 250 | $this->callAPISuccess('address', 'create', [ |
39b959db SL |
251 | 'contact_id' => $contactID, |
252 | 'city' => 'Cool City', | |
253 | 'location_type_id' => 1, | |
fb1ee468 | 254 | ]); |
255 | $params = [ | |
256 | 0 => [ | |
55eb4e22 EM |
257 | 0 => 'city-1', |
258 | 1 => '=', | |
259 | 2 => 'Dumb City', | |
260 | 3 => 1, | |
261 | 4 => 0, | |
fb1ee468 | 262 | ], |
263 | ]; | |
264 | $returnProperties = [ | |
55eb4e22 EM |
265 | 'contact_type' => 1, |
266 | 'contact_sub_type' => 1, | |
267 | 'sort_name' => 1, | |
fb1ee468 | 268 | ]; |
55eb4e22 EM |
269 | |
270 | $queryObj = new CRM_Contact_BAO_Query($params, $returnProperties); | |
271 | try { | |
63ae2e7b | 272 | $resultDAO = $queryObj->searchQuery(); |
55eb4e22 EM |
273 | $this->assertFalse($resultDAO->fetch()); |
274 | } | |
275 | catch (PEAR_Exception $e) { | |
276 | $err = $e->getCause(); | |
c26679b7 | 277 | $this->fail('invalid SQL created' . $e->getMessage() . ' ' . $err->userinfo); |
55eb4e22 EM |
278 | |
279 | } | |
280 | } | |
92915c55 | 281 | |
b3e1c09d | 282 | /** |
a3fccfc7 | 283 | * Test searchPrimaryDetailsOnly setting. |
8f36c0f5 | 284 | * |
285 | * @throws \CRM_Core_Exception | |
b3e1c09d | 286 | */ |
9349bcf7 | 287 | public function testSearchPrimaryLocTypes() { |
b3e1c09d | 288 | $contactID = $this->individualCreate(); |
fb1ee468 | 289 | $params = [ |
b3e1c09d | 290 | 'contact_id' => $contactID, |
291 | 'email' => 'primary@example.com', | |
292 | 'is_primary' => 1, | |
fb1ee468 | 293 | ]; |
b3e1c09d | 294 | $this->callAPISuccess('email', 'create', $params); |
295 | ||
296 | unset($params['is_primary']); | |
297 | $params['email'] = 'secondary@team.com'; | |
298 | $this->callAPISuccess('email', 'create', $params); | |
299 | ||
fb1ee468 | 300 | foreach ([0, 1] as $searchPrimary) { |
a3fccfc7 | 301 | Civi::settings()->set('searchPrimaryDetailsOnly', $searchPrimary); |
b3e1c09d | 302 | |
fb1ee468 | 303 | $params = [ |
304 | 0 => [ | |
b3e1c09d | 305 | 0 => 'email', |
306 | 1 => 'LIKE', | |
c245fd99 | 307 | 2 => 'sEcondary@example.com', |
b3e1c09d | 308 | 3 => 0, |
309 | 4 => 1, | |
fb1ee468 | 310 | ], |
311 | ]; | |
312 | $returnProperties = [ | |
b3e1c09d | 313 | 'contact_type' => 1, |
314 | 'contact_sub_type' => 1, | |
315 | 'sort_name' => 1, | |
fb1ee468 | 316 | ]; |
b3e1c09d | 317 | |
318 | $queryObj = new CRM_Contact_BAO_Query($params, $returnProperties); | |
63ae2e7b | 319 | $resultDAO = $queryObj->searchQuery(); |
b3e1c09d | 320 | |
321 | if ($searchPrimary) { | |
322 | $this->assertEquals($resultDAO->N, 0); | |
323 | } | |
324 | else { | |
325 | //Assert secondary email gets included in search results. | |
326 | while ($resultDAO->fetch()) { | |
327 | $this->assertEquals('secondary@example.com', $resultDAO->email); | |
328 | } | |
329 | } | |
330 | ||
331 | // API should always return primary email. | |
fb1ee468 | 332 | $result = $this->callAPISuccess('Contact', 'get', ['contact_id' => $contactID]); |
b3e1c09d | 333 | $this->assertEquals('primary@example.com', $result['values'][$contactID]['email']); |
334 | } | |
335 | } | |
336 | ||
db1a73f5 KE |
337 | /** |
338 | * Test created to prove failure of search on state when location | |
339 | * display name is different form location name (issue 607) | |
8f36c0f5 | 340 | * |
341 | * @throws \CRM_Core_Exception | |
db1a73f5 KE |
342 | */ |
343 | public function testSearchOtherLocationUpperLower() { | |
344 | ||
345 | $params = [ | |
346 | 0 => [ | |
347 | 0 => 'state_province-4', | |
348 | 1 => 'IS NOT EMPTY', | |
349 | 2 => '', | |
350 | 3 => 1, | |
351 | 4 => 0, | |
352 | ], | |
353 | ]; | |
354 | $returnProperties = [ | |
355 | 'contact_type' => 1, | |
356 | 'contact_sub_type' => 1, | |
357 | 'sort_name' => 1, | |
358 | 'location' => [ | |
359 | 'other' => [ | |
360 | 'location_type' => 4, | |
361 | 'state_province' => 1, | |
362 | ], | |
363 | ], | |
364 | ]; | |
365 | ||
6f1ae9ee KE |
366 | // update with the api does not work because it updates both the name and the |
367 | // the display_name. Plain SQL however does the job | |
db1a73f5 KE |
368 | CRM_Core_DAO::executeQuery('update civicrm_location_type set name=%2 where id=%1', |
369 | [ | |
370 | 1 => [4, 'Integer'], | |
371 | 2 => ['other', 'String'], | |
372 | ]); | |
373 | ||
374 | $queryObj = new CRM_Contact_BAO_Query($params, $returnProperties); | |
375 | ||
63ae2e7b | 376 | $resultDAO = $queryObj->searchQuery(); |
db1a73f5 KE |
377 | $resultDAO->fetch(); |
378 | } | |
379 | ||
6c6e6187 | 380 | /** |
fea8ae41 | 381 | * CRM-14263 search builder failure with search profile & address in criteria. |
382 | * | |
6c6e6187 TO |
383 | * We are retrieving primary here - checking the actual sql seems super prescriptive - but since the massive query object has |
384 | * so few tests detecting any change seems good here :-) | |
fea8ae41 | 385 | * |
386 | * @dataProvider getSearchProfileData | |
387 | * | |
388 | * @param array $params | |
39b959db SL |
389 | * @param string $selectClause |
390 | * @param string $whereClause | |
fb1ee468 | 391 | * |
392 | * @throws \CRM_Core_Exception | |
6c6e6187 | 393 | */ |
fea8ae41 | 394 | public function testSearchProfilePrimaryCityCRM14263($params, $selectClause, $whereClause) { |
6c6e6187 | 395 | $contactID = $this->individualCreate(); |
c26679b7 | 396 | Civi::settings()->set('defaultSearchProfileID', 1); |
fb1ee468 | 397 | $this->callAPISuccess('address', 'create', [ |
39b959db SL |
398 | 'contact_id' => $contactID, |
399 | 'city' => 'Cool CITY', | |
400 | 'street_address' => 'Long STREET', | |
401 | 'location_type_id' => 1, | |
fb1ee468 | 402 | ]); |
403 | $returnProperties = [ | |
92915c55 TO |
404 | 'contact_type' => 1, |
405 | 'contact_sub_type' => 1, | |
406 | 'sort_name' => 1, | |
fb1ee468 | 407 | ]; |
99827266 | 408 | $expectedSQL = 'SELECT contact_a.id as contact_id, contact_a.contact_type as `contact_type`, contact_a.contact_sub_type as `contact_sub_type`, contact_a.sort_name as `sort_name`, civicrm_address.id as address_id, ' . $selectClause . " FROM civicrm_contact contact_a LEFT JOIN civicrm_address ON ( contact_a.id = civicrm_address.contact_id AND civicrm_address.is_primary = 1 ) WHERE ( ( " . $whereClause . " ) ) AND ( 1 ) AND (contact_a.is_deleted = 0) ORDER BY `contact_a`.`sort_name` ASC, `contact_a`.`id` "; |
6c6e6187 TO |
409 | $queryObj = new CRM_Contact_BAO_Query($params, $returnProperties); |
410 | try { | |
299c1530 | 411 | $this->assertLike($expectedSQL, $queryObj->getSearchSQL()); |
fea8ae41 | 412 | list($select, $from, $where, $having) = $queryObj->query(); |
413 | $dao = CRM_Core_DAO::executeQuery("$select $from $where $having"); | |
414 | $dao->fetch(); | |
415 | $this->assertEquals('Anderson, Anthony', $dao->sort_name); | |
6c6e6187 TO |
416 | } |
417 | catch (PEAR_Exception $e) { | |
418 | $err = $e->getCause(); | |
c26679b7 | 419 | $this->fail('invalid SQL created' . $e->getMessage() . ' ' . $err->userinfo); |
55eb4e22 | 420 | |
55eb4e22 | 421 | } |
6c6e6187 | 422 | } |
96025800 | 423 | |
fea8ae41 | 424 | /** |
425 | * Get data sets to test for search. | |
426 | */ | |
427 | public function getSearchProfileData() { | |
428 | return [ | |
429 | [ | |
fb1ee468 | 430 | [['city', '=', 'Cool City', 1, 0]], |
c26679b7 | 431 | 'civicrm_address.city as `city`', |
fb1ee468 | 432 | "civicrm_address.city = 'Cool City'", |
fea8ae41 | 433 | ], |
434 | [ | |
435 | // Note that in the query 'long street' is lower cased. We eventually want to change that & not mess with the vars - it turns out | |
436 | // it doesn't work on some charsets. However, the the lcasing affects more vars & we are looking to stagger removal of lcasing 'in case' | |
437 | // (although we have been removing without blowback since 2017) | |
fb1ee468 | 438 | [['street_address', '=', 'Long Street', 1, 0]], |
c26679b7 | 439 | 'civicrm_address.street_address as `street_address`', |
fb1ee468 | 440 | "civicrm_address.street_address LIKE '%Long Street%'", |
fea8ae41 | 441 | ], |
442 | ]; | |
443 | } | |
444 | ||
fd11fc34 | 445 | /** |
446 | * Test similarly handled activity fields qill and where clauses. | |
447 | * | |
448 | * @throws \CRM_Core_Exception | |
449 | */ | |
450 | public function testSearchBuilderActivityType() { | |
451 | $queryObj = new CRM_Contact_BAO_Query([['activity_type', '=', '3', 1, 0]]); | |
452 | $this->assertContains('WHERE ( ( civicrm_activity.activity_type_id = 3 )', $queryObj->getSearchSQL()); | |
453 | $this->assertEquals('Activity Type = Email', $queryObj->_qill[1][0]); | |
454 | ||
455 | $queryObj = new CRM_Contact_BAO_Query([['activity_type_id', '=', '3', 1, 0]]); | |
456 | $this->assertContains('WHERE ( ( civicrm_activity.activity_type_id = 3 )', $queryObj->getSearchSQL()); | |
457 | $this->assertEquals('Activity Type ID = Email', $queryObj->_qill[1][0]); | |
458 | ||
459 | $queryObj = new CRM_Contact_BAO_Query([['activity_status', '=', '3', 1, 0]]); | |
460 | $this->assertContains('WHERE ( ( civicrm_activity.status_id = 3 )', $queryObj->getSearchSQL()); | |
461 | $this->assertEquals('Activity Status = Cancelled', $queryObj->_qill[1][0]); | |
462 | ||
463 | $queryObj = new CRM_Contact_BAO_Query([['activity_status_id', '=', '3', 1, 0]]); | |
464 | $this->assertContains('WHERE ( ( civicrm_activity.status_id = 3 )', $queryObj->getSearchSQL()); | |
465 | $this->assertEquals('Activity Status = Cancelled', $queryObj->_qill[1][0]); | |
466 | ||
467 | $queryObj = new CRM_Contact_BAO_Query([['activity_engagement_level', '=', '3', 1, 0]]); | |
468 | $this->assertContains('WHERE ( ( civicrm_activity.engagement_level = 3 )', $queryObj->getSearchSQL()); | |
469 | $this->assertEquals('Engagement Index = 3', $queryObj->_qill[1][0]); | |
470 | ||
471 | $queryObj = new CRM_Contact_BAO_Query([['activity_id', '=', '3', 1, 0]]); | |
472 | $this->assertContains('WHERE ( ( civicrm_activity.id = 3 )', $queryObj->getSearchSQL()); | |
473 | $this->assertEquals('Activity ID = 3', $queryObj->_qill[1][0]); | |
474 | ||
475 | $queryObj = new CRM_Contact_BAO_Query([['activity_campaign_id', '=', '3', 1, 0]]); | |
476 | $this->assertContains('WHERE ( ( civicrm_activity.campaign_id = 3 )', $queryObj->getSearchSQL()); | |
477 | $this->assertEquals('Campaign = 3', $queryObj->_qill[1][0]); | |
478 | ||
479 | $queryObj = new CRM_Contact_BAO_Query([['activity_priority_id', '=', '3', 1, 0]]); | |
480 | $this->assertContains('WHERE ( ( civicrm_activity.priority_id = 3 )', $queryObj->getSearchSQL()); | |
481 | $this->assertEquals('Priority = Low', $queryObj->_qill[1][0]); | |
482 | ||
483 | $queryObj = new CRM_Contact_BAO_Query([['activity_subject', '=', '3', 1, 0]]); | |
484 | $this->assertContains("WHERE ( ( civicrm_activity.subject = '3' )", $queryObj->getSearchSQL()); | |
485 | $this->assertEquals("Subject = '3'", $queryObj->_qill[1][0]); | |
486 | } | |
487 | ||
82ae55f4 | 488 | /** |
489 | * Test set up to test calling the query object per GroupContactCache BAO usage. | |
490 | * | |
491 | * CRM-17254 ensure that if only the contact_id is required other fields should | |
492 | * not be appended. | |
fd11fc34 | 493 | * |
494 | * @throws \CRM_Core_Exception | |
82ae55f4 | 495 | */ |
496 | public function testGroupContactCacheAddSearch() { | |
fb1ee468 | 497 | $returnProperties = ['contact_id']; |
498 | $params = [['group', 'IN', [1], 0, 0]]; | |
82ae55f4 | 499 | |
500 | $query = new CRM_Contact_BAO_Query( | |
501 | $params, $returnProperties, | |
502 | NULL, TRUE, FALSE, 1, | |
503 | TRUE, | |
504 | TRUE, FALSE | |
505 | ); | |
506 | ||
c26679b7 | 507 | list($select) = $query->query(); |
82ae55f4 | 508 | $this->assertEquals('SELECT contact_a.id as contact_id', $select); |
509 | } | |
510 | ||
9b1e4469 | 511 | /** |
512 | * Test smart groups with non-numeric don't fail on range queries. | |
513 | * | |
0e480632 | 514 | * @see https://issues.civicrm.org/jira/browse/CRM-14720 |
8f36c0f5 | 515 | * |
516 | * @throws \CRM_Core_Exception | |
9b1e4469 | 517 | */ |
518 | public function testNumericPostal() { | |
91c164ed | 519 | // Precaution as hitting some inconsistent set up running in isolation vs in the suite. |
520 | CRM_Core_DAO::executeQuery('UPDATE civicrm_address SET postal_code = NULL'); | |
521 | ||
fb1ee468 | 522 | $this->individualCreate(['api.address.create' => ['postal_code' => 5, 'location_type_id' => 'Main']]); |
523 | $this->individualCreate(['api.address.create' => ['postal_code' => 'EH10 4RB-889', 'location_type_id' => 'Main']]); | |
524 | $this->individualCreate(['api.address.create' => ['postal_code' => '4', 'location_type_id' => 'Main']]); | |
525 | $this->individualCreate(['api.address.create' => ['postal_code' => '6', 'location_type_id' => 'Main']]); | |
526 | $this->individualCreate(['api.address.create' => ['street_address' => 'just a street', 'location_type_id' => 'Main']]); | |
527 | $this->individualCreate(['api.address.create' => ['postal_code' => '12345678444455555555555555555555555555555555551314151617181920', 'location_type_id' => 'Main']]); | |
9b1e4469 | 528 | |
fb1ee468 | 529 | $params = [['postal_code_low', '=', 5, 0, 0]]; |
9b1e4469 | 530 | CRM_Contact_BAO_Query::convertFormValues($params); |
531 | ||
532 | $query = new CRM_Contact_BAO_Query( | |
fb1ee468 | 533 | $params, ['contact_id'], |
9b1e4469 | 534 | NULL, TRUE, FALSE, 1, |
535 | TRUE, | |
536 | TRUE, FALSE | |
537 | ); | |
538 | ||
c26679b7 | 539 | $sql = $query->query(); |
9b1e4469 | 540 | $result = CRM_Core_DAO::executeQuery(implode(' ', $sql)); |
541 | $this->assertEquals(2, $result->N); | |
542 | ||
543 | // We save this as a smart group and then load it. With mysql warnings on & CRM-14720 this | |
544 | // results in mysql warnings & hence fatal errors. | |
545 | /// I was unable to get mysql warnings to activate in the context of the unit tests - but | |
546 | // felt this code still provided a useful bit of coverage as it runs the various queries to load | |
547 | // the group & could generate invalid sql if a bug were introduced. | |
fb1ee468 | 548 | $groupParams = ['title' => 'postal codes', 'formValues' => $params, 'is_active' => 1]; |
9b1e4469 | 549 | $group = CRM_Contact_BAO_Group::createSmartGroup($groupParams); |
550 | CRM_Contact_BAO_GroupContactCache::load($group, TRUE); | |
551 | } | |
552 | ||
30415e03 | 553 | /** |
554 | * Test searches are case insensitive. | |
8f36c0f5 | 555 | * |
556 | * @throws \CRM_Core_Exception | |
30415e03 | 557 | */ |
558 | public function testCaseInsensitive() { | |
fb1ee468 | 559 | $orgID = $this->organizationCreate(['organization_name' => 'BOb']); |
560 | $params = [ | |
1809f3cf | 561 | 'display_name' => 'Minnie Mouse', |
562 | 'first_name' => 'Minnie', | |
563 | 'last_name' => 'Mouse', | |
564 | 'employer_id' => $orgID, | |
565 | 'contact_type' => 'Individual', | |
566 | 'nick_name' => 'Mins', | |
fb1ee468 | 567 | ]; |
1809f3cf | 568 | $this->callAPISuccess('Contact', 'create', $params); |
569 | unset($params['contact_type']); | |
570 | foreach ($params as $key => $value) { | |
8f36c0f5 | 571 | if ($key === 'employer_id') { |
fb1ee468 | 572 | $searchParams = [['current_employer', '=', 'bob', 0, 1]]; |
1809f3cf | 573 | } |
574 | else { | |
fb1ee468 | 575 | $searchParams = [[$key, '=', strtolower($value), 0, 1]]; |
1809f3cf | 576 | } |
8f36c0f5 | 577 | |
676a6ff4 | 578 | [$result] = CRM_Contact_BAO_Query::apiQuery($searchParams); |
579 | $this->assertCount(1, $result, 'search for ' . $key); | |
580 | $contact = reset($result); | |
1809f3cf | 581 | $this->assertEquals('Minnie Mouse', $contact['display_name']); |
582 | $this->assertEquals('BOb', $contact['current_employer']); | |
583 | } | |
30415e03 | 584 | } |
585 | ||
9a1491bb | 586 | /** |
587 | * Test smart groups with non-numeric don't fail on equal queries. | |
588 | * | |
0e480632 | 589 | * @see https://issues.civicrm.org/jira/browse/CRM-14720 |
8f36c0f5 | 590 | * |
591 | * @throws \CRM_Core_Exception | |
9a1491bb | 592 | */ |
593 | public function testNonNumericEqualsPostal() { | |
fb1ee468 | 594 | $this->individualCreate(['api.address.create' => ['postal_code' => 5, 'location_type_id' => 'Main']]); |
595 | $this->individualCreate(['api.address.create' => ['postal_code' => 'EH10 4RB-889', 'location_type_id' => 'Main']]); | |
596 | $this->individualCreate(['api.address.create' => ['postal_code' => '4', 'location_type_id' => 'Main']]); | |
597 | $this->individualCreate(['api.address.create' => ['postal_code' => '6', 'location_type_id' => 'Main']]); | |
9a1491bb | 598 | |
fb1ee468 | 599 | $params = [['postal_code', '=', 'EH10 4RB-889', 0, 0]]; |
9a1491bb | 600 | CRM_Contact_BAO_Query::convertFormValues($params); |
601 | ||
602 | $query = new CRM_Contact_BAO_Query( | |
fb1ee468 | 603 | $params, ['contact_id'], |
9a1491bb | 604 | NULL, TRUE, FALSE, 1, |
605 | TRUE, | |
606 | TRUE, FALSE | |
607 | ); | |
608 | ||
609 | $sql = $query->query(FALSE); | |
2fc64082 | 610 | $this->assertEquals("WHERE ( civicrm_address.postal_code = 'EH10 4RB-889' ) AND (contact_a.is_deleted = 0)", $sql[2]); |
9a1491bb | 611 | $result = CRM_Core_DAO::executeQuery(implode(' ', $sql)); |
612 | $this->assertEquals(1, $result->N); | |
613 | ||
614 | } | |
615 | ||
8f36c0f5 | 616 | /** |
617 | * Test relationship description. | |
618 | * | |
619 | * @throws \CRM_Core_Exception | |
620 | */ | |
6e83b317 CW |
621 | public function testRelationshipDescription() { |
622 | $relType = $this->callAPISuccess('RelationshipType', 'create', [ | |
8f36c0f5 | 623 | 'name_a_b' => 'blah', |
624 | 'name_b_a' => 'other blah', | |
6e83b317 CW |
625 | ]); |
626 | $contactID_a = $this->individualCreate([], 1); | |
627 | $contactID_b = $this->individualCreate([], 2); | |
628 | $contactID_c = $this->individualCreate([], 3); | |
629 | $contactID_d = $this->individualCreate([], 4); | |
630 | $desc = uniqid('rel', TRUE); | |
631 | $this->callAPISuccess('Relationship', 'create', [ | |
632 | 'contact_id_a' => $contactID_a, | |
633 | 'contact_id_b' => $contactID_b, | |
634 | 'relationship_type_id' => $relType['id'], | |
635 | 'is_active' => 1, | |
636 | 'description' => $desc, | |
637 | ]); | |
638 | $this->callAPISuccess('Relationship', 'create', [ | |
639 | 'contact_id_a' => $contactID_c, | |
640 | 'contact_id_b' => $contactID_d, | |
641 | 'relationship_type_id' => $relType['id'], | |
642 | 'is_active' => 1, | |
643 | 'description' => 'nothing of interest', | |
644 | ]); | |
645 | $params = [ | |
646 | ['relation_description', '=', substr($desc, 3, 18), 0, 0], | |
647 | ]; | |
648 | ||
649 | $query = new CRM_Contact_BAO_Query($params); | |
650 | $dao = $query->searchQuery(); | |
651 | // This is a little weird but seems consistent with the behavior of the search form in general. | |
652 | // Technically there are 2 contacts who share a relationship with the description searched for, | |
653 | // so one might expect the search form to return both of them instead of just Contact A... but it doesn't. | |
8f36c0f5 | 654 | $this->assertEquals('1', $dao->N, 'Search query returns exactly 1 result?'); |
655 | $this->assertTrue($dao->fetch(), 'Search query returns success?'); | |
656 | $this->assertEquals($contactID_a, $dao->contact_id, 'Search query returns contact A?'); | |
6e83b317 CW |
657 | } |
658 | ||
8f36c0f5 | 659 | /** |
660 | * Test non-reciprocal relationship. | |
661 | * | |
662 | * @throws \CRM_Core_Exception | |
663 | */ | |
72a2eeab AS |
664 | public function testNonReciprocalRelationshipTargetGroupIsCorrectResults() { |
665 | $contactID_a = $this->individualCreate(); | |
666 | $contactID_b = $this->individualCreate(); | |
fb1ee468 | 667 | $this->callAPISuccess('Relationship', 'create', [ |
72a2eeab AS |
668 | 'contact_id_a' => $contactID_a, |
669 | 'contact_id_b' => $contactID_b, | |
670 | 'relationship_type_id' => 1, | |
671 | 'is_active' => 1, | |
fb1ee468 | 672 | ]); |
72a2eeab AS |
673 | // Create a group and add contact A to it. |
674 | $groupID = $this->groupCreate(); | |
fb1ee468 | 675 | $this->callAPISuccess('GroupContact', 'create', ['group_id' => $groupID, 'contact_id' => $contactID_a, 'status' => 'Added']); |
72a2eeab AS |
676 | |
677 | // Add another (sans-relationship) contact to the group, | |
678 | $contactID_c = $this->individualCreate(); | |
fb1ee468 | 679 | $this->callAPISuccess('GroupContact', 'create', ['group_id' => $groupID, 'contact_id' => $contactID_c, 'status' => 'Added']); |
72a2eeab | 680 | |
fb1ee468 | 681 | $params = [ |
682 | [ | |
72a2eeab AS |
683 | 0 => 'relation_type_id', |
684 | 1 => 'IN', | |
685 | 2 => | |
fb1ee468 | 686 | [ |
687 | 0 => '1_b_a', | |
688 | ], | |
72a2eeab AS |
689 | 3 => 0, |
690 | 4 => 0, | |
fb1ee468 | 691 | ], |
692 | [ | |
72a2eeab AS |
693 | 0 => 'relation_target_group', |
694 | 1 => 'IN', | |
695 | 2 => | |
fb1ee468 | 696 | [ |
697 | 0 => $groupID, | |
698 | ], | |
72a2eeab AS |
699 | 3 => 0, |
700 | 4 => 0, | |
fb1ee468 | 701 | ], |
702 | ]; | |
72a2eeab AS |
703 | |
704 | $query = new CRM_Contact_BAO_Query($params); | |
705 | $dao = $query->searchQuery(); | |
c26679b7 | 706 | $this->assertEquals('1', $dao->N, 'Search query returns exactly 1 result?'); |
707 | $this->assertTrue($dao->fetch(), 'Search query returns success?'); | |
708 | $this->assertEquals($contactID_b, $dao->contact_id, 'Search query returns parent of contact A?'); | |
72a2eeab AS |
709 | } |
710 | ||
804261ab JP |
711 | /** |
712 | * Relationship search with custom fields. | |
c26679b7 | 713 | * |
714 | * @throws \CRM_Core_Exception | |
804261ab JP |
715 | */ |
716 | public function testReciprocalRelationshipWithCustomFields() { | |
717 | $params = [ | |
718 | 'extends' => 'Relationship', | |
719 | ]; | |
720 | $customGroup = $this->customGroupCreate($params); | |
721 | $customFieldId = $this->customFieldCreate(['custom_group_id' => $customGroup['id']])['id']; | |
722 | $contactID_a = $this->individualCreate(); | |
723 | $contactID_b = $this->individualCreate(); | |
724 | $relationship = $this->callAPISuccess('Relationship', 'create', [ | |
725 | 'contact_id_a' => $contactID_a, | |
726 | 'contact_id_b' => $contactID_b, | |
727 | 'relationship_type_id' => 2, | |
728 | 'is_active' => 1, | |
729 | "custom_{$customFieldId}" => 'testvalue', | |
730 | ]); | |
731 | $params = [ | |
732 | [ | |
733 | 0 => 'relation_type_id', | |
734 | 1 => 'IN', | |
735 | 2 => | |
736 | [ | |
737 | 0 => '2_a_b', | |
738 | ], | |
739 | 3 => 0, | |
740 | 4 => 0, | |
741 | ], | |
742 | [ | |
743 | 0 => "custom_{$customFieldId}", | |
744 | 1 => '=', | |
745 | 2 => 'testvalue', | |
746 | 3 => 0, | |
747 | 4 => 0, | |
748 | ], | |
749 | ]; | |
750 | ||
751 | $query = new CRM_Contact_BAO_Query($params); | |
752 | $dao = $query->searchQuery(); | |
753 | $this->assertEquals('2', $dao->N); | |
754 | $this->callAPISuccess('Relationship', 'delete', ['id' => $relationship['id']]); | |
755 | $this->callAPISuccess('Contact', 'delete', ['id' => $contactID_a, 'skip_undelete' => 1]); | |
756 | $this->callAPISuccess('Contact', 'delete', ['id' => $contactID_b, 'skip_undelete' => 1]); | |
757 | $this->callAPISuccess('CustomField', 'delete', ['id' => $customFieldId, 'skip_undelete' => 1]); | |
758 | $this->callAPISuccess('CustomGroup', 'delete', ['id' => $customGroup]); | |
759 | } | |
760 | ||
fb1ee468 | 761 | /** |
762 | * @throws \CRM_Core_Exception | |
763 | */ | |
72a2eeab AS |
764 | public function testReciprocalRelationshipTargetGroupIsCorrectResults() { |
765 | $contactID_a = $this->individualCreate(); | |
766 | $contactID_b = $this->individualCreate(); | |
fb1ee468 | 767 | $this->callAPISuccess('Relationship', 'create', [ |
72a2eeab AS |
768 | 'contact_id_a' => $contactID_a, |
769 | 'contact_id_b' => $contactID_b, | |
770 | 'relationship_type_id' => 2, | |
771 | 'is_active' => 1, | |
fb1ee468 | 772 | ]); |
72a2eeab AS |
773 | // Create a group and add contact A to it. |
774 | $groupID = $this->groupCreate(); | |
fb1ee468 | 775 | $this->callAPISuccess('GroupContact', 'create', ['group_id' => $groupID, 'contact_id' => $contactID_a, 'status' => 'Added']); |
72a2eeab AS |
776 | |
777 | // Add another (sans-relationship) contact to the group, | |
778 | $contactID_c = $this->individualCreate(); | |
fb1ee468 | 779 | $this->callAPISuccess('GroupContact', 'create', ['group_id' => $groupID, 'contact_id' => $contactID_c, 'status' => 'Added']); |
72a2eeab | 780 | |
fb1ee468 | 781 | $params = [ |
782 | [ | |
72a2eeab AS |
783 | 0 => 'relation_type_id', |
784 | 1 => 'IN', | |
785 | 2 => | |
fb1ee468 | 786 | [ |
787 | 0 => '2_a_b', | |
788 | ], | |
72a2eeab AS |
789 | 3 => 0, |
790 | 4 => 0, | |
fb1ee468 | 791 | ], |
792 | [ | |
72a2eeab AS |
793 | 0 => 'relation_target_group', |
794 | 1 => 'IN', | |
795 | 2 => | |
fb1ee468 | 796 | [ |
797 | 0 => $groupID, | |
798 | ], | |
72a2eeab AS |
799 | 3 => 0, |
800 | 4 => 0, | |
fb1ee468 | 801 | ], |
802 | ]; | |
72a2eeab AS |
803 | |
804 | $query = new CRM_Contact_BAO_Query($params); | |
805 | $dao = $query->searchQuery(); | |
c26679b7 | 806 | $this->assertEquals('1', $dao->N, 'Search query returns exactly 1 result?'); |
807 | $this->assertTrue($dao->fetch(), 'Search query returns success?'); | |
808 | $this->assertEquals($contactID_b, $dao->contact_id, 'Search query returns spouse of contact A?'); | |
72a2eeab AS |
809 | } |
810 | ||
c26679b7 | 811 | /** |
812 | * Test correct temporary table in reciprocal relationship search. | |
813 | * | |
814 | * @throws \CRM_Core_Exception | |
815 | */ | |
72a2eeab AS |
816 | public function testReciprocalRelationshipTargetGroupUsesTempTable() { |
817 | $groupID = $this->groupCreate(); | |
fb1ee468 | 818 | $params = [ |
819 | [ | |
72a2eeab AS |
820 | 0 => 'relation_type_id', |
821 | 1 => 'IN', | |
822 | 2 => | |
fb1ee468 | 823 | [ |
824 | 0 => '2_a_b', | |
825 | ], | |
72a2eeab AS |
826 | 3 => 0, |
827 | 4 => 0, | |
fb1ee468 | 828 | ], |
829 | [ | |
72a2eeab AS |
830 | 0 => 'relation_target_group', |
831 | 1 => 'IN', | |
832 | 2 => | |
fb1ee468 | 833 | [ |
834 | 0 => $groupID, | |
835 | ], | |
72a2eeab AS |
836 | 3 => 0, |
837 | 4 => 0, | |
fb1ee468 | 838 | ], |
839 | ]; | |
72a2eeab | 840 | $sql = CRM_Contact_BAO_Query::getQuery($params); |
c26679b7 | 841 | $this->assertContains('INNER JOIN civicrm_tmp_e', $sql, 'Query appears to use temporary table of compiled relationships?', TRUE); |
72a2eeab AS |
842 | } |
843 | ||
8f36c0f5 | 844 | /** |
845 | * Test relationship permission clause. | |
846 | * | |
847 | * @throws \CRM_Core_Exception | |
848 | */ | |
9c9908e9 | 849 | public function testRelationshipPermissionClause() { |
850 | $params = [['relation_type_id', 'IN', ['1_b_a'], 0, 0], ['relation_permission', 'IN', [2], 0, 0]]; | |
851 | $sql = CRM_Contact_BAO_Query::getQuery($params); | |
852 | $this->assertContains('(civicrm_relationship.is_permission_a_b IN (2))', $sql); | |
853 | } | |
854 | ||
5ad36be5 SL |
855 | /** |
856 | * Test Relationship Clause | |
0e1544e7 | 857 | * |
858 | * @throws \CRM_Core_Exception | |
5ad36be5 SL |
859 | */ |
860 | public function testRelationshipClause() { | |
861 | $today = date('Ymd'); | |
c26679b7 | 862 | $from1 = ' FROM civicrm_contact contact_a LEFT JOIN civicrm_relationship ON (civicrm_relationship.contact_id_a = contact_a.id ) LEFT JOIN civicrm_contact contact_b ON (civicrm_relationship.contact_id_b = contact_b.id )'; |
863 | $from2 = ' FROM civicrm_contact contact_a LEFT JOIN civicrm_relationship ON (civicrm_relationship.contact_id_b = contact_a.id ) LEFT JOIN civicrm_contact contact_b ON (civicrm_relationship.contact_id_a = contact_b.id )'; | |
5ad36be5 SL |
864 | $where1 = "WHERE ( ( |
865 | civicrm_relationship.is_active = 1 AND | |
866 | ( civicrm_relationship.end_date IS NULL OR civicrm_relationship.end_date >= {$today} ) AND | |
867 | ( civicrm_relationship.start_date IS NULL OR civicrm_relationship.start_date <= {$today} ) | |
868 | ) AND (contact_b.is_deleted = 0) AND civicrm_relationship.relationship_type_id IN (8) ) AND (contact_a.is_deleted = 0)"; | |
869 | $where2 = "WHERE ( ( | |
870 | civicrm_relationship.is_active = 1 AND | |
871 | ( civicrm_relationship.end_date IS NULL OR civicrm_relationship.end_date >= {$today} ) AND | |
872 | ( civicrm_relationship.start_date IS NULL OR civicrm_relationship.start_date <= {$today} ) | |
873 | ) AND (contact_b.is_deleted = 0) AND civicrm_relationship.relationship_type_id IN (8,10) ) AND (contact_a.is_deleted = 0)"; | |
874 | // Test Traditional single select format | |
fb1ee468 | 875 | $params1 = [['relation_type_id', '=', '8_a_b', 0, 0]]; |
5ad36be5 | 876 | $query1 = new CRM_Contact_BAO_Query( |
fb1ee468 | 877 | $params1, ['contact_id'], |
5ad36be5 SL |
878 | NULL, TRUE, FALSE, 1, |
879 | TRUE, | |
880 | TRUE, FALSE | |
881 | ); | |
c26679b7 | 882 | $sql1 = $query1->query(); |
299c1530 | 883 | $this->assertLike($from1, $sql1[1]); |
884 | $this->assertLike($where1, $sql1[2]); | |
5ad36be5 | 885 | // Test single relationship type selected in multiple select. |
fb1ee468 | 886 | $params2 = [['relation_type_id', 'IN', ['8_a_b'], 0, 0]]; |
5ad36be5 | 887 | $query2 = new CRM_Contact_BAO_Query( |
fb1ee468 | 888 | $params2, ['contact_id'], |
5ad36be5 SL |
889 | NULL, TRUE, FALSE, 1, |
890 | TRUE, | |
891 | TRUE, FALSE | |
892 | ); | |
893 | $sql2 = $query2->query(FALSE); | |
299c1530 | 894 | $this->assertLike($from1, $sql2[1]); |
895 | $this->assertLike($where1, $sql2[2]); | |
5ad36be5 | 896 | // Test multiple relationship types selected. |
fb1ee468 | 897 | $params3 = [['relation_type_id', 'IN', ['8_a_b', '10_a_b'], 0, 0]]; |
5ad36be5 | 898 | $query3 = new CRM_Contact_BAO_Query( |
fb1ee468 | 899 | $params3, ['contact_id'], |
5ad36be5 SL |
900 | NULL, TRUE, FALSE, 1, |
901 | TRUE, | |
902 | TRUE, FALSE | |
903 | ); | |
904 | $sql3 = $query3->query(FALSE); | |
299c1530 | 905 | $this->assertLike($from1, $sql3[1]); |
906 | $this->assertLike($where2, $sql3[2]); | |
5ad36be5 | 907 | // Test Multiple Relationship type selected where one doesn't actually exist. |
fb1ee468 | 908 | $params4 = [['relation_type_id', 'IN', ['8_a_b', '10_a_b', '14_a_b'], 0, 0]]; |
5ad36be5 | 909 | $query4 = new CRM_Contact_BAO_Query( |
fb1ee468 | 910 | $params4, ['contact_id'], |
5ad36be5 SL |
911 | NULL, TRUE, FALSE, 1, |
912 | TRUE, | |
913 | TRUE, FALSE | |
914 | ); | |
c26679b7 | 915 | $sql4 = $query4->query(); |
299c1530 | 916 | $this->assertLike($from1, $sql4[1]); |
917 | $this->assertLike($where2, $sql4[2]); | |
5de9b484 JP |
918 | |
919 | // Test Multiple b to a Relationship type . | |
fb1ee468 | 920 | $params5 = [['relation_type_id', 'IN', ['8_b_a', '10_b_a', '14_b_a'], 0, 0]]; |
5de9b484 | 921 | $query5 = new CRM_Contact_BAO_Query( |
fb1ee468 | 922 | $params5, ['contact_id'], |
5de9b484 JP |
923 | NULL, TRUE, FALSE, 1, |
924 | TRUE, | |
925 | TRUE, FALSE | |
926 | ); | |
927 | $sql5 = $query5->query(FALSE); | |
299c1530 | 928 | $this->assertLike($from2, $sql5[1]); |
929 | $this->assertLike($where2, $sql5[2]); | |
5ad36be5 | 930 | } |
8d710ea5 | 931 | |
932 | /** | |
933 | * Test we can narrow a group get by status. | |
fb1ee468 | 934 | * |
935 | * @throws \CRM_Core_Exception | |
8d710ea5 | 936 | */ |
937 | public function testGetByGroupWithStatus() { | |
938 | $groupID = $this->groupCreate(); | |
d7570a7f | 939 | $this->groupContactCreate($groupID, 3); |
8d710ea5 | 940 | $groupContactID = $this->callAPISuccessGetSingle('GroupContact', ['group_id' => $groupID, 'options' => ['limit' => 1]])['id']; |
941 | $this->callAPISuccess('GroupContact', 'create', ['id' => $groupContactID, 'status' => 'Removed']); | |
942 | $queryObj = new CRM_Contact_BAO_Query([['group', '=', $groupID, 0, 0], ['group_contact_status', 'IN', ['Removed' => 1], 0, 0]]); | |
943 | $resultDAO = $queryObj->searchQuery(); | |
944 | $this->assertEquals(1, $resultDAO->N); | |
945 | ||
946 | $queryObj = new CRM_Contact_BAO_Query([['group', '=', $groupID, 0, 0], ['group_contact_status', 'IN', ['Added' => 1], 0, 0]]); | |
947 | $resultDAO = $queryObj->searchQuery(); | |
948 | $this->assertEquals(2, $resultDAO->N); | |
949 | ||
950 | $queryObj = new CRM_Contact_BAO_Query([['group', '=', $groupID, 0, 0]]); | |
951 | $resultDAO = $queryObj->searchQuery(); | |
952 | $this->assertEquals(2, $resultDAO->N); | |
953 | } | |
5ad36be5 | 954 | |
0d38cb6d | 955 | /** |
956 | * Test we can narrow a group get by status. | |
957 | * | |
958 | * @throws \Exception | |
959 | */ | |
960 | public function testGetByGroupWithStatusSmartGroup() { | |
961 | $groupID = $this->smartGroupCreate(); | |
962 | // This means they are actually all hard-added, which is fine for this purpose. | |
963 | $this->groupContactCreate($groupID, 3); | |
964 | $groupContactID = $this->callAPISuccessGetSingle('GroupContact', ['group_id' => $groupID, 'options' => ['limit' => 1]])['id']; | |
965 | $this->callAPISuccess('GroupContact', 'create', ['id' => $groupContactID, 'status' => 'Removed']); | |
966 | ||
967 | $queryObj = new CRM_Contact_BAO_Query([['group', '=', $groupID, 0, 0], ['group_contact_status', 'IN', ['Removed' => 1], 0, 0]]); | |
968 | $resultDAO = $queryObj->searchQuery(); | |
969 | $this->assertEquals(1, $resultDAO->N); | |
dd606225 JP |
970 | |
971 | $queryObj = new CRM_Contact_BAO_Query([['group', 'IS NOT EMPTY', '', 0, 0], ['group_contact_status', 'IN', ['Removed' => 1], 0, 0]]); | |
972 | $resultDAO = $queryObj->searchQuery(); | |
973 | $this->assertEquals(1, $resultDAO->N); | |
0d38cb6d | 974 | } |
975 | ||
c3137c08 | 976 | /** |
977 | * Test the group contact clause does not contain an OR. | |
978 | * | |
979 | * The search should return 3 contacts - 2 households in the smart group of | |
980 | * Contact Type = Household and one Individual hard-added to it. The | |
981 | * Household that meets both criteria should be returned once. | |
0d38cb6d | 982 | * |
983 | * @throws \Exception | |
c3137c08 | 984 | */ |
985 | public function testGroupClause() { | |
986 | $this->householdCreate(); | |
987 | $householdID = $this->householdCreate(); | |
988 | $individualID = $this->individualCreate(); | |
989 | $groupID = $this->smartGroupCreate(); | |
fb1ee468 | 990 | $this->callAPISuccess('GroupContact', 'create', ['group_id' => $groupID, 'contact_id' => $individualID, 'status' => 'Added']); |
991 | $this->callAPISuccess('GroupContact', 'create', ['group_id' => $groupID, 'contact_id' => $householdID, 'status' => 'Added']); | |
c3137c08 | 992 | |
485a3a1f | 993 | // Refresh the cache for test purposes. It would be better to alter to alter the GroupContact add function to add contacts to the cache. |
0626851e | 994 | CRM_Contact_BAO_GroupContactCache::clearGroupContactCache($groupID); |
3875e6b6 | 995 | |
996 | $sql = CRM_Contact_BAO_Query::getQuery( | |
fb1ee468 | 997 | [['group', 'IN', [$groupID], 0, 0]], |
998 | ['contact_id'] | |
c3137c08 | 999 | ); |
1000 | ||
3875e6b6 | 1001 | $dao = CRM_Core_DAO::executeQuery($sql); |
c3137c08 | 1002 | $this->assertEquals(3, $dao->N); |
3875e6b6 | 1003 | $this->assertFalse(strstr($sql, ' OR ')); |
1004 | ||
1005 | $sql = CRM_Contact_BAO_Query::getQuery( | |
fb1ee468 | 1006 | [['group', 'IN', [$groupID], 0, 0]], |
1007 | ['contact_id' => 1, 'group' => 1] | |
3875e6b6 | 1008 | ); |
1009 | ||
1010 | $dao = CRM_Core_DAO::executeQuery($sql); | |
1011 | $this->assertEquals(3, $dao->N); | |
1012 | $this->assertFalse(strstr($sql, ' OR '), 'Query does not include or'); | |
1013 | while ($dao->fetch()) { | |
1014 | $this->assertTrue(($dao->groups == $groupID || $dao->groups == ',' . $groupID), $dao->groups . ' includes ' . $groupID); | |
1015 | } | |
c3137c08 | 1016 | } |
1017 | ||
b1128d0b | 1018 | /** |
3af96592 | 1019 | * CRM-19562 ensure that only ids are used for contact_id searching. |
b1128d0b SL |
1020 | */ |
1021 | public function testContactIDClause() { | |
fb1ee468 | 1022 | $params = [ |
8f36c0f5 | 1023 | ['mark_x_2', '=', 1, 0, 0], |
1024 | ['mark_x_foo@example.com', '=', 1, 0, 0], | |
fb1ee468 | 1025 | ]; |
1026 | $returnProperties = [ | |
8f36c0f5 | 1027 | 'sort_name' => 1, |
1028 | 'email' => 1, | |
1029 | 'do_not_email' => 1, | |
1030 | 'is_deceased' => 1, | |
1031 | 'on_hold' => 1, | |
1032 | 'display_name' => 1, | |
1033 | 'preferred_mail_format' => 1, | |
fb1ee468 | 1034 | ]; |
5cf7a77e | 1035 | $numberOfContacts = 2; |
8f36c0f5 | 1036 | |
b1128d0b | 1037 | try { |
8f36c0f5 | 1038 | CRM_Contact_BAO_Query::apiQuery($params, $returnProperties, NULL, NULL, 0, $numberOfContacts); |
b1128d0b SL |
1039 | } |
1040 | catch (Exception $e) { | |
5cf7a77e | 1041 | $this->assertEquals( |
8f36c0f5 | 1042 | 'One of parameters (value: foo@example.com) is not of the type Positive', |
5cf7a77e | 1043 | $e->getMessage() |
1044 | ); | |
1045 | $this->assertTrue(TRUE); | |
1046 | return; | |
b1128d0b | 1047 | } |
5cf7a77e | 1048 | $this->fail('Test failed for some reason which is not good'); |
b1128d0b SL |
1049 | } |
1050 | ||
7f594311 | 1051 | /** |
1052 | * Test the sorting on the contact ID query works. | |
1053 | * | |
1054 | * Checking for lack of fatal. | |
1055 | * | |
1056 | * @param string $sortOrder | |
1057 | * Param reflecting how sort is passed in. | |
1058 | * - 1_d is column 1 descending. | |
1059 | * | |
1060 | * @dataProvider getSortOptions | |
1061 | */ | |
1062 | public function testContactIDQuery($sortOrder) { | |
1063 | $selector = new CRM_Contact_Selector(NULL, ['radio_ts' => 'ts_all'], NULL, ['sort_name' => 1]); | |
1064 | $selector->contactIDQuery([], $sortOrder); | |
1065 | } | |
1066 | ||
708ce91f | 1067 | /** |
1068 | * Test the sorting on the contact ID query works with a profile search. | |
1069 | * | |
1070 | * Checking for lack of fatal. | |
8f36c0f5 | 1071 | * |
1072 | * @throws \CRM_Core_Exception | |
708ce91f | 1073 | */ |
1074 | public function testContactIDQueryProfileSearchResults() { | |
1075 | $profile = $this->callAPISuccess('UFGroup', 'create', ['group_type' => 'Contact', 'name' => 'search', 'title' => 'search']); | |
1076 | $this->callAPISuccess('UFField', 'create', [ | |
1077 | 'uf_group_id' => $profile['id'], | |
1078 | 'field_name' => 'postal_code', | |
1079 | 'field_type' => 'Contact', | |
1080 | 'in_selector' => TRUE, | |
1081 | 'is_searchable' => TRUE, | |
1082 | 'label' => 'postal code', | |
1083 | 'visibility' => 'Public Pages and Listings', | |
1084 | ]); | |
1085 | $selector = new CRM_Contact_Selector(NULL, ['radio_ts' => 'ts_all', 'uf_group_id' => $profile['id']], NULL, ['sort_name' => 1]); | |
1086 | $selector->contactIDQuery([], '2_d'); | |
1087 | } | |
1088 | ||
1089 | /** | |
1090 | * Get search options to reflect how a UI search would look. | |
1091 | * | |
1092 | * @return array | |
1093 | */ | |
7f594311 | 1094 | public function getSortOptions() { |
1095 | return [ | |
1096 | ['1_d'], | |
1097 | ['2_d'], | |
1098 | ['3_d'], | |
1099 | ['4_d'], | |
1100 | ['5_d'], | |
1101 | ['6_d'], | |
1102 | ]; | |
1103 | } | |
dbaa9d7d | 1104 | |
1105 | /** | |
1106 | * Test the summary query does not add an acl clause when acls not enabled.. | |
8f36c0f5 | 1107 | * |
1108 | * @throws \CRM_Core_Exception | |
dbaa9d7d | 1109 | */ |
5384a978 | 1110 | public function testGetSummaryQueryWithFinancialACLDisabled() { |
faba82fc | 1111 | $this->createContributionsForSummaryQueryTests(); |
1112 | ||
1113 | // Test the function directly | |
dbaa9d7d | 1114 | $where = $from = NULL; |
1115 | $queryObject = new CRM_Contact_BAO_Query(); | |
faba82fc | 1116 | $queryObject->appendFinancialTypeWhereAndFromToQueryStrings($where, |
dbaa9d7d | 1117 | $from); |
faba82fc | 1118 | $this->assertEquals(NULL, $where); |
1119 | $this->assertEquals(NULL, $from); | |
1120 | ||
1121 | // Test the function in action | |
1122 | $queryObject = new CRM_Contact_BAO_Query([['contribution_source', '=', 'SSF', '', '']]); | |
1123 | $summary = $queryObject->summaryContribution(); | |
1124 | $this->assertEquals([ | |
1125 | 'total' => [ | |
1126 | 'avg' => '$ 233.33', | |
1127 | 'amount' => '$ 1,400.00', | |
1128 | 'count' => 6, | |
39b959db | 1129 | ], |
faba82fc | 1130 | 'cancel' => [ |
1131 | 'count' => 2, | |
1132 | 'amount' => '$ 100.00', | |
1133 | 'avg' => '$ 50.00', | |
1134 | ], | |
1135 | ], $summary); | |
5384a978 VR |
1136 | } |
1137 | ||
dbaa9d7d | 1138 | /** |
1139 | * Test the summary query accurately adds financial acl filters. | |
8f36c0f5 | 1140 | * |
1141 | * @throws \CRM_Core_Exception | |
dbaa9d7d | 1142 | */ |
5384a978 | 1143 | public function testGetSummaryQueryWithFinancialACLEnabled() { |
dbaa9d7d | 1144 | $where = $from = NULL; |
faba82fc | 1145 | $this->createContributionsForSummaryQueryTests(); |
dbaa9d7d | 1146 | $this->enableFinancialACLs(); |
1147 | $this->createLoggedInUserWithFinancialACL(); | |
faba82fc | 1148 | |
1149 | // Test the function directly | |
dbaa9d7d | 1150 | $queryObject = new CRM_Contact_BAO_Query(); |
faba82fc | 1151 | $queryObject->appendFinancialTypeWhereAndFromToQueryStrings($where, |
dbaa9d7d | 1152 | $from); |
1153 | $donationTypeID = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Donation'); | |
5384a978 VR |
1154 | $this->assertEquals( |
1155 | " LEFT JOIN civicrm_line_item li | |
1156 | ON civicrm_contribution.id = li.contribution_id AND | |
dbaa9d7d | 1157 | li.entity_table = 'civicrm_contribution' AND li.financial_type_id NOT IN ({$donationTypeID}) ", $from); |
faba82fc | 1158 | |
1159 | // Test the function in action | |
1160 | $queryObject = new CRM_Contact_BAO_Query([['contribution_source', '=', 'SSF', '', '']]); | |
1161 | $summary = $queryObject->summaryContribution(); | |
1162 | $this->assertEquals([ | |
1163 | 'total' => [ | |
1164 | 'avg' => '$ 200.00', | |
1165 | 'amount' => '$ 400.00', | |
1166 | 'count' => 2, | |
faba82fc | 1167 | ], |
1168 | 'cancel' => [ | |
1169 | 'count' => 1, | |
1170 | 'amount' => '$ 50.00', | |
1171 | 'avg' => '$ 50.00', | |
1172 | ], | |
1173 | ], $summary); | |
dbaa9d7d | 1174 | $this->disableFinancialACLs(); |
5384a978 VR |
1175 | } |
1176 | ||
6245de60 JG |
1177 | /** |
1178 | * Test relative date filters to ensure they generate correct SQL. | |
1179 | * | |
1180 | * @dataProvider relativeDateFilters | |
c26679b7 | 1181 | * |
1182 | * @param string $filter | |
1183 | * @param string $expectedWhere | |
1184 | * | |
1185 | * @throws \CRM_Core_Exception | |
6245de60 JG |
1186 | */ |
1187 | public function testRelativeDateFilters($filter, $expectedWhere) { | |
1188 | $params = [['created_date_relative', '=', $filter, 0, 0]]; | |
1189 | ||
1190 | $dates = CRM_Utils_Date::getFromTo($filter, NULL, NULL); | |
1191 | $expectedWhere = str_replace(['date0', 'date1'], [$dates[0], $dates[1]], $expectedWhere); | |
1192 | ||
1193 | $query = new CRM_Contact_BAO_Query( | |
1194 | $params, [], | |
1195 | NULL, TRUE, FALSE, 1, | |
1196 | TRUE, | |
1197 | TRUE, FALSE | |
1198 | ); | |
1199 | ||
1200 | list($select, $from, $where, $having) = $query->query(); | |
1201 | $this->assertEquals($expectedWhere, $where); | |
1202 | } | |
1203 | ||
c26679b7 | 1204 | /** |
1205 | * Data provider to relative date filter configurations. | |
1206 | * | |
1207 | * @return array | |
1208 | */ | |
6245de60 JG |
1209 | public function relativeDateFilters() { |
1210 | $dataProvider[] = ['this.year', "WHERE ( contact_a.created_date BETWEEN 'date0' AND 'date1' ) AND (contact_a.is_deleted = 0)"]; | |
1211 | $dataProvider[] = ['greater.day', "WHERE ( contact_a.created_date >= 'date0' ) AND (contact_a.is_deleted = 0)"]; | |
1212 | $dataProvider[] = ['earlier.week', "WHERE ( contact_a.created_date <= 'date1' ) AND (contact_a.is_deleted = 0)"]; | |
1213 | return $dataProvider; | |
1214 | } | |
1215 | ||
faba82fc | 1216 | /** |
1217 | * Create contributions to test summary calculations. | |
1218 | * | |
1219 | * financial type | cancel_date |total_amount| source | line_item_financial_types |number_line_items| line_amounts | |
1220 | * Donation |NULL | 100.00 |SSF | Donation | 1 | 100.00 | |
1221 | * Member Dues |NULL | 100.00 |SSF | Member Dues | 1 | 100.00 | |
1222 | * Donation |NULL | 300.00 |SSF | Event Fee,Event Fee | 2 | 200.00,100.00 | |
1223 | * Donation |NULL | 300.00 |SSF | Event Fee,Donation | 2 | 200.00,100.00 | |
1224 | * Donation |NULL | 300.00 |SSF | Donation,Donation | 2 | 200.00,100.00 | |
1225 | * Donation |2019-02-13 00:00:00 | 50.00 |SSF | Donation | 1 | 50.00 | |
1226 | * Member Dues |2019-02-13 00:00:00 | 50.00 |SSF | Member Dues | 1 | 50.00 | |
80b5c9f1 | 1227 | * |
1228 | * @throws \CRM_Core_Exception | |
faba82fc | 1229 | */ |
1230 | protected function createContributionsForSummaryQueryTests() { | |
1231 | $contactID = $this->individualCreate(); | |
1232 | $this->contributionCreate(['contact_id' => $contactID]); | |
1233 | $this->contributionCreate([ | |
1234 | 'contact_id' => $contactID, | |
1235 | 'total_amount' => 100, | |
1236 | 'financial_type_id' => 'Member Dues', | |
1237 | ]); | |
1238 | $eventFeeType = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Event Fee'); | |
1239 | $this->createContributionWithTwoLineItemsAgainstPriceSet(['contact_id' => $contactID, 'source' => 'SSF']); | |
1240 | $this->createContributionWithTwoLineItemsAgainstPriceSet(['contact_id' => $contactID, 'source' => 'SSF'], [ | |
1241 | CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Donation'), | |
1242 | $eventFeeType, | |
1243 | ]); | |
1244 | $this->createContributionWithTwoLineItemsAgainstPriceSet(['contact_id' => $contactID, 'source' => 'SSF'], [ | |
1245 | CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Donation'), | |
1246 | CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Donation'), | |
1247 | ]); | |
1248 | $this->createContributionWithTwoLineItemsAgainstPriceSet(['contact_id' => $contactID, 'source' => 'SSF', 'financial_type_id' => $eventFeeType], [ | |
1249 | CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Donation'), | |
1250 | CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Donation'), | |
1251 | ]); | |
1252 | $this->contributionCreate([ | |
1253 | 'contact_id' => $contactID, | |
1254 | 'total_amount' => 50, | |
1255 | 'contribution_status_id' => 'Cancelled', | |
1256 | 'cancel_date' => 'yesterday', | |
1257 | ]); | |
1258 | $this->contributionCreate([ | |
1259 | 'contact_id' => $contactID, | |
1260 | 'total_amount' => 50, | |
1261 | 'contribution_status_id' => 'Cancelled', | |
1262 | 'cancel_date' => 'yesterday', | |
1263 | 'financial_type_id' => 'Member Dues', | |
1264 | ]); | |
1265 | } | |
1266 | ||
3fc41a5d | 1267 | /** |
1268 | * Test the options are handled for the qill. | |
1269 | */ | |
1270 | public function testQillOptions() { | |
1271 | $qill = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Activity_BAO_Activity', 'activity_type_id', 2, '='); | |
1272 | $this->assertEquals(['=', 'Phone Call'], $qill); | |
1273 | ||
1274 | $qill = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Activity_BAO_Activity', 'priority_id', 2, '='); | |
1275 | $this->assertEquals(['=', 'Normal'], $qill); | |
1276 | } | |
1277 | ||
9724097e | 1278 | /** |
1279 | * Test tests that a value on 'any entity' with the right metadata will be handled. | |
1280 | * | |
1281 | * @throws \CRM_Core_Exception | |
1282 | */ | |
1283 | public function testGenericWhereHandling() { | |
1284 | $query = new CRM_Contact_BAO_Query([['suffix_id', '=', 2, 0]]); | |
c26679b7 | 1285 | $this->assertEquals('contact_a.suffix_id = 2', $query->_where[0][0]); |
9724097e | 1286 | $this->assertEquals('Individual Suffix = Sr.', $query->_qill[0][0]); |
1287 | $this->assertNotTrue(isset($query->_tables['civicrm_activity'])); | |
1288 | ||
1289 | $query = new CRM_Contact_BAO_Query([['prefix_id', '=', 2, 0]]); | |
1290 | $this->assertEquals('contact_a.prefix_id = 2', $query->_where[0][0]); | |
1291 | $this->assertEquals('Individual Prefix = Ms.', $query->_qill[0][0]); | |
1292 | $this->assertNotTrue(isset($query->_tables['civicrm_activity'])); | |
1293 | ||
1294 | $query = new CRM_Contact_BAO_Query([['gender_id', '=', 2, 0]]); | |
1295 | $this->assertEquals('contact_a.gender_id = 2', $query->_where[0][0]); | |
1296 | $this->assertEquals('Gender = Male', $query->_qill[0][0]); | |
1297 | $this->assertNotTrue(isset($query->_tables['civicrm_activity'])); | |
1298 | ||
1299 | $query = new CRM_Contact_BAO_Query([['communication_style_id', '=', 2, 0]]); | |
1300 | $this->assertEquals('contact_a.communication_style_id = 2', $query->_where[0][0]); | |
1301 | $this->assertEquals('Communication Style = Familiar', $query->_qill[0][0]); | |
1302 | ||
1303 | $query = new CRM_Contact_BAO_Query([['communication_style_id', '=', 2, 0]]); | |
1304 | $this->assertEquals('contact_a.communication_style_id = 2', $query->_where[0][0]); | |
1305 | $this->assertEquals('Communication Style = Familiar', $query->_qill[0][0]); | |
1306 | ||
1307 | $query = new CRM_Contact_BAO_Query([['contact_type', '=', 'Household', 0]]); | |
1308 | $this->assertEquals("contact_a.contact_type = 'Household'", $query->_where[0][0]); | |
1309 | $this->assertEquals('Contact Type = Household', $query->_qill[0][0]); | |
1310 | ||
1311 | $query = new CRM_Contact_BAO_Query([['on_hold', '=', 0, 0]]); | |
1312 | $this->assertEquals('civicrm_email.on_hold = 0', $query->_where[0][0]); | |
1313 | $this->assertEquals('On Hold = 0', $query->_qill[0][0]); | |
1314 | ||
1315 | $query = new CRM_Contact_BAO_Query([['on_hold', '=', 1, 0]]); | |
1316 | $this->assertEquals('civicrm_email.on_hold = 1', $query->_where[0][0]); | |
1317 | $this->assertEquals('On Hold = 1', $query->_qill[0][0]); | |
1318 | ||
1319 | $query = new CRM_Contact_BAO_Query([['world_region', '=', 3, 0]]); | |
1320 | $this->assertEquals('civicrm_worldregion.id = 3', $query->_where[0][0]); | |
1321 | $this->assertEquals('World Region = Middle East and North Africa', $query->_qill[0][0]); | |
1322 | } | |
1323 | ||
6a488035 | 1324 | } |