/**
  * Based on the provided two contact_ids and a set of tables, move the belongings of the
  * other contact to the main one - be it Location / CustomFields or Contact .. related info.
  * A superset of moveContactBelongings() function.
  *
  * @param int $mainId
  *   Main contact with whom merge has to happen.
  * @param int $otherId
  *   Duplicate contact which would be deleted after merge operation.
  *
  * @param $migrationInfo
  *
  * @return bool
  */
 public static function moveAllBelongings($mainId, $otherId, $migrationInfo)
 {
     if (empty($migrationInfo)) {
         return FALSE;
     }
     $qfZeroBug = 'e8cddb72-a257-11dc-b9cc-0016d3330ee9';
     $relTables = CRM_Dedupe_Merger::relTables();
     $moveTables = $locBlocks = $tableOperations = array();
     foreach ($migrationInfo as $key => $value) {
         if ($value == $qfZeroBug) {
             $value = '0';
         }
         if ((in_array(substr($key, 5), CRM_Dedupe_Merger::getContactFields()) || substr($key, 0, 12) == 'move_custom_') && $value != NULL) {
             $submitted[substr($key, 5)] = $value;
         } elseif (substr($key, 0, 14) == 'move_location_' and $value != NULL) {
             $locField = explode('_', $key);
             $fieldName = $locField[2];
             $fieldCount = $locField[3];
             $operation = CRM_Utils_Array::value('operation', $migrationInfo['location'][$fieldName][$fieldCount]);
             // default operation is overwrite.
             if (!$operation) {
                 $operation = 2;
             }
             $locBlocks[$fieldName][$fieldCount]['operation'] = $operation;
             $locBlocks[$fieldName][$fieldCount]['locTypeId'] = CRM_Utils_Array::value('locTypeId', $migrationInfo['location'][$fieldName][$fieldCount]);
         } elseif (substr($key, 0, 15) == 'move_rel_table_' and $value == '1') {
             $moveTables = array_merge($moveTables, $relTables[substr($key, 5)]['tables']);
             if (array_key_exists('operation', $migrationInfo)) {
                 foreach ($relTables[substr($key, 5)]['tables'] as $table) {
                     if (array_key_exists($key, $migrationInfo['operation'])) {
                         $tableOperations[$table] = $migrationInfo['operation'][$key];
                     }
                 }
             }
         }
     }
     // **** Do location related migration:
     if (!empty($locBlocks)) {
         $locComponent = array('email' => 'Email', 'phone' => 'Phone', 'im' => 'IM', 'openid' => 'OpenID', 'address' => 'Address');
         $primaryBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($mainId, array('is_primary' => 1));
         $billingBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($mainId, array('is_billing' => 1));
         foreach ($locBlocks as $name => $block) {
             if (!is_array($block) || CRM_Utils_System::isNull($block)) {
                 continue;
             }
             $daoName = 'CRM_Core_DAO_' . $locComponent[$name];
             $primaryDAOId = array_key_exists($name, $primaryBlockIds) ? array_pop($primaryBlockIds[$name]) : NULL;
             $billingDAOId = array_key_exists($name, $billingBlockIds) ? array_pop($billingBlockIds[$name]) : NULL;
             foreach ($block as $blkCount => $values) {
                 $locTypeId = CRM_Utils_Array::value('locTypeId', $values, 1);
                 $operation = CRM_Utils_Array::value('operation', $values, 2);
                 $otherBlockId = CRM_Utils_Array::value($blkCount, $migrationInfo['other_details']['loc_block_ids'][$name]);
                 // keep 1-1 mapping for address - loc type.
                 $idKey = $blkCount;
                 if (array_key_exists($name, $locComponent)) {
                     $idKey = $locTypeId;
                 }
                 if (isset($migrationInfo['main_details']['loc_block_ids'][$name])) {
                     $mainBlockId = CRM_Utils_Array::value($idKey, $migrationInfo['main_details']['loc_block_ids'][$name]);
                 }
                 if (!$otherBlockId) {
                     continue;
                 }
                 // for the block which belongs to other-contact, link the contact to main-contact
                 $otherBlockDAO = new $daoName();
                 $otherBlockDAO->id = $otherBlockId;
                 $otherBlockDAO->contact_id = $mainId;
                 $otherBlockDAO->location_type_id = $locTypeId;
                 // if main contact already has primary & billing, set the flags to 0.
                 if ($primaryDAOId) {
                     $otherBlockDAO->is_primary = 0;
                 }
                 if ($billingDAOId) {
                     $otherBlockDAO->is_billing = 0;
                 }
                 // overwrite - need to delete block which belongs to main-contact.
                 if (isset($mainBlockId) && $mainBlockId && $operation == 2) {
                     $deleteDAO = new $daoName();
                     $deleteDAO->id = $mainBlockId;
                     $deleteDAO->find(TRUE);
                     // if we about to delete a primary / billing block, set the flags for new block
                     // that we going to assign to main-contact
                     if ($primaryDAOId && $primaryDAOId == $deleteDAO->id) {
                         $otherBlockDAO->is_primary = 1;
                     }
                     if ($billingDAOId && $billingDAOId == $deleteDAO->id) {
                         $otherBlockDAO->is_billing = 1;
                     }
                     $deleteDAO->delete();
                     $deleteDAO->free();
                 }
                 $otherBlockDAO->update();
                 $otherBlockDAO->free();
             }
         }
     }
     // **** Do tables related migrations
     if (!empty($moveTables)) {
         CRM_Dedupe_Merger::moveContactBelongings($mainId, $otherId, $moveTables, $tableOperations);
         unset($moveTables, $tableOperations);
     }
     // **** Do contact related migrations
     CRM_Dedupe_Merger::moveContactBelongings($mainId, $otherId);
     // FIXME: fix gender, prefix and postfix, so they're edible by createProfileContact()
     $names['gender'] = array('newName' => 'gender_id', 'groupName' => 'gender');
     $names['individual_prefix'] = array('newName' => 'prefix_id', 'groupName' => 'individual_prefix');
     $names['individual_suffix'] = array('newName' => 'suffix_id', 'groupName' => 'individual_suffix');
     $names['communication_style'] = array('newName' => 'communication_style_id', 'groupName' => 'communication_style');
     $names['addressee'] = array('newName' => 'addressee_id', 'groupName' => 'addressee');
     $names['email_greeting'] = array('newName' => 'email_greeting_id', 'groupName' => 'email_greeting');
     $names['postal_greeting'] = array('newName' => 'postal_greeting_id', 'groupName' => 'postal_greeting');
     CRM_Core_OptionGroup::lookupValues($submitted, $names, TRUE);
     // fix custom fields so they're edible by createProfileContact()
     static $treeCache = array();
     if (!array_key_exists($migrationInfo['main_details']['contact_type'], $treeCache)) {
         $treeCache[$migrationInfo['main_details']['contact_type']] = CRM_Core_BAO_CustomGroup::getTree($migrationInfo['main_details']['contact_type'], CRM_Core_DAO::$_nullObject, NULL, -1);
     }
     $cgTree =& $treeCache[$migrationInfo['main_details']['contact_type']];
     $cFields = array();
     foreach ($cgTree as $key => $group) {
         if (!isset($group['fields'])) {
             continue;
         }
         foreach ($group['fields'] as $fid => $field) {
             $cFields[$fid]['attributes'] = $field;
         }
     }
     if (!isset($submitted)) {
         $submitted = array();
     }
     foreach ($submitted as $key => $value) {
         if (substr($key, 0, 7) == 'custom_') {
             $fid = (int) substr($key, 7);
             if (empty($cFields[$fid])) {
                 continue;
             }
             $htmlType = $cFields[$fid]['attributes']['html_type'];
             switch ($htmlType) {
                 case 'File':
                     $customFiles[] = $fid;
                     unset($submitted["custom_{$fid}"]);
                     break;
                 case 'Select Country':
                 case 'Select State/Province':
                     $submitted[$key] = CRM_Core_BAO_CustomField::getDisplayValue($value, $fid, $cFields);
                     break;
                 case 'CheckBox':
                 case 'AdvMulti-Select':
                 case 'Multi-Select':
                 case 'Multi-Select Country':
                 case 'Multi-Select State/Province':
                     // Merge values from both contacts for multivalue fields, CRM-4385
                     // get the existing custom values from db.
                     $customParams = array('entityID' => $mainId, $key => TRUE);
                     $customfieldValues = CRM_Core_BAO_CustomValueTable::getValues($customParams);
                     if (!empty($customfieldValues[$key])) {
                         $existingValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $customfieldValues[$key]);
                         if (is_array($existingValue) && !empty($existingValue)) {
                             $mergeValue = $submmtedCustomValue = array();
                             if ($value) {
                                 $submmtedCustomValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value);
                             }
                             //hack to remove null and duplicate values from array.
                             foreach (array_merge($submmtedCustomValue, $existingValue) as $k => $v) {
                                 if ($v != '' && !in_array($v, $mergeValue)) {
                                     $mergeValue[] = $v;
                                 }
                             }
                             //keep state and country as array format.
                             //for checkbox and m-select format w/ VALUE_SEPARATOR
                             if (in_array($htmlType, array('CheckBox', 'Multi-Select', 'AdvMulti-Select'))) {
                                 $submitted[$key] = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR, $mergeValue) . CRM_Core_DAO::VALUE_SEPARATOR;
                             } else {
                                 $submitted[$key] = $mergeValue;
                             }
                         }
                     } elseif (in_array($htmlType, array('Multi-Select Country', 'Multi-Select State/Province'))) {
                         //we require submitted values should be in array format
                         if ($value) {
                             $mergeValueArray = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value);
                             //hack to remove null values from array.
                             $mergeValue = array();
                             foreach ($mergeValueArray as $k => $v) {
                                 if ($v != '') {
                                     $mergeValue[] = $v;
                                 }
                             }
                             $submitted[$key] = $mergeValue;
                         }
                     }
                     break;
                 default:
                     break;
             }
         }
     }
     // **** Do file custom fields related migrations
     // FIXME: move this someplace else (one of the BAOs) after discussing
     // where to, and whether CRM_Core_BAO_File::deleteFileReferences() shouldn't actually,
     // like, delete a file...
     if (!isset($customFiles)) {
         $customFiles = array();
     }
     foreach ($customFiles as $customId) {
         list($tableName, $columnName, $groupID) = CRM_Core_BAO_CustomField::getTableColumnGroup($customId);
         // get the contact_id -> file_id mapping
         $fileIds = array();
         $sql = "SELECT entity_id, {$columnName} AS file_id FROM {$tableName} WHERE entity_id IN ({$mainId}, {$otherId})";
         $dao = CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray);
         while ($dao->fetch()) {
             $fileIds[$dao->entity_id] = $dao->file_id;
         }
         $dao->free();
         // delete the main contact's file
         if (!empty($fileIds[$mainId])) {
             CRM_Core_BAO_File::deleteFileReferences($fileIds[$mainId], $mainId, $customId);
         }
         // move the other contact's file to main contact
         //NYSS need to INSERT or UPDATE depending on whether main contact has an existing record
         if (CRM_Core_DAO::singleValueQuery("SELECT id FROM {$tableName} WHERE entity_id = {$mainId}")) {
             $sql = "UPDATE {$tableName} SET {$columnName} = {$fileIds[$otherId]} WHERE entity_id = {$mainId}";
         } else {
             $sql = "INSERT INTO {$tableName} ( entity_id, {$columnName} ) VALUES ( {$mainId}, {$fileIds[$otherId]} )";
         }
         CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray);
         if (CRM_Core_DAO::singleValueQuery("\n        SELECT id\n        FROM civicrm_entity_file\n        WHERE entity_table = '{$tableName}' AND file_id = {$fileIds[$otherId]}")) {
             $sql = "\n          UPDATE civicrm_entity_file\n          SET entity_id = {$mainId}\n          WHERE entity_table = '{$tableName}' AND file_id = {$fileIds[$otherId]}";
         } else {
             $sql = "\n          INSERT INTO civicrm_entity_file ( entity_table, entity_id, file_id )\n          VALUES ( '{$tableName}', {$mainId}, {$fileIds[$otherId]} )";
         }
         CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray);
     }
     // move view only custom fields CRM-5362
     $viewOnlyCustomFields = array();
     foreach ($submitted as $key => $value) {
         $fid = (int) substr($key, 7);
         if (array_key_exists($fid, $cFields) && !empty($cFields[$fid]['attributes']['is_view'])) {
             $viewOnlyCustomFields[$key] = $value;
         }
     }
     // special case to set values for view only, CRM-5362
     if (!empty($viewOnlyCustomFields)) {
         $viewOnlyCustomFields['entityID'] = $mainId;
         CRM_Core_BAO_CustomValueTable::setValues($viewOnlyCustomFields);
     }
     // **** Delete other contact & update prev-next caching
     $otherParams = array('contact_id' => $otherId, 'id' => $otherId, 'version' => 3);
     if (CRM_Core_Permission::check('merge duplicate contacts') && CRM_Core_Permission::check('delete contacts')) {
         // if ext id is submitted then set it null for contact to be deleted
         if (!empty($submitted['external_identifier'])) {
             $query = "UPDATE civicrm_contact SET external_identifier = null WHERE id = {$otherId}";
             CRM_Core_DAO::executeQuery($query);
         }
         civicrm_api('contact', 'delete', $otherParams);
         CRM_Core_BAO_PrevNextCache::deleteItem($otherId);
     }
     // FIXME: else part
     /*         else { */
     /*             CRM_Core_Session::setStatus( ts('Do not have sufficient permission to delete duplicate contact.') ); */
     /*         } */
     // CRM-15681 merge sub_types
     if ($other_sub_types = CRM_Utils_array::value('contact_sub_type', $migrationInfo['other_details'])) {
         if ($main_sub_types = CRM_Utils_array::value('contact_sub_type', $migrationInfo['main_details'])) {
             $submitted['contact_sub_type'] = array_unique(array_merge($main_sub_types, $other_sub_types));
         } else {
             $submitted['contact_sub_type'] = $other_sub_types;
         }
     }
     // **** Update contact related info for the main contact
     if (!empty($submitted)) {
         $submitted['contact_id'] = $mainId;
         //update current employer field
         if ($currentEmloyerId = CRM_Utils_Array::value('current_employer_id', $submitted)) {
             if (!CRM_Utils_System::isNull($currentEmloyerId)) {
                 $submitted['current_employer'] = $submitted['current_employer_id'];
             } else {
                 $submitted['current_employer'] = '';
             }
             unset($submitted['current_employer_id']);
         }
         //CRM-14312 include prefix/suffix from mainId if not overridden for proper construction of display/sort name
         if (!isset($submitted['prefix_id']) && !empty($migrationInfo['main_details']['prefix_id'])) {
             $submitted['prefix_id'] = $migrationInfo['main_details']['prefix_id'];
         }
         if (!isset($submitted['suffix_id']) && !empty($migrationInfo['main_details']['suffix_id'])) {
             $submitted['suffix_id'] = $migrationInfo['main_details']['suffix_id'];
         }
         CRM_Contact_BAO_Contact::createProfileContact($submitted, CRM_Core_DAO::$_nullArray, $mainId);
         unset($submitted);
     }
     CRM_Utils_Hook::post('merge', 'Contact', $mainId, CRM_Core_DAO::$_nullObject);
     return TRUE;
 }
