Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.56% covered (success)
97.56%
40 / 41
90.00% covered (success)
90.00%
9 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
Pool
97.56% covered (success)
97.56%
40 / 41
90.00% covered (success)
90.00%
9 / 10
22
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getItem
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getItems
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
4
 hasItem
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 clear
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 deleteItem
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 deleteItems
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 save
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 saveDeferred
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 commit
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
1<?php declare(strict_types=1);
2/**
3 * Banker
4 *
5 * A Caching library implementing psr/cache (PSR 6) and psr/simple-cache (PSR 16)
6 *
7 * PHP version 8+
8 *
9 * @package     Banker
10 * @author      Timothy J. Warren <tim@timshomepage.net>
11 * @copyright   2016 - 2023  Timothy J. Warren
12 * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
13 * @version     4.1.0
14 * @link        https://git.timshomepage.net/timw4mail/banker
15 */
16namespace Aviat\Banker;
17
18use Aviat\Banker\Exception\InvalidArgumentException;
19use Psr\Cache\{CacheItemInterface, CacheItemPoolInterface};
20use Psr\Log\{LoggerAwareInterface, LoggerInterface};
21use PHPUnit\Framework\Attributes\CodeCoverageIgnore;
22
23use function is_string;
24
25/**
26 * The main cache manager
27 */
28final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
29    use _Driver;
30    use KeyValidateTrait;
31    use LoggerTrait;
32
33    /**
34     * Cache Items to be saved
35     *
36     * @var array
37     */
38    protected array $deferred = [];
39
40    /**
41     * Set up the cache backend
42     *
43     * @param array $config
44     * @param LoggerInterface|null $logger
45     */
46    public function __construct(array $config, ?LoggerInterface $logger = NULL)
47    {
48        $this->driver = $this->loadDriver($config);
49
50        if ($logger !== NULL)
51        {
52            $this->setLogger($logger);
53        }
54    }
55
56    /**
57     * Returns a Cache Item representing the specified key.
58     *
59     * This method must always return a CacheItemInterface object, even in case of
60     * a cache miss. It MUST NOT return null.
61     *
62     * @param string $key
63     *   The key for which to return the corresponding Cache Item.
64     *
65     * @throws InvalidArgumentException
66     *   If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
67     *   MUST be thrown.
68     *
69     * @return CacheItemInterface
70     *   The corresponding Cache Item.
71     */
72    public function getItem(string $key): CacheItemInterface
73    {
74        $this->validateKey($key);
75
76        // If a deferred item exists, return that
77        if (array_key_exists($key, $this->deferred))
78        {
79            return $this->deferred[$key];
80        }
81
82        return new Item($this->driver, $key);
83    }
84
85    /**
86     * Returns a traversable set of cache items.
87     *
88     * @param string[] $keys
89     *   An indexed array of keys of items to retrieve.
90     *
91     * @throws InvalidArgumentException
92     *   If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
93     *   MUST be thrown.
94     *
95     * @return iterable
96     *   A traversable collection of Cache Items keyed by the cache keys of
97     *   each item. A Cache item will be returned for each key, even if that
98     *   key is not found. However, if no keys are specified then an empty
99     *   traversable MUST be returned instead.
100     */
101    public function getItems(array $keys = []): iterable
102    {
103        $this->validateKeys($keys);
104
105        if (empty($keys))
106        {
107            return new ItemCollection([]);
108        }
109
110        // Get the set of items selected
111        $items = [];
112        foreach($keys as $key)
113        {
114            $items[$key] = array_key_exists($key, $this->deferred)
115                ? $this->deferred[$key]
116                : new Item($this->driver, $key);
117        }
118
119        return new ItemCollection($items);
120    }
121
122    /**
123     * Confirms if the cache contains specified cache item.
124     *
125     * Note: This method MAY avoid retrieving the cached value for performance reasons.
126     * This could result in a race condition with CacheItemInterface::get(). To avoid
127     * such situation use CacheItemInterface::isHit() instead.
128     *
129     * @param string $key
130     *   The key for which to check existence.
131     *
132     * @throws InvalidArgumentException
133     *   If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
134     *   MUST be thrown.
135     *
136     * @return bool
137     *   True if item exists in the cache, false otherwise.
138     */
139    public function hasItem(string $key): bool
140    {
141        $this->validateKey($key);
142
143        // See if there are any deferred items
144        if (array_key_exists($key, $this->deferred))
145        {
146            return TRUE;
147        }
148
149        return $this->driver->exists($key);
150    }
151
152    /**
153     * Deletes all items in the pool.
154     *
155     * @return bool
156     *   True if the pool was successfully cleared. False if there was an error.
157     */
158    public function clear(): bool
159    {
160        return $this->driver->flush();
161    }
162
163    /**
164     * Removes the item from the pool.
165     *
166     * @param string $key
167     *   The key to delete.
168     *
169     * @throws InvalidArgumentException
170     *   If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
171     *   MUST be thrown.
172     *
173     * @return bool
174     *   True if the item was successfully removed. False if there was an error.
175     */
176    public function deleteItem(string $key): bool
177    {
178        $this->validateKey($key);
179
180        if ( ! $this->hasItem($key))
181        {
182            return FALSE;
183        }
184
185        return $this->driver->delete($key);
186    }
187
188    /**
189     * Removes multiple items from the pool.
190     *
191     * @param string[] $keys
192     *   An array of keys that should be removed from the pool.
193
194     * @throws InvalidArgumentException
195     *   If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
196     *   MUST be thrown.
197     *
198     * @return bool
199     *   True if the items were successfully removed. False if there was an error.
200     */
201    public function deleteItems(array $keys): bool
202    {
203        $this->validateKeys($keys);
204
205        return $this->driver->deleteMultiple($keys);
206    }
207
208    /**
209     * Persists a cache item immediately.
210     *
211     * @param CacheItemInterface $item
212     *   The cache item to save.
213     *
214     * @return bool
215     *   True if the item was successfully persisted. False if there was an error.
216     */
217    public function save(CacheItemInterface $item): bool
218    {
219        if ( ! method_exists($item, 'save'))
220        {
221            return FALSE;
222        }
223
224        return $item->save();
225    }
226
227    /**
228     * Sets a cache item to be persisted later.
229     *
230     * @param CacheItemInterface $item
231     *   The cache item to save.
232     *
233     * @return bool
234     *   False if the item could not be queued or if a commit was attempted and failed. True otherwise.
235     */
236    public function saveDeferred(CacheItemInterface $item): bool
237    {
238        $key = $item->getKey();
239        $this->deferred[$key] = $item;
240
241        return TRUE;
242    }
243
244    /**
245     * Persists any deferred cache items.
246     *
247     * @return bool
248     *   True if all not-yet-saved items were successfully saved or there were none. False otherwise.
249     */
250    public function commit(): bool
251    {
252        if (empty($this->deferred))
253        {
254            return TRUE;
255        }
256
257        $result = TRUE;
258
259        foreach($this->deferred as $item)
260        {
261            $result = $result && $this->save($item);
262        }
263
264        if ($result === TRUE)
265        {
266            $this->deferred = [];
267        }
268
269        return $result;
270    }
271}