Skip to content

Commit

Permalink
New: Added psr-container integration for middlewares
Browse files Browse the repository at this point in the history
  • Loading branch information
merloxx committed Sep 19, 2023
1 parent f9f89f1 commit 09570db
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/Contracts/DispatcherInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* @author merloxx <[email protected]>
*/
interface DispatcherInterface extends MiddlewareAwareInterface, RequestHandlerInterface
interface DispatcherInterface extends MiddlewareAwareInterface, ContainerAwareInterface, RequestHandlerInterface
{
/**
* @param RouteInterface $route
Expand Down
3 changes: 2 additions & 1 deletion src/Dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Zaphyr\Router\Exceptions\MethodNotAllowedException;
use Zaphyr\Router\Exceptions\MiddlewareException;
use Zaphyr\Router\Exceptions\NotFoundException;
use Zaphyr\Router\Traits\ContainerAwareTrait;
use Zaphyr\Router\Traits\MiddlewareAwareTrait;

/**
Expand All @@ -23,6 +24,7 @@
class Dispatcher extends RegexBasedAbstract implements DispatcherInterface
{
use MiddlewareAwareTrait;
use ContainerAwareTrait;

/**
* @param RouteCollector $routeCollector
Expand Down Expand Up @@ -78,7 +80,6 @@ public function handle(ServerRequestInterface $request): ResponseInterface
/**
* @param RouteInterface $route
*
* @throws MiddlewareException if the middleware is not callable
* @return void
*/
protected function setFoundMiddleware(RouteInterface $route): void
Expand Down
1 change: 1 addition & 0 deletions src/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ protected function prepareRoutes(ServerRequestInterface $request): void

if ($this->getContainer() !== null) {
$route->setContainer($this->getContainer());
$this->dispatcher->setContainer($this->getContainer());
}

$this->dispatcher->addRoute($route->setPath($this->prepareRoutePath($route->getPath())));
Expand Down
11 changes: 10 additions & 1 deletion src/Traits/MiddlewareAwareTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
namespace Zaphyr\Router\Traits;

use Psr\Http\Server\MiddlewareInterface;
use Throwable;
use Zaphyr\Router\Exceptions\MiddlewareException;

/**
* @author merloxx <[email protected]>
*/
trait MiddlewareAwareTrait
{
use ContainerAwareTrait;

/**
* @var MiddlewareInterface[]|class-string[]
*/
Expand Down Expand Up @@ -71,7 +74,13 @@ public function shiftMiddleware(): MiddlewareInterface
public function resolveMiddleware(MiddlewareInterface|string $middleware): MiddlewareInterface
{
if (is_string($middleware) && class_exists($middleware)) {
$middleware = new $middleware();
$container = $this->getContainer();

try {
$middleware = $container !== null ? $container->get($middleware) : new $middleware();
} catch (Throwable $exception) {
throw new MiddlewareException($exception->getMessage(), $exception->getCode(), $exception);
}
}

if ($middleware instanceof MiddlewareInterface) {
Expand Down
12 changes: 12 additions & 0 deletions tests/RouterIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Zaphyr\RouterTests\TestAssets\ConditionGroupController;
use Zaphyr\RouterTests\TestAssets\Controller;
use Zaphyr\RouterTests\TestAssets\DependencyInjectionController;
use Zaphyr\RouterTests\TestAssets\DIMiddleware;
use Zaphyr\RouterTests\TestAssets\GroupController;
use Zaphyr\RouterTests\TestAssets\Middleware;
use Zaphyr\RouterTests\TestAssets\MiddlewareController;
Expand Down Expand Up @@ -1026,6 +1027,17 @@ public function testDependencyInjectionController(): void
self::assertSame('hello from foo', (string)$response->getBody());
}

public function testDependencyInjectionMiddleware(): void
{
$this->router->setContainer(new Container());

$this->router->add('/foo', ['GET'], static fn() => new Response())->setMiddleware(DIMiddleware::class);

$response = $this->router->handle(new ServerRequest(uri: '/foo'));

self::assertSame('hello from foo', (string)$response->getBody());
}

public function testDependencyInjectionThrowsExceptionWhenDependencyIsNotResolvable(): void
{
$this->expectException(RouteException::class);
Expand Down
26 changes: 26 additions & 0 deletions tests/TestAssets/DIMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Zaphyr\RouterTests\TestAssets;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zaphyr\HttpMessage\Response;

class DIMiddleware implements MiddlewareInterface
{
public function __construct(protected Foo $foo)
{
}

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = new Response();
$response->getBody()->write($this->foo->greet());

return $response;
}
}

0 comments on commit 09570db

Please sign in to comment.