Config   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 350
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 88
dl 0
loc 350
rs 9.76
c 0
b 0
f 0
wmc 33

14 Methods

Rating   Name   Duplication   Size   Complexity  
A searchAllConfigFiles() 0 28 6
A loadConfigFile() 0 12 3
A loadJsonConfigFile() 0 13 2
A loadPhpConfigFile() 0 3 1
A __construct() 0 4 1
A getConfig() 0 3 1
A loadFiles() 0 6 2
A getConfigDirName() 0 3 1
A getConfigByFilename() 0 10 2
A setConfigForFilename() 0 9 2
A getConfigFiles() 0 3 1
A getValue() 0 32 6
A getConfigDir() 0 3 1
A setConfigKeyForFilename() 0 23 4
1
<?php
2
3
namespace BFW;
4
5
use \Exception;
6
7
/**
8
 * Class to load all files from a directory in config dir.
9
 */
10
class Config
11
{
12
    /**
13
     * @const ERR_JSON_PARSE Exception code if the parse of a json file fail.
14
     */
15
    const ERR_JSON_PARSE = 1102001;
16
    
17
    /**
18
     * @const ERR_GETVALUE_FILE_NOT_INDICATED Exception code if the file to use
19
     * is not indicated into the method getValue().
20
     * (only if there are many config files)
21
     */
22
    const ERR_GETVALUE_FILE_NOT_INDICATED = 1102002;
23
    
24
    /**
25
     * @const ERR_GETVALUE_FILE_NOT_FOUND Exception code if the file to use is
26
     * not found.
27
     */
28
    const ERR_FILE_NOT_FOUND = 1102003;
29
    
30
    /**
31
     * @const ERR_GETVALUE_KEY_NOT_FOUND Exception code if the asked config key
32
     * not exist.
33
     */
34
    const ERR_KEY_NOT_FOUND = 1102004;
35
    
36
    /**
37
     * @const ERR_KEY_NOT_ADDED Exception code if the key can not be added to
38
     * the config.
39
     */
40
    const ERR_KEY_NOT_ADDED = 1102005;
41
    
42
    /**
43
     * @var string $configDirName Directory's name in config dir
44
     */
45
    protected $configDirName = '';
46
47
    /**
48
     * @var string $configDir Complete path of the readed directory
49
     */
50
    protected $configDir = '';
51
52
    /**
53
     * @var string[] $configFiles List of files to read
54
     */
55
    protected $configFiles = [];
56
57
    /**
58
     * @var array $config List of config value found
59
     */
60
    protected $config = [];
61
62
    /**
63
     * Constructor
64
     * Define properties configDirName and configDir
65
     * 
66
     * @param string $configDirName Directory's name in config dir
67
     */
68
    public function __construct(string $configDirName)
69
    {
70
        $this->configDirName = $configDirName;
71
        $this->configDir     = CONFIG_DIR.$this->configDirName;
72
    }
73
    
74
    /**
75
     * Getter accessor to the property configDirName
76
     * 
77
     * @return string
78
     */
79
    public function getConfigDirName(): string
80
    {
81
        return $this->configDirName;
82
    }
83
84
    /**
85
     * Getter accessor to the property configDir
86
     * 
87
     * @return string
88
     */
89
    public function getConfigDir(): string
90
    {
91
        return $this->configDir;
92
    }
93
94
    /**
95
     * Getter accessor to the property configFiles
96
     * 
97
     * @return string[]
98
     */
99
    public function getConfigFiles(): array
100
    {
101
        return $this->configFiles;
102
    }
103
    
104
    /**
105
     * Getter accessor to $config property
106
     * 
107
     * @return array
108
     */
109
    public function getConfig(): array
110
    {
111
        return $this->config;
112
    }
113
    
114
    /**
115
     * Getter accessor to have all values contain into a config file
116
     * 
117
     * @param string $filename The filename config to read
118
     * 
119
     * @return mixed
120
     */
121
    public function getConfigByFilename(string $filename)
122
    {
123
        if (!isset($this->config[$filename])) {
124
            throw new Exception(
125
                'The file '.$filename.' has not been found',
126
                $this::ERR_FILE_NOT_FOUND
127
            );
128
        }
129
        
130
        return $this->config[$filename];
131
    }
132
    
133
    /**
134
     * Search and load all config files which has been found
135
     * 
136
     * @return void
137
     */
138
    public function loadFiles()
139
    {
140
        $this->searchAllConfigFiles($this->configDir);
141
        
142
        foreach ($this->configFiles as $fileKey => $filePath) {
143
            $this->loadConfigFile($fileKey, $filePath);
144
        }
145
    }
146
147
    /**
148
     * Search all config files in a directory
149
     * Search also in sub-directory (2nd parameter)
150
     * 
151
     * @param string $dirPath The directory path where is run the search
152
     * @param string $pathIntoFirstDir (default '') Used when this method
153
     *  reads a subdirectory. It's the path of the readed directory during
154
     *  the first call to this method.
155
     * 
156
     * @return void
157
     */
158
    protected function searchAllConfigFiles(
159
        string $dirPath,
160
        string $pathIntoFirstDir = ''
161
    ) {
162
        if (!file_exists($dirPath)) {
163
            return;
164
        }
165
166
        //Remove some value in list of file
167
        $listFiles = array_diff(
168
            scandir($dirPath),
0 ignored issues
show
Bug introduced by
It seems like scandir($dirPath) can also be of type false; however, parameter $array1 of array_diff() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

168
            /** @scrutinizer ignore-type */ scandir($dirPath),
Loading history...
169
            ['.', '..', 'manifest.json']
170
        );
171
172
        foreach ($listFiles as $file) {
173
            $fileKey  = $pathIntoFirstDir.$file;
174
            $readPath = $dirPath.'/'.$file;
175
            
176
            if (is_link($readPath)) {
177
                $readPath = realpath($readPath);
178
            }
179
180
            if (is_file($readPath)) {
181
                $this->configFiles[$fileKey] = $readPath;
182
            } elseif (is_dir($readPath)) {
183
                $this->searchAllConfigFiles(
184
                    $readPath,
185
                    $pathIntoFirstDir.$file.'/'
186
                );
187
            }
188
        }
189
    }
190
191
    /**
192
     * Load a config file.
193
     * Find the file's extension and call the method to parse the file
194
     * 
195
     * @param string $fileKey The file's key. Most of the time, the path to
196
     *  the file from the $this->configDir value
197
     * @param string $filePath The path to the file
198
     * 
199
     * @return void
200
     */
201
    protected function loadConfigFile(string $fileKey, string $filePath)
202
    {
203
        $fileExtension = pathinfo($filePath, PATHINFO_EXTENSION);
204
205
        if ($fileExtension === 'json') {
206
            $this->loadJsonConfigFile($fileKey, $filePath);
207
            return;
208
        }
209
210
        if ($fileExtension === 'php') {
211
            $this->loadPhpConfigFile($fileKey, $filePath);
212
            return;
213
        }
214
215
        //@TODO : YAML
216
    }
217
218
    /**
219
     * Load a json config file
220
     * 
221
     * @param string $fileKey The file's key. Most of the time, the path to
222
     *  the file from the $this->configDir value
223
     * @param string $filePath The path to the file
224
     * 
225
     * @return void
226
     * 
227
     * @throws \Exception If there is an error from the json parser
228
     */
229
    protected function loadJsonConfigFile(string $fileKey, string $filePath)
230
    {
231
        $json   = file_get_contents($filePath);
232
        $config = json_decode($json);
233
234
        if ($config === null) {
235
            throw new Exception(
236
                json_last_error_msg(),
237
                $this::ERR_JSON_PARSE
238
            );
239
        }
240
241
        $this->config[$fileKey] = $config;
242
    }
243
244
    /**
245
     * Load a php config file
246
     * 
247
     * @param string $fileKey The file's key. Most of the time, the path to
248
     *  the file from the $this->configDir value
249
     * @param string $filePath The path to the file
250
     * 
251
     * @return void
252
     */
253
    protected function loadPhpConfigFile(string $fileKey, string $filePath)
254
    {
255
        $this->config[$fileKey] = require($filePath);
256
    }
257
258
    /**
259
     * Return a config value for a key
260
     * 
261
     * @param string $key The asked key for the value
262
     * @param string $file (default null) If many file is loaded, the file name
263
     *  where is the key. Is the file is into a sub-directory, the
264
     *  sub-directory should be present.
265
     * 
266
     * @return mixed
267
     * 
268
     * @throws \Exception If file parameter is null and there are many files. Or
269
     *  if the file not exist. Or if the key not exist.
270
     */
271
    public function getValue(string $key, string $file = null)
272
    {
273
        $nbConfigFile = count($this->config);
274
275
        if ($file === null && $nbConfigFile > 1) {
276
            throw new Exception(
277
                'There are many config files. Please indicate the file to'
278
                .' obtain the config '.$key,
279
                $this::ERR_GETVALUE_FILE_NOT_INDICATED
280
            );
281
        }
282
283
        if ($nbConfigFile === 1) {
284
            $file = key($this->config);
285
        }
286
287
        if (!isset($this->config[$file])) {
288
            throw new Exception(
289
                'The file '.$file.' has not been found for config '.$key,
290
                $this::ERR_FILE_NOT_FOUND
291
            );
292
        }
293
294
        $config = (array) $this->config[$file];
295
        if (!array_key_exists($key, $config)) {
296
            throw new Exception(
297
                'The config key '.$key.' has not been found',
298
                $this::ERR_KEY_NOT_FOUND
299
            );
300
        }
301
302
        return $config[$key];
303
    }
304
    
305
    /**
306
     * Setter to modify the all config value for a specific filename.
307
     * 
308
     * @param string $filename The filename config to modify
309
     * @param array $config The new config value
310
     * 
311
     * @return $this
312
     * 
313
     * @throws \Exception If the new value if not an array or an object.
314
     */
315
    public function setConfigForFilename(string $filename, array $config): self
316
    {
317
        if (!isset($this->configFiles[$filename])) {
318
            $this->configFiles[$filename] = $filename;
319
        }
320
        
321
        $this->config[$filename] = $config;
322
        
323
        return $this;
324
    }
325
    
326
    /**
327
     * Setter to modify a config key into the config of a filename
328
     * 
329
     * @param string $filename The filename config to modify
330
     * @param string $configKey The name of the key to modify
331
     * @param mixed $configValue The new value for the config key
332
     * 
333
     * @return $this
334
     * 
335
     * @throws \Exception If the key has not been found
336
     */
337
    public function setConfigKeyForFilename(
338
        string $filename,
339
        string $configKey,
340
        $configValue
341
    ): self {
342
        if (!isset($this->config[$filename])) {
343
            $this->config[$filename] = [];
344
        }
345
        
346
        if (!isset($this->configFiles[$filename])) {
347
            $this->configFiles[$filename] = $filename;
348
        }
349
        
350
        if (is_array($this->config[$filename])) {
351
            $this->config[$filename][$configKey] = $configValue;
352
        } else {
353
            throw new Exception(
354
                'The config key '.$configKey.' can not be added.',
355
                $this::ERR_KEY_NOT_ADDED
356
            );
357
        }
358
        
359
        return $this;
360
    }
361
}
362