From e07c320db52916964947d1dc006d913e02678afb Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 5 May 2026 16:27:44 +0300 Subject: [PATCH] Use `mixed` as push middleware definition format --- docs/guide/en/middleware-pipelines.md | 3 +++ src/Debug/QueueDecorator.php | 5 ++-- src/Middleware/Push/PushMiddlewareConfig.php | 2 +- .../Push/PushMiddlewareDispatcher.php | 24 +++---------------- src/Middleware/Push/PushMiddlewareFactory.php | 17 +++++++++---- .../Push/PushMiddlewareFactoryInterface.php | 14 ++++++++--- src/Queue.php | 14 +++++------ src/QueueInterface.php | 9 ++++--- stubs/StubQueue.php | 5 ++-- 9 files changed, 44 insertions(+), 49 deletions(-) diff --git a/docs/guide/en/middleware-pipelines.md b/docs/guide/en/middleware-pipelines.md index 690f621d..fa832af0 100644 --- a/docs/guide/en/middleware-pipelines.md +++ b/docs/guide/en/middleware-pipelines.md @@ -61,6 +61,9 @@ You can use any of these formats: - A string for your DI container to resolve the middleware, e.g. `FooMiddleware::class`. - An [extended callable definition](callable-definitions-extended.md). A callable should either be a middleware itself or return a configured middleware object. +> **Note:** The formats above are supported by the default `PushMiddlewareFactory`. When using a custom +> `PushMiddlewareFactoryInterface` implementation, it may accept additional definition formats. + The required interface depends on the pipeline: - Push: `Yiisoft\Queue\Middleware\Push\PushMiddlewareInterface` diff --git a/src/Debug/QueueDecorator.php b/src/Debug/QueueDecorator.php index 02345568..fcedb763 100644 --- a/src/Debug/QueueDecorator.php +++ b/src/Debug/QueueDecorator.php @@ -6,7 +6,6 @@ use Yiisoft\Queue\MessageStatus; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Middleware\Push\PushMiddlewareInterface; use Yiisoft\Queue\QueueInterface; final class QueueDecorator implements QueueInterface @@ -46,12 +45,12 @@ public function getName(): string return $this->queue->getName(); } - public function withMiddlewares(PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions): self + public function withMiddlewares(mixed ...$middlewareDefinitions): self { return new self($this->queue->withMiddlewares(...$middlewareDefinitions), $this->collector); } - public function withMiddlewaresAdded(PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions): self + public function withMiddlewaresAdded(mixed ...$middlewareDefinitions): self { return new self($this->queue->withMiddlewaresAdded(...$middlewareDefinitions), $this->collector); } diff --git a/src/Middleware/Push/PushMiddlewareConfig.php b/src/Middleware/Push/PushMiddlewareConfig.php index 848635aa..71ea7888 100644 --- a/src/Middleware/Push/PushMiddlewareConfig.php +++ b/src/Middleware/Push/PushMiddlewareConfig.php @@ -12,7 +12,7 @@ final class PushMiddlewareConfig { /** * @param PushMiddlewareFactoryInterface $middlewareFactory Factory used to instantiate middleware from definitions. - * @param array $commonMiddlewareDefinitions Middleware definitions. + * @param mixed[] $commonMiddlewareDefinitions Middleware definitions. */ public function __construct( public readonly PushMiddlewareFactoryInterface $middlewareFactory, diff --git a/src/Middleware/Push/PushMiddlewareDispatcher.php b/src/Middleware/Push/PushMiddlewareDispatcher.php index 697b25d4..8fc3af28 100644 --- a/src/Middleware/Push/PushMiddlewareDispatcher.php +++ b/src/Middleware/Push/PushMiddlewareDispatcher.php @@ -22,7 +22,7 @@ final class PushMiddlewareDispatcher /** * @param PushMiddlewareFactoryInterface $middlewareFactory Factory used to instantiate middleware. - * @param array $middlewareDefinitions Middleware definitions. + * @param mixed[] $middlewareDefinitions Middleware definitions. * @param PushHandlerInterface $finishHandler Finish message handler. */ public function __construct( @@ -60,16 +60,7 @@ public function withFinishHandler(PushHandlerInterface $finishHandler): self /** * Returns new instance with middleware handlers replaced with the ones provided. * - * @param array[]|callable[]|PushMiddlewareInterface[]|string[] $middlewareDefinitions Each array element is: - * - * - A name of a middleware class. The middleware instance will be obtained from container executed. - * - A callable with `function(MessageInterface $message, PushHandlerInterface $handler): - * MessageInterface` signature. - * - A "callable-like" array in format `[FooMiddleware::class, 'index']`. `FooMiddleware` instance will - * be created and `index()` method will be executed. - * - A function returning a middleware. The middleware returned will be executed. - * - * For callables typed parameters are automatically injected using dependency injection container. + * @param mixed[] $middlewareDefinitions Middleware definitions. * * @return self New instance of the {@see PushMiddlewareDispatcher} */ @@ -88,16 +79,7 @@ public function withMiddlewares(array $middlewareDefinitions): self /** * Returns a new instance with additional middleware handlers added to the existing ones. * - * @param array[]|callable[]|PushMiddlewareInterface[]|string[] $middlewareDefinitions Each array element is: - * - * - A name of a middleware class. The middleware instance will be obtained from container executed. - * - A callable with `function(MessageInterface $message, PushHandlerInterface $handler): - * MessageInterface` signature. - * - A "callable-like" array in format `[FooMiddleware::class, 'index']`. `FooMiddleware` instance will - * be created and `index()` method will be executed. - * - A function returning a middleware. The middleware returned will be executed. - * - * For callables typed parameters are automatically injected using dependency injection container. + * @param mixed[] $middlewareDefinitions Middleware definitions. * * @return self New instance of the {@see PushMiddlewareDispatcher} */ diff --git a/src/Middleware/Push/PushMiddlewareFactory.php b/src/Middleware/Push/PushMiddlewareFactory.php index abf06f83..4326e749 100644 --- a/src/Middleware/Push/PushMiddlewareFactory.php +++ b/src/Middleware/Push/PushMiddlewareFactory.php @@ -10,16 +10,20 @@ use Yiisoft\Queue\Middleware\InvalidMiddlewareDefinitionException; use Yiisoft\Queue\Middleware\MiddlewareFactory; +use function is_array; +use function is_callable; +use function is_string; + /** * Creates a middleware based on the definition provided. * * @template-extends MiddlewareFactory + * @template-implements PushMiddlewareFactoryInterface */ final class PushMiddlewareFactory extends MiddlewareFactory implements PushMiddlewareFactoryInterface { /** - * @param PushMiddlewareInterface|callable|array|string $middlewareDefinition Middleware definition in one of - * the following formats: + * @param mixed $middlewareDefinition Middleware definition in one of the following formats: * * - A middleware object. * - A name of a middleware class. The middleware instance will be obtained from container and executed. @@ -38,13 +42,16 @@ final class PushMiddlewareFactory extends MiddlewareFactory implements PushMiddl * * @return PushMiddlewareInterface */ - public function createPushMiddleware( - PushMiddlewareInterface|callable|array|string $middlewareDefinition, - ): PushMiddlewareInterface { + public function createPushMiddleware(mixed $middlewareDefinition): PushMiddlewareInterface + { if ($middlewareDefinition instanceof PushMiddlewareInterface) { return $middlewareDefinition; } + if (!is_callable($middlewareDefinition) && !is_array($middlewareDefinition) && !is_string($middlewareDefinition)) { + throw new InvalidMiddlewareDefinitionException($middlewareDefinition); + } + $middleware = $this->create($middlewareDefinition); if (!$middleware instanceof PushMiddlewareInterface) { diff --git a/src/Middleware/Push/PushMiddlewareFactoryInterface.php b/src/Middleware/Push/PushMiddlewareFactoryInterface.php index 925ad8f1..f256e65e 100644 --- a/src/Middleware/Push/PushMiddlewareFactoryInterface.php +++ b/src/Middleware/Push/PushMiddlewareFactoryInterface.php @@ -4,19 +4,27 @@ namespace Yiisoft\Queue\Middleware\Push; +use Yiisoft\Queue\Middleware\InvalidMiddlewareDefinitionException; + /** * Creates a middleware based on the definition provided. * You may implement this interface if you want to introduce custom definitions or pass additional data to * the middleware created. + * + * @template T */ interface PushMiddlewareFactoryInterface { /** - * Create a middleware based on definition provided. + * Create a middleware based on the definition provided. + * + * @param mixed $middlewareDefinition Middleware definition to use. * - * @param array|callable|PushMiddlewareInterface|string $middlewareDefinition Middleware definition to use. + * @throws InvalidMiddlewareDefinitionException If the definition is not supported or is invalid. * * @return PushMiddlewareInterface + * + * @psalm-param T $middlewareDefinition */ - public function createPushMiddleware(callable|array|string|PushMiddlewareInterface $middlewareDefinition): PushMiddlewareInterface; + public function createPushMiddleware(mixed $middlewareDefinition): PushMiddlewareInterface; } diff --git a/src/Queue.php b/src/Queue.php index 2da7e615..73ae0a63 100644 --- a/src/Queue.php +++ b/src/Queue.php @@ -13,7 +13,6 @@ use Yiisoft\Queue\Middleware\Push\PushHandlerInterface; use Yiisoft\Queue\Middleware\Push\PushMiddlewareConfig; use Yiisoft\Queue\Middleware\Push\PushMiddlewareDispatcher; -use Yiisoft\Queue\Middleware\Push\PushMiddlewareInterface; use Yiisoft\Queue\Middleware\Push\SynchronousPushHandler; use Yiisoft\Queue\Worker\WorkerInterface; use Yiisoft\Queue\Message\IdEnvelope; @@ -22,7 +21,7 @@ final class Queue implements QueueInterface { /** - * @var array Queue-specific middleware definitions. + * @var mixed[] Queue-specific middleware definitions. */ private array $middlewareDefinitions; @@ -48,8 +47,7 @@ final class Queue implements QueueInterface * definitions. * @param AdapterInterface|null $adapter The message adapter (`null` for synchronous mode). * @param string|BackedEnum $name The queue name. - * @param PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions Queue-specific middleware - * definitions. + * @param mixed ...$middlewareDefinitions Queue-specific middleware definitions. */ public function __construct( private readonly WorkerInterface $worker, @@ -58,7 +56,7 @@ public function __construct( PushMiddlewareConfig $middlewareConfig, private readonly ?AdapterInterface $adapter = null, string|BackedEnum $name = QueueProviderInterface::DEFAULT_QUEUE, - PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions, + mixed ...$middlewareDefinitions, ) { $this->name = StringNormalizer::normalize($name); $this->baseDispatcher = new PushMiddlewareDispatcher( @@ -160,14 +158,14 @@ public function status(string|int $id): MessageStatus return $this->adapter->status($id); } - public function withMiddlewares(PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions): self + public function withMiddlewares(mixed ...$middlewareDefinitions): self { $instance = clone $this; $instance->setMiddlewaresAndPrepareDispatcher($middlewareDefinitions); return $instance; } - public function withMiddlewaresAdded(PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions): self + public function withMiddlewaresAdded(mixed ...$middlewareDefinitions): self { $instance = clone $this; $instance->setMiddlewaresAndPrepareDispatcher([...array_values($instance->middlewareDefinitions), ...array_values($middlewareDefinitions)]); @@ -175,7 +173,7 @@ public function withMiddlewaresAdded(PushMiddlewareInterface|callable|array|stri } /** - * @param array $middlewareDefinitions + * @param mixed[] $middlewareDefinitions */ private function setMiddlewaresAndPrepareDispatcher(array $middlewareDefinitions): void { diff --git a/src/QueueInterface.php b/src/QueueInterface.php index 667bd235..08339681 100644 --- a/src/QueueInterface.php +++ b/src/QueueInterface.php @@ -5,7 +5,6 @@ namespace Yiisoft\Queue; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Middleware\Push\PushMiddlewareInterface; interface QueueInterface { @@ -45,14 +44,14 @@ public function getName(): string; /** * Creates a new instance with the specified middlewares. All the existing middlewares are replaced. * - * @param PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions The middleware definitions. + * @param mixed ...$middlewareDefinitions The middleware definitions. */ - public function withMiddlewares(PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions): self; + public function withMiddlewares(mixed ...$middlewareDefinitions): self; /** * Creates a new instance with the specified middlewares added after the existing ones. * - * @param PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions The middleware definitions. + * @param mixed ...$middlewareDefinitions The middleware definitions. */ - public function withMiddlewaresAdded(PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions): self; + public function withMiddlewaresAdded(mixed ...$middlewareDefinitions): self; } diff --git a/stubs/StubQueue.php b/stubs/StubQueue.php index 25d861fa..4dfc8282 100644 --- a/stubs/StubQueue.php +++ b/stubs/StubQueue.php @@ -6,7 +6,6 @@ use Yiisoft\Queue\MessageStatus; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Middleware\Push\PushMiddlewareInterface; use Yiisoft\Queue\QueueInterface; /** @@ -40,12 +39,12 @@ public function getName(): string return $this->name; } - public function withMiddlewares(PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions): self + public function withMiddlewares(mixed ...$middlewareDefinitions): self { return $this; } - public function withMiddlewaresAdded(PushMiddlewareInterface|callable|array|string ...$middlewareDefinitions): self + public function withMiddlewaresAdded(mixed ...$middlewareDefinitions): self { return $this; }