You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.3 KiB
144 lines
4.3 KiB
<?php
|
|
|
|
namespace App\Controller\Route;
|
|
|
|
use AltoRouter;
|
|
use App\Http\HttpCodes;
|
|
use App\Http\HttpResponse;
|
|
use App\Http\JsonHttpResponse;
|
|
use App\Http\ViewHttpResponse;
|
|
use App\Session\MutableSessionHandle;
|
|
use App\Validation\ValidationFail;
|
|
use Twig\Environment;
|
|
use Twig\Error\LoaderError;
|
|
use Twig\Error\RuntimeError;
|
|
use Twig\Error\SyntaxError;
|
|
use Twig\Loader\FilesystemLoader;
|
|
|
|
class FrontController {
|
|
private AltoRouter $router;
|
|
private string $basePath;
|
|
|
|
|
|
public function __construct(string $basePath) {
|
|
$this->router = $this->createRouter($basePath);
|
|
$this->basePath = $basePath;
|
|
}
|
|
|
|
public function addRoute(string $method, string $path, Action $action): void {
|
|
$this->router->map($method, $path, $action);
|
|
}
|
|
|
|
/**
|
|
* @param MutableSessionHandle $session
|
|
* @return void
|
|
* @throws LoaderError
|
|
* @throws RuntimeError
|
|
* @throws SyntaxError
|
|
*/
|
|
public function run(MutableSessionHandle $session): void {
|
|
$match = $this->router->match();
|
|
if ($match) {
|
|
$this->handleMatch($match, $session);
|
|
return;
|
|
}
|
|
|
|
$this->displayViewByKind(ViewHttpResponse::twig("error.html.twig", [
|
|
'failures' => [ValidationFail::notFound("Could not find page ${_SERVER['REQUEST_URI']}.")],
|
|
], HttpCodes::NOT_FOUND));
|
|
}
|
|
|
|
/**
|
|
* Create a new instance of an AltoRouter
|
|
*
|
|
* @param string $basePath
|
|
* @return AltoRouter
|
|
*/
|
|
public function createRouter(string $basePath): AltoRouter {
|
|
$router = new AltoRouter();
|
|
$router->setBasePath($basePath);
|
|
return $router;
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $match
|
|
* @param MutableSessionHandle $session
|
|
* @return void
|
|
*/
|
|
private function handleMatch(array $match, MutableSessionHandle $session): void {
|
|
$action = $match['target'];
|
|
$params = array_values($match["params"]);
|
|
$this->handleResponseByType($this->tryToCall($action, $params, $session));
|
|
}
|
|
|
|
|
|
/**
|
|
* @param Action $action
|
|
* @param array<int, mixed> $params
|
|
* @param MutableSessionHandle $session
|
|
* @return HttpResponse
|
|
*/
|
|
private function tryToCall(Action $action, array $params, MutableSessionHandle $session): HttpResponse {
|
|
$account = null;
|
|
if ($action->isAuthRequired()) {
|
|
$account = $session->getAccount();
|
|
if ($account == null) {
|
|
// put in the session the initial url the user wanted to get
|
|
$session->setInitialTarget($_SERVER['REQUEST_URI']);
|
|
return HttpResponse::redirect($this->basePath . "/login");
|
|
}
|
|
}
|
|
|
|
return $action->run($params, $session);
|
|
}
|
|
|
|
/**
|
|
* Redirect the return by the response's type
|
|
*
|
|
* @param HttpResponse $response
|
|
* @return void
|
|
*/
|
|
private function handleResponseByType(HttpResponse $response): void {
|
|
http_response_code($response->getCode());
|
|
|
|
foreach ($response->getHeaders() as $header => $value) {
|
|
header("$header: $value");
|
|
}
|
|
|
|
if ($response instanceof ViewHttpResponse) {
|
|
$this->displayViewByKind($response);
|
|
} elseif ($response instanceof JsonHttpResponse) {
|
|
header('Content-type: application/json');
|
|
echo $response->getJson();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Use the right method to display the response
|
|
*
|
|
* @param ViewHttpResponse $response
|
|
* @return void
|
|
*/
|
|
private function displayViewByKind(ViewHttpResponse $response): void {
|
|
$file = $response->getFile();
|
|
$args = $response->getArguments();
|
|
|
|
switch ($response->getViewKind()) {
|
|
case ViewHttpResponse::REACT_VIEW:
|
|
send_react_front($file, $args);
|
|
break;
|
|
case ViewHttpResponse::TWIG_VIEW:
|
|
try {
|
|
$loader = new FilesystemLoader('../src/Views/');
|
|
$twig = new Environment($loader);
|
|
$twig->display($file, $args);
|
|
} catch (RuntimeError|SyntaxError|LoaderError $e) {
|
|
http_response_code(500);
|
|
echo "There was an error rendering your view, please refer to an administrator.\nlogs date: " . date("YYYD, d M Y H:i:s");
|
|
throw $e;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|