X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FContact%2FBAO%2FQuery.php;h=3c99db2d6a58ce2a766d068c65d66b1729753acc;hb=96b84142a93631de44c52e5f533201ac0a7adb14;hp=13efcf013d302a68b2b85a7ea0111da874929017;hpb=0f0b0ad290e34b192018b37b7f7cf52766a55715;p=civicrm-core.git diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index 13efcf013d..3c99db2d6a 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -3,7 +3,7 @@ +--------------------------------------------------------------------+ | CiviCRM version 5 | +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2018 | + | Copyright CiviCRM LLC (c) 2004-2019 | +--------------------------------------------------------------------+ | This file is a part of CiviCRM. | | | @@ -28,7 +28,7 @@ /** * * @package CRM - * @copyright CiviCRM LLC (c) 2004-2018 + * @copyright CiviCRM LLC (c) 2004-2019 */ /** @@ -1427,7 +1427,7 @@ class CRM_Contact_BAO_Query { $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 @@ -2039,6 +2039,18 @@ class CRM_Contact_BAO_Query { // 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); @@ -2130,7 +2142,7 @@ class CRM_Contact_BAO_Query { $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]]; } @@ -3012,7 +3024,7 @@ class CRM_Contact_BAO_Query { $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) { @@ -3033,12 +3045,31 @@ class CRM_Contact_BAO_Query { } //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)); @@ -3074,9 +3105,14 @@ class CRM_Contact_BAO_Query { * * @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; } @@ -3106,16 +3142,15 @@ WHERE $smartGroupClause 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'); } @@ -3528,7 +3563,7 @@ WHERE $smartGroupClause * @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'; @@ -3864,7 +3899,21 @@ WHERE $smartGroupClause $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, + ]); } /** @@ -3921,7 +3970,7 @@ WHERE $smartGroupClause * @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}'"; @@ -4881,7 +4930,7 @@ civicrm_relationship.start_date > {$today} // 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(); @@ -4961,7 +5010,7 @@ civicrm_relationship.start_date > {$today} $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";