/**
  * @return $this
  */
 private function addSearchContactIdsToSession()
 {
     $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $form);
     $cacheKey = "civicrm search {$qfKey}";
     $selectedCids = CRM_Core_BAO_PrevNextCache::getSelection($cacheKey);
     $contactIds = array();
     // Set contact IDs to the IDs of contacts selected (ticked) on the search result
     foreach ($selectedCids[$cacheKey] as $selectedCid => $ignore) {
         $contactIds[$selectedCid] = $selectedCid;
     }
     // So a bit of magic happens here
     // When you instantiate a CRM_Contract_Controller_Search object, it checks to see if a qfKey is passed in the $_REQUEST
     // in our case you should see it in the GET
     // If this is passed in, the controller tries to create itself using data from the SESSION
     // that means your controller is automatically populated with search data from a previous page
     $searchController = new CRM_Contact_Controller_Search();
     $totalContacts = count($contactIds);
     if ($totalContacts <= 0) {
         $totalContacts = $searchController->get('rowCount');
     }
     // CS: This needs to be commented out because the contact IDs are irrelevant at this point.
     // If the user hasn't ticked any users then this code would just give you back the first 50 contacts
     // Better to leave the contactIds empty which tells us that nothing is actually selected
     if (!$contactIds) {
         foreach ($this->get('rows') as $contact) {
             $contactIds[$contact['contact_id']] = $contact['contact_id'];
         }
     }
     simplemail_civicrm_addToSessionScope('contactCountFromSearch', $totalContacts);
     simplemail_civicrm_addToSessionScope('contactIds', $contactIds);
     return $this;
 }
 /**
  * Used to store selected contacts across multiple pages in advanced search.
  */
 public static function selectUnselectRelationships()
 {
     $name = CRM_Utils_Array::value('name', $_REQUEST);
     $cacheKey = CRM_Utils_Array::value('qfKey', $_REQUEST);
     $state = CRM_Utils_Array::value('state', $_REQUEST, 'checked');
     $variableType = CRM_Utils_Array::value('variableType', $_REQUEST, 'single');
     $actionToPerform = CRM_Utils_Array::value('action', $_REQUEST, 'select');
     if ($variableType == 'multiple') {
         // action post value only works with multiple type variable
         if ($name) {
             //multiple names like mark_x_1-mark_x_2 where 1,2 are cids
             $elements = explode('-', $name);
             foreach ($elements as $key => $element) {
                 $elements[$key] = self::_convertToId($element);
             }
             CRM_Core_BAO_PrevNextCache::markSelection($cacheKey, $actionToPerform, $elements, 'civicrm_relationship');
         } else {
             CRM_Core_BAO_PrevNextCache::markSelection($cacheKey, $actionToPerform, NULL, 'civicrm_relationship');
         }
     } elseif ($variableType == 'single') {
         $cId = self::_convertToId($name);
         $action = $state == 'checked' ? 'select' : 'unselect';
         CRM_Core_BAO_PrevNextCache::markSelection($cacheKey, $action, $cId, 'civicrm_relationship');
     }
     $contactIds = CRM_Core_BAO_PrevNextCache::getSelection($cacheKey, 'get', 'civicrm_relationship');
     $countSelectionCids = count($contactIds[$cacheKey]);
     $arrRet = array('getCount' => $countSelectionCids);
     CRM_Utils_JSON::output($arrRet);
 }
 public function testFlipData()
 {
     $dao = new CRM_Core_BAO_PrevNextCache();
     $dao->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(1, $dao->entity_id1);
     $this->assertEquals(2, $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'));
 }
 /**
  * Set variables up before form is built.
  *
  * @return void
  */
 public function preProcess()
 {
     //when user come from search context.
     $ssID = $this->get('ssID');
     $this->assign('ssid', $ssID);
     $this->_searchBasedMailing = CRM_Contact_Form_Search::isSearchContext($this->get('context'));
     if (CRM_Contact_Form_Search::isSearchContext($this->get('context')) && !$ssID) {
         $params = array();
         $result = CRM_Core_BAO_PrevNextCache::getSelectedContacts();
         $this->assign("value", $result);
     }
 }
 public function preProcess()
 {
     $this->_mailingID = $this->get('mailing_id');
     if (CRM_Core_Permission::check('administer CiviCRM')) {
         $this->assign('isAdmin', 1);
     }
     //when user come from search context.
     $ssID = $this->get('ssID');
     $this->assign('ssid', $ssID);
     $this->_searchBasedMailing = CRM_Contact_Form_Search::isSearchContext($this->get('context'));
     if (CRM_Contact_Form_Search::isSearchContext($this->get('context')) && !$ssID) {
         $params = array();
         $result = CRM_Core_BAO_PrevNextCache::getSelectedContacts();
         $this->assign("value", $result);
     }
 }
 /**
  * Build a queue of tasks by dividing dupe pairs in batches.
  */
 public static function getRunner()
 {
     $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE, 0);
     $gid = CRM_Utils_Request::retrieve('gid', 'Positive', $this, FALSE, 0);
     $action = CRM_Utils_Request::retrieve('action', 'String', CRM_Core_DAO::$_nullObject);
     $mode = CRM_Utils_Request::retrieve('mode', 'String', CRM_Core_DAO::$_nullObject, FALSE, 'safe');
     $contactType = CRM_Core_DAO::getFieldValue('CRM_Dedupe_DAO_RuleGroup', $rgid, 'contact_type');
     $cacheKeyString = "merge {$contactType}";
     $cacheKeyString .= $rgid ? "_{$rgid}" : '_0';
     $cacheKeyString .= $gid ? "_{$gid}" : '_0';
     $urlQry = "reset=1&action=update&rgid={$rgid}";
     $urlQry = $gid ? $urlQry . "&gid={$gid}" : $urlQry;
     if ($mode == 'aggressive' && !CRM_Core_Permission::check('force merge duplicate contacts')) {
         CRM_Core_Session::setStatus(ts('You do not have permission to force merge duplicate contact records'), ts('Permission Denied'), 'error');
         CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry));
     }
     // Setup the Queue
     $queue = CRM_Queue_Service::singleton()->create(array('name' => $cacheKeyString, 'type' => 'Sql', 'reset' => TRUE));
     $where = NULL;
     if ($action == CRM_Core_Action::MAP) {
         $where = "pn.is_selected = 1";
         $isSelected = 1;
     } else {
         // else merge all (2)
         $isSelected = 2;
     }
     $total = CRM_Core_BAO_PrevNextCache::getCount($cacheKeyString, NULL, $where);
     if ($total <= 0) {
         // Nothing to do.
         CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry));
     }
     // reset merge stats, so we compute new stats
     CRM_Dedupe_Merger::resetMergeStats($cacheKeyString);
     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), "Processed " . $i * self::BATCHLIMIT . " pair of duplicates out of " . $total);
         // Add the Task to the Queue
         $queue->createItem($task);
     }
     // Setup the Runner
     $urlQry .= "&context=conflicts";
     $runner = new CRM_Queue_Runner(array('title' => ts('Merging Duplicates..'), 'queue' => $queue, 'errorMode' => CRM_Queue_Runner::ERROR_ABORT, 'onEndUrl' => CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry, TRUE, NULL, FALSE)));
     return $runner;
 }
