Esempio n. 1
0
 /**
  * Retrieve list of duplicate pairs from cache table.
  */
 public static function getDedupes()
 {
     $offset = isset($_REQUEST['start']) ? CRM_Utils_Type::escape($_REQUEST['start'], 'Integer') : 0;
     $rowCount = isset($_REQUEST['length']) ? CRM_Utils_Type::escape($_REQUEST['length'], 'Integer') : 25;
     $gid = CRM_Utils_Request::retrieve('gid', 'Positive');
     $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive');
     $selected = isset($_REQUEST['selected']) ? CRM_Utils_Type::escape($_REQUEST['selected'], 'Integer') : 0;
     if ($rowCount < 0) {
         $rowCount = 0;
     }
     $whereClause = $orderByClause = '';
     $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid);
     $searchRows = array();
     $searchParams = self::getSearchOptionsFromRequest();
     $queryParams = array();
     $join = '';
     $where = array();
     $isOrQuery = self::isOrQuery();
     $nextParamKey = 3;
     $mappings = array('dst' => 'cc1.display_name', 'src' => 'cc2.display_name', 'dst_email' => 'ce1.email', 'src_email' => 'ce2.email', 'dst_postcode' => 'ca1.postal_code', 'src_postcode' => 'ca2.postal_code', 'dst_street' => 'ca1.street', 'src_street' => 'ca2.street');
     foreach ($mappings as $key => $dbName) {
         if (!empty($searchParams[$key])) {
             $queryParams[$nextParamKey] = array('%' . $searchParams[$key] . '%', 'String');
             $where[] = $dbName . " LIKE %{$nextParamKey} ";
             $nextParamKey++;
         }
     }
     if ($isOrQuery) {
         $whereClause = ' ( ' . implode(' OR ', $where) . ' ) ';
     } else {
         if (!empty($where)) {
             $whereClause = implode(' AND ', $where);
         }
     }
     $whereClause .= $whereClause ? ' AND de.id IS NULL' : ' de.id IS NULL';
     if ($selected) {
         $whereClause .= ' AND pn.is_selected = 1';
     }
     $join .= CRM_Dedupe_Merger::getJoinOnDedupeTable();
     $select = array('cc1.contact_type' => 'dst_contact_type', 'cc1.display_name' => 'dst_display_name', 'cc1.contact_sub_type' => 'dst_contact_sub_type', 'cc2.contact_type' => 'src_contact_type', 'cc2.display_name' => 'src_display_name', 'cc2.contact_sub_type' => 'src_contact_sub_type', 'ce1.email' => 'dst_email', 'ce2.email' => 'src_email', 'ca1.postal_code' => 'dst_postcode', 'ca2.postal_code' => 'src_postcode', 'ca1.street_address' => 'dst_street', 'ca2.street_address' => 'src_street');
     if ($select) {
         $join .= " INNER JOIN civicrm_contact cc1 ON cc1.id = pn.entity_id1";
         $join .= " INNER JOIN civicrm_contact cc2 ON cc2.id = pn.entity_id2";
         $join .= " LEFT JOIN civicrm_email ce1 ON (ce1.contact_id = pn.entity_id1 AND ce1.is_primary = 1 )";
         $join .= " LEFT JOIN civicrm_email ce2 ON (ce2.contact_id = pn.entity_id2 AND ce2.is_primary = 1 )";
         $join .= " LEFT JOIN civicrm_address ca1 ON (ca1.contact_id = pn.entity_id1 AND ca1.is_primary = 1 )";
         $join .= " LEFT JOIN civicrm_address ca2 ON (ca2.contact_id = pn.entity_id2 AND ca2.is_primary = 1 )";
     }
     $iTotal = CRM_Core_BAO_PrevNextCache::getCount($cacheKeyString, $join, $whereClause, '=', $queryParams);
     if (!empty($_REQUEST['order'])) {
         foreach ($_REQUEST['order'] as $orderInfo) {
             if (!empty($orderInfo['column'])) {
                 $orderColumnNumber = $orderInfo['column'];
                 $dir = $orderInfo['dir'];
             }
         }
         $columnDetails = CRM_Utils_Array::value($orderColumnNumber, $_REQUEST['columns']);
     }
     if (!empty($columnDetails)) {
         switch ($columnDetails['data']) {
             case 'src':
                 $orderByClause = " ORDER BY cc2.display_name {$dir}";
                 break;
             case 'src_email':
                 $orderByClause = " ORDER BY ce2.email {$dir}";
                 break;
             case 'src_street':
                 $orderByClause = " ORDER BY ca2.street_address {$dir}";
                 break;
             case 'src_postcode':
                 $orderByClause = " ORDER BY ca2.postal_code {$dir}";
                 break;
             case 'dst':
                 $orderByClause = " ORDER BY cc1.display_name {$dir}";
                 break;
             case 'dst_email':
                 $orderByClause = " ORDER BY ce1.email {$dir}";
                 break;
             case 'dst_street':
                 $orderByClause = " ORDER BY ca1.street_address {$dir}";
                 break;
             case 'dst_postcode':
                 $orderByClause = " ORDER BY ca1.postal_code {$dir}";
                 break;
             default:
                 $orderByClause = " ORDER BY cc1.display_name ASC";
                 break;
         }
     }
     $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $whereClause, $offset, $rowCount, $select, $orderByClause, TRUE, $queryParams);
     $iFilteredTotal = CRM_Core_DAO::singleValueQuery("SELECT FOUND_ROWS()");
     $count = 0;
     foreach ($dupePairs as $key => $pairInfo) {
         $pair = $pairInfo['data'];
         $srcContactSubType = CRM_Utils_Array::value('src_contact_sub_type', $pairInfo);
         $dstContactSubType = CRM_Utils_Array::value('dst_contact_sub_type', $pairInfo);
         $srcTypeImage = CRM_Contact_BAO_Contact_Utils::getImage($srcContactSubType ? $srcContactSubType : $pairInfo['src_contact_type'], FALSE, $pairInfo['entity_id2']);
         $dstTypeImage = CRM_Contact_BAO_Contact_Utils::getImage($dstContactSubType ? $dstContactSubType : $pairInfo['dst_contact_type'], FALSE, $pairInfo['entity_id1']);
         $searchRows[$count]['is_selected'] = $pairInfo['is_selected'];
         $searchRows[$count]['is_selected_input'] = "<input type='checkbox' class='crm-dedupe-select' name='pnid_{$pairInfo['prevnext_id']}' value='{$pairInfo['is_selected']}' onclick='toggleDedupeSelect(this)'>";
         $searchRows[$count]['src_image'] = $srcTypeImage;
         $searchRows[$count]['src'] = CRM_Utils_System::href($pair['srcName'], 'civicrm/contact/view', "reset=1&cid={$pairInfo['entity_id2']}");
         $searchRows[$count]['src_email'] = CRM_Utils_Array::value('src_email', $pairInfo);
         $searchRows[$count]['src_street'] = CRM_Utils_Array::value('src_street', $pairInfo);
         $searchRows[$count]['src_postcode'] = CRM_Utils_Array::value('src_postcode', $pairInfo);
         $searchRows[$count]['dst_image'] = $dstTypeImage;
         $searchRows[$count]['dst'] = CRM_Utils_System::href($pair['dstName'], 'civicrm/contact/view', "reset=1&cid={$pairInfo['entity_id1']}");
         $searchRows[$count]['dst_email'] = CRM_Utils_Array::value('dst_email', $pairInfo);
         $searchRows[$count]['dst_street'] = CRM_Utils_Array::value('dst_street', $pairInfo);
         $searchRows[$count]['dst_postcode'] = CRM_Utils_Array::value('dst_postcode', $pairInfo);
         $searchRows[$count]['conflicts'] = str_replace("',", "',<br/>", CRM_Utils_Array::value('conflicts', $pair));
         $searchRows[$count]['weight'] = CRM_Utils_Array::value('weight', $pair);
         if (!empty($pairInfo['data']['canMerge'])) {
             $mergeParams = "reset=1&cid={$pairInfo['entity_id1']}&oid={$pairInfo['entity_id2']}&action=update&rgid={$rgid}&limit=" . CRM_Utils_Request::retrieve('limit', 'Integer');
             if ($gid) {
                 $mergeParams .= "&gid={$gid}";
             }
             $searchRows[$count]['actions'] = "<a class='crm-dedupe-flip' href='#' data-pnid={$pairInfo['prevnext_id']}>" . ts('flip') . "</a>&nbsp;|&nbsp;";
             $searchRows[$count]['actions'] .= CRM_Utils_System::href(ts('merge'), 'civicrm/contact/merge', $mergeParams);
             $searchRows[$count]['actions'] .= "&nbsp;|&nbsp;<a id='notDuplicate' href='#' onClick=\"processDupes( {$pairInfo['entity_id1']}, {$pairInfo['entity_id2']}, 'dupe-nondupe', 'dupe-listing'); return false;\">" . ts('not a duplicate') . "</a>";
         } else {
             $searchRows[$count]['actions'] = '<em>' . ts('Insufficient access rights - cannot merge') . '</em>';
         }
         $count++;
     }
     $dupePairs = array('data' => $searchRows, 'recordsTotal' => $iTotal, 'recordsFiltered' => $iFilteredTotal);
     if (!empty($_REQUEST['is_unit_test'])) {
         return $dupePairs;
     }
     CRM_Utils_JSON::output($dupePairs);
 }
