Unification of indents
This commit is contained in:
parent
37f220b561
commit
6b2abc1f89
|
@ -9,7 +9,7 @@ $session = new Session();
|
||||||
$router = new Router($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']);
|
$router = new Router($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']);
|
||||||
|
|
||||||
if (isset($_SERVER['HTTP_CONTENT_TYPE'])) {
|
if (isset($_SERVER['HTTP_CONTENT_TYPE'])) {
|
||||||
$router->setRequestBody($_SERVER['HTTP_CONTENT_TYPE'], file_get_contents('php://input'));
|
$router->setRequestBody($_SERVER['HTTP_CONTENT_TYPE'], file_get_contents('php://input'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$router->route();
|
$router->route();
|
||||||
|
|
|
@ -4,10 +4,10 @@ declare(strict_types=1);
|
||||||
|
|
||||||
class ApiBadRequestResponse extends ApiResponse
|
class ApiBadRequestResponse extends ApiResponse
|
||||||
{
|
{
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->setParameter('success', false);
|
$this->setParameter('success', false);
|
||||||
$this->setStatus(self::STATUS_BAD_REQUEST);
|
$this->setStatus(self::STATUS_BAD_REQUEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,24 +4,24 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class ApiJsonResponse extends ApiResponse
|
final class ApiJsonResponse extends ApiResponse
|
||||||
{
|
{
|
||||||
protected string $mimeType = MimeType::JSON;
|
protected string $mimeType = MimeType::JSON;
|
||||||
|
|
||||||
public function __construct(int $status = ServerStatus::OK)
|
public function __construct(int $status = ServerStatus::OK)
|
||||||
{
|
{
|
||||||
parent::__construct($status);
|
parent::__construct($status);
|
||||||
|
|
||||||
$this->setParameter('success', true);
|
$this->setParameter('success', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setResult(JsonSerializable $result): void
|
public function setResult(JsonSerializable $result): void
|
||||||
{
|
{
|
||||||
$this->setParameter('result', $result->jsonSerialize());
|
$this->setParameter('result', $result->jsonSerialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function respond(): void
|
public function respond(): void
|
||||||
{
|
{
|
||||||
parent::respond();
|
parent::respond();
|
||||||
|
|
||||||
echo json_encode($this->parameters);
|
echo json_encode($this->parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,74 +4,74 @@ declare(strict_types=1);
|
||||||
|
|
||||||
class ApiResponse implements JsonSerializable
|
class ApiResponse implements JsonSerializable
|
||||||
{
|
{
|
||||||
public const STATUS_OK = 200;
|
public const STATUS_OK = 200;
|
||||||
public const STATUS_FORBIDDEN = 403;
|
public const STATUS_FORBIDDEN = 403;
|
||||||
public const STATUS_UNAUTHORIZED = 401;
|
public const STATUS_UNAUTHORIZED = 401;
|
||||||
public const STATUS_BAD_REQUEST = 400;
|
public const STATUS_BAD_REQUEST = 400;
|
||||||
public const STATUS_NOT_FOUND = 404;
|
public const STATUS_NOT_FOUND = 404;
|
||||||
public const STATUS_SERVER_ERROR = 500;
|
public const STATUS_SERVER_ERROR = 500;
|
||||||
|
|
||||||
public const MIME_TYPE_PLAINTEXT = 'text/plain';
|
public const MIME_TYPE_PLAINTEXT = 'text/plain';
|
||||||
public const MIME_TYPE_JSON = 'application/json';
|
public const MIME_TYPE_JSON = 'application/json';
|
||||||
public const MIME_TYPE_SVG = 'image/svg+xml';
|
public const MIME_TYPE_SVG = 'image/svg+xml';
|
||||||
|
|
||||||
protected int $status = ServerStatus::OK;
|
protected int $status = ServerStatus::OK;
|
||||||
protected string $mimeType = MimeType::PLAINTEXT;
|
protected string $mimeType = MimeType::PLAINTEXT;
|
||||||
protected array $parameters = [];
|
protected array $parameters = [];
|
||||||
|
|
||||||
public function __construct(int $status = ServerStatus::OK)
|
public function __construct(int $status = ServerStatus::OK)
|
||||||
{
|
{
|
||||||
$this->setStatus($status);
|
$this->setStatus($status);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setParameter(string $key, $value): void
|
public function setParameter(string $key, $value): void
|
||||||
{
|
{
|
||||||
$this->parameters[$key] = $value;
|
$this->parameters[$key] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setStatus(int $status): void
|
public function setStatus(int $status): void
|
||||||
{
|
{
|
||||||
$this->status = $status;
|
$this->status = $status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setMessage(string $message): void
|
public function setMessage(string $message): void
|
||||||
{
|
{
|
||||||
$this->setParameter('message', $message);
|
$this->setParameter('message', $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setMimeType(string $mimeType): void
|
public function setMimeType(string $mimeType): void
|
||||||
{
|
{
|
||||||
$this->mimeType = $mimeType;
|
$this->mimeType = $mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setBody(JsonSerializable $data): void
|
public function setBody(JsonSerializable $data): void
|
||||||
{
|
{
|
||||||
$this->parameters = $data->jsonSerialize();
|
$this->parameters = $data->jsonSerialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetMessageIdNotFound(string $instanceName): void
|
public function SetMessageIdNotFound(string $instanceName): void
|
||||||
{
|
{
|
||||||
$this->setMessage(sprintf('Die für %s angeforderte ID existiert nicht!', $instanceName));
|
$this->setMessage(sprintf('Die für %s angeforderte ID existiert nicht!', $instanceName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStatus(): int
|
public function getStatus(): int
|
||||||
{
|
{
|
||||||
return $this->status;
|
return $this->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getMimeType(): string
|
public function getMimeType(): string
|
||||||
{
|
{
|
||||||
return $this->mimeType;
|
return $this->mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
return $this->parameters;
|
return $this->parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function respond(): void
|
public function respond(): void
|
||||||
{
|
{
|
||||||
http_response_code($this->status);
|
http_response_code($this->status);
|
||||||
header('Content-Type: ' . $this->mimeType);
|
header('Content-Type: ' . $this->mimeType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@ declare(strict_types=1);
|
||||||
|
|
||||||
class ApiSuccessResponse extends ApiResponse
|
class ApiSuccessResponse extends ApiResponse
|
||||||
{
|
{
|
||||||
public function __construct(bool $success = true)
|
public function __construct(bool $success = true)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->setParameter('success', $success);
|
$this->setParameter('success', $success);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,23 +4,23 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class ApiSvgResponse extends ApiResponse
|
final class ApiSvgResponse extends ApiResponse
|
||||||
{
|
{
|
||||||
private string $content;
|
private string $content;
|
||||||
protected string $mimeType = MimeType::SVG;
|
protected string $mimeType = MimeType::SVG;
|
||||||
|
|
||||||
public function __construct(int $status = ServerStatus::OK)
|
public function __construct(int $status = ServerStatus::OK)
|
||||||
{
|
{
|
||||||
parent::__construct($status);
|
parent::__construct($status);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setContent(string $content): void
|
public function setContent(string $content): void
|
||||||
{
|
{
|
||||||
$this->content = $content;
|
$this->content = $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function respond(): void
|
public function respond(): void
|
||||||
{
|
{
|
||||||
parent::respond();
|
parent::respond();
|
||||||
header('Content-Length: ' . strlen($this->content));
|
header('Content-Length: ' . strlen($this->content));
|
||||||
echo $this->content;
|
echo $this->content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@ declare(strict_types=1);
|
||||||
|
|
||||||
class ApiUnauthorizedResponse extends ApiResponse
|
class ApiUnauthorizedResponse extends ApiResponse
|
||||||
{
|
{
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->setStatus(self::STATUS_UNAUTHORIZED);
|
$this->setStatus(self::STATUS_UNAUTHORIZED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,37 +4,37 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class FingerprintGetController extends AbstractController
|
final class FingerprintGetController extends AbstractController
|
||||||
{
|
{
|
||||||
protected string $route = '/api/v1/fingerprint/{fingerprintId}';
|
protected string $route = '/api/v1/fingerprint/{fingerprintId}';
|
||||||
|
|
||||||
private int $fingerprintId;
|
private int $fingerprintId;
|
||||||
|
|
||||||
public function __construct(string $url)
|
public function __construct(string $url)
|
||||||
{
|
{
|
||||||
parent::__construct($url);
|
parent::__construct($url);
|
||||||
|
|
||||||
$this->fingerprintId = (int)$this->getUrlParamInt('fingerprintId');
|
$this->fingerprintId = (int)$this->getUrlParamInt('fingerprintId');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (!$this->isUserLoggedIn()) {
|
if (!$this->isUserLoggedIn()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fingerprint = new Fingerprint($this->fingerprintId);
|
$fingerprint = new Fingerprint($this->fingerprintId);
|
||||||
|
|
||||||
if (!$this->hasUserPermission($fingerprint->getUserId())) {
|
if (!$this->hasUserPermission($fingerprint->getUserId())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response = new ApiJsonResponse();
|
$this->response = new ApiJsonResponse();
|
||||||
$this->response->setResult($fingerprint);
|
$this->response->setResult($fingerprint);
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
$this->response = new ApiJsonResponse(ApiResponse::STATUS_NOT_FOUND);
|
$this->response = new ApiJsonResponse(ApiResponse::STATUS_NOT_FOUND);
|
||||||
$this->response->setParameter('success', false);
|
$this->response->setParameter('success', false);
|
||||||
$this->response->setMessage(sprintf('No fingerprint with id %d found!', $this->fingerprintId));
|
$this->response->setMessage(sprintf('No fingerprint with id %d found!', $this->fingerprintId));
|
||||||
$this->response->setMimeType(ApiResponse::MIME_TYPE_JSON);
|
$this->response->setMimeType(ApiResponse::MIME_TYPE_JSON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,68 +4,68 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class FingerprintPostController extends AbstractController
|
final class FingerprintPostController extends AbstractController
|
||||||
{
|
{
|
||||||
protected string $route = '/api/v1/fingerprint';
|
protected string $route = '/api/v1/fingerprint';
|
||||||
protected array $mandatoryAttributes = [
|
protected array $mandatoryAttributes = [
|
||||||
'fingerprint',
|
'fingerprint',
|
||||||
'userId',
|
'userId',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
if (!$this->isUserLoggedIn()) {
|
if (!$this->isUserLoggedIn()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::handle();
|
parent::handle();
|
||||||
|
|
||||||
$db = new MySqlDatabase();
|
$db = new MySqlDatabase();
|
||||||
$json = json_decode($this->requestBody);
|
$json = json_decode($this->requestBody);
|
||||||
$fingerprint = new Fingerprint(null, $db);
|
$fingerprint = new Fingerprint(null, $db);
|
||||||
$this->response = new ApiJsonResponse();
|
$this->response = new ApiJsonResponse();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!$this->hasUserPermission((int)$json->userId)) {
|
if (!$this->hasUserPermission((int)$json->userId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fingerprint->setFingerprint((string)$json->fingerprint);
|
$fingerprint->setFingerprint((string)$json->fingerprint);
|
||||||
$fingerprint->setUserId((int)$json->userId);
|
$fingerprint->setUserId((int)$json->userId);
|
||||||
|
|
||||||
if (!$db->hasTransaction()) {
|
if (!$db->hasTransaction()) {
|
||||||
$db->startTransaction();
|
$db->startTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
$fingerprint->Save();
|
$fingerprint->Save();
|
||||||
|
|
||||||
$qrCode = new QrCode($fingerprint->getFingerprintId(), $fingerprint->getFingerprint());
|
$qrCode = new QrCode($fingerprint->getFingerprintId(), $fingerprint->getFingerprint());
|
||||||
$qrCode->generate();
|
$qrCode->generate();
|
||||||
$qrCode->save();
|
$qrCode->save();
|
||||||
|
|
||||||
$db->commit();
|
$db->commit();
|
||||||
|
|
||||||
$this->response->setParameter('fingerprintId', $fingerprint->getFingerprintId());
|
$this->response->setParameter('fingerprintId', $fingerprint->getFingerprintId());
|
||||||
} catch (QrCodeException $e) {
|
} catch (QrCodeException $e) {
|
||||||
$this->response->setStatus(ServerStatus::INTERNAL_ERROR);
|
$this->response->setStatus(ServerStatus::INTERNAL_ERROR);
|
||||||
$this->response->setParameter('success', false);
|
$this->response->setParameter('success', false);
|
||||||
$this->response->setMessage('An error occured during QR code creation!');
|
$this->response->setMessage('An error occured during QR code creation!');
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
$this->catchDatabaseException($e->getMessage(), $json);
|
$this->catchDatabaseException($e->getMessage(), $json);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function catchDatabaseException(string $message, object $json): void
|
private function catchDatabaseException(string $message, object $json): void
|
||||||
{
|
{
|
||||||
$this->response->setParameter('success', false);
|
$this->response->setParameter('success', false);
|
||||||
|
|
||||||
if (substr_count($message, 'foreign key constraint fails') > 0) {
|
if (substr_count($message, 'foreign key constraint fails') > 0) {
|
||||||
$this->response->setMessage(sprintf('User with id %d doesn\'t exist!', $json->userId));
|
$this->response->setMessage(sprintf('User with id %d doesn\'t exist!', $json->userId));
|
||||||
$this->response->setStatus(ServerStatus::NOT_FOUND);
|
$this->response->setStatus(ServerStatus::NOT_FOUND);
|
||||||
} elseif (substr_count($message, 'Duplicate entry') > 0) {
|
} elseif (substr_count($message, 'Duplicate entry') > 0) {
|
||||||
$this->response->setMessage(sprintf('Fingerprint %s already exists!', $json->fingerprint));
|
$this->response->setMessage(sprintf('Fingerprint %s already exists!', $json->fingerprint));
|
||||||
$this->response->setStatus(ServerStatus::BAD_REQUEST);
|
$this->response->setStatus(ServerStatus::BAD_REQUEST);
|
||||||
} else {
|
} else {
|
||||||
$this->response->setMessage($message);
|
$this->response->setMessage($message);
|
||||||
$this->response->setStatus(ServerStatus::INTERNAL_ERROR);
|
$this->response->setStatus(ServerStatus::INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,30 +4,30 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class QrCodeGetController extends AbstractController
|
final class QrCodeGetController extends AbstractController
|
||||||
{
|
{
|
||||||
protected string $route = '/api/v1/fingerprint/{fingerprintId}/qr';
|
protected string $route = '/api/v1/fingerprint/{fingerprintId}/qr';
|
||||||
|
|
||||||
private int $fingerprintId;
|
private int $fingerprintId;
|
||||||
|
|
||||||
public function __construct(string $url)
|
public function __construct(string $url)
|
||||||
{
|
{
|
||||||
parent::__construct($url);
|
parent::__construct($url);
|
||||||
|
|
||||||
$this->fingerprintId = (int)$this->getUrlParamInt('fingerprintId');
|
$this->fingerprintId = (int)$this->getUrlParamInt('fingerprintId');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
$filename = Setting::PATH_QR_CODES . (string)$this->fingerprintId . '.svg';
|
$filename = Setting::PATH_QR_CODES . (string)$this->fingerprintId . '.svg';
|
||||||
|
|
||||||
if (!is_file($filename)) {
|
if (!is_file($filename)) {
|
||||||
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
|
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
|
||||||
$this->response->setParameter('success', false);
|
$this->response->setParameter('success', false);
|
||||||
$this->response->setMessage(sprintf('No QR code for fingerprint id %d found!', $this->fingerprintId));
|
$this->response->setMessage(sprintf('No QR code for fingerprint id %d found!', $this->fingerprintId));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->response = new ApiSvgResponse();
|
$this->response = new ApiSvgResponse();
|
||||||
|
|
||||||
$file = @fopen($filename, 'r');
|
$file = @fopen($filename, 'r');
|
||||||
|
@ -38,5 +38,5 @@ final class QrCodeGetController extends AbstractController
|
||||||
$this->response->setParameter('success', false);
|
$this->response->setParameter('success', false);
|
||||||
$this->response->setMessage($e->getMessage());
|
$this->response->setMessage($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,19 +4,19 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class UserGetController extends AbstractController
|
final class UserGetController extends AbstractController
|
||||||
{
|
{
|
||||||
protected string $route = '/api/v1/user/{userId}';
|
protected string $route = '/api/v1/user/{userId}';
|
||||||
|
|
||||||
private int $userId;
|
private int $userId;
|
||||||
|
|
||||||
public function __construct(string $url)
|
public function __construct(string $url)
|
||||||
{
|
{
|
||||||
parent::__construct($url);
|
parent::__construct($url);
|
||||||
|
|
||||||
$this->userId = (int)$this->getUrlParamInt('userId');
|
$this->userId = (int)$this->getUrlParamInt('userId');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
$this->response = new ApiJsonResponse();
|
$this->response = new ApiJsonResponse();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -27,5 +27,5 @@ final class UserGetController extends AbstractController
|
||||||
$this->response->setStatus($e->getCode() !== 0 ? $e->getCode() : ServerStatus::INTERNAL_ERROR);
|
$this->response->setStatus($e->getCode() !== 0 ? $e->getCode() : ServerStatus::INTERNAL_ERROR);
|
||||||
$this->response->setMessage($e->getMessage());
|
$this->response->setMessage($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,51 +4,51 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class UserPostController extends AbstractController
|
final class UserPostController extends AbstractController
|
||||||
{
|
{
|
||||||
protected string $route = '/api/v1/user';
|
protected string $route = '/api/v1/user';
|
||||||
protected array $mandatoryAttributes = [
|
protected array $mandatoryAttributes = [
|
||||||
'username',
|
'username',
|
||||||
'password',
|
'password',
|
||||||
'email',
|
'email',
|
||||||
'jabberAddress',
|
'jabberAddress',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
parent::handle();
|
parent::handle();
|
||||||
|
|
||||||
if ($this->response->getStatus() !== ServerStatus::OK) {
|
if ($this->response->getStatus() !== ServerStatus::OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$json = json_decode($this->requestBody);
|
$json = json_decode($this->requestBody);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$user = new User();
|
$user = new User();
|
||||||
|
|
||||||
$user->setUsername($json->username);
|
$user->setUsername($json->username);
|
||||||
$user->setPassword(Password::GetHash($json->password));
|
$user->setPassword(Password::GetHash($json->password));
|
||||||
$user->setEmail($json->email);
|
$user->setEmail($json->email);
|
||||||
$user->setJabberAddress($json->jabberAddress);
|
$user->setJabberAddress($json->jabberAddress);
|
||||||
$user->Save();
|
$user->Save();
|
||||||
|
|
||||||
$this->response = new ApiJsonResponse();
|
$this->response = new ApiJsonResponse();
|
||||||
$this->response->setParameter('userId', $user->getUserId());
|
$this->response->setParameter('userId', $user->getUserId());
|
||||||
} catch (DatabaseException $e) {
|
} catch (DatabaseException $e) {
|
||||||
$this->response = new ApiJsonResponse();
|
$this->response = new ApiJsonResponse();
|
||||||
$this->response->setParameter('success', false);
|
$this->response->setParameter('success', false);
|
||||||
$this->response->setMessage($e->getMessage());
|
$this->response->setMessage($e->getMessage());
|
||||||
|
|
||||||
switch ($e->getCode()) {
|
switch ($e->getCode()) {
|
||||||
case DatabaseException::CONNECTION_FAILED:
|
case DatabaseException::CONNECTION_FAILED:
|
||||||
$this->response->setStatus(ServerStatus::INTERNAL_ERROR);
|
$this->response->setStatus(ServerStatus::INTERNAL_ERROR);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->response->setStatus(ServerStatus::INTERNAL_ERROR);
|
$this->response->setStatus(ServerStatus::INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
|
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
|
||||||
$this->response->setParameter('success', false);
|
$this->response->setParameter('success', false);
|
||||||
$this->response->setMessage($e->getMessage());
|
$this->response->setMessage($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,25 +4,25 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class UserSessionDeleteController extends AbstractController
|
final class UserSessionDeleteController extends AbstractController
|
||||||
{
|
{
|
||||||
protected string $route = '/api/v1/user/session';
|
protected string $route = '/api/v1/user/session';
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
parent::handle();
|
parent::handle();
|
||||||
|
|
||||||
$session = new Session();
|
$session = new Session();
|
||||||
|
|
||||||
if (!$session->IsLoggedIn()) {
|
if (!$session->IsLoggedIn()) {
|
||||||
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
|
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
|
||||||
$this->response->setParameter('success', false);
|
$this->response->setParameter('success', false);
|
||||||
$this->response->setMessage('No session to delete!');
|
$this->response->setMessage('No session to delete!');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$session->Destroy();
|
$session->Destroy();
|
||||||
|
|
||||||
$this->response = new ApiJsonResponse();
|
$this->response = new ApiJsonResponse();
|
||||||
$this->response->setParameter('success', true);
|
$this->response->setParameter('success', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,41 +4,41 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class UserSessionPostController extends AbstractController
|
final class UserSessionPostController extends AbstractController
|
||||||
{
|
{
|
||||||
protected string $route = '/api/v1/user/session';
|
protected string $route = '/api/v1/user/session';
|
||||||
protected array $mandatoryAttributes = [
|
protected array $mandatoryAttributes = [
|
||||||
'username',
|
'username',
|
||||||
'password',
|
'password',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
parent::handle();
|
parent::handle();
|
||||||
|
|
||||||
if ($this->response->getStatus() !== ServerStatus::OK) {
|
if ($this->response->getStatus() !== ServerStatus::OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$json = json_decode($this->requestBody);
|
$json = json_decode($this->requestBody);
|
||||||
|
|
||||||
$session = new Session();
|
$session = new Session();
|
||||||
|
|
||||||
if ($session->IsLoggedIn()) {
|
if ($session->IsLoggedIn()) {
|
||||||
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
|
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
|
||||||
$this->response->setParameter('success', false);
|
$this->response->setParameter('success', false);
|
||||||
$this->response->setMessage('You are already logged in!');
|
$this->response->setMessage('You are already logged in!');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$session->Login($json->username, $json->password)) {
|
if (!$session->Login($json->username, $json->password)) {
|
||||||
$this->response = new ApiJsonResponse(ServerStatus::UNAUTHORIZED);
|
$this->response = new ApiJsonResponse(ServerStatus::UNAUTHORIZED);
|
||||||
$this->response->setParameter('success', false);
|
$this->response->setParameter('success', false);
|
||||||
$this->response->setMessage('Login failed!');
|
$this->response->setMessage('Login failed!');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response = new ApiJsonResponse();
|
$this->response = new ApiJsonResponse();
|
||||||
$this->response->setParameter('userId', $session->getUserId());
|
$this->response->setParameter('userId', $session->getUserId());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,61 +4,61 @@ declare(strict_types=1);
|
||||||
|
|
||||||
abstract class AbstractController
|
abstract class AbstractController
|
||||||
{
|
{
|
||||||
protected string $route;
|
protected string $route;
|
||||||
protected ApiResponse $response;
|
protected ApiResponse $response;
|
||||||
|
|
||||||
protected Session $session;
|
protected Session $session;
|
||||||
protected string $requestUrl;
|
protected string $requestUrl;
|
||||||
protected ?string $requestBody = null;
|
protected ?string $requestBody = null;
|
||||||
protected ?string $contentType = null;
|
protected ?string $contentType = null;
|
||||||
protected array $mandatoryAttributes = [];
|
protected array $mandatoryAttributes = [];
|
||||||
|
|
||||||
public function __construct(string $url)
|
public function __construct(string $url)
|
||||||
{
|
{
|
||||||
$this->requestUrl = $url;
|
$this->requestUrl = $url;
|
||||||
$this->response = new ApiResponse();
|
$this->response = new ApiResponse();
|
||||||
$this->session = new Session();
|
$this->session = new Session();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setRequestBody(string $contentType, string $content): void
|
public function setRequestBody(string $contentType, string $content): void
|
||||||
{
|
{
|
||||||
$this->requestBody = $content;
|
$this->requestBody = $content;
|
||||||
$this->contentType = $contentType;
|
$this->contentType = $contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getResponse(): ApiResponse
|
public function getResponse(): ApiResponse
|
||||||
{
|
{
|
||||||
return $this->response;
|
return $this->response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
if (!$this->validateJsonBody()) {
|
if (!$this->validateJsonBody()) {
|
||||||
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
|
$this->response = new ApiJsonResponse(ServerStatus::BAD_REQUEST);
|
||||||
$this->response->setParameter('success', false);
|
$this->response->setParameter('success', false);
|
||||||
$this->response->setMessage('The request body has not the required json attributes!');
|
$this->response->setMessage('The request body has not the required json attributes!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getUrlParam(string $name): ?string
|
protected function getUrlParam(string $name): ?string
|
||||||
{
|
{
|
||||||
foreach (explode('/', $this->route) as $index => $fragment) {
|
foreach (explode('/', $this->route) as $index => $fragment) {
|
||||||
if ($fragment === '{' . $name . '}') {
|
if ($fragment === '{' . $name . '}') {
|
||||||
return explode('/', $this->requestUrl)[$index];
|
return explode('/', $this->requestUrl)[$index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getUrlParamInt(string $name): ?int
|
protected function getUrlParamInt(string $name): ?int
|
||||||
{
|
{
|
||||||
$param = $this->getUrlParam($name);
|
$param = $this->getUrlParam($name);
|
||||||
|
|
||||||
return $param !== null ? (int)$param : null;
|
return $param !== null ? (int)$param : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isUserLoggedIn(): bool
|
public function isUserLoggedIn(): bool
|
||||||
{
|
{
|
||||||
if (!$this->session->IsLoggedIn()) {
|
if (!$this->session->IsLoggedIn()) {
|
||||||
$this->response = new ApiJsonResponse(ServerStatus::UNAUTHORIZED);
|
$this->response = new ApiJsonResponse(ServerStatus::UNAUTHORIZED);
|
||||||
|
@ -72,7 +72,7 @@ abstract class AbstractController
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasUserPermission(int $userId): bool
|
public function hasUserPermission(int $userId): bool
|
||||||
{
|
{
|
||||||
$this->response = new ApiJsonResponse();
|
$this->response = new ApiJsonResponse();
|
||||||
|
|
||||||
|
@ -87,28 +87,28 @@ abstract class AbstractController
|
||||||
return $hasPermission;
|
return $hasPermission;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function validateJsonBody(): bool
|
protected function validateJsonBody(): bool
|
||||||
{
|
{
|
||||||
if (count($this->mandatoryAttributes) === 0) {
|
if (count($this->mandatoryAttributes) === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->contentType === MimeType::JSON && $this->requestBody === null) {
|
if ($this->contentType === MimeType::JSON && $this->requestBody === null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$json = json_decode($this->requestBody);
|
$json = json_decode($this->requestBody);
|
||||||
|
|
||||||
foreach ($this->mandatoryAttributes as $attribute) {
|
foreach ($this->mandatoryAttributes as $attribute) {
|
||||||
if (!isset($json->{$attribute})) {
|
if (!isset($json->{$attribute})) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,243 +4,243 @@ declare(strict_types=1);
|
||||||
|
|
||||||
class Autoloader
|
class Autoloader
|
||||||
{
|
{
|
||||||
private const PATH_CLASSES = 'backend/classes';
|
private const PATH_CLASSES = 'backend/classes';
|
||||||
private const PATH_CONTROLLERS = self::PATH_CLASSES . '/controller';
|
private const PATH_CONTROLLERS = self::PATH_CLASSES . '/controller';
|
||||||
private const PATH_CACHE = 'backend/cache/';
|
private const PATH_CACHE = 'backend/cache/';
|
||||||
|
|
||||||
public function __construct(string $cachePath = self::PATH_CACHE)
|
public function __construct(string $cachePath = self::PATH_CACHE)
|
||||||
{
|
{
|
||||||
if ($cachePath !== self::PATH_CACHE) {
|
if ($cachePath !== self::PATH_CACHE) {
|
||||||
$cachePath = substr($cachePath, -1) === '/' ? $cachePath : $cachePath . '/';
|
$cachePath = substr($cachePath, -1) === '/' ? $cachePath : $cachePath . '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
$routesFound = @include($cachePath . 'routes.php');
|
$routesFound = @include($cachePath . 'routes.php');
|
||||||
$classesFound = @include($cachePath . 'classes.php');
|
$classesFound = @include($cachePath . 'classes.php');
|
||||||
|
|
||||||
if (!$routesFound || !$classesFound) {
|
if (!$routesFound || !$classesFound) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
sprintf(
|
sprintf(
|
||||||
'Autoloader cache not found! Please generate it with %s::BuildCache() at first!',
|
'Autoloader cache not found! Please generate it with %s::BuildCache() at first!',
|
||||||
self::class
|
self::class
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
spl_autoload_register(
|
spl_autoload_register(
|
||||||
function (string $className) {
|
function (string $className) {
|
||||||
if (!$this->loadClass($className)) {
|
if (!$this->loadClass($className)) {
|
||||||
throw new Exception(sprintf('Class %s couldn\'t be loaded!', $className));
|
throw new Exception(sprintf('Class %s couldn\'t be loaded!', $className));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function BuildCache(): void
|
public static function BuildCache(): void
|
||||||
{
|
{
|
||||||
self::BuildClassCache();
|
self::BuildClassCache();
|
||||||
self::BuildRouteCache();
|
self::BuildRouteCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function BuildClassCache(): void
|
public static function BuildClassCache(): void
|
||||||
{
|
{
|
||||||
$classesResult = self::scanForClasses();
|
$classesResult = self::scanForClasses();
|
||||||
|
|
||||||
$cacheContent = '';
|
$cacheContent = '';
|
||||||
|
|
||||||
foreach ($classesResult as $className => $path) {
|
foreach ($classesResult as $className => $path) {
|
||||||
$cacheContent .= sprintf("\t\t'%s' => '%s',\n", $className, $path);
|
$cacheContent .= sprintf("\t\t'%s' => '%s',\n", $className, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
$cacheContent .= "\t]\n);";
|
$cacheContent .= "\t]\n);";
|
||||||
|
|
||||||
self::buildCacheFile($cacheContent, 'classes');
|
self::buildCacheFile($cacheContent, 'classes');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadClass(string $className): bool
|
private function loadClass(string $className): bool
|
||||||
{
|
{
|
||||||
if (!isset(CLASSES[$className]) || !@include(CLASSES[$className])) {
|
if (!isset(CLASSES[$className]) || !@include(CLASSES[$className])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function BuildRouteCache(): void
|
public static function BuildRouteCache(): void
|
||||||
{
|
{
|
||||||
$controllersResult = self::scanForControllers();
|
$controllersResult = self::scanForControllers();
|
||||||
$controllerMethods = [
|
$controllerMethods = [
|
||||||
'GET' => [],
|
'GET' => [],
|
||||||
'POST' => [],
|
'POST' => [],
|
||||||
'PUT' => [],
|
'PUT' => [],
|
||||||
'DELETE' => [],
|
'DELETE' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($controllersResult as $className => $path) {
|
foreach ($controllersResult as $className => $path) {
|
||||||
$file = fopen($path, 'r');
|
$file = fopen($path, 'r');
|
||||||
$content = fread($file, filesize($path));
|
$content = fread($file, filesize($path));
|
||||||
fclose($file);
|
fclose($file);
|
||||||
|
|
||||||
preg_match_all('/(?<=private )\w+ \$\w+(?=;)/', $content, $matches);
|
preg_match_all('/(?<=private )\w+ \$\w+(?=;)/', $content, $matches);
|
||||||
|
|
||||||
$params = [];
|
$params = [];
|
||||||
|
|
||||||
foreach ($matches[0] as $match) {
|
foreach ($matches[0] as $match) {
|
||||||
$parts = explode(' ', $match);
|
$parts = explode(' ', $match);
|
||||||
$params[] = [
|
$params[] = [
|
||||||
'type' => $parts[0],
|
'type' => $parts[0],
|
||||||
'name' => $parts[1],
|
'name' => $parts[1],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
preg_match('/(?<=protected string \$route = \').*(?=\';)/', $content, $matches);
|
preg_match('/(?<=protected string \$route = \').*(?=\';)/', $content, $matches);
|
||||||
$route = $matches[0];
|
$route = $matches[0];
|
||||||
|
|
||||||
preg_match('/[A-Z][a-z]+(?=Controller)/', $className, $matches);
|
preg_match('/[A-Z][a-z]+(?=Controller)/', $className, $matches);
|
||||||
$method = strtoupper($matches[0]);
|
$method = strtoupper($matches[0]);
|
||||||
|
|
||||||
$controllerMethods[$method][$route] = [
|
$controllerMethods[$method][$route] = [
|
||||||
'name' => $className,
|
'name' => $className,
|
||||||
'params' => $params,
|
'params' => $params,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$cacheContent = '';
|
$cacheContent = '';
|
||||||
|
|
||||||
foreach ($controllerMethods as $method => $controllers) {
|
foreach ($controllerMethods as $method => $controllers) {
|
||||||
$cacheContent .= self::createRoutesForMethod($method, $controllers);
|
$cacheContent .= self::createRoutesForMethod($method, $controllers);
|
||||||
}
|
}
|
||||||
|
|
||||||
$cacheContent .= "\t]\n);";
|
$cacheContent .= "\t]\n);";
|
||||||
|
|
||||||
self::buildCacheFile($cacheContent, 'routes');
|
self::buildCacheFile($cacheContent, 'routes');
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function createRoutesForMethod(string $method, array $routes): string
|
private static function createRoutesForMethod(string $method, array $routes): string
|
||||||
{
|
{
|
||||||
krsort($routes);
|
krsort($routes);
|
||||||
$stringRoutes = '';
|
$stringRoutes = '';
|
||||||
|
|
||||||
foreach ($routes as $route => $params) {
|
foreach ($routes as $route => $params) {
|
||||||
$stringRoutes .= sprintf(
|
$stringRoutes .= sprintf(
|
||||||
"'%s' => [
|
"'%s' => [
|
||||||
'controller' => %s::class,
|
'controller' => %s::class,
|
||||||
'params' => [
|
'params' => [
|
||||||
%s
|
%s
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
",
|
",
|
||||||
$route,
|
$route,
|
||||||
$params['name'],
|
$params['name'],
|
||||||
self::createRouteParams($params['params'])
|
self::createRouteParams($params['params'])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf(
|
return sprintf(
|
||||||
"
|
"
|
||||||
'%s' => [
|
'%s' => [
|
||||||
%s
|
%s
|
||||||
],
|
],
|
||||||
",
|
",
|
||||||
$method,
|
$method,
|
||||||
$stringRoutes,
|
$stringRoutes,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function createRouteParams(array $params): string
|
private static function createRouteParams(array $params): string
|
||||||
{
|
{
|
||||||
$string = '';
|
$string = '';
|
||||||
|
|
||||||
foreach ($params as $param) {
|
foreach ($params as $param) {
|
||||||
$string .= sprintf(
|
$string .= sprintf(
|
||||||
"
|
"
|
||||||
'%s' => [
|
'%s' => [
|
||||||
'type' => '%s',
|
'type' => '%s',
|
||||||
],
|
],
|
||||||
",
|
",
|
||||||
str_replace('$', '', $param['name']),
|
str_replace('$', '', $param['name']),
|
||||||
$param['type']
|
$param['type']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $string;
|
return $string;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function reformatCacheFileContent(string $content): string
|
private static function reformatCacheFileContent(string $content): string
|
||||||
{
|
{
|
||||||
$depth = 0;
|
$depth = 0;
|
||||||
$reformatted = '';
|
$reformatted = '';
|
||||||
$replace = '';
|
$replace = '';
|
||||||
|
|
||||||
// Removing indents
|
// Removing indents
|
||||||
foreach (explode("\n", $content) as $line) {
|
foreach (explode("\n", $content) as $line) {
|
||||||
$trim = trim($line);
|
$trim = trim($line);
|
||||||
|
|
||||||
if ($trim !== '') {
|
if ($trim !== '') {
|
||||||
$replace .= $trim . "\n";
|
$replace .= $trim . "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ($i = 0; $i < strlen($replace); $i++) {
|
for ($i = 0; $i < strlen($replace); $i++) {
|
||||||
if (in_array($replace[$i], [')', ']'])) {
|
if (in_array($replace[$i], [')', ']'])) {
|
||||||
$depth--;
|
$depth--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($replace[$i - 1] === "\n") {
|
if ($replace[$i - 1] === "\n") {
|
||||||
$reformatted .= str_repeat("\t", $depth);
|
$reformatted .= str_repeat("\t", $depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
$reformatted .= $replace[$i];
|
$reformatted .= $replace[$i];
|
||||||
|
|
||||||
if (in_array($replace[$i], ['(', '['])) {
|
if (in_array($replace[$i], ['(', '['])) {
|
||||||
$depth++;
|
$depth++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $reformatted;
|
return $reformatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function buildCacheFile(string $content, string $cacheName): void
|
private static function buildCacheFile(string $content, string $cacheName): void
|
||||||
{
|
{
|
||||||
$cacheContent = sprintf(
|
$cacheContent = sprintf(
|
||||||
"<?php\n\n/*\n * This file was auto generated on %s\n */\n\ndefine(\n\t'%s',\n\t[\n",
|
"<?php\n\n/*\n * This file was auto generated on %s\n */\n\ndefine(\n\t'%s',\n\t[\n",
|
||||||
(new DateTime())->format('Y-m-d H:i:s'),
|
(new DateTime())->format('Y-m-d H:i:s'),
|
||||||
strtoupper($cacheName)
|
strtoupper($cacheName)
|
||||||
);
|
);
|
||||||
|
|
||||||
$cacheContent .= $content;
|
$cacheContent .= $content;
|
||||||
|
|
||||||
$file = fopen(getcwd() . '/' . self::PATH_CACHE . $cacheName . '.php', 'w');
|
$file = fopen(getcwd() . '/' . self::PATH_CACHE . $cacheName . '.php', 'w');
|
||||||
fwrite($file, self::reformatCacheFileContent($cacheContent));
|
fwrite($file, self::reformatCacheFileContent($cacheContent));
|
||||||
fclose($file);
|
fclose($file);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function scanForFiles(string $folder): array
|
private static function scanForFiles(string $folder): array
|
||||||
{
|
{
|
||||||
$folder = substr($folder, -1) === '/' ? substr($folder, 0, -1) : $folder;
|
$folder = substr($folder, -1) === '/' ? substr($folder, 0, -1) : $folder;
|
||||||
$files = [];
|
$files = [];
|
||||||
$handler = opendir($folder);
|
$handler = opendir($folder);
|
||||||
|
|
||||||
while ($file = readdir($handler)) {
|
while ($file = readdir($handler)) {
|
||||||
$path = $folder . '/' . $file;
|
$path = $folder . '/' . $file;
|
||||||
|
|
||||||
if (is_dir($path) && $file !== '.' && $file !== '..') {
|
if (is_dir($path) && $file !== '.' && $file !== '..') {
|
||||||
$files = array_merge($files, self::scanForFiles($path));
|
$files = array_merge($files, self::scanForFiles($path));
|
||||||
} elseif (is_file($path) && substr($path, -4) === '.php') {
|
} elseif (is_file($path) && substr($path, -4) === '.php') {
|
||||||
$className = substr($file, 0, -4);
|
$className = substr($file, 0, -4);
|
||||||
$files[$className] = $path;
|
$files[$className] = $path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $files;
|
return $files;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function scanForClasses(): array
|
private static function scanForClasses(): array
|
||||||
{
|
{
|
||||||
return self::scanForFiles(getcwd() . '/' . self::PATH_CLASSES);
|
return self::scanForFiles(getcwd() . '/' . self::PATH_CLASSES);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function scanForControllers(): array
|
private static function scanForControllers(): array
|
||||||
{
|
{
|
||||||
return self::scanForFiles(getcwd() . '/' . self::PATH_CONTROLLERS);
|
return self::scanForFiles(getcwd() . '/' . self::PATH_CONTROLLERS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,79 +2,79 @@
|
||||||
|
|
||||||
interface DatabaseInterface
|
interface DatabaseInterface
|
||||||
{
|
{
|
||||||
public const ORDER_ASC = true;
|
public const ORDER_ASC = true;
|
||||||
public const ORDER_DESC = false;
|
public const ORDER_DESC = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has to close the connection.
|
* Has to close the connection.
|
||||||
*/
|
*/
|
||||||
public function __destruct();
|
public function __destruct();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends an sql query to the database.
|
* Sends an sql query to the database.
|
||||||
*/
|
*/
|
||||||
public function Query(string $query, array $params = []): void;
|
public function Query(string $query, array $params = []): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getResult(): array;
|
public function getResult(): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects backend from a table.
|
* Selects backend from a table.
|
||||||
*/
|
*/
|
||||||
public function Select(
|
public function Select(
|
||||||
string $tableName,
|
string $tableName,
|
||||||
array $fields = [],
|
array $fields = [],
|
||||||
array $conditions = [],
|
array $conditions = [],
|
||||||
int $limit = 0,
|
int $limit = 0,
|
||||||
array $orderBy = [],
|
array $orderBy = [],
|
||||||
bool $asc = true,
|
bool $asc = true,
|
||||||
int $offset = 0
|
int $offset = 0
|
||||||
): array;
|
): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes rows from a table.
|
* Deletes rows from a table.
|
||||||
*/
|
*/
|
||||||
public function Delete(string $table, array $conditions): void;
|
public function Delete(string $table, array $conditions): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts a new row into the table.
|
* Inserts a new row into the table.
|
||||||
*/
|
*/
|
||||||
public function Insert(string $table, array $fields): ?int;
|
public function Insert(string $table, array $fields): ?int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits backend inside a table.
|
* Edits backend inside a table.
|
||||||
*/
|
*/
|
||||||
public function Update(string $table, array $fields, array $conditions): void;
|
public function Update(string $table, array $fields, array $conditions): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of entries found.
|
* Returns the number of entries found.
|
||||||
*/
|
*/
|
||||||
public function Count(string $table, array $conditions = []): int;
|
public function Count(string $table, array $conditions = []): int;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns if there's an open transaction.
|
* Returns if there's an open transaction.
|
||||||
*/
|
*/
|
||||||
public function hasTransaction(): bool;
|
public function hasTransaction(): bool;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Starts a transaction that can later be committed or rolled back.
|
* Starts a transaction that can later be committed or rolled back.
|
||||||
*/
|
*/
|
||||||
public function startTransaction(): void;
|
public function startTransaction(): void;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Quits a current transaction without saving.
|
* Quits a current transaction without saving.
|
||||||
*/
|
*/
|
||||||
public function rollback(): void;
|
public function rollback(): void;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Saves and exits a current transaction.
|
* Saves and exits a current transaction.
|
||||||
*/
|
*/
|
||||||
public function commit(): void;
|
public function commit(): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the primary key from the last inserted row.
|
* Returns the primary key from the last inserted row.
|
||||||
*/
|
*/
|
||||||
public function GetLastInsertedId(): int;
|
public function GetLastInsertedId(): int;
|
||||||
}
|
}
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class MimeType
|
final class MimeType
|
||||||
{
|
{
|
||||||
public const PLAINTEXT = 'text/plain';
|
public const PLAINTEXT = 'text/plain';
|
||||||
public const JSON = 'application/json';
|
public const JSON = 'application/json';
|
||||||
public const SVG = 'image/svg+xml';
|
public const SVG = 'image/svg+xml';
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,22 +8,22 @@ final class MySqlDatabase implements DatabaseInterface
|
||||||
|
|
||||||
private ?PDO $connection;
|
private ?PDO $connection;
|
||||||
private ?PDOStatement $cursor;
|
private ?PDOStatement $cursor;
|
||||||
private bool $isTransactionOpen = false;
|
private bool $isTransactionOpen = false;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $hostname = Setting::MYSQL_HOST,
|
string $hostname = Setting::MYSQL_HOST,
|
||||||
string $user = Setting::MYSQL_USER,
|
string $user = Setting::MYSQL_USER,
|
||||||
string $password = Setting::MYSQL_PASSWORD,
|
string $password = Setting::MYSQL_PASSWORD,
|
||||||
string $database = Setting::MYSQL_DATABASE
|
string $database = Setting::MYSQL_DATABASE
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
$this->connection = new PDO("mysql:host=$hostname;dbname=$database", $user, $password);
|
$this->connection = new PDO("mysql:host=$hostname;dbname=$database", $user, $password);
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
throw new DatabaseException(
|
throw new DatabaseException(
|
||||||
'Couldn\'t connect to the database!',
|
'Couldn\'t connect to the database!',
|
||||||
ServerStatus::INTERNAL_ERROR
|
ServerStatus::INTERNAL_ERROR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
|
@ -37,22 +37,22 @@ final class MySqlDatabase implements DatabaseInterface
|
||||||
|
|
||||||
if (!$this->cursor) {
|
if (!$this->cursor) {
|
||||||
throw new DatabaseException(
|
throw new DatabaseException(
|
||||||
'Initialization of database cursor failed',
|
'Initialization of database cursor failed',
|
||||||
DatabaseException::CONNECTION_FAILED
|
DatabaseException::CONNECTION_FAILED
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($params as $key => $param) {
|
foreach ($params as $key => $param) {
|
||||||
if (is_bool($param)) {
|
if (is_bool($param)) {
|
||||||
$param = (int)$param;
|
$param = (int)$param;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->cursor->bindValue(':' . $key, $param);
|
$this->cursor->bindValue(':' . $key, $param);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->cursor->execute()) {
|
if (!$this->cursor->execute()) {
|
||||||
throw new DatabaseException($this->cursor->errorInfo()[2], $this->cursor->errorInfo()[1]);
|
throw new DatabaseException($this->cursor->errorInfo()[2], $this->cursor->errorInfo()[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getResult(): array
|
public function getResult(): array
|
||||||
|
@ -72,17 +72,17 @@ final class MySqlDatabase implements DatabaseInterface
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects backend from a table.
|
* Selects backend from a table.
|
||||||
*/
|
*/
|
||||||
public function Select(
|
public function Select(
|
||||||
string $tableName,
|
string $tableName,
|
||||||
array $fields = [],
|
array $fields = [],
|
||||||
array $conditions = [],
|
array $conditions = [],
|
||||||
int $limit = 0,
|
int $limit = 0,
|
||||||
array $orderBy = [],
|
array $orderBy = [],
|
||||||
bool $asc = true,
|
bool $asc = true,
|
||||||
int $offset = 0
|
int $offset = 0
|
||||||
): array {
|
): array {
|
||||||
if (!self::isValidTableName($tableName)) {
|
if (!self::isValidTableName($tableName)) {
|
||||||
[];
|
[];
|
||||||
|
@ -125,8 +125,8 @@ final class MySqlDatabase implements DatabaseInterface
|
||||||
$offsetStatement = '';
|
$offsetStatement = '';
|
||||||
|
|
||||||
if ($offset > 0) {
|
if ($offset > 0) {
|
||||||
$offsetStatement = 'OFFSET ' . $offset;
|
$offsetStatement = 'OFFSET ' . $offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = sprintf(
|
$query = sprintf(
|
||||||
'SELECT %s FROM %s %s %s %s %s',
|
'SELECT %s FROM %s %s %s %s %s',
|
||||||
|
@ -135,139 +135,139 @@ final class MySqlDatabase implements DatabaseInterface
|
||||||
$conditionsExpression,
|
$conditionsExpression,
|
||||||
$orderStatement,
|
$orderStatement,
|
||||||
$limitStatement,
|
$limitStatement,
|
||||||
$offsetStatement
|
$offsetStatement
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->Query($query, $conditions);
|
$this->Query($query, $conditions);
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
throw new DatabaseException(
|
throw new DatabaseException(
|
||||||
$e->getMessage(),
|
$e->getMessage(),
|
||||||
ServerStatus::INTERNAL_ERROR
|
ServerStatus::INTERNAL_ERROR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getResult();
|
return $this->getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes rows from a table.
|
* Deletes rows from a table.
|
||||||
*/
|
*/
|
||||||
public function Delete(string $table, array $conditions): void
|
public function Delete(string $table, array $conditions): void
|
||||||
{
|
{
|
||||||
if (count($conditions) === 0) {
|
if (count($conditions) === 0) {
|
||||||
$conditionsStatement = '1';
|
$conditionsStatement = '1';
|
||||||
} else {
|
} else {
|
||||||
$conditionPairs = [];
|
$conditionPairs = [];
|
||||||
|
|
||||||
foreach ($conditions as $field => $value) {
|
foreach ($conditions as $field => $value) {
|
||||||
$conditionPairs[] = sprintf('%s=:Condition%s', $field, $field);
|
$conditionPairs[] = sprintf('%s=:Condition%s', $field, $field);
|
||||||
$conditions['Condition' . $field] = $value;
|
$conditions['Condition' . $field] = $value;
|
||||||
unset($conditions[$field]);
|
unset($conditions[$field]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$conditionsStatement = implode(' AND ', $conditionPairs);
|
$conditionsStatement = implode(' AND ', $conditionPairs);
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = sprintf('DELETE FROM %s WHERE %s', $table, $conditionsStatement);
|
$query = sprintf('DELETE FROM %s WHERE %s', $table, $conditionsStatement);
|
||||||
|
|
||||||
$this->Query($query, $conditions);
|
$this->Query($query, $conditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Insert(string $table, array $fields): ?int
|
public function Insert(string $table, array $fields): ?int
|
||||||
{
|
{
|
||||||
if (count($fields) === 0) {
|
if (count($fields) === 0) {
|
||||||
throw new DatabaseException('Row to insert is empty!');
|
throw new DatabaseException('Row to insert is empty!');
|
||||||
}
|
}
|
||||||
|
|
||||||
$fieldNames = implode(',', array_keys($fields));
|
$fieldNames = implode(',', array_keys($fields));
|
||||||
$fieldPlaceholder = [];
|
$fieldPlaceholder = [];
|
||||||
|
|
||||||
foreach ($fields as $name => $value) {
|
foreach ($fields as $name => $value) {
|
||||||
$fieldPlaceholder[] = ':' . $name;
|
$fieldPlaceholder[] = ':' . $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = sprintf(
|
$query = sprintf(
|
||||||
'INSERT INTO %s (%s) VALUES (%s)', $table, $fieldNames, implode(',', $fieldPlaceholder)
|
'INSERT INTO %s (%s) VALUES (%s)', $table, $fieldNames, implode(',', $fieldPlaceholder)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->Query($query, $fields);
|
$this->Query($query, $fields);
|
||||||
|
|
||||||
$lastInsertedId = $this->GetLastInsertedId();
|
$lastInsertedId = $this->GetLastInsertedId();
|
||||||
|
|
||||||
if ((int)$lastInsertedId === 0) {
|
if ((int)$lastInsertedId === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $lastInsertedId;
|
return $lastInsertedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Update(string $table, array $fields, array $conditions): void
|
public function Update(string $table, array $fields, array $conditions): void
|
||||||
{
|
{
|
||||||
$conditionPairs = [];
|
$conditionPairs = [];
|
||||||
|
|
||||||
foreach ($conditions as $field => $value) {
|
foreach ($conditions as $field => $value) {
|
||||||
$conditionPairs[] = sprintf('%s=:Condition%s', $field, $field);
|
$conditionPairs[] = sprintf('%s=:Condition%s', $field, $field);
|
||||||
$conditions['Condition' . $field] = $value;
|
$conditions['Condition' . $field] = $value;
|
||||||
unset($conditions[$field]);
|
unset($conditions[$field]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$conditionsStatement = implode(' AND ', $conditionPairs);
|
$conditionsStatement = implode(' AND ', $conditionPairs);
|
||||||
|
|
||||||
$fieldPairs = [];
|
$fieldPairs = [];
|
||||||
|
|
||||||
foreach ($fields as $field => $value) {
|
foreach ($fields as $field => $value) {
|
||||||
$fieldPairs[] = sprintf('%s=:%s', $field, $field);
|
$fieldPairs[] = sprintf('%s=:%s', $field, $field);
|
||||||
}
|
}
|
||||||
|
|
||||||
$fieldsStatement = implode(',', $fieldPairs);
|
$fieldsStatement = implode(',', $fieldPairs);
|
||||||
|
|
||||||
$query = sprintf('UPDATE %s SET %s WHERE %s', $table, $fieldsStatement, $conditionsStatement);
|
$query = sprintf('UPDATE %s SET %s WHERE %s', $table, $fieldsStatement, $conditionsStatement);
|
||||||
|
|
||||||
|
|
||||||
$this->Query($query, array_merge($fields, $conditions));
|
$this->Query($query, array_merge($fields, $conditions));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Count(string $table, array $conditions = []): int
|
public function Count(string $table, array $conditions = []): int
|
||||||
{
|
{
|
||||||
$result = $this->Select($table, ['count(*)'], $conditions);
|
$result = $this->Select($table, ['count(*)'], $conditions);
|
||||||
|
|
||||||
return (int)$result[0]['count(*)'];
|
return (int)$result[0]['count(*)'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasTransaction(): bool
|
public function hasTransaction(): bool
|
||||||
{
|
{
|
||||||
return $this->isTransactionOpen;
|
return $this->isTransactionOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function startTransaction(): void
|
public function startTransaction(): void
|
||||||
{
|
{
|
||||||
$this->connection->beginTransaction();
|
$this->connection->beginTransaction();
|
||||||
$this->isTransactionOpen = true;
|
$this->isTransactionOpen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rollback(): void
|
public function rollback(): void
|
||||||
{
|
{
|
||||||
$this->connection->rollBack();
|
$this->connection->rollBack();
|
||||||
$this->isTransactionOpen = false;
|
$this->isTransactionOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function commit(): void
|
public function commit(): void
|
||||||
{
|
{
|
||||||
$this->connection->commit();
|
$this->connection->commit();
|
||||||
$this->isTransactionOpen = false;
|
$this->isTransactionOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetLastInsertedId(): int
|
public function GetLastInsertedId(): int
|
||||||
{
|
{
|
||||||
$this->Query('SELECT LAST_INSERT_ID() as ID');
|
$this->Query('SELECT LAST_INSERT_ID() as ID');
|
||||||
|
|
||||||
return (int)$this->getResult()[0]['ID'];
|
return (int)$this->getResult()[0]['ID'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does a check if the given table name contains forbidden chars.
|
* Does a check if the given table name contains forbidden chars.
|
||||||
*/
|
*/
|
||||||
private static function isValidTableName(string $tableName): bool
|
private static function isValidTableName(string $tableName): bool
|
||||||
{
|
{
|
||||||
foreach (str_split($tableName) as $char) {
|
foreach (str_split($tableName) as $char) {
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
|
|
||||||
class MySqlTable extends Table
|
class MySqlTable extends Table
|
||||||
{
|
{
|
||||||
public function __construct(string $tableName, $id = null, DatabaseInterface &$database = null)
|
public function __construct(string $tableName, $id = null, DatabaseInterface &$database = null)
|
||||||
{
|
{
|
||||||
self::EnsureConnection($database);
|
self::EnsureConnection($database);
|
||||||
|
|
||||||
parent::__construct($tableName, $id, $database);
|
parent::__construct($tableName, $id, $database);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function EnsureConnection(?DatabaseInterface & $database): void
|
public static function EnsureConnection(?DatabaseInterface & $database): void
|
||||||
{
|
{
|
||||||
if (!($database instanceof MySqlDatabase)) {
|
if (!($database instanceof MySqlDatabase)) {
|
||||||
$database = new MySqlDatabase();
|
$database = new MySqlDatabase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,12 +4,12 @@ declare(strict_types=1);
|
||||||
|
|
||||||
class Password
|
class Password
|
||||||
{
|
{
|
||||||
public static function IsValid(string $password, string $hash): bool
|
public static function IsValid(string $password, string $hash): bool
|
||||||
{
|
{
|
||||||
return password_verify($password, $hash);
|
return password_verify($password, $hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetHash(string $password): string
|
public static function GetHash(string $password): string
|
||||||
{
|
{
|
||||||
return password_hash($password, PASSWORD_BCRYPT);
|
return password_hash($password, PASSWORD_BCRYPT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,41 +4,41 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class QrCode
|
final class QrCode
|
||||||
{
|
{
|
||||||
private int $fingerprintId;
|
private int $fingerprintId;
|
||||||
private string $fingerprint;
|
private string $fingerprint;
|
||||||
private string $temporaryFilename;
|
private string $temporaryFilename;
|
||||||
|
|
||||||
public function __construct(int $fingerprintId, string $fingerprint)
|
public function __construct(int $fingerprintId, string $fingerprint)
|
||||||
{
|
{
|
||||||
$this->fingerprintId = $fingerprintId;
|
$this->fingerprintId = $fingerprintId;
|
||||||
$this->fingerprint = $fingerprint;
|
$this->fingerprint = $fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save(): void
|
public function save(): void
|
||||||
{
|
{
|
||||||
if (!is_file($this->temporaryFilename)) {
|
if (!is_file($this->temporaryFilename)) {
|
||||||
throw new QrCodeException(
|
throw new QrCodeException(
|
||||||
sprintf('Temporary QR file %s couldn\'t be found!', $this->temporaryFilename)
|
sprintf('Temporary QR file %s couldn\'t be found!', $this->temporaryFilename)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$returnCode = 0;
|
$returnCode = 0;
|
||||||
|
|
||||||
$filename = $this->getFilePath();
|
$filename = $this->getFilePath();
|
||||||
|
|
||||||
passthru(
|
passthru(
|
||||||
sprintf('mv %s %s', $this->temporaryFilename, $filename),
|
sprintf('mv %s %s', $this->temporaryFilename, $filename),
|
||||||
$returnCode
|
$returnCode
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($returnCode !== 0 || !is_file($filename)) {
|
if ($returnCode !== 0 || !is_file($filename)) {
|
||||||
throw new QrCodeException(
|
throw new QrCodeException(
|
||||||
sprintf('QR code for fingerprint %d couldn\'t be created!', $this->fingerprintId)
|
sprintf('QR code for fingerprint %d couldn\'t be created!', $this->fingerprintId)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete(): void
|
public function delete(): void
|
||||||
{
|
{
|
||||||
$filepath = $this->getFilePath();
|
$filepath = $this->getFilePath();
|
||||||
|
|
||||||
|
@ -51,35 +51,35 @@ final class QrCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generate(): bool
|
public function generate(): bool
|
||||||
{
|
{
|
||||||
$returnCode = 0;
|
$returnCode = 0;
|
||||||
|
|
||||||
$path = substr(Setting::PATH_TMP, -1) === '/' ? Setting::PATH_TMP : Setting::PATH_TMP . '/';
|
$path = substr(Setting::PATH_TMP, -1) === '/' ? Setting::PATH_TMP : Setting::PATH_TMP . '/';
|
||||||
|
|
||||||
$this->temporaryFilename = $path . $this->generateTemporaryFilename() . '.svg';
|
$this->temporaryFilename = $path . $this->generateTemporaryFilename() . '.svg';
|
||||||
|
|
||||||
passthru(
|
passthru(
|
||||||
sprintf('qrencode -o %s -t SVG "%s"', $this->temporaryFilename, $this->fingerprint),
|
sprintf('qrencode -o %s -t SVG "%s"', $this->temporaryFilename, $this->fingerprint),
|
||||||
$returnCode
|
$returnCode
|
||||||
);
|
);
|
||||||
|
|
||||||
return !(bool)$returnCode;
|
return !(bool)$returnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasFile(): bool
|
public function hasFile(): bool
|
||||||
{
|
{
|
||||||
return is_file($this->getFilePath());
|
return is_file($this->getFilePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateTemporaryFilename(): string
|
private function generateTemporaryFilename(): string
|
||||||
{
|
{
|
||||||
$hash = hash('md5', (new DateTime())->format('U') . $this->fingerprint);
|
$hash = hash('md5', (new DateTime())->format('U') . $this->fingerprint);
|
||||||
|
|
||||||
return sprintf('%s.svg', $hash);
|
return sprintf('%s.svg', $hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFilePath(): string
|
private function getFilePath(): string
|
||||||
{
|
{
|
||||||
$path = substr(Setting::PATH_QR_CODES, -1) === '/'
|
$path = substr(Setting::PATH_QR_CODES, -1) === '/'
|
||||||
? Setting::PATH_QR_CODES
|
? Setting::PATH_QR_CODES
|
||||||
|
|
|
@ -4,55 +4,55 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class Router
|
final class Router
|
||||||
{
|
{
|
||||||
private string $route;
|
private string $route;
|
||||||
private string $method;
|
private string $method;
|
||||||
private ?string $requestBody = null;
|
private ?string $requestBody = null;
|
||||||
private ?string $contentType = null;
|
private ?string $contentType = null;
|
||||||
|
|
||||||
public function __construct(string $route, string $method)
|
public function __construct(string $route, string $method)
|
||||||
{
|
{
|
||||||
$this->route = $route;
|
$this->route = $route;
|
||||||
$this->method = $method;
|
$this->method = $method;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setRequestBody(string $contentType, string $content): void
|
public function setRequestBody(string $contentType, string $content): void
|
||||||
{
|
{
|
||||||
$this->contentType = $contentType;
|
$this->contentType = $contentType;
|
||||||
$this->requestBody = $content;
|
$this->requestBody = $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function route(): void
|
public function route(): void
|
||||||
{
|
{
|
||||||
foreach (ROUTES[$this->method] as $route => $params) {
|
foreach (ROUTES[$this->method] as $route => $params) {
|
||||||
preg_match_all($this->createRegex($route, $params['params']), $this->route, $matches);
|
preg_match_all($this->createRegex($route, $params['params']), $this->route, $matches);
|
||||||
|
|
||||||
if (count($matches[0]) > 0) {
|
if (count($matches[0]) > 0) {
|
||||||
$class = new ReflectionClass($params['controller']);
|
$class = new ReflectionClass($params['controller']);
|
||||||
|
|
||||||
/** @var AbstractController $controller */
|
/** @var AbstractController $controller */
|
||||||
$controller = $class->newInstance($matches[0][0]);
|
$controller = $class->newInstance($matches[0][0]);
|
||||||
|
|
||||||
if ($this->requestBody !== null && $this->contentType !== null) {
|
if ($this->requestBody !== null && $this->contentType !== null) {
|
||||||
$controller->setRequestBody($this->contentType, $this->requestBody);
|
$controller->setRequestBody($this->contentType, $this->requestBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
$controller->handle();
|
$controller->handle();
|
||||||
$controller->getResponse()->respond();
|
$controller->getResponse()->respond();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createRegex(string $route, array $params): string
|
private function createRegex(string $route, array $params): string
|
||||||
{
|
{
|
||||||
foreach ($params as $param => $values) {
|
foreach ($params as $param => $values) {
|
||||||
switch ($values['type']) {
|
switch ($values['type']) {
|
||||||
case 'int':
|
case 'int':
|
||||||
$route = str_replace('{' . $param . '}', '[0-9]+', $route);
|
$route = str_replace('{' . $param . '}', '[0-9]+', $route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return '/' . str_replace('/', '\\/', $route) . '/';
|
return '/' . str_replace('/', '\\/', $route) . '/';
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,10 +4,10 @@ declare(strict_types=1);
|
||||||
|
|
||||||
class ServerStatus
|
class ServerStatus
|
||||||
{
|
{
|
||||||
public const OK = 200;
|
public const OK = 200;
|
||||||
public const FORBIDDEN = 403;
|
public const FORBIDDEN = 403;
|
||||||
public const UNAUTHORIZED = 401;
|
public const UNAUTHORIZED = 401;
|
||||||
public const BAD_REQUEST = 400;
|
public const BAD_REQUEST = 400;
|
||||||
public const NOT_FOUND = 404;
|
public const NOT_FOUND = 404;
|
||||||
public const INTERNAL_ERROR = 500;
|
public const INTERNAL_ERROR = 500;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,92 +4,92 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class Session
|
final class Session
|
||||||
{
|
{
|
||||||
public const TYPE_INT = 1;
|
public const TYPE_INT = 1;
|
||||||
public const TYPE_STRING = 2;
|
public const TYPE_STRING = 2;
|
||||||
public const TYPE_BOOL = 3;
|
public const TYPE_BOOL = 3;
|
||||||
|
|
||||||
private const IS_LOGGED_IN = 'is_logged_in';
|
private const IS_LOGGED_IN = 'is_logged_in';
|
||||||
private const USER_ID = 'account_id';
|
private const USER_ID = 'account_id';
|
||||||
private const USERNAME = 'username';
|
private const USERNAME = 'username';
|
||||||
private const IS_ADMIN = 'admin';
|
private const IS_ADMIN = 'admin';
|
||||||
private const EMAIL = 'email';
|
private const EMAIL = 'email';
|
||||||
private const JABBER_ADDRESS = 'jabber';
|
private const JABBER_ADDRESS = 'jabber';
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@session_start();
|
@session_start();
|
||||||
|
|
||||||
if (!$this->HasValue(self::IS_LOGGED_IN)) {
|
if (!$this->HasValue(self::IS_LOGGED_IN)) {
|
||||||
$this->SetBool(self::IS_LOGGED_IN, false);
|
$this->SetBool(self::IS_LOGGED_IN, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Destroy(): bool
|
public function Destroy(): bool
|
||||||
{
|
{
|
||||||
return session_unset() && session_destroy();
|
return session_unset() && session_destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Login(string $usernameOrEmail, string $password): bool
|
public function Login(string $usernameOrEmail, string $password): bool
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$user = User::getFromUsername($usernameOrEmail);
|
$user = User::getFromUsername($usernameOrEmail);
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
$user = User::getFromEmail($usernameOrEmail);
|
$user = User::getFromEmail($usernameOrEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($user === null || !Password::IsValid($password, $user->getPassword())) {
|
if ($user === null || !Password::IsValid($password, $user->getPassword())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->SetBool(self::IS_LOGGED_IN, true);
|
$this->SetBool(self::IS_LOGGED_IN, true);
|
||||||
$this->SetInt(self::USER_ID, $user->getUserId());
|
$this->SetInt(self::USER_ID, $user->getUserId());
|
||||||
$this->SetString(self::USERNAME, $user->getUsername());
|
$this->SetString(self::USERNAME, $user->getUsername());
|
||||||
$this->SetString(self::EMAIL, $user->getEmail());
|
$this->SetString(self::EMAIL, $user->getEmail());
|
||||||
$this->SetString(self::JABBER_ADDRESS, $user->getJabberAddress());
|
$this->SetString(self::JABBER_ADDRESS, $user->getJabberAddress());
|
||||||
$this->SetBool(self::IS_ADMIN, $user->isAdmin());
|
$this->SetBool(self::IS_ADMIN, $user->isAdmin());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function HasValue(string $key): bool
|
public function HasValue(string $key): bool
|
||||||
{
|
{
|
||||||
return self::HasSession() && isset($_SESSION[$key]);
|
return self::HasSession() && isset($_SESSION[$key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetBool(string $key, bool $value): void
|
public function SetBool(string $key, bool $value): void
|
||||||
{
|
{
|
||||||
$_SESSION[$key] = $value;
|
$_SESSION[$key] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetString(string $key, string $value): void
|
public function SetString(string $key, string $value): void
|
||||||
{
|
{
|
||||||
$_SESSION[$key] = $value;
|
$_SESSION[$key] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetInt(string $key, int $value): void
|
public function SetInt(string $key, int $value): void
|
||||||
{
|
{
|
||||||
$_SESSION[$key] = $value;
|
$_SESSION[$key] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function IsLoggedIn(): bool
|
public function IsLoggedIn(): bool
|
||||||
{
|
{
|
||||||
return self::HasSession() && $this->GetBool(self::IS_LOGGED_IN);
|
return self::HasSession() && $this->GetBool(self::IS_LOGGED_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetInt(string $key): ?int
|
public function GetInt(string $key): ?int
|
||||||
{
|
{
|
||||||
return $this->HasValue($key) ? (int)$_SESSION[$key] : null;
|
return $this->HasValue($key) ? (int)$_SESSION[$key] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetString(string $key): ?string
|
public function GetString(string $key): ?string
|
||||||
{
|
{
|
||||||
return $this->HasValue($key) ? (string)$_SESSION[$key] : null;
|
return $this->HasValue($key) ? (string)$_SESSION[$key] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetBool(string $key): ?bool
|
public function GetBool(string $key): ?bool
|
||||||
{
|
{
|
||||||
return $this->HasValue($key) ? (bool)$_SESSION[$key] : null;
|
return $this->HasValue($key) ? (bool)$_SESSION[$key] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUserId(): ?int
|
public function getUserId(): ?int
|
||||||
{
|
{
|
||||||
|
@ -101,8 +101,8 @@ final class Session
|
||||||
return $this->GetBool(self::IS_ADMIN);
|
return $this->GetBool(self::IS_ADMIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function HasSession(): bool
|
public static function HasSession(): bool
|
||||||
{
|
{
|
||||||
return isset($_SESSION);
|
return isset($_SESSION);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,25 +18,25 @@ abstract class Table
|
||||||
protected string $tableName;
|
protected string $tableName;
|
||||||
protected array $fields;
|
protected array $fields;
|
||||||
protected string $primaryKey;
|
protected string $primaryKey;
|
||||||
protected bool $isPrimKeyManual = false;
|
protected bool $isPrimKeyManual = false;
|
||||||
|
|
||||||
public function __construct(string $tableName, $id, ?DatabaseInterface & $database)
|
public function __construct(string $tableName, $id, ?DatabaseInterface & $database)
|
||||||
{
|
{
|
||||||
$this->tableName = $tableName;
|
$this->tableName = $tableName;
|
||||||
$this->fields = [];
|
$this->fields = [];
|
||||||
|
|
||||||
$this->database = $database;
|
$this->database = $database;
|
||||||
|
|
||||||
$this->database->Query(sprintf('DESCRIBE %s', $tableName));
|
$this->database->Query(sprintf('DESCRIBE %s', $tableName));
|
||||||
|
|
||||||
$result = $this->database->getResult();
|
$result = $this->database->getResult();
|
||||||
|
|
||||||
foreach ($result as $field) {
|
foreach ($result as $field) {
|
||||||
$sqlType = substr_count(
|
$sqlType = substr_count(
|
||||||
$field['Type'], '(') === 0 ? $field['Type'] : strstr($field['Type'],
|
$field['Type'], '(') === 0 ? $field['Type'] : strstr($field['Type'],
|
||||||
'(',
|
'(',
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
switch ($sqlType) {
|
switch ($sqlType) {
|
||||||
case 'varchar':
|
case 'varchar':
|
||||||
|
@ -60,12 +60,12 @@ abstract class Table
|
||||||
$type = self::TYPE_FLOAT;
|
$type = self::TYPE_FLOAT;
|
||||||
break;
|
break;
|
||||||
case 'datetime':
|
case 'datetime':
|
||||||
case 'date':
|
case 'date':
|
||||||
$type = self::TYPE_DATETIME;
|
$type = self::TYPE_DATETIME;
|
||||||
break;
|
break;
|
||||||
case 'tinyint':
|
case 'tinyint':
|
||||||
$type = self::TYPE_BOOL;
|
$type = self::TYPE_BOOL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new DatabaseException(
|
throw new DatabaseException(
|
||||||
sprintf('Type %s of field %s couldn\'t be handled', $sqlType, $field['Field']),
|
sprintf('Type %s of field %s couldn\'t be handled', $sqlType, $field['Field']),
|
||||||
|
@ -73,40 +73,40 @@ abstract class Table
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addField($field['Field'], $type);
|
$this->addField($field['Field'], $type);
|
||||||
|
|
||||||
if ($field['Key'] === 'PRI') {
|
if ($field['Key'] === 'PRI') {
|
||||||
$this->primaryKey = $field['Field'];
|
$this->primaryKey = $field['Field'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->isPrimKeyManual && $id !== null) {
|
if (!$this->isPrimKeyManual && $id !== null) {
|
||||||
$this->loadById($id);
|
$this->loadById($id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPrimaryKey()
|
public function getPrimaryKey()
|
||||||
{
|
{
|
||||||
if ($this->primaryKey === null) {
|
if ($this->primaryKey === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getField($this->primaryKey);
|
return $this->getField($this->primaryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function addField(string $name, int $type): void
|
protected function addField(string $name, int $type): void
|
||||||
{
|
{
|
||||||
if (!self::IsValidType($type)) {
|
if (!self::IsValidType($type)) {
|
||||||
throw new DatabaseException(
|
throw new DatabaseException(
|
||||||
sprintf('Field %s has invalid type of %s!', $name, $type),
|
sprintf('Field %s has invalid type of %s!', $name, $type),
|
||||||
ServerStatus::INTERNAL_ERROR
|
ServerStatus::INTERNAL_ERROR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->fields[$name] = [self::VALUE => null, self::TYPE => $type];
|
$this->fields[$name] = [self::VALUE => null, self::TYPE => $type];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadById($id): void
|
protected function loadById($id): void
|
||||||
{
|
{
|
||||||
$this->database->Query(
|
$this->database->Query(
|
||||||
sprintf('SELECT * FROM %s WHERE %s = :id', $this->tableName, $this->primaryKey),
|
sprintf('SELECT * FROM %s WHERE %s = :id', $this->tableName, $this->primaryKey),
|
||||||
|
@ -128,18 +128,18 @@ abstract class Table
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Flush(): void
|
public function Flush(): void
|
||||||
{
|
{
|
||||||
$this->database->Delete($this->tableName, []);
|
$this->database->Delete($this->tableName, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Delete(): void
|
public function Delete(): void
|
||||||
{
|
{
|
||||||
$this->database->Delete($this->tableName, [$this->primaryKey => $this->getPrimaryKey()]);
|
$this->database->Delete($this->tableName, [$this->primaryKey => $this->getPrimaryKey()]);
|
||||||
|
|
||||||
foreach ($this->GetAllFieldNames() as $field) {
|
foreach ($this->GetAllFieldNames() as $field) {
|
||||||
$this->fields[$field][self::VALUE] = null;
|
$this->fields[$field][self::VALUE] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getField(string $name)
|
protected function getField(string $name)
|
||||||
{
|
{
|
||||||
|
@ -150,9 +150,9 @@ abstract class Table
|
||||||
return $this->fields[$name][self::VALUE];
|
return $this->fields[$name][self::VALUE];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value for the given field inside the database.
|
* Sets the value for the given field inside the database.
|
||||||
*/
|
*/
|
||||||
protected function setField(string $name, $value): void
|
protected function setField(string $name, $value): void
|
||||||
{
|
{
|
||||||
if (!$this->HasField($name)) {
|
if (!$this->HasField($name)) {
|
||||||
|
@ -179,51 +179,51 @@ abstract class Table
|
||||||
return;
|
return;
|
||||||
case self::TYPE_DATETIME:
|
case self::TYPE_DATETIME:
|
||||||
try {
|
try {
|
||||||
$this->fields[$name][self::VALUE] = new DateTime((string)$value);
|
$this->fields[$name][self::VALUE] = new DateTime((string)$value);
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
throw new DatabaseException(
|
throw new DatabaseException(
|
||||||
$e->getMessage(),
|
$e->getMessage(),
|
||||||
ServerStatus::INTERNAL_ERROR
|
ServerStatus::INTERNAL_ERROR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case self::TYPE_BOOL:
|
case self::TYPE_BOOL:
|
||||||
$this->fields[$name][self::VALUE] = (bool)$value;
|
$this->fields[$name][self::VALUE] = (bool)$value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the table has the given column.
|
* Checks if the table has the given column.
|
||||||
*/
|
*/
|
||||||
public function HasField(string $name): bool
|
public function HasField(string $name): bool
|
||||||
{
|
{
|
||||||
return array_key_exists($name, $this->fields);
|
return array_key_exists($name, $this->fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the whole object into the database.
|
* Saves the whole object into the database.
|
||||||
*/
|
*/
|
||||||
public function Save(): void
|
public function Save(): void
|
||||||
{
|
{
|
||||||
$fields = [];
|
$fields = [];
|
||||||
|
|
||||||
foreach ($this->GetAllFieldNames() as $fieldName) {
|
foreach ($this->GetAllFieldNames() as $fieldName) {
|
||||||
$field = $this->getField($fieldName);
|
$field = $this->getField($fieldName);
|
||||||
|
|
||||||
if ($field instanceof DateTime) {
|
if ($field instanceof DateTime) {
|
||||||
$fields[$fieldName] = $field->format('Y-m-d H:i:s');
|
$fields[$fieldName] = $field->format('Y-m-d H:i:s');
|
||||||
} else if (is_bool($field)) {
|
} else if (is_bool($field)) {
|
||||||
$fields[$fieldName] = (int)$field;
|
$fields[$fieldName] = (int)$field;
|
||||||
} else {
|
} else {
|
||||||
$fields[$fieldName] = $field;
|
$fields[$fieldName] = $field;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->isPrimKeyManual) {
|
if ($this->isPrimKeyManual) {
|
||||||
$this->saveWithManualId($fields);
|
$this->saveWithManualId($fields);
|
||||||
} else {
|
} else {
|
||||||
$this->saveWithPrimaryKey($fields);
|
$this->saveWithPrimaryKey($fields);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -240,9 +240,9 @@ abstract class Table
|
||||||
return $fieldNames;
|
return $fieldNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the index is a valid backend type.
|
* Checks if the index is a valid backend type.
|
||||||
*/
|
*/
|
||||||
public static function IsValidType(int $type): bool
|
public static function IsValidType(int $type): bool
|
||||||
{
|
{
|
||||||
$validTypes = [
|
$validTypes = [
|
||||||
|
@ -250,43 +250,43 @@ abstract class Table
|
||||||
self::TYPE_INTEGER,
|
self::TYPE_INTEGER,
|
||||||
self::TYPE_FLOAT,
|
self::TYPE_FLOAT,
|
||||||
self::TYPE_DATETIME,
|
self::TYPE_DATETIME,
|
||||||
self::TYPE_BOOL,
|
self::TYPE_BOOL,
|
||||||
];
|
];
|
||||||
|
|
||||||
return in_array($type, $validTypes);
|
return in_array($type, $validTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function saveWithManualId(array $fields): void
|
protected function saveWithManualId(array $fields): void
|
||||||
{
|
{
|
||||||
if ($this->getField($this->primaryKey) === null) {
|
if ($this->getField($this->primaryKey) === null) {
|
||||||
throw new DatabaseException(
|
throw new DatabaseException(
|
||||||
'Manual primary key must not be null!',
|
'Manual primary key must not be null!',
|
||||||
ServerStatus::INTERNAL_ERROR
|
ServerStatus::INTERNAL_ERROR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$hasKey = (bool)$this->database->Count(
|
$hasKey = (bool)$this->database->Count(
|
||||||
$this->tableName,
|
$this->tableName,
|
||||||
[$this->primaryKey => $this->getField($this->primaryKey)]
|
[$this->primaryKey => $this->getField($this->primaryKey)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($hasKey) {
|
if ($hasKey) {
|
||||||
$this->database->Update(
|
$this->database->Update(
|
||||||
$this->tableName, $fields, [$this->primaryKey => $this->getField($this->primaryKey)]
|
$this->tableName, $fields, [$this->primaryKey => $this->getField($this->primaryKey)]
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$this->database->Insert($this->tableName, $fields);
|
$this->database->Insert($this->tableName, $fields);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function saveWithPrimaryKey(array $fields): void
|
protected function saveWithPrimaryKey(array $fields): void
|
||||||
{
|
{
|
||||||
if ($this->getField($this->primaryKey) !== null) {
|
if ($this->getField($this->primaryKey) !== null) {
|
||||||
$this->database->Update(
|
$this->database->Update(
|
||||||
$this->tableName, $fields, [$this->primaryKey => $this->getField($this->primaryKey)]
|
$this->tableName, $fields, [$this->primaryKey => $this->getField($this->primaryKey)]
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$this->setField($this->primaryKey, $this->database->Insert($this->tableName, $fields));
|
$this->setField($this->primaryKey, $this->database->Insert($this->tableName, $fields));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,50 +4,50 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class Fingerprint extends MySqlTable implements JsonSerializable
|
final class Fingerprint extends MySqlTable implements JsonSerializable
|
||||||
{
|
{
|
||||||
public const FIELD_ID = 'FingerprintId';
|
public const FIELD_ID = 'FingerprintId';
|
||||||
public const FIELD_FINGERPRINT = 'Fingerprint';
|
public const FIELD_FINGERPRINT = 'Fingerprint';
|
||||||
public const FIELD_USER = 'UserId';
|
public const FIELD_USER = 'UserId';
|
||||||
|
|
||||||
public function __construct($id = null, DatabaseInterface &$database = null)
|
public function __construct($id = null, DatabaseInterface &$database = null)
|
||||||
{
|
{
|
||||||
parent::__construct(self::class, $id, $database);
|
parent::__construct(self::class, $id, $database);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFingerprintId(): ?int
|
public function getFingerprintId(): ?int
|
||||||
{
|
{
|
||||||
if ($this->getPrimaryKey() === null) {
|
if ($this->getPrimaryKey() === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)$this->getPrimaryKey();
|
return (int)$this->getPrimaryKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFingerprint(): string
|
public function getFingerprint(): string
|
||||||
{
|
{
|
||||||
return $this->getField(self::FIELD_FINGERPRINT);
|
return $this->getField(self::FIELD_FINGERPRINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUserId(): int
|
public function getUserId(): int
|
||||||
{
|
{
|
||||||
return $this->getField(self::FIELD_USER);
|
return $this->getField(self::FIELD_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setFingerprint(string $fingerprint): void
|
public function setFingerprint(string $fingerprint): void
|
||||||
{
|
{
|
||||||
$this->setField(self::FIELD_FINGERPRINT, $fingerprint);
|
$this->setField(self::FIELD_FINGERPRINT, $fingerprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUserId(int $userId): void
|
public function setUserId(int $userId): void
|
||||||
{
|
{
|
||||||
$this->setField(self::FIELD_USER, $userId);
|
$this->setField(self::FIELD_USER, $userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function jsonSerialize(): array
|
public function jsonSerialize(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'fingerprintId' => $this->getFingerprintId(),
|
'fingerprintId' => $this->getFingerprintId(),
|
||||||
'fingerprint' => $this->getFingerprint(),
|
'fingerprint' => $this->getFingerprint(),
|
||||||
'userId' => $this->getUserId()
|
'userId' => $this->getUserId()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,42 +4,42 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class Sharing extends MySqlTable implements JsonSerializable
|
final class Sharing extends MySqlTable implements JsonSerializable
|
||||||
{
|
{
|
||||||
public const FIELD_USER = 'User';
|
public const FIELD_USER = 'User';
|
||||||
public const FIELD_USER_SHARED = 'UserShared';
|
public const FIELD_USER_SHARED = 'UserShared';
|
||||||
|
|
||||||
public function __construct($id = null, DatabaseInterface &$database = null)
|
public function __construct($id = null, DatabaseInterface &$database = null)
|
||||||
{
|
{
|
||||||
parent::__construct(self::class, $id, $database);
|
parent::__construct(self::class, $id, $database);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSharingId(): ?int
|
public function getSharingId(): ?int
|
||||||
{
|
{
|
||||||
if ($this->getPrimaryKey() === null) {
|
if ($this->getPrimaryKey() === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)$this->getPrimaryKey();
|
return (int)$this->getPrimaryKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUserId(): int
|
public function getUserId(): int
|
||||||
{
|
{
|
||||||
return $this->getField(self::FIELD_USER);
|
return $this->getField(self::FIELD_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUserShared(): int
|
public function getUserShared(): int
|
||||||
{
|
{
|
||||||
return $this->getField(self::FIELD_USER_SHARED);
|
return $this->getField(self::FIELD_USER_SHARED);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUserId(int $userId): void
|
public function setUserId(int $userId): void
|
||||||
{
|
{
|
||||||
$this->setField(self::FIELD_USER, $userId);
|
$this->setField(self::FIELD_USER, $userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUserShared(int $userShared): void
|
public function setUserShared(int $userShared): void
|
||||||
{
|
{
|
||||||
$this->setField(self::FIELD_USER_SHARED, $userShared);
|
$this->setField(self::FIELD_USER_SHARED, $userShared);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,141 +4,141 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class User extends MySqlTable implements JsonSerializable
|
final class User extends MySqlTable implements JsonSerializable
|
||||||
{
|
{
|
||||||
public const FIELD_ID = 'UserId';
|
public const FIELD_ID = 'UserId';
|
||||||
public const FIELD_USERNAME = 'Username';
|
public const FIELD_USERNAME = 'Username';
|
||||||
public const FIELD_PASSWORD = 'Password';
|
public const FIELD_PASSWORD = 'Password';
|
||||||
public const FIELD_EMAIL = 'Email';
|
public const FIELD_EMAIL = 'Email';
|
||||||
public const FIELD_JABBER_ADDRESS = 'JabberAddress';
|
public const FIELD_JABBER_ADDRESS = 'JabberAddress';
|
||||||
public const FIELD_ADMIN = 'IsAdmin';
|
public const FIELD_ADMIN = 'IsAdmin';
|
||||||
|
|
||||||
public function __construct($id = null, DatabaseInterface &$database = null)
|
public function __construct($id = null, DatabaseInterface &$database = null)
|
||||||
{
|
{
|
||||||
parent::__construct(self::class, $id, $database);
|
parent::__construct(self::class, $id, $database);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUserId(): ?int
|
public function getUserId(): ?int
|
||||||
{
|
{
|
||||||
if ($this->getPrimaryKey() === null) {
|
if ($this->getPrimaryKey() === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)$this->getPrimaryKey();
|
return (int)$this->getPrimaryKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUsername(): string
|
public function getUsername(): string
|
||||||
{
|
{
|
||||||
return $this->getField(self::FIELD_USERNAME);
|
return $this->getField(self::FIELD_USERNAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPassword(): string
|
public function getPassword(): string
|
||||||
{
|
{
|
||||||
return $this->getField(self::FIELD_PASSWORD);
|
return $this->getField(self::FIELD_PASSWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getEmail(): string
|
public function getEmail(): string
|
||||||
{
|
{
|
||||||
return $this->getField(self::FIELD_EMAIL);
|
return $this->getField(self::FIELD_EMAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getJabberAddress(): string
|
public function getJabberAddress(): string
|
||||||
{
|
{
|
||||||
return $this->getField(self::FIELD_JABBER_ADDRESS);
|
return $this->getField(self::FIELD_JABBER_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isAdmin(): bool
|
public function isAdmin(): bool
|
||||||
{
|
{
|
||||||
return $this->getField(self::FIELD_ADMIN);
|
return $this->getField(self::FIELD_ADMIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUsername(string $username): void
|
public function setUsername(string $username): void
|
||||||
{
|
{
|
||||||
$this->setField(self::FIELD_USERNAME, $username);
|
$this->setField(self::FIELD_USERNAME, $username);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPassword(string $password): void
|
public function setPassword(string $password): void
|
||||||
{
|
{
|
||||||
$this->setField(self::FIELD_PASSWORD, $password);
|
$this->setField(self::FIELD_PASSWORD, $password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setEmail(string $email): void
|
public function setEmail(string $email): void
|
||||||
{
|
{
|
||||||
$this->setField(self::FIELD_EMAIL, $email);
|
$this->setField(self::FIELD_EMAIL, $email);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setJabberAddress(string $jabberAddress): void
|
public function setJabberAddress(string $jabberAddress): void
|
||||||
{
|
{
|
||||||
$this->setField(self::FIELD_JABBER_ADDRESS, $jabberAddress);
|
$this->setField(self::FIELD_JABBER_ADDRESS, $jabberAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAdmin(bool $isAdmin): void
|
public function setAdmin(bool $isAdmin): void
|
||||||
{
|
{
|
||||||
$this->setField(self::FIELD_ADMIN, $isAdmin);
|
$this->setField(self::FIELD_ADMIN, $isAdmin);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getFromUsername(string $username, DatabaseInterface &$database = null): self
|
public static function getFromUsername(string $username, DatabaseInterface &$database = null): self
|
||||||
{
|
{
|
||||||
$databaseGiven = true;
|
$databaseGiven = true;
|
||||||
|
|
||||||
if ($database === null) {
|
if ($database === null) {
|
||||||
$database = new MySqlDatabase();
|
$database = new MySqlDatabase();
|
||||||
$databaseGiven = false;
|
$databaseGiven = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($database->Count(self::class, [self::FIELD_USERNAME => $username]) === 0) {
|
if ($database->Count(self::class, [self::FIELD_USERNAME => $username]) === 0) {
|
||||||
throw new UserException(sprintf('No user with name %s found!', $username));
|
throw new UserException(sprintf('No user with name %s found!', $username));
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = $database->Select(self::class, [self::FIELD_ID], [self::FIELD_USERNAME => $username])[0][self::FIELD_ID];
|
$id = $database->Select(self::class, [self::FIELD_ID], [self::FIELD_USERNAME => $username])[0][self::FIELD_ID];
|
||||||
|
|
||||||
$user = $databaseGiven ? new User((int)$id, $database) : new User((int)$id);
|
$user = $databaseGiven ? new User((int)$id, $database) : new User((int)$id);
|
||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getFromEmail(string $email, DatabaseInterface &$database = null): self
|
public static function getFromEmail(string $email, DatabaseInterface &$database = null): self
|
||||||
{
|
{
|
||||||
$databaseGiven = true;
|
$databaseGiven = true;
|
||||||
|
|
||||||
if ($database === null) {
|
if ($database === null) {
|
||||||
$database = new MySqlDatabase();
|
$database = new MySqlDatabase();
|
||||||
$databaseGiven = false;
|
$databaseGiven = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($database->Count(self::class) === 0) {
|
if ($database->Count(self::class) === 0) {
|
||||||
throw new UserException(sprintf('No user with email %s found!', $email));
|
throw new UserException(sprintf('No user with email %s found!', $email));
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = $database->Select(self::class, [self::FIELD_ID], [self::FIELD_EMAIL => $email])[0][self::FIELD_ID];
|
$id = $database->Select(self::class, [self::FIELD_ID], [self::FIELD_EMAIL => $email])[0][self::FIELD_ID];
|
||||||
|
|
||||||
$user = $databaseGiven ? new User((int)$id, $database) : new User((int)$id);
|
$user = $databaseGiven ? new User((int)$id, $database) : new User((int)$id);
|
||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFingerprintIds(): array
|
public function getFingerprintIds(): array
|
||||||
{
|
{
|
||||||
$result = $this->database->Select(
|
$result = $this->database->Select(
|
||||||
Fingerprint::class,
|
Fingerprint::class,
|
||||||
[Fingerprint::FIELD_ID],
|
[Fingerprint::FIELD_ID],
|
||||||
[Fingerprint::FIELD_USER => $this->getUserId()]
|
[Fingerprint::FIELD_USER => $this->getUserId()]
|
||||||
);
|
);
|
||||||
|
|
||||||
$ids = [];
|
$ids = [];
|
||||||
|
|
||||||
foreach ($result as $record) {
|
foreach ($result as $record) {
|
||||||
$ids[] = (int)$record[Fingerprint::FIELD_ID];
|
$ids[] = (int)$record[Fingerprint::FIELD_ID];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ids;
|
return $ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'userId' => $this->getUserId(),
|
'userId' => $this->getUserId(),
|
||||||
'username' => $this->getUsername(),
|
'username' => $this->getUsername(),
|
||||||
'jabberAddress' => $this->getJabberAddress(),
|
'jabberAddress' => $this->getJabberAddress(),
|
||||||
'fingerprintIds' => $this->getFingerprintIds()
|
'fingerprintIds' => $this->getFingerprintIds()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,5 +4,5 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class DatabaseException extends Exception
|
final class DatabaseException extends Exception
|
||||||
{
|
{
|
||||||
public const CONNECTION_FAILED = 1;
|
public const CONNECTION_FAILED = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,14 @@ declare(strict_types=1);
|
||||||
|
|
||||||
final class Setting
|
final class Setting
|
||||||
{
|
{
|
||||||
public const MYSQL_HOST = \':HOST\';
|
public const MYSQL_HOST = \':HOST\';
|
||||||
public const MYSQL_USER = \':USER\';
|
public const MYSQL_USER = \':USER\';
|
||||||
public const MYSQL_PASSWORD = \':PASSWORD\';
|
public const MYSQL_PASSWORD = \':PASSWORD\';
|
||||||
public const MYSQL_DATABASE = \':DATABASE\';
|
public const MYSQL_DATABASE = \':DATABASE\';
|
||||||
|
|
||||||
public const PATH_ROOT = \':ROOT_PATH/\';
|
public const PATH_ROOT = \':ROOT_PATH/\';
|
||||||
public const PATH_QR_CODES = self::PATH_ROOT . \'backend/qr/\';
|
public const PATH_QR_CODES = self::PATH_ROOT . \'backend/qr/\';
|
||||||
public const PATH_TMP = self::PATH_ROOT . \'backend/tmp/\';
|
public const PATH_TMP = self::PATH_ROOT . \'backend/tmp/\';
|
||||||
}
|
}
|
||||||
';
|
';
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue