Perforce Chronicle 2012.2/486814
API Documentation
|
Abstracts operations against Perforce users. More...
Public Member Functions | |
addToGroup ($group) | |
Add this user to the named group. | |
delete () | |
Remove this user from Perforce. | |
getAccessDateTime () | |
Get the last access time for this user spec. | |
getClients () | |
Get an Iterator of all the Clients this user owns. | |
getEmail () | |
Get the user's email address. | |
getFullName () | |
Get the user's full name. | |
getGroups () | |
Get the names of groups that this user belongs to. | |
getJobView () | |
Get the user's job view (selects jobs for inclusion during changelist creation). | |
getPassword () | |
Get the in-memory password (if one is set). | |
getReviews () | |
Get the reviews for this client (depot paths to notify user of changes to). | |
getUpdateDateTime () | |
Get the last update time for this user spec. | |
isPassword ($password) | |
Test if the given password is correct for this user. | |
save () | |
Save this user to Perforce. | |
setEmail ($email) | |
Set the user's email address. | |
setFullName ($name) | |
Set the user's full name. | |
setJobView ($jobView) | |
Set the user's job view (selects jobs for inclusion during changelist creation). | |
setPassword ($newPassword, $oldPassword=null) | |
Set the user's password to the given password. | |
setReviews ($reviews) | |
Set the reviews for this user (depot paths to notify user of changes to). | |
Static Public Member Functions | |
static | exists ($id, P4_Connection_Interface $connection=null) |
Determine if the given user id exists. | |
static | fetchAll ($options=array(), P4_Connection_Interface $connection=null) |
Get all users from Perforce. | |
static | isAutoUserCreationEnabled (P4_Connection_Interface $connection=null) |
Check if automatic user creation is enabled. | |
Public Attributes | |
const | FETCH_BY_NAME = 'name' |
Protected Member Functions | |
_setPassword ($newPassword, $oldPassword=null, P4_Connection_Interface $connection=null) | |
Immediately set the user's password to the given password. | |
Static Protected Member Functions | |
static | _fromSpecListEntry ($listEntry, $flags, P4_Connection_Interface $connection) |
Given a spec entry from spec list output (p4 users), produce an instance of this spec with field values set where possible. | |
static | _getFetchAllFlags ($options) |
Produce set of flags for the spec list command, given fetch all options array. | |
static | _isValidId ($id) |
Check if the given id is in a valid format for user specs. | |
Static Protected Attributes | |
static | $_accessors |
static | $_idField = 'User' |
static | $_mutators |
static | $_specType = 'user' |
Abstracts operations against Perforce users.
The P4 User class differs from the 'user' spec definition in that it does not have a password field. This is because the password does not behave like other fields. To change a user's password, use the setPassword() function. To test if a given string matches a user's password, use the isPassword() method. It is not possible to get a user's password.
static P4_User::_fromSpecListEntry | ( | $ | listEntry, |
$ | flags, | ||
P4_Connection_Interface $ | connection | ||
) | [static, protected] |
Given a spec entry from spec list output (p4 users), produce an instance of this spec with field values set where possible.
array | $listEntry | a single spec entry from spec list output. |
array | $flags | the flags that were used for this 'fetchAll' run. |
P4_Connection_Interface | $connection | a specific connection to use. |
Reimplemented from P4_Spec_PluralAbstract.
{ // update/access time are return as longs. Unset to avoid figuring out timezone // for a proper conversion. unset($listEntry['update']); unset($listEntry['access']); return parent::_fromSpecListEntry($listEntry, $flags, $connection); }
static P4_User::_getFetchAllFlags | ( | $ | options | ) | [static, protected] |
Produce set of flags for the spec list command, given fetch all options array.
Extends parent to add support for filter option.
array | $options | array of options to augment fetch behavior. see fetchAll for documented options. |
Reimplemented from P4_Spec_PluralAbstract.
{ $flags = parent::_getFetchAllFlags($options); if (isset($options[static::FETCH_BY_NAME])) { $name = $options[static::FETCH_BY_NAME]; if ((!is_array($name) || !count($name)) && (!is_string($name) || trim($name) === "")) { throw new InvalidArgumentException( 'Filter by Name expects a non-empty string or an non-empty array as input' ); } // if array is given, ensure values are non-empty strings if (is_array($name)) { $names = $name; $filtered = array_filter($names, 'is_string'); $filtered = array_filter($filtered, 'trim'); if (count($names) !== count($filtered)) { throw new InvalidArgumentException( 'Filter by Name expects all names in the input array to be non-empty strings' ); } $flags = array_merge($flags, $names); } else { $flags[] = $name; } } return $flags; }
static P4_User::_isValidId | ( | $ | id | ) | [static, protected] |
Check if the given id is in a valid format for user specs.
string | $id | the id to check |
Reimplemented from P4_Spec_PluralAbstract.
{ $validator = new P4_Validate_UserName; return $validator->isValid($id); }
P4_User::_setPassword | ( | $ | newPassword, |
$ | oldPassword = null , |
||
P4_Connection_Interface $ | connection = null |
||
) | [protected] |
Immediately set the user's password to the given password.
If the current password is given, it will be validated.
string | $newPassword | the new password. |
string | $oldPassword | optional - existing password. |
P4_Connection_Interface | $connection | optional - a specific connection to use. |
P4_Exception | if the password can't be set. |
{ $input = array(); // if caller supplied an old password, prepend it to input array. if ($oldPassword) { $input[] = $oldPassword; } // always confirm old password $input[] = $newPassword; $input[] = $newPassword; // if no connection given, use default. $connection = $connection ?: $this->getConnection(); // if not connected as this user, supply user id. $flags = array(); if ($connection->getUser() !== $this->getId()) { $flags[] = $this->getId(); } // attempt to set password. $result = $connection->run("password", $flags, $input); // change connection credentials if password for connected user has been changed // if we don't do this automatically, subsequent commands will fail when using // the command-line connection, but would succeed using the P4PHP extension. if ($connection->getUser() === $this->getId()) { $connection->setPassword($newPassword); if ($connection->getTicket()) { $connection->login(); } } return $this; }
P4_User::addToGroup | ( | $ | group | ) |
Add this user to the named group.
string | $group | the name of the group to add the user to. |
{ $group = P4_Group::fetch($group, $this->getConnection()) ->addUser($this->getId()) ->save(); return $this; }
P4_User::delete | ( | ) |
Remove this user from Perforce.
P4_Spec_Exception | if no id has been set. |
{ if ($this->getId() === null) { throw new P4_Spec_Exception("Cannot delete. No id has been set."); } // initialize command flags with first arg. $flags = array("-d"); // if we are connected with super user privileges, add in the -f flag. // otherwise, if not connected as this user, connect as this user. $connection = $this->getConnection(); if ($connection->isSuperUser()) { $flags[] = "-f"; } else if ($connection->getUser() != $this->getId()) { $connection = P4_Connection::factory( $connection->getPort(), $this->getId() ); } // issue delete user command. $flags[] = $this->getId(); $result = $connection->run(static::_getSpecType(), $flags); // should re-populate. $this->_deferPopulate(true); return $this; }
static P4_User::exists | ( | $ | id, |
P4_Connection_Interface $ | connection = null |
||
) | [static] |
Determine if the given user id exists.
string | $id | the id to check for. |
P4_Connection_Interface | $connection | optional - a specific connection to use. |
Reimplemented from P4_Spec_PluralAbstract.
{ // check id for valid format if (!static::_isValidId($id)) { return false; } $users = static::fetchAll( array( static::FETCH_BY_NAME => $id, static::FETCH_MAXIMUM => 1 ), $connection ); return (bool) count($users); }
static P4_User::fetchAll | ( | $ | options = array() , |
P4_Connection_Interface $ | connection = null |
||
) | [static] |
Get all users from Perforce.
Adds filtering option.
array | $options | optional - array of options to augment fetch behavior. supported options are: |
FETCH_MAXIMUM - set to integer value to limit to the first 'max' number of entries. FETCH_BY_NAME - set to user name pattern (e.g. 'jdo*'), can be a single string or array of strings.
P4_Connection_Interface | $connection | optional - a specific connection to use. |
Reimplemented from P4_Spec_PluralAbstract.
{ $connection = $connection ?: static::getDefaultConnection(); // if not fetching by name, defer to parent if (!isset($options[static::FETCH_BY_NAME])) { return parent::fetchAll($options, $connection); } // get fetch max option and uset it from the options as we handle it manually $max = isset($options[static::FETCH_MAXIMUM]) ? $options[static::FETCH_MAXIMUM] : 0; unset($options[static::FETCH_MAXIMUM]); // sort names before fetching users from the server, so if max is set // we get the first max users (according to case-sensitivity of server) $names = (array) $options[static::FETCH_BY_NAME]; if ($connection->isCaseSensitive()) { sort($names); } else { usort($names, 'strcasecmp'); } // fetch users in several (as few as possible) runs as // there is a potential to exceed the arg-max on this command $users = new P4_Model_Iterator; foreach ($connection->batchArgs($names) as $batch) { $options[static::FETCH_BY_NAME] = $batch; foreach (parent::fetchAll($options, $connection) as $user) { $users[] = $user; // exit loop if we've reached the max limit if ($max && $users->count() == $max) { break(2); } } } return $users; }
P4_User::getAccessDateTime | ( | ) |
Get the last access time for this user spec.
This value is read only, no setAccessTime function is provided.
If this is a brand new spec, null will be returned in lieu of a time.
{ return $this->_getValue('Access'); }
P4_User::getClients | ( | ) |
Get an Iterator of all the Clients this user owns.
P4_Spec_Exception | If no ID is set for this user |
{ if (!static::_isValidId($this->getId())) { throw new P4_Spec_Exception("Cannot get clients. No user id has been set."); } return P4_Client::fetchAll( array(P4_Client::FETCH_BY_OWNER => $this->getId()), $this->getConnection() ); }
P4_User::getEmail | ( | ) |
Get the user's email address.
{ return $this->_getValue('Email'); }
P4_User::getFullName | ( | ) |
Get the user's full name.
{ return $this->_getValue('FullName'); }
P4_User::getGroups | ( | ) |
Get the names of groups that this user belongs to.
{ if (!static::_isValidId($this->getId())) { throw new P4_Spec_Exception("Cannot get groups. No user id has been set."); } return P4_Group::fetchAll( array(P4_Group::FETCH_BY_MEMBER => $this->getId(), P4_Group::FETCH_INDIRECT), $this->getConnection() ); }
P4_User::getJobView | ( | ) |
Get the user's job view (selects jobs for inclusion during changelist creation).
{ return $this->_getValue('JobView'); }
P4_User::getPassword | ( | ) |
Get the in-memory password (if one is set).
{ $password = $this->_getValue('Password'); return is_array($password) ? $password[0] : null; }
P4_User::getReviews | ( | ) |
Get the reviews for this client (depot paths to notify user of changes to).
{ return $this->_getValue('Reviews') ?: array(); }
P4_User::getUpdateDateTime | ( | ) |
Get the last update time for this user spec.
This value is read only, no setUpdateTime function is provided.
If this is a brand new spec, null will be returned in lieu of a time.
{ return $this->_getValue('Update'); }
static P4_User::isAutoUserCreationEnabled | ( | P4_Connection_Interface $ | connection = null | ) | [static] |
Check if automatic user creation is enabled.
P4_Connection_Interface | $connection | optional - a specific connection to use. |
P4_Exception | if we exceed the maximum number of unlikely usernames |
{ // if no connection given, use default. $connection = $connection ?: static::getDefaultConnection(); $port = $connection->getPort(); // limit the number of 'unlikely' username lookups to 3. $maxLookups = 3; for ($i = 0; $i < $maxLookups; $i++) { // generate an unlikely user name. $username = md5(mt_rand()); // try to run p4 users as the unlikely user // (perforce won't create an account for this lookup). try { $connection = P4_Connection::factory($port, $username); $result = $connection->run('users', $username); } catch (P4_Connection_CommandException $e) { return false; } // ensure unlikely user doesn't exist. if (!$result->getData()) { return true; } } throw new P4_Exception( "Failed to determine if auto user creation is enabled." . "Exceeded the maximum of $maxLookups 'unlikely' username lookups." ); }
P4_User::isPassword | ( | $ | password | ) |
Test if the given password is correct for this user.
string | $password | the password to test. |
{ $p4 = P4_Connection::factory( $this->getConnection()->getPort(), $this->getId(), null, $password ); try { $p4->login(); return true; } catch (P4_Connection_LoginException $e) { return false; } }
P4_User::save | ( | ) |
Save this user to Perforce.
This will not save changes to the password field. Passwords must be set via setPassword().
P4_Spec_Exception | if no id has been set. |
Reimplemented from P4_SpecAbstract.
{ // ensure all required fields have values. $this->_validateRequiredFields(); // set 'password' field to '******' otherwise password // will be deleted under certain security levels. $values = $this->_getValues(); $values['Password'] = '******'; // initialize command flags with first arg. $flags = array("-i"); // if we are connected with super user privileges, add in the -f flag. // otherwise, if not connected as this user, connect as this user. $connection = $this->getConnection(); if ($connection->isSuperUser()) { $flags[] = "-f"; } else if ($connection->getUser() != $this->getId()) { $connection = P4_Connection::factory( $connection->getPort(), $this->getId() ); } // send user spec to server. $password = $this->_getValue('Password'); try { $connection->run(static::_getSpecType(), $flags, $values); } catch (P4_Connection_CommandException $e) { // if saving user failed because password has not been // set, and the caller supplied a password, try setting // the password first, then saving user again. // // @todo This workaround relies on the fact, that user has been created although previous // command had failed. At the moment it seems, that when adding a new user (with non-superuser // connection) this error cannot be avoided. $errors = $e->getResult()->getErrors(); if (stristr($errors[0], "password must be set") && is_array($password) && isset($password[0])) { $this->_setPassword($password[0], null, $connection); $connection->run(static::_getSpecType(), $flags, $values); // avoid redundant password change $password[0] = null; } else { throw $e; } } // change the users password if they have set a new one. if (is_array($password) && $password[0] !== null) { $this->_setPassword($password[0], $password[1], $connection); } // should re-populate (server may change values). $this->_deferPopulate(true); return $this; }
P4_User::setEmail | ( | $ | ) |
Set the user's email address.
We don't require a valid email address here because Perforce doesn't enforce one. If we did then users with invalid emails would be innaccessible.
string | null | the email of the user. |
InvalidArgumentException | if given email is not a string. |
{ if ($email !== null && !is_string($email)) { throw new InvalidArgumentException("Cannot set email. Invalid type given."); } return $this->_setValue("Email", $email); }
P4_User::setFullName | ( | $ | name | ) |
Set the user's full name.
string | null | $name | the full name to give the user. |
InvalidArgumentException | if given name is not a string. |
{ if ($name !== null && !is_string($name)) { throw new InvalidArgumentException("Cannot set full name. Invalid type given."); } return $this->_setValue('FullName', $name); }
P4_User::setJobView | ( | $ | jobView | ) |
Set the user's job view (selects jobs for inclusion during changelist creation).
string | null | $jobView | the user's job view. |
InvalidArgumentException | if given job view is not a string. |
{ if ($jobView !== null && !is_string($jobView)) { throw new InvalidArgumentException("Cannot set job view. Invalid type given."); } return $this->_setValue("JobView", $jobView); }
P4_User::setPassword | ( | $ | newPassword, |
$ | oldPassword = null |
||
) |
Set the user's password to the given password.
Does not take effect until save() is called.
string | null | $newPassword | the new password string or null to clear in-memory password. |
string | $oldPassword | optional - existing password. |
{ $this->_setValue('Password', array($newPassword, $oldPassword)); return $this; }
P4_User::setReviews | ( | $ | reviews | ) |
Set the reviews for this user (depot paths to notify user of changes to).
Reviews is passed as an array of filespec strings.
array | $reviews | Review entries - an array of filespec strings. |
InvalidArgumentException | if reviews is not an array. |
{ if (!is_array($reviews)) { throw new InvalidArgumentException('Reviews must be passed as array.'); } return $this->_setValue('Reviews', $reviews); }
P4_User::$_accessors [static, protected] |
array( 'Email' => 'getEmail', 'Update' => 'getUpdateDateTime', 'Access' => 'getAccessDateTime', 'FullName' => 'getFullName', 'JobView' => 'getJobView', 'Reviews' => 'getReviews', 'Password' => 'getPassword', )
Reimplemented from P4_SpecAbstract.
P4_User::$_idField = 'User' [static, protected] |
Reimplemented from P4_Spec_PluralAbstract.
P4_User::$_mutators [static, protected] |
array( 'Email' => 'setEmail', 'FullName' => 'setFullName', 'JobView' => 'setJobView', 'Reviews' => 'setReviews', 'Password' => 'setPassword', )
Reimplemented from P4_SpecAbstract.
P4_User::$_specType = 'user' [static, protected] |
Reimplemented from P4_SpecAbstract.
const P4_User::FETCH_BY_NAME = 'name' |