Completed
Pull Request — master (#104)
by
unknown
04:14
created

Config   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 157
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 4
dl 0
loc 157
ccs 48
cts 48
cp 1
rs 10
c 0
b 0
f 0

5 Methods

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