Exemple #7
0
 /**
  * Function to set variables up before form is built
  *
  * @return void
  * @access public
  */
 public function preProcess()
 {
     if (CRM_Mailing_Info::workflowEnabled() && !CRM_Core_Permission::check('schedule mailings')) {
         $url = CRM_Utils_System::url('civicrm/mailing/browse/unscheduled', 'reset=1&scheduled=false');
         CRM_Utils_System::redirect($url);
     }
     //when user come from search context.
     $ssID = $this->get('ssID');
     $this->assign('ssid', $ssID);
     $this->_searchBasedMailing = CRM_Contact_Form_Search::isSearchContext($this->get('context'));
     if (CRM_Contact_Form_Search::isSearchContext($this->get('context')) && !$ssID) {
         $params = array();
         $result = CRM_Core_BAO_PrevNextCache::getSelectedContacts();
         $this->assign("value", $result);
     }
     $this->_mailingID = $this->get('mailing_id');
     $this->_scheduleFormOnly = FALSE;
     if (!$this->_mailingID) {
         $this->_mailingID = CRM_Utils_Request::retrieve('mid', 'Integer', $this, TRUE);
         $this->_scheduleFormOnly = TRUE;
     }
 }
 function fillupPrevNextCache($sort, $cacheKey = NULL)
 {
     if (!$cacheKey) {
         $cacheKey = "civicrm search {$this->_key}";
     }
     CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey, 'civicrm_contact');
     // lets fill up the prev next cache here, so view can scroll thru
     $sql = $this->_query->searchQuery(0, 0, $sort, FALSE, FALSE, FALSE, TRUE, TRUE, NULL);
     // CRM-9096
     // due to limitations in our search query writer, the above query does not work
     // in cases where the query is being sorted on a non-contact table
     // this results in a fatal error :(
     // see below for the gross hack of trapping the error and not filling
     // the prev next cache in this situation
     // the other alternative of running the FULL query will just be incredibly inefficient
     // and slow things down way too much on large data sets / complex queries
     $insertSQL = "\nINSERT INTO civicrm_prevnext_cache ( entity_table, entity_id1, entity_id2, cacheKey, data )\nSELECT 'civicrm_contact', contact_a.id, contact_a.id, '{$cacheKey}', contact_a.display_name\n";
     $replaceSQL = "SELECT contact_a.id as id";
     $sql = str_replace($replaceSQL, $insertSQL, $sql);
     CRM_Core_Error::ignoreException();
     $result = CRM_Core_DAO::executeQuery($sql);
     CRM_Core_Error::setCallback();
     if (is_a($result, 'DB_Error')) {
         // oops the above query failed, so lets just ignore it
         // and return
         // we print a sorry cant figure it out on view page
         return;
     }
     // also record an entry in the cache key table, so we can delete it periodically
     CRM_Core_BAO_Cache::setItem($cacheKey, 'CiviCRM Search PrevNextCache', $cacheKey);
 }
 /**
  * Process the form submission.
  *
  *
  * @return void
  */
 public function postProcess()
 {
     $values = $this->exportValues();
     //FIXME: Handle logic to replace is_default column by usage
     // reset used column to General (since there can only
     // be one 'Supervised' or 'Unsupervised' rule)
     if ($values['used'] != 'General') {
         $query = "\nUPDATE civicrm_dedupe_rule_group\n   SET used = 'General'\n WHERE contact_type = %1\n   AND used = %2";
         $queryParams = array(1 => array($this->_contactType, 'String'), 2 => array($values['used'], 'String'));
         CRM_Core_DAO::executeQuery($query, $queryParams);
     }
     $rgDao = new CRM_Dedupe_DAO_RuleGroup();
     if ($this->_action & CRM_Core_Action::UPDATE) {
         $rgDao->id = $this->_rgid;
     }
     $rgDao->title = $values['title'];
     $rgDao->is_reserved = CRM_Utils_Array::value('is_reserved', $values, FALSE);
     $rgDao->used = $values['used'];
     $rgDao->contact_type = $this->_contactType;
     $rgDao->threshold = $values['threshold'];
     $rgDao->save();
     // make sure name is set only during insert
     if ($this->_action & CRM_Core_Action::ADD) {
         // generate name based on title
         $rgDao->name = CRM_Utils_String::titleToVar($values['title']) . "_{$rgDao->id}";
         $rgDao->save();
     }
     // lets skip updating of fields for reserved dedupe group
     if ($rgDao->is_reserved) {
         CRM_Core_Session::setStatus(ts("The rule '%1' has been saved.", array(1 => $rgDao->title)), ts('Saved'), 'success');
         return;
     }
     $ruleDao = new CRM_Dedupe_DAO_Rule();
     $ruleDao->dedupe_rule_group_id = $rgDao->id;
     $ruleDao->delete();
     $ruleDao->free();
     $substrLenghts = array();
     $tables = array();
     $daoObj = new CRM_Core_DAO();
     $database = $daoObj->database();
     for ($count = 0; $count < self::RULES_COUNT; $count++) {
         if (empty($values["where_{$count}"])) {
             continue;
         }
         list($table, $field) = explode('.', CRM_Utils_Array::value("where_{$count}", $values));
         $length = !empty($values["length_{$count}"]) ? CRM_Utils_Array::value("length_{$count}", $values) : NULL;
         $weight = $values["weight_{$count}"];
         if ($table and $field) {
             $ruleDao = new CRM_Dedupe_DAO_Rule();
             $ruleDao->dedupe_rule_group_id = $rgDao->id;
             $ruleDao->rule_table = $table;
             $ruleDao->rule_field = $field;
             $ruleDao->rule_length = $length;
             $ruleDao->rule_weight = $weight;
             $ruleDao->save();
             $ruleDao->free();
             if (!array_key_exists($table, $tables)) {
                 $tables[$table] = array();
             }
             $tables[$table][] = $field;
         }
         // CRM-6245: we must pass table/field/length triples to the createIndexes() call below
         if ($length) {
             if (!isset($substrLenghts[$table])) {
                 $substrLenghts[$table] = array();
             }
             //CRM-13417 to avoid fatal error "Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys, 1089"
             $schemaQuery = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS\n          WHERE TABLE_SCHEMA = '{$database}' AND\n          TABLE_NAME = '{$table}' AND COLUMN_NAME = '{$field}';";
             $dao = CRM_Core_DAO::executeQuery($schemaQuery);
             if ($dao->fetch()) {
                 // set the length to null for all the fields where prefix length is not supported. eg. int,tinyint,date,enum etc dataTypes.
                 if ($dao->COLUMN_NAME == $field && !in_array($dao->DATA_TYPE, array('char', 'varchar', 'binary', 'varbinary', 'text', 'blob'))) {
                     $length = NULL;
                 } elseif ($dao->COLUMN_NAME == $field && !empty($dao->CHARACTER_MAXIMUM_LENGTH) && $length > $dao->CHARACTER_MAXIMUM_LENGTH) {
                     //set the length to CHARACTER_MAXIMUM_LENGTH in case the length provided by the user is greater than the limit
                     $length = $dao->CHARACTER_MAXIMUM_LENGTH;
                 }
             }
             $substrLenghts[$table][$field] = $length;
         }
     }
     // also create an index for this dedupe rule
     // CRM-3837
     CRM_Utils_Hook::dupeQuery($ruleDao, 'dedupeIndexes', $tables);
     CRM_Core_BAO_SchemaHandler::createIndexes($tables, 'dedupe_index', $substrLenghts);
     //need to clear cache of deduped contacts
     //based on the previous rule
     $cacheKey = "merge {$this->_contactType}_{$this->_rgid}_%";
     CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey);
     CRM_Core_Session::setStatus(ts("The rule '%1' has been saved.", array(1 => $rgDao->title)), ts('Saved'), 'success');
 }
