X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FDedupe%2FMerger.php;h=688cc8885b6a1f1caf5a73403f327727465587cb;hb=5dc8d80defb19ece6aed1a0b1a56dac949573ba2;hp=8504ef34f004caf5ebcc98672050d7a4d4efe3c5;hpb=247c61fa454779bdc86af166b95199c80d8435a0;p=civicrm-core.git diff --git a/CRM/Dedupe/Merger.php b/CRM/Dedupe/Merger.php index 8504ef34f0..688cc8885b 100644 --- a/CRM/Dedupe/Merger.php +++ b/CRM/Dedupe/Merger.php @@ -1,9 +1,9 @@ array('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'), - 'civicrm_contribution_page' => array('created_id'), - 'civicrm_contribution_recur' => array('contact_id'), - 'civicrm_contribution_soft' => array('contact_id'), - 'civicrm_financial_item' => array('contact_id'), - 'civicrm_custom_group' => array('created_id'), - 'civicrm_entity_tag' => array('entity_id'), - 'civicrm_event' => array('created_id'), - 'civicrm_grant' => array('contact_id'), - 'civicrm_group_contact' => array('contact_id'), - 'civicrm_group_organization' => array('organization_id'), - 'civicrm_log' => array('modified_id'), - 'civicrm_mailing' => array('created_id', 'scheduled_id'), - 'civicrm_mailing_event_queue' => array('contact_id'), - 'civicrm_mailing_event_subscribe' => array('contact_id'), - 'civicrm_membership' => array('contact_id'), - 'civicrm_membership_log' => array('modified_id'), - 'civicrm_membership_type' => array('member_of_contact_id'), - 'civicrm_note' => array('contact_id'), - 'civicrm_participant' => array('contact_id'), - 'civicrm_pcp' => array('contact_id'), - 'civicrm_relationship' => array('contact_id_a', 'contact_id_b'), - 'civicrm_uf_match' => array('contact_id'), - 'civicrm_uf_group' => array('created_id'), - 'civicrm_pledge' => array('contact_id'), - ); - - $cidRefs += self::getMultiValueCustomSets('cidRefs'); - - // Add ContactReference custom fields CRM-9561 - $sql = "SELECT cg.table_name, cf.column_name - FROM civicrm_custom_group cg, civicrm_custom_field cf - WHERE cg.id = cf.custom_group_id AND cf.data_type = 'ContactReference'"; + $sql = " +SELECT + table_name, + column_name +FROM information_schema.key_column_usage +WHERE + referenced_table_schema = database() AND + referenced_table_name = 'civicrm_contact' AND + referenced_column_name = 'id'; + "; $dao = CRM_Core_DAO::executeQuery($sql); while ($dao->fetch()) { $cidRefs[$dao->table_name][] = $dao->column_name; } + + // FixME for time being adding below line statically as no Foreign key constraint defined for table 'civicrm_entity_tag' + $cidRefs['civicrm_entity_tag'][] = 'entity_id'; $dao->free(); // Allow hook_civicrm_merge() to adjust $cidRefs @@ -372,6 +348,15 @@ INNER JOIN civicrm_participant participant ON ( participant.id = payment.partic return $sqls; } + /** + * @param $mainId + * @param $otherId + * @param $tableName + * @param array $tableOperations + * @param string $mode + * + * @return array + */ static function operationSql($mainId, $otherId, $tableName, $tableOperations = array(), $mode = 'add') { $sqls = array(); if (!$tableName || !$mainId || !$otherId) { @@ -474,11 +459,13 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m foreach ($cidRefs[$table] as $field) { // carry related contributions CRM-5359 if (in_array($table, $paymentTables)) { - $payOprSqls = self::operationSql($mainId, $otherId, $table, $tableOperations, 'payment'); - $sqls = array_merge($sqls, $payOprSqls); - $paymentSqls = self::paymentSql($table, $mainId, $otherId); $sqls = array_merge($sqls, $paymentSqls); + + if (!empty($tables) && !in_array('civicrm_contribution', $tables)) { + $payOprSqls = self::operationSql($mainId, $otherId, $table, $tableOperations, 'payment'); + $sqls = array_merge($sqls, $payOprSqls); + } } $preOperationSqls = self::operationSql($mainId, $otherId, $table, $tableOperations); @@ -518,6 +505,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m * @param array $main contact details * @param array $other contact details * + * @return array * @static */ static function findDifferences($main, $other) { @@ -551,16 +539,19 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m /** * Function to batch merge a set of contacts based on rule-group and group. * - * @param int $rgid rule group id - * @param int $gid group id - * @param array $cacheParams prev-next-cache params based on which next pair of contacts are computed. - * Generally used with batch-merge. - * @param string $mode helps decide how to behave when there are conflicts. + * @param int $rgid rule group id + * @param int $gid group id + * @param string $mode helps decide how to behave when there are conflicts. * A 'safe' value skips the merge if there are any un-resolved conflicts. * Does a force merge otherwise. - * @param boolean $autoFlip wether to let api decide which contact to retain and which to delete. + * @param boolean $autoFlip wether to let api decide which contact to retain and which to delete. + * * + * @param bool $redirectForPerformance * + * @return array|bool + * @internal param array $cacheParams prev-next-cache params based on which next pair of contacts are computed. + * Generally used with batch-merge. * @static * @access public */ @@ -594,15 +585,18 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m /** * Function to merge given set of contacts. Performs core operation. * - * @param array $dupePairs set of pair of contacts for whom merge is to be done. - * @param array $cacheParams prev-next-cache params based on which next pair of contacts are computed. + * @param array $dupePairs set of pair of contacts for whom merge is to be done. + * @param array $cacheParams prev-next-cache params based on which next pair of contacts are computed. * Generally used with batch-merge. - * @param string $mode helps decide how to behave when there are conflicts. + * @param string $mode helps decide how to behave when there are conflicts. * A 'safe' value skips the merge if there are any un-resolved conflicts. * Does a force merge otherwise (aggressive mode). - * @param boolean $autoFlip wether to let api decide which contact to retain and which to delete. + * @param boolean $autoFlip wether to let api decide which contact to retain and which to delete. * * + * @param bool $redirectForPerformance + * + * @return array|bool * @static * @access public */ @@ -620,10 +614,12 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m while (!empty($dupePairs)) { foreach ($dupePairs as $dupes) { + CRM_Utils_Hook::merge('flip', $dupes, $dupes['dstID'], $dupes['srcID']); $mainId = $dupes['dstID']; $otherId = $dupes['srcID']; - // make sure that $mainId is the one with lower id number - if ($autoFlip && ($mainId > $otherId)) { + $isAutoFlip = CRM_Utils_Array::value('auto_flip', $dupes, $autoFlip); + // if we can, make sure that $mainId is the one with lower id number + if ($isAutoFlip && ($mainId > $otherId)) { $mainId = $dupes['srcID']; $otherId = $dupes['dstID']; } @@ -681,13 +677,14 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m * A function which uses various rules / algorithms for choosing which contact to bias to * when there's a conflict (to handle "gotchas"). Plus the safest route to merge. * - * @param int $mainId main contact with whom merge has to happen - * @param int $otherId duplicate contact which would be deleted after merge operation - * @param array $migrationInfo array of information about which elements to merge. - * @param string $mode helps decide how to behave when there are conflicts. + * @param int $mainId main contact with whom merge has to happen + * @param int $otherId duplicate contact which would be deleted after merge operation + * @param array $migrationInfo array of information about which elements to merge. + * @param string $mode helps decide how to behave when there are conflicts. * A 'safe' value skips the merge if there are any un-resolved conflicts. * Does a force merge otherwise (aggressive mode). * + * @return bool * @static * @access public */ @@ -731,7 +728,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m // Rule: resolve address conflict if any - if ($fieldName == 'address') { $mainNewLocTypeId = $migrationInfo['location'][$fieldName][$fieldCount]['locTypeId']; - if (CRM_Utils_Array::value('main_loc_address', $migrationInfo) && + if (!empty($migrationInfo['main_loc_address']) && array_key_exists("main_{$mainNewLocTypeId}", $migrationInfo['main_loc_address'])) { // main loc already has some address for the loc-type. Its a overwrite situation. @@ -792,9 +789,10 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m /** * A function to build an array of information required by merge function and the merge UI. * - * @param int $mainId main contact with whom merge has to happen - * @param int $otherId duplicate contact which would be deleted after merge operation + * @param int $mainId main contact with whom merge has to happen + * @param int $otherId duplicate contact which would be deleted after merge operation * + * @return array|bool|int * @static * @access public */ @@ -827,7 +825,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m 'preferred_communication_method' => $value, ); - if (CRM_Utils_array::value('preferred_communication_method', $contact)){ + if (!empty($contact['preferred_communication_method'])){ // api 3 returns pref_comm_method as an array, which breaks the lookup; so we reconstruct $prefCommList = is_array($specialValues[$moniker]['preferred_communication_method']) ? implode(CRM_Core_DAO::VALUE_SEPARATOR, $specialValues[$moniker]['preferred_communication_method']) : @@ -864,7 +862,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m $value = CRM_Core_DAO::VALUE_SEPARATOR . trim($specialValues[$moniker][$field], CRM_Core_DAO::VALUE_SEPARATOR) . CRM_Core_DAO::VALUE_SEPARATOR; } $label = isset($specialValues[$moniker]["{$field}_display"]) ? $specialValues[$moniker]["{$field}_display"] : $value; - if (CRM_Utils_Array::value('type', $fields[$field]) && $fields[$field]['type'] == CRM_Utils_Type::T_DATE) { + if (!empty($fields[$field]['type']) && $fields[$field]['type'] == CRM_Utils_Type::T_DATE) { if ($value) { $value = str_replace('-', '', $value); $label = CRM_Utils_Date::customFormat($label); @@ -873,19 +871,21 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m $value = "null"; } } - elseif (CRM_Utils_Array::value('type', $fields[$field]) && $fields[$field]['type'] == CRM_Utils_Type::T_BOOLEAN) { + elseif (!empty($fields[$field]['type']) && $fields[$field]['type'] == CRM_Utils_Type::T_BOOLEAN) { if ($label === '0') { $label = ts('[ ]'); } if ($label === '1') { $label = ts('[x]'); } - } elseif ($field == 'individual_prefix' || $field == 'prefix_id') { - $label = CRM_Utils_Array::value('prefix', $contact); + } + elseif ($field == 'individual_prefix' || $field == 'prefix_id') { + $label = CRM_Utils_Array::value('individual_prefix', $contact); $value = CRM_Utils_Array::value('prefix_id', $contact); $field = 'prefix_id'; - } elseif ($field == 'individual_suffix' || $field == 'suffix_id') { - $label = CRM_Utils_Array::value('suffix', $contact); + } + elseif ($field == 'individual_suffix' || $field == 'suffix_id') { + $label = CRM_Utils_Array::value('individual_suffix', $contact); $value = CRM_Utils_Array::value('suffix_id', $contact); $field = 'suffix_id'; } @@ -898,8 +898,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m if ($value === 0 or $value === '0') { $value = $qfZeroBug; } - if (is_array($value) && - !CRM_Utils_Array::value(1, $value)) { + if (is_array($value) && empty($value[1])) { $value[1] = NULL; } $elements[] = array('advcheckbox', "move_$field", NULL, NULL, NULL, $value); @@ -1121,7 +1120,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m $rows["custom_group_$gid"]['title'] = $group['title']; $foundField = TRUE; } - if (CRM_Utils_Array::value('customValue', $mainTree[$gid]['fields'][$fid])) { + if (!empty($mainTree[$gid]['fields'][$fid]['customValue'])) { foreach ($mainTree[$gid]['fields'][$fid]['customValue'] as $valueId => $values) { $rows["move_custom_$fid"]['main'] = CRM_Core_BAO_CustomGroup::formatCustomValues($values, $field, TRUE @@ -1129,7 +1128,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m } } $value = "null"; - if (CRM_Utils_Array::value('customValue', $otherTree[$gid]['fields'][$fid])) { + if (!empty($otherTree[$gid]['fields'][$fid]['customValue'])) { foreach ($otherTree[$gid]['fields'][$fid]['customValue'] as $valueId => $values) { $rows["move_custom_$fid"]['other'] = CRM_Core_BAO_CustomGroup::formatCustomValues($values, $field, TRUE @@ -1169,9 +1168,12 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m * 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 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 * @static * @access public */ @@ -1313,6 +1315,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m $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'); @@ -1364,7 +1367,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m // get the existing custom values from db. $customParams = array('entityID' => $mainId, $key => TRUE); $customfieldValues = CRM_Core_BAO_CustomValueTable::getValues($customParams); - if (CRM_Utils_array::value($key, $customfieldValues)) { + if (!empty($customfieldValues[$key])) { $existingValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $customfieldValues[$key]); if (is_array($existingValue) && !empty($existingValue)) { $mergeValue = $submmtedCustomValue = array(); @@ -1471,9 +1474,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m $viewOnlyCustomFields = array(); foreach ($submitted as $key => $value) { $fid = (int) substr($key, 7); - if (array_key_exists($fid, $cFields) && - CRM_Utils_Array::value('is_view', $cFields[$fid]['attributes']) - ) { + if (array_key_exists($fid, $cFields) && !empty($cFields[$fid]['attributes']['is_view'])) { $viewOnlyCustomFields[$key] = $value; } } @@ -1494,7 +1495,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m CRM_Core_Permission::check('delete contacts') ) { // if ext id is submitted then set it null for contact to be deleted - if (CRM_Utils_Array::value('external_identifier', $submitted)) { + if (!empty($submitted['external_identifier'])) { $query = "UPDATE civicrm_contact SET external_identifier = null WHERE id = {$otherId}"; CRM_Core_DAO::executeQuery($query); } @@ -1524,6 +1525,14 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m 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); }