Completed
Push — master ( 31fd01...7575c0 )
by ARCANEDEV
04:07
created

SettingsManager::set()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 3
Bugs 0 Features 0
Metric Value
dl 0
loc 15
rs 9.4286
c 3
b 0
f 0
ccs 10
cts 10
cp 1
cc 2
eloc 8
nc 2
nop 2
crap 2
1
<?php namespace Arcanesoft\Settings;
2
3
use Arcanedev\Support\Collection;
4
use Arcanesoft\Settings\Helpers\Arr;
5
use Arcanesoft\Settings\Helpers\Comparator;
6
use Arcanesoft\Settings\Models\Setting;
7
use Illuminate\Contracts\Cache\Repository as Cache;
8
9
/**
10
 * Class     SettingsManager
11
 *
12
 * @package  Arcanesoft\Settings
13
 * @author   ARCANEDEV <[email protected]>
14
 */
15
class SettingsManager implements Contracts\Settings
16
{
17
    /* ------------------------------------------------------------------------------------------------
18
     |  Properties
19
     | ------------------------------------------------------------------------------------------------
20
     */
21
    /**
22
     * The settings data.
23
     *
24
     * @var \Arcanedev\Support\Collection
25
     */
26
    protected $data;
27
28
    /**
29
     * Whether the store has changed since it was last loaded.
30
     *
31
     * @var bool
32
     */
33
    protected $unsaved = false;
34
35
    /**
36
     * Whether the settings data are loaded.
37
     *
38
     * @var bool
39
     */
40
    protected $loaded = false;
41
42
    /** @var  \Arcanesoft\Settings\Stores\EloquentStore  */
43
    private $store;
44
45
    /* ------------------------------------------------------------------------------------------------
46
     |  Constructor
47
     | ------------------------------------------------------------------------------------------------
48
     */
49
    /**
50
     * SettingsManager constructor.
51
     *
52
     * @param  \Arcanesoft\Settings\Models\Setting     $model
53
     * @param  \Illuminate\Contracts\Cache\Repository  $cache
54
     */
55 40
    public function __construct(Setting $model, Cache $cache)
56
    {
57 40
        $this->store = new Stores\EloquentStore($model, $cache);
58 40
        $this->data  = new Collection;
59 40
    }
60
61
    /* ------------------------------------------------------------------------------------------------
62
     |  Getters & Setters
63
     | ------------------------------------------------------------------------------------------------
64
     */
65
    /**
66
     * Get the settings default domain.
67
     *
68
     * @return string
69
     */
70 36
    protected function getDefaultDomain()
71
    {
72 36
        return $this->config('default-domain', 'default');
73
    }
74
75
    /**
76
     * Get the config value by key.
77
     *
78
     * @param  string  $key
79
     * @param  mixed   $default
80
     *
81
     * @return mixed
82
     */
83 36
    private function config($key, $default = null)
84
    {
85 36
        return config("arcanesoft.settings.$key", $default);
86
    }
87
88
    /* ------------------------------------------------------------------------------------------------
89
     |  Main Functions
90
     | ------------------------------------------------------------------------------------------------
91
     */
92
    /**
93
     * Get a setting by key.
94
     *
95
     * @param  string      $key
96
     * @param  mixed|null  $default
97
     *
98
     * @return mixed
99
     */
100 24
    public function get($key, $default = null)
101
    {
102 24
        $this->checkLoaded();
103
104 24
        $domain = $this->grabDomain($key);
105
106 24
        return Arr::get($this->data->get($domain, []), $key, $default);
107
    }
108
109
    /**
110
     * Set a setting.
111
     *
112
     * @param  string  $key
113
     * @param  mixed   $value
114
     */
115 32
    public function set($key, $value)
116
    {
117 32
        $this->checkLoaded();
118
119 32
        $domain = $this->grabDomain($key);
120 32
        $data   = [];
121
122 32
        if ($this->data->has($domain)) {
123 16
            $data = $this->data->get($domain);
124 12
        }
125
126 32
        Arr::set($data, $key, $value);
127
128 32
        $this->data->put($domain, $data);
129 32
    }
130
131
    /**
132
     * Check if a setting exists by the key.
133
     *
134
     * @param  string  $key
135
     *
136
     * @return bool
137
     */
138 24
    public function has($key)
139
    {
140 24
        $this->checkLoaded();
141
142 24
        $domain = $this->grabDomain($key);
143
144 24
        if ( ! $this->data->has($domain)) {
145 12
            return false;
146
        }
147
148 24
        return Arr::has($this->data->get($domain), $key);
149
    }
150
151
    /**
152
     * Get all the setting by a specific domain.
153
     *
154
     * @param  string|null  $domain
155
     *
156
     * @return array
157
     */
158 20
    public function all($domain = null)
159
    {
160 20
        $this->checkLoaded();
161
162 20
        if (is_null($domain)) {
163 16
            $domain = $this->getDefaultDomain();
164 12
        }
165
166 20
        return $this->data->get($domain, []);
167
    }
168
169
    /**
170
     * Delete a setting.
171
     *
172
     * @param  string  $key
173
     */
174 8
    public function delete($key)
175
    {
176 8
        $this->checkLoaded();
177
178 8
        $domain = $this->getDefaultDomain();
179
180 8
        if (str_contains($key, '::')) {
181 4
            list($domain, $key) = explode('::', $key);
182 3
        }
183
184 8
        $data = $this->data->get($domain, []);
185 8
        Arr::forget($data, $key);
186 8
        $data = array_filter($data);
187
188 8
        if (empty($data)) {
189 8
            $this->data->forget($domain);
190 6
        }
191
        else {
192 4
            $this->data->put($domain, $data);
193
        }
194 8
    }
195
196
    /**
197
     * Reset/Delete all the settings.
198
     *
199
     * @param  string|null  $domain
200
     */
201 4
    public function reset($domain = null)
202
    {
203 4
        $this->checkLoaded();
204
205 4
        if (is_null($domain)) {
206 4
            $domain = $this->getDefaultDomain();
207 3
        }
208
209 4
        $this->data->forget($domain);
210 4
    }
211
212
    /**
213
     * Save the settings.
214
     */
215 28
    public function save()
216
    {
217 28
        $changes = $this->getChanges(
218 28
            $saved = $this->store->all()
219 21
        );
220
221 28
        $this->store->save($saved, $changes);
222 28
    }
223
224
    /**
225
     * Get the changes.
226
     *
227
     * @param  \Illuminate\Database\Eloquent\Collection  $saved
228
     *
229
     * @return array
230
     */
231 28
    private function getChanges($saved)
232
    {
233 28
        return Comparator::compare(
234
            $this->data->map(function (array $settings) {
235 24
                return Arr::dot($settings);
236 28
            })->toArray(),
237 28
            $saved->groupBy('domain')->map(function($item) {
238
                /** @var  \Illuminate\Database\Eloquent\Collection  $item */
239 16
                return $item->lists('casted_value', 'key');
240 28
            })->toArray()
241 21
        );
242
    }
243
244
    /**
245
     * Grab the settings domain name from the key.
246
     *
247
     * @param  string  $key
248
     *
249
     * @return string
250
     */
251 32
    private function grabDomain(&$key)
252
    {
253 32
        $domain = $this->getDefaultDomain();
254
255 32
        if (str_contains($key, '::')) {
256 8
            list($domain, $key) = explode('::', $key);
257 6
        }
258
259 32
        return $domain;
260
    }
261
262
    /* ------------------------------------------------------------------------------------------------
263
     |  Other Functions
264
     | ------------------------------------------------------------------------------------------------
265
     */
266
    /**
267
     * Check if the data is loaded
268
     */
269 36
    private function checkLoaded()
270
    {
271 36
        if ( ! $this->loaded) {
272 36
            $this->data->reset();
273 36
            $this->loadData();
274 36
            $this->loaded = true;
275 27
        }
276 36
    }
277
278
    /**
279
     * Load the data.
280
     */
281 36
    private function loadData()
282
    {
283 36
        foreach ($this->store->all() as $setting) {
284
            /** @var  \Arcanesoft\Settings\Models\Setting  $setting */
285 24
            $data = $this->data->get($setting->domain, []);
286 24
            Arr::set($data, $setting->key, $setting->casted_value);
287 24
            $this->data->put($setting->domain, $data);
288 27
        }
289 36
    }
290
}
291