Exemple #10
0
 /**
  * Build all the data structures needed to build the form.
  */
 public function preProcess()
 {
     $values = $this->controller->exportValues('Search');
     $this->_task = $values['task'];
     $campaignTasks = CRM_Campaign_Task::tasks();
     $taskName = CRM_Utils_Array::value($this->_task, $campaignTasks);
     $this->assign('taskName', $taskName);
     $ids = array();
     if ($values['radio_ts'] == 'ts_sel') {
         foreach ($values as $name => $value) {
             if (substr($name, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) {
                 $ids[] = substr($name, CRM_Core_Form::CB_PREFIX_LEN);
             }
         }
     } else {
         $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $this);
         $cacheKey = "civicrm search {$qfKey}";
         $allCids = CRM_Core_BAO_PrevNextCache::getSelection($cacheKey, "getall");
         $ids = array_keys($allCids[$cacheKey]);
         $this->assign('totalSelectedVoters', count($ids));
     }
     if (!empty($ids)) {
         $this->_componentClause = 'contact_a.id IN ( ' . implode(',', $ids) . ' ) ';
         $this->assign('totalSelectedVoters', count($ids));
     }
     $this->_voterIds = $this->_contactIds = $this->_componentIds = $ids;
     $this->assign('totalSelectedContacts', count($this->_contactIds));
     //set the context for redirection for any task actions
     $session = CRM_Core_Session::singleton();
     $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $this);
     $urlParams = 'force=1';
     if (CRM_Utils_Rule::qfKey($qfKey)) {
         $urlParams .= '&qfKey=' . $qfKey;
     }
     $session->replaceUserContext(CRM_Utils_System::url('civicrm/survey/search', $urlParams));
 }
 /**
  * Delete a contact and all its associated records.
  *
  * @param int $id
  *   Id of the contact to delete.
  * @param bool $restore
  *   Whether to actually restore, not delete.
  * @param bool $skipUndelete
  *   Whether to force contact delete or not.
  *
  * @return bool
  *   Was contact deleted?
  */
 public static function deleteContact($id, $restore = FALSE, $skipUndelete = FALSE)
 {
     if (!$id) {
         return FALSE;
     }
     // If trash is disabled in system settings then we always skip
     if (!CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'contact_undelete', NULL, 1)) {
         $skipUndelete = TRUE;
     }
     // make sure we have edit permission for this contact
     // before we delete
     if ($skipUndelete && !CRM_Core_Permission::check('delete contacts') || $restore && !CRM_Core_Permission::check('access deleted contacts')) {
         return FALSE;
     }
     // CRM-12929
     // Restrict contact to be delete if contact has financial trxns
     $error = NULL;
     if ($skipUndelete && CRM_Financial_BAO_FinancialItem::checkContactPresent(array($id), $error)) {
         return FALSE;
     }
     // make sure this contact_id does not have any membership types
     $membershipTypeID = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $id, 'id', 'member_of_contact_id');
     if ($membershipTypeID) {
         return FALSE;
     }
     $contact = new CRM_Contact_DAO_Contact();
     $contact->id = $id;
     if (!$contact->find(TRUE)) {
         return FALSE;
     }
     $contactType = $contact->contact_type;
     // currently we only clear employer cache.
     // we are now deleting inherited membership if any.
     if ($contact->contact_type == 'Organization') {
         $action = $restore ? CRM_Core_Action::ENABLE : CRM_Core_Action::DISABLE;
         $relationshipDtls = CRM_Contact_BAO_Relationship::getRelationship($id);
         if (!empty($relationshipDtls)) {
             foreach ($relationshipDtls as $rId => $details) {
                 CRM_Contact_BAO_Relationship::disableEnableRelationship($rId, $action);
             }
         }
         CRM_Contact_BAO_Contact_Utils::clearAllEmployee($id);
     }
     if ($restore) {
         return self::contactTrashRestore($contact, TRUE);
     }
     // start a new transaction
     $transaction = new CRM_Core_Transaction();
     if ($skipUndelete) {
         CRM_Utils_Hook::pre('delete', $contactType, $id, CRM_Core_DAO::$_nullArray);
         //delete billing address if exists.
         CRM_Contribute_BAO_Contribution::deleteAddress(NULL, $id);
         // delete the log entries since we dont have triggers enabled as yet
         $logDAO = new CRM_Core_DAO_Log();
         $logDAO->entity_table = 'civicrm_contact';
         $logDAO->entity_id = $id;
         $logDAO->delete();
         // delete contact participants CRM-12155
         CRM_Event_BAO_Participant::deleteContactParticipant($id);
         // delete contact contributions CRM-12155
         CRM_Contribute_BAO_Contribution::deleteContactContribution($id);
         // do activity cleanup, CRM-5604
         CRM_Activity_BAO_Activity::cleanupActivity($id);
         // delete all notes related to contact
         CRM_Core_BAO_Note::cleanContactNotes($id);
         // delete cases related to contact
         $contactCases = CRM_Case_BAO_Case::retrieveCaseIdsByContactId($id);
         if (!empty($contactCases)) {
             foreach ($contactCases as $caseId) {
                 //check if case is associate with other contact or not.
                 $caseContactId = CRM_Case_BAO_Case::getCaseClients($caseId);
                 if (count($caseContactId) <= 1) {
                     CRM_Case_BAO_Case::deleteCase($caseId);
                 }
             }
         }
         $contact->delete();
     } else {
         self::contactTrashRestore($contact);
     }
     //delete the contact id from recently view
     CRM_Utils_Recent::delContact($id);
     // Update the group contact cache
     if ($restore) {
         CRM_Contact_BAO_GroupContactCache::remove();
     } else {
         CRM_Contact_BAO_GroupContactCache::removeContact($id);
     }
     // delete any dupe cache entry
     CRM_Core_BAO_PrevNextCache::deleteItem($id);
     $transaction->commit();
     if ($skipUndelete) {
         CRM_Utils_Hook::post('delete', $contactType, $contact->id, $contact);
     }
     // also reset the DB_DO global array so we can reuse the memory
     // http://issues.civicrm.org/jira/browse/CRM-4387
     CRM_Core_DAO::freeResult();
     return TRUE;
 }
 /**
  * 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;
 }
 static function refillCache($rgid = NULL, $gid = NULL, $cacheKeyString = NULL)
 {
     if (!$cacheKeyString && $rgid) {
         $contactType = CRM_Core_DAO::getFieldValue('CRM_Dedupe_DAO_RuleGroup', $rgid, 'contact_type');
         $cacheKeyString = "merge {$contactType}";
         $cacheKeyString .= $rgid ? "_{$rgid}" : '_0';
         $cacheKeyString .= $gid ? "_{$gid}" : '_0';
     }
     if (!$cacheKeyString) {
         return FALSE;
     }
     // 1. Clear cache if any
     $sql = "DELETE FROM civicrm_prevnext_cache WHERE  cacheKey LIKE %1";
     CRM_Core_DAO::executeQuery($sql, array(1 => array("{$cacheKeyString}%", 'String')));
     // FIXME: we need to start using temp tables / queries here instead of arrays.
     // And cleanup code in CRM/Contact/Page/DedupeFind.php
     // 2. FILL cache
     $foundDupes = array();
     if ($rgid && $gid) {
         $foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid);
     } elseif ($rgid) {
         $foundDupes = CRM_Dedupe_Finder::dupes($rgid);
     }
     if (!empty($foundDupes)) {
         $cids = $displayNames = $values = 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);
         while ($dao->fetch()) {
             $displayNames[$dao->id] = $dao->display_name;
         }
         $session = CRM_Core_Session::singleton();
         $userId = $session->get('userID');
         foreach ($foundDupes as $dupes) {
             $srcID = $dupes[0];
             $dstID = $dupes[1];
             if ($dstID == $userId) {
                 $srcID = $dupes[1];
                 $dstID = $dupes[0];
             }
             $row = array('srcID' => $srcID, 'srcName' => $displayNames[$srcID], 'dstID' => $dstID, 'dstName' => $displayNames[$dstID], 'weight' => $dupes[2], 'canMerge' => TRUE);
             $data = CRM_Core_DAO::escapeString(serialize($row));
             $values[] = " ( 'civicrm_contact', {$srcID}, {$dstID}, '{$cacheKeyString}', '{$data}' ) ";
         }
         CRM_Core_BAO_PrevNextCache::setItem($values);
     }
 }
 /**
  * @param $sort
  *
  * @return string
  */
 function buildPrevNextCache($sort)
 {
     $cacheKey = 'civicrm search ' . $this->_key;
     // Get current page requested
     $pageNum = CRM_Utils_Request::retrieve('crmPID', 'Integer', CRM_Core_DAO::$_nullObject);
     // When starting from scratch, clear any old cache
     if (!$pageNum) {
         CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey, 'civicrm_contact');
         $pageNum = 1;
     }
     $pageSize = CRM_Utils_Request::retrieve('crmRowCount', 'Integer', CRM_Core_DAO::$_nullObject, FALSE, 50);
     $firstRecord = ($pageNum - 1) * $pageSize;
     //for alphabetic pagination selection save
     $sortByCharacter = CRM_Utils_Request::retrieve('sortByCharacter', 'String', CRM_Core_DAO::$_nullObject);
     //for text field pagination selection save
     $countRow = CRM_Core_BAO_PrevNextCache::getCount($cacheKey, NULL, "entity_table = 'civicrm_contact'");
     // $sortByCharacter triggers a refresh in the prevNext cache
     if ($sortByCharacter && $sortByCharacter != 'all') {
         $cacheKey .= "_alphabet";
         $this->fillupPrevNextCache($sort, $cacheKey);
     } elseif ($firstRecord >= $countRow) {
         $this->fillupPrevNextCache($sort, $cacheKey, $countRow, 500);
     }
     return $cacheKey;
 }
