AbstractConfig   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 185
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 3
dl 0
loc 185
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A addConfig() 0 6 1
A readConfig() 0 14 1
A setConfig() 0 11 1
A readFile() 0 14 3
A extractImports() 0 20 5
A extractDefault() 0 9 2
A mergeDefault() 0 4 1
A checkPath() 0 8 2
1
<?php
2
declare(strict_types=1);
3
/*
4
 * This file is part of the php-utilities package.
5
 *
6
 * (c) Marc Aschmann <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
namespace Asm\Config;
12
13
use Asm\Data\Data;
14
use Asm\Exception\InvalidConfigFileException;
15
use Symfony\Component\Yaml\Yaml;
16
17
/**
18
 * Class AbstractConfig
19
 *
20
 * @package Asm\Config
21
 * @author Marc Aschmann <[email protected]>
22
 * @codeCoverageIgnore
23
 * @uses Asm\Data\Data
24
 * @uses Symfony\Component\Yaml\Yaml
25
 */
26
abstract class AbstractConfig extends Data
27
{
28
    const IMPORTS = 'imports';
29
    const FILECHECK = 'filecheck';
30
    const FILE = 'file';
31
    const RESOURCE = 'resource';
32
    const DEFAULT = 'default';
33
    const DEFAULT_ENVIRONMENT = 'defaultEnv';
34
    const ENVIRONMENT = 'env';
35
36
    /**
37
     * @var bool
38
     */
39
    protected $filecheck = true;
40
41
    /**
42
     * @var string
43
     */
44
    private $currentBasepath;
45
46
    /**
47
     * @var array
48
     */
49
    protected $imports = [];
50
51
    /**
52
     * @var array
53
     */
54
    protected $default = [];
55
56
    /**
57
     * Default constructor.
58
     *
59
     * @param array $param
60
     */
61
    public function __construct(array $param)
62
    {
63
        if (isset($param[self::FILECHECK])) {
64
            $this->filecheck = (bool)$param[self::FILECHECK];
65
        }
66
67
        $this->setConfig($param['file']);
68
    }
69
70
    /**
71
     * Add named property to config object
72
     * and insert config as array.
73
     *
74
     * @param string $name name of property
75
     * @param string $file string $file absolute filepath/filename.ending
76
     * @return $this
77
     */
78
    public function addConfig(string $name, string $file)
79
    {
80
        $this->set($name, $this->readConfig($file));
81
82
        return $this;
83
    }
84
85
    /**
86
     * Read config file via YAML parser.
87
     *
88
     * @param  string $file absolute filepath/filename.ending
89
     * @return array config array
90
     */
91
    public function readConfig(string $file) : array
92
    {
93
        $this->currentBasepath = dirname($file);
94
95
        $config = $this->readFile($file);
96
        $config = $this->extractImports($config);
97
        $config = $this->extractDefault($config);
98
        $this->mergeDefault();
99
100
        return array_replace_recursive(
101
            $this->default,
102
            $config
103
        );
104
    }
105
106
    /**
107
     * Add config to data storage.
108
     *
109
     * @param string $file absolute filepath/filename.ending
110
     * @return $this
111
     */
112
    public function setConfig(string $file)
113
    {
114
        $this->setByArray(
115
            array_replace_recursive(
116
                $this->default,
117
                $this->readConfig($file)
118
            )
119
        );
120
121
        return $this;
122
    }
123
124
    /**
125
     * Read yaml files.
126
     *
127
     * @param string $file path/filename
128
     * @return array
129
     */
130
    private function readFile(string $file) : array
131
    {
132
        if ($this->filecheck) {
133
            if (is_file($file)) {
134
                $file = file_get_contents($file);
135
            } else {
136
                throw new InvalidConfigFileException(
137
                    "Config::Abstract() - Given config file {$file} does not exist!"
138
                );
139
            }
140
        }
141
142
        return (array)Yaml::parse($file);
143
    }
144
145
    /**
146
     * get all import files from config, if set and remove node.
147
     *
148
     * @param array $config
149
     * @return array
150
     */
151
    private function extractImports(array $config) : array
152
    {
153
        if (array_key_exists(self::IMPORTS, $config) && 0 < count($config[self::IMPORTS])) {
154
            $this->imports = [];
155
            foreach ($config[self::IMPORTS] as $key => $import) {
156
                if (false === empty($import[self::RESOURCE])) {
157
                    $include = $this->checkPath($import[self::RESOURCE]);
158
159
                    $this->imports = array_replace_recursive(
160
                        $this->imports,
161
                        $this->readFile($include)
162
                    );
163
                }
164
            }
165
166
            unset($config[self::IMPORTS]);
167
        }
168
169
        return $config;
170
    }
171
172
    /**
173
     * Get default values if set and remove node from config.
174
     *
175
     * @param array $config
176
     * @return array
177
     */
178
    private function extractDefault(array $config) : array
179
    {
180
        if (array_key_exists(self::DEFAULT, $config)) {
181
            $this->default = $config[self::DEFAULT];
182
            unset($config[self::DEFAULT]);
183
        }
184
185
        return $config;
186
    }
187
188
    /**
189
     * Prepare the defaults and replace recursively.
190
     */
191
    private function mergeDefault()
192
    {
193
        $this->default = array_replace_recursive($this->imports, $this->default);
194
    }
195
196
    /**
197
     * Only add basepath if not already in filename.
198
     *
199
     * @param string $include
200
     * @return string
201
     */
202
    private function checkPath(string $include) : string
203
    {
204
        if (0 !== strpos($include, $this->currentBasepath)) {
205
            $include = $this->currentBasepath . '/' . $include;
206
        }
207
208
        return $include;
209
    }
210
}
211