* @param string $tableName
* @param null $allGroups
* @param null $includedGroups
- * @param bool $flush
*
- * @return array
- * the ids of the groups for which the user has permissions
+ * @return bool
*/
public static function groupPermission(
$type,
$contactID = NULL,
$tableName = 'civicrm_saved_search',
$allGroups = NULL,
- $includedGroups = NULL,
- $flush = FALSE
+ $includedGroups = NULL
) {
- static $cache = array();
- $groups = array();
- //@todo this is pretty hacky!!!
- //adding a way for unit tests to flush the cache
- if ($flush) {
- $cache = array();
- return NULL;
+ if (!isset(Civi::$statics[__CLASS__]) || !isset(Civi::$statics[__CLASS__]['group_permission'])) {
+ Civi::$statics[__CLASS__]['group_permission'] = array();
}
+
if (!$contactID) {
- $session = CRM_Core_Session::singleton();
- $contactID = NULL;
- if ($session->get('userID')) {
- $contactID = $session->get('userID');
- }
+ $contactID = CRM_Core_Session::singleton()->getLoggedInContactID();
}
$key = "{$tableName}_{$type}_{$contactID}";
- if (array_key_exists($key, $cache)) {
- $groups = &$cache[$key];
- }
- else {
- $groups = self::group($type, $contactID, $tableName, $allGroups, $includedGroups);
- $cache[$key] = $groups;
- }
- if (empty($groups)) {
- return FALSE;
+ if (!array_key_exists($key, Civi::$statics[__CLASS__]['group_permission'])) {
+ Civi::$statics[__CLASS__]['group_permission'][$key] = self::group($type, $contactID, $tableName, $allGroups, $includedGroups);
}
- return in_array($groupID, $groups) ? TRUE : FALSE;
+ return in_array($groupID, Civi::$statics[__CLASS__]['group_permission'][$key]);
}
}
CRM_Contact_BAO_GroupOrganization::add($groupOrg);
}
- CRM_Utils_System::flushCache();
+ self::flushCaches();
CRM_Contact_BAO_GroupContactCache::add($group->id);
if (!empty($params['id'])) {
return $clause;
}
+ /**
+ * Flush caches that hold group data.
+ *
+ * (Actually probably some overkill at the moment.)
+ */
+ protected static function flushCaches() {
+ CRM_Utils_System::flushCache();
+ $staticCaches = array(
+ 'CRM_Core_PseudoConstant' => 'groups',
+ 'CRM_ACL_API' => 'group_permission',
+ 'CRM_ACL_BAO_ACL' => 'permissioned_groups',
+ );
+ foreach ($staticCaches as $class => $key) {
+ if (isset(Civi::$statics[$class][$key])) {
+ unset(Civi::$statics[$class][$key]);
+ }
+ }
+ }
+
/**
* @return string
*/
* @return array
*/
public static function getGroupList(&$params) {
- $config = CRM_Core_Config::singleton();
-
$whereClause = self::whereClause($params, FALSE);
- //$this->pagerAToZ( $whereClause, $params );
-
$limit = "";
if (!empty($params['rowCount']) &&
$params['rowCount'] > 0
$visibility = CRM_Core_SelectValues::ufVisibility();
while ($object->fetch()) {
- $permission = CRM_Contact_BAO_Group::checkPermission($object->id, TRUE);
- //@todo CRM-12209 introduced an ACL check in the whereClause function
- // it may be that this checking is now obsolete - or that what remains
- // should be removed to the whereClause (which is also accessed by getCount)
-
- if ($permission) {
- $newLinks = $links;
- $values[$object->id] = array(
- 'class' => array(),
- 'count' => '0',
+ $newLinks = $links;
+ $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') . ')';
+ // check if custom search, if so fix view link
+ $customSearchID = CRM_Core_DAO::getFieldValue(
+ 'CRM_Contact_DAO_SavedSearch',
+ $object->saved_search_id,
+ 'search_custom_id'
);
- CRM_Core_DAO::storeValues($object, $values[$object->id]);
-
- if ($object->saved_search_id) {
- $values[$object->id]['title'] .= ' (' . ts('Smart Group') . ')';
- // check if custom search, if so fix view link
- $customSearchID = CRM_Core_DAO::getFieldValue(
- 'CRM_Contact_DAO_SavedSearch',
- $object->saved_search_id,
- 'search_custom_id'
- );
-
- if ($customSearchID) {
- $newLinks[CRM_Core_Action::VIEW]['url'] = 'civicrm/contact/search/custom';
- $newLinks[CRM_Core_Action::VIEW]['qs'] = "reset=1&force=1&ssID={$object->saved_search_id}";
- }
+
+ if ($customSearchID) {
+ $newLinks[CRM_Core_Action::VIEW]['url'] = 'civicrm/contact/search/custom';
+ $newLinks[CRM_Core_Action::VIEW]['qs'] = "reset=1&force=1&ssID={$object->saved_search_id}";
}
+ }
- $action = array_sum(array_keys($newLinks));
+ $action = array_sum(array_keys($newLinks));
- // CRM-9936
- if (array_key_exists('is_reserved', $object)) {
- //if group is reserved and I don't have reserved permission, suppress delete/edit
- if ($object->is_reserved && !$reservedPermission) {
- $action -= CRM_Core_Action::DELETE;
- $action -= CRM_Core_Action::UPDATE;
- $action -= CRM_Core_Action::DISABLE;
- }
+ // CRM-9936
+ if (array_key_exists('is_reserved', $object)) {
+ //if group is reserved and I don't have reserved permission, suppress delete/edit
+ if ($object->is_reserved && !$reservedPermission) {
+ $action -= CRM_Core_Action::DELETE;
+ $action -= CRM_Core_Action::UPDATE;
+ $action -= CRM_Core_Action::DISABLE;
}
+ }
- if (array_key_exists('is_active', $object)) {
- if ($object->is_active) {
- $action -= CRM_Core_Action::ENABLE;
- }
- else {
- $values[$object->id]['class'][] = 'disabled';
- $action -= CRM_Core_Action::VIEW;
- $action -= CRM_Core_Action::DISABLE;
- }
+ if (array_key_exists('is_active', $object)) {
+ if ($object->is_active) {
+ $action -= CRM_Core_Action::ENABLE;
}
+ else {
+ $values[$object->id]['class'][] = 'disabled';
+ $action -= CRM_Core_Action::VIEW;
+ $action -= CRM_Core_Action::DISABLE;
+ }
+ }
- $action = $action & CRM_Core_Action::mask($groupPermissions);
+ $action = $action & CRM_Core_Action::mask($groupPermissions);
- $values[$object->id]['visibility'] = $visibility[$values[$object->id]['visibility']];
+ $values[$object->id]['visibility'] = $visibility[$values[$object->id]['visibility']];
- $groupsToCount[$object->saved_search_id ? 'civicrm_group_contact_cache' : 'civicrm_group_contact'][] = $object->id;
+ $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)
- );
- $types = array();
- foreach ($groupTypes as $type) {
- $types[] = CRM_Utils_Array::value($type, $allTypes);
- }
- $values[$object->id]['group_type'] = implode(', ', $types);
- }
- $values[$object->id]['action'] = CRM_Core_Action::formLink($newLinks,
- $action,
- array(
- 'id' => $object->id,
- 'ssid' => $object->saved_search_id,
- ),
- ts('more'),
- FALSE,
- 'group.selector.row',
- 'Group',
- $object->id
+ if (isset($values[$object->id]['group_type'])) {
+ $groupTypes = explode(CRM_Core_DAO::VALUE_SEPARATOR,
+ substr($values[$object->id]['group_type'], 1, -1)
);
-
- // If group has children, add class for link to view children
- $values[$object->id]['is_parent'] = FALSE;
- if (array_key_exists('children', $values[$object->id])) {
- $values[$object->id]['class'][] = "crm-group-parent";
- $values[$object->id]['is_parent'] = TRUE;
+ $types = array();
+ foreach ($groupTypes as $type) {
+ $types[] = CRM_Utils_Array::value($type, $allTypes);
}
+ $values[$object->id]['group_type'] = implode(', ', $types);
+ }
+ $values[$object->id]['action'] = CRM_Core_Action::formLink($newLinks,
+ $action,
+ array(
+ 'id' => $object->id,
+ 'ssid' => $object->saved_search_id,
+ ),
+ ts('more'),
+ FALSE,
+ 'group.selector.row',
+ 'Group',
+ $object->id
+ );
- // If group is a child, add child class
- if (array_key_exists('parents', $values[$object->id])) {
- $values[$object->id]['class'][] = "crm-group-child";
- }
+ // If group has children, add class for link to view children
+ $values[$object->id]['is_parent'] = FALSE;
+ if (array_key_exists('children', $values[$object->id])) {
+ $values[$object->id]['class'][] = "crm-group-parent";
+ $values[$object->id]['is_parent'] = TRUE;
+ }
- if ($groupOrg) {
- if ($object->org_id) {
- $contactUrl = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$object->org_id}");
- $values[$object->id]['org_info'] = "<a href='{$contactUrl}'>{$object->org_name}</a>";
- }
- else {
- $values[$object->id]['org_info'] = ''; // Empty cell
- }
+ // If group is a child, add child class
+ if (array_key_exists('parents', $values[$object->id])) {
+ $values[$object->id]['class'][] = "crm-group-child";
+ }
+
+ if ($groupOrg) {
+ if ($object->org_id) {
+ $contactUrl = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$object->org_id}");
+ $values[$object->id]['org_info'] = "<a href='{$contactUrl}'>{$object->org_name}</a>";
}
else {
- $values[$object->id]['org_info'] = NULL; // Collapsed column if all cells are NULL
- }
- if ($object->created_id) {
- $contactUrl = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$object->created_id}");
- $values[$object->id]['created_by'] = "<a href='{$contactUrl}'>{$object->created_by}</a>";
+ $values[$object->id]['org_info'] = ''; // Empty cell
}
}
+ else {
+ $values[$object->id]['org_info'] = NULL; // Collapsed column if all cells are NULL
+ }
+ if ($object->created_id) {
+ $contactUrl = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$object->created_id}");
+ $values[$object->id]['created_by'] = "<a href='{$contactUrl}'>{$object->created_by}</a>";
+ }
}
// Get group counts - executes one query for regular groups and another for smart groups
* @group headless
*/
class api_v3_GroupTest extends CiviUnitTestCase {
- protected $_apiversion;
+ protected $_apiversion = 3;
protected $_groupID;
+ /**
+ * Set up for tests.
+ */
public function setUp() {
- $this->_apiversion = 3;
-
parent::setUp();
$this->_groupID = $this->groupCreate();
+ $config = CRM_Core_Config::singleton();
+ $config->userPermissionClass->permissions = array();
}
+ /**
+ * Clean up after test.
+ */
public function tearDown() {
-
$this->groupDelete($this->_groupID);
+ CRM_Utils_Hook::singleton()->reset();
+ $config = CRM_Core_Config::singleton();
+ unset($config->userPermissionClass->permissions);
}
- public function testgroupCreateNoTitle() {
+ /**
+ * Test missing required title parameter results in an error.
+ */
+ public function testGroupCreateNoTitle() {
$params = array(
'name' => 'Test Group No title ',
'domain_id' => 1,
),
);
- $group = $this->callAPIFailure('group', 'create', $params, 'Mandatory key(s) missing from params array: title');
+ $this->callAPIFailure('group', 'create', $params, 'Mandatory key(s) missing from params array: title');
}
public function testGetGroupWithEmptyParams() {
- $group = $this->callAPISuccess('group', 'get', $params = array());
+ $group = $this->callAPISuccess('group', 'get', array());
$group = $group["values"];
$this->assertNotNull(count($group));
$params['parents'] = array();
$params['parents'][$this->_groupID] = 'test Group';
$params['parents']["(SELECT api_key FROM civicrm_contact where id = 1)"] = "Test";
- $group2 = $this->callAPIFailure('group', 'create', $params);
+ $this->callAPIFailure('group', 'create', $params);
unset($params['parents']["(SELECT api_key FROM civicrm_contact where id = 1)"]);
$group2 = $this->callAPISuccess('group', 'create', $params);
$this->assertEquals(count($group2['values'][$group2['id']]['parents']), 1);
}
+ /**
+ * Test that ACLs are applied to group.get calls.
+ */
+ public function testGroupGetACLs() {
+ $this->createLoggedInUser();
+ CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
+ $this->callAPISuccessGetCount('Group', array('check_permissions' => 1), 0);
+ $this->hookClass->setHook('civicrm_aclGroup', array($this, 'aclGroupAllGroups'));
+ unset(Civi::$statics['CRM_ACL_API']['group_permission']);
+ $this->callAPISuccessGetCount('Group', array('check_permissions' => 1), 1);
+ }
+
+ /**
+ * Implement hook to restrict to test group 1.
+ *
+ * @param string $type
+ * @param int $contactID
+ * @param string $tableName
+ * @param array $allGroups
+ * @param array $ids
+ */
+ public function aclGroupAllGroups($type, $contactID, $tableName, $allGroups, &$ids) {
+ $group = $this->callAPISuccess('Group', 'get', array('name' => 'Test Group 1'));
+ $ids = array_keys($group['values']);
+ }
+
}