Completed
Push — master ( a4d72b...95e519 )
by Ben
02:28
created

Config::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
1
<?php
2
3
namespace Benrowe\Laravel\Config;
4
5
use Benrowe\Laravel\Config\Modifiers\Collection;
6
use Benrowe\Laravel\Config\Modifiers\Modifier;
7
use Benrowe\Laravel\Config\Storage\StorageInterface;
8
use Illuminate\Contracts\Config\Repository;
9
use Illuminate\Support\Arr;
10
use InvalidArgumentException;
11
12
/**
13
 * Config class
14
 * Transforms a flattened key/value array configuration into a multi-dimensional
15
 * config handler
16
 *
17
 * @package Benrowe\Laravel\Config
18
 */
19
class Config implements Repository
20
{
21
    use StorageConverterTrait;
22
    /**
23
     * @var string The delimiter used in the array keys to specify the heirachy
24
     */
25
    const KEY_DELIMITER = '.';
26
27
    /**
28
     * @var string the pattern to match array keys
29
     */
30
    const ARRAY_PATTERN = "/\[([0-9]+)\]$/";
31
32
    /**
33
     * The configuration data
34
     * @var array
35
     */
36
    private $data;
37
38
    public $modifiers;
39
40
    /**
41
     * @var \Illuminate\Support\Arr
42
     */
43
    private $arrHelper;
44
45
    private $storage;
46
47
    /**
48
     * constructor
49
     * The initial data
50
     *
51
     * @param array|StorageInterface $data the flattened data
52
     * @param Arr|null $arrHelper the array helper
53
     */
54
    public function __construct($data = [], Arr $arrHelper = null)
55
    {
56
        $this->setArrHelper($arrHelper);
57
58
        // test $data is valid
59
        if (!is_array($data) && !($data instanceof StorageInterface)) {
60
            $msg = '$data must be either an array or an implementation of ';
61
            $msg .= StorageInterface::class;
62
            throw new \InvalidArgumentException($msg);
63
        }
64
65
        if ($data instanceof StorageInterface) {
66
            $this->storage = $data;
67
            $data = $this->storage->load();
68
        }
69
70
        $this->data = $this->dataDecode($data);
71
        $this->modifiers = new Collection;
72
    }
73
74
    /**
75
     * Set the array helper
76
     *
77
     * @param Arr|null $arrHelper
78
     */
79
    private function setArrHelper(Arr $arrHelper = null)
80
    {
81
        if ($arrHelper === null) {
82
            $arrHelper = new Arr;
83
        }
84
        $this->arrHelper = $arrHelper;
85
    }
86
87
    /**
88
     * Reduce the configuration to a simple key/value array, despite the
89
     * heirachy of information
90
     *
91
     * @return array
92
     */
93
    public function flatten()
94
    {
95
        return $this->dataEncode($this->data);
96
    }
97
98
    /**
99
     * Create/Update a configuration value
100
     *
101
     * @param string $key
102
     * @param mixed $value
103
     */
104
    public function set($key, $value = null)
105
    {
106
        $value = $this->modifiers->convert(
107
            $key,
108
            $value,
109
            Modifier::DIRECTION_FROM
110
        );
111
        // verify the array
112
        if (!$this->isValidValue($value)) {
113
            $msg = 'Value for "'.$key.'" is invalid. ';
114
            $msg .= 'Must be scalar or an array of scalar values';
115
            throw new InvalidArgumentException($msg);
116
        }
117
118
        $this->arrHelper->set($this->data, $key, $value);
119
        $this->storage && $this->storage->save($key, $value);
120
    }
121
122
    /**
123
     * Get the configuration value based on it's key
124
     *
125
     * @param  string $key
126
     * @param  mixed $default
127
     * @return mixed
128
     */
129
    public function get($key, $default = null)
130
    {
131
        return $this->modifiers->convert(
132
            $key,
133
            $this->arrHelper->get($this->data, $key, $default)
134
        );
135
    }
136
137
    /***
138
      * Get all of the configuration data in it's hierarchical state
139
      */
140
    public function all()
141
    {
142
        return $this->data;
143
    }
144
145
    /**
146
     * Remove an item from the configuration
147
     *
148
     * @param  string $key
149
     * @return boolean
150
     */
151
    public function forget($key)
152
    {
153
        if ($this->has($key)) {
154
            $this->arrHelper->forget($this->data, $key);
155
            return true;
156
        }
157
        return false;
158
    }
159
160
    /**
161
     * Clear all of the settings from the configuration
162
     *
163
     * @return boolean
164
     */
165
    public function clear()
166
    {
167
        if (!empty($this->data)) {
168
            $this->data = [];
169
            $this->storage && $this->storage->clear();
170
            return true;
171
        }
172
        return false;
173
    }
174
175
    /**
176
     * Check if a configuration setting exists
177
     *
178
     * @param  string $key
179
     * @return boolean
180
     */
181
    public function has($key)
182
    {
183
        return $this->arrHelper->has($this->data, $key);
184
    }
185
186
    /**
187
     * Prepend a value onto the key.
188
     *
189
     * If that existing key is not  an array it will be converted into an array
190
     * and the the value will be the first element of the array
191
     *
192
     * @param  string $key
193
     * @param  mixed $value
194
     * @return void
195
     */
196
    public function prepend($key, $value)
197
    {
198
        $existing = $this->getAsArray($key);
199
        array_unshift($existing, $value);
200
        $this->set($key, $existing);
201
    }
202
203
    /**
204
     * Push a value onto the key
205
     *
206
     * If that existing key is not  an array it will be converted into an array
207
     * and the the value will be the first element of the array
208
     *
209
     * @param  string $key
210
     * @param  mixed $value
211
     * @return void
212
     */
213
    public function push($key, $value)
214
    {
215
        $existing = $this->getAsArray($key);
216
        array_push($existing, $value);
217
        $this->set($key, $existing);
218
    }
219
220
    /**
221
     * Get the value, as an array
222
     *
223
     * @param  string $key
224
     * @return array any existing value will be converted to the first element
225
     *               of the array
226
     */
227
    private function getAsArray($key)
228
    {
229
        $value = $this->get($key);
230
        if (!is_array($value)) {
231
            $value = !is_null($value) ? [$value] : [];
232
        }
233
        return $value;
234
    }
235
236
237
    /**
238
     * Validate the value as safe for this object
239
     *
240
     * @param  mixed  $value the value to test
241
     * @return boolean
242
     */
243
    private function isValidValue($value)
244
    {
245
        return
246
            is_scalar($value) ||
247
            (
248
                is_array($value) &&
249
                !$this->arrHelper->isAssoc($value) &&
250
                count($value) === count(array_filter($value, 'is_scalar'))
251
            );
252
    }
253
}
254