Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00%
0 / 1
92.59%
25 / 27
CRAP
98.81%
250 / 253
User
0.00%
0 / 1
92.59%
25 / 27
81
98.81%
250 / 253
 __construct(\Scrivo\Context $context=null)
100.00%
1 / 1
2
100.00%
12 / 12
 __get($name)
100.00%
1 / 1
11
100.00%
11 / 11
 __set($name, $value)
100.00%
1 / 1
9
100.00%
9 / 9
 setFields(\Scrivo\Context $context, array $rd)
100.00%
1 / 1
4
100.00%
21 / 21
 patchId($id)
100.00%
1 / 1
3
100.00%
5 / 5
 getRoles()
100.00%
1 / 1
2
100.00%
5 / 5
 setStatus($status)
100.00%
1 / 1
4
100.00%
5 / 5
 setUserCode(\Scrivo\String $userCode)
100.00%
1 / 1
1
100.00%
2 / 2
 setPassword(\Scrivo\String $password)
100.00%
1 / 1
1
100.00%
2 / 2
 setGivenName(\Scrivo\String $givenName)
100.00%
1 / 1
1
100.00%
2 / 2
 setFamilyNamePrefix(\Scrivo\String $familyNamePrefix)
100.00%
1 / 1
1
100.00%
2 / 2
 setFamilyName(\Scrivo\String $familyName)
100.00%
1 / 1
1
100.00%
2 / 2
 setEmailAddress(\Scrivo\String $emailAddress)
100.00%
1 / 1
1
100.00%
2 / 2
 setContext(\Scrivo\Context $context)
0.00%
0 / 1
2
0.00%
0 / 2
 checkUserCode()
100.00%
1 / 1
3
100.00%
14 / 14
 encrypt(\Scrivo\String $password)
100.00%
1 / 1
1
100.00%
3 / 3
 validateInsert()
100.00%
1 / 1
1
100.00%
3 / 3
 insert()
100.00%
1 / 1
3
100.00%
23 / 23
 validateUpdate()
100.00%
1 / 1
1
100.00%
3 / 3
 update()
100.00%
1 / 1
2
100.00%
20 / 20
 updatePassword()
100.00%
1 / 1
2
100.00%
11 / 11
 checkPassword(\Scrivo\String $toTest)
100.00%
1 / 1
3
100.00%
12 / 12
 validateDelete(\Scrivo\Context $context, $id)
100.00%
1 / 1
3
100.00%
5 / 5
 delete(\Scrivo\Context $context, $id)
100.00%
1 / 1
3
100.00%
16 / 16
 assignRoles($roles)
100.00%
1 / 1
1
100.00%
3 / 3
 fetch(\Scrivo\Context $context, $id)
0.00%
0 / 1
10
97.14%
34 / 35
 select(\Scrivo\Context $context, $roleId = null)
