From: eileen Date: Wed, 10 Jul 2019 14:04:41 +0000 (+1200) Subject: More export Structure arrays to processor X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=44fc53abd9dab509d74c90dbf5cc28a104bfea1a;p=civicrm-core.git More export Structure arrays to processor --- diff --git a/CRM/Export/BAO/Export.php b/CRM/Export/BAO/Export.php index c1f78bf179..10a17b21af 100644 --- a/CRM/Export/BAO/Export.php +++ b/CRM/Export/BAO/Export.php @@ -228,7 +228,7 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c $addPaymentHeader = FALSE; - list($outputColumns, $metadata) = self::getExportStructureArrays($processor); + list($outputColumns, $metadata) = $processor->getExportStructureArrays(); if ($processor->isMergeSameAddress()) { //make sure the addressee fields are selected @@ -592,80 +592,6 @@ LIMIT $offset, $limit return $componentPaymentFields; } - /** - * Get the various arrays that we use to structure our output. - * - * The extraction of these has been moved to a separate function for clarity and so that - * tests can be added - in particular on the $outputHeaders array. - * - * However it still feels a bit like something that I'm too polite to write down and this should be seen - * as a step on the refactoring path rather than how it should be. - * - * @param \CRM_Export_BAO_ExportProcessor $processor - * - * @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. - * - headerRows Array of the column header strings to put in the csv header - non-associative. - * - sqlColumns Array of column names for the temp table. Not too sure why outputColumns can't be used here. - * - metadata Array of fields with specific parameters to pass to the translate function or another hacky nasty solution - * I'm too embarassed to discuss here. - * The keys need - * - to match the outputColumns keys (yes, the fact we ignore the output columns values & then pass another array with values - * we could use does suggest further refactors. However, you future improver, do remember that every check you do - * in the main DAO loop is done once per row & that coule be 100,000 times.) - * Finally a pop quiz: We need the translate context because we use a function other than ts() - is this because - * - a) the function used is more efficient or - * - 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($processor) { - $outputColumns = $metadata = []; - $queryFields = $processor->getQueryFields(); - foreach ($processor->getReturnProperties() as $key => $value) { - if (($key != 'location' || !is_array($value)) && !$processor->isRelationshipTypeKey($key)) { - $outputColumns[$key] = $value; - $processor->addOutputSpecification($key); - } - elseif ($processor->isRelationshipTypeKey($key)) { - $outputColumns[$key] = $value; - foreach ($value as $relationField => $relationValue) { - // below block is same as primary block (duplicate) - if (isset($queryFields[$relationField]['title'])) { - $processor->addOutputSpecification($relationField, $key); - } - elseif (is_array($relationValue) && $relationField == 'location') { - // fix header for location type case - foreach ($relationValue as $ltype => $val) { - foreach (array_keys($val) as $fld) { - $type = explode('-', $fld); - $processor->addOutputSpecification($type[0], $key, $ltype, CRM_Utils_Array::value(1, $type)); - } - } - } - } - } - else { - foreach ($value as $locationType => $locationFields) { - foreach (array_keys($locationFields) as $locationFieldName) { - $type = explode('-', $locationFieldName); - - $actualDBFieldName = $type[0]; - $daoFieldName = CRM_Utils_String::munge($locationType) . '-' . $actualDBFieldName; - - if (!empty($type[1])) { - $daoFieldName .= "-" . $type[1]; - } - $processor->addOutputSpecification($actualDBFieldName, NULL, $locationType, CRM_Utils_Array::value(1, $type)); - $metadata[$daoFieldName] = $processor->getMetaDataForField($actualDBFieldName); - $outputColumns[$daoFieldName] = TRUE; - } - } - } - } - return [$outputColumns, $metadata]; - } - /** * Get the values of linked household contact. * diff --git a/CRM/Export/BAO/ExportProcessor.php b/CRM/Export/BAO/ExportProcessor.php index 6898793312..6bd987a1be 100644 --- a/CRM/Export/BAO/ExportProcessor.php +++ b/CRM/Export/BAO/ExportProcessor.php @@ -1576,6 +1576,78 @@ class CRM_Export_BAO_ExportProcessor { return in_array($contactID, $this->householdsToSkip); } + /** + * Get the various arrays that we use to structure our output. + * + * The extraction of these has been moved to a separate function for clarity and so that + * tests can be added - in particular on the $outputHeaders array. + * + * However it still feels a bit like something that I'm too polite to write down and this should be seen + * as a step on the refactoring path rather than how it should be. + * + * @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. + * - headerRows Array of the column header strings to put in the csv header - non-associative. + * - sqlColumns Array of column names for the temp table. Not too sure why outputColumns can't be used here. + * - metadata Array of fields with specific parameters to pass to the translate function or another hacky nasty solution + * I'm too embarassed to discuss here. + * The keys need + * - to match the outputColumns keys (yes, the fact we ignore the output columns values & then pass another array with values + * we could use does suggest further refactors. However, you future improver, do remember that every check you do + * in the main DAO loop is done once per row & that coule be 100,000 times.) + * Finally a pop quiz: We need the translate context because we use a function other than ts() - is this because + * - a) the function used is more efficient or + * - b) this code is old & outdated. Submit your answers to circular bin or better + * yet find a way to comment them for posterity. + */ + public function getExportStructureArrays() { + $outputColumns = $metadata = []; + $queryFields = $this->getQueryFields(); + foreach ($this->getReturnProperties() as $key => $value) { + if (($key != 'location' || !is_array($value)) && !$this->isRelationshipTypeKey($key)) { + $outputColumns[$key] = $value; + $this->addOutputSpecification($key); + } + elseif ($this->isRelationshipTypeKey($key)) { + $outputColumns[$key] = $value; + foreach ($value as $relationField => $relationValue) { + // below block is same as primary block (duplicate) + if (isset($queryFields[$relationField]['title'])) { + $this->addOutputSpecification($relationField, $key); + } + elseif (is_array($relationValue) && $relationField == 'location') { + // fix header for location type case + foreach ($relationValue as $ltype => $val) { + foreach (array_keys($val) as $fld) { + $type = explode('-', $fld); + $this->addOutputSpecification($type[0], $key, $ltype, CRM_Utils_Array::value(1, $type)); + } + } + } + } + } + else { + foreach ($value as $locationType => $locationFields) { + foreach (array_keys($locationFields) as $locationFieldName) { + $type = explode('-', $locationFieldName); + + $actualDBFieldName = $type[0]; + $daoFieldName = CRM_Utils_String::munge($locationType) . '-' . $actualDBFieldName; + + if (!empty($type[1])) { + $daoFieldName .= "-" . $type[1]; + } + $this->addOutputSpecification($actualDBFieldName, NULL, $locationType, CRM_Utils_Array::value(1, $type)); + $metadata[$daoFieldName] = $this->getMetaDataForField($actualDBFieldName); + $outputColumns[$daoFieldName] = TRUE; + } + } + } + } + return [$outputColumns, $metadata]; + } + /** * Get default return property for export based on mode * diff --git a/tests/phpunit/CRM/Export/BAO/ExportTest.php b/tests/phpunit/CRM/Export/BAO/ExportTest.php index 5f5517b910..18eede0eb1 100644 --- a/tests/phpunit/CRM/Export/BAO/ExportTest.php +++ b/tests/phpunit/CRM/Export/BAO/ExportTest.php @@ -373,7 +373,7 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase { $processor->setQueryFields($query->_fields); $processor->setReturnProperties($returnProperties); - list($outputFields) = CRM_Export_BAO_Export::getExportStructureArrays($processor); + list($outputFields) = $processor->getExportStructureArrays(); foreach (array_keys($outputFields) as $fieldAlias) { if ($fieldAlias === 'Home-country') { $this->assertTrue(in_array($fieldAlias . '_id', $queryFieldAliases[1]), 'Country is subject to some funky translate so we make sure country id is present');