Passed
Push — main ( 3ecfdc...7ca620 )
by Marc
03:33
created

Config::getInt()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
nc 2
nop 2
dl 0
loc 6
rs 10
c 1
b 0
f 0
1
<?php declare(strict_types=1);
2
namespace html_go\model;
3
4
use InvalidArgumentException;
5
use html_go\exceptions\InternalException;
6
7
final class Config
8
{
9
    const KEY_SITE_URL = 'site.url';
10
    const KEY_SITE_NAME = 'site.name';
11
    const KEY_SITE_TITLE = 'site.title';
12
    const KEY_SITE_DESCRIPTION = 'site.description';
13
    const KEY_SITE_TAGLINE = 'site.tagline';
14
    const KEY_SITE_COPYRIGHT = 'site.copyright';
15
    const KEY_LANG = 'site.language';
16
    const KEY_TPL_ENGINE = 'template.engine';
17
    const KEY_TPL_CACHING = 'template.engine.caching';
18
    const KEY_TPL_FILE_EXT = 'template.engine.file.ext';
19
    const KEY_TPL_STRICT_VARS_TWIG = 'template.engine.twig.strict_variables';
20
    const KEY_STATIC_INDEX = 'static.index';
21
    const KEY_THEME_NAME = 'theme.name';
22
    const KEY_POSTS_PERPAGE = 'blog.posts_per_page';
23
    const KEY_POST_DATE_FMT = 'blog.post_date_format';
24
25
    /**
26
     * @var array<string, string>
27
     */
28
    private array $config;
29
30
    /**
31
     * Config constructor.
32
     * @param string $configRoot The root directory containing the 'config.ini' file.
33
     * @throws InvalidArgumentException
34
     * @throws InternalException
35
     */
36
    function __construct(string $configRoot) {
37
        $configFile = $configRoot.DS.'config.ini';
38
        if (!\is_file($configFile)) {
39
            throw new InvalidArgumentException("Configuration INI file not found [$configFile]");
40
        }
41
        if (($config = \parse_ini_file($configFile, false, INI_SCANNER_TYPED)) === false) {
42
            throw new InternalException("parse_ini_file() failed [$configFile]"); // @codeCoverageIgnore
43
        }
44
        $this->config = $this->validateConfig($config);
45
    }
46
47
    function getString(string $key, string $default = ''): string {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
48
        $var = $this->checkAndGet($key);
49
        if (empty($var) || \is_string($var) === false) {
50
            return $default;
51
        }
52
        return $var;
53
    }
54
55
    function getInt(string $key, int $default = -1): int {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
56
        $var = $this->checkAndGet($key);
57
        if (empty($var) || \is_int($var) === false) {
58
            return $default;
59
        }
60
        return $var;
61
    }
62
63
    function getBool(string $key, bool $default = false): bool {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
64
        $var = $this->checkAndGet($key);
65
        if (empty($var) || \is_bool($var) === false) {
66
            return $default;
67
        }
68
        return $var;
69
    }
70
71
    private function checkAndGet(string $key): mixed {
72
        if (isset($this->config[$key]) === false) {
73
            return null;
74
        }
75
        return $this->config[$key];
76
    }
77
78
    /**
79
     * @param array<mixed> $config
80
     * @param string $key
81
     * @param mixed $default
82
     * @return array<mixed>
83
     */
84
    private function checkSetOrDefault(array $config, string $key, mixed $default): array {
85
        if (isset($config[$key])) {
86
            return $config;
87
        }
88
        $config[$key] = $default;
89
        return $config;
90
    }
91
92
    /**
93
     * Check required options are set and set defaults.
94
     * @param array<string, string> $config
95
     * @return array<string, mixed>
96
     * @throws InvalidArgumentException
97
     */
98
    private function validateConfig(array $config): array {
99
        if (isset($config[self::KEY_SITE_URL]) === false) {
100
            throw new InvalidArgumentException("Configuration option 'site.url' not set.");
101
        }
102
        $config = $this->checkSetOrDefault($config, self::KEY_SITE_TITLE, ' | HTML-go');
103
        $config = $this->checkSetOrDefault($config, self::KEY_SITE_NAME, 'Another HTML-go Site');
104
        $config = $this->checkSetOrDefault($config, self::KEY_SITE_DESCRIPTION, 'Powered by HTML-go, a databaseless, flat-file blogging platform');
105
        $config = $this->checkSetOrDefault($config, self::KEY_SITE_TAGLINE, 'Another HTML-go website');
106
        $config = $this->checkSetOrDefault($config, self::KEY_SITE_COPYRIGHT, '(c) Copyright, Your Name');
107
        $config = $this->checkSetOrDefault($config, self::KEY_LANG, 'en');
108
        $config = $this->checkSetOrDefault($config, self::KEY_TPL_ENGINE, 'twig');
109
        $config = $this->checkSetOrDefault($config, self::KEY_TPL_CACHING, false);
110
        $config = $this->checkSetOrDefault($config, self::KEY_TPL_FILE_EXT, 'twig');
111
        $config = $this->checkSetOrDefault($config, self::KEY_TPL_STRICT_VARS_TWIG, true);
112
        $config = $this->checkSetOrDefault($config, self::KEY_THEME_NAME, 'default');
113
        $config = $this->checkSetOrDefault($config, self::KEY_STATIC_INDEX, true);
114
        $config = $this->checkSetOrDefault($config, self::KEY_POSTS_PERPAGE, 5);
115
        $config = $this->checkSetOrDefault($config, self::KEY_POST_DATE_FMT, 'jS M Y');
116
117
        return $config;
118
    }
119
}
120