Module   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 5
Bugs 1 Features 1
Metric Value
eloc 43
c 5
b 1
f 1
dl 0
loc 74
ccs 49
cts 49
cp 1
rs 10
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 1 1
A defaultConfiguration() 0 26 1
A configuration() 0 20 6
A configure() 0 18 1
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
        // Default authentication
44 39
        $container->bind(AuthBackend::class, SessionAuthBackend::class);
45 39
        $container->bind(AuthProcessor::class, BearerAuthProcessor::class);
46
    }
47
48 39
    private function configuration(): Configuration
49
    {
50 39
        $factory = new Config('', $this->defaultConfiguration());
51 39
        if (empty($this->configuration)) {
52 30
            goto load;
53
        }
54 9
        if (is_a($this->configuration, Configuration::class, true)) {
55 8
            $factory->fromObject($this->configuration);
56
            //$factory->root = dirname((new ReflectionClass($this->configuration))->getFileName());
57 1
        } elseif (is_readable($this->configuration)) {
58 1
            putenv(self::ENV_KEY . '=' . $this->configuration);
59 1
            $factory->fromEnvVariable(self::ENV_KEY);
60 1
            $factory->root = dirname($this->configuration);
61
        }
62
        load:
63 39
        is_readable("$factory->root/.env") and $factory->fromEnvFile("$factory->root/.env");
64 39
        foreach ($factory->get('autoloaders', []) as $autoloader) {
65 2
            include_once $autoloader;
66
        }
67 39
        return $factory;
68
    }
69
70 39
    private function defaultConfiguration(): Immutable
71
    {
72 39
        return new Immutable(
73 39
            [
74
                // I18n directives
75 39
                'translation.dir' => __DIR__ . '/../locale',
76 39
                'translation.formatter' => CurlyFormatter::class,
77
78
                // CORS overrides (all values are scalar)
79 39
                'cors.disable' => false,
80 39
                'cors.origin' => '',
81 39
                'cors.methods' => '',
82 39
                'cors.headers' => '',
83 39
                'cors.expose' => '',
84 39
                'cors.maxAge' => 0,
85
86
                // Logging
87 39
                'logging' => [
88 39
                    [
89 39
                        [
90 39
                            'class' => Cli::class,
91 39
                            'format' => '[levelname] message',
92 39
                            'levels' => Log::INFO
93 39
                        ]
94 39
                    ],
95 39
                    'dateformat' => 'd-m-Y H:i:s'
96 39
                ],
97 39
            ]);
98
    }
99
}
100