Completed
Push — develop ( 3fad72...7847b0 )
by Davide
03:35
created

Config::getParser()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.3332

Importance

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