Passed
Push — main ( 078a91...2ce56e )
by Alain
13:15 queued 52s
created

ConfigFactory::createFromFile()   B

Complexity

Conditions 7
Paths 18

Size

Total Lines 37
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 7.2694

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 7
eloc 18
c 3
b 0
f 0
nc 18
nop 1
dl 0
loc 37
ccs 14
cts 17
cp 0.8235
crap 7.2694
rs 8.8333
1
<?php
2
/**
3
 * Bright Nucleus Config Component.
4
 *
5
 * @package   BrightNucleus\Config
6
 * @author    Alain Schlesser <[email protected]>
7
 * @license   MIT
8
 * @link      http://www.brightnucleus.com/
9
 * @copyright 2016-2017 Alain Schlesser, Bright Nucleus
10
 */
11
12
namespace BrightNucleus\Config;
13
14
use Exception;
15
16
/**
17
 * Create new object instances that implement ConfigInterface.
18
 *
19
 * @since   0.3.0
20
 *
21
 * @package BrightNucleus\Config
22
 * @author  Alain Schlesser <[email protected]>
23
 */
24
class ConfigFactory
25
{
26
27
    /**
28
     * Cached contents of the config files.
29
     *
30
     * @since 0.4.3
31
     *
32
     * @var array
33
     */
34
    protected static $configFilesCache = [];
35
36
    /**
37
     * Create a new ConfigInterface object from a file.
38
     *
39
     * If a comma-separated list of files is provided, they are checked in sequence until the first one could be loaded
40
     * successfully.
41
     *
42
     * @since 0.3.0
43
     *
44
     * @param string|array $_ List of files.
45
     *
46
     * @return ConfigInterface Instance of a ConfigInterface implementation.
47
     */
48 2
    public static function createFromFile($_)
49
    {
50 2
        $files = array_reverse(func_get_args());
51
52 2
        if (is_array($files[0])) {
53 1
            $files = $files[0];
54
        }
55
56 2
        while (count($files) > 0) {
57
            try {
58 2
                $file = array_pop($files);
59
60 2
                if (! is_string($file)) {
61 1
                    continue;
62
                }
63
                
64 2
                if (! is_readable($file)) {
65 2
                    continue;
66 1
                }
67 2
68
                $config = static::createFromArray(
69
                    static::getFromCache($file, function ($file) {
70 2
                        return Loader::load($file);
71
                    })
72
                );
73
74 2
                if (null === $config) {
75
                    continue;
76
                }
77
78
                return $config;
79
            } catch (Exception $exception) {
80
                // Fail silently and try next file.
81
            }
82
        }
83
84
        return static::createFromArray([]);
85
    }
86
87
    /**
88
     * Create a new ConfigInterface object from an array.
89
     *
90
     * @since 0.3.0
91
     *
92 2
     * @param array $array Array with configuration values.
93
     *
94
     * @return ConfigInterface Instance of a ConfigInterface implementation.
95 2
     */
96
    public static function createFromArray(array $array)
97
    {
98
        try {
99
            return new Config($array);
100
        } catch (Exception $exception) {
101
            // Fail silently and try next file.
102
        }
103
104
        return null;
105
    }
106
107
    /**
108
     * Create a new ConfigInterface object.
109
     *
110
     * Tries to deduce the correct creation method by inspecting the provided arguments.
111
     *
112
     * @since 0.3.0
113
     *
114 4
     * @param mixed $_ Array with configuration values.
115
     *
116 4
     * @return ConfigInterface Instance of a ConfigInterface implementation.
117
     */
118
    public static function create($_)
119
    {
120 4
        if (func_num_args() < 1) {
121
            return static::createFromArray([]);
122 4
        }
123 1
124
        $arguments = func_get_args();
125
126 3
        if (is_array($arguments[0]) && func_num_args() === 1) {
127
            return static::createFromArray($arguments[0]);
128
        }
129
130
        return static::createFromFile($arguments);
131
    }
132
133
    /**
134
     * Create a new ConfigInterface object, by merging several files together.
135
     *
136
     * Duplicate keys in later files will override those in earlier files.
137
     *
138
     * @since 0.4.6
139
     *
140 3
     * @param mixed $_ Array with configuration values.
141
     *
142 3
     * @return ConfigInterface Instance of a ConfigInterface implementation.
143
     */
144
    public static function merge($_)
145
    {
146 3
        if (func_num_args() < 1) {
147
            return static::createFromArray([]);
148 3
        }
149
150
        $arguments = func_get_args();
151
152 3
        if (is_array($arguments[0]) && func_num_args() === 1) {
153
            return static::createFromArray($arguments[0]);
154
        }
155
156
        return static::mergeFromFiles($arguments);
157
    }
158
159
    /**
160
     * Create a new ConfigInterface object by merging data from several files.
161
     *
162
     * If a comma-separated list of files is provided, they are loaded in sequence and later files override settings in
163
     * earlier files.
164
     *
165
     * @since 0.4.6
166
     *
167
     * @param string|array $_ List of files.
168
     *
169
     * @return ConfigInterface Instance of a ConfigInterface implementation.
170
     */
171
    public static function mergeFromFiles($_)
172
    {
173
        $files = array_reverse(func_get_args());
174
        $data  = [];
175
176
        if (is_array($files[0])) {
177
            $files = array_reverse($files[0]);
178
        }
179
180
        while (count($files) > 0) {
181
            try {
182
                $file = array_pop($files);
183
184
                if (! is_readable($file)) {
185
                    continue;
186
                }
187
188
                $new_data = static::getFromCache($file, function ($file) {
189
                    return Loader::load($file);
190
                });
191
192
                if (null === $data) {
193
                    continue;
194
                }
195
196
                $data = array_replace_recursive($data, $new_data);
197
            } catch (Exception $exception) {
198
                // Fail silently and try next file.
199
            }
200
        }
201
202
        return static::createFromArray($data);
203
    }
204
205
    /**
206
     * Create a new ConfigInterface object from a file and return a sub-portion of it.
207
     *
208
     * The first argument needs to be the file name to load, and the subsequent arguments will be passed on to
209
     * `Config::getSubConfig()`.
210
     *
211
     * @since 0.4.5
212
     *
213
     * @param mixed $_ File name of the config to load as a string, followed by an array of keys to pass to
214 1
     *                 `Config::getSubConfig()`.
215
     *
216 1
     * @return ConfigInterface Instance of a ConfigInterface implementation.
217
     */
218
    public static function createSubConfig($_)
219
    {
220 1
        if (func_num_args() < 2) {
221 1
            return static::createFromArray([]);
222
        }
223 1
224
        $arguments = func_get_args();
225 1
        $file      = array_shift($arguments);
226
227
        $config = static::createFromFile($file);
228
229
        return $config->getSubConfig($arguments);
230
    }
231
232
    /**
233
     * Get a config file from the config file cache.
234
     *
235
     * @since 0.4.4
236
     *
237
     * @param string $identifier Identifier to look for in the cache.
238
     * @param mixed  $fallback   Fallback to use to fill the cache. If $fallback is a callable, it will be executed
239 1
     *                           with $identifier as an argument.
240
     *
241 1
     * @return mixed The latest content of the cache for the given identifier.
242 1
     */
243 1
    protected static function getFromCache($identifier, $fallback)
244
    {
245
        if (! array_key_exists($identifier, static::$configFilesCache)) {
246
            static::$configFilesCache[$identifier] = is_callable($fallback)
247 1
                ? $fallback($identifier)
248
                : $fallback;
249
        }
250
251
        return static::$configFilesCache[$identifier];
252
    }
253
}
254