├── LICENSE
├── README.md
├── UPGRADE-1.11.md
├── UPGRADE-1.4.md
├── composer.json
└── lib
└── Doctrine
└── Common
└── Cache
├── Cache.php
├── CacheProvider.php
├── ClearableCache.php
├── FlushableCache.php
├── MultiDeleteCache.php
├── MultiGetCache.php
├── MultiOperationCache.php
├── MultiPutCache.php
└── Psr6
├── CacheAdapter.php
├── CacheItem.php
├── DoctrineProvider.php
├── InvalidArgument.php
└── TypedCacheItem.php
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2006-2015 Doctrine Project
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7 | of the Software, and to permit persons to whom the Software is furnished to do
8 | so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Doctrine Cache
2 |
3 | [](https://github.com/doctrine/cache/actions)
4 | [](https://codecov.io/gh/doctrine/cache/branch/1.10.x)
5 |
6 | [](https://packagist.org/packages/doctrine/cache)
7 | [](https://packagist.org/packages/doctrine/cache)
8 |
9 | Cache component extracted from the Doctrine Common project. [Documentation](https://www.doctrine-project.org/projects/doctrine-cache/en/current/index.html)
10 |
11 | This library is deprecated and will no longer receive bug fixes from the
12 | Doctrine Project. Please use a different cache library, preferably PSR-6 or
13 | PSR-16 instead.
14 |
--------------------------------------------------------------------------------
/UPGRADE-1.11.md:
--------------------------------------------------------------------------------
1 | # Upgrade to 1.11
2 |
3 | doctrine/cache will no longer be maintained and all cache implementations have
4 | been marked as deprecated. These implementations will be removed in 2.0, which
5 | will only contain interfaces to provide a lightweight package for backward
6 | compatibility.
7 |
8 | There are two new classes to use in the `Doctrine\Common\Cache\Psr6` namespace:
9 | * The `CacheAdapter` class allows using any Doctrine Cache as PSR-6 cache. This
10 | is useful to provide a forward compatibility layer in libraries that accept
11 | Doctrine cache implementations and switch to PSR-6.
12 | * The `DoctrineProvider` class allows using any PSR-6 cache as Doctrine cache.
13 | This implementation is designed for libraries that leak the cache and want to
14 | switch to allowing PSR-6 implementations. This class is design to be used
15 | during the transition phase of sunsetting doctrine/cache support.
16 |
17 | A full example to setup a filesystem based PSR-6 cache with symfony/cache
18 | using the `DoctrineProvider` to convert back to Doctrine's `Cache` interface:
19 |
20 | ```php
21 | use Doctrine\Common\Cache\Psr6\DoctrineProvider;
22 | use Symfony\Component\Cache\Adapter\FilesystemAdapter;
23 |
24 | $cachePool = new FilesystemAdapter();
25 | $cache = DoctrineProvider::wrap($cachePool);
26 | // $cache instanceof \Doctrine\Common\Cache\Cache
27 | ```
28 |
--------------------------------------------------------------------------------
/UPGRADE-1.4.md:
--------------------------------------------------------------------------------
1 | # Upgrade to 1.4
2 |
3 | ## Minor BC Break: `Doctrine\Common\Cache\FileCache#$extension` is now `private`.
4 |
5 | If you need to override the value of `Doctrine\Common\Cache\FileCache#$extension`, then use the
6 | second parameter of `Doctrine\Common\Cache\FileCache#__construct()` instead of overriding
7 | the property in your own implementation.
8 |
9 | ## Minor BC Break: file based caches paths changed
10 |
11 | `Doctrine\Common\Cache\FileCache`, `Doctrine\Common\Cache\PhpFileCache` and
12 | `Doctrine\Common\Cache\FilesystemCache` are using a different cache paths structure.
13 |
14 | If you rely on warmed up caches for deployments, consider that caches generated
15 | with `doctrine/cache` `<1.4` are not compatible with the new directory structure,
16 | and will be ignored.
17 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "doctrine/cache",
3 | "type": "library",
4 | "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
5 | "keywords": [
6 | "php",
7 | "cache",
8 | "caching",
9 | "abstraction",
10 | "redis",
11 | "memcached",
12 | "couchdb",
13 | "xcache",
14 | "apcu"
15 | ],
16 | "homepage": "https://www.doctrine-project.org/projects/cache.html",
17 | "license": "MIT",
18 | "authors": [
19 | {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
20 | {"name": "Roman Borschel", "email": "roman@code-factory.org"},
21 | {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
22 | {"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
23 | {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
24 | ],
25 | "require": {
26 | "php": "~7.1 || ^8.0"
27 | },
28 | "require-dev": {
29 | "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
30 | "doctrine/coding-standard": "^9",
31 | "psr/cache": "^1.0 || ^2.0 || ^3.0",
32 | "cache/integration-tests": "dev-master",
33 | "symfony/cache": "^4.4 || ^5.4 || ^6",
34 | "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
35 | },
36 | "conflict": {
37 | "doctrine/common": ">2.2,<2.4"
38 | },
39 | "autoload": {
40 | "psr-4": { "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" }
41 | },
42 | "autoload-dev": {
43 | "psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" }
44 | },
45 | "config": {
46 | "allow-plugins": {
47 | "dealerdirect/phpcodesniffer-composer-installer": true
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/lib/Doctrine/Common/Cache/Cache.php:
--------------------------------------------------------------------------------
1 | hits
73 | * Number of keys that have been requested and found present.
74 | *
75 | * - misses
76 | * Number of items that have been requested and not found.
77 | *
78 | * - uptime
79 | * Time that the server is running.
80 | *
81 | * - memory_usage
82 | * Memory used by this server to store items.
83 | *
84 | * - memory_available
85 | * Memory allowed to use for storage.
86 | *
87 | * @return mixed[]|null An associative array with server's statistics if available, NULL otherwise.
88 | */
89 | public function getStats();
90 | }
91 |
--------------------------------------------------------------------------------
/lib/Doctrine/Common/Cache/CacheProvider.php:
--------------------------------------------------------------------------------
1 | namespace = (string) $namespace;
41 | $this->namespaceVersion = null;
42 | }
43 |
44 | /**
45 | * Retrieves the namespace that prefixes all cache ids.
46 | *
47 | * @return string
48 | */
49 | public function getNamespace()
50 | {
51 | return $this->namespace;
52 | }
53 |
54 | /**
55 | * {@inheritdoc}
56 | */
57 | public function fetch($id)
58 | {
59 | return $this->doFetch($this->getNamespacedId($id));
60 | }
61 |
62 | /**
63 | * {@inheritdoc}
64 | */
65 | public function fetchMultiple(array $keys)
66 | {
67 | if (empty($keys)) {
68 | return [];
69 | }
70 |
71 | // note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys
72 | $namespacedKeys = array_combine($keys, array_map([$this, 'getNamespacedId'], $keys));
73 | $items = $this->doFetchMultiple($namespacedKeys);
74 | $foundItems = [];
75 |
76 | // no internal array function supports this sort of mapping: needs to be iterative
77 | // this filters and combines keys in one pass
78 | foreach ($namespacedKeys as $requestedKey => $namespacedKey) {
79 | if (! isset($items[$namespacedKey]) && ! array_key_exists($namespacedKey, $items)) {
80 | continue;
81 | }
82 |
83 | $foundItems[$requestedKey] = $items[$namespacedKey];
84 | }
85 |
86 | return $foundItems;
87 | }
88 |
89 | /**
90 | * {@inheritdoc}
91 | */
92 | public function saveMultiple(array $keysAndValues, $lifetime = 0)
93 | {
94 | $namespacedKeysAndValues = [];
95 | foreach ($keysAndValues as $key => $value) {
96 | $namespacedKeysAndValues[$this->getNamespacedId($key)] = $value;
97 | }
98 |
99 | return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime);
100 | }
101 |
102 | /**
103 | * {@inheritdoc}
104 | */
105 | public function contains($id)
106 | {
107 | return $this->doContains($this->getNamespacedId($id));
108 | }
109 |
110 | /**
111 | * {@inheritdoc}
112 | */
113 | public function save($id, $data, $lifeTime = 0)
114 | {
115 | return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
116 | }
117 |
118 | /**
119 | * {@inheritdoc}
120 | */
121 | public function deleteMultiple(array $keys)
122 | {
123 | return $this->doDeleteMultiple(array_map([$this, 'getNamespacedId'], $keys));
124 | }
125 |
126 | /**
127 | * {@inheritdoc}
128 | */
129 | public function delete($id)
130 | {
131 | return $this->doDelete($this->getNamespacedId($id));
132 | }
133 |
134 | /**
135 | * {@inheritdoc}
136 | */
137 | public function getStats()
138 | {
139 | return $this->doGetStats();
140 | }
141 |
142 | /**
143 | * {@inheritDoc}
144 | */
145 | public function flushAll()
146 | {
147 | return $this->doFlush();
148 | }
149 |
150 | /**
151 | * {@inheritDoc}
152 | */
153 | public function deleteAll()
154 | {
155 | $namespaceCacheKey = $this->getNamespaceCacheKey();
156 | $namespaceVersion = $this->getNamespaceVersion() + 1;
157 |
158 | if ($this->doSave($namespaceCacheKey, $namespaceVersion)) {
159 | $this->namespaceVersion = $namespaceVersion;
160 |
161 | return true;
162 | }
163 |
164 | return false;
165 | }
166 |
167 | /**
168 | * Prefixes the passed id with the configured namespace value.
169 | *
170 | * @param string $id The id to namespace.
171 | *
172 | * @return string The namespaced id.
173 | */
174 | private function getNamespacedId(string $id): string
175 | {
176 | $namespaceVersion = $this->getNamespaceVersion();
177 |
178 | return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
179 | }
180 |
181 | /**
182 | * Returns the namespace cache key.
183 | */
184 | private function getNamespaceCacheKey(): string
185 | {
186 | return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
187 | }
188 |
189 | /**
190 | * Returns the namespace version.
191 | */
192 | private function getNamespaceVersion(): int
193 | {
194 | if ($this->namespaceVersion !== null) {
195 | return $this->namespaceVersion;
196 | }
197 |
198 | $namespaceCacheKey = $this->getNamespaceCacheKey();
199 | $this->namespaceVersion = (int) $this->doFetch($namespaceCacheKey) ?: 1;
200 |
201 | return $this->namespaceVersion;
202 | }
203 |
204 | /**
205 | * Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it.
206 | *
207 | * @param string[] $keys Array of keys to retrieve from cache
208 | *
209 | * @return mixed[] Array of values retrieved for the given keys.
210 | */
211 | protected function doFetchMultiple(array $keys)
212 | {
213 | $returnValues = [];
214 |
215 | foreach ($keys as $key) {
216 | $item = $this->doFetch($key);
217 | if ($item === false && ! $this->doContains($key)) {
218 | continue;
219 | }
220 |
221 | $returnValues[$key] = $item;
222 | }
223 |
224 | return $returnValues;
225 | }
226 |
227 | /**
228 | * Fetches an entry from the cache.
229 | *
230 | * @param string $id The id of the cache entry to fetch.
231 | *
232 | * @return mixed|false The cached data or FALSE, if no cache entry exists for the given id.
233 | */
234 | abstract protected function doFetch($id);
235 |
236 | /**
237 | * Tests if an entry exists in the cache.
238 | *
239 | * @param string $id The cache id of the entry to check for.
240 | *
241 | * @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
242 | */
243 | abstract protected function doContains($id);
244 |
245 | /**
246 | * Default implementation of doSaveMultiple. Each driver that supports multi-put should override it.
247 | *
248 | * @param mixed[] $keysAndValues Array of keys and values to save in cache
249 | * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these
250 | * cache entries (0 => infinite lifeTime).
251 | *
252 | * @return bool TRUE if the operation was successful, FALSE if it wasn't.
253 | */
254 | protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
255 | {
256 | $success = true;
257 |
258 | foreach ($keysAndValues as $key => $value) {
259 | if ($this->doSave($key, $value, $lifetime)) {
260 | continue;
261 | }
262 |
263 | $success = false;
264 | }
265 |
266 | return $success;
267 | }
268 |
269 | /**
270 | * Puts data into the cache.
271 | *
272 | * @param string $id The cache id.
273 | * @param string $data The cache entry/data.
274 | * @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this
275 | * cache entry (0 => infinite lifeTime).
276 | *
277 | * @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
278 | */
279 | abstract protected function doSave($id, $data, $lifeTime = 0);
280 |
281 | /**
282 | * Default implementation of doDeleteMultiple. Each driver that supports multi-delete should override it.
283 | *
284 | * @param string[] $keys Array of keys to delete from cache
285 | *
286 | * @return bool TRUE if the operation was successful, FALSE if it wasn't
287 | */
288 | protected function doDeleteMultiple(array $keys)
289 | {
290 | $success = true;
291 |
292 | foreach ($keys as $key) {
293 | if ($this->doDelete($key)) {
294 | continue;
295 | }
296 |
297 | $success = false;
298 | }
299 |
300 | return $success;
301 | }
302 |
303 | /**
304 | * Deletes a cache entry.
305 | *
306 | * @param string $id The cache id.
307 | *
308 | * @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
309 | */
310 | abstract protected function doDelete($id);
311 |
312 | /**
313 | * Flushes all cache entries.
314 | *
315 | * @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise.
316 | */
317 | abstract protected function doFlush();
318 |
319 | /**
320 | * Retrieves cached information from the data store.
321 | *
322 | * @return mixed[]|null An associative array with server's statistics if available, NULL otherwise.
323 | */
324 | abstract protected function doGetStats();
325 | }
326 |
--------------------------------------------------------------------------------
/lib/Doctrine/Common/Cache/ClearableCache.php:
--------------------------------------------------------------------------------
1 | infinite lifeTime).
20 | *
21 | * @return bool TRUE if the operation was successful, FALSE if it wasn't.
22 | */
23 | public function saveMultiple(array $keysAndValues, $lifetime = 0);
24 | }
25 |
--------------------------------------------------------------------------------
/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php:
--------------------------------------------------------------------------------
1 | */
36 | private $deferredItems = [];
37 |
38 | public static function wrap(Cache $cache): CacheItemPoolInterface
39 | {
40 | if ($cache instanceof DoctrineProvider && ! $cache->getNamespace()) {
41 | return $cache->getPool();
42 | }
43 |
44 | if ($cache instanceof SymfonyDoctrineProvider && ! $cache->getNamespace()) {
45 | $getPool = function () {
46 | // phpcs:ignore Squiz.Scope.StaticThisUsage.Found
47 | return $this->pool;
48 | };
49 |
50 | return $getPool->bindTo($cache, SymfonyDoctrineProvider::class)();
51 | }
52 |
53 | return new self($cache);
54 | }
55 |
56 | private function __construct(Cache $cache)
57 | {
58 | $this->cache = $cache;
59 | }
60 |
61 | /** @internal */
62 | public function getCache(): Cache
63 | {
64 | return $this->cache;
65 | }
66 |
67 | /**
68 | * {@inheritDoc}
69 | */
70 | public function getItem($key): CacheItemInterface
71 | {
72 | assert(self::validKey($key));
73 |
74 | if (isset($this->deferredItems[$key])) {
75 | $this->commit();
76 | }
77 |
78 | $value = $this->cache->fetch($key);
79 |
80 | if (PHP_VERSION_ID >= 80000) {
81 | if ($value !== false) {
82 | return new TypedCacheItem($key, $value, true);
83 | }
84 |
85 | return new TypedCacheItem($key, null, false);
86 | }
87 |
88 | if ($value !== false) {
89 | return new CacheItem($key, $value, true);
90 | }
91 |
92 | return new CacheItem($key, null, false);
93 | }
94 |
95 | /**
96 | * {@inheritDoc}
97 | */
98 | public function getItems(array $keys = []): array
99 | {
100 | if ($this->deferredItems) {
101 | $this->commit();
102 | }
103 |
104 | assert(self::validKeys($keys));
105 |
106 | $values = $this->doFetchMultiple($keys);
107 | $items = [];
108 |
109 | if (PHP_VERSION_ID >= 80000) {
110 | foreach ($keys as $key) {
111 | if (array_key_exists($key, $values)) {
112 | $items[$key] = new TypedCacheItem($key, $values[$key], true);
113 | } else {
114 | $items[$key] = new TypedCacheItem($key, null, false);
115 | }
116 | }
117 |
118 | return $items;
119 | }
120 |
121 | foreach ($keys as $key) {
122 | if (array_key_exists($key, $values)) {
123 | $items[$key] = new CacheItem($key, $values[$key], true);
124 | } else {
125 | $items[$key] = new CacheItem($key, null, false);
126 | }
127 | }
128 |
129 | return $items;
130 | }
131 |
132 | /**
133 | * {@inheritDoc}
134 | */
135 | public function hasItem($key): bool
136 | {
137 | assert(self::validKey($key));
138 |
139 | if (isset($this->deferredItems[$key])) {
140 | $this->commit();
141 | }
142 |
143 | return $this->cache->contains($key);
144 | }
145 |
146 | public function clear(): bool
147 | {
148 | $this->deferredItems = [];
149 |
150 | if (! $this->cache instanceof ClearableCache) {
151 | return false;
152 | }
153 |
154 | return $this->cache->deleteAll();
155 | }
156 |
157 | /**
158 | * {@inheritDoc}
159 | */
160 | public function deleteItem($key): bool
161 | {
162 | assert(self::validKey($key));
163 | unset($this->deferredItems[$key]);
164 |
165 | return $this->cache->delete($key);
166 | }
167 |
168 | /**
169 | * {@inheritDoc}
170 | */
171 | public function deleteItems(array $keys): bool
172 | {
173 | foreach ($keys as $key) {
174 | assert(self::validKey($key));
175 | unset($this->deferredItems[$key]);
176 | }
177 |
178 | return $this->doDeleteMultiple($keys);
179 | }
180 |
181 | public function save(CacheItemInterface $item): bool
182 | {
183 | return $this->saveDeferred($item) && $this->commit();
184 | }
185 |
186 | public function saveDeferred(CacheItemInterface $item): bool
187 | {
188 | if (! $item instanceof CacheItem && ! $item instanceof TypedCacheItem) {
189 | return false;
190 | }
191 |
192 | $this->deferredItems[$item->getKey()] = $item;
193 |
194 | return true;
195 | }
196 |
197 | public function commit(): bool
198 | {
199 | if (! $this->deferredItems) {
200 | return true;
201 | }
202 |
203 | $now = microtime(true);
204 | $itemsCount = 0;
205 | $byLifetime = [];
206 | $expiredKeys = [];
207 |
208 | foreach ($this->deferredItems as $key => $item) {
209 | $lifetime = ($item->getExpiry() ?? $now) - $now;
210 |
211 | if ($lifetime < 0) {
212 | $expiredKeys[] = $key;
213 |
214 | continue;
215 | }
216 |
217 | ++$itemsCount;
218 | $byLifetime[(int) $lifetime][$key] = $item->get();
219 | }
220 |
221 | $this->deferredItems = [];
222 |
223 | switch (count($expiredKeys)) {
224 | case 0:
225 | break;
226 | case 1:
227 | $this->cache->delete(current($expiredKeys));
228 | break;
229 | default:
230 | $this->doDeleteMultiple($expiredKeys);
231 | break;
232 | }
233 |
234 | if ($itemsCount === 1) {
235 | return $this->cache->save($key, $item->get(), (int) $lifetime);
236 | }
237 |
238 | $success = true;
239 | foreach ($byLifetime as $lifetime => $values) {
240 | $success = $this->doSaveMultiple($values, $lifetime) && $success;
241 | }
242 |
243 | return $success;
244 | }
245 |
246 | public function __destruct()
247 | {
248 | $this->commit();
249 | }
250 |
251 | /**
252 | * @param mixed $key
253 | */
254 | private static function validKey($key): bool
255 | {
256 | if (! is_string($key)) {
257 | throw new InvalidArgument(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
258 | }
259 |
260 | if ($key === '') {
261 | throw new InvalidArgument('Cache key length must be greater than zero.');
262 | }
263 |
264 | if (strpbrk($key, self::RESERVED_CHARACTERS) !== false) {
265 | throw new InvalidArgument(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS));
266 | }
267 |
268 | return true;
269 | }
270 |
271 | /**
272 | * @param mixed[] $keys
273 | */
274 | private static function validKeys(array $keys): bool
275 | {
276 | foreach ($keys as $key) {
277 | self::validKey($key);
278 | }
279 |
280 | return true;
281 | }
282 |
283 | /**
284 | * @param mixed[] $keys
285 | */
286 | private function doDeleteMultiple(array $keys): bool
287 | {
288 | if ($this->cache instanceof MultiDeleteCache) {
289 | return $this->cache->deleteMultiple($keys);
290 | }
291 |
292 | $success = true;
293 | foreach ($keys as $key) {
294 | $success = $this->cache->delete($key) && $success;
295 | }
296 |
297 | return $success;
298 | }
299 |
300 | /**
301 | * @param mixed[] $keys
302 | *
303 | * @return mixed[]
304 | */
305 | private function doFetchMultiple(array $keys): array
306 | {
307 | if ($this->cache instanceof MultiGetCache) {
308 | return $this->cache->fetchMultiple($keys);
309 | }
310 |
311 | $values = [];
312 | foreach ($keys as $key) {
313 | $value = $this->cache->fetch($key);
314 | if (! $value) {
315 | continue;
316 | }
317 |
318 | $values[$key] = $value;
319 | }
320 |
321 | return $values;
322 | }
323 |
324 | /**
325 | * @param mixed[] $keysAndValues
326 | */
327 | private function doSaveMultiple(array $keysAndValues, int $lifetime = 0): bool
328 | {
329 | if ($this->cache instanceof MultiPutCache) {
330 | return $this->cache->saveMultiple($keysAndValues, $lifetime);
331 | }
332 |
333 | $success = true;
334 | foreach ($keysAndValues as $key => $value) {
335 | $success = $this->cache->save($key, $value, $lifetime) && $success;
336 | }
337 |
338 | return $success;
339 | }
340 | }
341 |
--------------------------------------------------------------------------------
/lib/Doctrine/Common/Cache/Psr6/CacheItem.php:
--------------------------------------------------------------------------------
1 | key = $key;
37 | $this->value = $data;
38 | $this->isHit = $isHit;
39 | }
40 |
41 | public function getKey(): string
42 | {
43 | return $this->key;
44 | }
45 |
46 | /**
47 | * {@inheritDoc}
48 | *
49 | * @return mixed
50 | */
51 | public function get()
52 | {
53 | return $this->value;
54 | }
55 |
56 | public function isHit(): bool
57 | {
58 | return $this->isHit;
59 | }
60 |
61 | /**
62 | * {@inheritDoc}
63 | */
64 | public function set($value): self
65 | {
66 | $this->value = $value;
67 |
68 | return $this;
69 | }
70 |
71 | /**
72 | * {@inheritDoc}
73 | */
74 | public function expiresAt($expiration): self
75 | {
76 | if ($expiration === null) {
77 | $this->expiry = null;
78 | } elseif ($expiration instanceof DateTimeInterface) {
79 | $this->expiry = (float) $expiration->format('U.u');
80 | } else {
81 | throw new TypeError(sprintf(
82 | 'Expected $expiration to be an instance of DateTimeInterface or null, got %s',
83 | is_object($expiration) ? get_class($expiration) : gettype($expiration)
84 | ));
85 | }
86 |
87 | return $this;
88 | }
89 |
90 | /**
91 | * {@inheritDoc}
92 | */
93 | public function expiresAfter($time): self
94 | {
95 | if ($time === null) {
96 | $this->expiry = null;
97 | } elseif ($time instanceof DateInterval) {
98 | $this->expiry = microtime(true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
99 | } elseif (is_int($time)) {
100 | $this->expiry = $time + microtime(true);
101 | } else {
102 | throw new TypeError(sprintf(
103 | 'Expected $time to be either an integer, an instance of DateInterval or null, got %s',
104 | is_object($time) ? get_class($time) : gettype($time)
105 | ));
106 | }
107 |
108 | return $this;
109 | }
110 |
111 | /**
112 | * @internal
113 | */
114 | public function getExpiry(): ?float
115 | {
116 | return $this->expiry;
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace Doctrine\Common\Cache\Psr6;
13 |
14 | use Doctrine\Common\Cache\Cache;
15 | use Doctrine\Common\Cache\CacheProvider;
16 | use Psr\Cache\CacheItemPoolInterface;
17 | use Symfony\Component\Cache\Adapter\DoctrineAdapter as SymfonyDoctrineAdapter;
18 | use Symfony\Contracts\Service\ResetInterface;
19 |
20 | use function rawurlencode;
21 |
22 | /**
23 | * This class was copied from the Symfony Framework, see the original copyright
24 | * notice above. The code is distributed subject to the license terms in
25 | * https://github.com/symfony/symfony/blob/ff0cf61278982539c49e467db9ab13cbd342f76d/LICENSE
26 | */
27 | final class DoctrineProvider extends CacheProvider
28 | {
29 | /** @var CacheItemPoolInterface */
30 | private $pool;
31 |
32 | public static function wrap(CacheItemPoolInterface $pool): Cache
33 | {
34 | if ($pool instanceof CacheAdapter) {
35 | return $pool->getCache();
36 | }
37 |
38 | if ($pool instanceof SymfonyDoctrineAdapter) {
39 | $getCache = function () {
40 | // phpcs:ignore Squiz.Scope.StaticThisUsage.Found
41 | return $this->provider;
42 | };
43 |
44 | return $getCache->bindTo($pool, SymfonyDoctrineAdapter::class)();
45 | }
46 |
47 | return new self($pool);
48 | }
49 |
50 | private function __construct(CacheItemPoolInterface $pool)
51 | {
52 | $this->pool = $pool;
53 | }
54 |
55 | /** @internal */
56 | public function getPool(): CacheItemPoolInterface
57 | {
58 | return $this->pool;
59 | }
60 |
61 | public function reset(): void
62 | {
63 | if ($this->pool instanceof ResetInterface) {
64 | $this->pool->reset();
65 | }
66 |
67 | $this->setNamespace($this->getNamespace());
68 | }
69 |
70 | /**
71 | * {@inheritdoc}
72 | */
73 | protected function doFetch($id)
74 | {
75 | $item = $this->pool->getItem(rawurlencode($id));
76 |
77 | return $item->isHit() ? $item->get() : false;
78 | }
79 |
80 | /**
81 | * {@inheritdoc}
82 | *
83 | * @return bool
84 | */
85 | protected function doContains($id)
86 | {
87 | return $this->pool->hasItem(rawurlencode($id));
88 | }
89 |
90 | /**
91 | * {@inheritdoc}
92 | *
93 | * @return bool
94 | */
95 | protected function doSave($id, $data, $lifeTime = 0)
96 | {
97 | $item = $this->pool->getItem(rawurlencode($id));
98 |
99 | if (0 < $lifeTime) {
100 | $item->expiresAfter($lifeTime);
101 | }
102 |
103 | return $this->pool->save($item->set($data));
104 | }
105 |
106 | /**
107 | * {@inheritdoc}
108 | *
109 | * @return bool
110 | */
111 | protected function doDelete($id)
112 | {
113 | return $this->pool->deleteItem(rawurlencode($id));
114 | }
115 |
116 | /**
117 | * {@inheritdoc}
118 | *
119 | * @return bool
120 | */
121 | protected function doFlush()
122 | {
123 | return $this->pool->clear();
124 | }
125 |
126 | /**
127 | * {@inheritdoc}
128 | *
129 | * @return array|null
130 | */
131 | protected function doGetStats()
132 | {
133 | return null;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php:
--------------------------------------------------------------------------------
1 | key;
33 | }
34 |
35 | public function get(): mixed
36 | {
37 | return $this->value;
38 | }
39 |
40 | public function isHit(): bool
41 | {
42 | return $this->isHit;
43 | }
44 |
45 | public function set(mixed $value): static
46 | {
47 | $this->value = $value;
48 |
49 | return $this;
50 | }
51 |
52 | /**
53 | * {@inheritDoc}
54 | */
55 | public function expiresAt($expiration): static
56 | {
57 | if ($expiration === null) {
58 | $this->expiry = null;
59 | } elseif ($expiration instanceof DateTimeInterface) {
60 | $this->expiry = (float) $expiration->format('U.u');
61 | } else {
62 | throw new TypeError(sprintf(
63 | 'Expected $expiration to be an instance of DateTimeInterface or null, got %s',
64 | get_debug_type($expiration)
65 | ));
66 | }
67 |
68 | return $this;
69 | }
70 |
71 | /**
72 | * {@inheritDoc}
73 | */
74 | public function expiresAfter($time): static
75 | {
76 | if ($time === null) {
77 | $this->expiry = null;
78 | } elseif ($time instanceof DateInterval) {
79 | $this->expiry = microtime(true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
80 | } elseif (is_int($time)) {
81 | $this->expiry = $time + microtime(true);
82 | } else {
83 | throw new TypeError(sprintf(
84 | 'Expected $time to be either an integer, an instance of DateInterval or null, got %s',
85 | get_debug_type($time)
86 | ));
87 | }
88 |
89 | return $this;
90 | }
91 |
92 | /**
93 | * @internal
94 | */
95 | public function getExpiry(): ?float
96 | {
97 | return $this->expiry;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------