Test Failed
Branch master (c50bb7)
by Terry
15:06 queued 10:08
created

CacheProvider::get()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 16
ccs 9
cts 9
cp 1
crap 3
rs 10
1
<?php
2
/*
3
 * This file is part of the Shieldon Simple Cache package.
4
 *
5
 * (c) Terry L. <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
declare(strict_types=1);
12
13
namespace Shieldon\SimpleCache;
14
15
use Psr\SimpleCache\CacheInterface;
16
use Shieldon\SimpleCache\AssertTrait;
17
use DateInterval;
18
use Datetime;
19
20
/**
21
 * The abstract class for cache service providers.
22
 */
23
abstract class CacheProvider implements CacheInterface
24
{
25
    use AssertTrait;
26
27
    /**
28
     * @inheritDoc
29
     */
30 52
    public function get($key, $default = null)
31
    {
32 52
        $this->assertArgumentString($key);
33
34 50
        $data = $this->doGet($key);
35
36 50
        if (!empty($data)) {
37 50
            if ($this->isExpired($data['ttl'], $data['timestamp'])) {
38 10
                $this->delete($key);
39 10
                $data['value'] = $default;
40
            }
41
42 50
            $default = $data['value'];
43
        }
44
45 50
        return $default;
46
    }
47
48
    /**
49
     * @inheritDoc
50
     */
51 58
    public function set($key, $value, $ttl = null)
52
    {
53 58
        $this->assertArgumentString($key);
54 54
        $this->assertValidTypeOfTtl($ttl);
55
56 50
        $timestamp = time();
57
58 50
        return $this->doSet($key, $value, $ttl, $timestamp);
0 ignored issues
show
Bug introduced by
It seems like $ttl can also be of type DateInterval and null; however, parameter $ttl of Shieldon\SimpleCache\CacheProvider::doSet() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

58
        return $this->doSet($key, $value, /** @scrutinizer ignore-type */ $ttl, $timestamp);
Loading history...
59
    }
60
61
    /**
62
     * @inheritDoc
63
     */
64 28
    public function delete($key)
65
    {
66 28
        $this->assertArgumentString($key);
67
68 28
        return $this->doDelete($key);
69
    }
70
71
    /**
72
     * @inheritDoc
73
     */
74 18
    public function clear()
75
    {
76 18
        return $this->doClear();
77
    }
78
79
    /**
80
     * @inheritDoc
81
     */
82 36
    public function has($key)
83
    {
84 36
        $this->assertArgumentString($key);
85
86 34
        if ($this->doHas($key)) {
87 34
            return true;
88
        }
89
90 34
        return false;
91
    }
92
93
    /**
94
     * @inheritDoc
95
     */
96 18
    public function getMultiple($keys, $default = null)
97
    {
98 18
        $this->assertArgumentIterable($keys);
99
100 18
        $data = [];
101
102 18
        foreach ($keys as $key) {
103 18
            $data[$key] = $this->get($key, $default);
104
        }
105
106 18
        return $data;
107
    }
108
109
    /**
110
     * @inheritDoc
111
     */
112 22
    public function setMultiple($values, $ttl = null)
113
    {
114 22
        $this->assertArgumentIterable($values);
115
116 22
        foreach ($values as $key => $value) {
117 22
            if (!$this->set($key, $value, $ttl)) {
118
                // @codeCoverageIgnoreStart
119
                return false;
120
                // @codeCoverageIgnoreEnd
121
            }
122
        }
123
124 18
        return true;
125
    }
126
127
    /**
128
     * @inheritDoc
129
     */
130 20
    public function deleteMultiple($keys)
131
    {
132 20
        $this->assertArgumentIterable($keys);
133
134 18
        foreach ($keys as $key) {
135 18
            if (!$this->doDelete($key)) {
136
                // @codeCoverageIgnoreStart
137
                return false;
138
                // @codeCoverageIgnoreEnd
139
            }
140
        }
141
142 18
        return true;
143
    }
144
145
    /**
146
     * Check if the TTL is expired or not.
147
     *
148
     * @param int|null|DateInterval $ttl       The time to live of a cached data.
149
     * @param int                   $timestamp The unix timesamp that want to check.
150
     * 
151
     * @return bool
152
     */
153 52
    protected function isExpired($ttl, int $timestamp): bool
154
    {
155 52
        $now = time();
156
157 52
        if (is_null($ttl)) {
158 2
            return false;
159
160 52
        } elseif (is_integer($ttl) && ($now - $timestamp < $ttl)) {
161 50
            return false;
162
163 12
        } elseif ($ttl instanceof DateInterval) {
164 2
            $datetimeObj = new DateTime();
165 2
            $datetimeObj->add($ttl);
166 2
            $datetimeObj->getTimestamp();
167
168 2
            if ($now - $timestamp < $datetimeObj->getTimestamp()) {
169 2
                return false;
170
            }
171
        }
172
173 10
        return true;
174
    }
175
176
    /**
177
     * Fetch a cache by an extended Cache Driver.
178
     *
179
     * @param string $key     The key of a cache.
180
     * @param mixed  $default Default value to return if the key does not exist.
181
     *
182
     * @return array The data structure looks like:
183
     *
184
     * [
185
     *   [
186
     *     'value'     => (mixed) $value
187
     *     'ttl'       => (int)   $ttl,
188
     *     'timestamp' => (int)   $timestamp,
189
     *   ],
190
     *   ...
191
     * ]
192
     *
193
     */
194
    abstract protected function doGet(string $key): array;
195
196
    /**
197
     * Set a cache by an extended Cache Driver.
198
     *
199
     * @param string $key       The key of a cache.
200
     * @param mixed  $value     The value of a cache. (serialized)
201
     * @param int    $ttl       The time to live for a cache.
202
     * @param int    $timestamp The time to store a cache.
203
     *
204
     * @return bool
205
     */
206
    abstract protected function doSet(string $key, $value, int $ttl, int $timestamp): bool;
207
208
    /**
209
     * Delete a cache by an extended Cache Driver.
210
     *
211
     * @param string $key The key of a cache.
212
     * 
213
     * @return bool
214
     */
215
    abstract protected function doDelete(string $key): bool;
216
217
    /**
218
     * Delete all caches by an extended Cache Driver.
219
     * 
220
     * @return bool
221
     */
222
    abstract protected function doClear(): bool;
223
224
    /**
225
     * Check if a cahce exists or not.
226
     * 
227
     * @param string $key The key of a cache.
228
     * 
229
     * @return bool
230
     */
231
    abstract protected function doHas(string $key): bool;
232
}