* @return array|int $values
* the relevant data object values for the contact or the total count when $count is TRUE
*/
- public static function &getContactGroup(
+ public static function getContactGroup(
$contactId,
$status = NULL,
$numGroupContact = NULL,
civicrm_subscription_history.method as method';
}
- $where = " WHERE contact_a.id = %1 AND civicrm_group.is_active = 1";
+ $where = " WHERE contact_a.id = %1 AND civicrm_group.is_active = 1 AND saved_search_id IS NULL";
if ($excludeHidden) {
$where .= " AND civicrm_group.is_hidden = 0 ";
$from = CRM_Contact_BAO_Query::fromClause($tables);
- //CRM-16945: seems hackish but as per CRM-16483 of using group criteria for Search Builder it is mandatory
- //to include group_contact_cache clause when group table is present, so following code remove duplicacy
- $from = str_replace("OR civicrm_group.id = civicrm_group_contact_cache.group_id", 'AND civicrm_group.saved_search_id IS NULL', $from);
-
$where .= " AND $permission ";
if ($onlyPublicGroups) {
}
elseif ($name === 'groups') {
$this->_useGroupBy = TRUE;
- $this->_select[$name] = "GROUP_CONCAT(DISTINCT(civicrm_group.title)) as groups";
+ // Duplicates will be created here but better to sort them out in php land.
+ $this->_select[$name] = "
+ CONCAT_WS(',',
+ GROUP_CONCAT(DISTINCT IF(civicrm_group_contact.status = 'Added', civicrm_group_contact.group_id, '')),
+ GROUP_CONCAT(DISTINCT civicrm_group_contact_cache.group_id)
+ )
+ as groups";
$this->_element[$name] = 1;
- $this->_tables['civicrm_group'] = 1;
+ $this->_tables['civicrm_group_contact'] = 1;
+ $this->_tables['civicrm_group_contact_cache'] = 1;
+ $this->_pseudoConstantsSelect["{$name}"] = array(
+ 'pseudoField' => "groups",
+ 'idCol' => "groups",
+ );
}
elseif ($name === 'notes') {
// if note field is subject then return subject else body of the note
$this->_paramLookup['group'][0][1] = key($value);
}
+ // Presumably the lines below come into manage groups screen.
// make sure there is only one element
// this is used when we are running under smog and need to know
// how the contact was added (CRM-1203)
);
}
- // add group_contact and group_contact_cache table if group table is present
- if (!empty($tables['civicrm_group'])) {
- if (empty($tables['civicrm_group_contact'])) {
- $tables['civicrm_group_contact'] = " LEFT JOIN civicrm_group_contact ON civicrm_group_contact.contact_id = contact_a.id AND civicrm_group_contact.status = 'Added' ";
- }
- if (empty($tables['civicrm_group_contact_cache'])) {
- $tables['civicrm_group_contact_cache'] = " LEFT JOIN civicrm_group_contact_cache ON civicrm_group_contact_cache.contact_id = contact_a.id ";
- }
- }
-
// add group_contact and group table is subscription history is present
if (!empty($tables['civicrm_subscription_history']) && empty($tables['civicrm_group'])) {
$tables = array_merge(array(
continue;
case 'civicrm_group':
- $from .= " $side JOIN civicrm_group ON (civicrm_group.id = civicrm_group_contact.group_id OR civicrm_group.id = civicrm_group_contact_cache.group_id) ";
+ $from .= " $side JOIN civicrm_group ON civicrm_group.id = civicrm_group_contact.group_id ";
continue;
case 'civicrm_group_contact':
public static function getQuery($params = NULL, $returnProperties = NULL, $count = FALSE) {
$query = new CRM_Contact_BAO_Query($params, $returnProperties);
list($select, $from, $where, $having) = $query->query();
+ $groupBy = ($query->_useGroupBy) ? 'GROUP BY contact_a.id' : '';
- return "$select $from $where $having";
+ return "$select $from $where $groupBy $having";
}
/**
if (is_object($dao) && property_exists($dao, $value['idCol'])) {
$val = $dao->$value['idCol'];
+ if ($key == 'groups') {
+ $dao->groups = $this->convertGroupIDStringToLabelString($dao, $val);
+ return;
+ }
if (CRM_Utils_System::isNull($val)) {
$dao->$key = NULL;
return array($order, $additionalFromClause);
}
+ /**
+ * Convert a string of group IDs to a string of group labels.
+ *
+ * The original string may include duplicates and groups the user does not have
+ * permission to see.
+ *
+ * @param CRM_Core_DAO $dao
+ * @param string $val
+ *
+ * @return string
+ */
+ public function convertGroupIDStringToLabelString(&$dao, $val) {
+ $groupIDs = explode(',', $val);
+
+ // The pseudoConstant function does not actually cache.
+ static $allGroups;
+ if (!$allGroups) {
+ $allGroups = CRM_Core_PseudoConstant::group();
+ }
+ // Note that groups that the user does not have permission to will be excluded (good).
+ $groups = array_intersect_key($allGroups, array_flip($groupIDs));
+ return implode(', ', $groups);
+ }
+
}
// Refresh the cache for test purposes. It would be better to alter to alter the GroupContact add function to add contacts to the cache.
CRM_Contact_BAO_GroupContactCache::remove($groupID, FALSE);
- $query = new CRM_Contact_BAO_Query(
+
+ $sql = CRM_Contact_BAO_Query::getQuery(
array(array('group', 'IN', array($groupID), 0, 0)),
array('contact_id')
);
- $sql = $query->query();
- $queryString = implode(' ', $sql);
- $dao = CRM_Core_DAO::executeQuery($queryString);
+ $dao = CRM_Core_DAO::executeQuery($sql);
$this->assertEquals(3, $dao->N);
- $this->assertFalse(strstr(implode(' ', $sql), ' OR '));
+ $this->assertFalse(strstr($sql, ' OR '));
+
+ $sql = CRM_Contact_BAO_Query::getQuery(
+ array(array('group', 'IN', array($groupID), 0, 0)),
+ array('contact_id' => 1, 'group' => 1)
+ );
+
+ $dao = CRM_Core_DAO::executeQuery($sql);
+ $this->assertEquals(3, $dao->N);
+ $this->assertFalse(strstr($sql, ' OR '), 'Query does not include or');
+ while ($dao->fetch()) {
+ $this->assertTrue(($dao->groups == $groupID || $dao->groups == ',' . $groupID), $dao->groups . ' includes ' . $groupID);
+ }
}
}