Compare commits
No commits in common. "a85cdc63561bbd04e4b8b0e5901e38e9c6fafc59" and "5ce2215e44ed62bab95500eaf87093361c350bb4" have entirely different histories.
a85cdc6356
...
5ce2215e44
@ -9,23 +9,8 @@ use Khofmann\Input\Input;
|
||||
use Khofmann\Response\Response;
|
||||
use Khofmann\Models\User\User;
|
||||
|
||||
/**
|
||||
* Login route handlers
|
||||
*/
|
||||
class Login extends Api
|
||||
{
|
||||
/**
|
||||
* Login POST handler
|
||||
*
|
||||
* Log in a user. Required inputs are `email` and `password`.
|
||||
*
|
||||
* Returns user and tokens
|
||||
*
|
||||
* @throws 400 Missing field
|
||||
* @throws 401 Invalid credentials (login fails)
|
||||
* @throws 404 User not found
|
||||
* @throws 500 Failed to log in user
|
||||
*/
|
||||
public function post(): void
|
||||
{
|
||||
// Fetch all required inputs.
|
||||
|
||||
@ -7,20 +7,8 @@ use Khofmann\Models\User\User;
|
||||
use Khofmann\Request\Request;
|
||||
use Khofmann\Response\Response;
|
||||
|
||||
/**
|
||||
* Logout route handlers
|
||||
*/
|
||||
class Logout extends Api
|
||||
{
|
||||
/**
|
||||
* Logout POST handler
|
||||
*
|
||||
* Logout a user. User is retrieved using the authentication `token`.
|
||||
*
|
||||
* Returns user.
|
||||
*
|
||||
* @throws 404 User not found
|
||||
*/
|
||||
public function post(): void
|
||||
{
|
||||
// Get user auth token.
|
||||
|
||||
@ -11,16 +11,8 @@ use Khofmann\Models\User\User;
|
||||
use Khofmann\Request\Request;
|
||||
use Khofmann\Response\Response;
|
||||
|
||||
/**
|
||||
* Posts route handlers
|
||||
*/
|
||||
class Posts extends Api
|
||||
{
|
||||
/**
|
||||
* Posts GET handler
|
||||
*
|
||||
* Lists posts. Optional parameters are `l` (limit of returned list) and `p` (page, i.e. offset).
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
// Fetch and constrain all parameters.
|
||||
@ -32,15 +24,6 @@ class Posts extends Api
|
||||
Response::json(Post::list($page, $limit, $authed));
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts POST handler
|
||||
*
|
||||
* Create a new posts. Required inputs are `content`. Optional parameter is `l` (limit of list for which the returned pages is calculated).
|
||||
*
|
||||
* Returns created post and resulting amount of pages for a given limit.
|
||||
*
|
||||
* @throws 400 Missing fields
|
||||
*/
|
||||
public function post(): void
|
||||
{
|
||||
// Fetch all required inputs.
|
||||
@ -64,19 +47,6 @@ class Posts extends Api
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts PATCH handler
|
||||
*
|
||||
* Update a posts.
|
||||
*
|
||||
* Returns updated post.
|
||||
*
|
||||
* @param mixed $id ID of post to update
|
||||
*
|
||||
* @throws 401 Not authorized (trying to edit a different users post if not admin)
|
||||
* @throws 404 Post not found
|
||||
* @throws 500 Failed to update user
|
||||
*/
|
||||
public function patch($id): void
|
||||
{
|
||||
// Fetch all inputs.
|
||||
@ -105,20 +75,9 @@ class Posts extends Api
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts DELETE handler
|
||||
*
|
||||
* Delete a post. Optional parameter is `l` (limit of list for which the returned pages is calculated).
|
||||
*
|
||||
* Returns deleted post and resulting amount of pages for a given limit.
|
||||
*
|
||||
* @param mixed $id ID of posts to delete
|
||||
*
|
||||
* @throws 404 Post not found
|
||||
*/
|
||||
public function delete($id): void
|
||||
{
|
||||
// Fetch and constrain all parameters.
|
||||
// Fetch ax(0, intval(Input::get("p", 0)));
|
||||
$limit = constrain(0, 30, intval(Input::get("l", 10)));
|
||||
// Try delete, 404 if post was not found.
|
||||
try {
|
||||
|
||||
@ -10,22 +10,8 @@ use Khofmann\Response\Response;
|
||||
use Khofmann\Models\User\User;
|
||||
use Khofmann\Request\Request;
|
||||
|
||||
/**
|
||||
* Refresh route handlers
|
||||
*/
|
||||
class Refresh extends Api
|
||||
{
|
||||
/**
|
||||
* Refresh POST handler
|
||||
*
|
||||
* Refresh a users session. User is retrieved using the authentication `token`.
|
||||
*
|
||||
* Returns user and tokens.
|
||||
*
|
||||
* @throws 401 Missing field
|
||||
* @throws 404 User not found
|
||||
* @throws 500 Failed to refresh tokens
|
||||
*/
|
||||
public function post(): void
|
||||
{
|
||||
// Fetch all required inputs.
|
||||
|
||||
@ -9,22 +9,8 @@ use Khofmann\Input\Input;
|
||||
use Khofmann\Response\Response;
|
||||
use Khofmann\Models\User\User;
|
||||
|
||||
/**
|
||||
* Register route handlers
|
||||
*/
|
||||
class Register extends Api
|
||||
{
|
||||
/**
|
||||
* Register POST handler
|
||||
*
|
||||
* Register a new user. Required inputs are `username`, `email`, and `password`.
|
||||
*
|
||||
* Returns user.
|
||||
*
|
||||
* @throws 400 Missing fields
|
||||
* @throws 400 Duplicate
|
||||
* @throws 404 Failure to create
|
||||
*/
|
||||
public function post(): void
|
||||
{
|
||||
// Fetch all required inputs.
|
||||
@ -53,17 +39,6 @@ class Register extends Api
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register PATCH handler
|
||||
*
|
||||
* Confirms a user. Required input is `code`.
|
||||
*
|
||||
* Returns user.
|
||||
*
|
||||
* @throws 400 Missing field
|
||||
* @throws 404 User not found
|
||||
* @throws 404 User already confirmed
|
||||
*/
|
||||
public function patch(): void
|
||||
{
|
||||
// Fetch all required inputs.
|
||||
|
||||
@ -10,23 +10,8 @@ use Khofmann\Response\Response;
|
||||
use Khofmann\ApiError\ApiError;
|
||||
use Khofmann\Request\Request;
|
||||
|
||||
/**
|
||||
* User image route handlers
|
||||
*/
|
||||
class Image extends Api
|
||||
{
|
||||
/**
|
||||
* Image POST handler
|
||||
*
|
||||
* Set a new user image.
|
||||
*
|
||||
* Returns updated user.
|
||||
*
|
||||
* @param mixed $id User ID
|
||||
*
|
||||
* @throws 404 User not found
|
||||
* @throws 500 Failed to update user image
|
||||
*/
|
||||
public function post($id): void
|
||||
{
|
||||
// Fetch all inputs.
|
||||
@ -48,16 +33,6 @@ class Image extends Api
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Image POST handler
|
||||
*
|
||||
* Set a new user image. User is retrieved using the authentication `token`.
|
||||
*
|
||||
* Returns updated user.
|
||||
*
|
||||
* @throws 404 User not found
|
||||
* @throws 500 Failed to update user image
|
||||
*/
|
||||
public function postSelf(): void
|
||||
{
|
||||
// Fetch all inputs.
|
||||
|
||||
@ -9,20 +9,8 @@ use Khofmann\Response\Response;
|
||||
use Khofmann\ApiError\ApiError;
|
||||
use Khofmann\Input\Input;
|
||||
|
||||
/**
|
||||
* User posts route handlers
|
||||
*/
|
||||
class Posts extends Api
|
||||
{
|
||||
/**
|
||||
* Posts GET handler
|
||||
*
|
||||
* Lists posts for a user. Optional parameters are `l` (limit of returned list), `p` (page, i.e. offset), `s` (sort order).
|
||||
*
|
||||
* Returns list of posts.
|
||||
*
|
||||
* @throws 404 User not found
|
||||
*/
|
||||
public function get($id): void
|
||||
{
|
||||
// Fetch and constrain all parameters.
|
||||
|
||||
@ -10,18 +10,8 @@ use Khofmann\Response\Response;
|
||||
use Khofmann\ApiError\ApiError;
|
||||
use Khofmann\Request\Request;
|
||||
|
||||
/**
|
||||
* Users route handlers
|
||||
*/
|
||||
class Users extends Api
|
||||
{
|
||||
/**
|
||||
* Users GET handler
|
||||
*
|
||||
* Lists users. Optional parameters are `l` (limit of returned list) and `p` (page, i.e. offset).
|
||||
*
|
||||
* Returns list of users.
|
||||
*/
|
||||
public function list()
|
||||
{
|
||||
// Fetch and constrain all parameters.
|
||||
@ -32,17 +22,6 @@ class Users extends Api
|
||||
Response::json(User::list($page, $limit));
|
||||
}
|
||||
|
||||
/**
|
||||
* User GET handler
|
||||
*
|
||||
* Get a single user.
|
||||
*
|
||||
* Returns user.
|
||||
*
|
||||
* @param mixed $id User ID
|
||||
*
|
||||
* @throws 404 User not found
|
||||
*/
|
||||
public function get($id): void
|
||||
{
|
||||
// Try and get a user, 404 if not found.
|
||||
@ -58,18 +37,6 @@ class Users extends Api
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Users PATCH handler
|
||||
*
|
||||
* Update a user.
|
||||
*
|
||||
* Returns updated user.
|
||||
*
|
||||
* @param mixed $id User ID
|
||||
*
|
||||
* @throws 404 User not found
|
||||
* @throws 500 Failed to update user
|
||||
*/
|
||||
public function patch($id): void
|
||||
{
|
||||
// Fetch all inputs.
|
||||
@ -92,16 +59,6 @@ class Users extends Api
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Users PATCH handler
|
||||
*
|
||||
* Update a user. User is retrieved using the authentication `token`.
|
||||
*
|
||||
* Returns updated user.
|
||||
*
|
||||
* @throws 404 User not found
|
||||
* @throws 500 Failed to update user
|
||||
*/
|
||||
public function patchSelf(): void
|
||||
{
|
||||
// Fetch all inputs.
|
||||
@ -125,24 +82,11 @@ class Users extends Api
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Users DELETE handler
|
||||
*
|
||||
* Deletes a user. Optional parameter is `l` (limit of list for which the returned pages is calculated).
|
||||
*
|
||||
* Returns deleted user and resulting amount of pages for a given limit.
|
||||
*
|
||||
* @param mixed $id User ID
|
||||
*
|
||||
* @throws 404 User not found
|
||||
*/
|
||||
public function delete($id): void
|
||||
{
|
||||
// Fetch and constrain all parameters.
|
||||
$limit = constrain(0, 30, intval(Input::get("l", 10)));
|
||||
// Try to delete user, 404 if not found.
|
||||
try {
|
||||
Response::json(User::getByID($id)->delete($limit));
|
||||
Response::json(User::getByID($id)->delete());
|
||||
} catch (Exception $err) {
|
||||
switch ($err->getMessage()) {
|
||||
case "NotFound":
|
||||
|
||||
@ -560,21 +560,13 @@ paths:
|
||||
schema:
|
||||
type: integer
|
||||
format: int14
|
||||
- in: query
|
||||
name: l
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 30
|
||||
default: 10
|
||||
description: Number of items per page, influences returned pages count.
|
||||
responses:
|
||||
200:
|
||||
description: Success.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UserDeleteResponse"
|
||||
$ref: "#/components/schemas/UserResponse"
|
||||
404:
|
||||
description: User not found.
|
||||
content:
|
||||
@ -911,13 +903,6 @@ components:
|
||||
refreshToken:
|
||||
type: string
|
||||
format: uuid4
|
||||
UserDeleteResponse:
|
||||
type: object
|
||||
properties:
|
||||
pages:
|
||||
type: number
|
||||
post:
|
||||
$ref: "#/components/schemas/UserResponse"
|
||||
securitySchemes:
|
||||
BasicAuth:
|
||||
type: apiKey
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -4,11 +4,6 @@ namespace Khofmann\Api;
|
||||
|
||||
use Khofmann\Response\Response;
|
||||
|
||||
/**
|
||||
* Base class for all API handler classes.
|
||||
*
|
||||
* Sets common headers
|
||||
*/
|
||||
class Api
|
||||
{
|
||||
public function __construct()
|
||||
|
||||
@ -4,9 +4,6 @@ namespace Khofmann\ApiError;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Facade for common API errors
|
||||
*/
|
||||
class ApiError extends Exception
|
||||
{
|
||||
private function __construct($message = "", $code = 0)
|
||||
@ -14,11 +11,6 @@ class ApiError extends Exception
|
||||
parent::__construct($message, $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error for missing fields
|
||||
*
|
||||
* @param array $fields Array of strings denoting which fields were missing
|
||||
*/
|
||||
public static function missingField(array $fields): ApiError
|
||||
{
|
||||
return new ApiError(json_encode([
|
||||
@ -27,11 +19,6 @@ class ApiError extends Exception
|
||||
]), 400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error for duplicates
|
||||
*
|
||||
* @param string entity Entity for which a duplicate exists
|
||||
*/
|
||||
public static function duplicate(string $entity): ApiError
|
||||
{
|
||||
return new ApiError(json_encode([
|
||||
@ -40,11 +27,6 @@ class ApiError extends Exception
|
||||
]), 400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error for missing permissions
|
||||
*
|
||||
* @param string message Message specifics
|
||||
*/
|
||||
public static function notAllowed(string $message)
|
||||
{
|
||||
return new ApiError(json_encode([
|
||||
@ -53,11 +35,6 @@ class ApiError extends Exception
|
||||
]), 401);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error for missing authentication
|
||||
*
|
||||
* @param string $message Message specifics
|
||||
*/
|
||||
public static function unauthorized(string $message)
|
||||
{
|
||||
return new ApiError(json_encode([
|
||||
@ -66,11 +43,6 @@ class ApiError extends Exception
|
||||
]), 401);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error for not found
|
||||
*
|
||||
* @param string entity Entity for which a duplicate exists
|
||||
*/
|
||||
public static function notFound(string $entity)
|
||||
{
|
||||
return new ApiError(json_encode([
|
||||
@ -79,11 +51,6 @@ class ApiError extends Exception
|
||||
]), 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic error
|
||||
*
|
||||
* @param string message Message specifics
|
||||
*/
|
||||
public static function failed(string $message)
|
||||
{
|
||||
return new ApiError(json_encode([
|
||||
@ -92,12 +59,6 @@ class ApiError extends Exception
|
||||
]), 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error for missing fields
|
||||
*
|
||||
* @param array $fields Array of strings denoting which fields failed
|
||||
* @param array $fields Array of strings denoting why the fields failed
|
||||
*/
|
||||
public static function failedUpdate(array $fields, array $reasons)
|
||||
{
|
||||
return new ApiError(json_encode([
|
||||
|
||||
@ -8,20 +8,8 @@ use Pecee\Http\Request;
|
||||
use Khofmann\Models\User\User;
|
||||
use Khofmann\Response\Response;
|
||||
|
||||
/**
|
||||
* Middleware for admin authenticated routes
|
||||
*/
|
||||
class AdminAuth implements IMiddleware
|
||||
{
|
||||
/**
|
||||
* Request handler
|
||||
*
|
||||
* Returns 401 if `token`is missing, no user is found with the `token`or user is not admin.
|
||||
*
|
||||
* Keeps session fresh if request is authenticated.
|
||||
*
|
||||
* @param Request $request Incoming request
|
||||
*/
|
||||
public function handle(Request $request): void
|
||||
{
|
||||
$token = $request->getHeader("token");
|
||||
@ -38,9 +26,7 @@ class AdminAuth implements IMiddleware
|
||||
}
|
||||
|
||||
try {
|
||||
// Get user
|
||||
$user = User::getByToken($token);
|
||||
// Check if user is admin
|
||||
if (!$user->getIsAdmin()) {
|
||||
Response::response()
|
||||
->header("Cache-control: no-cache")
|
||||
|
||||
@ -8,20 +8,8 @@ use Pecee\Http\Request;
|
||||
use Khofmann\Models\User\User;
|
||||
use Khofmann\Response\Response;
|
||||
|
||||
/**
|
||||
* Middleware for authenticated routes
|
||||
*/
|
||||
class Auth implements IMiddleware
|
||||
{
|
||||
/**
|
||||
* Request handler
|
||||
*
|
||||
* Returns 401 if `token`is missing, or no user is found with the `token`.
|
||||
*
|
||||
* Keeps session fresh if request is authenticated.
|
||||
*
|
||||
* @param Request $request Incoming request
|
||||
*/
|
||||
public function handle(Request $request): void
|
||||
{
|
||||
$token = $request->getHeader("token");
|
||||
@ -38,7 +26,6 @@ class Auth implements IMiddleware
|
||||
}
|
||||
|
||||
try {
|
||||
// Get user
|
||||
$user = User::getByToken($token);
|
||||
|
||||
// Keep fresh
|
||||
|
||||
@ -8,31 +8,18 @@ use Pecee\Http\Request;
|
||||
use Khofmann\Models\User\User;
|
||||
use Khofmann\Response\Response;
|
||||
|
||||
/**
|
||||
* Middleware for optional authenticated routes
|
||||
*/
|
||||
class OptAuth implements IMiddleware
|
||||
{
|
||||
/**
|
||||
* Request handler
|
||||
*
|
||||
* Returns 401 if no user is found with the `token`.
|
||||
*
|
||||
* Keeps session fresh if request is authenticated.
|
||||
*
|
||||
* @param Request $request Incoming request
|
||||
*/
|
||||
public function handle(Request $request): void
|
||||
{
|
||||
$token = $request->getHeader("token");
|
||||
|
||||
// No token, since authentication is optional, pass
|
||||
// No token
|
||||
if ($token === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Get user
|
||||
$user = User::getByToken($token);
|
||||
|
||||
// Keep fresh
|
||||
|
||||
@ -4,50 +4,29 @@ namespace Khofmann\Config;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Facade for application configuration
|
||||
*/
|
||||
class Config
|
||||
{
|
||||
// Instances array to ensure singleton pattern
|
||||
private static array $instances = [];
|
||||
|
||||
// Configuration arrays
|
||||
private array $app;
|
||||
private array $database;
|
||||
|
||||
/**
|
||||
* Loads configurations into arrays.
|
||||
*
|
||||
* Private since singleton pattern.
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->app = require_once __DIR__ . "/../../config/app.php";
|
||||
$this->database = require_once __DIR__ . "/../../config/database.php";
|
||||
}
|
||||
|
||||
/**
|
||||
* Disallow clone
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
throw new Exception("Cannot clone a singleton.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Disallow wakeup
|
||||
*/
|
||||
private function __wakeup()
|
||||
{
|
||||
throw new Exception("Cannot unserialize a singleton.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance. Ensures singleton pattern.
|
||||
*
|
||||
* Private to ensure only facade methods can be used.
|
||||
*/
|
||||
private static function getInstance(): Config
|
||||
{
|
||||
$cls = static::class;
|
||||
@ -58,57 +37,36 @@ class Config
|
||||
return self::$instances[$cls];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Application base URI path
|
||||
*/
|
||||
public static function getBasePath(): string
|
||||
{
|
||||
return Config::getInstance()->app["basePath"];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Application base file system path
|
||||
*/
|
||||
public static function getBaseFSPath(): string
|
||||
{
|
||||
return Config::getInstance()->app["baseFSPath"];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Application storage URI path
|
||||
*/
|
||||
public static function getStoragePath(): string
|
||||
{
|
||||
return Config::getInstance()->app["storagePath"];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Application storage file system path
|
||||
*/
|
||||
public static function getStorageFSPath(): string
|
||||
{
|
||||
return Config::getInstance()->app["storageFSPath"];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Application base URI path
|
||||
*/
|
||||
public static function getDatabase(): array
|
||||
{
|
||||
return Config::getInstance()->database;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Application base URI path
|
||||
*/
|
||||
public static function getTokenExpiry(): string
|
||||
{
|
||||
return Config::getInstance()->app["tokenExpiry"];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Application base URI path
|
||||
*/
|
||||
public static function getRefreshTokenExpiry(): string
|
||||
{
|
||||
return Config::getInstance()->app["refreshTokenExpiry"];
|
||||
|
||||
@ -6,43 +6,25 @@ use PDO;
|
||||
use Khofmann\Config\Config;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Facade for database access
|
||||
*/
|
||||
class Database extends PDO
|
||||
{
|
||||
// Instances array to ensure singleton pattern
|
||||
private static array $instances = [];
|
||||
|
||||
/**
|
||||
* Private since singleton pattern.
|
||||
*/
|
||||
private function __construct(string $dsn, string $username = null, string $password = null, array $options = null)
|
||||
{
|
||||
parent::__construct($dsn, $username, $password, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disallow clone
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
throw new Exception("Cannot clone a singleton.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Disallow wakeup
|
||||
*/
|
||||
private function __wakeup()
|
||||
{
|
||||
throw new Exception("Cannot unserialize a singleton.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance. Ensures singleton pattern.
|
||||
*
|
||||
* Loads configuration from `Config` facade
|
||||
*/
|
||||
public static function getInstance(): Database
|
||||
{
|
||||
$cls = static::class;
|
||||
|
||||
@ -2,25 +2,12 @@
|
||||
|
||||
namespace Khofmann\GUID;
|
||||
|
||||
/**
|
||||
* Facade for GUID generators
|
||||
*/
|
||||
class GUID
|
||||
{
|
||||
/**
|
||||
* Private since facade.
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a UUID v4.
|
||||
*
|
||||
* @param mixed $data Optional data
|
||||
*
|
||||
* @return string UUID v4
|
||||
*/
|
||||
public static function v4($data = null): string
|
||||
{
|
||||
// Generate 16 bytes (128 bits) of random data or use the data passed into the function.
|
||||
|
||||
@ -4,60 +4,30 @@ namespace Khofmann\Input;
|
||||
|
||||
use Khofmann\Request\Request;
|
||||
|
||||
/**
|
||||
* Facade for Input (wraps SimpleRouter)
|
||||
*/
|
||||
class Input
|
||||
{
|
||||
/**
|
||||
* Private since facade.
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get POST parameter.
|
||||
*
|
||||
* @param string $index Parameter name
|
||||
* @param mixed $defaultValue Default value if parameter was null
|
||||
*/
|
||||
public static function post(string $index, $defaultValue = null)
|
||||
{
|
||||
$value = Request::request()->getInputHandler()->post($index, $defaultValue);
|
||||
return !is_object($value) ? $value : $value->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PATCH parameter.
|
||||
*
|
||||
* @param string $index Parameter name
|
||||
* @param mixed $defaultValue Default value if parameter was null
|
||||
*/
|
||||
public static function patch(string $index, $defaultValue = null)
|
||||
{
|
||||
$value = Request::request()->getInputHandler()->post($index, $defaultValue);
|
||||
return !is_object($value) ? $value : $value->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query string parameter.
|
||||
*
|
||||
* @param string $index Parameter name
|
||||
* @param mixed $defaultValue Default value if parameter was null
|
||||
*/
|
||||
public static function get(string $index, $defaultValue = null)
|
||||
{
|
||||
$value = Request::request()->getInputHandler()->get($index, $defaultValue);
|
||||
return !is_object($value) ? $value : $value->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get FILE entry.
|
||||
*
|
||||
* @param string $index File name
|
||||
* @param mixed $defaultValue Default value if parameter was null
|
||||
*/
|
||||
public static function file(string $index, $defaultValue = null)
|
||||
{
|
||||
$value = Request::request()->getInputHandler()->file($index, $defaultValue);
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Khofmann\Models\Post;
|
||||
|
||||
use Api\User\User as UserUser;
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use Khofmann\Models\User\User;
|
||||
@ -11,11 +12,6 @@ use Khofmann\Config\Config;
|
||||
use Khofmann\Database\Database;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Post database model
|
||||
*
|
||||
* Abstracts database access
|
||||
*/
|
||||
class Post implements JsonSerializable
|
||||
{
|
||||
private int $id;
|
||||
@ -41,16 +37,6 @@ class Post implements JsonSerializable
|
||||
* Statics
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get a post by ID.
|
||||
*
|
||||
* Also get creator (`User` object).
|
||||
*
|
||||
* @param int $id Post ID
|
||||
*
|
||||
* @throws NotFound Post not found
|
||||
* @throws NotFound Creator of post was not found
|
||||
*/
|
||||
public static function getByID(int $id): Post
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -73,15 +59,6 @@ class Post implements JsonSerializable
|
||||
return new Post($data["id"], $user, null, null, $data["beitrag"], $data["zeitstempel"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new post.
|
||||
*
|
||||
* @param User $user Creator of post
|
||||
* @param string $content Post content
|
||||
* @param int $limit Limit for posts list to calculate number of pages
|
||||
*
|
||||
* @return array Number of pages after creation (in accordance with `limit`) and created post
|
||||
*/
|
||||
public static function create(User $user, string $content, int $limit): array
|
||||
{
|
||||
$content = substr(trim($content), 0, 250);
|
||||
@ -114,15 +91,6 @@ class Post implements JsonSerializable
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* List of posts
|
||||
*
|
||||
* @param int $page Current page (offset)
|
||||
* @param int $limit Posts per page
|
||||
* @param bool $authed If `true`, include full `User` object. Defaults to `false`
|
||||
*
|
||||
* @return array Number of pages and posts of selected page
|
||||
*/
|
||||
public static function list(int $page, int $limit, bool $authed = false): array
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -160,20 +128,10 @@ class Post implements JsonSerializable
|
||||
* Members
|
||||
*/
|
||||
|
||||
/**
|
||||
* Update post
|
||||
*
|
||||
* Does nothing if new `content` is empty
|
||||
*
|
||||
* @param ?string $content New content
|
||||
*
|
||||
* @throws Failed Failed to update content
|
||||
*/
|
||||
public function update(?string $content): Post
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
|
||||
// Make sure we do all changes or none
|
||||
$db->beginTransaction();
|
||||
|
||||
$failed = [];
|
||||
@ -198,25 +156,16 @@ class Post implements JsonSerializable
|
||||
}
|
||||
}
|
||||
if (count($failed) > 0) {
|
||||
// We failed, go back
|
||||
$db->rollBack();
|
||||
|
||||
throw ApiError::failedUpdate($failed, $reason);
|
||||
}
|
||||
|
||||
// Commit the changes
|
||||
$db->commit();
|
||||
|
||||
return Post::getByID($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete post
|
||||
*
|
||||
* @param int $limit Limit of list for which the returned pages is calculated.
|
||||
*
|
||||
* @return array Returns deleted post and resulting amount of pages for a given limit.
|
||||
*/
|
||||
public function delete(int $limit): array
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -240,33 +189,21 @@ class Post implements JsonSerializable
|
||||
* Getters
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get post ID
|
||||
*/
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post creator
|
||||
*/
|
||||
public function getUser(): User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post content
|
||||
*/
|
||||
public function getContent(): string
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time when post was created
|
||||
*/
|
||||
public function getPostedAt(): DateTime
|
||||
{
|
||||
return $this->postedAt;
|
||||
|
||||
@ -11,12 +11,8 @@ use JsonSerializable;
|
||||
use Khofmann\ApiError\ApiError;
|
||||
use Khofmann\GUID\GUID;
|
||||
use Khofmann\Models\Post\Post;
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* User database model
|
||||
*
|
||||
* Abstracts database access
|
||||
*/
|
||||
class User implements JsonSerializable
|
||||
{
|
||||
private int $id;
|
||||
@ -40,13 +36,6 @@ class User implements JsonSerializable
|
||||
$this->postCount = $postCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user by their confirmation code.
|
||||
*
|
||||
* @param string $code Confirmation code
|
||||
*
|
||||
* @throws NotFound User not found
|
||||
*/
|
||||
private static function getByConfirmCode(string $code): User
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -73,13 +62,6 @@ class User implements JsonSerializable
|
||||
* Statics
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get a user by ID.
|
||||
*
|
||||
* @param int $id User ID
|
||||
*
|
||||
* @throws NotFound User not found
|
||||
*/
|
||||
public static function getByID(int $id): User
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -101,13 +83,6 @@ class User implements JsonSerializable
|
||||
return new User($id, $data["benutzer"], $data["status"], $data["email"], $data["zeitstempel"], $data["image"], $data["isadmin"] === 1, $data["postCount"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user by their email.
|
||||
*
|
||||
* @param string $email User email
|
||||
*
|
||||
* @throws NotFound User not found
|
||||
*/
|
||||
public static function getByEmail(string $email): User
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -129,13 +104,6 @@ class User implements JsonSerializable
|
||||
return new User($data["id"], $data["benutzer"], $data["status"], $email, $data["zeitstempel"], $data["image"], $data["isadmin"] === 1, $data["postCount"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user by their authentication token.
|
||||
*
|
||||
* @param string $token Authentication token
|
||||
*
|
||||
* @throws NotFound User not found
|
||||
*/
|
||||
public static function getByToken(string $token): User
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -158,18 +126,6 @@ class User implements JsonSerializable
|
||||
return new User($data["id"], $data["benutzer"], $data["status"], $data["email"], $data["zeitstempel"], $data["image"], $data["isadmin"] === 1, $data["postCount"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log in a user
|
||||
*
|
||||
* @param string $email User email
|
||||
* @param string $password USer password
|
||||
*
|
||||
* @return array Tokens and user
|
||||
*
|
||||
* @throws Failed Could not generate tokens
|
||||
* @throws Invalid Password was wrong
|
||||
* @throws NotFound User not found (email wrong)
|
||||
*/
|
||||
public static function logIn(string $email, string $password): array
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -235,15 +191,6 @@ class User implements JsonSerializable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a user
|
||||
*
|
||||
* @param string $username Username
|
||||
* @param string $email User email
|
||||
* @param string $password User password
|
||||
*
|
||||
* @throws Duplicate User with this username or email already exists
|
||||
*/
|
||||
public static function create(string $username, string $email, string $password): User
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -278,13 +225,6 @@ class User implements JsonSerializable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm a user
|
||||
*
|
||||
* @param string $confirmCode Confirmation code
|
||||
*
|
||||
* @throws NotFound User not found (invalid code or already confirmed)
|
||||
*/
|
||||
public static function confirm(string $confirmCode): User
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -303,14 +243,6 @@ class User implements JsonSerializable
|
||||
return User::getByID($user->getID());
|
||||
}
|
||||
|
||||
/**
|
||||
* List of users
|
||||
*
|
||||
* @param int $page Current page (offset)
|
||||
* @param int $limit Users per page
|
||||
*
|
||||
* @return array Number of pages and posts of selected page
|
||||
*/
|
||||
public static function list(int $page, int $limit)
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -342,15 +274,6 @@ class User implements JsonSerializable
|
||||
return ["pages" => intdiv($count, $limit + 1), "data" => $list];
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh a user session
|
||||
*
|
||||
* @param string $token Authentication token
|
||||
* @param string $refreshToken Refresh token
|
||||
*
|
||||
* @throws NotFound User not found (tokens do not exist, refresh token expired)
|
||||
* @throws Failed Could not regenerate tokens
|
||||
*/
|
||||
public static function refresh(string $token, string $refreshToken)
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -424,22 +347,10 @@ class User implements JsonSerializable
|
||||
return $stmt->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update post
|
||||
*
|
||||
* Does nothing if new all fields are empty
|
||||
*
|
||||
* @param ?string $username New username
|
||||
* @param ?string $password New password
|
||||
* @param ?string $email New email
|
||||
*
|
||||
* @throws Failed At least one field failed to update
|
||||
*/
|
||||
public function update(?string $username, ?string $password, ?string $email): User
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
|
||||
// Make sure we do all changes or none
|
||||
$db->beginTransaction();
|
||||
|
||||
$failed = [];
|
||||
@ -502,33 +413,20 @@ class User implements JsonSerializable
|
||||
}
|
||||
|
||||
if (count($failed) > 0) {
|
||||
// We failed, go back
|
||||
$db->rollBack();
|
||||
|
||||
throw ApiError::failedUpdate($failed, $reasons);
|
||||
}
|
||||
|
||||
// Commit the changes
|
||||
$db->commit();
|
||||
|
||||
return User::getByID($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update post
|
||||
*
|
||||
* Does nothing if all fields are empty
|
||||
*
|
||||
* @param mixed $image New file upload
|
||||
* @param ?string $predefined Predefined avatar
|
||||
*
|
||||
* @param Failed Image failed to update
|
||||
*/
|
||||
public function updateImage($image, ?string $predefined): User
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
|
||||
// Make sure we do all changes or none
|
||||
$db->beginTransaction();
|
||||
|
||||
$failed = [];
|
||||
@ -544,7 +442,6 @@ class User implements JsonSerializable
|
||||
}
|
||||
|
||||
if (!empty($image)) {
|
||||
// Move file and grab filename
|
||||
$destinationFilename = sprintf('%s.%s', uniqid(), $image->getExtension());
|
||||
$image->move(Config::getStorageFSPath() . "profilbilder/$destinationFilename");
|
||||
|
||||
@ -585,52 +482,25 @@ class User implements JsonSerializable
|
||||
}
|
||||
|
||||
if (count($failed) > 0) {
|
||||
// We failed, go back
|
||||
$db->rollBack();
|
||||
|
||||
throw ApiError::failedUpdate($failed, $reasons);
|
||||
}
|
||||
|
||||
// Commit the changes
|
||||
$db->commit();
|
||||
|
||||
return User::getByID($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete user
|
||||
*
|
||||
* @param int $limit Limit of list for which the returned pages is calculated.
|
||||
*
|
||||
* @return array Returns deleted user and resulting amount of pages for a given limit.
|
||||
*/
|
||||
public function delete(int $limit): array
|
||||
public function delete(): User
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
$stmt = $db->prepare("DELETE FROM egb_benutzer WHERE id = :ID");
|
||||
$stmt->bindValue(":ID", $this->id);
|
||||
|
||||
$stmt = $db->prepare(
|
||||
"SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
egb_benutzer"
|
||||
);
|
||||
$stmt->execute();
|
||||
$count = $stmt->fetch(PDO::FETCH_COLUMN, 0);
|
||||
|
||||
return ["pages" => intdiv($count, $limit + 1) + 1, "data" => $this];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of posts by user
|
||||
*
|
||||
* @param int $page Current page (offset)
|
||||
* @param int $limit Users per page
|
||||
* @param string $sort Sort direction
|
||||
*
|
||||
* @return array Number of pages and posts of selected page
|
||||
*/
|
||||
public function posts(int $page, int $limit, string $sort)
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
@ -673,9 +543,6 @@ class User implements JsonSerializable
|
||||
return ["pages" => intdiv($count, $limit + 1) + 1, "data" => $list];
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh user token expiry
|
||||
*/
|
||||
public function keepFresh()
|
||||
{
|
||||
try {
|
||||
@ -698,68 +565,41 @@ class User implements JsonSerializable
|
||||
* Getters
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get user ID
|
||||
*/
|
||||
public function getID(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get username
|
||||
*/
|
||||
public function getUsername(): string
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user status
|
||||
*
|
||||
* * 0: Not confirmed
|
||||
* * 1: Confirmed
|
||||
*/
|
||||
public function getStatus(): int
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user email
|
||||
*/
|
||||
public function getEmail(): string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user image path
|
||||
*/
|
||||
public function getImage(): ?string
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user admin status
|
||||
*/
|
||||
public function getIsAdmin(): bool
|
||||
{
|
||||
return $this->isAdmin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time of user creation
|
||||
*/
|
||||
public function getMemberSince(): DateTime
|
||||
{
|
||||
return $this->memberSince;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get count of posts by user
|
||||
*/
|
||||
public function getPostCount(): int
|
||||
{
|
||||
return $this->postCount;
|
||||
|
||||
@ -5,41 +5,22 @@ namespace Khofmann\Request;
|
||||
use Pecee\Http\Request as PRequest;
|
||||
use Pecee\SimpleRouter\SimpleRouter;
|
||||
|
||||
/**
|
||||
* Facade for Request access (wraps SimpleRouter)
|
||||
*/
|
||||
class Request
|
||||
{
|
||||
/**
|
||||
* Private since facade.
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current request
|
||||
*/
|
||||
public static function request(): PRequest
|
||||
{
|
||||
return SimpleRouter::request();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get header value from current request
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param mixed $defaultValue Default value if header field was null
|
||||
* @param bool $tryParse When enabled the method will try to find the header from both from client (http) and server-side variants, if the header is not found.
|
||||
*/
|
||||
public static function header(string $name, $defaultValue = null, bool $tryParse = true): ?string
|
||||
{
|
||||
return Request::request()->getHeader($name, $defaultValue, $tryParse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authentication header field
|
||||
*/
|
||||
public static function token()
|
||||
{
|
||||
return Request::header("token");
|
||||
|
||||
@ -5,33 +5,17 @@ namespace Khofmann\Response;
|
||||
use Pecee\SimpleRouter\SimpleRouter;
|
||||
use Pecee\Http\Response as PResponse;
|
||||
|
||||
/**
|
||||
* Facade for Response creation (wraps SimpleRouter)
|
||||
*/
|
||||
class Response
|
||||
{
|
||||
/**
|
||||
* Private since facade.
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current response
|
||||
*/
|
||||
public static function response(): PResponse
|
||||
{
|
||||
return SimpleRouter::response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create JSON response
|
||||
*
|
||||
* @param mixed $value Body of response
|
||||
* @param int $options Options passed to `json_encode`
|
||||
* @param int $dept Depth passed to `json_encode`
|
||||
*/
|
||||
public static function json($value, int $options = 0, int $dept = 512): void
|
||||
{
|
||||
if (is_bool($value)) {
|
||||
@ -42,12 +26,6 @@ class Response
|
||||
SimpleRouter::response()->json($value, $options, $dept);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create API error response
|
||||
*
|
||||
* @param string $value Body of error
|
||||
* @param int $code HTTP code of error
|
||||
*/
|
||||
public static function apiError(string $value, int $code): void
|
||||
{
|
||||
Response::response()->header('Content-Type: application/json; charset=utf-8')->httpCode($code);
|
||||
@ -55,12 +33,6 @@ class Response
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create redirect response
|
||||
*
|
||||
* @param string $url New target
|
||||
* @param ?int $code HTTP code
|
||||
*/
|
||||
public static function redirect(string $url, ?int $code = null): void
|
||||
{
|
||||
if ($code !== null) {
|
||||
|
||||
@ -1,11 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Constrain integer to interval `[min,max]`
|
||||
*
|
||||
* @param int $min lower bound
|
||||
* @param int $max upper bound
|
||||
*/
|
||||
function constrain(int $min, int $max, $n): int
|
||||
{
|
||||
return max(min($max, $n), $min);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user