Passed
Push — master ( 38b2b3...0a42af )
by Gombos
03:19
created

AbstractSettingsManager   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 213
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 29
eloc 56
c 2
b 0
f 0
dl 0
loc 213
ccs 49
cts 49
cp 1
rs 10

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 2
A deleteMultiple() 0 10 2
A exist() 0 3 1
A update() 0 3 1
A getMultiple() 0 17 4
A delete() 0 12 2
A allFlattened() 0 6 1
A has() 0 3 1
A set() 0 6 1
A isAssoc() 0 7 2
A dotFlatten() 0 13 5
A setMultiple() 0 8 2
A empty() 0 3 1
A all() 0 3 1
A clear() 0 3 1
A get() 0 3 2
1
<?php
2
3
namespace Glorand\Model\Settings\Managers;
4
5
use Glorand\Model\Settings\Contracts\SettingsManagerContract;
6
use Glorand\Model\Settings\Exceptions\ModelSettingsException;
7
use Glorand\Model\Settings\Traits\HasSettings;
8
use Illuminate\Database\Eloquent\Model;
9
use Illuminate\Support\Arr;
10
11
/**
12
 * Class AbstractSettingsManager
13
 * @package Glorand\Model\Settings\Managers
14
 */
15
abstract class AbstractSettingsManager implements SettingsManagerContract
16
{
17
    /** @var \Illuminate\Database\Eloquent\Model */
18
    protected $model;
19
20
    /** @var array */
21
    protected $defaultSettings = [];
22
23
    /**
24
     * AbstractSettingsManager constructor.
25
     * @param \Illuminate\Database\Eloquent\Model|HasSettings $model
26
     * @throws \Glorand\Model\Settings\Exceptions\ModelSettingsException
27
     */
28 198
    public function __construct(Model $model)
29
    {
30 198
        $this->model = $model;
31 198
        if (!in_array(HasSettings::class, class_uses_recursive($this->model))) {
32 3
            throw new ModelSettingsException('Wrong model, missing HasSettings trait.');
33
        }
34 195
    }
35
36
    /**
37
     * Check if array is associative and not sequential
38
     * @param array $arr
39 195
     * @return bool
40
     */
41 195
    private static function isAssoc(array $arr): bool
42 195
    {
43 171
        if ([] === $arr) {
44
            return false;
45
        }
46 186
47
        return array_keys($arr) !== range(0, count($arr) - 1);
48
    }
49
50
    /**
51
     * Flatten array with dots for settings package
52 12
     * @param $array
53
     * @param string $prepend
54 12
     * @return array
55
     */
56
    public static function dotFlatten($array, $prepend = ''): array
57
    {
58
        $results = [];
59
        foreach ($array as $key => $value) {
60 12
            // only re-run if nested array is associative (key-based)
61
            if (is_array($value) && static::isAssoc($value) && !empty($value)) {
62 12
                $results = array_merge($results, static::dotFlatten($value, $prepend . $key . '.'));
63
            } else {
64
                $results[$prepend . $key] = $value;
65
            }
66
        }
67
68
        return $results;
69 12
    }
70
71 12
    /**
72
     * Get nested merged array with all available keys
73
     * @return array
74
     */
75
    public function all(): array
76
    {
77
        return $this->getMultiple();
78
    }
79 48
80
    /**
81 48
     * Get flat merged array with dot-notation keys
82
     * @return array
83
     */
84
    public function allFlattened(): array
85
    {
86
        $flattenedDefaultSettings = static::dotFlatten($this->model->getDefaultSettings());
87
        $flattenedSettingsValue = static::dotFlatten($this->model->getSettingsValue());
88
89 12
        return array_merge($flattenedDefaultSettings, $flattenedSettingsValue);
90
    }
91 12
92 12
    /**
93 12
     * @return bool
94
     */
95
    public function exist(): bool
96 12
    {
97
        return count($this->all()) > 0;
98
    }
99
100
    /**
101
     * @return bool
102
     */
103
    public function empty(): bool
104 24
    {
105
        return count($this->all()) <= 0;
106 24
    }
107 24
108
    /**
109 24
     * @param string $path
110
     * @return bool
111
     */
112
    public function has(string $path): bool
113
    {
114
        return Arr::has($this->all(), $path);
115
    }
116
117 12
    /**
118
     * @param string|null $path
119 12
     * @param null $default
120
     * @return array|\ArrayAccess|mixed
121
     */
122
    public function get(string $path = null, $default = null)
123
    {
124
        return $path ? Arr::get($this->all(), $path, $default) : $this->all();
125
    }
126 60
127
    /**
128 60
     * @param iterable|null $paths
129 60
     * @param null $default
130
     * @return array
131 12
     */
132 12
    public function getMultiple(iterable $paths = null, $default = null): array
133
    {
134
        $array = [];
135 60
        $allFlattened = $this->allFlattened();
136
        $settingsArray = [];
137 60
        foreach ($allFlattened as $key => $value) {
138
            Arr::set($settingsArray, $key, $value);
139
        }
140
        if (is_null($paths)) {
141
            return $settingsArray;
142
        }
143 42
144
        foreach ($paths as $path) {
145 42
            Arr::set($array, $path, Arr::get($settingsArray, $path, $default));
146
        }
147
148
        return $array;
149
    }
150
151
    /**
152 12
     * @param string $path
153
     * @param $value
154 12
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
155 12
     */
156 12
    public function set(string $path, $value): SettingsManagerContract
157
    {
158
        $settings = $this->all();
159 12
        Arr::set($settings, $path, $value);
160
161
        return $this->apply($settings);
162
    }
163
164
    /**
165
     * @param string $path
166 12
     * @param mixed $value
167
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
168 12
     */
169 12
    public function update(string $path, $value): SettingsManagerContract
170 12
    {
171
        return $this->set($path, $value);
172
    }
173 12
174
    /**
175 12
     * @param string|null $path
176
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
177
     */
178
    public function delete(string $path = null): SettingsManagerContract
179
    {
180
        if (!$path) {
181
            $settings = [];
182
        } else {
183
            $settings = $this->all();
184
            Arr::forget($settings, $path);
185
        }
186
187
        $this->apply($settings);
188
189
        return $this;
190
    }
191
192
    /**
193
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
194
     */
195
    public function clear(): SettingsManagerContract
196
    {
197
        return $this->delete();
198
    }
199
200
    /**
201
     * @param iterable $values
202
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
203
     */
204
    public function setMultiple(iterable $values): SettingsManagerContract
205
    {
206
        $settings = $this->all();
207
        foreach ($values as $path => $value) {
208
            Arr::set($settings, $path, $value);
209
        }
210
211
        return $this->apply($settings);
212
    }
213
214
    /**
215
     * @param iterable $paths
216
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
217
     */
218
    public function deleteMultiple(iterable $paths): SettingsManagerContract
219
    {
220
        $settings = $this->all();
221
        foreach ($paths as $path) {
222
            Arr::forget($settings, $path);
223
        }
224
225
        $this->apply($settings);
226
227
        return $this;
228
    }
229
}
230