From 3663269c9965d84d960d66a0e4f2983f8b9c19ed Mon Sep 17 00:00:00 2001 From: eileen Date: Sat, 14 Jul 2018 13:04:23 +1200 Subject: [PATCH] Extract bulk of the transformation for each field to its own function --- CRM/Export/BAO/Export.php | 200 +++++++++-------- tests/phpunit/CRM/Export/BAO/ExportTest.php | 233 ++++++++++++++++++++ 2 files changed, 341 insertions(+), 92 deletions(-) diff --git a/CRM/Export/BAO/Export.php b/CRM/Export/BAO/Export.php index 4fb071ff20..38456651a6 100644 --- a/CRM/Export/BAO/Export.php +++ b/CRM/Export/BAO/Export.php @@ -355,7 +355,7 @@ class CRM_Export_BAO_Export { $processor = new CRM_Export_BAO_ExportProcessor($exportMode); $returnProperties = array(); - $paymentFields = $selectedPaymentFields = FALSE; + $paymentFields = $selectedPaymentFields = $paymentTableId = FALSE; $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id'); // Warning - this imProviders var is used in a somewhat fragile way - don't rename it @@ -732,102 +732,13 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c } } - if ($field == 'id') { - $row[$field] = $iterationDAO->contact_id; - // special case for calculated field - } - elseif ($field == 'source_contact_id') { - $row[$field] = $iterationDAO->contact_id; - } - elseif ($field == 'pledge_balance_amount') { - $row[$field] = $iterationDAO->pledge_amount - $iterationDAO->pledge_total_paid; - // special case for calculated field - } - elseif ($field == 'pledge_next_pay_amount') { - $row[$field] = $iterationDAO->pledge_next_pay_amount + $iterationDAO->pledge_outstanding_amount; - } - elseif (array_key_exists($field, self::$relationshipTypes)) { + if (array_key_exists($field, self::$relationshipTypes)) { $relDAO = CRM_Utils_Array::value($iterationDAO->contact_id, $allRelContactArray[$field]); $relationQuery[$field]->convertToPseudoNames($relDAO); self::fetchRelationshipDetails($relDAO, $value, $field, $row); } - elseif (isset($fieldValue) && - $fieldValue != '' - ) { - //check for custom data - if ($cfID = CRM_Core_BAO_CustomField::getKeyID($field)) { - $row[$field] = CRM_Core_BAO_CustomField::displayValue($fieldValue, $cfID); - } - - elseif (in_array($field, array( - 'email_greeting', - 'postal_greeting', - 'addressee', - ))) { - //special case for greeting replacement - $fldValue = "{$field}_display"; - $row[$field] = $iterationDAO->$fldValue; - } - else { - //normal fields with a touch of CRM-3157 - switch ($field) { - case 'country': - case 'world_region': - $row[$field] = $i18n->crm_translate($fieldValue, array('context' => 'country')); - break; - - case 'state_province': - $row[$field] = $i18n->crm_translate($fieldValue, array('context' => 'province')); - break; - - case 'gender': - case 'preferred_communication_method': - case 'preferred_mail_format': - case 'communication_style': - $row[$field] = $i18n->crm_translate($fieldValue); - break; - - default: - if (isset($metadata[$field])) { - // No I don't know why we do it this way & whether we could - // make better use of pseudoConstants. - if (!empty($metadata[$field]['context'])) { - $row[$field] = $i18n->crm_translate($fieldValue, $metadata[$field]); - break; - } - if (!empty($metadata[$field]['pseudoconstant'])) { - // This is not our normal syntax for pseudoconstants but I am a bit loath to - // call an external function until sure it is not increasing php processing given this - // may be iterated 100,000 times & we already have the $imProvider var loaded. - // That can be next refactor... - // Yes - definitely feeling hatred for this bit of code - I know you will beat me up over it's awfulness - // but I have to reach a stable point.... - $varName = $metadata[$field]['pseudoconstant']['var']; - $labels = $$varName; - $row[$field] = $labels[$fieldValue]; - break; - } - - } - $row[$field] = $fieldValue; - break; - } - } - } - elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) { - $paymentData = CRM_Utils_Array::value($iterationDAO->$paymentTableId, $paymentDetails); - $payFieldMapper = array( - 'componentPaymentField_total_amount' => 'total_amount', - 'componentPaymentField_contribution_status' => 'contribution_status', - 'componentPaymentField_payment_instrument' => 'pay_instru', - 'componentPaymentField_transaction_id' => 'trxn_id', - 'componentPaymentField_received_date' => 'receive_date', - ); - $row[$field] = CRM_Utils_Array::value($payFieldMapper[$field], $paymentData, ''); - } else { - // if field is empty or null - $row[$field] = ''; + $row[$field] = self::getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $selectedPaymentFields, $paymentDetails, $paymentTableId); } } @@ -2195,4 +2106,109 @@ WHERE {$whereClause}"; return array($relationQuery, $allRelContactArray); } + /** + * @param $field + * @param $iterationDAO + * @param $fieldValue + * @param $i18n + * @param $metadata + * @param $selectedPaymentFields + * @param $paymentDetails + * @param string $paymentTableId + * @return string + */ + protected static function getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $selectedPaymentFields, $paymentDetails, $paymentTableId) { + + if ($field == 'id') { + return $iterationDAO->contact_id; + // special case for calculated field + } + elseif ($field == 'source_contact_id') { + return $iterationDAO->contact_id; + } + elseif ($field == 'pledge_balance_amount') { + return $iterationDAO->pledge_amount - $iterationDAO->pledge_total_paid; + // special case for calculated field + } + elseif ($field == 'pledge_next_pay_amount') { + return $iterationDAO->pledge_next_pay_amount + $iterationDAO->pledge_outstanding_amount; + } + elseif (isset($fieldValue) && + $fieldValue != '' + ) { + //check for custom data + if ($cfID = CRM_Core_BAO_CustomField::getKeyID($field)) { + return CRM_Core_BAO_CustomField::displayValue($fieldValue, $cfID); + } + + elseif (in_array($field, array( + 'email_greeting', + 'postal_greeting', + 'addressee', + ))) { + //special case for greeting replacement + $fldValue = "{$field}_display"; + return $iterationDAO->$fldValue; + } + else { + //normal fields with a touch of CRM-3157 + switch ($field) { + case 'country': + case 'world_region': + return $i18n->crm_translate($fieldValue, array('context' => 'country')); + + case 'state_province': + return $i18n->crm_translate($fieldValue, array('context' => 'province')); + + case 'gender': + case 'preferred_communication_method': + case 'preferred_mail_format': + case 'communication_style': + return $i18n->crm_translate($fieldValue); + + default: + if (isset($metadata[$field])) { + // No I don't know why we do it this way & whether we could + // make better use of pseudoConstants. + if (!empty($metadata[$field]['context'])) { + return $i18n->crm_translate($fieldValue, $metadata[$field]); + } + if (!empty($metadata[$field]['pseudoconstant'])) { + // This is not our normal syntax for pseudoconstants but I am a bit loath to + // call an external function until sure it is not increasing php processing given this + // may be iterated 100,000 times & we already have the $imProvider var loaded. + // That can be next refactor... + // Yes - definitely feeling hatred for this bit of code - I know you will beat me up over it's awfulness + // but I have to reach a stable point.... + $varName = $metadata[$field]['pseudoconstant']['var']; + if ($varName === 'imProviders') { + return CRM_Core_PseudoConstant::getLabel('CRM_Core_DAO_IM', 'provider_id', $fieldValue); + } + if ($varName === 'phoneTypes') { + return CRM_Core_PseudoConstant::getLabel('CRM_Core_DAO_Phone', 'phone_type_id', $fieldValue); + } + } + + } + return $fieldValue; + } + } + } + elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) { + $paymentData = CRM_Utils_Array::value($iterationDAO->$paymentTableId, $paymentDetails); + $payFieldMapper = array( + 'componentPaymentField_total_amount' => 'total_amount', + 'componentPaymentField_contribution_status' => 'contribution_status', + 'componentPaymentField_payment_instrument' => 'pay_instru', + 'componentPaymentField_transaction_id' => 'trxn_id', + 'componentPaymentField_received_date' => 'receive_date', + ); + return CRM_Utils_Array::value($payFieldMapper[$field], $paymentData, ''); + } + else { + // if field is empty or null + return ''; + } + } + } diff --git a/tests/phpunit/CRM/Export/BAO/ExportTest.php b/tests/phpunit/CRM/Export/BAO/ExportTest.php index 175bbd4693..bbe82a5288 100644 --- a/tests/phpunit/CRM/Export/BAO/ExportTest.php +++ b/tests/phpunit/CRM/Export/BAO/ExportTest.php @@ -443,6 +443,214 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase { } } + /** + * Test master_address_id field. + */ + public function testExportCustomData() { + $this->setUpContactExportData(); + + $customData = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'ContactTest.php'); + + $this->callAPISuccess('Contact', 'create', [ + 'id' => $this->contactIDs[1], + 'custom_' . $customData['custom_field_id'] => 'BlahdeBlah', + 'api.Address.create' => ['location_type_id' => 'Billing', 'city' => 'Waipu'], + ]); + $selectedFields = [ + ['Individual', 'city', CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Address', 'location_type_id', 'Billing')], + ['Individual', 'custom_1'], + ]; + + list($tableName, $sqlColumns) = $this->doExport($selectedFields, $this->contactIDs[1]); + $this->assertEquals([ + 'billing_city' => 'billing_city text', + 'custom_1' => 'custom_1 varchar(255)', + ], $sqlColumns); + + $dao = CRM_Core_DAO::executeQuery('SELECT * FROM ' . $tableName); + while ($dao->fetch()) { + $this->assertEquals('BlahdeBlah', $dao->custom_1); + $this->assertEquals('Waipu', $dao->billing_city); + } + } + + /** + * Attempt to do a fairly full export of location data. + */ + public function testExportIMData() { + // Use default providers. + $providers = ['AIM', 'GTalk', 'Jabber', 'MSN', 'Skype', 'Yahoo']; + $locationTypes = ['Billing', 'Home', 'Main', 'Other']; + + $this->contactIDs[] = $this->individualCreate(); + $this->contactIDs[] = $this->individualCreate(); + $this->contactIDs[] = $this->householdCreate(); + $this->contactIDs[] = $this->organizationCreate(); + foreach ($this->contactIDs as $contactID) { + foreach ($providers as $provider) { + foreach ($locationTypes as $locationType) { + $this->callAPISuccess('IM', 'create', [ + 'contact_id' => $contactID, + 'location_type_id' => $locationType, + 'provider_id' => $provider, + 'name' => $locationType . $provider . $contactID, + ]); + } + } + } + + $relationships = [ + $this->contactIDs[1] => ['label' => 'Spouse of'], + $this->contactIDs[2] => ['label' => 'Household Member of'], + $this->contactIDs[3] => ['label' => 'Employee of'] + ]; + + foreach ($relationships as $contactID => $relationshipType) { + $relationshipTypeID = $this->callAPISuccess('RelationshipType', 'getvalue', ['label_a_b' => $relationshipType['label'], 'return' => 'id']); + $result = $this->callAPISuccess('Relationship', 'create', [ + 'contact_id_a' => $this->contactIDs[0], + 'relationship_type_id' => $relationshipTypeID, + 'contact_id_b' => $contactID + ]); + $relationships[$contactID]['id'] = $result['id']; + $relationships[$contactID]['relationship_type_id'] = $relationshipTypeID; + } + + $fields = [['Individual', 'contact_id']]; + // ' ' denotes primary location type. + foreach (array_merge($locationTypes, [' ']) as $locationType) { + $fields[] = [ + 'Individual', + 'im_provider', + CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'location_type_id', $locationType), + ]; + foreach ($relationships as $contactID => $relationship) { + $fields[] = [ + 'Individual', + $relationship['relationship_type_id'] . '_a_b', + 'im_provider', + CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'location_type_id', $locationType), + ]; + } + foreach ($providers as $provider) { + $fields[] = [ + 'Individual', + 'im', + CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'location_type_id', $locationType), + CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'provider_id', $provider), + ]; + foreach ($relationships as $contactID => $relationship) { + $fields[] = [ + 'Individual', + $relationship['relationship_type_id'] . '_a_b', + 'im', + CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'location_type_id', $locationType), + CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_IM', 'provider_id', $provider), + ]; + } + } + } + list($tableName, $sqlColumns) = $this->doExport($fields, $this->contactIDs[0]); + + $dao = CRM_Core_DAO::executeQuery('SELECT * FROM ' . $tableName); + while ($dao->fetch()) { + $id = $dao->contact_id; + $this->assertEquals('AIM', $dao->billing_im_provider); + $this->assertEquals('BillingJabber' . $id, $dao->billing_im_screen_name_jabber); + $this->assertEquals('BillingSkype' . $id, $dao->billing_im_screen_name_skype); + foreach ($relationships as $relatedContactID => $relationship) { + $relationshipString = $field = $relationship['relationship_type_id'] . '_a_b'; + $field = $relationshipString . '_billing_im_screen_name_yahoo'; + $this->assertEquals('BillingYahoo' . $relatedContactID, $dao->$field); + // @todo efforts to output 'im_provider' for related contacts seem to be giving a blank field. + } + } + + // early return for now until we solve a leakage issue. + return; + + $this->assertEquals([ + 'billing_im_provider' => 'billing_im_provider text', + 'billing_im_screen_name' => 'billing_im_screen_name text', + 'billing_im_screen_name_jabber' => 'billing_im_screen_name_jabber text', + 'billing_im_screen_name_skype' => 'billing_im_screen_name_skype text', + 'billing_im_screen_name_yahoo' => 'billing_im_screen_name_yahoo text', + 'home_im_provider' => 'home_im_provider text', + 'home_im_screen_name' => 'home_im_screen_name text', + 'home_im_screen_name_jabber' => 'home_im_screen_name_jabber text', + 'home_im_screen_name_skype' => 'home_im_screen_name_skype text', + 'home_im_screen_name_yahoo' => 'home_im_screen_name_yahoo text', + 'main_im_provider' => 'main_im_provider text', + 'main_im_screen_name' => 'main_im_screen_name text', + 'main_im_screen_name_jabber' => 'main_im_screen_name_jabber text', + 'main_im_screen_name_skype' => 'main_im_screen_name_skype text', + 'main_im_screen_name_yahoo' => 'main_im_screen_name_yahoo text', + 'other_im_provider' => 'other_im_provider text', + 'other_im_screen_name' => 'other_im_screen_name text', + 'other_im_screen_name_jabber' => 'other_im_screen_name_jabber text', + 'other_im_screen_name_skype' => 'other_im_screen_name_skype text', + 'other_im_screen_name_yahoo' => 'other_im_screen_name_yahoo text', + 'im_provider' => 'im_provider text', + 'im' => 'im varchar(64)', + 'contact_id' => 'contact_id varchar(255)', + '2_a_b_im_provider' => '2_a_b_im_provider text', + '2_a_b_billing_im_screen_name' => '2_a_b_billing_im_screen_name text', + '2_a_b_billing_im_screen_name_jabber' => '2_a_b_billing_im_screen_name_jabber text', + '2_a_b_billing_im_screen_name_skype' => '2_a_b_billing_im_screen_name_skype text', + '2_a_b_billing_im_screen_name_yahoo' => '2_a_b_billing_im_screen_name_yahoo text', + '2_a_b_home_im_screen_name' => '2_a_b_home_im_screen_name text', + '2_a_b_home_im_screen_name_jabber' => '2_a_b_home_im_screen_name_jabber text', + '2_a_b_home_im_screen_name_skype' => '2_a_b_home_im_screen_name_skype text', + '2_a_b_home_im_screen_name_yahoo' => '2_a_b_home_im_screen_name_yahoo text', + '2_a_b_main_im_screen_name' => '2_a_b_main_im_screen_name text', + '2_a_b_main_im_screen_name_jabber' => '2_a_b_main_im_screen_name_jabber text', + '2_a_b_main_im_screen_name_skype' => '2_a_b_main_im_screen_name_skype text', + '2_a_b_main_im_screen_name_yahoo' => '2_a_b_main_im_screen_name_yahoo text', + '2_a_b_other_im_screen_name' => '2_a_b_other_im_screen_name text', + '2_a_b_other_im_screen_name_jabber' => '2_a_b_other_im_screen_name_jabber text', + '2_a_b_other_im_screen_name_skype' => '2_a_b_other_im_screen_name_skype text', + '2_a_b_other_im_screen_name_yahoo' => '2_a_b_other_im_screen_name_yahoo text', + '2_a_b_im' => '2_a_b_im text', + '8_a_b_im_provider' => '8_a_b_im_provider text', + '8_a_b_billing_im_screen_name' => '8_a_b_billing_im_screen_name text', + '8_a_b_billing_im_screen_name_jabber' => '8_a_b_billing_im_screen_name_jabber text', + '8_a_b_billing_im_screen_name_skype' => '8_a_b_billing_im_screen_name_skype text', + '8_a_b_billing_im_screen_name_yahoo' => '8_a_b_billing_im_screen_name_yahoo text', + '8_a_b_home_im_screen_name' => '8_a_b_home_im_screen_name text', + '8_a_b_home_im_screen_name_jabber' => '8_a_b_home_im_screen_name_jabber text', + '8_a_b_home_im_screen_name_skype' => '8_a_b_home_im_screen_name_skype text', + '8_a_b_home_im_screen_name_yahoo' => '8_a_b_home_im_screen_name_yahoo text', + '8_a_b_main_im_screen_name' => '8_a_b_main_im_screen_name text', + '8_a_b_main_im_screen_name_jabber' => '8_a_b_main_im_screen_name_jabber text', + '8_a_b_main_im_screen_name_skype' => '8_a_b_main_im_screen_name_skype text', + '8_a_b_main_im_screen_name_yahoo' => '8_a_b_main_im_screen_name_yahoo text', + '8_a_b_other_im_screen_name' => '8_a_b_other_im_screen_name text', + '8_a_b_other_im_screen_name_jabber' => '8_a_b_other_im_screen_name_jabber text', + '8_a_b_other_im_screen_name_skype' => '8_a_b_other_im_screen_name_skype text', + '8_a_b_other_im_screen_name_yahoo' => '8_a_b_other_im_screen_name_yahoo text', + '8_a_b_im' => '8_a_b_im text', + '5_a_b_im_provider' => '5_a_b_im_provider text', + '5_a_b_billing_im_screen_name' => '5_a_b_billing_im_screen_name text', + '5_a_b_billing_im_screen_name_jabber' => '5_a_b_billing_im_screen_name_jabber text', + '5_a_b_billing_im_screen_name_skype' => '5_a_b_billing_im_screen_name_skype text', + '5_a_b_billing_im_screen_name_yahoo' => '5_a_b_billing_im_screen_name_yahoo text', + '5_a_b_home_im_screen_name' => '5_a_b_home_im_screen_name text', + '5_a_b_home_im_screen_name_jabber' => '5_a_b_home_im_screen_name_jabber text', + '5_a_b_home_im_screen_name_skype' => '5_a_b_home_im_screen_name_skype text', + '5_a_b_home_im_screen_name_yahoo' => '5_a_b_home_im_screen_name_yahoo text', + '5_a_b_main_im_screen_name' => '5_a_b_main_im_screen_name text', + '5_a_b_main_im_screen_name_jabber' => '5_a_b_main_im_screen_name_jabber text', + '5_a_b_main_im_screen_name_skype' => '5_a_b_main_im_screen_name_skype text', + '5_a_b_main_im_screen_name_yahoo' => '5_a_b_main_im_screen_name_yahoo text', + '5_a_b_other_im_screen_name' => '5_a_b_other_im_screen_name text', + '5_a_b_other_im_screen_name_jabber' => '5_a_b_other_im_screen_name_jabber text', + '5_a_b_other_im_screen_name_skype' => '5_a_b_other_im_screen_name_skype text', + '5_a_b_other_im_screen_name_yahoo' => '5_a_b_other_im_screen_name_yahoo text', + '5_a_b_im' => '5_a_b_im text', + ], $sqlColumns); + + } + /** * Test master_address_id field. */ @@ -587,4 +795,29 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase { return array($householdID, $houseHoldTypeID); } + /** + * @param $selectedFields + * @return array + */ + protected function doExport($selectedFields, $id) { + list($tableName, $sqlColumns) = CRM_Export_BAO_Export::exportComponents( + TRUE, + array($id), + array(), + NULL, + $selectedFields, + NULL, + CRM_Export_Form_Select::CONTACT_EXPORT, + "contact_a.id IN ({$id})", + NULL, + FALSE, + FALSE, + array( + 'exportOption' => CRM_Export_Form_Select::CONTACT_EXPORT, + 'suppress_csv_for_testing' => TRUE, + ) + ); + return array($tableName, $sqlColumns); + } + } -- 2.25.1