Beispiel #2
0
 /**
  * Based on the provided two contact_ids and a set of tables, move the belongings of the
  * other contact to the main one - be it Location / CustomFields or Contact .. related info.
  * A superset of moveContactBelongings() function.
  *
  * @param int $mainId
  *   Main contact with whom merge has to happen.
  * @param int $otherId
  *   Duplicate contact which would be deleted after merge operation.
  *
  * @param $migrationInfo
  *
  * @param bool $checkPermissions
  *   Respect logged in user permissions.
  *
  * @return bool
  */
 public static function moveAllBelongings($mainId, $otherId, $migrationInfo, $checkPermissions = TRUE)
 {
     if (empty($migrationInfo)) {
         return FALSE;
     }
     $qfZeroBug = 'e8cddb72-a257-11dc-b9cc-0016d3330ee9';
     $relTables = CRM_Dedupe_Merger::relTables();
     $moveTables = $locationMigrationInfo = $tableOperations = array();
     foreach ($migrationInfo as $key => $value) {
         if ($value == $qfZeroBug) {
             $value = '0';
         }
         if ((in_array(substr($key, 5), CRM_Dedupe_Merger::getContactFields()) || substr($key, 0, 12) == 'move_custom_') && $value != NULL) {
             $submitted[substr($key, 5)] = $value;
         } elseif (substr($key, 0, 14) == 'move_location_' and $value != NULL) {
             $locationMigrationInfo[$key] = $value;
         } elseif (substr($key, 0, 15) == 'move_rel_table_' and $value == '1') {
             $moveTables = array_merge($moveTables, $relTables[substr($key, 5)]['tables']);
             if (array_key_exists('operation', $migrationInfo)) {
                 foreach ($relTables[substr($key, 5)]['tables'] as $table) {
                     if (array_key_exists($key, $migrationInfo['operation'])) {
                         $tableOperations[$table] = $migrationInfo['operation'][$key];
                     }
                 }
             }
         }
     }
     self::mergeLocations($mainId, $otherId, $locationMigrationInfo, $migrationInfo);
     // **** Do tables related migrations
     if (!empty($moveTables)) {
         CRM_Dedupe_Merger::moveContactBelongings($mainId, $otherId, $moveTables, $tableOperations);
         unset($moveTables, $tableOperations);
     }
     // **** Do contact related migrations
     CRM_Dedupe_Merger::moveContactBelongings($mainId, $otherId);
     // FIXME: fix gender, prefix and postfix, so they're edible by createProfileContact()
     $names['gender'] = array('newName' => 'gender_id', 'groupName' => 'gender');
     $names['individual_prefix'] = array('newName' => 'prefix_id', 'groupName' => 'individual_prefix');
     $names['individual_suffix'] = array('newName' => 'suffix_id', 'groupName' => 'individual_suffix');
     $names['communication_style'] = array('newName' => 'communication_style_id', 'groupName' => 'communication_style');
     $names['addressee'] = array('newName' => 'addressee_id', 'groupName' => 'addressee');
     $names['email_greeting'] = array('newName' => 'email_greeting_id', 'groupName' => 'email_greeting');
     $names['postal_greeting'] = array('newName' => 'postal_greeting_id', 'groupName' => 'postal_greeting');
     CRM_Core_OptionGroup::lookupValues($submitted, $names, TRUE);
     // fix custom fields so they're edible by createProfileContact()
     static $treeCache = array();
     if (!array_key_exists($migrationInfo['main_details']['contact_type'], $treeCache)) {
         $treeCache[$migrationInfo['main_details']['contact_type']] = CRM_Core_BAO_CustomGroup::getTree($migrationInfo['main_details']['contact_type'], CRM_Core_DAO::$_nullObject, NULL, -1);
     }
     $cgTree =& $treeCache[$migrationInfo['main_details']['contact_type']];
     $cFields = array();
     foreach ($cgTree as $key => $group) {
         if (!isset($group['fields'])) {
             continue;
         }
         foreach ($group['fields'] as $fid => $field) {
             $cFields[$fid]['attributes'] = $field;
         }
     }
     if (!isset($submitted)) {
         $submitted = array();
     }
     foreach ($submitted as $key => $value) {
         if (substr($key, 0, 7) == 'custom_') {
             $fid = (int) substr($key, 7);
             if (empty($cFields[$fid])) {
                 continue;
             }
             $htmlType = $cFields[$fid]['attributes']['html_type'];
             switch ($htmlType) {
                 case 'File':
                     $customFiles[] = $fid;
                     unset($submitted["custom_{$fid}"]);
                     break;
                 case 'Select Country':
                 case 'Select State/Province':
                     $submitted[$key] = CRM_Core_BAO_CustomField::displayValue($value, $fid);
                     break;
                 case 'Select Date':
                     if ($cFields[$fid]['attributes']['is_view']) {
                         $submitted[$key] = date('YmdHis', strtotime($submitted[$key]));
                     }
                     break;
                 case 'CheckBox':
                 case 'AdvMulti-Select':
                 case 'Multi-Select':
                 case 'Multi-Select Country':
                 case 'Multi-Select State/Province':
                     // Merge values from both contacts for multivalue fields, CRM-4385
                     // get the existing custom values from db.
                     $customParams = array('entityID' => $mainId, $key => TRUE);
                     $customfieldValues = CRM_Core_BAO_CustomValueTable::getValues($customParams);
                     if (!empty($customfieldValues[$key])) {
                         $existingValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $customfieldValues[$key]);
                         if (is_array($existingValue) && !empty($existingValue)) {
                             $mergeValue = $submmtedCustomValue = array();
                             if ($value == 'null') {
                                 // CRM-19074 if someone has deliberately chosen to overwrite with 'null', respect it.
                                 $submitted[$key] = $value;
                             } else {
                                 if ($value) {
                                     $submmtedCustomValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value);
                                 }
                                 //hack to remove null and duplicate values from array.
                                 foreach (array_merge($submmtedCustomValue, $existingValue) as $k => $v) {
                                     if ($v != '' && !in_array($v, $mergeValue)) {
                                         $mergeValue[] = $v;
                                     }
                                 }
                                 //keep state and country as array format.
                                 //for checkbox and m-select format w/ VALUE_SEPARATOR
                                 if (in_array($htmlType, array('CheckBox', 'Multi-Select', 'AdvMulti-Select'))) {
                                     $submitted[$key] = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR, $mergeValue) . CRM_Core_DAO::VALUE_SEPARATOR;
                                 } else {
                                     $submitted[$key] = $mergeValue;
                                 }
                             }
                         }
                     } elseif (in_array($htmlType, array('Multi-Select Country', 'Multi-Select State/Province'))) {
                         //we require submitted values should be in array format
                         if ($value) {
                             $mergeValueArray = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value);
                             //hack to remove null values from array.
                             $mergeValue = array();
                             foreach ($mergeValueArray as $k => $v) {
                                 if ($v != '') {
                                     $mergeValue[] = $v;
                                 }
                             }
                             $submitted[$key] = $mergeValue;
                         }
                     }
                     break;
                 default:
                     break;
             }
         }
     }
     // **** Do file custom fields related migrations
     // FIXME: move this someplace else (one of the BAOs) after discussing
     // where to, and whether CRM_Core_BAO_File::deleteFileReferences() shouldn't actually,
     // like, delete a file...
     if (!isset($customFiles)) {
         $customFiles = array();
     }
     foreach ($customFiles as $customId) {
         list($tableName, $columnName, $groupID) = CRM_Core_BAO_CustomField::getTableColumnGroup($customId);
         // get the contact_id -> file_id mapping
         $fileIds = array();
         $sql = "SELECT entity_id, {$columnName} AS file_id FROM {$tableName} WHERE entity_id IN ({$mainId}, {$otherId})";
         $dao = CRM_Core_DAO::executeQuery($sql);
         while ($dao->fetch()) {
             $fileIds[$dao->entity_id] = $dao->file_id;
         }
         $dao->free();
         // delete the main contact's file
         if (!empty($fileIds[$mainId])) {
             CRM_Core_BAO_File::deleteFileReferences($fileIds[$mainId], $mainId, $customId);
         }
         // move the other contact's file to main contact
         //NYSS need to INSERT or UPDATE depending on whether main contact has an existing record
         if (CRM_Core_DAO::singleValueQuery("SELECT id FROM {$tableName} WHERE entity_id = {$mainId}")) {
             $sql = "UPDATE {$tableName} SET {$columnName} = {$fileIds[$otherId]} WHERE entity_id = {$mainId}";
         } else {
             $sql = "INSERT INTO {$tableName} ( entity_id, {$columnName} ) VALUES ( {$mainId}, {$fileIds[$otherId]} )";
         }
         CRM_Core_DAO::executeQuery($sql);
         if (CRM_Core_DAO::singleValueQuery("\n        SELECT id\n        FROM civicrm_entity_file\n        WHERE entity_table = '{$tableName}' AND file_id = {$fileIds[$otherId]}")) {
             $sql = "\n          UPDATE civicrm_entity_file\n          SET entity_id = {$mainId}\n          WHERE entity_table = '{$tableName}' AND file_id = {$fileIds[$otherId]}";
         } else {
             $sql = "\n          INSERT INTO civicrm_entity_file ( entity_table, entity_id, file_id )\n          VALUES ( '{$tableName}', {$mainId}, {$fileIds[$otherId]} )";
         }
         CRM_Core_DAO::executeQuery($sql);
     }
     // move view only custom fields CRM-5362
     $viewOnlyCustomFields = array();
     foreach ($submitted as $key => $value) {
         $fid = (int) substr($key, 7);
         if (array_key_exists($fid, $cFields) && !empty($cFields[$fid]['attributes']['is_view'])) {
             $viewOnlyCustomFields[$key] = $value;
         }
     }
     // special case to set values for view only, CRM-5362
     if (!empty($viewOnlyCustomFields)) {
         $viewOnlyCustomFields['entityID'] = $mainId;
         CRM_Core_BAO_CustomValueTable::setValues($viewOnlyCustomFields);
     }
     if (!$checkPermissions || CRM_Core_Permission::check('merge duplicate contacts') && CRM_Core_Permission::check('delete contacts')) {
         // if ext id is submitted then set it null for contact to be deleted
         if (!empty($submitted['external_identifier'])) {
             $query = "UPDATE civicrm_contact SET external_identifier = null WHERE id = {$otherId}";
             CRM_Core_DAO::executeQuery($query);
         }
         civicrm_api3('contact', 'delete', array('id' => $otherId));
     }
     // CRM-15681 merge sub_types
     if ($other_sub_types = CRM_Utils_Array::value('contact_sub_type', $migrationInfo['other_details'])) {
         if ($main_sub_types = CRM_Utils_Array::value('contact_sub_type', $migrationInfo['main_details'])) {
             $submitted['contact_sub_type'] = array_unique(array_merge($main_sub_types, $other_sub_types));
         } else {
             $submitted['contact_sub_type'] = $other_sub_types;
         }
     }
     // **** Update contact related info for the main contact
     if (!empty($submitted)) {
         $submitted['contact_id'] = $mainId;
         //update current employer field
         if ($currentEmloyerId = CRM_Utils_Array::value('current_employer_id', $submitted)) {
             if (!CRM_Utils_System::isNull($currentEmloyerId)) {
                 $submitted['current_employer'] = $submitted['current_employer_id'];
             } else {
                 $submitted['current_employer'] = '';
             }
             unset($submitted['current_employer_id']);
         }
         //CRM-14312 include prefix/suffix from mainId if not overridden for proper construction of display/sort name
         if (!isset($submitted['prefix_id']) && !empty($migrationInfo['main_details']['prefix_id'])) {
             $submitted['prefix_id'] = $migrationInfo['main_details']['prefix_id'];
         }
         if (!isset($submitted['suffix_id']) && !empty($migrationInfo['main_details']['suffix_id'])) {
             $submitted['suffix_id'] = $migrationInfo['main_details']['suffix_id'];
         }
         CRM_Contact_BAO_Contact::createProfileContact($submitted, CRM_Core_DAO::$_nullArray, $mainId);
     }
     CRM_Utils_Hook::post('merge', 'Contact', $mainId, CRM_Core_DAO::$_nullObject);
     self::createMergeActivities($mainId, $otherId);
     return TRUE;
 }