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