cc.id AND cc.id IN (" . implode(',', $contactIds) . ") AND cc.do_not_trade = 1 GROUP BY cc.id UNION SELECT MAX(contact_a.id) AS contact_id, cc.id AS og_contact_id FROM civicrm_contact contact_a INNER JOIN civicrm_relationship cr ON (cr.contact_id_b = contact_a.id) AND contact_a.is_deleted = 0 AND (contact_a.do_not_trade = 0 OR contact_a.do_not_trade IS NULL) AND cr.is_active = 1 INNER JOIN civicrm_contact cc ON (cr.contact_id_a = cc.id) AND contact_a.id <> cc.id AND cc.id IN (" . implode(',', $contactIds) . ") AND cc.do_not_trade = 1 GROUP BY cc.id ) AS temp GROUP BY contact_id "; } /** * Alter Quick search query. * * @param string $query * * @return string */ public static function getQuickSearchQuery($query) { $joinQuery = str_replace('WHERE ', 'WHERE (cc.do_not_trade = 1) AND ', $query); $sqls[] = "CREATE TEMPORARY TABLE quick_temp_table_1 {$joinQuery} "; $sqls[] = " CREATE TEMPORARY TABLE quick_temp_table_2 SELECT MAX(contact_a.id) AS contact_id, cc.id AS og_contact_id, MAX(cc.sort_name) AS og_sort_name FROM civicrm_contact contact_a INNER JOIN civicrm_relationship cr ON (cr.contact_id_a = contact_a.id OR cr.contact_id_b = contact_a.id) AND contact_a.is_deleted = 0 AND (contact_a.do_not_trade = 0 OR contact_a.do_not_trade IS NULL) AND cr.is_active = 1 INNER JOIN civicrm_contact cc ON (cr.contact_id_a = cc.id OR cr.contact_id_b = cc.id) AND contact_a.id <> cc.id AND cc.id IN (SELECT id FROM quick_temp_table_1) AND cc.do_not_trade = 1 GROUP BY cc.id "; foreach ($sqls as $sql) { CRM_Core_DAO::executeQuery($sql); } $startPoint = stripos($query, 'from'); $endPoint = stripos($query, 'union'); $firstQuery = substr($query, $startPoint, ($endPoint - $startPoint)); $firstQuery = substr($firstQuery, stripos($firstQuery, 'select')); $firstQuery = substr($firstQuery, 0, stripos($firstQuery, 'where')); $firstQuery = str_replace( 'sort_name, ', "CONCAT(cc.sort_name, ' (', og_sort_name, ')'), ", $firstQuery ); $strToReplace = " UNION ( $firstQuery INNER JOIN quick_temp_table_2 temp ON temp.contact_id = cc.id ) ) t "; $replace = 'WHERE (cc.do_not_trade IS NULL OR cc.do_not_trade = 0) AND '; $query = str_replace('WHERE ', $replace, $query); $query = str_replace(') t', $strToReplace, $query); return $query; } /** * Rebuild search result rows. * * @param array $rows * @param array $headers * * @return array */ public static function updateSearchRows($rows, $headers) { $contactIds = array_keys($rows); $sql = self::getConstituentSql($contactIds); $result = CRM_Core_DAO::executeQuery($sql); $relContactIds = []; while ($result->fetch()) { $relContactIds[$result->og_contact_id] = $result->contact_id; } if (!empty($relContactIds)) { $formValues = ['contact_id' => $relContactIds]; $url = CRM_Utils_Array::value('q', $_GET); $returnProperties = NULL; $request = $_REQUEST; $qfKey = $_REQUEST['qfKey']; $cache = "CRM_Contact_Controller_Search_{$qfKey}"; if (!empty($_REQUEST['has_js'])) { $formValuesFromSession = CRM_Core_Session::singleton()->get($cache); if (!empty($formValuesFromSession['formValues'])) { $request = $formValuesFromSession['formValues']; } } if (in_array($url, ['civicrm/contact/search/builder']) || !empty($request['uf_group_id'])) { $returnProperties = CRM_Core_Session::singleton()->get('return_properties_search'); if (!empty($returnProperties)) { foreach ($headers as $header) { if (!empty($header['sort'])) { $headerName = str_replace('`', '', $header['sort']); $returnProperties[$headerName] = 1; } } $returnProperties['contact_sub_type'] = 1; $returnProperties['contact_type'] = 1; } } $queryParams = CRM_Contact_BAO_Query::convertFormValues($formValues); $selector = new CRM_Contact_Selector( '', $queryParams, $queryParams, $returnProperties ); list($select, $from, $where, $having) = $selector->getQuery()->query(); $newRows = $selector->getRows('', '', '', ''); foreach ($relContactIds as $ogContactId => $cid) { if (empty($newRows[$cid])) { continue; } $newRows[$cid]['sort_name'] .= " ({$rows[$ogContactId]['sort_name']})"; $rows[$ogContactId] = $newRows[$cid]; $prevCacheKey = "civicrm search {$qfKey}"; $exists = CRM_Core_DAO::singleValueQuery( "SELECT count(id) FROM civicrm_prevnext_cache WHERE ( entity_id1 = %1 OR entity_id2 = %1 ) AND cacheKey = %2 AND entity_table = 'civicrm_contact' ", [ 1 => [$cid, 'Integer'], 2 => [$prevCacheKey, 'String'], ] ); if (!$exists) { $prevCache = [ "('civicrm_contact'", "'{$cid}'", "'{$cid}'", "'{$prevCacheKey}'", "'" . $newRows[$cid]['sort_name'] . "')", ]; CRM_Core_BAO_PrevNextCache::setItem($prevCache); } CRM_Core_BAO_PrevNextCache::deleteItem($ogContactId, $prevCacheKey); } } return $rows; } /** * Rebuild report result rows. * * @param array $rows * @param CRM_Core_Report $object * * @return array */ public static function updateReportRows($rows, &$object) { if (property_exists($object, '_donotTradeRowBuilding') && $object->_donotTradeRowBuilding ) { return $rows; } $contactIds = []; foreach ($rows as $id => $row) { if (CRM_Utils_Array::value( 'civicrm_contact_do_not_trade_alter', $row) == 'Yes' ) { $contactIds[$id] = $row['civicrm_contact_id']; } } if (empty($contactIds)) { return $rows; } $sql = self::getConstituentSql($contactIds); $result = CRM_Core_DAO::executeQuery($sql); $relContactIds = []; while ($result->fetch()) { $relContactIds[$result->og_contact_id] = $result->contact_id; } if (!empty($relContactIds)) { $object->_donotTradeRowBuilding = TRUE; $select = $object->getVar('_select'); $from = $object->getVar('_from'); $dbAliases = $object->getVar('_aliases'); $contactAlias = "`{$dbAliases['civicrm_contact']}`"; $query = " {$select} {$from} WHERE {$contactAlias}.id IN (" . implode(',', $relContactIds) . ") "; $newRows = []; $tempObj = $object; $tempObj->_columnHeaders = $object->_backupHeader; $tempObj->buildRows($query, $newRows); $tempObj->formatDisplay($newRows); foreach ($newRows as $id => $newRow) { $contactId = $newRow['civicrm_contact_id']; while (in_array($contactId, $relContactIds)) { $ogContactId = array_search($contactId, $relContactIds); $ogId = array_search($ogContactId, $contactIds); $newRow['civicrm_contact_sort_name'] .= " ({$rows[$ogId]['civicrm_contact_sort_name']})"; $rows[$ogId] = $newRow; unset($relContactIds[$ogContactId]); } } } return $rows; } /** * Update sql for report. * * @param CRM_Core_Report $object * */ public static function updateReportSql(&$object) { $where = $object->getVar('_where'); $sql = self::getCommonSql(); $dbAliases = $object->getVar('_aliases'); $contactAlias = "`{$dbAliases['civicrm_contact']}`"; $searchFrom = "{$contactAlias}.`do_not_trade` IS NULL OR ({$contactAlias}.`do_not_trade` = 0)"; $replaceFrom = "IF ( {$contactAlias}.`do_not_trade` = 1, {$contactAlias}.id IN ({$sql}), 1 )"; $where = str_replace($searchFrom, $replaceFrom, $where); $object->setVar('_where', $where); $object->_backupHeader = $object->getVar('_columnHeaders'); } }