100.00%
1 / 1
6
100.00%
23 / 23
<?php
/* Copyright (c) 2013, Geert Bergman (geert@scrivo.nl)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of "Scrivo" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id: User.php 866 2013-08-25 16:22:35Z geert $
*/
/**
* Implementation of the \Scrivo\User class.
*/
namespace Scrivo;
/**
* The Scrivo User class represents the user entity in Scrivo. Access rights
* to objects like pages and assets are determined using these user principals.
*
* An user is identified by it's object id, but also by it's user code.
* Convention (but not mandatory) is to use email addresses for user codes.
* Both the user id and user code can be used to retrieve a user.
*
* The User class defines some descriptive members for the user's name and
* and email address. For additional user data to store along with a user
* you can use the multipurose 'customData' field.
*
* Peudo users
*
* The situation that you'll need to autenticate to different user database
* arises frequently. Since the existence of Scrivo users is a requirement
* for dertermining access to pages and assest it is suggested to use psuedo
* users. After autenticating to an other database the user should adopt a
* predefined (or progamatically defined) Scrivo user to access Scrivo
* resources. This is already the case for annymous access to Scrivo resources,
* in that case the user will adopt the Scrivo anymous user identity.
*
* TODO currently object ids 1 and 2 are used for reserved user ids, this is
* not in line with the policy for object ids. In the code the are patched to
* the values 3 and 4.
*
* @property-read object $customData A facility for 'free' storage.
* @property-read int $id The user's user id (DB key)
* @property-read array[] $roles An array of role-ids representing the roles
* for the user.
* @property \Scrivo\String $emailAddress The user's email address.
* @property \Scrivo\String $familyName The user's family name.
* @property \Scrivo\String $familyNamePrefix A prefix for the user's family
* name.
* @property \Scrivo\String $givenName The user's given name.
* @property \Scrivo\String $password The user's password (encrypted).
* @property int $status The user's status, one out of the constants
* self::STATUS_*
* @property \Scrivo\String $userCode A more descriptive identification
* for the user than the user id.*
*/
class User {
/**
* Status value indicating an admin user.
*/
const STATUS_ADMIN = 1;
/**
* Status value indicating an editor.
*/
const STATUS_EDITOR = 2;
/**
* Status value indicating a member.
*/
const STATUS_MEMBER = 3;
/**
* Reserved user id for primary admin user.
*/
const PRIMARY_ADMIN_ID = 4;
/**
* Reserved user id for the anonymous user.
*/
const ANONYMOUS_USER_ID = 3;
/**
* The user's user id (DB key)
* @var int
*/
private $id = 0;
/**
* The user status, one out of the constants self::STATUS_*
* @var int
*/
private $status = self::STATUS_MEMBER;
/**
* A more descriptive identification for the user than the user id.
* @var \Scrivo\String
*/
private $userCode = null;
/**
* The user's password (encrypted).
* @var \Scrivo\String
*/
private $password = null;
/**
* The user's given name.
* @var \Scrivo\String
*/
private $givenName = null;
/**
* A prefix for the user's family name.
* @var \Scrivo\String
*/
private $familyNamePrefix = null;
/**
* The user's family name.
* @var \Scrivo\String
*/
private $familyName = null;
/**
* The user's email address.
* @var \Scrivo\String
*/
private $emailAddress = null;
/**
* An array of role-ids representing the roles for the user.
* @var array[]
*/
private $roles = null;
/**
* A facility for 'free' storage.
* @var object
*/
private $customData = null;
/**
* A Scrivo context.
* @var Context
*/
private $context = null;
/**
* Create an empty user object.
*
* @param \Scrivo\Context $context A Scrivo context.
*/
public function __construct(\Scrivo\Context $context=null) {
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null), 0);
if ($context) {
$this->userCode = new \Scrivo\String();
$this->password = new \Scrivo\String();
$this->givenName = new \Scrivo\String();
$this->familyNamePrefix = new \Scrivo\String();
$this->familyName = new \Scrivo\String();
$this->emailAddress = new \Scrivo\String();
$this->customData = new \stdClass;
$this->context = $context;
}
}
/**
* Implementation of the readable properties using the PHP magic
* method __get().
*
* @param string $name The name of the property to get.
*
* @return mixed The value of the requested property.
*/
public function __get($name) {
switch($name) {
case "id": return $this->id;
case "status": return $this->status;
case "userCode": return $this->userCode;
case "password": return $this->password;
case "givenName": return $this->givenName;
case "familyNamePrefix": return $this->familyNamePrefix;
case "familyName": return $this->familyName;
case "emailAddress": return $this->emailAddress;
case "roles": return $this->getRoles();
case "customData": return $this->customData;
}
throw new \Scrivo\SystemException("No such get-property '$name'.");
}
/**
* Implementation of the writable properties using the PHP magic
* method __set().
*
* @param string $name The name of the property to set.
* @param mixed $value The value of the property to set.
*/
public function __set($name, $value) {
switch($name) {
case "status": $this->setStatus($value); return;
case "userCode": $this->setUserCode($value); return;
case "password": $this->setPassword($value); return;
case "givenName": $this->setGivenName($value); return;
case "familyNamePrefix": $this->setFamilyNamePrefix($value); return;
case "familyName": $this->setFamilyName($value); return;
case "emailAddress": $this->setEmailAddress($value); return;
case "context": $this->setContext($value); return;
}
throw new \Scrivo\SystemException("No such set-property '$name'.");
}
/**
* Convenience method to set the fields of a user object from
* an array (result set row).
*
* @param \Scrivo\Context $context A Scrivo context.
* @param array $rd An array containing the field data using the database
* field names as keys.
*/
private function setFields(\Scrivo\Context $context, array $rd) {
$id = intval($rd["user_id"]);
if ($id === 1) {
$id = self::ANONYMOUS_USER_ID;
}
if ($id === 2) {
$id = self::PRIMARY_ADMIN_ID;
}
$this->id = $id;
$this->status = intval($rd["status"]);
$this->userCode = new \Scrivo\String($rd["user_code"]);
$this->password = new \Scrivo\String("- hidden -");
$this->givenName = new \Scrivo\String($rd["given_name"]);
$this->familyNamePrefix = new \Scrivo\String($rd["family_name_prefix"]);
$this->familyName = new \Scrivo\String($rd["family_name"]);
$this->emailAddress = new \Scrivo\String($rd["email_address"]);
$this->customData = unserialize($rd["custom_data"]);
if (is_array($this->customData)) {
$this->customData = (object)$this->customData;
}
$this->context = $context;
}
/**
* Utility to patch legacy ids 1 and 2.
* @param int $id The id to patch.
* @return int The patched id.
*/
public static function patchId($id) {
if ($id === self::ANONYMOUS_USER_ID) {
return 1;
}
if ($id === self::PRIMARY_ADMIN_ID) {
return 2;
}
return $id;
}
/**
* Get the user-roles for this user.
*
* @return UserRole[roleId] The set of user-roles for this user.
*/
private function getRoles() {
if (!is_array($this->roles)) {
$this->roles = UserRole::select($this->context, $this);
$this->context->cache["U".$this->id] = $this;
}
return $this->roles;
}
/**
* Set the user status, one out of the constants User::STATUS_*
*
* @param int The user status, one out of the constants User::STATUS_*
*/
private function setStatus($status) {
if ($status != self::STATUS_ADMIN && $status != self::STATUS_EDITOR
&& $status != self::STATUS_MEMBER) {
throw new \Scrivo\SystemException("Not a valid status");
}
$this->status = $status;
}
/**
* Set the user code.
*
* @param \Scrivo\String A more descriptive identification for the
* user than the user id.
*/
private function setUserCode(\Scrivo\String $userCode) {
$this->userCode = $userCode;
}
/**
* Set the user's password (not encrypted).
*
* @param \Scrivo\String The user's password (not encrypted).
*/
private function setPassword(\Scrivo\String $password) {
$this->password = new \Scrivo\String($this->encrypt($password));
}
/**
* Set the user's given name.
*
* @param \Scrivo\String The user's given name.
*/
private function setGivenName(\Scrivo\String $givenName) {
$this->givenName = $givenName;
}
/**
* Set a prefix for the user's family name.
*
* @param \Scrivo\String A prefix for the user's family name.
*/
private function setFamilyNamePrefix(\Scrivo\String $familyNamePrefix) {
$this->familyNamePrefix = $familyNamePrefix;
}
/**
* Set the user's family name.
*
* @param \Scrivo\String The user's family name.
*/
private function setFamilyName(\Scrivo\String $familyName) {
$this->familyName = $familyName;
}
/**
* Set the user's email address
*
* @param \Scrivo\String The user's email address
*/
private function setEmailAddress(\Scrivo\String $emailAddress) {
$this->emailAddress = $emailAddress;
}
/**
* Set the user's context.
*
* @param \Scrivo\Context $context A Scrivo context.
*/
private function setContext(\Scrivo\Context $context) {
$this->context = $context;
}
/**
* Check if the current user code is valid.
*
* The user code must be unique in the current database instance and at
* least three characters in length.
*
* @throws ApplicationException If the user code does not comply.
*/
private function checkUserCode() {
if ($this->userCode->length < 3) {
throw new ApplicationException("User code too short",
StatusCodes::USER_CODE_TOO_SHORT);
}
$sth = $this->context->connection->prepare(
"SELECT COUNT(*) FROM user
WHERE instance_id = :instId AND user_code = :userCode
AND user_id <> :id");
$this->context->connection->bindInstance($sth);
$sth->bindValue(":id", self::patchId($this->id), \PDO::PARAM_INT);
$sth->bindValue(":userCode", $this->userCode, \PDO::PARAM_STR);
$sth->execute();
$count = $sth->fetchColumn();
if ($count != 0) {
throw new \Scrivo\ApplicationException("User code already in use",
StatusCodes::USER_CODE_IN_USE);
}
}
/**
* Encrypt a password.
*
* @param \Scrivo\String $password
*
* @return string
*/
private function encrypt(\Scrivo\String $password) {
$salt = base_convert(md5(mt_rand(0, 1000000)), 16, 36);
$c = crypt($password, "\$2a\$07\$".$salt."\$");
return $c;
}
/**
* Check if this user object can be inserted into the database.
*
* @throws \Scrivo\ApplicationException If the data is not accessible or
* one or more of the fields contain invalid data.
*/
private function validateInsert() {
$this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS);
$this->checkUserCode();
}
/**
* Insert new user object data into the database.
*
* First it is checked if the data of this user object can be inserted
* into the database, then the data is inserted into the database. If no id
* was set a new object id is generated.
*
* @throws \Scrivo\ApplicationException If the data is not accessible or
* one or more of the fields contain invalid data.
*/
public function insert() {
try {
$this->validateInsert();
if (!$this->id) {
$this->id = $this->context->connection->generateId();
}
$sth = $this->context->connection->prepare(
"INSERT INTO user (
instance_id, user_id, status, user_code, password,
given_name, family_name_prefix, family_name, email_address,
custom_data
) VALUES (
:instId, :id, :status, :userCode, :password,
:givenName, :familyNamePrefix, :familyName, :emailAddress,
:customData
)");
$this->context->connection->bindInstance($sth);
$sth->bindValue(":id", $this->id, \PDO::PARAM_INT);
$sth->bindValue(":status", $this->status, \PDO::PARAM_INT);
$sth->bindValue(":userCode", $this->userCode, \PDO::PARAM_STR);
$sth->bindValue(":password", $this->password, \PDO::PARAM_STR);
$sth->bindValue(":givenName", $this->givenName, \PDO::PARAM_STR);
$sth->bindValue(
":familyNamePrefix", $this->familyNamePrefix, \PDO::PARAM_STR);
$sth->bindValue(":familyName", $this->familyName, \PDO::PARAM_STR);
$sth->bindValue(
":emailAddress", $this->emailAddress, \PDO::PARAM_STR);
$sth->bindValue(
":customData", serialize($this->customData), \PDO::PARAM_STR);
$sth->execute();
} catch(\PDOException $e) {
throw new \Scrivo\ResourceException($e);
}
}
/**
* Check if this user object can be updated in the database.
*
* @throws \Scrivo\ApplicationException If the data is not accessible or
* one or more of the fields contain invalid data.
*/
private function validateUpdate() {
$this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS);
$this->checkUserCode();
}
/**
* Update existing user object data in the database.
*
* First it is checked if the data of this user object can be updated
* in the database, then the data is updated in the database.
*
* The user's password cannot be updated with this method. Use
* User::updatePassword() in order to do that.
*
* @throws \Scrivo\ApplicationException If the data is not accessible or
* one or more of the fields contain invalid data.
*/
public function update() {
try {
$this->validateUpdate();
$sth = $this->context->connection->prepare(
"UPDATE user SET
status = :status, user_code = :userCode,
given_name = :givenName,
family_name_prefix = :familyNamePrefix,
family_name = :familyName, email_address = :emailAddress,
custom_data = :customData
WHERE instance_id = :instId AND user_id = :id");
$this->context->connection->bindInstance($sth);
$sth->bindValue(":id", self::patchId($this->id), \PDO::PARAM_INT);
$sth->bindValue(":status", $this->status, \PDO::PARAM_INT);
$sth->bindValue(":userCode", $this->userCode, \PDO::PARAM_STR);
$sth->bindValue(":givenName", $this->givenName, \PDO::PARAM_STR);
$sth->bindValue(
":familyNamePrefix", $this->familyNamePrefix, \PDO::PARAM_STR);
$sth->bindValue(":familyName", $this->familyName, \PDO::PARAM_STR);
$sth->bindValue(
":emailAddress", $this->emailAddress, \PDO::PARAM_STR);
$sth->bindValue(
":customData", serialize($this->customData), \PDO::PARAM_STR);
$sth->execute();
unset($this->context->cache["U".$this->id]);
} catch(\PDOException $e) {
throw new \Scrivo\ResourceException($e);
}
}
/**
* Update the password of this user.
*
* The password property should be set to its new value. When saving
* a encrypted value will be stored into the database. When this user
* object is loaded again its password property will contain the encrypted
* value for the new password.
*
* @throws ApplicationException If one or more of the fields contain
* invalid data.
*/
public function updatePassword() {
try {
$this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS);
$sth = $this->context->connection->prepare(
"UPDATE user SET password = :password
WHERE instance_id = :instId AND user_id = :id");
$this->context->connection->bindInstance($sth);
$sth->bindValue(":id", self::patchId($this->id), \PDO::PARAM_INT);
$sth->bindValue(
":password", $this->password, \PDO::PARAM_STR);
$sth->execute();
} catch(\PDOException $e) {
throw new \Scrivo\ResourceException($e);
}
}
/**
* Check if a given password matches with the one of this user.
*
* @param \Scrivo\String $toTest Password to test.
*
* @return boolean True if given password matches the user's, false if not.
*/
public function checkPassword(\Scrivo\String $toTest) {
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null));
try {
$sth = $this->context->connection->prepare(
"SELECT password FROM user
WHERE instance_id = :instId AND user_id = :id");
$this->context->connection->bindInstance($sth);
$sth->bindValue(":id", self::patchId($this->id), \PDO::PARAM_INT);
$sth->execute();
if ($sth->rowCount() != 1) {
throw new \Scrivo\SystemException("Failed to load User");
}
$pw = $sth->fetchColumn();
return $pw == crypt($toTest, $pw);
} catch(\PDOException $e) {
throw new \Scrivo\ResourceException($e);
}
}
/**
* Check if deletion of user object data does not violate any
* business rules.
*
* @param \Scrivo\Context $context A Scrivo context.
* @param int $id a valid object id.
*
* @throws \Scrivo\ApplicationException If the data is not accessible or
* if it is not possible to delete the user data.
*/
private function validateDelete(\Scrivo\Context $context, $id) {
$context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS);
if ($id == self::PRIMARY_ADMIN_ID || $id == self::ANONYMOUS_USER_ID) {
throw new \Scrivo\ApplicationException("Can't delete system users",
StatusCodes::CANNOT_DELETE_SYSTEM_USERS);
}
}
/**
* Delete existing user data from the database.
*
* First it is is checked if it's possible to delete user data,
* then the user data including its dependecies is deleted from
* the database.
*
* @param \Scrivo\Context $context A Scrivo context.
* @param int $id a valid object id.
*
* @throws \Scrivo\ApplicationException If the data is not accessible or
* if it is not possible to delete the user data.
*/
public static function delete(\Scrivo\Context $context, $id) {
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
null,
array(\Scrivo\ArgumentCheck::TYPE_INTEGER)
));
try {
self::validateDelete($context, $id);
foreach (array("user", "user_role") as $table) {
$sth = $context->connection->prepare(
"DELETE FROM $table
WHERE instance_id = :instId AND user_id = :id");
$context->connection->bindInstance($sth);
$sth->bindValue(":id", $id, \PDO::PARAM_INT);
$sth->execute();
}
unset($context->cache["U".$id]);
} catch(\PDOException $e) {
throw new \Scrivo\ResourceException($e);
}
}
/**
* Assign user roles to this user.
*
* The user roles to set is either an array of UserRole or stdObject
* objects. stdObject need to contain the members roleId and isPublisher.
*
* Note: this sets all the roles for the user at once. So not giving the
* the roles effectivily clears the roles for the given user.
*
* @param UserRole[]|object[] $roles A new set of user-roles for the given
* user.
*/
public function assignRoles($roles) {
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null));
UserRole::set($this->context, $this, $roles);
}
/**
* Fetch a user object from the database using the object id or
* user code.
*
* @param \Scrivo\Context $context A Scrivo context.
* @param int|\Scrivo\String $id a valid object id or user code.
*
* @return \Scrivo\User The requested user object.
*
* @throws \Scrivo\ApplicationException If the given user code was
* not found (when selecting by user code).
*/
public static function fetch(\Scrivo\Context $context, $id) {
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
null,
array(array(\Scrivo\ArgumentCheck::TYPE_INTEGER, "Scrivo\String"))
));
try {
if ($id instanceof \Scrivo\String) {
$byUserCode = true;
} else if (is_int($id)) {
$byUserCode = false;
} else {
throw new \Scrivo\SystemException("Invalid argument type");
}
// Try to retieve the user from the cache ...
if (!$byUserCode && isset($context->cache["U".$id])) {
// ... get it from the cache and set the context.
$user = $context->cache["U".$id];
$user->context = $context;
} else {
// ... else retrieve it and set it in the cache.
$sth = $context->connection->prepare(
"SELECT user_id, status, user_code,
given_name, family_name_prefix, family_name, email_address, custom_data
FROM user
WHERE instance_id = :instId AND
".($byUserCode ? "user_code" : "user_id")." = :id");
$user = new \Scrivo\User($context);
$context->connection->bindInstance($sth);
if ($byUserCode) {
$sth->bindValue(":id", $id, \PDO::PARAM_STR);
} else {
$sth->bindValue(
":id", $user->patchId($id), \PDO::PARAM_INT);
}
$sth->execute();
if ($sth->rowCount() != 1) {
if ($byUserCode) {
throw new \Scrivo\ApplicationException(
"Failed to load User $byUserCode");
}
throw new \Scrivo\SystemException("Failed to load User");
}
$rd = $sth->fetch(\PDO::FETCH_ASSOC);
$user->setFields($context, $rd);
$context->cache["U".$user->id] = $user;
}
return $user;
} catch(\PDOException $e) {
throw new \Scrivo\ResourceException($e);
}
}
/**
* Select users from the database.
*
* Depending on the given arguments all users or all users for a given
* role can be retrieved.
*
* @param \Scrivo\Context $context A Scrivo context.
* @param int $roleId Optional role id for which to retrieve the users.
*
* @return User[id] An array containing the selected users.
*/
public static function select(\Scrivo\Context $context, $roleId = null) {
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
null,
array(\Scrivo\ArgumentCheck::TYPE_INTEGER)
), 1);
try {
$sth = $context->connection->prepare(
"SELECT U.user_id, U.status, U.user_code, U.given_name, U.family_name_prefix,
U.family_name, U.email_address, U.custom_data
FROM user U" .($roleId? ", user_role": "")."
WHERE U.instance_id = :instId" .($roleId
? " AND user_role.instance_id = :instId AND
user_role.user_id = U.user_id AND role_id = :roleId"
: ""));
$context->connection->bindInstance($sth);
if ($roleId) {
$sth->bindValue(":roleId", $roleId, \PDO::PARAM_INT);
}
$sth->execute();
$res = array();
while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) {
$li = new User();
$li->setFields($context, $rd);
$res[$li->id] = $li;
}
return $res;
} catch(\PDOException $e) {
throw new \Scrivo\ResourceException($e);
}
}
}