124 lines
3.9 KiB
PHP
124 lines
3.9 KiB
PHP
<?php
|
|
namespace YTKNS;
|
|
|
|
use Exception;
|
|
|
|
class UserNotFoundException extends Exception {}
|
|
class UserCreationFailedException extends Exception {}
|
|
class UserCreationInvalidNameException extends Exception {}
|
|
class UserCreationInvalidPasswordException extends Exception {}
|
|
class UserCreationInvalidMailException extends Exception {}
|
|
|
|
class User {
|
|
public function __construct() {
|
|
}
|
|
|
|
public function getId(): int {
|
|
return $this->user_id ?? 0;
|
|
}
|
|
private function setId(int $userId): void {
|
|
$this->user_id = $userId;
|
|
}
|
|
|
|
public function getUsername(): string {
|
|
return $this->username ?? '';
|
|
}
|
|
|
|
public static function byId(int $userId): self {
|
|
$getUser = DB::prepare('
|
|
SELECT `user_id`, `username`, `email`, `password`, `user_created`
|
|
FROM `ytkns_users`
|
|
WHERE `user_id` = :user
|
|
');
|
|
$getUser->bindValue('user', $userId);
|
|
$getUser->execute();
|
|
$user = $getUser->fetchObject(self::class);
|
|
|
|
if($user === false)
|
|
throw new UserNotFoundException;
|
|
|
|
return $user;
|
|
}
|
|
|
|
public static function forLogin(string $usernameOrEmail): self {
|
|
$getUser = DB::prepare('
|
|
SELECT `user_id`, `username`, `email`, `password`, `user_created`
|
|
FROM `ytkns_users`
|
|
WHERE LOWER(`username`) = LOWER(:username)
|
|
OR LOWER(`email`) = LOWER(:email)
|
|
');
|
|
$getUser->bindValue('username', $usernameOrEmail);
|
|
$getUser->bindValue('email', $usernameOrEmail);
|
|
$getUser->execute();
|
|
$user = $getUser->fetchObject(self::class);
|
|
|
|
if($user === false)
|
|
throw new UserNotFoundException;
|
|
|
|
return $user;
|
|
}
|
|
|
|
public static function forProfile(string $username): self {
|
|
$getUser = DB::prepare('
|
|
SELECT `user_id`, `username`, `email`, `password`, `user_created`
|
|
FROM `ytkns_users`
|
|
WHERE LOWER(`username`) = LOWER(:username)
|
|
');
|
|
$getUser->bindValue('username', $username);
|
|
$getUser->execute();
|
|
$user = $getUser->fetchObject(self::class);
|
|
|
|
if($user === false)
|
|
throw new UserNotFoundException;
|
|
|
|
return $user;
|
|
}
|
|
|
|
public static function validatePassword(string $password): bool {
|
|
$chars = [];
|
|
$length = mb_strlen($password);
|
|
|
|
for($i = 0; $i < $length; $i++) {
|
|
$current = mb_substr($password, $i, 1);
|
|
|
|
if(!in_array($current, $chars, true))
|
|
$chars[] = $current;
|
|
}
|
|
|
|
return count($chars) >= 6;
|
|
}
|
|
|
|
public static function hashPassword(string $password): string {
|
|
return password_hash($password, PASSWORD_ARGON2ID);
|
|
}
|
|
|
|
public static function create(string $userName, string $password, string $email): self {
|
|
if(!preg_match('#^([a-zA-Z0-9-_]{1,20})$#', $userName))
|
|
throw new UserCreationInvalidNameException;
|
|
if(!filter_var($email, FILTER_VALIDATE_EMAIL))
|
|
throw new UserCreationInvalidMailException;
|
|
if(!self::validatePassword($password))
|
|
throw new UserCreationInvalidPasswordException;
|
|
|
|
$password = self::hashPassword($password);
|
|
|
|
$createUser = DB::prepare('
|
|
INSERT INTO `ytkns_users` (
|
|
`username`, `email`, `password`
|
|
) VALUES (
|
|
:username, :email, :password
|
|
)
|
|
');
|
|
$createUser->bindValue('username', $userName);
|
|
$createUser->bindValue('email', $email);
|
|
$createUser->bindValue('password', $password);
|
|
$userId = $createUser->execute() ? (int)DB::lastInsertId() : 0;
|
|
|
|
try {
|
|
return self::byId($userId);
|
|
} catch(UserNotFoundException $ex) {
|
|
throw new UserCreationFailedException;
|
|
}
|
|
}
|
|
}
|