Passed
Push — master ( 78d45d...0477bc )
by Alain
02:21
created

AbstractConfig::getKeyArguments()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 18
ccs 10
cts 10
cp 1
rs 8.8571
cc 5
eloc 10
nc 6
nop 1
crap 5
1
<?php
2
/**
3
 * Abstract Config Object
4
 *
5
 * @package   BrightNucleus\Config
6
 * @author    Alain Schlesser <[email protected]>
7
 * @license   GPL-2.0+
8
 * @link      http://www.brightnucleus.com/
9
 * @copyright 2016 Alain Schlesser, Bright Nucleus
10
 */
11
12
namespace BrightNucleus\Config;
13
14
use Exception;
15
use ArrayObject;
16
use OutOfRangeException;
17
use BadMethodCallException;
18
use BrightNucleus\Config\ConfigInterface;
19
20
/**
21
 * Config loader used to load config PHP files as objects.
22
 *
23
 * @since      0.1.0
24
 *
25
 * @package    BrightNucleus\Config
26
 * @author     Alain Schlesser <[email protected]>
27
 */
28
abstract class AbstractConfig extends ArrayObject implements ConfigInterface
29
{
30
31
    /**
32
     * Array of strings that are used as delimiters to parse configuration keys.
33
     *
34
     * @since 0.1.6
35
     *
36
     * @var array
37
     */
38
    protected $delimiter = ['\\', '/', '.'];
39
40
    /**
41
     * Instantiate the AbstractConfig object.
42
     *
43
     * @since 0.1.0
44
     * @since 0.1.6 Accepts a delimiter to parse configuration keys.
45
     *
46
     * @param array                $config    Array with settings.
47
     * @param string[]|string|null $delimiter A string or array of strings that are used as delimiters to parse
48
     *                                        configuration keys. Defaults to "\", "/" & ".".
49
     */
50 2
    public function __construct(array $config, $delimiter = null)
51
    {
52
        // Make sure the config entries can be accessed as properties.
53 2
        parent::__construct($config, ArrayObject::ARRAY_AS_PROPS);
54
55 2
        if (null !== $delimiter) {
56 1
            $this->delimiter = (array)$delimiter;
57
        }
58 2
    }
59
60
    /**
61
     * Check whether the Config has a specific key.
62
     *
63
     * To check a value several levels deep, add the keys for each level as a comma-separated list.
64
     *
65
     * @since 0.1.0
66
     * @since 0.1.4 Accepts list of keys.
67
     *
68
     * @param string ... List of keys.
69
     * @return bool
70
     */
71 2
    public function hasKey()
72
    {
73
        try {
74 2
            $keys = array_reverse($this->getKeyArguments(func_get_args()));
75
76 2
            $array = $this->getArrayCopy();
77 2
            while (count($keys) > 0) {
78 2
                $key = array_pop($keys);
79 2
                if ( ! array_key_exists($key, $array)) {
80 2
                    return false;
81
                }
82 2
                $array = $array[$key];
83
            }
84 1
        } catch (Exception $exception) {
85 1
            return false;
86
        }
87
88 2
        return true;
89
    }
90
91
    /**
92
     * Get the value of a specific key.
93
     *
94
     * To get a value several levels deep, add the keys for each level as a comma-separated list.
95
     *
96
     * @since 0.1.0
97
     * @since 0.1.4 Accepts list of keys.
98
     *
99
     * @param string ... List of keys.
100
     * @return mixed
101
     * @throws BadMethodCallException If no argument was provided.
102
     * @throws OutOfRangeException If an unknown key is requested.
103
     */
104 2
    public function getKey()
105
    {
106 2
        $keys = $this->getKeyArguments(func_get_args());
107
108 2
        if ( ! $this->hasKey($keys)) {
109 1
            throw new OutOfRangeException(sprintf(_('The configuration key %1$s does not exist.'),
110 1
                implode('->', $keys)));
111
        }
112
113 2
        $keys  = array_reverse($keys);
114 2
        $array = $this->getArrayCopy();
115 2
        while (count($keys) > 0) {
116 2
            $key   = array_pop($keys);
117 2
            $array = $array[$key];
118
        }
119
120 2
        return $array;
121
    }
122
123
    /**
124
     * Get a (multi-dimensional) array of all the configuration settings.
125
     *
126
     * @since 0.1.4
127
     *
128
     * @return array
129
     */
130 1
    public function getAll()
131
    {
132 1
        return $this->getArrayCopy();
133
    }
134
135
    /**
136
     * Get the an array with all the keys
137
     *
138
     * @since 0.1.0
139
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<integer|string>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
140
     */
141 1
    public function getKeys()
142
    {
143 1
        return array_keys((array)$this);
144
    }
145
146
    /**
147
     * Extract the configuration key arguments from an arbitrary array.
148
     *
149
     * @since 0.1.6
150
     *
151
     * @param array $arguments Array as fetched through get_func_args().
152
     * @return array Array of strings.
153
     * @throws BadMethodCallException If no argument was provided.
154
     */
155 4
    protected function getKeyArguments($arguments)
156
    {
157 4
        if (count($arguments) < 1) {
158 1
            throw new BadMethodCallException(_('No configuration key was provided.'));
159
        }
160
161 3
        $keys = [];
162 3
        foreach ($arguments as $argument) {
163 3
            if (is_array($argument)) {
164 3
                $keys = array_merge($keys, $this->getKeyArguments($argument));
165
            }
166 3
            if (is_string($argument)) {
167 3
                $keys = array_merge($keys, $this->parseKeysString($argument));
168
            }
169
        }
170
171 3
        return $keys;
172
    }
173
174
    /**
175
     * Extract individual keys from a delimited string.
176
     *
177
     * @since 0.1.6
178
     *
179
     * @param string $keyString Delimited string of keys.
180
     * @return array Array of key strings.
181
     */
182 1
    protected function parseKeysString($keyString)
183
    {
184
        // Replace all of the configured delimiters by the first one, so that we can then use explode().
185 1
        $normalizedString = str_replace($this->delimiter, $this->delimiter[0], $keyString);
186
187 1
        return (array)explode($this->delimiter[0], $normalizedString);
188
    }
189
190
    /**
191
     * Validate the Config file.
192
     *
193
     * @since  0.1.0
194
     * @return boolean
195
     */
196
    abstract public function isValid();
197
}
198