CRM-16826: Fix updating addresses via Profiles
authorJKingsnorth <john@johnkingsnorth.co.uk>
Fri, 10 Jul 2015 10:44:07 +0000 (11:44 +0100)
committerJKingsnorth <john@johnkingsnorth.co.uk>
Fri, 10 Jul 2015 10:44:07 +0000 (11:44 +0100)
CRM/Contact/Form/Contact.php
CRM/Core/BAO/Address.php

index 468c3f2c31c74dd97b222ed0a6eb254d2178df97..92252265a774d0947d7a4040744f76adf0aced91 100644 (file)
@@ -861,6 +861,9 @@ class CRM_Contact_Form_Contact extends CRM_Core_Form {
     }
     $this->assign('oldSubtypes', json_encode($this->_oldSubtypes));
 
+    // Add an element to distinguish the full contact edit form
+    $this->addElement('hidden', 'isFullContactEdit', TRUE);
+
     $this->addButtons($buttons);
   }
 
index e036b5e9f6d9fa42093e3e6742b7a11dc2a35c3b..d1fb6b0d0ca9bd7be3faa9bd698c99f529c56792 100644 (file)
@@ -64,7 +64,7 @@ class CRM_Core_BAO_Address extends CRM_Core_DAO_Address {
     if (!$entity) {
       $contactId = $params['contact_id'];
       //get all the addresses for this contact
-      $addresses = self::allAddress($contactId, $updateBlankLocInfo);
+      $addresses = self::allAddress($contactId);
     }
     else {
       // get all address from location block
@@ -83,23 +83,27 @@ class CRM_Core_BAO_Address extends CRM_Core_DAO_Address {
       }
 
       $addressExists = self::dataExists($value);
-      if (empty($value['id'])) {
-        if ($updateBlankLocInfo) {
-          if ((!empty($addresses) || !$addressExists) && array_key_exists($key, $addresses)) {
-            $value['id'] = $addresses[$key];
-          }
-        }
-        else {
-          if (!empty($addresses) && array_key_exists(CRM_Utils_Array::value('location_type_id', $value), $addresses)) {
-            $value['id'] = $addresses[CRM_Utils_Array::value('location_type_id', $value)];
-          }
+
+      // If the ID is empty then this is either a new address, or an edit coming
+      // from a Profile. So we need to match up the location type with any
+      // that are currently on the contact.
+      if (empty($value['id']) && !empty($value['location_type_id']) && !empty($addresses)) {
+
+        // Does the submitted address type already exist?
+        if (array_key_exists($value['location_type_id'], $addresses)) {
+
+          // Match the address ID and remove from the list so we know its matched
+          $value['id'] = $addresses[$value['location_type_id']];
+          unset($addresses[$value['location_type_id']]);
+
         }
+
       }
 
       // Note there could be cases when address info already exist ($value[id] is set) for a contact/entity
       // BUT info is not present at this time, and therefore we should be really careful when deleting the block.
       // $updateBlankLocInfo will help take appropriate decision. CRM-5969
-      if (isset($value['id']) && !$addressExists && $updateBlankLocInfo) {
+      if (!empty($value['id']) && !$addressExists && $updateBlankLocInfo) {
         //delete the existing record
         CRM_Core_BAO_Block::blockDelete('Address', array('id' => $value['id']));
         continue;
@@ -129,6 +133,14 @@ class CRM_Core_BAO_Address extends CRM_Core_DAO_Address {
       $blocks[] = self::add($value, $fixAddress);
     }
 
+    // If this is an edit from the full contact edit page then delete any
+    // addresses that we couldn't match on - because they were deleted on the form
+    if (!empty($params['isFullContactEdit']) && count($addresses)) {
+      foreach ($addresses as $addressId) {
+        CRM_Core_BAO_Block::blockDelete('Address', array('id' => $addressId));
+      }
+    }
+
     return $blocks;
   }
 
@@ -600,12 +612,12 @@ class CRM_Core_BAO_Address extends CRM_Core_DAO_Address {
    * @param int $id
    *   The contact id.
    *
-   * @param bool $updateBlankLocInfo
-   *
    * @return array
-   *   the array of adrress data
+   *   the array of address data
    */
-  public static function allAddress($id, $updateBlankLocInfo = FALSE) {
+  public static function allAddress($id) {
+
+    $addresses = array();
     if (!$id) {
       return NULL;
     }
@@ -615,18 +627,11 @@ SELECT civicrm_address.id as address_id, civicrm_address.location_type_id as loc
 FROM civicrm_contact, civicrm_address
 WHERE civicrm_address.contact_id = civicrm_contact.id AND civicrm_contact.id = %1
 ORDER BY civicrm_address.is_primary DESC, address_id ASC";
-    $params = array(1 => array($id, 'Integer'));
 
-    $addresses = array();
+    $params = array(1 => array($id, 'Integer'));
     $dao = CRM_Core_DAO::executeQuery($query, $params);
-    $count = 1;
     while ($dao->fetch()) {
-      if ($updateBlankLocInfo) {
-        $addresses[$count++] = $dao->address_id;
-      }
-      else {
-        $addresses[$dao->location_type_id] = $dao->address_id;
-      }
+      $addresses[$dao->location_type_id] = $dao->address_id;
     }
     return $addresses;
   }
@@ -639,9 +644,10 @@ ORDER BY civicrm_address.is_primary DESC, address_id ASC";
    *   entity_table name
    *
    * @return array
-   *   the array of adrress data
+   *   the array of address data
    */
   public static function allEntityAddress(&$entityElements) {
+
     $addresses = array();
     if (empty($entityElements)) {
       return $addresses;
@@ -651,7 +657,7 @@ ORDER BY civicrm_address.is_primary DESC, address_id ASC";
     $entityTable = $entityElements['entity_table'];
 
     $sql = "
-SELECT civicrm_address.id as address_id
+SELECT civicrm_address.id as address_id, civicrm_address.location_type_id as location_type_id
 FROM civicrm_loc_block loc, civicrm_location_type ltype, civicrm_address, {$entityTable} ev
 WHERE ev.id = %1
   AND loc.id = ev.loc_block_id
@@ -661,10 +667,8 @@ ORDER BY civicrm_address.is_primary DESC, civicrm_address.location_type_id DESC,
 
     $params = array(1 => array($entityId, 'Integer'));
     $dao = CRM_Core_DAO::executeQuery($sql, $params);
-    $locationCount = 1;
     while ($dao->fetch()) {
-      $addresses[$locationCount] = $dao->address_id;
-      $locationCount++;
+      $addresses[$dao->location_type_id] = $dao->address_id;
     }
     return $addresses;
   }