index/src/Routing/Route.php

70 lines
1.8 KiB
PHP

<?php
// Route.php
// Created: 2023-09-07
// Updated: 2023-09-07
namespace Index\Routing;
use Attribute;
use ReflectionObject;
use UnexpectedValueException;
/**
* Provides an attribute for marking methods in a class as routes.
*/
#[Attribute]
class Route {
/** @internal */
public function __construct(
private string $method,
private string $path
) {}
/**
* Returns the target method name.
*
* @return string
*/
public function getMethod(): string {
return $this->method;
}
/**
* Returns the target path.
*
* @return string
*/
public function getPath(): string {
return $this->path;
}
/**
* Reads attributes from methods in a IRouteHandler instance and registers them to a given IRouter instance.
*
* @param IRouter $router Router instance.
* @param IRouteHandler $handler Handler instance.
*/
public static function handleAttributes(IRouter $router, IRouteHandler $handler): void {
$objectInfo = new ReflectionObject($handler);
$methodInfos = $objectInfo->getMethods();
foreach($methodInfos as $methodInfo) {
$attrInfos = $methodInfo->getAttributes(Route::class);
foreach($attrInfos as $attrInfo) {
if($attrInfo->isRepeated())
throw new UnexpectedValueException('Only one instance of the Route attribute should be used per method.');
$routeInfo = $attrInfo->newInstance();
$router->add(
$routeInfo->getMethod(),
$routeInfo->getPath(),
$methodInfo->getClosure(
$methodInfo->isStatic() ? null : $handler
)
);
}
}
}
}