Exemple #15
0
 /**
  * Do periodic cleanup of the CiviCRM session table. Also delete all session cache entries
  * which are a couple of days old. This keeps the session cache to a manageable size
  *
  * @return void
  * @static
  * @access private
  */
 static function cleanup($session = false, $table = false, $prevNext = false)
 {
     // clean up the session cache every $cacheCleanUpNumber probabilistically
     $cleanUpNumber = 757;
     // clean up all sessions older than $cacheTimeIntervalDays days
     $timeIntervalDays = 2;
     $timeIntervalMins = 30;
     if (mt_rand(1, 100000) % $cleanUpNumber == 0) {
         $session = $table = $prevNext = true;
     }
     if (!$session && !$table && !$prevNext) {
         return;
     }
     if ($prevNext) {
         // delete all PrevNext caches
         CRM_Core_BAO_PrevNextCache::cleanupCache();
     }
     if ($table) {
         // also delete all the action temp tables
         // that were created the same interval ago
         $dao = new CRM_Core_DAO();
         $query = "\nSELECT TABLE_NAME as tableName\nFROM   INFORMATION_SCHEMA.TABLES\nWHERE  TABLE_SCHEMA = %1\nAND    ( TABLE_NAME LIKE 'civicrm_task_action_temp_%'\n OR      TABLE_NAME LIKE 'civicrm_export_temp_%'\n OR      TABLE_NAME LIKE 'civicrm_import_job_%' )\nAND    CREATE_TIME < date_sub( NOW( ), INTERVAL {$timeIntervalDays} day )\n";
         $params = array(1 => array($dao->database(), 'String'));
         $tableDAO = CRM_Core_DAO::executeQuery($query, $params);
         $tables = array();
         while ($tableDAO->fetch()) {
             $tables[] = $tableDAO->tableName;
         }
         if (!empty($tables)) {
             $table = implode(',', $tables);
             // drop leftover temporary tables
             CRM_Core_DAO::executeQuery("DROP TABLE {$table}");
         }
     }
     if ($session) {
         // first delete all sessions which are related to any potential transaction
         // page
         $transactionPages = array('CRM_Contribute_Controller_Contribution', 'CRM_Event_Controller_Registration');
         $params = array(1 => array(date('Y-m-d H:i:s', time() - $timeIntervalMins * 60), 'String'));
         foreach ($transactionPages as $trPage) {
             $params[] = array("%{$trPage}%", 'String');
             $where[] = 'path LIKE %' . sizeof($params);
         }
         $sql = "\nDELETE FROM civicrm_cache\nWHERE       group_name = 'CiviCRM Session'\nAND         created_date <= %1\nAND         (" . implode(' OR ', $where) . ")";
         CRM_Core_DAO::executeQuery($sql, $params);
         $sql = "\nDELETE FROM civicrm_cache\nWHERE       group_name = 'CiviCRM Session'\nAND         created_date < date_sub( NOW( ), INTERVAL {$timeIntervalDays} DAY )\n";
         CRM_Core_DAO::executeQuery($sql);
     }
 }
Exemple #16
0
 /**
  * @param CRM_Utils_Sort $sort
  *
  * @return string
  */
 public function buildPrevNextCache($sort)
 {
     $cacheKey = 'civicrm search ' . $this->_key;
     // We should clear the cache in following conditions:
     // 1. when starting from scratch, i.e new search
     // 2. if records are sorted
     // get current page requested
     $pageNum = CRM_Utils_Request::retrieve('crmPID', 'Integer', CRM_Core_DAO::$_nullObject);
     // get the current sort order
     $currentSortID = CRM_Utils_Request::retrieve('crmSID', 'String', CRM_Core_DAO::$_nullObject);
     $session = CRM_Core_Session::singleton();
     // get previous sort id
     $previousSortID = $session->get('previousSortID');
     // check for current != previous to ensure cache is not reset if paging is done without changing
     // sort criteria
     if (!$pageNum || !empty($currentSortID) && $currentSortID != $previousSortID) {
         CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey, 'civicrm_contact');
         // this means it's fresh search, so set pageNum=1
         if (!$pageNum) {
             $pageNum = 1;
         }
     }
     // set the current sort as previous sort
     if (!empty($currentSortID)) {
         $session->set('previousSortID', $currentSortID);
     }
     $pageSize = CRM_Utils_Request::retrieve('crmRowCount', 'Integer', CRM_Core_DAO::$_nullObject, FALSE, 50);
     $firstRecord = ($pageNum - 1) * $pageSize;
     //for alphabetic pagination selection save
     $sortByCharacter = CRM_Utils_Request::retrieve('sortByCharacter', 'String', CRM_Core_DAO::$_nullObject);
     //for text field pagination selection save
     $countRow = CRM_Core_BAO_PrevNextCache::getCount($cacheKey, NULL, "entity_table = 'civicrm_contact'");
     // $sortByCharacter triggers a refresh in the prevNext cache
     if ($sortByCharacter && $sortByCharacter != 'all') {
         $cacheKey .= "_alphabet";
         $this->fillupPrevNextCache($sort, $cacheKey);
     } elseif ($firstRecord >= $countRow) {
         $this->fillupPrevNextCache($sort, $cacheKey, $countRow, 500 + $firstRecord - $countRow);
     }
     return $cacheKey;
 }
Exemple #17
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();
 }
Exemple #18
0
 function buildPrevNextCache($sort)
 {
     //for prev/next pagination
     $crmPID = CRM_Utils_Request::retrieve('crmPID', 'Integer', CRM_Core_DAO::$_nullObject);
     if (!$crmPID) {
         $cacheKey = "civicrm search {$this->_key}";
         CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey, 'civicrm_contact');
         $sql = $this->_query->searchQuery(0, 0, $sort, FALSE, FALSE, FALSE, FALSE, TRUE, $this->_campaignWhereClause, NULL, $this->_campaignFromClause);
         list($select, $from) = explode(' FROM ', $sql);
         $insertSQL = "\nINSERT INTO civicrm_prevnext_cache ( entity_table, entity_id1, entity_id2, cacheKey, data )\nSELECT 'civicrm_contact', contact_a.id, contact_a.id, '{$cacheKey}', contact_a.display_name\nFROM {$from}\n";
         CRM_Core_Error::ignoreException();
         $result = CRM_Core_DAO::executeQuery($insertSQL);
         CRM_Core_Error::setCallback();
         if (is_a($result, 'DB_Error')) {
             return;
         }
         // also record an entry in the cache key table, so we can delete it periodically
         CRM_Core_BAO_Cache::setItem($cacheKey, 'CiviCRM Search PrevNextCache', $cacheKey);
     }
 }
 /**
  * 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();
 }
Exemple #20
0
 /**
  * Do periodic cleanup of the CiviCRM session table.
  *
  * Also delete all session cache entries which are a couple of days old.
  * This keeps the session cache to a manageable size
  *
  * @param bool $session
  * @param bool $table
  * @param bool $prevNext
  */
 public static function cleanup($session = FALSE, $table = FALSE, $prevNext = FALSE)
 {
     // clean up the session cache every $cacheCleanUpNumber probabilistically
     $cleanUpNumber = 757;
     // clean up all sessions older than $cacheTimeIntervalDays days
     $timeIntervalDays = 2;
     $timeIntervalMins = 30;
     if (mt_rand(1, 100000) % $cleanUpNumber == 0) {
         $session = $table = $prevNext = TRUE;
     }
     if (!$session && !$table && !$prevNext) {
         return;
     }
     if ($prevNext) {
         // delete all PrevNext caches
         CRM_Core_BAO_PrevNextCache::cleanupCache();
     }
     if ($table) {
         CRM_Core_Config::clearTempTables($timeIntervalDays . ' day');
     }
     if ($session) {
         // first delete all sessions which are related to any potential transaction
         // page
         $transactionPages = array('CRM_Contribute_Controller_Contribution', 'CRM_Event_Controller_Registration');
         $params = array(1 => array(date('Y-m-d H:i:s', time() - $timeIntervalMins * 60), 'String'));
         foreach ($transactionPages as $trPage) {
             $params[] = array("%{$trPage}%", 'String');
             $where[] = 'path LIKE %' . count($params);
         }
         $sql = "\nDELETE FROM civicrm_cache\nWHERE       group_name = 'CiviCRM Session'\nAND         created_date <= %1\nAND         (" . implode(' OR ', $where) . ")";
         CRM_Core_DAO::executeQuery($sql, $params);
         $sql = "\nDELETE FROM civicrm_cache\nWHERE       group_name = 'CiviCRM Session'\nAND         created_date < date_sub( NOW( ), INTERVAL {$timeIntervalDays} DAY )\n";
         CRM_Core_DAO::executeQuery($sql);
     }
 }
Exemple #21
0
 /**
  * Clear the contact cache so things are kosher. We started off being super aggressive with clearing
  * caches, but are backing off from this with every release. Compromise between ease of coding versus
  * performance versus being accurate at that very instant
  *
  * @param $contactID
  *   The contactID that was edited / deleted.
  */
 public static function clearContactCaches($contactID = NULL)
 {
     // clear acl cache if any.
     CRM_ACL_BAO_Cache::resetCache();
     if (empty($contactID)) {
         // also clear prev/next dedupe cache - if no contactID passed in
         CRM_Core_BAO_PrevNextCache::deleteItem();
     }
     CRM_Contact_BAO_GroupContactCache::opportunisticCacheFlush();
 }
