Still needs a bunch of work, but now it should at least autoload.
Also, switch to Horde_Db usage for the Sql driver.
}
if ($perms) {
- $groups = Group::singleton();
+ $groups = Horde_Group::singleton();
$group_list = $groups->getGroupMemberships(Horde_Auth::getAuth());
- if (!($group_list instanceof PEAR_Error) && count($group_list)) {
+ if (count($group_list)) {
foreach ($group_list as $group_id => $group_name) {
$perm->addGroupPermission($group_id, $perms, false);
}
require_once dirname(__FILE__) . '/lib/Application.php';
Horde_Registry::appInit('ansel');
-require_once 'Horde/Group.php';
-
-$groups = Group::singleton();
+$groups = Horde_Group::singleton();
$auth = $injector->getInstance('Horde_Auth')->getOb();
$form = null;
$userList = array();
}
-$groupList = $groups->listGroups();
-asort($groupList);
-if ($groupList instanceof PEAR_Error) {
- Horde::logMessage($groupList, 'NOTICE');
- $groupList = array();
+$groupList = array();
+try {
+ $groupList = $groups->listGroups();
+ asort($groupList);
+} catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'NOTICE');
}
require $registry->get('templates', 'horde') . '/common-header.inc';
public function prelogin($app)
{
- require_once 'Horde/Group.php';
- $group = Group::singleton();
+ $group = Horde_Group::singleton();
$user_uid = Horde_Auth::getAuth();
switch ($app) {
*/
require_once dirname(__FILE__) . '/lib/base.php';
-require_once 'Horde/Group.php';
$shares = $GLOBALS['injector']->getInstance('Horde_Share')->getScope();
-$groups = &Group::singleton();
+$groups = Horde_Group::singleton();
$auth = $injector->getInstance('Horde_Auth')->getOb();
$reload = false;
$userList = array();
}
-if (!empty($conf['share']['any_group'])) {
- $groupList = $groups->listGroups();
-} else {
- $groupList = $groups->getGroupMemberships(Horde_Auth::getAuth(), true);
-}
-if (is_a($groupList, 'PEAR_Error')) {
- Horde::logMessage($groupList, 'NOTICE');
- $groupList = array();
+$groupList = array();
+try {
+ $groupList = empty($conf['share']['any_group'])
+ ? $groups->getGroupMemberships(Horde_Auth::getAuth(), true)
+ : $groups->listGroups();
+ asort($groupList);
+} catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'NOTICE');
}
-asort($groupList);
require FOLKS_TEMPLATES . '/common-header.inc';
$notification->notify(array('listeners' => 'status'));
*/
public function listGroups()
{
- $result = new stdClass;
- require_once 'Horde/Group.php';
- $horde_groups = Group::singleton();
- if (!empty($GLOBALS['conf']['share']['any_group'])) {
- $groups = $horde_groups->listGroups();
- } else {
- $groups = $horde_groups->getGroupMemberships(Horde_Auth::getAuth(), true);
- }
- if ($groups) {
- if ($groups instanceof PEAR_Error) {
- $groups = array();
- }
+ try {
+ $horde_groups = Horde_Group::singleton();
+ $groups = empty($GLOBALS['conf']['share']['any_group'])
+ ? $horde_groups->getGroupMemberships(Horde_Auth::getAuth(), true)
+ : $horde_groups->listGroups();
asort($groups);
- $result->groups = $groups;
+ } catch (Horde_Group_Exception $e) {
+ $groups = array();
}
+
+ $result = new stdClass;
+ $result->groups = $groups;
+
return $result;
}
$imap = Horde_Imap_Client::factory('socket', $params);
- //@todo: The Group package needs to be converted to H4
- require_once 'Horde/Group.php';
-
$master = new Horde_Kolab_Storage_Driver_Imap(
$imap,
- Group::singleton()
+ Horde_Group::singleton()
);
return new Horde_Kolab_Storage(
/* Groups permissions. */
$perm_val = $permission->getGroupPermissions();
$this->_form->setSection('groups', _("Groups"), Horde::img('group.png'), false);
- require_once 'Horde/Group.php';
- $groups = Group::singleton();
- $group_list = $groups->listGroups();
- if ($group_list instanceof PEAR_Error) {
- $GLOBALS['notification']->push($group_list);
+ try {
+ $groups = Horde_Group::singleton();
+ $group_list = $groups->listGroups();
+ } catch (Horde_Group_Exception $e) {
+ $GLOBALS['notification']->push($e);
$group_list = array();
}
+++ /dev/null
-<?php
-
-require_once 'Horde/DataTree.php';
-
-/** The parent Group node */
-define('GROUP_ROOT', -1);
-
-/**
- * The Group:: class provides the Horde groups system.
- *
- * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Stephane Huther <shuther1@free.fr>
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Horde_Group
- */
-class Group {
-
- /**
- * Group driver parameters
- *
- * @var array
- */
- var $_params;
-
- /**
- * Pointer to a DataTree instance to manage the different groups.
- *
- * @var DataTree
- */
- var $_datatree;
-
- /**
- * Cache of previously retrieved group objects.
- *
- * @var array
- */
- var $_groupCache = array();
-
- /**
- * Id-name-map of already cached group objects.
- *
- * @var array
- */
- var $_groupMap = array();
-
- /**
- * Id-name-hash of all existing groups.
- *
- * @var array
- */
- var $_groupList;
-
- /**
- * List of sub groups.
- *
- * @see listAllUsers()
- * @var array
- */
- var $_subGroups = array();
-
- /**
- * Cache of parent groups.
- *
- * This is an array with group IDs as keys and the integer group id of the
- * direct parent as values.
- *
- * @see getGroupParent
- * @var array
- */
- var $_groupParents = array();
-
- /**
- * Cache of parent group trees.
- *
- * This is an array with group IDs as keys and id-name-hashes of all
- * parents as values.
- *
- * @see getGroupParentList
- * @var array
- */
- var $_groupParentList = array();
-
- /**
- * Cache of parents tree.
- *
- * @see getGroupParents()
- * @var array
- */
- var $_parentTree = array();
-
- /**
- * Hash of groups of certain users.
- *
- * @see getGroupMemberShips()
- * @var array
- */
- var $_userGroups;
-
- /**
- * Constructor.
- */
- function Group($params)
- {
- $this->_params = $params;
- $this->__wakeup();
- }
-
- /**
- * Initializes the object.
- *
- * @throws Horde_Exception
- */
- function __wakeup()
- {
- global $conf;
-
- if (empty($conf['datatree']['driver'])) {
- throw new Horde_Exception('You must configure a DataTree backend to use Groups.');
- }
-
- $driver = $conf['datatree']['driver'];
- $this->_datatree = &DataTree::singleton($driver,
- array_merge(Horde::getDriverConfig('datatree', $driver),
- array('group' => 'horde.groups')));
-
- foreach (array_keys($this->_groupCache) as $name) {
- $this->_groupCache[$name]->setGroupOb($this);
- $this->_groupCache[$name]->setDataTree($this->_datatree);
- }
- }
-
- /**
- * Returns a new group object.
- *
- * @param string $name The group's name.
- * @param string $parent The group's parent's name.
- *
- * @return DataTreeObject_Group A new group object.
- */
- function &newGroup($name, $parent = GROUP_ROOT)
- {
- if (empty($name)) {
- return PEAR::raiseError(_("Group names must be non-empty"));
- }
-
- if ($parent != GROUP_ROOT) {
- $name = $this->getGroupName($parent) . ':' . DataTree::encodeName($name);
- }
-
- $group = new DataTreeObject_Group($name);
- $group->setGroupOb($this);
- return $group;
- }
-
- /**
- * Returns a DataTreeObject_Group object corresponding to the named group,
- * with the users and other data retrieved appropriately.
- *
- * @param string $name The name of the group to retrieve.
- */
- function &getGroup($name)
- {
- if (!isset($this->_groupCache[$name])) {
- $this->_groupCache[$name] = &$this->_datatree->getObject($name, 'DataTreeObject_Group');
- if (!is_a($this->_groupCache[$name], 'PEAR_Error')) {
- $this->_groupCache[$name]->setGroupOb($this);
- $this->_groupMap[$this->_groupCache[$name]->getId()] = $name;
- }
- }
-
- return $this->_groupCache[$name];
- }
-
- /**
- * Returns a DataTreeObject_Group object corresponding to the given unique
- * ID, with the users and other data retrieved appropriately.
- *
- * @param integer $cid The unique ID of the group to retrieve.
- */
- function &getGroupById($cid)
- {
- if (isset($this->_groupMap[$cid])) {
- $group = $this->_groupCache[$this->_groupMap[$cid]];
- } else {
- $group = $this->_datatree->getObjectById($cid, 'DataTreeObject_Group');
- if (!is_a($group, 'PEAR_Error')) {
- $group->setGroupOb($this);
- $name = $group->getName();
- $this->_groupCache[$name] = &$group;
- $this->_groupMap[$cid] = $name;
- }
- }
-
- return $group;
- }
-
- /**
- * Returns a globally unique ID for a group.
- *
- * @param DataTreeObject_Group $group The group.
- *
- * @return string A GUID referring to $group.
- */
- function getGUID($group)
- {
- return 'horde:group:' . $this->getGroupId($group);
- }
-
- /**
- * Adds a group to the groups system. The group must first be created with
- * Group::newGroup(), and have any initial users added to it, before this
- * function is called.
- *
- * @param DataTreeObject_Group $group The new group object.
- *
- * @throws Horde_History_Exception
- * @throws InvalidArgumentException
- */
- function addGroup($group)
- {
- if (!is_a($group, 'DataTreeObject_Group')) {
- return PEAR::raiseError('Groups must be DataTreeObject_Group objects or extend that class.');
- }
- $result = $this->_datatree->add($group);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- $id = $group->getId();
- $name = $group->getName();
- $this->_groupCache[$name] = &$group;
- $this->_groupMap[$id] = $name;
- if (isset($this->_groupList)) {
- $this->_groupList[$id] = $name;
- }
-
- /* Log the addition of the group in the history log. */
- $GLOBALS['injector']->getInstance('Horde_History')->log($this->getGUID($group), array('action' => 'add'), true);
-
- return $result;
- }
-
- /**
- * Stores updated data - users, etc. - of a group to the backend system.
- *
- * @param DataTreeObject_Group $group The group to update.
- *
- * @throws Horde_History_Exception
- * @throws InvalidArgumentException
- */
- function updateGroup($group)
- {
- if (!is_a($group, 'DataTreeObject_Group')) {
- return PEAR::raiseError('Groups must be DataTreeObject_Group objects or extend that class.');
- }
- $result = $this->_datatree->updateData($group);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- $this->_groupCache[$group->getName()] = &$group;
-
- /* Log the update of the group users on the history log. */
- $history = $GLOBALS['injector']->getInstance('Horde_History');
- $guid = $this->getGUID($group);
- foreach ($group->getAuditLog() as $userId => $action) {
- $history->log($guid, array('action' => $action, 'user' => $userId), true);
- }
- $group->clearAuditLog();
-
- /* Log the group modification. */
- $history->log($guid, array('action' => 'modify'), true);
- return $result;
- }
-
- /**
- * Removes a group from the groups system permanently.
- *
- * @param DataTreeObject_Group $group The group to remove.
- * @param boolean $force Force to remove every child.
- *
- * @throws Horde_History_Exception
- * @throws InvalidArgumentException
- */
- function removeGroup($group, $force = false)
- {
- if (!is_a($group, 'DataTreeObject_Group')) {
- return PEAR::raiseError('Groups must be DataTreeObject_Group objects or extend that class.');
- }
-
- $id = $group->getId();
- unset($this->_groupMap[$id]);
- if (isset($this->_groupList)) {
- unset($this->_groupList[$id]);
- }
- unset($this->_groupCache[$group->getName()]);
-
- $GLOBALS['injector']->getInstance('Horde_History')->log($this->getGUID($group), array('action' => 'delete'), true);
-
- return $this->_datatree->remove($group, $force);
- }
-
- /**
- * Retrieves the name of a group.
- *
- * @param integer|DataTreeObject_Group $gid The id of the group or the
- * group object to retrieve the
- * name for.
- *
- * @return string The group's name.
- */
- function getGroupName($gid)
- {
- if (is_a($gid, 'DataTreeObject_Group')) {
- $gid = $gid->getId();
- }
-
- if (isset($this->_groupMap[$gid])) {
- return $this->_groupMap[$gid];
- }
- if (isset($this->_groupList[$gid])) {
- return $this->_groupList[$gid];
- }
-
- return $this->_datatree->getName($gid);
- }
-
- /**
- * Strips all parent references off of the given group name.
- *
- * @param string $group Name of the group.
- *
- * @return The name of the group without parents.
- */
- function getGroupShortName($group)
- {
- return $this->_datatree->getShortName($group);
- }
-
- /**
- * Retrieves the ID of a group.
- *
- * @param string|DataTreeObject_Group $group The group name or object to
- * retrieve the ID for.
- *
- * @return integer The group's ID.
- */
- function getGroupId($group)
- {
- if (is_a($group, 'DataTreeObject_Group')) {
- $group = $group->getName();
- }
-
- $id = array_search($group, $this->_groupMap);
- if ($id !== false) {
- return $id;
- }
- if (isset($this->_groupList)) {
- $id = array_search($group, $this->_groupList);
- if ($id !== false) {
- return $id;
- }
- }
-
- return $this->_datatree->getId($group);
- }
-
- /**
- * Check if a group exists in the system.
- *
- * @param string $group The group to check.
- *
- * @return boolean True if the group exists, false otherwise.
- */
- function exists($group)
- {
- if (isset($this->_groupCache[$group]) ||
- (isset($this->_groupList) &&
- array_search($group, $this->_groupList) !== false)) {
- return true;
- }
-
- return $this->_datatree->exists($group);
- }
-
- /**
- * Returns a tree of the parents of a child group.
- *
- * @param integer $gid The id of the child group.
- *
- * @return array The group parents tree, with groupnames as the keys.
- */
- function getGroupParents($gid)
- {
- if (!isset($this->_parentTree[$gid])) {
- $name = $this->getGroupName($gid);
- $parents = $this->_datatree->getParents($name);
- if (is_a($parents, 'PEAR_Error')) {
- return $parents;
- }
- $this->_parentTree[$gid] = $parents;
- }
-
- return $this->_parentTree[$gid];
- }
-
- /**
- * Returns the single parent ID of the given group.
- *
- * @param integer $gid The DataTree ID of the child group.
- *
- * @return integer The parent of the given group.
- */
- function getGroupParent($gid)
- {
- if (!isset($this->_groupParents[$gid])) {
- $parent = $this->_datatree->getParentById($gid);
- if (is_a($parent, 'PEAR_Error')) {
- return $parent;
- }
- $this->_groupParents[$gid] = $parent;
- }
-
- return $this->_groupParents[$gid];
- }
-
- /**
- * Returns a flat list of the parents of a child group
- *
- * @param integer $gid The id of the group.
- *
- * @return array A flat list of all of the parents of $group, hashed in
- * $id => $name format.
- */
- function getGroupParentList($gid)
- {
- if (!isset($this->_groupParentList[$gid])) {
- $parents = $this->_datatree->getParentList($gid);
- if (is_a($parents, 'PEAR_Error')) {
- return $parents;
- }
- $this->_groupParentList[$gid] = $parents;
- }
-
- return $this->_groupParentList[$gid];
- }
-
- /**
- * Returns a list of all groups, in the format id => groupname.
- *
- * @param boolean $refresh If true, the cached value is ignored and the
- * group list is refreshed from the group backend.
- *
- * @return array ID => groupname hash.
- */
- function listGroups($refresh = false)
- {
- if ($refresh || !isset($this->_groupList)) {
- $this->_groupList = $this->_datatree->get(DATATREE_FORMAT_FLAT, GROUP_ROOT, true);
- unset($this->_groupList[GROUP_ROOT]);
- }
-
- return $this->_groupList;
- }
-
- /**
- * Get a list of every user that is a part of this group ONLY.
- *
- * @param integer $gid The ID of the group.
- *
- * @return array The user list.
- */
- function listUsers($gid)
- {
- $groupOb = &$this->getGroupById($gid);
- if (is_a($groupOb, 'PEAR_Error')) {
- return $groupOb;
- }
-
- if (!isset($groupOb->data['users']) ||
- !is_array($groupOb->data['users'])) {
- return array();
- }
-
- return array_keys($groupOb->data['users']);
- }
-
- /**
- * Get a list of every user that is part of the specified group
- * and any of its subgroups.
- *
- * @param integer $group The ID of the parent group.
- *
- * @return array The complete user list.
- */
- function listAllUsers($gid)
- {
- if (!isset($this->_subGroups[$gid])) {
- // Get a list of every group that is a sub-group of $group.
- $groups = $this->_datatree->get(DATATREE_FORMAT_FLAT, $this->getGroupName($gid), true);
- if (is_a($groups, 'PEAR_Error')) {
- return $groups;
- }
- $this->_subGroups[$gid] = array_keys($groups);
- }
-
- $users = array();
- foreach ($this->_subGroups[$gid] as $groupId) {
- $users = array_merge($users, $this->listUsers($groupId));
- }
- return array_values(array_flip(array_flip($users)));
- }
-
- /**
- * Get a list of every group that $user is in.
- *
- * @param string $user The user to get groups for.
- * @param boolean $parentGroups Also return the parents of any groups?
- *
- * @return array An array of all groups the user is in.
- */
- function getGroupMemberships($user, $parentGroups = false)
- {
- if (!isset($this->_userGroups[$user])) {
- $criteria = array(
- 'AND' => array(
- array('field' => 'name', 'op' => '=', 'test' => 'user'),
- array('field' => 'key', 'op' => '=', 'test' => $user)));
- $groups = $this->_datatree->getByAttributes($criteria);
-
- if (is_a($groups, 'PEAR_Error')) {
- return $groups;
- }
-
- if ($parentGroups) {
- foreach ($groups as $id => $g) {
- $parents = $this->_datatree->getParentList($id);
- if (is_a($parents, 'PEAR_Error')) {
- return $parents;
- }
- $groups += $parents;
- }
- }
-
- $this->_userGroups[$user] = $groups;
- }
-
- return $this->_userGroups[$user];
- }
-
- /**
- * Say if a user is a member of a group or not.
- *
- * @param string $user The name of the user.
- * @param integer $gid The ID of the group.
- * @param boolean $subgroups Return true if the user is in any subgroups
- * of group with ID $gid, also.
- *
- * @return boolean
- */
- function userIsInGroup($user, $gid, $subgroups = true)
- {
- if (!$this->exists($this->getGroupName($gid))) {
- return false;
- } elseif ($subgroups) {
- $groups = $this->getGroupMemberships($user, true);
- if (is_a($groups, 'PEAR_Error')) {
- Horde::logMessage($groups, 'ERR');
- return false;
- }
-
- return !empty($groups[$gid]);
- } else {
- $users = $this->listUsers($gid);
- if (is_a($users, 'PEAR_Error')) {
- Horde::logMessage($users, 'ERR');
- return false;
- }
- return in_array($user, $users);
- }
- }
-
- /**
- * Returns the nesting level of the given group. 0 is returned for any
- * object directly below GROUP_ROOT.
- *
- * @param integer $gid The DataTree ID of the group.
- *
- * @return The DataTree level of the group.
- */
- function getLevel($gid)
- {
- $name = $this->getGroupName($gid);
- return substr_count($name, ':');
- }
-
- /**
- * Stores the object in the session cache.
- */
- function shutdown()
- {
- $session = new Horde_SessionObjects();
- $session->overwrite('horde_group', $this, false);
- }
-
- /**
- * Returns the properties that need to be serialized.
- *
- * @return array List of serializable properties.
- */
- function __sleep()
- {
- $properties = get_object_vars($this);
- unset($properties['_datatree']);
- $properties = array_keys($properties);
- return $properties;
- }
-
- /**
- * Attempts to return a concrete Group instance based on $driver.
- *
- * @param mixed $driver The type of concrete Group subclass to return.
- * @param array $params A hash containing any additional configuration or
- * connection parameters a subclass might need.
- *
- * @return Group The newly created concrete Group instance, or a
- * PEAR_Error object on an error.
- */
- public static function factory($driver = '', $params = null)
- {
- if (is_null($params)) {
- $params = Horde::getDriverConfig('group', $driver);
- }
-
- $class = Group::_loadDriver($driver);
- if (class_exists($class)) {
- $group = new $class($params);
- } else {
- $group = PEAR::raiseError('Class definition of ' . $class . ' not found.');
- }
-
- return $group;
- }
-
- /**
- * Attempts to return a reference to a concrete Group instance.
- * It will only create a new instance if no Group instance
- * currently exists.
- *
- * This method must be invoked as: $var = &Group::singleton()
- *
- * @return Group The concrete Group reference, or false on an error.
- */
- public static function singleton()
- {
- static $group;
-
- if (isset($group)) {
- return $group;
- }
-
- $group_driver = null;
- $group_params = null;
- $auth = $GLOBALS['injector']->getInstance('Horde_Auth')->getOb();
- if ($auth->hasCapability('groups')) {
- $group_driver = $auth->getDriver();
- $group_params = $auth;
- } elseif (!empty($GLOBALS['conf']['group']['driver']) &&
- $GLOBALS['conf']['group']['driver'] != 'datatree') {
- $group_driver = $GLOBALS['conf']['group']['driver'];
- $group_params = Horde::getDriverConfig('group', $group_driver);
- }
-
- Group::_loadDriver($group_driver);
-
- $group = null;
- if (!empty($GLOBALS['conf']['group']['cache'])) {
- $session = new Horde_SessionObjects();
- $group = $session->query('horde_group');
- }
-
- if (!$group) {
- $group = Group::factory($group_driver, $group_params);
- }
-
- if (!empty($GLOBALS['conf']['group']['cache'])) {
- register_shutdown_function(array(&$group, 'shutdown'));
- }
-
- return $group;
- }
-
- protected static function _loadDriver($driver)
- {
- if (!$driver) {
- $class = 'Group';
- } else {
- $driver = basename($driver);
- $class = 'Group_' . $driver;
- if (!class_exists($class)) {
- include 'Horde/Group/' . $driver . '.php';
- }
- }
-
- return $class;
- }
-
-}
-
-/**
- * Extension of the DataTreeObject class for storing Group information
- * in the Categories driver. If you want to store specialized Group
- * information, you should extend this class instead of extending
- * DataTreeObject directly.
- *
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Horde_Group
- */
-class DataTreeObject_Group extends DataTreeObject {
-
- /**
- * The Group object which this group is associated with - needed
- * for updating data in the backend to make changes stick, etc.
- *
- * @var Group
- */
- var $_groupOb;
-
- /**
- * This variable caches the users added or removed from the group
- * for History logging of user-groups relationship.
- *
- * @var array
- */
- var $_auditLog = array();
-
- /**
- * The DataTreeObject_Group constructor. Just makes sure to call
- * the parent constructor so that the group's name is set
- * properly.
- *
- * @param string $name The name of the group.
- */
- function DataTreeObject_Group($name)
- {
- parent::DataTreeObject($name);
- }
-
- /**
- * Returns the properties that need to be serialized.
- *
- * @return array List of serializable properties.
- */
- function __sleep()
- {
- $properties = get_object_vars($this);
- unset($properties['datatree'], $properties['_groupOb']);
- $properties = array_keys($properties);
- return $properties;
- }
-
- /**
- * Associates a Group object with this group.
- *
- * @param Group $groupOb The Group object.
- */
- function setGroupOb(&$groupOb)
- {
- $this->_groupOb = &$groupOb;
- }
-
- /**
- * Fetch the ID of this group
- *
- * @return string The group's ID
- */
- function getId()
- {
- return $this->_groupOb->getGroupId($this);
- }
-
- /**
- * Save any changes to this object to the backend permanently.
- */
- function save()
- {
- return $this->_groupOb->updateGroup($this);
-
- }
-
- /**
- * Adds a user to this group, and makes sure that the backend is
- * updated as well.
- *
- * @param string $username The user to add.
- */
- function addUser($username, $update = true)
- {
- $this->data['users'][$username] = 1;
- $this->_auditLog[$username] = 'addUser';
- if ($update && $this->_groupOb->exists($this->getName())) {
- return $this->save();
- }
- }
-
- /**
- * Removes a user from this group, and makes sure that the backend
- * is updated as well.
- *
- * @param string $username The user to remove.
- */
- function removeUser($username, $update = true)
- {
- unset($this->data['users'][$username]);
- $this->_auditLog[$username] = 'deleteUser';
- if ($update) {
- return $this->save();
- }
- }
-
- /**
- * Get a list of every user that is a part of this group
- * (and only this group)
- *
- * @return array The user list
- */
- function listUsers()
- {
- return $this->_groupOb->listUsers($this->getId());
- }
-
- /**
- * Get a list of every user that is a part of this group and
- * any of it's subgroups
- *
- * @return array The complete user list
- */
- function listAllUsers()
- {
- return $this->_groupOb->listAllUsers($this->getId());
- }
-
- /**
- * Get all the users recently added or removed from the group.
- */
- function getAuditLog()
- {
- return $this->_auditLog;
- }
-
- /**
- * Clears the audit log. To be called after group update.
- */
- function clearAuditLog()
- {
- $this->_auditLog = array();
- }
-
- /**
- * Map this object's attributes from the data array into a format
- * that we can store in the attributes storage backend.
- *
- * @return array The attributes array.
- */
- function _toAttributes()
- {
- // Default to no attributes.
- $attributes = array();
-
- // Loop through all users, if any.
- if (isset($this->data['users']) && is_array($this->data['users']) && count($this->data['users'])) {
- foreach ($this->data['users'] as $user => $active) {
- $attributes[] = array('name' => 'user',
- 'key' => $user,
- 'value' => $active);
- }
- }
- $attributes[] = array('name' => 'email',
- 'key' => '',
- 'value' => $this->get('email'));
-
- return $attributes;
- }
-
- /**
- * Take in a list of attributes from the backend and map it to our
- * internal data array.
- *
- * @param array $attributes The list of attributes from the
- * backend (attribute name, key, and value).
- */
- function _fromAttributes($attributes)
- {
- // Initialize data array.
- $this->data['users'] = array();
-
- foreach ($attributes as $attr) {
- if ($attr['name'] == 'user') {
- $this->data['users'][$attr['key']] = $attr['value'];
- } else {
- $this->data[$attr['name']] = $attr['value'];
- }
- }
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Group_contactlists class provides a groups system based on Turba
- * contact lists. Only SQL sources are supported.
- *
- * Copyright 2008-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Michael J. Rubinsky <mrubinsk@horde.org>
- * @package Horde_Group
- */
-class Group_contactlists extends Group {
-
- /**
- * A cache object
- *
- * @var Horde_Cache object
- */
- var $_cache = null;
-
- /**
- * Handles for the database connections. Need one for each possible source.
- *
- * @var DB
- */
- var $_db = array();
-
- /**
- * Local copy of available address book sources that the group driver can
- * use.
- *
- * @var array of Turba's cfgSource style entries.
- */
- var $_sources = array();
-
- /**
- * Local cache of retreived group entries from Turba storage.
- *
- * @var unknown_type
- */
- var $_listEntries = array();
-
- /**
- * Constructor.
- */
- function Group_contactlists($params)
- {
- // Get a list of all available Turba sources
- $turba_sources = Horde::loadConfiguration('sources.php',
- 'cfgSources', 'turba');
-
- // We only support sql type sources.
- foreach ($turba_sources as $key => $source) {
- if ($source['type'] == 'sql') {
- $this->_sources[$key] = $source;
- }
- }
-
- $this->_cache = $GLOBALS['injector']->getInstance('Horde_Cache');
- }
-
- /**
- * Initializes the object.
- */
- function __wakeup()
- {
- }
-
- /**
- * Returns the properties that need to be serialized.
- *
- * @return array List of serializable properties.
- */
- function __sleep()
- {
- }
-
- /**
- * Stores the object in the session cache.
- */
- function shutdown()
- {
- }
-
- /**
- * Returns a new group object.
- *
- * @param string $name The group's name.
- * @param string $parent The group's parent's name.
- *
- * @return PEAR_Error This functionality is not supported in this driver.
- */
- function newGroup($name, $parent = GROUP_ROOT)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Returns a Group object corresponding to the named group,
- * with the users and other data retrieved appropriately.
- *
- * This is deprecated. Use getGroupById instead.
- *
- * @param string $name The name of the group to retrieve.
- */
- function getGroup($name)
- {
- return PEAR::raiseError(_("Deprecated. Use getGroupById() instead."));
- }
-
- /**
- * Returns a ContactListObject_Group object corresponding to the given unique
- * ID, with the users and other data retrieved appropriately.
- *
- * @param integer $cid The unique ID of the group to retrieve.
- */
- function getGroupById($gid)
- {
-
- if (!empty($this->_groupCache[$gid])) {
- return $this->_groupCache[$gid];
- }
- list($source, $id) = explode(':', $gid);
- $entry = $this->_retrieveListEntry($gid);
- if (is_a($entry, 'PEAR_Error')) {
- return $entry;
- } elseif (empty($entry)) {
- return PEAR::raiseError($gid . ' does not exist');
- }
-
- $users = $this->_getAllMembers($gid);
- if (is_a($users, 'PEAR_Error')) {
- return $users;
- }
-
- $group = new ContactListObject_Group($entry[$this->_sources[$source]['map'][$this->_sources[$source]['list_name_field']]]);
- $group->id = $gid;
- $group->data['email'] = $entry[$this->_sources[$source]['map']['email']];
- if (!empty($users)) {
- $group->data['users'] = array_flip($users);
- }
-
- $group->setGroupOb($this);
- $this->_groupCache[$gid] = $group;
-
- return $group;
- }
-
- /**
- * Adds a group to the groups system. The group must first be created with
- * Group::newGroup(), and have any initial users added to it, before this
- * function is called.
- *
- * @param ContactListObjectObject_Group $group The new group object.
- *
- * @return PEAR_Error - unsupported
- */
- function addGroup($group)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Stores updated data - users, etc. - of a group to the backend system.
- *
- * @param ContactListObject_Group $group The group to update.
- */
- function updateGroup($group)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Removes a group from the groups system permanently.
- *
- * @param ContactListObject_Group $group The group to remove.
- * @param boolean $force Force to remove every child.
- *
- * @return PEAR_Error - unsupported.
- */
- function removeGroup($group, $force = false)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Retrieves the name of a group.
- *
- * @param integer|ContactListObject_Group $gid The id of the group or the
- * group object to retrieve the
- * name for.
- *
- * @return string The group's name.
- */
- function getGroupName($gid)
- {
- static $beenHere;
-
- if (strpos($gid, ':') === false) {
- return PEAR::raiseError(sprintf(_("Group %s not found."), $gid));
- }
-
- if (is_a($gid, 'ContactListObject_Group')) {
- $gid = $gid->getId();
- }
- if (!empty($this->_listEntries[$gid])) {
- list($source, $id) = explode(':', $gid);
- $beenHere = false;
- return $this->_listEntries[$gid][$this->_sources[$source]['map'][$this->_sources[$source]['list_name_field']]];
- }
-
- $result = $this->_retrieveListEntry($gid);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- // We should have the information cached now, try again..but protect
- // against anything nasty...
- if (!$beenHere) {
- $beenHere = true;
- return $this->getGroupName($gid);
- }
-
- return PEAR::raiseError(sprintf(_("Group %s not found."), $gid));
- }
-
- /**
- * Strips all parent references off of the given group name.
- *
- * Not used in this driver...group display names are ONLY for display.
- *
- * @param string $group Name of the group.
- *
- * @return The name of the group without parents.
- */
- function getGroupShortName($group)
- {
- return $group;
- }
-
- /**
- * Retrieves the ID of a group, given the group object.
- * Here for BC. Kinda silly, since if we have the object, we can just call
- * getId() ourselves.
- *
- * @param ContactListObject_Group $group The group object to retrieve the
- * ID for.
- *
- * @return integer The group's ID.
- */
- function getGroupId($group)
- {
- if (is_a($group, 'ContactListObject_Group')) {
- return $group->getId();
- }
-
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Check if a group exists in the system.
- *
- * This must either be a noop or we need to somehow "uniqueify" the
- * list's display name?
- *
- * @param string $group The group name to check.
- *
- * @return boolean True if the group exists, false otherwise.
- */
- function exists($group)
- {
- return true;
- }
-
- /**
- * Returns a tree of the parents of a child group.
- *
- * @param integer $gid The id of the child group.
- *
- * @return array The group parents tree, with groupnames as the keys.
- */
- function getGroupParents($gid)
- {
- return array();
- }
-
-
- /**
- * Returns the single parent ID of the given group.
- *
- * @param integer $gid The ID of the child group.
- *
- * @return integer The parent of the given group.
- */
- function getGroupParent($gid)
- {
- return GROUP_ROOT;
- }
-
- /**
- * Returns a flat list of the parents of a child group
- *
- * @param integer $gid The id of the group.
- *
- * @return array A flat list of all of the parents of $group, hashed in
- * $id => $name format.
- */
- function getGroupParentList($gid)
- {
- return array();
- }
-
- /**
- * Returns a list of all groups, in the format id => groupname.
- * The groups returned represent only the groups visible to the current user
- * only.
- *
- * @param boolean $refresh If true, the cached value is ignored and the
- * group list is refreshed from the group backend.
- *
- * @return array ID => groupname hash.
- */
- function listGroups($refresh = false)
- {
- if (isset($this->_groupList) && !$refresh) {
- return $this->_groupList;
- }
-
- // First, make sure we are connected to all sources
- $this->_connect();
-
- $groups = array();
- $owners = array();
- foreach ($this->_sources as $key => $source) {
- if ($source['use_shares']) {
- if (empty($contact_shares)) {
- $scope = $GLOBALS['registry']->hasInterface('contacts');
- $shares = $GLOBALS['injector']->getInstance('Horde_Share')->getScope($scope);
- $this->_contact_shares = $shares->listShares(Horde_Auth::getAuth(), Horde_Perms::SHOW, Horde_Auth::getAuth());
- }
- // Contruct a list of owner ids to use
- foreach ($this->_contact_shares as $id => $share) {
- $params = @unserialize($share->get('params'));
- if ($params['source'] == $key) {
- $owners[] = $params['name'];
- }
- }
- } else {
- $owners = array(Horde_Auth::getAuth());
- }
- $owner_ids = array();
- foreach ($owners as $owner) {
- $owner_ids[] = $this->_db[$key]->quote($owner);
- }
- $sql = 'SELECT ' . $source['map']['__key'] . ', ' . $source['map'][$source['list_name_field']]
- . ' FROM ' . $source['params']['table'] . ' WHERE '
- . $source['map']['__type'] . ' = \'Group\' AND '
- . $source['map']['__owner'] . ' IN (' . implode(',', $owner_ids ) . ')';
-
- $results = $this->_db[$key]->getAssoc($sql);
- foreach ($results as $id => $name) {
- $groups[$key . ':' . $id] = $name;
- }
- }
- $this->_groupList = $groups;
-
- return $this->_groupList;
- }
-
- /**
- * Get a list of every user that is part of the specified group
- * and any of its subgroups.
- *
- * @param integer $group The ID of the parent group.
- *
- * @return array The complete user list.
- */
- function listAllUsers($gid)
- {
- $members = $this->_getAllMembers($gid, true);
- if (is_a($members, 'PEAR_Error')) {
- return $members;
- }
-
- return array_values($members);
- }
-
- /**
- * Returns a hash representing the list entry. Items are keyed by the
- * backend specific keys.
- *
- * @param string $gid The group id
- * @return array | PEAR_Error
- */
- function _retrieveListEntry($gid)
- {
- if (!empty($this->_listEntries[$gid])) {
- return $this->_listEntries[$gid];
- }
-
- list($source, $id) = explode(':', $gid);
- if (empty($this->_sources[$source])) {
- return array();
- }
-
- $this->_connect($source);
- $sql = 'SELECT ' . $this->_sources[$source]['map']['__members'] . ','
- . $this->_sources[$source]['map']['email'] . ','
- . $this->_sources[$source]['map'][$this->_sources[$source]['list_name_field']]
- . ' from ' . $this->_sources[$source]['params']['table'] . ' WHERE '
- . $this->_sources[$source]['map']['__key'] . ' = ' . $this->_db[$source]->quote($id);
-
- $results = $this->_db[$source]->getRow($sql,array(), DB_FETCHMODE_ASSOC);
- if (is_a($results, 'PEAR_Error')) {
- Horde::logMessage($results, 'ERR');
- }
- $this->_listEntries[$gid] = $results;
-
- return $results;
-
- }
-
- /**
- * TODO
- */
- function _getAllMembers($gid, $subGroups = false)
- {
- if (empty($gid) || strpos($gid, ':') === false) {
- return PEAR::raiseError(sprintf(_("Unsupported group id: %s"), $gid));
- }
-
- list($source, $id) = explode(':', $gid);
- $entry = $this->_retrieveListEntry($gid);
- if (is_a($entry, 'PEAR_Error')) {
- return $entry;
- }
- $members = @unserialize($entry[$this->_sources[$source]['map']['__members']]);
- $users = array();
-
- // TODO: optimize this to only query each table once
- foreach ($members as $member) {
-
- // Is this member from the same source or a different one?
- if (strpos($member, ':') !== false) {
- list($newSource, $uid) = explode(':', $member);
- if (!empty($this->_contact_shares[$newSource])) {
- $params = @unserialize($this->_contact_shares[$newSource]->get('params'));
- $newSource = $params['source'];
- $member = $uid;
- $this->_connect($newSource);
- } elseif (empty($this->_sources[$newSource])) {
- // Last chance, it's not in one of our non-share sources
- continue;
- }
- } else {
- // Same source
- $newSource = $source;
- }
-
- $sql = 'SELECT ' . $this->_sources[$newSource]['map']['email']
- . ', ' . $this->_sources[$newSource]['map']['__type']
- . ' FROM ' . $this->_sources[$newSource]['params']['table']
- . ' WHERE ' . $this->_sources[$newSource]['map']['__key']
- . ' = ' . $this->_db[$newSource]->quote($member);
-
- $results = $this->_db[$newSource]->getRow($sql);
- if (is_a($results, 'PEAR_Error')) {
- Horde::logMessage($results, 'ERR');
- return $results;
- }
-
- // Sub-Lists are treated as sub groups the best that we can...
- if ($subGroups && $results[1] == 'Group') {
- $this->_subGroups[$gid] = $newSource . ':' . $member;
- $users = array_merge($users, $this->_getAllMembers($newSource . ':' . $member));
- }
- if (strlen($results[0])) {
- // use a key to dump dups
- $users[$results[0]] = $results[0];
- }
- }
-
- return $users;
- }
-
- /**
- * Returns ALL contact lists present in ALL sources that this driver knows
- * about.
- *
- */
- function _listAllLists()
- {
- // Clear the cache - we will rebuild it.
- $this->_listEntries = array();
-
- foreach ($this->_sources as $key => $source) {
- $this->_connect($key);
- $sql = 'SELECT ' . $source['map']['__key'] . ','
- . $source['map']['__members'] . ','
- . $source['map']['email'] . ','
- . $source['map'][$source['list_name_field']]
- . ' FROM ' . $source['params']['table'] . ' WHERE '
- . $source['map']['__type'] . ' = \'Group\'';
-
- $results = $this->_db[$key]->query($sql);
- if (is_a($results, 'PEAR_Error')) {
- return $results;
- }
- while ($row = $results->fetchRow(DB_FETCHMODE_ASSOC)) {
- $this->_listEntries[$key . ':' . $row[$source['map']['__key']]] = $row;
- }
- }
-
- return $this->_listEntries;
- }
-
- /**
- * Get a list of every group that $user is in.
- *
- * @param string $user The user to get groups for.
- * @param boolean $parentGroups Also return the parents of any groups?
- *
- * @return array An array of all groups the user is in.
- */
- function getGroupMemberships($user, $parentGroups = false)
- {
- if (($memberships = $this->_cache->get('Group_contactlists_memberships' . md5($user))) !== false) {
- return unserialize($memberships);
- }
- $lists = $this->_listAllLists();
- $memberships = array();
- foreach (array_keys($lists) as $list) {
- $members = $this->_getAllMembers($list, $parentGroups);
- if (!empty($members[$user])) {
- $memberships[] = $list;
- }
- }
-
- $this->_cache->set('Group_contactlists_memberships' . md5($user), serialize($memberships));
- return $memberships;
-
- }
-
- /**
- * Say if a user is a member of a group or not.
- *
- * @param string $user The name of the user.
- * @param integer $gid The ID of the group.
- * @param boolean $subgroups Return true if the user is in any subgroups
- * of group with ID $gid, also.
- *
- * @return boolean
- */
- function userIsInGroup($user, $gid, $subgroups = true)
- {
- if (isset($_SESSION['horde']['groups']['i'][$user][$subgroups][$gid])) {
- return $_SESSION['horde']['groups']['i'][$user][$subgroups][$gid];
- }
-
- $users = $this->_getAllMembers($gid, $subgroups);
- if (is_a($users, 'PEAR_Error')) {
- Horde::logMessage($users, 'ERR');
- return false;
- }
- $result = !empty($users[$user]);
- $_SESSION['horde']['groups']['i'][$user][$subgroups][$gid] = (bool)$result;
- return (bool)$result;
- }
-
- /**
- * Attempts to open a persistent connection to the sql server.
- *
- * @return boolean True on success.
- * @throws Horde_Exception
- */
- function _connect($source = null)
- {
- if (!is_null($source) && !empty($this->_db[$source])) {
- return true;
- }
- /* Connect to the sql server using the supplied parameters. */
- require_once 'DB.php';
-
- if (is_null($source)) {
- $sources = array_keys($this->_sources);
- } else {
- $sources = array($source);
- }
-
- foreach ($sources as $source) {
- if (empty($this->_db[$source])) {
- $this->_db[$source] = DB::connect($this->_sources[$source]['params'],
- array('persistent' => !empty($this->_sources[$source]['params']['persistent'])));
- if (is_a($this->_db[$source], 'PEAR_Error')) {
- throw new Horde_Exception_Prior($this->_db[$source]);
- }
-
- /* Set DB portability options. */
- switch ($this->_db[$source]->phptype) {
- case 'mssql':
- $this->_db[$source]->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
- break;
- default:
- $this->_db[$source]->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
- }
- }
- }
-
- return true;
- }
-
-}
-
-/**
- * Extension of the DataTreeObject_Group class for storing Group information.
- *
- * @author Michael J. Rubinsky <mrubinsk@horde.org>
- * @package Horde_Group
- */
-class ContactListObject_Group extends DataTreeObject_Group {
-
- /**
- * The unique name of this object.
- * These names have the same requirements as other object names - they must
- * be unique, etc.
- *
- * @var string
- */
- var $name;
-
- /**
- * The unique name of this object.
- * These names have the same requirements as other object names - they must
- * be unique, etc.
- *
- * @var integer
- */
- var $id;
-
- /**
- * Key-value hash that will be serialized.
- *
- * @see getData()
- * @var array
- */
- var $data = array();
-
- /**
- * Constructor.
- *
- * @param string $name The name of the group.
- */
- function ContactListObject_Group($name)
- {
- $this->name = $name;
- }
-
- /**
- * Gets the ID of this object.
- *
- * @return string The object's ID.
- */
- function getId()
- {
- return $this->id;
- }
-
- /**
- * Gets the name of this object.
- *
- * @return string The object name.
- */
- function getName()
- {
- return $this->name;
- }
-
- /**
- * Gets one of the attributes of the object, or null if it isn't defined.
- *
- * @param string $attribute The attribute to get.
- *
- * @return mixed The value of the attribute, or null.
- */
- function get($attribute)
- {
- return isset($this->data[$attribute])
- ? $this->data[$attribute]
- : null;
- }
-
- /**
- * Sets one of the attributes of the object.
- *
- * @param string $attribute The attribute to set.
- * @param mixed $value The value for $attribute.
- */
- function set($attribute, $value)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Save group
- */
- function save()
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- function removeUser($username, $update = true)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
- function addUser($username, $update = true)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-}
+++ /dev/null
-<?php
-/**
- * The Group_hooks:: class provides the Horde groups system with the
- * addition of adding support for hook functions to define if a user
- * is in a group.
- *
- * Copyright 2003-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Jason Rust <jrust@rustyparts.com>
- * @package Horde_Group
- */
-class Group_hooks extends Group {
-
- var $_hookFunction = false;
-
- /**
- * Constructor.
- */
- function Group_hooks($params)
- {
- parent::Group($params);
- Horde::loadConfiguration('hooks.php', null, 'horde');
- $this->_hookFunction = function_exists('_group_hook');
- }
-
- /**
- * Get a list of every group that $user is in.
- *
- * @param string $user The user to get groups for.
- * @param boolean $parentGroups Also return the parents of any groups?
- *
- * @return array An array of all groups the user is in.
- */
- function getGroupMemberships($user, $parentGroups = false)
- {
- $memberships = parent::getGroupMemberships($user, $parentGroups);
- if (!$this->_hookFunction) {
- return $memberships;
- }
-
- $groups = $this->listGroups();
- foreach ($groups as $gid => $groupName) {
- if (empty($memberships[$gid]) && _group_hook($groupName, $user)) {
- $memberships += array($gid => $groupName);
- }
-
- if ($parentGroups) {
- $parents = $this->getGroupParentList($gid);
- if (is_a($parents, 'PEAR_Error')) {
- return $parents;
- }
-
- $memberships += $parents;
- }
- }
-
- return $memberships;
- }
-
- /**
- * Say if a user is a member of a group or not.
- *
- * @param string $user The name of the user.
- * @param integer $gid The ID of the group.
- * @param boolean $subgroups Return true if the user is in any subgroups
- * of $group, also.
- *
- * @return boolean
- */
- function userIsInGroup($user, $gid, $subgroups = true)
- {
- $inGroup = ($this->_hookFunction && _group_hook($this->getGroupName($gid), $user));
- return ($inGroup || parent::userIsInGroup($user, $gid, $subgroups));
- }
-
-}
+++ /dev/null
-<?php
-
-require_once 'Horde/Group/ldap.php';
-
-/**
- * The Group_kolab class provides a Kolab backend for the Horde groups
- * system.
- *
- * FIXME: A better solution would be to let this class rely on
- * Horde/Kolab/LDAP.php.
- *
- * Copyright 2005-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Gunnar Wrobel <wrobel@pardus.de>
- * @package Horde_Group
- */
-class Group_kolab extends Group_ldap {
-
- /**
- * A marker for fatal errors
- */
- var $_error;
-
- /**
- * Constructor.
- */
- function Group_kolab($params)
- {
- if (!function_exists('ldap_connect')) {
- $this->_error = PEAR::raiseError(_("The Kolab group driver requires LDAP support."));
- }
-
- $this->_params = array();
- $this->_params['hostspec'] = $GLOBALS['conf']['kolab']['ldap']['server'];
- $this->_params['basedn'] = $GLOBALS['conf']['kolab']['ldap']['basedn'];
- $this->_params['binddn'] = $GLOBALS['conf']['kolab']['ldap']['phpdn'];
- $this->_params['password'] = $GLOBALS['conf']['kolab']['ldap']['phppw'];
- $this->_params['version'] = 3;
- $this->_params['gid'] = 'cn';
- $this->_params['memberuid'] = 'member';
- $this->_params['attrisdn'] = true;
- $this->_params['filter_type'] = 'objectclass';
- $this->_params['objectclass'] = 'kolabGroupOfNames';
- $this->_params['newgroup_objectclass'] = 'kolabGroupOfNames';
-
- $this->_filter = 'objectclass=' . $this->_params['objectclass'];
-
- $this->__wakeup();
- }
-
- /**
- * Initializes the object.
- */
- function __wakeup()
- {
- foreach (array_keys($this->_groupCache) as $name) {
- $this->_groupCache[$name]->setGroupOb($this);
- }
- }
-
- /**
- * Returns the properties that need to be serialized.
- *
- * @return array List of serializable properties.
- */
- function __sleep()
- {
- $properties = get_object_vars($this);
- unset($properties['_datatree'], $properties['_ds']);
- $properties = array_keys($properties);
- return $properties;
- }
-
-
- /**
- * Returns a new group object.
- *
- * @param string $name The group's name.
- * @param string $parent The group's parent's name.
- *
- * @return Kolab_Group A new group object.
- */
- function &newGroup($name)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Adds a group to the groups system. The group must first be created with
- * Group::newGroup(), and have any initial users added to it, before this
- * function is called.
- *
- * @param Kolab_Group $group The new group object.
- */
- function addGroup($group)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Stores updated data - users, etc. - of a group to the backend system.
- *
- * @param Kolab_Group $group The group to update.
- */
- function updateGroup($group)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Removes a group from the groups system permanently.
- *
- * @param Kolab_Group $group The group to remove.
- * @param boolean $force Force to remove every child.
- */
- function removeGroup($group, $force = false)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Return a Kolab_Group object corresponding to the given dn, with the
- * users and other data retrieved appropriately.
- *
- * @param string $dn The dn of the group to retrieve.
- *
- * @return Kolab_Group The requested group.
- */
- function &getGroupById($dn)
- {
- static $cache = array();
-
- if (!isset($cache[$dn])) {
-
- if (is_a($this->_error, 'PEAR_Error')) {
- return $this->_error;
- }
-
- /* Connect to the LDAP server. */
- $success = $this->_connect();
- if (is_a($success, 'PEAR_Error')) {
- return PEAR::raiseError($success->getMessage());
- }
-
- $search = @ldap_search($this->_ds, $dn, $this->_filter);
- if (!$search) {
- return PEAR::raiseError(_("Could not reach the LDAP server"));
- }
-
- $result = @ldap_get_entries($this->_ds, $search);
- @ldap_close($this->_ds);
- if (!is_array($result) || (count($result) <= 1)) {
- return PEAR::raiseError(_("Empty result"));
- }
-
- $attributes = array();
- for ($i = 0; $i < $result[0]['count']; $i++) {
- if ($result[0][$result[0][$i]]['count'] > 1) {
- $attributes[$result[0][$i]] = array();
- for ($j = 0; $j < $result[0][$result[0][$i]]['count']; $j++) {
- $attributes[$result[0][$i]][] = $result[0][$result[0][$i]][$j];
- }
- } else {
- $attributes[$result[0][$i]] = $result[0][$result[0][$i]][0];
- }
- }
- $attributes['dn'] = $result[0]['dn'];
-
- $group = new Kolab_Group($this->getGroupName($dn));
- $group->_fromAttributes($attributes);
- $group->setGroupOb($this);
- $cache[$dn] = $group;
- }
-
- return $cache[$dn];
- }
-
-
- /**
- * Retrieve the ID of the given group.
- *
- * NOTE: If given a group name, this function can be unreliable if more
- * than one group exists with the same name.
- *
- * @param mixed $group LDAP_Group object, or a group name (string)
- *
- * @return string The group's ID.
- */
- function getGroupId($group)
- {
- static $cache = array();
-
- if (is_a($group, 'Kolab_Group')) {
- return $group->getDn();
- }
-
- if (!isset($cache[$group])) {
-
- if (is_a($this->_error, 'PEAR_Error')) {
- return $this->_error;
- }
-
- $this->_connect();
- $search = @ldap_search($this->_ds, $this->_params['basedn'],
- $this->_params['gid'] . '=' . $group,
- array($this->_params['gid']));
- if (!$search) {
- return PEAR::raiseError(_("Could not reach the LDAP server"));
- }
-
- $result = @ldap_get_entries($this->_ds, $search);
- @ldap_close($this->_ds);
- if (!is_array($result) || (count($result) <= 1)) {
- return PEAR::raiseError(_("Empty result"));
- }
- $cache[$group] = $result[0]['dn'];
- }
-
- return $cache[$group];
- }
-
- /**
- * Get a list of the parents of a child group.
- *
- * @param string $dn The fully qualified group dn
- *
- * @return array Nested array of parents
- */
- function getGroupParents($dn)
- {
- return array();
- }
-
- /**
- * Get the parent of the given group.
- *
- * @param string $dn The dn of the child group.
- *
- * @return string The dn of the parent group.
- */
- function getGroupParent($dn)
- {
- return null;
- }
-
- /**
- * Get a list of parents all the way up to the root object for the given
- * group.
- *
- * @param string $dn The dn of the group.
- *
- * @return array A flat list of all of the parents of the given group,
- * hashed in $dn => $name format.
- */
- function getGroupParentList($dn)
- {
- return array();
- }
-
- /**
- * Tries to find a DN for a given kolab mail address.
- *
- * @param string $mail The mail address to search for.
- *
- * @return string The corresponding dn or false.
- */
- function dnForMail($mail)
- {
- $filter = '(&(objectclass=kolabInetOrgPerson)(mail=' . Horde_Ldap::quote($mail) . '))';
- $search = @ldap_search($this->_ds, $this->_params['basedn'], $filter);
- if (!$search) {
- return PEAR::raiseError(_("Could not reach the LDAP server"));
- }
- $dn = @ldap_first_entry($this->_ds, $search);
- if ($dn) {
- return ldap_get_dn($this->_ds, $dn);
- }
- return PEAR::raiseError(sprintf(_("Error searching for user with the email address \"%s\"!"),
- $mail));
- }
-
- /**
- * Get a list of every group that the given user is a member of.
- *
- * @param string $user The user to get groups for.
- * @param boolean $parentGroups Also return the parents of any groups?
- *
- * @return array An array of all groups the user is in.
- */
- function getGroupMemberships($user, $parentGroups = false)
- {
- static $cache = array();
-
- if (empty($cache[$user])) {
-
- if (is_a($this->_error, 'PEAR_Error')) {
- return $this->_error;
- }
-
- /* Connect to the LDAP server. */
- $success = $this->_connect();
- if (is_a($success, 'PEAR_Error')) {
- return PEAR::raiseError($success->getMessage());
- }
-
- $dn = $this->dnForMail($user);
- if (is_a($dn, 'PEAR_Error')) {
- return $dn;
- }
-
- // Set up search filter
- $filter = '(' . $this->_params['memberuid'] . '=' . $dn . ')';
-
- // Perform search
- $search = @ldap_search($this->_ds, $this->_params['basedn'], $filter);
- if (!$search) {
- return PEAR::raiseError(_("Could not reach the LDAP server"));
- }
-
- $result = @ldap_get_entries($this->_ds, $search);
- @ldap_close($this->_ds);
- if (!is_array($result) || (count($result) <= 1)) {
- return array();
- }
-
- $groups = array();
- $current_charset = Horde_Nls::getCharset();
- for ($i = 0; $i < $result['count']; $i++) {
- $utf8_dn = Horde_String::convertCharset($result[$i]['dn'], 'UTF-8', $current_charset);
- $groups[$utf8_dn] = $this->getGroupName($utf8_dn);
- }
-
- $cache[$user] = $groups;
- }
-
- return $cache[$user];
- }
-
-}
-
-/**
- *
- *
- * @author Ben Chavet <ben@horde.org>
- * @package Horde_Group
- */
-class Kolab_Group extends LDAP_Group {
-
- /**
- * Constructor.
- *
- * @param string $name The name of this group.
- * @param string $parent The dn of the parent of this group.
- */
- function Kolab_Group($name, $parent = null)
- {
- $this->setName($name);
- }
-
- /**
- * Fetch the ID of this group
- *
- * @return string The group's ID
- */
- function getId()
- {
- return $this->getDn();
- }
-
- /**
- * Save any changes to this object to the backend permanently.
- */
- function save()
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Adds a user to this group, and makes sure that the backend is
- * updated as well.
- *
- * @param string $username The user to add.
- */
- function addUser($username, $update = true)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
-
- /**
- * Removes a user from this group, and makes sure that the backend
- * is updated as well.
- *
- * @param string $username The user to remove.
- */
- function removeUser($username, $update = true)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Get all the users recently added or removed from the group.
- */
- function getAuditLog()
- {
- return array();
- }
-
- /**
- * Clears the audit log. To be called after group update.
- */
- function clearAuditLog()
- {
- }
-
- /**
- * Sets the name of this object.
- *
- * @param string $name The name to set this object's name to.
- */
- function getDn()
- {
- return $this->name . ',' . $GLOBALS['conf']['kolab']['ldap']['basedn'];
- }
-
- /**
- * Take in a list of attributes from the backend and map it to our
- * internal data array.
- *
- * @param array $attributes The list of attributes from the backend.
- */
- function _fromAttributes($attributes = array())
- {
- $this->data['users'] = array();
- foreach ($attributes as $key => $value) {
- if (Horde_String::lower($key) == 'member') {
- if (is_array($value)) {
- foreach ($value as $user) {
- $pattern = '/^cn=([^,]+).*$/';
- $results = array();
- preg_match($pattern, $user, $results);
- if (isset($results[1])) {
- $user = $results[1];
- }
- $this->data['users'][$user] = '1';
- }
- } else {
- $pattern = '/^cn=([^,]+).*$/';
- $results = array();
- preg_match($pattern, $value, $results);
- if (isset($results[1])) {
- $value = $results[1];
- }
- $this->data['users'][$value] = '1';
- }
- } elseif ($key == 'mail') {
- $this->data['email'] = $value;
- } else {
- $this->data[$key] = $value;
- }
- }
- }
-
- /**
- * Map this object's attributes from the data array into a format that
- * can be stored in an LDAP entry.
- *
- * @return array The entry array.
- */
- function _toAttributes()
- {
- $attributes = array();
- foreach ($this->data as $key => $value) {
- if ($key == 'users') {
- foreach ($value as $user => $membership) {
- $user = 'cn=' . $user . ',' . $GLOBALS['conf']['kolab']['ldap']['basedn'];
- $attributes['member'][] = $user;
- }
- } elseif ($key == 'email') {
- if (!empty($value)) {
- $attributes['mail'] = $value;
- }
- } elseif ($key != 'dn' && $key != 'member') {
- $attributes[$key] = !empty($value) ? $value : ' ';
- }
- }
-
- return $attributes;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Group_ldap class provides an LDAP backend for the Horde groups
- * system.
- *
- * Copyright 2005-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Ben Chavet <ben@horde.org>
- * @package Horde_Group
- */
-class Group_ldap extends Group {
-
- /**
- * LDAP connection handle
- */
- var $_ds;
-
- /**
- * Local copy of the global $conf['group']['params'] array. Simply
- * for coding convenience.
- */
- var $_params;
-
- /**
- * Generated LDAP filter based on the config parameters
- */
- var $_filter;
-
- /**
- * Constructor.
- */
- function Group_ldap($params)
- {
- $this->_params = $GLOBALS['conf']['group']['params'];
-
- $this->_params['gid'] = Horde_String::lower($this->_params['gid']);
- $this->_params['memberuid'] = Horde_String::lower($this->_params['memberuid']);
- foreach ($this->_params['newgroup_objectclass'] as $key => $val) {
- $this->_params['newgroup_objectclass'][$key] = Horde_String::lower($val);
- }
-
- /* Generate LDAP search filter. */
- if (!empty($this->_params['filter'])) {
- $this->_filter = $this->_params['filter'];
- } elseif (!is_array($this->_params['objectclass'])) {
- $this->_filter = 'objectclass=' . $this->_params['objectclass'];
- } else {
- $this->_filter = '';
- foreach ($this->_params['objectclass'] as $objectclass) {
- $this->_filter = '(&' . $this->_filter;
- $this->_filter .= '(objectclass=' . $objectclass . '))';
- }
- }
-
- $this->_filter = Horde_String::lower($this->_filter);
- }
-
- /**
- * Connects to the LDAP server.
- *
- * @return boolean True or False based on success of connect and bind.
- */
- function _connect()
- {
- /* Connect to the LDAP server. */
- $this->_ds = @ldap_connect($this->_params['hostspec']);
- if (!$this->_ds) {
- return PEAR::raiseError(_("Could not reach the LDAP server"));
- }
-
- if (!ldap_set_option($this->_ds, LDAP_OPT_PROTOCOL_VERSION,
- $this->_params['version'])) {
- Horde::logMessage(
- sprintf('Set LDAP protocol version to %d failed: [%d] %s',
- $this->_params['version'],
- ldap_errno($conn),
- ldap_error($conn),
- __FILE__, __LINE__));
- }
-
- /* Start TLS if we're using it. */
- if (!empty($this->_params['tls'])) {
- if (!@ldap_start_tls($this->_ds)) {
- Horde::logMessage(
- sprintf('STARTTLS failed: [%d] %s',
- @ldap_errno($this->_ds),
- @ldap_error($this->_ds)),
- 'ERR');
- }
- }
-
- if (isset($this->_params['binddn'])) {
- $bind = @ldap_bind($this->_ds, $this->_params['binddn'],
- $this->_params['password']);
- } else {
- $bind = @ldap_bind($this->_ds);
- }
-
- if (!$bind) {
- return PEAR::raiseError(_("Could not bind to LDAP server"));
- }
-
- return true;
- }
-
- /**
- * Recursively deletes $dn. $this->_ds MUST already be connected.
- *
- * @return mixed True if delete was successful, PEAR_Error otherwise.
- */
- function _recursive_delete($dn)
- {
- $search = @ldap_list($this->_ds, $dn, 'objectclass=*', array(''));
- if (!$search) {
- return PEAR::raiseError(_("Could not reach the LDAP server"));
- }
-
- $children = @ldap_get_entries($this->_ds, $search);
- for ($i = 0; $i < $children['count']; $i++) {
- $result = $this->_recursive_delete($children[$i]['dn']);
- if (!$result) {
- return PEAR::raiseError(sprintf(_("Group_ldap: Unable to delete group \"%s\". This is what the server said: %s"), $this->getName($children[$i]['dn']), @ldap_error($this->_ds)));
- }
- }
-
- $result = @ldap_delete($this->_ds, $dn);
- if (!$result) {
- return PEAR::raiseError(sprintf(_("Group_ldap: Unable to delete group \"%s\". This is what the server said: %s"), $dn, @ldap_error($this->_ds)));
- }
-
- return $result;
- }
-
- /**
- * Searches existing groups for the highest gidnumber, and returns
- * one higher.
- */
- function _nextGid()
- {
- /* Connect to the LDAP server. */
- $success = $this->_connect();
- if (is_a($success, 'PEAR_Error')) {
- return PEAR::raiseError($success->getMessage());
- }
-
- $search = @ldap_search($this->_ds, $this->_params['basedn'], $this->_filter);
- if (!$search) {
- return PEAR::raiseError(_("Could not reach the LDAP server"));
- }
-
- $result = @ldap_get_entries($this->_ds, $search);
- @ldap_close($this->_ds);
-
- if (!is_array($result) || (count($result) <= 1)) {
- return 1;
- }
-
- $nextgid = 0;
- for ($i = 0; $i < $result['count']; $i++) {
- if ($result[$i]['gidnumber'][0] > $nextgid) {
- $nextgid = $result[$i]['gidnumber'][0];
- }
- }
-
- return $nextgid + 1;
- }
-
- /**
- * Return a new group object.
- *
- * @param string $name The group's name.
- * @param string $parent The group's parent's ID (DN)
- *
- * @return LDAP_Group A new group object.
- * @throws Horde_Exception
- */
- function &newGroup($name, $parent = null)
- {
- if (empty($name)) {
- return PEAR::raiseError(_("Group names must be non-empty"));
- }
-
- try {
- $entry = Horde::callHook('groupldap', array($name, $parent));
- } catch (Horde_Exception_HookNotSet $e) {
- // Try this simple default and hope it works.
- $entry[$this->_params['gid']] = $name;
- $entry['objectclass'] = $this->_params['newgroup_objectclass'];
- $entry['gidnumber'] = $this->_nextGid();
- }
-
- $group = new LDAP_Group($name, $parent);
- $group->_fromAttributes($entry);
- $group->setGroupOb($this);
- return $group;
- }
-
- /**
- * Return an LDAP_Group object corresponding to the named group, with the
- * users and other data retrieved appropriately.
- *
- * @param string $name The name of the group to retrieve.
- *
- * @return LDAP_Group The requested group.
- */
- function &getGroup($name)
- {
- $dn = $this->getGroupId($name);
- if (is_a($dn, 'PEAR_Error')) {
- return PEAR::raiseError($dn->getMessage());
- }
- $group = &$this->getGroupById($dn);
- return $group;
- }
-
- /**
- * Return an LDAP_Object object corresponding to the given dn, with the
- * users and other data retrieved appropriately.
- *
- * @param string $dn The dn of the group to retrieve.
- *
- * @return LDAP_Object The requested group.
- */
- function &getGroupById($dn)
- {
- static $cache = array();
-
- if (!isset($cache[$dn])) {
- /* Connect to the LDAP server. */
- $success = $this->_connect();
- if (is_a($success, 'PEAR_Error')) {
- return PEAR::raiseError($success->getMessage());
- }
-
- $search = @ldap_search($this->_ds, $dn, $this->_filter);
- if (!$search) {
- return PEAR::raiseError(_("Could not reach the LDAP server"));
- }
-
- $result = @ldap_get_entries($this->_ds, $search);
- @ldap_close($this->_ds);
- if (!is_array($result) || (count($result) <= 1)) {
- return PEAR::raiseError(_("Empty result"));
- }
-
- $attributes = array();
- for ($i = 0; $i < $result[0]['count']; $i++) {
- if ($result[0][$result[0][$i]]['count'] > 1) {
- $attributes[$result[0][$i]] = array();
- for ($j = 0; $j < $result[0][$result[0][$i]]['count']; $j++) {
- $attributes[$result[0][$i]][] = $result[0][$result[0][$i]][$j];
- }
- } else {
- $attributes[$result[0][$i]] = $result[0][$result[0][$i]][0];
- }
- }
- $attributes['dn'] = $result[0]['dn'];
-
- $group = new LDAP_Group($this->getGroupName($dn));
- $group->_fromAttributes($attributes);
- $group->setGroupOb($this);
- $cache[$dn] = $group;
- }
-
- return $cache[$dn];
- }
-
- /**
- * Get a globally unique ID for a group. This really just returns the dn
- * for the group, but is included for compatibility with the Group class.
- *
- * @param LDAP_Object $group The group.
- *
- * @return string a GUID referring to $group.
- */
- function getGUID($group)
- {
- return $group->get('dn');
- }
-
- /**
- * Add a group to the groups system. The group must first be created with
- * Group_ldap::newGroup(), and have any initial users added to it, before
- * this function is called.
- *
- * @param LDAP_Group $group The new group object.
- *
- * @return mixed True if successful, PEAR_Error otherwise.
- */
- function addGroup($group)
- {
- if (!is_a($group, 'DataTreeObject_Group')) {
- return PEAR::raiseError('Groups must be DataTreeObject_Group objects or extend that class.');
- }
-
- /* Connect to the LDAP server. */
- $success = $this->_connect();
- if (is_a($success, 'PEAR_Error')) {
- return PEAR::raiseError($success->getMessage());
- }
-
- $dn = $group->get('dn');
-
- $entry = $group->_toAttributes();
- $success = @ldap_add($this->_ds, $dn, $entry);
-
- if (!$success) {
- return PEAR::raiseError(sprintf(_("Group_ldap: Unable to add group \"%s\". This is what the server said: "), $group->getName()) . @ldap_error($this->_ds));
- }
-
- @ldap_close($this->_ds);
-
- return true;
- }
-
- /**
- * Store updated data - users, etc. - of a group to the backend system.
- *
- * @param LDAP_Object $group The group to update
- *
- * @return mixed True on success, PEAR_Error otherwise.
- *
- * @throws Horde_History_Exception
- * @throws InvalidArgumentException
- */
- function updateGroup($group)
- {
- if (!is_a($group, 'DataTreeObject_Group')) {
- return PEAR::raiseError('Groups must be DataTreeObject_Group objects or extend that class.');
- }
-
- $entry = $group->_toAttributes();
-
- /* Connect to the LDAP server. */
- $success = $this->_connect();
- if (is_a($success, 'PEAR_Error')) {
- return PEAR::raiseError($success->getMessage());
- }
-
- // Do not attempt to change an LDAP object's objectClasses
- unset($entry['objectclass']);
-
- $result = @ldap_modify($this->_ds, $group->getId(), $entry);
- if (!$result) {
- return PEAR::raiseError(sprintf(_("Group_ldap: Unable to update group \"%s\". This is what the server said: %s"), $group->getName(), @ldap_error($this->_ds)));
- }
-
- @ldap_close($this->_ds);
-
- /* Log the update of the group users on the history log. */
- $history = $GLOBALS['injector']->getInstance('Horde_History');
- $guid = $this->getGUID($group);
- foreach ($group->getAuditLog() as $userId => $action) {
- $history->log($guid, array('action' => $action, 'user' => $userId), true);
- }
- $group->clearAuditLog();
-
- /* Log the group modification. */
- $history->log($guid, array('action' => 'modify'), true);
- return $result;
- }
-
- /**
- * Remove a group from the groups system permanently.
- *
- * @param LDAP_Group $group The group to remove.
- * @param boolean $force Recursively delete children groups if true.
- *
- * @return mixed True on success, PEAR_Error otherwise.
- */
- function removeGroup($group, $force = false)
- {
- if (!is_a($group, 'DataTreeObject_Group')) {
- return PEAR::raiseError('Groups must be DataTreeObject_Group objects or extend that class.');
- }
-
- $dn = $group->getId();
-
- /* Connect to the LDAP server. */
- $success = $this->_connect();
- if (is_a($success, 'PEAR_Error')) {
- return PEAR::raiseError($success->getMessage());
- }
-
- if ($force) {
- return $this->_recursive_delete($dn);
- } else {
- $result = @ldap_delete($this->_ds, $dn);
- if (!$result) {
- return PEAR::raiseError(sprintf(_("Group_ldap: Unable to delete group \"%s\". This is what the server said: %s"), $dn, @ldap_error($this->_ds)));
- }
- }
- }
-
- /**
- * Retrieve the name of a group.
- *
- * @param string $dn The dn of the group to retrieve the name for.
- *
- * @return string The group's name.
- */
- function getGroupName($dn)
- {
- $dn = Horde_String::convertCharset($dn, Horde_Nls::getCharset(), 'UTF-8');
- $result = @ldap_explode_dn($dn, 1);
- if ($result === false) {
- return PEAR::raiseError(_("Invalid group ID passed (bad DN syntax)"));
- }
-
- return $result[0];
- }
-
- /**
- * DataTreeObject full names include references to parents, but LDAP does
- * not have this concept. This function simply returns the $group
- * parameter and is included for compatibility with the Group class.
- *
- * @param string $group Group name.
- *
- * @return string $group.
- */
- function getGroupShortName($group)
- {
- return $group;
- }
-
- /**
- * Retrieve the ID of the given group.
- *
- * NOTE: If given a group name, this function can be unreliable if more
- * than one group exists with the same name.
- *
- * @param mixed $group LDAP_Group object, or a group name (string)
- *
- * @return string The group's ID.
- */
- function getGroupId($group)
- {
- static $cache = array();
-
- if (is_a($group, 'LDAP_Group')) {
- return $group->get('dn');
- }
-
- if (!isset($cache[$group])) {
- $this->_connect();
- $search = @ldap_search($this->_ds, $this->_params['basedn'],
- $this->_params['gid'] . '=' . $group,
- array($this->_params['gid']));
- if (!$search) {
- return PEAR::raiseError(_("Could not reach the LDAP server"));
- }
-
- $result = @ldap_get_entries($this->_ds, $search);
- @ldap_close($this->_ds);
- if (!is_array($result) || (count($result) <= 1)) {
- return PEAR::raiseError(_("Empty result"));
- }
- $cache[$group] = $result[0]['dn'];
- }
-
- return $cache[$group];
- }
-
- /**
- * Check if a group exists in the system.
- *
- * @param string $group The group name to check for.
- *
- * @return boolean True if the group exists, False otherwise.
- */
- function exists($group)
- {
- static $cache = array();
-
- if (!isset($cache[$group])) {
- /* Connect to the LDAP server. */
- $success = $this->_connect();
- if (is_a($success, 'PEAR_Error')) {
- return PEAR::raiseError($success->getMessage());
- }
-
- $groupDN = $this->getGroupId($group);
- $group = $this->getGroupShortName($group);
-
- $res = @ldap_compare($this->_ds, $groupDN, $this->_params['gid'], $group);
- if ($res === false) {
- return PEAR::raiseError(sprintf(_("Internal Error: An attribute must ALWAYS match itself: %s"), @ldap_error($this->_ds)));
- }
- // $res is True if the group exists, -1 if not, false never
- $cache[$group] = ($res === true);
- }
-
- return $cache[$group];
- }
-
- /**
- * Get a list of the parents of a child group.
- *
- * @param string $dn The fully qualified group dn
- *
- * @return array Nested array of parents
- */
- function getGroupParents($dn)
- {
- $parent = $this->getGroupParent($dn);
- $parents = array(DATATREE_ROOT => 1);
- while ($parent != DATATREE_ROOT) {
- $parents = array($parent => $parents);
- $parent = $this->getGroupParent($parent);
- }
- return $parents;
- }
-
- /**
- * Get the parent of the given group.
- *
- * @param string $dn The dn of the child group.
- *
- * @return string The dn of the parent group.
- */
- function getGroupParent($dn)
- {
- $result = @ldap_explode_dn($dn, 0);
- if ($result === false) {
- return PEAR::raiseError(_("Invalid group ID passed (bad DN syntax)"));
- }
-
- unset($result['count']);
- unset($result[0]);
- $parent_dn = implode(',', $result);
-
- if (Horde_String::lower($parent_dn) == Horde_String::lower($GLOBALS['conf']['group']['params']['basedn'])) {
- return DATATREE_ROOT;
- } else {
- return $parent_dn;
- }
- }
-
- /**
- * Get a list of parents all the way up to the root object for the given
- * group.
- *
- * @param string $dn The dn of the group.
- *
- * @return array A flat list of all of the parents of the given group,
- * hashed in $dn => $name format.
- */
- function getGroupParentList($dn)
- {
- $result = @ldap_explode_dn($dn, 0);
- if ($result === false) {
- return PEAR::raiseError(_("Invalid group ID passed (bad DN syntax)"));
- }
-
- $num = $result['count'];
- unset($result['count']);
- unset($result[0]);
-
- $count = 0;
- $parents = array();
- $parent_dn = implode(',', $result);
- while ($parent_dn != $this->_params['basedn'] && $count++ != $num) {
- $parents[$parent_dn] = $this->getGroupName($parent_dn);
- unset($result[$count]);
- $parent_dn = implode(',', $result);
- }
- $parents[DATATREE_ROOT] = DATATREE_ROOT;
-
- return $parents;
- }
-
- /**
- * Get a list of every group, in the format dn => groupname.
- *
- * @param boolean $refresh If true, the cached value is ignored and the
- * group list is refreshed from the group backend.
- *
- * @return array dn => groupname hash.
- */
- function listGroups($refresh = false)
- {
- static $groups;
-
- if ($refresh || is_null($groups)) {
- /* Connect to the LDAP server. */
- $success = $this->_connect();
- if (is_a($success, 'PEAR_Error')) {
- return PEAR::raiseError($success->getMessage());
- }
-
- $search = @ldap_search($this->_ds, $this->_params['basedn'], $this->_filter, array($this->_params['gid']));
- if (!$search) {
- return PEAR::raiseError(_("Could not reach the LDAP server"));
- }
-
- @ldap_sort($this->_ds, $search, $this->_params['gid']);
-
- $result = @ldap_get_entries($this->_ds, $search);
- @ldap_close($this->_ds);
- if (!is_array($result) || (count($result) <= 1)) {
- return array();
- }
-
- $groups = array();
- for ($i = 0; $i < $result['count']; $i++) {
- $groups[$result[$i]['dn']] = $this->getGroupName($result[$i]['dn']);
- }
- }
-
- return $groups;
- }
-
- /**
- * Get a list of every user that is part of the specified group and any
- * of its subgroups.
- *
- * @param string $dn The dn of the parent group.
- *
- * @return array The complete user list.
- */
- function listAllUsers($dn)
- {
- static $cache = array();
-
- if (!isset($cache[$dn])) {
- $success = $this->_connect();
- if (is_a($success, 'PEAR_Error')) {
- return PEAR::raiseError($success->getMessage());
- }
-
- $search = @ldap_search($this->_ds, $dn, $this->_filter);
- if (!$search) {
- return PEAR::raiseError(sprintf(_("Could not reach the LDAP server: %s"), @ldap_error($this->_ds)));
- }
-
- $result = @ldap_get_entries($this->_ds, $search);
- @ldap_close($this->_ds);
- if (!is_array($result) || (count($result) <= 1)) {
- // Not an error, we just don't have any users in this group.
- return array();
- }
-
- $users = array();
- for ($i = 0; $i < $result['count']; $i++) {
- $users = array_merge($users, $this->listUsers($result[$i]['dn']));
- }
-
- $cache[$dn] = array_keys(array_flip($users));
- }
-
- return $cache[$dn];
- }
-
- /**
- * Get a list of every group that the given user is a member of.
- *
- * @param string $user The user to get groups for.
- * @param boolean $parentGroups Also return the parents of any groups?
- *
- * @return array An array of all groups the user is in.
- */
- function getGroupMemberships($user, $parentGroups = false)
- {
- static $cache = array();
-
- if (empty($cache[$user])) {
- /* Connect to the LDAP server. */
- $success = $this->_connect();
- if (is_a($success, 'PEAR_Error')) {
- return PEAR::raiseError($success->getMessage());
- }
-
- // Set up search filter
- $filter = '(' . $this->_params['memberuid'] . '=';
- if ($GLOBALS['conf']['group']['params']['attrisdn']) {
- $filter .= $GLOBALS['conf']['auth']['params']['uid'] . '=';
- }
- $filter .= $user;
- if ($GLOBALS['conf']['group']['params']['attrisdn']) {
- $filter .= ',' . $GLOBALS['conf']['auth']['params']['basedn'];
- }
- $filter .= ')';
-
- // Perform search
- $search = @ldap_search($this->_ds, $this->_params['basedn'], $filter);
- if (!$search) {
- return PEAR::raiseError(_("Could not reach the LDAP server"));
- }
-
- $result = @ldap_get_entries($this->_ds, $search);
- @ldap_close($this->_ds);
- if (!is_array($result) || (count($result) <= 1)) {
- return array();
- }
-
- $groups = array();
- $current_charset = Horde_Nls::getCharset();
- for ($i = 0; $i < $result['count']; $i++) {
- $utf8_dn = Horde_String::convertCharset($result[$i]['dn'], 'UTF-8', $current_charset);
- $groups[$utf8_dn] = $this->getGroupName($utf8_dn);
- }
-
- $cache[$user] = $groups;
- }
-
- return $cache[$user];
- }
-
- /**
- * Returns the tree depth of the given group, relative to the base dn.
- * 0 is returned for any object directly below the base dn.
- *
- * @param string $dn The dn of the object.
- *
- * @return intenger The tree depth of the group.
- */
- function getLevel($dn)
- {
- $base = @ldap_explode_dn($this->_params['basedn'], 0);
- if ($base === false) {
- return PEAR::raiseError(_("Invalid basedn configured"));
- }
-
- $group = @ldap_explode_dn($dn, 0);
- if ($group === false) {
- return PEAR::raiseError(_("Invalid group ID passed (bad DN syntax)"));
- }
-
- return $group['count'] - $base['count'] - 1;
- }
-
-}
-
-/**
- * Extension of the DataTreeObject_Group class for storing group information
- * in an LDAP directory.
- *
- * @author Ben Chavet <ben@horde.org>
- * @package Horde_Group
- */
-class LDAP_Group extends DataTreeObject_Group {
-
- /**
- * Constructor.
- *
- * @param string $name The name of this group.
- * @param string $parent The dn of the parent of this group.
- */
- function LDAP_Group($name, $parent = null)
- {
- parent::DataTreeObject_Group($name);
- if ($parent) {
- $this->data['dn'] = Horde_String::lower($GLOBALS['conf']['group']['params']['gid']) . '=' . $name . ',' . $parent;
- } else {
- $this->data['dn'] = Horde_String::lower($GLOBALS['conf']['group']['params']['gid']) . '=' . $name .
- ',' . Horde_String::lower($GLOBALS['conf']['group']['params']['basedn']);
- }
- }
-
- /**
- * Get a list of every user that is part of this group (and only
- * this group).
- *
- * @return array The user list.
- */
- function listUsers()
- {
- return $this->_groupOb->listUsers($this->data['dn']);
- }
-
- /**
- * Get a list of every user that is a member of this group and any of
- * it's subgroups.
- *
- * @return array The complete user list.
- */
- function listAllUsers()
- {
- return $this->_groupOb->listAllUsers($this->data['dn']);
- }
-
- /**
- * Take in a list of attributes from the backend and map it to our
- * internal data array.
- *
- * @param array $attributes The list of attributes from the backend.
- */
- function _fromAttributes($attributes = array())
- {
- $this->data['users'] = array();
- foreach ($attributes as $key => $value) {
- if (Horde_String::lower($key) == Horde_String::lower($GLOBALS['conf']['group']['params']['memberuid'])) {
- if (is_array($value)) {
- foreach ($value as $user) {
- if ($GLOBALS['conf']['group']['params']['attrisdn']) {
- $pattern = '/^' . $GLOBALS['conf']['auth']['params']['uid'] . '=([^,]+).*$/';
- $results = array();
- preg_match($pattern, $user, $results);
- if (isset($results[1])) {
- $user = $results[1];
- }
- }
- $this->data['users'][$user] = '1';
- }
- } else {
- if ($GLOBALS['conf']['group']['params']['attrisdn']) {
- $pattern = '/^' . $GLOBALS['conf']['auth']['params']['uid'] . '=([^,]+).*$/';
- $results = array();
- preg_match($pattern, $value, $results);
- if (isset($results[1])) {
- $value = $results[1];
- }
- }
- $this->data['users'][$value] = '1';
- }
- } elseif ($key == 'mail') {
- $this->data['email'] = $value;
- } else {
- $this->data[$key] = $value;
- }
- }
- }
-
- /**
- * Map this object's attributes from the data array into a format that
- * can be stored in an LDAP entry.
- *
- * @return array The entry array.
- */
- function _toAttributes()
- {
- $attributes = array();
- foreach ($this->data as $key => $value) {
- if ($key == 'users') {
- foreach ($value as $user => $membership) {
- if ($GLOBALS['conf']['group']['params']['attrisdn']) {
- $user = $GLOBALS['conf']['auth']['params']['uid'] .
- '=' . $user . ',' . $GLOBALS['conf']['auth']['params']['basedn'];
- }
- $attributes[Horde_String::lower($GLOBALS['conf']['group']['params']['memberuid'])][] = $user;
- }
- } elseif ($key == 'email') {
- if (!empty($value)) {
- $attributes['mail'] = $value;
- }
- } elseif ($key != 'dn' && $key != Horde_String::lower($GLOBALS['conf']['group']['params']['memberuid'])) {
- $attributes[$key] = !empty($value) ? $value : ' ';
- }
- }
-
- return $attributes;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Group:: class provides the Horde groups system.
- *
- * Copyright 2008-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Duck <duck@obala.net>
- * @package Horde_Group
- */
-class Group_mock extends Group {
-
- /**
- * Constructor.
- */
- function Group_mock()
- {
- }
-
- /**
- * Initializes the object.
- */
- function __wakeup()
- {
- }
-
- /**
- * Returns a new group object.
- *
- * @param string $name The group's name.
- * @param string $parent The group's parent's name.
- *
- * @return DataTreeObject_Group A new group object.
- */
- function &newGroup($name, $parent = GROUP_ROOT)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Returns a DataTreeObject_Group object corresponding to the named group,
- * with the users and other data retrieved appropriately.
- *
- * @param string $name The name of the group to retrieve.
- */
- function &getGroup($name)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Returns a DataTreeObject_Group object corresponding to the given unique
- * ID, with the users and other data retrieved appropriately.
- *
- * @param integer $cid The unique ID of the group to retrieve.
- */
- function &getGroupById($cid)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Adds a group to the groups system. The group must first be created with
- * Group::newGroup(), and have any initial users added to it, before this
- * function is called.
- *
- * @param DataTreeObject_Group $group The new group object.
- */
- function addGroup($group)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Stores updated data - users, etc. - of a group to the backend system.
- *
- * @param DataTreeObject_Group $group The group to update.
- */
- function updateGroup($group)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Removes a group from the groups system permanently.
- *
- * @param DataTreeObject_Group $group The group to remove.
- * @param boolean $force Force to remove every child.
- */
- function removeGroup($group, $force = false)
- {
- return PEAR::raiseError(_("Unsupported"));
- }
-
- /**
- * Retrieves the name of a group.
- *
- * @param integer|DataTreeObject_Group $gid The id of the group or the
- * group object to retrieve the
- * name for.
- *
- * @return string The group's name.
- */
- function getGroupName($gid)
- {
- return '';
- }
-
- /**
- * Strips all parent references off of the given group name.
- *
- * @param string $group Name of the group.
- *
- * @return The name of the group without parents.
- */
- function getGroupShortName($group)
- {
- return '';
- }
-
- /**
- * Retrieves the ID of a group.
- *
- * @param string|DataTreeObject_Group $group The group name or object to
- * retrieve the ID for.
- *
- * @return integer The group's ID.
- */
- function getGroupId($group)
- {
- return '';
- }
-
- /**
- * Check if a group exists in the system.
- *
- * @param string $group The group to check.
- *
- * @return boolean True if the group exists, false otherwise.
- */
- function exists($group)
- {
- return false;
- }
-
- /**
- * Returns a tree of the parents of a child group.
- *
- * @param integer $gid The id of the child group.
- *
- * @return array The group parents tree, with groupnames as the keys.
- */
- function getGroupParents($gid)
- {
- return array();
- }
-
- /**
- * Returns the single parent ID of the given group.
- *
- * @param integer $gid The DataTree ID of the child group.
- *
- * @return integer The parent of the given group.
- */
- function getGroupParent($gid)
- {
- return null;
- }
-
- /**
- * Returns a flat list of the parents of a child group
- *
- * @param integer $gid The id of the group.
- *
- * @return array A flat list of all of the parents of $group, hashed in
- * $id => $name format.
- */
- function getGroupParentList($gid)
- {
- return array();
- }
-
- /**
- * Returns a list of all groups, in the format id => groupname.
- *
- * @param boolean $refresh If true, the cached value is ignored and the
- * group list is refreshed from the group backend.
- *
- * @return array ID => groupname hash.
- */
- function listGroups($refresh = false)
- {
- return array();
- }
-
- /**
- * Get a list of every user that is a part of this group ONLY.
- *
- * @param integer $gid The ID of the group.
- *
- * @return array The user list.
- */
- function listUsers($gid)
- {
- return array();
- }
-
- /**
- * Get a list of every user that is part of the specified group
- * and any of its subgroups.
- *
- * @param integer $group The ID of the parent group.
- *
- * @return array The complete user list.
- */
- function listAllUsers($gid)
- {
- return array();
- }
-
- /**
- * Get a list of every group that $user is in.
- *
- * @param string $user The user to get groups for.
- * @param boolean $parentGroups Also return the parents of any groups?
- *
- * @return array An array of all groups the user is in.
- */
- function getGroupMemberships($user, $parentGroups = false)
- {
- return array();
- }
-
- /**
- * Say if a user is a member of a group or not.
- *
- * @param string $user The name of the user.
- * @param integer $gid The ID of the group.
- * @param boolean $subgroups Return true if the user is in any subgroups
- * of group with ID $gid, also.
- *
- * @return boolean
- */
- function userIsInGroup($user, $gid, $subgroups = true)
- {
- return false;
- }
-
- /**
- * Returns the nesting level of the given group. 0 is returned for any
- * object directly below GROUP_ROOT.
- *
- * @param integer $gid The ID of the group.
- *
- * @return The nesting level of the group.
- */
- function getLevel($gid)
- {
- return 0;
- }
-
- /**
- * Stores the object in the session cache.
- */
- function shutdown()
- {
- }
-
- /**
- * Returns the properties that need to be serialized.
- *
- * @return array List of serializable properties.
- */
- function __sleep()
- {
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Group:: class provides the Horde groups system.
- *
- * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Duck <duck@obala.net>
- * @package Horde_Group
- */
-class Group_sql extends Group {
-
- /**
- * Boolean indicating whether or not we're connected to the SQL server.
- *
- * @var boolean
- */
- var $_connected = false;
-
- /**
- * Handle for the current database connection.
- *
- * @var DB
- */
- var $_db;
-
- /**
- * Handle for the current database connection, used for writing. Defaults
- * to the same handle as $db if a separate write database is not required.
- *
- * @var DB
- */
- var $_write_db;
-
- /**
- * Constructor.
- */
- function Group_sql($params)
- {
- $this->_params = $params;
- }
-
- /**
- * Initializes the object.
- */
- function __wakeup()
- {
- }
-
- /**
- * Returns the properties that need to be serialized.
- *
- * @return array List of serializable properties.
- */
- function __sleep()
- {
- }
-
- /**
- * Stores the object in the session cache.
- */
- function shutdown()
- {
- }
-
- /**
- * Replace all occurences of ':' in an object name with '.'.
- *
- * @param string $name The name of the object.
- *
- * @return string The encoded name.
- */
- function encodeName($name)
- {
- return str_replace(':', '.', $name);
- }
-
- /**
- * Returns a new group object.
- *
- * @param string $name The group's name.
- * @param string $parent The group's parent's name.
- *
- * @return SQLObject_Group A new group object.
- */
- function &newGroup($name, $parent = GROUP_ROOT)
- {
- if (empty($name)) {
- return PEAR::raiseError(_("Group names must be non-empty"));
- }
-
- if ($parent != GROUP_ROOT) {
- $name = $this->getGroupName($parent) . ':' . $this->encodeName($name);
- }
-
- $group = new SQLObject_Group($name);
- $group->setGroupOb($this);
- return $group;
- }
-
- /**
- * Returns a SQLObject_Group object corresponding to the named group,
- * with the users and other data retrieved appropriately.
- *
- * @param string $name The name of the group to retrieve.
- */
- function &getGroup($name)
- {
- if (!isset($this->_groupCache[$name])) {
- $this->_connect();
- $sql = 'SELECT group_uid, group_email FROM horde_groups WHERE group_name = ?';
- $group = $this->_db->getRow($sql, array($name), DB_FETCHMODE_ASSOC);
-
- if (is_a($group, 'PEAR_Error')) {
- return $group;
- } elseif (empty($group)) {
- return PEAR::raiseError($name . ' does not exist');
- }
-
- $sql = 'SELECT user_uid FROM horde_groups_members '
- . ' WHERE group_uid = ? ORDER BY user_uid ASC';
- $users = $this->_db->getCol($sql, 0, array($group['group_uid']));
- if (is_a($users, 'PEAR_Error')) {
- return $users;
- }
-
- $object = new SQLObject_Group($name);
- $object->id = $group['group_uid'];
- $object->data['email'] = $group['group_email'];
-
- if (!empty($users)) {
- $object->data['users'] = array_flip($users);
- }
-
- $this->_groupCache[$name] = $object;
- $this->_groupCache[$name]->setGroupOb($this);
- $this->_groupMap[$this->_groupCache[$name]->getId()] = $name;
- }
-
- return $this->_groupCache[$name];
- }
-
- /**
- * Returns a SQLObject_Group object corresponding to the given unique
- * ID, with the users and other data retrieved appropriately.
- *
- * @param integer $cid The unique ID of the group to retrieve.
- */
- function &getGroupById($cid)
- {
- if (isset($this->_groupMap[$cid])) {
- return $this->_groupCache[$this->_groupMap[$cid]];
- }
-
- $this->_connect();
- $sql = 'SELECT group_name, group_email FROM horde_groups WHERE group_uid = ?';
- $row = $this->_db->getRow($sql, array($cid), DB_FETCHMODE_ASSOC);
-
- if (is_a($row, 'PEAR_Error')) {
- return $row;
- } elseif (empty($row)) {
- return PEAR::raiseError($cid . ' does not exist');
- }
-
- $sql = 'SELECT user_uid FROM horde_groups_members '
- . ' WHERE group_uid = ? ORDER BY user_uid ASC';
- $users = $this->_db->getCol($sql, 0, array($cid));
- if (is_a($users, 'PEAR_Error')) {
- return $users;
- }
-
- $group = new SQLObject_Group($row['group_name']);
- $group->id = $cid;
- $group->data['email'] = $row['group_email'];
-
- if (!empty($users)) {
- $group->data['users'] = array_flip($users);
- }
-
- $group->setGroupOb($this);
- $name = $group->getName();
- $this->_groupCache[$name] = &$group;
- $this->_groupMap[$cid] = $name;
-
- return $group;
- }
-
- /**
- * Adds a group to the groups system. The group must first be created with
- * Group::newGroup(), and have any initial users added to it, before this
- * function is called.
- *
- * @param SQLObject_Group $group The new group object.
- *
- * @throws Horde_History_Exception
- * @throws InvalidArgumentException
- */
- function addGroup(&$group)
- {
- if (!is_a($group, 'SQLObject_Group')) {
- return PEAR::raiseError('Groups must be SQLObject_Group objects or extend that class.');
- }
-
- $this->_connect();
- $group->setGroupOb($this);
- $name = $group->getName();
-
- $email = isset($group->data['email']) ? $group->data['email'] : '';
- $group_id = $this->_write_db->nextId('horde_groups');
- if (is_a($group_id, 'PEAR_Error')) {
- return $group_id;
- }
-
- $group->id = $group_id;
- $query = 'INSERT INTO horde_groups (group_uid, group_name, group_parents, group_email) VALUES (?, ?, ?, ?)';
- $result = $this->_write_db->query($query, array($group->id, $name, '', $email));
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- if (!empty($group->data['users'])) {
- $query = 'INSERT INTO horde_groups_members (group_uid, user_uid)'
- .' VALUES (' . (int)$group->id . ', ?)';
- $sth = $this->_write_db->prepare($query);
- $result = $this->_write_db->executeMultiple($sth, $group->data['users']);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
- }
-
- $this->_groupCache[$name] = &$group;
- $this->_groupMap[$group_id] = $name;
- if (isset($this->_groupList)) {
- $this->_groupList[$group_id] = $name;
- }
-
- /* Log the addition of the group in the history log. */
- $GLOBALS['injector']->getInstance('Horde_History')->log($this->getGUID($group), array('action' => 'add'), true);
-
- return $result;
- }
-
- /**
- * Stores updated data - users, etc. - of a group to the backend system.
- *
- * @param SQLObject_Group $group The group to update.
- *
- * @throws Horde_History_Exception
- * @throws InvalidArgumentException
- */
- function updateGroup($group)
- {
- if (!is_a($group, 'SQLObject_Group')) {
- return PEAR::raiseError('Groups must be SQLObject_Group objects or extend that class.');
- }
-
- $this->_connect();
-
- $query = 'UPDATE horde_groups SET group_email = ? WHERE group_uid = ?';
- $result = $this->_write_db->query($query, array($this->data['email'], $this->id));
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- $query = 'DELETE FROM horde_groups_members WHERE group_uid = ?';
- $result = $this->_write_db->query($query, array($this->id));
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- $query = 'INSERT INTO horde_groups_members (group_uid, user_uid)'
- .' VALUES (' . (int)$this->id . ', ?)';
- $sth = $this->_write_db->prepare($query);
- $result = $this->_groupOb->_write_db->executeMultiple($sth, $this->data['users']);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- $this->_groupCache[$group->getName()] = &$group;
-
- /* Log the update of the group users on the history log. */
- $history = $GLOBALS['injector']->getInstance('Horde_History');
- $guid = $this->getGUID($group);
- foreach ($group->getAuditLog() as $userId => $action) {
- $history->log($guid, array('action' => $action, 'user' => $userId), true);
- }
-
- $group->clearAuditLog();
-
- /* Log the group modification. */
- $history->log($guid, array('action' => 'modify'), true);
- return $result;
- }
-
- /**
- * Removes a group from the groups system permanently.
- *
- * @param SQLObject_Group $group The group to remove.
- * @param boolean $force Force to remove every child.
- *
- * @throws Horde_History_Exception
- * @throws InvalidArgumentException
- */
- function removeGroup($group, $force = false)
- {
- if (!is_a($group, 'SQLObject_Group')) {
- return PEAR::raiseError('Groups must be SQLObject_Group objects or extend that class.');
- }
-
- $this->_connect();
- $id = $group->getId();
- $name = $group->getName();
- unset($this->_groupMap[$id]);
- if (isset($this->_groupList)) {
- unset($this->_groupList[$id]);
- }
- unset($this->_groupCache[$name]);
-
- $GLOBALS['injector']->getInstance('Horde_History')->log($this->getGUID($group), array('action' => 'delete'), true);
-
- $query = 'DELETE FROM horde_groups_members WHERE group_uid = ?';
- $result = $this->_write_db->query($query, array($id));
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- $query = 'DELETE FROM horde_groups WHERE group_uid = ?';
- $result = $this->_write_db->query($query, array($id));
- if (!$force || is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- $query = 'DELETE FROM horde_groups WHERE group_name LIKE ?';
- return $this->_write_db->query($query, array($name . ':%'));
- }
-
- /**
- * Retrieves the name of a group.
- *
- * @param integer|SQLObject_Group $gid The id of the group or the
- * group object to retrieve the
- * name for.
- *
- * @return string The group's name.
- */
- function getGroupName($gid)
- {
- if (is_a($gid, 'SQLObject_Group')) {
- $gid = $gid->getId();
- }
-
- if (isset($this->_groupMap[$gid])) {
- return $this->_groupMap[$gid];
- }
- if (isset($this->_groupList[$gid])) {
- return $this->_groupList[$gid];
- }
-
- $this->_connect();
- $query = 'SELECT group_name FROM horde_groups WHERE group_uid = ?';
- return $this->_db->getOne($query, $gid);
- }
-
- /**
- * Strips all parent references off of the given group name.
- *
- * @param string $group Name of the group.
- *
- * @return The name of the group without parents.
- */
- function getGroupShortName($group)
- {
- /* If there are several components to the name, explode and get the
- * last one, otherwise just return the name. */
- if (strpos($group, ':') !== false) {
- $name = explode(':', $group);
- return array_pop($name);
- }
-
- return $group;
- }
-
- /**
- * Retrieves the ID of a group.
- *
- * @param string|SQLObject_Group $group The group name or object to
- * retrieve the ID for.
- *
- * @return integer The group's ID.
- */
- function getGroupId($group)
- {
- if (is_a($group, 'SQLObject_Group')) {
- return $group->getId();
- }
-
- $id = array_search($group, $this->_groupMap);
- if ($id !== false) {
- return $id;
- }
- if (isset($this->_groupList)) {
- $id = array_search($group, $this->_groupList);
- if ($id !== false) {
- return $id;
- }
- }
-
- $this->_connect();
- $query = 'SELECT group_uid FROM horde_groups WHERE group_name = ?';
- return $this->_db->getOne($query, $group);
- }
-
- /**
- * Check if a group exists in the system.
- *
- * @param string $group The group to check.
- *
- * @return boolean True if the group exists, false otherwise.
- */
- function exists($group)
- {
- if (isset($this->_groupCache[$group]) ||
- (isset($this->_groupList) &&
- array_search($group, $this->_groupList) !== false)) {
- return true;
- }
-
- $this->_connect();
- $query = 'SELECT COUNT(*) FROM horde_groups WHERE group_name = ?';
- return (bool)$this->_db->getOne($query, $group);
- }
-
- /**
- * Returns a tree of the parents of a child group.
- *
- * @param integer $gid The id of the child group.
- *
- * @return array The group parents tree, with groupnames as the keys.
- */
- function getGroupParents($gid)
- {
- if (!isset($this->_parentTree[$gid])) {
- $name = $this->getGroupName($gid);
- $this->_connect();
- $parents = $this->_getGroupParents($name);
- if (is_a($parents, 'PEAR_Error')) {
- return $parents;
- }
-
- $this->_parentTree[$gid] = $parents;
- }
-
- return $this->_parentTree[$gid];
- }
-
- /**
- * Returns a list of parent permissions.
- *
- * @param string $child The name of the child to retrieve parents for.
- *
- * @return array A hash with all parents in a tree format.
- */
- function _getGroupParents($child)
- {
- if (($pos = strrpos($child, ':')) !== false) {
- $child = substr($child, 0, $pos);
- }
-
- return $this->_getParents($child);
- }
-
- /**
- */
- function _getParents($parents)
- {
- $mother = array();
- if (!empty($parents)) {
- $pname = $parents;
- $parents = substr($parents, 0, strrpos($parents, ':'));
- $mother[$pname] = $this->_getParents($parents);
- } else {
- return array(GROUP_ROOT => true);
- }
-
- return $mother;
- }
-
- /**
- * Returns the single parent ID of the given group.
- *
- * @param integer $gid The ID of the child group.
- *
- * @return integer The parent of the given group.
- */
- function getGroupParent($gid)
- {
- if (!isset($this->_groupParents[$gid])) {
- $this->_connect();
-
- $name = $this->getGroupName($gid);
- if (is_a($name, 'PEAR_Error')) {
- return $name;
- }
-
- if (($pos = strrpos($name, ':')) !== false) {
- $this->_groupParents[$gid] = $this->getGroupId(substr($name, 0, $pos));
- } else {
- $this->_groupParents[$gid] = GROUP_ROOT;
- }
- }
-
- return $this->_groupParents[$gid];
- }
-
- /**
- * Returns a flat list of the parents of a child group
- *
- * @param integer $gid The id of the group.
- *
- * @return array A flat list of all of the parents of $group, hashed in
- * $id => $name format.
- */
- function getGroupParentList($gid)
- {
- if (!isset($this->_groupParentList[$gid])) {
- $name = $this->getGroupName($gid);
- $pos = strpos($name, ':');
- if ($pos == false) {
- $this->_groupParentList[$gid] = array();
- return $this->_groupParentList[$gid];
- }
-
- $parents = array();
- while ($pos) {
- $name = substr($name, 0, $pos);
- $parents[] = $name;
- $pos = strpos($name, ':');
- }
-
- $query = 'SELECT group_uid, group_name FROM horde_groups '
- . ' WHERE group_name IN (' . str_repeat('?, ', count($parents) - 1) . '?) ';
- $parents = $this->_db->getAssoc($query, false, $parents);
- if (is_a($parents, 'PEAR_Error')) {
- return $parents;
- }
-
- $this->_groupParentList[$gid] = $parents;
- }
-
- return $this->_groupParentList[$gid];
- }
-
- /**
- * Returns a flat list of the parents of a child group
- *
- * @param integer $gid The id of the group.
- *
- * @return array A flat list of all of the parents of $group, hashed in
- * $id => $name format.
- */
- function _getGroupParentNameList($name)
- {
- $parents = array();
-
- while ($pos) {
- $name = substr($name, 0, $pos);
- $parents[] = $name;
- $pos = strpos($name, ':');
- }
-
- return $parents;
- }
-
- /**
- * Returns a list of all groups, in the format id => groupname.
- *
- * @param boolean $refresh If true, the cached value is ignored and the
- * group list is refreshed from the group backend.
- *
- * @return array ID => groupname hash.
- */
- function listGroups($refresh = false)
- {
- if ($refresh || !isset($this->_groupList)) {
- $this->_connect();
- $sql = 'SELECT group_uid, group_name FROM horde_groups ORDER BY group_uid';
- $this->_groupList = $this->_db->getAssoc($sql);
- }
-
- return $this->_groupList;
- }
-
- /**
- * Get a list of every user that is part of the specified group
- * and any of its subgroups.
- *
- * @param integer $group The ID of the parent group.
- *
- * @return array The complete user list.
- */
- function listAllUsers($gid)
- {
- if (!isset($this->_subGroups[$gid])) {
- // Get a list of every group that is a sub-group of $group.
- $name = $this->getGroupName($gid);
- $query = 'SELECT group_uid FROM horde_groups WHERE group_name LIKE ?';
- $parents = $this->_db->getCol($query, 0, array($name . ':%'));
- $this->_subGroups[$gid] = $parents;
- $this->_subGroups[$gid][] = $gid;
- }
-
- $users = array();
- foreach ($this->_subGroups[$gid] as $groupId) {
- $users = array_merge($users, $this->listUsers($groupId));
- }
-
- return array_values(array_flip(array_flip($users)));
- }
-
- /**
- * Get a list of every group that $user is in.
- *
- * @param string $user The user to get groups for.
- * @param boolean $parentGroups Also return the parents of any groups?
- *
- * @return array An array of all groups the user is in.
- */
- function getGroupMemberships($user, $parentGroups = false)
- {
- if (isset($_SESSION['horde']['groups']['m'][$user][$parentGroups])) {
- return $_SESSION['horde']['groups']['m'][$user][$parentGroups];
- }
-
- $this->_connect();
-
- $sql = 'SELECT g.group_uid AS group_uid, g.group_name AS group_name FROM horde_groups g, horde_groups_members m '
- . ' WHERE m.user_uid = ? AND g.group_uid = m.group_uid ORDER BY g.group_name';
- $result = $this->_db->query($sql, $user);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- $groups = array();
- while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC)) {
- $groups[(int)$row['group_uid']] = $this->getGroupShortName($row['group_name']);
- }
-
- if ($parentGroups) {
- foreach ($groups as $id => $g) {
- $parents = $this->getGroupParentList($id);
- if (is_a($parents, 'PEAR_Error')) {
- return $parents;
- }
- $groups += $parents;
- }
- }
-
- $_SESSION['horde']['groups']['m'][$user][$parentGroups] = $groups;
- return $groups;
- }
-
- /**
- * Say if a user is a member of a group or not.
- *
- * @param string $user The name of the user.
- * @param integer $gid The ID of the group.
- * @param boolean $subgroups Return true if the user is in any subgroups
- * of group with ID $gid, also.
- *
- * @return boolean
- */
- function userIsInGroup($user, $gid, $subgroups = true)
- {
- if (isset($_SESSION['horde']['groups']['i'][$user][$subgroups][$gid])) {
- return $_SESSION['horde']['groups']['i'][$user][$subgroups][$gid];
- }
-
- if ($subgroups) {
- $groups = $this->getGroupMemberships($user, true);
- if (is_a($groups, 'PEAR_Error')) {
- Horde::logMessage($groups, 'ERR');
- return false;
- }
-
- $result = !empty($groups[$gid]);
- } else {
- $this->_connect();
- $query = 'SELECT COUNT(*) FROM horde_groups_members WHERE group_uid = ? AND user_uid = ?';
- $result = $this->_db->getOne($query, array($gid, $user));
-
- }
-
- $_SESSION['horde']['groups']['i'][$user][$subgroups][$gid] = (bool)$result;
- return (bool)$result;
- }
-
- /**
- * Attempts to open a persistent connection to the sql server.
- *
- * @return boolean True on success.
- * @throws Horde_Exception
- */
- function _connect()
- {
- if ($this->_connected) {
- return true;
- }
- if (!isset($this->_params['database'])) {
- $this->_params['database'] = '';
- }
- if (!isset($this->_params['username'])) {
- $this->_params['username'] = '';
- }
- if (!isset($this->_params['hostspec'])) {
- $this->_params['hostspec'] = '';
- }
-
- /* Connect to the sql server using the supplied parameters. */
- require_once 'DB.php';
- $this->_write_db = DB::connect($this->_params,
- array('persistent' => !empty($this->_params['persistent']),
- 'ssl' => !empty($this->_params['ssl'])));
- if (is_a($this->_write_db, 'PEAR_Error')) {
- throw new Horde_Exception_Prior($this->_write_db);
- }
-
- /* Set DB portability options. */
- switch ($this->_write_db->phptype) {
- case 'mssql':
- $this->_write_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
- break;
- default:
- $this->_write_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
- }
-
- /* Check if we need to set up the read DB connection seperately. */
- if (!empty($this->_params['splitread'])) {
- $params = array_merge($this->_params, $this->_params['read']);
- $this->_db = DB::connect($params,
- array('persistent' => !empty($params['persistent']),
- 'ssl' => !empty($params['ssl'])));
- if (is_a($this->_db, 'PEAR_Error')) {
- throw new Horde_Exception_Prior($this->_db);
- }
-
- /* Set DB portability options. */
- switch ($this->_db->phptype) {
- case 'mssql':
- $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
- break;
- default:
- $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
- }
- } else {
- /* Default to the same DB handle for the writer too. */
- $this->_db = $this->_write_db;
- }
-
- $this->_connected = true;
- return true;
- }
-
-}
-
-/**
- * Extension of the SQLObject class for storing Group information
- * in the Categories driver. If you want to store specialized Group
- * information, you should extend this class instead of extending
- * SQLObject directly.
- *
- * @author Duck <duck@obala.net>
- * @package Horde_Group
- */
-class SQLObject_Group extends DataTreeObject_Group {
-
- /**
- * The unique name of this object.
- * These names have the same requirements as other object names - they must
- * be unique, etc.
- *
- * @var string
- */
- var $name;
-
- /**
- * The unique name of this object.
- * These names have the same requirements as other object names - they must
- * be unique, etc.
- *
- * @var integer
- */
- var $id;
-
- /**
- * Key-value hash that will be serialized.
- *
- * @see getData()
- * @var array
- */
- var $data = array();
-
- /**
- * The SQLObject_Group constructor. Just makes sure to call
- * the parent constructor so that the group's name is set
- * properly.
- *
- * @param string $name The name of the group.
- */
- function SQLObject_Group($name)
- {
- $this->name = $name;
- }
-
- /**
- * Gets the ID of this object.
- *
- * @return string The object's ID.
- */
- function getId()
- {
- return $this->id;
- }
-
- /**
- * Gets the name of this object.
- *
- * @return string The object name.
- */
- function getName()
- {
- return $this->name;
- }
-
- /**
- * Gets one of the attributes of the object, or null if it isn't defined.
- *
- * @param string $attribute The attribute to get.
- *
- * @return mixed The value of the attribute, or null.
- */
- function get($attribute)
- {
- return isset($this->data[$attribute])
- ? $this->data[$attribute]
- : null;
- }
-
- /**
- * Sets one of the attributes of the object.
- *
- * @param string $attribute The attribute to set.
- * @param mixed $value The value for $attribute.
- */
- function set($attribute, $value)
- {
- $this->data[$attribute] = $value;
- }
-
- /**
- * Save group
- */
- function save()
- {
- if (isset($this->data['email'])) {
- $query = 'UPDATE horde_groups SET group_email = ? WHERE group_uid = ?';
- $result = $this->_groupOb->_write_db->query($query, array($this->data['email'], $this->id));
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
- }
-
- $query = 'DELETE FROM horde_groups_members WHERE group_uid = ?';
- $result = $this->_groupOb->_write_db->query($query, array($this->id));
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- if (!empty($this->data['users'])) {
- $query = 'INSERT INTO horde_groups_members (group_uid, user_uid)'
- .' VALUES (' . $this->_groupOb->_write_db->quote($this->id) . ', ?)';
- $sth = $this->_groupOb->_write_db->prepare($query);
- $result = $this->_groupOb->_write_db->executeMultiple($sth, array_keys($this->data['users']));
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
- }
- }
-
-}
--- /dev/null
+<?php
+/**
+ * The Horde_Group:: class provides the Horde groups system.
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Stephane Huther <shuther1@free.fr>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group
+{
+ /** The parent Group node */
+ const ROOT = -1;
+
+ /**
+ * Group driver parameters
+ *
+ * @var array
+ */
+ protected $_params;
+
+ /**
+ * Pointer to a DataTree instance to manage the different groups.
+ *
+ * @var DataTree
+ */
+ protected $_datatree;
+
+ /**
+ * Cache of previously retrieved group objects.
+ *
+ * @var array
+ */
+ protected $_groupCache = array();
+
+ /**
+ * Id-name-map of already cached group objects.
+ *
+ * @var array
+ */
+ protected $_groupMap = array();
+
+ /**
+ * Id-name-hash of all existing groups.
+ *
+ * @var array
+ */
+ protected $_groupList;
+
+ /**
+ * List of sub groups.
+ *
+ * @see listAllUsers()
+ * @var array
+ */
+ protected $_subGroups = array();
+
+ /**
+ * Cache of parent groups.
+ *
+ * This is an array with group IDs as keys and the integer group id of the
+ * direct parent as values.
+ *
+ * @see getGroupParent()
+ * @var array
+ */
+ protected $_groupParents = array();
+
+ /**
+ * Cache of parent group trees.
+ *
+ * This is an array with group IDs as keys and id-name-hashes of all
+ * parents as values.
+ *
+ * @see getGroupParentList()
+ * @var array
+ */
+ protected $_groupParentList = array();
+
+ /**
+ * Cache of parents tree.
+ *
+ * @see getGroupParents()
+ * @var array
+ */
+ protected $_parentTree = array();
+
+ /**
+ * Hash of groups of certain users.
+ *
+ * @see getGroupMemberShips()
+ * @var array
+ */
+ protected $_userGroups;
+
+ /**
+ * Attempts to return a concrete Group instance based on $driver.
+ *
+ * @param mixed $driver The type of concrete Group subclass to return.
+ * @param array $params A hash containing any additional configuration or
+ * connection parameters a subclass might need.
+ *
+ * @return Horde_Group The newly created concrete Group instance.
+ * @throws Horde_Group_Exception
+ */
+ static public function factory($driver = '', $params = null)
+ {
+ if (is_null($params)) {
+ $params = Horde::getDriverConfig('group', $driver);
+ }
+
+ $class = self::_loadDriver($driver);
+ if (class_exists($class)) {
+ return new $class($params);
+ }
+
+ throw new Horde_Group_Exception('Class definition of ' . $class . ' not found.');
+ }
+
+ /**
+ * Attempts to return a reference to a concrete Group instance.
+ * It will only create a new instance if no Group instance
+ * currently exists.
+ *
+ * @return Group The concrete Group reference, or false on an error.
+ */
+ public static function singleton()
+ {
+ static $group;
+
+ if (isset($group)) {
+ return $group;
+ }
+
+ $group_driver = null;
+ $group_params = null;
+ $auth = $GLOBALS['injector']->getInstance('Horde_Auth')->getOb();
+ if ($auth->hasCapability('groups')) {
+ $group_driver = $auth->getDriver();
+ $group_params = $auth;
+ } elseif (!empty($GLOBALS['conf']['group']['driver']) &&
+ $GLOBALS['conf']['group']['driver'] != 'datatree') {
+ $group_driver = $GLOBALS['conf']['group']['driver'];
+ $group_params = Horde::getDriverConfig('group', $group_driver);
+ }
+
+ self::_loadDriver($group_driver);
+
+ $group = null;
+ if (!empty($GLOBALS['conf']['group']['cache'])) {
+ $session = new Horde_SessionObjects();
+ $group = $session->query('horde_group');
+ }
+
+ if (!$group) {
+ $group = self::factory($group_driver, $group_params);
+ }
+
+ if (!empty($GLOBALS['conf']['group']['cache'])) {
+ register_shutdown_function(array($group, 'shutdown'));
+ }
+
+ return $group;
+ }
+
+ /**
+ */
+ protected static function _loadDriver($driver)
+ {
+ if (!$driver) {
+ $class = __CLASS__;
+ } else {
+ $driver = ucfirst(strtolower(basename($driver)));
+ $class = __CLASS__ . '_' . $driver;
+ if (!class_exists($class)) {
+ }
+ }
+
+ return $class;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param array $params Configuration parameters.
+ */
+ public function __construct(array $params = array())
+ {
+ $this->_params = $params;
+ $this->__wakeup();
+ }
+
+ /**
+ * Stores the object in the session cache.
+ */
+ public function shutdown()
+ {
+ $GLOBALS['injector']->getInstance('Horde_SessionObjects')->overwrite('horde_group', $this, false);
+ }
+
+ /**
+ * Returns the properties that need to be serialized.
+ *
+ * @return array List of serializable properties.
+ */
+ public function __sleep()
+ {
+ return array_diff(array_keys(get_class_vars(__CLASS__)), array('_datatree'));
+ }
+ /**
+ * Initializes the object.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function __wakeup()
+ {
+ global $conf;
+
+ if (empty($conf['datatree']['driver'])) {
+ throw new Horde_Group_Exception('You must configure a DataTree backend to use Groups.');
+ }
+
+ $driver = $conf['datatree']['driver'];
+ $this->_datatree = DataTree::singleton($driver, array_merge(Horde::getDriverConfig('datatree', $driver), array('group' => 'horde.groups')));
+
+ foreach (array_keys($this->_groupCache) as $name) {
+ $this->_groupCache[$name]->setGroupOb($this);
+ $this->_groupCache[$name]->setDataTree($this->_datatree);
+ }
+ }
+
+ /**
+ * Returns a new group object.
+ *
+ * @param string $name The group's name.
+ * @param string $parent The group's parent's name.
+ *
+ * @return Horde_Group_DataTreeObject A new group object.
+ * @throws Horde_Group_Exception
+ */
+ public function newGroup(string $name, $parent = self::ROOT)
+ {
+ if ($parent != self::ROOT) {
+ $name = $this->getGroupName($parent) . ':' . DataTree::encodeName($name);
+ }
+
+ $group = new Horde_Group_DataTreeObject($name);
+ $group->setGroupOb($this);
+
+ return $group;
+ }
+
+ /**
+ * Returns a group object corresponding to the named group, with the users
+ * and other data retrieved appropriately.
+ *
+ * @param string $name The name of the group to retrieve.
+ *
+ * @return Horde_Group_DataTreeObject Group object.
+ */
+ public function getGroup($name)
+ {
+ if (!isset($this->_groupCache[$name])) {
+ $this->_groupCache[$name] = $this->_datatree->getObject($name, 'Horde_Group_DataTreeObject');
+ if (!($this->_groupCache[$name] instanceof PEAR_Error)) {
+ $this->_groupCache[$name]->setGroupOb($this);
+ $this->_groupMap[$this->_groupCache[$name]->getId()] = $name;
+ }
+ }
+
+ return $this->_groupCache[$name];
+ }
+
+ /**
+ * Returns a group object corresponding to the given unique ID, with the
+ * users and other data retrieved appropriately.
+ *
+ * @param integer $cid The unique ID of the group to retrieve.
+ *
+ * @return Horde_Group_DataTreeObject Group object.
+ */
+ public function getGroupById($cid)
+ {
+ if (isset($this->_groupMap[$cid])) {
+ $group = $this->_groupCache[$this->_groupMap[$cid]];
+ } else {
+ $group = $this->_datatree->getObjectById($cid, 'Horde_Group_DataTreeObject');
+ if (!($group instanceof PEAR_Error)) {
+ $group->setGroupOb($this);
+ $name = $group->getName();
+ $this->_groupCache[$name] = &$group;
+ $this->_groupMap[$cid] = $name;
+ }
+ }
+
+ return $group;
+ }
+
+ /**
+ * Returns a globally unique ID for a group.
+ *
+ * @param DataTreeObject_Group $group The group.
+ *
+ * @return string A GUID referring to $group.
+ */
+ public function getGUID($group)
+ {
+ return 'horde:group:' . $this->getGroupId($group);
+ }
+
+ /**
+ * Adds a group to the groups system. The group must first be created with
+ * newGroup(), and have any initial users added to it, before this
+ * function is called.
+ *
+ * @param Horde_Group_DataTreeObject $group The new group object.
+ *
+ * @throws Horde_Group_Exception
+ * @throws Horde_History_Exception
+ * @throws InvalidArgumentException
+ */
+ public function addGroup(Horde_Group_DataTreeObject $group)
+ {
+ $result = $this->_datatree->add($group);
+ if ($result instanceof PEAR_Error) {
+ throw new Horde_Group_Exception($result);
+ }
+
+ $id = $group->getId();
+ $name = $group->getName();
+ $this->_groupCache[$name] = &$group;
+ $this->_groupMap[$id] = $name;
+ if (isset($this->_groupList)) {
+ $this->_groupList[$id] = $name;
+ }
+
+ /* Log the addition of the group in the history log. */
+ $GLOBALS['injector']->getInstance('Horde_History')->log($this->getGUID($group), array('action' => 'add'), true);
+
+ return $result;
+ }
+
+ /**
+ * Stores updated data - users, etc. - of a group to the backend system.
+ *
+ * @param Horde_Group_DataTreeObject $group The group to update.
+ *
+ * @throws Horde_History_Exception
+ * @throws InvalidArgumentException
+ */
+ public function updateGroup(Horde_Group_DataTreeObject $group)
+ {
+ $result = $this->_datatree->updateData($group);
+ if ($result instanceof PEAR_Error) {
+ return $result;
+ }
+
+ $this->_groupCache[$group->getName()] = &$group;
+
+ /* Log the update of the group users on the history log. */
+ $history = $GLOBALS['injector']->getInstance('Horde_History');
+ $guid = $this->getGUID($group);
+ foreach ($group->getAuditLog() as $userId => $action) {
+ $history->log($guid, array('action' => $action, 'user' => $userId), true);
+ }
+ $group->clearAuditLog();
+
+ /* Log the group modification. */
+ $history->log($guid, array('action' => 'modify'), true);
+
+ return $result;
+ }
+
+ /**
+ * Removes a group from the groups system permanently.
+ *
+ * @param Horde_Group_DataTreeObject $group The group to remove.
+ * @param boolean $force Force to remove every child?
+ *
+ * @throws Horde_History_Exception
+ * @throws InvalidArgumentException
+ */
+ public function removeGroup(Horde_Group_DataTreeObject $group,
+ $force = false)
+ {
+ $id = $group->getId();
+ unset($this->_groupMap[$id]);
+ if (isset($this->_groupList)) {
+ unset($this->_groupList[$id]);
+ }
+ unset($this->_groupCache[$group->getName()]);
+
+ $GLOBALS['injector']->getInstance('Horde_History')->log($this->getGUID($group), array('action' => 'delete'), true);
+
+ return $this->_datatree->remove($group, $force);
+ }
+
+ /**
+ * Retrieves the name of a group.
+ *
+ * @param integer|Horde_Group_DataTreeObject $gid The id of the group or
+ * the group object to
+ * retrieve the name for.
+ *
+ * @return string The group's name.
+ */
+ public function getGroupName($gid)
+ {
+ if ($gid instanceof Horde_Group_DataTreeObject) {
+ $gid = $gid->getId();
+ }
+
+ if (isset($this->_groupMap[$gid])) {
+ return $this->_groupMap[$gid];
+ }
+ if (isset($this->_groupList[$gid])) {
+ return $this->_groupList[$gid];
+ }
+
+ return $this->_datatree->getName($gid);
+ }
+
+ /**
+ * Strips all parent references off of the given group name.
+ *
+ * @param string $group Name of the group.
+ *
+ * @return The name of the group without parents.
+ */
+ public function getGroupShortName($group)
+ {
+ return $this->_datatree->getShortName($group);
+ }
+
+ /**
+ * Retrieves the ID of a group.
+ *
+ * @param integer|Horde_Group_DataTreeObject $gid The id of the group or
+ * the group object to
+ * retrieve the ID for.
+ *
+ * @return integer The group's ID.
+ */
+ public function getGroupId($group)
+ {
+ if ($group instanceof Horde_Group_DataTreeObject) {
+ $group = $group->getName();
+ }
+
+ $id = array_search($group, $this->_groupMap);
+ if ($id !== false) {
+ return $id;
+ }
+
+ if (isset($this->_groupList)) {
+ $id = array_search($group, $this->_groupList);
+ if ($id !== false) {
+ return $id;
+ }
+ }
+
+ return $this->_datatree->getId($group);
+ }
+
+ /**
+ * Check if a group exists in the system.
+ *
+ * @param string $group The group to check.
+ *
+ * @return boolean True if the group exists, false otherwise.
+ */
+ public function exists($group)
+ {
+ if (isset($this->_groupCache[$group]) ||
+ (isset($this->_groupList) &&
+ array_search($group, $this->_groupList) !== false)) {
+ return true;
+ }
+
+ return $this->_datatree->exists($group);
+ }
+
+ /**
+ * Returns a tree of the parents of a child group.
+ *
+ * @param integer $gid The id of the child group.
+ *
+ * @return array The group parents tree, with groupnames as the keys.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupParents($gid)
+ {
+ if (!isset($this->_parentTree[$gid])) {
+ $name = $this->getGroupName($gid);
+ $parents = $this->_datatree->getParents($name);
+ if ($parents instanceof PEAR_Error) {
+ throw new Horde_Group_Exception($parents);
+ }
+ $this->_parentTree[$gid] = $parents;
+ }
+
+ return $this->_parentTree[$gid];
+ }
+
+ /**
+ * Returns the single parent ID of the given group.
+ *
+ * @param integer $gid The DataTree ID of the child group.
+ *
+ * @return integer The parent of the given group.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupParent($gid)
+ {
+ if (!isset($this->_groupParents[$gid])) {
+ $parent = $this->_datatree->getParentById($gid);
+ if ($parent instanceof PEAR_Error) {
+ throw new Horde_Group_Exception($parent);
+ }
+ $this->_groupParents[$gid] = $parent;
+ }
+
+ return $this->_groupParents[$gid];
+ }
+
+ /**
+ * Returns a flat list of the parents of a child group
+ *
+ * @param integer $gid The id of the group.
+ *
+ * @return array A flat list of all of the parents of $group, hashed in
+ * $id => $name format.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupParentList($gid)
+ {
+ if (!isset($this->_groupParentList[$gid])) {
+ $parents = $this->_datatree->getParentList($gid);
+ if ($parents instanceof PEAR_Error) {
+ throw new Horde_Group_Exception($parents);
+ }
+ $this->_groupParentList[$gid] = $parents;
+ }
+
+ return $this->_groupParentList[$gid];
+ }
+
+ /**
+ * Returns a list of all groups, in the format id => groupname.
+ *
+ * @param boolean $refresh If true, the cached value is ignored and the
+ * group list is refreshed from the group backend.
+ *
+ * @return array ID => groupname hash.
+ */
+ public function listGroups($refresh = false)
+ {
+ if ($refresh || !isset($this->_groupList)) {
+ $this->_groupList = $this->_datatree->get(DATATREE_FORMAT_FLAT, GROUP_ROOT, true);
+ unset($this->_groupList[GROUP_ROOT]);
+ }
+
+ return $this->_groupList;
+ }
+
+ /**
+ * Get a list of every user that is a part of this group ONLY.
+ *
+ * @param integer $gid The ID of the group.
+ *
+ * @return array The user list.
+ * @throws Horde_Group_Exception
+ */
+ public function listUsers($gid)
+ {
+ $groupOb = $this->getGroupById($gid);
+
+ if (!isset($groupOb->data['users']) ||
+ !is_array($groupOb->data['users'])) {
+ return array();
+ }
+
+ return array_keys($groupOb->data['users']);
+ }
+
+ /**
+ * Get a list of every user that is part of the specified group
+ * and any of its subgroups.
+ *
+ * @param integer $group The ID of the parent group.
+ *
+ * @return array The complete user list.
+ * @throws Horde_Group_Exception
+ */
+ public function listAllUsers($gid)
+ {
+ if (!isset($this->_subGroups[$gid])) {
+ // Get a list of every group that is a sub-group of $group.
+ $groups = $this->_datatree->get(DATATREE_FORMAT_FLAT, $this->getGroupName($gid), true);
+ if ($groups instanceof PEAR_Error) {
+ throw new Horde_Group_Exception($groups);
+ }
+ $this->_subGroups[$gid] = array_keys($groups);
+ }
+
+ $users = array();
+ foreach ($this->_subGroups[$gid] as $groupId) {
+ $users = array_merge($users, $this->listUsers($groupId));
+ }
+
+ return array_values(array_flip(array_flip($users)));
+ }
+
+ /**
+ * Get a list of every group that $user is in.
+ *
+ * @param string $user The user to get groups for.
+ * @param boolean $parentGroups Also return the parents of any groups?
+ *
+ * @return array An array of all groups the user is in.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupMemberships($user, $parentGroups = false)
+ {
+ if (!isset($this->_userGroups[$user])) {
+ $criteria = array(
+ 'AND' => array(
+ array('field' => 'name', 'op' => '=', 'test' => 'user'),
+ array('field' => 'key', 'op' => '=', 'test' => $user)));
+ $groups = $this->_datatree->getByAttributes($criteria);
+ if ($groups instanceof PEAR_Error) {
+ throw new Horde_Group_Exception($groups);
+ }
+
+ if ($parentGroups) {
+ foreach ($groups as $id => $g) {
+ $parents = $this->_datatree->getParentList($id);
+ if ($parents instanceof PEAR_Error) {
+ throw new Horde_Group_Exception($parents);
+ }
+ $groups += $parents;
+ }
+ }
+
+ $this->_userGroups[$user] = $groups;
+ }
+
+ return $this->_userGroups[$user];
+ }
+
+ /**
+ * Say if a user is a member of a group or not.
+ *
+ * @param string $user The name of the user.
+ * @param integer $gid The ID of the group.
+ * @param boolean $subgroups Return true if the user is in any subgroups
+ * of group with ID $gid, also.
+ *
+ * @return boolean
+ */
+ public function userIsInGroup($user, $gid, $subgroups = true)
+ {
+ if (!$this->exists($this->getGroupName($gid))) {
+ return false;
+ } elseif ($subgroups) {
+ try {
+ $groups = $this->getGroupMemberships($user, true);
+ } catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'ERR');
+ return false;
+ }
+
+ return !empty($groups[$gid]);
+ } else {
+ try {
+ $users = $this->listUsers($gid);
+ } catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'ERR');
+ return false;
+ }
+ return in_array($user, $users);
+ }
+ }
+
+ /**
+ * Returns the nesting level of the given group. 0 is returned for any
+ * object directly below self::ROOT.
+ *
+ * @param integer $gid The DataTree ID of the group.
+ *
+ * @return The DataTree level of the group.
+ */
+ public function getLevel($gid)
+ {
+ return substr_count($this->getGroupName($gid), ':');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Extension of the DataTreeObject_Group class for storing Group information.
+ *
+ * Copyright 2008-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael J. Rubinsky <mrubinsk@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_ContactListObject extends DataTreeObject_Group
+{
+
+ /**
+ * The unique name of this object.
+ * These names have the same requirements as other object names - they
+ * must be unique, etc.
+ *
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * The unique name of this object.
+ * These names have the same requirements as other object names - they
+ * must be unique, etc.
+ *
+ * @var integer
+ */
+ protected $id;
+
+ /**
+ * Key-value hash that will be serialized.
+ *
+ * @see getData()
+ * @var array
+ */
+ protected $data = array();
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the group.
+ */
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Gets the ID of this object.
+ *
+ * @return string The object's ID.
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * Gets the name of this object.
+ *
+ * @return string The object name.
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Gets one of the attributes of the object, or null if it isn't defined.
+ *
+ * @param string $attribute The attribute to get.
+ *
+ * @return mixed The value of the attribute, or null.
+ */
+ public function get($attribute)
+ {
+ return isset($this->data[$attribute])
+ ? $this->data[$attribute]
+ : null;
+ }
+
+ /**
+ * Sets one of the attributes of the object.
+ *
+ * @param string $attribute The attribute to set.
+ * @param mixed $value The value for $attribute.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function set($attribute, $value)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Save group.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function save()
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * @throws Horde_Group_Exception
+ */
+ public function removeUser($username, $update = true)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * @throws Horde_Group_Exception
+ */
+ function addUser($username, $update = true)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Group_contactlists class provides a groups system based on Turba
+ * contact lists. Only SQL sources are supported.
+ *
+ * Copyright 2008-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael J. Rubinsky <mrubinsk@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_Contactlists extends Horde_Group
+{
+ /**
+ * A cache object
+ *
+ * @var Horde_Cache object
+ */
+ protected $_cache = null;
+
+ /**
+ * Handles for the database connections. Need one for each possible
+ * source.
+ *
+ * @var DB
+ */
+ protected $_db = array();
+
+ /**
+ * Local copy of available address book sources that the group driver can
+ * use.
+ *
+ * @var array of Turba's cfgSource style entries.
+ */
+ protected $_sources = array();
+
+ /**
+ * Local cache of retreived group entries from Turba storage.
+ *
+ * @var unknown_type
+ */
+ protected $_listEntries = array();
+
+ /**
+ * Constructor.
+ */
+ public function __construct(array $params = array())
+ {
+ // Get a list of all available Turba sources
+ $turba_sources = Horde::loadConfiguration('sources.php',
+ 'cfgSources', 'turba');
+
+ // We only support sql type sources.
+ foreach ($turba_sources as $key => $source) {
+ if ($source['type'] == 'sql') {
+ $this->_sources[$key] = $source;
+ }
+ }
+
+ $this->_cache = $GLOBALS['injector']->getInstance('Horde_Cache');
+ }
+
+ /**
+ * Initializes the object.
+ */
+ public function __wakeup()
+ {
+ }
+
+ /**
+ * Returns the properties that need to be serialized.
+ *
+ * @return array List of serializable properties.
+ */
+ public function __sleep()
+ {
+ }
+
+ /**
+ * Stores the object in the session cache.
+ */
+ public function shutdown()
+ {
+ }
+
+ /**
+ * Returns a new group object.
+ *
+ * @param string $name The group's name.
+ * @param string $parent The group's parent's name.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function newGroup($name, $parent = GROUP_ROOT)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Returns a Group object corresponding to the named group,
+ * with the users and other data retrieved appropriately.
+ *
+ * This is deprecated. Use getGroupById() instead.
+ *
+ * @param string $name The name of the group to retrieve.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroup($name)
+ {
+ throw new Horde_Group_Exception('Deprecated. Use getGroupById() instead.');
+ }
+
+ /**
+ * Returns a Horde_Group_ContactListObject object corresponding to the
+ * given unique ID, with the users and other data retrieved
+ * appropriately.
+ *
+ * @param integer $cid The unique ID of the group to retrieve.
+ *
+ * @return Horde_Group_ContactListObject
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupById($gid)
+ {
+ if (!empty($this->_groupCache[$gid])) {
+ return $this->_groupCache[$gid];
+ }
+
+ list($source, $id) = explode(':', $gid);
+ $entry = $this->_retrieveListEntry($gid);
+ if (empty($entry)) {
+ throw new Horde_Group_Exception($gid . ' does not exist');
+ }
+
+ $users = $this->_getAllMembers($gid);
+
+ $group = new Horde_Group_ContactListObject($entry[$this->_sources[$source]['map'][$this->_sources[$source]['list_name_field']]]);
+ $group->id = $gid;
+ $group->data['email'] = $entry[$this->_sources[$source]['map']['email']];
+ if (!empty($users)) {
+ $group->data['users'] = array_flip($users);
+ }
+
+ $group->setGroupOb($this);
+ $this->_groupCache[$gid] = $group;
+
+ return $group;
+ }
+
+ /**
+ * Adds a group to the groups system. The group must first be created with
+ * newGroup(), and have any initial users added to it, before this
+ * function is called.
+ *
+ * @param Horde_Group_ContactListObject $group The new group object.
+ * @throws Horde_Group_Exception
+ */
+ public function addGroup($group)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Stores updated data - users, etc. - of a group to the backend system.
+ *
+ * @param ContactListObject_Group $group The group to update.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function updateGroup($group)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Removes a group from the groups system permanently.
+ *
+ * @param ContactListObject_Group $group The group to remove.
+ * @param boolean $force Force to remove every child.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function removeGroup($group, $force = false)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Retrieves the name of a group.
+ *
+ * @param integer|Horde_Group_ContactListObject $gid The id of the group
+ * or the group object
+ * to retrieve the name
+ * for.
+ *
+ * @return string The group's name.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupName($gid)
+ {
+ static $beenHere;
+
+ if (strpos($gid, ':') === false) {
+ throw new Horde_Group_Exception(sprintf('Group %s not found.', $gid));
+ }
+
+ if ($gid instanceof Horde_Group_ContactListObject) {
+ $gid = $gid->getId();
+ }
+
+ if (!empty($this->_listEntries[$gid])) {
+ list($source, $id) = explode(':', $gid);
+ $beenHere = false;
+ return $this->_listEntries[$gid][$this->_sources[$source]['map'][$this->_sources[$source]['list_name_field']]];
+ }
+
+ $this->_retrieveListEntry($gid);
+
+ // We should have the information cached now, try again..but protect
+ // against anything nasty...
+ if (!$beenHere) {
+ $beenHere = true;
+ return $this->getGroupName($gid);
+ }
+
+ throw new Horde_Group_Exception(sprintf('Group %s not found.', $gid));
+ }
+
+ /**
+ * Strips all parent references off of the given group name.
+ * Not used in this driver...group display names are ONLY for display.
+ *
+ * @param string $group Name of the group.
+ *
+ * @return string The name of the group without parents.
+ */
+ public function getGroupShortName($group)
+ {
+ return $group;
+ }
+
+ /**
+ * Retrieves the ID of a group, given the group object.
+ * Here for BC. Kinda silly, since if we have the object, we can just call
+ * getId() ourselves.
+ *
+ * @param ContactListObject_Group $group The group object to retrieve the
+ * ID for.
+ *
+ * @return integer The group's ID.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupId($group)
+ {
+ if ($group instanceof Horde_Group_ContactListObject) {
+ return $group->getId();
+ }
+
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Check if a group exists in the system.
+ * This must either be a noop or we need to somehow "uniqueify" the
+ * list's display name?
+ *
+ * @param string $group The group name to check.
+ *
+ * @return boolean True if the group exists, false otherwise.
+ */
+ public function exists($group)
+ {
+ return true;
+ }
+
+ /**
+ * Returns a tree of the parents of a child group.
+ *
+ * @param integer $gid The id of the child group.
+ *
+ * @return array The group parents tree, with groupnames as the keys.
+ */
+ public function getGroupParents($gid)
+ {
+ return array();
+ }
+
+ /**
+ * Returns the single parent ID of the given group.
+ *
+ * @param integer $gid The ID of the child group.
+ *
+ * @return integer The parent of the given group.
+ */
+ public function getGroupParent($gid)
+ {
+ return self::ROOT;
+ }
+
+ /**
+ * Returns a flat list of the parents of a child group
+ *
+ * @param integer $gid The id of the group.
+ *
+ * @return array A flat list of all of the parents of $group, hashed in
+ * $id => $name format.
+ */
+ public function getGroupParentList($gid)
+ {
+ return array();
+ }
+
+ /**
+ * Returns a list of all groups, in the format id => groupname.
+ * The groups returned represent only the groups visible to the current
+ * user only.
+ *
+ * @param boolean $refresh If true, the cached value is ignored and the
+ * group list is refreshed from the group backend.
+ *
+ * @return array ID => groupname hash.
+ */
+ public function listGroups($refresh = false)
+ {
+ if (isset($this->_groupList) && !$refresh) {
+ return $this->_groupList;
+ }
+
+ // First, make sure we are connected to all sources
+ $this->_connect();
+
+ $groups = $owners = array();
+
+ foreach ($this->_sources as $key => $source) {
+ if ($source['use_shares']) {
+ if (empty($contact_shares)) {
+ $scope = $GLOBALS['registry']->hasInterface('contacts');
+ $shares = $GLOBALS['injector']->getInstance('Horde_Share')->getScope($scope);
+ $this->_contact_shares = $shares->listShares(Horde_Auth::getAuth(), Horde_Perms::SHOW, Horde_Auth::getAuth());
+ }
+ // Contruct a list of owner ids to use
+ foreach ($this->_contact_shares as $id => $share) {
+ $params = @unserialize($share->get('params'));
+ if ($params['source'] == $key) {
+ $owners[] = $params['name'];
+ }
+ }
+ } else {
+ $owners = array(Horde_Auth::getAuth());
+ }
+ $owner_ids = array();
+ foreach ($owners as $owner) {
+ $owner_ids[] = $this->_db[$key]->quote($owner);
+ }
+ $sql = 'SELECT ' . $source['map']['__key'] . ', ' . $source['map'][$source['list_name_field']]
+ . ' FROM ' . $source['params']['table'] . ' WHERE '
+ . $source['map']['__type'] . ' = \'Group\' AND '
+ . $source['map']['__owner'] . ' IN (' . implode(',', $owner_ids ) . ')';
+
+ $results = $this->_db[$key]->getAssoc($sql);
+ foreach ($results as $id => $name) {
+ $groups[$key . ':' . $id] = $name;
+ }
+ }
+ $this->_groupList = $groups;
+
+ return $this->_groupList;
+ }
+
+ /**
+ * Get a list of every user that is part of the specified group
+ * and any of its subgroups.
+ *
+ * @param integer $group The ID of the parent group.
+ *
+ * @return array The complete user list.
+ * @throws Horde_Group_Exception
+ */
+ public function listAllUsers($gid)
+ {
+ return array_values($this->_getAllMembers($gid, true));
+ }
+
+ /**
+ * Returns a hash representing the list entry. Items are keyed by the
+ * backend specific keys.
+ *
+ * @param string $gid The group id.
+ *
+ * @return array
+ * @throws Horde_Group_Exception
+ */
+ protected function _retrieveListEntry($gid)
+ {
+ if (!empty($this->_listEntries[$gid])) {
+ return $this->_listEntries[$gid];
+ }
+
+ list($source, $id) = explode(':', $gid);
+ if (empty($this->_sources[$source])) {
+ return array();
+ }
+
+ $this->_connect($source);
+ $sql = 'SELECT ' . $this->_sources[$source]['map']['__members'] . ','
+ . $this->_sources[$source]['map']['email'] . ','
+ . $this->_sources[$source]['map'][$this->_sources[$source]['list_name_field']]
+ . ' from ' . $this->_sources[$source]['params']['table'] . ' WHERE '
+ . $this->_sources[$source]['map']['__key'] . ' = ' . $this->_db[$source]->quote($id);
+
+ $results = $this->_db[$source]->getRow($sql, array(), DB_FETCHMODE_ASSOC);
+ if ($results instanceof PEAR_Error) {
+ Horde::logMessage($results, 'ERR');
+ throw new Horde_Group_Exception($results);
+ }
+ $this->_listEntries[$gid] = $results;
+
+ return $results;
+ }
+
+ /**
+ * TODO
+ *
+ * @throws Horde_Group_Exception
+ */
+ protected function _getAllMembers($gid, $subGroups = false)
+ {
+ if (empty($gid) || strpos($gid, ':') === false) {
+ throw new Horde_Group_Exception(sprintf('Unsupported group id: %s', $gid));
+ }
+
+ list($source, $id) = explode(':', $gid);
+ $entry = $this->_retrieveListEntry($gid);
+ $members = @unserialize($entry[$this->_sources[$source]['map']['__members']]);
+ $users = array();
+
+ // TODO: optimize this to only query each table once
+ foreach ($members as $member) {
+ // Is this member from the same source or a different one?
+ if (strpos($member, ':') !== false) {
+ list($newSource, $uid) = explode(':', $member);
+ if (!empty($this->_contact_shares[$newSource])) {
+ $params = @unserialize($this->_contact_shares[$newSource]->get('params'));
+ $newSource = $params['source'];
+ $member = $uid;
+ $this->_connect($newSource);
+ } elseif (empty($this->_sources[$newSource])) {
+ // Last chance, it's not in one of our non-share sources
+ continue;
+ }
+ } else {
+ // Same source
+ $newSource = $source;
+ }
+
+ $sql = 'SELECT ' . $this->_sources[$newSource]['map']['email']
+ . ', ' . $this->_sources[$newSource]['map']['__type']
+ . ' FROM ' . $this->_sources[$newSource]['params']['table']
+ . ' WHERE ' . $this->_sources[$newSource]['map']['__key']
+ . ' = ' . $this->_db[$newSource]->quote($member);
+
+ $results = $this->_db[$newSource]->getRow($sql);
+ if ($results instanceof PEAR_Error) {
+ Horde::logMessage($results, 'ERR');
+ throw new Horde_Group_Exception($results);
+ }
+
+ // Sub-Lists are treated as sub groups the best that we can...
+ if ($subGroups && $results[1] == 'Group') {
+ $this->_subGroups[$gid] = $newSource . ':' . $member;
+ $users = array_merge($users, $this->_getAllMembers($newSource . ':' . $member));
+ }
+ if (strlen($results[0])) {
+ // use a key to dump dups
+ $users[$results[0]] = $results[0];
+ }
+ }
+
+ return $users;
+ }
+
+ /**
+ * Returns ALL contact lists present in ALL sources that this driver knows
+ * about.
+ *
+ * @throws Horde_Group_Exception
+ */
+ protected function _listAllLists()
+ {
+ // Clear the cache - we will rebuild it.
+ $this->_listEntries = array();
+
+ foreach ($this->_sources as $key => $source) {
+ $this->_connect($key);
+ $sql = 'SELECT ' . $source['map']['__key'] . ','
+ . $source['map']['__members'] . ','
+ . $source['map']['email'] . ','
+ . $source['map'][$source['list_name_field']]
+ . ' FROM ' . $source['params']['table'] . ' WHERE '
+ . $source['map']['__type'] . ' = \'Group\'';
+
+ $results = $this->_db[$key]->query($sql);
+ if ($results instanceof PEAR_Error) {
+ throw new Horde_Group_Exception($results);
+ }
+
+ while ($row = $results->fetchRow(DB_FETCHMODE_ASSOC)) {
+ $this->_listEntries[$key . ':' . $row[$source['map']['__key']]] = $row;
+ }
+ }
+
+ return $this->_listEntries;
+ }
+
+ /**
+ * Get a list of every group that $user is in.
+ *
+ * @param string $user The user to get groups for.
+ * @param boolean $parentGroups Also return the parents of any groups?
+ *
+ * @return array An array of all groups the user is in.
+ */
+ public function getGroupMemberships($user, $parentGroups = false)
+ {
+ if (($memberships = $this->_cache->get('Group_contactlists_memberships' . md5($user))) !== false) {
+ return unserialize($memberships);
+ }
+ $lists = $this->_listAllLists();
+ $memberships = array();
+ foreach (array_keys($lists) as $list) {
+ $members = $this->_getAllMembers($list, $parentGroups);
+ if (!empty($members[$user])) {
+ $memberships[] = $list;
+ }
+ }
+
+ $this->_cache->set('Group_contactlists_memberships' . md5($user), serialize($memberships));
+
+ return $memberships;
+ }
+
+ /**
+ * Say if a user is a member of a group or not.
+ *
+ * @param string $user The name of the user.
+ * @param integer $gid The ID of the group.
+ * @param boolean $subgroups Return true if the user is in any subgroups
+ * of group with ID $gid, also.
+ *
+ * @return boolean
+ */
+ public function userIsInGroup($user, $gid, $subgroups = true)
+ {
+ if (isset($_SESSION['horde']['groups']['i'][$user][$subgroups][$gid])) {
+ return $_SESSION['horde']['groups']['i'][$user][$subgroups][$gid];
+ }
+
+ try {
+ $users = $this->_getAllMembers($gid, $subgroups);
+ } catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'ERR');
+ return false;
+ }
+
+ $result = (bool)!empty($users[$user]);
+ $_SESSION['horde']['groups']['i'][$user][$subgroups][$gid] = $result;
+
+ return $result;
+ }
+
+ /**
+ * Attempts to open a persistent connection to the sql server.
+ *
+ * @return boolean True on success.
+ * @throws Horde_Group_Exception
+ */
+ protected function _connect($source = null)
+ {
+ if (!is_null($source) && !empty($this->_db[$source])) {
+ return;
+ }
+
+ $sources = is_null($source)
+ ? array_keys($this->_sources)
+ : array($source);
+
+ foreach ($sources as $source) {
+ if (empty($this->_db[$source])) {
+ $this->_db[$source] = DB::connect($this->_sources[$source]['params'],
+ array('persistent' => !empty($this->_sources[$source]['params']['persistent'])));
+ if ($this->_db[$source] instanceof PEAR_Error) {
+ throw new Horde_Group_Exception($this->_db[$source]);
+ }
+
+ /* Set DB portability options. */
+ switch ($this->_db[$source]->phptype) {
+ case 'mssql':
+ $this->_db[$source]->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
+ break;
+
+ default:
+ $this->_db[$source]->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
+ }
+ }
+ }
+
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Extension of the DataTreeObject class for storing Group information
+ * in the Categories driver. If you want to store specialized Group
+ * information, you should extend this class instead of extending
+ * DataTreeObject directly.
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_DataTreeObject extends DataTreeObject
+{
+ /**
+ * The Group object which this group is associated with - needed
+ * for updating data in the backend to make changes stick, etc.
+ *
+ * @var Horde_Group
+ */
+ protected $_groupOb;
+
+ /**
+ * This variable caches the users added or removed from the group
+ * for History logging of user-groups relationship.
+ *
+ * @var array
+ */
+ protected $_auditLog = array();
+
+ /**
+ * Returns the properties that need to be serialized.
+ *
+ * @return array List of serializable properties.
+ */
+ public function __sleep()
+ {
+ return array_diff(array_keys(get_class_vars(__CLASS__)), array('_datatree', '_groupOb'));
+ }
+
+ /**
+ * Associates a group object with this group.
+ *
+ * @param Horde_Group $groupOb The group object.
+ */
+ public function setGroupOb($groupOb)
+ {
+ $this->_groupOb = $groupOb;
+ }
+
+ /**
+ * Fetch the ID of this group
+ *
+ * @return string The group's ID
+ */
+ public function getId()
+ {
+ return $this->_groupOb->getGroupId($this);
+ }
+
+ /**
+ * Save any changes to this object to the backend permanently.
+ */
+ public function save()
+ {
+ return $this->_groupOb->updateGroup($this);
+
+ }
+
+ /**
+ * Adds a user to this group, and makes sure that the backend is
+ * updated as well.
+ *
+ * @param string $username The user to add.
+ */
+ public function addUser($username, $update = true)
+ {
+ $this->data['users'][$username] = 1;
+ $this->_auditLog[$username] = 'addUser';
+ if ($update && $this->_groupOb->exists($this->getName())) {
+ return $this->save();
+ }
+ }
+
+ /**
+ * Removes a user from this group, and makes sure that the backend
+ * is updated as well.
+ *
+ * @param string $username The user to remove.
+ */
+ public function removeUser($username, $update = true)
+ {
+ unset($this->data['users'][$username]);
+ $this->_auditLog[$username] = 'deleteUser';
+ if ($update) {
+ return $this->save();
+ }
+ }
+
+ /**
+ * Get a list of every user that is a part of this group
+ * (and only this group)
+ *
+ * @return array The user list.
+ */
+ public function listUsers()
+ {
+ return $this->_groupOb->listUsers($this->getId());
+ }
+
+ /**
+ * Get a list of every user that is a part of this group and
+ * any of it's subgroups
+ *
+ * @return array The complete user list.
+ */
+ public function listAllUsers()
+ {
+ return $this->_groupOb->listAllUsers($this->getId());
+ }
+
+ /**
+ * Get all the users recently added or removed from the group.
+ */
+ public function getAuditLog()
+ {
+ return $this->_auditLog;
+ }
+
+ /**
+ * Clears the audit log. To be called after group update.
+ */
+ public function clearAuditLog()
+ {
+ $this->_auditLog = array();
+ }
+
+ /**
+ * Map this object's attributes from the data array into a format
+ * that we can store in the attributes storage backend.
+ *
+ * @return array The attributes array.
+ */
+ protected function _toAttributes()
+ {
+ // Default to no attributes.
+ $attributes = array();
+
+ // Loop through all users, if any.
+ if (isset($this->data['users']) && is_array($this->data['users']) && count($this->data['users'])) {
+ foreach ($this->data['users'] as $user => $active) {
+ $attributes[] = array('name' => 'user',
+ 'key' => $user,
+ 'value' => $active);
+ }
+ }
+ $attributes[] = array('name' => 'email',
+ 'key' => '',
+ 'value' => $this->get('email'));
+
+ return $attributes;
+ }
+
+ /**
+ * Take in a list of attributes from the backend and map it to our
+ * internal data array.
+ *
+ * @param array $attributes The list of attributes from the
+ * backend (attribute name, key, and value).
+ */
+ protected function _fromAttributes($attributes)
+ {
+ // Initialize data array.
+ $this->data['users'] = array();
+
+ foreach ($attributes as $attr) {
+ if ($attr['name'] == 'user') {
+ $this->data['users'][$attr['key']] = $attr['value'];
+ } else {
+ $this->data[$attr['name']] = $attr['value'];
+ }
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Exception handler for the horde/Group package.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_Exception extends Horde_Exception_Prior
+{
+}
--- /dev/null
+<?php
+/**
+ * This class provides the Horde groups system with the addition of adding
+ * support for hook functions to define if a user is in a group.
+ *
+ * Copyright 2003-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jason Rust <jrust@rustyparts.com>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_Hooks extends Horde_Group
+{
+ /**
+ * @var boolean
+ */
+ protected $_hookFunction = false;
+
+ /**
+ * Constructor.
+ *
+ * @params array $params
+ */
+ public function __construct($params)
+ {
+ parent::__construct($params);
+ Horde::loadConfiguration('hooks.php', null, 'horde');
+ $this->_hookFunction = function_exists('_group_hook');
+ }
+
+ /**
+ * Get a list of every group that $user is in.
+ *
+ * @param string $user The user to get groups for.
+ * @param boolean $parentGroups Also return the parents of any groups?
+ *
+ * @return array An array of all groups the user is in.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupMemberships($user, $parentGroups = false)
+ {
+ $memberships = parent::getGroupMemberships($user, $parentGroups);
+ if (!$this->_hookFunction) {
+ return $memberships;
+ }
+
+ $groups = $this->listGroups();
+ foreach ($groups as $gid => $groupName) {
+ if (empty($memberships[$gid]) && _group_hook($groupName, $user)) {
+ $memberships += array($gid => $groupName);
+ }
+
+ if ($parentGroups) {
+ $memberships += $this->getGroupParentList($gid);
+ }
+ }
+
+ return $memberships;
+ }
+
+ /**
+ * Say if a user is a member of a group or not.
+ *
+ * @param string $user The name of the user.
+ * @param integer $gid The ID of the group.
+ * @param boolean $subgroups Return true if the user is in any subgroups
+ * of $group, also.
+ *
+ * @return boolean
+ */
+ public function userIsInGroup($user, $gid, $subgroups = true)
+ {
+ return ($this->_hookFunction && _group_hook($this->getGroupName($gid), $user)) ||
+ parent::userIsInGroup($user, $gid, $subgroups);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides a Kolab backend for the Horde groups system.
+ *
+ * FIXME: A better solution would be to let this class rely on
+ * Horde/Kolab/LDAP.php.
+ *
+ * Copyright 2005-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_Kolab extends Horde_Group_Ldap
+{
+ /**
+ * Constructor.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function __construct($params)
+ {
+ if (!function_exists('ldap_connect')) {
+ throw new Horde_Group_Exception('The Kolab group driver requires LDAP support.');
+ }
+
+ $this->_params = array(
+ 'hostspec' => $GLOBALS['conf']['kolab']['ldap']['server'],
+ 'basedn' => $GLOBALS['conf']['kolab']['ldap']['basedn'],
+ 'binddn' => $GLOBALS['conf']['kolab']['ldap']['phpdn'],
+ 'password' => $GLOBALS['conf']['kolab']['ldap']['phppw'],
+ 'version' => 3,
+ 'gid' => 'cn',
+ 'memberuid' => 'member',
+ 'attrisdn' => true,
+ 'filter_type' => 'objectclass',
+ 'objectclass' => 'kolabGroupOfNames',
+ 'newgroup_objectclass' => 'kolabGroupOfNames'
+ );
+
+ $this->_filter = 'objectclass=' . $this->_params['objectclass'];
+
+ $this->__wakeup();
+ }
+
+ /**
+ * Initializes the object.
+ */
+ public function __wakeup()
+ {
+ foreach (array_keys($this->_groupCache) as $name) {
+ $this->_groupCache[$name]->setGroupOb($this);
+ }
+ }
+
+ /**
+ * Returns the properties that need to be serialized.
+ *
+ * @return array List of serializable properties.
+ */
+ public function __sleep()
+ {
+ return array_diff(array_keys(get_class_vars(__CLASS__)), array('_datatree', '_ds'));
+ }
+
+ /**
+ * Returns a new group object.
+ *
+ * @param string $name The group's name.
+ * @param string $parent The group's parent's name.
+ *
+ * @return Horde_Group_KolabObject A new group object.
+ * @throws Horde_Group_Exception
+ */
+ public function newGroup($name)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Adds a group to the groups system. The group must first be created with
+ * newGroup(), and have any initial users added to it, before this
+ * function is called.
+ *
+ * @param Horde_Group_KolabObject $group The new group object.
+ * @throws Horde_Group_Exception
+ */
+ public function addGroup($group)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Stores updated data - users, etc. - of a group to the backend system.
+ *
+ * @param Horde_Group_KolabObject $group The group to update.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function updateGroup($group)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Removes a group from the groups system permanently.
+ *
+ * @param Horde_Group_KolabObject $group The group to remove.
+ * @param boolean $force Force to remove every child.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function removeGroup($group, $force = false)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Return a Horde_Group_KolabObject corresponding to the given dn, with the
+ * users and other data retrieved appropriately.
+ *
+ * @param string $dn The dn of the group to retrieve.
+ *
+ * @return Horde_Group_KolabObject The requested group.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupById($dn)
+ {
+ static $cache = array();
+
+ if (!isset($cache[$dn])) {
+ /* Connect to the LDAP server. */
+ $success = $this->_connect();
+
+ $search = @ldap_search($this->_ds, $dn, $this->_filter);
+ if (!$search) {
+ throw new Horde_Group_Exception('Could not reach the LDAP server');
+ }
+
+ $result = @ldap_get_entries($this->_ds, $search);
+ @ldap_close($this->_ds);
+ if (!is_array($result) || (count($result) <= 1)) {
+ throw new Horde_Group_Exception('Empty result');
+ }
+
+ $attributes = array();
+ for ($i = 0; $i < $result[0]['count']; $i++) {
+ if ($result[0][$result[0][$i]]['count'] > 1) {
+ $attributes[$result[0][$i]] = array();
+ for ($j = 0; $j < $result[0][$result[0][$i]]['count']; $j++) {
+ $attributes[$result[0][$i]][] = $result[0][$result[0][$i]][$j];
+ }
+ } else {
+ $attributes[$result[0][$i]] = $result[0][$result[0][$i]][0];
+ }
+ }
+ $attributes['dn'] = $result[0]['dn'];
+
+ $group = new Horde_Group_KolabObject($this->getGroupName($dn));
+ $group->_fromAttributes($attributes);
+ $group->setGroupOb($this);
+ $cache[$dn] = $group;
+ }
+
+ return $cache[$dn];
+ }
+
+
+ /**
+ * Retrieve the ID of the given group.
+ *
+ * NOTE: If given a group name, this function can be unreliable if more
+ * than one group exists with the same name.
+ *
+ * @param mixed $group LDAP_Group object, or a group name (string)
+ *
+ * @return string The group's ID.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupId($group)
+ {
+ static $cache = array();
+
+ if ($group instanceof Horde_Group_KolabObject) {
+ return $group->getDn();
+ }
+
+ if (!isset($cache[$group])) {
+ $this->_connect();
+ $search = @ldap_search($this->_ds, $this->_params['basedn'],
+ $this->_params['gid'] . '=' . $group,
+ array($this->_params['gid']));
+ if (!$search) {
+ throw new Horde_Group_Exception('Could not reach the LDAP server');
+ }
+
+ $result = @ldap_get_entries($this->_ds, $search);
+ @ldap_close($this->_ds);
+ if (!is_array($result) || (count($result) <= 1)) {
+ throw new Horde_Group_Exception('Empty result');
+ }
+ $cache[$group] = $result[0]['dn'];
+ }
+
+ return $cache[$group];
+ }
+
+ /**
+ * Get a list of the parents of a child group.
+ *
+ * @param string $dn The fully qualified group dn
+ *
+ * @return array Nested array of parents
+ */
+ public function getGroupParents($dn)
+ {
+ return array();
+ }
+
+ /**
+ * Get the parent of the given group.
+ *
+ * @param string $dn The dn of the child group.
+ *
+ * @return string The dn of the parent group.
+ */
+ public function getGroupParent($dn)
+ {
+ return null;
+ }
+
+ /**
+ * Get a list of parents all the way up to the root object for the given
+ * group.
+ *
+ * @param string $dn The dn of the group.
+ *
+ * @return array A flat list of all of the parents of the given group,
+ * hashed in $dn => $name format.
+ */
+ public function getGroupParentList($dn)
+ {
+ return array();
+ }
+
+ /**
+ * Tries to find a DN for a given kolab mail address.
+ *
+ * @param string $mail The mail address to search for.
+ *
+ * @return string The corresponding dn or false.
+ * @throws Horde_Group_Exception
+ */
+ public function dnForMail($mail)
+ {
+ $filter = '(&(objectclass=kolabInetOrgPerson)(mail=' . Horde_Ldap::quote($mail) . '))';
+ $search = @ldap_search($this->_ds, $this->_params['basedn'], $filter);
+ if (!$search) {
+ throw new Horde_Group_Exception('Could not reach the LDAP server');
+ }
+ $dn = @ldap_first_entry($this->_ds, $search);
+ if ($dn) {
+ return ldap_get_dn($this->_ds, $dn);
+ }
+
+ throw new Horde_Group_Exception(sprintf('Error searching for user with the email address "%s"!', $mail));
+ }
+
+ /**
+ * Get a list of every group that the given user is a member of.
+ *
+ * @param string $user The user to get groups for.
+ * @param boolean $parentGroups Also return the parents of any groups?
+ *
+ * @return array An array of all groups the user is in.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupMemberships($user, $parentGroups = false)
+ {
+ static $cache = array();
+
+ if (empty($cache[$user])) {
+ /* Connect to the LDAP server. */
+ $success = $this->_connect();
+ $dn = $this->dnForMail($user);
+
+ // Set up search filter
+ $filter = '(' . $this->_params['memberuid'] . '=' . $dn . ')';
+
+ // Perform search
+ $search = @ldap_search($this->_ds, $this->_params['basedn'], $filter);
+ if (!$search) {
+ throw new Horde_Group_Exception('Could not reach the LDAP server');
+ }
+
+ $result = @ldap_get_entries($this->_ds, $search);
+ @ldap_close($this->_ds);
+ if (!is_array($result) || (count($result) <= 1)) {
+ return array();
+ }
+
+ $groups = array();
+ $current_charset = Horde_Nls::getCharset();
+ for ($i = 0; $i < $result['count']; $i++) {
+ $utf8_dn = Horde_String::convertCharset($result[$i]['dn'], 'UTF-8', $current_charset);
+ $groups[$utf8_dn] = $this->getGroupName($utf8_dn);
+ }
+
+ $cache[$user] = $groups;
+ }
+
+ return $cache[$user];
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2005-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Ben Chavet <ben@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_KolabObject extends LDAP_Group
+{
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of this group.
+ * @param string $parent The dn of the parent of this group.
+ */
+ public function __construct($name, $parent = null)
+ {
+ $this->setName($name);
+ }
+
+ /**
+ * Fetch the ID of this group
+ *
+ * @return string The group's ID
+ */
+ public function getId()
+ {
+ return $this->getDn();
+ }
+
+ /**
+ * Save any changes to this object to the backend permanently.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function save()
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Adds a user to this group, and makes sure that the backend is
+ * updated as well.
+ *
+ * @param string $username The user to add.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function addUser($username, $update = true)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Removes a user from this group, and makes sure that the backend
+ * is updated as well.
+ *
+ * @param string $username The user to remove.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function removeUser($username, $update = true)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Get all the users recently added or removed from the group.
+ */
+ public function getAuditLog()
+ {
+ return array();
+ }
+
+ /**
+ * Clears the audit log. To be called after group update.
+ */
+ public function clearAuditLog()
+ {
+ }
+
+ /**
+ * Sets the name of this object.
+ *
+ * @param string $name The name to set this object's name to.
+ */
+ public function getDn()
+ {
+ return $this->name . ',' . $GLOBALS['conf']['kolab']['ldap']['basedn'];
+ }
+
+ /**
+ * Take in a list of attributes from the backend and map it to our
+ * internal data array.
+ *
+ * @param array $attributes The list of attributes from the backend.
+ */
+ protected function _fromAttributes($attributes = array())
+ {
+ $this->data['users'] = array();
+ foreach ($attributes as $key => $value) {
+ if (Horde_String::lower($key) == 'member') {
+ if (is_array($value)) {
+ foreach ($value as $user) {
+ $pattern = '/^cn=([^,]+).*$/';
+ $results = array();
+ preg_match($pattern, $user, $results);
+ if (isset($results[1])) {
+ $user = $results[1];
+ }
+ $this->data['users'][$user] = '1';
+ }
+ } else {
+ $pattern = '/^cn=([^,]+).*$/';
+ $results = array();
+ preg_match($pattern, $value, $results);
+ if (isset($results[1])) {
+ $value = $results[1];
+ }
+ $this->data['users'][$value] = '1';
+ }
+ } elseif ($key == 'mail') {
+ $this->data['email'] = $value;
+ } else {
+ $this->data[$key] = $value;
+ }
+ }
+ }
+
+ /**
+ * Map this object's attributes from the data array into a format that
+ * can be stored in an LDAP entry.
+ *
+ * @return array The entry array.
+ */
+ protected function _toAttributes()
+ {
+ $attributes = array();
+ foreach ($this->data as $key => $value) {
+ if ($key == 'users') {
+ foreach ($value as $user => $membership) {
+ $user = 'cn=' . $user . ',' . $GLOBALS['conf']['kolab']['ldap']['basedn'];
+ $attributes['member'][] = $user;
+ }
+ } elseif ($key == 'email') {
+ if (!empty($value)) {
+ $attributes['mail'] = $value;
+ }
+ } elseif ($key != 'dn' && $key != 'member') {
+ $attributes[$key] = !empty($value) ? $value : ' ';
+ }
+ }
+
+ return $attributes;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides an LDAP backend for the Horde groups system.
+ *
+ * Copyright 2005-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Ben Chavet <ben@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_Ldap extends Horde_Group
+{
+ /**
+ * LDAP connection handle
+ */
+ protected $_ds;
+
+ /**
+ * Local copy of the global $conf['group']['params'] array. Simply
+ * for coding convenience.
+ */
+ protected $_params;
+
+ /**
+ * Generated LDAP filter based on the config parameters
+ */
+ protected $_filter;
+
+ /**
+ * Constructor.
+ */
+ public function __construct($params)
+ {
+ $this->_params = $GLOBALS['conf']['group']['params'];
+
+ $this->_params['gid'] = Horde_String::lower($this->_params['gid']);
+ $this->_params['memberuid'] = Horde_String::lower($this->_params['memberuid']);
+ foreach ($this->_params['newgroup_objectclass'] as $key => $val) {
+ $this->_params['newgroup_objectclass'][$key] = Horde_String::lower($val);
+ }
+
+ /* Generate LDAP search filter. */
+ if (!empty($this->_params['filter'])) {
+ $this->_filter = $this->_params['filter'];
+ } elseif (!is_array($this->_params['objectclass'])) {
+ $this->_filter = 'objectclass=' . $this->_params['objectclass'];
+ } else {
+ $this->_filter = '';
+ foreach ($this->_params['objectclass'] as $objectclass) {
+ $this->_filter = '(&' . $this->_filter;
+ $this->_filter .= '(objectclass=' . $objectclass . '))';
+ }
+ }
+
+ $this->_filter = Horde_String::lower($this->_filter);
+ }
+
+ /**
+ * Connects to the LDAP server.
+ *
+ * @throws Horde_Group_Exception
+ */
+ protected function _connect()
+ {
+ /* Connect to the LDAP server. */
+ $this->_ds = @ldap_connect($this->_params['hostspec']);
+ if (!$this->_ds) {
+ throw new Horde_Group_Exception('Could not reach the LDAP server');
+ }
+
+ if (!ldap_set_option($this->_ds, LDAP_OPT_PROTOCOL_VERSION,
+ $this->_params['version'])) {
+ Horde::logMessage(
+ sprintf('Set LDAP protocol version to %d failed: [%d] %s',
+ $this->_params['version'],
+ ldap_errno($conn),
+ ldap_error($conn),
+ __FILE__, __LINE__));
+ }
+
+ /* Start TLS if we're using it. */
+ if (!empty($this->_params['tls'])) {
+ if (!@ldap_start_tls($this->_ds)) {
+ Horde::logMessage(
+ sprintf('STARTTLS failed: [%d] %s',
+ @ldap_errno($this->_ds),
+ @ldap_error($this->_ds)),
+ 'ERR');
+ }
+ }
+
+ if (isset($this->_params['binddn'])) {
+ $bind = @ldap_bind($this->_ds, $this->_params['binddn'],
+ $this->_params['password']);
+ } else {
+ $bind = @ldap_bind($this->_ds);
+ }
+
+ if (!$bind) {
+ throw new Horde_Group_Exception('Could not bind to LDAP server');
+ }
+ }
+
+ /**
+ * Recursively deletes $dn. $this->_ds MUST already be connected.
+ *
+ * @throws Horde_Group_Exception
+ */
+ protected function _recursive_delete($dn)
+ {
+ $search = @ldap_list($this->_ds, $dn, 'objectclass=*', array(''));
+ if (!$search) {
+ throw new Horde_Group_Exception('Could not reach the LDAP server');
+ }
+
+ $children = @ldap_get_entries($this->_ds, $search);
+ for ($i = 0; $i < $children['count']; $i++) {
+ $result = $this->_recursive_delete($children[$i]['dn']);
+ if (!$result) {
+ throw new Horde_Group_Exception(sprintf(__CLASS__ . ': Unable to delete group "%s". This is what the server said: %s', $this->getName($children[$i]['dn']), @ldap_error($this->_ds)));
+ }
+ }
+
+ if (!@ldap_delete($this->_ds, $dn)) {
+ throw new Horde_Group_Exception(sprintf(__CLASS__ . ': Unable to delete group "%s". This is what the server said: %s', $dn, @ldap_error($this->_ds)));
+ }
+ }
+
+ /**
+ * Searches existing groups for the highest gidnumber, and returns
+ * one higher.
+ *
+ * @return integer
+ *
+ * @throws Horde_Group_Exception
+ */
+ protected function _nextGid()
+ {
+ /* Connect to the LDAP server. */
+ $this->_connect();
+
+ $search = @ldap_search($this->_ds, $this->_params['basedn'], $this->_filter);
+ if (!$search) {
+ throw new Horde_Group_Exception('Could not reach the LDAP server');
+ }
+
+ $result = @ldap_get_entries($this->_ds, $search);
+ @ldap_close($this->_ds);
+
+ if (!is_array($result) || (count($result) <= 1)) {
+ return 1;
+ }
+
+ $nextgid = 0;
+ for ($i = 0; $i < $result['count']; $i++) {
+ if ($result[$i]['gidnumber'][0] > $nextgid) {
+ $nextgid = $result[$i]['gidnumber'][0];
+ }
+ }
+
+ return $nextgid + 1;
+ }
+
+ /**
+ * Return a new group object.
+ *
+ * @param string $name The group's name.
+ * @param string $parent The group's parent's ID (DN).
+ *
+ * @return Horde_Group_LdapObject A new group object.
+ * @throws Horde_Exception
+ */
+ public function newGroup(string $name, $parent = null)
+ {
+ try {
+ $entry = Horde::callHook('groupldap', array($name, $parent));
+ } catch (Horde_Exception_HookNotSet $e) {
+ // Try this simple default and hope it works.
+ $entry[$this->_params['gid']] = $name;
+ $entry['objectclass'] = $this->_params['newgroup_objectclass'];
+ $entry['gidnumber'] = $this->_nextGid();
+ }
+
+ $group = new Horde_Group_LdapObject($name, $parent);
+ $group->_fromAttributes($entry);
+ $group->setGroupOb($this);
+
+ return $group;
+ }
+
+ /**
+ * Return a group object corresponding to the named group, with the
+ * users and other data retrieved appropriately.
+ *
+ * @param string $name The name of the group to retrieve.
+ *
+ * @return Horde_Group_LdapObject The requested group.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroup($name)
+ {
+ return $this->getGroupById($this->getGroupId($name));
+ }
+
+ /**
+ * Return a group object corresponding to the given dn, with the
+ * users and other data retrieved appropriately.
+ *
+ * @param string $dn The dn of the group to retrieve.
+ *
+ * @return Horde_Group_LdapObject The requested group.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupById($dn)
+ {
+ static $cache = array();
+
+ if (!isset($cache[$dn])) {
+ /* Connect to the LDAP server. */
+ $this->_connect();
+
+ $search = @ldap_search($this->_ds, $dn, $this->_filter);
+ if (!$search) {
+ throw new Horde_Group_Exception('Could not reach the LDAP server');
+ }
+
+ $result = @ldap_get_entries($this->_ds, $search);
+ @ldap_close($this->_ds);
+ if (!is_array($result) || (count($result) <= 1)) {
+ throw new Horde_Group_Exception('Empty result');
+ }
+
+ $attributes = array();
+ for ($i = 0; $i < $result[0]['count']; $i++) {
+ if ($result[0][$result[0][$i]]['count'] > 1) {
+ $attributes[$result[0][$i]] = array();
+ for ($j = 0; $j < $result[0][$result[0][$i]]['count']; $j++) {
+ $attributes[$result[0][$i]][] = $result[0][$result[0][$i]][$j];
+ }
+ } else {
+ $attributes[$result[0][$i]] = $result[0][$result[0][$i]][0];
+ }
+ }
+ $attributes['dn'] = $result[0]['dn'];
+
+ $group = new Horde_Group_LdapObject($this->getGroupName($dn));
+ $group->_fromAttributes($attributes);
+ $group->setGroupOb($this);
+ $cache[$dn] = $group;
+ }
+
+ return $cache[$dn];
+ }
+
+ /**
+ * Get a globally unique ID for a group. This really just returns the dn
+ * for the group, but is included for compatibility with the Group class.
+ *
+ * @param Horde_Group_LdapObject $group The group.
+ *
+ * @return string A GUID referring to $group.
+ */
+ public function getGUID($group)
+ {
+ return $group->get('dn');
+ }
+
+ /**
+ * Add a group to the groups system. The group must first be created with
+ * Group_ldap::newGroup(), and have any initial users added to it, before
+ * this function is called.
+ *
+ * @param Horde_Group_LdapObject $group The new group object.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function addGroup(Horde_Group_DataTreeObject $group)
+ {
+ /* Connect to the LDAP server. */
+ $this->_connect();
+
+ $dn = $group->get('dn');
+
+ $entry = $group->_toAttributes();
+ $success = @ldap_add($this->_ds, $dn, $entry);
+
+ if (!$success) {
+ throw new Horde_Group_Exception(sprintf(__CLASS__ . ': Unable to add group "%s". This is what the server said: ', $group->getName()) . @ldap_error($this->_ds));
+ }
+
+ @ldap_close($this->_ds);
+ }
+
+ /**
+ * Store updated data - users, etc. - of a group to the backend system.
+ *
+ * @param Horde_Group_LdapObject $group The group to update
+ *
+ * @throws Horde_Group_Exception
+ * @throws Horde_History_Exception
+ * @throws InvalidArgumentException
+ */
+ public function updateGroup(Horde_Group_DataTreeObject $group)
+ {
+ $entry = $group->_toAttributes();
+
+ /* Connect to the LDAP server. */
+ $this->_connect();
+
+ // Do not attempt to change an LDAP object's objectClasses
+ unset($entry['objectclass']);
+
+ $result = @ldap_modify($this->_ds, $group->getId(), $entry);
+ if (!$result) {
+ throw new Horde_Group_Exception(sprintf(__CLASS__ . ': Unable to update group "%s". This is what the server said: %s', $group->getName(), @ldap_error($this->_ds)));
+ }
+
+ @ldap_close($this->_ds);
+
+ /* Log the update of the group users on the history log. */
+ $history = $GLOBALS['injector']->getInstance('Horde_History');
+ $guid = $this->getGUID($group);
+ foreach ($group->getAuditLog() as $userId => $action) {
+ $history->log($guid, array('action' => $action, 'user' => $userId), true);
+ }
+ $group->clearAuditLog();
+
+ /* Log the group modification. */
+ $history->log($guid, array('action' => 'modify'), true);
+
+ return $result;
+ }
+
+ /**
+ * Remove a group from the groups system permanently.
+ *
+ * @param Horde_Group_LdapObject $group The group to remove.
+ * @param boolean $force Recursively delete children groups if true.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function removeGroup(Horde_Group_DataTreeObject $group,
+ $force = false)
+ {
+ $dn = $group->getId();
+
+ /* Connect to the LDAP server. */
+ $this->_connect();
+
+ if ($force) {
+ return $this->_recursive_delete($dn);
+ }
+
+ if (!@ldap_delete($this->_ds, $dn)) {
+ throw new Horde_Group_Exception(sprintf(__CLASS__ . ': Unable to delete group "%s". This is what the server said: %s', $dn, @ldap_error($this->_ds)));
+ }
+ }
+
+ /**
+ * Retrieve the name of a group.
+ *
+ * @param string $dn The dn of the group to retrieve the name for.
+ *
+ * @return string The group's name.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupName($dn)
+ {
+ $dn = Horde_String::convertCharset($dn, Horde_Nls::getCharset(), 'UTF-8');
+ $result = @ldap_explode_dn($dn, 1);
+ if ($result === false) {
+ throw new Horde_Group_Exception('Invalid group ID passed (bad DN syntax)');
+ }
+
+ return $result[0];
+ }
+
+ /**
+ * DataTreeObject full names include references to parents, but LDAP does
+ * not have this concept. This function simply returns the $group
+ * parameter and is included for compatibility with the Group class.
+ *
+ * @param string $group Group name.
+ *
+ * @return string $group.
+ */
+ public function getGroupShortName($group)
+ {
+ return $group;
+ }
+
+ /**
+ * Retrieve the ID of the given group.
+ *
+ * NOTE: If given a group name, this function can be unreliable if more
+ * than one group exists with the same name.
+ *
+ * @param mixed $group Group object, or a group name (string).
+ *
+ * @return string The group's ID.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupId($group)
+ {
+ static $cache = array();
+
+ if ($group instanceof Horde_Group_LdapObject) {
+ return $group->get('dn');
+ }
+
+ if (!isset($cache[$group])) {
+ $this->_connect();
+ $search = @ldap_search($this->_ds, $this->_params['basedn'],
+ $this->_params['gid'] . '=' . $group,
+ array($this->_params['gid']));
+ if (!$search) {
+ throw new Horde_Group_Exception('Could not reach the LDAP server');
+ }
+
+ $result = @ldap_get_entries($this->_ds, $search);
+ @ldap_close($this->_ds);
+ if (!is_array($result) || (count($result) <= 1)) {
+ throw new Horde_Group_Exception('Empty result');
+ }
+ $cache[$group] = $result[0]['dn'];
+ }
+
+ return $cache[$group];
+ }
+
+ /**
+ * Check if a group exists in the system.
+ *
+ * @param string $group The group name to check for.
+ *
+ * @return boolean True if the group exists, False otherwise.
+ * @throws Horde_Group_Exception
+ */
+ public function exists($group)
+ {
+ static $cache = array();
+
+ if (!isset($cache[$group])) {
+ /* Connect to the LDAP server. */
+ $this->_connect();
+
+ $groupDN = $this->getGroupId($group);
+ $group = $this->getGroupShortName($group);
+
+ $res = @ldap_compare($this->_ds, $groupDN, $this->_params['gid'], $group);
+ if ($res === false) {
+ throw new Horde_Group_Exception(sprintf('Internal Error: An attribute must ALWAYS match itself: %s', @ldap_error($this->_ds)));
+ }
+ // $res is True if the group exists, -1 if not, false never
+ $cache[$group] = ($res === true);
+ }
+
+ return $cache[$group];
+ }
+
+ /**
+ * Get a list of the parents of a child group.
+ *
+ * @param string $dn The fully qualified group dn
+ *
+ * @return array Nested array of parents
+ */
+ public function getGroupParents($dn)
+ {
+ $parent = $this->getGroupParent($dn);
+ $parents = array(DATATREE_ROOT => 1);
+ while ($parent != DATATREE_ROOT) {
+ $parents = array($parent => $parents);
+ $parent = $this->getGroupParent($parent);
+ }
+ return $parents;
+ }
+
+ /**
+ * Get the parent of the given group.
+ *
+ * @param string $dn The dn of the child group.
+ *
+ * @return string The dn of the parent group.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupParent($dn)
+ {
+ if (@ldap_explode_dn($dn, 0) === false) {
+ throw new Horde_Group_Exception('Invalid group ID passed (bad DN syntax)');
+ }
+
+ unset($result['count'], $result[0]);
+ $parent_dn = implode(',', $result);
+
+ return (Horde_String::lower($parent_dn) == Horde_String::lower($GLOBALS['conf']['group']['params']['basedn']))
+ ? DATATREE_ROOT
+ : $parent_dn;
+ }
+
+ /**
+ * Get a list of parents all the way up to the root object for the given
+ * group.
+ *
+ * @param string $dn The dn of the group.
+ *
+ * @return array A flat list of all of the parents of the given group,
+ * hashed in $dn => $name format.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupParentList($dn)
+ {
+ if (@ldap_explode_dn($dn, 0) === false) {
+ throw new Horde_Group_Exception('Invalid group ID passed (bad DN syntax)');
+ }
+
+ $num = $result['count'];
+ unset($result['count'], $result[0]);
+
+ $count = 0;
+ $parents = array();
+ $parent_dn = implode(',', $result);
+ while ($parent_dn != $this->_params['basedn'] && $count++ != $num) {
+ $parents[$parent_dn] = $this->getGroupName($parent_dn);
+ unset($result[$count]);
+ $parent_dn = implode(',', $result);
+ }
+ $parents[DATATREE_ROOT] = DATATREE_ROOT;
+
+ return $parents;
+ }
+
+ /**
+ * Get a list of every group, in the format dn => groupname.
+ *
+ * @param boolean $refresh If true, the cached value is ignored and the
+ * group list is refreshed from the group backend.
+ *
+ * @return array dn => groupname hash.
+ * @throws Horde_Group_Exception
+ */
+ public function listGroups($refresh = false)
+ {
+ static $groups;
+
+ if ($refresh || is_null($groups)) {
+ /* Connect to the LDAP server. */
+ $this->_connect();
+
+ $search = @ldap_search($this->_ds, $this->_params['basedn'], $this->_filter, array($this->_params['gid']));
+ if (!$search) {
+ throw new Horde_Group_Exception('Could not reach the LDAP server');
+ }
+
+ @ldap_sort($this->_ds, $search, $this->_params['gid']);
+
+ $result = @ldap_get_entries($this->_ds, $search);
+ @ldap_close($this->_ds);
+ if (!is_array($result) || (count($result) <= 1)) {
+ return array();
+ }
+
+ $groups = array();
+ for ($i = 0; $i < $result['count']; $i++) {
+ $groups[$result[$i]['dn']] = $this->getGroupName($result[$i]['dn']);
+ }
+ }
+
+ return $groups;
+ }
+
+ /**
+ * Get a list of every user that is part of the specified group and any
+ * of its subgroups.
+ *
+ * @param string $dn The dn of the parent group.
+ *
+ * @return array The complete user list.
+ * @throws Horde_Group_Exception
+ */
+ public function listAllUsers($dn)
+ {
+ static $cache = array();
+
+ if (!isset($cache[$dn])) {
+ $this->_connect();
+
+ $search = @ldap_search($this->_ds, $dn, $this->_filter);
+ if (!$search) {
+ throw new Horde_Group_Exception(sprintf('Could not reach the LDAP server: %s', @ldap_error($this->_ds)));
+ }
+
+ $result = @ldap_get_entries($this->_ds, $search);
+ @ldap_close($this->_ds);
+ if (!is_array($result) || (count($result) <= 1)) {
+ // Not an error, we just don't have any users in this group.
+ return array();
+ }
+
+ $users = array();
+ for ($i = 0; $i < $result['count']; $i++) {
+ $users = array_merge($users, $this->listUsers($result[$i]['dn']));
+ }
+
+ $cache[$dn] = array_keys(array_flip($users));
+ }
+
+ return $cache[$dn];
+ }
+
+ /**
+ * Get a list of every group that the given user is a member of.
+ *
+ * @param string $user The user to get groups for.
+ * @param boolean $parentGroups Also return the parents of any groups?
+ *
+ * @return array An array of all groups the user is in.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupMemberships($user, $parentGroups = false)
+ {
+ static $cache = array();
+
+ if (empty($cache[$user])) {
+ /* Connect to the LDAP server. */
+ $this->_connect();
+
+ // Set up search filter
+ $filter = '(' . $this->_params['memberuid'] . '=';
+ if ($GLOBALS['conf']['group']['params']['attrisdn']) {
+ $filter .= $GLOBALS['conf']['auth']['params']['uid'] . '=';
+ }
+ $filter .= $user;
+ if ($GLOBALS['conf']['group']['params']['attrisdn']) {
+ $filter .= ',' . $GLOBALS['conf']['auth']['params']['basedn'];
+ }
+ $filter .= ')';
+
+ // Perform search
+ $search = @ldap_search($this->_ds, $this->_params['basedn'], $filter);
+ if (!$search) {
+ throw new Horde_Group_Exception('Could not reach the LDAP server');
+ }
+
+ $result = @ldap_get_entries($this->_ds, $search);
+ @ldap_close($this->_ds);
+ if (!is_array($result) || (count($result) <= 1)) {
+ return array();
+ }
+
+ $groups = array();
+ $current_charset = Horde_Nls::getCharset();
+ for ($i = 0; $i < $result['count']; $i++) {
+ $utf8_dn = Horde_String::convertCharset($result[$i]['dn'], 'UTF-8', $current_charset);
+ $groups[$utf8_dn] = $this->getGroupName($utf8_dn);
+ }
+
+ $cache[$user] = $groups;
+ }
+
+ return $cache[$user];
+ }
+
+ /**
+ * Returns the tree depth of the given group, relative to the base dn.
+ * 0 is returned for any object directly below the base dn.
+ *
+ * @param string $dn The dn of the object.
+ *
+ * @return intenger The tree depth of the group.
+ * @throws Horde_Group_Exception
+ */
+ public function getLevel($dn)
+ {
+ $base = @ldap_explode_dn($this->_params['basedn'], 0);
+ if ($base === false) {
+ throw new Horde_Group_Exception('Invalid basedn configured');
+ }
+
+ $group = @ldap_explode_dn($dn, 0);
+ if ($group === false) {
+ throw new Horde_Group_Exception('Invalid group ID passed (bad DN syntax)');
+ }
+
+ return $group['count'] - $base['count'] - 1;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Extension of the Horde_Group_DataTreeObject class for storing group
+ * information in an LDAP directory.
+ *
+ * Copyright 2005-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Ben Chavet <ben@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_LdapObject extends Horde_Group_DataTreeObject
+{
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of this group.
+ * @param string $parent The dn of the parent of this group.
+ */
+ public function __construct($name, $parent = null)
+ {
+ parent::__construct($name);
+ if ($parent) {
+ $this->data['dn'] = Horde_String::lower($GLOBALS['conf']['group']['params']['gid']) . '=' . $name . ',' . $parent;
+ } else {
+ $this->data['dn'] = Horde_String::lower($GLOBALS['conf']['group']['params']['gid']) . '=' . $name .
+ ',' . Horde_String::lower($GLOBALS['conf']['group']['params']['basedn']);
+ }
+ }
+
+ /**
+ * Get a list of every user that is part of this group (and only
+ * this group).
+ *
+ * @return array The user list.
+ */
+ public function listUsers()
+ {
+ return $this->_groupOb->listUsers($this->data['dn']);
+ }
+
+ /**
+ * Get a list of every user that is a member of this group and any of
+ * it's subgroups.
+ *
+ * @return array The complete user list.
+ */
+ public function listAllUsers()
+ {
+ return $this->_groupOb->listAllUsers($this->data['dn']);
+ }
+
+ /**
+ * Take in a list of attributes from the backend and map it to our
+ * internal data array.
+ *
+ * @param array $attributes The list of attributes from the backend.
+ */
+ protected function _fromAttributes($attributes = array())
+ {
+ $this->data['users'] = array();
+ foreach ($attributes as $key => $value) {
+ if (Horde_String::lower($key) == Horde_String::lower($GLOBALS['conf']['group']['params']['memberuid'])) {
+ if (is_array($value)) {
+ foreach ($value as $user) {
+ if ($GLOBALS['conf']['group']['params']['attrisdn']) {
+ $pattern = '/^' . $GLOBALS['conf']['auth']['params']['uid'] . '=([^,]+).*$/';
+ $results = array();
+ preg_match($pattern, $user, $results);
+ if (isset($results[1])) {
+ $user = $results[1];
+ }
+ }
+ $this->data['users'][$user] = '1';
+ }
+ } else {
+ if ($GLOBALS['conf']['group']['params']['attrisdn']) {
+ $pattern = '/^' . $GLOBALS['conf']['auth']['params']['uid'] . '=([^,]+).*$/';
+ $results = array();
+ preg_match($pattern, $value, $results);
+ if (isset($results[1])) {
+ $value = $results[1];
+ }
+ }
+ $this->data['users'][$value] = '1';
+ }
+ } elseif ($key == 'mail') {
+ $this->data['email'] = $value;
+ } else {
+ $this->data[$key] = $value;
+ }
+ }
+ }
+
+ /**
+ * Map this object's attributes from the data array into a format that
+ * can be stored in an LDAP entry.
+ *
+ * @return array The entry array.
+ */
+ protected function _toAttributes()
+ {
+ $attributes = array();
+ foreach ($this->data as $key => $value) {
+ if ($key == 'users') {
+ foreach ($value as $user => $membership) {
+ if ($GLOBALS['conf']['group']['params']['attrisdn']) {
+ $user = $GLOBALS['conf']['auth']['params']['uid'] .
+ '=' . $user . ',' . $GLOBALS['conf']['auth']['params']['basedn'];
+ }
+ $attributes[Horde_String::lower($GLOBALS['conf']['group']['params']['memberuid'])][] = $user;
+ }
+ } elseif ($key == 'email') {
+ if (!empty($value)) {
+ $attributes['mail'] = $value;
+ }
+ } elseif ($key != 'dn' && $key != Horde_String::lower($GLOBALS['conf']['group']['params']['memberuid'])) {
+ $attributes[$key] = !empty($value) ? $value : ' ';
+ }
+ }
+
+ return $attributes;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2008-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Duck <duck@obala.net>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_Mock extends Horde_Group {
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ }
+
+ /**
+ * Initializes the object.
+ */
+ public function __wakeup()
+ {
+ }
+
+ /**
+ * Returns a new group object.
+ *
+ * @param string $name The group's name.
+ * @param string $parent The group's parent's name.
+ *
+ * @return DataTreeObject_Group A new group object.
+ * @throws Horde_Group_Exception
+ */
+ public function newGroup($name, $parent = GROUP_ROOT)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Returns a DataTreeObject_Group object corresponding to the named group,
+ * with the users and other data retrieved appropriately.
+ *
+ * @param string $name The name of the group to retrieve.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function getGroup($name)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Returns a group object corresponding to the given unique
+ * ID, with the users and other data retrieved appropriately.
+ *
+ * @param integer $cid The unique ID of the group to retrieve.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupById($cid)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Adds a group to the groups system. The group must first be created with
+ * newGroup(), and have any initial users added to it, before this
+ * function is called.
+ *
+ * @param Horde_Group_DataTreeObject $group The new group object.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function addGroup($group)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Stores updated data - users, etc. - of a group to the backend system.
+ *
+ * @param Horde_Group_DataTreeObject $group The group to update.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function updateGroup($group)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Removes a group from the groups system permanently.
+ *
+ * @param Horde_Group_DataTreeObject $group The group to remove.
+ * @param boolean $force Force to remove every child.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function removeGroup($group, $force = false)
+ {
+ throw new Horde_Group_Exception('Unsupported.');
+ }
+
+ /**
+ * Retrieves the name of a group.
+ *
+ * @param integer|Horde_Group_DataTreeObject $gid The id of the group or the
+ * group object to retrieve the
+ * name for.
+ *
+ * @return string The group's name.
+ */
+ public function getGroupName($gid)
+ {
+ return '';
+ }
+
+ /**
+ * Strips all parent references off of the given group name.
+ *
+ * @param string $group Name of the group.
+ *
+ * @return The name of the group without parents.
+ */
+ public function getGroupShortName($group)
+ {
+ return '';
+ }
+
+ /**
+ * Retrieves the ID of a group.
+ *
+ * @param string|Horde_Group_DataTreeObject $group The group name or object to
+ * retrieve the ID for.
+ *
+ * @return integer The group's ID.
+ */
+ public function getGroupId($group)
+ {
+ return '';
+ }
+
+ /**
+ * Check if a group exists in the system.
+ *
+ * @param string $group The group to check.
+ *
+ * @return boolean True if the group exists, false otherwise.
+ */
+ public function exists($group)
+ {
+ return false;
+ }
+
+ /**
+ * Returns a tree of the parents of a child group.
+ *
+ * @param integer $gid The id of the child group.
+ *
+ * @return array The group parents tree, with groupnames as the keys.
+ */
+ public function getGroupParents($gid)
+ {
+ return array();
+ }
+
+ /**
+ * Returns the single parent ID of the given group.
+ *
+ * @param integer $gid The DataTree ID of the child group.
+ *
+ * @return integer The parent of the given group.
+ */
+ public function getGroupParent($gid)
+ {
+ return null;
+ }
+
+ /**
+ * Returns a flat list of the parents of a child group
+ *
+ * @param integer $gid The id of the group.
+ *
+ * @return array A flat list of all of the parents of $group, hashed in
+ * $id => $name format.
+ */
+ public function getGroupParentList($gid)
+ {
+ return array();
+ }
+
+ /**
+ * Returns a list of all groups, in the format id => groupname.
+ *
+ * @param boolean $refresh If true, the cached value is ignored and the
+ * group list is refreshed from the group backend.
+ *
+ * @return array ID => groupname hash.
+ */
+ public function listGroups($refresh = false)
+ {
+ return array();
+ }
+
+ /**
+ * Get a list of every user that is a part of this group ONLY.
+ *
+ * @param integer $gid The ID of the group.
+ *
+ * @return array The user list.
+ */
+ public function listUsers($gid)
+ {
+ return array();
+ }
+
+ /**
+ * Get a list of every user that is part of the specified group
+ * and any of its subgroups.
+ *
+ * @param integer $group The ID of the parent group.
+ *
+ * @return array The complete user list.
+ */
+ public function listAllUsers($gid)
+ {
+ return array();
+ }
+
+ /**
+ * Get a list of every group that $user is in.
+ *
+ * @param string $user The user to get groups for.
+ * @param boolean $parentGroups Also return the parents of any groups?
+ *
+ * @return array An array of all groups the user is in.
+ */
+ public function getGroupMemberships($user, $parentGroups = false)
+ {
+ return array();
+ }
+
+ /**
+ * Say if a user is a member of a group or not.
+ *
+ * @param string $user The name of the user.
+ * @param integer $gid The ID of the group.
+ * @param boolean $subgroups Return true if the user is in any subgroups
+ * of group with ID $gid, also.
+ *
+ * @return boolean
+ */
+ public function userIsInGroup($user, $gid, $subgroups = true)
+ {
+ return false;
+ }
+
+ /**
+ * Returns the nesting level of the given group. 0 is returned for any
+ * object directly below GROUP_ROOT.
+ *
+ * @param integer $gid The ID of the group.
+ *
+ * @return The nesting level of the group.
+ */
+ public function getLevel($gid)
+ {
+ return 0;
+ }
+
+ /**
+ * Stores the object in the session cache.
+ */
+ public function shutdown()
+ {
+ }
+
+ /**
+ * Returns the properties that need to be serialized.
+ *
+ * @return array List of serializable properties.
+ */
+ public function __sleep()
+ {
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Duck <duck@obala.net>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_Sql extends Horde_Group
+{
+ /**
+ * Handle for the current database connection.
+ *
+ * @var Horde_Db_Adapter_Base
+ */
+ public $db;
+
+ /**
+ * Constructor.
+ */
+ public function __construct($params)
+ {
+ $this->_params = $params;
+ $this->db = $GLOBALS['injector']->getInstance('Horde_Db')->getOb('horde', 'group');
+ }
+
+ /**
+ * Initializes the object.
+ */
+ public function __wakeup()
+ {
+ }
+
+ /**
+ * Returns the properties that need to be serialized.
+ *
+ * @return array List of serializable properties.
+ */
+ public function __sleep()
+ {
+ }
+
+ /**
+ * Stores the object in the session cache.
+ */
+ public function shutdown()
+ {
+ }
+
+ /**
+ * Replace all occurences of ':' in an object name with '.'.
+ *
+ * @param string $name The name of the object.
+ *
+ * @return string The encoded name.
+ */
+ public function encodeName($name)
+ {
+ return str_replace(':', '.', $name);
+ }
+
+ /**
+ * Returns a new group object.
+ *
+ * @param string $name The group's name.
+ * @param string $parent The group's parent's name.
+ *
+ * @return Horde_Group_SqlObject A new group object.
+ */
+ public function newGroup($name, $parent = self::ROOT)
+ {
+ if ($parent != self::ROOT) {
+ $name = $this->getGroupName($parent) . ':' . $this->encodeName($name);
+ }
+
+ $group = new Horde_Group_SqlObject($name);
+ $group->setGroupOb($this);
+
+ return $group;
+ }
+
+ /**
+ * Returns a group object corresponding to the named group,
+ * with the users and other data retrieved appropriately.
+ *
+ * @param string $name The name of the group to retrieve.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function getGroup($name)
+ {
+ if (!isset($this->_groupCache[$name])) {
+ $sql = 'SELECT group_uid, group_email FROM horde_groups WHERE group_name = ?';
+
+ try {
+ $group = $this->db->selectRow($sql, array($name));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+
+ if (empty($group)) {
+ throw new Horde_Group_Exception($name . ' does not exist');
+ }
+
+ $sql = 'SELECT user_uid FROM horde_groups_members '
+ . ' WHERE group_uid = ? ORDER BY user_uid ASC';
+
+ try {
+ $users = $this->db->selectValues($sql, array($group['group_uid']));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+
+ $object = new Horde_Group_SqlObject($name);
+ $object->id = $group['group_uid'];
+ $object->data['email'] = $group['group_email'];
+
+ if (!empty($users)) {
+ $object->data['users'] = array_flip($users);
+ }
+
+ $this->_groupCache[$name] = $object;
+ $this->_groupCache[$name]->setGroupOb($this);
+ $this->_groupMap[$this->_groupCache[$name]->getId()] = $name;
+ }
+
+ return $this->_groupCache[$name];
+ }
+
+ /**
+ * Returns a group object corresponding to the given unique
+ * ID, with the users and other data retrieved appropriately.
+ *
+ * @param integer $cid The unique ID of the group to retrieve.
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupById($cid)
+ {
+ if (isset($this->_groupMap[$cid])) {
+ return $this->_groupCache[$this->_groupMap[$cid]];
+ }
+
+ $sql = 'SELECT group_name, group_email FROM horde_groups WHERE group_uid = ?';
+
+ try {
+ $row = $this->db->selectOne($sql, array($cid));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+
+ if (empty($row)) {
+ throw new Horde_Group_Exception($cid . ' does not exist');
+ }
+
+ $sql = 'SELECT user_uid FROM horde_groups_members '
+ . ' WHERE group_uid = ? ORDER BY user_uid ASC';
+
+ try {
+ $users = $this->db->selectValues($sql, array($cid));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+
+ $group = new Horde_Group_SqlObject($row['group_name']);
+ $group->id = $cid;
+ $group->data['email'] = $row['group_email'];
+
+ if (!empty($users)) {
+ $group->data['users'] = array_flip($users);
+ }
+
+ $group->setGroupOb($this);
+ $name = $group->getName();
+ $this->_groupCache[$name] = $group;
+ $this->_groupMap[$cid] = $name;
+
+ return $group;
+ }
+
+ /**
+ * Adds a group to the groups system. The group must first be created with
+ * newGroup(), and have any initial users added to it, before this
+ * function is called.
+ *
+ * @param Horde_Group_SqlObject $group The new group object.
+ *
+ * @throws Horde_Group_Exception
+ * @throws Horde_History_Exception
+ * @throws InvalidArgumentException
+ */
+ public function addGroup(Horde_Group_SqlObject $group)
+ {
+ $group->setGroupOb($this);
+ $name = $group->getName();
+
+ $email = isset($group->data['email']) ? $group->data['email'] : '';
+
+ $query = 'INSERT INTO horde_groups (group_name, group_parents, group_email) VALUES (?, ?, ?)';
+
+ try {
+ $result = $this->db->insert($query, array($name, '', $email));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+
+ $group->id = $result;
+
+ if (!empty($group->data['users'])) {
+ $query = 'INSERT INTO horde_groups_members (group_uid, user_uid)'
+ .' VALUES (?, ?)';
+ foreach ($group->data['users'] as $user) {
+ try {
+ $this->db->insert($query, array($result, $user));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+ }
+ }
+
+ $this->_groupCache[$name] = $group;
+ $this->_groupMap[$group_id] = $name;
+ if (isset($this->_groupList)) {
+ $this->_groupList[$group_id] = $name;
+ }
+
+ /* Log the addition of the group in the history log. */
+ $GLOBALS['injector']->getInstance('Horde_History')->log($this->getGUID($group), array('action' => 'add'), true);
+ }
+
+ /**
+ * Stores updated data - users, etc. - of a group to the backend system.
+ *
+ * @param Horde_Group_SqlObject $group The group to update.
+ *
+ * @throws Horde_Group_Exception
+ * @throws Horde_History_Exception
+ * @throws InvalidArgumentException
+ */
+ public function updateGroup(Horde_Group_SqlObject $group)
+ {
+ $query = 'UPDATE horde_groups SET group_email = ? WHERE group_uid = ?';
+
+ try {
+ $this->db->update($query, array($this->data['email'], $this->id));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+
+ $query = 'DELETE FROM horde_groups_members WHERE group_uid = ?';
+
+ try {
+ $this->db->delete($query, array($this->id));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+
+ $query = 'INSERT INTO horde_groups_members (group_uid, user_uid)' .
+ ' VALUES (?, ?)';
+ foreach ($this->data['users'] as $user) {
+ try {
+ $this->db->insert($query, array(intval($this->id), $user));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+ }
+
+ $this->_groupCache[$group->getName()] = &$group;
+
+ /* Log the update of the group users on the history log. */
+ $history = $GLOBALS['injector']->getInstance('Horde_History');
+ $guid = $this->getGUID($group);
+ foreach ($group->getAuditLog() as $userId => $action) {
+ $history->log($guid, array('action' => $action, 'user' => $userId), true);
+ }
+
+ $group->clearAuditLog();
+
+ /* Log the group modification. */
+ $history->log($guid, array('action' => 'modify'), true);
+
+ return $result;
+ }
+
+ /**
+ * Removes a group from the groups system permanently.
+ *
+ * @param Horde_Group_SqlObject $group The group to remove.
+ * @param boolean $force Force to remove every child.
+ *
+ * @throws Horde_Group_Exception
+ * @throws Horde_History_Exception
+ * @throws InvalidArgumentException
+ */
+ public function removeGroup(Horde_Group_SqlObject $group, $force = false)
+ {
+ $id = $group->getId();
+ $name = $group->getName();
+ unset($this->_groupMap[$id]);
+ if (isset($this->_groupList)) {
+ unset($this->_groupList[$id]);
+ }
+ unset($this->_groupCache[$name]);
+
+ $GLOBALS['injector']->getInstance('Horde_History')->log($this->getGUID($group), array('action' => 'delete'), true);
+
+ $query = 'DELETE FROM horde_groups_members WHERE group_uid = ?';
+
+ try {
+ $this->db->delete($query, array($id));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+
+ $query = 'DELETE FROM horde_groups WHERE group_uid = ?';
+ try {
+ $this->db->delete($query, array($id));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+
+ if ($force) {
+ $query = 'DELETE FROM horde_groups WHERE group_name LIKE ?';
+
+ try {
+ $this->db->delete($query, array($name . ':%'));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+ }
+ }
+
+ /**
+ * Retrieves the name of a group.
+ *
+ * @param integer|Horde_Group_SqlObject $gid The id of the group or the
+ * group object to retrieve the
+ * name for.
+ *
+ * @return string The group's name.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupName($gid)
+ {
+ if ($gid instanceof Horde_Group_SqlObject) {
+ $gid = $gid->getId();
+ }
+
+ if (isset($this->_groupMap[$gid])) {
+ return $this->_groupMap[$gid];
+ }
+ if (isset($this->_groupList[$gid])) {
+ return $this->_groupList[$gid];
+ }
+
+ $query = 'SELECT group_name FROM horde_groups WHERE group_uid = ?';
+
+ try {
+ return $this->db->selectValue($query, $gid);
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+ }
+
+ /**
+ * Strips all parent references off of the given group name.
+ *
+ * @param string $group Name of the group.
+ *
+ * @return The name of the group without parents.
+ */
+ public function getGroupShortName($group)
+ {
+ /* If there are several components to the name, explode and get the
+ * last one, otherwise just return the name. */
+ if (strpos($group, ':') !== false) {
+ $name = explode(':', $group);
+ return array_pop($name);
+ }
+
+ return $group;
+ }
+
+ /**
+ * Retrieves the ID of a group.
+ *
+ * @param string|Horde_Group_SqlObject $group The group name or object to
+ * retrieve the ID for.
+ *
+ * @return integer The group's ID.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupId($group)
+ {
+ if ($group instanceof Horde_Group_SqlObject) {
+ return $group->getId();
+ }
+
+ $id = array_search($group, $this->_groupMap);
+ if ($id !== false) {
+ return $id;
+ }
+ if (isset($this->_groupList)) {
+ $id = array_search($group, $this->_groupList);
+ if ($id !== false) {
+ return $id;
+ }
+ }
+
+ $query = 'SELECT group_uid FROM horde_groups WHERE group_name = ?';
+
+ try {
+ return $this->db->selectValue($query, $group);
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+ }
+
+ /**
+ * Check if a group exists in the system.
+ *
+ * @param string $group The group to check.
+ *
+ * @return boolean True if the group exists, false otherwise.
+ */
+ public function exists($group)
+ {
+ if (isset($this->_groupCache[$group]) ||
+ (isset($this->_groupList) &&
+ array_search($group, $this->_groupList) !== false)) {
+ return true;
+ }
+
+ $query = 'SELECT COUNT(*) FROM horde_groups WHERE group_name = ?';
+
+ try {
+ return (bool)$this->db->selectValue($query, $group);
+ } catch (Horde_Db_Exception $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns a tree of the parents of a child group.
+ *
+ * @param integer $gid The id of the child group.
+ *
+ * @return array The group parents tree, with groupnames as the keys.
+ * @throws Horde_Group_Exception
+ */
+ function getGroupParents($gid)
+ {
+ if (!isset($this->_parentTree[$gid])) {
+ $name = $this->getGroupName($gid);
+ $this->_parentTree[$gid] = $this->_getGroupParents($name);
+ }
+
+ return $this->_parentTree[$gid];
+ }
+
+ /**
+ * Returns a list of parent permissions.
+ *
+ * @param string $child The name of the child to retrieve parents for.
+ *
+ * @return array A hash with all parents in a tree format.
+ */
+ protected function _getGroupParents($child)
+ {
+ if (($pos = strrpos($child, ':')) !== false) {
+ $child = substr($child, 0, $pos);
+ }
+
+ return $this->_getParents($child);
+ }
+
+ /**
+ */
+ protected function _getParents($parents)
+ {
+ $mother = array();
+ if (!empty($parents)) {
+ $pname = $parents;
+ $parents = substr($parents, 0, strrpos($parents, ':'));
+ $mother[$pname] = $this->_getParents($parents);
+ } else {
+ return array(self::ROOT => true);
+ }
+
+ return $mother;
+ }
+
+ /**
+ * Returns the single parent ID of the given group.
+ *
+ * @param integer $gid The ID of the child group.
+ *
+ * @return integer The parent of the given group.
+ */
+ public function getGroupParent($gid)
+ {
+ if (!isset($this->_groupParents[$gid])) {
+ $name = $this->getGroupName($gid);
+ if (($pos = strrpos($name, ':')) !== false) {
+ $this->_groupParents[$gid] = $this->getGroupId(substr($name, 0, $pos));
+ } else {
+ $this->_groupParents[$gid] = self::ROOT;
+ }
+ }
+
+ return $this->_groupParents[$gid];
+ }
+
+ /**
+ * Returns a flat list of the parents of a child group
+ *
+ * @param integer $gid The id of the group.
+ *
+ * @return array A flat list of all of the parents of $group, hashed in
+ * $id => $name format.
+ *@throws Horde_Group_Exception
+ */
+ public function getGroupParentList($gid)
+ {
+ if (!isset($this->_groupParentList[$gid])) {
+ $name = $this->getGroupName($gid);
+ $pos = strpos($name, ':');
+ if ($pos == false) {
+ $this->_groupParentList[$gid] = array();
+ return $this->_groupParentList[$gid];
+ }
+
+ $parents = array();
+ while ($pos) {
+ $name = substr($name, 0, $pos);
+ $parents[] = $name;
+ $pos = strpos($name, ':');
+ }
+
+ $query = 'SELECT group_uid, group_name FROM horde_groups '
+ . ' WHERE group_name IN (' . str_repeat('?, ', count($parents) - 1) . '?) ';
+ try {
+ $this->_groupParentList[$gid] = $this->db->selectAssoc($query, $parents);
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+ }
+
+ return $this->_groupParentList[$gid];
+ }
+
+ /**
+ * Returns a flat list of the parents of a child group
+ *
+ * @param integer $gid The id of the group.
+ *
+ * @return array A flat list of all of the parents of $group, hashed in
+ * $id => $name format.
+ */
+ protected function _getGroupParentNameList($name)
+ {
+ $parents = array();
+
+ while ($pos) {
+ $name = substr($name, 0, $pos);
+ $parents[] = $name;
+ $pos = strpos($name, ':');
+ }
+
+ return $parents;
+ }
+
+ /**
+ * Returns a list of all groups, in the format id => groupname.
+ *
+ * @param boolean $refresh If true, the cached value is ignored and the
+ * group list is refreshed from the group backend.
+ *
+ * @return array ID => groupname hash.
+ * @throws Horde_Group_Exception
+ */
+ public function listGroups($refresh = false)
+ {
+ if ($refresh || !isset($this->_groupList)) {
+ $sql = 'SELECT group_uid, group_name FROM horde_groups ORDER BY group_uid';
+ try {
+ $this->_groupList = $this->db->selectAssoc($sql);
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+ }
+
+ return $this->_groupList;
+ }
+
+ /**
+ * Get a list of every user that is part of the specified group
+ * and any of its subgroups.
+ *
+ * @param integer $group The ID of the parent group.
+ *
+ * @return array The complete user list.
+ * @throws Horde_Group_Exception
+ */
+ public function listAllUsers($gid)
+ {
+ if (!isset($this->_subGroups[$gid])) {
+ // Get a list of every group that is a sub-group of $group.
+ $name = $this->getGroupName($gid);
+ $query = 'SELECT group_uid FROM horde_groups WHERE group_name LIKE ?';
+
+ try {
+ $this->_subGroups[$gid] = $this->db->selectValues($query, array($name . ':%'));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+ $this->_subGroups[$gid][] = $gid;
+ }
+
+ $users = array();
+ foreach ($this->_subGroups[$gid] as $groupId) {
+ $users = array_merge($users, $this->listUsers($groupId));
+ }
+
+ return array_values(array_flip(array_flip($users)));
+ }
+
+ /**
+ * Get a list of every group that $user is in.
+ *
+ * @param string $user The user to get groups for.
+ * @param boolean $parentGroups Also return the parents of any groups?
+ *
+ * @return array An array of all groups the user is in.
+ * @throws Horde_Group_Exception
+ */
+ public function getGroupMemberships($user, $parentGroups = false)
+ {
+ if (isset($_SESSION['horde']['groups']['m'][$user][$parentGroups])) {
+ return $_SESSION['horde']['groups']['m'][$user][$parentGroups];
+ }
+
+ $sql = 'SELECT g.group_uid AS group_uid, g.group_name AS group_name FROM horde_groups g, horde_groups_members m '
+ . ' WHERE m.user_uid = ? AND g.group_uid = m.group_uid ORDER BY g.group_name';
+ try {
+ $result = $this->db->selectAll($sql, $user);
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+
+ $groups = array();
+ foreach ($result as $row) {
+ $groups[(int)$row['group_uid']] = $this->getGroupShortName($row['group_name']);
+ }
+
+ if ($parentGroups) {
+ foreach ($groups as $id => $g) {
+ $groups += $this->getGroupParentList($id);
+ }
+ }
+
+ $_SESSION['horde']['groups']['m'][$user][$parentGroups] = $groups;
+
+ return $groups;
+ }
+
+ /**
+ * Say if a user is a member of a group or not.
+ *
+ * @param string $user The name of the user.
+ * @param integer $gid The ID of the group.
+ * @param boolean $subgroups Return true if the user is in any subgroups
+ * of group with ID $gid, also.
+ *
+ * @return boolean
+ */
+ public function userIsInGroup($user, $gid, $subgroups = true)
+ {
+ if (isset($_SESSION['horde']['groups']['i'][$user][$subgroups][$gid])) {
+ return $_SESSION['horde']['groups']['i'][$user][$subgroups][$gid];
+ }
+
+ if ($subgroups) {
+ try {
+ $groups = $this->getGroupMemberships($user, true);
+ } catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'ERR');
+ return false;
+ }
+
+ $result = !empty($groups[$gid]);
+ } else {
+ $query = 'SELECT COUNT(*) FROM horde_groups_members WHERE group_uid = ? AND user_uid = ?';
+ try {
+ $result = $this->db->selectValue($query, array($gid, $user));
+ } catch (Horde_Db_Exception $e) {
+ $result = false;
+ }
+
+ }
+
+ $_SESSION['horde']['groups']['i'][$user][$subgroups][$gid] = (bool)$result;
+ return (bool)$result;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Duck <duck@obala.net>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @package Group
+ */
+class Horde_Group_SqlObject extends Horde_Group_DataTreeObject
+{
+ /**
+ * The unique name of this object.
+ * These names have the same requirements as other object names - they must
+ * be unique, etc.
+ *
+ * @var string
+ */
+ public $name;
+
+ /**
+ * The unique name of this object.
+ * These names have the same requirements as other object names - they must
+ * be unique, etc.
+ *
+ * @var integer
+ */
+ public $id;
+
+ /**
+ * Key-value hash that will be serialized.
+ *
+ * @see getData()
+ * @var array
+ */
+ public $data = array();
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the group.
+ */
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Gets the ID of this object.
+ *
+ * @return string The object's ID.
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * Gets the name of this object.
+ *
+ * @return string The object name.
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Gets one of the attributes of the object, or null if it isn't defined.
+ *
+ * @param string $attribute The attribute to get.
+ *
+ * @return mixed The value of the attribute, or null.
+ */
+ public get($attribute)
+ {
+ return isset($this->data[$attribute])
+ ? $this->data[$attribute]
+ : null;
+ }
+
+ /**
+ * Sets one of the attributes of the object.
+ *
+ * @param string $attribute The attribute to set.
+ * @param mixed $value The value for $attribute.
+ */
+ public set($attribute, $value)
+ {
+ $this->data[$attribute] = $value;
+ }
+
+ /**
+ * Save group
+ *
+ * @throws Horde_Group_Exception
+ */
+ public function save()
+ {
+ if (isset($this->data['email'])) {
+ $query = 'UPDATE horde_groups SET group_email = ? WHERE group_uid = ?';
+ try {
+ $this->_groupOb->db->update($query, array($this->data['email'], $this->id));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+ }
+
+ $query = 'DELETE FROM horde_groups_members WHERE group_uid = ?';
+
+ try {
+ $this->_groupOb->db->delete($query, array($this->id));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+
+ if (!empty($this->data['users'])) {
+ $query = 'INSERT INTO horde_groups_members (group_uid, user_uid)' .
+ ' VALUES (?, ?)';
+ foreach ($this->data['users'] as $user) {
+ try {
+ $this->db->insert($query, array(intval($this->id), $user));
+ } catch (Horde_Db_Exception $e) {
+ throw new Horde_Group_Exception($e);
+ }
+ }
+ }
+ }
+
+}
<email>jan@horde.org</email>
<active>yes</active>
</lead>
- <date>2008-09-16</date>
+ <date>2010-06-01</date>
<version>
- <release>0.1.0</release>
- <api>0.1.0</api>
+ <release>0.2.0</release>
+ <api>0.2.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
- <notes>* Added a mock driver for installations that don't need groups (Request #6157).
-* Added a beta SQL Group driver (Request #6175).
-* Removed unused renameGroup() function.
-* Fixed loading subclasses before unserializing session objects (Bug #4650)
-* Added caching.
-* Fixed getGroupParents().
-* Fixed listAllUsers().
-* Switched from hook functions for every group to a single hook function for all groups (Request #4324).
-* Added a Group driver for the Kolab groupware server.
-* Allow group members to be stored as DNs in LDAP driver (Bug #4131).
-* Significant changes to the LDAP Group driver (Bug #4135).
-* Fixed chicken and egg problem for creating the first LDAP group (Bug #4668).
-* Fixed nextgid calculation in the LDAP driver (Bug #4699).
-* UTF-8-encoded DNs in the LDAP Groups driver (Bugs #4692 and #4918).
+ <notes>* Throw exceptions, not PEAR_Errors.
+ * Initial Horde 4 release.
</notes>
<contents>
<dir name="/">
- <dir name="Group">
- <file baseinstalldir="/Horde" name="hooks.php" role="php" />
- <file baseinstalldir="/Horde" name="kolab.php" role="php" />
- <file baseinstalldir="/Horde" name="ldap.php" role="php" />
- <file baseinstalldir="/Horde" name="mock.php" role="php" />
- <file baseinstalldir="/Horde" name="sql.php" role="php" />
- <file baseinstalldir="/Horde" name="contactlists.php" role="php" />
- </dir> <!-- /Group -->
- <file baseinstalldir="/Horde" name="Group.php" role="php" />
+ <dir name="lib">
+ <dir name="Horde">
+ <dir name="Group">
+ <file name="ContactListObject.php" role="php" />
+ <file name="Contactlists.php" role="php" />
+ <file name="DataTreeObject.php" role="php" />
+ <file name="Exception.php" role="php" />
+ <file name="Hooks.php" role="php" />
+ <file name="Kolab.php" role="php" />
+ <file name="KolabObject.php" role="php" />
+ <file name="Ldap.php" role="php" />
+ <file name="LdapObject.php" role="php" />
+ <file name="Mock.php" role="php" />
+ <file name="Sql.php" role="php" />
+ <file name="SqlObject.php" role="php" />
+ </dir> <!-- /lib/Horde/Group -->
+ <file name="Group.php" role="php" />
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
</dir> <!-- / -->
</contents>
<dependencies>
<required>
<php>
- <min>4.3.0</min>
+ <min>5.2.0</min>
</php>
<pearinstaller>
- <min>1.5.4</min>
+ <min>1.7.0</min>
</pearinstaller>
<package>
- <name>Horde_Framework</name>
+ <name>Core</name>
<channel>pear.horde.org</channel>
</package>
<package>
- <name>Horde_DataTree</name>
+ <name>DataTree</name>
<channel>pear.horde.org</channel>
</package>
<package>
- <name>Auth</name>
+ <name>Exception</name>
<channel>pear.horde.org</channel>
</package>
- <extension>
- <name>gettext</name>
- </extension>
</required>
+ <package>
+ <name>Util</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ <optional>
+ <package>
+ <name>Auth</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ <package>
+ <name>Db</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ <package>
+ <name>Ldap</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ </optional>
</dependencies>
- <phprelease />
+ <phprelease>
+ <filelist>
+ <install name="lib/Horde/Group/ContactListObject.php" as="Horde/Group/ContactListObject.php" />
+ <install name="lib/Horde/Group/Contactlists.php" as="Horde/Group/Contactlists.php" />
+ <install name="lib/Horde/Group/DataTreeObject.php" as="Horde/Group/DataTreeObject.php" />
+ <install name="lib/Horde/Group/Exception.php" as="Horde/Group/Exception.php" />
+ <install name="lib/Horde/Group/Hooks.php" as="Horde/Group/Hooks.php" />
+ <install name="lib/Horde/Group/Kolab.php" as="Horde/Group/Kolab.php" />
+ <install name="lib/Horde/Group/KolabObject.php" as="Horde/Group/KolabObject.php" />
+ <install name="lib/Horde/Group/Ldap.php" as="Horde/Group/Ldap.php" />
+ <install name="lib/Horde/Group/LdapObject.php" as="Horde/Group/LdapObject.php" />
+ <install name="lib/Horde/Group/Mock.php" as="Horde/Group/Mock.php" />
+ <install name="lib/Horde/Group/Sql.php" as="Horde/Group/Sql.php" />
+ <install name="lib/Horde/Group/SqlObject.php" as="Horde/Group/SqlObject.php" />
+ <install name="lib/Horde/Group.php" as="Horde/Group.php" />
+ </filelist>
+ </phprelease>
<changelog>
<release>
+ <date>2008-09-16</date>
+ <version>
+ <release>0.1.0</release>
+ <api>0.1.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>* Added a mock driver for installations that don't need groups (Request #6157).
+ * Added a beta SQL Group driver (Request #6175).
+ * Removed unused renameGroup() function.
+ * Fixed loading subclasses before unserializing session objects (Bug #4650)
+ * Added caching.
+ * Fixed getGroupParents().
+ * Fixed listAllUsers().
+ * Switched from hook functions for every group to a single hook function for all groups (Request #4324).
+ * Added a Group driver for the Kolab groupware server.
+ * Allow group members to be stored as DNs in LDAP driver (Bug #4131).
+ * Significant changes to the LDAP Group driver (Bug #4135).
+ * Fixed chicken and egg problem for creating the first LDAP group (Bug #4668).
+ * Fixed nextgid calculation in the LDAP driver (Bug #4699).
+ * UTF-8-encoded DNs in the LDAP Groups driver (Bugs #4692 and #4918).
+ </notes>
+ </release>
+ <release>
<version>
<release>0.0.2</release>
<api>0.0.2</api>
if (isset($permission->data['groups']) &&
is_array($permission->data['groups']) &&
count($permission->data['groups'])) {
- require_once 'Horde/Group.php';
- $groups = Group::singleton();
+ $groups = Horde_Group::singleton();
$composite_perm = null;
$type = $permission->get('type');
// If the user has any group memberships, check for those also.
// @TODO: inject
- require_once 'Horde/Group.php';
- $group = &Group::singleton();
- $groups = $group->getGroupMemberships($userid, true);
- if (!($groups instanceof PEAR_Error) && $groups) {
- // (name == perm_groups and key in ($groups) and val & $perm)
- $criteria['OR'][] = array(
- 'AND' => array(
- array('field' => 'name', 'op' => '=', 'test' => 'perm_groups'),
- array('field' => 'key', 'op' => 'IN', 'test' => array_keys($groups)),
- array('field' => 'value', 'op' => '&', 'test' => $perm)));
- }
+ try {
+ $group = Horde_Group::singleton();
+ $groups = $group->getGroupMemberships($userid, true);
+ if ($groups) {
+ // (name == perm_groups and key in ($groups) and val & $perm)
+ $criteria['OR'][] = array(
+ 'AND' => array(
+ array('field' => 'name', 'op' => '=', 'test' => 'perm_groups'),
+o array('field' => 'key', 'op' => 'IN', 'test' => array_keys($groups)),
+ array('field' => 'value', 'op' => '&', 'test' => $perm)));
+ }
+ } catch (Horde_Group_Exception $e) {}
} else {
$criteria = array(
'AND' => array(
// If the user has any group memberships, check for those also.
// @TODO: Inject the group driver
- require_once 'Horde/Group.php';
- $group = Group::singleton();
- $groups = $group->getGroupMemberships($userid, true);
- if (!is_a($groups, 'PEAR_Error') && $groups) {
- // (name == perm_groups and key in ($groups) and val & $perm)
- $ids = array_keys($groups);
- $group_ids = array();
- foreach ($ids as $id) {
- $group_ids[] = $this->_db->quote((string)$id);
+ try {
+ $group = Horde_Group::singleton();
+ $groups = $group->getGroupMemberships($userid, true);
+ if ($groups) {
+ // (name == perm_groups and key in ($groups) and val & $perm)
+ $ids = array_keys($groups);
+ $group_ids = array();
+ foreach ($ids as $id) {
+ $group_ids[] = $this->_db->quote((string)$id);
+ }
+ $query .= ' LEFT JOIN ' . $this->_table . '_groups g ON g.share_id = s.share_id';
+ $where .= ' OR (g.group_uid IN (' . implode(',', $group_ids) . ')'
+ . ' AND (' . Horde_SQL::buildClause($this->_db, 'g.perm', '&', $perm) . '))';
}
- $query .= ' LEFT JOIN ' . $this->_table . '_groups g ON g.share_id = s.share_id';
- $where .= ' OR (g.group_uid IN (' . implode(',', $group_ids) . ')'
- . ' AND (' . Horde_SQL::buildClause($this->_db, 'g.perm', '&', $perm) . '))';
- } elseif ($groups instanceof PEAR_Error) {
- Horde::logMessage($groups, 'ERR');
+ } catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'ERR');
}
} else {
$where = '(' . Horde_SQL::buildClause($this->_db, 's.perm_guest', '&', $perm) . ')';
* @package Horde_Share
*/
class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql
-{
+{
/**
* The Horde_Share_Object subclass to instantiate objects as
*
// If the user has any group memberships, check for those also.
// @TODO: Inject the group driver
- require_once 'Horde/Group.php';
- $group = &Group::singleton();
- $groups = $group->getGroupMemberships($userid, true);
- if (!($groups instanceof PEAR_Error) && $groups) {
- // (name == perm_groups and key in ($groups) and val & $perm)
- $ids = array_keys($groups);
- $group_ids = array();
- foreach ($ids as $id) {
- $group_ids[] = $this->_db->quote((string)$id);
+ try {
+ $group = Horde_Group::singleton();
+ $groups = $group->getGroupMemberships($userid, true);
+ if ($groups) {
+ // (name == perm_groups and key in ($groups) and val & $perm)
+ $ids = array_keys($groups);
+ $group_ids = array();
+ foreach ($ids as $id) {
+ $group_ids[] = $this->_db->quote((string)$id);
+ }
+ $query .= ' LEFT JOIN ' . $this->_table . '_groups AS g ON g.share_id = s.share_id';
+ $where .= ' OR (g.group_uid IN (' . implode(',', $group_ids) . ')'
+ . ' AND (' . Horde_SQL::buildClause($this->_db, 'g.perm', '&', $perm) . '))';
}
- $query .= ' LEFT JOIN ' . $this->_table . '_groups AS g ON g.share_id = s.share_id';
- $where .= ' OR (g.group_uid IN (' . implode(',', $group_ids) . ')'
- . ' AND (' . Horde_SQL::buildClause($this->_db, 'g.perm', '&', $perm) . '))';
- }
+ } catch (Horde_Group_Exception $e) {}
}
}
require_once dirname(__FILE__) . '/../lib/Application.php';
Horde_Registry::appInit('horde', array('admin' => true));
-require_once 'Horde/Group.php';
-$groups = Group::singleton();
+$groups = Horde_Group::singleton();
$auth = $injector->getInstance('Horde_Auth')->getOb();
$form = null;
switch ($actionID) {
case 'addchild':
- if ($cid == GROUP_ROOT) {
+ if ($cid == Horde_Group::ROOT) {
$form = 'addchild.inc';
$gname = _("All Groups");
} else {
- $group = &$groups->getGroupById($cid);
- if (!is_a($group, 'PEAR_Error')) {
+ try {
+ $group = $groups->getGroupById($cid);
$gname = $group->getShortName();
$form = 'addchild.inc';
- }
+ } catch (Horde_Group_Exception $e) {]
}
break;
case 'addchildform':
$parent = $cid;
- if ($parent == GROUP_ROOT) {
- $child = &$groups->newGroup(Horde_Util::getFormData('child'));
- } else {
- $child = &$groups->newGroup(Horde_Util::getFormData('child'), $parent);
- }
- if (is_a($child, 'PEAR_Error')) {
- Horde::logMessage($child, 'ERR');
- $notification->push(sprintf(_("Group was not created: %s."), $child->getMessage()), 'horde.error');
+ try {
+ $child = ($parent == Horde_Group::ROOT)
+ ? $groups->newGroup(Horde_Util::getFormData('child'))
+ : $groups->newGroup(Horde_Util::getFormData('child'), $parent);
+ } catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'ERR');
+ $notification->push(sprintf(_("Group was not created: %s."), $e->getMessage()), 'horde.error');
break;
}
- $result = $groups->addGroup($child);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, 'ERR');
- $notification->push(sprintf(_("\"%s\" was not created: %s."), $child->getShortName(), $result->getMessage()), 'horde.error');
- } else {
+ try {
+ $groups->addGroup($child);
$notification->push(sprintf(_("\"%s\" was added to the groups system."), $child->getShortName()), 'horde.success');
$group = $child;
$form = 'edit.inc';
$reload = true;
+ } catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'ERR');
+ $notification->push(sprintf(_("\"%s\" was not created: %s."), $child->getShortName(), $e->getMessage()), 'horde.error');
}
break;
case 'delete':
- $group = &$groups->getGroupById($cid);
- if (!is_a($group, 'PEAR_Error')) {
+ try {
+ $group = $groups->getGroupById($cid);
$form = 'delete.inc';
- }
+ } catch (Horde_Group_Exception $e) {}
break;
case 'deleteform':
if (Horde_Util::getFormData('confirm') == _("Delete")) {
- $group = &$groups->getGroupById($cid);
- if (is_a($group, 'PEAR_Error')) {
+ try {
+ $group = $groups->getGroupById($cid);
+ } catch (Horde_Group_Exception $e) {
$notification->push(_("Attempt to delete a non-existent group."), 'horde.error');
- } else {
- $result = $groups->removeGroup($group, true);
- if (is_a($result, 'PEAR_Error')) {
- $notification->push(sprintf(_("Unable to delete \"%s\": %s."), $group->getShortName(), $result->getMessage()), 'horde.error');
- } else {
- $notification->push(sprintf(_("Successfully deleted \"%s\"."), $group->getShortName()), 'horde.success');
- $cid = null;
- $reload = true;
- }
+ break;
+ }
+
+ try {
+ $groups->removeGroup($group, true);
+ $notification->push(sprintf(_("Successfully deleted \"%s\"."), $group->getShortName()), 'horde.success');
+ $cid = null;
+ $reload = true;
+ } catch (Horde_Group_Exception $e) {
+ $notification->push(sprintf(_("Unable to delete \"%s\": %s."), $group->getShortName(), $e->getMessage()), 'horde.error');
}
}
break;
case 'edit':
- $group = &$groups->getGroupById($cid);
- if (!is_a($group, 'PEAR_Error')) {
+ try {
+ $group = $groups->getGroupById($cid);
$form = 'edit.inc';
- } elseif (($category = Horde_Util::getFormData('category')) !== null) {
- $group = &$groups->getGroup($category);
- if (!is_a($group, 'PEAR_Error')) {
+ break;
+ } catch (Horde_Group_Exception $e) {}
+
+ if (($category = Horde_Util::getFormData('category')) !== null) {
+ try {
+ $group = $groups->getGroup($category);
$form = 'edit.inc';
- } elseif (Horde_Util::getFormData('autocreate')) {
+ break;
+ } catch (Horde_Group_Exception $e) {}
+
+ if (Horde_Util::getFormData('autocreate')) {
$parent = Horde_Util::getFormData('parent');
- $group = &$groups->newGroup($category);
- $result = $groups->addGroup($group, $parent);
- if (!is_a($result, 'PEAR_Error')) {
+ $group = $groups->newGroup($category);
+ try {
+ $groups->addGroup($group, $parent);
$form = 'edit.inc';
- }
+ } catch (Horde_Group_Exception $e) {}
}
}
break;
case 'editform':
- $group = &$groups->getGroupById($cid);
+ $group = $groups->getGroupById($cid);
// make a copy of the group so we can restore it if there is an error.
- $restore = $group;
+ $restore = clone $group;
// Add any new users.
$newuser = Horde_Util::getFormData('new_user');
$group->set('email', Horde_Util::getFormData('email'));
// Save the group to the backend.
- $result = $group->save();
-
- if (is_a($result, 'PEAR_Error')) {
- $notification->push($result->getMessage(), 'horde.error');
+ try {
+ $group->save();
+ $notification->push(sprintf(_("Updated \"%s\"."), $group->getShortName()), 'horde.success');
+ } catch (Horde_Group_Exception $e) {
+ $notification->push($e, 'horde.error');
// restore backup copy
$group = $restore;
- } else {
- $notification->push(sprintf(_("Updated \"%s\"."), $group->getShortName()), 'horde.success');
}
$form = 'edit.inc';
case 'edit.inc':
/* Set up the lists. */
- $users = $group->listUsers();
- if (is_a($users, 'PEAR_Error')) {
- $notification->push($users, 'horde.error');
+ try {
+ $users = $group->listUsers();
+ } catch (Horde_Group_Exception $e) {
+ $notification->push($e, 'horde.error');
$users = array();
}
- $all_users = $group->listAllUsers();
- if (is_a($all_users, 'PEAR_Error')) {
- $notification->push($all_users, 'horde.error');
+
+ try {
+ $all_users = $group->listAllUsers();
+ } catch (Horde_Group_Exception $e) {
+ $notification->push($e, 'horde.error');
$all_users = array();
}
$inherited_users = array_diff($all_users, $users);
if ($auth->hasCapability('list')) {
- $user_list = $auth->listUsers();
- if (is_a($user_list, 'PEAR_Error')) {
- $notification->push($user_list, 'horde.error');
+ try {
+ $user_list = $auth->listUsers();
+ } catch (Horde_Auth_Exception $e) {
+ $notification->push($e, 'horde.error');
$user_list = array();
}
sort($user_list);
/* Get the perms tree. */
$nodes = $groups->listGroups(true);
-if (is_a($nodes, 'PEAR_Error')) {
- throw new Horde_Exception_Prior($nodes);
-}
-$nodes[GROUP_ROOT] = GROUP_ROOT;
+$nodes[Horde_Group::ROOT] = Horde_Group::ROOT;
/* Set up some node params. */
$spacer = ' ';
* for the root node. */
if ($cid > 0) {
$cid_parents = $groups->getGroupParentList($cid);
- if (is_a($cid_parents, 'PEAR_Error')) {
- throw new Horde_Exception_Prior($cid_parents);
- }
}
foreach ($nodes as $id => $node) {
$node_params = ($cid == $id) ? array('class' => 'selected') : array();
- if ($id == GROUP_ROOT) {
+ if ($id == Horde_Group::ROOT) {
$add_link = Horde::link(Horde_Util::addParameter($add, 'cid', $id), _("Add a new group")) . $add_img . '</a>';
$base_node_params = $icondir + array('icon' => 'administration.png');
}
/* Remove user from all groups */
- require_once 'Horde/Group.php';
- $groups = Group::singleton();
- $allGroups = $groups->getGroupMemberships($user);
- if (is_a($groups, 'PEAR_Error')) {
- Horde::logMessage($allGroups, 'ERR');
- $haveError = true;
- } else {
+ $groups = Horde_Group::singleton();
+ try {
+ $allGroups = $groups->getGroupMemberships($user);
foreach (array_keys($allGroups) as $id) {
$group = $groups->getGroupById($id);
$group->removeUser($user, true);
}
+ } catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'ERR');
+ $haveError = true;
}
/* Remove the user from all application permissions */
$perms = $GLOBALS['injector']->getInstance('Horde_Perms');
- $tree = $perms->getTree();
- if (is_a($tree, 'PEAR_Error')) {
- Horde::logMessage($tree, 'ERR');
+ try {
+ $tree = $perms->getTree();
+ } catch (Horde_Perms_Exception $e) {
+ Horde::logMessage($e, 'ERR');
$haveError = true;
- } else {
- foreach (array_keys($tree) as $id) {
+ $tree = array();
+ }
+
+ foreach (array_keys($tree) as $id) {
+ try {
$perm = $perms->getPermissionById($id);
- if (is_a($perm, 'PEAR_Error')) {
- Horde::logMessage($perm, 'ERR');
- $haveError = true;
- continue;
- }
if ($perms->getPermissions($perm, $user)) {
// The Horde_Perms::ALL is used if this is a matrix perm,
// otherwise it's ignored in the method and the entry is
// totally removed.
$perm->removeUserPermission($user, Horde_Perms::ALL, true);
}
+ } catch (Horde_Perms_Exception $e) {
+ Horde::logMessage($e, 'ERR');
+ $haveError = true;
}
}
throw new Horde_Exception(_("You are not allowed to add groups."));
}
- require_once 'Horde/Group.php';
- $groups = Group::singleton();
-
if (empty($parent)) {
- $parent = GROUP_ROOT;
- }
-
- if (is_a($group = &$groups->newGroup($name, $parent), 'PEAR_Error')) {
- throw new Horde_Exception($group);
+ $parent = Horde_Group::ROOT;
}
- if (is_a($result = $groups->addGroup($group), 'PEAR_Error')) {
- throw new Horde_Exception($result);
+ try {
+ $groups = Horde_Group::singleton();
+ $group = $groups->newGroup($name, $parent);
+ $groups->addGroup($group);
+ } catch (Horde_Group_Exception $e) {
+ throw new Horde_Exception($e);
}
}
throw new Horde_Exception(_("You are not allowed to delete groups."));
}
- require_once 'Horde/Group.php';
- $groups = Group::singleton();
-
- if (is_a($group = &$groups->getGroup($name), 'PEAR_Error')) {
- throw new Horde_Exception($group);
- }
-
- if (is_a($result = $groups->removeGroup($group, true), 'PEAR_Error')) {
- throw new Horde_Exception($result);
+ try {
+ $groups = Horde_Group::singleton();
+ $group = $groups->getGroup($name);
+ $groups->removeGroup($group, true);
+ } catch (Horde_Group_Exception $e) {
+ throw new Horde_Exception($e);
}
}
throw new Horde_Exception(_("You are not allowed to change groups."));
}
- require_once 'Horde/Group.php';
- $groups = Group::singleton();
-
- if (is_a($group = &$groups->getGroup($name), 'PEAR_Error')) {
- throw new Horde_Exception($group);
- }
-
- if (is_a($result = $group->addUser($user), 'PEAR_Error')) {
- throw new Horde_Exception($result);
+ try {
+ $groups = Horde_Group::singleton();
+ $group = $groups->getGroup($name);
+ $group->addUser($user);
+ } catch (Horde_Group_Exception $e) {
+ throw new Horde_Exception($e);
}
}
throw new Horde_Exception(_("You are not allowed to change groups."));
}
- require_once 'Horde/Group.php';
- $groups = Group::singleton();
-
- if (is_a($group = &$groups->getGroup($name), 'PEAR_Error')) {
- throw new Horde_Exception($group);
- }
-
- foreach ($users as $user) {
- $group->addUser($user, false);
- }
-
- if (is_a($result = $group->save(), 'PEAR_Error')) {
- throw new Horde_Exception($result);
+ try {
+ $groups = Horde_Group::singleton();
+ $group = $groups->getGroup($name);
+ foreach ($users as $user) {
+ $group->addUser($user, false);
+ }
+ $group->save();
+ } catch (Horde_Group_Exception $e) {
+ throw new Horde_Exception($e);
}
}
throw new Horde_Exception(_("You are not allowed to change groups."));
}
- require_once 'Horde/Group.php';
- $groups = Group::singleton();
-
- if (is_a($group = &$groups->getGroup($name), 'PEAR_Error')) {
- throw new Horde_Exception($group);
- }
-
- if (is_a($result = $group->removeUser($user), 'PEAR_Error')) {
- throw new Horde_Exception($result);
+ try {
+ $groups = Horde_Group::singleton();
+ $group = $groups->getGroup($name);
+ $group->removeUser($user);
+ } catch (Horde_Group_Exception $e) {
+ throw new Horde_Exception($e);
}
}
throw new Horde_Exception(_("You are not allowed to change groups."));
}
- require_once 'Horde/Group.php';
- $groups = Group::singleton();
-
- if (is_a($group = &$groups->getGroup($name), 'PEAR_Error')) {
- throw new Horde_Exception($group);
- }
-
- foreach ($users as $user) {
- if (is_a($result = $group->removeUser($user, false), 'PEAR_Error')) {
- throw new Horde_Exception($result);
+ try {
+ $groups = Horde_Group::singleton();
+ $group = $groups->getGroup($name);
+ foreach ($users as $user) {
+ $group->removeUser($user, false);
}
- }
-
- if (is_a($result = $group->save(), 'PEAR_Error')) {
- throw new Horde_Exception($result);
+ $group->save();
+ } catch (Horde_Group_Exception $e) {
+ throw new Horde_Exception($e);
}
}
throw new Horde_Exception(_("You are not allowed to list users of groups."));
}
- require_once 'Horde/Group.php';
- $groups = Group::singleton();
-
- if (is_a($group = &$groups->getGroup($name), 'PEAR_Error')) {
- throw new Horde_Exception($group);
+ try {
+ $groups = Horde_Group::singleton();
+ $group = $groups->getGroup($name);
+ return $group->listUsers();
+ } catch (Horde_Group_Exception $e) {
+ throw new Horde_Exception($e);
}
-
- return $group->listUsers();
}
/* Shares. */
throw new Horde_Exception(_("You are not allowed to change shares."));
}
- require_once 'Horde/Group.php';
$shares = $GLOBALS['injector']->getInstance('Horde_Share')->getScope($scope);
- $groups = Group::singleton();
if (is_a($share = &$shares->getShare($shareName), 'PEAR_Error')) {
throw new Horde_Exception($share);
}
- if (is_a($groupId = $groups->getGroupId($groupName), 'PEAR_Error')) {
- throw new Horde_Exception($groupId);
+
+ try {
+ $groups = Horde_Group::singleton();
+ $groupId = $groups->getGroupId($groupName);
+ } catch (Horde_Group_Exception $e) {
+ throw new Horde_Exception($e);
}
$perm = &$share->getPermission();
throw new Horde_Exception(_("You are not allowed to change shares."));
}
- require_once 'Horde/Group.php';
$shares = $GLOBALS['injector']->getInstance('Horde_Share')->getScope($scope);
- $groups = Group::singleton();
if (is_a($share = &$shares->getShare($shareName), 'PEAR_Error')) {
throw new Horde_Exception($share);
}
- if (is_a($groupId = $groups->getGroupId($groupName), 'PEAR_Error')) {
- throw new Horde_Exception($groupId);
+ try {
+ $groups = Horde_Group::singleton();
+ $groupId = $groups->getGroupId($groupName);
+ } catch (Horde_Group_Exception $e) {
+ throw new Horde_Exception($e);
}
if (is_a($result = $share->removeGroup($groupId), 'PEAR_Error')) {
CREATE TABLE horde_groups (
- group_uid INT(10) UNSIGNED NOT NULL,
+ group_uid INT(11) NOT NULL AUTO_INCREMENT,
group_name VARCHAR(255) NOT NULL,
group_parents VARCHAR(255) NOT NULL,
group_email VARCHAR(255),
);
CREATE TABLE horde_groups_members (
- group_uid INT(10) UNSIGNED NOT NULL,
+ group_uid INT(11) NOT NULL,
user_uid VARCHAR(255) NOT NULL
);
+
CREATE INDEX group_uid_idx ON horde_groups_members (group_uid);
CREATE INDEX user_uid_idx ON horde_groups_members (user_uid);
CREATE INDEX group_uid_idx ON horde_groups_members (group_uid);
CREATE INDEX user_uid_idx ON horde_groups_members (user_uid);
+
+CREATE SEQUENCE horde_groups_uid_seq;
+CREATE TRIGGER horde_groups_uid_trigger
+BEFORE INSERT ON horde_groups
+FOR EACH ROW
+BEGIN
+ SELECT horde_groups_uid_seq.nextval INTO :new.group_uid FROM dual;
+END;
CREATE TABLE horde_groups (
- group_uid INTEGER NOT NULL,
+ group_uid SERIAL UNIQUE,
group_name VARCHAR(255) NOT NULL UNIQUE,
group_parents VARCHAR(255) NOT NULL,
group_email VARCHAR(255),
group_uid INTEGER NOT NULL,
user_uid VARCHAR(255) NOT NULL
);
+
CREATE INDEX group_uid_idx ON horde_groups_members (group_uid);
CREATE INDEX user_uid_idx ON horde_groups_members (user_uid);
CREATE TABLE horde_groups (
- group_uid INTEGER NOT NULL,
+ group_uid INTEGER NOT NULL AUTO_INCREMENT,
group_name VARCHAR(255) NOT NULL,
group_parents VARCHAR(255) NOT NULL,
group_email VARCHAR(255),
--- /dev/null
+ALTER TABLE horde_groups CHANGE COLUMN group_uid group_uid INT(11) NOT NULL AUTO_INCREMENT;
--- /dev/null
+CREATE SEQUENCE horde_group_uid_seq;
+CREATE TRIGGER horde_group_uid_trigger
+BEFORE INSERT ON horde_groups
+FOR EACH ROW
+BEGIN
+SELECT horde_group_uid_seq.nextval INTO :new.group_uid FROM dual;
+END;
--- /dev/null
+CREATE SEQUENCE horde_group_uid_seq;
+ALTER TABLE horde_groups ALTER COLUMN group_uid SET DEFAULT NEXTVAL('horde_group_uid_seq');
require_once dirname(__FILE__) . '/../../lib/Application.php';
Horde_Registry::appInit('horde', array('authentication' => 'none', 'cli' => true));
-require_once 'Horde/Group.php';
-$g = Group::factory();
+$g = Horde_Group::factory();
$group_query = '
INSERT INTO
require_once dirname(__FILE__) . '/../../lib/Application.php';
Horde_Registry::appInit('horde');
-require_once 'Horde/Group.php';
-
// Exit if the user shouldn't be able to change share permissions.
if (!empty($conf['share']['no_sharing'])) {
throw new Horde_Exception('Permission denied.');
$app = Horde_Util::getFormData('app');
$shares = $GLOBALS['injector']->getInstance('Horde_Share')->getScope($app);
-$groups = Group::singleton();
+$groups = Horde_Group::singleton();
$auth = $injector->getInstance('Horde_Auth')->getOb();
if ($registry->hasMethod('shareHelp', $app)) {
$help = $registry->callByPackage($app, 'shareHelp');
$title = sprintf(_("Edit permissions for \"%s\""), $share->get('name'));
}
+$userList = array();
if ($auth->hasCapability('list') &&
($conf['auth']['list_users'] == 'list' ||
$conf['auth']['list_users'] == 'both')) {
- $userList = $auth->listUsers();
- if ($userList instanceof PEAR_Error) {
- Horde::logMessage($userList, 'ERR');
- $userList = array();
+ try {
+ $userList = $auth->listUsers();
+ sort($userList);
+ } catch (Horde_Auth_Exception $e) {
+ Horde::logMessage($e, 'ERR');
}
- sort($userList);
-} else {
- $userList = array();
}
-if (!empty($conf['share']['any_group'])) {
- $groupList = $groups->listGroups();
-} else {
- $groupList = $groups->getGroupMemberships(Horde_Auth::getAuth(), true);
-}
-if ($groupList instanceof PEAR_Error) {
- Horde::logMessage($groupList, 'NOTICE');
+try {
+ $groupList = empty($conf['share']['any_group'])
+ ? $groups->getGroupMemberships(Horde_Auth::getAuth(), true)
+ : $groups->listGroups();
+ asort($groupList);
+} catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'NOTICE');
$groupList = array();
}
-asort($groupList);
require HORDE_TEMPLATES . '/common-header.inc';
$notification->notify(array('listeners' => 'status'));
*/
public function listAlarms($time, $user = null)
{
- require_once 'Horde/Group.php';
-
$current_user = Horde_Auth::getAuth();
if ((empty($user) || $user != $current_user) && !$GLOBALS['registry']->isAdmin()) {
throw new Horde_Exception_PermissionDenied();
}
- $group = Group::singleton();
+ $group = Horde_Group::singleton();
$alarm_list = array();
$time = new Horde_Date($time);
$calendars = is_null($user) ? array_keys($GLOBALS['kronolith_shares']->listAllShares()) : $GLOBALS['display_calendars'];
$users = $share->listUsers(Horde_Perms::READ);
$groups = $share->listGroups(Horde_Perms::READ);
foreach ($groups as $gid) {
- $group_users = $group->listUsers($gid);
- if (!($group_users instanceof PEAR_Error)) {
- $users = array_merge($users, $group_users);
- }
+ try {
+ $users = array_merge($users, $group->listUsers($gid));
+ } catch (Horde_Group_Exception $e) {}
}
$users = array_unique($users);
} else {
$perm_value = Horde_Perms::READ | Horde_Perms::SHOW | Horde_Perms::EDIT | Horde_Perms::DELETE;
break;
}
- $groups = &Group::singleton();
- $group_list = $groups->getGroupMemberships(Horde_Auth::getAuth());
- if (!($group_list instanceof PEAR_Error) && count($group_list)) {
- $perm = $share->getPermission();
- // Add the default perm, not added otherwise
- $perm->addUserPermission(Horde_Auth::getAuth(), Horde_Perms::ALL, false);
- foreach ($group_list as $group_id => $group_name) {
- $perm->addGroupPermission($group_id, $perm_value, false);
+
+ try {
+ $groups = Horde_Group::singleton();
+ $group_list = $groups->getGroupMemberships(Horde_Auth::getAuth());
+ if (count($group_list)) {
+ $perm = $share->getPermission();
+ // Add the default perm, not added otherwise
+ $perm->addUserPermission(Horde_Auth::getAuth(), Horde_Perms::ALL, false);
+ foreach ($group_list as $group_id => $group_name) {
+ $perm->addGroupPermission($group_id, $perm_value, false);
+ }
+ $share->setPermission($perm);
+ $share->save();
+ $GLOBALS['notification']->push(sprintf(_("New calendar created and automatically shared with the following group(s): %s."), implode(', ', $group_list)), 'horde.success');
}
- $share->setPermission($perm);
- $share->save();
- $GLOBALS['notification']->push(sprintf(_("New calendar created and automatically shared with the following group(s): %s."), implode(', ', $group_list)), 'horde.success');
- }
+ } catch (Horde_Group_Exception $e) {}
}
$GLOBALS['prefs']->setValue('display_cals', serialize($GLOBALS['display_calendars']));
// Notify users that have been added.
if ($GLOBALS['conf']['share']['notify'] &&
!isset($current[$group]) && $has_perms) {
- $groupOb = Group::singleton()->getGroupById($group);
+ $groupOb = Horde_Group::singleton()->getGroupById($group);
if (!empty($groupOb->data['email'])) {
try {
$message = Horde::callHook('shareGroupNotification', array($group, $share));
throw new Kronolith_Exception('Unknown event action: ' . $action);
}
- require_once 'Horde/Group.php';
-
- $groups = Group::singleton();
+ $groups = Horde_Group::singleton();
$calendar = $event->calendar;
$recipients = array();
try {
}
foreach ($share->listGroups(Horde_Perms::READ) as $group) {
- $group = $groups->getGroupById($group);
- if ($group instanceof PEAR_Error) {
- continue;
- }
- $group_users = $group->listAllUsers();
- if ($group_users instanceof PEAR_Error) {
+ try {
+ $group = $groups->getGroupById($group);
+ $group_users = $group->listAllUsers();
+ } catch (Horde_Group_Exception $e) {
Horde::logMessage($group_users, 'ERR');
continue;
}
+
foreach ($group_users as $user) {
if (!isset($recipients[$user])) {
$recipients[$user] = self::_notificationPref($user, 'read', $calendar);
require_once dirname(__FILE__) . '/lib/Application.php';
Horde_Registry::appInit('kronolith');
-require_once 'Horde/Group.php';
-
// Exit if the user shouldn't be able to change share permissions.
if (!empty($conf['share']['no_sharing'])) {
throw new Horde_Exception('Permission denied.');
}
$shares = $GLOBALS['injector']->getInstance('Horde_Share')->getScope();
-$groups = Group::singleton();
+$groups = Horde_Group::singleton();
$auth = $injector->getInstance('Horde_Auth')->getOb();
$reload = false;
$userList = array();
}
-if (!empty($conf['share']['any_group'])) {
- $groupList = $groups->listGroups();
-} else {
- $groupList = $groups->getGroupMemberships(Horde_Auth::getAuth(), true);
-}
-if ($groupList instanceof PEAR_Error) {
- Horde::logMessage($groupList, 'NOTICE');
- $groupList = array();
+$groupList = array();
+try {
+ $groupList = empty($conf['share']['any_group'])
+ ? $groups->getGroupMemberships(Horde_Auth::getAuth(), true)
+ : $groups->listGroups();
+ asort($groupList);
+} catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'NOTICE');
}
-asort($groupList);
require KRONOLITH_TEMPLATES . '/common-header.inc';
$notification->notify(array('listeners' => 'status'));
<?php
$auth = $GLOBALS['injector']->getInstance('Horde_Auth')->getOb();
-require_once 'Horde/Group.php';
-$horde_groups = Group::singleton();
-if (!empty($GLOBALS['conf']['share']['any_group'])) {
- $groups = $horde_groups->listGroups();
-} else {
- $groups = $horde_groups->getGroupMemberships(Horde_Auth::getAuth(), true);
-}
-if ($groups instanceof PEAR_Error) {
- $groups = array();
-}
-asort($groups);
+$horde_groups = Horde_Group::singleton();
+
+$groups = array();
+try {
+ $groups = empty($GLOBALS['conf']['share']['any_group'])
+ ? $horde_groups->getGroupMemberships(Horde_Auth::getAuth(), true)
+ : $horde_groups->listGroups();
+ asort($groups);
+} catch (Horde_Group_Exception $e) {}
+
$file_upload = $GLOBALS['browser']->allowFileUploads();
?>
<div id="kronolithCalendarDialog" class="kronolithDialog">
*/
public function listAlarms($time, $user = null)
{
- require_once 'Horde/Group.php';
-
if ((empty($user) || $user != Horde_Auth::getAuth()) &&
!$GLOBALS['registry']->isAdmin()) {
return PEAR::raiseError(_("Permission Denied"));
}
$storage = Nag_Driver::singleton();
- $group = Group::singleton();
+ $group = Horde_Group::singleton();
$alarm_list = array();
$tasklists = is_null($user) ? array_keys($GLOBALS['nag_shares']->listAllShares()) : $GLOBALS['display_tasklists'];
$users = $share->listUsers(Horde_Perms::READ);
$groups = $share->listGroups(Horde_Perms::READ);
if (count($groups)) {
- require_once 'Horde/Group.php';
- $horde_group = Group::singleton();
+ $horde_group = Horde_Group::singleton();
foreach ($groups as $group) {
$users = array_merge($users,
$horde_group->listAllUsers($group));
throw new Nag_Exception($e);
}
- require_once 'Horde/Group.php';
-
- $groups = Group::singleton();
+ $groups = Horde_Group::singleton();
$recipients = array();
$identity = $GLOBALS['injector']->getInstance('Horde_Prefs_Identity')->getIdentity();
$from = $identity->getDefaultFromAddress(true);
}
}
foreach ($share->listGroups(Horde_Perms::READ) as $group) {
- $group = $groups->getGroupById($group);
- if (is_a($group, 'PEAR_Error')) {
- continue;
- }
- $group_users = $group->listAllUsers();
- if (is_a($group_users, 'PEAR_Error')) {
- Horde::logMessage($group_users, 'ERR');
+ try {
+ $group = $groups->getGroupById($group);
+ $group_users = $group->listAllUsers();
+ } catch (Horde_Group_Exception $e) {
+ Horde::logMessage($e, 'ERR');
continue;
}
+
foreach ($group_users as $user) {
if (empty($recipients[$user])) {
$recipients[$user] = Nag::_notificationPref($user, 'read', $task->tasklist);
// 'browse' => true,
//);
-//require_once 'Horde/Group.php';
//$_group_driver = &Group::singleton();
//$_group_list = $_group_driver->getGroupMemberships(Horde_Auth::getAuth());
//foreach ($_group_list as $_group_id => $_group_name) {
function _getAddressBook()
{
- require_once 'Horde/Group.php';
-
- $groups = Group::singleton();
+ $groups = Horde_Group::singleton();
$members = $groups->listAllUsers($this->_gid);
$addressbook = array();
foreach ($members as $member) {
protected function _init()
{
// TODO: Remove once they can be autoloaded
- require_once 'Horde/Group.php';
require_once 'Horde/Form.php';
require_once 'Horde/Form/Renderer.php';
/* Group restrictions. */
if ($GLOBALS['registry']->isAdmin(array('permission' => 'whups:admin')) ||
$GLOBALS['injector']->getInstance('Horde_Perms')->hasPermission('whups:hiddenComments', Horde_Auth::getAuth(), Horde_Perms::EDIT)) {
- $groups = &Group::singleton();
+ $groups = Horde_Group::singleton();
$mygroups = $groups->getGroupMemberships(Horde_Auth::getAuth());
if ($mygroups) {
foreach (array_keys($mygroups) as $gid) {
$this->addHidden('', 'deferred_attachment', 'text', false);
/* Groups. */
- $groups = &Group::singleton();
+ $groups = Horde_Group::singleton();
if ($conf['prefs']['assign_all_groups']) {
$mygroups = $groups->listGroups();
} else {
case 'owner':
if (Whups::hasPermission($vars->get('queue'), 'queue',
'assign')) {
- $groups = &Group::singleton();
+ $groups = Horde_Group::singleton();
if ($GLOBALS['conf']['prefs']['assign_all_groups']) {
$mygroups = $groups->listGroups();
} else {
}
/* Comment permissions. */
- $groups = &Group::singleton();
+ $groups = Horde_Group::singleton();
$mygroups = $groups->getGroupMemberships(Horde_Auth::getAuth());
if ($mygroups) {
foreach (array_keys($mygroups) as $gid) {
$this->addHidden('', 'edit', 'boolean', false);
- $groups = &Group::singleton();
- $grouplist = $groups->listGroups();
- if (is_a($grouplist, 'PEAR_Error') || !count($grouplist)) {
+ try {
+ $groups = Horde_Group::singleton();
+ $grouplist = $groups->listGroups();
+ } catch (Horde_Group_Exception $e) {
+ $grouplist = array();
+ }
+
+ if (count($grouplist)) {
$type_params = array(_("Could not find any groups."));
$this->addVariable(_("Groups"), 'groups', 'invalid', false, false, null, $type_params);
} else {
function getOwnerCriteria($user)
{
$criteria = array('user:' . $user);
- $groups = &Group::singleton();
+ $groups = Horde_Group::singleton();
$mygroups = $groups->getGroupMemberships(Horde_Auth::getAuth());
foreach ($mygroups as $id => $group) {
$criteria[] = 'group:' . $id;
$results[$user]['email'] = $identity->getValue('from_addr');
}
} elseif ($type == 'group') {
- $groups = &Group::singleton();
- $group = $groups->getGroupById($user);
- if (is_a($group, 'PEAR_Error')) {
- $results['user']['name'] = '';
- $results['user']['email'] = '';
- } else {
+ try {
+ $groups = Horde_Group::singleton();
+ $group = $groups->getGroupById($user);
+
$results[$user]['user'] = $group->getShortName();
$results[$user]['name'] = $group->getShortName();
$results[$user]['email'] = $group->get('email');
+ } catch (Horde_Group_Exception $e) {
+ $results['user']['name'] = '';
+ $results['user']['email'] = '';
}
}
}
if ($GLOBALS['registry']->isAdmin(array('permission' => 'whups:admin', 'permlevel' => Horde_Perms::EDIT)) ||
$GLOBALS['injector']->getInstance('Horde_Perms')->hasPermission('whups:hiddenComments',
Horde_Auth::getAuth(), Horde_Perms::EDIT)) {
- $groups = &Group::singleton();
+ $groups = Horde_Group::singleton();
$mygroups = $groups->getGroupMemberships(Horde_Auth::getAuth());
if ($mygroups) {
foreach (array_keys($mygroups) as $gid) {
$this->addVariable(_("Comment"), 'newcomment', 'longtext', false);
/* Group restrictions. */
- $groups = &Group::singleton();
+ $groups = Horde_Group::singleton();
$mygroups = $groups->getGroupMemberships(Horde_Auth::getAuth());
if ($mygroups) {
foreach (array_keys($mygroups) as $gid) {