[ Index ] |
|
Code source de Horde 3.1.3 |
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 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |