Merge pull request #1191 from davecivicrm/CRM-13034
[civicrm-core.git] / CRM / Dedupe / Merger.php
index 64fe53dd30ae6a89dee427c2b7766f6cc0fe35e4..24c96270382b1cddafd1505e89edbb9c8557329f 100644 (file)
  *
  */
 class CRM_Dedupe_Merger {
-  // FIXME: this should be auto-generated from the schema
-  static $validFields = array(
-    'addressee', 'addressee_custom', 'birth_date', 'contact_source', 'contact_type',
-    'deceased_date', 'do_not_email', 'do_not_mail', 'do_not_sms', 'do_not_phone',
-    'do_not_trade', 'external_identifier', 'email_greeting', 'email_greeting_custom', 'first_name', 'gender',
-    'home_URL', 'household_name', 'image_URL',
-    'individual_prefix', 'prefix_id', 'individual_suffix', 'suffix_id', 'is_deceased', 'is_opt_out',
-    'job_title', 'last_name', 'legal_identifier', 'legal_name',
-    'middle_name', 'nick_name', 'organization_name', 'postal_greeting', 'postal_greeting_custom',
-    'preferred_communication_method', 'preferred_mail_format', 'sic_code', 'current_employer_id'
-  );
 
   // FIXME: consider creating a common structure with cidRefs() and eidRefs()
   // FIXME: the sub-pages references by the URLs should
@@ -90,7 +79,7 @@ class CRM_Dedupe_Merger {
         ),
         'rel_table_activities' => array(
           'title' => ts('Activities'),
-          'tables' => array('civicrm_activity', 'civicrm_activity_target', 'civicrm_activity_assignment'),
+          'tables' => array('civicrm_activity', 'civicrm_activity_contact'),
           'url' => CRM_Utils_System::url('civicrm/contact/view', 'reset=1&force=1&cid=$cid&selectedChild=activity'),
         ),
         'rel_table_relationships' => array(
@@ -204,9 +193,7 @@ class CRM_Dedupe_Merger {
       // foreign keys referencing civicrm_contact(id)
       $cidRefs = array(
         'civicrm_acl_cache' => array('contact_id'),
-        'civicrm_activity' => array('source_contact_id'),
-        'civicrm_activity_assignment' => array('assignee_contact_id'),
-        'civicrm_activity_target' => array('target_contact_id'),
+        'civicrm_activity_contact' => array('contact_id'),
         'civicrm_case_contact' => array('contact_id'),
         'civicrm_contact' => array('primary_contact_id'),
         'civicrm_contribution' => array('contact_id', 'honor_contact_id'),
@@ -266,9 +253,6 @@ class CRM_Dedupe_Merger {
         'civicrm_log' => array('entity_table' => 'entity_id'),
         'civicrm_mailing_group' => array('entity_table' => 'entity_id'),
         'civicrm_note' => array('entity_table' => 'entity_id'),
-        'civicrm_project' => array('owner_entity_table' => 'owner_entity_id'),
-        'civicrm_task' => array('owner_entity_table' => 'owner_entity_id'),
-        'civicrm_task_status' => array('responsible_entity_table' => 'responsible_entity_id', 'target_entity_table' => 'target_entity_id'),
       );
 
       // Allow hook_civicrm_merge() to adjust $eidRefs
@@ -403,6 +387,7 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
     $eidRefs = self::eidRefs();
     $cpTables = self::cpTables();
     $paymentTables = self::paymentTables();
+    $membershipMerge = FALSE; // CRM-12695
 
     $affected = array_merge(array_keys($cidRefs), array_keys($eidRefs));
     if ($tables !== FALSE) {
@@ -417,6 +402,21 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
         $handled = array_merge($handled, $params['tables']);
       }
       $affected = array_diff($affected, $handled);
+      /**
+       * CRM-12695
+       * Set $membershipMerge flag only once
+       * while doing contact related migration
+       * to call addMembershipToRealtedContacts()
+       * function only once.
+       * Since the current function (moveContactBelongings) is called twice
+       * with & without parameters $tables & $tableOperations
+       */
+      // retrieve main contact's related table(s)
+      $activeMainRelTables = CRM_Dedupe_Merger::getActiveRelTables($mainId);
+      // check if membership table exists in main contact's related table(s)
+      if (in_array('rel_table_memberships', $activeMainRelTables)) {
+        $membershipMerge = TRUE; // set membership flag - CRM-12695
+      }
     }
 
     $mainId = (int) $mainId;
@@ -469,6 +469,11 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
     foreach ($sqls as $sql) {
       CRM_Core_DAO::executeQuery($sql, array(), TRUE, NULL, TRUE);
     }
+    // CRM-12695
+    if ($membershipMerge) {
+      // call to function adding membership to related contacts
+      CRM_Dedupe_Merger::addMembershipToRealtedContacts($mainId);
+    }
     $transaction->commit();
   }
 
@@ -485,7 +490,7 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
       'contact' => array(),
       'custom' => array(),
     );
-    foreach (self::$validFields as $validField) {
+    foreach (self::getContactFields() as $validField) {
       if (CRM_Utils_Array::value($validField, $main) != CRM_Utils_Array::value($validField, $other)) {
         $result['contact'][] = $validField;
       }
@@ -653,7 +658,7 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
       'old_migration_info' => $migrationInfo,
       'mode' => $mode,
     );
-    $allLocationTypes = CRM_Core_PseudoConstant::locationType();
+    $allLocationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
 
     foreach ($migrationInfo as $key => $val) {
       if ($val === "null") {
@@ -661,7 +666,7 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
         unset($migrationInfo[$key]);
         continue;
       }
-      elseif ((in_array(substr($key, 5), CRM_Dedupe_Merger::$validFields) or
+      elseif ((in_array(substr($key, 5), CRM_Dedupe_Merger::getContactFields()) or
           substr($key, 0, 12) == 'move_custom_'
         ) and $val != NULL) {
         // Rule: if both main-contact has other-contact, let $mode decide if to merge a
@@ -759,7 +764,7 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
 
     // Fetch contacts
     foreach (array('main' => $mainId, 'other' => $otherId) as $moniker => $cid) {
-      $params = array('contact_id' => $cid, 'version' => 3, 'return' => array_merge(array('display_name'), self::$validFields));
+      $params = array('contact_id' => $cid, 'version' => 3, 'return' => array_merge(array('display_name'), self::getContactFields()));
       $result = civicrm_api('contact', 'get', $params);
 
       if (empty($result['values'][$cid]['contact_type'])) {
@@ -905,7 +910,7 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
       }
     }
 
-    $allLocationTypes = CRM_Core_PseudoConstant::locationType();
+    $allLocationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
 
     $mainLocBlock = $locBlockIds = array();
     $locBlockIds['main'] = $locBlockIds['other'] = array();
@@ -1142,7 +1147,7 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
       if ($value == $qfZeroBug) {
         $value = '0';
       }
-      if ((in_array(substr($key, 5), CRM_Dedupe_Merger::$validFields) or
+      if ((in_array(substr($key, 5), CRM_Dedupe_Merger::getContactFields()) or
           substr($key, 0, 12) == 'move_custom_'
         ) and $value != NULL) {
         $submitted[substr($key, 5)] = $value;
@@ -1484,5 +1489,48 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
 
     return TRUE;
   }
+
+  /**
+   * @return array of field names which will be compared, so everything except ID.
+   */
+  static function getContactFields() {
+    $contactFields = CRM_Contact_DAO_Contact::fields();
+    unset($contactFields['id']);
+
+    return array_keys($contactFields);
+  }
+
+  /**
+   * Added for CRM-12695
+   * Based on the contactId provided
+   * add/update membership(s) to related contacts
+   *
+   * @param contactId
+   */
+  static function addMembershipToRealtedContacts($contactID) {
+    $dao = new CRM_Member_DAO_Membership();
+    $dao->contact_id = $contactID;
+    $dao->is_test = 0;
+    $dao->find();
+
+    //checks membership of contact itself
+    while ($dao->fetch()) {
+      $relationshipTypeId = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $dao->membership_type_id, 'relationship_type_id', 'id');
+      if ($relationshipTypeId) {
+        $membershipParams = array(
+          'id' => $dao->id,
+          'contact_id' => $dao->contact_id,
+          'membership_type_id' => $dao->membership_type_id,
+          'join_date' => CRM_Utils_Date::isoToMysql($dao->join_date),
+          'start_date' => CRM_Utils_Date::isoToMysql($dao->start_date),
+          'end_date' => CRM_Utils_Date::isoToMysql($dao->end_date),
+          'source' => $dao->source,
+          'status_id' => $dao->status_id
+        );
+        // create/update membership(s) for related contact(s)
+        CRM_Member_BAO_Membership::createRelatedMemberships($membershipParams, $dao);
+      } // end of if relationshipTypeId
+    }
+  }
 }