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