Passed
Push — master ( fa7b2e...1cfa67 )
by Mihail
14:51
created

Module::defaultConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 12
nc 1
nop 0
dl 0
loc 21
ccs 3
cts 3
cp 1
crap 1
rs 9.8666
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};
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 ReflectionClass;
17
use function dirname;
18
use function is_a;
19
use function is_readable;
20
use function Koded\Caching\simple_cache_factory;
21
use function putenv;
22
23
final class Module implements DIModule
24
{
25
    private const ENV_KEY = '__KODED_CONFIG';
26
27 20
    public function __construct(private Configuration|string $configuration) {}
28
29 20
    public function configure(DIContainer $container): void
30
    {
31 20
        $container->named('$errorSerializer', 'default_serialize_error');
32 20
        $container->bind(Request::class,         /* defer */);
33 20
        $container->bind(Response::class,        /* defer */);
34 20
        $container->bind(Configuration::class,   /* defer */);
35 20
        $container->bind(CacheInterface::class,  /* defer */);
36 20
        $container->bind(LoggerInterface::class, /* defer */);
37 20
        $container->bind(ServerRequestInterface::class, ServerRequest::class);
38 20
        $container->bind(ResponseInterface::class, ServerResponse::class);
39
        // Core instances
40 20
        $container->share($conf = $this->configuration());
41 20
        I18n::register(I18nCatalog::new($conf), true);
42 20
        $container->share(new Log(...$conf->get('logging', [])));
43 20
        $container->share(simple_cache_factory(...$conf->get('caching', [])));
44 20
        $container->share($container->new(Router::class));
45
        // Default authentication
46 20
        $container->bind(AuthBackend::class, SessionAuthBackend::class);
47 20
        $container->bind(AuthProcessor::class, BearerAuthProcessor::class);
48
    }
49
50 20
    private function configuration(): Configuration
51
    {
52 20
        $factory = new Config('', $this->defaultConfiguration());
53 20
        if (empty($this->configuration)) {
54 14
            goto load;
55
        }
56 6
        if (is_a($this->configuration, Configuration::class, true)) {
57 6
            $factory->fromObject($this->configuration);
58 6
            $factory->rootPath = dirname((new ReflectionClass($this->configuration))->getFileName());
59
        } elseif (is_readable($this->configuration)) {
60
            putenv(self::ENV_KEY . '=' . $this->configuration);
61
            $factory->fromEnvVariable(self::ENV_KEY);
62
            $factory->rootPath = dirname($this->configuration);
63
        }
64
        load:
65 20
        @$factory->fromEnvFile('.env');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fromEnvFile(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

65
        /** @scrutinizer ignore-unhandled */ @$factory->fromEnvFile('.env');

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
66 20
        foreach ($factory->get('autoloaders', []) as $autoloader) {
67
            include_once $autoloader;
68
        }
69 20
        return $factory;
70
    }
71
72 20
    private function defaultConfiguration(): Immutable
73
    {
74 20
        return new Immutable(
75
            [
76
                // CORS overrides (all values are scalar)
77 20
                'cors.disable' => false,
78
                'cors.origin' => '',
79
                'cors.methods' => '',
80
                'cors.headers' => '',
81
                'cors.expose' => 'Authorization, X-Forwarded-With',
82
                'cors.maxAge' => 0,
83
84
                'logging' => [
85
                    [
86
                        [
87
                            'class' => Cli::class,
88
                            'format' => '[levelname] message',
89
                            'levels' => Log::INFO
90
                        ]
91
                    ],
92
                    'dateformat' => 'd-m-Y H:i:s'
93
                ],
94
            ]);
95
    }
96
}
97