Passed
Push — master ( 37709b...f45e89 )
by Aleksei
06:22 queued 17s
created

HttpBootloader::addInputBag()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Bootloader\Http;
6
7
use Psr\Container\ContainerInterface;
8
use Psr\Http\Message\ResponseFactoryInterface;
9
use Psr\Http\Message\ServerRequestInterface as RequestInterface;
10
use Psr\Http\Server\MiddlewareInterface;
11
use Psr\Http\Server\RequestHandlerInterface;
12
use Spiral\Boot\Bootloader\Bootloader;
13
use Spiral\Bootloader\Http\Exception\InvalidRequestScopeException;
14
use Spiral\Config\ConfiguratorInterface;
15
use Spiral\Config\Patch\Append;
16
use Spiral\Core\Attribute\Proxy;
17
use Spiral\Core\Attribute\Singleton;
18
use Spiral\Core\BinderInterface;
19
use Spiral\Core\Container;
20
use Spiral\Core\Container\Autowire;
21
use Spiral\Core\InvokerInterface;
22
use Spiral\Framework\Spiral;
23
use Spiral\Http\Config\HttpConfig;
24
use Spiral\Http\CurrentRequest;
25
use Spiral\Http\Http;
26
use Spiral\Http\Pipeline;
27
use Spiral\Telemetry\Bootloader\TelemetryBootloader;
28
use Spiral\Telemetry\TracerFactoryInterface;
29
30
/**
31
 * Configures Http dispatcher.
32
 */
33
#[Singleton]
34
final class HttpBootloader extends Bootloader
35
{
36 373
    public function __construct(
37
        private readonly ConfiguratorInterface $config,
38
        private readonly BinderInterface $binder,
39
    ) {
40 373
    }
41
42 373
    public function defineDependencies(): array
43
    {
44 373
        return [
45 373
            TelemetryBootloader::class,
46 373
        ];
47
    }
48
49 373
    public function defineSingletons(): array
50
    {
51 373
        $httpBinder = $this->binder->getBinder(Spiral::Http);
0 ignored issues
show
Bug introduced by
The method getBinder() does not exist on Spiral\Core\BinderInterface. It seems like you code against a sub-type of Spiral\Core\BinderInterface such as Spiral\Core\Container. ( Ignorable by Annotation )

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

51
        /** @scrutinizer ignore-call */ 
52
        $httpBinder = $this->binder->getBinder(Spiral::Http);
Loading history...
52
53 373
        $httpBinder->bindSingleton(Http::class, [self::class, 'httpCore']);
54 373
        $httpBinder->bindSingleton(CurrentRequest::class, CurrentRequest::class);
55 373
        $httpBinder->bind(
56 373
            RequestInterface::class,
57 373
            new \Spiral\Core\Config\Proxy(
58 373
                interface: RequestInterface::class,
59 373
                fallbackFactory: static fn (ContainerInterface $c): RequestInterface => $c
60 373
                    ->get(CurrentRequest::class)
61 373
                    ->get() ?? throw new InvalidRequestScopeException(
62 373
                        RequestInterface::class,
63 373
                        $c instanceof Container ? $c : null,
64 373
                    ),
65 373
            ),
66 373
        );
67
68
        /**
69
         * @deprecated since v3.12. Will be removed in v4.0.
70
         */
71 373
        $this->binder->bindSingleton(
72 373
            Http::class,
73
            function (InvokerInterface $invoker, #[Proxy] ContainerInterface $container): Http {
74
                @trigger_error(\sprintf(
75
                    'Using `%s` outside of the `%s` scope is deprecated and will be impossible in version 4.0.',
76
                    Http::class,
77
                    Spiral::Http->value
78
                ), \E_USER_DEPRECATED);
79
80
                return $invoker->invoke([self::class, 'httpCore'], ['container' => $container]);
81 373
            }
82 373
        );
83
84 373
        return [];
85
    }
86
87 373
    public function init(): void
88
    {
89 373
        $this->config->setDefaults(
90 373
            HttpConfig::CONFIG,
91 373
            [
92 373
                'basePath'   => '/',
93 373
                'headers'    => [
94 373
                    'Content-Type' => 'text/html; charset=UTF-8',
95 373
                ],
96 373
                'middleware' => [],
97 373
                'chunkSize' => null,
98 373
                'inputBags' => [],
99 373
            ]
100 373
        );
101
    }
102
103
    /**
104
     * Register new http middleware.
105
     *
106
     * @psalm-param MiddlewareInterface|Autowire|class-string<MiddlewareInterface> Middleware definition
107
     */
108 356
    public function addMiddleware(string|Autowire|MiddlewareInterface $middleware): void
109
    {
110 356
        $this->config->modify(HttpConfig::CONFIG, new Append('middleware', null, $middleware));
111
    }
112
113
    /**
114
     * @param non-empty-string $bag
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
115
     * @param array{"class": class-string, "source": string, "alias": string} $config
116
     */
117 1
    public function addInputBag(string $bag, array $config): void
118
    {
119 1
        $this->config->modify(HttpConfig::CONFIG, new Append('inputBags', $bag, $config));
120
    }
121
122
    /**
123
     * @deprecated since v3.12. Will be removed in v4.0 and replaced with callback.
124
     */
125 49
    protected function httpCore(
126
        HttpConfig $config,
127
        Pipeline $pipeline,
128
        RequestHandlerInterface $handler,
129
        ResponseFactoryInterface $responseFactory,
130
        ContainerInterface $container,
131
        TracerFactoryInterface $tracerFactory
132
    ): Http {
133 49
        $core = new Http($config, $pipeline, $responseFactory, $container, $tracerFactory);
134 49
        $core->setHandler($handler);
135
136 49
        return $core;
137
    }
138
}
139