1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
<?php
namespace App;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
class Router
{
use Singleton;
private RouteCollection $routes;
private RouteConfigurator $configurator;
public function __construct()
{
$this->routes = new RouteCollection();
$this->configurator = new RouteConfigurator($this->routes, $this->routes);
$this->addRoutes();
}
/**
* match the current url against the routes.
* also add preflight CORS headers on OPTIONS requests.
*/
public function run(): Response
{
$request = Request::createFromGlobals();
if ($request->isMethod("OPTIONS")) {
$response = new Response();
$response->headers->add([
"Access-Control-Allow-Origin" => "*",
"Access-Control-Allow-Methods" => "GET, POST, PUT, DELETE, OPTIONS, PATCH, HEAD",
"Access-Control-Allow-Headers" => "X-Requested-With, Content-Type, Authorization",
]);
return $response;
}
$context = new RequestContext();
$context->fromRequest($request);
try {
$matcher = new UrlMatcher($this->routes, $context);
$match = $matcher->matchRequest($request);
$class = $match["_controller"][0];
$method = $match["_controller"][1];
return (new $class)->$method();
} catch (\Exception $exception) {
return new ErrorResponse(ErrorCode::UNKNOWN, "Unknown error occured");
}
}
/**
* add routes from the routes file
*/
private function addRoutes(): void
{
$routes = include_once(__DIR__ . "/routes.php");
$routes($this->configurator);
}
}
|