aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/Models/User.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/Models/User.php')
-rw-r--r--src/app/Models/User.php118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/app/Models/User.php b/src/app/Models/User.php
new file mode 100644
index 0000000..d4c5c88
--- /dev/null
+++ b/src/app/Models/User.php
@@ -0,0 +1,118 @@
+<?php
+
+declare(strict_types=1);
+// User model: database operations for the users table.
+
+namespace App\Models;
+
+use App\Database;
+
+class User
+{
+ private \PDO $pdo;
+
+ public function __construct()
+ {
+ $this->pdo = Database::getInstance()->getPdo();
+ }
+
+ public function create(string $username, string $email, string $password): int
+ {
+ $hash = password_hash($password, PASSWORD_DEFAULT);
+ $token = bin2hex(random_bytes(32));
+
+ $stmt = $this->pdo->prepare(
+ 'INSERT INTO users (username, email, password_hash, verification_token)
+ VALUES (:username, :email, :hash, :token)'
+ );
+ $stmt->execute([
+ 'username' => $username,
+ 'email' => $email,
+ 'hash' => $hash,
+ 'token' => $token,
+ ]);
+
+ return (int) $this->pdo->lastInsertId();
+ }
+
+ public function findByUsername(string $username): ?array
+ {
+ $stmt = $this->pdo->prepare('SELECT * FROM users WHERE username = :username');
+ $stmt->execute(['username' => $username]);
+ $row = $stmt->fetch();
+ return $row ?: null;
+ }
+
+ public function findByEmail(string $email): ?array
+ {
+ $stmt = $this->pdo->prepare('SELECT * FROM users WHERE email = :email');
+ $stmt->execute(['email' => $email]);
+ $row = $stmt->fetch();
+ return $row ?: null;
+ }
+
+ public function findById(int $id): ?array
+ {
+ $stmt = $this->pdo->prepare('SELECT * FROM users WHERE id = :id');
+ $stmt->execute(['id' => $id]);
+ $row = $stmt->fetch();
+ return $row ?: null;
+ }
+
+ public function findByVerificationToken(string $token): ?array
+ {
+ $stmt = $this->pdo->prepare('SELECT * FROM users WHERE verification_token = :token');
+ $stmt->execute(['token' => $token]);
+ $row = $stmt->fetch();
+ return $row ?: null;
+ }
+
+ public function verify(int $id): void
+ {
+ $stmt = $this->pdo->prepare(
+ 'UPDATE users SET is_verified = TRUE, verification_token = NULL WHERE id = :id'
+ );
+ $stmt->execute(['id' => $id]);
+ }
+
+ public function setResetToken(int $id): string
+ {
+ $token = bin2hex(random_bytes(32));
+ // Token expires in 1 hour
+ $expires = date('Y-m-d H:i:s', time() + 3600);
+
+ $stmt = $this->pdo->prepare(
+ 'UPDATE users SET reset_token = :token, reset_token_expires = :expires WHERE id = :id'
+ );
+ $stmt->execute(['token' => $token, 'expires' => $expires, 'id' => $id]);
+
+ return $token;
+ }
+
+ public function findByResetToken(string $token): ?array
+ {
+ $stmt = $this->pdo->prepare(
+ 'SELECT * FROM users WHERE reset_token = :token AND reset_token_expires > NOW()'
+ );
+ $stmt->execute(['token' => $token]);
+ $row = $stmt->fetch();
+ return $row ?: null;
+ }
+
+ public function updatePassword(int $id, string $password): void
+ {
+ $hash = password_hash($password, PASSWORD_DEFAULT);
+ $stmt = $this->pdo->prepare(
+ 'UPDATE users SET password_hash = :hash, reset_token = NULL, reset_token_expires = NULL WHERE id = :id'
+ );
+ $stmt->execute(['hash' => $hash, 'id' => $id]);
+ }
+
+ public function getVerificationToken(int $id): ?string
+ {
+ $stmt = $this->pdo->prepare('SELECT verification_token FROM users WHERE id = :id');
+ $stmt->execute(['id' => $id]);
+ $row = $stmt->fetch();
+ return $row ? $row['verification_token'] : null;
+ }
+}