SimpleCacheAdapter::get()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 8
cts 8
cp 1
rs 9.7333
c 0
b 0
f 0
cc 3
nc 3
nop 2
crap 3
1
<?php
2
declare(strict_types = 1);
3
4
namespace Roave\DoctrineSimpleCache;
5
6
use Doctrine\Common\Cache\Cache as DoctrineCache;
7
use Doctrine\Common\Cache\ClearableCache;
8
use Doctrine\Common\Cache\MultiOperationCache;
9
use Psr\SimpleCache\CacheInterface as PsrCache;
10
use Roave\DoctrineSimpleCache\Exception\InvalidArgumentException;
11
12
final class SimpleCacheAdapter implements PsrCache
13
{
14
    /**
15
     * @var DoctrineCache|ClearableCache|MultiOperationCache
16
     */
17
    private $doctrineCache;
18
19
    /**
20
     * @param DoctrineCache $doctrineCache
21
     * @throws \Roave\DoctrineSimpleCache\Exception\CacheException
22
     */
23 62
    public function __construct(DoctrineCache $doctrineCache)
24
    {
25 62
        $this->doctrineCache = $doctrineCache;
26
27 62
        if (!$this->doctrineCache instanceof ClearableCache) {
28 1
            throw Exception\CacheException::fromNonClearableCache($this->doctrineCache);
29
        }
30
31 61
        if (!$this->doctrineCache instanceof MultiOperationCache) {
32 1
            throw Exception\CacheException::fromNonMultiOperationCache($this->doctrineCache);
33
        }
34 60
    }
35
36
    /**
37
     * @param mixed $key
38
     * @throws \Roave\DoctrineSimpleCache\Exception\InvalidArgumentException
39
     */
40 57
    private function validateKey($key) : void
41
    {
42 57
        if (!is_string($key)) {
43 7
            throw Exception\InvalidArgumentException::fromInvalidType($key);
44
        }
45
46 50
        if ('' === $key) {
47 1
            throw Exception\InvalidArgumentException::fromEmptyKey();
48
        }
49
50 49
        if (preg_match('/[' . preg_quote('{}()/\@:', '/') . ']/', $key)) {
51 10
            throw Exception\InvalidArgumentException::fromInvalidKeyCharacters($key);
52
        }
53 39
    }
54
55
    /**
56
     * @param mixed $keys
57
     * @return array
58
     * @throws \Roave\DoctrineSimpleCache\Exception\InvalidArgumentException
59
     */
60 28
    private function filterValidateMultipleKeys($keys) : array
61
    {
62 28
        if ($keys instanceof \Traversable) {
63 3
            $keys = iterator_to_array($keys, false);
64
        }
65
66 28
        if (!is_array($keys)) {
67 1
            throw Exception\InvalidArgumentException::fromNonIterableKeys($keys);
68
        }
69
70 27
        array_map([$this, 'validateKey'], $keys);
71
72 9
        return $keys;
73
    }
74
75
    /**
76
     * {@inheritDoc}
77
     */
78 7
    public function get($key, $default = null)
79
    {
80 7
        $this->validateKey($key);
81
82 7
        $value = $this->doctrineCache->fetch($key);
0 ignored issues
show
Bug introduced by
The method fetch does only exist in Doctrine\Common\Cache\Cache, but not in Doctrine\Common\Cache\Cl...che\MultiOperationCache.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
83 7
        if ($value === false) {
84
            // Doctrine cache returns `false` when cache doesn't contain, but also `false` if the value stored is
85
            // `false`, so check to see if the cache contains the key; if so, we probably meant to return `false`
86 4
            if ($this->doctrineCache->contains($key)) {
0 ignored issues
show
Bug introduced by
The method contains does only exist in Doctrine\Common\Cache\Cache, but not in Doctrine\Common\Cache\Cl...che\MultiOperationCache.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
87 1
                return false;
88
            }
89 3
            return $default;
90
        }
91
92 6
        return $value;
93
    }
94
95
    /**
96
     * {@inheritDoc}
97
     */
98 15
    public function set($key, $value, $ttl = null) : bool
99
    {
100 15
        $this->validateKey($key);
101
102 15
        if ($ttl === null) {
103 2
            return $this->doctrineCache->save($key, $value);
0 ignored issues
show
Bug introduced by
The method save does only exist in Doctrine\Common\Cache\Cache, but not in Doctrine\Common\Cache\Cl...che\MultiOperationCache.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
104
        }
105
106 13
        if ($ttl instanceof \DateInterval) {
107 1
            $ttl = $this->convertDateIntervalToInteger($ttl);
108
        }
109
110 13
        if (!is_int($ttl)) {
111 10
            throw InvalidArgumentException::fromKeyAndInvalidTTL($key, $ttl);
112
        }
113
114 3
        if ($ttl <= 0) {
115 1
            return $this->delete($key);
116
        }
117
118 3
        return $this->doctrineCache->save($key, $value, $ttl);
119
    }
120
121
    /**
122
     * {@inheritDoc}
123
     */
124 2
    public function delete($key) : bool
125
    {
126 2
        $this->validateKey($key);
127 2
        return $this->doctrineCache->delete($key);
0 ignored issues
show
Bug introduced by
The method delete does only exist in Doctrine\Common\Cache\Cache, but not in Doctrine\Common\Cache\Cl...che\MultiOperationCache.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
128
    }
129
130
    /**
131
     * {@inheritDoc}
132
     */
133 1
    public function clear() : bool
134
    {
135 1
        return $this->doctrineCache->deleteAll();
0 ignored issues
show
Bug introduced by
The method deleteAll does only exist in Doctrine\Common\Cache\ClearableCache, but not in Doctrine\Common\Cache\Ca...che\MultiOperationCache.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
136
    }
137
138
    /**
139
     * @param array|\Traversable $keys
140
     * @param mixed $default
141
     * @return array
142
     * @throws \Roave\DoctrineSimpleCache\Exception\InvalidArgumentException
143
     */
144 25
    public function getMultiple($keys, $default = null) : array
145
    {
146 25
        $keys = $this->filterValidateMultipleKeys($keys);
147 6
        return array_merge(array_fill_keys($keys, $default), $this->doctrineCache->fetchMultiple($keys));
0 ignored issues
show
Bug introduced by
The method fetchMultiple does only exist in Doctrine\Common\Cache\MultiOperationCache, but not in Doctrine\Common\Cache\Ca...on\Cache\ClearableCache.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
148
    }
149
150
    /**
151
     * @param array|\Traversable $values
152
     * @param null|int|\DateInterval $ttl
153
     * @return bool
154
     * @throws \Roave\DoctrineSimpleCache\Exception\InvalidArgumentException
155
     * @throws \Exception
156
     */
157 17
    public function setMultiple($values, $ttl = null) : bool
158
    {
159 17
        if (!$values instanceof \Traversable && !is_array($values)) {
160 1
            throw Exception\InvalidArgumentException::fromNonIterableKeys($values);
161
        }
162
163 16
        $validatedValues = [];
164 16
        foreach ($values as $k => $v) {
165 16
            $this->validateKey($k);
166 16
            $validatedValues[$k] = $v;
167
        }
168
169 16
        if ($ttl === null) {
170 5
            return $this->doctrineCache->saveMultiple($validatedValues);
0 ignored issues
show
Bug introduced by
The method saveMultiple does only exist in Doctrine\Common\Cache\MultiOperationCache, but not in Doctrine\Common\Cache\Ca...on\Cache\ClearableCache.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
171
        }
172
173 12
        if ($ttl instanceof \DateInterval) {
174 1
            $ttl = $this->convertDateIntervalToInteger($ttl);
175
        }
176
177 12
        if (!is_int($ttl)) {
178 10
            throw InvalidArgumentException::fromKeyAndInvalidTTL(key($validatedValues), $ttl);
179
        }
180
181 2
        if ($ttl <= 0) {
182 1
            return $this->deleteMultiple(array_keys($validatedValues));
183
        }
184
185 1
        return $this->doctrineCache->saveMultiple($validatedValues, $ttl);
186
    }
187
188
    /**
189
     * @param array|\Traversable $keys
190
     * @return bool
191
     * @throws \Roave\DoctrineSimpleCache\Exception\InvalidArgumentException
192
     */
193 3
    public function deleteMultiple($keys) : bool
194
    {
195 3
        return $this->doctrineCache->deleteMultiple($this->filterValidateMultipleKeys($keys));
0 ignored issues
show
Bug introduced by
The method deleteMultiple does only exist in Doctrine\Common\Cache\MultiOperationCache, but not in Doctrine\Common\Cache\Ca...on\Cache\ClearableCache.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
196
    }
197
198
    /**
199
     * {@inheritDoc}
200
     */
201 1
    public function has($key) : bool
202
    {
203 1
        $this->validateKey($key);
204 1
        return $this->doctrineCache->contains($key);
0 ignored issues
show
Bug introduced by
The method contains does only exist in Doctrine\Common\Cache\Cache, but not in Doctrine\Common\Cache\Cl...che\MultiOperationCache.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
205
    }
206
207
    /**
208
     * @throws \Exception
209
     */
210 2
    private function convertDateIntervalToInteger(\DateInterval $ttl) : int
211
    {
212
        // Timestamp has 2038 year limitation, but it's unlikely to set TTL that long.
213 2
        return (new \DateTime())
214 2
            ->setTimestamp(0)
215 2
            ->add($ttl)
216 2
            ->getTimestamp();
217
    }
218
}
219