Completed
Push — master ( 83fb2b...ee99d6 )
by recca
03:55
created

DatabaseRepository::store()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 14
ccs 0
cts 11
cp 0
rs 9.4285
c 1
b 0
f 0
cc 2
eloc 9
nc 2
nop 0
crap 6
1
<?php
2
3
namespace Recca0120\Config\Repositories;
4
5
use Illuminate\Support\Arr;
6
use Recca0120\Config\Config;
7
use Illuminate\Filesystem\Filesystem;
8
use Illuminate\Contracts\Config\Repository;
9
10
class DatabaseRepository extends AbstractRepository
11
{
12
    /**
13
     * $original.
14
     *
15
     * @var array
16
     */
17
    protected $original = [];
18
19
    /**
20
     * $key.
21
     *
22
     * @var string
23
     */
24
    protected $key = 'configs';
25
26
    /**
27
     * $repository.
28
     *
29
     * @var \Recca0120\Config\Config
30
     */
31
    protected $model;
32
33
    /**
34
     * $files.
35
     *
36
     * @var \Illuminate\Filesystem\Filesystem
37
     */
38
    protected $files;
39
40
    /**
41
     * $config.
42
     *
43
     * @var array
44
     */
45
    protected $config;
46
47
    /**
48
     * __construct.
49
     *
50
     * @param \Illuminate\Contracts\Config\Repository $repository
51
     * @param \Recca0120\Config\Config $model
52
     * @param array $config
53
     */
54 2
    public function __construct(Repository $repository, Config $model, Filesystem $files, $config = [])
55
    {
56 2
        parent::__construct($repository);
57
58 2
        $this->original = $repository->all();
59 2
        $this->model = $model;
60 2
        $this->files = $files;
61 2
        $this->config = $config;
62
63 2
        foreach (Arr::dot($this->load()) as $key => $value) {
64
            $repository->set($key, $value);
65 1
        }
66 1
    }
67
68
    /**
69
     * Set a given configuration value.
70
     *
71
     * @param array|string $key
72
     * @param mixed $value
73
     */
74
    public function set($key, $value = null)
75
    {
76
        parent::set($key, $value);
77
        $this->store();
78
    }
79
80
    /**
81
     * Unset a configuration option.
82
     *
83
     * @param string $key
84
     */
85
    public function offsetUnset($key)
86
    {
87
        parent::offsetUnset($key);
88
        $this->store();
89
    }
90
91
    /**
92
     * getStorageFile.
93
     *
94
     * @return string
95
     */
96 2
    public function getStorageFile()
97
    {
98 2
        return Arr::get($this->config, 'path').'/config.json';
99
    }
100
101
    /**
102
     * cloneModel.
103
     *
104
     * @return \Recca0120\Config\Config
105
     */
106 1
    protected function cloneModel()
107
    {
108 1
        return clone $this->model;
109
    }
110
111
    /**
112
     * getModel.
113
     *
114
     * @return \Recca0120\Config\Config
115
     */
116 1
    protected function getModel()
117
    {
118 1
        return $this->cloneModel()->firstOrCreate([
119 1
            'key' => $this->key,
120 1
        ]);
121
    }
122
123
    /**
124
     * storeToFile.
125
     *
126
     * @param mixed $data
127
     * @return $this
128
     */
129 1
    protected function storeToFile($data)
130
    {
131 1
        if (is_null($data) === true) {
132
            $data = [];
133
        }
134 1
        $option = JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE;
135 1
        $this->files->put(
136 1
            $this->getStorageFile(),
137 1
            json_encode($data, $option)
138 1
        );
139
140 1
        return $this;
141
    }
142
143
    /**
144
     * load.
145
     *
146
     * @return array
147
     */
148 2
    protected function load()
149
    {
150 2
        $storageFile = $this->getStorageFile();
151 2
        if ($this->files->exists($storageFile) === true) {
152
            return (array) json_decode($this->files->get($storageFile), true);
153
        }
154 1
        $data = (array) $this->getModel()->value;
155 1
        $this->storeToFile($data);
156
157 1
        return $data;
158
    }
159
160
    /**
161
     * store.
162
     */
163
    protected function store()
164
    {
165
        $data = $this->protectedKeys(
166
            $this->arrayDiffAssocRecursive($this->all(), $this->original)
167
        );
168
169
        if (empty($data) === false) {
170
            $model = $this->getModel();
171
            $model
172
                ->fill(['value' => $data])
173
                ->save();
174
            $this->storeToFile($data);
175
        }
176
    }
177
178
    /**
179
     * arrayDiffAssocRecursive.
180
     *
181
     * @param array $array1
182
     * @param array $array2
183
     * @return array
184
     */
185
    protected function arrayDiffAssocRecursive($array1, $array2)
186
    {
187
        $difference = [];
188
        foreach ($array1 as $key => $value) {
189
            if (is_array($value)) {
190
                if (isset($array2[$key]) === false || is_array($array2[$key]) === false) {
191
                    $difference[$key] = $value;
192
                } else {
193
                    $new_diff = $this->arrayDiffAssocRecursive($value, $array2[$key]);
194
                    if (empty($new_diff) === false) {
195
                        $difference[$key] = $new_diff;
196
                    }
197
                }
198
            } elseif (array_key_exists($key, $array2) === false || $array2[$key] !== $value) {
199
                $difference[$key] = $value;
200
            }
201
        }
202
203
        return $difference;
204
    }
205
206
    /**
207
     * protectedKeys.
208
     *
209
     * @param array $data
210
     * @return array
211
     */
212
    protected function protectedKeys($data)
213
    {
214
        if (empty($keys = Arr::get($this->config, 'protected')) === false) {
215
            $data = Arr::except($data, $keys);
216
        }
217
218
        return $data;
219
    }
220
}
221