Compare commits

...

11 Commits

4 changed files with 145 additions and 54 deletions

View File

@ -59,21 +59,39 @@ class CRM_ConstituentsOnly_BAO_ConstituentsOnly {
*
* @return string
*/
public static function getConstituentSql($contactIds) {
return "
SELECT MAX(contact_a.id) AS contact_id, cc.id AS og_contact_id
public static function getConstituentSql($contactIds, $returnArray = FALSE) {
$sql[] = "
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 (" . implode(',', $contactIds) . ")
AND cc.do_not_trade = 1
GROUP BY cc.id
INNER JOIN civicrm_relationship cr
ON (cr.contact_id_a = 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_b = cc.id)
AND cc.id IN (" . implode(',', $contactIds) . ")
AND cc.do_not_trade = 1
GROUP BY cc.id";
$sql[] = "
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_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 cc.id IN (" . implode(',', $contactIds) . ")
AND cc.do_not_trade = 1
GROUP BY cc.id";
if ($returnArray) {
return $sql;
}
return "
SELECT contact_id, MAX(og_contact_id) AS og_contact_id, MAX(og_sort_name) AS og_sort_name
FROM (" . implode(' UNION ', $sql) . ") AS temp GROUP BY contact_id
";
}
@ -89,24 +107,15 @@ class CRM_ConstituentsOnly_BAO_ConstituentsOnly {
$sqls[] = "CREATE TEMPORARY TABLE quick_temp_table_1
{$joinQuery}
";
$queries = self::getConstituentSql(["SELECT id FROM quick_temp_table_1"], TRUE);
$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
{$queries[0]}
";
$sqls[] = "
INSERT INTO quick_temp_table_2
{$queries[1]}
";
foreach ($sqls as $sql) {
CRM_Core_DAO::executeQuery($sql);
}
@ -147,7 +156,6 @@ class CRM_ConstituentsOnly_BAO_ConstituentsOnly {
public static function updateSearchRows($rows, $headers) {
$contactIds = array_keys($rows);
$sql = self::getConstituentSql($contactIds);
$result = CRM_Core_DAO::executeQuery($sql);
$relContactIds = [];
@ -161,22 +169,29 @@ class CRM_ConstituentsOnly_BAO_ConstituentsOnly {
$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'])) {
$qfKey = $_REQUEST['qfKey'];
$formValuesFromSession = CRM_Core_Session::singleton()->get("CRM_Contact_Controller_Search_{$qfKey}");
$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'])) {
foreach ($headers as $header) {
if (!empty($header['sort'])) {
$returnProperties[$header['sort']] = 1;
$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;
}
$returnProperties['contact_sub_type'] = 1;
$returnProperties['contact_type'] = 1;
}
$queryParams = CRM_Contact_BAO_Query::convertFormValues($formValues);
$selector = new CRM_Contact_Selector(
'',
@ -190,8 +205,34 @@ class CRM_ConstituentsOnly_BAO_ConstituentsOnly {
if (empty($newRows[$cid])) {
continue;
}
$newRows[$cid]['sort_name'] .= "({$rows[$ogContactId]['sort_name']})";
$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;

View File

@ -13,6 +13,7 @@ class CRM_ConstituentsOnly_BAO_Query extends CRM_Contact_BAO_Query_Interface {
*
*/
public function select(&$query) {
CRM_Core_Session::singleton()->set('return_properties_search', $query->_returnProperties);
// hack for profile search
$url = CRM_Utils_Array::value('q', $_GET);
if (in_array($url, ['civicrm/profile', 'civicrm/contact/search/builder'])) {
@ -44,18 +45,41 @@ class CRM_ConstituentsOnly_BAO_Query extends CRM_Contact_BAO_Query_Interface {
return;
}
$url = CRM_Utils_Array::value('q', $_GET);
if (strpos($url, 'civicrm/contact/') === FALSE) {
return;
}
if (!empty($query->_paramLookup['ignore_constituent_search'])) {
$query->_qill[0][] = ts("Include non-constituents in this search");
return;
}
if (CRM_Utils_Array::value('civicrm_contact', $query->_tables) && empty($query->_paramLookup['do_not_trade'])) {
$query->_where[0][] = "
IF (contact_a.do_not_trade = 1,
CASE
WHEN (cr.id IS NULL OR cc1.is_deleted = 1 OR cc1.do_not_trade = 1)
THEN 0
ELSE 1
END,
1)
contact_a.id NOT IN (SELECT id FROM (
SELECT contact_a.id
FROM civicrm_contact contact_a
LEFT JOIN civicrm_relationship cr
ON (cr.contact_id_a = contact_a.id)
AND cr.is_active = 1
LEFT JOIN civicrm_contact cc1
ON (cr.contact_id_a = cc1.id)
WHERE contact_a.do_not_trade = 1 AND (cr.id IS NULL OR cc1.is_deleted = 1 OR cc1.do_not_trade = 1)
AND contact_a.id <> cc1.id
UNION
SELECT contact_a.id
FROM civicrm_contact contact_a
LEFT JOIN civicrm_relationship cr
ON (cr.contact_id_b = contact_a.id)
AND cr.is_active = 1
LEFT JOIN civicrm_contact cc1
ON (cr.contact_id_b = cc1.id)
WHERE contact_a.do_not_trade = 1 AND (cr.id IS NULL OR cc1.is_deleted = 1 OR cc1.do_not_trade = 1)
AND contact_a.id <> cc1.id
) AS temp GROUP BY id
)
";
$query->_tables['civicrm_do_not_trade'] = 1;
$query->_whereTables['civicrm_do_not_trade'] = 1;
}
}
@ -66,13 +90,6 @@ class CRM_ConstituentsOnly_BAO_Query extends CRM_Contact_BAO_Query_Interface {
*
*/
public function from($name, $mode, $side) {
if ($name == 'civicrm_do_not_trade') {
return " LEFT JOIN civicrm_relationship cr
ON (cr.contact_id_a = contact_a.id OR cr.contact_id_b = contact_a.id)
LEFT JOIN civicrm_contact cc1
ON (cr.contact_id_a = cc1.id OR cr.contact_id_b = cc1.id)
AND contact_a.id <> cc1.id";
}
}
/**

View File

@ -190,6 +190,26 @@ function constituentsonly_civicrm_selectWhereClause($entity, &$clauses) {
*/
function constituentsonly_civicrm_searchColumns($objectName, &$headers, &$rows, &$selector) {
if (in_array($objectName, ['contact']) && !empty($rows)) {
if (!empty($_POST['ignore_constituent_search'])) {
return;
}
$rows = CRM_ConstituentsOnly_BAO_ConstituentsOnly::updateSearchRows($rows, $headers);
}
}
/**
* Implements hook_civicrm_buildForm().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_buildForm
*/
function constituentsonly_civicrm_buildForm($formName, &$form) {
if ('CRM_Contact_Form_Search_Advanced' == $formName
&& !($form->getVar('_action') == CRM_Core_Action::DELETE)
&& empty($form->_searchPane)
) {
$form->addElement('checkbox', 'ignore_constituent_search', ts('Include non-constituents'));
CRM_Core_Region::instance('page-body')->add(array(
'template' => 'CRM/common.tpl',
));
}
}

13
templates/CRM/common.tpl Normal file
View File

@ -0,0 +1,13 @@
<table class="ignore_constituent_search-block">
<tr class="ignore_constituent_search">
<td>{$form.ignore_constituent_search.html} {$form.ignore_constituent_search.label}</td>
</tr>
</table>
{literal}
<script type="text/javascript">
CRM.$(function($) {
$('#search-settings td.adv-search-top-submit').before($('table.ignore_constituent_search-block tr td'));
});
</script>
{/literal}