Perforce Chronicle 2012.2/486814
API Documentation

P4Cms_Acl_Role Class Reference

This is the 'role' model. More...

Inheritance diagram for P4Cms_Acl_Role:
P4Cms_Record_Connected P4Cms_Model P4Cms_ModelInterface

List of all members.

Public Member Functions

 addOwner ($user)
 Add given user to the owners list of the associated group in Perforce.
 addUser (P4Cms_User $user)
 Assign this role to the given user.
 delete ()
 Delete this role entry.
 getRealUsers ()
 Get members of this role that actually exist.
 getRoleId ()
 Defined by Zend_Acl_Role_Interface; returns the Role identifier.
 getType ()
 Get the type of this role (system or custom).
 getUsers ()
 Get the members of this role.
 hasUser (P4Cms_User $user)
 Determine if given user has this role.
 isSystem ()
 Determine if this role is a system role.
 isVirtual ()
 Determine if this role is a virtual role.
 removeUser (P4Cms_User $user)
 Remove this role from a given user.
 save ()
 Save this role entry.
 setId ($id)
 Set the role id - extended to proxy to p4 group.
 setType ()
 Make type a read-only field.
 setUsers ($users=array())
 Assign this role to all of the given users.

Static Public Member Functions

static addSuperRole ($role)
 Register given role as a super role.
static count ($options=array(), P4Cms_Record_Adapter $adapter=null)
 Count all roles - extended to route through fetch all.
static exists ($roleId, $options=null, P4Cms_Record_Adapter $adapter=null)
 Check if the named role exists.
static fetch ($roleId, array $options=null, P4Cms_Record_Adapter $adapter=null)
 Fetch the named role.
static fetchAll ($options=array(), P4Cms_Record_Adapter $adapter=null)
 Fetch all roles.
static isSuper ($role)
 Determine if this role is a super-user role.
static setUserRoles (P4Cms_User $user, array $roles=null, P4Cms_Record_Adapter $adapter=null)
 Set given roles to the given user, i.e.

Public Attributes

const FETCH_BY_MEMBER = 'member'
const FETCH_HIDE_VIRTUAL = 'hideVirtual'
const PARENT_GROUP = 'parentGroup'
const PREFIX_DELIMITER = '--'
const ROLE_ADMINISTRATOR = 'administrator'
const ROLE_ANONYMOUS = 'anonymous'
const ROLE_MEMBER = 'member'
const TYPE_CUSTOM = 'custom'
const TYPE_SYSTEM = 'system'

Protected Member Functions

 _getP4Group ()
 Get the p4 group object that corresponds to this role.
 _setP4Group (P4_Group $group)
 Set the corresponding p4 group object instance.

Static Protected Member Functions

static _getGroupPrefix (P4Cms_Record_Adapter $adapter)
 Get the group prefix property of the record adapter.

Protected Attributes

 $_p4Group = null

Static Protected Attributes

static $_fields
static $_idField = 'id'
static $_superRoles
static $_systemRoles
static $_virtualRoles

Detailed Description

This is the 'role' model.

Each role corresponds to a group in Perforce, except for the virtual roles which always exist.

Virtual roles cannot be permanently assigned to any user and serve for special cases, such as to recognize unknown (anonymous) user.

Some roles are recognized as system roles - their existence is guaranteed as their corresponding groups in Perforce are created during site setup.

Both system and virtual roles are protected from being deleted or altered.

The role class also introduces the concept of a 'parent group'. A parent group acts like a folder under which all roles are stored. When a parent group is set on the storage adapter, only roles with the parent group name as a prefix are accessible.

The prefix is read from the storage adapter and is not exposed outside of the class. It is managed internally and automatically prepended or stripped from role ids as appropriate. Any new roles that are created will be added as sub-groups of the parent group.

Copyright:
2011-2012 Perforce Software. All rights reserved
License:
Please see LICENSE.txt in top-level folder of this distribution.
Version:
2012.2/486814

Member Function Documentation

static P4Cms_Acl_Role::_getGroupPrefix ( P4Cms_Record_Adapter adapter) [static, protected]

Get the group prefix property of the record adapter.

