Completed
Pull Request — master (#91)
by
unknown
04:40
created

Config::getValidPath()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 22
c 0
b 0
f 0
cc 5
eloc 11
nc 5
nop 1
ccs 10
cts 10
cp 1
crap 5
rs 8.6737
1
<?php
2
namespace mhndev\config;
3
4
use mhndev\config\Exception\FileNotFoundException;
5
use mhndev\config\Exception\UnsupportedFormatException;
6
use mhndev\config\Exception\EmptyDirectoryException;
7
use mhndev\config\FileParser\Ini;
8
use mhndev\config\FileParser\Json;
9
use mhndev\config\FileParser\Php;
10
use mhndev\config\FileParser\Xml;
11
use mhndev\config\FileParser\Yaml;
12
13
/**
14
 * Config
15
 *
16
 * @package    Config
17
 * @author     Jesus A. Domingo <[email protected]>
18
 * @author     Hassan Khan <[email protected]>
19
 * @link       https://github.com/noodlehaus/config
20
 * @license    MIT
21
 */
22
class Config extends AbstractConfig
23
{
24
    /**
25
     * All file formats supported by Config
26
     *
27
     * @var array
28
     */
29
    private $supportedFileParsers = array(
30
        Php::class,
31
        Ini::class,
32
        Json::class,
33
        Xml::class,
34
        Yaml::class
35
    );
36
37
    /**
38
     * Static method for loading a Config instance.
39
     *
40 3
     * @param  string|array $path
41
     *
42 3
     * @return Config
43
     */
44
    public static function load($path)
45
    {
46
        return new static($path);
47
    }
48
49
    /**
50
     * Loads a supported configuration file format.
51
     *
52 30
     * @param  string|array $path
53
     *
54 30
     * @throws EmptyDirectoryException    If `$path` is an empty directory
55 21
     */
56
    public function __construct($path)
57 21
    {
58
        $paths      = $this->getValidPath($path);
59
        $this->data = array();
60 21
61 21
        foreach ($paths as $path) {
62 21
63
64
            // Get file information
65 18
            $info      = pathinfo($path);
66 18
67
            $parts = explode('.', $info['basename']);
68 18
            $extension = array_pop($parts);
69 18
            if ($extension === 'dist') {
70
                $extension = array_pop($parts);
71
            }
72
            $parser    = $this->getParser($extension);
73
74
            $data = [$info['filename'] => (array) $parser->parse($path) ];
75
76
            // Try and load file
77
            $this->data = array_replace_recursive($this->data, $data);
78
        }
79
80 24
        parent::__construct($this->data);
81
    }
82 24
83
    /**
84 24
     * Gets a parser for a given file extension
85 24
     *
86
     * @param  string $extension
87 24
     *
88 18
     * @return Noodlehaus\FileParser\FileParserInterface
89 18
     *
90
     * @throws UnsupportedFormatException If `$path` is an unsupported file format
91
     */
92 24
    private function getParser($extension)
93
    {
94
        foreach ($this->supportedFileParsers as $fileParser) {
95 24
            if (in_array($extension, $fileParser::getSupportedExtensions($extension))) {
96 6
                return new $fileParser();
97
            }
98
99 18
        }
100
101
        // If none exist, then throw an exception
102
        throw new UnsupportedFormatException('Unsupported configuration format');
103
    }
104
105
    /**
106
     * Gets an array of paths
107
     *
108
     * @param  array $path
109
     *
110
     * @return array
111 12
     *
112
     * @throws FileNotFoundException   If a file is not found at `$path`
113 12
     */
114
    private function getPathFromArray($path)
115 12
    {
116
        $paths = array();
117
118
        foreach ($path as $unverifiedPath) {
119
            try {
120 12
                // Check if `$unverifiedPath` is optional
121 12
                // If it exists, then it's added to the list
122 12
                // If it doesn't, it throws an exception which we catch
123
                if ($unverifiedPath[0] !== '?') {
124 6
                    $paths = array_merge($paths, $this->getValidPath($unverifiedPath));
125 6
                    continue;
126
                }
127 9
                $optionalPath = ltrim($unverifiedPath, '?');
128
                $paths = array_merge($paths, $this->getValidPath($optionalPath));
129 6
130 3
            } catch (FileNotFoundException $e) {
131
                // If `$unverifiedPath` is optional, then skip it
132
                if ($unverifiedPath[0] === '?') {
133 3
                    continue;
134
                }
135 9
                // Otherwise rethrow the exception
136
                throw $e;
137 9
            }
138
        }
139
140
        return $paths;
141
    }
142
143
    /**
144
     * Checks `$path` to see if it is either an array, a directory, or a file
145
     *
146
     * @param  string|array $path
147
     *
148
     * @return array
149
     *
150
     * @throws EmptyDirectoryException If `$path` is an empty directory
151 27
     *
152
     * @throws FileNotFoundException   If a file is not found at `$path`
153
     */
154 27
    private function getValidPath($path)
155 12
    {
156
        // If `$path` is array
157
        if (is_array($path)) {
158
            return $this->getPathFromArray($path);
159 27
        }
160 6
161 6
        // If `$path` is a directory
162 3
        if (is_dir($path)) {
163
            $paths = glob($path . '/*.*');
164 3
            if (empty($paths)) {
165
                throw new EmptyDirectoryException("Configuration directory: [$path] is empty");
166
            }
167
            return $paths;
168 21
        }
169 9
170
        // If `$path` is not a file, throw an exception
171 18
        if (!file_exists($path)) {
172
            throw new FileNotFoundException("Configuration file: [$path] cannot be found");
173
        }
174
        return array($path);
175
    }
176
}
177