Completed
Push — master ( 8d39d6...58e1d9 )
by Xeriab
02:50
created

Konfig::keys()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 0
cts 0
cp 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * Konfig
5
 *
6
 * Yet another simple configuration loader library.
7
 *
8
 * @author  Xeriab Nabil (aka KodeBurner) <[email protected]>
9
 * @license https://raw.github.com/xeriab/konfig/master/LICENSE MIT
10
 * @link    https://xeriab.github.io/projects/konfig
11
 */
12
13
namespace Exen\Konfig;
14
15
use Exen\Konfig\Exception\Exception;
16
use Exen\Konfig\Exception\EmptyDirectoryException;
17
use Exen\Konfig\Exception\FileNotFoundException;
18
use Exen\Konfig\Exception\UnsupportedFileFormatException;
19
20
final class Konfig extends AbstractKonfig
21
{
22
    /**
23
     * @var FileParser[] $fileParsers Array of file parsers objects
24
     * @since 0.1.0
25
     */
26
    protected $fileParsers;
27
28
    /**
29
     * Stores loaded configuration files
30
     *
31
     * @var array $loadedFiles Array of loaded configuration files
32
     * @since 0.1.0
33
     */
34
    static protected $loadedFiles = [];
35
    
36
    static protected $loadedData = null;
37
38
    /**
39
     * Loads a supported configuration file format.
40
     *
41
     * @param  string|array|mixed $path String file | configuration array | Konfig instance
42
     * @throws EmptyDirectoryException If `$path` is an empty directory
43
     */
44
    public function __construct($path = null, array $parsers = [])
45
    {
46 33
        $this->setFileParsers($parsers);
47
48 33
        $paths = $this->getValidPath($path);
49
50 33
        $this->data = [];
51
52 24
        foreach ($paths as $path) {
53
            // Get file information
54 24
            $info = pathinfo($path);
55
            // $info  = pathinfo($path, PATHINFO_EXTENSION);
56 24
            $parts = explode('.', $info['basename']);
57
            $ext = array_pop($parts);
58 24
59 24
            if ($ext === 'dist') {
60
                $ext = array_pop($parts);
61 24
            }
62 3
63 2
            $parser = $this->getParser($ext);
64
65 24
            // Try and load file
66
            $this->data = array_replace_recursive($this->data, (array) $parser->parse($path));
67
68 21
            self::$loadedFiles[$path] = true;
69
        }
70 21
        
71 14
        self::$loadedData = $this->data;
72
73 21
        parent::__construct($this->data);
74
    }
75 21
76 21
    /**
77
     * Static method for loading a Konfig instance.
78
     *
79
     * @param  string|array|mixed $path string file | configuration array | Konfig instance
80
     * @param  array $parsers Parsers to use with Konfig
81
     * @param  bool $overwrite Whether to overwrite existing values
82
     * @param  bool $cache Allow caching
83
     * @return Konfig
84
     */
85 3
    public static function load($path = null, array $parsers = [], $overwrite = false, $cache = true)
0 ignored issues
show
Unused Code introduced by
The parameter $overwrite is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $cache is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
86
    {
87 3
        return new static($path, $parsers);
88
    }
89
90
    /**
91
     * Static method for getting loaded Konfig files.
92
     *
93
     * @return array
94
     */
95
    public static function loaded()
96
    {
97
        return self::$loadedFiles;
98
    }
99
100
    /**
101
     * @return FileParser[]
102
     * @since 0.1.0
103
     */
104
    public function getFileParsers()
105
    {
106
        return $this->fileParsers;
107
    }
108
109
    /**
110
     * @return void
111
     * @since 0.1.0
112
     */
113
    protected function addFileParser(FileParser $fileParser)
114
    {
115
        $this->fileParsers[] = $fileParser;
116
    }
117
118
    /**
119
     * @return void
120
     * @since 0.1.0
121
     */
122
    protected function setFileParsers(array $fileParsers = [])
123
    {
124
        if (empty($fileParsers)) {
125
            $fileParsers = [
126
                new FileParser\Xml(),
127
                new FileParser\Ini(),
128
                new FileParser\Json(),
129
                new FileParser\Yaml(),
130
                new FileParser\Neon(),
131
                new FileParser\Toml(),
132
                new FileParser\Php(),
133
                new FileParser\Properties(),
134
            ];
135
        }
136
137
        $this->fileParsers = [];
138
139
        foreach ($fileParsers as $fileParser) {
140
            $this->addFileParser($fileParser);
141
        }
142
    }
143
144
    /**
145
     * Gets a parser for a given file extension
146
     *
147
     * @param  string $ext File extension
148
     * @return Konfig\FileParser
149
     * @throws Exception If `$ext` is empty
150
     * @throws UnsupportedFileFormatException If `$path` is an unsupported file format
151
     */
152
    private function getParser($ext = null)
153
    {
154
        $parser = null;
155
156
        if (empty($ext)) {
157
            throw new Exception('Files with empty extensions are not allowed');
158
        }
159
160
        $fileParsers = $this->getFileParsers();
161
162 27
        foreach ($fileParsers as $fileParser) {
163
            if (in_array($ext, $fileParser->getSupportedFileExtensions(), true)) {
164 27
                $parser = $fileParser;
165
                break;
166 27
            }
167
        }
168
169
        // If none exist, then throw an exception
170 27
        if (is_null($parser)) {
171
            throw new UnsupportedFileFormatException('Unsupported configuration format');
172 27
        }
173 27
174 21
        return $parser;
175 23
    }
176
177 18
    /**
178
     * Gets an array of paths
179
     *
180 27
     * @param array $path Path to analyze and handle
181 6
     * @return array
182
     * @throws FileNotFoundException If a file is not found in `$path`
183
     */
184 21
    private function pathFromArray($path)
185
    {
186
        $paths = [];
187
188
        foreach ($path as $unverifiedPath) {
189
            try {
190
                // Check if `$unverifiedPath` is optional
191
                // If it exists, then it's added to the list
192
                // If it doesn't, it throws an exception which we catch
193
                if ($unverifiedPath[0] !== '?') {
194
                    $paths = array_merge($paths, $this->getValidPath($unverifiedPath));
195
                    continue;
196
                }
197
198
                $optionalPath = ltrim($unverifiedPath, '?');
199
200
                $paths = array_merge($paths, $this->getValidPath($optionalPath));
201
            } catch (FileNotFoundException $e) {
202
                // If `$unverifiedPath` is optional, then skip it
203
                if ($unverifiedPath[0] === '?') {
204
                    continue;
205
                }
206
207
                // Otherwise rethrow the exception
208
                throw $e;
209
            }
210
        }
211
212
        return $paths;
213
    }
214
215
    /**
216
     * Checks `$path` to see if it is either an array, a directory, or a file
217
     *
218
     * @param  string|array $path Path to analyze and handle
219
     * @return array
220
     * @throws EmptyDirectoryException If `$path` is an empty directory
221
     * @throws FileNotFoundException If a file is not found at `$path`
222
     */
223
    private function getValidPath($path)
224
    {
225
        // If `$path` is array
226
        if (is_array($path)) {
227
            return $this->pathFromArray($path);
228
        }
229
230
        // If `$path` is a directory
231
        if (is_dir($path)) {
232
            $paths = glob($path . '/*.*');
233 30
234
            if (empty($paths)) {
235
                throw new EmptyDirectoryException("Configuration directory: [$path] is empty");
236 30
            }
237 12
238
            return $paths;
239
        }
240
241 30
        // If `$path` is not a file, throw an exception
242 6
        if (!file_exists($path)) {
243
            throw new FileNotFoundException("Configuration file: [$path] cannot be found");
244 6
        }
245 3
246
        return [$path];
247
    }
248 3
249
    /**
250
     * @return string
251
     * @codeCoverageIgnore
252 24
     * @since 0.1.2
253 9
     */
254
    public function __toString()
255
    {
256 21
        return 'Exen\Konfig\Konfig' . PHP_EOL;
257
    }
258
}
259
260
// END OF ./src/Konfig.php FILE
261