Completed
Push — master ( e3a86e...4a78f3 )
by ARCANEDEV
03:15
created

DatabaseStore::write()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 9.4286
cc 1
eloc 5
nc 1
nop 1
crap 1
1
<?php namespace Arcanedev\Settings\Stores;
2
3
use Arcanedev\Settings\Bases\Store;
4
use Arcanedev\Settings\Contracts\Store as StoreContract;
5
use Arcanedev\Settings\Models\Setting;
6
use Arcanedev\Settings\Utilities\Arr;
7
use Closure;
8
9
/**
10
 * Class     DatabaseStore
11
 *
12
 * @package  Arcanedev\Settings\Stores
13
 * @author   ARCANEDEV <[email protected]>
14
 */
15
class DatabaseStore extends Store implements StoreContract
16
{
17
    /* ------------------------------------------------------------------------------------------------
18
     |  Properties
19
     | ------------------------------------------------------------------------------------------------
20
     */
21
    /** @var  \Arcanedev\Settings\Models\Setting */
22
    protected $model;
23
24
    /**
25
     * Any query constraints that should be applied.
26
     *
27
     * @var Closure|null
28
     */
29
    protected $queryConstraint;
30
31
    /**
32
     * Any extra columns that should be added to the rows.
33
     *
34
     * @var array
35
     */
36
    protected $extraColumns = [];
37
38
    /* ------------------------------------------------------------------------------------------------
39
     |  Constructor
40
     | ------------------------------------------------------------------------------------------------
41
     */
42
    /**
43
     * Make the Database store instance.
44
     *
45
     * @param  string  $connection
46
     * @param  string  $table
47
     */
48 24
    public function __construct($connection, $table = null)
49
    {
50 24
        $this->model = new Setting;
51 24
        $this->setConnection($connection);
52 24
        $this->setTable($table ?: 'settings');
53 24
    }
54
55
    /* ------------------------------------------------------------------------------------------------
56
     |  Getters & Setters
57
     | ------------------------------------------------------------------------------------------------
58
     */
59
    /**
60
     * Set the database connection.
61
     *
62
     * @param  string  $connection
63
     *
64
     * @return self
65
     */
66 24
    public function setConnection($connection)
67
    {
68 24
        $this->model->setConnection($connection);
69
70 24
        return $this;
71
    }
72
73
    /**
74
     * Set the table to query from.
75
     *
76
     * @param  string  $table
77
     *
78
     * @return self
79
     */
80 24
    public function setTable($table)
81
    {
82 24
        $this->model->setTable($table);
83
84 24
        return $this;
85
    }
86
87
    /**
88
     * Set the query constraint.
89
     *
90
     * @param  \Closure  $callback
91
     *
92
     * @return self
93
     */
94
    public function setConstraint(Closure $callback)
95
    {
96
        $this->data            = [];
97
        $this->loaded          = false;
98
        $this->queryConstraint = $callback;
99
100
        return $this;
101
    }
102
103
    /**
104
     * Set extra columns to be added to the rows.
105
     *
106
     * @param  array  $columns
107
     *
108
     * @return self
109
     */
110
    public function setExtraColumns(array $columns)
111
    {
112
        $this->extraColumns = $columns;
113
114
        return $this;
115
    }
116
117
    /* ------------------------------------------------------------------------------------------------
118
     |  Main Functions
119
     | ------------------------------------------------------------------------------------------------
120
     */
121
    /**
122
     * {@inheritdoc}
123
     */
124 6
    public function forget($key)
125
    {
126 6
        parent::forget($key);
127
128
        // because the database store cannot store empty arrays, remove empty
129
        // arrays to keep data consistent before and after saving
130 6
        $segments = explode('.', $key);
131 6
        array_pop($segments);
132
133 6
        while ( ! empty($segments)) {
134 3
            $segment = implode('.', $segments);
135
136
            // non-empty array - exit out of the loop
137 3
            if ($this->get($segment)) {
138 3
                break;
139
            }
140
141
            // remove the empty array and move on to the next segment
142 3
            $this->forget($segment);
143 3
            array_pop($segments);
144 3
        }
145 6
    }
146
147
    /* ------------------------------------------------------------------------------------------------
148
     |  Other Functions
149
     | ------------------------------------------------------------------------------------------------
150
     */
151
    /**
152
     * {@inheritdoc}
153
     */
154 21
    protected function read()
155
    {
156 21
        $results  = [];
157
158 21
        foreach ($this->model->all() as $setting) {
159
            /** @var Setting $setting */
160 15
            Arr::set($results, $setting->key, $setting->value);
161 21
        }
162
163 21
        return $results;
164
    }
165
166
    /**
167
     * {@inheritdoc}
168
     */
169 15
    protected function write(array $data)
170
    {
171 15
        list($inserts, $updates, $deletes) = $this->prepareData($data);
172
173 15
        $this->updateSettings($updates);
174 15
        $this->insertSettings($inserts);
175 15
        $this->deleteSettings($deletes);
176 15
    }
177
178
    /* ------------------------------------------------------------------------------------------------
179
     |  CRUD Functions
180
     | ------------------------------------------------------------------------------------------------
181
     */
182
    /**
183
     * Prepare settings data.
184
     *
185
     * @param  array  $data
186
     *
187
     * @return array
188
     */
189 15
    private function prepareData(array $data)
190
    {
191 15
        $inserts = array_dot($data);
192 15
        $updates = [];
193 15
        $deletes = [];
194
195 15
        foreach ($this->model()->lists('key') as $key) {
196 9
            if (isset($inserts[$key]))
197 9
                $updates[$key] = $inserts[$key];
198
            else
199 9
                $deletes[]     = $key;
200
201 9
            unset($inserts[$key]);
202 15
        }
203
204 15
        return [$inserts, $updates, $deletes];
205
    }
206
207
    /**
208
     * Update settings data.
209
     *
210
     * @param  array $updates
211
     */
212 15
    private function updateSettings($updates)
213
    {
214 15
        foreach ($updates as $key => $value) {
215 6
            $this->model()->where('key', $key)->update(compact('value'));
216 15
        }
217 15
    }
218
219
    /**
220
     * Insert settings data.
221
     *
222
     * @param  array $inserts
223
     */
224 15
    private function insertSettings(array $inserts)
225
    {
226 15
        if (empty($inserts)) {
227 9
            return;
228
        }
229
230 15
        $dbData = [];
231
232 15
        foreach ($inserts as $key => $value) {
233 15
            $data     = compact('key', 'value');
234 15
            $dbData[] = empty($this->extraColumns) ? $data : array_merge($this->extraColumns, $data);
235 15
        }
236
237 15
        $this->model(true)->insert($dbData);
238 15
    }
239
240
    /**
241
     * Delete settings data.
242
     *
243
     * @param  array  $deletes
244
     */
245 15
    private function deleteSettings(array $deletes)
246
    {
247 15
        if (empty($deletes)) {
248 15
            return;
249
        }
250
251 9
        $this->model()->whereIn('key', $deletes)->delete();
252 9
    }
253
254
    /**
255
     * Create a new query builder instance.
256
     *
257
     * @param  $insert  bool  Whether the query is an insert or not.
258
     *
259
     * @return \Arcanedev\Settings\Models\Setting
260
     */
261 15
    private function model($insert = false)
262
    {
263 15
        $model = $this->model;
264
265 15
        if ($insert === false) {
266 15
            foreach ($this->extraColumns as $key => $value) {
267
                $model->where($key, $value);
268 15
            }
269 15
        }
270
271 15
        if ( ! is_null($this->queryConstraint)) {
272
            /** @var  Closure  $callback */
273
            $callback = $this->queryConstraint;
274
            $callback($model, $insert);
275
        }
276
277 15
        return $model;
278
    }
279
}
280