LICENSE 0000644 00000002051 14051141442 0005543 0 ustar 00 Copyright (c) 2006-2015 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
README.md 0000644 00000001617 14051141442 0006024 0 ustar 00 # Doctrine Cache
[![Build Status](https://github.com/doctrine/cache/workflows/Continuous%20Integration/badge.svg)](https://github.com/doctrine/cache/actions)
[![Code Coverage](https://codecov.io/gh/doctrine/cache/branch/1.10.x/graph/badge.svg)](https://codecov.io/gh/doctrine/cache/branch/1.10.x)
[![Latest Stable Version](https://img.shields.io/packagist/v/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache)
[![Total Downloads](https://img.shields.io/packagist/dt/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache)
Cache component extracted from the Doctrine Common project. [Documentation](https://www.doctrine-project.org/projects/doctrine-cache/en/current/index.html)
This library is deprecated and will no longer receive bug fixes from the
Doctrine Project. Please use a different cache library, preferably PSR-6 or
PSR-16 instead.
UPGRADE-1.11.md 0000644 00000001537 14051141442 0006535 0 ustar 00 # Upgrade to 1.11
doctrine/cache will no longer be maintained and all cache implementations have
been marked as deprecated. These implementations will be removed in 2.0, which
will only contain interfaces to provide a lightweight package for backward
compatibility.
There are two new classes to use in the `Doctrine\Common\Cache\Psr6` namespace:
* The `CacheAdapter` class allows using any Doctrine Cache as PSR-6 cache. This
is useful to provide a forward compatibility layer in libraries that accept
Doctrine cache implementations and switch to PSR-6.
* The `DoctrineProvider` class allows using any PSR-6 cache as Doctrine cache.
This implementation is designed for libraries that leak the cache and want to
switch to allowing PSR-6 implementations. This class is design to be used
during the transition phase of sunsetting doctrine/cache support.
UPGRADE-1.4.md 0000644 00000001326 14051141442 0006453 0 ustar 00 # Upgrade to 1.4
## Minor BC Break: `Doctrine\Common\Cache\FileCache#$extension` is now `private`.
If you need to override the value of `Doctrine\Common\Cache\FileCache#$extension`, then use the
second parameter of `Doctrine\Common\Cache\FileCache#__construct()` instead of overriding
the property in your own implementation.
## Minor BC Break: file based caches paths changed
`Doctrine\Common\Cache\FileCache`, `Doctrine\Common\Cache\PhpFileCache` and
`Doctrine\Common\Cache\FilesystemCache` are using a different cache paths structure.
If you rely on warmed up caches for deployments, consider that caches generated
with `doctrine/cache` `<1.4` are not compatible with the new directory structure,
and will be ignored.
composer.json 0000644 00000003235 14051141442 0007265 0 ustar 00 {
"name": "doctrine/cache",
"type": "library",
"description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
"keywords": [
"php",
"cache",
"caching",
"abstraction",
"redis",
"memcached",
"couchdb",
"xcache",
"apcu"
],
"homepage": "https://www.doctrine-project.org/projects/cache.html",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
],
"require": {
"php": "~7.1 || ^8.0"
},
"require-dev": {
"alcaeus/mongo-php-adapter": "^1.1",
"mongodb/mongodb": "^1.1",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"predis/predis": "~1.0",
"doctrine/coding-standard": "^8.0",
"psr/cache": "^1.0 || ^2.0",
"cache/integration-tests": "dev-master",
"symfony/cache": "^4.4 || ^5.2"
},
"suggest": {
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
},
"conflict": {
"doctrine/common": ">2.2,<2.4",
"psr/cache": ">=3"
},
"autoload": {
"psr-4": { "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" }
},
"autoload-dev": {
"psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" }
}
}
lib/Doctrine/Common/Cache/Cache.php 0000644 00000005357 14051141442 0013036 0 ustar 00 hits
* Number of keys that have been requested and found present.
*
* - misses
* Number of items that have been requested and not found.
*
* - uptime
* Time that the server is running.
*
* - memory_usage
* Memory used by this server to store items.
*
* - memory_available
* Memory allowed to use for storage.
*
* @return mixed[]|null An associative array with server's statistics if available, NULL otherwise.
*/
public function getStats();
}
lib/Doctrine/Common/Cache/CacheProvider.php 0000644 00000020433 14051141442 0014541 0 ustar 00 namespace = (string) $namespace;
$this->namespaceVersion = null;
}
/**
* Retrieves the namespace that prefixes all cache ids.
*
* @return string
*/
public function getNamespace()
{
return $this->namespace;
}
/**
* {@inheritdoc}
*/
public function fetch($id)
{
return $this->doFetch($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function fetchMultiple(array $keys)
{
if (empty($keys)) {
return [];
}
// note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys
$namespacedKeys = array_combine($keys, array_map([$this, 'getNamespacedId'], $keys));
$items = $this->doFetchMultiple($namespacedKeys);
$foundItems = [];
// no internal array function supports this sort of mapping: needs to be iterative
// this filters and combines keys in one pass
foreach ($namespacedKeys as $requestedKey => $namespacedKey) {
if (! isset($items[$namespacedKey]) && ! array_key_exists($namespacedKey, $items)) {
continue;
}
$foundItems[$requestedKey] = $items[$namespacedKey];
}
return $foundItems;
}
/**
* {@inheritdoc}
*/
public function saveMultiple(array $keysAndValues, $lifetime = 0)
{
$namespacedKeysAndValues = [];
foreach ($keysAndValues as $key => $value) {
$namespacedKeysAndValues[$this->getNamespacedId($key)] = $value;
}
return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime);
}
/**
* {@inheritdoc}
*/
public function contains($id)
{
return $this->doContains($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function save($id, $data, $lifeTime = 0)
{
return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
public function deleteMultiple(array $keys)
{
return $this->doDeleteMultiple(array_map([$this, 'getNamespacedId'], $keys));
}
/**
* {@inheritdoc}
*/
public function delete($id)
{
return $this->doDelete($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function getStats()
{
return $this->doGetStats();
}
/**
* {@inheritDoc}
*/
public function flushAll()
{
return $this->doFlush();
}
/**
* {@inheritDoc}
*/
public function deleteAll()
{
$namespaceCacheKey = $this->getNamespaceCacheKey();
$namespaceVersion = $this->getNamespaceVersion() + 1;
if ($this->doSave($namespaceCacheKey, $namespaceVersion)) {
$this->namespaceVersion = $namespaceVersion;
return true;
}
return false;
}
/**
* Prefixes the passed id with the configured namespace value.
*
* @param string $id The id to namespace.
*
* @return string The namespaced id.
*/
private function getNamespacedId(string $id): string
{
$namespaceVersion = $this->getNamespaceVersion();
return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
}
/**
* Returns the namespace cache key.
*/
private function getNamespaceCacheKey(): string
{
return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
}
/**
* Returns the namespace version.
*/
private function getNamespaceVersion(): int
{
if ($this->namespaceVersion !== null) {
return $this->namespaceVersion;
}
$namespaceCacheKey = $this->getNamespaceCacheKey();
$this->namespaceVersion = (int) $this->doFetch($namespaceCacheKey) ?: 1;
return $this->namespaceVersion;
}
/**
* Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it.
*
* @param string[] $keys Array of keys to retrieve from cache
*
* @return mixed[] Array of values retrieved for the given keys.
*/
protected function doFetchMultiple(array $keys)
{
$returnValues = [];
foreach ($keys as $key) {
$item = $this->doFetch($key);
if ($item === false && ! $this->doContains($key)) {
continue;
}
$returnValues[$key] = $item;
}
return $returnValues;
}
/**
* Fetches an entry from the cache.
*
* @param string $id The id of the cache entry to fetch.
*
* @return mixed|false The cached data or FALSE, if no cache entry exists for the given id.
*/
abstract protected function doFetch($id);
/**
* Tests if an entry exists in the cache.
*
* @param string $id The cache id of the entry to check for.
*
* @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
*/
abstract protected function doContains($id);
/**
* Default implementation of doSaveMultiple. Each driver that supports multi-put should override it.
*
* @param mixed[] $keysAndValues Array of keys and values to save in cache
* @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these
* cache entries (0 => infinite lifeTime).
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't.
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$success = true;
foreach ($keysAndValues as $key => $value) {
if ($this->doSave($key, $value, $lifetime)) {
continue;
}
$success = false;
}
return $success;
}
/**
* Puts data into the cache.
*
* @param string $id The cache id.
* @param string $data The cache entry/data.
* @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this
* cache entry (0 => infinite lifeTime).
*
* @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
*/
abstract protected function doSave($id, $data, $lifeTime = 0);
/**
* Default implementation of doDeleteMultiple. Each driver that supports multi-delete should override it.
*
* @param string[] $keys Array of keys to delete from cache
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't
*/
protected function doDeleteMultiple(array $keys)
{
$success = true;
foreach ($keys as $key) {
if ($this->doDelete($key)) {
continue;
}
$success = false;
}
return $success;
}
/**
* Deletes a cache entry.
*
* @param string $id The cache id.
*
* @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
*/
abstract protected function doDelete($id);
/**
* Flushes all cache entries.
*
* @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise.
*/
abstract protected function doFlush();
/**
* Retrieves cached information from the data store.
*
* @return mixed[]|null An associative array with server's statistics if available, NULL otherwise.
*/
abstract protected function doGetStats();
}
lib/Doctrine/Common/Cache/ClearableCache.php 0000644 00000000765 14051141442 0014627 0 ustar 00 infinite lifeTime).
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't.
*/
public function saveMultiple(array $keysAndValues, $lifetime = 0);
}
lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php 0000644 00000016413 14051141442 0015164 0 ustar 00 getPool();
}
if ($cache instanceof SymfonyDoctrineProvider) {
$getPool = function () {
// phpcs:ignore Squiz.Scope.StaticThisUsage.Found
return $this->pool;
};
return $getPool->bindTo($cache, SymfonyDoctrineProvider::class)();
}
return new self($cache);
}
private function __construct(Cache $cache)
{
$this->cache = $cache;
}
/** @internal */
public function getCache(): Cache
{
return $this->cache;
}
/**
* {@inheritDoc}
*/
public function getItem($key): CacheItemInterface
{
assert(self::validKey($key));
if (isset($this->deferredItems[$key])) {
$this->commit();
}
$value = $this->cache->fetch($key);
if ($value !== false) {
return new CacheItem($key, $value, true);
}
return new CacheItem($key, null, false);
}
/**
* {@inheritDoc}
*/
public function getItems(array $keys = []): array
{
if ($this->deferredItems) {
$this->commit();
}
assert(self::validKeys($keys));
$values = $this->doFetchMultiple($keys);
$items = [];
foreach ($keys as $key) {
if (array_key_exists($key, $values)) {
$items[$key] = new CacheItem($key, $values[$key], true);
} else {
$items[$key] = new CacheItem($key, null, false);
}
}
return $items;
}
/**
* {@inheritDoc}
*/
public function hasItem($key): bool
{
assert(self::validKey($key));
if (isset($this->deferredItems[$key])) {
$this->commit();
}
return $this->cache->contains($key);
}
public function clear(): bool
{
$this->deferredItems = [];
if (! $this->cache instanceof ClearableCache) {
return false;
}
return $this->cache->deleteAll();
}
/**
* {@inheritDoc}
*/
public function deleteItem($key): bool
{
assert(self::validKey($key));
unset($this->deferredItems[$key]);
return $this->cache->delete($key);
}
/**
* {@inheritDoc}
*/
public function deleteItems(array $keys): bool
{
foreach ($keys as $key) {
assert(self::validKey($key));
unset($this->deferredItems[$key]);
}
return $this->doDeleteMultiple($keys);
}
public function save(CacheItemInterface $item): bool
{
return $this->saveDeferred($item) && $this->commit();
}
public function saveDeferred(CacheItemInterface $item): bool
{
if (! $item instanceof CacheItem) {
return false;
}
$this->deferredItems[$item->getKey()] = $item;
return true;
}
public function commit(): bool
{
if (! $this->deferredItems) {
return true;
}
$now = microtime(true);
$itemsCount = 0;
$byLifetime = [];
$expiredKeys = [];
foreach ($this->deferredItems as $key => $item) {
$lifetime = ($item->getExpiry() ?? $now) - $now;
if ($lifetime < 0) {
$expiredKeys[] = $key;
continue;
}
++$itemsCount;
$byLifetime[(int) $lifetime][$key] = $item->get();
}
switch (count($expiredKeys)) {
case 0:
break;
case 1:
$this->cache->delete(current($expiredKeys));
break;
default:
$this->doDeleteMultiple($expiredKeys);
break;
}
if ($itemsCount === 1) {
return $this->cache->save($key, $item->get(), (int) $lifetime);
}
$success = true;
foreach ($byLifetime as $lifetime => $values) {
$success = $this->doSaveMultiple($values, $lifetime) && $success;
}
return $success;
}
public function __destruct()
{
$this->commit();
}
/**
* @param mixed $key
*/
private static function validKey($key): bool
{
if (! is_string($key)) {
throw new InvalidArgument(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
}
if ($key === '') {
throw new InvalidArgument('Cache key length must be greater than zero.');
}
if (strpbrk($key, self::RESERVED_CHARACTERS) !== false) {
throw new InvalidArgument(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS));
}
return true;
}
/**
* @param mixed[] $keys
*/
private static function validKeys(array $keys): bool
{
foreach ($keys as $key) {
self::validKey($key);
}
return true;
}
/**
* @param mixed[] $keys
*/
private function doDeleteMultiple(array $keys): bool
{
if ($this->cache instanceof MultiDeleteCache) {
return $this->cache->deleteMultiple($keys);
}
$success = true;
foreach ($keys as $key) {
$success = $this->cache->delete($key) && $success;
}
return $success;
}
/**
* @param mixed[] $keys
*
* @return mixed[]
*/
private function doFetchMultiple(array $keys): array
{
if ($this->cache instanceof MultiGetCache) {
return $this->cache->fetchMultiple($keys);
}
$values = [];
foreach ($keys as $key) {
$value = $this->cache->fetch($key);
if (! $value) {
continue;
}
$values[$key] = $value;
}
return $values;
}
/**
* @param mixed[] $keysAndValues
*/
private function doSaveMultiple(array $keysAndValues, int $lifetime = 0): bool
{
if ($this->cache instanceof MultiPutCache) {
return $this->cache->saveMultiple($keysAndValues, $lifetime);
}
$success = true;
foreach ($keysAndValues as $key => $value) {
$success = $this->cache->save($key, $value, $lifetime) && $success;
}
return $success;
}
}
lib/Doctrine/Common/Cache/Psr6/CacheItem.php 0000644 00000004752 14051141442 0014505 0 ustar 00 key = $key;
$this->value = $data;
$this->isHit = $isHit;
}
public function getKey(): string
{
return $this->key;
}
/**
* {@inheritDoc}
*/
public function get()
{
return $this->value;
}
public function isHit(): bool
{
return $this->isHit;
}
/**
* {@inheritDoc}
*/
public function set($value): self
{
$this->value = $value;
return $this;
}
/**
* {@inheritDoc}
*/
public function expiresAt($expiration): self
{
if ($expiration === null) {
$this->expiry = null;
} elseif ($expiration instanceof DateTimeInterface) {
$this->expiry = (float) $expiration->format('U.u');
} else {
throw new TypeError(sprintf(
'Expected $expiration to be an instance of DateTimeInterface or null, got %s',
is_object($expiration) ? get_class($expiration) : gettype($expiration)
));
}
return $this;
}
/**
* {@inheritDoc}
*/
public function expiresAfter($time): self
{
if ($time === null) {
$this->expiry = null;
} elseif ($time instanceof DateInterval) {
$this->expiry = microtime(true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
} elseif (is_int($time)) {
$this->expiry = $time + microtime(true);
} else {
throw new TypeError(sprintf(
'Expected $time to be either an integer, an instance of DateInterval or null, got %s',
is_object($time) ? get_class($time) : gettype($time)
));
}
return $this;
}
/**
* @internal
*/
public function getExpiry(): ?float
{
return $this->expiry;
}
}
lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php 0000644 00000005252 14051141442 0016141 0 ustar 00
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Doctrine\Common\Cache\Psr6;
use Doctrine\Common\Cache\CacheProvider;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\DoctrineAdapter as SymfonyDoctrineAdapter;
use function rawurlencode;
/**
* This class was copied from the Symfony Framework, see the original copyright
* notice above. The code is distributed subject to the license terms in
* https://github.com/symfony/symfony/blob/ff0cf61278982539c49e467db9ab13cbd342f76d/LICENSE
*/
final class DoctrineProvider extends CacheProvider
{
/** @var CacheItemPoolInterface */
private $pool;
public static function wrap(CacheItemPoolInterface $pool): CacheProvider
{
if ($pool instanceof CacheAdapter) {
return $pool->getCache();
}
if ($pool instanceof SymfonyDoctrineAdapter) {
$getCache = function () {
// phpcs:ignore Squiz.Scope.StaticThisUsage.Found
return $this->provider;
};
return $getCache->bindTo($pool, SymfonyDoctrineAdapter::class)();
}
return new self($pool);
}
private function __construct(CacheItemPoolInterface $pool)
{
$this->pool = $pool;
}
/** @internal */
public function getPool(): CacheItemPoolInterface
{
return $this->pool;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
$item = $this->pool->getItem(rawurlencode($id));
return $item->isHit() ? $item->get() : false;
}
/**
* {@inheritdoc}
*
* @return bool
*/
protected function doContains($id)
{
return $this->pool->hasItem(rawurlencode($id));
}
/**
* {@inheritdoc}
*
* @return bool
*/
protected function doSave($id, $data, $lifeTime = 0)
{
$item = $this->pool->getItem(rawurlencode($id));
if (0 < $lifeTime) {
$item->expiresAfter($lifeTime);
}
return $this->pool->save($item->set($data));
}
/**
* {@inheritdoc}
*
* @return bool
*/
protected function doDelete($id)
{
return $this->pool->deleteItem(rawurlencode($id));
}
/**
* {@inheritdoc}
*
* @return bool
*/
protected function doFlush()
{
return $this->pool->clear();
}
/**
* {@inheritdoc}
*
* @return array|null
*/
protected function doGetStats()
{
return null;
}
}
lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php 0000644 00000000421 14051141442 0015741 0 ustar 00