Passed
Branch main (078a91)
by Alain
15:46
created

ConfigFactory::createFromFile()   A

Complexity

Conditions 6
Paths 14

Size

Total Lines 33
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 6.1979

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 16
c 2
b 0
f 0
nc 14
nop 1
dl 0
loc 33
ccs 14
cts 17
cp 0.8235
crap 6.1979
rs 9.1111
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_readable($file)) {
61 1
                    continue;
62
                }
63
64 2
                $config = static::createFromArray(
65 2
                    static::getFromCache($file, function ($file) {
66 1
                        return Loader::load($file);
67 2
                    })
68
                );
69
70 2
                if (null === $config) {
71
                    continue;
72
                }
73
74 2
                return $config;
75
            } catch (Exception $exception) {
76
                // Fail silently and try next file.
77
            }
78
        }
79
80
        return static::createFromArray([]);
81
    }
82
83
    /**
84
     * Create a new ConfigInterface object from an array.
85
     *
86
     * @since 0.3.0
87
     *
88
     * @param array $array Array with configuration values.
89
     *
90
     * @return ConfigInterface Instance of a ConfigInterface implementation.
91
     */
92 2
    public static function createFromArray(array $array)
93
    {
94
        try {
95 2
            return new Config($array);
96
        } catch (Exception $exception) {
97
            // Fail silently and try next file.
98
        }
99
100
        return null;
101
    }
102
103
    /**
104
     * Create a new ConfigInterface object.
105
     *
106
     * Tries to deduce the correct creation method by inspecting the provided arguments.
107
     *
108
     * @since 0.3.0
109
     *
110
     * @param mixed $_ Array with configuration values.
111
     *
112
     * @return ConfigInterface Instance of a ConfigInterface implementation.
113
     */
114 4
    public static function create($_)
115
    {
116 4
        if (func_num_args() < 1) {
117
            return static::createFromArray([]);
118
        }
119
120 4
        $arguments = func_get_args();
121
122 4
        if (is_array($arguments[0]) && func_num_args() === 1) {
123 1
            return static::createFromArray($arguments[0]);
124
        }
125
126 3
        return static::createFromFile($arguments);
127
    }
128
129
    /**
130
     * Create a new ConfigInterface object, by merging several files together.
131
     *
132
     * Duplicate keys in later files will override those in earlier files.
133
     *
134
     * @since 0.4.6
135
     *
136
     * @param mixed $_ Array with configuration values.
137
     *
138
     * @return ConfigInterface Instance of a ConfigInterface implementation.
139
     */
140 3
    public static function merge($_)
141
    {
142 3
        if (func_num_args() < 1) {
143
            return static::createFromArray([]);
144
        }
145
146 3
        $arguments = func_get_args();
147
148 3
        if (is_array($arguments[0]) && func_num_args() === 1) {
149
            return static::createFromArray($arguments[0]);
150
        }
151
152 3
        return static::mergeFromFiles($arguments);
153
    }
154
155
    /**
156
     * Create a new ConfigInterface object by merging data from several files.
157
     *
158
     * If a comma-separated list of files is provided, they are loaded in sequence and later files override settings in
159
     * earlier files.
160
     *
161
     * @since 0.4.6
162
     *
163
     * @param string|array $_ List of files.
164
     *
165
     * @return ConfigInterface Instance of a ConfigInterface implementation.
166
     */
167
    public static function mergeFromFiles($_)
168
    {
169
        $files = array_reverse(func_get_args());
170
        $data  = [];
171
172
        if (is_array($files[0])) {
173
            $files = array_reverse($files[0]);
174
        }
175
176
        while (count($files) > 0) {
177
            try {
178
                $file = array_pop($files);
179
180
                if (! is_readable($file)) {
181
                    continue;
182
                }
183
184
                $new_data = static::getFromCache($file, function ($file) {
185
                    return Loader::load($file);
186
                });
187
188
                if (null === $data) {
189
                    continue;
190
                }
191
192
                $data = array_replace_recursive($data, $new_data);
193
            } catch (Exception $exception) {
194
                // Fail silently and try next file.
195
            }
196
        }
197
198
        return static::createFromArray($data);
199
    }
200
201
    /**
202
     * Create a new ConfigInterface object from a file and return a sub-portion of it.
203
     *
204
     * The first argument needs to be the file name to load, and the subsequent arguments will be passed on to
205
     * `Config::getSubConfig()`.
206
     *
207
     * @since 0.4.5
208
     *
209
     * @param mixed $_ File name of the config to load as a string, followed by an array of keys to pass to
210
     *                 `Config::getSubConfig()`.
211
     *
212
     * @return ConfigInterface Instance of a ConfigInterface implementation.
213
     */
214 1
    public static function createSubConfig($_)
215
    {
216 1
        if (func_num_args() < 2) {
217
            return static::createFromArray([]);
218
        }
219
220 1
        $arguments = func_get_args();
221 1
        $file      = array_shift($arguments);
222
223 1
        $config = static::createFromFile($file);
224
225 1
        return $config->getSubConfig($arguments);
226
    }
227
228
    /**
229
     * Get a config file from the config file cache.
230
     *
231
     * @since 0.4.4
232
     *
233
     * @param string $identifier Identifier to look for in the cache.
234
     * @param mixed  $fallback   Fallback to use to fill the cache. If $fallback is a callable, it will be executed
235
     *                           with $identifier as an argument.
236
     *
237
     * @return mixed The latest content of the cache for the given identifier.
238
     */
239 1
    protected static function getFromCache($identifier, $fallback)
240
    {
241 1
        if (! array_key_exists($identifier, static::$configFilesCache)) {
242 1
            static::$configFilesCache[$identifier] = is_callable($fallback)
243 1
                ? $fallback($identifier)
244
                : $fallback;
245
        }
246
247 1
        return static::$configFilesCache[$identifier];
248
    }
249
}
250