Completed
Push — master ( 9ee7f1...b3e331 )
by Franck
18:55 queued 05:58
created

Pool::setMultiple()   C

Complexity

Conditions 8
Paths 21

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 19
nc 21
nop 2
1
<?php
2
3
/**
4
 *
5
 * This file is part of the Apix Project.
6
 *
7
 * (c) Franck Cassedanne <franck at ouarz.net>
8
 *
9
 * @license     http://opensource.org/licenses/BSD-3-Clause  New BSD License
10
 *
11
 */
12
13
namespace Apix\SimpleCache\PsrSimpleCache;
14
15
use Apix\Cache\PsrCache\Item as CacheItem;
16
use Psr\SimpleCache\CacheInterface as SimpleCacheInterface;
17
use Psr\Cache\CacheItemPoolInterface as CacheItemPool;
18
use Psr\Cache\InvalidArgumentException as CacheInvalidArgumentException;
19
20
/**
21
 * Provides a PSR-16 (SimpleCache) wrapper to PSR-6 (Cache).
22
 *
23
 * @author Franck Cassedanne <franck at ouarz.net>
24
 */
25
class Pool implements SimpleCacheInterface
26
{
27
28
    /**
29
     * @var CacheItemPool
30
     */
31
    protected $cache_item_pool;
32
33
    /**
34
     * Constructor.
35
     */
36
    public function __construct(CacheItemPool $cache_item_pool)
37
    {
38
        $this->cache_item_pool = $cache_item_pool;
39
    }
40
41
    /**
42
     * {@inheritdoc}
43
     */
44 View Code Duplication
    public function get($key, $default = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
45
    {
46
        try {
47
            $item = $this->cache_item_pool->getItem($key);
48
        } catch (CacheInvalidArgumentException $e) {
49
            self::_rethrow($e);
50
        }
51
52
        return $item->isHit() ? $item->get() : $default;
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function getMultiple($keys, $default = null)
59
    {
60
        $keys = static::_normalizedKeys($keys);
0 ignored issues
show
Bug introduced by
Since _normalizedKeys() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of _normalizedKeys() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
61
62
        $items = array();
63
        foreach ($keys as $key) {
64
            $items[$key] = $this->get($key, $default);
65
        }
66
67
        return $items;
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73
    public function has($key)
74
    {
75
        try {
76
            $bool = $this->cache_item_pool->hasItem($key);
77
        } catch (CacheInvalidArgumentException $e) {
78
            self::_rethrow($e);
79
        }
80
81
        return $bool;
82
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87
    public function clear()
88
    {
89
        return $this->cache_item_pool->clear();
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95
    public function deleteMultiple($keys)
96
    {
97
        $keys = static::_normalizedKeys($keys);
0 ignored issues
show
Bug introduced by
Since _normalizedKeys() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of _normalizedKeys() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
98
99
        try {
100
            $bool = $this->cache_item_pool->deleteItems($keys);
101
        } catch (CacheInvalidArgumentException $e) {
102
            self::_rethrow($e);
103
        }
104
105
        return $bool;
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     */
111
    public function delete($key)
112
    {
113
        try {
114
            $bool = $this->cache_item_pool->deleteItem($key);
115
        } catch (CacheInvalidArgumentException $e) {
116
            self::_rethrow($e);
117
        }
118
119
        return $bool;
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125 View Code Duplication
    public function set($key, $value, $ttl = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
    {
127
        try {
128
            $item = $this->cache_item_pool->getItem($key);
129
            $this->setItemProperties($item, $value, $ttl);
0 ignored issues
show
Compatibility introduced by
$item of type object<Psr\Cache\CacheItemInterface> is not a sub-type of object<Apix\Cache\PsrCache\Item>. It seems like you assume a concrete implementation of the interface Psr\Cache\CacheItemInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
130
        } catch (CacheInvalidArgumentException $e) {
131
            self::_rethrow($e);
132
        }
133
134
        return $this->cache_item_pool->save($item);
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140
    public function setMultiple($values, $ttl = null)
141
    {
142
        if (!is_array($values) && !$values instanceof \Traversable) {
143
            throw new InvalidArgumentException(sprintf(
144
                'Expected an array or a \Traversable, got `%s`.',
145
                gettype($values)
146
            ));
147
        }
148
149
        $keys = array_keys((array) $values);
150
151
        try {
152
            $items = $this->cache_item_pool->getItems($keys);
153
        } catch (CacheInvalidArgumentException $e) {
154
            self::_rethrow($e);
155
        }
156
157
        $success = true;
158
        foreach ($items as $key => $item) {
159
            try {
160
                $this->setItemProperties($item, $values[$key], $ttl);
161
            } catch (CacheInvalidArgumentException $e) {
162
                self::_rethrow($e);
163
            }
164
165
            $success = $success
166
                       && $this->cache_item_pool->saveDeferred($item);
167
        }
168
169
        return $success && $this->cache_item_pool->commit();
170
    }
171
172
    /**
173
     * Sets the properties of an item object.
174
     *
175
     * @param CacheItem              $item
176
     * @param mixed                  $value The item value (unserialized)
177
     * @param integer|\DateInterval|null $ttl
178
     *
179
     * @return static The invoked object.
180
     */
181
    protected function setItemProperties(
182
        CacheItem $item, $value, $ttl = null
183
    ) {
184
        return $item->set($value)
185
                    ->expiresAfter($ttl);
186
    }
187
188
    private static function _normalizedKeys($keys)
189
    {
190
        if (!is_array($keys)) {
191
            if (!$keys instanceof \Traversable) {
192
                throw new InvalidArgumentException(sprintf(
193
                    'Expected an array or a \Traversable, got `%s`.',
194
                    gettype($keys)
195
                ));
196
            }
197
198
            $keys = iterator_to_array($keys, false);
199
        }
200
201
        return $keys;
202
    }
203
204
    private static function _rethrow(CacheInvalidArgumentException $e)
205
    {
206
        throw new InvalidArgumentException(
207
            $e->getMessage(), $e->getCode(), $e
208
        );
209
    }
210
211
    /**
212
     * Returns the cache adapter for this pool.
213
     *
214
     * @return CacheAdapter
215
     */
216
    public function getCacheAdapter()
217
    {
218
        return $this->cache_item_pool->getCacheAdapter();
219
    }
220
}
221