Exemple #22
0
 public function postProcess()
 {
     $formValues = $this->exportValues();
     // reset all selected contact ids from session
     // when we came from search context, CRM-3526
     $session = CRM_Core_Session::singleton();
     if ($session->get('selectedSearchContactIds')) {
         $session->resetScope('selectedSearchContactIds');
     }
     $formValues['main_details'] = $this->_mainDetails;
     $formValues['other_details'] = $this->_otherDetails;
     CRM_Dedupe_Merger::moveAllBelongings($this->_cid, $this->_oid, $formValues);
     $name = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_cid, 'display_name');
     $message = '<ul><li>' . ts('%1 has been updated.', array(1 => $name)) . '</li><li>' . ts('Contact ID %1 has been deleted.', array(1 => $this->_oid)) . '</li></ul>';
     CRM_Core_Session::setStatus($message, ts('Contacts Merged'), 'success');
     //create activity for merge
     //To do: this should be refactored into BAO layer at some point.
     $messageActivity = ts('Contact ID %1 has been merged and deleted.', array(1 => $this->_oid));
     $activityParams = array('subject' => $messageActivity, 'source_contact_id' => $session->get('userID'), 'target_contact_id' => $this->_cid, 'activity_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Contact Merged'), 'status_id' => 'Completed', 'priority_id' => 'Normal', 'activity_date_time' => date('YmdHis'));
     civicrm_api3('activity', 'create', $activityParams);
     $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->_cid}");
     if (!empty($formValues['_qf_Merge_submit'])) {
         $listParamsURL = "reset=1&action=update&rgid={$this->_rgid}";
         if ($this->_gid) {
             $listParamsURL .= "&gid={$this->_gid}";
         }
         $lisitingURL = CRM_Utils_System::url('civicrm/contact/dedupefind', $listParamsURL);
         CRM_Utils_System::redirect($lisitingURL);
     }
     if (!empty($formValues['_qf_Merge_done'])) {
         CRM_Utils_System::redirect($url);
     }
     if ($this->next && $this->_mergeId) {
         $cacheKey = "merge {$this->_contactType}";
         $cacheKey .= $this->_rgid ? "_{$this->_rgid}" : '_0';
         $cacheKey .= $this->_gid ? "_{$this->_gid}" : '_0';
         $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";
         $pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, NULL, NULL, $this->_mergeId, $join, $where);
         if (!empty($pos) && $pos['next']['id1'] && $pos['next']['id2']) {
             $urlParam = "reset=1&cid={$pos['next']['id1']}&oid={$pos['next']['id2']}&mergeId={$pos['next']['mergeId']}&action=update";
             if ($this->_rgid) {
                 $urlParam .= "&rgid={$this->_rgid}";
             }
             if ($this->_gid) {
                 $urlParam .= "&gid={$this->_gid}";
             }
             $url = CRM_Utils_System::url('civicrm/contact/merge', $urlParam);
         }
     }
     CRM_Utils_System::redirect($url);
 }
Exemple #23
0
 public function postProcess()
 {
     $formValues = $this->exportValues();
     // reset all selected contact ids from session
     // when we came from search context, CRM-3526
     $session = CRM_Core_Session::singleton();
     if ($session->get('selectedSearchContactIds')) {
         $session->resetScope('selectedSearchContactIds');
     }
     $formValues['main_details'] = $formValues['other_details'] = array();
     $formValues['main_details']['contact_type'] = $this->_contactType;
     $formValues['main_details']['loc_block_ids'] = $this->_locBlockIds['main'];
     $formValues['other_details']['loc_block_ids'] = $this->_locBlockIds['other'];
     CRM_Dedupe_Merger::moveAllBelongings($this->_cid, $this->_oid, $formValues);
     CRM_Core_Session::setStatus(ts('Contact id %1 has been updated and contact id %2 has been deleted.', array(1 => $this->_cid, 2 => $this->_oid)), ts('Contacts Merged'), 'success');
     $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->_cid}");
     if (CRM_Utils_Array::value('_qf_Merge_submit', $formValues)) {
         $listParamsURL = "reset=1&action=update&rgid={$this->_rgid}";
         if ($this->_gid) {
             $listParamsURL .= "&gid={$this->_gid}";
         }
         $lisitingURL = CRM_Utils_System::url('civicrm/contact/dedupefind', $listParamsURL);
         CRM_Utils_System::redirect($lisitingURL);
     }
     if (CRM_Utils_Array::value('_qf_Merge_done', $formValues)) {
         CRM_Utils_System::redirect($url);
     }
     if ($this->next && $this->_mergeId) {
         $cacheKey = "merge {$this->_contactType}";
         $cacheKey .= $this->_rgid ? "_{$this->_rgid}" : '_0';
         $cacheKey .= $this->_gid ? "_{$this->_gid}" : '_0';
         $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";
         $pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, NULL, NULL, $this->_mergeId, $join, $where);
         if (!empty($pos) && $pos['next']['id1'] && $pos['next']['id2']) {
             $urlParam = "reset=1&cid={$pos['next']['id1']}&oid={$pos['next']['id2']}&mergeId={$pos['next']['mergeId']}&action=update";
             if ($this->_rgid) {
                 $urlParam .= "&rgid={$this->_rgid}";
             }
             if ($this->_gid) {
                 $urlParam .= "&gid={$this->_gid}";
             }
             $url = CRM_Utils_System::url('civicrm/contact/merge', $urlParam);
         }
     }
     CRM_Utils_System::redirect($url);
 }
Exemple #24
0
 public function postProcess()
 {
     $formValues = $this->exportValues();
     // reset all selected contact ids from session
     // when we came from search context, CRM-3526
     $session = CRM_Core_Session::singleton();
     if ($session->get('selectedSearchContactIds')) {
         $session->resetScope('selectedSearchContactIds');
     }
     $formValues['main_details'] = $this->_mainDetails;
     $formValues['other_details'] = $this->_otherDetails;
     $migrationData = array('migration_info' => $formValues);
     CRM_Utils_Hook::merge('form', $migrationData, $this->_cid, $this->_oid);
     CRM_Dedupe_Merger::moveAllBelongings($this->_cid, $this->_oid, $migrationData['migration_info']);
     $name = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_cid, 'display_name');
     $message = '<ul><li>' . ts('%1 has been updated.', array(1 => $name)) . '</li><li>' . ts('Contact ID %1 has been deleted.', array(1 => $this->_oid)) . '</li></ul>';
     CRM_Core_Session::setStatus($message, ts('Contacts Merged'), 'success');
     $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->_cid}");
     $urlParams = "reset=1&gid={$this->_gid}&rgid={$this->_rgid}&limit={$this->limit}";
     if (!empty($formValues['_qf_Merge_submit'])) {
         $urlParams .= "&action=update";
         $lisitingURL = CRM_Utils_System::url('civicrm/contact/dedupefind', $urlParams);
         CRM_Utils_System::redirect($lisitingURL);
     }
     if (!empty($formValues['_qf_Merge_done'])) {
         CRM_Utils_System::redirect($url);
     }
     if ($this->next && $this->_mergeId) {
         $cacheKey = CRM_Dedupe_Merger::getMergeCacheKeyString($this->_rgid, $this->_gid);
         $join = CRM_Dedupe_Merger::getJoinOnDedupeTable();
         $where = "de.id IS NULL";
         $pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, NULL, NULL, $this->_mergeId, $join, $where);
         if (!empty($pos) && $pos['next']['id1'] && $pos['next']['id2']) {
             $urlParams .= "&cid={$pos['next']['id1']}&oid={$pos['next']['id2']}&mergeId={$pos['next']['mergeId']}&action=update";
             $url = CRM_Utils_System::url('civicrm/contact/merge', $urlParams);
         }
     }
     CRM_Utils_System::redirect($url);
 }
Exemple #25
0
 /**
  * Clear the contact cache so things are kosher. We started off being super aggressive with clearing
  * caches, but are backing off from this with every release. Compromise between ease of coding versus
  * performance versus being accurate at that very instant
  *
  * @param $contactID
  *   The contactID that was edited / deleted.
  */
 public static function clearContactCaches($contactID = NULL)
 {
     // clear acl cache if any.
     CRM_ACL_BAO_Cache::resetCache();
     if (empty($contactID)) {
         // also clear prev/next dedupe cache - if no contactID passed in
         CRM_Core_BAO_PrevNextCache::deleteItem();
     }
     // reset the group contact cache for this group
     CRM_Contact_BAO_GroupContactCache::remove();
 }
 static function selectUnselectContacts()
 {
     $name = CRM_Utils_Array::value('name', $_POST);
     $cacheKey = CRM_Utils_Array::value('qfKey', $_POST);
     $state = CRM_Utils_Array::value('state', $_POST, 'checked');
     $variableType = CRM_Utils_Array::value('variableType', $_POST, 'single');
     $actionToPerform = CRM_Utils_Array::value('action', $_POST, 'select');
     if ($actionToPerform == 'countSelection') {
         $contactIds = CRM_Core_BAO_PrevNextCache::getSelection($cacheKey);
         $countSelectionCids = count($contactIds[$cacheKey]);
         $arrRet = array('getCount' => $countSelectionCids);
         echo json_encode($arrRet);
         CRM_Utils_System::civiExit();
     } elseif ($variableType == 'multiple') {
         // action post value only works with multiple type variable
         if ($name) {
             //multiple names like mark_x_1-mark_x_2 where 1,2 are cids
             $elements = explode('-', $name);
             foreach ($elements as $key => $element) {
                 $elements[$key] = self::_convertToId($element);
             }
             CRM_Core_BAO_PrevNextCache::markSelection($cacheKey, $actionToPerform, $elements);
         } else {
             CRM_Core_BAO_PrevNextCache::markSelection($cacheKey, $actionToPerform);
         }
     } elseif ($variableType == 'single') {
         $cId = self::_convertToId($name);
         $action = $state == 'checked' ? 'select' : 'unselect';
         CRM_Core_BAO_PrevNextCache::markSelection($cacheKey, $action, $cId);
     }
 }
