Passed
Push — master ( 724c5e...51e478 )
by Mihail
02:14
created

Module::configuration()   A

Complexity

Conditions 6
Paths 16

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 14
nc 16
nop 0
dl 0
loc 20
ccs 14
cts 14
cp 1
crap 6
rs 9.2222
c 1
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Koded\Framework;
4
5
use Koded\{DIContainer, DIModule};
6
use Koded\Framework\Auth\{AuthBackend, AuthProcessor, BearerAuthProcessor, SessionAuthBackend};
7
use Koded\Http\{ServerRequest, ServerResponse};
8
use Koded\Http\Interfaces\{Request, Response};
9
use Koded\I18n\{I18n, I18nCatalog, CurlyFormatter};
10
use Koded\Logging\Log;
11
use Koded\Logging\Processors\Cli;
12
use Koded\Stdlib\{Config, Configuration, Immutable};
13
use Psr\Http\Message\{ResponseInterface, ServerRequestInterface};
14
use Psr\Log\LoggerInterface;
15
use Psr\SimpleCache\CacheInterface;
16
use function dirname;
17
use function is_a;
18
use function is_readable;
19
use function Koded\Caching\simple_cache_factory;
20
use function putenv;
21
22
final class Module implements DIModule
23
{
24
    private const ENV_KEY = '__KODED_CONFIG';
25
26
    public function __construct(private Configuration|string $configuration) {}
27
28 39
    public function configure(DIContainer $container): void
29
    {
30 39
        $container->named('$errorSerializer', 'default_serialize_error');
31 39
        $container->bind(Request::class,         /* defer */);
32 39
        $container->bind(Response::class,        /* defer */);
33 39
        $container->bind(Configuration::class,   /* defer */);
34 39
        $container->bind(CacheInterface::class,  /* defer */);
35 39
        $container->bind(LoggerInterface::class, /* defer */);
36 39
        $container->bind(ServerRequestInterface::class, ServerRequest::class);
37 39
        $container->bind(ResponseInterface::class, ServerResponse::class);
38
        // Core instances
39 39
        $container->share($conf = $this->configuration());
40 39
        I18n::register(I18nCatalog::new($conf), true);
41 39
        $container->share(new Log(...$conf->get('logging', [])));
42 39
        $container->share(simple_cache_factory(...$conf->get('caching', [])));
43 39
        $container->share($container->new(Router::class));
44
        // Default authentication
45 39
        $container->bind(AuthBackend::class, SessionAuthBackend::class);
46 39
        $container->bind(AuthProcessor::class, BearerAuthProcessor::class);
47
    }
48
49 39
    private function configuration(): Configuration
50
    {
51 39
        $factory = new Config('', $this->defaultConfiguration());
52 39
        if (empty($this->configuration)) {
53 30
            goto load;
54
        }
55 9
        if (is_a($this->configuration, Configuration::class, true)) {
56 8
            $factory->fromObject($this->configuration);
57
            //$factory->root = dirname((new ReflectionClass($this->configuration))->getFileName());
58 1
        } elseif (is_readable($this->configuration)) {
59 1
            putenv(self::ENV_KEY . '=' . $this->configuration);
60 1
            $factory->fromEnvVariable(self::ENV_KEY);
61 1
            $factory->root = dirname($this->configuration);
62
        }
63
        load:
64 39
        is_readable("$factory->root/.env") and $factory->fromEnvFile("$factory->root/.env");
65 39
        foreach ($factory->get('autoloaders', []) as $autoloader) {
66 2
            include_once $autoloader;
67
        }
68 39
        return $factory;
69
    }
70
71 39
    private function defaultConfiguration(): Immutable
72
    {
73 39
        return new Immutable(
74 39
            [
75
                // I18n directives
76 39
                'translation.dir' => __DIR__ . '/../locale',
77 39
                'translation.formatter' => CurlyFormatter::class,
78
79
                // CORS overrides (all values are scalar)
80 39
                'cors.disable' => false,
81 39
                'cors.origin' => '',
82 39
                'cors.methods' => '',
83 39
                'cors.headers' => '',
84 39
                'cors.expose' => '',
85 39
                'cors.maxAge' => 0,
86
87
                // Logging
88 39
                'logging' => [
89 39
                    [
90 39
                        [
91 39
                            'class' => Cli::class,
92 39
                            'format' => '[levelname] message',
93 39
                            'levels' => Log::INFO
94 39
                        ]
95 39
                    ],
96 39
                    'dateformat' => 'd-m-Y H:i:s'
97 39
                ],
98 39
            ]);
99
    }
100
}
101