Esempio n. 2
0
 /**
  * Retrieve list of duplicate pairs from cache table.
  */
 public static function getDedupes()
 {
     $offset = isset($_REQUEST['start']) ? CRM_Utils_Type::escape($_REQUEST['start'], 'Integer') : 0;
     $rowCount = isset($_REQUEST['length']) ? CRM_Utils_Type::escape($_REQUEST['length'], 'Integer') : 25;
     $gid = isset($_REQUEST['gid']) ? CRM_Utils_Type::escape($_REQUEST['gid'], 'Integer') : 0;
     $rgid = isset($_REQUEST['rgid']) ? CRM_Utils_Type::escape($_REQUEST['rgid'], 'Integer') : 0;
     $selected = isset($_REQUEST['selected']) ? CRM_Utils_Type::escape($_REQUEST['selected'], 'Integer') : 0;
     if ($rowCount < 0) {
         $rowCount = 0;
     }
     $contactType = '';
     if ($rgid) {
         $contactType = CRM_Core_DAO::getFieldValue('CRM_Dedupe_DAO_RuleGroup', $rgid, 'contact_type');
     }
     $cacheKeyString = "merge {$contactType}_{$rgid}_{$gid}";
     $searchRows = array();
     $selectorElements = array('is_selected', 'is_selected_input', 'src_image', 'src', 'src_email', 'src_street', 'src_postcode', 'dst_image', 'dst', 'dst_email', 'dst_street', 'dst_postcode', 'conflicts', 'weight', 'actions');
     foreach ($_REQUEST['columns'] as $columnInfo) {
         if (!empty($columnInfo['search']['value'])) {
             ${$columnInfo['data']} = CRM_Utils_Type::escape($columnInfo['search']['value'], 'String');
         }
     }
     $join = '';
     $where = array();
     $searchData = CRM_Utils_Array::value('search', $_REQUEST);
     $searchData['value'] = CRM_Utils_Type::escape($searchData['value'], 'String');
     if ($src || !empty($searchData['value'])) {
         $src = $src ? $src : $searchData['value'];
         $where[] = " cc1.display_name LIKE '%{$src}%'";
     }
     if ($dst || !empty($searchData['value'])) {
         $dst = $dst ? $dst : $searchData['value'];
         $where[] = " cc2.display_name LIKE '%{$dst}%'";
     }
     if ($src_email || !empty($searchData['value'])) {
         $src_email = $src_email ? $src_email : $searchData['value'];
         $where[] = " (ce1.is_primary = 1 AND ce1.email LIKE '%{$src_email}%')";
     }
     if ($dst_email || !empty($searchData['value'])) {
         $dst_email = $dst_email ? $dst_email : $searchData['value'];
         $where[] = " (ce2.is_primary = 1 AND ce2.email LIKE '%{$dst_email}%')";
     }
     if ($src_postcode || !empty($searchData['value'])) {
         $src_postcode = $src_postcode ? $src_postcode : $searchData['value'];
         $where[] = " (ca1.is_primary = 1 AND ca1.postal_code LIKE '%{$src_postcode}%')";
     }
     if ($dst_postcode || !empty($searchData['value'])) {
         $dst_postcode = $dst_postcode ? $dst_postcode : $searchData['value'];
         $where[] = " (ca2.is_primary = 1 AND ca2.postal_code LIKE '%{$dst_postcode}%')";
     }
     if ($src_street || !empty($searchData['value'])) {
         $src_street = $src_street ? $src_street : $searchData['value'];
         $where[] = " (ca1.is_primary = 1 AND ca1.street_address LIKE '%{$src_street}%')";
     }
     if ($dst_street || !empty($searchData['value'])) {
         $dst_street = $dst_street ? $dst_street : $searchData['value'];
         $where[] = " (ca2.is_primary = 1 AND ca2.street_address LIKE '%{$dst_street}%')";
     }
     if (!empty($searchData['value'])) {
         $whereClause = ' ( ' . implode(' OR ', $where) . ' ) ';
     } else {
         if (!empty($where)) {
             $whereClause = implode(' AND ', $where);
         }
     }
     $whereClause .= $whereClause ? ' AND de.id IS NULL' : ' de.id IS NULL';
     if ($selected) {
         $whereClause .= ' AND pn.is_selected = 1';
     }
     $join .= " LEFT JOIN civicrm_dedupe_exception de ON ( pn.entity_id1 = de.contact_id1 AND pn.entity_id2 = de.contact_id2 )";
     $select = array('cc1.contact_type' => 'src_contact_type', 'cc1.display_name' => 'src_display_name', 'cc1.contact_sub_type' => 'src_contact_sub_type', 'cc2.contact_type' => 'dst_contact_type', 'cc2.display_name' => 'dst_display_name', 'cc2.contact_sub_type' => 'dst_contact_sub_type', 'ce1.email' => 'src_email', 'ce2.email' => 'dst_email', 'ca1.postal_code' => 'src_postcode', 'ca2.postal_code' => 'dst_postcode', 'ca1.street_address' => 'src_street', 'ca2.street_address' => 'dst_street');
     if ($select) {
         $join .= " INNER JOIN civicrm_contact cc1 ON cc1.id = pn.entity_id1";
         $join .= " INNER JOIN civicrm_contact cc2 ON cc2.id = pn.entity_id2";
         $join .= " LEFT JOIN civicrm_email ce1 ON (ce1.contact_id = pn.entity_id1 AND ce1.is_primary = 1 )";
         $join .= " LEFT JOIN civicrm_email ce2 ON (ce2.contact_id = pn.entity_id2 AND ce2.is_primary = 1 )";
         $join .= " LEFT JOIN civicrm_address ca1 ON (ca1.contact_id = pn.entity_id1 AND ca1.is_primary = 1 )";
         $join .= " LEFT JOIN civicrm_address ca2 ON (ca2.contact_id = pn.entity_id2 AND ca2.is_primary = 1 )";
     }
     $iTotal = CRM_Core_BAO_PrevNextCache::getCount($cacheKeyString, $join, $whereClause);
     foreach ($_REQUEST['order'] as $orderInfo) {
         if (!empty($orderInfo['column'])) {
             $orderColumnNumber = $orderInfo['column'];
             $dir = $orderInfo['dir'];
         }
     }
     $columnDetails = CRM_Utils_Array::value($orderColumnNumber, $_REQUEST['columns']);
     if (!empty($columnDetails)) {
         switch ($columnDetails['data']) {
             case 'src':
                 $whereClause .= " ORDER BY cc1.display_name {$dir}";
                 break;
             case 'src_email':
                 $whereClause .= " ORDER BY ce1.email {$dir}";
                 break;
             case 'src_street':
                 $whereClause .= " ORDER BY ca1.street_address {$dir}";
                 break;
             case 'src_postcode':
                 $whereClause .= " ORDER BY ca1.postal_code {$dir}";
                 break;
             case 'dst':
                 $whereClause .= " ORDER BY cc2.display_name {$dir}";
                 break;
             case 'dst_email':
                 $whereClause .= " ORDER BY ce2.email {$dir}";
                 break;
             case 'dst_street':
                 $whereClause .= " ORDER BY ca2.street_address {$dir}";
                 break;
             case 'dst_postcode':
                 $whereClause .= " ORDER BY ca2.postal_code {$dir}";
                 break;
             default:
                 break;
         }
     }
     $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $whereClause, $offset, $rowCount, $select);
     $iFilteredTotal = CRM_Core_DAO::singleValueQuery("SELECT FOUND_ROWS()");
     $count = 0;
     foreach ($dupePairs as $key => $pairInfo) {
         $pair =& $pairInfo['data'];
         $srcContactSubType = CRM_Utils_Array::value('src_contact_sub_type', $pairInfo);
         $dstContactSubType = CRM_Utils_Array::value('dst_contact_sub_type', $pairInfo);
         $srcTypeImage = CRM_Contact_BAO_Contact_Utils::getImage($srcContactSubType ? $srcContactSubType : $pairInfo['src_contact_type'], FALSE, $pairInfo['entity_id1']);
         $dstTypeImage = CRM_Contact_BAO_Contact_Utils::getImage($dstContactSubType ? $dstContactSubType : $pairInfo['dst_contact_type'], FALSE, $pairInfo['entity_id2']);
         $searchRows[$count]['is_selected'] = $pairInfo['is_selected'];
         $searchRows[$count]['is_selected_input'] = "<input type='checkbox' class='crm-dedupe-select' name='pnid_{$pairInfo['prevnext_id']}' value='{$pairInfo['is_selected']}' onclick='toggleDedupeSelect(this)'>";
         $searchRows[$count]['src_image'] = $srcTypeImage;
         $searchRows[$count]['src'] = CRM_Utils_System::href($pair['srcName'], 'civicrm/contact/view', "reset=1&cid={$pairInfo['entity_id1']}");
         $searchRows[$count]['src_email'] = CRM_Utils_Array::value('src_email', $pairInfo);
         $searchRows[$count]['src_street'] = CRM_Utils_Array::value('src_street', $pairInfo);
         $searchRows[$count]['src_postcode'] = CRM_Utils_Array::value('src_postcode', $pairInfo);
         $searchRows[$count]['dst_image'] = $dstTypeImage;
         $searchRows[$count]['dst'] = CRM_Utils_System::href($pair['dstName'], 'civicrm/contact/view', "reset=1&cid={$pairInfo['entity_id2']}");
         $searchRows[$count]['dst_email'] = CRM_Utils_Array::value('dst_email', $pairInfo);
         $searchRows[$count]['dst_street'] = CRM_Utils_Array::value('dst_street', $pairInfo);
         $searchRows[$count]['dst_postcode'] = CRM_Utils_Array::value('dst_postcode', $pairInfo);
         $searchRows[$count]['conflicts'] = str_replace("',", "',<br/>", CRM_Utils_Array::value('conflicts', $pair));
         $searchRows[$count]['weight'] = CRM_Utils_Array::value('weight', $pair);
         if (!empty($pairInfo['data']['canMerge'])) {
             $mergeParams = "reset=1&cid={$pairInfo['entity_id1']}&oid={$pairInfo['entity_id2']}&action=update&rgid={$rgid}";
             if ($gid) {
                 $mergeParams .= "&gid={$gid}";
             }
             $searchRows[$count]['actions'] = "<a class='crm-dedupe-flip' href='#' data-pnid={$pairInfo['prevnext_id']}>" . ts('flip') . "</a>&nbsp;|&nbsp;";
             $searchRows[$count]['actions'] .= CRM_Utils_System::href(ts('merge'), 'civicrm/contact/merge', $mergeParams);
             $searchRows[$count]['actions'] .= "&nbsp;|&nbsp;<a id='notDuplicate' href='#' onClick=\"processDupes( {$pairInfo['entity_id1']}, {$pairInfo['entity_id2']}, 'dupe-nondupe', 'dupe-listing'); return false;\">" . ts('not a duplicate') . "</a>";
         } else {
             $searchRows[$count]['actions'] = '<em>' . ts('Insufficient access rights - cannot merge') . '</em>';
         }
         $count++;
     }
     $dupePairs = array('data' => $searchRows, 'recordsTotal' => $iTotal, 'recordsFiltered' => $iFilteredTotal);
     CRM_Utils_JSON::output($dupePairs);
 }
