Extract bulk of the transformation for each field to its own function
authoreileen <emcnaughton@wikimedia.org>
Sat, 14 Jul 2018 01:04:23 +0000 (13:04 +1200)
committereileen <emcnaughton@wikimedia.org>
Tue, 17 Jul 2018 02:27:27 +0000 (14:27 +1200)
CRM/Export/BAO/Export.php
tests/phpunit/CRM/Export/BAO/ExportTest.php

index 4fb071ff200773f7f39e283604c2d4847b40cc93..38456651a642c83938fd716d413ad9dcb36f62ba 100644 (file)
@@ -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 '';
+    }
+  }
+
 }
index 175bbd4693cabc3bf1755e44a26c3b7daf294c18..bbe82a5288c54c53cdafebd32027970f246e17f8 100644 (file)
@@ -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);
+  }
+
 }