Issues (12)

src/Settings.php (3 issues)

Labels
1
<?php
2
/**
3
 * @link https://github.com/lav45/yii2-settings
4
 * @copyright Copyright (c) 2016 LAV45
5
 * @author Aleksey Loban <[email protected]>
6
 * @license http://opensource.org/licenses/BSD-3-Clause
7
 */
8
9
namespace lav45\settings;
10
11
use lav45\settings\behaviors\CacheBehavior;
12
use lav45\settings\behaviors\QuickAccessBehavior;
13
use lav45\settings\events\DecodeEvent;
14
use lav45\settings\events\DeleteEvent;
15
use lav45\settings\events\GetEvent;
16
use lav45\settings\events\SetEvent;
17
use lav45\settings\storage\DbStorage;
18
use lav45\settings\storage\StorageInterface;
19
use yii\base\Component;
20
use yii\di\Instance;
21
use yii\helpers\StringHelper;
22
23
/**
24
 * Class Settings
25
 * @package lav45\settings
26
 * @mixin CacheBehavior
27
 * @mixin QuickAccessBehavior
28
 */
29
class Settings extends Component implements SettingsInterface
30
{
31
    public const EVENT_BEFORE_GET = 'beforeGet';
32
    public const EVENT_AFTER_GET = 'afterGet';
33
    public const EVENT_AFTER_DECODE = 'afterDecode';
34
    public const EVENT_BEFORE_SET = 'beforeSet';
35
    public const EVENT_AFTER_SET = 'afterSet';
36
    public const EVENT_BEFORE_DELETE = 'beforeDelete';
37
    public const EVENT_AFTER_DELETE = 'afterDelete';
38
39
    /**
40
     * @var string
41
     */
42
    public $keyPrefix;
43
    /**
44
     * @var bool
45
     */
46
    public $buildKey = true;
47
    /**
48
     * @var array|boolean
49
     */
50
    public $serializer;
51
    /**
52
     * @var StorageInterface|string|array
53
     */
54
    public $storage = DbStorage::class;
55
56
    /**
57
     * @inheritdoc
58
     */
59 22
    public function init()
60
    {
61 22
        parent::init();
62 22
        $this->storage = Instance::ensure($this->storage, StorageInterface::class);
63
    }
64
65
    /**
66
     * @param string|array $key
67
     * @return string
68
     */
69 24
    public function buildKey($key)
70
    {
71 24
        if ($this->buildKey === true) {
72 24
            if (is_string($key)) {
73 20
                $key = StringHelper::byteLength($key) <= 32 ? $key : md5($key);
74
            } else {
75 4
                $key = md5(json_encode($key, JSON_THROW_ON_ERROR));
76
            }
77
        }
78 24
        return $this->keyPrefix . $key;
0 ignored issues
show
Are you sure $key of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

78
        return $this->keyPrefix . /** @scrutinizer ignore-type */ $key;
Loading history...
79
    }
80
81
    /**
82
     * @param mixed $value
83
     * @return string
84
     */
85 22
    protected function encode($value)
86
    {
87 22
        if ($this->serializer === null) {
88 20
            return serialize($value);
89
        }
90 12
        if ($this->serializer !== false) {
91 1
            return call_user_func($this->serializer[0], $value);
92
        }
93 11
        return $value;
94
    }
95
96
    /**
97
     * @param string $value
98
     * @return mixed
99
     */
100 22
    protected function decode($value)
101
    {
102 22
        if ($this->serializer === null) {
103 20
            return @unserialize($value, ['allowed_classes' => true]);
104
        }
105 11
        if ($this->serializer !== false) {
106 1
            return call_user_func($this->serializer[1], $value);
107
        }
108 10
        return $value;
109
    }
110
111
    /**
112
     * @param string|array $key
113
     * @param mixed|\Closure $default
114
     * @return mixed
115
     */
116 23
    public function get($key, $default = null)
117
    {
118 23
        $key = $this->buildKey($key);
119 23
        $value = $this->beforeGetValue($key);
120 23
        if ($value === null) {
0 ignored issues
show
The condition $value === null is always false.
Loading history...
121 22
            $value = $this->storage->getValue($key);
122 22
            $value = $this->afterGetValue($key, $value);
123
        }
124 23
        if ($value === false) {
0 ignored issues
show
The condition $value === false is always false.
Loading history...
125 9
            if ($default instanceof \Closure) {
126 1
                return $default();
127
            }
128 9
            return $default;
129
        }
130 22
        $value = $this->decode($value);
131 22
        return $this->afterDecodeValue($key, $value, $default);
132
    }
133
134
    /**
135
     * @param string|array $key
136
     * @param mixed $value
137
     * @return boolean
138
     */
139 22
    public function set($key, $value)
140
    {
141 22
        $value = $this->beforeSetValue($key, $value);
142
143 22
        $key = $this->buildKey($key);
144 22
        $value = $this->encode($value);
145 22
        $result = $this->storage->setValue($key, $value);
146
147 22
        $this->afterSetValue($key, $value);
148
149 22
        return $result;
150
    }
151
152
    /**
153
     * @param string $key
154
     * @return boolean
155
     */
156 3
    public function delete($key)
157
    {
158 3
        $this->beforeDeleteValue($key);
159
160 3
        $key = $this->buildKey($key);
161 3
        $result = $this->storage->deleteValue($key);
162
163 3
        $this->afterDeleteValue($key);
164
165 3
        return $result;
166
    }
167
168
    /**
169
     * @param string $key
170
     * @return string
171
     */
172 23
    protected function beforeGetValue(&$key)
173
    {
174 23
        $event = new GetEvent();
175 23
        $event->key = &$key;
176 23
        $this->trigger(self::EVENT_BEFORE_GET, $event);
177 23
        return $event->value;
178
    }
179
180
    /**
181
     * @param string $key
182
     * @param string $value
183
     * @return string
184
     */
185 22
    protected function afterGetValue($key, $value)
186
    {
187 22
        $event = new GetEvent();
188 22
        $event->key = $key;
189 22
        $event->value = $value;
190 22
        $this->trigger(self::EVENT_AFTER_GET, $event);
191 22
        return $event->value;
192
    }
193
194
    /**
195
     * @param string|array $key
196
     * @param mixed $value
197
     * @param mixed $default
198
     * @return mixed
199
     */
200 22
    protected function afterDecodeValue($key, $value, $default)
201
    {
202 22
        $event = new DecodeEvent();
203 22
        $event->key = $key;
204 22
        $event->value = $value;
205 22
        $event->default = $default;
206 22
        $this->trigger(self::EVENT_AFTER_DECODE, $event);
207 22
        return $event->value;
208
    }
209
210
    /**
211
     * @param string|array $key
212
     * @param mixed $value
213
     * @return mixed
214
     */
215 22
    protected function beforeSetValue($key, $value)
216
    {
217 22
        $event = new SetEvent();
218 22
        $event->key = $key;
219 22
        $event->value = $value;
220 22
        $this->trigger(self::EVENT_BEFORE_SET, $event);
221 22
        return $event->value;
222
    }
223
224
    /**
225
     * @param string $key
226
     * @param string $value
227
     */
228 22
    protected function afterSetValue($key, $value)
229
    {
230 22
        $event = new SetEvent();
231 22
        $event->key = $key;
232 22
        $event->value = $value;
233 22
        $this->trigger(self::EVENT_AFTER_SET, $event);
234
    }
235
236
    /**
237
     * @param string|array $key
238
     */
239 3
    protected function beforeDeleteValue($key)
240
    {
241 3
        $event = new DeleteEvent();
242 3
        $event->key = $key;
243 3
        $this->trigger(self::EVENT_BEFORE_DELETE, $event);
244
    }
245
246
    /**
247
     * @param string|array $key
248
     */
249 3
    protected function afterDeleteValue($key)
250
    {
251 3
        $event = new DeleteEvent();
252 3
        $event->key = $key;
253 3
        $this->trigger(self::EVENT_AFTER_DELETE, $event);
254
    }
255
256
    /**
257
     * @inheritDoc
258
     */
259 1
    public function offsetExists($offset): bool
260
    {
261 1
        return $this->get($offset) !== null;
262
    }
263
264
    /**
265
     * @inheritDoc
266
     */
267 2
    #[\ReturnTypeWillChange]
268
    public function offsetGet($offset)
269
    {
270 2
        return $this->get($offset);
271
    }
272
273
    /**
274
     * @inheritDoc
275
     */
276 1
    public function offsetSet($offset, $value): void
277
    {
278 1
        $this->set($offset, $value);
279
    }
280
281
    /**
282
     * @inheritDoc
283
     */
284 1
    public function offsetUnset($offset): void
285
    {
286 1
        $this->delete($offset);
287
    }
288
}