Esempio n. 3
0
 public static function getDedupes()
 {
     $sEcho = CRM_Utils_Type::escape($_REQUEST['sEcho'], 'Integer');
     $offset = isset($_REQUEST['iDisplayStart']) ? CRM_Utils_Type::escape($_REQUEST['iDisplayStart'], 'Integer') : 0;
     $rowCount = isset($_REQUEST['iDisplayLength']) ? CRM_Utils_Type::escape($_REQUEST['iDisplayLength'], 'Integer') : 25;
     $sort = 'sort_name';
     $sortOrder = isset($_REQUEST['sSortDir_0']) ? CRM_Utils_Type::escape($_REQUEST['sSortDir_0'], 'String') : 'asc';
     $gid = isset($_REQUEST['gid']) ? CRM_Utils_Type::escape($_REQUEST['gid'], 'Integer') : 0;
     $rgid = isset($_REQUEST['rgid']) ? CRM_Utils_Type::escape($_REQUEST['rgid'], 'Integer') : 0;
     $contactType = '';
     if ($rgid) {
         $contactType = CRM_Core_DAO::getFieldValue('CRM_Dedupe_DAO_RuleGroup', $rgid, 'contact_type');
     }
     $cacheKeyString = "merge {$contactType}_{$rgid}_{$gid}";
     $searchRows = array();
     $selectorElements = array('src', 'dst', 'weight', 'actions');
     $join = "LEFT JOIN civicrm_dedupe_exception de ON ( pn.entity_id1 = de.contact_id1 AND\n                                                             pn.entity_id2 = de.contact_id2 )";
     $where = "de.id IS NULL";
     $iFilteredTotal = $iTotal = CRM_Core_BAO_PrevNextCache::getCount($cacheKeyString, $join, $where);
     $mainContacts = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where, $offset, $rowCount);
     foreach ($mainContacts as $mainId => $main) {
         $searchRows[$mainId]['src'] = CRM_Utils_System::href($main['srcName'], 'civicrm/contact/view', "reset=1&cid={$main['srcID']}");
         $searchRows[$mainId]['dst'] = CRM_Utils_System::href($main['dstName'], 'civicrm/contact/view', "reset=1&cid={$main['dstID']}");
         $searchRows[$mainId]['weight'] = CRM_Utils_Array::value('weight', $main);
         if (!empty($main['canMerge'])) {
             $mergeParams = "reset=1&cid={$main['srcID']}&oid={$main['dstID']}&action=update&rgid={$rgid}";
             if ($gid) {
                 $mergeParams .= "&gid={$gid}";
             }
             $searchRows[$mainId]['actions'] = '<a class="action-item crm-hover-button" href="' . CRM_Utils_System::url('civicrm/contact/merge', $mergeParams) . '">' . ts('merge') . '</a>';
             $searchRows[$mainId]['actions'] .= "<a class='action-item crm-hover-button crm-notDuplicate' href='#' onClick=\"processDupes( {$main['srcID']}, {$main['dstID']}, 'dupe-nondupe', 'dupe-listing'); return false;\">" . ts('not a duplicate') . "</a>";
         } else {
             $searchRows[$mainId]['actions'] = '<em>' . ts('Insufficient access rights - cannot merge') . '</em>';
         }
     }
     CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
     echo CRM_Utils_JSON::encodeDataTableSelector($searchRows, $sEcho, $iTotal, $iFilteredTotal, $selectorElements);
     CRM_Utils_System::civiExit();
 }
