Initial Version
This commit is contained in:
112
core/lib/Http/Middleware/MiddlewarePipeline.php
Normal file
112
core/lib/Http/Middleware/MiddlewarePipeline.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace KTXC\Http\Middleware;
|
||||
|
||||
use KTXC\Http\Request\Request;
|
||||
use KTXC\Http\Response\Response;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Middleware pipeline - processes request through a stack of middleware
|
||||
*/
|
||||
class MiddlewarePipeline implements RequestHandlerInterface
|
||||
{
|
||||
/** @var array<string|MiddlewareInterface> */
|
||||
private array $middleware = [];
|
||||
|
||||
private ?ContainerInterface $container = null;
|
||||
|
||||
public function __construct(?ContainerInterface $container = null)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add middleware to the pipeline
|
||||
*
|
||||
* @param string|MiddlewareInterface $middleware Middleware class name or instance
|
||||
* @return self
|
||||
*/
|
||||
public function pipe(string|MiddlewareInterface $middleware): self
|
||||
{
|
||||
$this->middleware[] = $middleware;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request through the middleware pipeline
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function handle(Request $request): Response
|
||||
{
|
||||
// Create a handler for the pipeline
|
||||
$handler = $this->createHandler(0);
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a handler for a specific position in the pipeline
|
||||
*
|
||||
* @param int $index Current position in the middleware stack
|
||||
* @return RequestHandlerInterface
|
||||
*/
|
||||
public function createHandler(int $index): RequestHandlerInterface
|
||||
{
|
||||
// If we've reached the end of the pipeline, return a default handler
|
||||
if (!isset($this->middleware[$index])) {
|
||||
return new class implements RequestHandlerInterface {
|
||||
public function handle(Request $request): Response {
|
||||
return new Response(Response::$statusTexts[Response::HTTP_NOT_FOUND], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return new class($this->middleware[$index], $this, $index, $this->container) implements RequestHandlerInterface {
|
||||
private string|MiddlewareInterface $middleware;
|
||||
private MiddlewarePipeline $pipeline;
|
||||
private int $index;
|
||||
private ?ContainerInterface $container;
|
||||
|
||||
public function __construct(
|
||||
string|MiddlewareInterface $middleware,
|
||||
MiddlewarePipeline $pipeline,
|
||||
int $index,
|
||||
?ContainerInterface $container
|
||||
) {
|
||||
$this->middleware = $middleware;
|
||||
$this->pipeline = $pipeline;
|
||||
$this->index = $index;
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function handle(Request $request): Response
|
||||
{
|
||||
// Resolve middleware instance if it's a class name
|
||||
$middleware = $this->middleware;
|
||||
|
||||
if (is_string($middleware)) {
|
||||
if ($this->container && $this->container->has($middleware)) {
|
||||
$middleware = $this->container->get($middleware);
|
||||
} else {
|
||||
$middleware = new $middleware();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$middleware instanceof MiddlewareInterface) {
|
||||
throw new \RuntimeException(
|
||||
sprintf('Middleware must implement %s', MiddlewareInterface::class)
|
||||
);
|
||||
}
|
||||
|
||||
// Create the next handler in the chain
|
||||
$next = $this->pipeline->createHandler($this->index + 1);
|
||||
|
||||
// Process this middleware
|
||||
return $middleware->process($request, $next);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user