Merge pull request #14085 from totten/master-cron-doc
[civicrm-core.git] / CRM / Contact / Import / Parser.php
index fd1f644da73510c21953c1ec807bc36344705992..ec054e8688b8af8438491f1f5ecbee841544641f 100644 (file)
@@ -43,16 +43,19 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
 
   /**
    * Running total number of un-matched Contacts.
+   * @var int
    */
   protected $_unMatchCount;
 
   /**
    * Array of unmatched lines
+   * @var array
    */
   protected $_unMatch;
 
   /**
    * Total number of contacts with unparsed addresses
+   * @var int
    */
   protected $_unparsedAddressCount;
 
@@ -140,17 +143,17 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
     $this->_invalidRowCount = $this->_validCount = 0;
     $this->_totalCount = $this->_conflictCount = 0;
 
-    $this->_errors = array();
-    $this->_warnings = array();
-    $this->_conflicts = array();
-    $this->_unparsedAddresses = array();
+    $this->_errors = [];
+    $this->_warnings = [];
+    $this->_conflicts = [];
+    $this->_unparsedAddresses = [];
 
     $this->_tableName = $tableName;
     $this->_primaryKeyName = $primaryKeyName;
     $this->_statusFieldName = $statusFieldName;
 
     if ($mode == self::MODE_MAPFIELD) {
-      $this->_rows = array();
+      $this->_rows = [];
     }
     else {
       $this->_activeFieldCount = count($this->_activeFields);
@@ -293,54 +296,44 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
 
       if ($this->_invalidRowCount) {
         // removed view url for invlaid contacts
-        $headers = array_merge(array(
-            ts('Line Number'),
-            ts('Reason'),
-          ),
-          $customHeaders
-        );
+        $headers = array_merge([
+          ts('Line Number'),
+          ts('Reason'),
+        ], $customHeaders);
         $this->_errorFileName = self::errorFileName(self::ERROR);
         self::exportCSV($this->_errorFileName, $headers, $this->_errors);
       }
       if ($this->_conflictCount) {
-        $headers = array_merge(array(
-            ts('Line Number'),
-            ts('Reason'),
-          ),
-          $customHeaders
-        );
+        $headers = array_merge([
+          ts('Line Number'),
+          ts('Reason'),
+        ], $customHeaders);
         $this->_conflictFileName = self::errorFileName(self::CONFLICT);
         self::exportCSV($this->_conflictFileName, $headers, $this->_conflicts);
       }
       if ($this->_duplicateCount) {
-        $headers = array_merge(array(
-            ts('Line Number'),
-            ts('View Contact URL'),
-          ),
-          $customHeaders
-        );
+        $headers = array_merge([
+          ts('Line Number'),
+          ts('View Contact URL'),
+        ], $customHeaders);
 
         $this->_duplicateFileName = self::errorFileName(self::DUPLICATE);
         self::exportCSV($this->_duplicateFileName, $headers, $this->_duplicates);
       }
       if ($this->_unMatchCount) {
-        $headers = array_merge(array(
-            ts('Line Number'),
-            ts('Reason'),
-          ),
-          $customHeaders
-        );
+        $headers = array_merge([
+          ts('Line Number'),
+          ts('Reason'),
+        ], $customHeaders);
 
         $this->_misMatchFilemName = self::errorFileName(self::NO_MATCH);
         self::exportCSV($this->_misMatchFilemName, $headers, $this->_unMatch);
       }
       if ($this->_unparsedAddressCount) {
-        $headers = array_merge(array(
-            ts('Line Number'),
-            ts('Contact Edit URL'),
-          ),
-          $customHeaders
-        );
+        $headers = array_merge([
+          ts('Line Number'),
+          ts('Contact Edit URL'),
+        ], $customHeaders);
         $this->_errorFileName = self::errorFileName(self::UNPARSED_ADDRESS_WARNING);
         self::exportCSV($this->_errorFileName, $headers, $this->_unparsedAddresses);
       }
@@ -380,6 +373,7 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
   /**
    * @param $elements
    */
+
   /**
    * @param $elements
    */
@@ -485,7 +479,7 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
    *   (reference ) associative array of name/value pairs
    */
   public function &getActiveFieldParams() {
-    $params = array();
+    $params = [];
 
     for ($i = 0; $i < $this->_activeFieldCount; $i++) {
       if ($this->_activeFields[$i]->_name == 'do_not_import') {
@@ -495,13 +489,13 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
       if (isset($this->_activeFields[$i]->_value)) {
         if (isset($this->_activeFields[$i]->_hasLocationType)) {
           if (!isset($params[$this->_activeFields[$i]->_name])) {
-            $params[$this->_activeFields[$i]->_name] = array();
+            $params[$this->_activeFields[$i]->_name] = [];
           }
 
-          $value = array(
+          $value = [
             $this->_activeFields[$i]->_name => $this->_activeFields[$i]->_value,
             'location_type_id' => $this->_activeFields[$i]->_hasLocationType,
-          );
+          ];
 
           if (isset($this->_activeFields[$i]->_phoneType)) {
             $value['phone_type_id'] = $this->_activeFields[$i]->_phoneType;
@@ -515,10 +509,10 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
           $params[$this->_activeFields[$i]->_name][] = $value;
         }
         elseif (isset($this->_activeFields[$i]->_websiteType)) {
-          $value = array(
+          $value = [
             $this->_activeFields[$i]->_name => $this->_activeFields[$i]->_value,
             'website_type_id' => $this->_activeFields[$i]->_websiteType,
-          );
+          ];
 
           $params[$this->_activeFields[$i]->_name][] = $value;
         }
@@ -532,7 +526,7 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
         //minor fix for CRM-4062
         if (isset($this->_activeFields[$i]->_related)) {
           if (!isset($params[$this->_activeFields[$i]->_related])) {
-            $params[$this->_activeFields[$i]->_related] = array();
+            $params[$this->_activeFields[$i]->_related] = [];
           }
 
           if (!isset($params[$this->_activeFields[$i]->_related]['contact_type']) && !empty($this->_activeFields[$i]->_relatedContactType)) {
@@ -543,12 +537,12 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
             if (!empty($params[$this->_activeFields[$i]->_related][$this->_activeFields[$i]->_relatedContactDetails]) &&
               !is_array($params[$this->_activeFields[$i]->_related][$this->_activeFields[$i]->_relatedContactDetails])
             ) {
-              $params[$this->_activeFields[$i]->_related][$this->_activeFields[$i]->_relatedContactDetails] = array();
+              $params[$this->_activeFields[$i]->_related][$this->_activeFields[$i]->_relatedContactDetails] = [];
             }
-            $value = array(
+            $value = [
               $this->_activeFields[$i]->_relatedContactDetails => $this->_activeFields[$i]->_value,
               'location_type_id' => $this->_activeFields[$i]->_relatedContactLocType,
-            );
+            ];
 
             if (isset($this->_activeFields[$i]->_relatedContactPhoneType)) {
               $value['phone_type_id'] = $this->_activeFields[$i]->_relatedContactPhoneType;
@@ -562,10 +556,10 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
             $params[$this->_activeFields[$i]->_related][$this->_activeFields[$i]->_relatedContactDetails][] = $value;
           }
           elseif (isset($this->_activeFields[$i]->_relatedContactWebsiteType)) {
-            $params[$this->_activeFields[$i]->_related][$this->_activeFields[$i]->_relatedContactDetails][] = array(
+            $params[$this->_activeFields[$i]->_related][$this->_activeFields[$i]->_relatedContactDetails][] = [
               'url' => $this->_activeFields[$i]->_value,
               'website_type_id' => $this->_activeFields[$i]->_relatedContactWebsiteType,
-            );
+            ];
           }
           else {
             $params[$this->_activeFields[$i]->_related][$this->_activeFields[$i]->_relatedContactDetails] = $this->_activeFields[$i]->_value;
@@ -581,7 +575,7 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
    * @return array
    */
   public function getColumnPatterns() {
-    $values = array();
+    $values = [];
     foreach ($this->_fields as $name => $field) {
       $values[$name] = $field->_columnPattern;
     }
@@ -682,8 +676,8 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
       CRM_Core_Error::movedSiteError($fileName);
     }
     //hack to remove '_status', '_statusMsg' and '_id' from error file
-    $errorValues = array();
-    $dbRecordStatus = array('IMPORTED', 'ERROR', 'DUPLICATE', 'INVALID', 'NEW');
+    $errorValues = [];
+    $dbRecordStatus = ['IMPORTED', 'ERROR', 'DUPLICATE', 'INVALID', 'NEW'];
     foreach ($data as $rowCount => $rowValues) {
       $count = 0;
       foreach ($rowValues as $key => $val) {
@@ -696,7 +690,7 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
     }
     $data = $errorValues;
 
-    $output = array();
+    $output = [];
     $fd = fopen($fileName, 'w');
 
     foreach ($header as $key => $value) {
@@ -733,11 +727,11 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
                       SET    $statusFieldName = ?,
                              ${statusFieldName}Msg = ?
                       WHERE  $primaryKeyName = ?";
-      $args = array(
+      $args = [
         $params[$statusFieldName],
         CRM_Utils_Array::value("${statusFieldName}Msg", $params),
         $id,
-      );
+      ];
 
       //print "Running query: $query<br/>With arguments: ".$params[$statusFieldName].", ".$params["${statusFieldName}Msg"].", $id<br/>";
 
@@ -756,9 +750,9 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
    *   Contact DAO fields.
    */
   public function formatCommonData($params, &$formatted, &$contactFields) {
-    $csType = array(
+    $csType = [
       CRM_Utils_Array::value('contact_type', $formatted),
-    );
+    ];
 
     //CRM-5125
     //add custom fields for contact sub type
@@ -776,11 +770,11 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
     $customFields = $customFields + $addressCustomFields;
 
     //if a Custom Email Greeting, Custom Postal Greeting or Custom Addressee is mapped, and no "Greeting / Addressee Type ID" is provided, then automatically set the type = Customized, CRM-4575
-    $elements = array(
+    $elements = [
       'email_greeting_custom' => 'email_greeting',
       'postal_greeting_custom' => 'postal_greeting',
       'addressee_custom' => 'addressee',
-    );
+    ];
     foreach ($elements as $k => $v) {
       if (array_key_exists($k, $params) && !(array_key_exists($v, $params))) {
         $label = key(CRM_Core_OptionGroup::values($v, TRUE, NULL, NULL, 'AND v.name = "Customized"'));
@@ -860,9 +854,9 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
         }
       }
 
-      $formatValues = array(
+      $formatValues = [
         $key => $field,
-      );
+      ];
 
       if (($key !== 'preferred_communication_method') && (array_key_exists($key, $contactFields))) {
         // due to merging of individual table and
@@ -909,8 +903,8 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
             if (!empty($formatted[$key]) && !empty($params[$key])) {
               $mulValues = explode(',', $formatted[$key]);
               $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
-              $formatted[$key] = array();
-              $params[$key] = array();
+              $formatted[$key] = [];
+              $params[$key] = [];
               foreach ($mulValues as $v1) {
                 foreach ($customOption as $v2) {
                   if ((strtolower($v2['label']) == strtolower(trim($v1))) ||
@@ -1002,7 +996,7 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
     //      Custom
 
     // Cache the various object fields
-    static $fields = array();
+    static $fields = [];
 
     // first add core contact values since for other Civi modules they are not added
     $contactFields = CRM_Contact_DAO_Contact::fields();
@@ -1042,10 +1036,10 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
     // CRM-4575
     if (isset($values['email_greeting'])) {
       if (!empty($params['email_greeting_id'])) {
-        $emailGreetingFilter = array(
+        $emailGreetingFilter = [
           'contact_type' => CRM_Utils_Array::value('contact_type', $params),
           'greeting_type' => 'email_greeting',
-        );
+        ];
         $emailGreetings = CRM_Core_PseudoConstant::greeting($emailGreetingFilter);
         $params['email_greeting'] = $emailGreetings[$params['email_greeting_id']];
       }
@@ -1058,10 +1052,10 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
 
     if (isset($values['postal_greeting'])) {
       if (!empty($params['postal_greeting_id'])) {
-        $postalGreetingFilter = array(
+        $postalGreetingFilter = [
           'contact_type' => CRM_Utils_Array::value('contact_type', $params),
           'greeting_type' => 'postal_greeting',
-        );
+        ];
         $postalGreetings = CRM_Core_PseudoConstant::greeting($postalGreetingFilter);
         $params['postal_greeting'] = $postalGreetings[$params['postal_greeting_id']];
       }
@@ -1073,10 +1067,10 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
 
     if (isset($values['addressee'])) {
       if (!empty($params['addressee_id'])) {
-        $addresseeFilter = array(
+        $addresseeFilter = [
           'contact_type' => CRM_Utils_Array::value('contact_type', $params),
           'greeting_type' => 'addressee',
-        );
+        ];
         $addressee = CRM_Core_PseudoConstant::addressee($addresseeFilter);
         $params['addressee'] = $addressee[$params['addressee_id']];
       }
@@ -1098,7 +1092,7 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
     }
 
     if (!empty($values['preferred_communication_method'])) {
-      $comm = array();
+      $comm = [];
       $pcm = array_change_key_case(array_flip(CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method')), CASE_LOWER);
 
       $preffComm = explode(',', $values['preferred_communication_method']);
@@ -1122,7 +1116,7 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
       if (!array_key_exists('website', $params) ||
         !is_array($params['website'])
       ) {
-        $params['website'] = array();
+        $params['website'] = [];
       }
 
       $websiteCount = count($params['website']);
@@ -1135,153 +1129,17 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
 
     // get the formatted location blocks into params - w/ 3.0 format, CRM-4605
     if (!empty($values['location_type_id'])) {
-      $blockTypes = array(
-        'phone' => 'Phone',
-        'email' => 'Email',
-        'im' => 'IM',
-        'openid' => 'OpenID',
-        'phone_ext' => 'Phone',
-      );
-      foreach ($blockTypes as $blockFieldName => $block) {
-        if (!array_key_exists($blockFieldName, $values)) {
-          continue;
-        }
-
-        // block present in value array.
-        if (!array_key_exists($blockFieldName, $params) || !is_array($params[$blockFieldName])) {
-          $params[$blockFieldName] = array();
-        }
-
-        if (!array_key_exists($block, $fields)) {
-          $className = "CRM_Core_DAO_$block";
-          $fields[$block] = $className::fields();
-        }
-
-        $blockCnt = count($params[$blockFieldName]);
-
-        // copy value to dao field name.
-        if ($blockFieldName == 'im') {
-          $values['name'] = $values[$blockFieldName];
-        }
-
-        _civicrm_api3_store_values($fields[$block], $values,
-          $params[$blockFieldName][++$blockCnt]
-        );
-
-        if ($values['location_type_id'] === 'Primary') {
-          if (!empty($params['id'])) {
-            $primary = civicrm_api3($block, 'get', array('return' => 'location_type_id', 'contact_id' => $params['id'], 'is_primary' => 1, 'sequential' => 1));
-          }
-          $defaultLocationType = CRM_Core_BAO_LocationType::getDefault();
-          $values['location_type_id'] = (isset($primary) && $primary['count']) ? $primary['values'][0]['location_type_id'] : $defaultLocationType->id;
-          $values['is_primary'] = 1;
-        }
-
-        if (empty($params['id']) && ($blockCnt == 1)) {
-          $params[$blockFieldName][$blockCnt]['is_primary'] = TRUE;
-        }
-
-        // we only process single block at a time.
-        return TRUE;
-      }
-
-      // handle address fields.
-      if (!array_key_exists('address', $params) || !is_array($params['address'])) {
-        $params['address'] = array();
-      }
-
-      if (!array_key_exists('Address', $fields)) {
-        $fields['Address'] = CRM_Core_DAO_Address::fields();
-      }
-
-      // Note: we doing multiple value formatting here for address custom fields, plus putting into right format.
-      // The actual formatting (like date, country ..etc) for address custom fields is taken care of while saving
-      // the address in CRM_Core_BAO_Address::create method
-      if (!empty($values['location_type_id'])) {
-        static $customFields = array();
-        if (empty($customFields)) {
-          $customFields = CRM_Core_BAO_CustomField::getFields('Address');
-        }
-        // make a copy of values, as we going to make changes
-        $newValues = $values;
-        foreach ($values as $key => $val) {
-          $customFieldID = CRM_Core_BAO_CustomField::getKeyID($key);
-          if ($customFieldID && array_key_exists($customFieldID, $customFields)) {
-            // mark an entry in fields array since we want the value of custom field to be copied
-            $fields['Address'][$key] = NULL;
-
-            $htmlType = CRM_Utils_Array::value('html_type', $customFields[$customFieldID]);
-            switch ($htmlType) {
-              case 'CheckBox':
-              case 'Multi-Select':
-                if ($val) {
-                  $mulValues = explode(',', $val);
-                  $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
-                  $newValues[$key] = array();
-                  foreach ($mulValues as $v1) {
-                    foreach ($customOption as $v2) {
-                      if ((strtolower($v2['label']) == strtolower(trim($v1))) ||
-                        (strtolower($v2['value']) == strtolower(trim($v1)))
-                      ) {
-                        if ($htmlType == 'CheckBox') {
-                          $newValues[$key][$v2['value']] = 1;
-                        }
-                        else {
-                          $newValues[$key][] = $v2['value'];
-                        }
-                      }
-                    }
-                  }
-                }
-                break;
-            }
-          }
-        }
-        // consider new values
-        $values = $newValues;
-      }
-
-      _civicrm_api3_store_values($fields['Address'], $values, $params['address'][$values['location_type_id']]);
-
-      $addressFields = array(
-        'county',
-        'country',
-        'state_province',
-        'supplemental_address_1',
-        'supplemental_address_2',
-        'supplemental_address_3',
-        'StateProvince.name',
-      );
-
-      foreach ($addressFields as $field) {
-        if (array_key_exists($field, $values)) {
-          if (!array_key_exists('address', $params)) {
-            $params['address'] = array();
-          }
-          $params['address'][$values['location_type_id']][$field] = $values[$field];
-        }
-      }
-
-      if ($values['location_type_id'] === 'Primary') {
-        if (!empty($params['id'])) {
-          $primary = civicrm_api3('Address', 'get', array('return' => 'location_type_id', 'contact_id' => $params['id'], 'is_primary' => 1, 'sequential' => 1));
-        }
-        $defaultLocationType = CRM_Core_BAO_LocationType::getDefault();
-        $params['address'][$values['location_type_id']]['location_type_id'] = (isset($primary) && $primary['count']) ? $primary['values'][0]['location_type_id'] : $defaultLocationType->id;
-        $params['address'][$values['location_type_id']]['is_primary'] = 1;
-
-      }
-      return TRUE;
+      return $this->formatLocationBlock($values, $params, $fields);
     }
 
     if (isset($values['note'])) {
       // add a note field
       if (!isset($params['note'])) {
-        $params['note'] = array();
+        $params['note'] = [];
       }
       $noteBlock = count($params['note']) + 1;
 
-      $params['note'][$noteBlock] = array();
+      $params['note'][$noteBlock] = [];
       if (!isset($fields['Note'])) {
         $fields['Note'] = CRM_Core_DAO_Note::fields();
       }
@@ -1322,4 +1180,169 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
     return TRUE;
   }
 
+  /**
+   * Format location block ready for importing.
+   *
+   * There is some test coverage for this in CRM_Contact_Import_Parser_ContactTest
+   * e.g. testImportPrimaryAddress.
+   *
+   * @param array $values
+   * @param array $params
+   * @param array $fields
+   *
+   * @return bool
+   */
+  protected function formatLocationBlock(&$values, &$params, $fields) {
+    if (empty($values['location_type_id'])) {
+      return FALSE;
+    }
+    $blockTypes = [
+      'phone' => 'Phone',
+      'email' => 'Email',
+      'im' => 'IM',
+      'openid' => 'OpenID',
+      'phone_ext' => 'Phone',
+    ];
+    foreach ($blockTypes as $blockFieldName => $block) {
+      if (!array_key_exists($blockFieldName, $values)) {
+        continue;
+      }
+
+      // block present in value array.
+      if (!array_key_exists($blockFieldName, $params) || !is_array($params[$blockFieldName])) {
+        $params[$blockFieldName] = [];
+      }
+
+      if (!array_key_exists($block, $fields)) {
+        $className = "CRM_Core_DAO_$block";
+        $fields[$block] = $className::fields();
+      }
+
+      $blockCnt = count($params[$blockFieldName]);
+
+      // copy value to dao field name.
+      if ($blockFieldName == 'im') {
+        $values['name'] = $values[$blockFieldName];
+      }
+
+      _civicrm_api3_store_values($fields[$block], $values,
+        $params[$blockFieldName][++$blockCnt]
+      );
+
+      if ($values['location_type_id'] === 'Primary') {
+        if (!empty($params['id'])) {
+          $primary = civicrm_api3($block, 'get', [
+            'return' => 'location_type_id',
+            'contact_id' => $params['id'],
+            'is_primary' => 1,
+            'sequential' => 1
+          ]);
+        }
+        $defaultLocationType = CRM_Core_BAO_LocationType::getDefault();
+        $values['location_type_id'] = (isset($primary) && $primary['count']) ? $primary['values'][0]['location_type_id'] : $defaultLocationType->id;
+        $values['is_primary'] = 1;
+      }
+
+      if (empty($params['id']) && ($blockCnt == 1)) {
+        $params[$blockFieldName][$blockCnt]['is_primary'] = TRUE;
+      }
+
+      // we only process single block at a time.
+      return TRUE;
+    }
+
+    // handle address fields.
+    if (!array_key_exists('address', $params) || !is_array($params['address'])) {
+      $params['address'] = [];
+    }
+
+    if (!array_key_exists('Address', $fields)) {
+      $fields['Address'] = CRM_Core_DAO_Address::fields();
+    }
+
+    // Note: we doing multiple value formatting here for address custom fields, plus putting into right format.
+    // The actual formatting (like date, country ..etc) for address custom fields is taken care of while saving
+    // the address in CRM_Core_BAO_Address::create method
+    if (!empty($values['location_type_id'])) {
+      static $customFields = [];
+      if (empty($customFields)) {
+        $customFields = CRM_Core_BAO_CustomField::getFields('Address');
+      }
+      // make a copy of values, as we going to make changes
+      $newValues = $values;
+      foreach ($values as $key => $val) {
+        $customFieldID = CRM_Core_BAO_CustomField::getKeyID($key);
+        if ($customFieldID && array_key_exists($customFieldID, $customFields)) {
+          // mark an entry in fields array since we want the value of custom field to be copied
+          $fields['Address'][$key] = NULL;
+
+          $htmlType = CRM_Utils_Array::value('html_type', $customFields[$customFieldID]);
+          switch ($htmlType) {
+            case 'CheckBox':
+            case 'Multi-Select':
+              if ($val) {
+                $mulValues = explode(',', $val);
+                $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
+                $newValues[$key] = [];
+                foreach ($mulValues as $v1) {
+                  foreach ($customOption as $v2) {
+                    if ((strtolower($v2['label']) == strtolower(trim($v1))) ||
+                      (strtolower($v2['value']) == strtolower(trim($v1)))
+                    ) {
+                      if ($htmlType == 'CheckBox') {
+                        $newValues[$key][$v2['value']] = 1;
+                      }
+                      else {
+                        $newValues[$key][] = $v2['value'];
+                      }
+                    }
+                  }
+                }
+              }
+              break;
+          }
+        }
+      }
+      // consider new values
+      $values = $newValues;
+    }
+
+    _civicrm_api3_store_values($fields['Address'], $values, $params['address'][$values['location_type_id']]);
+
+    $addressFields = [
+      'county',
+      'country',
+      'state_province',
+      'supplemental_address_1',
+      'supplemental_address_2',
+      'supplemental_address_3',
+      'StateProvince.name',
+    ];
+
+    foreach ($addressFields as $field) {
+      if (array_key_exists($field, $values)) {
+        if (!array_key_exists('address', $params)) {
+          $params['address'] = [];
+        }
+        $params['address'][$values['location_type_id']][$field] = $values[$field];
+      }
+    }
+
+    if ($values['location_type_id'] === 'Primary') {
+      if (!empty($params['id'])) {
+        $primary = civicrm_api3('Address', 'get', [
+          'return' => 'location_type_id',
+          'contact_id' => $params['id'],
+          'is_primary' => 1,
+          'sequential' => 1
+        ]);
+      }
+      $defaultLocationType = CRM_Core_BAO_LocationType::getDefault();
+      $params['address'][$values['location_type_id']]['location_type_id'] = (isset($primary) && $primary['count']) ? $primary['values'][0]['location_type_id'] : $defaultLocationType->id;
+      $params['address'][$values['location_type_id']]['is_primary'] = 1;
+
+    }
+    return TRUE;
+  }
+
 }