username = $username; $this->password = $password; } public function getUsername(): string { return $this->username; } public function getPassword(): string { return $this->password; } } class User { private int $id; private ?array $spaces; private string $username; private bool $isActive; private ?string $profilePicture; private ?string $bio; private ?string $website; private int $role; public function __construct(int $id = -1, ?array $spaces, string $username, ?string $profilePicture = null, ?string $bio = null, ?string $website = null, int $role = 3, ?string $passwordHash) { // Basic XSS prevention on construction (can be enhanced) $username = htmlspecialchars($username, ENT_QUOTES, 'UTF-8'); $bio = htmlspecialchars($bio ?? '', ENT_QUOTES, 'UTF-8'); $website = htmlspecialchars($website ?? '', ENT_QUOTES, 'UTF-8'); $profilePicture = htmlspecialchars($profilePicture ?? 'default-profile.png', ENT_QUOTES, 'UTF-8'); // Basic SQL injection prevention (should primarily rely on prepared statements) /* if (preg_match('/[\'";\-\_]/', $username) || preg_match('/[\'";\-\_]/', $bio) || preg_match('/[\'";\-\_]/', $website) || preg_match('/[\'";\-\_]/', $profilePicture)) { */ /* throw new InvalidArgumentException('Invalid characters in user data.'); */ /* } */ $this->username = $username; $this->profilePicture = $profilePicture; $this->bio = $bio; $this->website = $website; $this->isActive = false; $this->role = $role; $this->spaces = null; if ($id < 0) { $this->id = $id * -1; $stmt = 'INSERT INTO user (id, username, passwordHash, profilePicture, bio, website) VALUES (?, ?, ?, ?, ?, ?)'; exec_stmt($stmt, 'isssss', $this->id, $this->username, $passwordHash, $this->profilePicture, $this->bio, $this->website); Space::addUserToSpace($this->id, 2025); new Space($id, $this->username, $this->username . "'s private Space.", 5, [$this], [], null, true); } else $this->id = $id; } public static function exists($identifier): bool { if (is_int($identifier)) { $stmt = 'SELECT count(id) FROM user WHERE id = ?'; $result = exec_stmt($stmt, 'i', $identifier)->fetch_assoc(); if ($result['count(id)'] == 1) return true; else if ($result['count(id)'] > 1) return true; else return false; } else if (is_string($identifier)) { $stmt = 'SELECT count(id) FROM user WHERE username = ?'; $result = exec_stmt($stmt, 's', $identifier)->fetch_assoc(); if ($result['count(id)'] == 1) return true; else if ($result['count(id)'] > 1) return true; else return false; } return true; } public static function retrieveFromDB(int $userId): ?User { $stmt = 'SELECT id, username, profilePicture, bio, website, role FROM user WHERE id = ?'; $user = exec_stmt($stmt, 'i', $userId)->fetch_assoc(); if ($user) return new User($user['id'], null, $user['username'], $user['profilePicture'], $user['bio'], $user['website'], $user['role'], null); else return null; } public static function getSignupHTML() { $experimentalHTML = '