Passed
Push — master ( dc4a0e...73b95c )
by Mr
14:47
created

HttpPipelineProvisioner::provision()   B

Complexity

Conditions 4
Paths 1

Size

Total Lines 77
Code Lines 58

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 4
eloc 58
c 4
b 0
f 0
nc 1
nop 3
dl 0
loc 77
ccs 0
cts 14
cp 0
crap 20
rs 8.9163

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the daikon-cqrs/boot project.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Daikon\Boot\Service\Provisioner;
10
11
use Aura\Router\RouterContainer;
12
use Auryn\Injector;
13
use Daikon\Boot\Config\RoutingConfigLoader;
14
use Daikon\Boot\Middleware\PipelineBuilderInterface;
15
use Daikon\Boot\Middleware\RoutingHandler;
16
use Daikon\Boot\Service\ServiceDefinitionInterface;
17
use Daikon\Config\ConfigProviderInterface;
18
use Middlewares\ContentEncoding;
19
use Middlewares\ContentLanguage;
20
use Middlewares\ContentType;
21
use Middlewares\JsonPayload;
22
use Middlewares\RequestHandler;
23
use Middlewares\UrlEncodePayload;
24
use Neomerx\Cors\Analyzer;
25
use Neomerx\Cors\Contracts\AnalyzerInterface;
26
use Neomerx\Cors\Strategies\Settings;
27
use Psr\Container\ContainerInterface;
28
use Psr\Log\LoggerInterface;
29
30
final class HttpPipelineProvisioner implements ProvisionerInterface
31
{
32
    public function provision(
33
        Injector $injector,
34
        ConfigProviderInterface $configProvider,
35
        ServiceDefinitionInterface $serviceDefinition
36
    ): void {
37
        $serviceClass = $serviceDefinition->getServiceClass();
38
        $settings = $serviceDefinition->getSettings();
39
40
        $injector
41
            ->define($serviceClass, [':settings' => $settings])
42
            ->share($serviceClass)
43
            ->alias(PipelineBuilderInterface::class, $serviceClass)
44
            // Content Negotiation
45
            ->define(ContentLanguage::class, [
46
                ':languages' => $configProvider->get('project.negotiation.languages', ['en'])
47
            ])
48
            ->define(ContentEncoding::class, [':encodings' => ['gzip', 'deflate']])
49
            ->delegate(ContentType::class, function () use ($configProvider): ContentType {
50
                return (new ContentType($configProvider->get('project.negotiation.content_types')))
51
                    ->charsets($configProvider->get('project.negotiation.charsets', ['UTF-8']))
52
                    ->nosniff($configProvider->get('project.negotiation.nosniff', true))
53
                    ->errorResponse();
54
            })
55
            // Cors
56
            ->share(AnalyzerInterface::class)
57
            ->alias(AnalyzerInterface::class, Analyzer::class)
58
            ->delegate(Analyzer::class, function () use ($injector, $configProvider): AnalyzerInterface {
59
                $corsSettings = (new Settings)
60
                    // skipping ->init() because it doesn't look good
61
                    ->disableCheckHost()
62
                    ->disableAddAllowedMethodsToPreFlightResponse()
63
                    ->disableAddAllowedHeadersToPreFlightResponse()
64
                    ->setCredentialsNotSupported()
65
                    ->setServerOrigin(
66
                        $configProvider->get('project.cors.scheme'),
67
                        $configProvider->get('project.cors.host'),
68
                        $configProvider->get('project.cors.port')
69
                    )->setAllowedOrigins(
70
                        $configProvider->get('project.cors.request.allowed_origins', [])
71
                    )->setAllowedHeaders(
72
                        $configProvider->get('project.cors.request.allowed_headers', [])
73
                    )->setAllowedMethods(
74
                        $configProvider->get('project.cors.request.allowed_methods', [])
75
                    )->setPreFlightCacheMaxAge(
76
                        $configProvider->get('project.cors.response.preflight_cache_max_age', 0)
77
                    )->setExposedHeaders(
78
                        $configProvider->get('project.cors.response.exposed_headers', [])
79
                    );
80
                if ($configProvider->get('project.cors.request.enable_check_host') === true) {
81
                    $corsSettings = $corsSettings->enableCheckHost();
82
                }
83
                if ($configProvider->get('project.cors.request.allowed_all_origins') === true) {
84
                    $corsSettings = $corsSettings->enableAllOriginsAllowed();
85
                }
86
                if ($configProvider->get('project.cors.request.allowed_credentials') === true) {
87
                    $corsSettings = $corsSettings->setCredentialsSupported();
88
                }
89
                $corsSettings->setLogger($injector->make(LoggerInterface::class));
90
                return Analyzer::instance($corsSettings);
91
            })
92
            // Routing and request
93
            ->share(JsonPayload::class)
94
            ->delegate(JsonPayload::class, fn(): JsonPayload => (new JsonPayload)->depth(8)->override(true))
95
            ->share(UrlEncodePayload::class)
96
            ->delegate(UrlEncodePayload::class, fn(): UrlEncodePayload => (new UrlEncodePayload)->override(true))
97
            ->share(RoutingHandler::class)
98
            ->delegate(
99
                RoutingHandler::class,
100
                function (ContainerInterface $container) use ($configProvider): RoutingHandler {
101
                    return new RoutingHandler($this->routerFactory($configProvider), $container);
102
                }
103
            )
104
            ->share(RequestHandler::class)
105
            ->delegate(
106
                RequestHandler::class,
107
                function (ContainerInterface $container): RequestHandler {
108
                    return (new RequestHandler($container))->handlerAttribute(RoutingHandler::REQUEST_HANDLER);
109
                }
110
            );
111
    }
112
113
    private function routerFactory(ConfigProviderInterface $configProvider): RouterContainer
114
    {
115
        $appContext = $configProvider->get('app.context');
116
        $appEnv = $configProvider->get('app.env');
117
        $appConfigDir = $configProvider->get('app.config_dir');
118
        $router = new RouterContainer;
119
        (new RoutingConfigLoader($router, $configProvider))->load(
120
            array_merge([$appConfigDir], (array)$configProvider->get('crates.*.config_dir', [])),
121
            [
122
                'routing.php',
123
                "routing.$appContext.php",
124
                "routing.$appEnv.php",
125
                "routing.$appContext.$appEnv.php"
126
            ]
127
        );
128
        return $router;
129
    }
130
}
131