Passed
Push — master ( 1bb27c...390798 )
by Stephen
02:58 queued 01:21
created

redisCreateIfMissing()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 9
rs 10
1
<?php
2
3
use Illuminate\Support\Facades\Cache;
4
use Illuminate\Support\Facades\Redis;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Redis. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
5
use Illuminate\Support\Facades\View;
6
7
// todo: create CacheService & CacheService package?
8
9
/**
10
 * Retrieve a formatted RedisKey with the environment prefix included
11
 *
12
 * @param string $redis_key
13
 * @return string
14
 */
15
function redisKey(string $redis_key) {
16
    return env('REDIS_KEY_PREFIX', 'projects') . ":$redis_key";
17
}
18
19
20
/**
21
 * Retrieve an array of keys that begin with a prefix
22
 *
23
 * @param string $redis_key_prefix
24
 * @return mixed list of keys without prefix
25
 */
26
function redisKeys(string $redis_key_prefix) {
27
    return array_map(
28
        // Remove prefix from each key so it is not concatenated twice
29
        function ($key) {
30
            return substr($key, strlen(env('REDIS_KEY_PREFIX')) + 1);
31
        },
32
33
        // List of Redis key's matching pattern
34
        Redis::connection('default')->client()->keys(redisKey($redis_key_prefix . '*'))
35
    );
36
}
37
38
39
/**
40
 * Get items from the cache
41
 *
42
 * @param string $redis_key
43
 * @return mixed
44
 */
45
function redisGet(string $redis_key) {
46
    return Cache::get($redis_key);
47
}
48
49
50
/**
51
 * Put items in the cache with a TTL
52
 *
53
 * Use's environment's REDIS_KEY_EXPIRATION value if $expiration is null.
54
 *
55
 * @param string $redis_key
56
 * @param mixed|null $value
57
 * @param int|null $expiration
58
 * @return mixed|null $value
59
 */
60
function redisSet(string $redis_key, $value=null, $expiration=null) {
61
    Cache::put($redis_key, $value, (isset($expiration)?$expiration:env('REDIS_KEY_EXPIRATION')));
62
    return $value;
63
}
64
65
66
/**
67
 * Add a TTL attribute (time to live or time til expiration) to a Redis key
68
 *
69
 * @param string $redis_key
70
 * @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...
71
 * @return mixed
72
 */
73
function redisExpire(string $redis_key, $expiration=null) {
74
    // Use environment REDIS_KEY_EXPIRATION value if not set
75
    if (!$expiration) {
0 ignored issues
show
introduced by
$expiration is of type null, thus it always evaluated to false.
Loading history...
76
        $expiration = env('REDIS_KEY_EXPIRATION');
77
    }
78
79
    // Create a key value pair with a null value and a TTL if the key is missing
80
    if (redisMissing($redis_key)) {
81
        return redisSet($redis_key, null, $expiration);
0 ignored issues
show
Bug introduced by
Are you sure the usage of redisSet($redis_key, null, $expiration) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
82
    }
83
84
    // Create a key value pair with original value and a TTL if the key exists
85
    else {
86
        return redisSet($redis_key, redisGet($redis_key), $expiration);
87
    }
88
}
89
90
91
/**
92
 * Delete Redis key's from the Cache.
93
 *
94
 * @param $redis_key array|string
95
 * @return array
96
 */
97
function redisDelete($redis_key) {
98
    // Empty array of keys to delete
99
    $keys = [];
100
101
    // Check if an array of keys has been passed
102
    if (gettype($redis_key) == 'array') {
103
        // Recursively merge arrays of keys found matching pattern
104
        foreach (array_values($redis_key) as $value) {
105
            $keys = array_merge($keys, redisKeys($value));
106
        }
107
    } else {
108
        // All keys matching pattern
109
        $keys = array_merge($keys, redisKeys($redis_key));
110
    }
111
112
    // Remove all keys that match param patterns
113
    $to_remove = array_values($keys);
114
    foreach ($to_remove as $value) {
115
        Cache::forget($value);
116
    }
117
    return array_values($to_remove);
118
}
119
120
121
/**
122
 * Determine if a redis key exists in the cache
123
 *
124
 * @param string $redis_key
125
 * @return bool
126
 */
127
function redisExists(string $redis_key) {
128
    return Cache::has($redis_key);
129
}
130
131
132
/**
133
 * Determine if a redis key is missing from the cache
134
 *
135
 * @param string $redis_key
136
 * @return bool
137
 */
138
function redisMissing(string $redis_key) {
139
    return Cache::missing($redis_key);
140
}
141
142
143
/**
144
 * Render a view & cache its output for reuse
145
 *
146
 * @param string $redis_key
147
 * @param string $view
148
 * @param array $data
149
 * @param int|null $expiration
150
 * @return mixed|null
151
 */
152
function redisCacheView(string $redis_key, string $view, array $data, int $expiration=null) {
153
    return redisSet($redis_key, View::make($view, $data)->render(), $expiration);
154
}
155
156
157
/**
158
 * Create a Redis Key with a null value if it is missing
159
 *
160
 * @param string $redis_key
161
 * @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...
162
 * @param int|null $expiration
163
 * @return bool
164
 */
165
function redisCreateIfMissing(string $redis_key, $value = null, int $expiration = null): bool {
166
    // Create the redis Key with an expiration
167
    if (redisMissing($redis_key)) {
168
        redisSet($redis_key, $value, $expiration);
169
        return true;
170
    }
171
172
    // Not created
173
    return false;
174
}
175
176
177
/**
178
 * Increment a Redis Key's value & return the new value
179
 *
180
 * @param string $redis_key
181
 * @param int $value
182
 * @param int|null $expiration
183
 * @return mixed
184
 */
185
function redisIncrement(string $redis_key, int $value = 1, int $expiration = null) {
186
    // Create the Key if it's missing
187
    redisCreateIfMissing($redis_key, 0, $expiration);
188
189
    // Increment the value
190
    Cache::increment($redis_key, $value);
191
192
    // Return the new value
193
    return Cache::get($redis_key);
194
}
195
196
197
/**
198
 * Flush the entire redis cache
199
 *
200
 * @return mixed
201
 */
202
function redisFlush() {
203
    return Redis::connection('default')->client()->flushAll();
204
}
205
206
207
/**
208
 * Flush the redis cache of all keys with environment's prefix
209
 *
210
 * @return array
211
 */
212
function redisClearCache() {
213
    return redisDelete('');
214
}
215