Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F12574023
D3858.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
16 KB
Referenced Files
None
Subscribers
None
D3858.diff
View Options
diff --git a/workspaces/src/Engines/Auth/AuthenticationMethod.php b/workspaces/src/Engines/Auth/AuthenticationMethod.php
--- a/workspaces/src/Engines/Auth/AuthenticationMethod.php
+++ b/workspaces/src/Engines/Auth/AuthenticationMethod.php
@@ -21,6 +21,7 @@
use Waystone\Workspaces\Engines\Auth\Actions\GivePermissionUserAction;
use Waystone\Workspaces\Engines\Framework\Context;
use Waystone\Workspaces\Engines\Serialization\ArrayDeserializableWithContext;
+use Waystone\Workspaces\Engines\Users\User;
use Keruald\OmniTools\DataTypes\Option\None;
use Keruald\OmniTools\DataTypes\Option\Option;
@@ -28,7 +29,6 @@
use Language;
use Message;
-use User;
use Exception;
use InvalidArgumentException;
@@ -202,13 +202,15 @@
throw new Exception("Can't create user: the canCreateUser property is set at false.");
}
- $user = User::create($this->context->db);
+ $users = $this->context->userRepository;
+
+ $user = $users->create();
$user->name = $this->name;
$user->email = $this->email;
- $user->save_to_database();
+ $users->saveToDatabase($user);
- $user->setRemoteIdentity(
- $this->id, $this->remoteUserId,
+ $users->setRemoteIdentity(
+ $user, $this->id, $this->remoteUserId,
);
$this->localUser = $user;
diff --git a/workspaces/src/Engines/Auth/UserAction.php b/workspaces/src/Engines/Auth/UserAction.php
--- a/workspaces/src/Engines/Auth/UserAction.php
+++ b/workspaces/src/Engines/Auth/UserAction.php
@@ -19,8 +19,7 @@
namespace Waystone\Workspaces\Engines\Auth;
use Waystone\Workspaces\Engines\Framework\Context;
-
-use User;
+use Waystone\Workspaces\Engines\Users\User;
/**
* User action class, to be extended to implement an action related to user
diff --git a/workspaces/src/Engines/Exceptions/UserNotFoundException.php b/workspaces/src/Engines/Exceptions/UserNotFoundException.php
new file mode 100644
--- /dev/null
+++ b/workspaces/src/Engines/Exceptions/UserNotFoundException.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace Waystone\Workspaces\Engines\Exceptions;
+
+use RuntimeException;
+
+class UserNotFoundException extends RuntimeException {
+
+}
diff --git a/workspaces/src/Engines/Framework/Context.php b/workspaces/src/Engines/Framework/Context.php
--- a/workspaces/src/Engines/Framework/Context.php
+++ b/workspaces/src/Engines/Framework/Context.php
@@ -19,7 +19,7 @@
use Keruald\Database\DatabaseEngine;
use Smarty\Smarty;
-use User;
+use Waystone\Workspaces\Engines\Users\User;
use Waystone\Workspaces\Engines\Users\UserRepository;
use Waystone\Workspaces\Engines\Workspaces\WorkSpace;
@@ -53,9 +53,9 @@
public Resources $resources;
/**
- * @var User the user currently logged in
+ * @var ?User the user currently logged in
*/
- public User $user;
+ public ?User $user = null;
/**
* @var Session the current session
diff --git a/workspaces/src/Engines/Framework/Session.php b/workspaces/src/Engines/Framework/Session.php
--- a/workspaces/src/Engines/Framework/Session.php
+++ b/workspaces/src/Engines/Framework/Session.php
@@ -22,12 +22,11 @@
namespace Waystone\Workspaces\Engines\Framework;
use Waystone\Workspaces\Engines\Errors\ErrorHandling;
+use Waystone\Workspaces\Engines\Users\User;
use Waystone\Workspaces\Engines\Users\UserRepository;
use Keruald\Database\DatabaseEngine;
-use User;
-
/**
* Session class
*/
@@ -260,8 +259,11 @@
$row = $db->fetchRow($result);
//Gets user instance
- require_once('includes/objects/user.php');
- $user = new User($row['user_id'], $db);
+ $user_id = (int)$row['user_id'];
+ $user = match ($user_id) {
+ ANONYMOUS_USER => User::anonymous(),
+ default => $this->users->get($user_id),
+ };
//Adds session property to this user instance
$user->session = $row;
diff --git a/workspaces/src/includes/objects/user.php b/workspaces/src/Engines/Users/User.php
rename from workspaces/src/includes/objects/user.php
rename to workspaces/src/Engines/Users/User.php
--- a/workspaces/src/includes/objects/user.php
+++ b/workspaces/src/Engines/Users/User.php
@@ -16,11 +16,15 @@
*
*/
+namespace Waystone\Workspaces\Engines\Users;
+
use Waystone\Workspaces\Engines\Errors\ErrorHandling;
use Waystone\Workspaces\Engines\Workspaces\Workspace;
use Keruald\Database\DatabaseEngine;
+use UserGroup;
+
/**
* User class
*/
@@ -44,20 +48,46 @@
private DatabaseEngine $db;
- /*
- * Initializes a new instance
+ ///
+ /// Constructors
+ ///
+
+ public static function fromRow (array $row) : self {
+ $user = new self;
+ $user->load_from_row($row);
+
+ return $user;
+ }
+
+ /**
+ * Create a new user instance with arbitrary user_id
+ *
+ * The created user is not saved in the database.
*
- * @param int $id the primary key
+ * @param int $user_id A unassigned user ID
+ * @return self
*/
- function __construct ($id = null, DatabaseEngine $db = null) {
- $this->id = $id;
- $this->db = $db;
+ public static function create (int $user_id) : self {
+ $user = new self;
- if ($id) {
- $this->load_from_database();
- }
+ $user->id = $user_id;
+ $user->active = true;
+ $user->regdate = time();
+
+ return $user;
+ }
+
+ /**
+ * Creates a new anonymous user instance
+ */
+ public static function anonymous () : User {
+ return User::create(ANONYMOUS_USER);
}
+ ///
+ /// Load data
+ ///
+
/**
* Loads the object User (ie fill the properties) from the $_POST array
*/
@@ -70,25 +100,6 @@
if (array_key_exists('regdate', $_POST)) $this->regdate = $_POST['regdate'];
}
- /**
- * Loads the object User (ie fill the properties) from the database
- */
- function load_from_database () {
- $db = $this->db;
-
- $id = $this->db->escape($this->id);
- $sql = "SELECT * FROM " . TABLE_USERS . " WHERE user_id = '" . $id . "'";
- if ( !($result = $db->query($sql)) ) ErrorHandling::messageAndDie(SQL_ERROR, "Unable to query users", '', __LINE__, __FILE__, $sql);
- if (!$row = $db->fetchRow($result)) {
- $this->lastError = "User unknown: " . $this->id;
- return false;
- }
-
- $this->load_from_row($row);
-
- return true;
- }
-
/**
* Loads the object User (ie fill the properties) from the database row
*/
@@ -101,114 +112,20 @@
$this->regdate = $row['user_regdate'];
}
- /**
- * Saves to database
- */
- function save_to_database () {
- $db = $this->db;
-
- $id = $this->id ? "'" . $db->escape($this->id) . "'" : 'NULL';
- $name = $db->escape($this->name);
- $password = $db->escape($this->password);
- $active = $this->active ? 1 : 0;
- $email = $db->escape($this->email);
- $regdate = $this->regdate ? "'" . $db->escape($this->regdate) . "'" : 'NULL';
-
- //Updates or inserts
- $sql = "REPLACE INTO " . TABLE_USERS . " (`user_id`, `username`, `user_password`, `user_active`, `user_email`, `user_regdate`) VALUES ($id, '$name', '$password', $active, '$email', $regdate)";
- if (!$db->query($sql)) {
- ErrorHandling::messageAndDie(SQL_ERROR, "Unable to save user", '', __LINE__, __FILE__, $sql);
- }
-
- if (!$this->id) {
- //Gets new record id value
- $this->id = $db->nextId();
- }
- }
-
- /**
- * Updates the specified field in the database record
- */
- function save_field ($field) {
- $db = $this->db;
-
- if (!$this->id) {
- ErrorHandling::messageAndDie(GENERAL_ERROR, "You're trying to update a record not yet saved in the database");
- }
- $id = $db->escape($this->id);
- $value = $db->escape($this->$field);
- $sql = "UPDATE " . TABLE_USERS . " SET `$field` = '$value' WHERE user_id = '$id'";
- if (!$db->query($sql)) {
- ErrorHandling::messageAndDie(SQL_ERROR, "Unable to save $field field", '', __LINE__, __FILE__, $sql);
- }
- }
-
//
- // USER MANAGEMENT FUNCTIONS
+ // User properties
//
- /**
- * Generates a unique user id
- */
- function generate_id () {
- $db = $this->db;
-
- do {
- $this->id = mt_rand(2001, 9999);
- $sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE user_id = $this->id";
- if (!$result = $db->query($sql)) {
- ErrorHandling::messageAndDie(SQL_ERROR, "Can't check if a user id is free", '', __LINE__, __FILE__, $sql);
- }
- $row = $db->fetchRow($result);
- } while ($row[0]);
- }
-
/**
* Fills password field with encrypted version
* of the specified clear password
*/
- public function set_password ($newpassword) {
- $this->password = md5($newpassword);
- }
-
- /**
- * Initializes a new User instance ready to have its property filled
- *
- * @return User the new user instance
- */
- public static function create (DatabaseEngine $db) {
- $user = new User(null, $db);
- $user->generate_id();
- $user->active = true;
- $user->regdate = time();
- return $user;
- }
-
- //
- // REMOTE IDENTITY PROVIDERS
- //
-
- /**
- * Sets user's remote identity provider identifiant
- *
- * @param $authType The authentication method type
- * @param $remoteUserId The remote user identifier
- * */
- public function setRemoteIdentity ($authType, $remoteUserId, $properties = null) {
- $db = $this->db;
-
- $authType = $db->escape($authType);
- $remoteUserId = $db->escape($remoteUserId);
- $properties = ($properties === NULL) ? 'NULL' : "'" . $db->escape($properties) . "'";
- $sql = "INSERT INTO " . TABLE_USERS_AUTH . " (auth_type, auth_identity, auth_properties, user_id) "
- . "VALUES ('$authType', '$remoteUserId', $properties, $this->id)";
- if (!$db->query($sql)) {
- ErrorHandling::messageAndDie(SQL_ERROR, "Can't set user remote identity provider information", '', __LINE__, __FILE__, $sql);
- }
+ public function setPassword ($password) {
+ $this->password = md5($password);
}
//
- // INTERACTION WITH OTHER OBJECTS
+ // Interaction with groups and permissions
//
/**
diff --git a/workspaces/src/Engines/Users/UserRepository.php b/workspaces/src/Engines/Users/UserRepository.php
--- a/workspaces/src/Engines/Users/UserRepository.php
+++ b/workspaces/src/Engines/Users/UserRepository.php
@@ -3,6 +3,7 @@
namespace Waystone\Workspaces\Engines\Users;
use Waystone\Workspaces\Engines\Errors\ErrorHandling;
+use Waystone\Workspaces\Engines\Exceptions\UserNotFoundException;
use Waystone\Workspaces\Engines\Framework\Repository;
use Keruald\Database\Exceptions\SqlException;
@@ -10,7 +11,7 @@
use Keruald\OmniTools\DataTypes\Option\Option;
use Keruald\OmniTools\DataTypes\Option\Some;
-use User;
+use RuntimeException;
class UserRepository extends Repository {
@@ -40,8 +41,7 @@
return new None;
}
- $user = new User(null, $this->db);
- $user->load_from_row($row);
+ $user = User::fromRow($row);
$this->table[$user->id] = $user;
return new Some($user);
@@ -118,17 +118,138 @@
* Gets an instance of the class from the table or loads it from database.
*
* @param int $id the user ID
+ *
* @return User the user instance
+ * @throws Exception when the user is not found
*/
public function get (int $id) : User {
if ($this->table->has($id)) {
return $this->table[$id];
}
- $user = new User($id, $this->db);
+ $user = $this->loadFromDatabase($id);
+ if ($user->isNone()) {
+ throw new UserNotFoundException;
+ }
+
+ $user = $user->getValue();
$this->table[$id] = $user;
return $user;
}
+ /**
+ * Loads the object User (ie fill the properties) from the database
+ *
+ * @return Option<User> the user instance, or None if not found
+ */
+ private function loadFromDatabase (int $id) : Option {
+ $db = $this->db;
+
+ $sql = "SELECT * FROM " . TABLE_USERS . " WHERE user_id = '" . $id . "'";
+ if (!$result = $db->query($sql)) {
+ ErrorHandling::messageAndDie(SQL_ERROR, "Unable to query users", '', __LINE__, __FILE__, $sql);
+ }
+
+ $row = $db->fetchRow($result);
+ if (!$row) {
+ return new None;
+ }
+
+ return new Some(User::fromRow($row));
+ }
+
+ ///
+ /// Create object
+ ///
+
+ /**
+ * Initializes a new User instance ready to have its property filled
+ *
+ * @return User the new user instance
+ */
+ public function create () : User {
+ $id = $this->generateId();
+
+ return User::create($id);
+ }
+
+ /**
+ * Generates a unique user id
+ */
+ private function generateId () : int {
+ $db = $this->db;
+
+ do {
+ $id = mt_rand(2001, 9999);
+ $sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE user_id = $this->id";
+
+ try {
+ $result = $db->queryScalar($sql);
+ } catch (SqlException) {
+ ErrorHandling::messageAndDie(SQL_ERROR, "Can't check if a user id is free", '', __LINE__, __FILE__, $sql);
+ }
+ } while ($result);
+
+ return $id;
+ }
+
+ ///
+ /// Save object
+ ///
+
+ /**
+ * Saves to database
+ */
+ function saveToDatabase (User $user) : void {
+ $db = $this->db;
+
+ $id = $user->id ? "'" . $db->escape($user->id) . "'" : 'NULL';
+ $name = $db->escape($user->name);
+ $password = $db->escape($user->password);
+ $active = $user->active ? 1 : 0;
+ $email = $db->escape($user->email);
+ $regdate = $user->regdate ? "'" . $db->escape($user->regdate) . "'" : 'NULL';
+
+ //Updates or inserts
+ $sql = "REPLACE INTO " . TABLE_USERS . " (`user_id`, `username`, `user_password`, `user_active`, `user_email`, `user_regdate`) VALUES ($id, '$name', '$password', $active, '$email', $regdate)";
+ if (!$db->query($sql)) {
+ ErrorHandling::messageAndDie(SQL_ERROR, "Unable to save user", '', __LINE__, __FILE__, $sql);
+ }
+
+ if (!$user->id) {
+ //Gets new record id value
+ $user->id = $db->nextId();
+ }
+ }
+
+ //
+ // User authentication
+ //
+
+ /**
+ * Sets user's remote identity provider identifiant
+ *
+ * @param User $user
+ * @param string $authType The authentication method type
+ * @param string $remoteUserId The remote user identifier
+ * @param array $properties The authentication method properties
+ */
+ public function setRemoteIdentity (User $user, string $authType, string $remoteUserId, array $properties = []) : void {
+ $db = $this->db;
+
+ if ($properties != []) {
+ throw new RuntimeException("The remote identity provider properties have not been implemented yet.");
+ }
+
+ $authType = $db->escape($authType);
+ $remoteUserId = $db->escape($remoteUserId);
+ $properties = "NULL";
+ $sql = "INSERT INTO " . TABLE_USERS_AUTH . " (auth_type, auth_identity, auth_properties, user_id) "
+ . "VALUES ('$authType', '$remoteUserId', $properties, $user->id)";
+ if (!$db->query($sql)) {
+ ErrorHandling::messageAndDie(SQL_ERROR, "Can't set user remote identity provider information", '', __LINE__, __FILE__, $sql);
+ }
+ }
+
}
diff --git a/workspaces/src/Engines/Workspaces/Workspace.php b/workspaces/src/Engines/Workspaces/Workspace.php
--- a/workspaces/src/Engines/Workspaces/Workspace.php
+++ b/workspaces/src/Engines/Workspaces/Workspace.php
@@ -19,10 +19,10 @@
use Waystone\Workspaces\Engines\Errors\ErrorHandling;
use Waystone\Workspaces\Engines\Framework\Context;
+use Waystone\Workspaces\Engines\Users\User;
use Cache;
use Language;
-use User;
use Exception;
use LogicException;
diff --git a/workspaces/src/includes/autoload.php b/workspaces/src/includes/autoload.php
--- a/workspaces/src/includes/autoload.php
+++ b/workspaces/src/includes/autoload.php
@@ -57,7 +57,6 @@
if ($name == 'TextFileMessage') { require $dir . '/includes/i18n/TextFileMessage.php'; return true; }
if ($name == 'Disclaimer') { require $dir . '/includes/objects/Disclaimer.php'; return true; }
- if ($name == 'User') { require $dir . '/includes/objects/user.php'; return true; }
if ($name == 'UserGroup') { require $dir . '/includes/objects/usergroup.php'; return true; }
return false;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 12, 05:50 (17 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3158845
Default Alt Text
D3858.diff (16 KB)
Attached To
Mode
D3858: Split concerns between Users and UserRepository
Attached
Detach File
Event Timeline
Log In to Comment