slovocast/app/src/Domain/Repository/User/UserRepository.php

135 lines
3.9 KiB
PHP

<?php
namespace Slovocast\Domain\Repository\User;
use DateTime;
use DateTimeImmutable;
use Slovocast\Domain\Entity\User;
use Slovocast\Exception\EntityNotFoundException;
use Slovocast\Infrastructure\Api\User\UserAuthorizationInterface;
use Slovocast\Infrastructure\Api\Database\DatabaseHandlerInterface;
class UserRepository implements UserRepositoryInterface
{
const CREATE_QUERY = "INSERT INTO users (email, password, name)
VALUES (:email, :password, :name)";
const UPDATE_QUERY = "UPDATE users
SET email = :email,
name = :name,
password = :password
WHERE id = :id";
public function __construct(
private DatabaseHandlerInterface $db,
private UserAuthorizationInterface $userAuth
) {}
/**
* @param array $results The Query Results asking for all properties from
* the database tables.
* @return User
*/
protected function userFromQueryResults(array $results): User
{
return User::fromArray([
'id' => $results['id'],
'email' => $results['email'],
'password' => $results['password'],
'name' => $results['name'],
'createdAt' => $results['created_at'],
'updatedAt' => $results['updated_at']
]);
}
/**
* Get a single instance of the User Entity.
*/
public function get(int $id): User
{
$query = "SELECT * FROM users WHERE id = :id LIMIT 1";
$statement = $this->db->getConnection()->prepare($query);
$statement->execute([ ':id' => $id ]);
$results = $statement->fetch(\PDO::FETCH_ASSOC);
return $this->userFromQueryResults($results);
}
/**
* Get a single instance of the User Entity by their Email address.
*
* @param string $email
* @return User
*/
public function getFromEmail(string $email): User
{
$query = "SELECT * FROM users WHERE email = :email LIMIT 1";
$results = $this->db->query($query, [ ':email' => $email ]);
if (!is_array($results) || count($results)) {
throw new EntityNotFoundException("Unable to find User");
}
return $this->userFromQueryResults($results);
}
public function create(User $user): bool
{
$results = $this->db->execute(self::CREATE_QUERY, [
':email' => $user->getEmail(),
':password' => $this->userAuth->hash($user->getPassword()),
':name' => $user->getName(),
]);
if ($results) {
$insertId = $this->db->getConnection()->lastInsertId();
$user->setId($insertId);
$user->setCreatedAt(new DateTimeImmutable());
$user->setUpdatedAt(new DateTime());
}
return $results;
}
public function update(User $user): bool
{
$query = "UPDATE users
SET email = :email,
name = :name,
password = :password
WHERE id = :id";
$results = $this->db->execute(self::UPDATE_QUERY, [
':email' => $user->getEmail(),
':name' => $user->getName(),
':password' => $this->userAuth->hash($user->getPassword()),
':id' => $user->getId()
]);
if ($results == true) {
$user->setUpdatedAt(new DateTime());
}
return $results;
}
/**
* @TODO Figure out soft/hard delete logic for users
*/
public function delete(User $user): bool
{
return false;
}
public function verifyPassword(string $email, string $password): bool
{
try {
$user = $this->getFromEmail($email);
return $this->authUser->verify($password, $user->getPassword());
} catch (\Exception $e) {
return false;
}
}
}