APCUCache::checkReservedCharacters()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 2
Bugs 0 Features 2
Metric Value
eloc 7
c 2
b 0
f 2
dl 0
loc 10
ccs 8
cts 8
cp 1
rs 10
cc 4
nc 4
nop 1
crap 4
1
<?php
2
3
namespace Soupmix\Cache;
4
5
use Soupmix\Cache\Exceptions\InvalidArgumentException;
6
use Psr\SimpleCache\CacheInterface;
7
use DateInterval;
8
use DateTime;
9
10
use function apcu_fetch;
11
use function apcu_store;
12
use function apcu_delete;
13
use function apcu_clear_cache;
14
use function apcu_dec;
15
use function apcu_inc;
16
17
class APCUCache implements CacheInterface
18
{
19
    private const PSR16_RESERVED_CHARACTERS = ['{','}','(',')','/','@',':'];
20
21
    /**
22
     * {@inheritDoc}
23
     */
24 1
    public function get($key, $default = null)
25
    {
26 1
        $this->checkReservedCharacters($key);
27 1
        $value = apcu_fetch($key);
28 1
        return $value ?: $default;
29
    }
30
31
    /**
32
     * {@inheritDoc}
33
     */
34 5
    public function set($key, $value, $ttl = null) : bool
35
    {
36 5
        $this->checkReservedCharacters($key);
37 3
        if ($ttl instanceof DateInterval) {
38 1
            $ttl = (new DateTime('now'))->add($ttl)->getTimeStamp() - time();
39
        }
40 3
        return apcu_store($key, $value, (int) $ttl);
0 ignored issues
show
Bug Best Practice introduced by
The expression return apcu_store($key, $value, (int)$ttl) could return the type array which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
41
    }
42
43
    /**
44
     * {@inheritDoc}
45
     */
46 1
    public function delete($key) : bool
47
    {
48 1
        $this->checkReservedCharacters($key);
49 1
        return (bool) apcu_delete($key);
50
    }
51
52
    /**
53
     * {@inheritDoc}
54
     */
55 7
    public function clear() : bool
56
    {
57 7
        return apcu_clear_cache();
58
    }
59
    /**
60
     * {@inheritDoc}
61
     */
62 1
    public function getMultiple($keys, $default = null)
63
    {
64 1
        $defaults = array_fill(0, count($keys), $default);
65 1
        foreach ($keys as $key) {
66 1
            $this->checkReservedCharacters($key);
67
        }
68 1
        return array_merge(apcu_fetch($keys), $defaults);
69
    }
70
71
    /**
72
     * {@inheritDoc}
73
     */
74 1
    public function setMultiple($values, $ttl = null) : bool
75
    {
76 1
        foreach ($values as $key => $value) {
77 1
            $this->checkReservedCharacters($key);
78
        }
79 1
        if ($ttl instanceof DateInterval) {
80 1
            $ttl = (new DateTime('now'))->add($ttl)->getTimeStamp() - time();
81
        }
82 1
        $result =  apcu_store($values, null, $ttl);
83 1
        return empty($result);
84
    }
85
86
    /**
87
     * {@inheritDoc}
88
     */
89 1
    public function deleteMultiple($keys) : array
90
    {
91 1
        $ret = [];
92 1
        foreach ($keys as $key) {
93 1
            $this->checkReservedCharacters($key);
94 1
            $ret[$key] = apcu_delete($key);
95
        }
96 1
        return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret returns the type array which is incompatible with the return type mandated by Psr\SimpleCache\CacheInterface::deleteMultiple() of boolean.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
97
    }
98
99 1
    public function increment($key, $step = 1)
100
    {
101 1
        $this->checkReservedCharacters($key);
102 1
        return apcu_inc($key, $step);
103
    }
104
105 1
    public function decrement($key, $step = 1)
106
    {
107 1
        $this->checkReservedCharacters($key);
108 1
        return apcu_dec($key, $step);
109
    }
110
111
    /**
112
     * {@inheritDoc}
113
     */
114 1
    public function has($key)
115
    {
116 1
        $this->checkReservedCharacters($key);
117 1
        return apcu_exists($key);
0 ignored issues
show
Bug Best Practice introduced by
The expression return apcu_exists($key) also could return the type string[] which is incompatible with the return type mandated by Psr\SimpleCache\CacheInterface::has() of boolean.
Loading history...
118
    }
119
120 6
    private function checkReservedCharacters($key) : void
121
    {
122 6
        if (!is_string($key)) {
123 1
            $message = sprintf('key %s is not a string.', $key);
124 1
            throw new InvalidArgumentException($message);
125
        }
126 5
        foreach (self::PSR16_RESERVED_CHARACTERS as $needle) {
127 5
            if (strpos($key, $needle) !== false) {
128 1
                $message = sprintf('%s string is not a legal value.', $key);
129 1
                throw new InvalidArgumentException($message);
130
            }
131
        }
132 4
    }
133
}
134