Parameters:
P4Cms_Record_Adapter$adapterthe adapter to get the property from
Returns:
string the group prefix or null if no prefix set.
    {
        return $adapter->hasProperty(static::PARENT_GROUP)
            ? $adapter->getProperty(static::PARENT_GROUP) . static::PREFIX_DELIMITER
            : '';
    }
P4Cms_Acl_Role::_getP4Group ( ) [protected]

Get the p4 group object that corresponds to this role.

Returns:
P4_Group corresponding p4 group instance.
Exceptions:
P4Cms_User_Exceptionthrow exception if role is a virtual role.
    {
        // virtual roles have no corresponding Perforce group.
        if ($this->isVirtual()) {
            throw new P4Cms_Acl_Exception(
                "Cannot get p4 group for virtual roles."
            );
        }

        // only fetch once.
        if (!$this->_p4Group instanceof P4_Group) {
            $adapter        = $this->getAdapter();
            $this->_p4Group = new P4_Group($adapter->getConnection());
            $this->_p4Group->setId(
                static::_getGroupPrefix($adapter) . $this->getId()
            );
        }

        return $this->_p4Group;
    }
P4Cms_Acl_Role::_setP4Group ( P4_Group group) [protected]

Set the corresponding p4 group object instance.

Used when fetching groups to prime the role object.

Parameters:
P4_Group$groupthe corresponding P4_Group object.
Returns:
P4Cms_Acl_Role provides fluent interface.
Exceptions:
P4Cms_User_Exceptionif the role is a virtual role or the given group is not a valid P4_Group object.
    {
        // virtual roles can't have corresponding Perforce group.
        if ($this->isVirtual()) {
            throw new P4Cms_Acl_Exception(
                "Cannot set p4 group for virtual roles."
            );
        }

        $this->_p4Group = $group;

        return $this;
    }
P4Cms_Acl_Role::addOwner ( user)

Add given user to the owners list of the associated group in Perforce.

Parameters:
P4Cms_User | string$userid or instance of user to add
Returns:
P4Cms_Acl_Role provides a fluent interface
    {
        $user = $user instanceof P4Cms_User ? $user->getId() : $user;

        if ($user !== null) {
            $this->_getP4Group()->addOwner($user);
        }

        return $this;
    }
static P4Cms_Acl_Role::addSuperRole ( role) [static]

Register given role as a super role.

Parameters:
string | Zend_Acl_Role_Interface$rolerole to register as a super role
    {
        if ($role instanceof Zend_Acl_Role_Interface) {
            $role = $role->getRoleId();
        } else if (!is_string($role)) {
            throw new P4Cms_Acl_Exception(
                "addSuperRole() expects $role to be of type string or Zend_Acl_Role_Interface"
            );
        }

        static::$_superRoles[] = $role;
    }
P4Cms_Acl_Role::addUser ( P4Cms_User user)

Assign this role to the given user.

Parameters:
P4Cms_User$useruser to add
Returns:
P4Cms_Acl_Role provides a fluent interface
    {
        $this->_getP4Group()->addUser($user->getId());
        return $this;
    }
static P4Cms_Acl_Role::count ( options = array(),
P4Cms_Record_Adapter adapter = null 
) [static]

Count all roles - extended to route through fetch all.

Parameters:
array$optionsoptional - array of options to augment count
P4Cms_Record_Adapter$adapteroptional - storage adapter to use.
Returns:
integer The count of all matching records
    {
        return static::fetchAll($options, $adapter)->count();
    }
P4Cms_Acl_Role::delete ( )

Delete this role entry.

Returns:
P4Cms_Acl_Role provides fluent interface.
Exceptions:
P4Cms_User_Exceptionif the role is protected as such roles cannot be deleted
    {
        // clear user roles cache
        P4Cms_User::clearRolesCache();

        // system roles cannot be deleted
        if ($this->isSystem()) {
            throw new P4Cms_Acl_Exception(
                "Cannot delete system role."
            );
        }

        // delete the group spec.
        $this->_getP4Group()->delete();

        return $this;
    }
static P4Cms_Acl_Role::exists ( roleId,
options = null,
P4Cms_Record_Adapter adapter = null 
) [static]