Esempio n. 4
0
 /**
  * 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.
  *                              Generally used with batch-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).
  * @param bool $autoFlip to let api decide which contact to retain and which to delete.
  *   Wether to let api decide which contact to retain and which to delete.
  *
  *
  * @param bool $redirectForPerformance
  *
  * @return array|bool
  */
 public static function merge($dupePairs = array(), $cacheParams = array(), $mode = 'safe', $autoFlip = TRUE, $redirectForPerformance = FALSE)
 {
     $cacheKeyString = CRM_Utils_Array::value('cache_key_string', $cacheParams);
     $resultStats = array('merged' => array(), 'skipped' => array());
     // we don't want dupe caching to get reset after every-merge, and therefore set the
     // doNotResetCache flag
     $config = CRM_Core_Config::singleton();
     $config->doNotResetCache = 1;
     while (!empty($dupePairs)) {
         foreach ($dupePairs as $dupes) {
             CRM_Utils_Hook::merge('flip', $dupes, $dupes['dstID'], $dupes['srcID']);
             $mainId = $dupes['dstID'];
             $otherId = $dupes['srcID'];
             $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'];
             }
             if (!$mainId || !$otherId) {
                 // return error
                 return FALSE;
             }
             // Generate var $migrationInfo. The variable structure is exactly same as
             // $formValues submitted during a UI merge for a pair of contacts.
             $rowsElementsAndInfo = CRM_Dedupe_Merger::getRowsElementsAndInfo($mainId, $otherId);
             $migrationInfo =& $rowsElementsAndInfo['migration_info'];
             // add additional details that we might need to resolve conflicts
             $migrationInfo['main_details'] =& $rowsElementsAndInfo['main_details'];
             $migrationInfo['other_details'] =& $rowsElementsAndInfo['other_details'];
             $migrationInfo['main_loc_block'] =& $rowsElementsAndInfo['main_loc_block'];
             $migrationInfo['rows'] =& $rowsElementsAndInfo['rows'];
             // go ahead with merge if there is no conflict
             if (!CRM_Dedupe_Merger::skipMerge($mainId, $otherId, $migrationInfo, $mode)) {
                 CRM_Dedupe_Merger::moveAllBelongings($mainId, $otherId, $migrationInfo);
                 $resultStats['merged'][] = array('main_id' => $mainId, 'other_id' => $otherId);
             } else {
                 $resultStats['skipped'][] = array('main_id' => $mainId, 'other_id' => $otherId);
             }
             // delete entry from PrevNextCache table so we don't consider the pair next time
             // pair may have been flipped, so make sure we delete using both orders
             CRM_Core_BAO_PrevNextCache::deletePair($mainId, $otherId, $cacheKeyString);
             CRM_Core_BAO_PrevNextCache::deletePair($otherId, $mainId, $cacheKeyString);
             CRM_Core_DAO::freeResult();
             unset($rowsElementsAndInfo, $migrationInfo);
         }
         if ($cacheKeyString && !$redirectForPerformance) {
             // retrieve next pair of dupes
             $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $cacheParams['join'], $cacheParams['where']);
         } else {
             // do not proceed. Terminate the loop
             unset($dupePairs);
         }
     }
     return $resultStats;
 }
