Merge pull request #11437 from civicrm/4.7.29-rc
[civicrm-core.git] / tests / phpunit / api / v3 / ContactTest.php
1 <?php
2 /**
3 * @file
4 * File for the TestContact class.
5 *
6 * (PHP 5)
7 *
8 * @author Walt Haas <walt@dharmatech.org> (801) 534-1262
9 * @copyright Copyright CiviCRM LLC (C) 2009
10 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html
11 * GNU Affero General Public License version 3
12 * @version $Id: ContactTest.php 31254 2010-12-15 10:09:29Z eileen $
13 * @package CiviCRM
14 *
15 * This file is part of CiviCRM
16 *
17 * CiviCRM is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Affero General Public License
19 * as published by the Free Software Foundation; either version 3 of
20 * the License, or (at your option) any later version.
21 *
22 * CiviCRM is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU Affero General Public License for more details.
26 *
27 * You should have received a copy of the GNU Affero General Public
28 * License along with this program. If not, see
29 * <http://www.gnu.org/licenses/>.
30 */
31
32 /**
33 * Test APIv3 civicrm_contact* functions
34 *
35 * @package CiviCRM_APIv3
36 * @subpackage API_Contact
37 * @group headless
38 */
39 class api_v3_ContactTest extends CiviUnitTestCase {
40 public $DBResetRequired = FALSE;
41 protected $_apiversion;
42 protected $_entity;
43 protected $_params;
44
45 protected $_contactID;
46 protected $_financialTypeId = 1;
47
48 /**
49 * Test setup for every test.
50 *
51 * Connect to the database, truncate the tables that will be used
52 * and redirect stdin to a temporary file
53 */
54 public function setUp() {
55 // Connect to the database.
56 parent::setUp();
57 $this->_apiversion = 3;
58 $this->_entity = 'contact';
59 $this->_params = array(
60 'first_name' => 'abc1',
61 'contact_type' => 'Individual',
62 'last_name' => 'xyz1',
63 );
64 }
65
66 /**
67 * Restore the DB for the next test.
68 *
69 * @throws \Exception
70 */
71 public function tearDown() {
72 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
73 // truncate a few tables
74 $tablesToTruncate = array(
75 'civicrm_email',
76 'civicrm_contribution',
77 'civicrm_line_item',
78 'civicrm_website',
79 'civicrm_relationship',
80 'civicrm_uf_match',
81 'civicrm_phone',
82 'civicrm_address',
83 'civicrm_acl_contact_cache',
84 'civicrm_activity_contact',
85 'civicrm_activity',
86 'civicrm_group',
87 'civicrm_group_contact',
88 'civicrm_saved_search',
89 'civicrm_group_contact_cache',
90 );
91
92 $this->quickCleanup($tablesToTruncate, TRUE);
93 parent::tearDown();
94 }
95
96 /**
97 * Test civicrm_contact_create.
98 *
99 * Verify that attempt to create individual contact with only
100 * first and last names succeeds
101 */
102 public function testAddCreateIndividual() {
103 $oldCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
104 $params = array(
105 'first_name' => 'abc1',
106 'contact_type' => 'Individual',
107 'last_name' => 'xyz1',
108 );
109
110 $contact = $this->callAPISuccess('contact', 'create', $params);
111 $this->assertTrue(is_numeric($contact['id']));
112 $this->assertTrue($contact['id'] > 0);
113 $newCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_contact');
114 $this->assertEquals($oldCount + 1, $newCount);
115
116 $this->assertDBState('CRM_Contact_DAO_Contact',
117 $contact['id'],
118 $params
119 );
120 }
121
122 /**
123 * Test that it is possible to prevent cache clearing via option.
124 *
125 * Cache clearing is bypassed if 'options' => array('do_not_reset_cache' => 1 is used.
126 */
127 public function testCreateIndividualNoCacheClear() {
128
129 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
130 $groupID = $this->groupCreate();
131
132 $this->putGroupContactCacheInClearableState($groupID, $contact);
133
134 $this->callAPISuccess('contact', 'create', array('id' => $contact['id']));
135 $this->assertEquals(0, CRM_Core_DAO::singleValueQuery("SELECT count(*) FROM civicrm_group_contact_cache"));
136
137 // Rinse & repeat, but with the option.
138 $this->putGroupContactCacheInClearableState($groupID, $contact);
139 CRM_Core_Config::setPermitCacheFlushMode(FALSE);
140 $this->callAPISuccess('contact', 'create', array('id' => $contact['id']));
141 $this->assertEquals(1, CRM_Core_DAO::singleValueQuery("SELECT count(*) FROM civicrm_group_contact_cache"));
142 CRM_Core_Config::setPermitCacheFlushMode(TRUE);
143 }
144
145 /**
146 * Test for international string acceptance (CRM-10210).
147 *
148 * @dataProvider getInternationalStrings
149 *
150 * @param string $string
151 * String to be tested.
152 *
153 * @throws \Exception
154 */
155 public function testInternationalStrings($string) {
156 $this->callAPISuccess('Contact', 'create', array_merge(
157 $this->_params,
158 array('first_name' => $string)
159 ));
160 $result = $this->callAPISuccessGetSingle('Contact', array('first_name' => $string));
161 $this->assertEquals($string, $result['first_name']);
162
163 $organizationParams = array(
164 'organization_name' => $string,
165 'contact_type' => 'Organization',
166 );
167
168 $this->callAPISuccess('Contact', 'create', $organizationParams);
169 $result = $this->callAPISuccessGetSingle('Contact', $organizationParams);
170 $this->assertEquals($string, $result['organization_name']);
171 }
172
173 /**
174 * Get international string data for testing against api calls.
175 */
176 public function getInternationalStrings() {
177 $invocations = array();
178 $invocations[] = array('Scarabée');
179 $invocations[] = array('Iñtërnâtiônàlizætiøn');
180 $invocations[] = array('これは日本語のテキストです。読めますか');
181 $invocations[] = array('देखें हिन्दी कैसी नजर आती है। अरे वाह ये तो नजर आती है।');
182 return $invocations;
183 }
184
185 /**
186 * Test civicrm_contact_create.
187 *
188 * Verify that preferred language can be set.
189 */
190 public function testAddCreateIndividualWithPreferredLanguage() {
191 $params = array(
192 'first_name' => 'abc1',
193 'contact_type' => 'Individual',
194 'last_name' => 'xyz1',
195 'preferred_language' => 'es_ES',
196 );
197
198 $contact = $this->callAPISuccess('contact', 'create', $params);
199 $this->getAndCheck($params, $contact['id'], 'Contact');
200 }
201
202 /**
203 * Test civicrm_contact_create with sub-types.
204 *
205 * Verify that sub-types are created successfully and not deleted by subsequent updates.
206 */
207 public function testIndividualSubType() {
208 $params = array(
209 'first_name' => 'test abc',
210 'contact_type' => 'Individual',
211 'last_name' => 'test xyz',
212 'contact_sub_type' => array('Student', 'Staff'),
213 );
214 $contact = $this->callAPISuccess('contact', 'create', $params);
215 $cid = $contact['id'];
216
217 $params = array(
218 'id' => $cid,
219 'middle_name' => 'foo',
220 );
221 $this->callAPISuccess('contact', 'create', $params);
222 unset($params['middle_name']);
223
224 $contact = $this->callAPISuccess('contact', 'get', $params);
225
226 $this->assertEquals(array('Student', 'Staff'), $contact['values'][$cid]['contact_sub_type']);
227 }
228
229 /**
230 * Verify that we can retreive contacts of different sub types
231 */
232 public function testGetMultipleContactSubTypes() {
233
234 // This test presumes that there are no parents or students in the dataset
235
236 // create a student
237 $student = $this->callAPISuccess('contact', 'create', array(
238 'email' => 'student@example.com',
239 'contact_type' => 'Individual',
240 'contact_sub_type' => 'Student',
241 ));
242
243 // create a parent
244 $parent = $this->callAPISuccess('contact', 'create', array(
245 'email' => 'parent@example.com',
246 'contact_type' => 'Individual',
247 'contact_sub_type' => 'Parent',
248 ));
249
250 // create a parent
251 $contact = $this->callAPISuccess('contact', 'create', array(
252 'email' => 'parent@example.com',
253 'contact_type' => 'Individual',
254 ));
255
256 // get all students and parents
257 $getParams = array('contact_sub_type' => array('IN' => array('Parent', 'Student')));
258 $result = civicrm_api3('contact', 'get', $getParams);
259
260 // check that we retrieved the student and the parent
261 $this->assertArrayHasKey($student['id'], $result['values']);
262 $this->assertArrayHasKey($parent['id'], $result['values']);
263 $this->assertEquals(2, $result['count']);
264
265 }
266
267 /**
268 * Verify that attempt to create contact with empty params fails.
269 */
270 public function testCreateEmptyContact() {
271 $this->callAPIFailure('contact', 'create', array());
272 }
273
274 /**
275 * Verify that attempt to create contact with bad contact type fails.
276 */
277 public function testCreateBadTypeContact() {
278 $params = array(
279 'email' => 'man1@yahoo.com',
280 'contact_type' => 'Does not Exist',
281 );
282 $this->callAPIFailure('contact', 'create', $params, "'Does not Exist' is not a valid option for field contact_type");
283 }
284
285 /**
286 * Verify that attempt to create individual contact without required fields fails.
287 */
288 public function testCreateBadRequiredFieldsIndividual() {
289 $params = array(
290 'middle_name' => 'This field is not required',
291 'contact_type' => 'Individual',
292 );
293 $this->callAPIFailure('contact', 'create', $params);
294 }
295
296 /**
297 * Verify that attempt to create household contact without required fields fails.
298 */
299 public function testCreateBadRequiredFieldsHousehold() {
300 $params = array(
301 'middle_name' => 'This field is not required',
302 'contact_type' => 'Household',
303 );
304 $this->callAPIFailure('contact', 'create', $params);
305 }
306
307 /**
308 * Test required field check.
309 *
310 * Verify that attempt to create organization contact without required fields fails.
311 */
312 public function testCreateBadRequiredFieldsOrganization() {
313 $params = array(
314 'middle_name' => 'This field is not required',
315 'contact_type' => 'Organization',
316 );
317
318 $this->callAPIFailure('contact', 'create', $params);
319 }
320
321 /**
322 * Verify that attempt to create individual contact with only an email succeeds.
323 */
324 public function testCreateEmailIndividual() {
325 $primaryEmail = 'man3@yahoo.com';
326 $notPrimaryEmail = 'man4@yahoo.com';
327 $params = array(
328 'email' => $primaryEmail,
329 'contact_type' => 'Individual',
330 'location_type_id' => 1,
331 );
332
333 $contact1 = $this->callAPISuccess('contact', 'create', $params);
334
335 $this->assertEquals(3, $contact1['id']);
336 $email1 = $this->callAPISuccess('email', 'get', array('contact_id' => $contact1['id']));
337 $this->assertEquals(1, $email1['count']);
338 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
339
340 $email2 = $this->callAPISuccess('email', 'create', array('contact_id' => $contact1['id'], 'is_primary' => 0, 'email' => $notPrimaryEmail));
341
342 // Case 1: Check with criteria primary 'email' => array('IS NOT NULL' => 1)
343 $result = $this->callAPISuccess('contact', 'get', array('email' => array('IS NOT NULL' => 1)));
344 $primaryEmailContactIds = array_keys($result['values']);
345 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
346
347 // Case 2: Check with criteria primary 'email' => array('<>' => '')
348 $result = $this->callAPISuccess('contact', 'get', array('email' => array('<>' => '')));
349 $primaryEmailContactIds = array_keys($result['values']);
350 $this->assertEquals($primaryEmail, $email1['values'][$email1['id']]['email']);
351
352 // Case 3: Check with email_id='primary email id'
353 $result = $this->callAPISuccess('contact', 'get', array('email_id' => $email1['id']));
354 $this->assertEquals(1, $result['count']);
355 $this->assertEquals($contact1['id'], $result['id']);
356
357 $this->callAPISuccess('contact', 'delete', $contact1);
358 }
359
360 /**
361 * Test creating individual by name.
362 *
363 * Verify create individual contact with only first and last names succeeds.
364 */
365 public function testCreateNameIndividual() {
366 $params = array(
367 'first_name' => 'abc1',
368 'contact_type' => 'Individual',
369 'last_name' => 'xyz1',
370 );
371
372 $this->callAPISuccess('contact', 'create', $params);
373 }
374
375 /**
376 * Test creating individual by display_name.
377 *
378 * Display name & sort name should be set.
379 */
380 public function testCreateDisplayNameIndividual() {
381 $params = array(
382 'display_name' => 'abc1',
383 'contact_type' => 'Individual',
384 );
385
386 $contact = $this->callAPISuccess('contact', 'create', $params);
387 $params['sort_name'] = 'abc1';
388 $this->getAndCheck($params, $contact['id'], 'contact');
389 }
390
391 /**
392 * Test old keys still work.
393 *
394 * Verify that attempt to create individual contact with
395 * first and last names and old key values works
396 */
397 public function testCreateNameIndividualOldKeys() {
398 $params = array(
399 'individual_prefix' => 'Dr.',
400 'first_name' => 'abc1',
401 'contact_type' => 'Individual',
402 'last_name' => 'xyz1',
403 'individual_suffix' => 'Jr.',
404 );
405
406 $contact = $this->callAPISuccess('contact', 'create', $params);
407 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
408
409 $this->assertArrayKeyExists('prefix_id', $result);
410 $this->assertArrayKeyExists('suffix_id', $result);
411 $this->assertArrayKeyExists('gender_id', $result);
412 $this->assertEquals(4, $result['prefix_id']);
413 $this->assertEquals(1, $result['suffix_id']);
414 }
415
416 /**
417 * Test preferred keys work.
418 *
419 * Verify that attempt to create individual contact with
420 * first and last names and old key values works
421 */
422 public function testCreateNameIndividualRecommendedKeys2() {
423 $params = array(
424 'prefix_id' => 'Dr.',
425 'first_name' => 'abc1',
426 'contact_type' => 'Individual',
427 'last_name' => 'xyz1',
428 'suffix_id' => 'Jr.',
429 'gender_id' => 'Male',
430 );
431
432 $contact = $this->callAPISuccess('contact', 'create', $params);
433 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
434
435 $this->assertArrayKeyExists('prefix_id', $result);
436 $this->assertArrayKeyExists('suffix_id', $result);
437 $this->assertArrayKeyExists('gender_id', $result);
438 $this->assertEquals(4, $result['prefix_id']);
439 $this->assertEquals(1, $result['suffix_id']);
440 }
441
442 /**
443 * Test household name is sufficient for create.
444 *
445 * Verify that attempt to create household contact with only
446 * household name succeeds
447 */
448 public function testCreateNameHousehold() {
449 $params = array(
450 'household_name' => 'The abc Household',
451 'contact_type' => 'Household',
452 );
453 $this->callAPISuccess('contact', 'create', $params);
454 }
455
456 /**
457 * Test organization name is sufficient for create.
458 *
459 * Verify that attempt to create organization contact with only
460 * organization name succeeds.
461 */
462 public function testCreateNameOrganization() {
463 $params = array(
464 'organization_name' => 'The abc Organization',
465 'contact_type' => 'Organization',
466 );
467 $this->callAPISuccess('contact', 'create', $params);
468 }
469
470 /**
471 * Verify that attempt to create organization contact without organization name fails.
472 */
473 public function testCreateNoNameOrganization() {
474 $params = array(
475 'first_name' => 'The abc Organization',
476 'contact_type' => 'Organization',
477 );
478 $this->callAPIFailure('contact', 'create', $params);
479 }
480
481 /**
482 * Check that permissions on API key are restricted (CRM-18112).
483 */
484 public function testCreateApiKey() {
485 $config = CRM_Core_Config::singleton();
486 $contactId = $this->individualCreate(array(
487 'first_name' => 'A',
488 'last_name' => 'B',
489 ));
490
491 // Allow edit -- because permissions aren't being checked
492 $config->userPermissionClass->permissions = array();
493 $result = $this->callAPISuccess('Contact', 'create', array(
494 'id' => $contactId,
495 'api_key' => 'original',
496 ));
497 $this->assertEquals('original', $result['values'][$contactId]['api_key']);
498
499 // Allow edit -- because we have adequate permission
500 $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts', 'edit api keys');
501 $result = $this->callAPISuccess('Contact', 'create', array(
502 'check_permissions' => 1,
503 'id' => $contactId,
504 'api_key' => 'abcd1234',
505 ));
506 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
507
508 // Disallow edit -- because we don't have permission
509 $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts');
510 $result = $this->callAPIFailure('Contact', 'create', array(
511 'check_permissions' => 1,
512 'id' => $contactId,
513 'api_key' => 'defg4321',
514 ));
515 $this->assertRegExp(';Permission denied to modify api key;', $result['error_message']);
516
517 // Return everything -- because permissions are not being checked
518 $config->userPermissionClass->permissions = array();
519 $result = $this->callAPISuccess('Contact', 'create', array(
520 'id' => $contactId,
521 'first_name' => 'A2',
522 ));
523 $this->assertEquals('A2', $result['values'][$contactId]['first_name']);
524 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
525 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
526
527 // Return everything -- because we have adequate permission
528 $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts', 'edit api keys');
529 $result = $this->callAPISuccess('Contact', 'create', array(
530 'check_permissions' => 1,
531 'id' => $contactId,
532 'first_name' => 'A3',
533 ));
534 $this->assertEquals('A3', $result['values'][$contactId]['first_name']);
535 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
536 $this->assertEquals('abcd1234', $result['values'][$contactId]['api_key']);
537
538 // Restricted return -- because we don't have permission
539 $config->userPermissionClass->permissions = array('access CiviCRM', 'edit all contacts');
540 $result = $this->callAPISuccess('Contact', 'create', array(
541 'check_permissions' => 1,
542 'id' => $contactId,
543 'first_name' => 'A4',
544 ));
545 $this->assertEquals('A4', $result['values'][$contactId]['first_name']);
546 $this->assertEquals('B', $result['values'][$contactId]['last_name']);
547 $this->assertTrue(empty($result['values'][$contactId]['api_key']));
548 }
549
550 /**
551 * Check with complete array + custom field.
552 *
553 * Note that the test is written on purpose without any
554 * variables specific to participant so it can be replicated into other entities
555 * and / or moved to the automated test suite
556 */
557 public function testCreateWithCustom() {
558 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
559
560 $params = $this->_params;
561 $params['custom_' . $ids['custom_field_id']] = "custom string";
562 $description = "This demonstrates setting a custom field through the API.";
563 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, $description);
564
565 $check = $this->callAPISuccess($this->_entity, 'get', array(
566 'return.custom_' . $ids['custom_field_id'] => 1,
567 'id' => $result['id'],
568 ));
569 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
570
571 $this->customFieldDelete($ids['custom_field_id']);
572 $this->customGroupDelete($ids['custom_group_id']);
573 }
574
575 /**
576 * CRM-12773 - expectation is that civicrm quietly ignores fields without values.
577 */
578 public function testCreateWithNULLCustomCRM12773() {
579 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
580 $params = $this->_params;
581 $params['custom_' . $ids['custom_field_id']] = NULL;
582 $this->callAPISuccess('contact', 'create', $params);
583 $this->customFieldDelete($ids['custom_field_id']);
584 $this->customGroupDelete($ids['custom_group_id']);
585 }
586
587 /**
588 * CRM-14232 test preferred language set to site default if not passed.
589 */
590 public function testCreatePreferredLanguageUnset() {
591 $this->callAPISuccess('Contact', 'create', array(
592 'first_name' => 'Snoop',
593 'last_name' => 'Dog',
594 'contact_type' => 'Individual')
595 );
596 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
597 $this->assertEquals('en_US', $result['preferred_language']);
598 }
599
600 /**
601 * CRM-14232 test preferred language returns setting if not passed.
602 */
603 public function testCreatePreferredLanguageSet() {
604 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'fr_FR'));
605 $this->callAPISuccess('Contact', 'create', array(
606 'first_name' => 'Snoop',
607 'last_name' => 'Dog',
608 'contact_type' => 'Individual',
609 ));
610 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
611 $this->assertEquals('fr_FR', $result['preferred_language']);
612 }
613
614 /**
615 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
616 */
617 public function testCreatePreferredLanguageNull() {
618 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
619 $this->callAPISuccess('Contact', 'create', array(
620 'first_name' => 'Snoop',
621 'last_name' => 'Dog',
622 'contact_type' => 'Individual',
623 )
624 );
625 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
626 $this->assertEquals(NULL, $result['preferred_language']);
627 }
628
629 /**
630 * CRM-14232 test preferred language returns setting if not passed where setting is NULL.
631 */
632 public function testCreatePreferredLanguagePassed() {
633 $this->callAPISuccess('Setting', 'create', array('contact_default_language' => 'null'));
634 $this->callAPISuccess('Contact', 'create', array(
635 'first_name' => 'Snoop',
636 'last_name' => 'Dog',
637 'contact_type' => 'Individual',
638 'preferred_language' => 'en_AU',
639 ));
640 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Dog'));
641 $this->assertEquals('en_AU', $result['preferred_language']);
642 }
643
644 /**
645 * CRM-15792 - create/update datetime field for contact.
646 */
647 public function testCreateContactCustomFldDateTime() {
648 $customGroup = $this->customGroupCreate(array('extends' => 'Individual', 'title' => 'datetime_test_group'));
649 $dateTime = CRM_Utils_Date::currentDBDate();
650 //check date custom field is saved along with time when time_format is set
651 $params = array(
652 'first_name' => 'abc3',
653 'last_name' => 'xyz3',
654 'contact_type' => 'Individual',
655 'email' => 'man3@yahoo.com',
656 'api.CustomField.create' => array(
657 'custom_group_id' => $customGroup['id'],
658 'name' => 'test_datetime',
659 'label' => 'Demo Date',
660 'html_type' => 'Select Date',
661 'data_type' => 'Date',
662 'time_format' => 2,
663 'weight' => 4,
664 'is_required' => 1,
665 'is_searchable' => 0,
666 'is_active' => 1,
667 ),
668 );
669
670 $result = $this->callAPISuccess('Contact', 'create', $params);
671 $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
672 $this->assertNotNull($result['id']);
673 $this->assertNotNull($customFldId);
674
675 $params = array(
676 'id' => $result['id'],
677 "custom_{$customFldId}" => $dateTime,
678 'api.CustomValue.get' => 1,
679 );
680
681 $result = $this->callAPISuccess('Contact', 'create', $params);
682 $this->assertNotNull($result['id']);
683 $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
684 $this->assertNotNull($customFldDate);
685 $this->assertEquals($dateTime, $customFldDate);
686 $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
687 $dateTime = date('Ymd');
688 //date custom field should not contain time part when time_format is null
689 $params = array(
690 'id' => $result['id'],
691 'api.CustomField.create' => array(
692 'id' => $customFldId,
693 'html_type' => 'Select Date',
694 'data_type' => 'Date',
695 'time_format' => '',
696 ),
697 'api.CustomValue.create' => array(
698 'id' => $customValueId,
699 'entity_id' => $result['id'],
700 "custom_{$customFldId}" => $dateTime,
701 ),
702 'api.CustomValue.get' => 1,
703 );
704 $result = $this->callAPISuccess('Contact', 'create', $params);
705 $this->assertNotNull($result['id']);
706 $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
707 $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
708 $this->assertNotNull($customFldDate);
709 $this->assertEquals($dateTime, $customFldDate);
710 $this->assertEquals(000000, $customFldTime);
711 $this->callAPISuccess('Contact', 'create', $params);
712 }
713
714
715 /**
716 * Test creating a current employer through API.
717 */
718 public function testContactCreateCurrentEmployer() {
719 // Here we will just do the get for set-up purposes.
720 $count = $this->callAPISuccess('contact', 'getcount', array(
721 'organization_name' => 'new employer org',
722 'contact_type' => 'Organization',
723 ));
724 $this->assertEquals(0, $count);
725 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
726 'current_employer' => 'new employer org',
727 )
728 ));
729 // do it again as an update to check it doesn't cause an error
730 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
731 'current_employer' => 'new employer org',
732 'id' => $employerResult['id'],
733 )
734 ));
735 $expectedCount = 1;
736 $this->callAPISuccess('contact', 'getcount', array(
737 'organization_name' => 'new employer org',
738 'contact_type' => 'Organization',
739 ),
740 $expectedCount);
741
742 $result = $this->callAPISuccess('contact', 'getsingle', array(
743 'id' => $employerResult['id'],
744 ));
745
746 $this->assertEquals('new employer org', $result['current_employer']);
747
748 }
749
750 /**
751 * Test creating a current employer through API.
752 *
753 * Check it will re-activate a de-activated employer
754 */
755 public function testContactCreateDuplicateCurrentEmployerEnables() {
756 // Set up - create employer relationship.
757 $employerResult = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
758 'current_employer' => 'new employer org',
759 )
760 ));
761 $relationship = $this->callAPISuccess('relationship', 'get', array(
762 'contact_id_a' => $employerResult['id'],
763 ));
764
765 //disable & check it is disabled
766 $this->callAPISuccess('relationship', 'create', array('id' => $relationship['id'], 'is_active' => 0));
767 $this->callAPISuccess('relationship', 'getvalue', array(
768 'id' => $relationship['id'],
769 'return' => 'is_active',
770 ), 0);
771
772 // Re-set the current employer - thus enabling the relationship.
773 $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
774 'current_employer' => 'new employer org',
775 'id' => $employerResult['id'],
776 )
777 ));
778 //check is_active is now 1
779 $relationship = $this->callAPISuccess('relationship', 'getsingle', array(
780 'return' => 'is_active',
781 ));
782 $this->assertEquals(1, $relationship['is_active']);
783 }
784
785 /**
786 * Check deceased contacts are not retrieved.
787 *
788 * Note at time of writing the default is to return default. This should possibly be changed & test added.
789 */
790 public function testGetDeceasedRetrieved() {
791 $this->callAPISuccess($this->_entity, 'create', $this->_params);
792 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
793 'first_name' => 'bb',
794 'last_name' => 'ccc',
795 'contact_type' => 'Individual',
796 'is_deceased' => 1,
797 ));
798 $result = $this->callAPISuccess($this->_entity, 'get', array('is_deceased' => 0));
799 $this->assertFalse(array_key_exists($c2['id'], $result['values']));
800 }
801
802 /**
803 * Test that sort works - old syntax.
804 */
805 public function testGetSort() {
806 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
807 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
808 'first_name' => 'bb',
809 'last_name' => 'ccc',
810 'contact_type' => 'Individual',
811 ));
812 $result = $this->callAPISuccess($this->_entity, 'get', array(
813 'sort' => 'first_name ASC',
814 'return.first_name' => 1,
815 'sequential' => 1,
816 'rowCount' => 1,
817 'contact_type' => 'Individual',
818 ));
819
820 $this->assertEquals('abc1', $result['values'][0]['first_name']);
821 $result = $this->callAPISuccess($this->_entity, 'get', array(
822 'sort' => 'first_name DESC',
823 'return.first_name' => 1,
824 'sequential' => 1,
825 'rowCount' => 1,
826 ));
827 $this->assertEquals('bb', $result['values'][0]['first_name']);
828
829 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
830 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
831 }
832
833 /**
834 * Test that we can retrieve contacts using array syntax.
835 *
836 * I.e 'id' => array('IN' => array('3,4')).
837 */
838 public function testGetINIDArray() {
839 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
840 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
841 'first_name' => 'bb',
842 'last_name' => 'ccc',
843 'contact_type' => 'Individual',
844 ));
845 $c3 = $this->callAPISuccess($this->_entity, 'create', array(
846 'first_name' => 'hh',
847 'last_name' => 'll',
848 'contact_type' => 'Individual',
849 ));
850 $result = $this->callAPISuccess($this->_entity, 'get', array('id' => array('IN' => array($c1['id'], $c3['id']))));
851 $this->assertEquals(2, $result['count']);
852 $this->assertEquals(array($c1['id'], $c3['id']), array_keys($result['values']));
853 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
854 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
855 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c3['id']));
856 }
857
858 /**
859 * Test variants on deleted behaviour.
860 */
861 public function testGetDeleted() {
862 $params = $this->_params;
863 $contact1 = $this->callAPISuccess('contact', 'create', $params);
864 $params['is_deleted'] = 1;
865 $params['last_name'] = 'bcd';
866 $contact2 = $this->callAPISuccess('contact', 'create', $params);
867 $countActive = $this->callAPISuccess('contact', 'getcount', array(
868 'showAll' => 'active',
869 'contact_type' => 'Individual',
870 ));
871 $countAll = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'all', 'contact_type' => 'Individual'));
872 $countTrash = $this->callAPISuccess('contact', 'getcount', array('showAll' => 'trash', 'contact_type' => 'Individual'));
873 $countDefault = $this->callAPISuccess('contact', 'getcount', array('contact_type' => 'Individual'));
874 $countDeleted = $this->callAPISuccess('contact', 'getcount', array(
875 'contact_type' => 'Individual',
876 'contact_is_deleted' => 1,
877 ));
878 $countNotDeleted = $this->callAPISuccess('contact', 'getcount', array(
879 'contact_is_deleted' => 0,
880 'contact_type' => 'Individual',
881 ));
882 $this->callAPISuccess('contact', 'delete', array('id' => $contact1['id']));
883 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
884 $this->assertEquals(1, $countNotDeleted, 'contact_is_deleted => 0 is respected');
885 $this->assertEquals(1, $countActive);
886 $this->assertEquals(1, $countTrash);
887 $this->assertEquals(2, $countAll);
888 $this->assertEquals(1, $countDeleted);
889 $this->assertEquals(1, $countDefault, 'Only active by default in line');
890 }
891
892 /**
893 * Test that sort works - new syntax.
894 */
895 public function testGetSortNewSyntax() {
896 $c1 = $this->callAPISuccess($this->_entity, 'create', $this->_params);
897 $c2 = $this->callAPISuccess($this->_entity, 'create', array(
898 'first_name' => 'bb',
899 'last_name' => 'ccc',
900 'contact_type' => 'Individual',
901 ));
902 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
903 'return' => 'first_name',
904 'contact_type' => 'Individual',
905 'options' => array(
906 'limit' => 1,
907 'sort' => 'first_name',
908 ),
909 ));
910 $this->assertEquals('abc1', $result);
911
912 $result = $this->callAPISuccess($this->_entity, 'getvalue', array(
913 'return' => 'first_name',
914 'contact_type' => 'Individual',
915 'options' => array(
916 'limit' => 1,
917 'sort' => 'first_name DESC',
918 ),
919 ));
920 $this->assertEquals('bb', $result);
921
922 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c1['id']));
923 $this->callAPISuccess($this->_entity, 'delete', array('id' => $c2['id']));
924 }
925
926 /**
927 * Test sort and limit for chained relationship get.
928 *
929 * https://issues.civicrm.org/jira/browse/CRM-15983
930 */
931 public function testSortLimitChainedRelationshipGetCRM15983() {
932 // Some contact
933 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
934 'first_name' => 'Jules',
935 'last_name' => 'Smos',
936 'contact_type' => 'Individual',
937 ));
938
939 // Create another contact with two relationships.
940 $create_params = array(
941 'first_name' => 'Jos',
942 'last_name' => 'Smos',
943 'contact_type' => 'Individual',
944 'api.relationship.create' => array(
945 array(
946 'contact_id_a' => '$value.id',
947 'contact_id_b' => $create_result_1['id'],
948 // spouse of:
949 'relationship_type_id' => 2,
950 'start_date' => '2005-01-12',
951 'end_date' => '2006-01-11',
952 'description' => 'old',
953 ),
954 array(
955 'contact_id_a' => '$value.id',
956 'contact_id_b' => $create_result_1['id'],
957 // spouse of (was married twice :))
958 'relationship_type_id' => 2,
959 'start_date' => '2006-07-01',
960 'end_date' => '2010-07-01',
961 'description' => 'new',
962 ),
963 ),
964 );
965 $create_result = $this->callAPISuccess('contact', 'create', $create_params);
966
967 // Try to retrieve the contact and the most recent relationship.
968 $get_params = array(
969 'sequential' => 1,
970 'id' => $create_result['id'],
971 'api.relationship.get' => array(
972 'contact_id_a' => '$value.id',
973 'options' => array(
974 'limit' => '1',
975 'sort' => 'start_date DESC',
976 )),
977 );
978 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
979
980 // Clean up.
981 $this->callAPISuccess('contact', 'delete', array(
982 'id' => $create_result['id'],
983 ));
984
985 // Assert.
986 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
987 $this->assertEquals('new', $get_result['api.relationship.get']['values'][0]['description']);
988 }
989
990 /**
991 * Test apostrophe works in get & create.
992 */
993 public function testGetApostropheCRM10857() {
994 $params = array_merge($this->_params, array('last_name' => "O'Connor"));
995 $this->callAPISuccess($this->_entity, 'create', $params);
996 $result = $this->callAPISuccess($this->_entity, 'getsingle', array(
997 'last_name' => "O'Connor",
998 'sequential' => 1,
999 ));
1000 $this->assertEquals("O'Connor", $result['last_name'], 'in line' . __LINE__);
1001 }
1002
1003 /**
1004 * Check with complete array + custom field.
1005 *
1006 * Note that the test is written on purpose without any
1007 * variables specific to participant so it can be replicated into other entities
1008 * and / or moved to the automated test suite
1009 */
1010 public function testGetWithCustom() {
1011 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1012
1013 $params = $this->_params;
1014 $params['custom_' . $ids['custom_field_id']] = "custom string";
1015 $description = "This demonstrates setting a custom field through the API.";
1016 $subfile = "CustomFieldGet";
1017 $result = $this->callAPISuccess($this->_entity, 'create', $params);
1018
1019 $check = $this->callAPIAndDocument($this->_entity, 'get', array(
1020 'return.custom_' . $ids['custom_field_id'] => 1,
1021 'id' => $result['id'],
1022 ), __FUNCTION__, __FILE__, $description, $subfile);
1023
1024 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
1025 $fields = ($this->callAPISuccess('contact', 'getfields', $params));
1026 $this->assertTrue(is_array($fields['values']['custom_' . $ids['custom_field_id']]));
1027 $this->customFieldDelete($ids['custom_field_id']);
1028 $this->customGroupDelete($ids['custom_group_id']);
1029 }
1030
1031 /**
1032 * Check with complete array + custom field.
1033 *
1034 * Note that the test is written on purpose without any
1035 * variables specific to participant so it can be replicated into other entities
1036 * and / or moved to the automated test suite
1037 */
1038 public function testGetWithCustomReturnSyntax() {
1039 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
1040
1041 $params = $this->_params;
1042 $params['custom_' . $ids['custom_field_id']] = "custom string";
1043 $description = "This demonstrates setting a custom field through the API.";
1044 $subfile = "CustomFieldGetReturnSyntaxVariation";
1045 $result = $this->callAPISuccess($this->_entity, 'create', $params);
1046 $params = array('return' => 'custom_' . $ids['custom_field_id'], 'id' => $result['id']);
1047 $check = $this->callAPIAndDocument($this->_entity, 'get', $params, __FUNCTION__, __FILE__, $description, $subfile);
1048
1049 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
1050 $this->customFieldDelete($ids['custom_field_id']);
1051 $this->customGroupDelete($ids['custom_group_id']);
1052 }
1053
1054 /**
1055 * Check that address name, ID is returned if required.
1056 */
1057 public function testGetReturnAddress() {
1058 $contactID = $this->individualCreate();
1059 $result = $this->callAPISuccess('address', 'create', array(
1060 'contact_id' => $contactID,
1061 'address_name' => 'My house',
1062 'location_type_id' => 'Home',
1063 'street_address' => '1 my road',
1064 ));
1065 $addressID = $result['id'];
1066
1067 $result = $this->callAPISuccessGetSingle('contact', array(
1068 'return' => 'address_name, street_address, address_id',
1069 'id' => $contactID,
1070 ));
1071 $this->assertEquals($addressID, $result['address_id']);
1072 $this->assertEquals('1 my road', $result['street_address']);
1073 $this->assertEquals('My house', $result['address_name']);
1074
1075 }
1076
1077 /**
1078 * Test group filter syntaxes.
1079 */
1080 public function testGetGroupIDFromContact() {
1081 $groupId = $this->groupCreate();
1082 $params = array(
1083 'email' => 'man2@yahoo.com',
1084 'contact_type' => 'Individual',
1085 'location_type_id' => 1,
1086 'api.group_contact.create' => array('group_id' => $groupId),
1087 );
1088
1089 $this->callAPISuccess('contact', 'create', $params);
1090 // testing as integer
1091 $params = array(
1092 'filter.group_id' => $groupId,
1093 'contact_type' => 'Individual',
1094 );
1095 $result = $this->callAPISuccess('contact', 'get', $params);
1096 $this->assertEquals(1, $result['count']);
1097 // group 26 doesn't exist, but we can still search contacts in it.
1098 $params = array(
1099 'filter.group_id' => 26,
1100 'contact_type' => 'Individual',
1101 );
1102 $this->callAPISuccess('contact', 'get', $params);
1103 // testing as string
1104 $params = array(
1105 'filter.group_id' => "$groupId, 26",
1106 'contact_type' => 'Individual',
1107 );
1108 $result = $this->callAPISuccess('contact', 'get', $params);
1109 $this->assertEquals(1, $result['count']);
1110 $params = array(
1111 'filter.group_id' => "26,27",
1112 'contact_type' => 'Individual',
1113 );
1114 $this->callAPISuccess('contact', 'get', $params);
1115
1116 // testing as string
1117 $params = array(
1118 'filter.group_id' => array($groupId, 26),
1119 'contact_type' => 'Individual',
1120 );
1121 $result = $this->callAPISuccess('contact', 'get', $params);
1122 $this->assertEquals(1, $result['count']);
1123
1124 //test in conjunction with other criteria
1125 $params = array(
1126 'filter.group_id' => array($groupId, 26),
1127 'contact_type' => 'Organization',
1128 );
1129 $this->callAPISuccess('contact', 'get', $params);
1130 $params = array(
1131 'filter.group_id' => array(26, 27),
1132 'contact_type' => 'Individual',
1133 );
1134 $result = $this->callAPISuccess('contact', 'get', $params);
1135 $this->assertEquals(0, $result['count']);
1136 }
1137
1138 /**
1139 * Verify that attempt to create individual contact with two chained websites succeeds.
1140 */
1141 public function testCreateIndividualWithContributionDottedSyntax() {
1142 $description = "This demonstrates the syntax to create 2 chained entities.";
1143 $subFile = "ChainTwoWebsites";
1144 $params = array(
1145 'first_name' => 'abc3',
1146 'last_name' => 'xyz3',
1147 'contact_type' => 'Individual',
1148 'email' => 'man3@yahoo.com',
1149 'api.contribution.create' => array(
1150 'receive_date' => '2010-01-01',
1151 'total_amount' => 100.00,
1152 'financial_type_id' => $this->_financialTypeId,
1153 'payment_instrument_id' => 1,
1154 'non_deductible_amount' => 10.00,
1155 'fee_amount' => 50.00,
1156 'net_amount' => 90.00,
1157 'trxn_id' => 15345,
1158 'invoice_id' => 67990,
1159 'source' => 'SSF',
1160 'contribution_status_id' => 1,
1161 ),
1162 'api.website.create' => array(
1163 'url' => "http://civicrm.org",
1164 ),
1165 'api.website.create.2' => array(
1166 'url' => "http://chained.org",
1167 ),
1168 );
1169
1170 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subFile);
1171
1172 // checking child function result not covered in callAPIAndDocument
1173 $this->assertAPISuccess($result['values'][$result['id']]['api.website.create']);
1174 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create.2']['values'][0]['url']);
1175 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create']['values'][0]['url']);
1176
1177 // delete the contact
1178 $this->callAPISuccess('contact', 'delete', $result);
1179 }
1180
1181 /**
1182 * Verify that attempt to create individual contact with chained contribution and website succeeds.
1183 */
1184 public function testCreateIndividualWithContributionChainedArrays() {
1185 $params = array(
1186 'first_name' => 'abc3',
1187 'last_name' => 'xyz3',
1188 'contact_type' => 'Individual',
1189 'email' => 'man3@yahoo.com',
1190 'api.contribution.create' => array(
1191 'receive_date' => '2010-01-01',
1192 'total_amount' => 100.00,
1193 'financial_type_id' => $this->_financialTypeId,
1194 'payment_instrument_id' => 1,
1195 'non_deductible_amount' => 10.00,
1196 'fee_amount' => 50.00,
1197 'net_amount' => 90.00,
1198 'trxn_id' => 12345,
1199 'invoice_id' => 67890,
1200 'source' => 'SSF',
1201 'contribution_status_id' => 1,
1202 ),
1203 'api.website.create' => array(
1204 array(
1205 'url' => "http://civicrm.org",
1206 ),
1207 array(
1208 'url' => "http://chained.org",
1209 'website_type_id' => 2,
1210 ),
1211 ),
1212 );
1213
1214 $description = "Demonstrates creating two websites as an array.";
1215 $subfile = "ChainTwoWebsitesSyntax2";
1216 $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
1217
1218 // the callAndDocument doesn't check the chained call
1219 $this->assertEquals(0, $result['values'][$result['id']]['api.website.create'][0]['is_error']);
1220 $this->assertEquals("http://chained.org", $result['values'][$result['id']]['api.website.create'][1]['values'][0]['url']);
1221 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.create'][0]['values'][0]['url']);
1222
1223 $this->callAPISuccess('contact', 'delete', $result);
1224 }
1225
1226 /**
1227 * Test for direction when chaining relationships.
1228 *
1229 * https://issues.civicrm.org/jira/browse/CRM-16084
1230 */
1231 public function testDirectionChainingRelationshipsCRM16084() {
1232 // Some contact, called Jules.
1233 $create_result_1 = $this->callAPISuccess('contact', 'create', array(
1234 'first_name' => 'Jules',
1235 'last_name' => 'Smos',
1236 'contact_type' => 'Individual',
1237 ));
1238
1239 // Another contact: Jos, child of Jules.
1240 $create_params = array(
1241 'first_name' => 'Jos',
1242 'last_name' => 'Smos',
1243 'contact_type' => 'Individual',
1244 'api.relationship.create' => array(
1245 array(
1246 'contact_id_a' => '$value.id',
1247 'contact_id_b' => $create_result_1['id'],
1248 // child of
1249 'relationship_type_id' => 1,
1250 ),
1251 ),
1252 );
1253 $create_result_2 = $this->callAPISuccess('contact', 'create', $create_params);
1254
1255 // Mia is the child of Jos.
1256 $create_params = array(
1257 'first_name' => 'Mia',
1258 'last_name' => 'Smos',
1259 'contact_type' => 'Individual',
1260 'api.relationship.create' => array(
1261 array(
1262 'contact_id_a' => '$value.id',
1263 'contact_id_b' => $create_result_2['id'],
1264 // child of
1265 'relationship_type_id' => 1,
1266 ),
1267 ),
1268 );
1269 $create_result_3 = $this->callAPISuccess('contact', 'create', $create_params);
1270
1271 // Get Jos and his children.
1272 $get_params = array(
1273 'sequential' => 1,
1274 'id' => $create_result_2['id'],
1275 'api.relationship.get' => array(
1276 'contact_id_b' => '$value.id',
1277 'relationship_type_id' => 1,
1278 ),
1279 );
1280 $get_result = $this->callAPISuccess('contact', 'getsingle', $get_params);
1281
1282 // Clean up first.
1283 $this->callAPISuccess('contact', 'delete', array(
1284 'id' => $create_result_1['id'],
1285 ));
1286 $this->callAPISuccess('contact', 'delete', array(
1287 'id' => $create_result_2['id'],
1288 ));
1289 $this->callAPISuccess('contact', 'delete', array(
1290 'id' => $create_result_2['id'],
1291 ));
1292
1293 // Assert.
1294 $this->assertEquals(1, $get_result['api.relationship.get']['count']);
1295 $this->assertEquals($create_result_3['id'], $get_result['api.relationship.get']['values'][0]['contact_id_a']);
1296 }
1297
1298 /**
1299 * Verify that attempt to create individual contact with first, and last names and email succeeds.
1300 */
1301 public function testCreateIndividualWithNameEmail() {
1302 $params = array(
1303 'first_name' => 'abc3',
1304 'last_name' => 'xyz3',
1305 'contact_type' => 'Individual',
1306 'email' => 'man3@yahoo.com',
1307 );
1308
1309 $contact = $this->callAPISuccess('contact', 'create', $params);
1310
1311 $this->callAPISuccess('contact', 'delete', $contact);
1312 }
1313
1314 /**
1315 * Verify that attempt to create individual contact with no data fails.
1316 */
1317 public function testCreateIndividualWithOutNameEmail() {
1318 $params = array(
1319 'contact_type' => 'Individual',
1320 );
1321 $this->callAPIFailure('contact', 'create', $params);
1322 }
1323
1324 /**
1325 * Test create individual contact with first &last names, email and location type succeeds.
1326 */
1327 public function testCreateIndividualWithNameEmailLocationType() {
1328 $params = array(
1329 'first_name' => 'abc4',
1330 'last_name' => 'xyz4',
1331 'email' => 'man4@yahoo.com',
1332 'contact_type' => 'Individual',
1333 'location_type_id' => 1,
1334 );
1335 $result = $this->callAPISuccess('contact', 'create', $params);
1336
1337 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
1338 }
1339
1340 /**
1341 * Verify that when changing employers the old employer relationship becomes inactive.
1342 */
1343 public function testCreateIndividualWithEmployer() {
1344 $employer = $this->organizationCreate();
1345 $employer2 = $this->organizationCreate();
1346
1347 $params = array(
1348 'email' => 'man4@yahoo.com',
1349 'contact_type' => 'Individual',
1350 'employer_id' => $employer,
1351 );
1352
1353 $result = $this->callAPISuccess('contact', 'create', $params);
1354 $relationships = $this->callAPISuccess('relationship', 'get', array(
1355 'contact_id_a' => $result['id'],
1356 'sequential' => 1,
1357 ));
1358
1359 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1360
1361 // Add more random relationships to make the test more realistic
1362 foreach (array('Employee of', 'Volunteer for') as $relationshipType) {
1363 $relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $relationshipType, 'id', 'name_a_b');
1364 $this->callAPISuccess('relationship', 'create', array(
1365 'contact_id_a' => $result['id'],
1366 'contact_id_b' => $this->organizationCreate(),
1367 'is_active' => 1,
1368 'relationship_type_id' => $relTypeId,
1369 ));
1370 }
1371
1372 // Add second employer
1373 $params['employer_id'] = $employer2;
1374 $params['id'] = $result['id'];
1375 $result = $this->callAPISuccess('contact', 'create', $params);
1376
1377 $relationships = $this->callAPISuccess('relationship', 'get', array(
1378 'contact_id_a' => $result['id'],
1379 'sequential' => 1,
1380 'is_active' => 0,
1381 ));
1382
1383 $this->assertEquals($employer, $relationships['values'][0]['contact_id_b']);
1384 }
1385
1386 /**
1387 * Verify that attempt to create household contact with details succeeds.
1388 */
1389 public function testCreateHouseholdDetails() {
1390 $params = array(
1391 'household_name' => 'abc8\'s House',
1392 'nick_name' => 'x House',
1393 'email' => 'man8@yahoo.com',
1394 'contact_type' => 'Household',
1395 );
1396
1397 $contact = $this->callAPISuccess('contact', 'create', $params);
1398
1399 $this->callAPISuccess('contact', 'delete', $contact);
1400 }
1401
1402 /**
1403 * Verify that attempt to create household contact with inadequate details fails.
1404 */
1405 public function testCreateHouseholdInadequateDetails() {
1406 $params = array(
1407 'nick_name' => 'x House',
1408 'email' => 'man8@yahoo.com',
1409 'contact_type' => 'Household',
1410 );
1411 $this->callAPIFailure('contact', 'create', $params);
1412 }
1413
1414 /**
1415 * Verify successful update of individual contact.
1416 */
1417 public function testUpdateIndividualWithAll() {
1418 // Insert a row in civicrm_contact creating individual contact.
1419 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1420 $op->execute($this->_dbconn,
1421 $this->createXMLDataSet(
1422 dirname(__FILE__) . '/dataset/contact_ind.xml'
1423 )
1424 );
1425
1426 $params = array(
1427 'id' => 23,
1428 'first_name' => 'abcd',
1429 'contact_type' => 'Individual',
1430 'nick_name' => 'This is nickname first',
1431 'do_not_email' => '1',
1432 'do_not_phone' => '1',
1433 'do_not_mail' => '1',
1434 'do_not_trade' => '1',
1435 'legal_identifier' => 'ABC23853ZZ2235',
1436 'external_identifier' => '1928837465',
1437 'image_URL' => 'http://some.url.com/image.jpg',
1438 'home_url' => 'http://www.example.org',
1439
1440 );
1441
1442 $this->callAPISuccess('Contact', 'Update', $params);
1443 $getResult = $this->callAPISuccess('Contact', 'Get', $params);
1444 unset($params['contact_id']);
1445 //Todo - neither API v2 or V3 are testing for home_url - not sure if it is being set.
1446 //reducing this test partially back to api v2 level to get it through
1447 unset($params['home_url']);
1448 foreach ($params as $key => $value) {
1449 $this->assertEquals($value, $getResult['values'][23][$key]);
1450 }
1451 // Check updated civicrm_contact against expected.
1452 $expected = $this->createXMLDataSet(
1453 dirname(__FILE__) . '/dataset/contact_ind_upd.xml'
1454 );
1455 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1456 $this->_dbconn
1457 );
1458 $actual->addTable('civicrm_contact');
1459 $expected->matches($actual);
1460 }
1461
1462 /**
1463 * Verify successful update of organization contact.
1464 */
1465 public function testUpdateOrganizationWithAll() {
1466 // Insert a row in civicrm_contact creating organization contact
1467 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1468 $op->execute($this->_dbconn,
1469 $this->createXMLDataSet(
1470 dirname(__FILE__) . '/dataset/contact_org.xml'
1471 )
1472 );
1473
1474 $params = array(
1475 'id' => 24,
1476 'organization_name' => 'WebAccess India Pvt Ltd',
1477 'legal_name' => 'WebAccess',
1478 'sic_code' => 'ABC12DEF',
1479 'contact_type' => 'Organization',
1480 );
1481
1482 $this->callAPISuccess('Contact', 'Update', $params);
1483
1484 // Check updated civicrm_contact against expected.
1485 $expected = $this->createXMLDataSet(
1486 dirname(__FILE__) . '/dataset/contact_org_upd.xml'
1487 );
1488 $actual = new PHPUnit_Extensions_Database_DataSet_QueryDataSet(
1489 $this->_dbconn
1490 );
1491 $actual->addTable('civicrm_contact');
1492 $expected->matches($actual);
1493 }
1494
1495 /**
1496 * Verify successful update of household contact.
1497 */
1498 public function testUpdateHouseholdWithAll() {
1499 // Insert a row in civicrm_contact creating household contact
1500 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1501 $op->execute($this->_dbconn,
1502 $this->createXMLDataSet(
1503 dirname(__FILE__) . '/dataset/contact_hld.xml'
1504 )
1505 );
1506
1507 $params = array(
1508 'id' => 25,
1509 'household_name' => 'ABC household',
1510 'nick_name' => 'ABC House',
1511 'contact_type' => 'Household',
1512 );
1513
1514 $result = $this->callAPISuccess('Contact', 'Update', $params);
1515
1516 $expected = array(
1517 'contact_type' => 'Household',
1518 'is_opt_out' => 0,
1519 'sort_name' => 'ABC household',
1520 'display_name' => 'ABC household',
1521 'nick_name' => 'ABC House',
1522 );
1523 $this->getAndCheck($expected, $result['id'], 'contact');
1524 }
1525
1526 /**
1527 * Test civicrm_update() without contact type.
1528 *
1529 * Deliberately exclude contact_type as it should still cope using civicrm_api.
1530 *
1531 * CRM-7645.
1532 */
1533 public function testUpdateCreateWithID() {
1534 // Insert a row in civicrm_contact creating individual contact.
1535 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1536 $op->execute($this->_dbconn,
1537 $this->createXMLDataSet(
1538 dirname(__FILE__) . '/dataset/contact_ind.xml'
1539 )
1540 );
1541
1542 $params = array(
1543 'id' => 23,
1544 'first_name' => 'abcd',
1545 'last_name' => 'wxyz',
1546 );
1547 $this->callAPISuccess('Contact', 'Update', $params);
1548 }
1549
1550 /**
1551 * Test civicrm_contact_delete() with no contact ID.
1552 */
1553 public function testContactDeleteNoID() {
1554 $params = array(
1555 'foo' => 'bar',
1556 );
1557 $this->callAPIFailure('contact', 'delete', $params);
1558 }
1559
1560 /**
1561 * Test civicrm_contact_delete() with error.
1562 */
1563 public function testContactDeleteError() {
1564 $params = array('contact_id' => 999);
1565 $this->callAPIFailure('contact', 'delete', $params);
1566 }
1567
1568 /**
1569 * Test civicrm_contact_delete().
1570 */
1571 public function testContactDelete() {
1572 $contactID = $this->individualCreate();
1573 $params = array(
1574 'id' => $contactID,
1575 );
1576 $this->callAPIAndDocument('contact', 'delete', $params, __FUNCTION__, __FILE__);
1577 }
1578
1579 /**
1580 * Test civicrm_contact_get() return only first name.
1581 */
1582 public function testContactGetRetFirst() {
1583 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1584 $params = array(
1585 'contact_id' => $contact['id'],
1586 'return_first_name' => TRUE,
1587 'sort' => 'first_name',
1588 );
1589 $result = $this->callAPISuccess('contact', 'get', $params);
1590 $this->assertEquals(1, $result['count']);
1591 $this->assertEquals($contact['id'], $result['id']);
1592 $this->assertEquals('abc1', $result['values'][$contact['id']]['first_name']);
1593 }
1594
1595 /**
1596 * Test civicrm_contact_get() return only first name & last name.
1597 *
1598 * Use comma separated string return with a space.
1599 */
1600 public function testContactGetReturnFirstLast() {
1601 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1602 $params = array(
1603 'contact_id' => $contact['id'],
1604 'return' => 'first_name, last_name',
1605 );
1606 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1607 $this->assertEquals('abc1', $result['first_name']);
1608 $this->assertEquals('xyz1', $result['last_name']);
1609 //check that other defaults not returns
1610 $this->assertArrayNotHasKey('sort_name', $result);
1611 $params = array(
1612 'contact_id' => $contact['id'],
1613 'return' => 'first_name,last_name',
1614 );
1615 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1616 $this->assertEquals('abc1', $result['first_name']);
1617 $this->assertEquals('xyz1', $result['last_name']);
1618 //check that other defaults not returns
1619 $this->assertArrayNotHasKey('sort_name', $result);
1620 }
1621
1622 /**
1623 * Test civicrm_contact_get() return only first name & last name.
1624 *
1625 * Use comma separated string return without a space
1626 */
1627 public function testContactGetReturnFirstLastNoComma() {
1628 $contact = $this->callAPISuccess('contact', 'create', $this->_params);
1629 $params = array(
1630 'contact_id' => $contact['id'],
1631 'return' => 'first_name,last_name',
1632 );
1633 $result = $this->callAPISuccess('contact', 'getsingle', $params);
1634 $this->assertEquals('abc1', $result['first_name']);
1635 $this->assertEquals('xyz1', $result['last_name']);
1636 //check that other defaults not returns
1637 $this->assertArrayNotHasKey('sort_name', $result);
1638 }
1639
1640 /**
1641 * Test civicrm_contact_get() with default return properties.
1642 */
1643 public function testContactGetRetDefault() {
1644 $contactID = $this->individualCreate();
1645 $params = array(
1646 'contact_id' => $contactID,
1647 'sort' => 'first_name',
1648 );
1649 $result = $this->callAPISuccess('contact', 'get', $params);
1650 $this->assertEquals($contactID, $result['values'][$contactID]['contact_id']);
1651 $this->assertEquals('Anthony', $result['values'][$contactID]['first_name']);
1652 }
1653
1654 /**
1655 * Test civicrm_contact_getquick() with empty name param.
1656 */
1657 public function testContactGetQuick() {
1658 // Insert a row in civicrm_contact creating individual contact.
1659 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1660 $op->execute($this->_dbconn,
1661 $this->createXMLDataSet(
1662 dirname(__FILE__) . '/dataset/contact_17.xml'
1663 )
1664 );
1665 $op->execute($this->_dbconn,
1666 $this->createXMLDataSet(
1667 dirname(__FILE__) . '/dataset/email_contact_17.xml'
1668 )
1669 );
1670 $params = array(
1671 'name' => "T",
1672 );
1673
1674 $result = $this->callAPISuccess('contact', 'getquick', $params);
1675 $this->assertEquals(17, $result['values'][0]['id']);
1676 }
1677
1678 /**
1679 * Test civicrm_contact_get) with empty params.
1680 */
1681 public function testContactGetEmptyParams() {
1682 $this->callAPISuccess('contact', 'get', array());
1683 }
1684
1685 /**
1686 * Test civicrm_contact_get(,true) with no matches.
1687 */
1688 public function testContactGetOldParamsNoMatches() {
1689 // Insert a row in civicrm_contact creating contact 17.
1690 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1691 $op->execute($this->_dbconn,
1692 $this->createXMLDataSet(
1693 dirname(__FILE__) . '/dataset/contact_17.xml'
1694 )
1695 );
1696
1697 $params = array(
1698 'first_name' => 'Fred',
1699 );
1700 $result = $this->callAPISuccess('contact', 'get', $params);
1701 $this->assertEquals(0, $result['count']);
1702 }
1703
1704 /**
1705 * Test civicrm_contact_get(,true) with one match.
1706 */
1707 public function testContactGetOldParamsOneMatch() {
1708 // Insert a row in civicrm_contact creating contact 17
1709 $op = new PHPUnit_Extensions_Database_Operation_Insert();
1710 $op->execute($this->_dbconn,
1711 $this->createXMLDataSet(dirname(__FILE__) . '/dataset/contact_17.xml'
1712 )
1713 );
1714
1715 $params = array(
1716 'first_name' => 'Test',
1717 );
1718 $result = $this->callAPISuccess('contact', 'get', $params);
1719 $this->assertEquals(17, $result['values'][17]['contact_id']);
1720 $this->assertEquals(17, $result['id']);
1721 }
1722
1723 /**
1724 * Test civicrm_contact_search_count().
1725 */
1726 public function testContactGetEmail() {
1727 $params = array(
1728 'email' => 'man2@yahoo.com',
1729 'contact_type' => 'Individual',
1730 'location_type_id' => 1,
1731 );
1732
1733 $contact = $this->callAPISuccess('contact', 'create', $params);
1734
1735 $params = array(
1736 'email' => 'man2@yahoo.com',
1737 );
1738 $result = $this->callAPIAndDocument('contact', 'get', $params, __FUNCTION__, __FILE__);
1739 $this->assertEquals('man2@yahoo.com', $result['values'][$result['id']]['email']);
1740
1741 $this->callAPISuccess('contact', 'delete', $contact);
1742 }
1743
1744 /**
1745 * Ensure consistent return format for option group fields.
1746 */
1747 public function testSetPreferredCommunicationNull() {
1748 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
1749 'preferred_communication_method' => array('Phone', 'SMS'),
1750 )));
1751 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1752 'id' => $contact['id'],
1753 'return' => 'preferred_communication_method',
1754 ));
1755 $this->assertNotEmpty($preferredCommunicationMethod);
1756 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array(
1757 'preferred_communication_method' => 'null',
1758 'id' => $contact['id'],
1759 )));
1760 $preferredCommunicationMethod = $this->callAPISuccessGetValue('Contact', array(
1761 'id' => $contact['id'],
1762 'return' => 'preferred_communication_method',
1763 ));
1764 $this->assertEmpty($preferredCommunicationMethod);
1765 }
1766
1767 /**
1768 * Ensure consistent return format for option group fields.
1769 */
1770 public function testPseudoFields() {
1771 $params = array(
1772 'preferred_communication_method' => array('Phone', 'SMS'),
1773 'preferred_language' => 'en_US',
1774 'gender_id' => 'Female',
1775 'prefix_id' => 'Mrs.',
1776 'suffix_id' => 'II',
1777 'communication_style_id' => 'Formal',
1778 );
1779
1780 $contact = $this->callAPISuccess('contact', 'create', array_merge($this->_params, $params));
1781
1782 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contact['id']));
1783 $this->assertEquals('Both', $result['preferred_mail_format']);
1784
1785 $this->assertEquals('en_US', $result['preferred_language']);
1786 $this->assertEquals(1, $result['communication_style_id']);
1787 $this->assertEquals(1, $result['gender_id']);
1788 $this->assertEquals('Female', $result['gender']);
1789 $this->assertEquals('Mrs.', $result['individual_prefix']);
1790 $this->assertEquals(1, $result['prefix_id']);
1791 $this->assertEquals('II', $result['individual_suffix']);
1792 $this->assertEquals(CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'suffix_id', 'II'), $result['suffix_id']);
1793 $this->callAPISuccess('contact', 'delete', $contact);
1794 $this->assertEquals(array(
1795 CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'Phone'),
1796 CRM_Core_PseudoConstant::getKey("CRM_Contact_BAO_Contact", 'preferred_communication_method', 'SMS'),
1797 ), $result['preferred_communication_method']);
1798 }
1799
1800
1801 /**
1802 * Test birth date parameters.
1803 *
1804 * These include value, array & birth_date_high, birth_date_low
1805 * && deceased.
1806 */
1807 public function testContactGetBirthDate() {
1808 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 2 years')));
1809 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month - 5 years')));
1810 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('birth_date' => 'first day of next month -20 years')));
1811
1812 $result = $this->callAPISuccess('contact', 'get', array());
1813 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['birth_date']);
1814 $result = $this->callAPISuccess('contact', 'get', array('birth_date' => 'first day of next month -5 years'));
1815 $this->assertEquals(1, $result['count']);
1816 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1817 $result = $this->callAPISuccess('contact', 'get', array('birth_date_high' => date('Y-m-d', strtotime('-6 years'))));
1818 $this->assertEquals(1, $result['count']);
1819 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['birth_date']);
1820 $result = $this->callAPISuccess('contact', 'get', array(
1821 'birth_date_low' => date('Y-m-d', strtotime('-6 years')),
1822 'birth_date_high' => date('Y-m-d', strtotime('- 3 years')),
1823 ));
1824 $this->assertEquals(1, $result['count']);
1825 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1826 $result = $this->callAPISuccess('contact', 'get', array(
1827 'birth_date_low' => '-6 years',
1828 'birth_date_high' => '- 3 years',
1829 ));
1830 $this->assertEquals(1, $result['count']);
1831 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['birth_date']);
1832 }
1833
1834 /**
1835 * Test Address parameters
1836 *
1837 * This include state_province, state_province_name, country
1838 */
1839 public function testContactGetWithAddressFields() {
1840 $individuals = array(
1841 array(
1842 'first_name' => 'abc1',
1843 'contact_type' => 'Individual',
1844 'last_name' => 'xyz1',
1845 'api.address.create' => array(
1846 'country' => 'United States',
1847 'state_province_id' => 'Michigan',
1848 'location_type_id' => 1,
1849 ),
1850 ),
1851 array(
1852 'first_name' => 'abc2',
1853 'contact_type' => 'Individual',
1854 'last_name' => 'xyz2',
1855 'api.address.create' => array(
1856 'country' => 'United States',
1857 'state_province_id' => 'Alabama',
1858 'location_type_id' => 1,
1859 ),
1860 ),
1861 );
1862 foreach ($individuals as $params) {
1863 $contact = $this->callAPISuccess('contact', 'create', $params);
1864 }
1865
1866 // Check whether Contact get API return successfully with below Address params.
1867 $fieldsToTest = array(
1868 'state_province_name' => 'Michigan',
1869 'state_province' => 'Michigan',
1870 'country' => 'United States',
1871 'state_province_name' => array('IN' => array('Michigan', 'Alabama')),
1872 'state_province' => array('IN' => array('Michigan', 'Alabama')),
1873 );
1874 foreach ($fieldsToTest as $field => $value) {
1875 $getParams = array(
1876 'id' => $contact['id'],
1877 $field => $value,
1878 );
1879 $result = $this->callAPISuccess('Contact', 'get', $getParams);
1880 $this->assertEquals(1, $result['count']);
1881 }
1882 }
1883
1884 /**
1885 * Test Deceased date parameters.
1886 *
1887 * These include value, array & Deceased_date_high, Deceased date_low
1888 * && deceased.
1889 */
1890 public function testContactGetDeceasedDate() {
1891 $contact1 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 2 years')));
1892 $contact2 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month - 5 years')));
1893 $contact3 = $this->callAPISuccess('contact', 'create', array_merge($this->_params, array('deceased_date' => 'first day of next month -20 years')));
1894
1895 $result = $this->callAPISuccess('contact', 'get', array());
1896 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -2 years')), $result['values'][$contact1['id']]['deceased_date']);
1897 $result = $this->callAPISuccess('contact', 'get', array('deceased_date' => 'first day of next month -5 years'));
1898 $this->assertEquals(1, $result['count']);
1899 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1900 $result = $this->callAPISuccess('contact', 'get', array('deceased_date_high' => date('Y-m-d', strtotime('-6 years'))));
1901 $this->assertEquals(1, $result['count']);
1902 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -20 years')), $result['values'][$contact3['id']]['deceased_date']);
1903 $result = $this->callAPISuccess('contact', 'get', array(
1904 'deceased_date_low' => '-6 years',
1905 'deceased_date_high' => date('Y-m-d', strtotime('- 3 years')),
1906 ));
1907 $this->assertEquals(1, $result['count']);
1908 $this->assertEquals(date('Y-m-d', strtotime('first day of next month -5 years')), $result['values'][$contact2['id']]['deceased_date']);
1909 }
1910
1911 /**
1912 * Test for Contact.get id=@user:username.
1913 */
1914 public function testContactGetByUsername() {
1915 // Setup - create contact with a uf-match.
1916 $cid = $this->individualCreate(array(
1917 'contact_type' => 'Individual',
1918 'first_name' => 'testGetByUsername',
1919 'last_name' => 'testGetByUsername',
1920 ));
1921
1922 $ufMatchParams = array(
1923 'domain_id' => CRM_Core_Config::domainID(),
1924 'uf_id' => 99,
1925 'uf_name' => 'the-email-matching-key-is-not-really-the-username',
1926 'contact_id' => $cid,
1927 );
1928 $ufMatch = CRM_Core_BAO_UFMatch::create($ufMatchParams);
1929 $this->assertTrue(is_numeric($ufMatch->id));
1930
1931 // setup - mock the calls to CRM_Utils_System_*::getUfId
1932 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
1933 $userSystem->expects($this->once())
1934 ->method('getUfId')
1935 ->with($this->equalTo('exampleUser'))
1936 ->will($this->returnValue(99));
1937 CRM_Core_Config::singleton()->userSystem = $userSystem;
1938
1939 // perform a lookup
1940 $result = $this->callAPISuccess('Contact', 'get', array(
1941 'id' => '@user:exampleUser',
1942 ));
1943 $this->assertEquals('testGetByUsername', $result['values'][$cid]['first_name']);
1944 }
1945
1946 /**
1947 * Test to check return works OK.
1948 */
1949 public function testContactGetReturnValues() {
1950 $extraParams = array(
1951 'nick_name' => 'Bob',
1952 'phone' => '456',
1953 'email' => 'e@mail.com',
1954 );
1955 $contactID = $this->individualCreate($extraParams);
1956 //actually it turns out the above doesn't create a phone
1957 $this->callAPISuccess('phone', 'create', array('contact_id' => $contactID, 'phone' => '456'));
1958 $result = $this->callAPISuccess('contact', 'getsingle', array('id' => $contactID));
1959 foreach ($extraParams as $key => $value) {
1960 $this->assertEquals($result[$key], $value);
1961 }
1962 //now we check they are still returned with 'return' key
1963 $result = $this->callAPISuccess('contact', 'getsingle', array(
1964 'id' => $contactID,
1965 'return' => array_keys($extraParams),
1966 ));
1967 foreach ($extraParams as $key => $value) {
1968 $this->assertEquals($result[$key], $value);
1969 }
1970 }
1971
1972 /**
1973 * Test creating multiple phones using chaining.
1974 *
1975 * @throws \Exception
1976 */
1977 public function testCRM13252MultipleChainedPhones() {
1978 $contactID = $this->householdCreate();
1979 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 0);
1980 $params = array(
1981 'contact_id' => $contactID,
1982 'household_name' => 'Household 1',
1983 'contact_type' => 'Household',
1984 'api.phone.create' => array(
1985 0 => array(
1986 'phone' => '111-111-1111',
1987 'location_type_id' => 1,
1988 'phone_type_id' => 1,
1989 ),
1990 1 => array(
1991 'phone' => '222-222-2222',
1992 'location_type_id' => 1,
1993 'phone_type_id' => 2,
1994 ),
1995 ),
1996 );
1997 $this->callAPISuccess('contact', 'create', $params);
1998 $this->callAPISuccessGetCount('phone', array('contact_id' => $contactID), 2);
1999
2000 }
2001
2002 /**
2003 * Test for Contact.get id=@user:username (with an invalid username).
2004 */
2005 public function testContactGetByUnknownUsername() {
2006 // setup - mock the calls to CRM_Utils_System_*::getUfId
2007 $userSystem = $this->getMock('CRM_Utils_System_UnitTests', array('getUfId'));
2008 $userSystem->expects($this->once())
2009 ->method('getUfId')
2010 ->with($this->equalTo('exampleUser'))
2011 ->will($this->returnValue(NULL));
2012 CRM_Core_Config::singleton()->userSystem = $userSystem;
2013
2014 // perform a lookup
2015 $result = $this->callAPIFailure('Contact', 'get', array(
2016 'id' => '@user:exampleUser',
2017 ));
2018 $this->assertRegExp('/cannot be resolved to a contact ID/', $result['error_message']);
2019 }
2020
2021 /**
2022 * Verify attempt to create individual with chained arrays and sequential.
2023 */
2024 public function testGetIndividualWithChainedArraysAndSequential() {
2025 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2026 $params['custom_' . $ids['custom_field_id']] = "custom string";
2027
2028 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2029 $params = array(
2030 'sequential' => 1,
2031 'first_name' => 'abc3',
2032 'last_name' => 'xyz3',
2033 'contact_type' => 'Individual',
2034 'email' => 'man3@yahoo.com',
2035 'api.website.create' => array(
2036 array(
2037 'url' => "http://civicrm.org",
2038 ),
2039 array(
2040 'url' => "https://civicrm.org",
2041 ),
2042 ),
2043 );
2044
2045 $result = $this->callAPISuccess('Contact', 'create', $params);
2046
2047 // delete the contact and custom groups
2048 $this->callAPISuccess('contact', 'delete', array('id' => $result['id']));
2049 $this->customGroupDelete($ids['custom_group_id']);
2050 $this->customGroupDelete($moreIDs['custom_group_id']);
2051
2052 $this->assertEquals($result['id'], $result['values'][0]['id']);
2053 $this->assertArrayKeyExists('api.website.create', $result['values'][0]);
2054 }
2055
2056 /**
2057 * Verify attempt to create individual with chained arrays.
2058 */
2059 public function testGetIndividualWithChainedArrays() {
2060 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2061 $params['custom_' . $ids['custom_field_id']] = "custom string";
2062
2063 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2064 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2065 $subfile = "APIChainedArray";
2066 $params = array(
2067 'first_name' => 'abc3',
2068 'last_name' => 'xyz3',
2069 'contact_type' => 'Individual',
2070 'email' => 'man3@yahoo.com',
2071 'api.contribution.create' => array(
2072 'receive_date' => '2010-01-01',
2073 'total_amount' => 100.00,
2074 'financial_type_id' => 1,
2075 'payment_instrument_id' => 1,
2076 'non_deductible_amount' => 10.00,
2077 'fee_amount' => 50.00,
2078 'net_amount' => 90.00,
2079 'trxn_id' => 12345,
2080 'invoice_id' => 67890,
2081 'source' => 'SSF',
2082 'contribution_status_id' => 1,
2083 ),
2084 'api.contribution.create.1' => array(
2085 'receive_date' => '2011-01-01',
2086 'total_amount' => 120.00,
2087 'financial_type_id' => $this->_financialTypeId = 1,
2088 'payment_instrument_id' => 1,
2089 'non_deductible_amount' => 10.00,
2090 'fee_amount' => 50.00,
2091 'net_amount' => 90.00,
2092 'trxn_id' => 12335,
2093 'invoice_id' => 67830,
2094 'source' => 'SSF',
2095 'contribution_status_id' => 1,
2096 ),
2097 'api.website.create' => array(
2098 array(
2099 'url' => "http://civicrm.org",
2100 ),
2101 ),
2102 );
2103
2104 $result = $this->callAPISuccess('Contact', 'create', $params);
2105 $params = array(
2106 'id' => $result['id'],
2107 'api.website.get' => array(),
2108 'api.Contribution.get' => array(
2109 'total_amount' => '120.00',
2110 ),
2111 'api.CustomValue.get' => 1,
2112 'api.Note.get' => 1,
2113 );
2114 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2115 // delete the contact
2116 $this->callAPISuccess('contact', 'delete', $result);
2117 $this->customGroupDelete($ids['custom_group_id']);
2118 $this->customGroupDelete($moreIDs['custom_group_id']);
2119 $this->assertEquals(0, $result['values'][$result['id']]['api.website.get']['is_error']);
2120 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.get']['values'][0]['url']);
2121 }
2122
2123 /**
2124 * Verify attempt to create individual with chained arrays and sequential.
2125 *
2126 * See https://issues.civicrm.org/jira/browse/CRM-15815
2127 */
2128 public function testCreateIndividualWithChainedArrayAndSequential() {
2129 $params = array(
2130 'sequential' => 1,
2131 'first_name' => 'abc5',
2132 'last_name' => 'xyz5',
2133 'contact_type' => 'Individual',
2134 'email' => 'woman5@yahoo.com',
2135 'api.phone.create' => array(
2136 array('phone' => '03-231 07 95'),
2137 array('phone' => '03-232 51 62'),
2138 ),
2139 'api.website.create' => array(
2140 'url' => 'http://civicrm.org',
2141 ),
2142 );
2143 $result = $this->callAPISuccess('Contact', 'create', $params);
2144
2145 // I could try to parse the result to see whether the two phone numbers
2146 // and the website are there, but I am not sure about the correct format.
2147 // So I will just fetch it again before checking.
2148 // See also http://forum.civicrm.org/index.php/topic,35393.0.html
2149 $params = array(
2150 'sequential' => 1,
2151 'id' => $result['id'],
2152 'api.website.get' => array(),
2153 'api.phone.get' => array(),
2154 );
2155 $result = $this->callAPISuccess('Contact', 'get', $params);
2156
2157 // delete the contact
2158 $this->callAPISuccess('contact', 'delete', $result);
2159
2160 $this->assertEquals(2, $result['values'][0]['api.phone.get']['count']);
2161 $this->assertEquals(1, $result['values'][0]['api.website.get']['count']);
2162 }
2163
2164 /**
2165 * Test retrieving an individual with chained array syntax.
2166 */
2167 public function testGetIndividualWithChainedArraysFormats() {
2168 $description = "This demonstrates the usage of chained api functions.\nIn this case no notes or custom fields have been created.";
2169 $subfile = "APIChainedArrayFormats";
2170 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2171 $params['custom_' . $ids['custom_field_id']] = "custom string";
2172
2173 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2174 $params = array(
2175 'first_name' => 'abc3',
2176 'last_name' => 'xyz3',
2177 'contact_type' => 'Individual',
2178 'email' => 'man3@yahoo.com',
2179 'api.contribution.create' => array(
2180 'receive_date' => '2010-01-01',
2181 'total_amount' => 100.00,
2182 'financial_type_id' => $this->_financialTypeId,
2183 'payment_instrument_id' => 1,
2184 'non_deductible_amount' => 10.00,
2185 'fee_amount' => 50.00,
2186 'net_amount' => 90.00,
2187 'source' => 'SSF',
2188 'contribution_status_id' => 1,
2189 ),
2190 'api.contribution.create.1' => array(
2191 'receive_date' => '2011-01-01',
2192 'total_amount' => 120.00,
2193 'financial_type_id' => $this->_financialTypeId,
2194 'payment_instrument_id' => 1,
2195 'non_deductible_amount' => 10.00,
2196 'fee_amount' => 50.00,
2197 'net_amount' => 90.00,
2198 'source' => 'SSF',
2199 'contribution_status_id' => 1,
2200 ),
2201 'api.website.create' => array(
2202 array(
2203 'url' => "http://civicrm.org",
2204 ),
2205 ),
2206 );
2207
2208 $result = $this->callAPISuccess('Contact', 'create', $params);
2209 $params = array(
2210 'id' => $result['id'],
2211 'api.website.getValue' => array('return' => 'url'),
2212 'api.Contribution.getCount' => array(),
2213 'api.CustomValue.get' => 1,
2214 'api.Note.get' => 1,
2215 'api.Membership.getCount' => array(),
2216 );
2217 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2218 $this->assertEquals(2, $result['values'][$result['id']]['api.Contribution.getCount']);
2219 $this->assertEquals(0, $result['values'][$result['id']]['api.Note.get']['is_error']);
2220 $this->assertEquals("http://civicrm.org", $result['values'][$result['id']]['api.website.getValue']);
2221
2222 $this->callAPISuccess('contact', 'delete', $result);
2223 $this->customGroupDelete($ids['custom_group_id']);
2224 $this->customGroupDelete($moreIDs['custom_group_id']);
2225 }
2226
2227 /**
2228 * Test complex chaining.
2229 */
2230 public function testGetIndividualWithChainedArraysAndMultipleCustom() {
2231 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
2232 $params['custom_' . $ids['custom_field_id']] = "custom string";
2233 $moreIDs = $this->CustomGroupMultipleCreateWithFields();
2234 $andMoreIDs = $this->CustomGroupMultipleCreateWithFields(array(
2235 'title' => "another group",
2236 'name' => 'another name',
2237 ));
2238 $description = "This demonstrates the usage of chained api functions with multiple custom fields.";
2239 $subfile = "APIChainedArrayMultipleCustom";
2240 $params = array(
2241 'first_name' => 'abc3',
2242 'last_name' => 'xyz3',
2243 'contact_type' => 'Individual',
2244 'email' => 'man3@yahoo.com',
2245 'api.contribution.create' => array(
2246 'receive_date' => '2010-01-01',
2247 'total_amount' => 100.00,
2248 'financial_type_id' => 1,
2249 'payment_instrument_id' => 1,
2250 'non_deductible_amount' => 10.00,
2251 'fee_amount' => 50.00,
2252 'net_amount' => 90.00,
2253 'trxn_id' => 12345,
2254 'invoice_id' => 67890,
2255 'source' => 'SSF',
2256 'contribution_status_id' => 1,
2257 ),
2258 'api.contribution.create.1' => array(
2259 'receive_date' => '2011-01-01',
2260 'total_amount' => 120.00,
2261 'financial_type_id' => 1,
2262 'payment_instrument_id' => 1,
2263 'non_deductible_amount' => 10.00,
2264 'fee_amount' => 50.00,
2265 'net_amount' => 90.00,
2266 'trxn_id' => 12335,
2267 'invoice_id' => 67830,
2268 'source' => 'SSF',
2269 'contribution_status_id' => 1,
2270 ),
2271 'api.website.create' => array(
2272 array(
2273 'url' => "http://civicrm.org",
2274 ),
2275 ),
2276 'custom_' . $ids['custom_field_id'] => "value 1",
2277 'custom_' . $moreIDs['custom_field_id'][0] => "value 2",
2278 'custom_' . $moreIDs['custom_field_id'][1] => "warm beer",
2279 'custom_' . $andMoreIDs['custom_field_id'][1] => "vegemite",
2280 );
2281
2282 $result = $this->callAPISuccess('Contact', 'create', $params);
2283 $result = $this->callAPISuccess('Contact', 'create', array(
2284 'contact_type' => 'Individual',
2285 'id' => $result['id'],
2286 'custom_' .
2287 $moreIDs['custom_field_id'][0] => "value 3",
2288 'custom_' .
2289 $ids['custom_field_id'] => "value 4",
2290 ));
2291
2292 $params = array(
2293 'id' => $result['id'],
2294 'api.website.getValue' => array('return' => 'url'),
2295 'api.Contribution.getCount' => array(),
2296 'api.CustomValue.get' => 1,
2297 );
2298 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2299
2300 $this->customGroupDelete($ids['custom_group_id']);
2301 $this->customGroupDelete($moreIDs['custom_group_id']);
2302 $this->customGroupDelete($andMoreIDs['custom_group_id']);
2303 $this->assertEquals(0, $result['values'][$result['id']]['api.CustomValue.get']['is_error']);
2304 $this->assertEquals('http://civicrm.org', $result['values'][$result['id']]['api.website.getValue']);
2305 }
2306
2307 /**
2308 * Test checks usage of $values to pick & choose inputs.
2309 */
2310 public function testChainingValuesCreate() {
2311 $description = "This demonstrates the usage of chained api functions. Specifically it has one 'parent function' &
2312 2 child functions - one receives values from the parent (Contact) and the other child (Tag).";
2313 $subfile = "APIChainedArrayValuesFromSiblingFunction";
2314 $params = array(
2315 'display_name' => 'batman',
2316 'contact_type' => 'Individual',
2317 'api.tag.create' => array(
2318 'name' => '$value.id',
2319 'description' => '$value.display_name',
2320 'format.only_id' => 1,
2321 ),
2322 'api.entity_tag.create' => array('tag_id' => '$value.api.tag.create'),
2323 );
2324 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
2325 $this->assertEquals(0, $result['values'][$result['id']]['api.entity_tag.create']['is_error']);
2326
2327 $tablesToTruncate = array(
2328 'civicrm_contact',
2329 'civicrm_activity',
2330 'civicrm_entity_tag',
2331 'civicrm_tag',
2332 );
2333 $this->quickCleanup($tablesToTruncate, TRUE);
2334 }
2335
2336 /**
2337 * Test TrueFalse format - I couldn't come up with an easy way to get an error on Get.
2338 */
2339 public function testContactGetFormatIsSuccessTrue() {
2340 $this->createContactFromXML();
2341 $description = "This demonstrates use of the 'format.is_success' param.
2342 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2343 $subfile = "FormatIsSuccess_True";
2344 $params = array('id' => 17, 'format.is_success' => 1);
2345 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2346 $this->assertEquals(1, $result);
2347 $this->callAPISuccess('Contact', 'Delete', $params);
2348 }
2349
2350 /**
2351 * Test TrueFalse format.
2352 */
2353 public function testContactCreateFormatIsSuccessFalse() {
2354
2355 $description = "This demonstrates use of the 'format.is_success' param.
2356 This param causes only the success or otherwise of the function to be returned as BOOLEAN";
2357 $subfile = "FormatIsSuccess_Fail";
2358 $params = array('id' => 500, 'format.is_success' => 1);
2359 $result = $this->callAPIAndDocument('Contact', 'Create', $params, __FUNCTION__, __FILE__, $description, $subfile);
2360 $this->assertEquals(0, $result);
2361 }
2362
2363 /**
2364 * Test long display names.
2365 *
2366 * CRM-21258
2367 */
2368 public function testContactCreateLongDisplayName() {
2369 $result = $this->callAPISuccess('Contact', 'Create', array(
2370 'first_name' => str_pad('a', 64, 'a'),
2371 'last_name' => str_pad('a', 64, 'a'),
2372 'contact_type' => 'Individual',
2373 ));
2374 $this->assertEquals('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $result['values'][$result['id']]['display_name']);
2375 $this->assertEquals('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $result['values'][$result['id']]['sort_name']);
2376 }
2377
2378 /**
2379 * Test Single Entity format.
2380 */
2381 public function testContactGetSingleEntityArray() {
2382 $this->createContactFromXML();
2383 $description = "This demonstrates use of the 'format.single_entity_array' param.
2384 This param causes the only contact to be returned as an array without the other levels.
2385 It will be ignored if there is not exactly 1 result";
2386 $subfile = "GetSingleContact";
2387 $params = array('id' => 17);
2388 $result = $this->callAPIAndDocument('Contact', 'GetSingle', $params, __FUNCTION__, __FILE__, $description, $subfile);
2389 $this->assertEquals('Test Contact', $result['display_name']);
2390 $this->callAPISuccess('Contact', 'Delete', $params);
2391 }
2392
2393 /**
2394 * Test Single Entity format.
2395 */
2396 public function testContactGetFormatCountOnly() {
2397 $this->createContactFromXML();
2398 $description = "This demonstrates use of the 'getCount' action.
2399 This param causes the count of the only function to be returned as an integer.";
2400 $params = array('id' => 17);
2401 $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__, __FILE__, $description,
2402 'GetCountContact');
2403 $this->assertEquals('1', $result);
2404 $this->callAPISuccess('Contact', 'Delete', $params);
2405 }
2406
2407 /**
2408 * Test id only format.
2409 */
2410 public function testContactGetFormatIDOnly() {
2411 $this->createContactFromXML();
2412 $description = "This demonstrates use of the 'format.id_only' param.
2413 This param causes the id of the only entity to be returned as an integer.
2414 It will be ignored if there is not exactly 1 result";
2415 $subfile = "FormatOnlyID";
2416 $params = array('id' => 17, 'format.only_id' => 1);
2417 $result = $this->callAPIAndDocument('Contact', 'Get', $params, __FUNCTION__, __FILE__, $description, $subfile);
2418 $this->assertEquals('17', $result);
2419 $this->callAPISuccess('Contact', 'Delete', $params);
2420 }
2421
2422 /**
2423 * Test id only format.
2424 */
2425 public function testContactGetFormatSingleValue() {
2426 $this->createContactFromXML();
2427 $description = "This demonstrates use of the 'format.single_value' param.
2428 This param causes only a single value of the only entity to be returned as an string.
2429 It will be ignored if there is not exactly 1 result";
2430 $subFile = "FormatSingleValue";
2431 $params = array('id' => 17, 'return' => 'display_name');
2432 $result = $this->callAPIAndDocument('Contact', 'getvalue', $params, __FUNCTION__, __FILE__, $description, $subFile);
2433 $this->assertEquals('Test Contact', $result);
2434 $this->callAPISuccess('Contact', 'Delete', $params);
2435 }
2436
2437 /**
2438 * Test that permissions are respected when creating contacts.
2439 */
2440 public function testContactCreationPermissions() {
2441 $params = array(
2442 'contact_type' => 'Individual',
2443 'first_name' => 'Foo',
2444 'last_name' => 'Bear',
2445 'check_permissions' => TRUE,
2446 );
2447 $config = CRM_Core_Config::singleton();
2448 $config->userPermissionClass->permissions = array('access CiviCRM');
2449 $result = $this->callAPIFailure('contact', 'create', $params);
2450 $this->assertEquals('API permission check failed for Contact/create call; insufficient permission: require access CiviCRM and add contacts', $result['error_message'], 'lacking permissions should not be enough to create a contact');
2451
2452 $config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'import contacts');
2453 $this->callAPISuccess('contact', 'create', $params);
2454 }
2455
2456 /**
2457 * Test that delete with skip undelete respects permissions.
2458 */
2459 public function testContactDeletePermissions() {
2460 $contactID = $this->individualCreate();
2461 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
2462 $this->callAPIFailure('Contact', 'delete', array(
2463 'id' => $contactID,
2464 'check_permissions' => 1,
2465 'skip_undelete' => 1,
2466 ));
2467 $this->callAPISuccess('Contact', 'delete', array(
2468 'id' => $contactID,
2469 'check_permissions' => 0,
2470 'skip_undelete' => 1,
2471 ));
2472 }
2473
2474 /**
2475 * Test update with check permissions set.
2476 */
2477 public function testContactUpdatePermissions() {
2478 $params = array(
2479 'contact_type' => 'Individual',
2480 'first_name' => 'Foo',
2481 'last_name' => 'Bear',
2482 'check_permissions' => TRUE,
2483 );
2484 $result = $this->callAPISuccess('contact', 'create', $params);
2485 $config = CRM_Core_Config::singleton();
2486 $params = array(
2487 'id' => $result['id'],
2488 'contact_type' => 'Individual',
2489 'last_name' => 'Bar',
2490 'check_permissions' => TRUE,
2491 );
2492
2493 $config->userPermissionClass->permissions = array('access CiviCRM');
2494 $result = $this->callAPIFailure('contact', 'update', $params);
2495 $this->assertEquals('Permission denied to modify contact record', $result['error_message']);
2496
2497 $config->userPermissionClass->permissions = array(
2498 'access CiviCRM',
2499 'add contacts',
2500 'view all contacts',
2501 'edit all contacts',
2502 'import contacts',
2503 );
2504 $this->callAPISuccess('contact', 'update', $params);
2505 }
2506
2507 /**
2508 * Set up helper to create a contact.
2509 */
2510 public function createContactFromXML() {
2511 // Insert a row in civicrm_contact creating contact 17.
2512 $op = new PHPUnit_Extensions_Database_Operation_Insert();
2513 $op->execute($this->_dbconn,
2514 $this->createXMLDataSet(
2515 dirname(__FILE__) . '/dataset/contact_17.xml'
2516 )
2517 );
2518 }
2519
2520 /**
2521 * Test contact proximity api.
2522 */
2523 public function testContactProximity() {
2524 // first create a contact with a SF location with a specific
2525 // geocode
2526 $contactID = $this->organizationCreate();
2527
2528 // now create the address
2529 $params = array(
2530 'street_address' => '123 Main Street',
2531 'city' => 'San Francisco',
2532 'is_primary' => 1,
2533 'country_id' => 1228,
2534 'state_province_id' => 1004,
2535 'geo_code_1' => '37.79',
2536 'geo_code_2' => '-122.40',
2537 'location_type_id' => 1,
2538 'contact_id' => $contactID,
2539 );
2540
2541 $result = $this->callAPISuccess('address', 'create', $params);
2542 $this->assertEquals(1, $result['count']);
2543
2544 // now do a proximity search with a close enough geocode and hope to match
2545 // that specific contact only!
2546 $proxParams = array(
2547 'latitude' => 37.7,
2548 'longitude' => -122.3,
2549 'unit' => 'mile',
2550 'distance' => 10,
2551 );
2552 $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
2553 $this->assertEquals(1, $result['count']);
2554 }
2555
2556 /**
2557 * Test that Ajax API permission is sufficient to access getquick api.
2558 *
2559 * (note that getquick api is required for autocomplete & has ACL permissions applied)
2560 */
2561 public function testGetquickPermissionCRM13744() {
2562 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviEvent');
2563 $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2564 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
2565 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2566 CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access AJAX API');
2567 $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
2568 }
2569
2570 /**
2571 * Test that getquick returns contacts with an exact first name match first.
2572 *
2573 * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
2574 * is true (default) but if it is false then matches are returned in ID order.
2575 *
2576 * @dataProvider getSearchSortOptions
2577 */
2578 public function testGetQuickExactFirst($searchParameters, $settings, $firstContact, $secondContact = NULL) {
2579 $this->getQuickSearchSampleData();
2580 $this->callAPISuccess('Setting', 'create', $settings);
2581 $result = $this->callAPISuccess('contact', 'getquick', $searchParameters);
2582 $this->assertEquals($firstContact, $result['values'][0]['sort_name']);
2583 $this->assertEquals($secondContact, $result['values'][1]['sort_name']);
2584 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE));
2585 }
2586
2587 public function getSearchSortOptions() {
2588 $firstAlphabeticalContactBySortName = 'A Bobby, Bobby';
2589 $secondAlphabeticalContactBySortName = 'Aadvark, Bob';
2590 $secondAlphabeticalContactWithEmailBySortName = 'Bob, Bob';
2591 $firstAlphabeticalContactFirstNameBob = 'Aadvark, Bob';
2592 $secondAlphabeticalContactFirstNameBob = 'Bob, Bob';
2593 $firstByIDContactFirstNameBob = 'Bob, Bob';
2594 $secondByIDContactFirstNameBob = 'K Bobby, Bob';
2595 $firstContactByID = 'Bob, Bob';
2596 $secondContactByID = 'E Bobby, Bobby';
2597 $bobLikeEmail = 'A Bobby, Bobby';
2598
2599 return array(
2600 'empty_search_basic' => array(
2601 'search_parameters' => array('name' => '%'),
2602 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2603 'first_contact' => $firstAlphabeticalContactBySortName,
2604 'second_contact' => $secondAlphabeticalContactBySortName,
2605 ),
2606 'empty_search_basic_no_wildcard' => array(
2607 'search_parameters' => array('name' => '%'),
2608 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2609 'first_contact' => $firstAlphabeticalContactBySortName,
2610 'second_contact' => $secondAlphabeticalContactBySortName,
2611 ),
2612 'single_letter_search_basic' => array(
2613 'search_parameters' => array('name' => 'b'),
2614 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2615 'first_contact' => $firstAlphabeticalContactBySortName,
2616 'second_contact' => $secondAlphabeticalContactBySortName,
2617 ),
2618 'bob_search_basic' => array(
2619 'search_parameters' => array('name' => 'bob'),
2620 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2621 'first_contact' => $firstAlphabeticalContactBySortName,
2622 'second_contact' => $secondAlphabeticalContactBySortName,
2623 ),
2624 'bob_search_no_orderby' => array(
2625 'search_parameters' => array('name' => 'bob'),
2626 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2627 'first_contact' => $firstContactByID,
2628 'second_contact' => $secondContactByID,
2629 ),
2630 'bob_search_no_wildcard' => array(
2631 'search_parameters' => array('name' => 'bob'),
2632 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2633 'second_contact' => $bobLikeEmail,
2634 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2635 ),
2636 // This should be the same as just no wildcard as if we had an exactMatch while searching by
2637 // sort name it would rise to the top CRM-19547
2638 'bob_search_no_wildcard_no_orderby' => array(
2639 'search_parameters' => array('name' => 'bob'),
2640 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2641 'second_contact' => $bobLikeEmail,
2642 'first_contact' => $secondAlphabeticalContactFirstNameBob,
2643 ),
2644 'first_name_search_basic' => array(
2645 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2646 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => TRUE),
2647 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2648 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2649 ),
2650 'first_name_search_no_wildcard' => array(
2651 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2652 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2653 'first_contact' => $firstAlphabeticalContactFirstNameBob,
2654 'second_contact' => $secondAlphabeticalContactFirstNameBob,
2655 ),
2656 'first_name_search_no_orderby' => array(
2657 'search_parameters' => array('name' => 'bob', 'field_name' => 'first_name'),
2658 'settings' => array('includeWildCardInName' => TRUE, 'includeOrderByClause' => FALSE),
2659 'first_contact' => $firstByIDContactFirstNameBob,
2660 'second_contact' => $secondByIDContactFirstNameBob,
2661 ),
2662 'email_search_basic' => array(
2663 'search_parameters' => array('name' => 'bob', 'field_name' => 'email', 'table_name' => 'eml'),
2664 'settings' => array('includeWildCardInName' => FALSE, 'includeOrderByClause' => TRUE),
2665 'first_contact' => $firstAlphabeticalContactBySortName,
2666 'second_contact' => $secondAlphabeticalContactWithEmailBySortName,
2667 ),
2668 );
2669 }
2670
2671 /**
2672 * Test that getquick returns contacts with an exact first name match first.
2673 */
2674 public function testGetQuickEmail() {
2675 $this->getQuickSearchSampleData();
2676 $loggedInContactID = $this->createLoggedInUser();
2677 $result = $this->callAPISuccess('contact', 'getquick', array(
2678 'name' => 'c',
2679 ));
2680 $expectedData = array(
2681 'A Bobby, Bobby :: bob@bobby.com',
2682 'Bob, Bob :: bob@bob.com',
2683 'C Bobby, Bobby',
2684 'H Bobby, Bobby :: bob@h.com',
2685 'Second Domain',
2686 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2687 );
2688 $this->assertEquals(6, $result['count']);
2689 foreach ($expectedData as $index => $value) {
2690 $this->assertEquals($value, $result['values'][$index]['data']);
2691 }
2692 $result = $this->callAPISuccess('contact', 'getquick', array(
2693 'name' => 'h.',
2694 ));
2695 $expectedData = array(
2696 'H Bobby, Bobby :: bob@h.com',
2697 );
2698 foreach ($expectedData as $index => $value) {
2699 $this->assertEquals($value, $result['values'][$index]['data']);
2700 }
2701 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
2702 $result = $this->callAPISuccess('contact', 'getquick', array(
2703 'name' => 'h.',
2704 ));
2705 $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
2706 $this->assertEquals(0, $result['count']);
2707 }
2708
2709 /**
2710 * Test that getquick returns contacts with an exact first name match first.
2711 */
2712 public function testGetQuickEmailACL() {
2713 $this->getQuickSearchSampleData();
2714 $loggedInContactID = $this->createLoggedInUser();
2715 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2716 $result = $this->callAPISuccess('contact', 'getquick', array(
2717 'name' => 'c',
2718 ));
2719 $this->assertEquals(0, $result['count']);
2720
2721 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2722 CRM_Contact_BAO_Contact_Permission::cache($loggedInContactID, CRM_Core_Permission::VIEW, TRUE);
2723 $result = $this->callAPISuccess('contact', 'getquick', array(
2724 'name' => 'c',
2725 ));
2726
2727 // Without the acl it would be 6 like the previous email getquick test.
2728 $this->assertEquals(5, $result['count']);
2729 $expectedData = array(
2730 'A Bobby, Bobby :: bob@bobby.com',
2731 'Bob, Bob :: bob@bob.com',
2732 'C Bobby, Bobby',
2733 'Second Domain',
2734 $this->callAPISuccessGetValue('Contact', array('id' => $loggedInContactID, 'return' => 'last_name')) . ', Logged In :: anthony_anderson@civicrm.org',
2735 );
2736 foreach ($expectedData as $index => $value) {
2737 $this->assertEquals($value, $result['values'][$index]['data']);
2738 }
2739 }
2740
2741 /**
2742 * Test that getquick returns contacts with an exact first name match first.
2743 */
2744 public function testGetQuickExternalID() {
2745 $this->getQuickSearchSampleData();
2746 $result = $this->callAPISuccess('contact', 'getquick', array(
2747 'name' => 'b',
2748 'field_name' => 'external_identifier',
2749 'table_name' => 'cc',
2750 ));
2751 $this->assertEquals(0, $result['count']);
2752 $result = $this->callAPISuccess('contact', 'getquick', array(
2753 'name' => 'abc',
2754 'field_name' => 'external_identifier',
2755 'table_name' => 'cc',
2756 ));
2757 $this->assertEquals(1, $result['count']);
2758 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2759 }
2760
2761 /**
2762 * Test that getquick returns contacts with an exact first name match first.
2763 */
2764 public function testGetQuickID() {
2765 $max = CRM_Core_DAO::singleValueQuery("SELECT max(id) FROM civicrm_contact");
2766 $this->getQuickSearchSampleData();
2767 $result = $this->callAPISuccess('contact', 'getquick', array(
2768 'name' => $max + 2,
2769 'field_name' => 'id',
2770 'table_name' => 'cc',
2771 ));
2772 $this->assertEquals(1, $result['count']);
2773 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2774 $result = $this->callAPISuccess('contact', 'getquick', array(
2775 'name' => $max + 2,
2776 'field_name' => 'contact_id',
2777 'table_name' => 'cc',
2778 ));
2779 $this->assertEquals(1, $result['count']);
2780 $this->assertEquals('E Bobby, Bobby', $result['values'][0]['sort_name']);
2781 }
2782
2783 /**
2784 * Test that getquick returns contacts with an exact first name match first.
2785 *
2786 * Depending on the setting the sort name sort might click in next or not - test!
2787 */
2788 public function testGetQuickFirstName() {
2789 $this->getQuickSearchSampleData();
2790 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2791 $result = $this->callAPISuccess('contact', 'getquick', array(
2792 'name' => 'Bob',
2793 'field_name' => 'first_name',
2794 'table_name' => 'cc',
2795 ));
2796 $expected = array(
2797 'Aadvark, Bob',
2798 'Bob, Bob',
2799 'K Bobby, Bob',
2800 'A Bobby, Bobby',
2801 );
2802
2803 foreach ($expected as $index => $value) {
2804 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2805 }
2806 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2807 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2808 $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
2809 $this->assertEquals('E Bobby, Bobby', $result['values'][1]['sort_name']);
2810 }
2811
2812 /**
2813 * Test that getquick applies ACLs.
2814 */
2815 public function testGetQuickFirstNameACLs() {
2816 $this->getQuickSearchSampleData();
2817 $userID = $this->createLoggedInUser();
2818 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE, 'search_autocomplete_count' => 15));
2819 CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
2820 $result = $this->callAPISuccess('contact', 'getquick', array(
2821 'name' => 'Bob',
2822 'field_name' => 'first_name',
2823 'table_name' => 'cc',
2824 ));
2825 $this->assertEquals(0, $result['count']);
2826
2827 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
2828 CRM_Contact_BAO_Contact_Permission::cache($userID, CRM_Core_Permission::VIEW, TRUE);
2829 $result = $this->callAPISuccess('contact', 'getquick', array(
2830 'name' => 'Bob',
2831 'field_name' => 'first_name',
2832 'table_name' => 'cc',
2833 ));
2834 $this->assertEquals('K Bobby, Bob', $result['values'][2]['sort_name']);
2835 // Without the ACL 9 would be bob@h.com.
2836 $this->assertEquals('I Bobby, Bobby', $result['values'][10]['sort_name']);
2837 }
2838
2839 /**
2840 * Full results returned.
2841 * @implements CRM_Utils_Hook::aclWhereClause
2842 *
2843 * @param string $type
2844 * @param array $tables
2845 * @param array $whereTables
2846 * @param int $contactID
2847 * @param string $where
2848 */
2849 public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
2850 $where = " (email <> 'bob@h.com' OR email IS NULL) ";
2851 $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
2852 }
2853
2854 /**
2855 * Test that getquick returns contacts with an exact last name match first.
2856 */
2857 public function testGetQuickLastName() {
2858 $this->getQuickSearchSampleData();
2859 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
2860 $result = $this->callAPISuccess('contact', 'getquick', array(
2861 'name' => 'Bob',
2862 'field_name' => 'last_name',
2863 'table_name' => 'cc',
2864 ));
2865 $expected = array(
2866 'Bob, Bob',
2867 'A Bobby, Bobby',
2868 'B Bobby, Bobby',
2869 );
2870
2871 foreach ($expected as $index => $value) {
2872 $this->assertEquals($value, $result['values'][$index]['sort_name']);
2873 }
2874 $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
2875 $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
2876 $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
2877 }
2878
2879 /**
2880 * Test that getquick returns contacts by city.
2881 */
2882 public function testGetQuickCity() {
2883 $this->getQuickSearchSampleData();
2884 $result = $this->callAPISuccess('contact', 'getquick', array(
2885 'name' => 'o',
2886 'field_name' => 'city',
2887 'table_name' => 'sts',
2888 ));
2889 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2890 $result = $this->callAPISuccess('contact', 'getquick', array(
2891 'name' => 'n',
2892 'field_name' => 'city',
2893 'table_name' => 'sts',
2894 ));
2895 $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
2896 $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
2897 }
2898
2899 /**
2900 * Set up some sample data for testing quicksearch.
2901 */
2902 public function getQuickSearchSampleData() {
2903 $contacts = array(
2904 array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
2905 array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'abcd'),
2906 array(
2907 'first_name' => 'Bobby',
2908 'last_name' => 'B Bobby',
2909 'external_identifier' => 'bcd',
2910 'api.address.create' => array(
2911 'street_address' => 'Sesame Street',
2912 'city' => 'Toronto',
2913 'location_type_id' => 1,
2914 ),
2915 ),
2916 array(
2917 'first_name' => 'Bobby',
2918 'last_name' => 'C Bobby',
2919 'external_identifier' => 'bcde',
2920 'api.address.create' => array(
2921 'street_address' => 'Te huarahi',
2922 'city' => 'Whanganui',
2923 'location_type_id' => 1,
2924 ),
2925 ),
2926 array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
2927 array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
2928 array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
2929 array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
2930 array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
2931 array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
2932 array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
2933 array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
2934 array('first_name' => 'Bob', 'last_name' => 'Aadvark'),
2935 );
2936 foreach ($contacts as $type => $contact) {
2937 $contact['contact_type'] = 'Individual';
2938 $this->callAPISuccess('Contact', 'create', $contact);
2939 }
2940 }
2941
2942 /**
2943 * Test get ref api - gets a list of references to an entity.
2944 */
2945 public function testGetReferenceCounts() {
2946 $result = $this->callAPISuccess('Contact', 'create', array(
2947 'first_name' => 'Testily',
2948 'last_name' => 'McHaste',
2949 'contact_type' => 'Individual',
2950 'api.Address.replace' => array(
2951 'values' => array(),
2952 ),
2953 'api.Email.replace' => array(
2954 'values' => array(
2955 array(
2956 'email' => 'spam@dev.null',
2957 'is_primary' => 0,
2958 'location_type_id' => 1,
2959 ),
2960 ),
2961 ),
2962 'api.Phone.replace' => array(
2963 'values' => array(
2964 array(
2965 'phone' => '234-567-0001',
2966 'is_primary' => 1,
2967 'location_type_id' => 1,
2968 ),
2969 array(
2970 'phone' => '234-567-0002',
2971 'is_primary' => 0,
2972 'location_type_id' => 1,
2973 ),
2974 ),
2975 ),
2976 ));
2977
2978 //$dao = new CRM_Contact_BAO_Contact();
2979 //$dao->id = $result['id'];
2980 //$this->assertTrue((bool) $dao->find(TRUE));
2981 //
2982 //$refCounts = $dao->getReferenceCounts();
2983 //$this->assertTrue(is_array($refCounts));
2984 //$refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts);
2985
2986 $refCounts = $this->callAPISuccess('Contact', 'getrefcount', array(
2987 'id' => $result['id'],
2988 ));
2989 $refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts['values']);
2990
2991 $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']);
2992 $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']);
2993 $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']);
2994 $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']);
2995 $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id']));
2996 }
2997
2998 /**
2999 * Test the use of sql operators.
3000 */
3001 public function testSQLOperatorsOnContactAPI() {
3002 $this->individualCreate();
3003 $this->organizationCreate();
3004 $this->householdCreate();
3005 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NOT NULL' => TRUE)));
3006 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NOT NULL'));
3007 $contacts = $this->callAPISuccess('contact', 'get', array('legal_name' => array('IS NULL' => TRUE)));
3008 $this->assertEquals($contacts['count'], CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact WHERE legal_name IS NULL'));
3009 }
3010
3011 /**
3012 * CRM-14743 - test api respects search operators.
3013 */
3014 public function testGetModifiedDateByOperators() {
3015 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
3016 $contact1 = $this->individualCreate();
3017 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01', modified_date = '2013-01-01' WHERE id = " . $contact1;
3018 CRM_Core_DAO::executeQuery($sql);
3019 $contact2 = $this->individualCreate();
3020 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01', modified_date = '2013-02-01' WHERE id = " . $contact2;
3021 CRM_Core_DAO::executeQuery($sql);
3022 $contact3 = $this->householdCreate();
3023 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01', modified_date = '2013-03-01' WHERE id = " . $contact3;
3024 CRM_Core_DAO::executeQuery($sql);
3025 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('<' => '2014-01-01')));
3026 $this->assertEquals($contacts['count'], 3);
3027 $contacts = $this->callAPISuccess('contact', 'get', array('modified_date' => array('>' => '2014-01-01')));
3028 $this->assertEquals($contacts['count'], $preExistingContactCount);
3029 }
3030
3031 /**
3032 * CRM-14743 - test api respects search operators.
3033 */
3034 public function testGetCreatedDateByOperators() {
3035 $preExistingContactCount = CRM_Core_DAO::singleValueQuery('select count(*) FROM civicrm_contact');
3036 $contact1 = $this->individualCreate();
3037 $sql = "UPDATE civicrm_contact SET created_date = '2012-01-01' WHERE id = " . $contact1;
3038 CRM_Core_DAO::executeQuery($sql);
3039 $contact2 = $this->individualCreate();
3040 $sql = "UPDATE civicrm_contact SET created_date = '2012-02-01' WHERE id = " . $contact2;
3041 CRM_Core_DAO::executeQuery($sql);
3042 $contact3 = $this->householdCreate();
3043 $sql = "UPDATE civicrm_contact SET created_date = '2012-03-01' WHERE id = " . $contact3;
3044 CRM_Core_DAO::executeQuery($sql);
3045 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('<' => '2014-01-01')));
3046 $this->assertEquals($contacts['count'], 3);
3047 $contacts = $this->callAPISuccess('contact', 'get', array('created_date' => array('>' => '2014-01-01')));
3048 $this->assertEquals($contacts['count'], $preExistingContactCount);
3049 }
3050
3051 /**
3052 * CRM-14263 check that API is not affected by search profile related bug.
3053 */
3054 public function testReturnCityProfile() {
3055 $contactID = $this->individualCreate();
3056 CRM_Core_Config::singleton()->defaultSearchProfileID = 1;
3057 $this->callAPISuccess('address', 'create', array(
3058 'contact_id' => $contactID,
3059 'city' => 'Cool City',
3060 'location_type_id' => 1,
3061 ));
3062 $result = $this->callAPISuccess('contact', 'get', array('city' => 'Cool City', 'return' => 'contact_type'));
3063 $this->assertEquals(1, $result['count']);
3064 }
3065
3066 /**
3067 * CRM-15443 - ensure getlist api does not return deleted contacts.
3068 */
3069 public function testGetlistExcludeConditions() {
3070 $name = md5(time());
3071 $contact = $this->individualCreate(array('last_name' => $name));
3072 $this->individualCreate(array('last_name' => $name, 'is_deceased' => 1));
3073 $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
3074 // We should get all but the deleted contact.
3075 $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
3076 $this->assertEquals(2, $result['count']);
3077 // Force-exclude the deceased contact.
3078 $result = $this->callAPISuccess('contact', 'getlist', array(
3079 'input' => $name,
3080 'params' => array('is_deceased' => 0),
3081 ));
3082 $this->assertEquals(1, $result['count']);
3083 $this->assertEquals($contact, $result['values'][0]['id']);
3084 }
3085
3086 /**
3087 * Test contact getactions.
3088 */
3089 public function testGetActions() {
3090 $description = "Getting the available actions for an entity.";
3091 $result = $this->callAPIAndDocument($this->_entity, 'getactions', array(), __FUNCTION__, __FILE__, $description);
3092 $expected = array(
3093 'create',
3094 'delete',
3095 'get',
3096 'getactions',
3097 'getcount',
3098 'getfields',
3099 'getlist',
3100 'getoptions',
3101 'getquick',
3102 'getrefcount',
3103 'getsingle',
3104 'getvalue',
3105 'merge',
3106 'proximity',
3107 'replace',
3108 'setvalue',
3109 'update',
3110 );
3111 $deprecated = array(
3112 'update',
3113 'getquick',
3114 );
3115 foreach ($expected as $action) {
3116 $this->assertTrue(in_array($action, $result['values']), "Expected action $action");
3117 }
3118 foreach ($deprecated as $action) {
3119 $this->assertArrayKeyExists($action, $result['deprecated']);
3120 }
3121 }
3122
3123 /**
3124 * Test the duplicate check function.
3125 */
3126 public function testDuplicateCheck() {
3127 $harry = array(
3128 'first_name' => 'Harry',
3129 'last_name' => 'Potter',
3130 'email' => 'harry@hogwarts.edu',
3131 'contact_type' => 'Individual',
3132 );
3133 $this->callAPISuccess('Contact', 'create', $harry);
3134 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3135 'match' => $harry,
3136 ));
3137
3138 $this->assertEquals(1, $result['count']);
3139 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3140 'match' => array(
3141 'first_name' => 'Harry',
3142 'last_name' => 'Potter',
3143 'email' => 'no5@privet.drive',
3144 'contact_type' => 'Individual',
3145 ),
3146 ));
3147 $this->assertEquals(0, $result['count']);
3148 $this->callAPIFailure('Contact', 'create', array_merge($harry, array('dupe_check' => 1)));
3149 }
3150
3151 /**
3152 * Test the duplicate check function.
3153 */
3154 public function testDuplicateCheckRuleNotReserved() {
3155 $harry = array(
3156 'first_name' => 'Harry',
3157 'last_name' => 'Potter',
3158 'email' => 'harry@hogwarts.edu',
3159 'contact_type' => 'Individual',
3160 );
3161 $defaultRule = $this->callAPISuccess('RuleGroup', 'getsingle', array('used' => 'Unsupervised', 'is_reserved' => 1));
3162 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 0));
3163 $this->callAPISuccess('Contact', 'create', $harry);
3164 $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
3165 'match' => $harry,
3166 ));
3167
3168 $this->assertEquals(1, $result['count']);
3169 $this->callAPISuccess('RuleGroup', 'create', array('id' => $defaultRule['id'], 'is_reserved' => 1));
3170 }
3171
3172 /**
3173 * Test variants on retrieving contact by type.
3174 */
3175 public function testGetByContactType() {
3176 $individual = $this->callAPISuccess('Contact', 'create', array(
3177 'email' => 'individual@test.com',
3178 'contact_type' => 'Individual',
3179 ));
3180 $household = $this->callAPISuccess('Contact', 'create', array(
3181 'household_name' => 'household@test.com',
3182 'contact_type' => 'Household',
3183 ));
3184 $organization = $this->callAPISuccess('Contact', 'create', array(
3185 'organization_name' => 'organization@test.com',
3186 'contact_type' => 'Organization',
3187 ));
3188 // Test with id - getsingle will throw an exception if not found
3189 $this->callAPISuccess('Contact', 'getsingle', array(
3190 'id' => $individual['id'],
3191 'contact_type' => 'Individual',
3192 ));
3193 $this->callAPISuccess('Contact', 'getsingle', array(
3194 'id' => $individual['id'],
3195 'contact_type' => array('IN' => array('Individual')),
3196 'return' => 'id',
3197 ));
3198 $this->callAPISuccess('Contact', 'getsingle', array(
3199 'id' => $organization['id'],
3200 'contact_type' => array('IN' => array('Individual', 'Organization')),
3201 ));
3202 // Test as array
3203 $result = $this->callAPISuccess('Contact', 'get', array(
3204 'contact_type' => array('IN' => array('Individual', 'Organization')),
3205 'options' => array('limit' => 0),
3206 'return' => 'id',
3207 ));
3208 $this->assertContains($organization['id'], array_keys($result['values']));
3209 $this->assertContains($individual['id'], array_keys($result['values']));
3210 $this->assertNotContains($household['id'], array_keys($result['values']));
3211 // Test as string
3212 $result = $this->callAPISuccess('Contact', 'get', array(
3213 'contact_type' => 'Household',
3214 'options' => array('limit' => 0),
3215 'return' => 'id',
3216 ));
3217 $this->assertNotContains($organization['id'], array_keys($result['values']));
3218 $this->assertNotContains($individual['id'], array_keys($result['values']));
3219 $this->assertContains($household['id'], array_keys($result['values']));
3220 }
3221
3222 /**
3223 * Test merging 2 contacts.
3224 *
3225 * Someone kindly bequethed us the legacy of mixed up use of main_id & other_id
3226 * in the params for contact.merge api.
3227 *
3228 * This test protects that legacy.
3229 */
3230 public function testMergeBizzareOldParams() {
3231 $this->createLoggedInUser();
3232 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3233 $mainContact = $this->callAPISuccess('contact', 'create', $this->_params);
3234 $this->callAPISuccess('contact', 'merge', array(
3235 'main_id' => $mainContact['id'],
3236 'other_id' => $otherContact['id'],
3237 ));
3238 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
3239 $this->assertEquals($otherContact['id'], $contacts['id']);
3240 }
3241
3242 /**
3243 * Test merging 2 contacts.
3244 */
3245 public function testMerge() {
3246 $this->createLoggedInUser();
3247 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3248 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
3249 $this->callAPISuccess('contact', 'merge', array(
3250 'to_keep_id' => $retainedContact['id'],
3251 'to_remove_id' => $otherContact['id'],
3252 'auto_flip' => FALSE,
3253 ));
3254
3255 $contacts = $this->callAPISuccess('contact', 'get', $this->_params);
3256 $this->assertEquals($retainedContact['id'], $contacts['id']);
3257 $activity = $this->callAPISuccess('Activity', 'getsingle', array(
3258 'target_contact_id' => $retainedContact['id'],
3259 'activity_type_id' => 'Contact Merged',
3260 ));
3261 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($activity['activity_date_time'])));
3262 $activity2 = $this->callAPISuccess('Activity', 'getsingle', array(
3263 'target_contact_id' => $otherContact['id'],
3264 'activity_type_id' => 'Contact Deleted by Merge',
3265 ));
3266 $this->assertEquals($activity['id'], $activity2['parent_id']);
3267 $this->assertEquals('Normal', civicrm_api3('option_value', 'getvalue', array(
3268 'value' => $activity['priority_id'],
3269 'return' => 'label',
3270 'option_group_id' => 'priority',
3271 )));
3272
3273 }
3274
3275 /**
3276 * Test merging 2 contacts with delete to trash off.
3277 *
3278 * We are checking that there is no error due to attempting to add an activity for the
3279 * deleted contact.
3280 *
3281 * CRM-18307
3282 */
3283 public function testMergeNoTrash() {
3284 $this->createLoggedInUser();
3285 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => FALSE));
3286 $otherContact = $this->callAPISuccess('contact', 'create', $this->_params);
3287 $retainedContact = $this->callAPISuccess('contact', 'create', $this->_params);
3288 $this->callAPISuccess('contact', 'merge', array(
3289 'to_keep_id' => $retainedContact['id'],
3290 'to_remove_id' => $otherContact['id'],
3291 'auto_flip' => FALSE,
3292 ));
3293 $this->callAPISuccess('Setting', 'create', array('contact_undelete' => TRUE));
3294 }
3295
3296 /**
3297 * Ensure format with return=group shows comma-separated group IDs.
3298 *
3299 * CRM-19426
3300 */
3301 public function testContactGetReturnGroup() {
3302 // Set up a contact, asser that they were created.
3303 $contact_params = array(
3304 'contact_type' => 'Individual',
3305 'first_name' => 'Test',
3306 'last_name' => 'Groupmember',
3307 'email' => 'test@example.org',
3308 );
3309 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3310 $this->assertEquals(0, $create_contact['is_error']);
3311 $this->assertInternalType('int', $create_contact['id']);
3312
3313 $created_contact_id = $create_contact['id'];
3314
3315 // Set up multiple groups, add the contact to the groups.
3316 $test_groups = array('Test group A', 'Test group B');
3317 foreach ($test_groups as $title) {
3318 // Use this contact as group owner, since we know they exist.
3319 $group_params = array(
3320 'title' => $title,
3321 'created_id' => $created_contact_id,
3322 );
3323 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3324 $this->assertEquals(0, $create_group['is_error']);
3325 $this->assertInternalType('int', $create_group['id']);
3326
3327 $created_group_ids[] = $create_group['id'];
3328
3329 // Add contact to the new group.
3330 $group_contact_params = array(
3331 'contact_id' => $created_contact_id,
3332 'group_id' => $create_group['id'],
3333 );
3334 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3335 $this->assertEquals(0, $create_group_contact['is_error']);
3336 $this->assertInternalType('int', $create_group_contact['added']);
3337 }
3338
3339 // Use the Contact,get API to retrieve the contact
3340 $contact_get_params = array(
3341 'id' => $created_contact_id,
3342 'return' => 'group',
3343 );
3344 $contact_get = $this->callApiSuccess('Contact', 'get', $contact_get_params);
3345 $this->assertInternalType('array', $contact_get['values'][$created_contact_id]);
3346 $this->assertInternalType('string', $contact_get['values'][$created_contact_id]['groups']);
3347
3348 // Ensure they are shown as being in each created group.
3349 $contact_group_ids = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3350 foreach ($created_group_ids as $created_group_id) {
3351 $this->assertContains($created_group_id, $contact_group_ids);
3352 }
3353 }
3354
3355 /**
3356 * CRM-20144 Verify that passing title of group works as well as id
3357 * Tests the following formats
3358 * contact.get group='title1'
3359 * contact.get group=id1
3360 */
3361 public function testContactGetWithGroupTitle() {
3362 // Set up a contact, asser that they were created.
3363 $contact_params = array(
3364 'contact_type' => 'Individual',
3365 'first_name' => 'Test2',
3366 'last_name' => 'Groupmember',
3367 'email' => 'test@example.org',
3368 );
3369 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3370 $created_contact_id = $create_contact['id'];
3371 // Set up multiple groups, add the contact to the groups.
3372 $test_groups = array('Test group C', 'Test group D');
3373 foreach ($test_groups as $title) {
3374 $group_params = array(
3375 'title' => $title,
3376 'created_id' => $created_contact_id,
3377 );
3378 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3379 $created_group_id = $create_group['id'];
3380
3381 // Add contact to the new group.
3382 $group_contact_params = array(
3383 'contact_id' => $created_contact_id,
3384 'group_id' => $create_group['id'],
3385 );
3386 $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3387 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $title, 'return' => 'group'));
3388 $this->assertEquals(1, $contact_get['count']);
3389 $this->assertEquals($created_contact_id, $contact_get['id']);
3390 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3391 $this->assertContains((string) $create_group['id'], $contact_groups);
3392 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => $created_group_id, 'return' => 'group'));
3393 $this->assertEquals($created_contact_id, $contact_get2['id']);
3394 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3395 $this->assertContains((string) $create_group['id'], $contact_groups2);
3396 $this->callAPISuccess('group', 'delete', array('id' => $created_group_id));
3397 }
3398 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3399 }
3400
3401 /**
3402 * CRM-20144 Verify that passing title of group works as well as id
3403 * Tests the following formats
3404 * contact.get group=array('title1', title1)
3405 * contact.get group=array('IN' => array('title1', 'title2)
3406 */
3407 public function testContactGetWithGroupTitleMultipleGroups() {
3408 $description = "Get all from group and display contacts.";
3409 $subFile = "GroupFilterUsingContactAPI";
3410 // Set up a contact, asser that they were created.
3411 $contact_params = array(
3412 'contact_type' => 'Individual',
3413 'first_name' => 'Test2',
3414 'last_name' => 'Groupmember',
3415 'email' => 'test@example.org',
3416 );
3417 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3418 $created_contact_id = $create_contact['id'];
3419 $createdGroupsTitles = $createdGroupsIds = array();
3420 // Set up multiple groups, add the contact to the groups.
3421 $test_groups = array('Test group C', 'Test group D');
3422 foreach ($test_groups as $title) {
3423 $group_params = array(
3424 'title' => $title,
3425 'created_id' => $created_contact_id,
3426 );
3427 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3428 $created_group_id = $create_group['id'];
3429 $createdGroupsIds[] = $create_group['id'];
3430 $createdGroupTitles[] = $title;
3431 // Add contact to the new group.
3432 $group_contact_params = array(
3433 'contact_id' => $created_contact_id,
3434 'group_id' => $create_group['id'],
3435 );
3436 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3437 }
3438 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => $createdGroupTitles, 'return' => 'group'));
3439 $this->assertEquals(1, $contact_get['count']);
3440 $this->assertEquals($created_contact_id, $contact_get['id']);
3441 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3442 foreach ($createdGroupsIds as $id) {
3443 $this->assertContains((string) $id, $contact_groups);
3444 }
3445 $contact_get2 = $this->callAPIAndDocument('contact', 'get', array('group' => array('IN' => $createdGroupTitles)), __FUNCTION__, __FILE__, $description, $subFile);
3446 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array('IN' => $createdGroupTitles), 'return' => 'group'));
3447 $this->assertEquals($created_contact_id, $contact_get2['id']);
3448 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3449 foreach ($createdGroupsIds as $id) {
3450 $this->assertContains((string) $id, $contact_groups2);
3451 }
3452 foreach ($createdGroupsIds as $id) {
3453 $this->callAPISuccess('group', 'delete', array('id' => $id));
3454 }
3455 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3456 }
3457
3458 /**
3459 * CRM-20144 Verify that passing title of group works as well as id
3460 * Tests the following formats
3461 * contact.get group=array('title1' => 1)
3462 * contact.get group=array('titke1' => 1, 'title2' => 1)
3463 * contact.get group=array('id1' => 1)
3464 * contact.get group=array('id1' => 1, id2 => 1)
3465 */
3466 public function testContactGetWithGroupTitleMultipleGroupsLegacyFormat() {
3467 // Set up a contact, asser that they were created.
3468 $contact_params = array(
3469 'contact_type' => 'Individual',
3470 'first_name' => 'Test2',
3471 'last_name' => 'Groupmember',
3472 'email' => 'test@example.org',
3473 );
3474 $create_contact = $this->callApiSuccess('Contact', 'create', $contact_params);
3475 $created_contact_id = $create_contact['id'];
3476 $createdGroupsTitles = $createdGroupsIds = array();
3477 // Set up multiple groups, add the contact to the groups.
3478 $test_groups = array('Test group C', 'Test group D');
3479 foreach ($test_groups as $title) {
3480 $group_params = array(
3481 'title' => $title,
3482 'created_id' => $created_contact_id,
3483 );
3484 $create_group = $this->callApiSuccess('Group', 'create', $group_params);
3485 $created_group_id = $create_group['id'];
3486 $createdGroupsIds[] = $create_group['id'];
3487 $createdGroupTitles[] = $title;
3488 // Add contact to the new group.
3489 $group_contact_params = array(
3490 'contact_id' => $created_contact_id,
3491 'group_id' => $create_group['id'],
3492 );
3493 $create_group_contact = $this->callApiSuccess('GroupContact', 'create', $group_contact_params);
3494 }
3495 $contact_get = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1), 'return' => 'group'));
3496 $this->assertEquals(1, $contact_get['count']);
3497 $this->assertEquals($created_contact_id, $contact_get['id']);
3498 $contact_groups = explode(',', $contact_get['values'][$created_contact_id]['groups']);
3499 foreach ($createdGroupsIds as $id) {
3500 $this->assertContains((string) $id, $contact_groups);
3501 }
3502 $contact_get2 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupTitles[0] => 1, $createdGroupTitles[1] => 1), 'return' => 'group'));
3503 $this->assertEquals(1, $contact_get2['count']);
3504 $this->assertEquals($created_contact_id, $contact_get2['id']);
3505 $contact_groups2 = explode(',', $contact_get2['values'][$created_contact_id]['groups']);
3506 foreach ($createdGroupsIds as $id) {
3507 $this->assertContains((string) $id, $contact_groups2);
3508 }
3509 $contact_get3 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1), 'return' => 'group'));
3510 $this->assertEquals($created_contact_id, $contact_get3['id']);
3511 $contact_groups3 = explode(',', $contact_get3['values'][$created_contact_id]['groups']);
3512 foreach ($createdGroupsIds as $id) {
3513 $this->assertContains((string) $id, $contact_groups3);
3514 }
3515 $contact_get4 = $this->callAPISuccess('contact', 'get', array('group' => array($createdGroupsIds[0] => 1, $createdGroupsIds[1] => 1), 'return' => 'group'));
3516 $this->assertEquals($created_contact_id, $contact_get4['id']);
3517 $contact_groups4 = explode(',', $contact_get4['values'][$created_contact_id]['groups']);
3518 foreach ($createdGroupsIds as $id) {
3519 $this->assertContains((string) $id, $contact_groups4);
3520 }
3521 foreach ($createdGroupsIds as $id) {
3522 $this->callAPISuccess('group', 'delete', array('id' => $id));
3523 }
3524 $this->callAPISuccess('contact', 'delete', array('id' => $created_contact_id, 'skip_undelete' => TRUE));
3525 }
3526
3527 public function testLoggedInUserAPISupportToken() {
3528 $description = "Get contact id of the current logged in user";
3529 $subFile = "ContactIDOfLoggedInUserContactAPI";
3530 $cid = $this->createLoggedInUser();
3531 $contact = $this->callAPIAndDocument('contact', 'get', array('id' => 'user_contact_id'), __FUNCTION__, __FILE__, $description, $subFile);
3532 $this->assertEquals($cid, $contact['id']);
3533 }
3534
3535 /**
3536 * @param $groupID
3537 * @param $contact
3538 */
3539 protected function putGroupContactCacheInClearableState($groupID, $contact) {
3540 // We need to force the situation where there is invalid data in the cache and it
3541 // is due to be cleared.
3542 CRM_Core_DAO::executeQuery("
3543 INSERT INTO civicrm_group_contact_cache (group_id, contact_id)
3544 VALUES ({$groupID}, {$contact['id']})
3545 ");
3546 CRM_Core_DAO::executeQuery("UPDATE civicrm_group SET cache_date = '2017-01-01'");
3547 // Reset so it does not skip.
3548 Civi::$statics['CRM_Contact_BAO_GroupContactCache']['is_refresh_init'] = FALSE;
3549 }
3550
3551 /**
3552 * CRM-21041 Test if 'communication style' is set to site default if not passed.
3553 */
3554 public function testCreateCommunicationStyleUnset() {
3555 $this->callAPISuccess('Contact', 'create', array(
3556 'first_name' => 'John',
3557 'last_name' => 'Doe',
3558 'contact_type' => 'Individual')
3559 );
3560 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Doe'));
3561 $this->assertEquals(1, $result['communication_style_id']);
3562 }
3563
3564 /**
3565 * CRM-21041 Test if 'communication style' is set if value is passed.
3566 */
3567 public function testCreateCommunicationStylePassed() {
3568 $this->callAPISuccess('Contact', 'create', array(
3569 'first_name' => 'John',
3570 'last_name' => 'Doe',
3571 'contact_type' => 'Individual',
3572 'communication_style_id' => 'Familiar',
3573 ));
3574 $result = $this->callAPISuccessGetSingle('Contact', array('last_name' => 'Doe'));
3575 $params = array(
3576 'option_group_id' => 'communication_style',
3577 'label' => 'Familiar',
3578 'return' => 'value',
3579 );
3580 $optionResult = civicrm_api3('OptionValue', 'get', $params);
3581 $communicationStyle = reset($optionResult['values']);
3582 $this->assertEquals($communicationStyle['value'], $result['communication_style_id']);
3583 }
3584
3585 /**
3586 * Test that creating a contact with various contact greetings works.
3587 */
3588 public function testContactGreetingsCreate() {
3589 $contact = $this->callAPISuccess('Contact', 'create', array('first_name' => 'Alan', 'last_name' => 'MouseMouse', 'contact_type' => 'Individual'));
3590 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3591 $this->assertEquals('Dear Alan', $contact['postal_greeting_display']);
3592
3593 $contact = $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'postal_greeting_id' => 2));
3594 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3595 $this->assertEquals('Dear Alan MouseMouse', $contact['postal_greeting_display']);
3596
3597 $contact = $this->callAPISuccess('Contact', 'create', array('organization_name' => 'Alan\'s Show', 'contact_type' => 'Organization'));
3598 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting, addressee, email_greeting'));
3599 $this->assertEquals('', $contact['postal_greeting_display']);
3600 $this->assertEquals('', $contact['email_greeting_display']);
3601 $this->assertEquals('Alan\'s Show', $contact['addressee_display']);
3602 }
3603
3604 /**
3605 * Test that creating a contact with various contact greetings works.
3606 */
3607 public function testContactGreetingsCreateWithCustomField() {
3608 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
3609 $contact = $this->callAPISuccess('Contact', 'create', array('first_name' => 'Alan', 'contact_type' => 'Individual', 'custom_' . $ids['custom_field_id'] => 'Mice'));
3610
3611 // Change postal greeting to involve a custom field.
3612 $postalOption = $this->callAPISuccessGetSingle('OptionValue', array('option_group_id' => 'postal_greeting', 'filter' => 1, 'is_default' => 1));
3613 $this->callAPISuccess('OptionValue', 'create', array(
3614 'id' => $postalOption['id'],
3615 'name' => 'Dear {contact.first_name} {contact.custom_' . $ids['custom_field_id'] . '}',
3616 'label' => 'Dear {contact.first_name} {contact.custom_' . $ids['custom_field_id'] . '}',
3617 ));
3618
3619 // Update contact & see if postal greeting now reflects the new string.
3620 $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'last_name' => 'MouseyMousey'));
3621 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3622 $this->assertEquals('Dear Alan Mice', $contact['postal_greeting_display']);
3623
3624 // Set contact to have no postal greeting & check it is correct.
3625 $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'postal_greeting_id' => 'null'));
3626 $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting'));
3627 $this->assertEquals('', $contact['postal_greeting_display']);
3628
3629 //Cleanup
3630 $this->callAPISuccess('OptionValue', 'create', array('id' => $postalOption['id'], 'name' => 'Dear {contact.first_name}'));
3631 $this->customFieldDelete($ids['custom_field_id']);
3632 $this->customGroupDelete($ids['custom_group_id']);
3633 }
3634
3635 }