Passed
Push — master ( d6dac1...ba598e )
by Mihail
03:07 queued 01:05
created

functions.php (3 issues)

1
<?php
2
3
/*
4
 * This file is part of the Koded package.
5
 *
6
 * (c) Mihail Binev <[email protected]>
7
 *
8
 * Please view the LICENSE distributed with this source code
9
 * for the full copyright and license information.
10
 *
11
 */
12
13
namespace Koded\Caching;
14
15
use DateInterval;
16
use DateTimeInterface;
17
use Koded\Caching\Client\CacheClientFactory;
18
use Koded\Caching\Configuration\ConfigFactory;
19
use Throwable;
20
use function Koded\Stdlib\now;
21
22
/**
23
 * Factory function for SimpleCache.
24
 *
25
 * Example:
26
 *
27
 * $cache = simple_cache_factory('redis', ['host' => 'redis']);
28
 * $cache->get('foo');
29
 *
30
 * @param string $client    [optional] The client name (ex. memcached, redis, etc)
31
 * @param array  $arguments [optional] A configuration parameters for the client
32
 *
33
 * @return Cache
34
 * @throws CacheException
35
 */
36
function simple_cache_factory(string $client = '', array $arguments = []): Cache
37
{
38
    try {
39 1500
        return (new CacheClientFactory(new ConfigFactory($arguments)))->new($client);
40 1
    } catch (Throwable $e) {
41 1
        throw CacheException::from($e);
42
    }
43
}
44
45
/**
46
 * Guards the cache key value.
47
 *
48
 * Differs from PSR-16 by allowing the ":" in the reserved characters list.
49
 * The colon is a wide accepted convention for Redis to "group" the key.
50
 *
51
 * @param string $name The cache key
52
 *
53
 * @throws CacheException
54
 * @see https://github.com/php-cache/integration-tests/issues/92
55
 */
56
function verify_key($name): void
57
{
58
    /*
59
     * This thing is here because the bug in the integration test,
60
     * $this->cache->setMultiple(['0' => 'value0']) in SimpleCacheTest.php:239
61
     */
62 1527
    if (0 === $name) {
0 ignored issues
show
The condition 0 === $name is always false.
Loading history...
63 8
        return;
64
    }
65
66 1527
    if ('' === $name
67 1495
        || false === is_string($name)
68 1527
        || preg_match('/[@\{\}\(\)\/\\\]/', $name)
69
    ) {
70 953
        throw CacheException::forInvalidKey($name);
71
    }
72 982
}
73
74
/**
75
 * Transforms the provided TTL to expiration seconds,
76
 * or NULL for special cases for cache clients that do
77
 * not have built-in expiry mechanism.
78
 *
79
 * Please use integers as seconds for TTL.
80
 *
81
 * @param int|DateInterval|DateTimeInterface|null $value An argument that wants to be a TTL
82
 *
83
 * @return int|null Returns the TTL is seconds or NULL
84
 */
85
function normalize_ttl($value): ?int
86
{
87 565
    if (null === $value || is_int($value)) {
88 401
        return $value;
89
    }
90
91 180
    if ($value instanceof DateTimeInterface) {
92 1
        return $value->getTimestamp() - now()->getTimestamp();
93
    }
94
95 179
    if ($value instanceof DateInterval) {
0 ignored issues
show
$value is always a sub-type of DateInterval.
Loading history...
96 18
        return date_create('@0', timezone_open('UTC'))->add($value)->getTimestamp();
0 ignored issues
show
It seems like timezone_open('UTC') can also be of type false; however, parameter $timezone of date_create() does only seem to accept DateTimeZone|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

96
        return date_create('@0', /** @scrutinizer ignore-type */ timezone_open('UTC'))->add($value)->getTimestamp();
Loading history...
97
    }
98
99 161
    throw CacheException::generic('Invalid TTL, given ' . var_export($value, true));
100
}
101
102
/**
103
 * Filters out the cache items keys and performs a validation on them.
104
 *
105
 * @param iterable $iterable    The cache item
106
 * @param bool     $associative To return an associative array or sequential
107
 *
108
 * @return array Valid cache name keys
109
 */
110
function filter_keys($iterable, bool $associative): array
111
{
112 671
    if (false === is_iterable($iterable)) {
113 24
        throw CacheException::forInvalidKey($iterable);
114
    }
115
116 647
    $keys = [];
117 647
    foreach ($iterable as $k => $v) {
118 647
        if (false === $associative) {
119 398
            verify_key($v);
120 398
            $keys[] = $v;
121 398
            continue;
122
        }
123
124 343
        verify_key($k);
125 343
        $keys[$k] = $v;
126
    }
127
128 239
    return $keys;
129
}
130