PSR16Util::step()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 7
ccs 0
cts 0
cp 0
rs 10
cc 2
nc 2
nop 1
crap 6
1
<?php
2
3
namespace Vectorface\Cache\Common;
4
5
use DateInterval;
6
use DateTime;
7
use Exception;
8
use Traversable;
9
use Vectorface\Cache\Exception\CacheException;
10
use Vectorface\Cache\Exception\InvalidArgumentException as CacheArgumentException;
11
12
/**
13
 * Utility methods common to many PSR-16 cache implementations
14
 */
15
trait PSR16Util
16
{
17
    /**
18
     * The DateTime implementation to use
19
     */
20
    private static string $dateTimeClass = DateTime::class;
21
22
    /**
23
     * Enforce a fairly standard key format
24
     *
25
     * @throws CacheArgumentException Thrown if the key is not a legal value
26
     */
27
    protected function key(mixed $key) : string
28
    {
29
        if (is_numeric($key) || is_string($key)) {
30
            return (string)$key;
31 101
        }
32
33 101
        throw new CacheArgumentException("key is not a legal value");
34 97
    }
35
36
    /**
37 7
     * Enforce fairly standard key formats on an iterable of values
38
     *
39
     * @throws CacheArgumentException Thrown if any of the keys is not a legal value
40
     */
41
    protected function values(iterable $values) : iterable
42
    {
43
        if (!is_array($values) && !($values instanceof Traversable)) {
44
            throw new CacheArgumentException("values must be provided as an array or a Traversable");
45
        }
46 17
47 17
        $array = [];
48 5
        foreach ($values as $key => $value) {
49
            $array[$this->key($key)] = $value;
50
        }
51 12
        return $array;
52 12
    }
53 12
54
    /**
55 12
     * Enforce a fairly standard key format on an array or Traversable of keys
56
     *
57
     * @throws CacheArgumentException Thrown if any of the keys is not a legal value
58
     */
59
    protected function keys(iterable $keys) : array
60
    {
61
        if (!is_array($keys) && !($keys instanceof Traversable)) {
62
            throw new CacheArgumentException("keys must be provided as an array or a Traversable");
63
        }
64
65 21
        $array = [];
66
        foreach ($keys as $key) {
67 21
            $array[] = $this->key($key);
68 6
        }
69
        return $array;
70
    }
71 15
72 15
    /**
73 15
     * Enforce a valid step value for increment/decrement methods
74
     *
75 14
     * @throws CacheArgumentException Thrown if the step is not a legal value
76
     */
77
    protected function step(mixed $step) : int
78
    {
79
        if (!is_integer($step)) {
80
            throw new CacheArgumentException("step must be an integer");
81
        }
82
83
        return $step;
84
    }
85 5
86
    /**
87 5
     * Add defaults to an array of values from a cache
88
     *
89
     * Note: This does NOT check the keys array
90
     *
91 5
     * @param iterable|array $keys An array of expected keys
92
     * @param array $values An array of values pulled from the cache
93
     * @param mixed $default The default value to be populated for missing entries
94
     * @return array The values array, with defaults added
95
     */
96
    protected static function defaults(iterable $keys, array $values, mixed $default) : array
97
    {
98
        foreach ($keys as $key) {
99
            $values[$key] ??= $default;
100
        }
101
        return $values;
102
    }
103
104 2
    /**
105
     * Convert a PSR-16 compatible TTL argument to a standard integer TTL as used by most caches
106 2
     *
107 2
     * @throws CacheException Throws if the argument is not a valid TTL
108 2
     */
109
    public static function ttl(mixed $ttl) : int|null
110
    {
111 2
        if ($ttl instanceof DateInterval) {
112
            return static::intervalToTTL($ttl);
113
        }
114
        if (is_numeric($ttl) || $ttl === null) {
115
            return $ttl;
116
        }
117
118
        throw new CacheArgumentException("TTL must be specified as a number, a DateInterval, or null");
119
    }
120
121 98
    /**
122
     * Convert a DateInterval to a time diff in seconds
123 98
     *
124 2
     * @throws CacheException
125 96
     */
126 93
    public static function intervalToTTL(DateInterval $interval) : int
127
    {
128
        $dateClass = self::$dateTimeClass;
129 5
130
        try {
131
            $now = new $dateClass();
132
            $exp = (new $dateClass())->add($interval);
133
        } catch (Exception) {
134
            throw new CacheException("Could not get current DateTime");
135
        }
136
137
        return $exp->getTimestamp() - $now->getTimestamp();
138
    }
139
}
140