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