<?php
/*
+--------------------------------------------------------------------+
- | CiviCRM version 4.5 |
+ | CiviCRM version 4.6 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2014 |
+--------------------------------------------------------------------+
class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
/**
- * class constructor
+ * Class constructor
*/
- function __construct() {
+ public function __construct() {
parent::__construct();
}
* @param array $params (reference ) an assoc array of name/value pairs
* @param array $defaults (reference ) an assoc array to hold the flattened values
*
- * @return object CRM_Contact_BAO_Group object
- * @access public
+ * @return CRM_Contact_BAO_Group object
* @static
*/
- static function retrieve(&$params, &$defaults) {
+ public static function retrieve(&$params, &$defaults) {
$group = new CRM_Contact_DAO_Group();
$group->copyValues($params);
if ($group->find(TRUE)) {
}
/**
- * Function to delete the group and all the object that connect to
+ * Delete the group and all the object that connect to
* this group. Incredibly destructive
*
* @param int $id group id
*
* @return null
- * @access public
* @static
*
*/
- static function discard($id) {
+ public static function discard($id) {
CRM_Utils_Hook::pre('delete', 'Group', $id, CRM_Core_DAO::$_nullArray);
$transaction = new CRM_Core_Transaction();
'is_enabled'
)) {
// clear any descendant groups cache if exists
- $finalGroups = CRM_Core_BAO_Cache::deleteGroup('descendant groups for an org');
+ CRM_Core_BAO_Cache::deleteGroup('descendant groups for an org');
}
// delete from group table
* Returns an array of the contacts in the given group.
*
*/
- static function getGroupContacts($id) {
+ public static function getGroupContacts($id) {
$params = array(array('group', 'IN', array($id => 1), 0, 0));
list($contacts, $_) = CRM_Contact_BAO_Query::apiQuery($params, array('contact_id'));
return $contacts;
/**
* Get the count of a members in a group with the specific status
*
- * @param int $id group id
- * @param enum $status status of members in group
+ * @param int $id group id
+ * @param enum|string $status status of members in group
+ *
+ * @param bool $countChildGroups
*
* @return int count of members in the group with above status
- * @access public
*/
- static function memberCount($id, $status = 'Added', $countChildGroups = FALSE) {
+ public static function memberCount($id, $status = 'Added', $countChildGroups = FALSE) {
$groupContact = new CRM_Contact_DAO_GroupContact();
$groupIds = array($id);
if ($countChildGroups) {
/**
* Get the list of member for a group id
*
- * @param int $lngGroupId this is group id
+ * @param int $groupID
+ * @param bool $useCache
*
- * @return array $aMembers this arrray contains the list of members for this group id
- * @access public
+ * @return array $aMembers this array contains the list of members for this group id
* @static
*/
- static function &getMember($groupID, $useCache = TRUE) {
+ public static function &getMember($groupID, $useCache = TRUE) {
$params = array(array('group', 'IN', array($groupID => 1), 0, 0));
$returnProperties = array('contact_id');
list($contacts, $_) = CRM_Contact_BAO_Query::apiQuery($params, $returnProperties, NULL, NULL, 0, 0, $useCache);
/**
* Returns array of group object(s) matching a set of one or Group properties.
*
- * @param array $param Array of one or more valid property_name=>value pairs.
- * Limits the set of groups returned.
- * @param array $returnProperties Which properties should be included in the returned group objects.
+ * @param array $params Limits the set of groups returned.
+ * @param array $returnProperties Which properties should be included in the returned group objects.
* (member_count should be last element.)
*
- * @return An array of group objects.
+ * @param null $sort
+ * @param null $offset
+ * @param null $rowCount
+ *
+ * @return array of group objects.
*
- * @access public
*
* @todo other BAO functions that use returnProperties (e.g. Query Objects) receive the array flipped & filled with 1s and
* add in essential fields (e.g. id). This should follow a regular pattern like the others
}
/**
- * make sure that the user has permission to access this group
+ * Make sure that the user has permission to access this group
*
* @param int $id the id of the object
*
* @return string the permission that the user has (or null)
- * @access public
* @static
*/
- static function checkPermission($id) {
+ public static function checkPermission($id) {
$allGroups = CRM_Core_PseudoConstant::allGroup();
$permissions = NULL;
* @param array $params Associative array of parameters
*
* @return object|null The new group BAO (if created)
- * @access public
* @static
*/
public static function &create(&$params) {
}
/**
- * given a saved search compute the clause and the tables
+ * Given a saved search compute the clause and the tables
* and store it for future use
*/
- function buildClause() {
+ public function buildClause() {
$params = array(array('group', 'IN', array($this->id => 1), 0, 0));
if (!empty($params)) {
* @param array $params Associative array of parameters
*
* @return object|null The new group BAO (if created)
- * @access public
* @static
*/
public static function createSmartGroup(&$params) {
}
/**
- * update the is_active flag in the db
+ * Update the is_active flag in the db
*
* @param int $id id of the database record
* @param boolean $isActive value we want to set the is_active field
* @return Object DAO object on sucess, null otherwise
* @static
*/
- static function setIsActive($id, $isActive) {
+ public static function setIsActive($id, $isActive) {
return CRM_Core_DAO::setFieldValue('CRM_Contact_DAO_Group', $id, 'is_active', $isActive);
}
/**
- * build the condition to retrieve groups.
+ * Build the condition to retrieve groups.
*
- * @param string $groupType type of group(Access/Mailing) OR the key of the group
- * @param boolen $excludeHidden exclude hidden groups.
+ * @param string $groupType type of group(Access/Mailing) OR the key of the group
+ * @param bool|\boolen $excludeHidden exclude hidden groups.
*
* @return string $condition
* @static
*/
- static function groupTypeCondition($groupType = NULL, $excludeHidden = TRUE) {
+ public static function groupTypeCondition($groupType = NULL, $excludeHidden = TRUE) {
$value = NULL;
if ($groupType == 'Mailing') {
$value = CRM_Core_DAO::VALUE_SEPARATOR . '2' . CRM_Core_DAO::VALUE_SEPARATOR;
return $condition;
}
+ /**
+ * Get permission relevant clauses
+ * CRM-12209
+ *
+ * @param bool $force
+ *
+ * @return array
+ */
+ public static function getPermissionClause($force = FALSE) {
+ static $clause = 1;
+ static $retrieved = FALSE;
+ if ((!$retrieved || $force ) && !CRM_Core_Permission::check('view all contacts') && !CRM_Core_Permission::check('edit all contacts')) {
+ //get the allowed groups for the current user
+ $groups = CRM_ACL_API::group(CRM_ACL_API::VIEW);
+ if (!empty($groups)) {
+ $groupList = implode(', ', array_values($groups));
+ $clause = "groups.id IN ( $groupList ) ";
+ }
+ else {
+ $clause = '1 = 0';
+ }
+ }
+ $retrieved = TRUE;
+ return $clause;
+ }
+
+ /**
+ * @return string
+ */
public function __toString() {
return $this->title;
}
* @param array $params ( reference ) an assoc array of name/value pairs
*
* @return array ( smartGroupId, ssId ) smart group id and saved search id
- * @access public
* @static
*/
- static function createHiddenSmartGroup($params) {
+ public static function createHiddenSmartGroup($params) {
$ssId = CRM_Utils_Array::value('saved_search_id', $params);
//add mapping record only for search builder saved search
* -page= offset
* @todo there seems little reason for the small number of functions that call this to pass in
* params that then need to be translated in this function since they are coding them when calling
- * @access public
*/
static public function getGroupListSelector(&$params) {
// format the params
if (!empty($groups)) {
foreach ($groups as $id => $value) {
$groupList[$id]['group_id'] = $value['id'];
+ $groupList[$id]['count'] = $value['count'];
$groupList[$id]['group_name'] = $value['title'];
- $groupList[$id]['class'] = implode(' ', $value['class']);
// append parent names if in search mode
if (empty($params['parent_id']) && !empty($value['parents'])) {
$title[] = $allGroups[$gId];
}
$groupList[$id]['group_name'] .= '<div class="crm-row-parent-name"><em>'.ts('Child of').'</em>: ' . implode(', ', $title) . '</div>';
- $groupList[$id]['class'] = in_array('disabled', $value['class']) ? 'disabled' : '';
+ $value['class'] = array_diff($value['class'], array('crm-row-parent'));
}
+ $value['class'][] = 'crm-entity';
+ $groupList[$id]['class'] = $value['id'] . ',' . implode(' ', $value['class']);
$groupList[$id]['group_description'] = CRM_Utils_Array::value('description', $value);
if (!empty($value['group_type'])) {
/**
* This function to get list of groups
*
- * @param array $params associated array for params
- * @access public
+ * @param array $params associated array for params
+ *
+ * @return array
*/
- static function getGroupList(&$params) {
+ public static function getGroupList(&$params) {
$config = CRM_Core_Config::singleton();
$whereClause = self::whereClause($params, FALSE);
$query = "
SELECT groups.*, createdBy.sort_name as created_by {$select}
FROM civicrm_group groups
- LEFT JOIN civicrm_contact createdBy
- ON createdBy.id = groups.created_id
- {$from}
+ LEFT JOIN civicrm_contact createdBy
+ ON createdBy.id = groups.created_id
+ {$from}
WHERE $whereClause {$where}
+ GROUP BY groups.id
{$orderBy}
{$limit}";
$links = self::actionLinks();
$allTypes = CRM_Core_OptionGroup::values('group_type');
- $values = array();
+ $values = $groupsToCount = array();
$visibility = CRM_Core_SelectValues::ufVisibility();
if ($permission) {
$newLinks = $links;
- $values[$object->id] = array('class' => array());
+ $values[$object->id] = array(
+ 'class' => array(),
+ 'count' => '0',
+ );
CRM_Core_DAO::storeValues($object, $values[$object->id]);
if ($object->saved_search_id) {
$values[$object->id]['title'] .= ' (' . ts('Smart Group') . ')';
$values[$object->id]['visibility'] = $visibility[$values[$object->id]['visibility']];
+ $groupsToCount[$object->saved_search_id ? 'civicrm_group_contact_cache' : 'civicrm_group_contact'][] = $object->id;
+
if (isset($values[$object->id]['group_type'])) {
$groupTypes = explode(CRM_Core_DAO::VALUE_SEPARATOR,
substr($values[$object->id]['group_type'], 1, -1)
}
}
+ // Get group counts
+ foreach ($groupsToCount as $table => $groups) {
+ $where = "group_id IN (" . implode(',', $groups) . ")";
+ if ($table == 'civicrm_group_contact') {
+ $where .= " AND status = 'Added'";
+ }
+ $dao = CRM_Core_DAO::executeQuery("SELECT group_id, COUNT(id) as `count` FROM $table WHERE $where GROUP BY group_id");
+ while($dao->fetch()) {
+ $values[$dao->group_id]['count'] = $dao->count;
+ }
+ }
+
return $values;
}
/**
* This function to get hierarchical list of groups (parent followed by children)
*
- * @param array $groupIDs array of group ids
+ * @param array $groupIDs array of group ids
+ *
+ * @param null $parents
+ * @param string $spacer
+ * @param bool $titleOnly
*
- * @access public
+ * @return array
*/
- static function getGroupsHierarchy (
+ static function getGroupsHierarchy(
$groupIDs,
- $parents = NULL,
+ $parents = NULL,
$spacer = '<span class="child-indent"></span>',
$titleOnly = FALSE
- ) {
+ ) {
if (empty($groupIDs)) {
return array();
}
$groupIdString = '(' . implode(',', array_keys($groupIDs)) . ')';
- // <span class="child-icon"></span>
- // need to return id, title (w/ spacer), description, visibility
-
- // We need to build a list of tags ordered by hierarchy and sorted by
- // name. The heirarchy will be communicated by an accumulation of
- // separators in front of the name to give it a visual offset.
- // Instead of recursively making mysql queries, we'll make one big
- // query and build the heirarchy with the algorithm below.
- $groups = array();
- $args = array(1 => array($groupIdString, 'String'));
- $query = "
+ // <span class="child-icon"></span>
+ // need to return id, title (w/ spacer), description, visibility
+
+ // We need to build a list of tags ordered by hierarchy and sorted by
+ // name. The heirarchy will be communicated by an accumulation of
+ // separators in front of the name to give it a visual offset.
+ // Instead of recursively making mysql queries, we'll make one big
+ // query and build the heirarchy with the algorithm below.
+ $groups = array();
+ $args = array(1 => array($groupIdString, 'String'));
+ $query = "
SELECT id, title, description, visibility, parents
FROM civicrm_group
WHERE id IN $groupIdString
";
- if ($parents) {
- // group can have > 1 parent so parents may be comma separated list (eg. '1,2,5'). We just grab and match on 1st parent.
- $parentArray = explode(',', $parents);
- $parent = $parentArray[0];
- $args[2] = array($parent, 'Integer');
- $query .= " AND SUBSTRING_INDEX(parents, ',', 1) = %2";
- }
- $query .= " ORDER BY title";
- $dao = CRM_Core_DAO::executeQuery($query, $args);
-
- // Sort the groups into the correct storage by the parent
- // $roots represent the current leaf nodes that need to be checked for
- // children. $rows represent the unplaced nodes
- $roots = $rows = $allGroups = array();
- while ($dao->fetch()) {
- $allGroups[$dao->id] = array('title' => $dao->title,
- 'visibility' => $dao->visibility,
- 'description' => $dao->description);
-
- if ($dao->parents == $parents) {
- $roots[] = array('id' => $dao->id,
- 'prefix' => '',
- 'title' => $dao->title);
- }
- else {
- // group can have > 1 parent so $dao->parents may be comma separated list (eg. '1,2,5'). Grab and match on 1st parent.
- $parentArray = explode(',', $dao->parents);
- $parent = $parentArray[0];
- $rows[] = array('id' => $dao->id,
- 'prefix' => '',
- 'title' => $dao->title,
- 'parents' => $parent);
- }
- }
- $dao->free();
- // While we have nodes left to build, shift the first (alphabetically)
- // node of the list, place it in our groups list and loop through the
- // list of unplaced nodes to find its children. We make a copy to
- // iterate through because we must modify the unplaced nodes list
- // during the loop.
- while (count($roots)) {
- $new_roots = array();
- $current_rows = $rows;
- $root = array_shift($roots);
- $groups[$root['id']] = array($root['prefix'], $root['title']);
-
- // As you find the children, append them to the end of the new set
- // of roots (maintain alphabetical ordering). Also remove the node
- // from the set of unplaced nodes.
- if (is_array($current_rows)) {
- foreach ($current_rows as $key => $row) {
- if ($row['parents'] == $root['id']) {
- $new_roots[] = array('id' => $row['id'], 'prefix' => $groups[$root['id']][0] . $spacer, 'title' => $row['title']);
- unset($rows[$key]);
- }
- }
- }
-
- //As a group, insert the new roots into the beginning of the roots
- //list. This maintains the hierarchical ordering of the tags.
- $roots = array_merge($new_roots, $roots);
- }
-
- // Prefix titles with the calcuated spacing to give the visual
- // appearance of ordering when transformed into HTML in the form layer. Add description and visibility.
- $groupsReturn = array();
- foreach ($groups as $key=>$value) {
- if ($titleOnly) {
- $groupsReturn[$key] = $value[0] . $value[1];
- } else {
- $groupsReturn[$key] = array(
- 'title' => $value[0] . $value[1],
- 'description' => $allGroups[$key]['description'],
- 'visibility' => $allGroups[$key]['visibility'],
- );
- }
- }
-
- return $groupsReturn;
+ if ($parents) {
+ // group can have > 1 parent so parents may be comma separated list (eg. '1,2,5'). We just grab and match on 1st parent.
+ $parentArray = explode(',', $parents);
+ $parent = $parentArray[0];
+ $args[2] = array($parent, 'Integer');
+ $query .= " AND SUBSTRING_INDEX(parents, ',', 1) = %2";
+ }
+ $query .= " ORDER BY title";
+ $dao = CRM_Core_DAO::executeQuery($query, $args);
+
+ // Sort the groups into the correct storage by the parent
+ // $roots represent the current leaf nodes that need to be checked for
+ // children. $rows represent the unplaced nodes
+ $roots = $rows = $allGroups = array();
+ while ($dao->fetch()) {
+ $allGroups[$dao->id] = array(
+ 'title' => $dao->title,
+ 'visibility' => $dao->visibility,
+ 'description' => $dao->description
+ );
+
+ if ($dao->parents == $parents) {
+ $roots[] = array(
+ 'id' => $dao->id,
+ 'prefix' => '',
+ 'title' => $dao->title
+ );
+ }
+ else {
+ // group can have > 1 parent so $dao->parents may be comma separated list (eg. '1,2,5'). Grab and match on 1st parent.
+ $parentArray = explode(',', $dao->parents);
+ $parent = $parentArray[0];
+ $rows[] = array(
+ 'id' => $dao->id,
+ 'prefix' => '',
+ 'title' => $dao->title,
+ 'parents' => $parent
+ );
+ }
+ }
+ $dao->free();
+ // While we have nodes left to build, shift the first (alphabetically)
+ // node of the list, place it in our groups list and loop through the
+ // list of unplaced nodes to find its children. We make a copy to
+ // iterate through because we must modify the unplaced nodes list
+ // during the loop.
+ while (count($roots)) {
+ $new_roots = array();
+ $current_rows = $rows;
+ $root = array_shift($roots);
+ $groups[$root['id']] = array($root['prefix'], $root['title']);
+
+ // As you find the children, append them to the end of the new set
+ // of roots (maintain alphabetical ordering). Also remove the node
+ // from the set of unplaced nodes.
+ if (is_array($current_rows)) {
+ foreach ($current_rows as $key => $row) {
+ if ($row['parents'] == $root['id']) {
+ $new_roots[] = array(
+ 'id' => $row['id'],
+ 'prefix' => $groups[$root['id']][0] . $spacer,
+ 'title' => $row['title']
+ );
+ unset($rows[$key]);
+ }
+ }
+ }
+
+ //As a group, insert the new roots into the beginning of the roots
+ //list. This maintains the hierarchical ordering of the tags.
+ $roots = array_merge($new_roots, $roots);
+ }
+
+ // below is the redundant looping to ensure child groups are populated in the case where user does not have
+ // access to parent groups ( esp. using ACL permissions and logged in user can assess only child groups )
+ foreach ($rows as $value) {
+ $groups[$value['id']] = array($value['prefix'], $value['title']);
+ }
+ // Prefix titles with the calcuated spacing to give the visual
+ // appearance of ordering when transformed into HTML in the form layer. Add description and visibility.
+ $groupsReturn = array();
+ foreach ($groups as $key => $value) {
+ if ($titleOnly) {
+ $groupsReturn[$key] = $value[0] . $value[1];
+ }
+ else {
+ $groupsReturn[$key] = array(
+ 'title' => $value[0] . $value[1],
+ 'description' => $allGroups[$key]['description'],
+ 'visibility' => $allGroups[$key]['visibility'],
+ );
+ }
+ }
+
+ return $groupsReturn;
}
- static function getGroupCount(&$params) {
+ /**
+ * @param array $params
+ *
+ * @return null|string
+ */
+ public static function getGroupCount(&$params) {
$whereClause = self::whereClause($params, FALSE);
$query = "SELECT COUNT(*) FROM civicrm_group groups";
return CRM_Core_DAO::singleValueQuery($query, $params);
}
- static function whereClause(&$params, $sortBy = TRUE, $excludeHidden = TRUE) {
+ /**
+ * Generate permissioned where clause for group search
+ * @param array $params
+ * @param bool $sortBy
+ * @param bool $excludeHidden
+ *
+ * @return string
+ */
+ public static function whereClause(&$params, $sortBy = TRUE, $excludeHidden = TRUE) {
$values = array();
- $clauses = array();
-
$title = CRM_Utils_Array::value('title', $params);
if ($title) {
$clauses[] = "groups.title LIKE %1";
}
}
- /*
- if ( $sortBy &&
- $this->_sortByCharacter !== null ) {
- $clauses[] =
- "groups.title LIKE '" .
- strtolower(CRM_Core_DAO::escapeWildCardString($this->_sortByCharacter)) .
- "%'";
- }
-
- // dont do a the below assignement when doing a
- // AtoZ pager clause
- if ( $sortBy ) {
- if ( count( $clauses ) > 1 ) {
- $this->assign( 'isSearch', 1 );
- } else {
- $this->assign( 'isSearch', 0 );
- }
- }
- */
-
-
if (empty($clauses)) {
$clauses[] = 'groups.is_active = 1';
}
if ($excludeHidden) {
$clauses[] = 'groups.is_hidden = 0';
}
- //CRM-12209
- if (!CRM_Core_Permission::check('view all contacts')) {
- //get the allowed groups for the current user
- $groups = CRM_ACL_API::group(CRM_ACL_API::VIEW);
- if (!empty( $groups)) {
- $groupList = implode( ', ', array_values( $groups ) );
- $clauses[] = "groups.id IN ( $groupList ) ";
- }
- }
+ ;
+ $clauses[] = self::getPermissionClause();
+
return implode(' AND ', $clauses);
}
/**
- * Function to define action links
+ * Define action links
*
* @return array $links array of action links
- * @access public
*/
- static function actionLinks() {
+ public static function actionLinks() {
$links = array(
CRM_Core_Action::VIEW => array(
'name' => ts('Contacts'),
return $links;
}
- function pagerAtoZ($whereClause, $whereParams) {
+ /**
+ * @param $whereClause
+ * @param array $whereParams
+ *
+ * @return string
+ */
+ public function pagerAtoZ($whereClause, $whereParams) {
$query = "
SELECT DISTINCT UPPER(LEFT(groups.title, 1)) as sort_name
FROM civicrm_group groups
return CRM_Utils_PagerAToZ::getAToZBar($dao, $this->_sortByCharacter, TRUE);
}
}
-