summaryrefslogtreecommitdiff
path: root/src/http/Router.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/Router.php')
-rw-r--r--src/http/Router.php80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/http/Router.php b/src/http/Router.php
new file mode 100644
index 0000000..db75f81
--- /dev/null
+++ b/src/http/Router.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace App\http;
+
+use App\http\Support\RouteLoader;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Generator\UrlGenerator;
+use Symfony\Component\Routing\Loader\AnnotationFileLoader;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\RouteCollection;
+
+class Router
+{
+ public static Request $request;
+ public static RequestContext $context;
+ public static RouteCollection $routes;
+
+ public static function init(Request $request): void
+ {
+ self::$request = $request;
+
+ self::$context = new RequestContext();
+ self::$context->fromRequest($request);
+
+ self::$routes = new RouteCollection();
+ $loader = new AnnotationFileLoader(new FileLocator(), new RouteLoader());
+ $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(__DIR__ . '/Controller'));
+ foreach ($iterator as $file) {
+ /**@var \SplFileInfo $file*/
+ if (in_array($file->getFilename(), ['.', '..'])) continue;
+
+ $collection = $loader->load($file->getPathname(), 'attribute');
+ self::$routes->addCollection($collection);
+ }
+ }
+
+ public static function execute(): Response
+ {
+ try {
+ $matcher = new UrlMatcher(self::$routes, self::$context);
+ $match = $matcher->matchRequest(self::$request);
+
+ foreach ($match as $key => $value) {
+ if (str_starts_with($key, '_')) continue;
+
+ self::$request->query->set($key, $value);
+ }
+
+ /**@var \ReflectionClass $class*/
+ $class = $match['_']['class'];
+ /**@var \ReflectionMethod $method*/
+ $method = $match['_']['method'];
+
+ return ($class->newInstance())->{$method->getName()}(self::$request);
+ } catch (ResourceNotFoundException $exception) {
+ return new Response('404', 404);
+ } catch (MethodNotAllowedException $exception) {
+ return new Response('403', 403);
+ } catch (\Exception $exception) {
+ return new Response('500: ' . $exception->getMessage(), 500);
+ }
+ }
+
+ /**
+ * @param string $name
+ * @param array $parameters
+ * @param int $referenceType
+ */
+ public static function generate(string $name, array $parameters = [], int $referenceType = 1): string
+ {
+ $generator = new UrlGenerator(self::$routes, self::$context);
+
+ return $generator->generate($name, $parameters, $referenceType);
+ }
+}