Esempio n. 5
0
 /**
  * Browse all rule groups.
  */
 public function run()
 {
     $gid = CRM_Utils_Request::retrieve('gid', 'Positive', $this, FALSE, 0);
     $action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 0);
     $context = CRM_Utils_Request::retrieve('context', 'String', $this);
     $session = CRM_Core_Session::singleton();
     $contactIds = $session->get('selectedSearchContactIds');
     if ($context == 'search' || !empty($contactIds)) {
         $context = 'search';
         $this->assign('backURL', $session->readUserContext());
     }
     if ($action & CRM_Core_Action::RENEW) {
         // empty cache
         $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE, 0);
         if ($rgid) {
             $contactType = CRM_Core_DAO::getFieldValue('CRM_Dedupe_DAO_RuleGroup', $rgid, 'contact_type');
             $cacheKeyString = "merge {$contactType}";
             $cacheKeyString .= $rgid ? "_{$rgid}" : '_0';
             $cacheKeyString .= $gid ? "_{$gid}" : '_0';
             CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKeyString);
         }
         $urlQry = "reset=1&action=update&rgid={$rgid}";
         if ($gid) {
             $urlQry .= "&gid={$gid}";
         }
         CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry));
     } elseif ($action & CRM_Core_Action::MAP) {
         // do a batch merge if requested
         $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE, 0);
         $result = CRM_Dedupe_Merger::batchMerge($rgid, $gid, 'safe', TRUE, 75);
         $skippedCount = CRM_Utils_Request::retrieve('skipped', 'Positive', $this, FALSE, 0);
         $skippedCount = $skippedCount + count($result['skipped']);
         $mergedCount = CRM_Utils_Request::retrieve('merged', 'Positive', $this, FALSE, 0);
         $mergedCount = $mergedCount + count($result['merged']);
         if (empty($result['merged']) && empty($result['skipped'])) {
             $message = '';
             if ($mergedCount >= 1) {
                 $message = ts("%1 pairs of duplicates were merged", array(1 => $mergedCount));
             }
             if ($skippedCount >= 1) {
                 $message = $message ? "{$message} and " : '';
                 $message .= ts("%1 pairs of duplicates were skipped due to conflict", array(1 => $skippedCount));
             }
             $message .= ts(" during the batch merge process with safe mode.");
             CRM_Core_Session::setStatus($message, ts('Merge Complete'), 'success');
             $urlQry = "reset=1&action=update&rgid={$rgid}";
             if ($gid) {
                 $urlQry .= "&gid={$gid}";
             }
             CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry));
         } else {
             $urlQry = "reset=1&action=map&rgid={$rgid}";
             if ($gid) {
                 $urlQry .= "&gid={$gid}";
             }
             $urlQry .= "&skipped={$skippedCount}&merged={$mergedCount}";
             CRM_Utils_System::jsRedirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry), ts('Batch Merge Task in progress'), ts('The batch merge task is still in progress. This page will be refreshed automatically.'));
         }
     }
     if ($action & CRM_Core_Action::UPDATE || $action & CRM_Core_Action::BROWSE) {
         $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE, 0);
         $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE, 0);
         $this->action = CRM_Core_Action::UPDATE;
         //calculate the $contactType
         if ($rgid) {
             $contactType = CRM_Core_DAO::getFieldValue('CRM_Dedupe_DAO_RuleGroup', $rgid, 'contact_type');
         }
         $sourceParams = 'snippet=4';
         if ($gid) {
             $sourceParams .= "&gid={$gid}";
         }
         if ($rgid) {
             $sourceParams .= "&rgid={$rgid}";
         }
         if ($context == 'conflicts') {
             $sourceParams .= "&selected=1";
         }
         $this->assign('sourceUrl', CRM_Utils_System::url('civicrm/ajax/dedupefind', $sourceParams, FALSE, NULL, FALSE));
         //reload from cache table
         $cacheKeyString = "merge {$contactType}";
         $cacheKeyString .= $rgid ? "_{$rgid}" : '_0';
         $cacheKeyString .= $gid ? "_{$gid}" : '_0';
         $stats = CRM_Dedupe_Merger::getMergeStatsMsg($cacheKeyString);
         if ($stats) {
             CRM_Core_Session::setStatus($stats);
             // reset so we not displaying same message again
             CRM_Dedupe_Merger::resetMergeStats($cacheKeyString);
         }
         $join = "LEFT JOIN civicrm_dedupe_exception de ON ( pn.entity_id1 = de.contact_id1 AND\n                                                                 pn.entity_id2 = de.contact_id2 )";
         $where = "de.id IS NULL";
         if ($context == 'conflicts') {
             $where .= " AND pn.is_selected = 1";
         }
         $this->_mainContacts = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where);
         if (empty($this->_mainContacts)) {
             if ($context == 'conflicts') {
                 // if the current screen was intended to list only selected contacts, move back to full dupe list
                 $sourceParams = 'reset=1&action=update';
                 if ($gid) {
                     $sourceParams .= "&gid={$gid}";
                 }
                 if ($rgid) {
                     $sourceParams .= "&rgid={$rgid}";
                 }
                 CRM_Utils_System::redirect(CRM_Utils_System::url(CRM_Utils_System::currentPath(), $sourceParams));
             }
             if ($gid) {
                 $foundDupes = $this->get("dedupe_dupes_{$gid}");
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid);
                 }
                 $this->set("dedupe_dupes_{$gid}", $foundDupes);
             } elseif (!empty($contactIds)) {
                 $foundDupes = $this->get("search_dedupe_dupes_{$gid}");
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupes($rgid, $contactIds);
                 }
                 $this->get("search_dedupe_dupes_{$gid}", $foundDupes);
             } else {
                 $foundDupes = $this->get('dedupe_dupes');
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupes($rgid);
                 }
                 $this->set('dedupe_dupes', $foundDupes);
             }
             if (!$foundDupes) {
                 $ruleGroup = new CRM_Dedupe_BAO_RuleGroup();
                 $ruleGroup->id = $rgid;
                 $ruleGroup->find(TRUE);
                 $session = CRM_Core_Session::singleton();
                 $session->setStatus(ts('No possible duplicates were found using %1 rule.', array(1 => $ruleGroup->name)), ts('None Found'), 'info');
                 $url = CRM_Utils_System::url('civicrm/contact/deduperules', 'reset=1');
                 if ($context == 'search') {
                     $url = $session->readUserContext();
                 }
                 CRM_Utils_System::redirect($url);
             } else {
                 $cids = array();
                 foreach ($foundDupes as $dupe) {
                     $cids[$dupe[0]] = 1;
                     $cids[$dupe[1]] = 1;
                 }
                 $cidString = implode(', ', array_keys($cids));
                 $sql = "SELECT id, display_name FROM civicrm_contact WHERE id IN ({$cidString}) ORDER BY sort_name";
                 $dao = new CRM_Core_DAO();
                 $dao->query($sql);
                 $displayNames = array();
                 while ($dao->fetch()) {
                     $displayNames[$dao->id] = $dao->display_name;
                 }
                 // FIXME: sort the contacts; $displayName
                 // is already sort_name-sorted, so use that
                 // (also, consider sorting by dupe count first)
                 // lobo - change the sort to by threshold value
                 // so the more likely dupes are sorted first
                 $session = CRM_Core_Session::singleton();
                 $userId = $session->get('userID');
                 $mainContacts = $permission = array();
                 foreach ($foundDupes as $dupes) {
                     $srcID = $dupes[0];
                     $dstID = $dupes[1];
                     if ($dstID == $userId) {
                         $srcID = $dupes[1];
                         $dstID = $dupes[0];
                     }
                     /***
                      * Eliminate this since it introduces 3 queries PER merge row
                      * and hence is very expensive
                      * CRM-8822
                      * if ( !array_key_exists( $srcID, $permission ) ) {
                      * $permission[$srcID] = CRM_Contact_BAO_Contact_Permission::allow( $srcID, CRM_Core_Permission::EDIT );
                      * }
                      * if ( !array_key_exists( $dstID, $permission ) ) {
                      * $permission[$dstID] = CRM_Contact_BAO_Contact_Permission::allow( $dstID, CRM_Core_Permission::EDIT );
                      * }
                      *
                      * $canMerge = ( $permission[$dstID] && $permission[$srcID] );
                      *
                      */
                     // we'll do permission checking during the merge process
                     $canMerge = TRUE;
                     $mainContacts[] = $row = array('srcID' => $srcID, 'srcName' => $displayNames[$srcID], 'dstID' => $dstID, 'dstName' => $displayNames[$dstID], 'weight' => $dupes[2], 'canMerge' => $canMerge);
                     $data = CRM_Core_DAO::escapeString(serialize($row));
                     $values[] = " ( 'civicrm_contact', {$srcID}, {$dstID}, '{$cacheKeyString}', '{$data}' ) ";
                 }
                 if ($cid) {
                     $this->_cid = $cid;
                 }
                 if ($gid) {
                     $this->_gid = $gid;
                 }
                 $this->_rgid = $rgid;
                 $this->_mainContacts = $mainContacts;
                 CRM_Core_BAO_PrevNextCache::setItem($values);
                 $session = CRM_Core_Session::singleton();
                 if ($this->_cid) {
                     $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/deduperules', "action=update&rgid={$this->_rgid}&gid={$this->_gid}&cid={$this->_cid}"));
                 } else {
                     $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/dedupefind', "reset=1&action=update&rgid={$this->_rgid}"));
                 }
             }
         } else {
             if ($cid) {
                 $this->_cid = $cid;
             }
             if ($gid) {
                 $this->_gid = $gid;
             }
             $this->_rgid = $rgid;
         }
         $this->assign('action', $this->action);
         $this->browse();
     } else {
         $this->action = CRM_Core_Action::UPDATE;
         $this->edit($this->action);
         $this->assign('action', $this->action);
     }
     $this->assign('context', $context);
     // parent run
     return parent::run();
 }
