$group->find(TRUE);
if (!isset($group->saved_search_id)) {
- $tbName = "`civicrm_group_contact-{$groupId}`";
+ $tbName = "civicrm_group_contact";
// CRM-17254 don't retrieve extra fields if contact_id is specifically requested
// as this will add load to an intentionally light query.
// ideally this code would be removed as it appears to be to support CRM-1203
// check for both id and contact_id
if ($this->_params[$id][0] == 'id' || $this->_params[$id][0] == 'contact_id') {
$this->_where[0][] = self::buildClause("contact_a.id", $this->_params[$id][1], $this->_params[$id][2]);
+ $field = CRM_Utils_Array::value('id', $this->_fields);
+ list($qillop, $qillVal) = CRM_Contact_BAO_Query::buildQillForFieldValue(
+ 'CRM_Contact_BAO_Contact',
+ "contact_a.id",
+ $this->_params[$id][2],
+ $this->_params[$id][1]
+ );
+ $this->_qill[0][] = ts("%1 %2 %3", [
+ 1 => $field['title'],
+ 2 => $qillop,
+ 3 => $qillVal
+ ]);
}
else {
$this->whereClauseSingle($this->_params[$id], $apiEntity);
$setTables = TRUE;
- $locationType = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
+ $locationType = CRM_Core_DAO_Address::buildOptions('location_type_id', 'validate');
if (isset($locType[1]) && is_numeric($locType[1])) {
$lType = $locationType[$locType[1]];
}
$op = strpos($op, 'IN') ? $op : ($op == '!=') ? 'NOT IN' : 'IN';
}
$groupIds = implode(',', (array) $regularGroupIDs);
- $gcTable = "`civicrm_group_contact-{$groupIds}`";
+ $gcTable = "`civicrm_group_contact-" . uniqid() . "`";
$joinClause = array("contact_a.id = {$gcTable}.contact_id");
if (strpos($op, 'IN') !== FALSE) {
}
//CRM-19589: contact(s) removed from a Smart Group, resides in civicrm_group_contact table
- if (count($smartGroupIDs)) {
- $groupClause[] = " ( " . $this->addGroupContactCache($smartGroupIDs, NULL, "contact_a", $op) . " ) ";
+ $groupContactCacheClause = '';
+ if (count($smartGroupIDs) || empty($value)) {
+ $gccTableAlias = "civicrm_group_contact_cache";
+ $groupContactCacheClause = $this->addGroupContactCache($smartGroupIDs, $gccTableAlias, "contact_a", $op);
+ if (!empty($groupContactCacheClause)) {
+ if ($isNotOp) {
+ $groupIds = implode(',', (array) $smartGroupIDs);
+ $gcTable = "civicrm_group_contact";
+ $joinClause = array("contact_a.id = {$gcTable}.contact_id");
+ $this->_tables[$gcTable] = $this->_whereTables[$gcTable] = " LEFT JOIN civicrm_group_contact {$gcTable} ON (" . implode(' AND ', $joinClause) . ")";
+ if (strpos($op, 'IN') !== FALSE) {
+ $groupClause[] = "{$gcTable}.group_id $op ( $groupIds ) AND {$gccTableAlias}.group_id IS NULL";
+ }
+ else {
+ $groupClause[] = "{$gcTable}.group_id $op $groupIds AND {$gccTableAlias}.group_id IS NULL";
+ }
+ }
+ $groupClause[] = " ( {$groupContactCacheClause} ) ";
+ }
}
$and = ($op == 'IS NULL') ? ' AND ' : ' OR ';
- $this->_where[$grouping][] = ' ( ' . implode($and, $groupClause) . ' ) ';
+ if (!empty($groupClause)) {
+ $this->_where[$grouping][] = ' ( ' . implode($and, $groupClause) . ' ) ';
+ }
list($qillop, $qillVal) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Contact_DAO_Group', 'id', $value, $op);
$this->_qill[$grouping][] = ts("Group(s) %1 %2", array(1 => $qillop, 2 => $qillVal));
*
* @return string WHERE clause component for smart group criteria.
*/
- public function addGroupContactCache($groups, $tableAlias = NULL, $joinTable = "contact_a", $op, $joinColumn = 'id') {
+ public function addGroupContactCache($groups, $tableAlias, $joinTable = "contact_a", $op, $joinColumn = 'id') {
$isNullOp = (strpos($op, 'NULL') !== FALSE);
$groupsIds = $groups;
+
+ $operator = ['=' => 'IN', '!=' => 'NOT IN'];
+ if (!empty($operator[$op]) && is_array($groups)) {
+ $op = $operator[$op];
+ }
if (!$isNullOp && !$groups) {
return NULL;
}
CRM_Contact_BAO_GroupContactCache::load($group);
}
}
- if ($group->N == 0) {
+ if ($group->N == 0 && $op != 'NOT IN') {
return NULL;
}
- if (!$tableAlias) {
- $tableAlias = "`civicrm_group_contact_cache_";
- $tableAlias .= ($isNullOp) ? "a`" : implode(',', (array) $groupsIds) . "`";
- }
-
$this->_tables[$tableAlias] = $this->_whereTables[$tableAlias] = " LEFT JOIN civicrm_group_contact_cache {$tableAlias} ON {$joinTable}.{$joinColumn} = {$tableAlias}.contact_id ";
+
+ if ($op == 'NOT IN') {
+ return "{$tableAlias}.contact_id NOT IN (SELECT contact_id FROM civicrm_group_contact_cache cgcc WHERE cgcc.group_id IN ( " . implode(',', (array) $groupsIds) . " ) )";
+ }
return self::buildClause("{$tableAlias}.group_id", $op, $groups, 'Int');
}
* @param array $values
*/
public function street_address(&$values) {
- list($name, $op, $value, $grouping, $wildcard) = $values;
+ list($name, $op, $value, $grouping) = $values;
if (!$op) {
$op = 'LIKE';
$name = $targetName[4] ? "%$name%" : $name;
$this->_where[$grouping][] = "contact_b_log.sort_name LIKE '%$name%'";
$this->_tables['civicrm_log'] = $this->_whereTables['civicrm_log'] = 1;
- $this->_qill[$grouping][] = ts('Modified By') . " $name";
+ $fieldTitle = ts('Added By');
+ foreach ($this->_params as $params) {
+ if ($params[0] == 'log_date') {
+ if ($params[2] == 2) {
+ $fieldTitle = ts('Modified By');
+ }
+ break;
+ }
+ }
+ list($qillop, $qillVal) = self::buildQillForFieldValue(NULL, 'changed_by', $name, 'LIKE');
+ $this->_qill[$grouping][] = ts("%1 %2 %3", [
+ 1 => $fieldTitle,
+ 2 => $qillop,
+ 3 => $qillVal,
+ ]);
}
/**
* @param $values
*/
public function privacy(&$values) {
- list($name, $op, $value, $grouping, $wildcard) = $values;
+ list($name, $op, $value, $grouping) = $values;
//fixed for profile search listing CRM-4633
if (strpbrk($value, "[")) {
$value = "'{$value}'";
// MySQL expect the columns present in GROUP BY, must be present in SELECT clause and that results into error, needless to have other columns.
// 2. When GROUP BY columns are present then disable FGB otherwise it demands to add ORDER BY columns in GROUP BY and eventually in SELECT
// clause. This will impact the search query output.
- $disableFullGroupByMode = ($sortByChar || !empty($groupByCols));
+ $disableFullGroupByMode = ($sortByChar || !empty($groupByCols) || $groupContacts);
if ($disableFullGroupByMode) {
CRM_Core_DAO::disableFullGroupByMode();
$select .= sprintf(", (%s) AS _wgt", $this->createSqlCase('contact_a.id', $cids));
$where .= sprintf(' AND contact_a.id IN (%s)', implode(',', $cids));
$order = 'ORDER BY _wgt';
- $groupBy = '';
+ $groupBy = $this->_useGroupBy ? ' GROUP BY contact_a.id' : '';
$limit = '';
$query = "$select $from $where $groupBy $order $limit";