PushMiddlewareDispatcher::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 5
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Queue\Middleware\Push;
6
7
use Closure;
8
9
final class PushMiddlewareDispatcher
10
{
11
    /**
12
     * Contains a middleware pipeline handler.
13
     *
14
     * @var MiddlewarePushStack|null The middleware stack.
15
     */
16
    private ?MiddlewarePushStack $stack = null;
17
    /**
18
     * @var array[]|callable[]|MiddlewarePushInterface[]|string[]
19
     */
20
    private array $middlewareDefinitions;
21
22 27
    public function __construct(
23
        private MiddlewareFactoryPushInterface $middlewareFactory,
24
        array|callable|string|MiddlewarePushInterface ...$middlewareDefinitions,
25
    ) {
26 27
        $this->middlewareDefinitions = array_reverse($middlewareDefinitions);
27
    }
28
29
    /**
30
     * Dispatch request through middleware to get response.
31
     *
32
     * @param PushRequest $request Request to pass to middleware.
33
     * @param MessageHandlerPushInterface $finishHandler Handler to use in case no middleware produced response.
34
     */
35 15
    public function dispatch(
36
        PushRequest $request,
37
        MessageHandlerPushInterface $finishHandler
38
    ): PushRequest {
39 15
        if ($this->stack === null) {
40 15
            $this->stack = new MiddlewarePushStack($this->buildMiddlewares(), $finishHandler);
41
        }
42
43 15
        return $this->stack->handlePush($request);
0 ignored issues
show
Bug introduced by
The method handlePush() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

43
        return $this->stack->/** @scrutinizer ignore-call */ handlePush($request);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
44
    }
45
46
    /**
47
     * Returns new instance with middleware handlers replaced with the ones provided.
48
     * Last specified handler will be executed first.
49
     *
50
     * @param array[]|callable[]|MiddlewarePushInterface[]|string[] $middlewareDefinitions Each array element is:
51
     *
52
     * - A name of a middleware class. The middleware instance will be obtained from container executed.
53
     * - A callable with `function(ServerRequestInterface $request, RequestHandlerInterface $handler):
54
     *     ResponseInterface` signature.
55
     * - A "callable-like" array in format `[FooMiddleware::class, 'index']`. `FooMiddleware` instance will
56
     *   be created and `index()` method will be executed.
57
     * - A function returning a middleware. The middleware returned will be executed.
58
     *
59
     * For callables typed parameters are automatically injected using dependency injection container.
60
     *
61
     * @return self New instance of the {@see PushMiddlewareDispatcher}
62
     */
63 18
    public function withMiddlewares(array $middlewareDefinitions): self
64
    {
65 18
        $instance = clone $this;
66 18
        $instance->middlewareDefinitions = array_reverse($middlewareDefinitions);
67
68
        // Fixes a memory leak.
69 18
        unset($instance->stack);
70 18
        $instance->stack = null;
71
72 18
        return $instance;
73
    }
74
75
    /**
76
     * @return bool Whether there are middleware defined in the dispatcher.
77
     */
78 2
    public function hasMiddlewares(): bool
79
    {
80 2
        return $this->middlewareDefinitions !== [];
81
    }
82
83
    /**
84
     * @return Closure[]
85
     */
86 15
    private function buildMiddlewares(): array
87
    {
88 15
        $middlewares = [];
89 15
        $factory = $this->middlewareFactory;
90
91 15
        foreach ($this->middlewareDefinitions as $middlewareDefinition) {
92 7
            $middlewares[] = static fn (): MiddlewarePushInterface => $factory->createPushMiddleware(
93 7
                $middlewareDefinition
94 7
            );
95
        }
96
97 15
        return $middlewares;
98
    }
99
}
100