From 808c05a997dadef04c8a0903d6762545550c617c Mon Sep 17 00:00:00 2001 From: eileen Date: Sat, 18 Jun 2016 11:34:03 +1200 Subject: [PATCH] CRM-18575 autoflip fix. Do not pass autoflip when batch merging. Fix autoflip by passing do not autoflip to respect prevnext contents & fully altering those contents. I was going to refactor further but without an api for the entity it's a drag & there is contention about adding apis just to help improve code quality because they aren't 'protected' --- CRM/Contact/Page/AJAX.php | 20 ++---- CRM/Contact/Page/DedupeMerge.php | 7 +- CRM/Core/BAO/PrevNextCache.php | 31 +++++++++ .../CRM/Core/BAO/PrevNextCacheTest.php | 65 +++++++++++++++++++ 4 files changed, 106 insertions(+), 17 deletions(-) create mode 100644 tests/phpunit/CRM/Core/BAO/PrevNextCacheTest.php diff --git a/CRM/Contact/Page/AJAX.php b/CRM/Contact/Page/AJAX.php index 2ff0ea6a69..84052e751f 100644 --- a/CRM/Contact/Page/AJAX.php +++ b/CRM/Contact/Page/AJAX.php @@ -886,22 +886,16 @@ LIMIT {$offset}, {$rowCount} */ public static function flipDupePairs($prevNextId = NULL) { if (!$prevNextId) { - $prevNextId = $_REQUEST['pnid']; + // @todo figure out if this is always POST & specify that rather than inexact GET + $prevNextId = CRM_Utils_Request::retrieve('pnid', 'Integer'); } - $query = " - UPDATE civicrm_prevnext_cache cpc - INNER JOIN civicrm_prevnext_cache old on cpc.id = old.id - SET cpc.entity_id1 = cpc.entity_id2, cpc.entity_id2 = old.entity_id1 "; + + $onlySelected = FALSE; if (is_array($prevNextId) && !CRM_Utils_Array::crmIsEmptyArray($prevNextId)) { - CRM_Utils_Type::escapeAll($prevNextId, 'Positive'); - $prevNextId = implode(', ', $prevNextId); - $query .= "WHERE cpc.id IN ({$prevNextId}) AND cpc.is_selected = 1"; - } - else { - $prevNextId = CRM_Utils_Type::escape($prevNextId, 'Positive'); - $query .= "WHERE cpc.id = $prevNextId"; + $onlySelected = TRUE; } - CRM_Core_DAO::executeQuery($query); + $prevNextId = CRM_Utils_Type::escapeAll((array) $prevNextId, 'Positive'); + CRM_Core_BAO_PrevNextCache::flipPair($prevNextId, $onlySelected); CRM_Utils_JSON::output(); } diff --git a/CRM/Contact/Page/DedupeMerge.php b/CRM/Contact/Page/DedupeMerge.php index 3c52f02683..1bdd99c717 100644 --- a/CRM/Contact/Page/DedupeMerge.php +++ b/CRM/Contact/Page/DedupeMerge.php @@ -98,7 +98,7 @@ class CRM_Contact_Page_DedupeMerge extends CRM_Core_Page { for ($i = 1; $i <= ceil($total / self::BATCHLIMIT); $i++) { $task = new CRM_Queue_Task( array('CRM_Contact_Page_DedupeMerge', 'callBatchMerge'), - array($rgid, $gid, $mode, TRUE, self::BATCHLIMIT, $isSelected), + array($rgid, $gid, $mode, FALSE, self::BATCHLIMIT, $isSelected), "Processed " . $i * self::BATCHLIMIT . " pair of duplicates out of " . $total ); @@ -135,9 +135,8 @@ class CRM_Contact_Page_DedupeMerge extends CRM_Core_Page { * * @return int */ - public static function callBatchMerge(CRM_Queue_TaskContext $ctx, $rgid, $gid = NULL, $mode = 'safe', $autoFlip = TRUE, $batchLimit = 1, $isSelected = 2) { - $result = CRM_Dedupe_Merger::batchMerge($rgid, $gid, $mode, $autoFlip, $batchLimit, $isSelected); - + public static function callBatchMerge(CRM_Queue_TaskContext $ctx, $rgid, $gid, $mode = 'safe', $autoFlip, $batchLimit, $isSelected) { + CRM_Dedupe_Merger::batchMerge($rgid, $gid, $mode, $autoFlip, $batchLimit, $isSelected); return CRM_Queue_Task::TASK_SUCCESS; } diff --git a/CRM/Core/BAO/PrevNextCache.php b/CRM/Core/BAO/PrevNextCache.php index 91bb827804..649d997e70 100644 --- a/CRM/Core/BAO/PrevNextCache.php +++ b/CRM/Core/BAO/PrevNextCache.php @@ -601,4 +601,35 @@ WHERE cacheKey LIKE %1 return $params; } + /** + * Flip 2 contacts in the prevNext cache. + * + * @param array $prevNextId + * @param bool $onlySelected + * Only flip those which have been marked as selected. + */ + public static function flipPair(array $prevNextId, $onlySelected) { + $dao = new CRM_Core_DAO_PrevNextCache(); + if ($onlySelected) { + $dao->is_selected = 1; + } + foreach ($prevNextId as $id) { + $dao->id = $id; + if ($dao->find(TRUE)) { + $originalData = unserialize($dao->data); + $srcFields = array('ID', 'Name'); + $swapFields = array('srcID', 'srcName', 'dstID', 'dstName'); + $data = array_diff_assoc($originalData, array_fill_keys($swapFields, 1)); + foreach ($srcFields as $key) { + $data['src' . $key] = $originalData['dst' . $key]; + $data['dst' . $key] = $originalData['src' . $key]; + } + $dao->data = serialize($data); + $dao->entity_id1 = $data['srcID']; + $dao->entity_id2 = $data['dstID']; + $dao->save(); + } + } + } + } diff --git a/tests/phpunit/CRM/Core/BAO/PrevNextCacheTest.php b/tests/phpunit/CRM/Core/BAO/PrevNextCacheTest.php new file mode 100644 index 0000000000..4883618798 --- /dev/null +++ b/tests/phpunit/CRM/Core/BAO/PrevNextCacheTest.php @@ -0,0 +1,65 @@ +entity_id1 = 1; + $dao->entity_id2 = 2; + $dao->data = serialize(array( + 'srcID' => 1, + 'srcName' => 'Ms. Meliissa Mouse II', + 'dstID' => 2, + 'dstName' => 'Mr. Maurice Mouse II', + 'weight' => 20, + 'canMerge' => TRUE, + )); + $dao->save(); + $dao = new CRM_Core_BAO_PrevNextCache(); + $dao->id = 1; + CRM_Core_BAO_PrevNextCache::flipPair(array(1), 0); + $dao->find(TRUE); + $this->assertEquals(2, $dao->entity_id1); + $this->assertEquals(1, $dao->entity_id2); + $this->assertEquals(serialize(array( + 'srcName' => 'Mr. Maurice Mouse II', + 'dstID' => 1, + 'dstName' => 'Ms. Meliissa Mouse II', + 'weight' => 20, + 'canMerge' => TRUE, + 'srcID' => 2, + )), $dao->data); + + $this->quickCleanup(array('civicrm_prevnext_cache')); + } + +} -- 2.25.1