Completed
Push — master ( ee99d6...c3ac1f )
by recca
01:54
created

DatabaseRepository::getCacheFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
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 2
        }
66 2
    }
67
68
    /**
69
     * Set a given configuration value.
70
     *
71
     * @param array|string $key
72
     * @param mixed $value
73
     */
74 1
    public function set($key, $value = null)
75
    {
76 1
        parent::set($key, $value);
77 1
        $this->store();
78 1
    }
79
80
    /**
81
     * Unset a configuration option.
82
     *
83
     * @param string $key
84
     */
85 1
    public function offsetUnset($key)
86
    {
87 1
        parent::offsetUnset($key);
88 1
        $this->store();
89 1
    }
90
91
    /**
92
     * getCacheFile.
93
     *
94
     * @return string
95
     */
96 2
    public function getCacheFile()
97
    {
98 2
        return Arr::get($this->config, 'cache');
99
    }
100
101
    /**
102
     * cloneModel.
103
     *
104
     * @return \Recca0120\Config\Config
105
     */
106 2
    protected function cloneModel()
107
    {
108 2
        return clone $this->model;
109
    }
110
111
    /**
112
     * getModel.
113
     *
114
     * @return \Recca0120\Config\Config
115
     */
116 2
    protected function getModel()
117
    {
118 2
        return $this->cloneModel()->firstOrCreate([
119 2
            'key' => $this->key,
120 2
        ]);
121
    }
122
123
    /**
124
     * storeToFile.
125
     *
126
     * @param mixed $data
127
     * @return $this
128
     */
129 2
    protected function storeToFile($data)
130
    {
131 2
        if (is_null($data) === true) {
132
            $data = [];
133
        }
134 2
        $option = JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE;
135 2
        $this->files->put(
136 2
            $this->getCacheFile(),
137 2
            json_encode($data, $option)
138 2
        );
139
140 2
        return $this;
141
    }
142
143
    /**
144
     * load.
145
     *
146
     * @return array
147
     */
148 2
    protected function load()
149
    {
150 2
        $storageFile = $this->getCacheFile();
151 2
        if ($this->files->exists($storageFile) === true) {
152 1
            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 1
    protected function store()
164
    {
165 1
        $data = $this->protectedKeys(
166 1
            $this->arrayDiffAssocRecursive($this->all(), $this->original)
167 1
        );
168
169 1
        if (empty($data) === false) {
170 1
            $model = $this->getModel();
171
            $model
172 1
                ->fill(['value' => $data])
173 1
                ->save();
174 1
            $this->storeToFile($data);
175 1
        }
176 1
    }
177
178
    /**
179
     * arrayDiffAssocRecursive.
180
     *
181
     * @param array $array1
182
     * @param array $array2
183
     * @return array
184
     */
185 1
    protected function arrayDiffAssocRecursive($array1, $array2)
186
    {
187 1
        $difference = [];
188 1
        foreach ($array1 as $key => $value) {
189 1
            if (is_array($value)) {
190 1
                if (isset($array2[$key]) === false || is_array($array2[$key]) === false) {
191 1
                    $difference[$key] = $value;
192 1
                } else {
193 1
                    $new_diff = $this->arrayDiffAssocRecursive($value, $array2[$key]);
194 1
                    if (empty($new_diff) === false) {
195 1
                        $difference[$key] = $new_diff;
196 1
                    }
197
                }
198 1
            } elseif (array_key_exists($key, $array2) === false || $array2[$key] !== $value) {
199 1
                $difference[$key] = $value;
200 1
            }
201 1
        }
202
203 1
        return $difference;
204
    }
205
206
    /**
207
     * protectedKeys.
208
     *
209
     * @param array $data
210
     * @return array
211
     */
212 1
    protected function protectedKeys($data)
213
    {
214 1
        if (empty($keys = Arr::get($this->config, 'protected')) === false) {
215 1
            $data = Arr::except($data, $keys);
216 1
        }
217
218 1
        return $data;
219
    }
220
}
221