Passed
Push — master ( b20537...482d06 )
by Stephen
01:58
created

RedisCache::setMany()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 7
rs 10
1
<?php
2
3
namespace Sfneal\Helpers\Redis;
4
5
use Closure;
6
use Illuminate\Support\Facades\Cache;
7
use Illuminate\Support\Facades\Redis;
8
use Sfneal\Actions\AbstractService;
9
10
class RedisCache extends AbstractService
11
{
12
    /**
13
     * Retrieve the Redis Key prefix from the config.
14
     *
15
     * @return string
16
     */
17
    public static function prefix(): string
18
    {
19
        return config('redis-helpers.prefix', 'app');
20
    }
21
22
    /**
23
     * Retrieve the Redis Key TTL from the config.
24
     *
25
     * @return int
26
     */
27
    public static function ttl(): int
28
    {
29
        return config('redis-helpers.ttl', 3600);
30
    }
31
32
    /**
33
     * Retrieve a formatted RedisKey with the environment prefix included.
34
     *
35
     * @param string $key
36
     * @return string
37
     */
38
    public static function key(string $key): string
39
    {
40
        return self::prefix().":$key";
41
    }
42
43
    /**
44
     * Retrieve an array of keys that begin with a prefix.
45
     *
46
     * @param string $prefix
47
     * @return mixed list of keys without prefix
48
     */
49
    public static function keys(string $prefix)
50
    {
51
        return array_map(
52
            // Remove prefix from each key so it is not concatenated twice
53
            function ($key) {
54
                return substr($key, strlen(self::prefix()) + 1);
55
            },
56
57
            // List of Redis key's matching pattern
58
            Redis::connection('default')->client()->keys(self::key($prefix.'*'))
59
        );
60
    }
61
62
    /**
63
     * Get items from the cache.
64
     *
65
     * @param string $key
66
     * @return mixed
67
     */
68
    public static function get(string $key)
69
    {
70
        return Cache::get(self::key($key));
71
    }
72
73
    /**
74
     * Put items in the cache with a TTL.
75
     *
76
     * Use's environment's REDIS_KEY_EXPIRATION value if $expiration is null.
77
     *
78
     * @param string $key
79
     * @param null $value
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $value is correct as it would always require null to be passed?
Loading history...
80
     * @param int|null $expiration
81
     * @return string
82
     */
83
    public static function set(string $key, $value = null, int $expiration = null)
84
    {
85
        // Store the $value in the Cache
86
        // todo: change return type to pull
87
        Cache::put(
88
            self::key($key),
89
            $value,
90
            (isset($expiration) ? $expiration : self::ttl())
91
        );
92
93
        // Return the $value
94
        return $value;
95
    }
96
97
    /**
98
     * Put an array of key value pairs into the cache with a TTL
99
     *
100
     * @param array $array
101
     * @param int|null $expiration
102
     * @return array
103
     */
104
    public static function setMany(array $array, int $expiration = null): array
105
    {
106
        foreach ($array as $key => $value) {
107
            self::set($key, $value, $expiration);
108
        }
109
110
        return array_values($array);
111
    }
112
113
    /**
114
     * Add a TTL attribute (time to live or time til expiration) to a Redis key.
115
     *
116
     * @param string $key
117
     * @param null $expiration
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $expiration is correct as it would always require null to be passed?
Loading history...
118
     * @return string|null
119
     */
120
    public static function expire(string $key, $expiration = null)
121
    {
122
        // Use environment REDIS_KEY_EXPIRATION value if not set
123
        if (! $expiration) {
0 ignored issues
show
introduced by
$expiration is of type null, thus it always evaluated to false.
Loading history...
124
            $expiration = self::ttl();
125
        }
126
127
        // Create a key value pair with a null value and a TTL if the key is missing
128
        if (self::missing($key)) {
129
            return self::set($key, null, $expiration);
130
        }
131
132
        // Create a key value pair with original value and a TTL if the key exists
133
        else {
134
            return self::set($key, self::get($key), $expiration);
135
        }
136
    }
137
138
    /**
139
     * Delete Redis key's from the Cache.
140
     *
141
     * @param $key array|string
142
     * @return mixed
143
     */
144
    public static function delete($key)
145
    {
146
        // Empty array of keys to delete
147
        $keys = [];
148
149
        // Check if an array of keys has been passed
150
        if (gettype($key) == 'array') {
151
            // Recursively merge arrays of keys found matching pattern
152
            foreach (array_values($key) as $value) {
153
                $keys = array_merge($keys, self::keys($value));
154
            }
155
        } else {
156
            // All keys matching pattern
157
            $keys = array_merge($keys, self::keys($key));
158
        }
159
160
        // Remove all keys that match param patterns
161
        $to_remove = array_values($keys);
162
        foreach ($to_remove as $value) {
163
            Cache::forget($value);
164
        }
165
166
        // Return array of deleted keys
167
        return array_values($to_remove);
168
    }
169
170
    /**
171
     * Determine if a redis key exists in the cache.
172
     *
173
     * @param string $key
174
     * @return bool
175
     */
176
    public static function exists(string $key): bool
177
    {
178
        return Cache::has(self::key($key));
179
    }
180
181
    /**
182
     * Determine if a redis key is missing from the cache.
183
     *
184
     * @param string $key
185
     * @return bool
186
     */
187
    public static function missing(string $key): bool
188
    {
189
        return Cache::missing(self::key($key));
190
    }
191
192
    /**
193
     * Create a Redis Key with a null value if it is missing.
194
     *
195
     * @param string $key
196
     * @param null $value
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $value is correct as it would always require null to be passed?
Loading history...
197
     * @param null $expiration
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $expiration is correct as it would always require null to be passed?
Loading history...
198
     * @return bool
199
     */
200
    public static function setIfMissing(string $key, $value = null, $expiration = null): bool
201
    {
202
        // Create the redis Key with an expiration
203
        if (self::missing($key)) {
204
            self::set($key, $value, $expiration);
205
206
            return true;
207
        }
208
209
        // Not created
210
        return false;
211
    }
212
213
    /**
214
     * Increment a Redis Key's value & return the new value.
215
     *
216
     * @param string $key
217
     * @param int $value
218
     * @param int|null $expiration
219
     * @return mixed
220
     */
221
    public static function increment(string $key, int $value = 1, int $expiration = null)
222
    {
223
        // Create the Key if it's missing
224
        self::setIfMissing($key, 0, $expiration);
0 ignored issues
show
Bug introduced by
It seems like $expiration can also be of type integer; however, parameter $expiration of Sfneal\Helpers\Redis\RedisCache::setIfMissing() does only seem to accept null, 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

224
        self::setIfMissing($key, 0, /** @scrutinizer ignore-type */ $expiration);
Loading history...
225
226
        // Increment the value
227
        Cache::increment(self::key($key), $value);
228
229
        // Return the new value
230
        // todo: check if this is needed
231
        return self::get($key);
232
    }
233
234
    /**
235
     * Flush the entire redis cache.
236
     *
237
     * @return mixed
238
     */
239
    public static function flush()
240
    {
241
        return Redis::connection('default')->client()->flushAll();
242
    }
243
244
    /**
245
     * Flush the redis cache of all keys with environment's prefix.
246
     *
247
     * @return mixed
248
     */
249
    public static function clear()
250
    {
251
        return self::delete('');
252
    }
253
254
    /**
255
     * Pass a $callback function to be stored in the Cache for an amount of time.
256
     *
257
     * @param string $key
258
     * @param int $ttl
259
     * @param Closure $callback
260
     * @return mixed
261
     */
262
    public static function remember(string $key, int $ttl, Closure $callback)
263
    {
264
        return Cache::remember($key, $ttl, $callback);
265
    }
266
267
    /**
268
     * Pass a $callback function to be stored in the Cache forever.
269
     *
270
     * @param string $key
271
     * @param Closure $callback
272
     * @return mixed
273
     */
274
    public static function rememberForever(string $key, Closure $callback)
275
    {
276
        return Cache::rememberForever($key, $callback);
277
    }
278
}
279