. */ /** * An interface to the user table in the database */ class user { /** * @var pdo $pdo The PDO class for database communication * @var int $id The id of the user * @var string $username The username of the user * @var string $password The (hashed) password of the user */ protected $pdo, $id, $username, $password; /** * Generate a random password * * @return string The password */ public static function generateRandomPassword() { return preg_replace('/[^\w]/', '', base64_encode(bin2hex(openssl_random_pseudo_bytes(4)))); } /** * Hash a password * * @param string $password The password to be hashed * @param int $cost The password cost * * @return string The hashed password */ public static function hash($password, $cost=null) { return password_hash( $password, constants::password_algo, ['cost' => is_null($cost) ? constants::password_cost : $cost] ); } /** * Create a new instance * * @param PDO $pdo The PDO class, to access the database * @param int $id The id of the user to fetch * * @throws PDOException If something went wrong with the database * @throws Exception If the user could not be found */ public function __construct($pdo, $id) { $this->pdo = $pdo; $stmt = $this->pdo->prepare("SELECT * FROM `".constants::db_prefix."user` WHERE `id`=?"); $stmt->execute(array($id)); if ($stmt->rowCount() == 0) { throw new Exception("The user with id '$id' could not be found."); } $user = $stmt->fetch(PDO::FETCH_ASSOC); $this->id = $user['id']; $this->username = $user['username']; $this->password = $user['password']; } //------------------------------------------------------------------------------ // Getters and setters //------------------------------------------------------------------------------ /** * Get the ID of the user * * @return int The ID */ public function getId() { return $this->id; } /** * Get the username of the user * * @return string The username */ public function getUsername() { return $this->username; } /** * Set the username of the user * * @param string $username The new username for the user * * @throws PDOException If something went wrong with the database * * @return bool True on succes, false on failure */ public function setName($username) { $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."user` SET `username`=? WHERE `id`=?"); $stmt->execute(array($username, $this->id)); if ($stmt->rowCount() == 1) { $this->username = $username; return true; } else { return false; } } /** * Set the password of the user * * @param string $password The new password for the user * * @throws PDOException If something went wrong with the database * * @return bool True on succes, false on failure */ public function setPassword($password) { $password = self::hash($password); $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."user` SET `password`=? WHERE `id`=?"); $stmt->execute(array($password, $this->id)); if ($stmt->rowCount() == 1) { $this->password = $password; return true; } else { return false; } } //------------------------------------------------------------------------------ // Other functions //------------------------------------------------------------------------------ /** * Check if a user has administrator rights * * @return bool True iff the user has administrator rights */ public function isAdmin() { return $this->getId() == 1; } /** * Verify a password * * @param string $password The password to verify * * @return bool True iff the password can be accepted */ public function verifyPassword($password) { if (!password_verify($password, $this->password)) { return false; } if (password_needs_rehash($this->password, constants::password_algo, ['cost' => constants::password_cost])) { $this->setPassword($password); } return true; } /** * Remove this user from the database * * If this doesn't succeed (i.e. false is returned), that means the user was removed manually or by another instance of this class * * @throws PDOException If something went wrong with the database * * @return bool True on success, false on failure */ public function delete() { $stmt = $this->pdo->prepare("DELETE FROM `".constants::db_prefix."user` WHERE `id`=?"); $stmt->execute(array($this->id)); if ($stmt->rowCount() != 1) { return false; } else { return true; } } }