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

Config::getParser()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 21
ccs 9
cts 9
cp 1
rs 9.0534
cc 4
eloc 10
nc 6
nop 1
crap 4

1 Method

Rating   Name   Duplication   Size   Complexity  
A 0 12 3
1
<?php
2
3
namespace mhndev\config;
4
5
use mhndev\config\Exception\FileNotFoundException;
6
use mhndev\config\Exception\UnsupportedFormatException;
7
use mhndev\config\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 3
    public static function load($path)
41
    {
42 3
        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 30
    public function __construct($path)
53
    {
54 30
        $paths      = $this->getValidPath($path);
55 21
        $this->data = array();
56
57 21
        foreach ($paths as $path) {
58
59
60 21
            // Get file information
61 21
            $info      = pathinfo($path);
62 21
63
            $parts = explode('.', $info['basename']);
64
            $extension = array_pop($parts);
65 18
            if ($extension === 'dist') {
66 18
                $extension = array_pop($parts);
67
            }
68 18
            $parser    = $this->getParser($extension);
69 18
70
            $data = [$info['filename'] => (array) $parser->parse($path) ];
71
72
            // Try and load file
73
            $this->data = array_replace_recursive($this->data, $data);
74
        }
75
76
        parent::__construct($this->data);
77
    }
78
79
    /**
80 24
     * Gets a parser for a given file extension
81
     *
82 24
     * @param  string $extension
83
     *
84 24
     * @return Noodlehaus\FileParser\FileParserInterface
85 24
     *
86
     * @throws UnsupportedFormatException If `$path` is an unsupported file format
87 24
     */
88 18
    private function getParser($extension)
89 18
    {
90
        foreach ($this->supportedFileParsers as $fileParser) {
91
            if (in_array($extension, $fileParser::getSupportedExtensions($extension))) {
92 24
                return new $fileParser();
93
            }
94
95 24
        }
96 6
97
        // If none exist, then throw an exception
98
        throw new UnsupportedFormatException('Unsupported configuration format');
99 18
    }
100
101
    /**
102
     * Gets an array of paths
103
     *
104
     * @param  array $path
105
     *
106
     * @return array
107
     *
108
     * @throws FileNotFoundException   If a file is not found at `$path`
109
     */
110
    private function getPathFromArray($path)
111 12
    {
112
        $paths = array();
113 12
114
        foreach ($path as $unverifiedPath) {
115 12
            try {
116
                // Check if `$unverifiedPath` is optional
117
                // If it exists, then it's added to the list
118
                // If it doesn't, it throws an exception which we catch
119
                if ($unverifiedPath[0] !== '?') {
120 12
                    $paths = array_merge($paths, $this->getValidPath($unverifiedPath));
121 12
                    continue;
122 12
                }
123
                $optionalPath = ltrim($unverifiedPath, '?');
124 6
                $paths = array_merge($paths, $this->getValidPath($optionalPath));
125 6
126
            } catch (FileNotFoundException $e) {
127 9
                // If `$unverifiedPath` is optional, then skip it
128
                if ($unverifiedPath[0] === '?') {
129 6
                    continue;
130 3
                }
131
                // Otherwise rethrow the exception
132
                throw $e;
133 3
            }
134
        }
135 9
136
        return $paths;
137 9
    }
138
139
    /**
140
     * Checks `$path` to see if it is either an array, a directory, or a file
141
     *
142
     * @param  string|array $path
143
     *
144
     * @return array
145
     *
146
     * @throws EmptyDirectoryException If `$path` is an empty directory
147
     *
148
     * @throws FileNotFoundException   If a file is not found at `$path`
149
     */
150
    private function getValidPath($path)
151 27
    {
152
        // If `$path` is array
153
        if (is_array($path)) {
154 27
            return $this->getPathFromArray($path);
155 12
        }
156
157
        // If `$path` is a directory
158
        if (is_dir($path)) {
159 27
            $paths = glob($path . '/*.*');
160 6
            if (empty($paths)) {
161 6
                throw new EmptyDirectoryException("Configuration directory: [$path] is empty");
162 3
            }
163
            return $paths;
164 3
        }
165
166
        // If `$path` is not a file, throw an exception
167
        if (!file_exists($path)) {
168 21
            throw new FileNotFoundException("Configuration file: [$path] cannot be found");
169 9
        }
170
        return array($path);
171 18
    }
172
}
173