normalize_ttl()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 9
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 14
ccs 9
cts 9
cp 1
crap 5
rs 9.6111
1
<?php
2
/*
3
 * This file is part of the Koded package.
4
 *
5
 * (c) Mihail Binev <[email protected]>
6
 *
7
 * Please view the LICENSE distributed with this source code
8
 * for the full copyright and license information.
9
 */
10
11
namespace Koded\Caching;
12
13
use DateInterval;
14
use DateTimeInterface;
15
use Koded\Caching\Client\ClientFactory;
16
use Koded\Caching\Configuration\ConfigFactory;
17
use Throwable;
18
use function date_create;
19
use function is_int;
20
use function is_iterable;
21
use function is_string;
22
use function Koded\Stdlib\now;
23
use function preg_match;
24
use function timezone_open;
25
use function var_export;
26
27
/**
28
 * Factory function for SimpleCache.
29
 *
30
 * Example:
31
 *
32
 * $cache = simple_cache_factory('redis', ['host' => 'redis']);
33
 * $cache->get('foo');
34
 *
35
 * @param string $client    [optional] The client name (ex. memcached, redis, etc)
36
 * @param array  $arguments [optional] A configuration parameters for the client
37
 *
38
 * @return Cache
39
 * @throws CacheException
40
 */
41
function simple_cache_factory(string $client = '', array $arguments = []): Cache
42
{
43
    try {
44 491
        return (new ClientFactory(new ConfigFactory($arguments)))->new($client);
45 1
    } catch (Throwable $e) {
46 1
        throw CacheException::from($e);
47
    }
48
}
49
50
/**
51
 * Guards the cache key value.
52
 *
53
 * Differs from PSR-16 by allowing the ":" in the reserved characters list.
54
 * The colon is a wide accepted delimiter for Redis to "group" the keys.
55
 *
56
 * @param string $name The cache key
57
 *
58
 * @throws CacheException
59
 * @see https://github.com/php-cache/integration-tests/issues/92
60
 */
61
function verify_key(mixed $name): void
62
{
63 541
    if ('' === $name
64 541
        || false === is_string($name)
65 541
        || preg_match('/[@\{\}\(\)\/\\\]/', $name)
66
    ) {
67 137
        throw CacheException::forInvalidKey($name);
68
    }
69
}
70
71
/**
72
 * Transforms the provided TTL to expiration seconds,
73
 * or NULL for special cases for cache clients that do
74
 * not have built-in expiry mechanism.
75
 *
76
 * Please use integers as seconds for TTL.
77
 *
78
 * @param int|DateInterval|DateTimeInterface|null $value An argument that wants to be a TTL
79
 *
80
 * @return int|null Returns the TTL is seconds or NULL
81
 */
82
function normalize_ttl(mixed $value): ?int
83
{
84 396
    if (null === $value || is_int($value)) {
85 392
        return $value;
86
    }
87 20
    if ($value instanceof DateTimeInterface) {
88 1
        return $value->getTimestamp() - now()->getTimestamp();
89
    }
90 19
    if ($value instanceof DateInterval) {
91 18
        return date_create('@0', timezone_open('UTC'))
92 18
            ->add($value)
93 18
            ->getTimestamp();
94
    }
95 1
    throw CacheException::generic('Invalid TTL, given ' . var_export($value, true));
96
}
97
98
/**
99
 * Filters out the cache item keys and performs a validation on them.
100
 *
101
 * @param iterable $iterable    The cache item
102
 * @param bool     $associative To return an associative array or sequential
103
 *
104
 * @return array Valid cache name keys
105
 */
106
function filter_keys(mixed $iterable, bool $associative): array
107
{
108 287
    if (/*!is_array($iterable) ||*/ false === is_iterable($iterable)) {
109
        throw CacheException::forInvalidKey($iterable);
110
    }
111 287
    $keys = [];
112 287
    foreach ($iterable as $k => $v) {
113 287
        if (false === $associative) {
114 262
            verify_key($v);
115 262
            $keys[] = $v;
116 262
            continue;
117
        }
118 119
        verify_key($k);
119 119
        $keys[$k] = $v;
120
    }
121 151
    return $keys;
122
}
123