Completed
Push — dev ( d75f3f...7b5e19 )
by Ben
02:14
created

Config   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 9
Bugs 1 Features 4
Metric Value
wmc 19
c 9
b 1
f 4
lcom 1
cbo 1
dl 0
loc 184
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A flatten() 0 4 1
A set() 0 4 1
A get() 0 4 1
A forget() 0 4 1
A clear() 0 8 2
A exists() 0 4 1
A dataDecode() 0 14 2
A unpackArray() 0 15 3
A dataEncode() 0 12 3
A encodeArray() 0 11 3
1
<?php
2
3
namespace Benrowe\Laravel\Config;
4
5
use Illuminate\Support\Arr;
6
7
/**
8
 * Config class
9
 * Transforms a flattened key/value array configuration into a multi-dimensional
10
 * config handler
11
 */
12
class Config
13
{
14
    /**
15
     * @var string The delimiter used in the array keys to specify the heirachy
16
     */
17
    const KEY_DELIMITER = '.';
18
19
    /**
20
     * @var string the pattern to match array keys
21
     */
22
    const ARRAY_PATTERN = "/\[([0-9]+)\]$/";
23
24
    /**
25
     * The configuration data
26
     * @var array
27
     */
28
    private $data;
29
30
    /**
31
     * constructor
32
     * The initial data
33
     *
34
     * @param array $data the flattened data
35
     */
36
    public function __construct($data)
37
    {
38
        $this->data = $this->dataDecode($data);
39
    }
40
41
    /**
42
     * Reduce the configuration to a simple key/value array, despite the heirachy
43
     * of information
44
     *
45
     * @return array
46
     */
47
    public function flatten()
48
    {
49
        return $this->dataEncode($this->data);
50
    }
51
52
    /**
53
     * Create/Update a configuration value
54
     *
55
     * @param string $key
56
     * @param mixed $value
57
     */
58
    public function set($key, $value)
59
    {
60
        Arr::set($this->data, $key, $value);
61
    }
62
63
    /**
64
     * Get the configuration value based on it's key
65
     *
66
     * @param  string $key
67
     * @param  mixed $default
68
     * @return mixed
69
     */
70
    public function get($key, $default = null)
71
    {
72
        return Arr::get($this->data, $key, $default);
73
    }
74
75
    /**
76
     * From an item from the configuration
77
     *
78
     * @param  string $key
79
     * @return boolean
80
     */
81
    public function forget($key)
82
    {
83
        return Arr::forget($this->data, $key);
84
    }
85
86
    /**
87
     * Clear all of the settings from the configuration
88
     *
89
     * @return boolean
90
     */
91
    public function clear()
92
    {
93
        if (!empty($this->data)) {
94
            $this->data = [];
95
            return true;
96
        }
97
        return false;
98
    }
99
100
    /**
101
     * Check if a configuration setting exists
102
     *
103
     * @param  string $key
104
     * @return boolean
105
     */
106
    public function exists($key)
107
    {
108
        return Arr::has($this->data, $key);
109
    }
110
111
    /**
112
     * Converts the flat key/value from the storage engine
113
     * to a heirachy structure based on the key sytax
114
     *
115
     * @param  array $data
116
     * @return array
117
     */
118
    private function dataDecode($data)
119
    {
120
        // preprocess the keys into a unique list where the array values are
121
        // stored against the same key
122
123
        $data = $this->unpackArray($data);
124
125
        $newData = [];
126
        foreach ($data as $key => $value) {
127
            Arr::set($newData, $key, $value);
128
        }
129
130
        return $newData;
131
    }
132
133
    /**
134
     * unpack the keys that are structured for arrays so that they no
135
     * longer have the [] syntax at the end. Rather they're now a proper
136
     * array.
137
     *
138
     * @param  array $data [description]
139
     * @return array
140
     */
141
    private function unpackArray($data)
142
    {
143
        $arrKeys = array_filter($data, function ($val) {
144
            return preg_match(self::ARRAY_PATTERN, $val);
145
        });
146
        foreach ($arrKeys as $key => $value) {
147
            $newKey = preg_replace(self::ARRAY_PATTERN, '', $key);
148
            if (!isset($data[$newKey])) {
149
                $data[$newKey] = [];
150
            }
151
            $data[$newKey][] = $value;
152
            unset($data[$key]);
153
        }
154
        return $data;
155
    }
156
157
    /**
158
     * Flatten a multi-dimensional array into a linear key/value list
159
     *
160
     * @param  array $data
161
     * @return array
162
     */
163
    private function dataEncode($data, $prefix = null)
164
    {
165
        $newData = [];
166
        foreach ($data as $key => $value) {
167
            if (is_array($value)) {
168
                $newData = array_merge($newData, $this->encodeArray($key, $value, $prefix));
169
                continue;
170
            }
171
            $newData[$prefix.$key] = $value;
172
        }
173
        return $newData;
174
    }
175
176
    /**
177
     * Encode the array of values against the provided key
178
     *
179
     * @param  string $key
180
     * @param  array  $value  either an associative or keyed array
181
     * @param  string $prefix
182
     * @return array
183
     */
184
    private function encodeArray($key, array $value, $prefix = null)
185
    {
186
        $data = [];
187
        if (!Arr::isAssoc($value)) {
188
            foreach ($value as $index => $val) {
189
                $data[$prefix.$key.'['.$index.']'] = $val;
190
            }
191
            return $data;
192
        }
193
        return $this->dataEncode($value, $prefix.$key.self::KEY_DELIMITER);
194
    }
195
}
196