Merge pull request #15330 from mattwire/paymentprocessor_testmodelivemode
[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',
91786f44 306 'Contribution Status' => 'Pending Label**',
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();
285fa729 649 $this->assertCount(1, $this->csv);
07b892fc 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([
f61dd144
SL
989 'contact_id' => '`contact_id` varchar(16)',
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
15d60ff5 1047 /**
1048 * Test merging same address when specifying fields.
1049 *
1050 * @throws \CRM_Core_Exception
1051 * @throws \League\Csv\Exception
1052 */
1053 public function testMergeSameAddressSpecifyFields() {
1054 $this->setUpContactSameAddressExportData();
1055 $this->doExportTest(['mergeSameAddress' => TRUE, 'fields' => [['contact_type' => 'Individual', 'name' => 'master_id', 'location_type_id' => 1]]]);
1056 }
1057
c2aec6ad 1058 /**
1059 * Test the merge same address option.
1060 *
1061 * @throws \CRM_Core_Exception
1062 * @throws \League\Csv\Exception
1063 */
1064 public function testMergeSameAddress() {
0b60a345 1065 $this->setUpContactSameAddressExportData();
1066 $this->doExportTest(['mergeSameAddress' => TRUE]);
c2aec6ad 1067 // ie 2 merged, one extra.
1068 $this->assertCount(2, $this->csv);
1069 $expected = [
1070 'Contact ID' => $this->contactIDs[0],
1071 'Contact Type' => 'Individual',
1072 'Contact Subtype' => '',
1073 'Do Not Email' => '',
1074 'Do Not Phone' => '',
1075 'Do Not Mail' => '',
1076 'Do Not Sms' => '',
1077 'Do Not Trade' => '',
1078 'No Bulk Emails (User Opt Out)' => '',
1079 'Legal Identifier' => '',
1080 'External Identifier' => '',
1081 'Sort Name' => 'Anderson, Anthony',
1082 'Display Name' => 'Mr. Anthony Anderson II',
1083 'Nickname' => '',
1084 'Legal Name' => '',
1085 'Image Url' => '',
1086 'Preferred Communication Method' => '',
1087 'Preferred Language' => 'en_US',
1088 'Preferred Mail Format' => 'Both',
1089 'Contact Hash' => 'e9bd0913cc05cc5aeae69ba04ee3be84',
1090 'Contact Source' => '',
1091 'First Name' => 'Anthony',
1092 'Middle Name' => 'J.',
1093 'Last Name' => 'Anderson',
1094 'Individual Prefix' => 'Mr.',
1095 'Individual Suffix' => 'II',
1096 'Formal Title' => '',
1097 'Communication Style' => 'Formal',
1098 'Email Greeting ID' => '1',
1099 'Postal Greeting ID' => '1',
1100 'Addressee ID' => '1',
1101 'Job Title' => '',
1102 'Gender' => 'Female',
1103 'Birth Date' => '',
1104 'Deceased' => '',
1105 'Deceased Date' => '',
1106 'Household Name' => '',
1107 'Organization Name' => '',
1108 'Sic Code' => '',
1109 'Unique ID (OpenID)' => '',
1110 'Current Employer ID' => '',
1111 'Contact is in Trash' => '',
1112 'Created Date' => '2019-07-11 10:28:15',
1113 'Modified Date' => '2019-07-11 10:28:15',
1114 'Addressee' => 'Mr. Anthony J. Anderson II, Dr. Sarah J. Smith II',
1115 'Email Greeting' => 'Dear Anthony, Sarah',
1116 'Postal Greeting' => 'Dear Anthony, Sarah',
1117 'Current Employer' => '',
1118 'Location Type' => 'Home',
1119 'Street Address' => 'Ambachtstraat 23',
1120 'Street Number' => '',
1121 'Street Number Suffix' => '',
1122 'Street Name' => '',
1123 'Street Unit' => '',
1124 'Supplemental Address 1' => '',
1125 'Supplemental Address 2' => '',
1126 'Supplemental Address 3' => '',
1127 'City' => 'Brummen',
1128 'Postal Code Suffix' => '',
1129 'Postal Code' => '6971 BN',
1130 'Latitude' => '',
1131 'Longitude' => '',
1132 'Address Name' => '',
1133 'Master Address Belongs To' => '',
1134 'County' => '',
1135 'State' => '',
1136 'Country' => 'Netherlands',
1137 'Phone' => '',
1138 'Phone Extension' => '',
1139 'Phone Type' => '',
1140 'Email' => 'home@example.com',
1141 'On Hold' => '',
1142 'Use for Bulk Mail' => '',
1143 'Signature Text' => '',
1144 'Signature Html' => '',
1145 'IM Provider' => '',
1146 'IM Screen Name' => '',
1147 'OpenID' => '',
1148 'World Region' => 'Europe and Central Asia',
1149 'Website' => '',
1150 'Group(s)' => '',
1151 'Tag(s)' => '',
1152 'Note(s)' => '',
1153 ];
f143b245
SL
1154 // Include both possible options as we rely on implicit order here and MySQL 8 in testing is returning a different value for some fields.
1155 $this->assertExpectedOutput($expected, $this->csv->fetchOne(), [
1156 'Email' => ['home@example.com', 'work@example.com'],
1157 'Location Type' => ['Home', 'Work'],
1158 ]);
c2aec6ad 1159 }
1160
0b60a345 1161 /**
1162 * Tests the options for greeting templates when choosing to merge same address.
1163 *
1164 * @throws \CRM_Core_Exception
1165 * @throws \League\Csv\Exception
1166 */
1167 public function testMergeSameAddressGreetingOptions() {
1168 $this->setUpContactSameAddressExportData();
1169 $this->callAPISuccess('OptionValue', 'create', [
1170 'option_group_id' => 'postal_greeting',
1171 'label' => '{contact.individual_suffix} {contact.last_name} and first is {contact.first_name} ',
1172 // This hard coded number makes it available for export use.
1173 'filter' => 4,
1174 ]);
1175 $this->doExportTest([
1176 'mergeSameAddress' => TRUE,
1177 'exportParams' => [
1178 'postal_greeting' => '2',
1179 'postal_greeting_other' => '',
1180 'addressee' => '2',
1181 'addressee_other' => 'random string {contact.display_name}',
1182 'mergeOption' => '1',
1183 'additional_group' => '',
1184 'mapping' => '',
1185 ],
1186 ]);
1187 $this->assertExpectedOutput([
1188 'Addressee' => 'random string Mr. Anthony Anderson II, Dr. Sarah Smith II',
1189 'Email Greeting' => 'II Anderson and first is Anthony , II Smith Sarah ',
1190 'Postal Greeting' => 'II Anderson and first is Anthony , II Smith Sarah ',
1191 ], $this->csv->fetchOne());
1192 // 3 contacts merged to 2.
1193 $this->assertCount(2, $this->csv);
1194 }
1195
e2ea63f5 1196 /**
1197 * Test exporting when no rows are retrieved.
1198 *
1199 * @throws \CRM_Core_Exception
1200 * @throws \League\Csv\Exception
1201 */
1202 public function testExportNoRows() {
1203 $contactA = $this->callAPISuccess('contact', 'create', [
1204 'first_name' => 'John',
1205 'last_name' => 'Doe',
1206 'contact_type' => 'Individual',
1207 ]);
1208 $this->doExportTest([
1209 'selectAll' => TRUE,
1210 'ids' => [$contactA['id']],
1211 'exportParams' => [
1212 'postal_mailing_export' => [
1213 'postal_mailing_export' => TRUE,
1214 ],
1215 'mergeSameAddress' => TRUE,
1216 ],
1217 ]);
1218 $this->assertEquals('Contact ID', $this->csv->getHeader()[0]);
1219 }
1220
285fa729 1221 /**
1222 * Test to ensure that 'Merge All Contacts with the Same Address' works on export.
1223 *
1224 * 3 contacts are created A, B and C where A and B are individual contacts that share same address via master_id.
1225 * C is a household contact whose member is contact A.
1226 *
1227 * These 3 contacts are selected for export with 'Merge All Contacts with the Same Address' = TRUE
1228 * And at the end export table contain only 1 contact i.e. is C as A and B got merged into 1 as they share same address but then A is Household member of C.
1229 * So C take preference over A and thus C is exported as result.
1230 *
1231 * @throws \CRM_Core_Exception
1232 * @throws \League\Csv\Exception
1233 */
1234 public function testMergeSameAddressOnExport() {
1235 $this->individualCreate();
1236 $householdID = $this->setUpHousehold()[0];
1237 $contactIDs = array_merge($this->contactIDs, [$householdID]);
1238 // Empty existing addresses & start fresh.
1239 $this->callAPISuccess('Address', 'get', ['api.Address.delete' => 1]);
1240 foreach ($contactIDs as $id) {
1241 $this->callAPISuccess('Address', 'create', [
1242 'city' => 'Portland',
1243 'street_address' => 'Ambachtstraat 23',
1244 'state_province_id' => 'Maine',
1245 'location_type_id' => 'Home',
1246 'contact_id' => $id,
1247 ]);
1248 }
1249
1250 $this->doExportTest([
1251 'selectAll' => FALSE,
1252 'ids' => $contactIDs,
1253 'mergeSameAddress' => TRUE,
1254 ]);
8669d9a7 1255
1256 $this->assertCount(1, $this->csv);
285fa729 1257 $row = $this->csv->fetchOne();
8669d9a7 1258 $this->assertEquals('Household', $this->csv->fetchOne()['Contact Type']);
285fa729 1259 }
1260
6382c24c
LCA
1261 /**
1262 * Test that deceased and do not mail contacts are removed from contacts before
6d52bfe5 1263 *
1264 * @dataProvider getReasonsNotToMail
1265 *
1266 * @param array $reason
1267 * @param array $addressReason
46312f7d 1268 *
1269 * @throws \CRM_Core_Exception
efaa3367 1270 * @throws \League\Csv\Exception
6382c24c 1271 */
6d52bfe5 1272 public function testExportDeceasedDoNotMail($reason, $addressReason) {
46312f7d 1273 $contactA = $this->callAPISuccess('contact', 'create', [
6382c24c
LCA
1274 'first_name' => 'John',
1275 'last_name' => 'Doe',
1276 'contact_type' => 'Individual',
46312f7d 1277 ]);
6382c24c 1278
6d52bfe5 1279 $contactB = $this->callAPISuccess('contact', 'create', array_merge([
6382c24c
LCA
1280 'first_name' => 'Jane',
1281 'last_name' => 'Doe',
1282 'contact_type' => 'Individual',
6d52bfe5 1283 ], $reason));
6382c24c 1284
62a39786 1285 // Create another contact not included in the exporrt set.
1286 $this->callAPISuccess('contact', 'create', array_merge([
1287 'first_name' => 'Janet',
1288 'last_name' => 'Doe',
1289 'contact_type' => 'Individual',
1290 'api.address.create' => ['supplemental_address_1' => 'An address'],
1291 ], $reason));
1292
1293 // Create another contact not included in the exporrt set.
1294 $this->callAPISuccess('contact', 'create', array_merge([
1295 'first_name' => 'Janice',
1296 'last_name' => 'Doe',
1297 'contact_type' => 'Individual',
1298 ], $reason));
1299
6382c24c 1300 //create address for contact A
6d52bfe5 1301 $this->callAPISuccess('address', 'create', [
6382c24c
LCA
1302 'contact_id' => $contactA['id'],
1303 'location_type_id' => 'Home',
1304 'street_address' => 'ABC 12',
1305 'postal_code' => '123 AB',
1306 'country_id' => '1152',
1307 'city' => 'ABC',
1308 'is_primary' => 1,
6d52bfe5 1309 ]);
6382c24c
LCA
1310
1311 //create address for contact B
6d52bfe5 1312 $this->callAPISuccess('address', 'create', array_merge([
6382c24c
LCA
1313 'contact_id' => $contactB['id'],
1314 'location_type_id' => 'Home',
1315 'street_address' => 'ABC 12',
1316 'postal_code' => '123 AB',
1317 'country_id' => '1152',
1318 'city' => 'ABC',
1319 'is_primary' => 1,
6d52bfe5 1320 ], $addressReason));
6382c24c 1321
efaa3367 1322 $this->doExportTest([
1323 'selectAll' => TRUE,
1324 'ids' => [$contactA['id'], $contactB['id']],
1325 'exportParams' => [
46312f7d 1326 'postal_mailing_export' => [
6382c24c 1327 'postal_mailing_export' => TRUE,
46312f7d 1328 ],
efaa3367 1329 'mergeSameAddress' => TRUE,
1330 ],
1331 ]);
1332 $row = $this->csv->fetchOne(0);
6382c24c 1333
efaa3367 1334 $this->assertTrue(!in_array('Stage', $this->processor->getHeaderRows()));
1335 $this->assertEquals('Dear John', $row['Email Greeting']);
1336 $this->assertCount(1, $this->csv);
6382c24c
LCA
1337 }
1338
6d52bfe5 1339 /**
1340 * Get reasons that a contact is not postalable.
46312f7d 1341 *
6d52bfe5 1342 * @return array
1343 */
1344 public function getReasonsNotToMail() {
1345 return [
1346 [['is_deceased' => 1], []],
1347 [['do_not_mail' => 1], []],
1348 [[], ['street_address' => '']],
1349 ];
1350 }
39b959db 1351
2593f7dc 1352 /**
46312f7d 1353 * Set up household for tests.
1354 *
2593f7dc 1355 * @return array
c46c033c 1356 *
1357 * @throws CRM_Core_Exception
2593f7dc 1358 */
1359 protected function setUpHousehold() {
1360 $this->setUpContactExportData();
1361 $householdID = $this->householdCreate([
cedeaa5c 1362 'source' => 'household sauce',
2593f7dc 1363 'api.Address.create' => [
1364 'city' => 'Portland',
1365 'state_province_id' => 'Maine',
39b959db
SL
1366 'location_type_id' => 'Home',
1367 ],
2593f7dc 1368 ]);
1369
1370 $relationshipTypes = $this->callAPISuccess('RelationshipType', 'get', [])['values'];
1371 $houseHoldTypeID = NULL;
1372 foreach ($relationshipTypes as $id => $relationshipType) {
1373 if ($relationshipType['name_a_b'] === 'Household Member of') {
1374 $houseHoldTypeID = $relationshipType['id'];
1375 }
1376 }
1377 $this->callAPISuccess('Relationship', 'create', [
1378 'contact_id_a' => $this->contactIDs[0],
1379 'contact_id_b' => $householdID,
1380 'relationship_type_id' => $houseHoldTypeID,
1381 ]);
1382 $this->callAPISuccess('Relationship', 'create', [
1383 'contact_id_a' => $this->contactIDs[1],
1384 'contact_id_b' => $householdID,
1385 'relationship_type_id' => $houseHoldTypeID,
1386 ]);
46312f7d 1387 return [$householdID, $houseHoldTypeID];
2593f7dc 1388 }
1389
0a3b035f 1390 /**
1391 * Ensure component is enabled.
1392 *
1393 * @param int $exportMode
1394 */
1395 public function ensureComponentIsEnabled($exportMode) {
1396 if ($exportMode === CRM_Export_Form_Select::CASE_EXPORT) {
1397 CRM_Core_BAO_ConfigSetting::enableComponent('CiviCase');
1398 }
1399 }
1400
ce14544c 1401 /**
1402 * Test our export all field metadata retrieval.
1403 *
1404 * @dataProvider additionalFieldsDataProvider
46312f7d 1405 *
ce14544c 1406 * @param int $exportMode
1407 * @param $expected
1408 */
1409 public function testAdditionalReturnProperties($exportMode, $expected) {
1410 $this->ensureComponentIsEnabled($exportMode);
1411 $processor = new CRM_Export_BAO_ExportProcessor($exportMode, NULL, 'AND');
1412 $metadata = $processor->getAdditionalReturnProperties();
1413 $this->assertEquals($expected, $metadata);
1414 }
1415
1416 /**
1417 * Test our export all field metadata retrieval.
1418 *
1419 * @dataProvider allFieldsDataProvider
46312f7d 1420 *
ce14544c 1421 * @param int $exportMode
1422 * @param $expected
1423 */
1424 public function testDefaultReturnProperties($exportMode, $expected) {
1425 $this->ensureComponentIsEnabled($exportMode);
1426 $processor = new CRM_Export_BAO_ExportProcessor($exportMode, NULL, 'AND');
1427 $metadata = $processor->getDefaultReturnProperties();
1428 $this->assertEquals($expected, $metadata);
1429 }
1430
1431 /**
1432 * Get fields returned from additionalFields function.
1433 *
1434 * @return array
1435 */
1436 public function additionalFieldsDataProvider() {
1437 return [
1438 [
1439 'anything that will then be defaulting ton contact',
1440 $this->getExtraReturnProperties(),
1441 ],
1442 [
1443 CRM_Export_Form_Select::ACTIVITY_EXPORT,
1444 array_merge($this->getExtraReturnProperties(), $this->getActivityReturnProperties()),
1445 ],
1446 [
1447 CRM_Export_Form_Select::CASE_EXPORT,
1448 array_merge($this->getExtraReturnProperties(), $this->getCaseReturnProperties()),
1449 ],
1450 [
1451 CRM_Export_Form_Select::CONTRIBUTE_EXPORT,
1452 array_merge($this->getExtraReturnProperties(), $this->getContributionReturnProperties()),
1453 ],
1454 [
1455 CRM_Export_Form_Select::EVENT_EXPORT,
1456 array_merge($this->getExtraReturnProperties(), $this->getEventReturnProperties()),
1457 ],
1458 [
1459 CRM_Export_Form_Select::MEMBER_EXPORT,
1460 array_merge($this->getExtraReturnProperties(), $this->getMembershipReturnProperties()),
1461 ],
1462 [
1463 CRM_Export_Form_Select::PLEDGE_EXPORT,
1464 array_merge($this->getExtraReturnProperties(), $this->getPledgeReturnProperties()),
1465 ],
1466
1467 ];
1468 }
1469
1470 /**
1471 * get data for testing field metadata by query mode.
1472 */
1473 public function allFieldsDataProvider() {
1474 return [
1475 [
1476 'anything that will then be defaulting ton contact',
1477 $this->getBasicReturnProperties(TRUE),
1478 ],
1479 [
1480 CRM_Export_Form_Select::ACTIVITY_EXPORT,
1481 array_merge($this->getBasicReturnProperties(FALSE), $this->getActivityReturnProperties()),
1482 ],
1483 [
1484 CRM_Export_Form_Select::CASE_EXPORT,
1485 array_merge($this->getBasicReturnProperties(FALSE), $this->getCaseReturnProperties()),
1486 ],
1487 [
1488 CRM_Export_Form_Select::CONTRIBUTE_EXPORT,
1489 array_merge($this->getBasicReturnProperties(FALSE), $this->getContributionReturnProperties()),
1490 ],
1491 [
1492 CRM_Export_Form_Select::EVENT_EXPORT,
1493 array_merge($this->getBasicReturnProperties(FALSE), $this->getEventReturnProperties()),
1494 ],
1495 [
1496 CRM_Export_Form_Select::MEMBER_EXPORT,
1497 array_merge($this->getBasicReturnProperties(FALSE), $this->getMembershipReturnProperties()),
1498 ],
1499 [
1500 CRM_Export_Form_Select::PLEDGE_EXPORT,
1501 array_merge($this->getBasicReturnProperties(FALSE), $this->getPledgeReturnProperties()),
1502 ],
1503 ];
1504 }
1505
1506 /**
1507 * Get return properties manually added in.
1508 */
1509 public function getExtraReturnProperties() {
7626754f 1510 return [];
ce14544c 1511 }
1512
1513 /**
1514 * Get basic return properties.
1515 *
704e3e9a 1516 * @param bool $isContactMode
ce14544c 1517 * Are we in contact mode or not
1518 *
1519 * @return array
1520 */
1521 protected function getBasicReturnProperties($isContactMode) {
1522 $returnProperties = [
1523 'id' => 1,
1524 'contact_type' => 1,
1525 'contact_sub_type' => 1,
1526 'do_not_email' => 1,
1527 'do_not_phone' => 1,
1528 'do_not_mail' => 1,
1529 'do_not_sms' => 1,
1530 'do_not_trade' => 1,
1531 'is_opt_out' => 1,
1532 'legal_identifier' => 1,
1533 'external_identifier' => 1,
1534 'sort_name' => 1,
1535 'display_name' => 1,
1536 'nick_name' => 1,
1537 'legal_name' => 1,
1538 'image_URL' => 1,
1539 'preferred_communication_method' => 1,
1540 'preferred_language' => 1,
1541 'preferred_mail_format' => 1,
1542 'hash' => 1,
1543 'contact_source' => 1,
1544 'first_name' => 1,
1545 'middle_name' => 1,
1546 'last_name' => 1,
1547 'prefix_id' => 1,
1548 'suffix_id' => 1,
1549 'formal_title' => 1,
1550 'communication_style_id' => 1,
1551 'email_greeting_id' => 1,
1552 'postal_greeting_id' => 1,
1553 'addressee_id' => 1,
1554 'job_title' => 1,
1555 'gender_id' => 1,
1556 'birth_date' => 1,
1557 'is_deceased' => 1,
1558 'deceased_date' => 1,
1559 'household_name' => 1,
1560 'organization_name' => 1,
1561 'sic_code' => 1,
1562 'user_unique_id' => 1,
1563 'current_employer_id' => 1,
1564 'contact_is_deleted' => 1,
1565 'created_date' => 1,
1566 'modified_date' => 1,
1567 'addressee' => 1,
1568 'email_greeting' => 1,
1569 'postal_greeting' => 1,
1570 'current_employer' => 1,
1571 'location_type' => 1,
7e18723f 1572 'address_id' => 1,
ce14544c 1573 'street_address' => 1,
1574 'street_number' => 1,
1575 'street_number_suffix' => 1,
1576 'street_name' => 1,
1577 'street_unit' => 1,
1578 'supplemental_address_1' => 1,
1579 'supplemental_address_2' => 1,
1580 'supplemental_address_3' => 1,
1581 'city' => 1,
1582 'postal_code_suffix' => 1,
1583 'postal_code' => 1,
1584 'geo_code_1' => 1,
1585 'geo_code_2' => 1,
4fcfc078 1586 'manual_geo_code' => 1,
ce14544c 1587 'address_name' => 1,
1588 'master_id' => 1,
1589 'county' => 1,
1590 'state_province' => 1,
1591 'country' => 1,
1592 'phone' => 1,
1593 'phone_ext' => 1,
1594 'email' => 1,
1595 'on_hold' => 1,
1596 'is_bulkmail' => 1,
1597 'signature_text' => 1,
1598 'signature_html' => 1,
1599 'im_provider' => 1,
1600 'im' => 1,
1601 'openid' => 1,
1602 'world_region' => 1,
1603 'url' => 1,
1604 'groups' => 1,
1605 'tags' => 1,
1606 'notes' => 1,
1607 'phone_type_id' => 1,
ce14544c 1608 ];
1609 if (!$isContactMode) {
1610 unset($returnProperties['groups']);
1611 unset($returnProperties['tags']);
1612 unset($returnProperties['notes']);
1613 }
1614 return $returnProperties;
1615 }
1616
1617 /**
1618 * Get return properties for pledges.
1619 *
1620 * @return array
1621 */
1622 public function getPledgeReturnProperties() {
1623 return [
1624 'contact_type' => 1,
1625 'contact_sub_type' => 1,
1626 'sort_name' => 1,
1627 'display_name' => 1,
1628 'pledge_id' => 1,
1629 'pledge_amount' => 1,
1630 'pledge_total_paid' => 1,
1631 'pledge_create_date' => 1,
1632 'pledge_start_date' => 1,
1633 'pledge_next_pay_date' => 1,
1634 'pledge_next_pay_amount' => 1,
1635 'pledge_status' => 1,
1636 'pledge_is_test' => 1,
1637 'pledge_contribution_page_id' => 1,
1638 'pledge_financial_type' => 1,
1639 'pledge_frequency_interval' => 1,
1640 'pledge_frequency_unit' => 1,
1641 'pledge_currency' => 1,
1642 'pledge_campaign_id' => 1,
1643 'pledge_balance_amount' => 1,
1644 'pledge_payment_id' => 1,
1645 'pledge_payment_scheduled_amount' => 1,
1646 'pledge_payment_scheduled_date' => 1,
1647 'pledge_payment_paid_amount' => 1,
1648 'pledge_payment_paid_date' => 1,
1649 'pledge_payment_reminder_date' => 1,
1650 'pledge_payment_reminder_count' => 1,
1651 'pledge_payment_status' => 1,
1652 ];
1653 }
1654
1655 /**
1656 * Get membership return properties.
1657 *
1658 * @return array
1659 */
1660 public function getMembershipReturnProperties() {
1661 return [
ce14544c 1662 'contact_type' => 1,
1663 'contact_sub_type' => 1,
1664 'sort_name' => 1,
1665 'display_name' => 1,
1666 'membership_type' => 1,
1667 'member_is_test' => 1,
1668 'member_is_pay_later' => 1,
09ba1975 1669 'membership_join_date' => 1,
ce14544c 1670 'membership_start_date' => 1,
1671 'membership_end_date' => 1,
1672 'membership_source' => 1,
1673 'membership_status' => 1,
1674 'membership_id' => 1,
1675 'owner_membership_id' => 1,
1676 'max_related' => 1,
1677 'membership_recur_id' => 1,
1678 'member_campaign_id' => 1,
1679 'member_is_override' => 1,
ce14544c 1680 ];
1681 }
1682
1683 /**
1684 * Get return properties for events.
1685 *
1686 * @return array
1687 */
1688 public function getEventReturnProperties() {
1689 return [
1690 'contact_type' => 1,
1691 'contact_sub_type' => 1,
1692 'sort_name' => 1,
1693 'display_name' => 1,
1694 'event_id' => 1,
1695 'event_title' => 1,
1696 'event_start_date' => 1,
1697 'event_end_date' => 1,
1698 'event_type' => 1,
1699 'participant_id' => 1,
1700 'participant_status' => 1,
1701 'participant_status_id' => 1,
1702 'participant_role' => 1,
1703 'participant_role_id' => 1,
1704 'participant_note' => 1,
1705 'participant_register_date' => 1,
1706 'participant_source' => 1,
1707 'participant_fee_level' => 1,
1708 'participant_is_test' => 1,
1709 'participant_is_pay_later' => 1,
1710 'participant_fee_amount' => 1,
1711 'participant_discount_name' => 1,
1712 'participant_fee_currency' => 1,
1713 'participant_registered_by_id' => 1,
1714 'participant_campaign_id' => 1,
1715 ];
1716 }
1717
1718 /**
1719 * Get return properties for activities.
1720 *
1721 * @return array
1722 */
1723 public function getActivityReturnProperties() {
1724 return [
1725 'activity_id' => 1,
1726 'contact_type' => 1,
1727 'contact_sub_type' => 1,
1728 'sort_name' => 1,
1729 'display_name' => 1,
1730 'activity_type' => 1,
1731 'activity_type_id' => 1,
1732 'activity_subject' => 1,
1733 'activity_date_time' => 1,
1734 'activity_duration' => 1,
1735 'activity_location' => 1,
1736 'activity_details' => 1,
1737 'activity_status' => 1,
1738 'activity_priority' => 1,
1739 'source_contact' => 1,
1740 'source_record_id' => 1,
1741 'activity_is_test' => 1,
1742 'activity_campaign_id' => 1,
1743 'result' => 1,
1744 'activity_engagement_level' => 1,
1745 'parent_id' => 1,
1746 ];
1747 }
1748
1749 /**
1750 * Get return properties for Case.
1751 *
1752 * @return array
1753 */
1754 public function getCaseReturnProperties() {
1755 return [
1756 'contact_type' => 1,
1757 'contact_sub_type' => 1,
1758 'sort_name' => 1,
1759 'display_name' => 1,
1760 'phone' => 1,
1761 'case_start_date' => 1,
1762 'case_end_date' => 1,
1763 'case_subject' => 1,
1764 'case_source_contact_id' => 1,
1765 'case_activity_status' => 1,
1766 'case_activity_duration' => 1,
1767 'case_activity_medium_id' => 1,
1768 'case_activity_details' => 1,
1769 'case_activity_is_auto' => 1,
1770 'contact_id' => 1,
1771 'case_id' => 1,
1772 'case_activity_subject' => 1,
1773 'case_status' => 1,
1774 'case_type' => 1,
1775 'case_role' => 1,
1776 'case_deleted' => 1,
1777 'case_recent_activity_date' => 1,
1778 'case_recent_activity_type' => 1,
1779 'case_scheduled_activity_date' => 1,
1780 ];
1781 }
1782
1783 /**
1784 * Get return properties for contribution.
1785 *
1786 * @return array
1787 */
1788 public function getContributionReturnProperties() {
1789 return [
1790 'contact_type' => 1,
1791 'contact_sub_type' => 1,
1792 'sort_name' => 1,
1793 'display_name' => 1,
1794 'financial_type' => 1,
1795 'contribution_source' => 1,
1796 'receive_date' => 1,
1797 'thankyou_date' => 1,
6e7cc0f5 1798 'contribution_cancel_date' => 1,
ce14544c 1799 'total_amount' => 1,
1800 'accounting_code' => 1,
1801 'payment_instrument' => 1,
1802 'payment_instrument_id' => 1,
1803 'contribution_check_number' => 1,
1804 'non_deductible_amount' => 1,
1805 'fee_amount' => 1,
1806 'net_amount' => 1,
1807 'trxn_id' => 1,
1808 'invoice_id' => 1,
1809 'invoice_number' => 1,
1810 'currency' => 1,
1811 'cancel_reason' => 1,
1812 'receipt_date' => 1,
ce14544c 1813 'is_test' => 1,
1814 'is_pay_later' => 1,
1815 'contribution_status' => 1,
1816 'contribution_recur_id' => 1,
1817 'amount_level' => 1,
1818 'contribution_note' => 1,
1819 'contribution_batch' => 1,
1820 'contribution_campaign_title' => 1,
1821 'contribution_campaign_id' => 1,
ce14544c 1822 'contribution_soft_credit_name' => 1,
1823 'contribution_soft_credit_amount' => 1,
1824 'contribution_soft_credit_type' => 1,
1825 'contribution_soft_credit_contact_id' => 1,
1826 'contribution_soft_credit_contribution_id' => 1,
1827 ];
1828 }
1829
0a3b035f 1830 /**
1831 * Test the column definition when 'all' fields defined.
1832 *
6c93b9a9 1833 * @param int $exportMode
1834 * @param array $expected
1835 * @param array $expectedHeaders
0a3b035f 1836 *
46312f7d 1837 * @throws \CRM_Core_Exception
fce27eeb 1838 * @throws \League\Csv\Exception
1839 *
0a3b035f 1840 * @dataProvider getSqlColumnsOutput
1841 */
6c93b9a9 1842 public function testGetSQLColumnsAndHeaders($exportMode, $expected, $expectedHeaders) {
0a3b035f 1843 $this->ensureComponentIsEnabled($exportMode);
1844 // We need some data so that we can get to the end of the export
1845 // function. Hopefully one day that won't be required to get metadata info out.
1846 // eventually aspire to call $provider->getSQLColumns straight after it
1847 // is intiated.
1848 $this->setupBaseExportData($exportMode);
fce27eeb 1849 $this->doExportTest(['selectAll' => TRUE, 'exportMode' => $exportMode, 'ids' => [1]]);
1850 $this->assertEquals($expected, $this->processor->getSQLColumns());
1851 $this->assertEquals($expectedHeaders, $this->processor->getHeaderRows());
0a3b035f 1852 }
1853
6202c5bb 1854 /**
1855 * Test exported with data entry mis-fire.
1856 *
1857 * Not fatal error if data incomplete.
1858 *
1859 * https://lab.civicrm.org/dev/core/issues/819
ee3aa985 1860 *
1861 * @throws \CRM_Core_Exception
1862 * @throws \League\Csv\Exception
6202c5bb 1863 */
1864 public function testExportIncompleteSubmission() {
1865 $this->setUpContactExportData();
ee3aa985 1866 $this->doExportTest(['fields' => [['contact_type' => 'Individual', 'name' => '']], 'ids' => [$this->contactIDs[1]]]);
6202c5bb 1867 }
1868
5506290d 1869 /**
1870 * Test exported with fields to output specified.
1871 *
1872 * @dataProvider getAllSpecifiableReturnFields
1873 *
1874 * @param int $exportMode
1875 * @param array $selectedFields
1876 * @param array $expected
ee3aa985 1877 *
1878 * @throws \CRM_Core_Exception
1879 * @throws \League\Csv\Exception
5506290d 1880 */
1881 public function testExportSpecifyFields($exportMode, $selectedFields, $expected) {
1882 $this->ensureComponentIsEnabled($exportMode);
1883 $this->setUpContributionExportData();
ee3aa985 1884 $this->doExportTest(['fields' => $selectedFields, 'ids' => [$this->contactIDs[1]], 'exportMode' => $exportMode]);
1885 $this->assertEquals($expected, $this->processor->getSQLColumns());
5506290d 1886 }
1887
c66a5741 1888 /**
1889 * Test export fields when no payment fields to be exported.
68f97b77 1890 *
1891 * @throws \CRM_Core_Exception
1892 * @throws \League\Csv\Exception
c66a5741 1893 */
1894 public function textExportParticipantSpecifyFieldsNoPayment() {
1895 $selectedFields = $this->getAllSpecifiableParticipantReturnFields();
1896 foreach ($selectedFields as $index => $field) {
1897 if (substr($field[1], 0, 22) === 'componentPaymentField_') {
420384a0 1898 unset($selectedFields[$index]);
c66a5741 1899 }
1900 }
1901
1902 $expected = $this->getAllSpecifiableParticipantReturnFields();
1903 foreach ($expected as $index => $field) {
1904 if (substr($index, 0, 22) === 'componentPaymentField_') {
420384a0 1905 unset($expected[$index]);
c66a5741 1906 }
1907 }
68f97b77 1908 $this->doExportTest(['fields' => $selectedFields, 'ids' => [$this->contactIDs[1]], 'exportMode' => CRM_Export_Form_Select::EVENT_EXPORT]);
1909 $this->assertEquals($expected, $this->processor->getSQLColumns());
c66a5741 1910 }
39b959db 1911
5506290d 1912 /**
46312f7d 1913 * Get all return fields (@return array
1914 *
1915 * @todo - still being built up.
5506290d 1916 *
5506290d 1917 */
1918 public function getAllSpecifiableReturnFields() {
1919 return [
1920 [
1921 CRM_Export_Form_Select::EVENT_EXPORT,
1922 $this->getAllSpecifiableParticipantReturnFields(),
c66a5741 1923 $this->getAllSpecifiableParticipantReturnColumns(),
5506290d 1924 ],
1925 ];
1926 }
1927
c66a5741 1928 /**
1929 * Get expected return column output for participant mode return all columns.
1930 *
1931 * @return array
1932 */
1933 public function getAllSpecifiableParticipantReturnColumns() {
1934 return [
f61dd144
SL
1935 'participant_campaign_id' => '`participant_campaign_id` varchar(16)',
1936 'participant_contact_id' => '`participant_contact_id` varchar(16)',
1937 'componentpaymentfield_contribution_status' => '`componentpaymentfield_contribution_status` varchar(255)',
1938 'currency' => '`currency` varchar(3)',
1939 'componentpaymentfield_received_date' => '`componentpaymentfield_received_date` varchar(32)',
1940 'default_role_id' => '`default_role_id` varchar(16)',
1941 'participant_discount_name' => '`participant_discount_name` varchar(16)',
1942 'event_id' => '`event_id` varchar(16)',
1943 'event_end_date' => '`event_end_date` varchar(32)',
1944 'event_start_date' => '`event_start_date` varchar(32)',
1945 'template_title' => '`template_title` varchar(255)',
1946 'event_title' => '`event_title` varchar(255)',
1947 'participant_fee_amount' => '`participant_fee_amount` varchar(32)',
1948 'participant_fee_currency' => '`participant_fee_currency` varchar(3)',
1949 'fee_label' => '`fee_label` varchar(255)',
1950 'participant_fee_level' => '`participant_fee_level` longtext',
1951 'participant_is_pay_later' => '`participant_is_pay_later` varchar(16)',
1952 'participant_id' => '`participant_id` varchar(16)',
1953 'participant_note' => '`participant_note` text',
1954 'participant_role_id' => '`participant_role_id` varchar(128)',
1955 'participant_role' => '`participant_role` varchar(255)',
1956 'participant_source' => '`participant_source` varchar(128)',
1957 'participant_status_id' => '`participant_status_id` varchar(16)',
1958 'participant_status' => '`participant_status` varchar(255)',
1959 'participant_register_date' => '`participant_register_date` varchar(32)',
1960 'participant_registered_by_id' => '`participant_registered_by_id` varchar(16)',
1961 'participant_is_test' => '`participant_is_test` varchar(16)',
1962 'componentpaymentfield_total_amount' => '`componentpaymentfield_total_amount` varchar(32)',
1963 'componentpaymentfield_transaction_id' => '`componentpaymentfield_transaction_id` varchar(255)',
1964 'transferred_to_contact_id' => '`transferred_to_contact_id` varchar(16)',
c66a5741 1965 ];
1966 }
1967
5506290d 1968 /**
1969 * @return array
1970 */
1971 public function getAllSpecifiableParticipantReturnFields() {
1972 return [
1973 0 =>
1974 [
1975 0 => 'Participant',
ee3aa985 1976 'name' => '',
5506290d 1977 ],
1978 1 =>
1979 [
1980 0 => 'Participant',
ee3aa985 1981 'name' => 'participant_campaign_id',
5506290d 1982 ],
1983 2 =>
1984 [
1985 0 => 'Participant',
ee3aa985 1986 'name' => 'participant_contact_id',
5506290d 1987 ],
1988 3 =>
1989 [
1990 0 => 'Participant',
ee3aa985 1991 'name' => 'componentPaymentField_contribution_status',
5506290d 1992 ],
1993 4 =>
1994 [
1995 0 => 'Participant',
ee3aa985 1996 'name' => 'currency',
5506290d 1997 ],
1998 5 =>
1999 [
2000 0 => 'Participant',
ee3aa985 2001 'name' => 'componentPaymentField_received_date',
5506290d 2002 ],
2003 6 =>
2004 [
2005 0 => 'Participant',
ee3aa985 2006 'name' => 'default_role_id',
5506290d 2007 ],
2008 7 =>
2009 [
2010 0 => 'Participant',
ee3aa985 2011 'name' => 'participant_discount_name',
5506290d 2012 ],
2013 8 =>
2014 [
2015 0 => 'Participant',
ee3aa985 2016 'name' => 'event_id',
5506290d 2017 ],
2018 9 =>
2019 [
2020 0 => 'Participant',
ee3aa985 2021 'name' => 'event_end_date',
5506290d 2022 ],
2023 10 =>
2024 [
2025 0 => 'Participant',
ee3aa985 2026 'name' => 'event_start_date',
5506290d 2027 ],
2028 11 =>
2029 [
2030 0 => 'Participant',
ee3aa985 2031 'name' => 'template_title',
5506290d 2032 ],
2033 12 =>
2034 [
2035 0 => 'Participant',
ee3aa985 2036 'name' => 'event_title',
5506290d 2037 ],
2038 13 =>
2039 [
2040 0 => 'Participant',
ee3aa985 2041 'name' => 'participant_fee_amount',
5506290d 2042 ],
2043 14 =>
2044 [
2045 0 => 'Participant',
ee3aa985 2046 'name' => 'participant_fee_currency',
5506290d 2047 ],
2048 15 =>
2049 [
2050 0 => 'Participant',
ee3aa985 2051 'name' => 'fee_label',
5506290d 2052 ],
2053 16 =>
2054 [
2055 0 => 'Participant',
ee3aa985 2056 'name' => 'participant_fee_level',
5506290d 2057 ],
2058 17 =>
2059 [
2060 0 => 'Participant',
ee3aa985 2061 'name' => 'participant_is_pay_later',
5506290d 2062 ],
2063 18 =>
2064 [
2065 0 => 'Participant',
ee3aa985 2066 'name' => 'participant_id',
5506290d 2067 ],
2068 19 =>
2069 [
2070 0 => 'Participant',
ee3aa985 2071 'name' => 'participant_note',
5506290d 2072 ],
2073 20 =>
2074 [
2075 0 => 'Participant',
ee3aa985 2076 'name' => 'participant_role_id',
5506290d 2077 ],
2078 21 =>
2079 [
2080 0 => 'Participant',
ee3aa985 2081 'name' => 'participant_role',
5506290d 2082 ],
2083 22 =>
2084 [
2085 0 => 'Participant',
ee3aa985 2086 'name' => 'participant_source',
5506290d 2087 ],
2088 23 =>
2089 [
2090 0 => 'Participant',
ee3aa985 2091 'name' => 'participant_status_id',
5506290d 2092 ],
2093 24 =>
2094 [
2095 0 => 'Participant',
ee3aa985 2096 'name' => 'participant_status',
5506290d 2097 ],
2098 25 =>
2099 [
2100 0 => 'Participant',
ee3aa985 2101 'name' => 'participant_status',
5506290d 2102 ],
2103 26 =>
2104 [
2105 0 => 'Participant',
ee3aa985 2106 'name' => 'participant_register_date',
5506290d 2107 ],
2108 27 =>
2109 [
2110 0 => 'Participant',
ee3aa985 2111 'name' => 'participant_registered_by_id',
5506290d 2112 ],
2113 28 =>
2114 [
2115 0 => 'Participant',
ee3aa985 2116 'name' => 'participant_is_test',
5506290d 2117 ],
2118 29 =>
2119 [
2120 0 => 'Participant',
ee3aa985 2121 'name' => 'componentPaymentField_total_amount',
5506290d 2122 ],
2123 30 =>
2124 [
2125 0 => 'Participant',
ee3aa985 2126 'name' => 'componentPaymentField_transaction_id',
5506290d 2127 ],
2128 31 =>
2129 [
2130 0 => 'Participant',
ee3aa985 2131 'name' => 'transferred_to_contact_id',
5506290d 2132 ],
2133 ];
2134 }
2135
0a3b035f 2136 /**
2137 * @param string $exportMode
2138 */
2139 public function setupBaseExportData($exportMode) {
2140 $this->createLoggedInUser();
2141 if ($exportMode === CRM_Export_Form_Select::CASE_EXPORT) {
2142 $this->setupCaseExportData();
2143 }
2144 if ($exportMode === CRM_Export_Form_Select::CONTRIBUTE_EXPORT) {
2145 $this->setUpContributionExportData();
2146 }
2147 if ($exportMode === CRM_Export_Form_Select::MEMBER_EXPORT) {
2148 $this->setUpMembershipExportData();
2149 }
2150 if ($exportMode === CRM_Export_Form_Select::ACTIVITY_EXPORT) {
2151 $this->setUpActivityExportData();
2152 }
2153 }
2154
2155 /**
2156 * Get comprehensive sql columns output.
2157 *
2158 * @return array
2159 */
2160 public function getSqlColumnsOutput() {
2161 return [
2162 [
2163 'anything that will then be defaulting ton contact',
2164 $this->getBasicSqlColumnDefinition(TRUE),
6c93b9a9 2165 $this->getBasicHeaderDefinition(TRUE),
0a3b035f 2166 ],
2167 [
2168 CRM_Export_Form_Select::ACTIVITY_EXPORT,
2169 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getActivitySqlColumns()),
6c93b9a9 2170 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getActivityHeaderDefinition()),
0a3b035f 2171 ],
2172 [
2173 CRM_Export_Form_Select::CASE_EXPORT,
2174 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getCaseSqlColumns()),
6c93b9a9 2175 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getCaseHeaderDefinition()),
0a3b035f 2176 ],
2177 [
2178 CRM_Export_Form_Select::CONTRIBUTE_EXPORT,
2179 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getContributionSqlColumns()),
6c93b9a9 2180 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getContributeHeaderDefinition()),
0a3b035f 2181 ],
2182 [
2183 CRM_Export_Form_Select::EVENT_EXPORT,
2184 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getParticipantSqlColumns()),
6c93b9a9 2185 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getParticipantHeaderDefinition()),
0a3b035f 2186 ],
2187 [
2188 CRM_Export_Form_Select::MEMBER_EXPORT,
2189 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getMembershipSqlColumns()),
6c93b9a9 2190 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getMemberHeaderDefinition()),
0a3b035f 2191 ],
2192 [
2193 CRM_Export_Form_Select::PLEDGE_EXPORT,
2194 array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getPledgeSqlColumns()),
6c93b9a9 2195 array_merge($this->getBasicHeaderDefinition(FALSE), $this->getPledgeHeaderDefinition()),
0a3b035f 2196 ],
2197
2198 ];
2199 }
2200
6c93b9a9 2201 /**
2202 * Get the header definition for exports.
2203 *
2204 * @param bool $isContactExport
2205 *
2206 * @return array
2207 */
2208 protected function getBasicHeaderDefinition($isContactExport) {
2209 $headers = [
39b959db
SL
2210 0 => 'Contact ID',
2211 1 => 'Contact Type',
2212 2 => 'Contact Subtype',
2213 3 => 'Do Not Email',
2214 4 => 'Do Not Phone',
2215 5 => 'Do Not Mail',
2216 6 => 'Do Not Sms',
2217 7 => 'Do Not Trade',
2218 8 => 'No Bulk Emails (User Opt Out)',
2219 9 => 'Legal Identifier',
2220 10 => 'External Identifier',
2221 11 => 'Sort Name',
2222 12 => 'Display Name',
2223 13 => 'Nickname',
2224 14 => 'Legal Name',
2225 15 => 'Image Url',
2226 16 => 'Preferred Communication Method',
2227 17 => 'Preferred Language',
2228 18 => 'Preferred Mail Format',
2229 19 => 'Contact Hash',
2230 20 => 'Contact Source',
2231 21 => 'First Name',
2232 22 => 'Middle Name',
2233 23 => 'Last Name',
2234 24 => 'Individual Prefix',
2235 25 => 'Individual Suffix',
2236 26 => 'Formal Title',
2237 27 => 'Communication Style',
2238 28 => 'Email Greeting ID',
2239 29 => 'Postal Greeting ID',
2240 30 => 'Addressee ID',
2241 31 => 'Job Title',
2242 32 => 'Gender',
2243 33 => 'Birth Date',
2244 34 => 'Deceased',
2245 35 => 'Deceased Date',
2246 36 => 'Household Name',
2247 37 => 'Organization Name',
2248 38 => 'Sic Code',
2249 39 => 'Unique ID (OpenID)',
2250 40 => 'Current Employer ID',
2251 41 => 'Contact is in Trash',
2252 42 => 'Created Date',
2253 43 => 'Modified Date',
2254 44 => 'Addressee',
2255 45 => 'Email Greeting',
2256 46 => 'Postal Greeting',
2257 47 => 'Current Employer',
2258 48 => 'Location Type',
7e18723f
JG
2259 49 => 'Address ID',
2260 50 => 'Street Address',
2261 51 => 'Street Number',
2262 52 => 'Street Number Suffix',
2263 53 => 'Street Name',
2264 54 => 'Street Unit',
2265 55 => 'Supplemental Address 1',
2266 56 => 'Supplemental Address 2',
2267 57 => 'Supplemental Address 3',
2268 58 => 'City',
2269 59 => 'Postal Code Suffix',
2270 60 => 'Postal Code',
2271 61 => 'Latitude',
2272 62 => 'Longitude',
2273 63 => 'Is Manually Geocoded',
2274 64 => 'Address Name',
2275 65 => 'Master Address Belongs To',
2276 66 => 'County',
2277 67 => 'State',
2278 68 => 'Country',
2279 69 => 'Phone',
2280 70 => 'Phone Extension',
2281 71 => 'Phone Type',
2282 72 => 'Email',
2283 73 => 'On Hold',
2284 74 => 'Use for Bulk Mail',
2285 75 => 'Signature Text',
2286 76 => 'Signature Html',
2287 77 => 'IM Provider',
2288 78 => 'IM Screen Name',
2289 79 => 'OpenID',
2290 80 => 'World Region',
2291 81 => 'Website',
2292 82 => 'Group(s)',
2293 83 => 'Tag(s)',
2294 84 => 'Note(s)',
39b959db 2295 ];
6c93b9a9 2296 if (!$isContactExport) {
219c47d6 2297 unset($headers[82]);
4fcfc078 2298 unset($headers[83]);
7e18723f 2299 unset($headers[84]);
6c93b9a9 2300 }
2301 return $headers;
2302 }
2303
2304 /**
2305 * Get the definition for activity headers.
2306 *
2307 * @return array
2308 */
2309 protected function getActivityHeaderDefinition() {
2310 return [
7e18723f
JG
2311 82 => 'Activity ID',
2312 83 => 'Activity Type',
2313 84 => 'Activity Type ID',
2314 85 => 'Subject',
2315 86 => 'Activity Date',
2316 87 => 'Duration',
2317 88 => 'Location',
2318 89 => 'Details',
2319 90 => 'Activity Status',
2320 91 => 'Activity Priority',
2321 92 => 'Source Contact',
2322 93 => 'source_record_id',
2323 94 => 'Test',
2324 95 => 'Campaign ID',
2325 96 => 'result',
2326 97 => 'Engagement Index',
2327 98 => 'parent_id',
6c93b9a9 2328 ];
2329 }
2330
2331 /**
2332 * Get the definition for case headers.
2333 *
2334 * @return array
2335 */
2336 protected function getCaseHeaderDefinition() {
2337 return [
7e18723f
JG
2338 82 => 'Contact ID',
2339 83 => 'Case ID',
2340 84 => 'case_activity_subject',
2341 85 => 'Case Subject',
2342 86 => 'Case Status',
2343 87 => 'Case Type',
2344 88 => 'Role in Case',
2345 89 => 'Case is in the Trash',
2346 90 => 'case_recent_activity_date',
2347 91 => 'case_recent_activity_type',
2348 92 => 'case_scheduled_activity_date',
2349 93 => 'Case Start Date',
2350 94 => 'Case End Date',
2351 95 => 'case_source_contact_id',
2352 96 => 'case_activity_status',
2353 97 => 'case_activity_duration',
2354 98 => 'case_activity_medium_id',
2355 99 => 'case_activity_details',
2356 100 => 'case_activity_is_auto',
6c93b9a9 2357 ];
2358 }
2359
2360 /**
2361 * Get the definition for contribute headers.
2362 *
2363 * @return array
2364 */
2365 protected function getContributeHeaderDefinition() {
2366 return [
7e18723f
JG
2367 82 => 'Financial Type',
2368 83 => 'Contribution Source',
2369 84 => 'Date Received',
2370 85 => 'Thank-you Date',
2371 86 => 'Cancelled / Refunded Date',
2372 87 => 'Total Amount',
2373 88 => 'Accounting Code',
2374 89 => 'Payment Methods',
2375 90 => 'Payment Method ID',
2376 91 => 'Check Number',
2377 92 => 'Non-deductible Amount',
2378 93 => 'Fee Amount',
2379 94 => 'Net Amount',
2380 95 => 'Transaction ID',
2381 96 => 'Invoice Reference',
2382 97 => 'Invoice Number',
2383 98 => 'Currency',
2384 99 => 'Cancellation / Refund Reason',
2385 100 => 'Receipt Date',
2386 101 => 'Test',
2387 102 => 'Is Pay Later',
2388 103 => 'Contribution Status',
2389 104 => 'Recurring Contribution ID',
2390 105 => 'Amount Label',
2391 106 => 'Contribution Note',
2392 107 => 'Batch Name',
2393 108 => 'Campaign Title',
2394 109 => 'Campaign ID',
2395 110 => 'Soft Credit For',
2396 111 => 'Soft Credit Amount',
2397 112 => 'Soft Credit Type',
2398 113 => 'Soft Credit For Contact ID',
2399 114 => 'Soft Credit For Contribution ID',
6c93b9a9 2400 ];
2401 }
2402
2403 /**
2404 * Get the definition for event headers.
2405 *
2406 * @return array
2407 */
2408 protected function getParticipantHeaderDefinition() {
2409 return [
7e18723f
JG
2410 82 => 'Event',
2411 83 => 'Event Title',
2412 84 => 'Event Start Date',
2413 85 => 'Event End Date',
2414 86 => 'Event Type',
2415 87 => 'Participant ID',
2416 88 => 'Participant Status',
2417 89 => 'Participant Status Id',
2418 90 => 'Participant Role',
2419 91 => 'Participant Role Id',
2420 92 => 'Participant Note',
2421 93 => 'Register date',
2422 94 => 'Participant Source',
2423 95 => 'Fee level',
2424 96 => 'Test',
2425 97 => 'Is Pay Later',
2426 98 => 'Fee Amount',
2427 99 => 'Discount Name',
2428 100 => 'Fee Currency',
2429 101 => 'Registered By ID',
2430 102 => 'Campaign ID',
6c93b9a9 2431 ];
2432 }
2433
2434 /**
2435 * Get the definition for member headers.
2436 *
2437 * @return array
2438 */
2439 protected function getMemberHeaderDefinition() {
2440 return [
7e18723f
JG
2441 82 => 'Membership Type',
2442 83 => 'Test',
2443 84 => 'Is Pay Later',
2444 85 => 'Member Since',
2445 86 => 'Membership Start Date',
2446 87 => 'Membership Expiration Date',
2447 88 => 'Source',
2448 89 => 'Membership Status',
2449 90 => 'Membership ID',
2450 91 => 'Primary Member ID',
2451 92 => 'Max Related',
2452 93 => 'Membership Recurring Contribution',
2453 94 => 'Campaign ID',
2454 95 => 'Status Override',
6c93b9a9 2455 ];
2456 }
2457
2458 /**
2459 * Get the definition for pledge headers.
2460 *
2461 * @return array
2462 */
2463 protected function getPledgeHeaderDefinition() {
2464 return [
7e18723f
JG
2465 82 => 'Pledge ID',
2466 83 => 'Total Pledged',
2467 84 => 'Total Paid',
2468 85 => 'Pledge Made',
2469 86 => 'Pledge Start Date',
2470 87 => 'Next Payment Date',
2471 88 => 'Next Payment Amount',
2472 89 => 'Pledge Status',
2473 90 => 'Test',
2474 91 => 'Pledge Contribution Page Id',
2475 92 => 'pledge_financial_type',
2476 93 => 'Pledge Frequency Interval',
2477 94 => 'Pledge Frequency Unit',
2478 95 => 'pledge_currency',
2479 96 => 'Campaign ID',
2480 97 => 'Balance Amount',
2481 98 => 'Payment ID',
2482 99 => 'Scheduled Amount',
2483 100 => 'Scheduled Date',
2484 101 => 'Paid Amount',
2485 102 => 'Paid Date',
2486 103 => 'Last Reminder',
2487 104 => 'Reminders Sent',
2488 105 => 'Pledge Payment Status',
6c93b9a9 2489 ];
2490 }
2491
0a3b035f 2492 /**
2493 * Get the column definition for exports.
2494 *
2495 * @param bool $isContactExport
2496 *
2497 * @return array
2498 */
2499 protected function getBasicSqlColumnDefinition($isContactExport) {
2500 $columns = [
f61dd144
SL
2501 'civicrm_primary_id' => '`civicrm_primary_id` varchar(16)',
2502 'contact_type' => '`contact_type` varchar(64)',
2503 'contact_sub_type' => '`contact_sub_type` varchar(255)',
2504 'do_not_email' => '`do_not_email` varchar(16)',
2505 'do_not_phone' => '`do_not_phone` varchar(16)',
2506 'do_not_mail' => '`do_not_mail` varchar(16)',
2507 'do_not_sms' => '`do_not_sms` varchar(16)',
2508 'do_not_trade' => '`do_not_trade` varchar(16)',
2509 'is_opt_out' => '`is_opt_out` varchar(16)',
2510 'legal_identifier' => '`legal_identifier` varchar(32)',
2511 'external_identifier' => '`external_identifier` varchar(64)',
2512 'sort_name' => '`sort_name` varchar(128)',
2513 'display_name' => '`display_name` varchar(128)',
2514 'nick_name' => '`nick_name` varchar(128)',
2515 'legal_name' => '`legal_name` varchar(128)',
2516 'image_url' => '`image_url` longtext',
2517 'preferred_communication_method' => '`preferred_communication_method` varchar(255)',
2518 'preferred_language' => '`preferred_language` varchar(5)',
2519 'preferred_mail_format' => '`preferred_mail_format` varchar(8)',
2520 'hash' => '`hash` varchar(32)',
2521 'contact_source' => '`contact_source` varchar(255)',
2522 'first_name' => '`first_name` varchar(64)',
2523 'middle_name' => '`middle_name` varchar(64)',
2524 'last_name' => '`last_name` varchar(64)',
2525 'prefix_id' => '`prefix_id` varchar(255)',
2526 'suffix_id' => '`suffix_id` varchar(255)',
2527 'formal_title' => '`formal_title` varchar(64)',
2528 'communication_style_id' => '`communication_style_id` varchar(255)',
2529 'email_greeting_id' => '`email_greeting_id` varchar(16)',
2530 'postal_greeting_id' => '`postal_greeting_id` varchar(16)',
2531 'addressee_id' => '`addressee_id` varchar(16)',
2532 'job_title' => '`job_title` varchar(255)',
2533 'gender_id' => '`gender_id` varchar(255)',
2534 'birth_date' => '`birth_date` varchar(32)',
2535 'is_deceased' => '`is_deceased` varchar(16)',
2536 'deceased_date' => '`deceased_date` varchar(32)',
2537 'household_name' => '`household_name` varchar(128)',
2538 'organization_name' => '`organization_name` varchar(128)',
2539 'sic_code' => '`sic_code` varchar(8)',
2540 'user_unique_id' => '`user_unique_id` varchar(255)',
2541 'current_employer_id' => '`current_employer_id` varchar(16)',
2542 'contact_is_deleted' => '`contact_is_deleted` varchar(16)',
2543 'created_date' => '`created_date` varchar(32)',
2544 'modified_date' => '`modified_date` varchar(32)',
2545 'addressee' => '`addressee` varchar(255)',
2546 'email_greeting' => '`email_greeting` varchar(255)',
2547 'postal_greeting' => '`postal_greeting` varchar(255)',
2548 'current_employer' => '`current_employer` varchar(128)',
2549 'location_type' => '`location_type` text',
7e18723f 2550 'address_id' => '`address_id` varchar(16)',
f61dd144
SL
2551 'street_address' => '`street_address` varchar(96)',
2552 'street_number' => '`street_number` varchar(16)',
2553 'street_number_suffix' => '`street_number_suffix` varchar(8)',
2554 'street_name' => '`street_name` varchar(64)',
2555 'street_unit' => '`street_unit` varchar(16)',
2556 'supplemental_address_1' => '`supplemental_address_1` varchar(96)',
2557 'supplemental_address_2' => '`supplemental_address_2` varchar(96)',
2558 'supplemental_address_3' => '`supplemental_address_3` varchar(96)',
2559 'city' => '`city` varchar(64)',
2560 'postal_code_suffix' => '`postal_code_suffix` varchar(12)',
2561 'postal_code' => '`postal_code` varchar(64)',
2562 'geo_code_1' => '`geo_code_1` varchar(32)',
2563 'geo_code_2' => '`geo_code_2` varchar(32)',
2564 'manual_geo_code' => '`manual_geo_code` varchar(16)',
2565 'address_name' => '`address_name` varchar(255)',
2566 'master_id' => '`master_id` varchar(128)',
2567 'county' => '`county` varchar(64)',
2568 'state_province' => '`state_province` varchar(64)',
2569 'country' => '`country` varchar(64)',
2570 'phone' => '`phone` varchar(32)',
2571 'phone_ext' => '`phone_ext` varchar(16)',
2572 'phone_type_id' => '`phone_type_id` varchar(16)',
2573 'email' => '`email` varchar(254)',
2574 'on_hold' => '`on_hold` varchar(16)',
2575 'is_bulkmail' => '`is_bulkmail` varchar(16)',
2576 'signature_text' => '`signature_text` longtext',
2577 'signature_html' => '`signature_html` longtext',
2578 'im_provider' => '`im_provider` text',
2579 'im_screen_name' => '`im_screen_name` varchar(64)',
2580 'openid' => '`openid` varchar(255)',
2581 'world_region' => '`world_region` varchar(128)',
2582 'url' => '`url` varchar(128)',
2583 'groups' => '`groups` text',
2584 'tags' => '`tags` text',
2585 'notes' => '`notes` text',
0a3b035f 2586 ];
2587 if (!$isContactExport) {
2588 unset($columns['groups']);
2589 unset($columns['tags']);
2590 unset($columns['notes']);
2591 }
2592 return $columns;
2593 }
2594
2595 /**
2596 * Get Case SQL columns.
2597 *
2598 * @return array
2599 */
2600 protected function getCaseSqlColumns() {
2601 return [
f61dd144
SL
2602 'case_start_date' => '`case_start_date` varchar(32)',
2603 'case_end_date' => '`case_end_date` varchar(32)',
2604 'case_subject' => '`case_subject` varchar(128)',
2605 'case_source_contact_id' => '`case_source_contact_id` varchar(255)',
2606 'case_activity_status' => '`case_activity_status` text',
2607 'case_activity_duration' => '`case_activity_duration` text',
2608 'case_activity_medium_id' => '`case_activity_medium_id` varchar(255)',
2609 'case_activity_details' => '`case_activity_details` text',
2610 'case_activity_is_auto' => '`case_activity_is_auto` text',
2611 'contact_id' => '`contact_id` varchar(16)',
2612 'case_id' => '`case_id` varchar(16)',
2613 'case_activity_subject' => '`case_activity_subject` text',
2614 'case_status' => '`case_status` text',
2615 'case_type' => '`case_type` text',
2616 'case_role' => '`case_role` text',
2617 'case_deleted' => '`case_deleted` varchar(16)',
2618 'case_recent_activity_date' => '`case_recent_activity_date` text',
2619 'case_recent_activity_type' => '`case_recent_activity_type` text',
2620 'case_scheduled_activity_date' => '`case_scheduled_activity_date` text',
0a3b035f 2621 ];
2622 }
2623
2624 /**
2625 * Get activity sql columns.
2626 *
2627 * @return array
2628 */
2629 protected function getActivitySqlColumns() {
2630 return [
f61dd144
SL
2631 'activity_id' => '`activity_id` varchar(16)',
2632 'activity_type' => '`activity_type` varchar(255)',
2633 'activity_type_id' => '`activity_type_id` varchar(16)',
2634 'activity_subject' => '`activity_subject` varchar(255)',
2635 'activity_date_time' => '`activity_date_time` varchar(32)',
2636 'activity_duration' => '`activity_duration` varchar(16)',
2637 'activity_location' => '`activity_location` varchar(255)',
2638 'activity_details' => '`activity_details` longtext',
2639 'activity_status' => '`activity_status` varchar(255)',
2640 'activity_priority' => '`activity_priority` varchar(255)',
2641 'source_contact' => '`source_contact` varchar(255)',
2642 'source_record_id' => '`source_record_id` varchar(255)',
2643 'activity_is_test' => '`activity_is_test` varchar(16)',
2644 'activity_campaign_id' => '`activity_campaign_id` varchar(16)',
2645 'result' => '`result` text',
2646 'activity_engagement_level' => '`activity_engagement_level` varchar(16)',
2647 'parent_id' => '`parent_id` varchar(255)',
0a3b035f 2648 ];
2649 }
2650
2651 /**
2652 * Get participant sql columns.
2653 *
2654 * @return array
2655 */
2656 protected function getParticipantSqlColumns() {
2657 return [
f61dd144
SL
2658 'event_id' => '`event_id` varchar(16)',
2659 'event_title' => '`event_title` varchar(255)',
2660 'event_start_date' => '`event_start_date` varchar(32)',
2661 'event_end_date' => '`event_end_date` varchar(32)',
2662 'event_type' => '`event_type` varchar(255)',
2663 'participant_id' => '`participant_id` varchar(16)',
2664 'participant_status' => '`participant_status` varchar(255)',
2665 'participant_status_id' => '`participant_status_id` varchar(16)',
2666 'participant_role' => '`participant_role` varchar(255)',
2667 'participant_role_id' => '`participant_role_id` varchar(128)',
2668 'participant_note' => '`participant_note` text',
2669 'participant_register_date' => '`participant_register_date` varchar(32)',
2670 'participant_source' => '`participant_source` varchar(128)',
2671 'participant_fee_level' => '`participant_fee_level` longtext',
2672 'participant_is_test' => '`participant_is_test` varchar(16)',
2673 'participant_is_pay_later' => '`participant_is_pay_later` varchar(16)',
2674 'participant_fee_amount' => '`participant_fee_amount` varchar(32)',
2675 'participant_discount_name' => '`participant_discount_name` varchar(16)',
2676 'participant_fee_currency' => '`participant_fee_currency` varchar(3)',
2677 'participant_registered_by_id' => '`participant_registered_by_id` varchar(16)',
2678 'participant_campaign_id' => '`participant_campaign_id` varchar(16)',
0a3b035f 2679 ];
2680 }
2681
2682 /**
2683 * Get contribution sql columns.
2684 *
2685 * @return array
2686 */
2687 public function getContributionSqlColumns() {
2688 return [
f61dd144
SL
2689 'civicrm_primary_id' => '`civicrm_primary_id` varchar(16)',
2690 'contact_type' => '`contact_type` varchar(64)',
2691 'contact_sub_type' => '`contact_sub_type` varchar(255)',
2692 'do_not_email' => '`do_not_email` varchar(16)',
2693 'do_not_phone' => '`do_not_phone` varchar(16)',
2694 'do_not_mail' => '`do_not_mail` varchar(16)',
2695 'do_not_sms' => '`do_not_sms` varchar(16)',
2696 'do_not_trade' => '`do_not_trade` varchar(16)',
2697 'is_opt_out' => '`is_opt_out` varchar(16)',
2698 'legal_identifier' => '`legal_identifier` varchar(32)',
2699 'external_identifier' => '`external_identifier` varchar(64)',
2700 'sort_name' => '`sort_name` varchar(128)',
2701 'display_name' => '`display_name` varchar(128)',
2702 'nick_name' => '`nick_name` varchar(128)',
2703 'legal_name' => '`legal_name` varchar(128)',
2704 'image_url' => '`image_url` longtext',
2705 'preferred_communication_method' => '`preferred_communication_method` varchar(255)',
2706 'preferred_language' => '`preferred_language` varchar(5)',
2707 'preferred_mail_format' => '`preferred_mail_format` varchar(8)',
2708 'hash' => '`hash` varchar(32)',
2709 'contact_source' => '`contact_source` varchar(255)',
2710 'first_name' => '`first_name` varchar(64)',
2711 'middle_name' => '`middle_name` varchar(64)',
2712 'last_name' => '`last_name` varchar(64)',
2713 'prefix_id' => '`prefix_id` varchar(255)',
2714 'suffix_id' => '`suffix_id` varchar(255)',
2715 'formal_title' => '`formal_title` varchar(64)',
2716 'communication_style_id' => '`communication_style_id` varchar(255)',
2717 'email_greeting_id' => '`email_greeting_id` varchar(16)',
2718 'postal_greeting_id' => '`postal_greeting_id` varchar(16)',
2719 'addressee_id' => '`addressee_id` varchar(16)',
2720 'job_title' => '`job_title` varchar(255)',
2721 'gender_id' => '`gender_id` varchar(255)',
2722 'birth_date' => '`birth_date` varchar(32)',
2723 'is_deceased' => '`is_deceased` varchar(16)',
2724 'deceased_date' => '`deceased_date` varchar(32)',
2725 'household_name' => '`household_name` varchar(128)',
2726 'organization_name' => '`organization_name` varchar(128)',
2727 'sic_code' => '`sic_code` varchar(8)',
2728 'user_unique_id' => '`user_unique_id` varchar(255)',
2729 'current_employer_id' => '`current_employer_id` varchar(16)',
2730 'contact_is_deleted' => '`contact_is_deleted` varchar(16)',
2731 'created_date' => '`created_date` varchar(32)',
2732 'modified_date' => '`modified_date` varchar(32)',
2733 'addressee' => '`addressee` varchar(255)',
2734 'email_greeting' => '`email_greeting` varchar(255)',
2735 'postal_greeting' => '`postal_greeting` varchar(255)',
2736 'current_employer' => '`current_employer` varchar(128)',
2737 'location_type' => '`location_type` text',
2738 'street_address' => '`street_address` varchar(96)',
2739 'street_number' => '`street_number` varchar(16)',
2740 'street_number_suffix' => '`street_number_suffix` varchar(8)',
2741 'street_name' => '`street_name` varchar(64)',
2742 'street_unit' => '`street_unit` varchar(16)',
2743 'supplemental_address_1' => '`supplemental_address_1` varchar(96)',
2744 'supplemental_address_2' => '`supplemental_address_2` varchar(96)',
2745 'supplemental_address_3' => '`supplemental_address_3` varchar(96)',
2746 'city' => '`city` varchar(64)',
2747 'postal_code_suffix' => '`postal_code_suffix` varchar(12)',
2748 'postal_code' => '`postal_code` varchar(64)',
2749 'geo_code_1' => '`geo_code_1` varchar(32)',
2750 'geo_code_2' => '`geo_code_2` varchar(32)',
2751 'address_name' => '`address_name` varchar(255)',
2752 'master_id' => '`master_id` varchar(128)',
2753 'county' => '`county` varchar(64)',
2754 'state_province' => '`state_province` varchar(64)',
2755 'country' => '`country` varchar(64)',
2756 'phone' => '`phone` varchar(32)',
2757 'phone_ext' => '`phone_ext` varchar(16)',
2758 'email' => '`email` varchar(254)',
2759 'on_hold' => '`on_hold` varchar(16)',
2760 'is_bulkmail' => '`is_bulkmail` varchar(16)',
2761 'signature_text' => '`signature_text` longtext',
2762 'signature_html' => '`signature_html` longtext',
2763 'im_provider' => '`im_provider` text',
2764 'im_screen_name' => '`im_screen_name` varchar(64)',
2765 'openid' => '`openid` varchar(255)',
2766 'world_region' => '`world_region` varchar(128)',
2767 'url' => '`url` varchar(128)',
2768 'phone_type_id' => '`phone_type_id` varchar(16)',
2769 'financial_type' => '`financial_type` varchar(255)',
2770 'contribution_source' => '`contribution_source` varchar(255)',
2771 'receive_date' => '`receive_date` varchar(32)',
2772 'thankyou_date' => '`thankyou_date` varchar(32)',
2773 'contribution_cancel_date' => '`contribution_cancel_date` varchar(32)',
2774 'total_amount' => '`total_amount` varchar(32)',
2775 'accounting_code' => '`accounting_code` varchar(64)',
2776 'payment_instrument' => '`payment_instrument` varchar(255)',
2777 'payment_instrument_id' => '`payment_instrument_id` varchar(16)',
2778 'contribution_check_number' => '`contribution_check_number` varchar(255)',
2779 'non_deductible_amount' => '`non_deductible_amount` varchar(32)',
2780 'fee_amount' => '`fee_amount` varchar(32)',
2781 'net_amount' => '`net_amount` varchar(32)',
2782 'trxn_id' => '`trxn_id` varchar(255)',
2783 'invoice_id' => '`invoice_id` varchar(255)',
2784 'invoice_number' => '`invoice_number` varchar(255)',
2785 'currency' => '`currency` varchar(3)',
2786 'cancel_reason' => '`cancel_reason` longtext',
2787 'receipt_date' => '`receipt_date` varchar(32)',
2788 'is_test' => '`is_test` varchar(16)',
2789 'is_pay_later' => '`is_pay_later` varchar(16)',
2790 'contribution_status' => '`contribution_status` varchar(255)',
2791 'contribution_recur_id' => '`contribution_recur_id` varchar(16)',
2792 'amount_level' => '`amount_level` longtext',
2793 'contribution_note' => '`contribution_note` text',
2794 'contribution_batch' => '`contribution_batch` text',
2795 'contribution_campaign_title' => '`contribution_campaign_title` varchar(255)',
2796 'contribution_campaign_id' => '`contribution_campaign_id` varchar(16)',
2797 'contribution_soft_credit_name' => '`contribution_soft_credit_name` varchar(255)',
2798 'contribution_soft_credit_amount' => '`contribution_soft_credit_amount` varchar(255)',
2799 'contribution_soft_credit_type' => '`contribution_soft_credit_type` varchar(255)',
2800 'contribution_soft_credit_contact_id' => '`contribution_soft_credit_contact_id` varchar(255)',
2801 'contribution_soft_credit_contribution_id' => '`contribution_soft_credit_contribution_id` varchar(255)',
0a3b035f 2802 ];
2803 }
2804
2805 /**
2806 * Get pledge sql columns.
2807 *
2808 * @return array
2809 */
2810 public function getPledgeSqlColumns() {
2811 return [
f61dd144
SL
2812 'pledge_id' => '`pledge_id` varchar(16)',
2813 'pledge_amount' => '`pledge_amount` varchar(32)',
2814 'pledge_total_paid' => '`pledge_total_paid` text',
2815 'pledge_create_date' => '`pledge_create_date` varchar(32)',
2816 'pledge_start_date' => '`pledge_start_date` varchar(32)',
2817 'pledge_next_pay_date' => '`pledge_next_pay_date` text',
2818 'pledge_next_pay_amount' => '`pledge_next_pay_amount` text',
2819 'pledge_status' => '`pledge_status` varchar(255)',
2820 'pledge_is_test' => '`pledge_is_test` varchar(16)',
2821 'pledge_contribution_page_id' => '`pledge_contribution_page_id` varchar(255)',
2822 'pledge_financial_type' => '`pledge_financial_type` text',
2823 'pledge_frequency_interval' => '`pledge_frequency_interval` varchar(255)',
2824 'pledge_frequency_unit' => '`pledge_frequency_unit` varchar(255)',
2825 'pledge_currency' => '`pledge_currency` text',
2826 'pledge_campaign_id' => '`pledge_campaign_id` varchar(16)',
2827 'pledge_balance_amount' => '`pledge_balance_amount` text',
2828 'pledge_payment_id' => '`pledge_payment_id` varchar(16)',
2829 'pledge_payment_scheduled_amount' => '`pledge_payment_scheduled_amount` varchar(32)',
2830 'pledge_payment_scheduled_date' => '`pledge_payment_scheduled_date` varchar(32)',
2831 'pledge_payment_paid_amount' => '`pledge_payment_paid_amount` text',
2832 'pledge_payment_paid_date' => '`pledge_payment_paid_date` text',
2833 'pledge_payment_reminder_date' => '`pledge_payment_reminder_date` varchar(32)',
2834 'pledge_payment_reminder_count' => '`pledge_payment_reminder_count` varchar(16)',
2835 'pledge_payment_status' => '`pledge_payment_status` varchar(255)',
0a3b035f 2836 ];
2837 }
2838
2839 /**
2840 * Get membership sql columns.
2841 *
2842 * @return array
2843 */
2844 public function getMembershipSqlColumns() {
2845 return [
f61dd144
SL
2846 'membership_type' => '`membership_type` varchar(128)',
2847 'member_is_test' => '`member_is_test` varchar(16)',
2848 'member_is_pay_later' => '`member_is_pay_later` varchar(16)',
2849 'membership_join_date' => '`membership_join_date` varchar(32)',
2850 'membership_start_date' => '`membership_start_date` varchar(32)',
2851 'membership_end_date' => '`membership_end_date` varchar(32)',
2852 'membership_source' => '`membership_source` varchar(128)',
2853 'membership_status' => '`membership_status` varchar(255)',
2854 'membership_id' => '`membership_id` varchar(16)',
2855 'owner_membership_id' => '`owner_membership_id` varchar(16)',
2856 'max_related' => '`max_related` varchar(16)',
2857 'membership_recur_id' => '`membership_recur_id` varchar(16)',
2858 'member_campaign_id' => '`member_campaign_id` varchar(16)',
2859 'member_is_override' => '`member_is_override` varchar(16)',
0a3b035f 2860 ];
2861 }
2862
a16a432a 2863 /**
2864 * Change our location types so we have some edge cases in the mix.
2865 *
2866 * - a space in the name
2867 * - name differs from label
2868 * - non-anglo char in the label (not valid in the name).
2869 */
2870 protected function diversifyLocationTypes() {
2871 $this->locationTypes['Main'] = $this->callAPISuccess('Location_type', 'get', [
2872 'name' => 'Main',
2873 'return' => 'id',
2874 'api.LocationType.Create' => ['display_name' => 'Méin'],
2875 ]);
2876 $this->locationTypes['Whare Kai'] = $this->callAPISuccess('Location_type', 'create', [
2877 'name' => 'Whare Kai',
2878 'display_name' => 'Whare Kai',
2879 ]);
2880 }
2881
12a6fdef 2882 /**
2883 * Test export components.
2884 *
2885 * Tests the exportComponents function with the provided parameters.
2886 *
2887 * This exportComponents will export a csv but it will also throw a prematureExitException
2888 * which we catch & grab the processor from.
2889 *
2890 * $this->processor is set to the export processor.
2891 *
2892 * @param $params
2893 *
2894 * @throws \CRM_Core_Exception
c746d2b2 2895 * @throws \League\Csv\Exception
12a6fdef 2896 */
2897 protected function doExportTest($params) {
2898 $this->startCapturingOutput();
2899 try {
0b60a345 2900 $exportMode = CRM_Utils_Array::value('exportMode', $params, CRM_Export_Form_Select::CONTACT_EXPORT);
2901 $ids = CRM_Utils_Array::value('ids', $params, ($exportMode === CRM_Export_Form_Select::CONTACT_EXPORT ? $this->contactIDs : []));
2902 $defaultClause = (empty($ids) ? NULL : "contact_a.id IN (" . implode(',', $ids) . ")");
12a6fdef 2903 CRM_Export_BAO_Export::exportComponents(
2904 CRM_Utils_Array::value('selectAll', $params, (empty($params['fields']))),
0b60a345 2905 $ids,
12a6fdef 2906 CRM_Utils_Array::value('params', $params, []),
2907 CRM_Utils_Array::value('order', $params),
e15ec147 2908 CRM_Utils_Array::value('fields', $params, []),
12a6fdef 2909 CRM_Utils_Array::value('moreReturnProperties', $params),
0b60a345 2910 $exportMode,
45cee669 2911 CRM_Utils_Array::value('componentClause', $params, $defaultClause),
12a6fdef 2912 CRM_Utils_Array::value('componentTable', $params),
2913 CRM_Utils_Array::value('mergeSameAddress', $params, FALSE),
0b60a345 2914 CRM_Utils_Array::value('mergeSameHousehold', $params, FALSE),
2915 CRM_Utils_Array::value('exportParams', $params, [])
12a6fdef 2916 );
2917 }
2918 catch (CRM_Core_Exception_PrematureExitException $e) {
2919 $this->processor = $e->errorData['processor'];
c746d2b2 2920 $this->csv = $this->captureOutputToCSV();
12a6fdef 2921 return;
2922 }
2923 $this->fail('We expected a premature exit exception');
2924 }
2925
c2aec6ad 2926 /**
2927 * Assert that the received array matches the expected, ignoring time sensitive fields.
2928 *
2929 * @param array $expected
2930 * @param array $row
f143b245 2931 * @param array $alternatives
c2aec6ad 2932 */
f143b245 2933 protected function assertExpectedOutput(array $expected, array $row, array $alternatives = []) {
c2aec6ad 2934 $variableFields = ['Created Date', 'Modified Date', 'Contact Hash'];
2935 foreach ($expected as $key => $value) {
2936 if (in_array($key, $variableFields)) {
2937 $this->assertTrue(!empty($row[$key]));
2938 }
f143b245
SL
2939 elseif (array_key_exists($key, $alternatives)) {
2940 $this->assertContains($row[$key], $alternatives[$key]);
2941 }
c2aec6ad 2942 else {
2943 $this->assertEquals($value, $row[$key]);
2944 }
2945 }
2946 }
2947
978f5005 2948 /**
2949 * Test get preview function on export processor.
2950 *
2951 * @throws \CRM_Core_Exception
2952 */
2953 public function testExportGetPreview() {
2954 $this->setUpContactExportData();
2955 $fields = [
2956 ['Individual', 'first_name'],
2957 ['Individual', 'last_name'],
2958 ['Individual', 'street_address', 1],
2959 ['Individual', 'city', 1],
2960 ['Individual', 'country', 1],
2961 ['Individual', 'email', 1],
2962 ];
2963 $mappedFields = [];
2964 foreach ($fields as $field) {
2965 $mappedFields[] = CRM_Core_BAO_Mapping::getMappingParams([], $field);
2966 }
2967 $processor = new CRM_Export_BAO_ExportProcessor(FALSE, $mappedFields,
2968 'AND');
2969 $processor->setComponentClause('contact_a.id IN (' . implode(',', $this->contactIDs) . ')');
2970 $result = $processor->getPreview(2);
2971 $this->assertEquals([
2972 [
2973 'first_name' => 'Anthony',
2974 'last_name' => 'Anderson',
2975 'Home-street_address' => 'Ambachtstraat 23',
2976 'Home-city' => 'Brummen',
2977 'Home-country' => 'Netherlands',
2978 'Home-email' => 'home@example.com',
2979 ],
2980 [
2981 'first_name' => 'Anthony',
2982 'last_name' => 'Anderson',
2983 'Home-street_address' => '',
2984 'Home-city' => '',
2985 'Home-country' => '',
2986 'Home-email' => 'anthony_anderson@civicrm.org',
2987 ],
2988 ], $result);
2989 }
2990
0b60a345 2991 /**
2992 * Set up contacts which will be merged with the same address option.
2993 *
2994 * @throws \CRM_Core_Exception
2995 */
2996 protected function setUpContactSameAddressExportData() {
2997 $this->setUpContactExportData();
2998 $this->contactIDs[] = $contact3 = $this->individualCreate(['first_name' => 'Sarah', 'last_name' => 'Smith', 'prefix_id' => 'Dr.']);
2999 // Create address for contact A.
3000 $params = [
3001 'contact_id' => $contact3,
3002 'location_type_id' => 'Home',
3003 'street_address' => 'Ambachtstraat 23',
3004 'postal_code' => '6971 BN',
3005 'country_id' => '1152',
3006 'city' => 'Brummen',
3007 'is_primary' => 1,
3008 ];
3009 $this->callAPISuccess('address', 'create', $params);
3010 }
3011
ef51caa8 3012}