Exemple #27
0
 /**
  * Common post processing.
  */
 public function postProcess()
 {
     /*
      * sometime we do a postProcess early on, so we dont need to repeat it
      * this will most likely introduce some more bugs :(
      */
     if ($this->_done) {
         return;
     }
     $this->_done = TRUE;
     //for prev/next pagination
     $crmPID = CRM_Utils_Request::retrieve('crmPID', 'Integer', CRM_Core_DAO::$_nullObject);
     if (array_key_exists($this->_searchButtonName, $_POST) || $this->_force && !$crmPID) {
         //reset the cache table for new search
         $cacheKey = "civicrm search {$this->controller->_key}";
         CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey);
     }
     //get the button name
     $buttonName = $this->controller->getButtonName();
     if (isset($this->_ufGroupID) && empty($this->_formValues['uf_group_id'])) {
         $this->_formValues['uf_group_id'] = $this->_ufGroupID;
     }
     if (isset($this->_componentMode) && empty($this->_formValues['component_mode'])) {
         $this->_formValues['component_mode'] = $this->_componentMode;
     }
     if (isset($this->_operator) && empty($this->_formValues['operator'])) {
         $this->_formValues['operator'] = $this->_operator;
     }
     if (empty($this->_formValues['qfKey'])) {
         $this->_formValues['qfKey'] = $this->controller->_key;
     }
     if (!CRM_Core_Permission::check('access deleted contacts')) {
         unset($this->_formValues['deleted_contacts']);
     }
     $this->set('type', $this->_action);
     $this->set('formValues', $this->_formValues);
     $this->set('queryParams', $this->_params);
     $this->set('returnProperties', $this->_returnProperties);
     if ($buttonName == $this->_actionButtonName) {
         // check actionName and if next, then do not repeat a search, since we are going to the next page
         // hack, make sure we reset the task values
         $stateMachine = $this->controller->getStateMachine();
         $formName = $stateMachine->getTaskFormName();
         $this->controller->resetPage($formName);
         return;
     } else {
         $output = CRM_Core_Selector_Controller::SESSION;
         // create the selector, controller and run - store results in session
         $searchChildGroups = TRUE;
         if ($this->get('isAdvanced')) {
             $searchChildGroups = FALSE;
         }
         $setDynamic = FALSE;
         if (strpos(self::$_selectorName, 'CRM_Contact_Selector') !== FALSE) {
             $selector = new self::$_selectorName($this->_customSearchClass, $this->_formValues, $this->_params, $this->_returnProperties, $this->_action, FALSE, $searchChildGroups, $this->_context, $this->_contextMenu);
             $setDynamic = TRUE;
         } else {
             $selector = new self::$_selectorName($this->_params, $this->_action, NULL, FALSE, NULL, "search", "advanced");
         }
         $selector->setKey($this->controller->_key);
         // added the sorting  character to the form array
         $config = CRM_Core_Config::singleton();
         // do this only for contact search
         if ($setDynamic && $config->includeAlphabeticalPager) {
             // Don't recompute if we are just paging/sorting
             if ($this->_reset || empty($_GET['crmPID']) && empty($_GET['crmSID']) && !$this->_sortByCharacter) {
                 $aToZBar = CRM_Utils_PagerAToZ::getAToZBar($selector, $this->_sortByCharacter);
                 $this->set('AToZBar', $aToZBar);
             }
         }
         $sortID = NULL;
         if ($this->get(CRM_Utils_Sort::SORT_ID)) {
             $sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID), $this->get(CRM_Utils_Sort::SORT_DIRECTION));
         }
         $controller = new CRM_Contact_Selector_Controller($selector, $this->get(CRM_Utils_Pager::PAGE_ID), $sortID, CRM_Core_Action::VIEW, $this, $output);
         $controller->setEmbedded(TRUE);
         $controller->setDynamicAction($setDynamic);
         $controller->run();
     }
 }
Exemple #28
0
 /**
  * Common pre-processing function.
  *
  * @param CRM_Core_Form $form
  * @param bool $useTable
  */
 public static function preProcessCommon(&$form, $useTable = FALSE)
 {
     $form->_contactIds = array();
     $form->_contactTypes = array();
     // get the submitted values of the search form
     // we'll need to get fv from either search or adv search in the future
     $fragment = 'search';
     if ($form->_action == CRM_Core_Action::ADVANCED) {
         self::$_searchFormValues = $form->controller->exportValues('Advanced');
         $fragment .= '/advanced';
     } elseif ($form->_action == CRM_Core_Action::PROFILE) {
         self::$_searchFormValues = $form->controller->exportValues('Builder');
         $fragment .= '/builder';
     } elseif ($form->_action == CRM_Core_Action::COPY) {
         self::$_searchFormValues = $form->controller->exportValues('Custom');
         $fragment .= '/custom';
     } else {
         self::$_searchFormValues = $form->controller->exportValues('Basic');
     }
     //set the user context for redirection of task actions
     $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $form);
     $urlParams = 'force=1';
     if (CRM_Utils_Rule::qfKey($qfKey)) {
         $urlParams .= "&qfKey={$qfKey}";
     }
     $cacheKey = "civicrm search {$qfKey}";
     $url = CRM_Utils_System::url('civicrm/contact/' . $fragment, $urlParams);
     $session = CRM_Core_Session::singleton();
     $session->replaceUserContext($url);
     $form->_task = CRM_Utils_Array::value('task', self::$_searchFormValues);
     $crmContactTaskTasks = CRM_Contact_Task::taskTitles();
     $form->assign('taskName', CRM_Utils_Array::value($form->_task, $crmContactTaskTasks));
     if ($useTable) {
         $form->_componentTable = CRM_Core_DAO::createTempTableName('civicrm_task_action', TRUE, $qfKey);
         $sql = " DROP TABLE IF EXISTS {$form->_componentTable}";
         CRM_Core_DAO::executeQuery($sql);
         $sql = "CREATE TABLE {$form->_componentTable} ( contact_id int primary key) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci";
         CRM_Core_DAO::executeQuery($sql);
     }
     // all contacts or action = save a search
     if (CRM_Utils_Array::value('radio_ts', self::$_searchFormValues) == 'ts_all' || $form->_task == CRM_Contact_Task::SAVE_SEARCH) {
         $sortByCharacter = $form->get('sortByCharacter');
         $cacheKey = $sortByCharacter && $sortByCharacter != 'all' ? "{$cacheKey}_alphabet" : $cacheKey;
         // since we don't store all contacts in prevnextcache, when user selects "all" use query to retrieve contacts
         // rather than prevnext cache table for most of the task actions except export where we rebuild query to fetch
         // final result set
         if ($useTable) {
             $allCids = CRM_Core_BAO_PrevNextCache::getSelection($cacheKey, "getall");
         } else {
             $allCids[$cacheKey] = $form->getContactIds();
         }
         $form->_contactIds = array();
         if ($useTable) {
             $count = 0;
             $insertString = array();
             foreach ($allCids[$cacheKey] as $cid => $ignore) {
                 $count++;
                 $insertString[] = " ( {$cid} ) ";
                 if ($count % 200 == 0) {
                     $string = implode(',', $insertString);
                     $sql = "REPLACE INTO {$form->_componentTable} ( contact_id ) VALUES {$string}";
                     CRM_Core_DAO::executeQuery($sql);
                     $insertString = array();
                 }
             }
             if (!empty($insertString)) {
                 $string = implode(',', $insertString);
                 $sql = "REPLACE INTO {$form->_componentTable} ( contact_id ) VALUES {$string}";
                 CRM_Core_DAO::executeQuery($sql);
             }
         } else {
             // filter duplicates here
             // CRM-7058
             // might be better to do this in the query, but that logic is a bit complex
             // and it decides when to use distinct based on input criteria, which needs
             // to be fixed and optimized.
             foreach ($allCids[$cacheKey] as $cid => $ignore) {
                 $form->_contactIds[] = $cid;
             }
         }
     } elseif (CRM_Utils_Array::value('radio_ts', self::$_searchFormValues) == 'ts_sel') {
         // selected contacts only
         // need to perform action on only selected contacts
         $insertString = array();
         // refire sql in case of custom seach
         if ($form->_action == CRM_Core_Action::COPY) {
             // selected contacts only
             // need to perform action on only selected contacts
             foreach (self::$_searchFormValues as $name => $value) {
                 if (substr($name, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) {
                     $contactID = substr($name, CRM_Core_Form::CB_PREFIX_LEN);
                     if ($useTable) {
                         $insertString[] = " ( {$contactID} ) ";
                     } else {
                         $form->_contactIds[] = substr($name, CRM_Core_Form::CB_PREFIX_LEN);
                     }
                 }
             }
         } else {
             // fetching selected contact ids of passed cache key
             $selectedCids = CRM_Core_BAO_PrevNextCache::getSelection($cacheKey);
             foreach ($selectedCids[$cacheKey] as $selectedCid => $ignore) {
                 if ($useTable) {
                     $insertString[] = " ( {$selectedCid} ) ";
                 } else {
                     $form->_contactIds[] = $selectedCid;
                 }
             }
         }
         if (!empty($insertString)) {
             $string = implode(',', $insertString);
             $sql = "REPLACE INTO {$form->_componentTable} ( contact_id ) VALUES {$string}";
             CRM_Core_DAO::executeQuery($sql);
         }
     }
     //contact type for pick up profiles as per selected contact types with subtypes
     //CRM-5521
     if ($selectedTypes = CRM_Utils_Array::value('contact_type', self::$_searchFormValues)) {
         if (!is_array($selectedTypes)) {
             $selectedTypes = explode(' ', $selectedTypes);
         }
         foreach ($selectedTypes as $ct => $dontcare) {
             if (strpos($ct, CRM_Core_DAO::VALUE_SEPARATOR) === FALSE) {
                 $form->_contactTypes[] = $ct;
             } else {
                 $separator = strpos($ct, CRM_Core_DAO::VALUE_SEPARATOR);
                 $form->_contactTypes[] = substr($ct, $separator + 1);
             }
         }
     }
     if (CRM_Utils_Array::value('radio_ts', self::$_searchFormValues) == 'ts_sel' && $form->_action != CRM_Core_Action::COPY) {
         $sel = CRM_Utils_Array::value('radio_ts', self::$_searchFormValues);
         $form->assign('searchtype', $sel);
         $result = CRM_Core_BAO_PrevNextCache::getSelectedContacts();
         $form->assign("value", $result);
     }
     if (!empty($form->_contactIds)) {
         $form->_componentClause = ' contact_a.id IN ( ' . implode(',', $form->_contactIds) . ' ) ';
         $form->assign('totalSelectedContacts', count($form->_contactIds));
         $form->_componentIds = $form->_contactIds;
     }
 }
