Issues (26)

src/Cache/ArrayCache.php (1 issue)

Labels
Severity
1
<?php namespace JSONAPI\Resource\Cache;
2
3
use Psr\SimpleCache\CacheInterface;
4
5
use Exception;
6
use DateInterval;
7
use DateTime;
8
9
/**
10
 * Cache implementation that can be used for metadata caching.
11
 */
12
class ArrayCache implements CacheInterface
13
{
14
    /** @var array<string, mixed> */
15
    private array $store = [];
16
17
    /** @var array<string, DateTime> */
18
    private array $storeExpire = [];
19
20
    public function set($key, $value, $ttl = null)
21
    {
22
        $this->verifyKey($key);
23
24
        $this->store[$key] = $value;
25
26
        if (null !== ($expireAt = $this->buildExpireData($ttl))) {
27
            $this->storeExpire[$key] = $expireAt;
28
        }
29
30
        return true;
31
    }
32
33
    /**
34
     * @param iterable<mixed> $values
35
     */
36
    public function setMultiple($values, $ttl = null)
37
    {
38
        if (!is_array($values)) {
39
            throw new InvalidKeyException('Key => value map must be an array', 3);
40
        }
41
42
        return array_reduce(
43
            array_keys($values),
44
            fn($result, $key) => $result && $this->set($key, $values[$key], $ttl),
45
            true
46
        );
47
    }
48
49
    public function get($key, $default = null)
50
    {
51
        $this->verifyKey($key);
52
        $this->verifyExpired($key);
53
54
        if (isset($this->store[$key])) {
55
            return $this->store[$key];
56
        }
57
58
        return $default;
59
    }
60
61
    /**
62
     * @param iterable<string> $keys
63
     * @return mixed[]
64
     */
65
    public function getMultiple($keys, $default = null)
66
    {
67
        if (!is_array($keys)) {
68
            throw new InvalidKeyException('Keys must be an array', 3);
69
        }
70
71
        return array_map(fn($key) => $this->get($key, $default), $keys);
72
    }
73
74
    public function has($key)
75
    {
76
        $this->verifyKey($key);
77
        $this->verifyExpired($key);
78
79
        return isset($this->store[$key]);
80
    }
81
82
    public function delete($key)
83
    {
84
        $this->verifyKey($key);
85
86
        unset($this->store[$key]);
87
        unset($this->storeExpire[$key]);
88
89
        return true;
90
    }
91
92
    /**
93
     * @param iterable<string> $keys
94
     */
95
    public function deleteMultiple($keys)
96
    {
97
        if (!is_array($keys)) {
98
            throw new InvalidKeyException('Keys must be an array', 3);
99
        }
100
101
        return array_reduce(
102
            $keys,
103
            fn($result, $key) => $result && $this->delete($key),
104
            true
105
        );
106
    }
107
108
    public function clear(): bool
109
    {
110
        $this->store = [];
111
        $this->storeExpire = [];
112
113
        return true;
114
    }
115
116
    protected function verifyExpired(string $key): void
117
    {
118
        if (isset($this->storeExpire[$key]) && $this->now() > $this->storeExpire[$key]) {
119
            unset($this->store[$key]);
120
            unset($this->storeExpire[$key]);
121
        }
122
    }
123
124
    /**
125
     * @param null|int|DateInterval $ttl
126
     * @return DateTime|null
127
     *
128
     * @throws InvalidTTLException
129
     */
130
    protected function buildExpireData($ttl = null): DateTime | null
0 ignored issues
show
A parse error occurred: Syntax error, unexpected '|', expecting '{' or ';' on line 130 at column 62
Loading history...
131
    {
132
        if (is_null($ttl)) {
133
            return null;
134
        }
135
136
        if (is_integer($ttl)) {
137
            $ttl = new DateInterval(sprintf('PT%sS', (int) $ttl));
138
        }
139
140
        if (!$ttl instanceof DateInterval) {
141
            throw new InvalidTTLException('Failed to parse provided ttl');
142
        }
143
144
        return $this->now()->add($ttl);
145
    }
146
147
    protected function verifyKey(mixed $key): string
148
    {
149
        if (!is_string($key)) {
150
            throw new InvalidKeyException('Key is not string', 2);
151
        }
152
153
        return $key;
154
    }
155
156
    protected function now(): DateTime
157
    {
158
        return new DateTime('now');
159
    }
160
}