Passed
Pull Request — master (#13)
by BENOIT
07:04
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\Command\Command;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Console\Input\InputOption;
8
9
use function BenTools\MercurePHP\filterCLIInput;
0 ignored issues
show
introduced by
The function BenTools\MercurePHP\filterCLIInput was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
10
use function BenTools\MercurePHP\nullify;
11
12
final class Configuration
13
{
14
    public const ADDR = 'addr';
15
    public const TRANSPORT_URL = 'transport_url';
16
    public const STORAGE_URL = 'storage_url';
17
    public const METRICS_URL = 'metrics_url';
18
    public const CORS_ALLOWED_ORIGINS = 'cors_allowed_origins';
19
    public const PUBLISH_ALLOWED_ORIGINS = 'publish_allowed_origins';
20
    public const JWT_KEY = 'jwt_key';
21
    public const JWT_ALGORITHM = 'jwt_algorithm';
22
    public const PUBLISHER_JWT_KEY = 'publisher_jwt_key';
23
    public const PUBLISHER_JWT_ALGORITHM = 'publisher_jwt_algorithm';
24
    public const SUBSCRIBER_JWT_KEY = 'subscriber_jwt_key';
25
    public const SUBSCRIBER_JWT_ALGORITHM = 'subscriber_jwt_algorithm';
26
    public const ALLOW_ANONYMOUS = 'allow_anonymous';
27
    private const DEFAULT_CONFIG = [
28
        self::ADDR => '127.0.0.1:3000',
29
        self::TRANSPORT_URL => 'php://localhost?size=1000',
30
        self::STORAGE_URL => null,
31
        self::METRICS_URL => null,
32
        self::CORS_ALLOWED_ORIGINS => '*',
33
        self::PUBLISH_ALLOWED_ORIGINS => '*',
34
        self::JWT_KEY => null,
35
        self::JWT_ALGORITHM => 'HS256',
36
        self::PUBLISHER_JWT_KEY => null,
37
        self::PUBLISHER_JWT_ALGORITHM => null,
38 413
        self::SUBSCRIBER_JWT_KEY => null,
39
        self::SUBSCRIBER_JWT_ALGORITHM => null,
40 413
        self::ALLOW_ANONYMOUS => false,
41 408
    ];
42
43 413
    private array $config = self::DEFAULT_CONFIG;
44
45 413
    public function __construct(array $config = [])
46
    {
47 413
        foreach ($config as $key => $value) {
48 413
            $this->set($key, $value);
49 1
        }
50 1
    }
51
52
    private function export(): array
53
    {
54 412
        $config = \array_map(fn($value) => \is_string($value) && '' === \trim($value) ? null : $value, $this->config);
55
        if (null === $config[self::JWT_KEY] && null === $config[self::PUBLISHER_JWT_KEY]) {
56
            throw new \InvalidArgumentException(
57 413
                "One of \"jwt_key\" or \"publisher_jwt_key\" configuration parameter must be defined."
58
            );
59 413
        }
60
61
        return $config;
62 412
    }
63
64 412
    public function asArray(): array
65 412
    {
66
        return $this->export();
67
    }
68 412
69
    private function set(string $key, $value): void
70
    {
71 412
        $key = self::normalize($key);
72 412
        if (!\array_key_exists($key, self::DEFAULT_CONFIG)) {
73
            return;
74 4
        }
75
        if (null === $value && \is_bool(self::DEFAULT_CONFIG[$key])) {
76 4
            $value = self::DEFAULT_CONFIG[$key];
77 4
        }
78 4
        $this->config[$key] = $value;
79
    }
80
81 4
    public function overrideWith(array $values): self
82
    {
83
        $clone = clone $this;
84 412
        foreach ($values as $key => $value) {
85
            $clone->set($key, $value);
86 412
        }
87
88
        return $clone;
89
    }
90
91
    private static function normalize(string $key): string
92
    {
93
        return \strtolower(\strtr($key, ['-' => '_']));
94
    }
95
96
    public static function bootstrapFromCLI(InputInterface $input): self
97
    {
98
        return (new self())
99
            ->overrideWith($_SERVER)
100
            ->overrideWith(self::filterCLIInput($input));
101
    }
102
103
    private static function filterCLIInput(InputInterface $input): array
104
    {
105
        return \array_filter(
106
            $input->getOptions(),
107
            fn($value) => null !== nullify($value) && false !== $value
108
        );
109
    }
110
}
111