Skip to content

Commit

Permalink
Merge pull request #2817 from l0gicgate/MiddlewareDispatcherInterface
Browse files Browse the repository at this point in the history
4.x - MiddlewareDispatcherInterface
  • Loading branch information
l0gicgate committed Aug 20, 2019
2 parents 89f8076 + e830a8c commit a0435c3
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 34 deletions.
39 changes: 28 additions & 11 deletions Slim/App.php
Expand Up @@ -17,6 +17,7 @@
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Factory\ServerRequestCreatorFactory;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\MiddlewareDispatcherInterface;
use Slim\Interfaces\RouteCollectorInterface;
use Slim\Interfaces\RouteResolverInterface;
use Slim\Middleware\BodyParsingMiddleware;
Expand All @@ -36,28 +37,30 @@ class App extends RouteCollectorProxy implements RequestHandlerInterface
public const VERSION = '4.1.0';

/**
* @var MiddlewareDispatcher
* @var RouteResolverInterface
*/
protected $middlewareDispatcher;
protected $routeResolver;

/**
* @var RouteResolverInterface
* @var MiddlewareDispatcherInterface
*/
protected $routeResolver;
protected $middlewareDispatcher;

/**
* @param ResponseFactoryInterface $responseFactory
* @param ContainerInterface|null $container
* @param CallableResolverInterface|null $callableResolver
* @param RouteCollectorInterface|null $routeCollector
* @param RouteResolverInterface|null $routeResolver
* @param ResponseFactoryInterface $responseFactory
* @param ContainerInterface|null $container
* @param CallableResolverInterface|null $callableResolver
* @param RouteCollectorInterface|null $routeCollector
* @param RouteResolverInterface|null $routeResolver
* @param MiddlewareDispatcherInterface|null $middlewareDispatcher
*/
public function __construct(
ResponseFactoryInterface $responseFactory,
?ContainerInterface $container = null,
?CallableResolverInterface $callableResolver = null,
?RouteCollectorInterface $routeCollector = null,
?RouteResolverInterface $routeResolver = null
?RouteResolverInterface $routeResolver = null,
?MiddlewareDispatcherInterface $middlewareDispatcher = null
) {
parent::__construct(
$responseFactory,
Expand All @@ -69,7 +72,13 @@ public function __construct(
$this->routeResolver = $routeResolver ?? new RouteResolver($this->routeCollector);
$routeRunner = new RouteRunner($this->routeResolver, $this->routeCollector->getRouteParser());

$this->middlewareDispatcher = new MiddlewareDispatcher($routeRunner, $this->callableResolver, $container);
if (!$middlewareDispatcher) {
$middlewareDispatcher = new MiddlewareDispatcher($routeRunner, $this->callableResolver, $container);
} else {
$middlewareDispatcher->seedMiddlewareStack($routeRunner);
}

$this->middlewareDispatcher = $middlewareDispatcher;
}

/**
Expand All @@ -80,6 +89,14 @@ public function getRouteResolver(): RouteResolverInterface
return $this->routeResolver;
}

/**
* @return MiddlewareDispatcherInterface
*/
public function getMiddlewareDispatcher(): MiddlewareDispatcherInterface
{
return $this->middlewareDispatcher;
}

/**
* @param MiddlewareInterface|string|callable $middleware
* @return self
Expand Down
44 changes: 36 additions & 8 deletions Slim/Factory/AppFactory.php
Expand Up @@ -18,6 +18,7 @@
use Slim\Factory\Psr17\Psr17FactoryProvider;
use Slim\Factory\Psr17\SlimHttpPsr17Factory;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\MiddlewareDispatcherInterface;
use Slim\Interfaces\Psr17FactoryProviderInterface;
use Slim\Interfaces\RouteCollectorInterface;
use Slim\Interfaces\RouteResolverInterface;
Expand Down Expand Up @@ -59,33 +60,41 @@ class AppFactory
*/
protected static $routeResolver;

/**
* @var MiddlewareDispatcherInterface|null
*/
protected static $middlewareDispatcher;

/**
* @var bool
*/
protected static $slimHttpDecoratorsAutomaticDetectionEnabled = true;

/**
* @param ResponseFactoryInterface|null $responseFactory
* @param ContainerInterface|null $container
* @param CallableResolverInterface|null $callableResolver
* @param RouteCollectorInterface|null $routeCollector
* @param RouteResolverInterface|null $routeResolver
* @param ResponseFactoryInterface|null $responseFactory
* @param ContainerInterface|null $container
* @param CallableResolverInterface|null $callableResolver
* @param RouteCollectorInterface|null $routeCollector
* @param RouteResolverInterface|null $routeResolver
* @param MiddlewareDispatcherInterface|null $middlewareDispatcher
* @return App
*/
public static function create(
?ResponseFactoryInterface $responseFactory = null,
?ContainerInterface $container = null,
?CallableResolverInterface $callableResolver = null,
?RouteCollectorInterface $routeCollector = null,
?RouteResolverInterface $routeResolver = null
?RouteResolverInterface $routeResolver = null,
?MiddlewareDispatcherInterface $middlewareDispatcher = null
): App {
static::$responseFactory = $responseFactory ?? static::$responseFactory;
return new App(
self::determineResponseFactory(),
$container ?? static::$container,
$callableResolver ?? static::$callableResolver,
$routeCollector ?? static::$routeCollector,
$routeResolver ?? static::$routeResolver
$routeResolver ?? static::$routeResolver,
$middlewareDispatcher ?? static::$middlewareDispatcher
);
}

Expand All @@ -111,7 +120,18 @@ public static function createFromContainer(ContainerInterface $container): App
? $container->get(RouteResolverInterface::class)
: null;

return new App($responseFactory, $container, $callableResolver, $routeCollector, $routeResolver);
$middlewareDispatcher = $container->has(MiddlewareDispatcherInterface::class)
? $container->get(MiddlewareDispatcherInterface::class)
: null;

return new App(
$responseFactory,
$container,
$callableResolver,
$routeCollector,
$routeResolver,
$middlewareDispatcher
);
}

/**
Expand Down Expand Up @@ -224,6 +244,14 @@ public static function setRouteResolver(RouteResolverInterface $routeResolver):
static::$routeResolver = $routeResolver;
}

/**
* @param MiddlewareDispatcherInterface $middlewareDispatcher
*/
public static function setMiddlewareDispatcher(MiddlewareDispatcherInterface $middlewareDispatcher): void
{
static::$middlewareDispatcher = $middlewareDispatcher;
}

/**
* @param bool $enabled
*/
Expand Down
48 changes: 48 additions & 0 deletions Slim/Interfaces/MiddlewareDispatcherInterface.php
@@ -0,0 +1,48 @@
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/

declare(strict_types=1);

namespace Slim\Interfaces;

use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

interface MiddlewareDispatcherInterface extends RequestHandlerInterface
{
/**
* Add a new middleware to the stack
*
* Middleware are organized as a stack. That means middleware
* that have been added before will be executed after the newly
* added one (last in, first out).
*
* @param MiddlewareInterface|string|callable $middleware
* @return self
*/
public function add($middleware): self;

/**
* Add a new middleware to the stack
*
* Middleware are organized as a stack. That means middleware
* that have been added before will be executed after the newly
* added one (last in, first out).
*
* @param MiddlewareInterface $middleware
* @return self
*/
public function addMiddleware(MiddlewareInterface $middleware): self;

/**
* Seed the middleware stack with the inner request handler
*
* @param RequestHandlerInterface $kernel
* @return void
*/
public function seedMiddlewareStack(RequestHandlerInterface $kernel): void;
}
28 changes: 13 additions & 15 deletions Slim/MiddlewareDispatcher.php
Expand Up @@ -18,8 +18,9 @@
use RuntimeException;
use Slim\Interfaces\AdvancedCallableResolverInterface;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\MiddlewareDispatcherInterface;

class MiddlewareDispatcher implements RequestHandlerInterface
class MiddlewareDispatcher implements MiddlewareDispatcherInterface
{
/**
* Tip of the middleware call stack
Expand All @@ -29,7 +30,7 @@ class MiddlewareDispatcher implements RequestHandlerInterface
protected $tip;

/**
* @var CallableResolverInterface
* @var CallableResolverInterface|null
*/
protected $callableResolver;

Expand All @@ -39,13 +40,13 @@ class MiddlewareDispatcher implements RequestHandlerInterface
protected $container;

/**
* @param RequestHandlerInterface $kernel
* @param CallableResolverInterface $callableResolver
* @param ContainerInterface|null $container
* @param RequestHandlerInterface $kernel
* @param CallableResolverInterface|null $callableResolver
* @param ContainerInterface|null $container
*/
public function __construct(
RequestHandlerInterface $kernel,
CallableResolverInterface $callableResolver,
?CallableResolverInterface $callableResolver = null,
?ContainerInterface $container = null
) {
$this->seedMiddlewareStack($kernel);
Expand All @@ -54,12 +55,9 @@ public function __construct(
}

/**
* Seed the middleware stack with the inner request handler
*
* @param RequestHandlerInterface $kernel
* @return void
* {@inheritdoc}
*/
protected function seedMiddlewareStack(RequestHandlerInterface $kernel): void
public function seedMiddlewareStack(RequestHandlerInterface $kernel): void
{
$this->tip = $kernel;
}
Expand All @@ -83,9 +81,9 @@ public function handle(ServerRequestInterface $request): ResponseInterface
* added one (last in, first out).
*
* @param MiddlewareInterface|string|callable $middleware
* @return self
* @return MiddlewareDispatcherInterface
*/
public function add($middleware): self
public function add($middleware): MiddlewareDispatcherInterface
{
if ($middleware instanceof MiddlewareInterface) {
return $this->addMiddleware($middleware);
Expand Down Expand Up @@ -113,9 +111,9 @@ public function add($middleware): self
* added one (last in, first out).
*
* @param MiddlewareInterface $middleware
* @return self
* @return MiddlewareDispatcherInterface
*/
public function addMiddleware(MiddlewareInterface $middleware): self
public function addMiddleware(MiddlewareInterface $middleware): MiddlewareDispatcherInterface
{
$next = $this->tip;
$this->tip = new class($middleware, $next) implements RequestHandlerInterface
Expand Down
22 changes: 22 additions & 0 deletions tests/AppTest.php
Expand Up @@ -25,6 +25,7 @@
use Slim\Exception\HttpNotFoundException;
use Slim\Handlers\Strategies\RequestResponseArgs;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\MiddlewareDispatcherInterface;
use Slim\Interfaces\RouteCollectorInterface;
use Slim\Interfaces\RouteCollectorProxyInterface;
use Slim\Interfaces\RouteParserInterface;
Expand Down Expand Up @@ -118,6 +119,27 @@ public function testCreatesRouteCollectorWhenNullWithInjectedContainer()
$this->assertEquals($routeCollector, $app->getRouteCollector());
}

public function testGetMiddlewareDispatcherGetsSeededAndReturnsInjectedInstance()
{
$responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class);

$middlewareDispatcherProphecy = $this->prophesize(MiddlewareDispatcherInterface::class);
$middlewareDispatcherProphecy
->seedMiddlewareStack(Argument::any())
->shouldBeCalledOnce();

$app = new App(
$responseFactoryProphecy->reveal(),
null,
null,
null,
null,
$middlewareDispatcherProphecy->reveal()
);

$this->assertSame($middlewareDispatcherProphecy->reveal(), $app->getMiddlewareDispatcher());
}

public function lowerCaseRequestMethodsProvider()
{
return [
Expand Down

0 comments on commit a0435c3

Please sign in to comment.