Check if the named role exists.

Parameters:
string$roleIdthe name of the role to look for.
array | null$optionsoptional - no options are presently supported.
P4Cms_Record_Adapter$adapteroptional - storage adapter to use.
Returns:
bool true if the role exists, false otherwise.
    {
        if (!is_array($options) && !is_null($options)) {
            throw new InvalidArgumentException(
                'Options must be an array or null'
            );
        }

        try {
            static::fetch($roleId, null, $adapter);
            return true;
        } catch (P4Cms_Model_NotFoundException $e) {
            return false;
        } catch (InvalidArgumentException $e) {
            return false;
        }
    }
static P4Cms_Acl_Role::fetch ( roleId,
array $  options = null,
P4Cms_Record_Adapter adapter = null 
) [static]

Fetch the named role.

Parameters:
string$roleIdname of the role to fetch.
array | null$optionsoptional - no options are presently supported.
P4Cms_Record_Adapter$adapteroptional - storage adapter to use.
Returns:
P4Cms_Acl_Role instance of the requested role.
Exceptions:
P4Cms_Model_NotFoundExceptionif the requested role does not exist.
    {
        if (!is_array($options) && !is_null($options)) {
            throw new InvalidArgumentException(
                'Options must be an array or null'
            );
        }

        $adapter = $adapter ?: static::getDefaultAdapter();

        // attempt to fetch group from Perforce.
        try {
            $groupId = static::_getGroupPrefix($adapter) . $roleId;
            $p4Group = P4_Group::fetch($groupId, $adapter->getConnection());
        } catch (P4_Spec_NotFoundException $e) {
            // if role is not virtual, throw an exception
            if (!in_array($roleId, static::$_virtualRoles)) {
                throw new P4Cms_Model_NotFoundException(
                    "Cannot fetch role. Role '$roleId' does not exist."
                );
            }
        }

        $role = new static;
        $role->setAdapter($adapter)
             ->setId($roleId);

        if (isset($p4Group)) {
            $role->_setP4Group($p4Group);
        }

        return $role;
    }
static P4Cms_Acl_Role::fetchAll ( options = array(),
P4Cms_Record_Adapter adapter = null 
) [static]

Fetch all roles.

Fetches groups from perforce (filtered by group prefix) and adds virtual roles (unless excluded).

Parameters:
array$optionsoptional - array of options to augment fetch behavior. Supported options are: FETCH_BY_MEMBER - get roles for given user FETCH_HIDE_VIRTUAL - don't include virtual roles in the result
P4Cms_Record_Adapter$adapteroptional - storage adapter to use.
Returns:
P4Cms_Model_Iterator all user roles in the system.
    {
        $adapter = $adapter ?: static::getDefaultAdapter();
        $roles   = new P4Cms_Model_Iterator;
        $prefix  = static::_getGroupPrefix($adapter);

        // get roles represented by groups with given prefix
        foreach (P4_Group::fetchAll($options, $adapter->getConnection()) as $p4Group) {

            // skip groups without the required prefix.
            if (strpos($p4Group->getId(), $prefix) !== 0) {
                continue;
            }

            $role = new static;
            $role->setAdapter($adapter)
                 ->setId(substr($p4Group->getId(), strlen($prefix)))
                 ->_setP4Group($p4Group);

            $roles[] = $role;
        }

        // add virtual roles (with respect to options)
        if ((!isset($options[self::FETCH_HIDE_VIRTUAL]) || $options[self::FETCH_HIDE_VIRTUAL] != true)
            && !isset($options[self::FETCH_BY_MEMBER])
        ) {
            foreach (static::$_virtualRoles as $roleId) {
                $roles[] = static::fetch($roleId, null, $adapter);
            }
        }

        // ensure consistent ordering of roles.
        $flags = array();
        if (!$adapter->getConnection()->isCaseSensitive()) {
            $flags = array(P4Cms_Model_Iterator::SORT_NO_CASE);
        }
        $roles->sortBy('id', $flags);

        return $roles;
    }
P4Cms_Acl_Role::getRealUsers ( )

Get members of this role that actually exist.

