X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FDedupe%2FMerger.php;h=147512875c5d7bde8eedbc82e4676c4676fc0df2;hb=b5a6c6c508d243a0d424ba1e4b62853045279a3c;hp=bf42eb89e45bdbbc03b4da9831410d1bd2630896;hpb=536a7c4fb7a0b9bb107cfba5ca287837892878c5;p=civicrm-core.git diff --git a/CRM/Dedupe/Merger.php b/CRM/Dedupe/Merger.php index bf42eb89e4..147512875c 100644 --- a/CRM/Dedupe/Merger.php +++ b/CRM/Dedupe/Merger.php @@ -1,7 +1,7 @@ userSystem->getUserRecordUrl() - however that function takes a contact_id & - // we may need a different function when it is not known. - $title = $userRecordUrl = ''; + if (!isset(Civi::$statics[__CLASS__]['relTables'])) { - $config = CRM_Core_Config::singleton(); - if ($config->userSystem->is_drupal) { - $userRecordUrl = CRM_Utils_System::url('user/%ufid'); - $title = ts('%1 User: %2; user id: %3', array(1 => $config->userFramework, 2 => '$ufname', 3 => '$ufid')); - } - elseif ($config->userFramework == 'Joomla') { - $userRecordUrl = $config->userSystem->getVersion() > 1.5 ? $config->userFrameworkBaseURL . "index.php?option=com_users&view=user&task=user.edit&id=" . '%ufid' : $config->userFrameworkBaseURL . "index2.php?option=com_users&view=user&task=edit&id[]=" . '%ufid'; - $title = ts('%1 User: %2; user id: %3', array(1 => $config->userFramework, 2 => '$ufname', 3 => '$ufid')); - } + // Setting these merely prevents enotices - but it may be more appropriate not to add the user table below + // if the url can't be retrieved. A more standardised way to retrieve them is. + // CRM_Core_Config::singleton()->userSystem->getUserRecordUrl() - however that function takes a contact_id & + // we may need a different function when it is not known. + $title = $userRecordUrl = ''; + + $config = CRM_Core_Config::singleton(); + if ($config->userSystem->is_drupal) { + $userRecordUrl = CRM_Utils_System::url('user/%ufid'); + $title = ts('%1 User: %2; user id: %3', array(1 => $config->userFramework, 2 => '$ufname', 3 => '$ufid')); + } + elseif ($config->userFramework == 'Joomla') { + $userRecordUrl = $config->userSystem->getVersion() > 1.5 ? $config->userFrameworkBaseURL . "index.php?option=com_users&view=user&task=user.edit&id=" . '%ufid' : $config->userFrameworkBaseURL . "index2.php?option=com_users&view=user&task=edit&id[]=" . '%ufid'; + $title = ts('%1 User: %2; user id: %3', array(1 => $config->userFramework, 2 => '$ufname', 3 => '$ufid')); + } - if (!$relTables) { $relTables = array( 'rel_table_contributions' => array( 'title' => ts('Contributions'), @@ -155,8 +155,12 @@ class CRM_Dedupe_Merger { // Allow hook_civicrm_merge() to adjust $relTables CRM_Utils_Hook::merge('relTables', $relTables); + + // Cache the results in a static variable + Civi::$statics[__CLASS__]['relTables'] = $relTables; } - return $relTables; + + return Civi::$statics[__CLASS__]['relTables']; } /** @@ -273,11 +277,12 @@ class CRM_Dedupe_Merger { * We treat multi-valued custom sets as "related tables" similar to activities, contributions, etc. * @param string $request * 'relTables' or 'cidRefs'. + * @return array * @see CRM-13836 */ public static function getMultiValueCustomSets($request) { - static $data = NULL; - if ($data === NULL) { + + if (!isset(Civi::$statics[__CLASS__]['multiValueCustomSets'])) { $data = array( 'relTables' => array(), 'cidRefs' => array(), @@ -296,8 +301,12 @@ class CRM_Dedupe_Merger { 'url' => CRM_Utils_System::url('civicrm/contact/view', 'reset=1&force=1&cid=$cid' . $urlSuffix), ); } + + // Store the result in a static variable cache + Civi::$statics[__CLASS__]['multiValueCustomSets'] = $data; } - return $data[$request]; + + return Civi::$statics[__CLASS__]['multiValueCustomSets'][$request]; } /** @@ -313,6 +322,7 @@ class CRM_Dedupe_Merger { // Empty array == do nothing - this table is handled by mergeGroupContact 'civicrm_subscription_history' => array(), 'civicrm_relationship' => array('CRM_Contact_BAO_Relationship' => 'mergeRelationships'), + 'civicrm_membership' => array('CRM_Member_BAO_Membership' => 'mergeMemberships'), ); } return $tables; @@ -495,18 +505,21 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m $mainId = (int) $mainId; $otherId = (int) $otherId; + $multi_value_tables = array_keys(CRM_Dedupe_Merger::getMultiValueCustomSets('cidRefs')); $sqls = array(); foreach ($affected as $table) { - // skipping non selected custom table's value migration - if ($customTableToCopyFrom !== NULL && in_array($table, $customTables) && !in_array($table, $customTableToCopyFrom)) { - continue; + // skipping non selected single-value custom table's value migration + if (!in_array($table, $multi_value_tables)) { + if ($customTableToCopyFrom !== NULL && in_array($table, $customTables) && !in_array($table, $customTableToCopyFrom)) { + continue; + } } // Call custom processing function for objects that require it if (isset($cpTables[$table])) { foreach ($cpTables[$table] as $className => $fnName) { - $className::$fnName($mainId, $otherId, $sqls); + $className::$fnName($mainId, $otherId, $sqls, $tables, $tableOperations); } // Skip normal processing continue; @@ -638,18 +651,31 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m * mode does a force merge. * @param int $batchLimit number of merges to carry out in one batch. * @param int $isSelected if records with is_selected column needs to be processed. + * Note the option of '2' is only used in conjunction with $redirectForPerformance + * to determine when to reload the cache (!). The use of anything other than a boolean is being grandfathered + * out in favour of explicitly passing in $reloadCacheIfEmpty * * @param array $criteria * Criteria to use in the filter. * * @param bool $checkPermissions * Respect logged in user permissions. + * @param bool|NULL $reloadCacheIfEmpty + * If not set explicitly this is calculated but it is preferred that it be set + * per comments on isSelected above. * * @return array|bool */ - public static function batchMerge($rgid, $gid = NULL, $mode = 'safe', $batchLimit = 1, $isSelected = 2, $criteria = array(), $checkPermissions = TRUE) { + public static function batchMerge($rgid, $gid = NULL, $mode = 'safe', $batchLimit = 1, $isSelected = 2, $criteria = array(), $checkPermissions = TRUE, $reloadCacheIfEmpty = NULL) { $redirectForPerformance = ($batchLimit > 1) ? TRUE : FALSE; - $reloadCacheIfEmpty = (!$redirectForPerformance && $isSelected == 2); + + if (!isset($reloadCacheIfEmpty)) { + $reloadCacheIfEmpty = (!$redirectForPerformance && $isSelected == 2); + } + if ($isSelected !== 0 && $isSelected !== 1) { + // explicitly set to NULL if not 1 or 0 as part of grandfathering out the mystical '2' value. + $isSelected = NULL; + } $dupePairs = self::getDuplicatePairs($rgid, $gid, $reloadCacheIfEmpty, $batchLimit, $isSelected, '', ($mode == 'aggressive'), $criteria, $checkPermissions); $cacheParams = array( @@ -657,7 +683,8 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m // @todo stop passing these parameters in & instead calculate them in the merge function based // on the 'real' params like $isRespectExclusions $batchLimit and $isSelected. 'join' => self::getJoinOnDedupeTable(), - 'where' => self::getWhereString($batchLimit, $isSelected), + 'where' => self::getWhereString($isSelected), + 'limit' => (int) $batchLimit, ); return CRM_Dedupe_Merger::merge($dupePairs, $cacheParams, $mode, $redirectForPerformance, $checkPermissions); } @@ -680,21 +707,15 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m /** * Get where string for dedupe join. * - * @param int $batchLimit * @param bool $isSelected * * @return string */ - protected static function getWhereString($batchLimit, $isSelected) { + protected static function getWhereString($isSelected) { $where = "de.id IS NULL"; if ($isSelected === 0 || $isSelected === 1) { $where .= " AND pn.is_selected = {$isSelected}"; } - // else consider all dupe pairs - // @todo Adding limit to Where??!! - if ($batchLimit) { - $where .= " LIMIT {$batchLimit}"; - } return $where; } @@ -845,7 +866,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m $cacheParams['join'], $cacheParams['where'], 0, - 0, + $cacheParams['limit'], array(), '', FALSE @@ -1620,7 +1641,6 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m break; case 'CheckBox': - case 'AdvMulti-Select': case 'Multi-Select': case 'Multi-Select Country': case 'Multi-Select State/Province': @@ -1654,7 +1674,6 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m if (in_array($htmlType, array( 'CheckBox', 'Multi-Select', - 'AdvMulti-Select', ))) { $submitted[$key] = CRM_Core_DAO::VALUE_SEPARATOR . implode(CRM_Core_DAO::VALUE_SEPARATOR, $mergeValue @@ -1981,16 +2000,16 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m * Array of matches meeting the criteria. */ public static function getDuplicatePairs($rule_group_id, $group_id, $reloadCacheIfEmpty, $batchLimit, $isSelected, $orderByClause = '', $includeConflicts = TRUE, $criteria = array(), $checkPermissions = TRUE, $searchLimit = 0) { - $where = self::getWhereString($batchLimit, $isSelected); + $where = self::getWhereString($isSelected); $cacheKeyString = self::getMergeCacheKeyString($rule_group_id, $group_id, $criteria, $checkPermissions); $join = self::getJoinOnDedupeTable(); - $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where, 0, 0, array(), $orderByClause, $includeConflicts); + $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where, 0, $batchLimit, array(), $orderByClause, $includeConflicts); if (empty($dupePairs) && $reloadCacheIfEmpty) { // If we haven't found any dupes, probably cache is empty. // Try filling cache and give another try. We don't need to specify include conflicts here are there will not be any // until we have done some processing. CRM_Core_BAO_PrevNextCache::refillCache($rule_group_id, $group_id, $cacheKeyString, $criteria, $checkPermissions, $searchLimit); - $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where, 0, 0, array(), $orderByClause, $includeConflicts); + $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where, 0, $batchLimit, array(), $orderByClause, $includeConflicts); return $dupePairs; } return $dupePairs;