eee
This commit is contained in:
+251
-250
@@ -21,300 +21,301 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private array $_item = [];
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private array $_item = [];
|
||||
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private array $dump = [];
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private array $dump = [];
|
||||
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $groupTack = [];
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $groupTack = [];
|
||||
|
||||
|
||||
/**
|
||||
* @var array<string, Handler>
|
||||
*/
|
||||
private array $methods = [];
|
||||
/**
|
||||
* @var array<string, Handler>
|
||||
*/
|
||||
private array $methods = [];
|
||||
|
||||
|
||||
/**
|
||||
* @var array<string, HttpRequestHandler>
|
||||
*/
|
||||
protected array $httpHandler = [];
|
||||
/**
|
||||
* @var array<string, HttpRequestHandler>
|
||||
*/
|
||||
protected array $httpHandler = [];
|
||||
|
||||
|
||||
/**
|
||||
* @var Handler
|
||||
*/
|
||||
protected Handler $found;
|
||||
/**
|
||||
* @var Handler
|
||||
*/
|
||||
protected Handler $found;
|
||||
|
||||
|
||||
/**
|
||||
* @throws
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->found = new Handler([NotFoundController::class, 'fail'], [], ResponseFormat::class);
|
||||
}
|
||||
/**
|
||||
* @throws
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->found = new Handler([NotFoundController::class, 'fail'], [], ResponseFormat::class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Handler[]
|
||||
*/
|
||||
public function getMethods(): array
|
||||
{
|
||||
return $this->methods;
|
||||
}
|
||||
/**
|
||||
* @return Handler[]
|
||||
*/
|
||||
public function getMethods(): array
|
||||
{
|
||||
return $this->methods;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param HttpRequestHandler $handler
|
||||
* @return void
|
||||
*/
|
||||
public function setHttpHandler(string $method, HttpRequestHandler $handler): void
|
||||
{
|
||||
$this->httpHandler[$method] = $handler;
|
||||
}
|
||||
/**
|
||||
* @param string $method
|
||||
* @param HttpRequestHandler $handler
|
||||
* @return void
|
||||
*/
|
||||
public function setHttpHandler(string $method, HttpRequestHandler $handler): void
|
||||
{
|
||||
$this->httpHandler[$method] = $handler;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDump(): array
|
||||
{
|
||||
return $this->dump;
|
||||
}
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDump(): array
|
||||
{
|
||||
return $this->dump;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Traversable
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
return new \ArrayIterator($this->_item);
|
||||
}
|
||||
/**
|
||||
* @return Traversable
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
return new \ArrayIterator($this->_item);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $method
|
||||
* @param string $route
|
||||
* @param string|array|Closure $closure
|
||||
*/
|
||||
public function addRoute(array $method, string $route, string|array|Closure $closure): void
|
||||
{
|
||||
try {
|
||||
$route = $this->_splicing_routing($route);
|
||||
if ($closure instanceof Closure) {
|
||||
$handler = di(ControllerInterpreter::class)->addRouteByClosure($closure);
|
||||
} else {
|
||||
$handler = $this->resolve($closure, di(ControllerInterpreter::class));
|
||||
}
|
||||
foreach ($method as $value) {
|
||||
if ($value instanceof RequestMethod) {
|
||||
$value = $value->getString();
|
||||
}
|
||||
$handler->setRequestMethod($value);
|
||||
if (is_array($closure)) {
|
||||
$closure[0] = is_object($closure[0]) ? get_class($closure[0]) : $closure;
|
||||
} else if (is_string($closure)) {
|
||||
$closure = explode('@', $closure);
|
||||
}
|
||||
$this->register($route, $value, $handler);
|
||||
}
|
||||
} catch (Throwable $throwable) {
|
||||
error($throwable);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param array $method
|
||||
* @param string $route
|
||||
* @param string|array|Closure $closure
|
||||
*/
|
||||
public function addRoute(array $method, string $route, string|array|Closure $closure): void
|
||||
{
|
||||
try {
|
||||
$route = $this->_splicing_routing($route);
|
||||
if ($closure instanceof Closure) {
|
||||
$handler = di(ControllerInterpreter::class)->addRouteByClosure($closure);
|
||||
} else {
|
||||
$handler = $this->resolve($closure, di(ControllerInterpreter::class));
|
||||
}
|
||||
foreach ($method as $value) {
|
||||
if ($value instanceof RequestMethod) {
|
||||
$value = $value->getString();
|
||||
}
|
||||
$handler->setRequestMethod($value);
|
||||
if (is_array($closure)) {
|
||||
$closure[0] = is_object($closure[0]) ? get_class($closure[0]) : $closure;
|
||||
} else if (is_string($closure)) {
|
||||
$closure = explode('@', $closure);
|
||||
}
|
||||
$this->register($route, $value, $handler);
|
||||
}
|
||||
} catch (Throwable $throwable) {
|
||||
error($throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function dump(): array
|
||||
{
|
||||
$array = [];
|
||||
foreach ($this->methods as $methodPath => $handler) {
|
||||
[$path, $method] = explode('_', $methodPath);
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function dump(): array
|
||||
{
|
||||
$array = [];
|
||||
foreach ($this->methods as $methodPath => $handler) {
|
||||
[$path, $method] = explode('_', $methodPath);
|
||||
|
||||
$controller = $handler instanceof Closure ? '\Closure' : $handler->getClass() . '::' . $handler->getMethod();
|
||||
$array[] = [
|
||||
'path' => $path,
|
||||
'method' => $method,
|
||||
'handler' => $controller
|
||||
];
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
$controller = $handler instanceof Closure ? '\Closure' : $handler->getClass() . '::' . $handler->getMethod();
|
||||
$array[] = [
|
||||
'path' => $path,
|
||||
'method' => $method,
|
||||
'handler' => $controller
|
||||
];
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|array $closure
|
||||
* @param ControllerInterpreter $interpreter
|
||||
* @return Handler
|
||||
* @throws
|
||||
*/
|
||||
private function resolve(string|array $closure, ControllerInterpreter $interpreter): Handler
|
||||
{
|
||||
$container = \Kiri::getDi();
|
||||
if (is_array($closure)) {
|
||||
if (is_string($closure[0])) {
|
||||
$closure[0] = $container->get($closure[0]);
|
||||
}
|
||||
return $interpreter->addRouteByString(... $closure);
|
||||
}
|
||||
if (!str_contains($closure, '@')) {
|
||||
$closure .= '@';
|
||||
}
|
||||
[$className, $method] = explode('@', $closure);
|
||||
$class = $container->get($this->resetName($className));
|
||||
return $interpreter->addRouteByString($class, $method);
|
||||
}
|
||||
/**
|
||||
* @param string|array $closure
|
||||
* @param ControllerInterpreter $interpreter
|
||||
* @return Handler
|
||||
* @throws
|
||||
*/
|
||||
private function resolve(string|array $closure, ControllerInterpreter $interpreter): Handler
|
||||
{
|
||||
$container = \Kiri::getDi();
|
||||
if (is_array($closure)) {
|
||||
if (is_string($closure[0])) {
|
||||
$closure[0] = $container->get($closure[0]);
|
||||
}
|
||||
return $interpreter->addRouteByString(... $closure);
|
||||
}
|
||||
if (!str_contains($closure, '@')) {
|
||||
$closure .= '@';
|
||||
}
|
||||
[$className, $method] = explode('@', $closure);
|
||||
$class = $container->get($this->resetName($className));
|
||||
return $interpreter->addRouteByString($class, $method);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @return string
|
||||
*/
|
||||
private function resetName(string $className): string
|
||||
{
|
||||
$namespace = array_filter(array_column($this->groupTack, 'namespace'));
|
||||
if (count($namespace) < 1) {
|
||||
return $className;
|
||||
}
|
||||
return implode('\\', $namespace) . '\\' . $className;
|
||||
}
|
||||
/**
|
||||
* @param string $className
|
||||
* @return string
|
||||
*/
|
||||
private function resetName(string $className): string
|
||||
{
|
||||
$namespace = array_filter(array_column($this->groupTack, 'namespace'));
|
||||
if (count($namespace) < 1) {
|
||||
return $className;
|
||||
}
|
||||
return implode('\\', $namespace) . '\\' . $className;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $method
|
||||
* @param Handler $handler
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
public function register(string $path, string $method, Handler $handler): void
|
||||
{
|
||||
$this->methods[$method . '_' . $path] = $handler;
|
||||
$this->registerMiddleware($handler->getClass(), $handler->getMethod());
|
||||
}
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $method
|
||||
* @param Handler $handler
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
public function register(string $path, string $method, Handler $handler): void
|
||||
{
|
||||
$this->methods[$method . '_' . $path] = $handler;
|
||||
$this->registerMiddleware($handler->getClass(), $handler->getMethod());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $method
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
public function registerMiddleware(string $class, string $method): void
|
||||
{
|
||||
$middlewares = \request()->middlewares;
|
||||
if (count($middlewares) > 0) {
|
||||
$this->appendMiddleware($middlewares, $class, $method);
|
||||
}
|
||||
$middlewares = array_column($this->groupTack, 'middleware');
|
||||
if (count($middlewares) > 0) {
|
||||
$this->appendMiddleware($middlewares, $class, $method);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $method
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
public function registerMiddleware(string $class, string $method): void
|
||||
{
|
||||
$middlewares = \request()->middlewares;
|
||||
var_dump($class . '::' . $method . '('.json_encode($middlewares,JSON_UNESCAPED_UNICODE).')');
|
||||
if (count($middlewares) > 0) {
|
||||
$this->appendMiddleware($middlewares, $class, $method);
|
||||
}
|
||||
$middlewares = array_column($this->groupTack, 'middleware');
|
||||
if (count($middlewares) > 0) {
|
||||
$this->appendMiddleware($middlewares, $class, $method);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $middlewares
|
||||
* @param $class
|
||||
* @param $method
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
private function appendMiddleware(array $middlewares, $class, $method): void
|
||||
{
|
||||
foreach ($middlewares as $middleware) {
|
||||
if (is_string($middleware)) {
|
||||
$middleware = [$middleware];
|
||||
}
|
||||
foreach ($middleware as $value) {
|
||||
Middleware::set($class, $method, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param array $middlewares
|
||||
* @param $class
|
||||
* @param $method
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
private function appendMiddleware(array $middlewares, $class, $method): void
|
||||
{
|
||||
foreach ($middlewares as $middleware) {
|
||||
if (is_string($middleware)) {
|
||||
$middleware = [$middleware];
|
||||
}
|
||||
foreach ($middleware as $value) {
|
||||
Middleware::set($class, $method, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $method
|
||||
* @return HttpRequestHandler
|
||||
* @throws
|
||||
*/
|
||||
public function query(string $path, string $method): HttpRequestHandler
|
||||
{
|
||||
return $this->httpHandler[$method . '_' . $path] ?? new HttpRequestHandler([], $this->found);
|
||||
}
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $method
|
||||
* @return HttpRequestHandler
|
||||
* @throws
|
||||
*/
|
||||
public function query(string $path, string $method): HttpRequestHandler
|
||||
{
|
||||
return $this->httpHandler[$method . '_' . $path] ?? new HttpRequestHandler([], $this->found);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
* @return string
|
||||
*/
|
||||
protected function _splicing_routing(string $route): string
|
||||
{
|
||||
$route = ltrim($route, '/');
|
||||
$prefix = array_column($this->groupTack, 'prefix');
|
||||
if (empty($prefix = array_filter($prefix))) {
|
||||
return '/' . $route;
|
||||
}
|
||||
return '/' . implode('/', $prefix) . '/' . $route;
|
||||
}
|
||||
/**
|
||||
* @param string $route
|
||||
* @return string
|
||||
*/
|
||||
protected function _splicing_routing(string $route): string
|
||||
{
|
||||
$route = ltrim($route, '/');
|
||||
$prefix = array_column($this->groupTack, 'prefix');
|
||||
if (empty($prefix = array_filter($prefix))) {
|
||||
return '/' . $route;
|
||||
}
|
||||
return '/' . implode('/', $prefix) . '/' . $route;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
// TODO: Implement offsetExists() method.
|
||||
return isset($this->_item[$offset]);
|
||||
}
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
// TODO: Implement offsetExists() method.
|
||||
return isset($this->_item[$offset]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return Router|null
|
||||
*/
|
||||
public function offsetGet(mixed $offset): ?Router
|
||||
{
|
||||
if ($this->offsetExists($offset)) {
|
||||
return $this->_item[$offset];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return Router|null
|
||||
*/
|
||||
public function offsetGet(mixed $offset): ?Router
|
||||
{
|
||||
if ($this->offsetExists($offset)) {
|
||||
return $this->_item[$offset];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
// TODO: Implement offsetSet() method.
|
||||
$this->_item[$offset] = $value;
|
||||
}
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
// TODO: Implement offsetSet() method.
|
||||
$this->_item[$offset] = $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return void
|
||||
*/
|
||||
public function offsetUnset(mixed $offset): void
|
||||
{
|
||||
unset($this->_item[$offset]);
|
||||
}
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return void
|
||||
*/
|
||||
public function offsetUnset(mixed $offset): void
|
||||
{
|
||||
unset($this->_item[$offset]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user