Returns:
array list of all valid users having this role.
    {
        $users = array();
        foreach ($this->getUsers() as $user) {
            if (P4Cms_User::exists($user, null, $this->getAdapter())) {
                $users[] = $user;
            }
        }

        return $users;
    }
P4Cms_Acl_Role::getRoleId ( )

Defined by Zend_Acl_Role_Interface; returns the Role identifier.

Returns:
string id of this role
    {
        // performance optimization - do not change without good reason.
        // effectively the same as calling getId(), but more direct.
        // under some circumstances getRoleId() can be called a great
        // many times and according to xdebug/webgrind this helps a
        // lot, according to real world testing, it helps a little.
        return isset($this->_values['id']) ? $this->_values['id'] : null;
    }
P4Cms_Acl_Role::getType ( )

Get the type of this role (system or custom).

Returns:
string the type of this role.
    {
        return $this->isSystem()
            ? static::TYPE_SYSTEM
            : static::TYPE_CUSTOM;
    }
P4Cms_Acl_Role::getUsers ( )

Get the members of this role.

Returns:
array list of all users having this role.
    {
        return $this->_getP4Group()->getUsers();
    }
P4Cms_Acl_Role::hasUser ( P4Cms_User user)

Determine if given user has this role.

Parameters:
P4Cms_User$useruser to check
Returns:
boolean true if user has this role otherwise false
    {
        return in_array($user->getId(), $this->getUsers());
    }
static P4Cms_Acl_Role::isSuper ( role) [static]

Determine if this role is a super-user role.

Parameters:
Zend_Acl_Role_Interface | string$rolerole to check for
Returns:
boolean true if given role is a super role, false otherwise
    {
        if ($role instanceof Zend_Acl_Role_Interface) {
            $role = $role->getRoleId();
        } else if (!is_string($role)) {
            throw new P4Cms_Acl_Exception(
                "isSuper() expects $role to be of type string or Zend_Acl_Role_Interface"
            );
        }

        return in_array($role, static::$_superRoles);
    }
P4Cms_Acl_Role::isSystem ( )

Determine if this role is a system role.

Returns:
boolean true if this role is a system role, false otherwise
    {
        return in_array($this->getId(), static::$_systemRoles);
    }
P4Cms_Acl_Role::isVirtual ( )

Determine if this role is a virtual role.

Returns:
boolean true if this role is a virtual role, false otherwise
    {
        return in_array($this->getId(), static::$_virtualRoles);
    }
P4Cms_Acl_Role::removeUser ( P4Cms_User user)

Remove this role from a given user.

Parameters:
P4Cms_User$useruser to remove the role from
Returns:
P4Cms_Acl_Role provides a fluent interface
    {
        $users = $this->getUsers();
        $this->setUsers(array_diff($users, array($user->getId())));

        return $this;
    }
P4Cms_Acl_Role::save ( )

Save this role entry.

Returns:
P4Cms_Acl_Role provides fluent interface.
    {
        // clear user roles cache
        P4Cms_User::clearRolesCache();

        // save the group spec.
        // if not connected as a super user, try as owner.
        $group = $this->_getP4Group();
        $owner = !$group->getConnection()->isSuperUser();
        $group->save($owner);

        // if a parent group is specified, add role to parent group.
        $adapter = $this->getAdapter();
        if ($adapter->hasProperty(static::PARENT_GROUP)
            && $adapter->getProperty(static::PARENT_GROUP)
        ) {
            $parent = P4_Group::fetch(
                $adapter->getProperty(static::PARENT_GROUP),
                $adapter->getConnection()
            );
            if (!in_array($group->getId(), $parent->getSubgroups())) {
                $parent->addSubgroup($group->getId())->save($owner);
            }
        }

        return $this;
    }
P4Cms_Acl_Role::setId ( id)

Set the role id - extended to proxy to p4 group.

Add prefix to the id for associated group name in Perforce.

Parameters:
string | int | null$idthe identifier of this record.
Returns:
P4Cms_Acl_Role provides fluent interface.