Exemple #29
0
 /**
  * Heart of the viewing process.
  *
  * The runner gets all the meta data for the contact and calls the appropriate type of page to view.
  */
 public function preProcess()
 {
     // process url params
     $this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this);
     $this->assign('id', $this->_id);
     $qfKey = CRM_Utils_Request::retrieve('key', 'String', $this);
     //validate the qfKey
     if (!CRM_Utils_Rule::qfKey($qfKey)) {
         $qfKey = NULL;
     }
     $this->assign('searchKey', $qfKey);
     // retrieve the group contact id, so that we can get contact id
     $gcid = CRM_Utils_Request::retrieve('gcid', 'Positive', $this);
     if (!$gcid) {
         $this->_contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE);
     } else {
         $this->_contactId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_GroupContact', $gcid, 'contact_id');
     }
     if (!$this->_contactId) {
         CRM_Core_Error::statusBounce(ts('We could not find a contact id.'), CRM_Utils_System::url('civicrm/dashboard', 'reset=1'));
     }
     // ensure that the id does exist
     if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'id') != $this->_contactId) {
         CRM_Core_Error::statusBounce(ts('A Contact with that ID does not exist: %1', array(1 => $this->_contactId)), CRM_Utils_System::url('civicrm/dashboard', 'reset=1'));
     }
     $this->assign('contactId', $this->_contactId);
     // see if we can get prev/next positions from qfKey
     $navContacts = array('prevContactID' => NULL, 'prevContactName' => NULL, 'nextContactID' => NULL, 'nextContactName' => NULL, 'nextPrevError' => 0);
     if ($qfKey) {
         $pos = CRM_Core_BAO_PrevNextCache::getPositions("civicrm search {$qfKey}", $this->_contactId, $this->_contactId);
         $found = FALSE;
         if (isset($pos['prev'])) {
             $navContacts['prevContactID'] = $pos['prev']['id1'];
             $navContacts['prevContactName'] = $pos['prev']['data'];
             $found = TRUE;
         }
         if (isset($pos['next'])) {
             $navContacts['nextContactID'] = $pos['next']['id1'];
             $navContacts['nextContactName'] = $pos['next']['data'];
             $found = TRUE;
         }
         $context = CRM_Utils_Array::value('context', $_GET);
         if (!$found) {
             // seems like we did not find any contacts
             // maybe due to bug CRM-9096
             // however we should account for 1 contact results (which dont have prev next)
             if (!$pos['foundEntry']) {
                 $navContacts['nextPrevError'] = 1;
             }
         } elseif ($context) {
             $this->assign('context', $context);
             CRM_Utils_System::appendBreadCrumb(array(array('title' => ts('Search Results'), 'url' => CRM_Utils_System::url("civicrm/contact/search/{$context}", array('qfKey' => $qfKey)))));
         }
     }
     $this->assign($navContacts);
     $path = CRM_Utils_System::url('civicrm/contact/view', 'reset=1&cid=' . $this->_contactId);
     CRM_Utils_System::appendBreadCrumb(array(array('title' => ts('View Contact'), 'url' => $path)));
     if ($image_URL = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'image_URL')) {
         //CRM-7265 --time being fix.
         $config = CRM_Core_Config::singleton();
         $image_URL = str_replace('https://', 'http://', $image_URL);
         if (Civi::settings()->get('enableSSL')) {
             $image_URL = str_replace('http://', 'https://', $image_URL);
         }
         list($imageWidth, $imageHeight) = getimagesize(CRM_Utils_String::unstupifyUrl($image_URL));
         list($imageThumbWidth, $imageThumbHeight) = CRM_Contact_BAO_Contact::getThumbSize($imageWidth, $imageHeight);
         $this->assign("imageWidth", $imageWidth);
         $this->assign("imageHeight", $imageHeight);
         $this->assign("imageThumbWidth", $imageThumbWidth);
         $this->assign("imageThumbHeight", $imageThumbHeight);
         $this->assign("imageURL", $image_URL);
     }
     // also store in session for future use
     $session = CRM_Core_Session::singleton();
     $session->set('view.id', $this->_contactId);
     $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 'browse');
     $this->assign('action', $this->_action);
     // check logged in user permission
     self::checkUserPermission($this);
     list($displayName, $contactImage, $contactType, $contactSubtype, $contactImageUrl) = self::getContactDetails($this->_contactId);
     $this->assign('displayName', $displayName);
     $this->set('contactType', $contactType);
     // note: there could still be multiple subtypes. We just trimming the outer separator.
     $this->set('contactSubtype', trim($contactSubtype, CRM_Core_DAO::VALUE_SEPARATOR));
     // add to recently viewed block
     $isDeleted = (bool) CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'is_deleted');
     $recentOther = array('imageUrl' => $contactImageUrl, 'subtype' => $contactSubtype, 'isDeleted' => $isDeleted);
     if (CRM_Contact_BAO_Contact_Permission::allow($this->_contactId, CRM_Core_Permission::EDIT)) {
         $recentOther['editUrl'] = CRM_Utils_System::url('civicrm/contact/add', "reset=1&action=update&cid={$this->_contactId}");
     }
     if ($session->get('userID') != $this->_contactId && CRM_Core_Permission::check('delete contacts') && !$isDeleted) {
         $recentOther['deleteUrl'] = CRM_Utils_System::url('civicrm/contact/view/delete', "reset=1&delete=1&cid={$this->_contactId}");
     }
     CRM_Utils_Recent::add($displayName, CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->_contactId}"), $this->_contactId, $contactType, $this->_contactId, $displayName, $recentOther);
     $this->assign('isDeleted', $isDeleted);
     // set page title
     $title = self::setTitle($this->_contactId, $isDeleted);
     $this->assign('title', $title);
     // Check if this is default domain contact CRM-10482
     if (CRM_Contact_BAO_Contact::checkDomainContact($this->_contactId)) {
         $this->assign('domainContact', TRUE);
     } else {
         $this->assign('domainContact', FALSE);
     }
     // Add links for actions menu
     self::addUrls($this, $this->_contactId);
     if ($contactType == 'Organization' && CRM_Core_Permission::check('administer Multiple Organizations') && Civi::settings()->get('is_enabled')) {
         //check is any relationship between the organization and groups
         $groupOrg = CRM_Contact_BAO_GroupOrganization::hasGroupAssociated($this->_contactId);
         if ($groupOrg) {
             $groupOrganizationUrl = CRM_Utils_System::url('civicrm/group', "reset=1&oid={$this->_contactId}");
             $this->assign('groupOrganizationUrl', $groupOrganizationUrl);
         }
     }
 }
 /**
  * Heart of the viewing process. The runner gets all the meta data for
  * the contact and calls the appropriate type of page to view.
  *
  * @return void
  * @access public
  *
  */
 function preProcess()
 {
     // process url params
     $this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this);
     $this->assign('id', $this->_id);
     $qfKey = CRM_Utils_Request::retrieve('key', 'String', $this);
     //validate the qfKey
     if (!CRM_Utils_Rule::qfKey($qfKey)) {
         $qfKey = NULL;
     }
     $this->assign('searchKey', $qfKey);
     // retrieve the group contact id, so that we can get contact id
     $gcid = CRM_Utils_Request::retrieve('gcid', 'Positive', $this);
     if (!$gcid) {
         $this->_contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE);
     } else {
         $this->_contactId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_GroupContact', $gcid, 'contact_id');
     }
     if (!$this->_contactId) {
         CRM_Core_Error::statusBounce(ts('We could not find a contact id.'), CRM_Utils_System::url('civicrm/dashboard', 'reset=1'));
     }
     // ensure that the id does exist
     if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'id') != $this->_contactId) {
         CRM_Core_Error::statusBounce(ts('A Contact with that ID does not exist: %1', array(1 => $this->_contactId)), CRM_Utils_System::url('civicrm/dashboard', 'reset=1'));
     }
     $this->assign('contactId', $this->_contactId);
     // see if we can get prev/next positions from qfKey
     $navContacts = array('prevContactID' => NULL, 'prevContactName' => NULL, 'nextContactID' => NULL, 'nextContactName' => NULL, 'nextPrevError' => 0);
     if ($qfKey) {
         $pos = CRM_Core_BAO_PrevNextCache::getPositions("civicrm search {$qfKey}", $this->_contactId, $this->_contactId);
         $found = FALSE;
         if (isset($pos['prev'])) {
             $navContacts['prevContactID'] = $pos['prev']['id1'];
             $navContacts['prevContactName'] = $pos['prev']['data'];
             $found = TRUE;
         }
         if (isset($pos['next'])) {
             $navContacts['nextContactID'] = $pos['next']['id1'];
             $navContacts['nextContactName'] = $pos['next']['data'];
             $found = TRUE;
         }
         if (!$found) {
             // seems like we did not find any contacts
             // maybe due to bug CRM-9096
             // however we should account for 1 contact results (which dont have prev next)
             if (!$pos['foundEntry']) {
                 $navContacts['nextPrevError'] = 1;
             }
         }
     }
     $this->assign($navContacts);
     $path = CRM_Utils_System::url('civicrm/contact/view', 'reset=1&cid=' . $this->_contactId);
     CRM_Utils_System::appendBreadCrumb(array(array('title' => ts('View Contact'), 'url' => $path)));
     CRM_Utils_System::appendBreadCrumb(array(array('title' => ts('Search Results'), 'url' => self::getSearchURL())));
     if ($image_URL = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'image_URL')) {
         //CRM-7265 --time being fix.
         $config = CRM_Core_Config::singleton();
         $image_URL = str_replace('https://', 'http://', $image_URL);
         if (CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'enableSSL')) {
             $image_URL = str_replace('http://', 'https://', $image_URL);
         }
         list($imageWidth, $imageHeight) = getimagesize($image_URL);
         list($imageThumbWidth, $imageThumbHeight) = CRM_Contact_BAO_Contact::getThumbSize($imageWidth, $imageHeight);
         $this->assign("imageWidth", $imageWidth);
         $this->assign("imageHeight", $imageHeight);
         $this->assign("imageThumbWidth", $imageThumbWidth);
         $this->assign("imageThumbHeight", $imageThumbHeight);
         $this->assign("imageURL", $image_URL);
     }
     // also store in session for future use
     $session = CRM_Core_Session::singleton();
     $session->set('view.id', $this->_contactId);
     $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 'browse');
     $this->assign('action', $this->_action);
     // check logged in user permission
     self::checkUserPermission($this);
     list($displayName, $contactImage, $contactType, $contactSubtype, $contactImageUrl) = self::getContactDetails($this->_contactId);
     $this->assign('displayName', $displayName);
     $this->set('contactType', $contactType);
     $this->set('contactSubtype', $contactSubtype);
     // see if other modules want to add a link activtity bar
     $hookLinks = CRM_Utils_Hook::links('view.contact.activity', 'Contact', $this->_contactId, CRM_Core_DAO::$_nullObject, CRM_Core_DAO::$_nullObject);
     if (is_array($hookLinks)) {
         $this->assign('hookLinks', $hookLinks);
     }
     // add to recently viewed block
     $isDeleted = (bool) CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'is_deleted');
     $recentOther = array('imageUrl' => $contactImageUrl, 'subtype' => $contactSubtype, 'isDeleted' => $isDeleted);
     if ($session->get('userID') == $this->_contactId || CRM_Contact_BAO_Contact_Permission::allow($this->_contactId, CRM_Core_Permission::EDIT)) {
         $recentOther['editUrl'] = CRM_Utils_System::url('civicrm/contact/add', "reset=1&action=update&cid={$this->_contactId}");
     }
     if ($session->get('userID') != $this->_contactId && CRM_Core_Permission::check('delete contacts') && !$isDeleted) {
         $recentOther['deleteUrl'] = CRM_Utils_System::url('civicrm/contact/view/delete', "reset=1&delete=1&cid={$this->_contactId}");
     }
     CRM_Utils_Recent::add($displayName, CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->_contactId}"), $this->_contactId, $contactType, $this->_contactId, $displayName, $recentOther);
     $this->assign('isDeleted', $isDeleted);
     // set page title
     self::setTitle($this->_contactId, $isDeleted);
     $config = CRM_Core_Config::singleton();
     $uid = CRM_Core_BAO_UFMatch::getUFId($this->_contactId);
     if ($uid) {
         // To do: we should also allow drupal users with CRM_Core_Permission::check( 'view user profiles' ) true to access $userRecordUrl
         // but this is currently returning false regardless of permission set for the role. dgg
         if ($config->userSystem->is_drupal == '1' && ($session->get('userID') == $this->_contactId || CRM_Core_Permission::check('administer users'))) {
             $userRecordUrl = CRM_Utils_System::url('user/' . $uid);
         } elseif ($config->userFramework == 'Joomla') {
             $userRecordUrl = NULL;
             // if logged in user is super user, then he can view other users joomla profile
             if (JFactory::getUser()->authorise('core.admin')) {
                 $userRecordUrl = $config->userFrameworkBaseURL . "index.php?option=com_users&view=user&task=user.edit&id=" . $uid;
             } elseif ($session->get('userID') == $this->_contactId) {
                 $userRecordUrl = $config->userFrameworkBaseURL . "index.php?option=com_admin&view=profile&layout=edit&id=" . $uid;
             }
         } else {
             $userRecordUrl = NULL;
         }
         $this->assign('userRecordUrl', $userRecordUrl);
         $this->assign('userRecordId', $uid);
     } elseif ($config->userSystem->is_drupal == '1' && CRM_Core_Permission::check('administer users') || $config->userFramework == 'Joomla' && JFactory::getUser()->authorise('core.create', 'com_users')) {
         $userAddUrl = CRM_Utils_System::url('civicrm/contact/view/useradd', 'reset=1&action=add&cid=' . $this->_contactId);
         $this->assign('userAddUrl', $userAddUrl);
     }
     if (CRM_Core_Permission::check('access Contact Dashboard')) {
         $dashboardURL = CRM_Utils_System::url('civicrm/user', "reset=1&id={$this->_contactId}");
         $this->assign('dashboardURL', $dashboardURL);
     }
     if ($contactType == 'Organization' && CRM_Core_Permission::check('administer Multiple Organizations') && CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MULTISITE_PREFERENCES_NAME, 'is_enabled')) {
         //check is any relationship between the organization and groups
         $groupOrg = CRM_Contact_BAO_GroupOrganization::hasGroupAssociated($this->_contactId);
         if ($groupOrg) {
             $groupOrganizationUrl = CRM_Utils_System::url('civicrm/group', "reset=1&oid={$this->_contactId}");
             $this->assign('groupOrganizationUrl', $groupOrganizationUrl);
         }
     }
 }