[ Index ]
 

Code source de Horde 3.1.3

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/Horde/ -> Group.php (source)

   1  <?php
   2  
   3  require_once 'Horde/DataTree.php';
   4  require_once 'Horde/History.php';
   5  
   6  /**
   7   * The Group:: class provides the Horde groups system.
   8   *
   9   * $Horde: framework/Group/Group.php,v 1.67.2.15 2006/07/17 14:40:19 jan Exp $
  10   *
  11   * Copyright 1999-2006 Stephane Huther <shuther@bigfoot.com>
  12   * Copyright 2001-2006 Chuck Hagenbuch <chuck@horde.org>
  13   *
  14   * See the enclosed file COPYING for license information (LGPL). If you
  15   * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  16   *
  17   * @author  Stephane Huther <shuther@bigfoot.com>
  18   * @author  Chuck Hagenbuch <chuck@horde.org>
  19   * @since   Horde 2.1
  20   * @package Horde_Group
  21   */
  22  class Group {
  23  
  24      /**
  25       * Pointer to a DataTree instance to manage the different groups.
  26       *
  27       * @var DataTree
  28       */
  29      var $_datatree;
  30  
  31      /**
  32       * Constructor
  33       */
  34      function Group()
  35      {
  36          global $conf;
  37  
  38          if (empty($conf['datatree']['driver'])) {
  39              Horde::fatal('You must configure a DataTree backend to use Groups.', __FILE__, __LINE__);
  40          }
  41  
  42          $driver = $conf['datatree']['driver'];
  43          $this->_datatree = &DataTree::singleton($driver,
  44                                                  array_merge(Horde::getDriverConfig('datatree', $driver),
  45                                                              array('group' => 'horde.groups')));
  46      }
  47  
  48      /**
  49       * Return a new group object.
  50       *
  51       * @param string $name    The group's name.
  52       * @param string $parent  The group's parent's name.
  53       *
  54       * @return DataTreeObject_Group  A new group object.
  55       */
  56      function &newGroup($name, $parent = DATATREE_ROOT)
  57      {
  58          if (empty($name)) {
  59              return PEAR::raiseError(_("Group names must be non-empty"));
  60          }
  61  
  62          if ($parent != DATATREE_ROOT) {
  63              $name = $this->getGroupName($parent) . ':' . DataTree::encodeName($name);
  64          }
  65  
  66          $group = &new DataTreeObject_Group($name);
  67          $group->setGroupOb($this);
  68          return $group;
  69      }
  70  
  71      /**
  72       * Return a DataTreeObject_Group object corresponding to the named
  73       * group, with the users and other data retrieved appropriately.
  74       *
  75       * @param string $name The name of the group to retrieve.
  76       */
  77      function &getGroup($name)
  78      {
  79          /* cache of previous retrieved groups */
  80          static $groupCache;
  81  
  82          if (!is_array($groupCache)) {
  83              $groupCache = array();
  84          }
  85  
  86          if (!isset($groupCache[$name])) {
  87              $groupCache[$name] = $this->_datatree->getObject($name, 'DataTreeObject_Group');
  88              if (!is_a($groupCache[$name], 'PEAR_Error')) {
  89                  $groupCache[$name]->setGroupOb($this);
  90              }
  91          }
  92  
  93          return $groupCache[$name];
  94      }
  95  
  96      /**
  97       * Return a DataTreeObject_Group object corresponding to the given
  98       * unique ID, with the users and other data retrieved
  99       * appropriately.
 100       *
 101       * @param integer $cid  The unique ID of the group to retrieve.
 102       */
 103      function &getGroupById($cid)
 104      {
 105          $group = $this->_datatree->getObjectById($cid, 'DataTreeObject_Group');
 106          if (!is_a($group, 'PEAR_Error')) {
 107              $group->setGroupOb($this);
 108          }
 109          return $group;
 110      }
 111  
 112      /**
 113       * Get a globally unique ID for a group.
 114       *
 115       * @param DataTreeObject_Group $group  The group.
 116       *
 117       * @return string  A GUID referring to $group.
 118       */
 119      function getGUID($group)
 120      {
 121          return 'horde:group:' . $this->getGroupId($group);
 122      }
 123  
 124      /**
 125       * Add a group to the groups system. The group must first be
 126       * created with Group::newGroup(), and have any initial users
 127       * added to it, before this function is called.
 128       *
 129       * @param DataTreeObject_Group $group  The new group object.
 130       */
 131      function addGroup($group)
 132      {
 133          if (!is_a($group, 'DataTreeObject_Group')) {
 134              return PEAR::raiseError('Groups must be DataTreeObject_Group objects or extend that class.');
 135          }
 136          $result = $this->_datatree->add($group);
 137          if (is_a($result, 'PEAR_Error')) {
 138              return $result;
 139          }
 140  
 141          /* Log the addition of the group in the history log. */
 142          $history = &Horde_History::singleton();
 143          $log = $history->log($this->getGUID($group), array('action' => 'add'), true);
 144          if (is_a($log, 'PEAR_Error')) {
 145              return $log;
 146          }
 147  
 148          return $result;
 149      }
 150  
 151      /**
 152       * Store updated data - users, etc. - of a group to the backend system.
 153       *
 154       * @param DataTreeObject_Group $group  The group to update.
 155       */
 156      function updateGroup($group)
 157      {
 158          if (!is_a($group, 'DataTreeObject_Group')) {
 159              return PEAR::raiseError('Groups must be DataTreeObject_Group objects or extend that class.');
 160          }
 161          $result = $this->_datatree->updateData($group);
 162          if (is_a($result, 'PEAR_Error')) {
 163              return $result;
 164          }
 165  
 166          /* Log the update of the group users on the history log. */
 167          $history = &Horde_History::singleton();
 168          $guid = $this->getGUID($group);
 169          foreach ($group->getAuditLog() as $userId => $action) {
 170              $history->log($guid, array('action' => $action, 'user' => $userId), true);
 171          }
 172          $group->clearAuditLog();
 173  
 174          /* Log the group modification. */
 175          $history->log($guid, array('action' => 'modify'), true);
 176          return $result;
 177      }
 178  
 179      /**
 180       * Change the name of a group without changing its contents or
 181       * where it is in the groups hierarchy.
 182       *
 183       * @param DataTreeObject_Group $group  The group to rename.
 184       * @param string $newName              The group's new name.
 185       */
 186      function renameGroup($group, $newName)
 187      {
 188          if (!is_a($group, 'DataTreeObject_Group')) {
 189              return PEAR::raiseError('Groups must be DataTreeObject_Group objects or extend that class.');
 190          }
 191          $result = $this->_datatree->rename($group, $newName);
 192          if (is_a($result, 'PEAR_Error')) {
 193              return $result;
 194          }
 195  
 196          /* History Log the name change of the group. */
 197          $history = &Horde_History::singleton();
 198          $history->log($this->getGUID($group), array('action' => 'rename'), true);
 199          return $result;
 200      }
 201  
 202      /**
 203       * Remove a group from the groups system permanently.
 204       *
 205       * @param DataTreeObject_Group $group  The group to remove.
 206       * @param boolean $force               Force to remove every child.
 207       */
 208      function removeGroup($group, $force = false)
 209      {
 210          if (!is_a($group, 'DataTreeObject_Group')) {
 211              return PEAR::raiseError('Groups must be DataTreeObject_Group objects or extend that class.');
 212          }
 213  
 214          $history = &Horde_History::singleton();
 215          $history->log($this->getGUID($group), array('action' => 'delete'), true);
 216  
 217          return $this->_datatree->remove($group, $force);
 218      }
 219  
 220      /**
 221       * Retrieve the name of a group.
 222       *
 223       * @param integer $gid  The id of the group to retrieve the name for.
 224       *
 225       * @return string  The group's name.
 226       */
 227      function getGroupName($gid)
 228      {
 229          if (is_a($gid, 'DataTreeObject_Group')) {
 230              return $this->_datatree->getName($gid->getId());
 231          } else {
 232              return $this->_datatree->getName($gid);
 233          }
 234      }
 235  
 236      /**
 237       * Strips all parent references off of the given group name.
 238       *
 239       * @param string $group  Name of the group.
 240       *
 241       * @return The name of the group without parents.
 242       */
 243      function getGroupShortName($group)
 244      {
 245          return $this->_datatree->getShortName($group);
 246      }
 247  
 248      /**
 249       * Retrieve the ID of a group.
 250       *
 251       * @param string $group  The group to retrieve the ID for.
 252       *
 253       * @return integer  The group's ID.
 254       */
 255      function getGroupId($group)
 256      {
 257          if (is_a($group, 'DataTreeObject_Group')) {
 258              return $this->_datatree->getId($group->getName());
 259          } else {
 260              return $this->_datatree->getId($group);
 261          }
 262      }
 263  
 264      /**
 265       * Check if a group exists in the system.
 266       *
 267       * @param string $group  The group to check.
 268       *
 269       * @return boolean  True if the group exists, false otherwise.
 270       */
 271      function exists($group)
 272      {
 273          return $this->_datatree->exists($group);
 274      }
 275  
 276      /**
 277       * Get a list of the parents of a child group.
 278       *
 279       * @param integer $gid The id of the child group.
 280       *
 281       * @return array
 282       */
 283      function getGroupParents($gid)
 284      {
 285          $name = $this->getGroupName($gid);
 286          return $this->_datatree->getParents($name);
 287      }
 288  
 289      /**
 290       * Return the single parent of the given group.
 291       *
 292       * @param integer $gid  The DataTree ID of the child group.
 293       *
 294       * @return the parent of the given group.
 295       */
 296      function getGroupParent($gid)
 297      {
 298          return $this->_datatree->getParentById($gid);
 299      }
 300  
 301      /**
 302       * Get a list of parents all the way up to the root object for $group.
 303       *
 304       * @param integer $gid  The id of the group.
 305       *
 306       * @return array  A flat list of all of the parents of $group,
 307       *                hashed in $id => $name format.
 308       */
 309      function getGroupParentList($gid)
 310      {
 311          return $this->_datatree->getParentList($gid);
 312      }
 313  
 314      /**
 315       * Get a list of every group, in the format cid => groupname.
 316       *
 317       * @param boolean $refresh  If true, the cached value is ignored and the group
 318       *                          list is refreshed from the group backend.
 319       *
 320       * @return array  CID => groupname hash.
 321       */
 322      function listGroups($refresh = false)
 323      {
 324          static $groups;
 325  
 326          if ($refresh || is_null($groups)) {
 327              $groups = $this->_datatree->get(DATATREE_FORMAT_FLAT, DATATREE_ROOT, true);
 328              unset($groups[DATATREE_ROOT]);
 329          }
 330  
 331          return $groups;
 332      }
 333  
 334      /**
 335       * Get a list of every user that is a part of this group ONLY.
 336       *
 337       * @param integer $gid  The ID of the group.
 338       *
 339       * @return array  The user list.
 340       */
 341      function listUsers($gid)
 342      {
 343          $groupOb = &$this->getGroupById($gid);
 344          if (is_a($groupOb, 'PEAR_Error')) {
 345              return $groupOb;
 346          }
 347  
 348          if (!isset($groupOb->data['users']) ||
 349              !is_array($groupOb->data['users'])) {
 350              return array();
 351          }
 352  
 353          return array_keys($groupOb->data['users']);
 354      }
 355  
 356      /**
 357       * Get a list of every user that is part of the specified group
 358       * and any of its subgroups.
 359       *
 360       * @param integer $group  The ID of the parent group.
 361       *
 362       * @return array  The complete user list.
 363       */
 364      function listAllUsers($gid)
 365      {
 366          // Get a list of every group that is a sub-group of $group.
 367          $groups = $this->_datatree->get(DATATREE_FORMAT_FLAT, $this->getGroupName($gid), true);
 368          if (is_a($groups, 'PEAR_Error')) {
 369              return $groups;
 370          }
 371  
 372          $groups = array_keys($groups);
 373          $users = array();
 374          foreach ($groups as $groupId) {
 375              $users = array_merge($users, $this->listUsers($groupId));
 376          }
 377          return array_values(array_flip(array_flip($users)));
 378      }
 379  
 380      /**
 381       * Get a list of every group that $user is in.
 382       *
 383       * @param string  $user          The user to get groups for.
 384       * @param boolean $parentGroups  Also return the parents of any groups?
 385       *
 386       * @return array  An array of all groups the user is in.
 387       */
 388      function getGroupMemberships($user, $parentGroups = false)
 389      {
 390          static $cache;
 391  
 392          if (empty($cache[$user])) {
 393              $criteria = array(
 394                  'AND' => array(
 395                      array('field' => 'name', 'op' => '=', 'test' => 'user'),
 396                      array('field' => 'key', 'op' => '=', 'test' => $user)));
 397              $groups = $this->_datatree->getByAttributes($criteria);
 398  
 399              if (is_a($groups, 'PEAR_Error')) {
 400                  Horde::logMessage($groups, __FILE__, __LINE__, PEAR_LOG_ERROR);
 401                  return false;
 402              }
 403  
 404              if ($parentGroups) {
 405                  foreach ($groups as $id => $g) {
 406                      $parents = $this->_datatree->getParentList($id);
 407                      if (is_a($parents, 'PEAR_Error')) {
 408                          return $parents;
 409                      }
 410                      $groups += $parents;
 411                  }
 412              }
 413  
 414              $cache[$user] = $groups;
 415          }
 416  
 417          return $cache[$user];
 418      }
 419  
 420      /**
 421       * Say if a user is a member of a group or not.
 422       *
 423       * @param string $user        The name of the user.
 424       * @param integer $gid        The ID of the group.
 425       * @param boolean $subgroups  Return true if the user is in any subgroups
 426       *                            of group with ID $gid, also.
 427       *
 428       * @return boolean
 429       */
 430      function userIsInGroup($user, $gid, $subgroups = true)
 431      {
 432          if (!$this->exists($this->getGroupName($gid))) {
 433              return false;
 434          } elseif ($subgroups) {
 435              $groups = $this->getGroupMemberships($user, true);
 436              if (is_a($groups, 'PEAR_Error')) {
 437                  Horde::logMessage($groups, __FILE__, __LINE__, PEAR_LOG_ERR);
 438                  return false;
 439              }
 440  
 441              return !empty($groups[$gid]);
 442          } else {
 443              $users = $this->listUsers($gid);
 444              if (is_a($users, 'PEAR_Error')) {
 445                  Horde::logMessage($users, __FILE__, __LINE__, PEAR_LOG_ERR);
 446                  return false;
 447              }
 448              return in_array($user, $users);
 449          }
 450      }
 451  
 452      /**
 453       * Returns the DataTree level of the given group. 0 is returned for
 454       * and object directly below DATATREE_ROOT.
 455       *
 456       * @param integer $gid  The DataTree ID of the group.
 457       *
 458       * @return The DataTree level of the group.
 459       */
 460      function getLevel($gid)
 461      {
 462          $name = $this->_datatree->getName($gid);
 463          return substr_count($name, ':');
 464      }
 465  
 466      /**
 467       * Attempts to return a concrete Group instance based on $driver.
 468       *
 469       * @param mixed $driver  The type of concrete Group subclass to return.
 470       * @param array $params  A hash containing any additional configuration or
 471       *                       connection parameters a subclass might need.
 472       *
 473       * @return Group  The newly created concrete Group instance, or a
 474       *                PEAR_Error object on an error.
 475       */
 476      function &factory($driver = '', $params = null)
 477      {
 478          $driver = basename($driver);
 479  
 480          if (@file_exists(dirname(__FILE__) . '/Group/' . $driver . '.php')) {
 481              require_once dirname(__FILE__) . '/Group/' . $driver . '.php';
 482          } else {
 483              @include_once 'Horde/Group/' . $driver . '.php';
 484          }
 485          $class = 'Group_' . $driver;
 486          if (class_exists($class)) {
 487              $group = &new $class($params);
 488          } else {
 489              $group = PEAR::raiseError('Class definition of ' . $class . ' not found.');
 490          }
 491  
 492          return $group;
 493      }
 494  
 495      /**
 496       * Attempts to return a reference to a concrete Group instance.
 497       * It will only create a new instance if no Group instance
 498       * currently exists.
 499       *
 500       * This method must be invoked as: $var = &Group::singleton()
 501       *
 502       * @return Group  The concrete Group reference, or false on an error.
 503       */
 504      function &singleton()
 505      {
 506          static $group;
 507  
 508          if (!isset($group)) {
 509              global $conf;
 510  
 511              require_once  'Horde/Auth.php';
 512              $auth = &Auth::singleton($conf['auth']['driver']);
 513              if ($auth->hasCapability('groups')) {
 514                  $group = &Group::factory($auth->getDriver(), $auth);
 515              } elseif (!empty($conf['group']['driver']) && $conf['group']['driver'] != 'datatree') {
 516                  $group = &Group::factory($conf['group']['driver']);
 517              } else {
 518                  $group = new Group();
 519              }
 520          }
 521  
 522          return $group;
 523      }
 524  
 525  }
 526  
 527  /**
 528   * Extension of the DataTreeObject class for storing Group information
 529   * in the Categories driver. If you want to store specialized Group
 530   * information, you should extend this class instead of extending
 531   * DataTreeObject directly.
 532   *
 533   * @author  Chuck Hagenbuch <chuck@horde.org>
 534   * @since   Horde 2.1
 535   * @package Horde_Group
 536   */
 537  class DataTreeObject_Group extends DataTreeObject {
 538  
 539      /**
 540       * The Group object which this group is associated with - needed
 541       * for updating data in the backend to make changes stick, etc.
 542       *
 543       * @var Group
 544       */
 545      var $_groupOb;
 546  
 547      /**
 548       * This variable caches the users added or removed from the group
 549       * for History logging of user-groups relationship.
 550       *
 551       * @var array
 552       */
 553      var $_auditLog = array();
 554  
 555      /**
 556       * The DataTreeObject_Group constructor. Just makes sure to call
 557       * the parent constructor so that the group's name is set
 558       * properly.
 559       *
 560       * @param string $name  The name of the group.
 561       */
 562      function DataTreeObject_Group($name)
 563      {
 564          parent::DataTreeObject($name);
 565      }
 566  
 567      /**
 568       * Associates a Group object with this group.
 569       *
 570       * @param Group $groupOb  The Group object.
 571       */
 572      function setGroupOb(&$groupOb)
 573      {
 574          $this->_groupOb = &$groupOb;
 575      }
 576  
 577      /**
 578       * Fetch the ID of this group
 579       *
 580       * @return string The group's ID
 581       */
 582      function getId()
 583      {
 584          return $this->_groupOb->getGroupId($this);
 585      }
 586  
 587      /**
 588       * Save any changes to this object to the backend permanently.
 589       */
 590      function save()
 591      {
 592          return $this->_groupOb->updateGroup($this);
 593  
 594      }
 595  
 596      /**
 597       * Adds a user to this group, and makes sure that the backend is
 598       * updated as well.
 599       *
 600       * @param string $username The user to add.
 601       */
 602      function addUser($username, $update = true)
 603      {
 604          $this->data['users'][$username] = 1;
 605          $this->_auditLog[$username] = 'addUser';
 606          if ($update && $this->_groupOb->exists($this->getName())) {
 607              return $this->save();
 608          }
 609      }
 610  
 611      /**
 612       * Removes a user from this group, and makes sure that the backend
 613       * is updated as well.
 614       *
 615       * @param string $username The user to remove.
 616       */
 617      function removeUser($username, $update = true)
 618      {
 619          unset($this->data['users'][$username]);
 620          $this->_auditLog[$username] = 'deleteUser';
 621          if ($update) {
 622              return $this->save();
 623          }
 624      }
 625  
 626      /**
 627       * Get a list of every user that is a part of this group
 628       * (and only this group)
 629       *
 630       * @return array  The user list
 631       */
 632      function listUsers()
 633      {
 634          return $this->_groupOb->listUsers($this->getId());
 635      }
 636  
 637      /**
 638       * Get a list of every user that is a part of this group and
 639       * any of it's subgroups
 640       *
 641       * @return array  The complete user list
 642       */
 643      function listAllUsers()
 644      {
 645          return $this->_groupOb->listAllUsers($this->getId());
 646      }
 647  
 648      /**
 649       * Get all the users recently added or removed from the group.
 650       */
 651      function getAuditLog()
 652      {
 653          return $this->_auditLog;
 654      }
 655  
 656      /**
 657       * Clears the audit log. To be called after group update.
 658       */
 659      function clearAuditLog()
 660      {
 661          $this->_auditLog = array();
 662      }
 663  
 664      /**
 665       * Map this object's attributes from the data array into a format
 666       * that we can store in the attributes storage backend.
 667       *
 668       * @return array  The attributes array.
 669       */
 670      function _toAttributes()
 671      {
 672          // Default to no attributes.
 673          $attributes = array();
 674  
 675          // Loop through all users, if any.
 676          if (isset($this->data['users']) && is_array($this->data['users']) && count($this->data['users'])) {
 677              foreach ($this->data['users'] as $user => $active) {
 678                  $attributes[] = array('name' => 'user',
 679                                        'key' => $user,
 680                                        'value' => $active);
 681              }
 682          }
 683          $attributes[] = array('name' => 'email',
 684                                'key' => '',
 685                                'value' => $this->get('email'));
 686  
 687          return $attributes;
 688      }
 689  
 690      /**
 691       * Take in a list of attributes from the backend and map it to our
 692       * internal data array.
 693       *
 694       * @param array $attributes  The list of attributes from the
 695       *                           backend (attribute name, key, and value).
 696       */
 697      function _fromAttributes($attributes)
 698      {
 699          // Initialize data array.
 700          $this->data['users'] = array();
 701  
 702          foreach ($attributes as $attr) {
 703              if ($attr['name'] == 'user') {
 704                  $this->data['users'][$attr['key']] = $attr['value'];
 705              } else {
 706                  $this->data[$attr['name']] = $attr['value'];
 707              }
 708          }
 709      }
 710  
 711  }


Généré le : Sun Feb 25 18:01:28 2007 par Balluche grâce à PHPXref 0.7