From: Coleman Watts Date: Sun, 10 May 2015 01:35:58 +0000 (-0400) Subject: CRM-16483 - Fix search builder groups operators X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=d79d2a59f03f41d2ca0972de16e1deb2f060a760;p=civicrm-core.git CRM-16483 - Fix search builder groups operators --- diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index ef207bbb05..a17756fa77 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -2804,13 +2804,19 @@ class CRM_Contact_BAO_Query { $this->_useDistinct = TRUE; } - $groupNames = CRM_Core_PseudoConstant::group(); - $groupIds = implode(',', array_keys($value)); + // Replace pseudo operators from search builder + $op = str_replace('EMPTY', 'NULL', $op); + $groupNames = CRM_Core_PseudoConstant::group(); + $groupIds = ''; $names = array(); - foreach ($value as $id => $dontCare) { - if (array_key_exists($id, $groupNames) && $dontCare) { - $names[] = $groupNames[$id]; + + if ($value) { + $groupIds = implode(',', array_keys($value)); + foreach ($value as $id => $dontCare) { + if (array_key_exists($id, $groupNames) && $dontCare) { + $names[] = $groupNames[$id]; + } } } @@ -2855,19 +2861,36 @@ class CRM_Contact_BAO_Query { if (!$skipGroup) { $gcTable = "`civicrm_group_contact-{$groupIds}`"; - $this->_tables[$gcTable] = $this->_whereTables[$gcTable] = " LEFT JOIN civicrm_group_contact {$gcTable} ON ( contact_a.id = {$gcTable}.contact_id AND {$gcTable}.group_id $op ( $groupIds ) )"; + $joinClause = array("contact_a.id = {$gcTable}.contact_id"); + if ($groupIds && ($op == 'IN' || $op == 'NOT IN')) { + $joinClause[] = "{$gcTable}.group_id IN ( $groupIds )"; + } + // For NOT IN we join on groups the contact IS in, then exclude them in the where clause + if ($statii && $op == 'NOT IN') { + $joinClause[] = "{$gcTable}.status IN (" . implode(', ', $statii) . ")"; + } + $this->_tables[$gcTable] = $this->_whereTables[$gcTable] = " LEFT JOIN civicrm_group_contact {$gcTable} ON (" . implode(' AND ', $joinClause) . ")"; } - $qill = ts('Contacts %1', array(1 => $op)); + if ($op == 'IN') { + $qill = ts('In group'); + } + else { + $qill = ts('Groups %1', array(1 => $op)); + } $qill .= ' ' . implode(' ' . ts('or') . ' ', $names); $groupClause = NULL; if (!$skipGroup) { - $groupClause = "{$gcTable}.group_id $op ( $groupIds )"; - if (!empty($statii)) { + $groupClause = "{$gcTable}.group_id $op" . ($groupIds ? " ( $groupIds ) " : ''); + if (!empty($statii) && $groupIds) { $groupClause .= " AND {$gcTable}.status IN (" . implode(', ', $statii) . ")"; - $qill .= " " . ts('AND') . " " . ts('Group Status') . ' - ' . implode(' ' . ts('or') . ' ', $statii); + $qill .= " " . ($op == 'NOT IN' ? ts('WHERE') : ts('AND')) . " " . ts('Group Status') . ' - ' . implode(' ' . ts('or') . ' ', $statii); + } + // For NOT IN op, params were set in the join + if ($op == 'NOT IN') { + $groupClause = "{$gcTable}.group_id IS NULL"; } } @@ -2895,7 +2918,7 @@ class CRM_Contact_BAO_Query { */ public function getGroupsFromTypeCriteria($value) { $groupIds = array(); - foreach ($value as $groupTypeValue) { + foreach ((array) $value as $groupTypeValue) { $groupList = CRM_Core_PseudoConstant::group($groupTypeValue); $groupIds = ($groupIds + $groupList); } @@ -2911,7 +2934,7 @@ class CRM_Contact_BAO_Query { */ public function savedSearch(&$values) { list($name, $op, $value, $grouping, $wildcard) = $values; - return $this->addGroupContactCache(array_keys($value)); + return $this->addGroupContactCache(array_keys((array) $value)); } /** diff --git a/CRM/Core/BAO/Mapping.php b/CRM/Core/BAO/Mapping.php index 0cb7fb353a..2ea67c4bec 100644 --- a/CRM/Core/BAO/Mapping.php +++ b/CRM/Core/BAO/Mapping.php @@ -1038,7 +1038,7 @@ class CRM_Core_BAO_Mapping extends CRM_Core_DAO_Mapping { // CRM-14563: we store checkbox, multi-select and adv-multi select custom field using separator, hence it // needs special handling. - if ($cfID = CRM_Core_BAO_CustomField::getKeyID($v[1])) { + if ($cfID = CRM_Core_BAO_CustomField::getKeyID(CRM_Utils_Array::value(1, $v))) { $isCustomField = TRUE; $customFieldType = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', $cfID, 'html_type'); $specialHTMLType = array(