diff --git a/1 b/1 new file mode 100644 index 000000000000..efd985e0dada --- /dev/null +++ b/1 @@ -0,0 +1,7 @@ +Merge commit 'refs/pull/12541/head' of https://github.com/civicrm/civicrm-core into redis + +# Please enter a commit message to explain why this merge is necessary, +# especially if it merges an updated upstream into a topic branch. +# +# Lines starting with '#' will be ignored, and an empty message aborts +# the commit. diff --git a/CRM/Export/BAO/Export.php b/CRM/Export/BAO/Export.php index 8822076944f3..1c042f6f8886 100644 --- a/CRM/Export/BAO/Export.php +++ b/CRM/Export/BAO/Export.php @@ -246,9 +246,6 @@ public static function exportComponents( $processor = new CRM_Export_BAO_ExportProcessor($exportMode, $fields, $queryOperator); $returnProperties = array(); - $selectedPaymentFields = FALSE; - // @todo - this variable is overwritten later - it should be wholly definable in the processor fn. - $paymentTableId = $processor->getPaymentTableID(); $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 @@ -292,14 +289,6 @@ public static function exportComponents( if ($fieldName == 'event_id') { $returnProperties['event_id'] = 1; } - elseif ( - $exportMode == CRM_Export_Form_Select::EVENT_EXPORT && - array_key_exists($fieldName, self::componentPaymentFields()) - ) { - $selectedPaymentFields = TRUE; - $paymentTableId = 'participant_id'; - $returnProperties[$fieldName] = 1; - } else { $returnProperties[$fieldName] = 1; } @@ -313,6 +302,9 @@ public static function exportComponents( else { $returnProperties = $processor->getDefaultReturnProperties(); } + // @todo - we are working towards this being entirely a property of the processor + $processor->setReturnProperties($returnProperties); + $paymentTableId = $processor->getPaymentTableID(); if ($mergeSameAddress) { //make sure the addressee fields are selected @@ -463,14 +455,14 @@ public static function exportComponents( $addPaymentHeader = FALSE; $paymentDetails = array(); - if ($processor->isExportPaymentFields() || $selectedPaymentFields) { + if ($processor->isExportPaymentFields()) { // get payment related in for event and members $paymentDetails = CRM_Contribute_BAO_Contribution::getContributionDetails($exportMode, $ids); //get all payment headers. // If we haven't selected specific payment fields, load in all the // payment headers. - if (!$selectedPaymentFields) { + if (!$processor->isExportSpecifiedPaymentFields()) { $paymentHeaders = self::componentPaymentFields(); if (!empty($paymentDetails)) { $addPaymentHeader = TRUE; @@ -498,7 +490,7 @@ public static function exportComponents( // for CRM-3157 purposes $i18n = CRM_Core_I18n::singleton(); - list($outputColumns, $headerRows, $sqlColumns, $metadata) = self::getExportStructureArrays($returnProperties, $processor, $relationQuery, $selectedPaymentFields); + list($outputColumns, $headerRows, $sqlColumns, $metadata) = self::getExportStructureArrays($returnProperties, $processor, $relationQuery); $limitReached = FALSE; while (!$limitReached) { @@ -549,7 +541,7 @@ public static function exportComponents( self::fetchRelationshipDetails($relDAO, $value, $field, $row); } else { - $row[$field] = self::getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $selectedPaymentFields, $paymentDetails, $paymentTableId); + $row[$field] = self::getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $paymentDetails, $processor); } } @@ -574,7 +566,7 @@ public static function exportComponents( // data will already be in $row. Otherwise, add payment related // information, if appropriate. if ($addPaymentHeader) { - if (!$selectedPaymentFields) { + if (!$processor->isExportSpecifiedPaymentFields()) { if ($processor->isExportPaymentFields()) { $paymentData = CRM_Utils_Array::value($row[$paymentTableId], $paymentDetails); if (!is_array($paymentData) || empty($paymentData)) { @@ -1528,10 +1520,10 @@ public static function componentPaymentFields() { * @param array $phoneTypes * @param array $imProviders * @param string $relationQuery - * @param array $selectedPaymentFields + * * @return array */ - public static function setHeaderRows($field, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery, $selectedPaymentFields) { + public static function setHeaderRows($field, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery) { $queryFields = $processor->getQueryFields(); // Split campaign into 2 fields for id and title @@ -1610,7 +1602,7 @@ public static function setHeaderRows($field, $headerRows, $sqlColumns, $processo } self::manipulateHeaderRows($headerRows); } - elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) { + elseif ($processor->isExportPaymentFields() && array_key_exists($field, self::componentPaymentFields())) { $headerRows[] = CRM_Utils_Array::value($field, self::componentPaymentFields()); } else { @@ -1634,7 +1626,7 @@ public static function setHeaderRows($field, $headerRows, $sqlColumns, $processo * @param array $returnProperties * @param \CRM_Export_BAO_ExportProcessor $processor * @param string $relationQuery - * @param array $selectedPaymentFields + * * @return array * - outputColumns Array of columns to be exported. The values don't matter but the key must match the * alias for the field generated by BAO_Query object. @@ -1651,7 +1643,7 @@ public static function setHeaderRows($field, $headerRows, $sqlColumns, $processo * - b) this code is old & outdated. Submit your answers to circular bin or better * yet find a way to comment them for posterity. */ - public static function getExportStructureArrays($returnProperties, $processor, $relationQuery, $selectedPaymentFields) { + public static function getExportStructureArrays($returnProperties, $processor, $relationQuery) { $metadata = $headerRows = $outputColumns = $sqlColumns = array(); $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id'); $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'); @@ -1660,7 +1652,7 @@ public static function getExportStructureArrays($returnProperties, $processor, $ foreach ($returnProperties as $key => $value) { if ($key != 'location' || !is_array($value)) { $outputColumns[$key] = $value; - list($headerRows, $sqlColumns) = self::setHeaderRows($key, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery, $selectedPaymentFields); + list($headerRows, $sqlColumns) = self::setHeaderRows($key, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery); } else { foreach ($value as $locationType => $locationFields) { @@ -1685,7 +1677,7 @@ public static function getExportStructureArrays($returnProperties, $processor, $ $metadata[$daoFieldName]['pseudoconstant']['var'] = 'imProviders'; } self::sqlColumnDefn($processor, $sqlColumns, $outputFieldName); - list($headerRows, $sqlColumns) = self::setHeaderRows($outputFieldName, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery, $selectedPaymentFields); + list($headerRows, $sqlColumns) = self::setHeaderRows($outputFieldName, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery); if ($actualDBFieldName == 'country' || $actualDBFieldName == 'world_region') { $metadata[$daoFieldName] = array('context' => 'country'); } @@ -1920,12 +1912,13 @@ protected static function buildRelatedContactArray($selectAll, $ids, $exportMode * @param $fieldValue * @param $i18n * @param $metadata - * @param $selectedPaymentFields * @param $paymentDetails - * @param string $paymentTableId + * + * @param \CRM_Export_BAO_ExportProcessor $processor + * * @return string */ - protected static function getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $selectedPaymentFields, $paymentDetails, $paymentTableId) { + protected static function getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $paymentDetails, $processor) { if ($field == 'id') { return $iterationDAO->contact_id; @@ -2002,7 +1995,8 @@ protected static function getTransformedFieldValue($field, $iterationDAO, $field } } } - elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) { + elseif ($processor->isExportSpecifiedPaymentFields() && array_key_exists($field, self::componentPaymentFields())) { + $paymentTableId = $processor->getPaymentTableID(); $paymentData = CRM_Utils_Array::value($iterationDAO->$paymentTableId, $paymentDetails); $payFieldMapper = array( 'componentPaymentField_total_amount' => 'total_amount', diff --git a/CRM/Export/BAO/ExportProcessor.php b/CRM/Export/BAO/ExportProcessor.php index 8efc7102551c..7f7a0569ca0a 100644 --- a/CRM/Export/BAO/ExportProcessor.php +++ b/CRM/Export/BAO/ExportProcessor.php @@ -88,6 +88,11 @@ class CRM_Export_BAO_ExportProcessor { */ protected $relationshipReturnProperties = []; + /** + * @var array + */ + protected $returnProperties = []; + /** * CRM_Export_BAO_ExportProcessor constructor. * @@ -117,6 +122,21 @@ public function setRequestedFields($requestedFields) { $this->requestedFields = $requestedFields; } + + /** + * @return array + */ + public function getReturnProperties() { + return $this->returnProperties; + } + + /** + * @param array $returnProperties + */ + public function setReturnProperties($returnProperties) { + $this->returnProperties = $returnProperties; + } + /** * @return array */ @@ -310,9 +330,25 @@ public function isExportPaymentFields() { ])) { return TRUE; } + elseif ($this->isExportSpecifiedPaymentFields()) { + return TRUE; + } return FALSE; } + /** + * Has specific payment fields been requested (as opposed to via all fields). + * + * If specific fields have been requested then they get added at various points. + * + * @return bool + */ + public function isExportSpecifiedPaymentFields() { + if ($this->getRequestedFields() !== NULL && $this->hasRequestedComponentPaymentFields()) { + return TRUE; + } + } + /** * Get the name of the id field in the table that connects contributions to the export entity. */ @@ -325,9 +361,42 @@ public function getPaymentTableID() { ]; return isset($mapping[$this->getQueryMode()]) ? $mapping[$this->getQueryMode()] : ''; } + elseif ($this->hasRequestedComponentPaymentFields()) { + return 'participant_id'; + } return FALSE; } + /** + * Have component payment fields been requested. + * + * @return bool + */ + protected function hasRequestedComponentPaymentFields() { + if ($this->getQueryMode() === CRM_Contact_BAO_Query::MODE_EVENT) { + $participantPaymentFields = array_intersect_key($this->getComponentPaymentFields(), $this->getReturnProperties()); + if (!empty($participantPaymentFields)) { + return TRUE; + } + } + return FALSE; + } + + /** + * Get fields that indicate payment fields have been requested for a component. + * + * @return array + */ + protected function getComponentPaymentFields() { + return [ + 'componentPaymentField_total_amount' => ts('Total Amount'), + 'componentPaymentField_contribution_status' => ts('Contribution Status'), + 'componentPaymentField_received_date' => ts('Date Received'), + 'componentPaymentField_payment_instrument' => ts('Payment Method'), + 'componentPaymentField_transaction_id' => ts('Transaction ID'), + ]; + } + /** * Get the default properties when not specified. * diff --git a/tests/phpunit/CRM/Export/BAO/ExportTest.php b/tests/phpunit/CRM/Export/BAO/ExportTest.php index 1140be9e5a81..5e375b657940 100644 --- a/tests/phpunit/CRM/Export/BAO/ExportTest.php +++ b/tests/phpunit/CRM/Export/BAO/ExportTest.php @@ -843,9 +843,11 @@ protected function setUpHousehold() { * @param $selectedFields * @param int $id * + * @param int $exportMode + * * @return array */ - protected function doExport($selectedFields, $id) { + protected function doExport($selectedFields, $id, $exportMode = CRM_Export_Form_Select::CONTACT_EXPORT) { list($tableName, $sqlColumns) = CRM_Export_BAO_Export::exportComponents( TRUE, array($id), @@ -853,7 +855,7 @@ protected function doExport($selectedFields, $id) { NULL, $selectedFields, NULL, - CRM_Export_Form_Select::CONTACT_EXPORT, + $exportMode, "contact_a.id IN ({$id})", NULL, FALSE, @@ -1370,10 +1372,31 @@ public function testGetSQLColumns($exportMode, $expected) { public function testExportSpecifyFields($exportMode, $selectedFields, $expected) { $this->ensureComponentIsEnabled($exportMode); $this->setUpContributionExportData(); - list($tableName, $sqlColumns) = $this->doExport($selectedFields, $this->contactIDs[1]); + list($tableName, $sqlColumns) = $this->doExport($selectedFields, $this->contactIDs[1], $exportMode); $this->assertEquals($expected, $sqlColumns); } + /** + * Test export fields when no payment fields to be exported. + */ + public function textExportParticipantSpecifyFieldsNoPayment() { + $selectedFields = $this->getAllSpecifiableParticipantReturnFields(); + foreach ($selectedFields as $index => $field) { + if (substr($field[1], 0, 22) === 'componentPaymentField_') { + unset ($selectedFields[$index]); + } + } + + $expected = $this->getAllSpecifiableParticipantReturnFields(); + foreach ($expected as $index => $field) { + if (substr($index, 0, 22) === 'componentPaymentField_') { + unset ($expected[$index]); + } + } + + list($tableName, $sqlColumns) = $this->doExport($selectedFields, $this->contactIDs[1], CRM_Export_Form_Select::EVENT_EXPORT); + $this->assertEquals($expected, $sqlColumns); + } /** * Get all return fields (@todo - still being built up. * @@ -1384,42 +1407,51 @@ public function getAllSpecifiableReturnFields() { [ CRM_Export_Form_Select::EVENT_EXPORT, $this->getAllSpecifiableParticipantReturnFields(), - [ - 'participant_campaign_id' => 'participant_campaign_id varchar(128)', - 'participant_contact_id' => 'participant_contact_id varchar(16)', - 'componentpaymentfield_contribution_status' => 'componentpaymentfield_contribution_status text', - 'currency' => 'currency varchar(3)', - 'componentpaymentfield_received_date' => 'componentpaymentfield_received_date text', - 'default_role_id' => 'default_role_id varchar(16)', - 'participant_discount_name' => 'participant_discount_name varchar(16)', - 'event_id' => 'event_id varchar(16)', - 'event_end_date' => 'event_end_date varchar(32)', - 'event_start_date' => 'event_start_date varchar(32)', - 'template_title' => 'template_title varchar(255)', - 'event_title' => 'event_title varchar(255)', - 'participant_fee_amount' => 'participant_fee_amount varchar(32)', - 'participant_fee_currency' => 'participant_fee_currency varchar(3)', - 'fee_label' => 'fee_label varchar(255)', - 'participant_fee_level' => 'participant_fee_level longtext', - 'participant_is_pay_later' => 'participant_is_pay_later varchar(16)', - 'participant_id' => 'participant_id varchar(16)', - 'participant_note' => 'participant_note text', - 'participant_role_id' => 'participant_role_id varchar(128)', - 'participant_role' => 'participant_role varchar(255)', - 'participant_source' => 'participant_source varchar(128)', - 'participant_status_id' => 'participant_status_id varchar(16)', - 'participant_status' => 'participant_status varchar(255)', - 'participant_register_date' => 'participant_register_date varchar(32)', - 'participant_registered_by_id' => 'participant_registered_by_id varchar(16)', - 'participant_is_test' => 'participant_is_test varchar(16)', - 'componentpaymentfield_total_amount' => 'componentpaymentfield_total_amount text', - 'componentpaymentfield_transaction_id' => 'componentpaymentfield_transaction_id varchar(255)', - 'transferred_to_contact_id' => 'transferred_to_contact_id varchar(16)', - ], + $this->getAllSpecifiableParticipantReturnColumns(), ], ]; } + /** + * Get expected return column output for participant mode return all columns. + * + * @return array + */ + public function getAllSpecifiableParticipantReturnColumns() { + return [ + 'participant_campaign_id' => 'participant_campaign_id varchar(128)', + 'participant_contact_id' => 'participant_contact_id varchar(16)', + 'componentpaymentfield_contribution_status' => 'componentpaymentfield_contribution_status text', + 'currency' => 'currency varchar(3)', + 'componentpaymentfield_received_date' => 'componentpaymentfield_received_date text', + 'default_role_id' => 'default_role_id varchar(16)', + 'participant_discount_name' => 'participant_discount_name varchar(16)', + 'event_id' => 'event_id varchar(16)', + 'event_end_date' => 'event_end_date varchar(32)', + 'event_start_date' => 'event_start_date varchar(32)', + 'template_title' => 'template_title varchar(255)', + 'event_title' => 'event_title varchar(255)', + 'participant_fee_amount' => 'participant_fee_amount varchar(32)', + 'participant_fee_currency' => 'participant_fee_currency varchar(3)', + 'fee_label' => 'fee_label varchar(255)', + 'participant_fee_level' => 'participant_fee_level longtext', + 'participant_is_pay_later' => 'participant_is_pay_later varchar(16)', + 'participant_id' => 'participant_id varchar(16)', + 'participant_note' => 'participant_note text', + 'participant_role_id' => 'participant_role_id varchar(128)', + 'participant_role' => 'participant_role varchar(255)', + 'participant_source' => 'participant_source varchar(128)', + 'participant_status_id' => 'participant_status_id varchar(16)', + 'participant_status' => 'participant_status varchar(255)', + 'participant_register_date' => 'participant_register_date varchar(32)', + 'participant_registered_by_id' => 'participant_registered_by_id varchar(16)', + 'participant_is_test' => 'participant_is_test varchar(16)', + 'componentpaymentfield_total_amount' => 'componentpaymentfield_total_amount text', + 'componentpaymentfield_transaction_id' => 'componentpaymentfield_transaction_id varchar(255)', + 'transferred_to_contact_id' => 'transferred_to_contact_id varchar(16)', + ]; + } + /** * @return array */