Fix metadata on member export
[civicrm-core.git] / tests / phpunit / CRM / Export / BAO / ExportTest.php
CommitLineData
ef51caa8 1<?php
ef51caa8 2
3/**
4 * Class CRM_Core_DAOTest
46312f7d 5 *
acb109b7 6 * @group headless
ef51caa8 7 */
8class CRM_Export_BAO_ExportTest extends CiviUnitTestCase {
9
d989f2a4 10 use CRMTraits_Custom_CustomDataTrait;
12a36993 11 /**
12 * Contact IDs created for testing.
13 *
14 * @var array
15 */
c7224305 16 protected $contactIDs = [];
12a36993 17
18 /**
19 * Contribution IDs created for testing.
20 *
21 * @var array
22 */
c7224305 23 protected $contributionIDs = [];
24
25 /**
26 * Contribution IDs created for testing.
27 *
28 * @var array
29 */
30 protected $activityIDs = [];
12a36993 31
0a3b035f 32 /**
33 * Contribution IDs created for testing.
34 *
35 * @var array
36 */
37 protected $membershipIDs = [];
38
77544f6f
SV
39 /**
40 * Master Address ID created for testing.
41 *
42 * @var int
43 */
44 protected $masterAddressID;
45
a16a432a 46 protected $locationTypes = [];
47
68989e71 48 /**
49 * Processor generated in test.
50 *
51 * @var \CRM_Export_BAO_ExportProcessor
52 */
53 protected $processor;
54
c746d2b2 55 /**
56 * Csv output from export.
57 *
58 * @var \League\Csv\Reader
59 */
60 protected $csv;
61
68989e71 62 /**
63 * Cleanup data.
64 *
65 * @throws \Exception
66 */
4d251131 67 public function tearDown() {
68989e71 68 $this->quickCleanUpFinancialEntities();
0a3b035f 69 $this->quickCleanup([
70 'civicrm_contact',
71 'civicrm_email',
c2aec6ad 72 'civicrm_phone',
73 'civicrm_im',
74 'civicrm_website',
0a3b035f 75 'civicrm_address',
76 'civicrm_relationship',
77 'civicrm_membership',
78 'civicrm_case',
79 'civicrm_case_contact',
80 'civicrm_case_activity',
07b892fc 81 'civicrm_campaign',
0a3b035f 82 ]);
68989e71 83
a16a432a 84 if (!empty($this->locationTypes)) {
85 $this->callAPISuccess('LocationType', 'delete', ['id' => $this->locationTypes['Whare Kai']['id']]);
86 $this->callAPISuccess('LocationType', 'create', ['id' => $this->locationTypes['Main']['id'], 'name' => 'Main']);
87 }
68989e71 88 if ($this->processor && $this->processor->getTemporaryTable()) {
89 // delete the export temp table
90 CRM_Core_DAO::executeQuery("DROP TABLE IF EXISTS " . $this->processor->getTemporaryTable());
91 }
4d251131 92 parent::tearDown();
93 }
94
ef51caa8 95 /**
96 * Basic test to ensure the exportComponents function completes without error.
46312f7d 97 *
98 * @throws \CRM_Core_Exception
68989e71 99 * @throws \League\Csv\Exception
ef51caa8 100 */
12a36993 101 public function testExportComponentsNull() {
12a6fdef 102 $this->doExportTest([]);
ef51caa8 103 }
12a36993 104
105 /**
106 * Basic test to ensure the exportComponents function can export selected fields for contribution.
295549b4 107 *
108 * @throws \CRM_Core_Exception
c2aec6ad 109 * @throws \League\Csv\Exception
12a36993 110 */
111 public function testExportComponentsContribution() {
112 $this->setUpContributionExportData();
46312f7d 113 $selectedFields = [
e15ec147 114 ['contact_type' => 'Individual', 'name' => 'first_name'],
115 ['contact_type' => 'Individual', 'name' => 'last_name'],
116 ['name' => 'receive_date'],
117 ['name' => 'contribution_source'],
118 ['contact_type' => 'Individual', 'name' => 'street_address', 1],
119 ['contact_type' => 'Individual', 'name' => 'city', 1],
120 ['contact_type' => 'Individual', 'name' => 'country', 1],
121 ['contact_type' => 'Individual', 'name' => 'email', 1],
122 ['name' => 'trxn_id'],
46312f7d 123 ];
994a070c 124
295549b4 125 $this->doExportTest([
126 'ids' => $this->contributionIDs,
127 'order' => 'receive_date desc',
128 'fields' => $selectedFields,
129 'exportMode' => CRM_Export_Form_Select::CONTRIBUTE_EXPORT,
130 'componentClause' => 'civicrm_contribution.id IN ( ' . implode(',', $this->contributionIDs) . ')',
131 ]);
12a36993 132 }
c7224305 133
8535cfc6 134 /**
135 * Basic test to ensure the exportComponents function can export with soft credits enabled.
136 *
137 * @throws \CRM_Core_Exception
138 * @throws \League\Csv\Exception
139 */
140 public function testExportComponentsContributionSoftCredits() {
141 $this->setUpContributionExportData();
142 $this->callAPISuccess('ContributionSoft', 'create', ['contact_id' => $this->contactIDs[1], 'contribution_id' => $this->contributionIDs[0], 'amount' => 5]);
143 $params = [
c2aec6ad 144 ['receive_date_low', '=', '20160101000000', 0, 0],
8535cfc6 145 ['receive_date_high', '=', '20191231235959', 0, 0],
146 ['contribution_amount_low', '=', '1', 0, 0],
147 ['contribution_amount_high', '=', '10000000', 0, 0],
148 ['contribution_test', '=', '0', 0, 0],
149 ['contribution_or_softcredits', '=', 'both', 0, 0],
150 ];
151
c2aec6ad 152 $this->doExportTest([
153 'selectAll' => FALSE,
154 'ids' => $this->contributionIDs,
155 'params' => $params,
156 'order' => 'receive_date desc',
157 'exportMode' => CRM_Export_Form_Select::CONTRIBUTE_EXPORT,
158 'componentClause' => 'civicrm_contribution.id IN ( ' . implode(',', $this->contributionIDs) . ')',
159 ]);
160
161 $this->assertEquals(array_merge($this->getBasicHeaderDefinition(FALSE), $this->getContributeHeaderDefinition()), $this->csv->getHeader());
162 $this->assertCount(3, $this->csv);
163 $row = $this->csv->fetchOne(0);
164 $this->assertEquals(95, $row['Net Amount']);
165 $this->assertEquals('', $row['Soft Credit Amount']);
166 $row = $this->csv->fetchOne(1);
167 $this->assertEquals(95, $row['Net Amount']);
168 $this->assertEquals(5, $row['Soft Credit Amount']);
169 $this->assertEquals('Anderson, Anthony', $row['Soft Credit For']);
170 $this->assertEquals($this->contributionIDs[0], $row['Soft Credit For Contribution ID']);
171
8535cfc6 172 // Ideally we would use a randomised temp table name & use generic temp cleanup for cleanup - but
173 // for now just make sure we don't leave a mess.
174 CRM_Core_DAO::executeQuery('DROP TABLE IF EXISTS contribution_search_scredit_combined');
175
176 }
177
18711469 178 /**
179 * Basic test to ensure the exportComponents function can export selected fields for contribution.
65cfeed6 180 *
181 * @throws \CRM_Core_Exception
182 * @throws \League\Csv\Exception
18711469 183 */
184 public function testExportComponentsMembership() {
185 $this->setUpMembershipExportData();
65cfeed6 186 $this->doExportTest([
187 'selectAll' => TRUE,
188 'ids' => $this->membershipIDs,
189 'exportMode' => CRM_Export_Form_Select::MEMBER_EXPORT,
f03241be 190 'componentClause' => 'civicrm_membership.id IN ( ' . $this->ids['membership'] . ')',
65cfeed6 191 ]);
f03241be 192 $membership = $this->callAPISuccessGetSingle('Membership', ['id' => $this->ids['membership']]);
18711469 193
65cfeed6 194 $row = $this->csv->fetchOne();
195 $expected = [
196 'Contact ID' => $this->contactIDs[0],
197 'Contact Type' => 'Individual',
198 'Contact Subtype' => '',
199 'Do Not Email' => '',
200 'Do Not Phone' => '',
201 'Do Not Mail' => '',
202 'Do Not Sms' => '',
203 'Do Not Trade' => '',
204 'No Bulk Emails (User Opt Out)' => '',
205 'Legal Identifier' => '',
206 'External Identifier' => '',
207 'Sort Name' => 'Anderson, Anthony',
208 'Display Name' => 'Mr. Anthony Anderson II',
209 'Nickname' => '',
210 'Legal Name' => '',
211 'Image Url' => '',
212 'Preferred Communication Method' => '',
213 'Preferred Language' => 'en_US',
214 'Preferred Mail Format' => 'Both',
215 'Contact Hash' => '059023a02d27d4e7f285a40ee0e30be8',
216 'Contact Source' => '',
217 'First Name' => 'Anthony',
218 'Middle Name' => 'J.',
219 'Last Name' => 'Anderson',
220 'Individual Prefix' => 'Mr.',
221 'Individual Suffix' => 'II',
222 'Formal Title' => '',
223 'Communication Style' => 'Formal',
224 'Email Greeting ID' => '1',
225 'Postal Greeting ID' => '1',
226 'Addressee ID' => '1',
227 'Job Title' => '',
228 'Gender' => 'Female',
229 'Birth Date' => '',
230 'Deceased' => '',
231 'Deceased Date' => '',
232 'Household Name' => '',
233 'Organization Name' => '',
234 'Sic Code' => '',
235 'Unique ID (OpenID)' => '',
236 'Current Employer ID' => '',
237 'Contact is in Trash' => '',
238 'Created Date' => '2019-07-11 09:56:18',
239 'Modified Date' => '2019-07-11 09:56:19',
240 'Addressee' => 'Mr. Anthony J. Anderson II',
241 'Email Greeting' => 'Dear Anthony',
242 'Postal Greeting' => 'Dear Anthony',
243 'Current Employer' => '',
244 'Location Type' => 'Home',
245 'Street Address' => 'Ambachtstraat 23',
246 'Street Number' => '',
247 'Street Number Suffix' => '',
248 'Street Name' => '',
249 'Street Unit' => '',
250 'Supplemental Address 1' => '',
251 'Supplemental Address 2' => '',
252 'Supplemental Address 3' => '',
253 'City' => 'Brummen',
254 'Postal Code Suffix' => '',
255 'Postal Code' => '6971 BN',
256 'Latitude' => '',
257 'Longitude' => '',
258 'Address Name' => '',
259 'Master Address Belongs To' => '',
260 'County' => '',
261 'State' => '',
262 'Country' => 'Netherlands',
263 'Phone' => '',
264 'Phone Extension' => '',
265 'Phone Type' => '',
266 'Email' => 'home@example.com',
267 'On Hold' => '',
268 'Use for Bulk Mail' => '',
269 'Signature Text' => '',
270 'Signature Html' => '',
271 'IM Provider' => '',
272 'IM Screen Name' => '',
273 'OpenID' => '',
274 'World Region' => 'Europe and Central Asia',
275 'Website' => '',
276 'Membership Type' => 'General',
277 'Test' => '',
278 'Is Pay Later' => '',
f03241be 279 'Member Since' => $membership['join_date'],
280 'Membership Start Date' => $membership['start_date'],
281 'Membership Expiration Date' => $membership['end_date'],
65cfeed6 282 'Source' => 'Payment',
f03241be 283 'Membership Status' => 'New',
65cfeed6 284 'Membership ID' => '2',
285 'Primary Member ID' => '',
8f67d99a 286 'Max Related' => '',
287 'Membership Recurring Contribution' => 1,
65cfeed6 288 'Campaign ID' => '',
8f67d99a 289 'Status Override' => '',
f03241be 290 'Total Amount' => '200.00',
291 'Contribution Status' => 'Pending',
65cfeed6 292 'Date Received' => '2019-07-25 07:34:23',
f03241be 293 'Payment Method' => 'Check',
65cfeed6 294 'Transaction ID' => '',
295 ];
296 $this->assertExpectedOutput($expected, $row);
18711469 297 }
298
c7224305 299 /**
b20c1bb3 300 * Basic test to ensure the exportComponents function can export selected fields for activity
301 *
302 * @throws \CRM_Core_Exception
303 * @throws \League\Csv\Exception
c7224305 304 */
305 public function testExportComponentsActivity() {
306 $this->setUpActivityExportData();
46312f7d 307 $selectedFields = [
7d0e773c
CW
308 ['contact_type' => 'Individual', 'name' => 'display_name'],
309 ['contact_type' => 'Individual', 'relationship_type_id' => '5', 'relationship_direction' => 'a_b', 'name' => 'display_name'],
46312f7d 310 ];
c7224305 311
b20c1bb3 312 $this->doExportTest([
313 'ids' => $this->activityIDs,
314 'order' => '`activity_date_time` desc',
315 'fields' => $selectedFields,
316 'exportMode' => CRM_Export_Form_Select::ACTIVITY_EXPORT,
317 'componentClause' => 'civicrm_activity.id IN ( ' . implode(',', $this->activityIDs) . ')',
318 ]);
319 $row = $this->csv->fetchOne();
320 $this->assertEquals($this->activityIDs[0], $row['Activity ID']);
c7224305 321 }
322
12a36993 323 /**
324 * Test the function that extracts the arrays used to structure the output.
325 *
326 * The keys in the output fields array should by matched by field aliases in the sql query (with
327 * exceptions of course - currently country is one - although maybe a future refactor can change that!).
328 *
329 * We are trying to move towards simpler processing in the per row iteration as that may be
330 * repeated 100,000 times and in general we should simply be able to match the query fields to
331 * our expected rows & do a little pseudoconstant mapping.
332 */
333 public function testGetExportStructureArrays() {
334 // This is how return properties are formatted internally within the function for passing to the BAO query.
46312f7d 335 $returnProperties = [
12a36993 336 'first_name' => 1,
337 'last_name' => 1,
338 'receive_date' => 1,
339 'contribution_source' => 1,
46312f7d 340 'location' => [
341 'Home' => [
12a36993 342 'street_address' => 1,
343 'city' => 1,
344 'country' => 1,
345 'email' => 1,
346 'im-1' => 1,
347 'im_provider' => 1,
348 'phone-1' => 1,
46312f7d 349 ],
350 ],
12a36993 351 'phone' => 1,
352 'trxn_id' => 1,
353 'contribution_id' => 1,
46312f7d 354 ];
efc76c0a 355
46312f7d 356 $query = new CRM_Contact_BAO_Query([], $returnProperties, NULL,
12a36993 357 FALSE, FALSE, CRM_Contact_BAO_Query::MODE_CONTRIBUTE,
358 FALSE, TRUE, TRUE, NULL, 'AND'
359 );
360
361 list($select) = $query->query();
362 $pattern = '/as `?([^`,]*)/';
46312f7d 363 $queryFieldAliases = [];
12a36993 364 preg_match_all($pattern, $select, $queryFieldAliases, PREG_PATTERN_ORDER);
d41ab886 365 $processor = new CRM_Export_BAO_ExportProcessor(CRM_Contact_BAO_Query::MODE_CONTRIBUTE, NULL, 'AND');
adabfa40 366 $processor->setQueryFields($query->_fields);
6df77635 367 $processor->setReturnProperties($returnProperties);
12a36993 368
44fc53ab 369 list($outputFields) = $processor->getExportStructureArrays();
12a36993 370 foreach (array_keys($outputFields) as $fieldAlias) {
6df77635 371 if ($fieldAlias === 'Home-country') {
12a36993 372 $this->assertTrue(in_array($fieldAlias . '_id', $queryFieldAliases[1]), 'Country is subject to some funky translate so we make sure country id is present');
373 }
374 else {
375 $this->assertTrue(in_array($fieldAlias, $queryFieldAliases[1]), 'looking for field ' . $fieldAlias . ' in generaly the alias fields need to match the outputfields');
376 }
377 }
378
379 }
380
381 /**
382 * Set up some data for us to do testing on.
c2aec6ad 383 *
384 * @throws \CRM_Core_Exception
12a36993 385 */
386 public function setUpContributionExportData() {
387 $this->setUpContactExportData();
c2aec6ad 388 $this->contributionIDs[] = $this->contributionCreate(['contact_id' => $this->contactIDs[0], 'trxn_id' => 'null', 'invoice_id' => 'null', 'receive_date' => '2019-07-25 07:34:23']);
389 $this->contributionIDs[] = $this->contributionCreate(['contact_id' => $this->contactIDs[1], 'trxn_id' => 'null', 'invoice_id' => 'null', 'receive_date' => '2018-12-01 00:00:00']);
12a36993 390 }
391
0a3b035f 392 /**
393 * Set up some data for us to do testing on.
c2aec6ad 394 *
395 * @throws \CRM_Core_Exception
0a3b035f 396 */
397 public function setUpMembershipExportData() {
398 $this->setUpContactExportData();
18711469 399 // Create an extra so we don't get false passes due to 1
400 $this->contactMembershipCreate(['contact_id' => $this->contactIDs[0]]);
f03241be 401
402 $this->_contactID = $this->contactIDs[0];
403 $this->_invoiceID = 1234;
404 $this->_contributionPageID = NULL;
405 $this->_paymentProcessorID = $this->paymentProcessorCreate();
406 $this->setupMembershipRecurringPaymentProcessorTransaction();
407
408 $membershipID = $this->callAPISuccessGetValue('Membership', ['return' => 'id', 'contact_id' => $this->_contactID, 'options' => ['limit' => 1, 'sort' => 'id DESC']]);
409
410 $this->membershipIDs[] = $membershipID;
0a3b035f 411 }
412
413 /**
414 * Set up data to test case export.
f03241be 415 *
416 * @throws \CRM_Core_Exception
0a3b035f 417 */
418 public function setupCaseExportData() {
419 $contactID1 = $this->individualCreate();
46312f7d 420 $contactID2 = $this->individualCreate([], 1);
0a3b035f 421
46312f7d 422 $case = $this->callAPISuccess('case', 'create', [
0a3b035f 423 'case_type_id' => 1,
424 'subject' => 'blah',
425 'contact_id' => $contactID1,
46312f7d 426 ]);
0a3b035f 427 $this->callAPISuccess('CaseContact', 'create', [
428 'case_id' => $case['id'],
429 'contact_id' => $contactID2,
430 ]);
431 }
432
c7224305 433 /**
434 * Set up some data for us to do testing on.
b20c1bb3 435 *
436 * @throws \CRM_Core_Exception
c7224305 437 */
438 public function setUpActivityExportData() {
439 $this->setUpContactExportData();
46312f7d 440 $this->activityIDs[] = $this->activityCreate(['contact_id' => $this->contactIDs[0]])['id'];
c7224305 441 }
442
12a36993 443 /**
444 * Set up some data for us to do testing on.
c2aec6ad 445 *
446 * @throws \CRM_Core_Exception
12a36993 447 */
448 public function setUpContactExportData() {
bab4f15e 449 $this->contactIDs[] = $contactA = $this->individualCreate(['gender_id' => 'Female']);
4d251131 450 // Create address for contact A.
46312f7d 451 $params = [
994a070c 452 'contact_id' => $contactA,
453 'location_type_id' => 'Home',
454 'street_address' => 'Ambachtstraat 23',
455 'postal_code' => '6971 BN',
456 'country_id' => '1152',
457 'city' => 'Brummen',
458 'is_primary' => 1,
46312f7d 459 ];
994a070c 460 $result = $this->callAPISuccess('address', 'create', $params);
461 $addressId = $result['id'];
462
46312f7d 463 $this->callAPISuccess('email', 'create', [
4d251131 464 'id' => $this->callAPISuccessGetValue('Email', ['contact_id' => $params['contact_id'], 'return' => 'id']),
465 'location_type_id' => 'Home',
466 'email' => 'home@example.com',
467 'is_primary' => 1,
46312f7d 468 ]);
469 $this->callAPISuccess('email', 'create', ['contact_id' => $params['contact_id'], 'location_type_id' => 'Work', 'email' => 'work@example.com', 'is_primary' => 0]);
4d251131 470
471 $params['is_primary'] = 0;
472 $params['location_type_id'] = 'Work';
473 $this->callAPISuccess('address', 'create', $params);
474 $this->contactIDs[] = $contactB = $this->individualCreate();
475
46312f7d 476 $this->callAPISuccess('address', 'create', [
994a070c 477 'contact_id' => $contactB,
478 'location_type_id' => "Home",
479 'master_id' => $addressId,
46312f7d 480 ]);
77544f6f 481 $this->masterAddressID = $addressId;
994a070c 482
4d251131 483 }
484
485 /**
486 * Test variants of primary address exporting.
487 *
488 * @param int $isPrimaryOnly
489 *
ebebd629 490 * @dataProvider getBooleanDataProvider
491 * @throws \CRM_Core_Exception
c746d2b2 492 * @throws \League\Csv\Exception
4d251131 493 */
494 public function testExportPrimaryAddress($isPrimaryOnly) {
495 \Civi::settings()->set('searchPrimaryDetailsOnly', $isPrimaryOnly);
496 $this->setUpContactExportData();
497
e15ec147 498 $selectedFields = [
499 ['contact_type' => 'Individual', 'name' => 'email'],
500 ['contact_type' => 'Individual', 'name' => 'email', 'location_type_id' => '1'],
501 ['contact_type' => 'Individual', 'name' => 'email', 'location_type_id' => '2'],
502 ];
c746d2b2 503 $this->doExportTest([
504 'ids' => [],
505 'params' => [['email', 'LIKE', 'c', 0, 1]],
506 'fields' => $selectedFields,
507 'componentClause' => "contact_a.id IN ({$this->contactIDs[0]}, {$this->contactIDs[1]})",
508 'selectAll' => TRUE,
509 ]);
4d251131 510
c746d2b2 511 $row = $this->csv->fetchOne();
512 $this->assertEquals([
513 'Email' => 'home@example.com',
514 'Home-Email' => 'home@example.com',
515 'Work-Email' => 'work@example.com',
516 ], $row);
517 $this->assertEquals(2, count($this->csv));
4d251131 518 \Civi::settings()->set('searchPrimaryDetailsOnly', FALSE);
519 }
520
bab4f15e 521 /**
522 * Test that when exporting a pseudoField it is reset for NULL entries.
523 *
524 * ie. we have a contact WITH a gender & one without - make sure the latter one
525 * does NOT retain the gender of the former.
46312f7d 526 *
527 * @throws \CRM_Core_Exception
714ab070 528 * @throws \League\Csv\Exception
bab4f15e 529 */
530 public function testExportPseudoField() {
531 $this->setUpContactExportData();
714ab070 532 $this->callAPISuccess('OptionValue', 'create', ['option_group_id' => 'gender', 'name' => 'Really long string', 'value' => 678, 'label' => 'Really long string']);
533 $selectedFields = [['contact_type' => 'Individual', 'name' => 'gender_id']];
534 $this->callAPISuccess('Contact', 'create', ['id' => $this->contactIDs[0], 'gender_id' => 678]);
535 $this->doExportTest(['fields' => $selectedFields, 'ids' => $this->contactIDs]);
536 $row = $this->csv->fetchOne();
537 $this->assertEquals('Really long string', $row['Gender']);
bab4f15e 538 }
539
540 /**
541 * Test that when exporting a pseudoField it is reset for NULL entries.
542 *
543 * This is specific to the example in CRM-14398
07b892fc 544 *
545 * @throws \CRM_Core_Exception
546 * @throws \League\Csv\Exception
bab4f15e 547 */
548 public function testExportPseudoFieldCampaign() {
549 $this->setUpContributionExportData();
07b892fc 550 $campaign = $this->callAPISuccess('Campaign', 'create', ['title' => 'Big campaign and kinda long too']);
551 $this->callAPISuccess('Contribution', 'create', ['campaign_id' => 'Big_campaign_and_kinda_long_too', 'id' => $this->contributionIDs[0]]);
7d0e773c
CW
552 $selectedFields = [
553 ['contact_type' => 'Individual', 'name' => 'gender_id'],
554 ['contact_type' => 'Contribution', 'name' => 'contribution_campaign_title'],
07b892fc 555 ['contact_type' => 'Contribution', 'name' => 'contribution_campaign_id'],
7d0e773c 556 ];
07b892fc 557 $this->doExportTest([
558 'ids' => [$this->contactIDs[1]],
559 'exportMode' => CRM_Export_Form_Select::CONTRIBUTE_EXPORT,
560 'fields' => $selectedFields,
561 'componentClause' => "contact_a.id IN (" . implode(",", $this->contactIDs) . ")",
562 ]);
563 $row = $this->csv->fetchOne();
564 $this->assertEquals('Big campaign and kinda long too', $row['Campaign Title']);
565 $this->assertEquals($campaign['id'], $row['Campaign ID']);
bab4f15e 566 }
567
ce12a9e0 568 /**
569 * Test exporting relationships.
ea71cb07 570 *
571 * @throws \CRM_Core_Exception
572 * @throws \League\Csv\Exception
ce12a9e0 573 */
574 public function testExportRelationships() {
cedeaa5c 575 $organization1 = $this->organizationCreate(['organization_name' => 'Org 1', 'legal_name' => 'pretty legal', 'contact_source' => 'friend who took a law paper once']);
ce12a9e0 576 $organization2 = $this->organizationCreate(['organization_name' => 'Org 2', 'legal_name' => 'well dodgey']);
577 $contact1 = $this->individualCreate(['employer_id' => $organization1, 'first_name' => 'one']);
578 $contact2 = $this->individualCreate(['employer_id' => $organization2, 'first_name' => 'one']);
579 $employerRelationshipTypeID = $this->callAPISuccessGetValue('RelationshipType', ['return' => 'id', 'label_a_b' => 'Employee of']);
580 $selectedFields = [
e15ec147 581 ['contact_type' => 'Individual', 'name' => 'first_name'],
582 ['contact_type' => 'Individual', 'relationship_type_id' => $employerRelationshipTypeID, 'relationship_direction' => 'a_b', 'name' => 'organization_name'],
583 ['contact_type' => 'Individual', 'relationship_type_id' => $employerRelationshipTypeID, 'relationship_direction' => 'a_b', 'name' => 'legal_name'],
584 ['contact_type' => 'Individual', 'relationship_type_id' => $employerRelationshipTypeID, 'relationship_direction' => 'a_b', 'name' => 'contact_source'],
ce12a9e0 585 ];
ea71cb07 586 $this->doExportTest([
587 'ids' => [$contact1, $contact2],
588 'componentClause' => "contact_a.id IN ( $contact1, $contact2 )",
589 'fields' => $selectedFields,
590 ]);
5359d42b 591
ea71cb07 592 $row = $this->csv->fetchOne();
593 $this->assertEquals('one', $row['First Name']);
594 $this->assertEquals('Org 1', $row['Employee of-Organization Name']);
595 $this->assertEquals('pretty legal', $row['Employee of-Legal Name']);
596 $this->assertEquals('friend who took a law paper once', $row['Employee of-Contact Source']);
597
598 $row = $this->csv->fetchOne(1);
599 $this->assertEquals('Org 2', $row['Employee of-Organization Name']);
600 $this->assertEquals('well dodgey', $row['Employee of-Legal Name']);
ce12a9e0 601 }
602
b0eb1d74 603 /**
604 * Test exporting relationships.
605 *
606 * This is to ensure that CRM-13995 remains fixed.
ebebd629 607 *
608 * @dataProvider getBooleanDataProvider
609 *
610 * @param bool $includeHouseHold
611 *
c46c033c 612 * @throws CRM_Core_Exception
07b892fc 613 * @throws \League\Csv\Exception
b0eb1d74 614 */
ebebd629 615 public function testExportRelationshipsMergeToHousehold($includeHouseHold) {
2593f7dc 616 list($householdID, $houseHoldTypeID) = $this->setUpHousehold();
b0eb1d74 617
ebebd629 618 if ($includeHouseHold) {
619 $this->contactIDs[] = $householdID;
620 }
b0eb1d74 621 $selectedFields = [
7d0e773c
CW
622 ['contact_type' => 'Individual', 'relationship_type_id' => $houseHoldTypeID, 'relationship_direction' => 'a_b', 'name' => 'state_province', 'location_type_id' => ''],
623 ['contact_type' => 'Individual', 'relationship_type_id' => $houseHoldTypeID, 'relationship_direction' => 'a_b', 'name' => 'city', 'location_type_id' => ''],
624 ['contact_type' => 'Individual', 'name' => 'city', 'location_type_id' => ''],
625 ['contact_type' => 'Individual', 'name' => 'state_province', 'location_type_id' => ''],
626 ['contact_type' => 'Individual', 'name' => 'contact_source', 'location_type_id' => ''],
b0eb1d74 627 ];
07b892fc 628 $this->doExportTest([
629 'ids' => $this->contactIDs,
630 'fields' => $selectedFields,
631 'mergeSameHousehold' => TRUE,
632 ]);
633 $row = $this->csv->fetchOne();
634 $this->assertEquals(1, count($this->csv));
635 $this->assertEquals('Portland', $row['City']);
636 $this->assertEquals('ME', $row['State']);
637 $this->assertEquals($householdID, $row['Household ID']);
638 $this->assertEquals('household sauce', $row['Contact Source']);
b0eb1d74 639 }
640
2593f7dc 641 /**
642 * Test exporting relationships.
381f3a66 643 *
644 * @throws \CRM_Core_Exception
645 * @throws \League\Csv\Exception
2593f7dc 646 */
647 public function testExportRelationshipsMergeToHouseholdAllFields() {
2593f7dc 648 list($householdID) = $this->setUpHousehold();
381f3a66 649 $this->doExportTest(['ids' => $this->contactIDs, 'mergeSameHousehold' => TRUE]);
650 $row = $this->csv->fetchOne();
651 $this->assertCount(1, $this->csv);
652 $this->assertEquals('Unit Test household', $row['Display Name']);
653 $this->assertEquals('Portland', $row['City']);
654 $this->assertEquals('ME', $row['State']);
655 $this->assertEquals($householdID, $row['Household ID']);
656 $this->assertEquals('Unit Test household', $row['Addressee']);
657 $this->assertEquals('Dear Unit Test household', $row['Postal Greeting']);
2593f7dc 658 }
659
3663269c 660 /**
d989f2a4 661 * Test custom data exporting.
662 *
663 * @throws \CRM_Core_Exception
664 * @throws \League\Csv\Exception
3663269c 665 */
666 public function testExportCustomData() {
667 $this->setUpContactExportData();
d989f2a4 668 $this->entity = 'Contact';
669 $this->createCustomGroupWithFieldsOfAllTypes();
3663269c 670 $this->callAPISuccess('Contact', 'create', [
671 'id' => $this->contactIDs[1],
d989f2a4 672 $this->getCustomFieldName('text') => 'BlahdeBlah',
673 $this->getCustomFieldName('country') => 'LA',
3663269c 674 'api.Address.create' => ['location_type_id' => 'Billing', 'city' => 'Waipu'],
675 ]);
676 $selectedFields = [
d989f2a4 677 ['name' => 'city', 'location_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Address', 'location_type_id', 'Billing')],
678 ['name' => $this->getCustomFieldName('text')],
679 ['name' => $this->getCustomFieldName('country')],
3663269c 680 ];
681
d989f2a4 682 $this->doExportTest([
683 'fields' => $selectedFields,
684 'ids' => [$this->contactIDs[1]],
685 ]);
686 $row = $this->csv->fetchOne();
687 $this->assertEquals('BlahdeBlah', $row['Enter text here']);
688 $this->assertEquals('Waipu', $row['Billing-City']);
689 $this->assertEquals("Lao People's Democratic Republic", $row['Country']);
3663269c 690 }
691
692 /**
693 * Attempt to do a fairly full export of location data.
9d7c8793 694 *
695 * @throws \CRM_Core_Exception
696 * @throws \League\Csv\Exception
3663269c 697 */
698 public function testExportIMData() {
699 // Use default providers.
700 $providers = ['AIM', 'GTalk', 'Jabber', 'MSN', 'Skype', 'Yahoo'];
a16a432a 701 // Main sure labels are not all anglo chars.
702 $this->diversifyLocationTypes();
703
704 $locationTypes = ['Billing' => 'Billing', 'Home' => 'Home', 'Main' => 'Méin', 'Other' => 'Other', 'Whare Kai' => 'Whare Kai'];
3663269c 705
706 $this->contactIDs[] = $this->individualCreate();
707 $this->contactIDs[] = $this->individualCreate();
708 $this->contactIDs[] = $this->householdCreate();
709 $this->contactIDs[] = $this->organizationCreate();
710 foreach ($this->contactIDs as $contactID) {
711 foreach ($providers as $provider) {
a16a432a 712 foreach ($locationTypes as $locationName => $locationLabel) {
3663269c 713 $this->callAPISuccess('IM', 'create', [
714 'contact_id' => $contactID,
a16a432a 715 'location_type_id' => $locationName,
3663269c 716 'provider_id' => $provider,
a16a432a 717 'name' => $locationName . $provider . $contactID,
3663269c 718 ]);
719 }
720 }
721 }
722
723 $relationships = [
724 $this->contactIDs[1] => ['label' => 'Spouse of'],
725 $this->contactIDs[2] => ['label' => 'Household Member of'],
39b959db 726 $this->contactIDs[3] => ['label' => 'Employee of'],
3663269c 727 ];
728
729 foreach ($relationships as $contactID => $relationshipType) {
730 $relationshipTypeID = $this->callAPISuccess('RelationshipType', 'getvalue', ['label_a_b' => $relationshipType['label'], 'return' => 'id']);
731 $result = $this->callAPISuccess('Relationship', 'create', [
732 'contact_id_a' => $this->contactIDs[0],
733 'relationship_type_id' => $relationshipTypeID,
39b959db 734 'contact_id_b' => $contactID,
3663269c 735 ]);
736 $relationships[$contactID]['id'] = $result['id'];
737 $relationships[$contactID]['relationship_type_id'] = $relationshipTypeID;
738 }
739
740 $fields = [['Individual', 'contact_id']];
741 // ' ' denotes primary location type.
a16a432a 742 foreach (array_keys(array_merge($locationTypes, [' ' => ['Primary']])) as $locationType) {
3663269c 743 $fields[] = [
744 'Individual',
745 'im_provider',
746 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'location_type_id', $locationType),
747 ];
748 foreach ($relationships as $contactID => $relationship) {
749 $fields[] = [
750 'Individual',
751 $relationship['relationship_type_id'] . '_a_b',
752 'im_provider',
753 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'location_type_id', $locationType),
754 ];
755 }
756 foreach ($providers as $provider) {
757 $fields[] = [
758 'Individual',
759 'im',
760 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'location_type_id', $locationType),
761 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'provider_id', $provider),
762 ];
763 foreach ($relationships as $contactID => $relationship) {
764 $fields[] = [
765 'Individual',
766 $relationship['relationship_type_id'] . '_a_b',
767 'im',
768 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'location_type_id', $locationType),
769 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'provider_id', $provider),
770 ];
771 }
772 }
773 }
e15ec147 774
775 // @todo switch to just declaring the new format....
776 $mappedFields = [];
777 foreach ($fields as $field) {
778 $mappedFields[] = CRM_Core_BAO_Mapping::getMappingParams([], $field);
779 }
780 $this->doExportTest(['fields' => $mappedFields, 'ids' => [$this->contactIDs[0]]]);
9d7c8793 781
782 foreach ($this->csv->getRecords() as $row) {
783 $id = $row['contact_id'];
784 $this->assertEquals('AIM', $row['Billing-IM Provider']);
785 $this->assertEquals('AIM', $row['Whare Kai-IM Provider']);
786 $this->assertEquals('BillingJabber' . $id, $row['Billing-IM Screen Name-Jabber']);
787 $this->assertEquals('Whare KaiJabber' . $id, $row['Whare Kai-IM Screen Name-Jabber']);
788 $this->assertEquals('BillingSkype' . $id, $row['Billing-IM Screen Name-Skype']);
3663269c 789 foreach ($relationships as $relatedContactID => $relationship) {
9d7c8793 790 $this->assertEquals('BillingYahoo' . $relatedContactID, $row[$relationship['label'] . '-Billing-IM Screen Name-Yahoo']);
791 $this->assertEquals('Whare KaiJabber' . $relatedContactID, $row[$relationship['label'] . '-Whare Kai-IM Screen Name-Jabber']);
3663269c 792 }
793 }
3663269c 794 }
795
f797aeb8 796 /**
797 * Test phone data export.
798 *
799 * Less over the top complete than the im test.
45cee669 800 *
801 * @throws \CRM_Core_Exception
802 * @throws \League\Csv\Exception
f797aeb8 803 */
804 public function testExportPhoneData() {
805 $this->contactIDs[] = $this->individualCreate();
806 $this->contactIDs[] = $this->individualCreate();
807 $locationTypes = ['Billing' => 'Billing', 'Home' => 'Home'];
808 $phoneTypes = ['Mobile', 'Phone'];
809 foreach ($this->contactIDs as $contactID) {
810 $this->callAPISuccess('Phone', 'create', [
811 'contact_id' => $contactID,
812 'location_type_id' => 'Billing',
813 'phone_type_id' => 'Mobile',
001a515b 814 'phone' => 'Billing' . 'Mobile' . $contactID,
f797aeb8 815 'is_primary' => 1,
816 ]);
817 $this->callAPISuccess('Phone', 'create', [
818 'contact_id' => $contactID,
819 'location_type_id' => 'Home',
820 'phone_type_id' => 'Phone',
001a515b 821 'phone' => 'Home' . 'Phone' . $contactID,
f797aeb8 822 ]);
823 }
824
825 $relationships = [
39b959db 826 $this->contactIDs[1] => ['label' => 'Spouse of'],
f797aeb8 827 ];
828
829 foreach ($relationships as $contactID => $relationshipType) {
830 $relationshipTypeID = $this->callAPISuccess('RelationshipType', 'getvalue', ['label_a_b' => $relationshipType['label'], 'return' => 'id']);
831 $result = $this->callAPISuccess('Relationship', 'create', [
832 'contact_id_a' => $this->contactIDs[0],
833 'relationship_type_id' => $relationshipTypeID,
39b959db 834 'contact_id_b' => $contactID,
f797aeb8 835 ]);
836 $relationships[$contactID]['id'] = $result['id'];
837 $relationships[$contactID]['relationship_type_id'] = $relationshipTypeID;
838 }
839
840 $fields = [['Individual', 'contact_id']];
841 // ' ' denotes primary location type.
842 foreach (array_keys(array_merge($locationTypes, [' ' => ['Primary']])) as $locationType) {
843 $fields[] = [
844 'Individual',
845 'phone',
846 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Phone', 'location_type_id', $locationType),
847 ];
848 $fields[] = [
849 'Individual',
850 'phone_type_id',
851 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Phone', 'location_type_id', $locationType),
852 ];
853 foreach ($relationships as $contactID => $relationship) {
854 $fields[] = [
855 'Individual',
856 $relationship['relationship_type_id'] . '_a_b',
857 'phone_type_id',
858 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Phone', 'location_type_id', $locationType),
859 ];
860 }
861 foreach ($phoneTypes as $phoneType) {
862 $fields[] = [
863 'Individual',
864 'phone',
865 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Phone', 'location_type_id', $locationType),
866 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Phone', 'phone_type_id', $phoneType),
867 ];
868 foreach ($relationships as $contactID => $relationship) {
869 $fields[] = [
870 'Individual',
871 $relationship['relationship_type_id'] . '_a_b',
872 'phone_type_id',
873 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Phone', 'location_type_id', $locationType),
874 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Phone', 'phone_type_id', $phoneType),
875 ];
876 }
877 }
878 }
e15ec147 879 // @todo switch to just declaring the new format....
880 $mappedFields = [];
881 foreach ($fields as $field) {
882 $mappedFields[] = CRM_Core_BAO_Mapping::getMappingParams([], $field);
883 }
884 $this->doExportTest(['fields' => $mappedFields, 'ids' => [$this->contactIDs[0]]]);
45cee669 885 foreach ($this->csv->getRecords() as $row) {
886 $this->assertEquals('BillingMobile3', $row['Billing-Phone-Mobile']);
887 $this->assertEquals('', $row['Billing-Phone-Phone']);
888 $this->assertEquals('Phone', $row['Spouse of-Phone Type']);
889 $this->assertEquals('Mobile', $row['Phone Type']);
890 $this->assertEquals('Mobile', $row['Billing-Phone Type']);
f797aeb8 891 }
892 }
893
a16a432a 894 /**
895 * Export City against multiple location types.
896 */
897 public function testExportAddressData() {
898 $this->diversifyLocationTypes();
899
900 $locationTypes = ['Billing' => 'Billing', 'Home' => 'Home', 'Main' => 'Méin', 'Other' => 'Other', 'Whare Kai' => 'Whare Kai'];
901
902 $this->contactIDs[] = $this->individualCreate();
903 $this->contactIDs[] = $this->individualCreate();
904 $this->contactIDs[] = $this->householdCreate();
905 $this->contactIDs[] = $this->organizationCreate();
906 $fields = [['Individual', 'contact_id']];
907 foreach ($this->contactIDs as $contactID) {
908 foreach ($locationTypes as $locationName => $locationLabel) {
909 $this->callAPISuccess('Address', 'create', [
910 'contact_id' => $contactID,
911 'location_type_id' => $locationName,
912 'street_address' => $locationLabel . $contactID . 'street_address',
913 'city' => $locationLabel . $contactID . 'city',
914 'postal_code' => $locationLabel . $contactID . 'postal_code',
915 ]);
916 $fields[] = ['Individual', 'city', CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Address', 'location_type_id', $locationName)];
917 $fields[] = ['Individual', 'street_address', CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Address', 'location_type_id', $locationName)];
918 $fields[] = ['Individual', 'postal_code', CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Address', 'location_type_id', $locationName)];
919 }
920 }
921
922 $relationships = [
923 $this->contactIDs[1] => ['label' => 'Spouse of'],
924 $this->contactIDs[2] => ['label' => 'Household Member of'],
39b959db 925 $this->contactIDs[3] => ['label' => 'Employee of'],
a16a432a 926 ];
927
928 foreach ($relationships as $contactID => $relationshipType) {
929 $relationshipTypeID = $this->callAPISuccess('RelationshipType', 'getvalue', ['label_a_b' => $relationshipType['label'], 'return' => 'id']);
930 $result = $this->callAPISuccess('Relationship', 'create', [
931 'contact_id_a' => $this->contactIDs[0],
932 'relationship_type_id' => $relationshipTypeID,
39b959db 933 'contact_id_b' => $contactID,
a16a432a 934 ]);
935 $relationships[$contactID]['id'] = $result['id'];
936 $relationships[$contactID]['relationship_type_id'] = $relationshipTypeID;
937 }
938
939 // ' ' denotes primary location type.
940 foreach (array_keys(array_merge($locationTypes, [' ' => ['Primary']])) as $locationType) {
941 foreach ($relationships as $contactID => $relationship) {
942 $fields[] = [
943 'Individual',
944 $relationship['relationship_type_id'] . '_a_b',
945 'city',
946 CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'location_type_id', $locationType),
947 ];
948 }
949 }
950 list($tableName, $sqlColumns) = $this->doExport($fields, $this->contactIDs[0]);
951
952 $dao = CRM_Core_DAO::executeQuery('SELECT * FROM ' . $tableName);
953 while ($dao->fetch()) {
954 $id = $dao->contact_id;
955 $this->assertEquals('Méin' . $id . 'city', $dao->main_city);
956 $this->assertEquals('Billing' . $id . 'street_address', $dao->billing_street_address);
957 $this->assertEquals('Whare Kai' . $id . 'postal_code', $dao->whare_kai_postal_code);
958 foreach ($relationships as $relatedContactID => $relationship) {
959 $relationshipString = $field = $relationship['relationship_type_id'] . '_a_b';
960 $field = $relationshipString . '_main_city';
961 $this->assertEquals('Méin' . $relatedContactID . 'city', $dao->$field);
962 }
963 }
964
965 $this->assertEquals([
966 'contact_id' => 'contact_id varchar(255)',
5ebd7d09 967 'billing_city' => 'billing_city varchar(64)',
968 'billing_street_address' => 'billing_street_address varchar(96)',
969 'billing_postal_code' => 'billing_postal_code varchar(64)',
970 'home_city' => 'home_city varchar(64)',
971 'home_street_address' => 'home_street_address varchar(96)',
972 'home_postal_code' => 'home_postal_code varchar(64)',
973 'main_city' => 'main_city varchar(64)',
974 'main_street_address' => 'main_street_address varchar(96)',
975 'main_postal_code' => 'main_postal_code varchar(64)',
976 'other_city' => 'other_city varchar(64)',
977 'other_street_address' => 'other_street_address varchar(96)',
978 'other_postal_code' => 'other_postal_code varchar(64)',
979 'whare_kai_city' => 'whare_kai_city varchar(64)',
980 'whare_kai_street_address' => 'whare_kai_street_address varchar(96)',
981 'whare_kai_postal_code' => 'whare_kai_postal_code varchar(64)',
982 '2_a_b_billing_city' => '2_a_b_billing_city varchar(64)',
983 '2_a_b_home_city' => '2_a_b_home_city varchar(64)',
984 '2_a_b_main_city' => '2_a_b_main_city varchar(64)',
985 '2_a_b_other_city' => '2_a_b_other_city varchar(64)',
986 '2_a_b_whare_kai_city' => '2_a_b_whare_kai_city varchar(64)',
987 '2_a_b_city' => '2_a_b_city varchar(64)',
988 '8_a_b_billing_city' => '8_a_b_billing_city varchar(64)',
989 '8_a_b_home_city' => '8_a_b_home_city varchar(64)',
990 '8_a_b_main_city' => '8_a_b_main_city varchar(64)',
991 '8_a_b_other_city' => '8_a_b_other_city varchar(64)',
992 '8_a_b_whare_kai_city' => '8_a_b_whare_kai_city varchar(64)',
993 '8_a_b_city' => '8_a_b_city varchar(64)',
994 '5_a_b_billing_city' => '5_a_b_billing_city varchar(64)',
995 '5_a_b_home_city' => '5_a_b_home_city varchar(64)',
996 '5_a_b_main_city' => '5_a_b_main_city varchar(64)',
997 '5_a_b_other_city' => '5_a_b_other_city varchar(64)',
998 '5_a_b_whare_kai_city' => '5_a_b_whare_kai_city varchar(64)',
999 '5_a_b_city' => '5_a_b_city varchar(64)',
a16a432a 1000 ], $sqlColumns);
1001 }
1002
4d251131 1003 /**
ffd511ee 1004 * Test master_address_id field when no merge is in play.
1005 *
1006 * @throws \CRM_Core_Exception
1007 * @throws \League\Csv\Exception
4d251131 1008 */
1009 public function testExportMasterAddress() {
1010 $this->setUpContactExportData();
1011
994a070c 1012 //export the master address for contact B
46312f7d 1013 $selectedFields = [
7d0e773c 1014 ['contact_type' => 'Individual', 'name' => 'master_id', 'location_type_id' => 1],
46312f7d 1015 ];
ffd511ee 1016 $this->doExportTest([
1017 'fields' => $selectedFields,
1018 'ids' => [$this->contactIDs[1]],
1019 ]);
1020 $row = $this->csv->fetchOne();
1021 $this->assertEquals(CRM_Contact_BAO_Contact::getMasterDisplayName($this->masterAddressID), $row['Home-Master Address Belongs To']);
994a070c 1022 }
1023
c2aec6ad 1024 /**
1025 * Test the merge same address option.
1026 *
1027 * @throws \CRM_Core_Exception
1028 * @throws \League\Csv\Exception
1029 */
1030 public function testMergeSameAddress() {
0b60a345 1031 $this->setUpContactSameAddressExportData();
1032 $this->doExportTest(['mergeSameAddress' => TRUE]);
c2aec6ad 1033 // ie 2 merged, one extra.
1034 $this->assertCount(2, $this->csv);
1035 $expected = [
1036 'Contact ID' => $this->contactIDs[0],
1037 'Contact Type' => 'Individual',
1038 'Contact Subtype' => '',
1039 'Do Not Email' => '',
1040 'Do Not Phone' => '',
1041 'Do Not Mail' => '',
1042 'Do Not Sms' => '',
1043 'Do Not Trade' => '',
1044 'No Bulk Emails (User Opt Out)' => '',
1045 'Legal Identifier' => '',
1046 'External Identifier' => '',
1047 'Sort Name' => 'Anderson, Anthony',
1048 'Display Name' => 'Mr. Anthony Anderson II',
1049 'Nickname' => '',
1050 'Legal Name' => '',
1051 'Image Url' => '',
1052 'Preferred Communication Method' => '',
1053 'Preferred Language' => 'en_US',
1054 'Preferred Mail Format' => 'Both',
1055 'Contact Hash' => 'e9bd0913cc05cc5aeae69ba04ee3be84',
1056 'Contact Source' => '',
1057 'First Name' => 'Anthony',
1058 'Middle Name' => 'J.',
1059 'Last Name' => 'Anderson',
1060 'Individual Prefix' => 'Mr.',
1061 'Individual Suffix' => 'II',
1062 'Formal Title' => '',
1063 'Communication Style' => 'Formal',
1064 'Email Greeting ID' => '1',
1065 'Postal Greeting ID' => '1',
1066 'Addressee ID' => '1',
1067 'Job Title' => '',
1068 'Gender' => 'Female',
1069 'Birth Date' => '',
1070 'Deceased' => '',
1071 'Deceased Date' => '',
1072 'Household Name' => '',
1073 'Organization Name' => '',
1074 'Sic Code' => '',
1075 'Unique ID (OpenID)' => '',
1076 'Current Employer ID' => '',
1077 'Contact is in Trash' => '',
1078 'Created Date' => '2019-07-11 10:28:15',
1079 'Modified Date' => '2019-07-11 10:28:15',
1080 'Addressee' => 'Mr. Anthony J. Anderson II, Dr. Sarah J. Smith II',
1081 'Email Greeting' => 'Dear Anthony, Sarah',
1082 'Postal Greeting' => 'Dear Anthony, Sarah',
1083 'Current Employer' => '',
1084 'Location Type' => 'Home',
1085 'Street Address' => 'Ambachtstraat 23',
1086 'Street Number' => '',
1087 'Street Number Suffix' => '',
1088 'Street Name' => '',
1089 'Street Unit' => '',
1090 'Supplemental Address 1' => '',
1091 'Supplemental Address 2' => '',
1092 'Supplemental Address 3' => '',
1093 'City' => 'Brummen',
1094 'Postal Code Suffix' => '',
1095 'Postal Code' => '6971 BN',
1096 'Latitude' => '',
1097 'Longitude' => '',
1098 'Address Name' => '',
1099 'Master Address Belongs To' => '',
1100 'County' => '',
1101 'State' => '',
1102 'Country' => 'Netherlands',
1103 'Phone' => '',
1104 'Phone Extension' => '',
1105 'Phone Type' => '',
1106 'Email' => 'home@example.com',
1107 'On Hold' => '',
1108 'Use for Bulk Mail' => '',
1109 'Signature Text' => '',
1110 'Signature Html' => '',
1111 'IM Provider' => '',
1112 'IM Screen Name' => '',
1113 'OpenID' => '',
1114 'World Region' => 'Europe and Central Asia',
1115 'Website' => '',
1116 'Group(s)' => '',
1117 'Tag(s)' => '',
1118 'Note(s)' => '',
1119 ];
1120 $this->assertExpectedOutput($expected, $this->csv->fetchOne());
1121 }
1122
0b60a345 1123 /**
1124 * Tests the options for greeting templates when choosing to merge same address.
1125 *
1126 * @throws \CRM_Core_Exception
1127 * @throws \League\Csv\Exception
1128 */
1129 public function testMergeSameAddressGreetingOptions() {
1130 $this->setUpContactSameAddressExportData();
1131 $this->callAPISuccess('OptionValue', 'create', [
1132 'option_group_id' => 'postal_greeting',
1133 'label' => '{contact.individual_suffix} {contact.last_name} and first is {contact.first_name} ',
1134 // This hard coded number makes it available for export use.
1135 'filter' => 4,
1136 ]);
1137 $this->doExportTest([
1138 'mergeSameAddress' => TRUE,
1139 'exportParams' => [
1140 'postal_greeting' => '2',
1141 'postal_greeting_other' => '',
1142 'addressee' => '2',
1143 'addressee_other' => 'random string {contact.display_name}',
1144 'mergeOption' => '1',
1145 'additional_group' => '',
1146 'mapping' => '',
1147 ],
1148 ]);
1149 $this->assertExpectedOutput([
1150 'Addressee' => 'random string Mr. Anthony Anderson II, Dr. Sarah Smith II',
1151 'Email Greeting' => 'II Anderson and first is Anthony , II Smith Sarah ',
1152 'Postal Greeting' => 'II Anderson and first is Anthony , II Smith Sarah ',
1153 ], $this->csv->fetchOne());
1154 // 3 contacts merged to 2.
1155 $this->assertCount(2, $this->csv);
1156 }
1157
6382c24c
LCA
1158 /**
1159 * Test that deceased and do not mail contacts are removed from contacts before
6d52bfe5 1160 *
1161 * @dataProvider getReasonsNotToMail
1162 *
1163 * @param array $reason
1164 * @param array $addressReason
46312f7d 1165 *
1166 * @throws \CRM_Core_Exception
efaa3367 1167 * @throws \League\Csv\Exception
6382c24c 1168 */
6d52bfe5 1169 public function testExportDeceasedDoNotMail($reason, $addressReason) {
46312f7d 1170 $contactA = $this->callAPISuccess('contact', 'create', [
6382c24c
LCA
1171 'first_name' => 'John',
1172 'last_name' => 'Doe',
1173 'contact_type' => 'Individual',
46312f7d 1174 ]);
6382c24c 1175
6d52bfe5 1176 $contactB = $this->callAPISuccess('contact', 'create', array_merge([
6382c24c
LCA
1177 'first_name' => 'Jane',
1178 'last_name' => 'Doe',
1179 'contact_type' => 'Individual',
6d52bfe5 1180 ], $reason));
6382c24c
LCA
1181
1182 //create address for contact A
6d52bfe5 1183 $this->callAPISuccess('address', 'create', [
6382c24c
LCA
1184 'contact_id' => $contactA['id'],
1185 'location_type_id' => 'Home',
1186 'street_address' => 'ABC 12',
1187 'postal_code' => '123 AB',
1188 'country_id' => '1152',
1189 'city' => 'ABC',
1190 'is_primary' => 1,
6d52bfe5 1191 ]);
6382c24c
LCA
1192
1193 //create address for contact B
6d52bfe5 1194 $this->callAPISuccess('address', 'create', array_merge([
6382c24c
LCA
1195 'contact_id' => $contactB['id'],
1196 'location_type_id' => 'Home',
1197 'street_address' => 'ABC 12',
1198 'postal_code' => '123 AB',
1199 'country_id' => '1152',
1200 'city' => 'ABC',
1201 'is_primary' => 1,
6d52bfe5 1202 ], $addressReason));
6382c24c 1203
efaa3367 1204 $this->doExportTest([
1205 'selectAll' => TRUE,
1206 'ids' => [$contactA['id'], $contactB['id']],
1207 'exportParams' => [
46312f7d 1208 'postal_mailing_export' => [
6382c24c 1209 'postal_mailing_export' => TRUE,
46312f7d 1210 ],
efaa3367 1211 'mergeSameAddress' => TRUE,
1212 ],
1213 ]);
1214 $row = $this->csv->fetchOne(0);
6382c24c 1215
efaa3367 1216 $this->assertTrue(!in_array('Stage', $this->processor->getHeaderRows()));
1217 $this->assertEquals('Dear John', $row['Email Greeting']);
1218 $this->assertCount(1, $this->csv);
6382c24c
LCA
1219 }
1220
6d52bfe5 1221 /**
1222 * Get reasons that a contact is not postalable.
46312f7d 1223 *
6d52bfe5 1224 * @return array
1225 */
1226 public function getReasonsNotToMail() {
1227 return [
1228 [['is_deceased' => 1], []],
1229 [['do_not_mail' => 1], []],
1230 [[], ['street_address' => '']],
1231 ];
1232 }
39b959db 1233
2593f7dc 1234 /**
46312f7d 1235 * Set up household for tests.
1236 *
2593f7dc 1237 * @return array
c46c033c 1238 *
1239 * @throws CRM_Core_Exception
2593f7dc 1240 */
1241 protected function setUpHousehold() {
1242 $this->setUpContactExportData();
1243 $householdID = $this->householdCreate([
cedeaa5c 1244 'source' => 'household sauce',
2593f7dc 1245 'api.Address.create' => [
1246 'city' => 'Portland',
1247 'state_province_id' => 'Maine',
39b959db
SL
1248 'location_type_id' => 'Home',
1249 ],
2593f7dc 1250 ]);
1251
1252 $relationshipTypes = $this->callAPISuccess('RelationshipType', 'get', [])['values'];
1253 $houseHoldTypeID = NULL;
1254 foreach ($relationshipTypes as $id => $relationshipType) {
1255 if ($relationshipType['name_a_b'] === 'Household Member of') {
1256 $houseHoldTypeID = $relationshipType['id'];
1257 }
1258 }
1259 $this->callAPISuccess('Relationship', 'create', [
1260 'contact_id_a' => $this->contactIDs[0],
1261 'contact_id_b' => $householdID,
1262 'relationship_type_id' => $houseHoldTypeID,
1263 ]);
1264 $this->callAPISuccess('Relationship', 'create', [
1265 'contact_id_a' => $this->contactIDs[1],
1266 'contact_id_b' => $householdID,
1267 'relationship_type_id' => $houseHoldTypeID,
1268 ]);
46312f7d 1269 return [$householdID, $houseHoldTypeID];
2593f7dc 1270 }
1271
3663269c 1272 /**
704e3e9a 1273 * Do a CiviCRM export.
1274 *
46312f7d 1275 * @param array $selectedFields
704e3e9a 1276 * @param int $id
1277 *
c66a5741 1278 * @param int $exportMode
1279 *
3663269c 1280 * @return array
46312f7d 1281 * @throws \CRM_Core_Exception
3663269c 1282 */
c66a5741 1283 protected function doExport($selectedFields, $id, $exportMode = CRM_Export_Form_Select::CONTACT_EXPORT) {
f797aeb8 1284 $ids = (array) $id;
7d0e773c
CW
1285 $mappedFields = [];
1286 foreach ((array) $selectedFields as $field) {
1287 $mappedFields[] = CRM_Core_BAO_Mapping::getMappingParams([], $field);
1288 }
3663269c 1289 list($tableName, $sqlColumns) = CRM_Export_BAO_Export::exportComponents(
1290 TRUE,
f797aeb8 1291 $ids,
46312f7d 1292 [],
3663269c 1293 NULL,
7d0e773c 1294 $mappedFields,
3663269c 1295 NULL,
c66a5741 1296 $exportMode,
f797aeb8 1297 "contact_a.id IN (" . implode(',', $ids) . ")",
3663269c 1298 NULL,
1299 FALSE,
1300 FALSE,
46312f7d 1301 [
3663269c 1302 'suppress_csv_for_testing' => TRUE,
46312f7d 1303 ]
3663269c 1304 );
46312f7d 1305 return [$tableName, $sqlColumns];
3663269c 1306 }
1307
0a3b035f 1308 /**
1309 * Ensure component is enabled.
1310 *
1311 * @param int $exportMode
1312 */
1313 public function ensureComponentIsEnabled($exportMode) {
1314 if ($exportMode === CRM_Export_Form_Select::CASE_EXPORT) {
1315 CRM_Core_BAO_ConfigSetting::enableComponent('CiviCase');
1316 }
1317 }
1318
ce14544c 1319 /**
1320 * Test our export all field metadata retrieval.
1321 *
1322 * @dataProvider additionalFieldsDataProvider
46312f7d 1323 *
ce14544c 1324 * @param int $exportMode
1325 * @param $expected
1326 */
1327 public function testAdditionalReturnProperties($exportMode, $expected) {
1328 $this->ensureComponentIsEnabled($exportMode);
1329 $processor = new CRM_Export_BAO_ExportProcessor($exportMode, NULL, 'AND');
1330 $metadata = $processor->getAdditionalReturnProperties();
1331 $this->assertEquals($expected, $metadata);
1332 }
1333
1334 /**
1335 * Test our export all field metadata retrieval.
1336 *
1337 * @dataProvider allFieldsDataProvider
46312f7d 1338 *
ce14544c 1339 * @param int $exportMode
1340 * @param $expected
1341 */
1342 public function testDefaultReturnProperties($exportMode, $expected) {
1343 $this->ensureComponentIsEnabled($exportMode);
1344 $processor = new CRM_Export_BAO_ExportProcessor($exportMode, NULL, 'AND');
1345 $metadata = $processor->getDefaultReturnProperties();
1346 $this->assertEquals($expected, $metadata);
1347 }
1348
1349 /**
1350 * Get fields returned from additionalFields function.
1351 *
1352 * @return array
1353 */
1354 public function additionalFieldsDataProvider() {
1355 return [
1356 [
1357 'anything that will then be defaulting ton contact',
1358 $this->getExtraReturnProperties(),
1359 ],
1360 [
1361 CRM_Export_Form_Select::ACTIVITY_EXPORT,
1362 array_merge($this->getExtraReturnProperties(), $this->getActivityReturnProperties()),
1363 ],
1364 [
1365 CRM_Export_Form_Select::CASE_EXPORT,
1366 array_merge($this->getExtraReturnProperties(), $this->getCaseReturnProperties()),
1367 ],
1368 [
1369 CRM_Export_Form_Select::CONTRIBUTE_EXPORT,
1370 array_merge($this->getExtraReturnProperties(), $this->getContributionReturnProperties()),
1371 ],
1372 [
1373 CRM_Export_Form_Select::EVENT_EXPORT,
1374 array_merge($this->getExtraReturnProperties(), $this->getEventReturnProperties()),
1375 ],
1376 [
1377 CRM_Export_Form_Select::MEMBER_EXPORT,
1378 array_merge($this->getExtraReturnProperties(), $this->getMembershipReturnProperties()),
1379 ],
1380 [
1381 CRM_Export_Form_Select::PLEDGE_EXPORT,
1382 array_merge($this->getExtraReturnProperties(), $this->getPledgeReturnProperties()),
1383 ],
1384
1385 ];
1386 }
1387
1388 /**
1389 * get data for testing field metadata by query mode.
1390 */
1391 public function allFieldsDataProvider() {
1392 return [
1393 [
1394 'anything that will then be defaulting ton contact',
1395 $this->getBasicReturnProperties(TRUE),
1396 ],
1397 [
1398 CRM_Export_Form_Select::ACTIVITY_EXPORT,
1399 array_merge($this->getBasicReturnProperties(FALSE), $this->getActivityReturnProperties()),
1400 ],
1401 [
1402 CRM_Export_Form_Select::CASE_EXPORT,
1403 array_merge($this->getBasicReturnProperties(FALSE), $this->getCaseReturnProperties()),
1404 ],
1405 [
1406 CRM_Export_Form_Select::CONTRIBUTE_EXPORT,
1407 array_merge($this->getBasicReturnProperties(FALSE), $this->getContributionReturnProperties()),
1408 ],
1409 [
1410 CRM_Export_Form_Select::EVENT_EXPORT,
1411 array_merge($this->getBasicReturnProperties(FALSE), $this->getEventReturnProperties()),
1412 ],
1413 [
1414 CRM_Export_Form_Select::MEMBER_EXPORT,
1415 array_merge($this->getBasicReturnProperties(FALSE), $this->getMembershipReturnProperties()),
1416 ],
1417 [
1418 CRM_Export_Form_Select::PLEDGE_EXPORT,
1419 array_merge($this->getBasicReturnProperties(FALSE), $this->getPledgeReturnProperties()),
1420 ],
1421 ];
1422 }
1423
1424 /**
1425 * Get return properties manually added in.
1426 */
1427 public function getExtraReturnProperties() {
7626754f 1428 return [];
ce14544c 1429 }
1430
1431 /**
1432 * Get basic return properties.
1433 *
704e3e9a 1434 * @param bool $isContactMode
ce14544c 1435 * Are we in contact mode or not
1436 *
1437 * @return array
1438 */
1439 protected function getBasicReturnProperties($isContactMode) {
1440 $returnProperties = [
1441 'id' => 1,
1442 'contact_type' => 1,
1443 'contact_sub_type' => 1,
1444 'do_not_email' => 1,
1445 'do_not_phone' => 1,
1446 'do_not_mail' => 1,
1447 'do_not_sms' => 1,
1448 'do_not_trade' => 1,
1449 'is_opt_out' => 1,
1450 'legal_identifier' => 1,
1451 'external_identifier' => 1,
1452 'sort_name' => 1,
1453 'display_name' => 1,
1454 'nick_name' => 1,
1455 'legal_name' => 1,
1456 'image_URL' => 1,
1457 'preferred_communication_method' => 1,
1458 'preferred_language' => 1,
1459 'preferred_mail_format' => 1,
1460 'hash' => 1,
1461 'contact_source' => 1,
1462 'first_name' => 1,
1463 'middle_name' => 1,
1464 'last_name' => 1,
1465 'prefix_id' => 1,
1466 'suffix_id' => 1,
1467 'formal_title' => 1,
1468 'communication_style_id' => 1,
1469 'email_greeting_id' => 1,
1470 'postal_greeting_id' => 1,
1471 'addressee_id' => 1,
1472 'job_title' => 1,
1473 'gender_id' => 1,
1474 'birth_date' => 1,
1475 'is_deceased' => 1,
1476 'deceased_date' => 1,
1477 'household_name' => 1,
1478 'organization_name' => 1,
1479 'sic_code' => 1,
1480 'user_unique_id' => 1,
1481 'current_employer_id' => 1,
1482 'contact_is_deleted' => 1,
1483 'created_date' => 1,
1484 'modified_date' => 1,
1485 'addressee' => 1,
1486 'email_greeting' => 1,
1487 'postal_greeting' => 1,
1488 'current_employer' => 1,
1489 'location_type' => 1,
1490 'street_address' => 1,
1491 'street_number' => 1,
1492 'street_number_suffix' => 1,
1493 'street_name' => 1,
1494 'street_unit' => 1,
1495 'supplemental_address_1' => 1,
1496 'supplemental_address_2' => 1,
1497 'supplemental_address_3' => 1,
1498 'city' => 1,
1499 'postal_code_suffix' => 1,
1500 'postal_code' => 1,
1501 'geo_code_1' => 1,
1502 'geo_code_2' => 1,
4fcfc078 1503 'manual_geo_code' => 1,
ce14544c 1504 'address_name' => 1,
1505 'master_id' => 1,
1506 'county' => 1,
1507 'state_province' => 1,
1508 'country' => 1,
1509 'phone' => 1,
1510 'phone_ext' => 1,
1511 'email' => 1,
1512 'on_hold' => 1,
1513 'is_bulkmail' => 1,
1514 'signature_text' => 1,
1515 'signature_html' => 1,
1516 'im_provider' => 1,
1517 'im' => 1,
1518 'openid' => 1,
1519 'world_region' => 1,
1520 'url' => 1,
1521 'groups' => 1,
1522 'tags' => 1,
1523 'notes' => 1,
1524 'phone_type_id' => 1,
ce14544c 1525 ];
1526 if (!$isContactMode) {
1527 unset($returnProperties['groups']);
1528 unset($returnProperties['tags']);
1529 unset($returnProperties['notes']);
1530 }
1531 return $returnProperties;
1532 }
1533
1534 /**
1535 * Get return properties for pledges.
1536 *
1537 * @return array
1538 */
1539 public function getPledgeReturnProperties() {
1540 return [
1541 'contact_type' => 1,
1542 'contact_sub_type' => 1,
1543 'sort_name' => 1,
1544 'display_name' => 1,
1545 'pledge_id' => 1,
1546 'pledge_amount' => 1,
1547 'pledge_total_paid' => 1,
1548 'pledge_create_date' => 1,
1549 'pledge_start_date' => 1,
1550 'pledge_next_pay_date' => 1,
1551 'pledge_next_pay_amount' => 1,
1552 'pledge_status' => 1,
1553 'pledge_is_test' => 1,
1554 'pledge_contribution_page_id' => 1,
1555 'pledge_financial_type' => 1,
1556 'pledge_frequency_interval' => 1,
1557 'pledge_frequency_unit' => 1,
1558 'pledge_currency' => 1,
1559 'pledge_campaign_id' => 1,
1560 'pledge_balance_amount' => 1,
1561 'pledge_payment_id' => 1,
1562 'pledge_payment_scheduled_amount' => 1,
1563 'pledge_payment_scheduled_date' => 1,
1564 'pledge_payment_paid_amount' => 1,
1565 'pledge_payment_paid_date' => 1,
1566 'pledge_payment_reminder_date' => 1,
1567 'pledge_payment_reminder_count' => 1,
1568 'pledge_payment_status' => 1,
1569 ];
1570 }
1571
1572 /**
1573 * Get membership return properties.
1574 *
1575 * @return array
1576 */
1577 public function getMembershipReturnProperties() {
1578 return [
ce14544c 1579 'contact_type' => 1,
1580 'contact_sub_type' => 1,
1581 'sort_name' => 1,
1582 'display_name' => 1,
1583 'membership_type' => 1,
1584 'member_is_test' => 1,
1585 'member_is_pay_later' => 1,
1586 'join_date' => 1,
1587 'membership_start_date' => 1,
1588 'membership_end_date' => 1,
1589 'membership_source' => 1,
1590 'membership_status' => 1,
1591 'membership_id' => 1,
1592 'owner_membership_id' => 1,
1593 'max_related' => 1,
1594 'membership_recur_id' => 1,
1595 'member_campaign_id' => 1,
1596 'member_is_override' => 1,
ce14544c 1597 ];
1598 }
1599
1600 /**
1601 * Get return properties for events.
1602 *
1603 * @return array
1604 */
1605 public function getEventReturnProperties() {
1606 return [
1607 'contact_type' => 1,
1608 'contact_sub_type' => 1,
1609 'sort_name' => 1,
1610 'display_name' => 1,
1611 'event_id' => 1,
1612 'event_title' => 1,
1613 'event_start_date' => 1,
1614 'event_end_date' => 1,
1615 'event_type' => 1,
1616 'participant_id' => 1,
1617 'participant_status' => 1,
1618 'participant_status_id' => 1,
1619 'participant_role' => 1,
1620 'participant_role_id' => 1,
1621 'participant_note' => 1,
1622 'participant_register_date' => 1,
1623 'participant_source' => 1,
1624 'participant_fee_level' => 1,
1625 'participant_is_test' => 1,
1626 'participant_is_pay_later' => 1,
1627 'participant_fee_amount' => 1,
1628 'participant_discount_name' => 1,
1629 'participant_fee_currency' => 1,
1630 'participant_registered_by_id' => 1,
1631 'participant_campaign_id' => 1,
1632 ];
1633 }
1634
1635 /**
1636 * Get return properties for activities.
1637 *
1638 * @return array
1639 */
1640 public function getActivityReturnProperties() {
1641 return [
1642 'activity_id' => 1,
1643 'contact_type' => 1,
1644 'contact_sub_type' => 1,
1645 'sort_name' => 1,
1646 'display_name' => 1,
1647 'activity_type' => 1,
1648 'activity_type_id' => 1,
1649 'activity_subject' => 1,
1650 'activity_date_time' => 1,
1651 'activity_duration' => 1,
1652 'activity_location' => 1,
1653 'activity_details' => 1,
1654 'activity_status' => 1,
1655 'activity_priority' => 1,
1656 'source_contact' => 1,
1657 'source_record_id' => 1,
1658 'activity_is_test' => 1,
1659 'activity_campaign_id' => 1,
1660 'result' => 1,
1661 'activity_engagement_level' => 1,
1662 'parent_id' => 1,
1663 ];
1664 }
1665
1666 /**
1667 * Get return properties for Case.
1668 *
1669 * @return array
1670 */
1671 public function getCaseReturnProperties() {
1672 return [
1673 'contact_type' => 1,
1674 'contact_sub_type' => 1,
1675 'sort_name' => 1,
1676 'display_name' => 1,
1677 'phone' => 1,
1678 'case_start_date' => 1,
1679 'case_end_date' => 1,
1680 'case_subject' => 1,
1681 'case_source_contact_id' => 1,
1682 'case_activity_status' => 1,
1683 'case_activity_duration' => 1,
1684 'case_activity_medium_id' => 1,
1685 'case_activity_details' => 1,
1686 'case_activity_is_auto' => 1,
1687 'contact_id' => 1,
1688 'case_id' => 1,
1689 'case_activity_subject' => 1,
1690 'case_status' => 1,
1691 'case_type' => 1,
1692 'case_role' => 1,
1693 'case_deleted' => 1,
1694 'case_recent_activity_date' => 1,
1695 'case_recent_activity_type' => 1,
1696 'case_scheduled_activity_date' => 1,
1697 ];
1698 }
1699
1700 /**
1701 * Get return properties for contribution.
1702 *
1703 * @return array
1704 */
1705 public function getContributionReturnProperties() {
1706 return [
1707 'contact_type' => 1,
1708 'contact_sub_type' => 1,
1709 'sort_name' => 1,
1710 'display_name' => 1,
1711 'financial_type' => 1,
1712 'contribution_source' => 1,
1713 'receive_date' => 1,
1714 'thankyou_date' => 1,
6e7cc0f5 1715 'contribution_cancel_date' => 1,
ce14544c 1716 'total_amount' => 1,
1717 'accounting_code' => 1,
1718 'payment_instrument' => 1,
1719 'payment_instrument_id' => 1,
1720 'contribution_check_number' => 1,
1721 'non_deductible_amount' => 1,
1722 'fee_amount' => 1,
1723 'net_amount' => 1,
1724 'trxn_id' => 1,
1725 'invoice_id' => 1,
1726 'invoice_number' => 1,
1727 'currency' => 1,
1728 'cancel_reason' => 1,
1729 'receipt_date' => 1,
ce14544c 1730 'is_test' => 1,
1731 'is_pay_later' => 1,
1732 'contribution_status' => 1,
1733 'contribution_recur_id' => 1,
1734 'amount_level' => 1,
1735 'contribution_note' => 1,
1736 'contribution_batch' => 1,
1737 'contribution_campaign_title' => 1,
1738 'contribution_campaign_id' => 1,
ce14544c 1739 'contribution_soft_credit_name' => 1,
1740 'contribution_soft_credit_amount' => 1,
1741 'contribution_soft_credit_type' => 1,
1742 'contribution_soft_credit_contact_id' => 1,
1743 'contribution_soft_credit_contribution_id' => 1,
1744 ];
1745 }
1746
0a3b035f 1747 /**
1748 * Test the column definition when 'all' fields defined.
1749 *
6c93b9a9 1750 * @param int $exportMode
1751 * @param array $expected
1752 * @param array $expectedHeaders
0a3b035f 1753 *
46312f7d 1754 * @throws \CRM_Core_Exception
fce27eeb 1755 * @throws \League\Csv\Exception
1756 *
0a3b035f 1757 * @dataProvider getSqlColumnsOutput
1758 */
6c93b9a9 1759 public function testGetSQLColumnsAndHeaders($exportMode, $expected, $expectedHeaders) {
0a3b035f 1760 $this->ensureComponentIsEnabled($exportMode);
1761 // We need some data so that we can get to the end of the export
1762 // function. Hopefully one day that won't be required to get metadata info out.
1763 // eventually aspire to call $provider->getSQLColumns straight after it
1764 // is intiated.
1765 $this->setupBaseExportData($exportMode);
fce27eeb 1766 $this->doExportTest(['selectAll' => TRUE, 'exportMode' => $exportMode, 'ids' => [1]]);
1767 $this->assertEquals($expected, $this->processor->getSQLColumns());
1768 $this->assertEquals($expectedHeaders, $this->processor->getHeaderRows());
0a3b035f 1769 }
1770
6202c5bb 1771 /**
1772 * Test exported with data entry mis-fire.
1773 *
1774 * Not fatal error if data incomplete.
1775 *
1776 * https://lab.civicrm.org/dev/core/issues/819
ee3aa985 1777 *
1778 * @throws \CRM_Core_Exception
1779 * @throws \League\Csv\Exception
6202c5bb 1780 */
1781 public function testExportIncompleteSubmission() {
1782 $this->setUpContactExportData();
ee3aa985 1783 $this->doExportTest(['fields' => [['contact_type' => 'Individual', 'name' => '']], 'ids' => [$this->contactIDs[1]]]);
6202c5bb 1784 }
1785
5506290d 1786 /**
1787 * Test exported with fields to output specified.
1788 *
1789 * @dataProvider getAllSpecifiableReturnFields
1790 *
1791 * @param int $exportMode
1792 * @param array $selectedFields
1793 * @param array $expected
ee3aa985 1794 *
1795 * @throws \CRM_Core_Exception
1796 * @throws \League\Csv\Exception
5506290d 1797 */
1798 public function testExportSpecifyFields($exportMode, $selectedFields, $expected) {
1799 $this->ensureComponentIsEnabled($exportMode);
1800 $this->setUpContributionExportData();
ee3aa985 1801 $this->doExportTest(['fields' => $selectedFields, 'ids' => [$this->contactIDs[1]], 'exportMode' => $exportMode]);
1802 $this->assertEquals($expected, $this->processor->getSQLColumns());
5506290d 1803 }
1804
c66a5741 1805 /**
1806 * Test export fields when no payment fields to be exported.
1807 */
1808 public function textExportParticipantSpecifyFieldsNoPayment() {
1809 $selectedFields = $this->getAllSpecifiableParticipantReturnFields();
1810 foreach ($selectedFields as $index => $field) {
1811 if (substr($field[1], 0, 22) === 'componentPaymentField_') {
420384a0 1812 unset($selectedFields[$index]);
c66a5741 1813 }
1814 }
1815
1816 $expected = $this->getAllSpecifiableParticipantReturnFields();
1817 foreach ($expected as $index => $field) {
1818 if (substr($index, 0, 22) === 'componentPaymentField_') {
420384a0 1819 unset($expected[$index]);
c66a5741 1820 }
1821 }
1822
1823 list($tableName, $sqlColumns) = $this->doExport($selectedFields, $this->contactIDs[1], CRM_Export_Form_Select::EVENT_EXPORT);
1824 $this->assertEquals($expected, $sqlColumns);
1825 }
39b959db 1826
5506290d 1827 /**
46312f7d 1828 * Get all return fields (@return array
1829 *
1830 * @todo - still being built up.
5506290d 1831 *
5506290d 1832 */
1833 public function getAllSpecifiableReturnFields() {
1834 return [
1835 [
1836 CRM_Export_Form_Select::EVENT_EXPORT,
1837 $this->getAllSpecifiableParticipantReturnFields(),
c66a5741 1838 $this->getAllSpecifiableParticipantReturnColumns(),
5506290d 1839 ],
1840 ];
1841 }
1842
c66a5741 1843 /**
1844 * Get expected return column output for participant mode return all columns.
1845 *
1846 * @return array
1847 */
1848 public function getAllSpecifiableParticipantReturnColumns() {
1849 return [
07b892fc 1850 'participant_campaign_id' => 'participant_campaign_id varchar(16)',
c66a5741 1851 'participant_contact_id' => 'participant_contact_id varchar(16)',
1852 'componentpaymentfield_contribution_status' => 'componentpaymentfield_contribution_status text',
1853 'currency' => 'currency varchar(3)',
1854 'componentpaymentfield_received_date' => 'componentpaymentfield_received_date text',
1855 'default_role_id' => 'default_role_id varchar(16)',
1856 'participant_discount_name' => 'participant_discount_name varchar(16)',
1857 'event_id' => 'event_id varchar(16)',
1858 'event_end_date' => 'event_end_date varchar(32)',
1859 'event_start_date' => 'event_start_date varchar(32)',
1860 'template_title' => 'template_title varchar(255)',
1861 'event_title' => 'event_title varchar(255)',
1862 'participant_fee_amount' => 'participant_fee_amount varchar(32)',
1863 'participant_fee_currency' => 'participant_fee_currency varchar(3)',
1864 'fee_label' => 'fee_label varchar(255)',
1865 'participant_fee_level' => 'participant_fee_level longtext',
1866 'participant_is_pay_later' => 'participant_is_pay_later varchar(16)',
1867 'participant_id' => 'participant_id varchar(16)',
1868 'participant_note' => 'participant_note text',
1869 'participant_role_id' => 'participant_role_id varchar(128)',
1870 'participant_role' => 'participant_role varchar(255)',
1871 'participant_source' => 'participant_source varchar(128)',
1872 'participant_status_id' => 'participant_status_id varchar(16)',
1873 'participant_status' => 'participant_status varchar(255)',
1874 'participant_register_date' => 'participant_register_date varchar(32)',
1875 'participant_registered_by_id' => 'participant_registered_by_id varchar(16)',
1876 'participant_is_test' => 'participant_is_test varchar(16)',
1877 'componentpaymentfield_total_amount' => 'componentpaymentfield_total_amount text',
1878 'componentpaymentfield_transaction_id' => 'componentpaymentfield_transaction_id varchar(255)',
1879 'transferred_to_contact_id' => 'transferred_to_contact_id varchar(16)',
1880 ];
1881 }
1882
5506290d 1883 /**
1884 * @return array
1885 */
1886 public function getAllSpecifiableParticipantReturnFields() {
1887 return [
1888 0 =>
1889 [
1890 0 => 'Participant',
ee3aa985 1891 'name' => '',
5506290d 1892 ],
1893 1 =>
1894 [
1895 0 => 'Participant',
ee3aa985 1896 'name' => 'participant_campaign_id',
5506290d 1897 ],
1898 2 =>
1899 [
1900 0 => 'Participant',
ee3aa985 1901 'name' => 'participant_contact_id',
5506290d 1902 ],
1903 3 =>
1904 [
1905 0 => 'Participant',
ee3aa985 1906 'name' => 'componentPaymentField_contribution_status',
5506290d 1907 ],
1908 4 =>
1909 [
1910 0 => 'Participant',
ee3aa985 1911 'name' => 'currency',
5506290d 1912 ],
1913 5 =>
1914 [
1915 0 => 'Participant',
ee3aa985 1916 'name' => 'componentPaymentField_received_date',
5506290d 1917 ],
1918 6 =>
1919 [
1920 0 => 'Participant',
ee3aa985 1921 'name' => 'default_role_id',
5506290d 1922 ],
1923 7 =>
1924 [
1925 0 => 'Participant',
ee3aa985 1926 'name' => 'participant_discount_name',
5506290d 1927 ],
1928 8 =>
1929 [
1930 0 => 'Participant',
ee3aa985 1931 'name' => 'event_id',
5506290d 1932 ],
1933 9 =>
1934 [
1935 0 => 'Participant',
ee3aa985 1936 'name' => 'event_end_date',
5506290d 1937 ],
1938 10 =>
1939 [
1940 0 => 'Participant',
ee3aa985 1941 'name' => 'event_start_date',
5506290d 1942 ],
1943 11 =>
1944 [
1945 0 => 'Participant',
ee3aa985 1946 'name' => 'template_title',
5506290d 1947 ],
1948 12 =>
1949 [
1950 0 => 'Participant',
ee3aa985 1951 'name' => 'event_title',
5506290d 1952 ],
1953 13 =>
1954 [
1955 0 => 'Participant',
ee3aa985 1956 'name' => 'participant_fee_amount',
5506290d 1957 ],
1958 14 =>
1959 [
1960 0 => 'Participant',
ee3aa985 1961 'name' => 'participant_fee_currency',
5506290d 1962 ],
1963 15 =>
1964 [
1965 0 => 'Participant',
ee3aa985 1966 'name' => 'fee_label',
5506290d 1967 ],
1968 16 =>
1969 [
1970 0 => 'Participant',
ee3aa985 1971 'name' => 'participant_fee_level',
5506290d 1972 ],
1973 17 =>
1974 [
1975 0 => 'Participant',
ee3aa985 1976 'name' => 'participant_is_pay_later',
5506290d 1977 ],
1978 18 =>
1979 [
1980 0 => 'Participant',
ee3aa985 1981 'name' => 'participant_id',
5506290d 1982 ],
1983 19 =>
1984 [
1985 0 => 'Participant',
ee3aa985 1986 'name' => 'participant_note',
5506290d 1987 ],
1988 20 =>
1989 [
1990 0 => 'Participant',
ee3aa985 1991 'name' => 'participant_role_id',
5506290d 1992 ],
1993 21 =>
1994 [
1995 0 => 'Participant',
ee3aa985 1996 'name' => 'participant_role',
5506290d 1997 ],
1998 22 =>
1999 [
2000 0 => 'Participant',
ee3aa985 2001 'name' => 'participant_source',
5506290d 2002 ],
2003 23 =>
2004 [
2005 0 => 'Participant',
ee3aa985 2006 'name' => 'participant_status_id',
5506290d 2007 ],
2008 24 =>
2009 [
2010 0 => 'Participant',
ee3aa985 2011 'name' => 'participant_status',
5506290d 2012 ],
2013 25 =>
2014 [
2015 0 => 'Participant',
ee3aa985 2016 'name' => 'participant_status',
5506290d 2017 ],
2018 26 =>
2019 [
2020 0 => 'Participant',
ee3aa985 2021 'name' => 'participant_register_date',
5506290d 2022 ],
2023 27 =>
2024 [
2025 0 => 'Participant',
ee3aa985 2026 'name' => 'participant_registered_by_id',
5506290d 2027 ],
2028 28 =>
2029 [
2030 0 => 'Participant',
ee3aa985 2031 'name' => 'participant_is_test',
5506290d 2032 ],
2033 29 =>
2034 [
2035 0 => 'Participant',
ee3aa985 2036 'name' => 'componentPaymentField_total_amount',
5506290d 2037 ],
2038 30 =>
2039 [
2040 0 => 'Participant',
ee3aa985 2041 'name' => 'componentPaymentField_transaction_id',
5506290d 2042 ],
2043 31 =>
2044 [
2045 0 => 'Participant',
ee3aa985 2046 'name' => 'transferred_to_contact_id',
5506290d 2047 ],
2048 ];
2049 }
2050
0a3b035f 2051 /**
2052 * @param string $exportMode
2053 */
2054 public function setupBaseExportData($exportMode) {
2055 $this->createLoggedInUser();
2056 if ($exportMode === CRM_Export_Form_Select::CASE_EXPORT) {
2057 $this->setupCaseExportData();
2058 }
2059 if ($exportMode === CRM_Export_Form_Select::CONTRIBUTE_EXPORT) {
2060 $this->setUpContributionExportData();
2061 }
2062 if ($exportMode === CRM_Export_Form_Select::MEMBER_EXPORT) {
2063 $this->setUpMembershipExportData();
2064 }
2065 if ($exportMode === CRM_Export_Form_Select::ACTIVITY_EXPORT) {
2066 $this->setUpActivityExportData();
2067 }
2068 }
2069
2070 /**
2071 * Get comprehensive sql columns output.
2072 *
2073 * @return array
2074 */
2075 public function getSqlColumnsOutput() {
2076 return [
2077 [
2078 'anything that will then be defaulting ton contact',
2079 $this->getBasicSqlColumnDefinition(TRUE),
6c93b9a9 2080 $this->getBasicHeaderDefinition(TRUE),
0a3b035f 2081 ],
2082 [
2083 CRM_Export_Form_Select::ACTIVITY_EXPORT,
2084 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getActivitySqlColumns()),
6c93b9a9 2085 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getActivityHeaderDefinition()),
0a3b035f 2086 ],
2087 [
2088 CRM_Export_Form_Select::CASE_EXPORT,
2089 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getCaseSqlColumns()),
6c93b9a9 2090 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getCaseHeaderDefinition()),
0a3b035f 2091 ],
2092 [
2093 CRM_Export_Form_Select::CONTRIBUTE_EXPORT,
2094 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getContributionSqlColumns()),
6c93b9a9 2095 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getContributeHeaderDefinition()),
0a3b035f 2096 ],
2097 [
2098 CRM_Export_Form_Select::EVENT_EXPORT,
2099 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getParticipantSqlColumns()),
6c93b9a9 2100 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getParticipantHeaderDefinition()),
0a3b035f 2101 ],
2102 [
2103 CRM_Export_Form_Select::MEMBER_EXPORT,
2104 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getMembershipSqlColumns()),
6c93b9a9 2105 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getMemberHeaderDefinition()),
0a3b035f 2106 ],
2107 [
2108 CRM_Export_Form_Select::PLEDGE_EXPORT,
2109 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getPledgeSqlColumns()),
6c93b9a9 2110 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getPledgeHeaderDefinition()),
0a3b035f 2111 ],
2112
2113 ];
2114 }
2115
6c93b9a9 2116 /**
2117 * Get the header definition for exports.
2118 *
2119 * @param bool $isContactExport
2120 *
2121 * @return array
2122 */
2123 protected function getBasicHeaderDefinition($isContactExport) {
2124 $headers = [
39b959db
SL
2125 0 => 'Contact ID',
2126 1 => 'Contact Type',
2127 2 => 'Contact Subtype',
2128 3 => 'Do Not Email',
2129 4 => 'Do Not Phone',
2130 5 => 'Do Not Mail',
2131 6 => 'Do Not Sms',
2132 7 => 'Do Not Trade',
2133 8 => 'No Bulk Emails (User Opt Out)',
2134 9 => 'Legal Identifier',
2135 10 => 'External Identifier',
2136 11 => 'Sort Name',
2137 12 => 'Display Name',
2138 13 => 'Nickname',
2139 14 => 'Legal Name',
2140 15 => 'Image Url',
2141 16 => 'Preferred Communication Method',
2142 17 => 'Preferred Language',
2143 18 => 'Preferred Mail Format',
2144 19 => 'Contact Hash',
2145 20 => 'Contact Source',
2146 21 => 'First Name',
2147 22 => 'Middle Name',
2148 23 => 'Last Name',
2149 24 => 'Individual Prefix',
2150 25 => 'Individual Suffix',
2151 26 => 'Formal Title',
2152 27 => 'Communication Style',
2153 28 => 'Email Greeting ID',
2154 29 => 'Postal Greeting ID',
2155 30 => 'Addressee ID',
2156 31 => 'Job Title',
2157 32 => 'Gender',
2158 33 => 'Birth Date',
2159 34 => 'Deceased',
2160 35 => 'Deceased Date',
2161 36 => 'Household Name',
2162 37 => 'Organization Name',
2163 38 => 'Sic Code',
2164 39 => 'Unique ID (OpenID)',
2165 40 => 'Current Employer ID',
2166 41 => 'Contact is in Trash',
2167 42 => 'Created Date',
2168 43 => 'Modified Date',
2169 44 => 'Addressee',
2170 45 => 'Email Greeting',
2171 46 => 'Postal Greeting',
2172 47 => 'Current Employer',
2173 48 => 'Location Type',
2174 49 => 'Street Address',
2175 50 => 'Street Number',
2176 51 => 'Street Number Suffix',
2177 52 => 'Street Name',
2178 53 => 'Street Unit',
2179 54 => 'Supplemental Address 1',
2180 55 => 'Supplemental Address 2',
2181 56 => 'Supplemental Address 3',
2182 57 => 'City',
2183 58 => 'Postal Code Suffix',
2184 59 => 'Postal Code',
2185 60 => 'Latitude',
2186 61 => 'Longitude',
4fcfc078
SL
2187 62 => 'Is Manually Geocoded',
2188 63 => 'Address Name',
2189 64 => 'Master Address Belongs To',
2190 65 => 'County',
2191 66 => 'State',
2192 67 => 'Country',
2193 68 => 'Phone',
2194 69 => 'Phone Extension',
2195 70 => 'Phone Type',
2196 71 => 'Email',
2197 72 => 'On Hold',
2198 73 => 'Use for Bulk Mail',
2199 74 => 'Signature Text',
2200 75 => 'Signature Html',
2201 76 => 'IM Provider',
2202 77 => 'IM Screen Name',
2203 78 => 'OpenID',
2204 79 => 'World Region',
2205 80 => 'Website',
2206 81 => 'Group(s)',
2207 82 => 'Tag(s)',
2208 83 => 'Note(s)',
39b959db 2209 ];
6c93b9a9 2210 if (!$isContactExport) {
6c93b9a9 2211 unset($headers[81]);
219c47d6 2212 unset($headers[82]);
4fcfc078 2213 unset($headers[83]);
6c93b9a9 2214 }
2215 return $headers;
2216 }
2217
2218 /**
2219 * Get the definition for activity headers.
2220 *
2221 * @return array
2222 */
2223 protected function getActivityHeaderDefinition() {
2224 return [
2225 81 => 'Activity ID',
2226 82 => 'Activity Type',
2227 83 => 'Activity Type ID',
2228 84 => 'Subject',
2229 85 => 'Activity Date',
2230 86 => 'Duration',
2231 87 => 'Location',
2232 88 => 'Details',
2233 89 => 'Activity Status',
2234 90 => 'Activity Priority',
2235 91 => 'Source Contact',
2236 92 => 'source_record_id',
2237 93 => 'Test',
2238 94 => 'Campaign ID',
2239 95 => 'result',
2240 96 => 'Engagement Index',
2241 97 => 'parent_id',
2242 ];
2243 }
2244
2245 /**
2246 * Get the definition for case headers.
2247 *
2248 * @return array
2249 */
2250 protected function getCaseHeaderDefinition() {
2251 return [
2252 81 => 'contact_id',
2253 82 => 'Case ID',
2254 83 => 'case_activity_subject',
2255 84 => 'Case Subject',
2256 85 => 'Case Status',
2257 86 => 'Case Type',
2258 87 => 'Role in Case',
2259 88 => 'Case is in the Trash',
2260 89 => 'case_recent_activity_date',
2261 90 => 'case_recent_activity_type',
2262 91 => 'case_scheduled_activity_date',
2263 92 => 'Case Start Date',
2264 93 => 'Case End Date',
2265 94 => 'case_source_contact_id',
2266 95 => 'case_activity_status',
2267 96 => 'case_activity_duration',
2268 97 => 'case_activity_medium_id',
2269 98 => 'case_activity_details',
2270 99 => 'case_activity_is_auto',
2271 ];
2272 }
2273
2274 /**
2275 * Get the definition for contribute headers.
2276 *
2277 * @return array
2278 */
2279 protected function getContributeHeaderDefinition() {
2280 return [
2281 81 => 'Financial Type',
2282 82 => 'Contribution Source',
2283 83 => 'Date Received',
2284 84 => 'Thank-you Date',
6e7cc0f5 2285 85 => 'Cancelled / Refunded Date',
6c93b9a9 2286 86 => 'Total Amount',
2287 87 => 'Accounting Code',
a0090e6b 2288 88 => 'Payment Methods',
6c93b9a9 2289 89 => 'Payment Method ID',
2290 90 => 'Check Number',
2291 91 => 'Non-deductible Amount',
2292 92 => 'Fee Amount',
2293 93 => 'Net Amount',
2294 94 => 'Transaction ID',
2295 95 => 'Invoice Reference',
2296 96 => 'Invoice Number',
2297 97 => 'Currency',
927898c5 2298 98 => 'Cancellation / Refund Reason',
6c93b9a9 2299 99 => 'Receipt Date',
4fcfc078
SL
2300 100 => 'Test',
2301 101 => 'Is Pay Later',
2302 102 => 'Contribution Status',
2303 103 => 'Recurring Contribution ID',
2304 104 => 'Amount Label',
2305 105 => 'Contribution Note',
2306 106 => 'Batch Name',
2307 107 => 'Campaign Title',
2308 108 => 'Campaign ID',
2309 109 => 'Soft Credit For',
2310 110 => 'Soft Credit Amount',
2311 111 => 'Soft Credit Type',
2312 112 => 'Soft Credit For Contact ID',
2313 113 => 'Soft Credit For Contribution ID',
6c93b9a9 2314 ];
2315 }
2316
2317 /**
2318 * Get the definition for event headers.
2319 *
2320 * @return array
2321 */
2322 protected function getParticipantHeaderDefinition() {
2323 return [
2324 81 => 'Event',
2325 82 => 'Event Title',
2326 83 => 'Event Start Date',
2327 84 => 'Event End Date',
2328 85 => 'Event Type',
2329 86 => 'Participant ID',
2330 87 => 'Participant Status',
2331 88 => 'Participant Status Id',
2332 89 => 'Participant Role',
2333 90 => 'Participant Role Id',
2334 91 => 'Participant Note',
2335 92 => 'Register date',
2336 93 => 'Participant Source',
2337 94 => 'Fee level',
2338 95 => 'Test',
2339 96 => 'Is Pay Later',
2340 97 => 'Fee Amount',
2341 98 => 'Discount Name',
2342 99 => 'Fee Currency',
2343 100 => 'Registered By ID',
2344 101 => 'Campaign ID',
2345 ];
2346 }
2347
2348 /**
2349 * Get the definition for member headers.
2350 *
2351 * @return array
2352 */
2353 protected function getMemberHeaderDefinition() {
2354 return [
2355 81 => 'Membership Type',
2356 82 => 'Test',
2357 83 => 'Is Pay Later',
2358 84 => 'Member Since',
2359 85 => 'Membership Start Date',
2360 86 => 'Membership Expiration Date',
2361 87 => 'Source',
2362 88 => 'Membership Status',
2363 89 => 'Membership ID',
2364 90 => 'Primary Member ID',
8f67d99a 2365 91 => 'Max Related',
2366 92 => 'Membership Recurring Contribution',
6c93b9a9 2367 93 => 'Campaign ID',
8f67d99a 2368 94 => 'Status Override',
6c93b9a9 2369 ];
2370 }
2371
2372 /**
2373 * Get the definition for pledge headers.
2374 *
2375 * @return array
2376 */
2377 protected function getPledgeHeaderDefinition() {
2378 return [
2379 81 => 'Pledge ID',
2380 82 => 'Total Pledged',
2381 83 => 'Total Paid',
2382 84 => 'Pledge Made',
2383 85 => 'pledge_start_date',
2384 86 => 'Next Payment Date',
2385 87 => 'Next Payment Amount',
2386 88 => 'Pledge Status',
2387 89 => 'Test',
2388 90 => 'Pledge Contribution Page Id',
2389 91 => 'pledge_financial_type',
2390 92 => 'Pledge Frequency Interval',
2391 93 => 'Pledge Frequency Unit',
2392 94 => 'pledge_currency',
2393 95 => 'Campaign ID',
2394 96 => 'Balance Amount',
2395 97 => 'Payment ID',
2396 98 => 'Scheduled Amount',
2397 99 => 'Scheduled Date',
2398 100 => 'Paid Amount',
2399 101 => 'Paid Date',
2400 102 => 'Last Reminder',
2401 103 => 'Reminders Sent',
2402 104 => 'Pledge Payment Status',
2403 ];
2404 }
2405
0a3b035f 2406 /**
2407 * Get the column definition for exports.
2408 *
2409 * @param bool $isContactExport
2410 *
2411 * @return array
2412 */
2413 protected function getBasicSqlColumnDefinition($isContactExport) {
2414 $columns = [
2415 'civicrm_primary_id' => 'civicrm_primary_id varchar(16)',
2416 'contact_type' => 'contact_type varchar(64)',
2417 'contact_sub_type' => 'contact_sub_type varchar(255)',
2418 'do_not_email' => 'do_not_email varchar(16)',
2419 'do_not_phone' => 'do_not_phone varchar(16)',
2420 'do_not_mail' => 'do_not_mail varchar(16)',
2421 'do_not_sms' => 'do_not_sms varchar(16)',
2422 'do_not_trade' => 'do_not_trade varchar(16)',
2423 'is_opt_out' => 'is_opt_out varchar(16)',
2424 'legal_identifier' => 'legal_identifier varchar(32)',
2425 'external_identifier' => 'external_identifier varchar(64)',
2426 'sort_name' => 'sort_name varchar(128)',
2427 'display_name' => 'display_name varchar(128)',
2428 'nick_name' => 'nick_name varchar(128)',
2429 'legal_name' => 'legal_name varchar(128)',
2430 'image_url' => 'image_url longtext',
2431 'preferred_communication_method' => 'preferred_communication_method varchar(255)',
2432 'preferred_language' => 'preferred_language varchar(5)',
2433 'preferred_mail_format' => 'preferred_mail_format varchar(8)',
2434 'hash' => 'hash varchar(32)',
2435 'contact_source' => 'contact_source varchar(255)',
2436 'first_name' => 'first_name varchar(64)',
2437 'middle_name' => 'middle_name varchar(64)',
2438 'last_name' => 'last_name varchar(64)',
2439 'prefix_id' => 'prefix_id varchar(255)',
2440 'suffix_id' => 'suffix_id varchar(255)',
2441 'formal_title' => 'formal_title varchar(64)',
714ab070 2442 'communication_style_id' => 'communication_style_id varchar(255)',
0a3b035f 2443 'email_greeting_id' => 'email_greeting_id varchar(16)',
2444 'postal_greeting_id' => 'postal_greeting_id varchar(16)',
2445 'addressee_id' => 'addressee_id varchar(16)',
2446 'job_title' => 'job_title varchar(255)',
714ab070 2447 'gender_id' => 'gender_id varchar(255)',
0a3b035f 2448 'birth_date' => 'birth_date varchar(32)',
2449 'is_deceased' => 'is_deceased varchar(16)',
2450 'deceased_date' => 'deceased_date varchar(32)',
2451 'household_name' => 'household_name varchar(128)',
2452 'organization_name' => 'organization_name varchar(128)',
2453 'sic_code' => 'sic_code varchar(8)',
2454 'user_unique_id' => 'user_unique_id varchar(255)',
2455 'current_employer_id' => 'current_employer_id varchar(16)',
2456 'contact_is_deleted' => 'contact_is_deleted varchar(16)',
2457 'created_date' => 'created_date varchar(32)',
2458 'modified_date' => 'modified_date varchar(32)',
2459 'addressee' => 'addressee varchar(255)',
2460 'email_greeting' => 'email_greeting varchar(255)',
2461 'postal_greeting' => 'postal_greeting varchar(255)',
2462 'current_employer' => 'current_employer varchar(128)',
2463 'location_type' => 'location_type text',
2464 'street_address' => 'street_address varchar(96)',
2465 'street_number' => 'street_number varchar(16)',
2466 'street_number_suffix' => 'street_number_suffix varchar(8)',
2467 'street_name' => 'street_name varchar(64)',
2468 'street_unit' => 'street_unit varchar(16)',
2469 'supplemental_address_1' => 'supplemental_address_1 varchar(96)',
2470 'supplemental_address_2' => 'supplemental_address_2 varchar(96)',
2471 'supplemental_address_3' => 'supplemental_address_3 varchar(96)',
2472 'city' => 'city varchar(64)',
2473 'postal_code_suffix' => 'postal_code_suffix varchar(12)',
2474 'postal_code' => 'postal_code varchar(64)',
2475 'geo_code_1' => 'geo_code_1 varchar(32)',
2476 'geo_code_2' => 'geo_code_2 varchar(32)',
4fcfc078 2477 'manual_geo_code' => 'manual_geo_code varchar(16)',
0a3b035f 2478 'address_name' => 'address_name varchar(255)',
2479 'master_id' => 'master_id varchar(128)',
2480 'county' => 'county varchar(64)',
2481 'state_province' => 'state_province varchar(64)',
2482 'country' => 'country varchar(64)',
2483 'phone' => 'phone varchar(32)',
2484 'phone_ext' => 'phone_ext varchar(16)',
219c47d6 2485 'phone_type_id' => 'phone_type_id varchar(16)',
0a3b035f 2486 'email' => 'email varchar(254)',
2487 'on_hold' => 'on_hold varchar(16)',
2488 'is_bulkmail' => 'is_bulkmail varchar(16)',
2489 'signature_text' => 'signature_text longtext',
2490 'signature_html' => 'signature_html longtext',
2491 'im_provider' => 'im_provider text',
5ebd7d09 2492 'im_screen_name' => 'im_screen_name varchar(64)',
0a3b035f 2493 'openid' => 'openid varchar(255)',
2494 'world_region' => 'world_region varchar(128)',
2495 'url' => 'url varchar(128)',
2496 'groups' => 'groups text',
2497 'tags' => 'tags text',
2498 'notes' => 'notes text',
0a3b035f 2499 ];
2500 if (!$isContactExport) {
2501 unset($columns['groups']);
2502 unset($columns['tags']);
2503 unset($columns['notes']);
2504 }
2505 return $columns;
2506 }
2507
2508 /**
2509 * Get Case SQL columns.
2510 *
2511 * @return array
2512 */
2513 protected function getCaseSqlColumns() {
2514 return [
2515 'case_start_date' => 'case_start_date varchar(32)',
2516 'case_end_date' => 'case_end_date varchar(32)',
2517 'case_subject' => 'case_subject varchar(128)',
2518 'case_source_contact_id' => 'case_source_contact_id varchar(255)',
2519 'case_activity_status' => 'case_activity_status text',
2520 'case_activity_duration' => 'case_activity_duration text',
2521 'case_activity_medium_id' => 'case_activity_medium_id varchar(255)',
2522 'case_activity_details' => 'case_activity_details text',
2523 'case_activity_is_auto' => 'case_activity_is_auto text',
2524 'contact_id' => 'contact_id varchar(255)',
2525 'case_id' => 'case_id varchar(16)',
2526 'case_activity_subject' => 'case_activity_subject text',
2527 'case_status' => 'case_status text',
2528 'case_type' => 'case_type text',
2529 'case_role' => 'case_role text',
2530 'case_deleted' => 'case_deleted varchar(16)',
2531 'case_recent_activity_date' => 'case_recent_activity_date text',
2532 'case_recent_activity_type' => 'case_recent_activity_type text',
2533 'case_scheduled_activity_date' => 'case_scheduled_activity_date text',
2534 ];
2535 }
2536
2537 /**
2538 * Get activity sql columns.
2539 *
2540 * @return array
2541 */
2542 protected function getActivitySqlColumns() {
2543 return [
2544 'activity_id' => 'activity_id varchar(16)',
2545 'activity_type' => 'activity_type varchar(255)',
2546 'activity_type_id' => 'activity_type_id varchar(16)',
2547 'activity_subject' => 'activity_subject varchar(255)',
2548 'activity_date_time' => 'activity_date_time varchar(32)',
2549 'activity_duration' => 'activity_duration varchar(16)',
2550 'activity_location' => 'activity_location varchar(255)',
2551 'activity_details' => 'activity_details longtext',
2552 'activity_status' => 'activity_status varchar(255)',
2553 'activity_priority' => 'activity_priority varchar(255)',
2554 'source_contact' => 'source_contact varchar(255)',
2555 'source_record_id' => 'source_record_id varchar(255)',
2556 'activity_is_test' => 'activity_is_test varchar(16)',
07b892fc 2557 'activity_campaign_id' => 'activity_campaign_id varchar(16)',
0a3b035f 2558 'result' => 'result text',
2559 'activity_engagement_level' => 'activity_engagement_level varchar(16)',
2560 'parent_id' => 'parent_id varchar(255)',
2561 ];
2562 }
2563
2564 /**
2565 * Get participant sql columns.
2566 *
2567 * @return array
2568 */
2569 protected function getParticipantSqlColumns() {
2570 return [
2571 'event_id' => 'event_id varchar(16)',
2572 'event_title' => 'event_title varchar(255)',
2573 'event_start_date' => 'event_start_date varchar(32)',
2574 'event_end_date' => 'event_end_date varchar(32)',
2575 'event_type' => 'event_type varchar(255)',
2576 'participant_id' => 'participant_id varchar(16)',
2577 'participant_status' => 'participant_status varchar(255)',
2578 'participant_status_id' => 'participant_status_id varchar(16)',
2579 'participant_role' => 'participant_role varchar(255)',
2580 'participant_role_id' => 'participant_role_id varchar(128)',
2581 'participant_note' => 'participant_note text',
2582 'participant_register_date' => 'participant_register_date varchar(32)',
2583 'participant_source' => 'participant_source varchar(128)',
2584 'participant_fee_level' => 'participant_fee_level longtext',
2585 'participant_is_test' => 'participant_is_test varchar(16)',
2586 'participant_is_pay_later' => 'participant_is_pay_later varchar(16)',
2587 'participant_fee_amount' => 'participant_fee_amount varchar(32)',
2588 'participant_discount_name' => 'participant_discount_name varchar(16)',
2589 'participant_fee_currency' => 'participant_fee_currency varchar(3)',
2590 'participant_registered_by_id' => 'participant_registered_by_id varchar(16)',
07b892fc 2591 'participant_campaign_id' => 'participant_campaign_id varchar(16)',
0a3b035f 2592 ];
2593 }
2594
2595 /**
2596 * Get contribution sql columns.
2597 *
2598 * @return array
2599 */
2600 public function getContributionSqlColumns() {
2601 return [
2602 'civicrm_primary_id' => 'civicrm_primary_id varchar(16)',
2603 'contact_type' => 'contact_type varchar(64)',
2604 'contact_sub_type' => 'contact_sub_type varchar(255)',
2605 'do_not_email' => 'do_not_email varchar(16)',
2606 'do_not_phone' => 'do_not_phone varchar(16)',
2607 'do_not_mail' => 'do_not_mail varchar(16)',
2608 'do_not_sms' => 'do_not_sms varchar(16)',
2609 'do_not_trade' => 'do_not_trade varchar(16)',
2610 'is_opt_out' => 'is_opt_out varchar(16)',
2611 'legal_identifier' => 'legal_identifier varchar(32)',
2612 'external_identifier' => 'external_identifier varchar(64)',
2613 'sort_name' => 'sort_name varchar(128)',
2614 'display_name' => 'display_name varchar(128)',
2615 'nick_name' => 'nick_name varchar(128)',
2616 'legal_name' => 'legal_name varchar(128)',
2617 'image_url' => 'image_url longtext',
2618 'preferred_communication_method' => 'preferred_communication_method varchar(255)',
2619 'preferred_language' => 'preferred_language varchar(5)',
2620 'preferred_mail_format' => 'preferred_mail_format varchar(8)',
2621 'hash' => 'hash varchar(32)',
2622 'contact_source' => 'contact_source varchar(255)',
2623 'first_name' => 'first_name varchar(64)',
2624 'middle_name' => 'middle_name varchar(64)',
2625 'last_name' => 'last_name varchar(64)',
2626 'prefix_id' => 'prefix_id varchar(255)',
2627 'suffix_id' => 'suffix_id varchar(255)',
2628 'formal_title' => 'formal_title varchar(64)',
714ab070 2629 'communication_style_id' => 'communication_style_id varchar(255)',
0a3b035f 2630 'email_greeting_id' => 'email_greeting_id varchar(16)',
2631 'postal_greeting_id' => 'postal_greeting_id varchar(16)',
2632 'addressee_id' => 'addressee_id varchar(16)',
2633 'job_title' => 'job_title varchar(255)',
714ab070 2634 'gender_id' => 'gender_id varchar(255)',
0a3b035f 2635 'birth_date' => 'birth_date varchar(32)',
2636 'is_deceased' => 'is_deceased varchar(16)',
2637 'deceased_date' => 'deceased_date varchar(32)',
2638 'household_name' => 'household_name varchar(128)',
2639 'organization_name' => 'organization_name varchar(128)',
2640 'sic_code' => 'sic_code varchar(8)',
2641 'user_unique_id' => 'user_unique_id varchar(255)',
2642 'current_employer_id' => 'current_employer_id varchar(16)',
2643 'contact_is_deleted' => 'contact_is_deleted varchar(16)',
2644 'created_date' => 'created_date varchar(32)',
2645 'modified_date' => 'modified_date varchar(32)',
2646 'addressee' => 'addressee varchar(255)',
2647 'email_greeting' => 'email_greeting varchar(255)',
2648 'postal_greeting' => 'postal_greeting varchar(255)',
2649 'current_employer' => 'current_employer varchar(128)',
2650 'location_type' => 'location_type text',
2651 'street_address' => 'street_address varchar(96)',
2652 'street_number' => 'street_number varchar(16)',
2653 'street_number_suffix' => 'street_number_suffix varchar(8)',
2654 'street_name' => 'street_name varchar(64)',
2655 'street_unit' => 'street_unit varchar(16)',
2656 'supplemental_address_1' => 'supplemental_address_1 varchar(96)',
2657 'supplemental_address_2' => 'supplemental_address_2 varchar(96)',
2658 'supplemental_address_3' => 'supplemental_address_3 varchar(96)',
2659 'city' => 'city varchar(64)',
2660 'postal_code_suffix' => 'postal_code_suffix varchar(12)',
2661 'postal_code' => 'postal_code varchar(64)',
2662 'geo_code_1' => 'geo_code_1 varchar(32)',
2663 'geo_code_2' => 'geo_code_2 varchar(32)',
2664 'address_name' => 'address_name varchar(255)',
2665 'master_id' => 'master_id varchar(128)',
2666 'county' => 'county varchar(64)',
2667 'state_province' => 'state_province varchar(64)',
2668 'country' => 'country varchar(64)',
2669 'phone' => 'phone varchar(32)',
2670 'phone_ext' => 'phone_ext varchar(16)',
2671 'email' => 'email varchar(254)',
2672 'on_hold' => 'on_hold varchar(16)',
2673 'is_bulkmail' => 'is_bulkmail varchar(16)',
2674 'signature_text' => 'signature_text longtext',
2675 'signature_html' => 'signature_html longtext',
2676 'im_provider' => 'im_provider text',
5ebd7d09 2677 'im_screen_name' => 'im_screen_name varchar(64)',
0a3b035f 2678 'openid' => 'openid varchar(255)',
2679 'world_region' => 'world_region varchar(128)',
2680 'url' => 'url varchar(128)',
219c47d6 2681 'phone_type_id' => 'phone_type_id varchar(16)',
124f3c1b 2682 'financial_type' => 'financial_type varchar(255)',
0a3b035f 2683 'contribution_source' => 'contribution_source varchar(255)',
2684 'receive_date' => 'receive_date varchar(32)',
2685 'thankyou_date' => 'thankyou_date varchar(32)',
6e7cc0f5 2686 'contribution_cancel_date' => 'contribution_cancel_date varchar(32)',
0a3b035f 2687 'total_amount' => 'total_amount varchar(32)',
2688 'accounting_code' => 'accounting_code varchar(64)',
a0090e6b 2689 'payment_instrument' => 'payment_instrument varchar(255)',
0a3b035f 2690 'payment_instrument_id' => 'payment_instrument_id varchar(16)',
2691 'contribution_check_number' => 'contribution_check_number varchar(255)',
2692 'non_deductible_amount' => 'non_deductible_amount varchar(32)',
2693 'fee_amount' => 'fee_amount varchar(32)',
2694 'net_amount' => 'net_amount varchar(32)',
2695 'trxn_id' => 'trxn_id varchar(255)',
2696 'invoice_id' => 'invoice_id varchar(255)',
2697 'invoice_number' => 'invoice_number varchar(255)',
2698 'currency' => 'currency varchar(3)',
2699 'cancel_reason' => 'cancel_reason longtext',
2700 'receipt_date' => 'receipt_date varchar(32)',
0a3b035f 2701 'is_test' => 'is_test varchar(16)',
2702 'is_pay_later' => 'is_pay_later varchar(16)',
a0090e6b 2703 'contribution_status' => 'contribution_status varchar(255)',
0a3b035f 2704 'contribution_recur_id' => 'contribution_recur_id varchar(16)',
2705 'amount_level' => 'amount_level longtext',
2706 'contribution_note' => 'contribution_note text',
2707 'contribution_batch' => 'contribution_batch text',
2708 'contribution_campaign_title' => 'contribution_campaign_title varchar(255)',
07b892fc 2709 'contribution_campaign_id' => 'contribution_campaign_id varchar(16)',
0a3b035f 2710 'contribution_soft_credit_name' => 'contribution_soft_credit_name varchar(255)',
2711 'contribution_soft_credit_amount' => 'contribution_soft_credit_amount varchar(255)',
2712 'contribution_soft_credit_type' => 'contribution_soft_credit_type varchar(255)',
2713 'contribution_soft_credit_contact_id' => 'contribution_soft_credit_contact_id varchar(255)',
2714 'contribution_soft_credit_contribution_id' => 'contribution_soft_credit_contribution_id varchar(255)',
2715 ];
2716 }
2717
2718 /**
2719 * Get pledge sql columns.
2720 *
2721 * @return array
2722 */
2723 public function getPledgeSqlColumns() {
2724 return [
2725 'pledge_id' => 'pledge_id varchar(16)',
2726 'pledge_amount' => 'pledge_amount varchar(32)',
2727 'pledge_total_paid' => 'pledge_total_paid text',
2728 'pledge_create_date' => 'pledge_create_date varchar(32)',
2729 'pledge_start_date' => 'pledge_start_date text',
2730 'pledge_next_pay_date' => 'pledge_next_pay_date text',
2731 'pledge_next_pay_amount' => 'pledge_next_pay_amount text',
2732 'pledge_status' => 'pledge_status varchar(255)',
2733 'pledge_is_test' => 'pledge_is_test varchar(16)',
2734 'pledge_contribution_page_id' => 'pledge_contribution_page_id varchar(255)',
2735 'pledge_financial_type' => 'pledge_financial_type text',
2736 'pledge_frequency_interval' => 'pledge_frequency_interval varchar(255)',
2737 'pledge_frequency_unit' => 'pledge_frequency_unit varchar(255)',
2738 'pledge_currency' => 'pledge_currency text',
07b892fc 2739 'pledge_campaign_id' => 'pledge_campaign_id varchar(16)',
0a3b035f 2740 'pledge_balance_amount' => 'pledge_balance_amount text',
2741 'pledge_payment_id' => 'pledge_payment_id varchar(16)',
2742 'pledge_payment_scheduled_amount' => 'pledge_payment_scheduled_amount varchar(32)',
2743 'pledge_payment_scheduled_date' => 'pledge_payment_scheduled_date varchar(32)',
2744 'pledge_payment_paid_amount' => 'pledge_payment_paid_amount text',
2745 'pledge_payment_paid_date' => 'pledge_payment_paid_date text',
2746 'pledge_payment_reminder_date' => 'pledge_payment_reminder_date varchar(32)',
2747 'pledge_payment_reminder_count' => 'pledge_payment_reminder_count varchar(16)',
2748 'pledge_payment_status' => 'pledge_payment_status varchar(255)',
2749 ];
2750 }
2751
2752 /**
2753 * Get membership sql columns.
2754 *
2755 * @return array
2756 */
2757 public function getMembershipSqlColumns() {
2758 return [
2759 'membership_type' => 'membership_type varchar(128)',
2760 'member_is_test' => 'member_is_test varchar(16)',
2761 'member_is_pay_later' => 'member_is_pay_later varchar(16)',
2762 'join_date' => 'join_date varchar(32)',
2763 'membership_start_date' => 'membership_start_date varchar(32)',
2764 'membership_end_date' => 'membership_end_date varchar(32)',
2765 'membership_source' => 'membership_source varchar(128)',
2766 'membership_status' => 'membership_status varchar(255)',
2767 'membership_id' => 'membership_id varchar(16)',
2768 'owner_membership_id' => 'owner_membership_id varchar(16)',
8f67d99a 2769 'max_related' => 'max_related varchar(16)',
2770 'membership_recur_id' => 'membership_recur_id varchar(16)',
07b892fc 2771 'member_campaign_id' => 'member_campaign_id varchar(16)',
8f67d99a 2772 'member_is_override' => 'member_is_override varchar(16)',
0a3b035f 2773 ];
2774 }
2775
a16a432a 2776 /**
2777 * Change our location types so we have some edge cases in the mix.
2778 *
2779 * - a space in the name
2780 * - name differs from label
2781 * - non-anglo char in the label (not valid in the name).
2782 */
2783 protected function diversifyLocationTypes() {
2784 $this->locationTypes['Main'] = $this->callAPISuccess('Location_type', 'get', [
2785 'name' => 'Main',
2786 'return' => 'id',
2787 'api.LocationType.Create' => ['display_name' => 'Méin'],
2788 ]);
2789 $this->locationTypes['Whare Kai'] = $this->callAPISuccess('Location_type', 'create', [
2790 'name' => 'Whare Kai',
2791 'display_name' => 'Whare Kai',
2792 ]);
2793 }
2794
12a6fdef 2795 /**
2796 * Test export components.
2797 *
2798 * Tests the exportComponents function with the provided parameters.
2799 *
2800 * This exportComponents will export a csv but it will also throw a prematureExitException
2801 * which we catch & grab the processor from.
2802 *
2803 * $this->processor is set to the export processor.
2804 *
2805 * @param $params
2806 *
2807 * @throws \CRM_Core_Exception
c746d2b2 2808 * @throws \League\Csv\Exception
12a6fdef 2809 */
2810 protected function doExportTest($params) {
2811 $this->startCapturingOutput();
2812 try {
0b60a345 2813 $exportMode = CRM_Utils_Array::value('exportMode', $params, CRM_Export_Form_Select::CONTACT_EXPORT);
2814 $ids = CRM_Utils_Array::value('ids', $params, ($exportMode === CRM_Export_Form_Select::CONTACT_EXPORT ? $this->contactIDs : []));
2815 $defaultClause = (empty($ids) ? NULL : "contact_a.id IN (" . implode(',', $ids) . ")");
12a6fdef 2816 CRM_Export_BAO_Export::exportComponents(
2817 CRM_Utils_Array::value('selectAll', $params, (empty($params['fields']))),
0b60a345 2818 $ids,
12a6fdef 2819 CRM_Utils_Array::value('params', $params, []),
2820 CRM_Utils_Array::value('order', $params),
e15ec147 2821 CRM_Utils_Array::value('fields', $params, []),
12a6fdef 2822 CRM_Utils_Array::value('moreReturnProperties', $params),
0b60a345 2823 $exportMode,
45cee669 2824 CRM_Utils_Array::value('componentClause', $params, $defaultClause),
12a6fdef 2825 CRM_Utils_Array::value('componentTable', $params),
2826 CRM_Utils_Array::value('mergeSameAddress', $params, FALSE),
0b60a345 2827 CRM_Utils_Array::value('mergeSameHousehold', $params, FALSE),
2828 CRM_Utils_Array::value('exportParams', $params, [])
12a6fdef 2829 );
2830 }
2831 catch (CRM_Core_Exception_PrematureExitException $e) {
2832 $this->processor = $e->errorData['processor'];
c746d2b2 2833 $this->csv = $this->captureOutputToCSV();
12a6fdef 2834 return;
2835 }
2836 $this->fail('We expected a premature exit exception');
2837 }
2838
c2aec6ad 2839 /**
2840 * Assert that the received array matches the expected, ignoring time sensitive fields.
2841 *
2842 * @param array $expected
2843 * @param array $row
2844 */
2845 protected function assertExpectedOutput(array $expected, array $row) {
2846 $variableFields = ['Created Date', 'Modified Date', 'Contact Hash'];
2847 foreach ($expected as $key => $value) {
2848 if (in_array($key, $variableFields)) {
2849 $this->assertTrue(!empty($row[$key]));
2850 }
2851 else {
2852 $this->assertEquals($value, $row[$key]);
2853 }
2854 }
2855 }
2856
978f5005 2857 /**
2858 * Test get preview function on export processor.
2859 *
2860 * @throws \CRM_Core_Exception
2861 */
2862 public function testExportGetPreview() {
2863 $this->setUpContactExportData();
2864 $fields = [
2865 ['Individual', 'first_name'],
2866 ['Individual', 'last_name'],
2867 ['Individual', 'street_address', 1],
2868 ['Individual', 'city', 1],
2869 ['Individual', 'country', 1],
2870 ['Individual', 'email', 1],
2871 ];
2872 $mappedFields = [];
2873 foreach ($fields as $field) {
2874 $mappedFields[] = CRM_Core_BAO_Mapping::getMappingParams([], $field);
2875 }
2876 $processor = new CRM_Export_BAO_ExportProcessor(FALSE, $mappedFields,
2877 'AND');
2878 $processor->setComponentClause('contact_a.id IN (' . implode(',', $this->contactIDs) . ')');
2879 $result = $processor->getPreview(2);
2880 $this->assertEquals([
2881 [
2882 'first_name' => 'Anthony',
2883 'last_name' => 'Anderson',
2884 'Home-street_address' => 'Ambachtstraat 23',
2885 'Home-city' => 'Brummen',
2886 'Home-country' => 'Netherlands',
2887 'Home-email' => 'home@example.com',
2888 ],
2889 [
2890 'first_name' => 'Anthony',
2891 'last_name' => 'Anderson',
2892 'Home-street_address' => '',
2893 'Home-city' => '',
2894 'Home-country' => '',
2895 'Home-email' => 'anthony_anderson@civicrm.org',
2896 ],
2897 ], $result);
2898 }
2899
0b60a345 2900 /**
2901 * Set up contacts which will be merged with the same address option.
2902 *
2903 * @throws \CRM_Core_Exception
2904 */
2905 protected function setUpContactSameAddressExportData() {
2906 $this->setUpContactExportData();
2907 $this->contactIDs[] = $contact3 = $this->individualCreate(['first_name' => 'Sarah', 'last_name' => 'Smith', 'prefix_id' => 'Dr.']);
2908 // Create address for contact A.
2909 $params = [
2910 'contact_id' => $contact3,
2911 'location_type_id' => 'Home',
2912 'street_address' => 'Ambachtstraat 23',
2913 'postal_code' => '6971 BN',
2914 'country_id' => '1152',
2915 'city' => 'Brummen',
2916 'is_primary' => 1,
2917 ];
2918 $this->callAPISuccess('address', 'create', $params);
2919 }
2920
ef51caa8 2921}