Passed
Pull Request — master (#1104)
by Maxim
12:14
created

HttpBootloader::defineSingletons()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 1.0233

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 17
dl 0
loc 30
ccs 15
cts 21
cp 0.7143
rs 9.7
c 1
b 0
f 0
cc 1
nc 1
nop 0
crap 1.0233
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;
10
use Psr\Http\Server\MiddlewareInterface;
11
use Psr\Http\Server\RequestHandlerInterface;
12
use Spiral\Boot\Bootloader\Bootloader;
13
use Spiral\Config\ConfiguratorInterface;
14
use Spiral\Config\Patch\Append;
15
use Spiral\Core\Attribute\Proxy;
16
use Spiral\Core\Attribute\Singleton;
17
use Spiral\Core\BinderInterface;
18
use Spiral\Core\Container\Autowire;
19
use Spiral\Core\InvokerInterface;
20
use Spiral\Framework\Spiral;
21
use Spiral\Http\Config\HttpConfig;
22
use Spiral\Http\CurrentRequest;
23
use Spiral\Http\Exception\HttpException;
24
use Spiral\Http\Http;
25
use Spiral\Http\Pipeline;
26
use Spiral\Telemetry\Bootloader\TelemetryBootloader;
27
use Spiral\Telemetry\TracerFactoryInterface;
28
29
/**
30
 * Configures Http dispatcher.
31
 */
32
#[Singleton]
33
final class HttpBootloader extends Bootloader
34
{
35 360
    public function __construct(
36
        private readonly ConfiguratorInterface $config,
37
        private readonly BinderInterface $binder,
38
    ) {
39 360
    }
40
41 360
    public function defineDependencies(): array
42
    {
43 360
        return [
44 360
            TelemetryBootloader::class,
45 360
        ];
46
    }
47
48 360
    public function defineSingletons(): array
49
    {
50 360
        $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

50
        /** @scrutinizer ignore-call */ 
51
        $httpBinder = $this->binder->getBinder(Spiral::Http);
Loading history...
51
52 360
        $httpBinder->bindSingleton(Http::class, [self::class, 'httpCore']);
53 360
        $httpBinder->bindSingleton(CurrentRequest::class, CurrentRequest::class);
54 360
        $httpBinder->bind(
55 360
            ServerRequestInterface::class,
56 360
            static fn (CurrentRequest $request): ServerRequestInterface => $request->get() ?? throw new HttpException(
57 360
                'Unable to resolve current server request.',
58 360
            )
59 360
        );
60
61
        /**
62
         * @deprecated since v3.12. Will be removed in v4.0.
63
         */
64 360
        $this->binder->bindSingleton(
65 360
            Http::class,
66
            function (InvokerInterface $invoker, #[Proxy] ContainerInterface $container): Http {
67
                @trigger_error(\sprintf(
68
                    'Using `%s` outside of the `%s` scope is deprecated and will be impossible in version 4.0.',
69
                    Http::class,
70
                    Spiral::Http->value
71
                ), \E_USER_DEPRECATED);
72
73
                return $invoker->invoke([self::class, 'httpCore'], ['container' => $container]);
74 360
            }
75 360
        );
76
77 360
        return [];
78
    }
79
80 360
    public function init(): void
81
    {
82 360
        $this->config->setDefaults(
83 360
            HttpConfig::CONFIG,
84 360
            [
85 360
                'basePath'   => '/',
86 360
                'headers'    => [
87 360
                    'Content-Type' => 'text/html; charset=UTF-8',
88 360
                ],
89 360
                'middleware' => [],
90 360
                'chunkSize' => null,
91 360
                'inputBags' => [],
92 360
            ]
93 360
        );
94
    }
95
96
    /**
97
     * Register new http middleware.
98
     *
99
     * @psalm-param MiddlewareInterface|Autowire|class-string<MiddlewareInterface> Middleware definition
100
     */
101 355
    public function addMiddleware(string|Autowire|MiddlewareInterface $middleware): void
102
    {
103 355
        $this->config->modify(HttpConfig::CONFIG, new Append('middleware', null, $middleware));
104
    }
105
106
    /**
107
     * @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...
108
     * @param array{"class": class-string, "source": string, "alias": string} $config
109
     */
110 1
    public function addInputBag(string $bag, array $config): void
111
    {
112 1
        $this->config->modify(HttpConfig::CONFIG, new Append('inputBags', $bag, $config));
113
    }
114
115
    /**
116
     * @deprecated since v3.12. Will be removed in v4.0 and replaced with callback.
117
     */
118 48
    protected function httpCore(
119
        HttpConfig $config,
120
        Pipeline $pipeline,
121
        RequestHandlerInterface $handler,
122
        ResponseFactoryInterface $responseFactory,
123
        ContainerInterface $container,
124
        TracerFactoryInterface $tracerFactory
125
    ): Http {
126 48
        $core = new Http($config, $pipeline, $responseFactory, $container, $tracerFactory);
127 48
        $core->setHandler($handler);
128
129 48
        return $core;
130
    }
131
}
132