Reimplemented from P4Cms_Model.

    {
        parent::setId($id);

        // if role is not virtual, we need to add a prefix
        // to the id for the associated group in Perforce
        if (!$this->isVirtual()) {
            $adapter = $this->hasAdapter()
                ? $this->getAdapter()
                : static::getDefaultAdapter();
            $this->_getP4Group()->setId(
                static::_getGroupPrefix($adapter) . $id
            );
        }

        return $this;
    }
P4Cms_Acl_Role::setType ( )

Make type a read-only field.

Exceptions:
P4Cms_Acl_Exceptiontype is read-only.
    {
        throw new P4Cms_Acl_Exception("Cannot set type. Type is read-only.");
    }
static P4Cms_Acl_Role::setUserRoles ( P4Cms_User user,
array $  roles = null,
P4Cms_Record_Adapter adapter = null 
) [static]

Set given roles to the given user, i.e.

after this action, user will have only the roles given in the parameter.

Parameters:
P4Cms_User$useruser to set roles.
array | null$roleslist of roles to assign.
P4Cms_Record_Adapter | null$adapteroptional - storage adapter to use.
    {
        $roles      = $roles ?: array();
        $adapter    = $adapter ?: static::getDefaultAdapter();
        $userRoles  = $user->getRoles()->invoke('getId');

        // add new roles
        foreach (array_diff($roles, $userRoles) as $roleId) {
            static::fetch($roleId, null, $adapter)->addUser($user)
                                                  ->save();
        }

        // remove roles (remove administrator role last)
        $roleAdministrator = null;
        foreach (array_diff($userRoles, $roles) as $roleId) {
            $role = static::fetch($roleId, null, $adapter)->removeUser($user);
            $roleId === static::ROLE_ADMINISTRATOR
             ? $roleAdministrator = $role
             : $role->save();
        }

        // remove administrator role if needed
        if ($roleAdministrator !== null) {
            $roleAdministrator->save();
        }
    }
P4Cms_Acl_Role::setUsers ( users = array())

Assign this role to all of the given users.

Parameters:
array | P4Cms_Model_Iterator$userslist of users to assign this role to
Returns:
P4Cms_Acl_Role provides a fluent interface
    {
        // normalize to array/iterator form.
        $users = is_null($users) ? array() : $users;

        // collect user ids.
        $ids = array();
        foreach ($users as $user) {
            $ids[] = $user instanceof P4Cms_User ? $user->getId() : $user;
        }

        $this->_getP4Group()->setUsers($ids);

        return $this;
    }

Member Data Documentation

P4Cms_Acl_Role::$_fields [static, protected]
Initial value:
 array(
        'users'         => array(
            'accessor'  => 'getUsers',
            'mutator'   => 'setUsers'
        ),
        'type'          => array(
            'accessor'  => 'getType',
            'mutator'   => 'setType'
        )
    )

Reimplemented from P4Cms_Model.

P4Cms_Acl_Role::$_idField = 'id' [static, protected]

Reimplemented from P4Cms_Model.

P4Cms_Acl_Role::$_p4Group = null [protected]
P4Cms_Acl_Role::$_superRoles [static, protected]
Initial value:
 array(
                            self::ROLE_ADMINISTRATOR,
                        )
P4Cms_Acl_Role::$_systemRoles [static, protected]
Initial value:
 array(
                            self::ROLE_MEMBER,
                            self::ROLE_ADMINISTRATOR,
                            self::ROLE_ANONYMOUS
                        )
P4Cms_Acl_Role::$_virtualRoles [static, protected]
Initial value:
 array(
                            self::ROLE_ANONYMOUS,
                        )
const P4Cms_Acl_Role::FETCH_HIDE_VIRTUAL = 'hideVirtual'
const P4Cms_Acl_Role::PARENT_GROUP = 'parentGroup'
const P4Cms_Acl_Role::ROLE_ADMINISTRATOR = 'administrator'
const P4Cms_Acl_Role::ROLE_ANONYMOUS = 'anonymous'
const P4Cms_Acl_Role::ROLE_MEMBER = 'member'
const P4Cms_Acl_Role::TYPE_CUSTOM = 'custom'
const P4Cms_Acl_Role::TYPE_SYSTEM = 'system'

The documentation for this class was generated from the following file: