Passed
Push — master ( 5c8ce9...10deca )
by Rustam
12:11
created

anonymous//src/WrapperFactory.php$0   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 23
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 4
c 1
b 0
f 0
dl 0
loc 23
ccs 9
cts 9
cp 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Middleware\Dispatcher;
6
7
use Psr\Container\ContainerInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\ServerRequestInterface;
10
use Psr\Http\Server\MiddlewareInterface;
11
use Psr\Http\Server\RequestHandlerInterface;
12
use Yiisoft\Injector\Injector;
13
14
final class WrapperFactory implements WrapperFactoryInterface
15
{
16
    private ContainerInterface $container;
17
18 27
    public function __construct(ContainerInterface $container)
19
    {
20 27
        $this->container = $container;
21
    }
22
23
    /**
24
     * {@inheritDoc}
25
     */
26 13
    public function create($callable): MiddlewareInterface
27
    {
28 13
        if (is_array($callable)) {
29 5
            return $this->createActionWrapper($callable[0], $callable[1]);
30
        }
31
32 8
        return $this->createCallableWrapper($callable);
33
    }
34
35 8
    public function createCallableWrapper(callable $callback): MiddlewareInterface
36
    {
37 8
        return new class ($callback, $this->container) implements MiddlewareInterface {
38
            private ContainerInterface $container;
39
            private $callback;
40
41
            public function __construct(callable $callback, ContainerInterface $container)
42
            {
43 8
                $this->callback = $callback;
44 8
                $this->container = $container;
45
            }
46
47
            public function process(
48
                ServerRequestInterface $request,
49
                RequestHandlerInterface $handler
50
            ): ResponseInterface {
51
                /** @var MiddlewareInterface|mixed|ResponseInterface $response */
52 8
                $response = (new Injector($this->container))->invoke($this->callback, [$request, $handler]);
53 8
                if ($response instanceof ResponseInterface) {
54 5
                    return $response;
55
                }
56 3
                if ($response instanceof MiddlewareInterface) {
57 2
                    return $response->process($request, $handler);
58
                }
59 1
                throw new InvalidMiddlewareDefinitionException($this->callback);
60
            }
61
        };
62
    }
63
64 5
    private function createActionWrapper(string $class, string $method): MiddlewareInterface
65
    {
66 5
        return new class ($this->container, $class, $method) implements MiddlewareInterface {
67
            private string $class;
68
            private string $method;
69
            private ContainerInterface $container;
70
71
            public function __construct(ContainerInterface $container, string $class, string $method)
72
            {
73 5
                $this->container = $container;
74 5
                $this->class = $class;
75 5
                $this->method = $method;
76
            }
77
78
            public function process(
79
                ServerRequestInterface $request,
80
                RequestHandlerInterface $handler
81
            ): ResponseInterface {
82
                /** @var mixed $controller */
83 5
                $controller = $this->container->get($this->class);
84
85
                /** @var mixed|ResponseInterface $response */
86 5
                $response = (new Injector($this->container))
87 5
                    ->invoke([$controller, $this->method], [$request, $handler]);
88 5
                if ($response instanceof ResponseInterface) {
89 4
                    return $response;
90
                }
91
92 1
                throw new InvalidMiddlewareDefinitionException([$this->class, $this->method]);
93
            }
94
95
            public function __debugInfo()
96
            {
97
                return [
98 1
                    'callback' => [$this->class, $this->method],
99
                ];
100
            }
101
        };
102
    }
103
}
104