More export Structure arrays to processor
authoreileen <emcnaughton@wikimedia.org>
Wed, 10 Jul 2019 14:04:41 +0000 (02:04 +1200)
committereileen <emcnaughton@wikimedia.org>
Fri, 12 Jul 2019 04:20:53 +0000 (16:20 +1200)
CRM/Export/BAO/Export.php
CRM/Export/BAO/ExportProcessor.php
tests/phpunit/CRM/Export/BAO/ExportTest.php

index c1f78bf1790924458952adb070f852ecd92c37b6..10a17b21af8448e1f466ecc48bd7f7e592049fd9 100644 (file)
@@ -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.
    *
index 6898793312b88501f898bfd45ef3f8b7a8ffde8c..6bd987a1be0710a13fbc35ad008183cb9abaa989 100644 (file)
@@ -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
    *
index 5f5517b910a4cbca2dec20014b81a1c8be5490dd..18eede0eb1f57af21afe0dbf7a24045fcc85cdd8 100644 (file)
@@ -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');