Passed
Pull Request — master (#1194)
by butschster
16:45 queued 05:28
created

CacheRepository   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Test Coverage

Coverage 97.65%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 24
eloc 71
c 1
b 0
f 0
dl 0
loc 161
ccs 83
cts 85
cp 0.9765
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A get() 0 17 2
A __construct() 0 5 1
A resolveKey() 0 3 1
A clear() 0 3 1
A getMultiple() 0 31 5
A delete() 0 15 2
A has() 0 3 1
A getStorage() 0 3 1
A setMultiple() 0 22 4
A set() 0 15 2
A deleteMultiple() 0 23 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Cache;
6
7
use Psr\EventDispatcher\EventDispatcherInterface;
8
use Psr\SimpleCache\CacheInterface;
9
use Spiral\Cache\Event\CacheHit;
10
use Spiral\Cache\Event\CacheMissed;
11
use Spiral\Cache\Event\CacheRetrieving;
12
use Spiral\Cache\Event\KeyDeleted;
13
use Spiral\Cache\Event\KeyDeleteFailed;
14
use Spiral\Cache\Event\KeyDeleting;
15
use Spiral\Cache\Event\KeyWriteFailed;
16
use Spiral\Cache\Event\KeyWriting;
17
use Spiral\Cache\Event\KeyWritten;
18
19
/**
20
 * @internal
21
 */
22
class CacheRepository implements CacheInterface
23
{
24 57
    public function __construct(
25
        protected CacheInterface $storage,
26
        protected ?EventDispatcherInterface $dispatcher = null,
27
        protected ?string $prefix = null,
28 57
    ) {}
29
30 8
    public function get(string $key, mixed $default = null): mixed
31
    {
32 8
        $key = $this->resolveKey($key);
33
34 8
        $this->dispatcher?->dispatch(new CacheRetrieving($key));
35
36 8
        $value = $this->storage->get($key);
37
38 8
        if ($value === null) {
39 5
            $this->dispatcher?->dispatch(new CacheMissed($key));
40
41 5
            return $default;
42
        }
43
44 3
        $this->dispatcher?->dispatch(new CacheHit($key, $value));
45
46 3
        return $value;
47
    }
48
49 8
    public function set(string $key, mixed $value, \DateInterval|int|null $ttl = null): bool
50
    {
51 8
        $key = $this->resolveKey($key);
52
53 8
        $this->dispatcher?->dispatch(new KeyWriting($key, $value));
54
55 8
        $result = $this->storage->set($key, $value, $ttl);
56
57 8
        $this->dispatcher?->dispatch(
58 8
            $result
59 2
                ? new KeyWritten($key, $value)
60 3
                : new KeyWriteFailed($key, $value),
61 8
        );
62
63 8
        return $result;
64
    }
65
66 6
    public function delete(string $key): bool
67
    {
68 6
        $key = $this->resolveKey($key);
69
70 6
        $this->dispatcher?->dispatch(new KeyDeleting($key));
71
72 6
        $result = $this->storage->delete($key);
73
74 6
        $this->dispatcher?->dispatch(
75 6
            $result
76 1
                ? new KeyDeleted($key)
77 2
                : new KeyDeleteFailed($key),
78 6
        );
79
80 6
        return $result;
81
    }
82
83
    public function clear(): bool
84
    {
85
        return $this->storage->clear();
86
    }
87
88 6
    public function getMultiple(iterable $keys, mixed $default = null): iterable
89
    {
90 6
        $array = [];
91
        // Resolve keys and dispatch events
92 6
        foreach ($keys as $key) {
93 6
            $key = $this->resolveKey($key);
94 6
            $this->dispatcher?->dispatch(new CacheRetrieving($key));
95
            // Fill resulting array with default values
96 6
            $array[$key] = $default;
97
        }
98
99
        // If no dispatcher is set, we can skip the loop with events
100
        // to save some CPU cycles
101 6
        $keys = \array_keys($array);
102 6
        if ($this->dispatcher === null) {
103 4
            return $this->storage->getMultiple($keys, $default);
104
        }
105
106 2
        $result = $this->storage->getMultiple($keys);
107
108 2
        foreach ($result as $key => $value) {
109 2
            if ($value === null) {
110 1
                $this->dispatcher->dispatch(new CacheMissed($key));
111
            } else {
112
                // Replace default value with actual value in the resulting array
113 1
                $array[$key] = $value;
114 1
                $this->dispatcher->dispatch(new CacheHit($key, $value));
115
            }
116
        }
117
118 2
        return $array;
119
    }
120
121 7
    public function setMultiple(iterable $values, \DateInterval|int|null $ttl = null): bool
122
    {
123 7
        $dispatcher = $this->dispatcher;
124 7
        $array = [];
125
        // Resolve keys and dispatch events
126 7
        foreach ($values as $key => $value) {
127 7
            $key = $this->resolveKey($key);
128 7
            $dispatcher?->dispatch(new KeyWriting($key, $value));
129 7
            $array[$key] = $value;
130
        }
131
132 7
        $result = $this->storage->setMultiple($array, $ttl);
133
134
        // If there is a dispatcher, we need to dispatch events for each key
135 7
        $dispatcher === null or \array_walk(
136 7
            $array,
137 7
            $result
138 2
                ? static fn(mixed $value, string $key) => $dispatcher->dispatch(new KeyWritten($key, $value))
139 3
                : static fn(mixed $value, string $key) => $dispatcher->dispatch(new KeyWriteFailed($key, $value)),
140 7
        );
141
142 7
        return $result;
143
    }
144
145 6
    public function deleteMultiple(iterable $keys): bool
146
    {
147 6
        $dispatcher = $this->dispatcher;
148
149 6
        $array = [];
150
        // Resolve keys and dispatch events
151 6
        foreach ($keys as $key) {
152 6
            $key = $this->resolveKey($key);
153 6
            $dispatcher?->dispatch(new KeyDeleting($key));
154 6
            $array[] = $key;
155
        }
156
157 6
        $result = $this->storage->deleteMultiple($array);
158
159
        // If there is a dispatcher, we need to dispatch events for each key
160 6
        $dispatcher === null or \array_walk(
161 6
            $array,
162 6
            $result
163 1
                ? static fn(string $key) => $dispatcher->dispatch(new KeyDeleted($key))
164 2
                : static fn(string $key) => $dispatcher->dispatch(new KeyDeleteFailed($key)),
165 6
        );
166
167 6
        return $result;
168
    }
169
170 5
    public function has(string $key): bool
171
    {
172 5
        return $this->storage->has($this->resolveKey($key));
173
    }
174
175 15
    public function getStorage(): CacheInterface
176
    {
177 15
        return $this->storage;
178
    }
179
180 40
    private function resolveKey(string $key): string
181
    {
182 40
        return $this->prefix . $key;
183
    }
184
}
185