Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## 5.3.1 under development

- no changes in this release.
- Enh #110: Add support for using middlewares from container-registered identifier (@rustamwin)

## 5.3.0 August 06, 2025

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ request instance, dispatcher executes it and produces a response instance.

## Requirements

- PHP 8.1 or higher.
- PHP 8.1 - 8.4.

## Installation

Expand Down Expand Up @@ -64,6 +64,7 @@ In the above we have used a callback. Overall the following options are availabl
`index()` method will be executed.
- A name of PSR-15 middleware class. The middleware instance will be obtained from container.
- A name of PSR-15 request handler class. The request handler instance will be obtained from container and executed.
- An identifier of container definition for PSR-15 middleware. The middleware instance will be obtained from container and executed.
- A name or instance of invokable class. If the name of invokable class is provided, the instance will be
obtained from container and executed.
- A function returning a middleware such as
Expand Down
13 changes: 13 additions & 0 deletions src/InvalidMiddlewareDefinitionException.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ public function getSolution(): ?string
Yiisoft\Session\SessionMiddleware::class
```

PSR request handler class name:

```php
Yiisoft\Yii\Swagger\Action\SwaggerUi::class
```

An identifier of container definition for PSR middleware:

```php
'sessionMiddleware'
```
where `sessionMiddleware` is the identifier of container definition for `Yiisoft\Session\SessionMiddleware`.

PSR middleware array definition:

```php
Expand Down
20 changes: 18 additions & 2 deletions src/MiddlewareFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Yiisoft\Middleware\Dispatcher;

use Closure;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
Expand Down Expand Up @@ -44,6 +43,7 @@ public function __construct(
* - A name of PSR-15 middleware class. The middleware instance will be obtained from container and executed.
* - A name of PSR-15 request handler class. The request handler instance will be obtained from container and executed.
* - A name of invokable class. The invokable class instance will be obtained from container and executed.
* - An identifier of container definition for PSR-15 middleware. The middleware instance will be obtained from container and executed.
* - A callable with
* `function(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface`
* signature.
Expand Down Expand Up @@ -87,6 +87,14 @@ public function create(array|callable|string $middlewareDefinition): MiddlewareI
return ArrayDefinition::fromConfig($middlewareDefinition)->resolve($this->container);
}

if ($this->isContainerAlias($middlewareDefinition)) {
/** @var mixed $resolvedDefinition */
$resolvedDefinition = $this->container->get($middlewareDefinition);
if ($resolvedDefinition instanceof MiddlewareInterface) {
return $resolvedDefinition;
}
}

throw new InvalidMiddlewareDefinitionException($middlewareDefinition);
}

Expand Down Expand Up @@ -158,6 +166,14 @@ private function isArrayDefinition(array|callable|string $definition): bool
return is_subclass_of((string) ($definition['class'] ?? ''), MiddlewareInterface::class);
}

/**
* @psalm-assert-if-true string $definition
*/
private function isContainerAlias(array|callable|string $definition): bool
{
return is_string($definition) && $this->container->has($definition);
}

/**
* @param array{0:class-string, 1:non-empty-string}|callable $callable
*/
Expand Down Expand Up @@ -187,7 +203,7 @@ public function __construct(
private readonly ?ParametersResolverInterface $parametersResolver
) {
$this->callback = $callback;
$callback = Closure::fromCallable($callback);
$callback = $callback(...);

$callableParameters = (new ReflectionFunction($callback))->getParameters();
foreach ($callableParameters as $parameter) {
Expand Down
10 changes: 10 additions & 0 deletions tests/MiddlewareFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ public function testCreateFromString(): void
self::assertInstanceOf(TestMiddleware::class, $middleware);
}

public function testCreateFromContainerDefinitionIdentifier(): void
{
$container = $this->getContainer([
'test' => new TestMiddleware(),
]);
$middleware = $this->getMiddlewareFactory($container)->create('test');

self::assertInstanceOf(TestMiddleware::class, $middleware);
}

public function testCreateFromInvokable(): void
{
$container = $this->getContainer([InvokeableAction::class => new InvokeableAction()]);
Expand Down
Loading