Esempio n. 6
0
 public function testBatchMergeAllDuplicates()
 {
     $this->createDupeContacts();
     // verify that all contacts have been created separately
     $this->assertEquals(count($this->_contactIds), 9, 'Check for number of contacts.');
     $dao = new CRM_Dedupe_DAO_RuleGroup();
     $dao->contact_type = 'Individual';
     $dao->name = 'IndividualSupervised';
     $dao->is_default = 1;
     $dao->find(TRUE);
     $foundDupes = CRM_Dedupe_Finder::dupesInGroup($dao->id, $this->_groupId);
     // -------------------------------------------------------------------------
     // Name and Email (reserved) Matches ( 3 pairs )
     // --------------------------------------------------------------------------
     // robin  - hood - robin@example.com
     // robin  - hood - robin@example.com
     // little - dale - dale@example.com
     // little - dale - dale@example.com
     // will   - dale - will@example.com
     // will   - dale - will@example.com
     // so 3 pairs for - first + last + mail
     $this->assertEquals(count($foundDupes), 3, 'Check Individual-Supervised dupe rule for dupesInGroup().');
     // Run dedupe finder as the browser would
     $_SERVER['REQUEST_METHOD'] = 'GET';
     //avoid invalid key error
     $object = new CRM_Contact_Page_DedupeFind();
     $object->set('gid', $this->_groupId);
     $object->set('rgid', $dao->id);
     $object->set('action', CRM_Core_Action::UPDATE);
     @$object->run();
     // Retrieve pairs from prev next cache table
     $select = array('pn.is_selected' => 'is_selected');
     $cacheKeyString = "merge Individual_{$dao->id}_{$this->_groupId}";
     $pnDupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, NULL, NULL, 0, 0, $select);
     $this->assertEquals(count($foundDupes), count($pnDupePairs), 'Check number of dupe pairs in prev next cache.');
     // batch merge all dupes
     $result = CRM_Dedupe_Merger::batchMerge($dao->id, $this->_groupId, 'safe', TRUE, 5, 2);
     $this->assertEquals(count($result['merged']), 3, 'Check number of merged pairs.');
     // retrieve pairs from prev next cache table
     $pnDupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, NULL, NULL, 0, 0, $select);
     $this->assertEquals(count($pnDupePairs), 0, 'Check number of remaining dupe pairs in prev next cache.');
     $this->deleteDupeContacts();
 }
