Passed
Push — master ( 0e7627...09a47c )
by BENOIT
01:58
created

Configuration::bootstrapFromCLI()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 5
rs 10
ccs 0
cts 0
cp 0
crap 2
1
<?php
2
3
namespace BenTools\MercurePHP\Configuration;
4
5
use Symfony\Component\Console\Input\InputInterface;
6
7
use function BenTools\MercurePHP\nullify;
8
9
final class Configuration
10
{
11
    public const ADDR = 'addr';
12
    public const TRANSPORT_URL = 'transport_url';
13
    public const STORAGE_URL = 'storage_url';
14
    public const METRICS_URL = 'metrics_url';
15
    public const CORS_ALLOWED_ORIGINS = 'cors_allowed_origins';
16
    public const PUBLISH_ALLOWED_ORIGINS = 'publish_allowed_origins';
17
    public const JWT_KEY = 'jwt_key';
18
    public const JWT_ALGORITHM = 'jwt_algorithm';
19
    public const PUBLISHER_JWT_KEY = 'publisher_jwt_key';
20
    public const PUBLISHER_JWT_ALGORITHM = 'publisher_jwt_algorithm';
21
    public const SUBSCRIBER_JWT_KEY = 'subscriber_jwt_key';
22
    public const SUBSCRIBER_JWT_ALGORITHM = 'subscriber_jwt_algorithm';
23
    public const ALLOW_ANONYMOUS = 'allow_anonymous';
24
    private const DEFAULT_CONFIG = [
25
        self::ADDR => '127.0.0.1:3000',
26
        self::TRANSPORT_URL => 'php://localhost?size=1000',
27
        self::STORAGE_URL => null,
28
        self::METRICS_URL => null,
29
        self::CORS_ALLOWED_ORIGINS => '*',
30
        self::PUBLISH_ALLOWED_ORIGINS => '*',
31
        self::JWT_KEY => null,
32
        self::JWT_ALGORITHM => 'HS256',
33
        self::PUBLISHER_JWT_KEY => null,
34
        self::PUBLISHER_JWT_ALGORITHM => null,
35
        self::SUBSCRIBER_JWT_KEY => null,
36
        self::SUBSCRIBER_JWT_ALGORITHM => null,
37
        self::ALLOW_ANONYMOUS => false,
38 413
    ];
39
40 413
    private array $config = self::DEFAULT_CONFIG;
41 408
42
    public function __construct(array $config = [])
43 413
    {
44
        foreach ($config as $key => $value) {
45 413
            $this->set($key, $value);
46
        }
47 413
    }
48 413
49 1
    private function export(): array
50 1
    {
51
        $config = \array_map(fn($value) => \is_string($value) && '' === \trim($value) ? null : $value, $this->config);
52
        if (null === $config[self::JWT_KEY] && null === $config[self::PUBLISHER_JWT_KEY]) {
53
            throw new \InvalidArgumentException(
54 412
                "One of \"jwt_key\" or \"publisher_jwt_key\" configuration parameter must be defined."
55
            );
56
        }
57 413
58
        return $config;
59 413
    }
60
61
    public function asArray(): array
62 412
    {
63
        return $this->export();
64 412
    }
65 412
66
    private function set(string $key, $value): void
67
    {
68 412
        $key = self::normalize($key);
69
        if (!\array_key_exists($key, self::DEFAULT_CONFIG)) {
70
            return;
71 412
        }
72 412
        if (null === $value && \is_bool(self::DEFAULT_CONFIG[$key])) {
73
            $value = self::DEFAULT_CONFIG[$key];
74 4
        }
75
        $this->config[$key] = $value;
76 4
    }
77 4
78 4
    public function overrideWith(array $values): self
79
    {
80
        $clone = clone $this;
81 4
        foreach ($values as $key => $value) {
82
            $clone->set($key, $value);
83
        }
84 412
85
        return $clone;
86 412
    }
87
88
    private static function normalize(string $key): string
89
    {
90
        return \strtolower(\strtr($key, ['-' => '_']));
91
    }
92
93
    public static function bootstrapFromCLI(InputInterface $input): self
94
    {
95
        return (new self())
96
            ->overrideWith($_SERVER)
97
            ->overrideWith(self::filterCLIInput($input));
98
    }
99
100
    private static function filterCLIInput(InputInterface $input): array
101
    {
102
        return \array_filter(
103
            $input->getOptions(),
104
            fn($value) => null !== nullify($value) && false !== $value
105
        );
106
    }
107
}
108