misuzu/src/Http/Routing/Route.php

112 lines
3.7 KiB
PHP

<?php
namespace Misuzu\Http\Routing;
use InvalidArgumentException;
use Misuzu\Http\HttpRequestMessage;
use Misuzu\Http\HttpResponseMessage;
class Route {
private $methods = [];
private $path = '';
private $children = [];
private $filters = [];
private $parentRoute = null;
private $handlerClass = null;
private $handlerMethod = null;
public function __construct(array $methods, string $path, ?string $method = null, ?string $class = null) {
$this->methods = array_map('strtoupper', $methods);
$this->path = $path;
$this->handlerClass = $class;
$this->handlerMethod = $method;
}
public static function create(array $methods, string $path, ?string $method = null, ?string $class = null): self {
return new Route($methods, $path, $method, $class);
}
public static function get(string $path, ?string $method = null, ?string $class = null): self {
return self::create(['GET'], $path, $method, $class);
}
public static function post(string $path, ?string $method = null, ?string $class = null): self {
return self::create(['POST'], $path, $method, $class);
}
public static function delete(string $path, ?string $method = null, ?string $class = null): self {
return self::create(['DELETE'], $path, $method, $class);
}
public static function group(string $path, ?string $class = null): self {
return self::create([''], $path, null, $class);
}
public function getHandlerClass(): string {
return $this->handlerClass ?? ($this->parentRoute === null ? '' : $this->parentRoute->getHandlerClass());
}
public function setHandlerClass(string $class): self {
$this->handlerClass = $class;
return $this;
}
public function getHandlerMethod() {
return $this->handlerMethod;
}
public function getParent(): ?self {
return $this->parentRoute;
}
public function setParent(self $route): self {
$this->parentRoute = $route;
return $this;
}
public function getPath(): string {
$path = $this->path;
if($this->parentRoute !== null)
$path = $this->parentRoute->getPath() . ($path[0] !== '.' ? '/' : '') . trim($path, '/');
return $path;
}
public function setPath(string $path): self {
$this->path = $path;
return $this;
}
public function addFilters(string ...$filters): self {
$this->filters = array_merge($this->filters, $filters);
return $this;
}
public function getFilters(): array {
$filters = $this->filters;
if($this->parentRoute !== null)
$filters += $this->parentRoute->getFilters();
return $filters;
}
public function getChildren(): array {
return $this->children;
}
public function addChildren(Route ...$routes): self {
foreach($routes as $route)
$this->children[] = $route->setParent($this);
return $this;
}
public function match(HttpRequestMessage $request, array &$matches): bool {
$matches = [];
if(!in_array($request->getMethod(), $this->methods))
return false;
return preg_match('#^' . $this->getPath() . '$#', '/' . trim($request->getUri()->getPath(), '/'), $matches) === 1;
}
public function __serialize(): array {
return [
$this->methods,
$this->getPath(),
$this->getFilters(),
$this->getHandlerClass(),
$this->getHandlerMethod(),
];
}
public function __unserialize(array $data): void {
[$this->methods, $this->path, $this->filters, $this->handlerClass, $this->handlerMethod] = $data;
}
}