AbstractSettingsManager   A
last analyzed

Complexity

Total Complexity 30

Size/Duplication

Total Lines 223
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 30
eloc 57
c 2
b 0
f 0
dl 0
loc 223
ccs 49
cts 49
cp 1
rs 10

17 Methods

Rating   Name   Duplication   Size   Complexity  
A update() 0 3 1
A __construct() 0 5 2
A delete() 0 12 2
A clear() 0 3 1
A isAssoc() 0 7 2
A deleteMultiple() 0 10 2
A exist() 0 3 1
A getMultiple() 0 17 4
A allFlattened() 0 6 1
A has() 0 3 1
A validate() 0 3 1
A set() 0 6 1
A dotFlatten() 0 13 5
A setMultiple() 0 8 2
A empty() 0 3 1
A all() 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\Support\Facades\Validator;
9
use Illuminate\Database\Eloquent\Model;
10
use Illuminate\Support\Arr;
11
12
/**
13
 * Class AbstractSettingsManager
14
 * @package Glorand\Model\Settings\Managers
15
 * @SuppressWarnings(PHPMD.StaticAccess)
16
 */
17
abstract class AbstractSettingsManager implements SettingsManagerContract
18
{
19
    /** @var \Illuminate\Database\Eloquent\Model */
20
    protected $model;
21
22
    /** @var array */
23
    protected $defaultSettings = [];
24
25
    /**
26
     * AbstractSettingsManager constructor.
27
     * @param \Illuminate\Database\Eloquent\Model|HasSettings $model
28 198
     * @throws \Glorand\Model\Settings\Exceptions\ModelSettingsException
29
     */
30 198
    public function __construct(Model $model)
31 198
    {
32 3
        $this->model = $model;
33
        if (!in_array(HasSettings::class, class_uses_recursive($this->model))) {
34 195
            throw new ModelSettingsException('Wrong model, missing HasSettings trait.');
35
        }
36
    }
37
38
    /**
39 195
     * Check if array is associative and not sequential
40
     * @param array $arr
41 195
     * @return bool
42 195
     */
43 171
    private static function isAssoc(array $arr): bool
44
    {
45
        if ([] === $arr) {
46 186
            return false;
47
        }
48
49
        return array_keys($arr) !== range(0, count($arr) - 1);
50
    }
51
52 12
    /**
53
     * Flatten array with dots for settings package
54 12
     * @param array $array
55
     * @param string $prepend
56
     * @return array
57
     * @SuppressWarnings(PHPMD.ElseExpression)
58
     */
59
    public static function dotFlatten(array $array, string $prepend = ''): array
60 12
    {
61
        $results = [];
62 12
        foreach ($array as $key => $value) {
63
            // only re-run if nested array is associative (key-based)
64
            if (is_array($value) && static::isAssoc($value) && !empty($value)) {
65
                $results = array_merge($results, static::dotFlatten($value, $prepend . $key . '.'));
66
            } else {
67
                $results[$prepend . $key] = $value;
68
            }
69 12
        }
70
71 12
        return $results;
72
    }
73
74
    /**
75
     * Get nested merged array with all available keys
76
     * @return array
77
     */
78
    public function all(): array
79 48
    {
80
        return $this->getMultiple();
81 48
    }
82
83
    /**
84
     * Get flat merged array with dot-notation keys
85
     * @return array
86
     */
87
    public function allFlattened(): array
88
    {
89 12
        $flattenedDefaultSettings = static::dotFlatten($this->model->getDefaultSettings());
0 ignored issues
show
Bug introduced by
It seems like $this->model->getDefaultSettings() can also be of type Illuminate\Database\Eloquent\Builder; however, parameter $array of Glorand\Model\Settings\M...gsManager::dotFlatten() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

89
        $flattenedDefaultSettings = static::dotFlatten(/** @scrutinizer ignore-type */ $this->model->getDefaultSettings());
Loading history...
90
        $flattenedSettingsValue = static::dotFlatten($this->model->getSettingsValue());
91 12
92 12
        return array_merge($flattenedDefaultSettings, $flattenedSettingsValue);
93 12
    }
94
95
    /**
96 12
     * @return bool
97
     */
98
    public function exist(): bool
99
    {
100
        return count($this->all()) > 0;
101
    }
102
103
    /**
104 24
     * @return bool
105
     */
106 24
    public function empty(): bool
107 24
    {
108
        return count($this->all()) <= 0;
109 24
    }
110
111
    /**
112
     * @param string $path
113
     * @return bool
114
     */
115
    public function has(string $path): bool
116
    {
117 12
        return Arr::has($this->all(), $path);
118
    }
119 12
120
    /**
121
     * @param string|null $path
122
     * @param null $default
123
     * @return array|\ArrayAccess|mixed
124
     */
125
    public function get(string $path = null, $default = null)
126 60
    {
127
        return $path ? Arr::get($this->all(), $path, $default) : $this->all();
128 60
    }
129 60
130
    /**
131 12
     * @param iterable|null $paths
132 12
     * @param null $default
133
     * @return array
134
     */
135 60
    public function getMultiple(iterable $paths = null, $default = null): array
136
    {
137 60
        $array = [];
138
        $allFlattened = $this->allFlattened();
139
        $settingsArray = [];
140
        foreach ($allFlattened as $key => $value) {
141
            Arr::set($settingsArray, $key, $value);
142
        }
143 42
        if (is_null($paths)) {
144
            return $settingsArray;
145 42
        }
146
147
        foreach ($paths as $path) {
148
            Arr::set($array, $path, Arr::get($settingsArray, $path, $default));
149
        }
150
151
        return $array;
152 12
    }
153
154 12
    /**
155 12
     * @param string $path
156 12
     * @param $value
157
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
158
     */
159 12
    public function set(string $path, $value): SettingsManagerContract
160
    {
161
        $settings = $this->all();
162
        Arr::set($settings, $path, $value);
163
164
        return $this->apply($settings);
165
    }
166 12
167
    /**
168 12
     * @param string $path
169 12
     * @param mixed $value
170 12
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
171
     */
172
    public function update(string $path, $value): SettingsManagerContract
173 12
    {
174
        return $this->set($path, $value);
175 12
    }
176
177
    /**
178
     * @param string|null $path
179
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
180
     */
181
    public function delete(string $path = null): SettingsManagerContract
182
    {
183
        if (!$path) {
184
            $settings = [];
185
        } else {
186
            $settings = $this->all();
187
            Arr::forget($settings, $path);
188
        }
189
190
        $this->apply($settings);
191
192
        return $this;
193
    }
194
195
    /**
196
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
197
     */
198
    public function clear(): SettingsManagerContract
199
    {
200
        return $this->delete();
201
    }
202
203
    /**
204
     * @param iterable $values
205
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
206
     */
207
    public function setMultiple(iterable $values): SettingsManagerContract
208
    {
209
        $settings = $this->all();
210
        foreach ($values as $path => $value) {
211
            Arr::set($settings, $path, $value);
212
        }
213
214
        return $this->apply($settings);
215
    }
216
217
    /**
218
     * @param iterable $paths
219
     * @return \Glorand\Model\Settings\Contracts\SettingsManagerContract
220
     */
221
    public function deleteMultiple(iterable $paths): SettingsManagerContract
222
    {
223
        $settings = $this->all();
224
        foreach ($paths as $path) {
225
            Arr::forget($settings, $path);
226
        }
227
228
        $this->apply($settings);
229
230
        return $this;
231
    }
232
233
    /**
234
     * @param  array  $settings
235
     * @throws \Illuminate\Validation\ValidationException
236
     */
237
    protected function validate(array $settings)
238
    {
239
        Validator::make(Arr::wrap($settings), Arr::wrap($this->model->getRules()))->validate();
240
    }
241
}
242