Esempio n. 7
0
 /**
  * Get Duplicate Pairs based on a rule for a group.
  *
  * @param int $rule_group_id
  * @param int $group_id
  * @param bool $reloadCacheIfEmpty
  * @param int $batchLimit
  * @param bool $isSelected
  * @param array|string $orderByClause
  * @param bool $includeConflicts
  * @param array $criteria
  *   Additional criteria to narrow down the merge group.
  *
  * @param bool $checkPermissions
  *   Respect logged in user permissions.
  *
  * @return array
  *    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)
 {
     $where = self::getWhereString($batchLimit, $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);
     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);
         $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where, 0, 0, array(), $orderByClause, $includeConflicts);
         return $dupePairs;
     }
     return $dupePairs;
 }
Esempio n. 8
0
 /**
  * Browse all rule groups.
  */
 public function run()
 {
     $gid = CRM_Utils_Request::retrieve('gid', 'Positive', $this, FALSE, 0);
     $action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 0);
     $context = CRM_Utils_Request::retrieve('context', 'String', $this);
     $limit = CRM_Utils_Request::retrieve('limit', 'Integer', $this);
     $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive');
     $urlQry = "reset=1&rgid={$rgid}&gid={$gid}&limit={$limit}";
     $this->assign('urlQuery', $urlQry);
     $session = CRM_Core_Session::singleton();
     $contactIds = $session->get('selectedSearchContactIds');
     if ($context == 'search' || !empty($contactIds)) {
         $context = 'search';
         $this->assign('backURL', $session->readUserContext());
     }
     if ($action & CRM_Core_Action::RENEW) {
         // empty cache
         if ($rgid) {
             CRM_Core_BAO_PrevNextCache::deleteItem(NULL, CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid));
         }
         CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry . "&action=update"));
     } elseif ($action & CRM_Core_Action::MAP) {
         // do a batch merge if requested
         $result = CRM_Dedupe_Merger::batchMerge($rgid, $gid, 'safe', TRUE, 75);
         $skippedCount = CRM_Utils_Request::retrieve('skipped', 'Positive', $this, FALSE, 0);
         $skippedCount = $skippedCount + count($result['skipped']);
         $mergedCount = CRM_Utils_Request::retrieve('merged', 'Positive', $this, FALSE, 0);
         $mergedCount = $mergedCount + count($result['merged']);
         if (empty($result['merged']) && empty($result['skipped'])) {
             $message = '';
             if ($mergedCount >= 1) {
                 $message = ts("%1 pairs of duplicates were merged", array(1 => $mergedCount));
             }
             if ($skippedCount >= 1) {
                 $message = $message ? "{$message} and " : '';
                 $message .= ts("%1 pairs of duplicates were skipped due to conflict", array(1 => $skippedCount));
             }
             $message .= ts(" during the batch merge process with safe mode.");
             CRM_Core_Session::setStatus($message, ts('Merge Complete'), 'success');
             CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry . "&action=update"));
         } else {
             $urlQry .= "&action=map&skipped={$skippedCount}&merged={$mergedCount}";
             CRM_Utils_System::jsRedirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry), ts('Batch Merge Task in progress'), ts('The batch merge task is still in progress. This page will be refreshed automatically.'));
         }
     }
     if ($action & CRM_Core_Action::UPDATE || $action & CRM_Core_Action::BROWSE) {
         $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE, 0);
         $this->action = CRM_Core_Action::UPDATE;
         $urlQry .= '&snippet=4';
         if ($context == 'conflicts') {
             $urlQry .= "&selected=1";
         }
         $this->assign('sourceUrl', CRM_Utils_System::url('civicrm/ajax/dedupefind', $urlQry, FALSE, NULL, FALSE));
         //reload from cache table
         $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid);
         $stats = CRM_Dedupe_Merger::getMergeStatsMsg($cacheKeyString);
         if ($stats) {
             CRM_Core_Session::setStatus($stats);
             // reset so we not displaying same message again
             CRM_Dedupe_Merger::resetMergeStats($cacheKeyString);
         }
         $join = CRM_Dedupe_Merger::getJoinOnDedupeTable();
         $where = "de.id IS NULL";
         if ($context == 'conflicts') {
             $where .= " AND pn.is_selected = 1";
         }
         $this->_mainContacts = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where);
         if (empty($this->_mainContacts)) {
             if ($context == 'conflicts') {
                 // if the current screen was intended to list only selected contacts, move back to full dupe list
                 CRM_Utils_System::redirect(CRM_Utils_System::url(CRM_Utils_System::currentPath(), $urlQry . '&action=update'));
             }
             if ($gid) {
                 $foundDupes = $this->get("dedupe_dupes_{$gid}");
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid, $limit);
                 }
                 $this->set("dedupe_dupes_{$gid}", $foundDupes);
             } elseif (!empty($contactIds)) {
                 $foundDupes = $this->get("search_dedupe_dupes_{$gid}");
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupes($rgid, $contactIds);
                 }
                 $this->set("search_dedupe_dupes_{$gid}", $foundDupes);
             } else {
                 $foundDupes = $this->get('dedupe_dupes');
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupes($rgid, array(), TRUE, $limit);
                 }
                 $this->set('dedupe_dupes', $foundDupes);
             }
             if (!$foundDupes) {
                 $ruleGroup = new CRM_Dedupe_BAO_RuleGroup();
                 $ruleGroup->id = $rgid;
                 $ruleGroup->find(TRUE);
                 $session = CRM_Core_Session::singleton();
                 $session->setStatus(ts('No possible duplicates were found using %1 rule.', array(1 => $ruleGroup->name)), ts('None Found'), 'info');
                 $url = CRM_Utils_System::url('civicrm/contact/deduperules', 'reset=1');
                 if ($context == 'search') {
                     $url = $session->readUserContext();
                 }
                 CRM_Utils_System::redirect($url);
             } else {
                 $mainContacts = CRM_Dedupe_Finder::parseAndStoreDupePairs($foundDupes, $cacheKeyString);
                 if ($cid) {
                     $this->_cid = $cid;
                 }
                 if ($gid) {
                     $this->_gid = $gid;
                 }
                 $this->_rgid = $rgid;
                 $this->_mainContacts = $mainContacts;
                 $session = CRM_Core_Session::singleton();
                 if ($this->_cid) {
                     $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/deduperules', $urlQry . "&action=update&cid={$this->_cid}"));
                 } else {
                     $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry . "&action=update"));
                 }
             }
         } else {
             if ($cid) {
                 $this->_cid = $cid;
             }
             if ($gid) {
                 $this->_gid = $gid;
             }
             $this->_rgid = $rgid;
         }
         $this->assign('action', $this->action);
         $this->browse();
     } else {
         $this->action = CRM_Core_Action::UPDATE;
         $this->edit($this->action);
         $this->assign('action', $this->action);
     }
     $this->assign('context', $context);
     // parent run
     return parent::run();
 }