Repository: doctrine/cache
Branch: 2.2.x
Commit: e0a9919443c1
Files: 38
Total size: 82.2 KB
Directory structure:
gitextract_4su6f833/
├── .doctrine-project.json
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ ├── coding-standards.yml
│ ├── continuous-integration.yml
│ └── release-on-milestone-closed.yml
├── .gitignore
├── LICENSE
├── README.md
├── UPGRADE-1.11.md
├── UPGRADE-1.4.md
├── build.properties
├── build.xml
├── composer.json
├── docs/
│ └── en/
│ └── index.rst
├── 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
├── phpcs.xml.dist
├── phpunit.xml.dist
└── tests/
├── Doctrine/
│ └── Tests/
│ ├── Common/
│ │ └── Cache/
│ │ ├── ArrayCache.php
│ │ ├── ArrayCacheTest.php
│ │ ├── CacheProviderTest.php
│ │ ├── CacheTest.php
│ │ └── Psr6/
│ │ ├── CacheAdapterTest.php
│ │ └── DoctrineProviderTest.php
│ └── DoctrineTestCase.php
└── travis/
└── php.ini
================================================
FILE CONTENTS
================================================
================================================
FILE: .doctrine-project.json
================================================
{
"active": false,
"name": "Cache",
"slug": "cache",
"docsSlug": "doctrine-cache",
"versions": [
{
"name": "2.2",
"branchName": "2.2.x",
"slug": "2.2",
"current": true
},
{
"name": "2.1",
"branchName": "2.1.x",
"slug": "2.1",
"maintained": false
},
{
"name": "2.0",
"branchName": "2.0.x",
"slug": "2.0",
"maintained": false
},
{
"name": "1.13",
"branchName": "1.13.x",
"slug": "1.13",
"maintained": true
},
{
"name": "1.12",
"branchName": "1.12.x",
"slug": "1.12",
"maintained": false
},
{
"name": "1.11",
"branchName": "1.11.x",
"slug": "1.11",
"maintained": false
},
{
"name": "1.10",
"branchName": "1.10.x",
"slug": "1.10",
"maintained": false
},
{
"name": "1.9",
"branchName": "1.9.x",
"slug": "1.9",
"maintained": false
},
{
"name": "1.8",
"branchName": "1.8.x",
"slug": "1.8",
"maintained": false
}
]
}
================================================
FILE: .gitattributes
================================================
/docs export-ignore
/.github export-ignore
/tests export-ignore
.doctrine-project.json export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.scrutinizer.yml export-ignore
build.properties export-ignore
build.xml export-ignore
phpcs.xml.dist export-ignore
phpunit.xml.dist export-ignore
================================================
FILE: .github/FUNDING.yml
================================================
patreon: phpdoctrine
tidelift: packagist/doctrine%2Fcache
custom: https://www.doctrine-project.org/sponsorship.html
================================================
FILE: .github/workflows/coding-standards.yml
================================================
name: "Coding Standards"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
jobs:
coding-standards:
uses: "doctrine/.github/.github/workflows/coding-standards.yml@5.0.1"
================================================
FILE: .github/workflows/continuous-integration.yml
================================================
name: "Continuous Integration"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
env:
fail-fast: true
jobs:
phpunit:
name: "PHPUnit"
runs-on: "ubuntu-22.04"
strategy:
fail-fast: false
matrix:
php-version:
- "7.1"
- "7.2"
- "7.3"
- "7.4"
- "8.0"
- "8.1"
- "8.2"
- "8.3"
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
with:
fetch-depth: 2
- name: "Install PHP with XDebug"
uses: "shivammathur/setup-php@v2"
if: "${{ matrix.php-version == '7.1' }}"
with:
php-version: "${{ matrix.php-version }}"
coverage: "xdebug"
ini-values: "zend.assertions=1"
- name: "Install PHP with PCOV"
uses: "shivammathur/setup-php@v2"
if: "${{ matrix.php-version != '7.1' }}"
with:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
ini-values: "zend.assertions=1"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v3"
with:
dependency-versions: "${{ matrix.dependencies }}"
composer-options: "--prefer-dist --no-suggest"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit --coverage-clover=coverage.xml"
- name: "Upload coverage file"
uses: "actions/upload-artifact@v4"
with:
name: "phpunit-${{ matrix.php-version }}.coverage"
path: "coverage.xml"
upload_coverage:
name: "Upload coverage to Codecov"
runs-on: "ubuntu-22.04"
needs:
- "phpunit"
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
with:
fetch-depth: 2
- name: "Download coverage files"
uses: "actions/download-artifact@v4"
with:
path: "reports"
- name: "Upload to Codecov"
uses: "codecov/codecov-action@v4"
with:
directory: reports
================================================
FILE: .github/workflows/release-on-milestone-closed.yml
================================================
name: "Automatic Releases"
on:
milestone:
types:
- "closed"
jobs:
release:
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@5.0.1"
secrets:
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}
ORGANIZATION_ADMIN_TOKEN: ${{ secrets.ORGANIZATION_ADMIN_TOKEN }}
SIGNING_SECRET_KEY: ${{ secrets.SIGNING_SECRET_KEY }}
================================================
FILE: .gitignore
================================================
vendor/
/composer.lock
build/
phpunit.xml
/.phpunit.result.cache
clover.xml
.phpcs-cache
phpcs.xml
================================================
FILE: LICENSE
================================================
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.
================================================
FILE: README.md
================================================
# Doctrine Cache
[](https://github.com/doctrine/cache/actions)
[](https://codecov.io/gh/doctrine/cache/branch/1.10.x)
[](https://packagist.org/packages/doctrine/cache)
[](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.
================================================
FILE: UPGRADE-1.11.md
================================================
# 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.
A full example to setup a filesystem based PSR-6 cache with symfony/cache
using the `DoctrineProvider` to convert back to Doctrine's `Cache` interface:
```php
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cachePool = new FilesystemAdapter();
$cache = DoctrineProvider::wrap($cachePool);
// $cache instanceof \Doctrine\Common\Cache\Cache
```
================================================
FILE: UPGRADE-1.4.md
================================================
# 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.
================================================
FILE: build.properties
================================================
# Version class and file
project.version_class = Doctrine\\Common\\Cache\\Version
project.version_file = lib/Doctrine/Common/Cache/Version.php
================================================
FILE: build.xml
================================================
<?xml version="1.0"?>
<project name="DoctrineCommonCache" default="build" basedir=".">
<property file="build.properties" />
<target name="php">
<exec executable="which" outputproperty="php_executable">
<arg value="php" />
</exec>
</target>
<target name="prepare">
<mkdir dir="build" />
</target>
<target name="build" depends="check-git-checkout-clean,prepare,php,composer">
<exec executable="${php_executable}">
<arg value="build/composer.phar" />
<arg value="archive" />
<arg value="--dir=build" />
</exec>
</target>
<target name="composer" depends="php,composer-check,composer-download">
<exec executable="${php_executable}">
<arg value="build/composer.phar" />
<arg value="install" />
</exec>
</target>
<target name="composer-check" depends="prepare">
<available file="build/composer.phar" property="composer.present"/>
</target>
<target name="composer-download" unless="composer.present">
<exec executable="wget">
<arg value="-Obuild/composer.phar" />
<arg value="http://getcomposer.org/composer.phar" />
</exec>
</target>
<target name="make-release" depends="check-git-checkout-clean,prepare,php">
<replace file="${project.version_file}" token="-DEV" value="" failOnNoReplacements="true" />
<exec executable="git" failonerror="true" outputproperty="current_git_branch">
<arg value="rev-parse" />
<arg value="--abbrev-ref" />
<arg value="HEAD" />
</exec>
<exec executable="${php_executable}" outputproperty="doctrine.current_version" failonerror="true">
<arg value="-r" />
<arg value="require_once '${project.version_file}';echo ${project.version_class}::VERSION;" />
</exec>
<exec executable="${php_executable}" outputproperty="doctrine.next_version" failonerror="true">
<arg value="-r" />
<arg value="$parts = explode('.', str_ireplace(array('-DEV', '-ALPHA', '-BETA'), '', '${doctrine.current_version}'));
if (count($parts) != 3) {
throw new \InvalidArgumentException('Version is assumed in format x.y.z, ${doctrine.current_version} given');
}
$parts[2]++;
echo implode('.', $parts);
" />
</exec>
<git-commit file="${project.version_file}" message="Release ${doctrine.current_version}" />
<git-tag version="${doctrine.current_version}" />
<replace file="${project.version_file}" token="${doctrine.current_version}" value="${doctrine.next_version}-DEV" />
<git-commit file="${project.version_file}" message="Bump version to ${doctrine.next_version}" />
</target>
<target name="check-git-checkout-clean">
<exec executable="git" failonerror="true">
<arg value="diff-index" />
<arg value="--quiet" />
<arg value="HEAD" />
</exec>
</target>
<macrodef name="git-commit">
<attribute name="file" default="NOT SET"/>
<attribute name="message" default="NOT SET"/>
<sequential>
<exec executable="git">
<arg value="add" />
<arg value="@{file}" />
</exec>
<exec executable="git">
<arg value="commit" />
<arg value="-m" />
<arg value="@{message}" />
</exec>
</sequential>
</macrodef>
<macrodef name="git-tag">
<attribute name="version" default="NOT SET" />
<sequential>
<exec executable="git">
<arg value="tag" />
<arg value="-m" />
<arg value="v@{version}" />
<arg value="v@{version}" />
</exec>
</sequential>
</macrodef>
</project>
================================================
FILE: composer.json
================================================
{
"name": "doctrine/cache",
"abandoned": true,
"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": {
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"doctrine/coding-standard": "^9",
"psr/cache": "^1.0 || ^2.0 || ^3.0",
"cache/integration-tests": "dev-master",
"symfony/cache": "^4.4 || ^5.4 || ^6",
"symfony/var-exporter": "^4.4 || ^5.4 || ^6"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"autoload": {
"psr-4": { "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" }
},
"autoload-dev": {
"psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" }
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}
================================================
FILE: docs/en/index.rst
================================================
Deprecation Notice
==================
Please note that doctrine/cache is deprecated and no longer maintained. The last
version to include cache drivers is 1.11. The 2.x major release series only
provides the interfaces for libraries that need to maintain backward
compatibility. For all cache uses, we suggest relying on PSR-6 or PSR-16 instead
and using a cache library that supports those interfaces.
Introduction
============
Doctrine Cache is a library that provides an interface for caching data.
Here is what the ``Cache`` interface looks like.
.. code-block:: php
namespace Doctrine\Common\Cache;
interface Cache
{
public function fetch($id);
public function contains($id);
public function save($id, $data, $lifeTime = 0);
public function delete($id);
public function getStats();
}
Use with PSR-6
==============
If you are using the ``Cache`` interface in your application, then you need to
upgrade your application to use a PSR-6 cache library and wrap the PSR-6
``CacheItemPoolInterface`` into the
``Doctrine\Common\Cache\Psr6\DoctrineProvider`` wrapper:
.. code-block:: php
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
$cache = DoctrineProvider::wrap($psr6CachePool);
An implementation of the PSR-6 cache is provided by `"symfony/cache" library
<https://symfony.com/doc/current/components/cache.html>`_ for example, you can install it
via Composer with:
::
composer require symfony/cache
A full example to setup a filesystem based cache with symfony/cache then looks
like this:
.. code-block:: php
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cachePool = new FilesystemAdapter();
$cache = DoctrineProvider::wrap($cachePool);
// $cache instanceof \Doctrine\Common\Cache\Cache
================================================
FILE: lib/Doctrine/Common/Cache/Cache.php
================================================
<?php
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers.
*
* @link www.doctrine-project.org
*/
interface Cache
{
public const STATS_HITS = 'hits';
public const STATS_MISSES = 'misses';
public const STATS_UPTIME = 'uptime';
public const STATS_MEMORY_USAGE = 'memory_usage';
public const STATS_MEMORY_AVAILABLE = 'memory_available';
/**
* Only for backward compatibility (may be removed in next major release)
*
* @deprecated
*/
public const STATS_MEMORY_AVAILIABLE = 'memory_available';
/**
* Fetches an entry from the cache.
*
* @param string $id The id of the cache entry to fetch.
*
* @return mixed The cached data or FALSE, if no cache entry exists for the given id.
*/
public function fetch($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.
*/
public function contains($id);
/**
* Puts data into the cache.
*
* If a cache entry with the given id already exists, its data will be replaced.
*
* @param string $id The cache id.
* @param mixed $data The cache entry/data.
* @param int $lifeTime The lifetime in number of seconds for this cache entry.
* If zero (the default), the entry never expires (although it may be deleted from the cache
* to make place for other entries).
*
* @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
*/
public function save($id, $data, $lifeTime = 0);
/**
* Deletes a cache entry.
*
* @param string $id The cache id.
*
* @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
* Deleting a non-existing entry is considered successful.
*/
public function delete($id);
/**
* Retrieves cached information from the data store.
*
* The server's statistics array has the following values:
*
* - <b>hits</b>
* Number of keys that have been requested and found present.
*
* - <b>misses</b>
* Number of items that have been requested and not found.
*
* - <b>uptime</b>
* Time that the server is running.
*
* - <b>memory_usage</b>
* Memory used by this server to store items.
*
* - <b>memory_available</b>
* Memory allowed to use for storage.
*
* @return mixed[]|null An associative array with server's statistics if available, NULL otherwise.
*/
public function getStats();
}
================================================
FILE: lib/Doctrine/Common/Cache/CacheProvider.php
================================================
<?php
namespace Doctrine\Common\Cache;
use function array_combine;
use function array_key_exists;
use function array_map;
use function sprintf;
/**
* Base class for cache provider implementations.
*/
abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiOperationCache
{
public const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]';
/**
* The namespace to prefix all cache ids with.
*
* @var string
*/
private $namespace = '';
/**
* The namespace version.
*
* @var int|null
*/
private $namespaceVersion;
/**
* Sets the namespace to prefix all cache ids with.
*
* @param string $namespace
*
* @return void
*/
public function setNamespace($namespace)
{
$this->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();
}
================================================
FILE: lib/Doctrine/Common/Cache/ClearableCache.php
================================================
<?php
namespace Doctrine\Common\Cache;
/**
* Interface for cache that can be flushed.
*
* Intended to be used for partial clearing of a cache namespace. For a more
* global "flushing", see {@see FlushableCache}.
*
* @link www.doctrine-project.org
*/
interface ClearableCache
{
/**
* Deletes all cache entries in the current cache namespace.
*
* @return bool TRUE if the cache entries were successfully deleted, FALSE otherwise.
*/
public function deleteAll();
}
================================================
FILE: lib/Doctrine/Common/Cache/FlushableCache.php
================================================
<?php
namespace Doctrine\Common\Cache;
/**
* Interface for cache that can be flushed.
*
* @link www.doctrine-project.org
*/
interface FlushableCache
{
/**
* Flushes all cache entries, globally.
*
* @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise.
*/
public function flushAll();
}
================================================
FILE: lib/Doctrine/Common/Cache/MultiDeleteCache.php
================================================
<?php
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers that allows to put many items at once.
*
* @deprecated
*
* @link www.doctrine-project.org
*/
interface MultiDeleteCache
{
/**
* Deletes several cache entries.
*
* @param string[] $keys Array of keys to delete from cache
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't.
*/
public function deleteMultiple(array $keys);
}
================================================
FILE: lib/Doctrine/Common/Cache/MultiGetCache.php
================================================
<?php
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers that allows to get many items at once.
*
* @deprecated
*
* @link www.doctrine-project.org
*/
interface MultiGetCache
{
/**
* Returns an associative array of values for keys is found in cache.
*
* @param string[] $keys Array of keys to retrieve from cache
*
* @return mixed[] Array of retrieved values, indexed by the specified keys.
* Values that couldn't be retrieved are not contained in this array.
*/
public function fetchMultiple(array $keys);
}
================================================
FILE: lib/Doctrine/Common/Cache/MultiOperationCache.php
================================================
<?php
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers that supports multiple items manipulation.
*
* @link www.doctrine-project.org
*/
interface MultiOperationCache extends MultiGetCache, MultiDeleteCache, MultiPutCache
{
}
================================================
FILE: lib/Doctrine/Common/Cache/MultiPutCache.php
================================================
<?php
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers that allows to put many items at once.
*
* @deprecated
*
* @link www.doctrine-project.org
*/
interface MultiPutCache
{
/**
* Returns a boolean value indicating if the operation succeeded.
*
* @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.
*/
public function saveMultiple(array $keysAndValues, $lifetime = 0);
}
================================================
FILE: lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php
================================================
<?php
namespace Doctrine\Common\Cache\Psr6;
use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Cache\ClearableCache;
use Doctrine\Common\Cache\MultiDeleteCache;
use Doctrine\Common\Cache\MultiGetCache;
use Doctrine\Common\Cache\MultiPutCache;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\DoctrineProvider as SymfonyDoctrineProvider;
use function array_key_exists;
use function assert;
use function count;
use function current;
use function get_class;
use function gettype;
use function is_object;
use function is_string;
use function microtime;
use function sprintf;
use function strpbrk;
use const PHP_VERSION_ID;
final class CacheAdapter implements CacheItemPoolInterface
{
private const RESERVED_CHARACTERS = '{}()/\@:';
/** @var Cache */
private $cache;
/** @var array<CacheItem|TypedCacheItem> */
private $deferredItems = [];
public static function wrap(Cache $cache): CacheItemPoolInterface
{
if ($cache instanceof DoctrineProvider && ! $cache->getNamespace()) {
return $cache->getPool();
}
if ($cache instanceof SymfonyDoctrineProvider && ! $cache->getNamespace()) {
$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 (PHP_VERSION_ID >= 80000) {
if ($value !== false) {
return new TypedCacheItem($key, $value, true);
}
return new TypedCacheItem($key, null, false);
}
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 = [];
if (PHP_VERSION_ID >= 80000) {
foreach ($keys as $key) {
if (array_key_exists($key, $values)) {
$items[$key] = new TypedCacheItem($key, $values[$key], true);
} else {
$items[$key] = new TypedCacheItem($key, null, false);
}
}
return $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 && ! $item instanceof TypedCacheItem) {
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();
}
$this->deferredItems = [];
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;
}
}
================================================
FILE: lib/Doctrine/Common/Cache/Psr6/CacheItem.php
================================================
<?php
namespace Doctrine\Common\Cache\Psr6;
use DateInterval;
use DateTime;
use DateTimeInterface;
use Psr\Cache\CacheItemInterface;
use TypeError;
use function get_class;
use function gettype;
use function is_int;
use function is_object;
use function microtime;
use function sprintf;
final class CacheItem implements CacheItemInterface
{
/** @var string */
private $key;
/** @var mixed */
private $value;
/** @var bool */
private $isHit;
/** @var float|null */
private $expiry;
/**
* @internal
*
* @param mixed $data
*/
public function __construct(string $key, $data, bool $isHit)
{
$this->key = $key;
$this->value = $data;
$this->isHit = $isHit;
}
public function getKey(): string
{
return $this->key;
}
/**
* {@inheritDoc}
*
* @return mixed
*/
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;
}
}
================================================
FILE: lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php
================================================
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\Cache;
use Doctrine\Common\Cache\CacheProvider;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\DoctrineAdapter as SymfonyDoctrineAdapter;
use Symfony\Contracts\Service\ResetInterface;
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): Cache
{
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;
}
public function reset(): void
{
if ($this->pool instanceof ResetInterface) {
$this->pool->reset();
}
$this->setNamespace($this->getNamespace());
}
/**
* {@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;
}
}
================================================
FILE: lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php
================================================
<?php
namespace Doctrine\Common\Cache\Psr6;
use InvalidArgumentException;
use Psr\Cache\InvalidArgumentException as PsrInvalidArgumentException;
/**
* @internal
*/
final class InvalidArgument extends InvalidArgumentException implements PsrInvalidArgumentException
{
}
================================================
FILE: lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php
================================================
<?php
namespace Doctrine\Common\Cache\Psr6;
use DateInterval;
use DateTime;
use DateTimeInterface;
use Psr\Cache\CacheItemInterface;
use TypeError;
use function get_debug_type;
use function is_int;
use function microtime;
use function sprintf;
final class TypedCacheItem implements CacheItemInterface
{
private ?float $expiry = null;
/**
* @internal
*/
public function __construct(
private string $key,
private mixed $value,
private bool $isHit,
) {
}
public function getKey(): string
{
return $this->key;
}
public function get(): mixed
{
return $this->value;
}
public function isHit(): bool
{
return $this->isHit;
}
public function set(mixed $value): static
{
$this->value = $value;
return $this;
}
/**
* {@inheritDoc}
*/
public function expiresAt($expiration): static
{
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',
get_debug_type($expiration)
));
}
return $this;
}
/**
* {@inheritDoc}
*/
public function expiresAfter($time): static
{
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',
get_debug_type($time)
));
}
return $this;
}
/**
* @internal
*/
public function getExpiry(): ?float
{
return $this->expiry;
}
}
================================================
FILE: phpcs.xml.dist
================================================
<?xml version="1.0"?>
<ruleset name="Coding Standards for doctrine">
<description>Coding Standards for doctrine.</description>
<arg name="basepath" value="."/>
<arg name="extensions" value="php"/>
<arg name="parallel" value="80"/>
<arg name="cache" value=".phpcs-cache"/>
<arg name="colors" />
<config name="php_version" value="70100"/>
<!-- Ignore warnings and show progress of the run -->
<arg value="np"/>
<file>lib</file>
<file>tests</file>
<rule ref="Doctrine">
<exclude name="SlevomatCodingStandard.TypeHints.DeclareStrictTypes"/>
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint"/>
<exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint"/>
<exclude name="SlevomatCodingStandard.Operators.DisallowEqualOperators"/>
<exclude name="SlevomatCodingStandard.Classes.DisallowLateStaticBindingForConstants" />
</rule>
<rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses">
<exclude-pattern>tests/Doctrine/Tests/Common/Cache/PhpFileCacheTest.php</exclude-pattern>
</rule>
<!-- Multiple classes confuse this rule -->
<rule ref="Squiz.Classes.ClassFileName">
<exclude-pattern>tests/Doctrine/Tests/Common/Cache/PhpFileCacheTest.php</exclude-pattern>
</rule>
</ruleset>
================================================
FILE: phpunit.xml.dist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
colors="true"
verbose="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutChangesToGlobalState="true"
>
<php>
<ini name="error_reporting" value="-1" />
</php>
<testsuites>
<testsuite name="Doctrine Cache Test Suite">
<directory>./tests/Doctrine/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./lib/Doctrine/</directory>
<exclude>
<file>lib/Doctrine/Common/Cache/ApcCache.php</file>
<file>lib/Doctrine/Common/Cache/CouchbaseCache.php</file>
<file>lib/Doctrine/Common/Cache/XcacheCache.php</file>
</exclude>
</whitelist>
</filter>
</phpunit>
================================================
FILE: tests/Doctrine/Tests/Common/Cache/ArrayCache.php
================================================
<?php
namespace Doctrine\Tests\Common\Cache;
use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Cache\CacheProvider;
use function time;
/**
* Array cache driver used for testing
*
* @internal
*/
class ArrayCache extends CacheProvider
{
/** @psalm-var array<string, array{mixed, int|bool}>> $data each element being a tuple of [$data, $expiration], where the expiration is int|bool */
private $data = [];
/** @var int */
private $hitsCount = 0;
/** @var int */
private $missesCount = 0;
/** @var int */
private $upTime;
/**
* {@inheritdoc}
*/
public function __construct()
{
$this->upTime = time();
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
if (! $this->doContains($id)) {
$this->missesCount += 1;
return false;
}
$this->hitsCount += 1;
return $this->data[$id][0];
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
if (! isset($this->data[$id])) {
return false;
}
$expiration = $this->data[$id][1];
if ($expiration && $expiration < time()) {
$this->doDelete($id);
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
$this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false];
return true;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
unset($this->data[$id]);
return true;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
$this->data = [];
return true;
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
return [
Cache::STATS_HITS => $this->hitsCount,
Cache::STATS_MISSES => $this->missesCount,
Cache::STATS_UPTIME => $this->upTime,
Cache::STATS_MEMORY_USAGE => null,
Cache::STATS_MEMORY_AVAILABLE => null,
];
}
}
================================================
FILE: tests/Doctrine/Tests/Common/Cache/ArrayCacheTest.php
================================================
<?php
namespace Doctrine\Tests\Common\Cache;
use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Cache\CacheProvider;
class ArrayCacheTest extends CacheTest
{
protected function getCacheDriver(): CacheProvider
{
return new ArrayCache();
}
public function testGetStats(): void
{
$cache = $this->getCacheDriver();
$cache->fetch('test1');
$cache->fetch('test2');
$cache->fetch('test3');
$cache->save('test1', 123);
$cache->save('test2', 123);
$cache->fetch('test1');
$cache->fetch('test2');
$cache->fetch('test3');
$stats = $cache->getStats();
self::assertEquals(2, $stats[Cache::STATS_HITS]);
self::assertEquals(5, $stats[Cache::STATS_MISSES]); // +1 for internal call to DoctrineNamespaceCacheKey
self::assertNotNull($stats[Cache::STATS_UPTIME]);
self::assertNull($stats[Cache::STATS_MEMORY_USAGE]);
self::assertNull($stats[Cache::STATS_MEMORY_AVAILABLE]);
$cache->delete('test1');
$cache->delete('test2');
$cache->fetch('test1');
$cache->fetch('test2');
$cache->fetch('test3');
$stats = $cache->getStats();
self::assertEquals(2, $stats[Cache::STATS_HITS]);
self::assertEquals(8, $stats[Cache::STATS_MISSES]); // +1 for internal call to DoctrineNamespaceCacheKey
}
protected function isSharedStorage(): bool
{
return false;
}
}
================================================
FILE: tests/Doctrine/Tests/Common/Cache/CacheProviderTest.php
================================================
<?php
namespace Doctrine\Tests\Common\Cache;
use Doctrine\Common\Cache\CacheProvider;
use Doctrine\Tests\DoctrineTestCase;
use PHPUnit_Framework_MockObject_MockObject;
use function assert;
class CacheProviderTest extends DoctrineTestCase
{
public function testFetchMultiWillFilterNonRequestedKeys(): void
{
$cache = $this->getMockForAbstractClass(
CacheProvider::class,
[],
'',
true,
true,
true,
['doFetchMultiple']
);
assert($cache instanceof CacheProvider || $cache instanceof PHPUnit_Framework_MockObject_MockObject);
$cache
->expects($this->once())
->method('doFetchMultiple')
->will($this->returnValue([
'[foo][1]' => 'bar',
'[bar][1]' => 'baz',
'[baz][1]' => 'tab',
]));
self::assertEquals(
['foo' => 'bar', 'bar' => 'baz'],
$cache->fetchMultiple(['foo', 'bar'])
);
}
public function testFailedDeleteAllDoesNotChangeNamespaceVersion(): void
{
$cache = $this->getMockForAbstractClass(
CacheProvider::class,
[],
'',
true,
true,
true,
['doFetch', 'doSave', 'doContains']
);
assert($cache instanceof CacheProvider || $cache instanceof PHPUnit_Framework_MockObject_MockObject);
$cache
->expects($this->once())
->method('doFetch')
->with('DoctrineNamespaceCacheKey[]')
->will($this->returnValue(false));
// doSave is only called once from deleteAll as we do not need to persist the default version in getNamespaceVersion()
$cache
->expects($this->once())
->method('doSave')
->with('DoctrineNamespaceCacheKey[]')
->will($this->returnValue(false));
// After a failed deleteAll() the local namespace version is not increased (still 1). Otherwise all data written afterwards
// would be lost outside the current instance.
$cache
->expects($this->once())
->method('doContains')
->with('[key][1]')
->will($this->returnValue(true));
self::assertFalse($cache->deleteAll(), 'deleteAll() returns false when saving the namespace version fails');
$cache->contains('key');
}
public function testSaveMultipleNoFail(): void
{
$cache = $this->getMockForAbstractClass(
CacheProvider::class,
[],
'',
true,
true,
true,
['doSave']
);
assert($cache instanceof CacheProvider || $cache instanceof PHPUnit_Framework_MockObject_MockObject);
$cache
->expects($this->at(1))
->method('doSave')
->with('[kerr][1]', 'verr', 0)
->will($this->returnValue(false));
$cache
->expects($this->at(2))
->method('doSave')
->with('[kok][1]', 'vok', 0)
->will($this->returnValue(true));
$cache->saveMultiple([
'kerr' => 'verr',
'kok' => 'vok',
]);
}
public function testDeleteMultipleNoFail(): void
{
$cache = $this
->getMockBuilder(CacheProvider::class)
->setMethods(['doDelete'])
->getMockForAbstractClass();
assert($cache instanceof CacheProvider || $cache instanceof PHPUnit_Framework_MockObject_MockObject);
$cache
->expects($this->at(1))
->method('doDelete')
->with('[kerr][1]')
->will($this->returnValue(false));
$cache
->expects($this->at(2))
->method('doDelete')
->with('[kok][1]')
->will($this->returnValue(true));
$cache->deleteMultiple(['kerr', 'kok']);
}
public function testInvalidNamespaceVersionCacheEntry(): void
{
$cache = $this->getMockForAbstractClass(CacheProvider::class);
assert($cache instanceof CacheProvider || $cache instanceof PHPUnit_Framework_MockObject_MockObject);
$cache->expects($this->once())
->method('doFetch')
->with('DoctrineNamespaceCacheKey[]')
->willReturn('corruptedStringKey');
$cache->expects($this->once())
->method('doSave')
->with('DoctrineNamespaceCacheKey[]', 2, 0)
->willReturn(true);
self::assertTrue($cache->deleteAll());
}
}
================================================
FILE: tests/Doctrine/Tests/Common/Cache/CacheTest.php
================================================
<?php
namespace Doctrine\Tests\Common\Cache;
use ArrayObject;
use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Cache\CacheProvider;
use Doctrine\Tests\DoctrineTestCase;
use stdClass;
use function array_keys;
use function array_map;
use function array_slice;
use function is_object;
use function restore_error_handler;
use function set_error_handler;
use function sleep;
use function sprintf;
use function str_repeat;
abstract class CacheTest extends DoctrineTestCase
{
/**
* @param mixed $value
*
* @dataProvider provideDataToCache
*/
public function testSetContainsFetchDelete($value): void
{
$cache = $this->getCacheDriver();
// Test saving a value, checking if it exists, and fetching it back
self::assertTrue($cache->save('key', $value));
self::assertTrue($cache->contains('key'));
if (is_object($value)) {
self::assertEquals($value, $cache->fetch('key'), 'Objects retrieved from the cache must be equal but not necessarily the same reference');
} else {
self::assertSame($value, $cache->fetch('key'), 'Scalar and array data retrieved from the cache must be the same as the original, e.g. same type');
}
// Test deleting a value
self::assertTrue($cache->delete('key'));
self::assertFalse($cache->contains('key'));
self::assertFalse($cache->fetch('key'));
}
/**
* @param mixed $value
*
* @dataProvider provideDataToCache
*/
public function testUpdateExistingEntry($value): void
{
$cache = $this->getCacheDriver();
self::assertTrue($cache->save('key', 'old-value'));
self::assertTrue($cache->contains('key'));
self::assertTrue($cache->save('key', $value));
self::assertTrue($cache->contains('key'));
if (is_object($value)) {
self::assertEquals($value, $cache->fetch('key'), 'Objects retrieved from the cache must be equal but not necessarily the same reference');
} else {
self::assertSame($value, $cache->fetch('key'), 'Scalar and array data retrieved from the cache must be the same as the original, e.g. same type');
}
}
public function testCacheKeyIsCaseSensitive(): void
{
$cache = $this->getCacheDriver();
self::assertTrue($cache->save('key', 'value'));
self::assertTrue($cache->contains('key'));
self::assertSame('value', $cache->fetch('key'));
self::assertFalse($cache->contains('KEY'));
self::assertFalse($cache->fetch('KEY'));
$cache->delete('KEY');
self::assertTrue($cache->contains('key'), 'Deleting cache item with different case must not affect other cache item');
}
public function testFetchMultiple(): void
{
$cache = $this->getCacheDriver();
$values = $this->provideDataToCache();
$saved = [];
foreach ($values as $key => $value) {
$cache->save($key, $value[0]);
$saved[$key] = $value[0];
}
$keys = array_keys($saved);
self::assertEquals(
$saved,
$cache->fetchMultiple($keys),
'Testing fetchMultiple with different data types'
);
self::assertEquals(
array_slice($saved, 0, 1),
$cache->fetchMultiple(array_slice($keys, 0, 1)),
'Testing fetchMultiple with a single key'
);
$keysWithNonExisting = [];
$keysWithNonExisting[] = 'non_existing1';
$keysWithNonExisting[] = $keys[0];
$keysWithNonExisting[] = 'non_existing2';
$keysWithNonExisting[] = $keys[1];
$keysWithNonExisting[] = 'non_existing3';
self::assertEquals(
array_slice($saved, 0, 2),
$cache->fetchMultiple($keysWithNonExisting),
'Testing fetchMultiple with a subset of keys and mixed with non-existing ones'
);
}
public function testFetchMultipleWithNoKeys(): void
{
$cache = $this->getCacheDriver();
self::assertSame([], $cache->fetchMultiple([]));
}
public function testSaveMultiple(): void
{
$cache = $this->getCacheDriver();
$cache->deleteAll();
$data = array_map(static function ($value) {
return $value[0];
}, $this->provideDataToCache());
self::assertTrue($cache->saveMultiple($data));
$keys = array_keys($data);
self::assertEquals($data, $cache->fetchMultiple($keys));
}
/**
* @return array<string, array{mixed}>
*/
public function provideDataToCache(): array
{
$obj = new stdClass();
$obj->foo = 'bar';
$obj2 = new stdClass();
$obj2->bar = 'foo';
$obj2->obj = $obj;
$obj->obj2 = $obj2;
return [
'array' => [['one', 2, 3.01]],
'string' => ['value'],
'string_invalid_utf8' => ["\xc3\x28"],
'string_null_byte' => ['with' . "\0" . 'null char'],
'integer' => [1],
'float' => [1.5],
'object' => [new ArrayObject(['one', 2, 3.01])],
'object_recursive' => [$obj],
'true' => [true],
// the following are considered FALSE in boolean context, but caches should still recognize their existence
'null' => [null],
'false' => [false],
'array_empty' => [[]],
'string_zero' => ['0'],
'integer_zero' => [0],
'float_zero' => [0.0],
'string_empty' => [''],
];
}
public function testDeleteIsSuccessfulWhenKeyDoesNotExist(): void
{
$cache = $this->getCacheDriver();
$cache->delete('key');
self::assertFalse($cache->contains('key'));
self::assertTrue($cache->delete('key'));
}
public function testDeleteAll(): void
{
$cache = $this->getCacheDriver();
self::assertTrue($cache->save('key1', 1));
self::assertTrue($cache->save('key2', 2));
self::assertTrue($cache->deleteAll());
self::assertFalse($cache->contains('key1'), sprintf(
'key1 should have disappeared but did not. The namespace is "%s"',
$cache->getNamespace()
));
self::assertFalse($cache->contains('key2'));
}
public function testDeleteMulti(): void
{
$cache = $this->getCacheDriver();
self::assertTrue($cache->save('key1', 1));
self::assertTrue($cache->save('key2', 1));
self::assertTrue($cache->deleteMultiple(['key1', 'key2', 'key3']));
self::assertFalse($cache->contains('key1'));
self::assertFalse($cache->contains('key2'));
self::assertFalse($cache->contains('key3'));
}
/**
* @dataProvider provideCacheIds
*/
public function testCanHandleSpecialCacheIds(string $id): void
{
$cache = $this->getCacheDriver();
self::assertTrue($cache->save($id, 'value'));
self::assertTrue($cache->contains($id));
self::assertEquals('value', $cache->fetch($id));
self::assertTrue($cache->delete($id));
self::assertFalse($cache->contains($id));
self::assertFalse($cache->fetch($id));
}
public function testNoCacheIdCollisions(): void
{
$cache = $this->getCacheDriver();
$ids = $this->provideCacheIds();
// fill cache with each id having a different value
foreach ($ids as $index => $id) {
$cache->save($id[0], $index);
}
// then check value of each cache id
foreach ($ids as $index => $id) {
$value = $cache->fetch($id[0]);
self::assertNotFalse($value, sprintf('Failed to retrieve data for cache id "%s".', $id[0]));
if ($index === $value) {
continue;
}
$this->fail(sprintf('Cache id "%s" collides with id "%s".', $id[0], $ids[$value][0]));
}
}
/**
* Returns cache ids with special characters that should still work.
*
* For example, the characters :\/<>"*?| are not valid in Windows filenames. So they must be encoded properly.
* Each cache id should be considered different from the others.
*
* @psalm-return list<array{string}>
*/
public function provideCacheIds(): array
{
return [
[':'],
['\\'],
['/'],
['<'],
['>'],
['"'],
['*'],
['?'],
['|'],
['['],
[']'],
['ä'],
['a'],
['é'],
['e'],
['.'], // directory traversal
['..'], // directory traversal
['-'],
['_'],
['$'],
['%'],
[' '],
["\0"],
[''],
[str_repeat('a', 300)], // long key
[str_repeat('a', 113)],
];
}
public function testLifetime(): void
{
$cache = $this->getCacheDriver();
$cache->save('expire', 'value', 1);
self::assertTrue($cache->contains('expire'), 'Data should not be expired yet');
// @TODO should more TTL-based tests pop up, so then we should mock the `time` API instead
sleep(2);
self::assertFalse($cache->contains('expire'), 'Data should be expired');
}
public function testNoExpire(): void
{
$cache = $this->getCacheDriver();
$cache->save('noexpire', 'value', 0);
// @TODO should more TTL-based tests pop up, so then we should mock the `time` API instead
sleep(1);
self::assertTrue($cache->contains('noexpire'), 'Data with lifetime of zero should not expire');
}
public function testLongLifetime(): void
{
$cache = $this->getCacheDriver();
$cache->save('longlifetime', 'value', 30 * 24 * 3600 + 1);
self::assertTrue($cache->contains('longlifetime'), 'Data with lifetime > 30 days should be accepted');
}
public function testDeleteAllAndNamespaceVersioningBetweenCaches(): void
{
if (! $this->isSharedStorage()) {
$this->markTestSkipped('The cache storage needs to be shared.');
}
$cache1 = $this->getCacheDriver();
$cache2 = $this->getCacheDriver();
self::assertTrue($cache1->save('key1', 1));
self::assertTrue($cache2->save('key2', 2));
/* Both providers are initialized with the same namespace version, so
* they can see entries set by each other.
*/
self::assertTrue($cache1->contains('key1'));
self::assertTrue($cache1->contains('key2'));
self::assertTrue($cache2->contains('key1'));
self::assertTrue($cache2->contains('key2'));
/* Deleting all entries through one provider will only increment the
* namespace version on that object (and in the cache itself, which new
* instances will use to initialize). The second provider will retain
* its original version and still see stale data.
*/
self::assertTrue($cache1->deleteAll());
self::assertFalse($cache1->contains('key1'));
self::assertFalse($cache1->contains('key2'));
self::assertTrue($cache2->contains('key1'));
self::assertTrue($cache2->contains('key2'));
/* A new cache provider should not see the deleted entries, since its
* namespace version will be initialized.
*/
$cache3 = $this->getCacheDriver();
self::assertFalse($cache3->contains('key1'));
self::assertFalse($cache3->contains('key2'));
}
public function testFlushAll(): void
{
$cache = $this->getCacheDriver();
self::assertTrue($cache->save('key1', 1));
self::assertTrue($cache->save('key2', 2));
self::assertTrue($cache->flushAll());
self::assertFalse($cache->contains('key1'));
self::assertFalse($cache->contains('key2'));
}
public function testFlushAllAndNamespaceVersioningBetweenCaches(): void
{
if (! $this->isSharedStorage()) {
$this->markTestSkipped('The cache storage needs to be shared.');
}
$cache1 = $this->getCacheDriver();
$cache2 = $this->getCacheDriver();
/* Deleting all elements from the first provider should increment its
* namespace version before saving the first entry.
*/
$cache1->deleteAll();
self::assertTrue($cache1->save('key1', 1));
/* The second provider will be initialized with the same namespace
* version upon its first save operation.
*/
self::assertTrue($cache2->save('key2', 2));
/* Both providers have the same namespace version and can see entries
* set by each other.
*/
self::assertTrue($cache1->contains('key1'));
self::assertTrue($cache1->contains('key2'));
self::assertTrue($cache2->contains('key1'));
self::assertTrue($cache2->contains('key2'));
/* Flushing all entries through one cache will remove all entries from
* the cache but leave their namespace version as-is.
*/
self::assertTrue($cache1->flushAll());
self::assertFalse($cache1->contains('key1'));
self::assertFalse($cache1->contains('key2'));
self::assertFalse($cache2->contains('key1'));
self::assertFalse($cache2->contains('key2'));
/* Inserting a new entry will use the same, incremented namespace
* version, and it will be visible to both providers.
*/
self::assertTrue($cache1->save('key1', 1));
self::assertTrue($cache1->contains('key1'));
self::assertTrue($cache2->contains('key1'));
/* A new cache provider will be initialized with the original namespace
* version and not share any visibility with the first two providers.
*/
$cache3 = $this->getCacheDriver();
self::assertFalse($cache3->contains('key1'));
self::assertFalse($cache3->contains('key2'));
self::assertTrue($cache3->save('key3', 3));
self::assertTrue($cache3->contains('key3'));
}
public function testNamespace(): void
{
$cache = $this->getCacheDriver();
$cache->setNamespace('ns1_');
self::assertTrue($cache->save('key1', 1));
self::assertTrue($cache->contains('key1'));
$cache->setNamespace('ns2_');
self::assertFalse($cache->contains('key1'));
}
public function testDeleteAllNamespace(): void
{
$cache = $this->getCacheDriver();
$cache->setNamespace('ns1');
self::assertFalse($cache->contains('key1'));
$cache->save('key1', 'test');
self::assertTrue($cache->contains('key1'));
$cache->setNamespace('ns2');
self::assertFalse($cache->contains('key1'));
$cache->save('key1', 'test');
self::assertTrue($cache->contains('key1'));
$cache->setNamespace('ns1');
self::assertTrue($cache->contains('key1'));
$cache->deleteAll();
self::assertFalse($cache->contains('key1'));
$cache->setNamespace('ns2');
self::assertTrue($cache->contains('key1'));
$cache->deleteAll();
self::assertFalse($cache->contains('key1'));
}
/**
* @group DCOM-43
*/
public function testGetStats(): void
{
$cache = $this->getCacheDriver();
$stats = $cache->getStats();
self::assertArrayHasKey(Cache::STATS_HITS, $stats);
self::assertArrayHasKey(Cache::STATS_MISSES, $stats);
self::assertArrayHasKey(Cache::STATS_UPTIME, $stats);
self::assertArrayHasKey(Cache::STATS_MEMORY_USAGE, $stats);
self::assertArrayHasKey(Cache::STATS_MEMORY_AVAILABLE, $stats);
}
public function testSaveReturnsTrueWithAndWithoutTTlSet(): void
{
$cache = $this->getCacheDriver();
$cache->deleteAll();
self::assertTrue($cache->save('without_ttl', 'without_ttl'));
self::assertTrue($cache->save('with_ttl', 'with_ttl', 3600));
}
public function testValueThatIsFalseBooleanIsProperlyRetrieved()
{
$cache = $this->getCacheDriver();
$cache->deleteAll();
self::assertTrue($cache->save('key1', false));
self::assertTrue($cache->contains('key1'));
self::assertFalse($cache->fetch('key1'));
}
/**
* @group 147
* @group 152
*/
public function testFetchingANonExistingKeyShouldNeverCauseANoticeOrWarning(): void
{
$cache = $this->getCacheDriver();
$errorHandler = function () {
restore_error_handler();
$this->fail('include failure captured');
};
set_error_handler($errorHandler);
$cache->fetch('key');
self::assertSame(
$errorHandler,
set_error_handler(static function () {
}),
'The error handler is the one set by this test, and wasn\'t replaced'
);
restore_error_handler();
restore_error_handler();
}
/**
* Return whether multiple cache providers share the same storage.
*
* This is used for skipping certain tests for shared storage behavior.
*/
protected function isSharedStorage(): bool
{
return true;
}
abstract protected function getCacheDriver(): CacheProvider;
}
================================================
FILE: tests/Doctrine/Tests/Common/Cache/Psr6/CacheAdapterTest.php
================================================
<?php
namespace Doctrine\Tests\Common\Cache\Psr6;
use Cache\IntegrationTests\CachePoolTest;
use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Cache\Psr6\CacheAdapter;
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\Tests\Common\Cache\ArrayCache;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\DoctrineProvider as SymfonyDoctrineProvider;
use function array_key_exists;
use function assert;
final class CacheAdapterTest extends CachePoolTest
{
/** @var ArrayCache */
private $arrayCache;
public function createCachePool(): CacheItemPoolInterface
{
if (! $this->arrayCache) {
$this->arrayCache = new ArrayCache();
}
return CacheAdapter::wrap($this->arrayCache);
}
public function testWithWrappedCache()
{
$rootCache = new ArrayAdapter();
$wrapped = DoctrineProvider::wrap($rootCache);
self::assertSame($rootCache, CacheAdapter::wrap($wrapped));
}
/**
* @requires function Symfony\Component\Cache\DoctrineProvider::__construct
*/
public function testWithWrappedSymfonyCache()
{
$rootCache = new ArrayAdapter();
$wrapped = new SymfonyDoctrineProvider($rootCache);
self::assertSame($rootCache, CacheAdapter::wrap($wrapped));
}
public function testWithWrappedMinimalCache()
{
$rootCache = new class implements Cache {
/** @var mixed[] */
public $values = [];
/** @inheritdoc **/
public function fetch($id)
{
return $values[$id] ?? false;
}
/** @inheritdoc **/
public function contains($id)
{
return array_key_exists($id, $this->values);
}
/** @inheritdoc **/
public function save($id, $data, $lifeTime = 0)
{
$this->values[$id] = $data;
return true;
}
/** @inheritdoc **/
public function delete($id)
{
unset($this->values[$id]);
return true;
}
/** @inheritdoc **/
public function getStats()
{
return null;
}
};
$adapter = CacheAdapter::wrap($rootCache);
self::assertInstanceOf(CacheAdapter::class, $adapter);
assert($adapter instanceof CacheAdapter);
/** @var CacheItemInterface[] $items */
$items = $adapter->getItems(['1', '2', '3']);
self::assertCount(3, $items);
foreach ($items as $key => $item) {
$item->set($key);
$adapter->saveDeferred($item);
}
self::assertTrue($adapter->commit());
self::assertCount(3, $rootCache->values);
self::assertFalse($adapter->clear());
self::assertCount(3, $rootCache->values);
self::assertTrue($adapter->deleteItems(['1', '2']));
self::assertCount(1, $rootCache->values);
}
public function testItemsAreFlushedToTheUnderlyingCacheOnce(): void
{
$wrapped = $this->createMock(Cache::class);
$adapter = CacheAdapter::wrap($wrapped);
$cacheItem = $adapter->getItem('answer-to-life-universe-everything');
$cacheItem->set(42);
$adapter->saveDeferred($cacheItem);
$wrapped->expects(self::once())
->method('save')
->willReturn(true);
$adapter->commit();
$adapter->commit();
}
public function testNamespacingFeatureIsPreservedWithDoctrineProvider(): void
{
$wrapped = new ArrayAdapter();
$cacheApp1 = DoctrineProvider::wrap($wrapped);
$cacheApp1->setNamespace('app 1');
$cacheApp2 = DoctrineProvider::wrap($wrapped);
$cacheApp2->setNamespace('app 2');
$psrCacheApp1 = CacheAdapter::wrap($cacheApp1);
$psrCacheApp2 = CacheAdapter::wrap($cacheApp2);
$item = $psrCacheApp1->getItem('some key')->set('some value');
$psrCacheApp1->save($item);
self::assertFalse($psrCacheApp2->getItem('some key')->isHit());
}
/**
* @requires function Symfony\Component\Cache\DoctrineProvider::__construct
*/
public function testNamespacingFeatureIsPreservedWithSymfonyDoctrineProvider(): void
{
$wrapped = new ArrayAdapter();
$cacheApp1 = new SymfonyDoctrineProvider($wrapped);
$cacheApp1->setNamespace('app 1');
$cacheApp2 = new SymfonyDoctrineProvider($wrapped);
$cacheApp2->setNamespace('app 2');
$psrCacheApp1 = CacheAdapter::wrap($cacheApp1);
$psrCacheApp2 = CacheAdapter::wrap($cacheApp2);
$item = $psrCacheApp1->getItem('some key')->set('some value');
$psrCacheApp1->save($item);
self::assertFalse($psrCacheApp2->getItem('some key')->isHit());
}
}
================================================
FILE: tests/Doctrine/Tests/Common/Cache/Psr6/DoctrineProviderTest.php
================================================
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Doctrine\Tests\Common\Cache\Psr6;
use Doctrine\Common\Cache\CacheProvider;
use Doctrine\Common\Cache\Psr6\CacheAdapter;
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\Tests\Common\Cache\ArrayCache;
use Doctrine\Tests\Common\Cache\CacheTest;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\DoctrineAdapter as SymfonyDoctrineAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use function class_exists;
use function sprintf;
use function sys_get_temp_dir;
class DoctrineProviderTest extends CacheTest
{
protected function getCacheDriver(): CacheProvider
{
$pool = new ArrayAdapter();
return DoctrineProvider::wrap($pool);
}
public function testProvider()
{
$cache = $this->getCacheDriver();
$this->assertInstanceOf(CacheProvider::class, $cache);
$key = '{}()/\@:';
$this->assertTrue($cache->delete($key));
$this->assertFalse($cache->contains($key));
$this->assertTrue($cache->save($key, 'bar'));
$this->assertTrue($cache->contains($key));
$this->assertSame('bar', $cache->fetch($key));
$this->assertTrue($cache->delete($key));
$this->assertFalse($cache->fetch($key));
$this->assertTrue($cache->save($key, 'bar'));
$cache->flushAll();
$this->assertFalse($cache->fetch($key));
$this->assertFalse($cache->contains($key));
}
public function testWithWrappedCache()
{
$rootCache = new ArrayCache();
$wrapped = CacheAdapter::wrap($rootCache);
self::assertSame($rootCache, DoctrineProvider::wrap($wrapped));
}
public function testWithWrappedSymfonyCache()
{
if (! class_exists(SymfonyDoctrineAdapter::class)) {
self::markTestSkipped('This test requires Symfony 5 or lower.');
}
$rootCache = new ArrayCache();
$wrapped = new SymfonyDoctrineAdapter($rootCache);
self::assertSame($rootCache, DoctrineProvider::wrap($wrapped));
}
public function testGetStats(): void
{
$this->markTestSkipped(sprintf('"%s" does not expose statistics', DoctrineProvider::class));
}
public function testResetArrayAdapter()
{
$cache = $this->getCacheDriver();
$cache->save('test', 'test');
$cache->reset();
$this->assertSame(false, $cache->fetch('test'));
}
public function testResetFilesystemAdapter()
{
$pool = new FilesystemAdapter('', 0, sys_get_temp_dir() . '/doctrine-cache-test');
$pool2 = new FilesystemAdapter('', 0, sys_get_temp_dir() . '/doctrine-cache-test');
$cache = DoctrineProvider::wrap($pool);
$cache2 = DoctrineProvider::wrap($pool2);
$cache->save('test', 'test');
$cache->reset();
// we make sure with the next assertion the cache behave like expected and the test is not accidentally changed
// to use ArrayAdapter as this test scenario requires a persisted cache adapter
$this->assertSame('test', $cache->fetch('test'));
// the second cache instance will now remove all exist files via namespaceVersion still the first cache
// will receive the data until then the reset is called. the assertion after deleteAll is not required
// but better show why the reset is even needed when cache service is used in long-running processes.
$cache2->deleteAll();
$this->assertSame('test', $cache->fetch('test'));
$cache->reset();
// the previous called reset will reset the namespaceVersion and so the cache is correctly false now
$this->assertSame(false, $cache->fetch('test'));
}
protected function isSharedStorage(): bool
{
return false;
}
}
================================================
FILE: tests/Doctrine/Tests/DoctrineTestCase.php
================================================
<?php
namespace Doctrine\Tests;
use PHPUnit\Framework\TestCase;
/**
* Base testcase class for all Doctrine testcases.
*/
abstract class DoctrineTestCase extends TestCase
{
}
================================================
FILE: tests/travis/php.ini
================================================
extension="apcu.so"
extension="mongodb.so"
extension="memcached.so"
extension="redis.so"
extension="couchbase.so"
apc.enabled=1
apc.enable_cli=1
gitextract_4su6f833/
├── .doctrine-project.json
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ ├── coding-standards.yml
│ ├── continuous-integration.yml
│ └── release-on-milestone-closed.yml
├── .gitignore
├── LICENSE
├── README.md
├── UPGRADE-1.11.md
├── UPGRADE-1.4.md
├── build.properties
├── build.xml
├── composer.json
├── docs/
│ └── en/
│ └── index.rst
├── 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
├── phpcs.xml.dist
├── phpunit.xml.dist
└── tests/
├── Doctrine/
│ └── Tests/
│ ├── Common/
│ │ └── Cache/
│ │ ├── ArrayCache.php
│ │ ├── ArrayCacheTest.php
│ │ ├── CacheProviderTest.php
│ │ ├── CacheTest.php
│ │ └── Psr6/
│ │ ├── CacheAdapterTest.php
│ │ └── DoctrineProviderTest.php
│ └── DoctrineTestCase.php
└── travis/
└── php.ini
SYMBOL INDEX (155 symbols across 20 files)
FILE: lib/Doctrine/Common/Cache/Cache.php
type Cache (line 10) | interface Cache
method fetch (line 31) | public function fetch($id);
method contains (line 40) | public function contains($id);
method save (line 55) | public function save($id, $data, $lifeTime = 0);
method delete (line 65) | public function delete($id);
method getStats (line 89) | public function getStats();
FILE: lib/Doctrine/Common/Cache/CacheProvider.php
class CacheProvider (line 13) | abstract class CacheProvider implements Cache, FlushableCache, Clearable...
method setNamespace (line 38) | public function setNamespace($namespace)
method getNamespace (line 49) | public function getNamespace()
method fetch (line 57) | public function fetch($id)
method fetchMultiple (line 65) | public function fetchMultiple(array $keys)
method saveMultiple (line 92) | public function saveMultiple(array $keysAndValues, $lifetime = 0)
method contains (line 105) | public function contains($id)
method save (line 113) | public function save($id, $data, $lifeTime = 0)
method deleteMultiple (line 121) | public function deleteMultiple(array $keys)
method delete (line 129) | public function delete($id)
method getStats (line 137) | public function getStats()
method flushAll (line 145) | public function flushAll()
method deleteAll (line 153) | public function deleteAll()
method getNamespacedId (line 174) | private function getNamespacedId(string $id): string
method getNamespaceCacheKey (line 184) | private function getNamespaceCacheKey(): string
method getNamespaceVersion (line 192) | private function getNamespaceVersion(): int
method doFetchMultiple (line 211) | protected function doFetchMultiple(array $keys)
method doFetch (line 234) | abstract protected function doFetch($id);
method doContains (line 243) | abstract protected function doContains($id);
method doSaveMultiple (line 254) | protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
method doSave (line 279) | abstract protected function doSave($id, $data, $lifeTime = 0);
method doDeleteMultiple (line 288) | protected function doDeleteMultiple(array $keys)
method doDelete (line 310) | abstract protected function doDelete($id);
method doFlush (line 317) | abstract protected function doFlush();
method doGetStats (line 324) | abstract protected function doGetStats();
FILE: lib/Doctrine/Common/Cache/ClearableCache.php
type ClearableCache (line 13) | interface ClearableCache
method deleteAll (line 20) | public function deleteAll();
FILE: lib/Doctrine/Common/Cache/FlushableCache.php
type FlushableCache (line 10) | interface FlushableCache
method flushAll (line 17) | public function flushAll();
FILE: lib/Doctrine/Common/Cache/MultiDeleteCache.php
type MultiDeleteCache (line 12) | interface MultiDeleteCache
method deleteMultiple (line 21) | public function deleteMultiple(array $keys);
FILE: lib/Doctrine/Common/Cache/MultiGetCache.php
type MultiGetCache (line 12) | interface MultiGetCache
method fetchMultiple (line 22) | public function fetchMultiple(array $keys);
FILE: lib/Doctrine/Common/Cache/MultiOperationCache.php
type MultiOperationCache (line 10) | interface MultiOperationCache extends MultiGetCache, MultiDeleteCache, M...
FILE: lib/Doctrine/Common/Cache/MultiPutCache.php
type MultiPutCache (line 12) | interface MultiPutCache
method saveMultiple (line 23) | public function saveMultiple(array $keysAndValues, $lifetime = 0);
FILE: lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php
class CacheAdapter (line 28) | final class CacheAdapter implements CacheItemPoolInterface
method wrap (line 38) | public static function wrap(Cache $cache): CacheItemPoolInterface
method __construct (line 56) | private function __construct(Cache $cache)
method getCache (line 62) | public function getCache(): Cache
method getItem (line 70) | public function getItem($key): CacheItemInterface
method getItems (line 98) | public function getItems(array $keys = []): array
method hasItem (line 135) | public function hasItem($key): bool
method clear (line 146) | public function clear(): bool
method deleteItem (line 160) | public function deleteItem($key): bool
method deleteItems (line 171) | public function deleteItems(array $keys): bool
method save (line 181) | public function save(CacheItemInterface $item): bool
method saveDeferred (line 186) | public function saveDeferred(CacheItemInterface $item): bool
method commit (line 197) | public function commit(): bool
method __destruct (line 246) | public function __destruct()
method validKey (line 254) | private static function validKey($key): bool
method validKeys (line 274) | private static function validKeys(array $keys): bool
method doDeleteMultiple (line 286) | private function doDeleteMultiple(array $keys): bool
method doFetchMultiple (line 305) | private function doFetchMultiple(array $keys): array
method doSaveMultiple (line 327) | private function doSaveMultiple(array $keysAndValues, int $lifetime = ...
FILE: lib/Doctrine/Common/Cache/Psr6/CacheItem.php
class CacheItem (line 18) | final class CacheItem implements CacheItemInterface
method __construct (line 34) | public function __construct(string $key, $data, bool $isHit)
method getKey (line 41) | public function getKey(): string
method get (line 51) | public function get()
method isHit (line 56) | public function isHit(): bool
method set (line 64) | public function set($value): self
method expiresAt (line 74) | public function expiresAt($expiration): self
method expiresAfter (line 93) | public function expiresAfter($time): self
method getExpiry (line 114) | public function getExpiry(): ?float
FILE: lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php
class DoctrineProvider (line 27) | final class DoctrineProvider extends CacheProvider
method wrap (line 32) | public static function wrap(CacheItemPoolInterface $pool): Cache
method __construct (line 50) | private function __construct(CacheItemPoolInterface $pool)
method getPool (line 56) | public function getPool(): CacheItemPoolInterface
method reset (line 61) | public function reset(): void
method doFetch (line 73) | protected function doFetch($id)
method doContains (line 85) | protected function doContains($id)
method doSave (line 95) | protected function doSave($id, $data, $lifeTime = 0)
method doDelete (line 111) | protected function doDelete($id)
method doFlush (line 121) | protected function doFlush()
method doGetStats (line 131) | protected function doGetStats()
FILE: lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php
class InvalidArgument (line 11) | final class InvalidArgument extends InvalidArgumentException implements ...
FILE: lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php
class TypedCacheItem (line 16) | final class TypedCacheItem implements CacheItemInterface
method __construct (line 23) | public function __construct(
method getKey (line 30) | public function getKey(): string
method get (line 35) | public function get(): mixed
method isHit (line 40) | public function isHit(): bool
method set (line 45) | public function set(mixed $value): static
method expiresAt (line 55) | public function expiresAt($expiration): static
method expiresAfter (line 74) | public function expiresAfter($time): static
method getExpiry (line 95) | public function getExpiry(): ?float
FILE: tests/Doctrine/Tests/Common/Cache/ArrayCache.php
class ArrayCache (line 15) | class ArrayCache extends CacheProvider
method __construct (line 32) | public function __construct()
method doFetch (line 40) | protected function doFetch($id)
method doContains (line 56) | protected function doContains($id)
method doSave (line 76) | protected function doSave($id, $data, $lifeTime = 0)
method doDelete (line 86) | protected function doDelete($id)
method doFlush (line 96) | protected function doFlush()
method doGetStats (line 106) | protected function doGetStats()
FILE: tests/Doctrine/Tests/Common/Cache/ArrayCacheTest.php
class ArrayCacheTest (line 8) | class ArrayCacheTest extends CacheTest
method getCacheDriver (line 10) | protected function getCacheDriver(): CacheProvider
method testGetStats (line 15) | public function testGetStats(): void
method isSharedStorage (line 48) | protected function isSharedStorage(): bool
FILE: tests/Doctrine/Tests/Common/Cache/CacheProviderTest.php
class CacheProviderTest (line 11) | class CacheProviderTest extends DoctrineTestCase
method testFetchMultiWillFilterNonRequestedKeys (line 13) | public function testFetchMultiWillFilterNonRequestedKeys(): void
method testFailedDeleteAllDoesNotChangeNamespaceVersion (line 41) | public function testFailedDeleteAllDoesNotChangeNamespaceVersion(): void
method testSaveMultipleNoFail (line 79) | public function testSaveMultipleNoFail(): void
method testDeleteMultipleNoFail (line 110) | public function testDeleteMultipleNoFail(): void
method testInvalidNamespaceVersionCacheEntry (line 133) | public function testInvalidNamespaceVersionCacheEntry(): void
FILE: tests/Doctrine/Tests/Common/Cache/CacheTest.php
class CacheTest (line 21) | abstract class CacheTest extends DoctrineTestCase
method testSetContainsFetchDelete (line 28) | public function testSetContainsFetchDelete($value): void
method testUpdateExistingEntry (line 52) | public function testUpdateExistingEntry($value): void
method testCacheKeyIsCaseSensitive (line 68) | public function testCacheKeyIsCaseSensitive(): void
method testFetchMultiple (line 83) | public function testFetchMultiple(): void
method testFetchMultipleWithNoKeys (line 122) | public function testFetchMultipleWithNoKeys(): void
method testSaveMultiple (line 129) | public function testSaveMultiple(): void
method provideDataToCache (line 148) | public function provideDataToCache(): array
method testDeleteIsSuccessfulWhenKeyDoesNotExist (line 178) | public function testDeleteIsSuccessfulWhenKeyDoesNotExist(): void
method testDeleteAll (line 187) | public function testDeleteAll(): void
method testDeleteMulti (line 201) | public function testDeleteMulti(): void
method testCanHandleSpecialCacheIds (line 216) | public function testCanHandleSpecialCacheIds(string $id): void
method testNoCacheIdCollisions (line 229) | public function testNoCacheIdCollisions(): void
method provideCacheIds (line 260) | public function provideCacheIds(): array
method testLifetime (line 292) | public function testLifetime(): void
method testNoExpire (line 302) | public function testNoExpire(): void
method testLongLifetime (line 311) | public function testLongLifetime(): void
method testDeleteAllAndNamespaceVersioningBetweenCaches (line 318) | public function testDeleteAllAndNamespaceVersioningBetweenCaches(): void
method testFlushAll (line 357) | public function testFlushAll(): void
method testFlushAllAndNamespaceVersioningBetweenCaches (line 368) | public function testFlushAllAndNamespaceVersioningBetweenCaches(): void
method testNamespace (line 422) | public function testNamespace(): void
method testDeleteAllNamespace (line 436) | public function testDeleteAllNamespace(): void
method testGetStats (line 464) | public function testGetStats(): void
method testSaveReturnsTrueWithAndWithoutTTlSet (line 476) | public function testSaveReturnsTrueWithAndWithoutTTlSet(): void
method testValueThatIsFalseBooleanIsProperlyRetrieved (line 484) | public function testValueThatIsFalseBooleanIsProperlyRetrieved()
method testFetchingANonExistingKeyShouldNeverCauseANoticeOrWarning (line 498) | public function testFetchingANonExistingKeyShouldNeverCauseANoticeOrWa...
method isSharedStorage (line 528) | protected function isSharedStorage(): bool
method getCacheDriver (line 533) | abstract protected function getCacheDriver(): CacheProvider;
FILE: tests/Doctrine/Tests/Common/Cache/Psr6/CacheAdapterTest.php
class CacheAdapterTest (line 18) | final class CacheAdapterTest extends CachePoolTest
method createCachePool (line 23) | public function createCachePool(): CacheItemPoolInterface
method testWithWrappedCache (line 32) | public function testWithWrappedCache()
method testWithWrappedSymfonyCache (line 43) | public function testWithWrappedSymfonyCache()
method testWithWrappedMinimalCache (line 51) | public function testWithWrappedMinimalCache()
method testItemsAreFlushedToTheUnderlyingCacheOnce (line 114) | public function testItemsAreFlushedToTheUnderlyingCacheOnce(): void
method testNamespacingFeatureIsPreservedWithDoctrineProvider (line 131) | public function testNamespacingFeatureIsPreservedWithDoctrineProvider(...
method testNamespacingFeatureIsPreservedWithSymfonyDoctrineProvider (line 152) | public function testNamespacingFeatureIsPreservedWithSymfonyDoctrinePr...
FILE: tests/Doctrine/Tests/Common/Cache/Psr6/DoctrineProviderTest.php
class DoctrineProviderTest (line 27) | class DoctrineProviderTest extends CacheTest
method getCacheDriver (line 29) | protected function getCacheDriver(): CacheProvider
method testProvider (line 36) | public function testProvider()
method testWithWrappedCache (line 60) | public function testWithWrappedCache()
method testWithWrappedSymfonyCache (line 68) | public function testWithWrappedSymfonyCache()
method testGetStats (line 80) | public function testGetStats(): void
method testResetArrayAdapter (line 85) | public function testResetArrayAdapter()
method testResetFilesystemAdapter (line 96) | public function testResetFilesystemAdapter()
method isSharedStorage (line 121) | protected function isSharedStorage(): bool
FILE: tests/Doctrine/Tests/DoctrineTestCase.php
class DoctrineTestCase (line 10) | abstract class DoctrineTestCase extends TestCase
Condensed preview — 38 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (91K chars).
[
{
"path": ".doctrine-project.json",
"chars": 1409,
"preview": "{\n \"active\": false,\n \"name\": \"Cache\",\n \"slug\": \"cache\",\n \"docsSlug\": \"doctrine-cache\",\n \"versions\": [\n "
},
{
"path": ".gitattributes",
"chars": 301,
"preview": "/docs export-ignore\n/.github export-ignore\n/tests export-ignore\n.doctrine-project.json export-ignore\n.gitattributes expo"
},
{
"path": ".github/FUNDING.yml",
"chars": 116,
"preview": "patreon: phpdoctrine\ntidelift: packagist/doctrine%2Fcache\ncustom: https://www.doctrine-project.org/sponsorship.html\n"
},
{
"path": ".github/workflows/coding-standards.yml",
"chars": 211,
"preview": "name: \"Coding Standards\"\n\non:\n pull_request:\n branches:\n - \"*.x\"\n push:\n branches:\n - \"*.x\"\n\njobs:\n c"
},
{
"path": ".github/workflows/continuous-integration.yml",
"chars": 2049,
"preview": "\nname: \"Continuous Integration\"\n\non:\n pull_request:\n branches:\n - \"*.x\"\n push:\n branches:\n - \"*.x\"\n\nen"
},
{
"path": ".github/workflows/release-on-milestone-closed.yml",
"chars": 431,
"preview": "name: \"Automatic Releases\"\n\non:\n milestone:\n types:\n - \"closed\"\n\njobs:\n release:\n uses: \"doctrine/.github/."
},
{
"path": ".gitignore",
"chars": 99,
"preview": "vendor/\n/composer.lock\nbuild/\nphpunit.xml\n/.phpunit.result.cache\nclover.xml\n.phpcs-cache\nphpcs.xml\n"
},
{
"path": "LICENSE",
"chars": 1065,
"preview": "Copyright (c) 2006-2015 Doctrine Project\n\nPermission is hereby granted, free of charge, to any person obtaining a copy o"
},
{
"path": "README.md",
"chars": 911,
"preview": "# Doctrine Cache\n\n[](http"
},
{
"path": "UPGRADE-1.11.md",
"chars": 1266,
"preview": "# Upgrade to 1.11\n\ndoctrine/cache will no longer be maintained and all cache implementations have\nbeen marked as depreca"
},
{
"path": "UPGRADE-1.4.md",
"chars": 726,
"preview": "# Upgrade to 1.4\n\n## Minor BC Break: `Doctrine\\Common\\Cache\\FileCache#$extension` is now `private`.\n\nIf you need to over"
},
{
"path": "build.properties",
"chars": 143,
"preview": "# Version class and file\nproject.version_class = Doctrine\\\\Common\\\\Cache\\\\Version\nproject.version_file = lib/Doctrine/Co"
},
{
"path": "build.xml",
"chars": 3992,
"preview": "<?xml version=\"1.0\"?>\n<project name=\"DoctrineCommonCache\" default=\"build\" basedir=\".\">\n <property file=\"build.propert"
},
{
"path": "composer.json",
"chars": 1665,
"preview": "{\n \"name\": \"doctrine/cache\",\n \"abandoned\": true,\n \"type\": \"library\",\n \"description\": \"PHP Doctrine Cache lib"
},
{
"path": "docs/en/index.rst",
"chars": 1854,
"preview": "Deprecation Notice\n==================\n\nPlease note that doctrine/cache is deprecated and no longer maintained. The last\n"
},
{
"path": "lib/Doctrine/Common/Cache/Cache.php",
"chars": 2799,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache;\n\n/**\n * Interface for cache drivers.\n *\n * @link www.doctrine-project.org\n */\n"
},
{
"path": "lib/Doctrine/Common/Cache/CacheProvider.php",
"chars": 8475,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache;\n\nuse function array_combine;\nuse function array_key_exists;\nuse function array_m"
},
{
"path": "lib/Doctrine/Common/Cache/ClearableCache.php",
"chars": 501,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache;\n\n/**\n * Interface for cache that can be flushed.\n *\n * Intended to be used for p"
},
{
"path": "lib/Doctrine/Common/Cache/FlushableCache.php",
"chars": 350,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache;\n\n/**\n * Interface for cache that can be flushed.\n *\n * @link www.doctrine-proj"
},
{
"path": "lib/Doctrine/Common/Cache/MultiDeleteCache.php",
"chars": 466,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache;\n\n/**\n * Interface for cache drivers that allows to put many items at once.\n *\n *"
},
{
"path": "lib/Doctrine/Common/Cache/MultiGetCache.php",
"chars": 593,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache;\n\n/**\n * Interface for cache drivers that allows to get many items at once.\n *\n *"
},
{
"path": "lib/Doctrine/Common/Cache/MultiOperationCache.php",
"chars": 251,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache;\n\n/**\n * Interface for cache drivers that supports multiple items manipulation.\n "
},
{
"path": "lib/Doctrine/Common/Cache/MultiPutCache.php",
"chars": 704,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache;\n\n/**\n * Interface for cache drivers that allows to put many items at once.\n *\n *"
},
{
"path": "lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php",
"chars": 8218,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache\\Psr6;\n\nuse Doctrine\\Common\\Cache\\Cache;\nuse Doctrine\\Common\\Cache\\ClearableCache;"
},
{
"path": "lib/Doctrine/Common/Cache/Psr6/CacheItem.php",
"chars": 2566,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache\\Psr6;\n\nuse DateInterval;\nuse DateTime;\nuse DateTimeInterface;\nuse Psr\\Cache\\Cache"
},
{
"path": "lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php",
"chars": 2998,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php",
"chars": 273,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache\\Psr6;\n\nuse InvalidArgumentException;\nuse Psr\\Cache\\InvalidArgumentException as Ps"
},
{
"path": "lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php",
"chars": 2171,
"preview": "<?php\n\nnamespace Doctrine\\Common\\Cache\\Psr6;\n\nuse DateInterval;\nuse DateTime;\nuse DateTimeInterface;\nuse Psr\\Cache\\Cache"
},
{
"path": "phpcs.xml.dist",
"chars": 1372,
"preview": "<?xml version=\"1.0\"?>\n<ruleset name=\"Coding Standards for doctrine\">\n <description>Coding Standards for doctrine.</de"
},
{
"path": "phpunit.xml.dist",
"chars": 1006,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:noNamespa"
},
{
"path": "tests/Doctrine/Tests/Common/Cache/ArrayCache.php",
"chars": 2188,
"preview": "<?php\n\nnamespace Doctrine\\Tests\\Common\\Cache;\n\nuse Doctrine\\Common\\Cache\\Cache;\nuse Doctrine\\Common\\Cache\\CacheProvider;"
},
{
"path": "tests/Doctrine/Tests/Common/Cache/ArrayCacheTest.php",
"chars": 1475,
"preview": "<?php\n\nnamespace Doctrine\\Tests\\Common\\Cache;\n\nuse Doctrine\\Common\\Cache\\Cache;\nuse Doctrine\\Common\\Cache\\CacheProvider;"
},
{
"path": "tests/Doctrine/Tests/Common/Cache/CacheProviderTest.php",
"chars": 4647,
"preview": "<?php\n\nnamespace Doctrine\\Tests\\Common\\Cache;\n\nuse Doctrine\\Common\\Cache\\CacheProvider;\nuse Doctrine\\Tests\\DoctrineTestC"
},
{
"path": "tests/Doctrine/Tests/Common/Cache/CacheTest.php",
"chars": 17516,
"preview": "<?php\n\nnamespace Doctrine\\Tests\\Common\\Cache;\n\nuse ArrayObject;\nuse Doctrine\\Common\\Cache\\Cache;\nuse Doctrine\\Common\\Cac"
},
{
"path": "tests/Doctrine/Tests/Common/Cache/Psr6/CacheAdapterTest.php",
"chars": 4998,
"preview": "<?php\n\nnamespace Doctrine\\Tests\\Common\\Cache\\Psr6;\n\nuse Cache\\IntegrationTests\\CachePoolTest;\nuse Doctrine\\Common\\Cache\\"
},
{
"path": "tests/Doctrine/Tests/Common/Cache/Psr6/DoctrineProviderTest.php",
"chars": 4055,
"preview": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the ful"
},
{
"path": "tests/Doctrine/Tests/DoctrineTestCase.php",
"chars": 179,
"preview": "<?php\n\nnamespace Doctrine\\Tests;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * Base testcase class for all Doctrine testcases"
},
{
"path": "tests/travis/php.ini",
"chars": 146,
"preview": "extension=\"apcu.so\"\nextension=\"mongodb.so\"\nextension=\"memcached.so\"\nextension=\"redis.so\"\nextension=\"couchbase.so\"\n\napc.e"
}
]
About this extraction
This page contains the full source code of the doctrine/cache GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 38 files (82.2 KB), approximately 21.2k tokens, and a symbol index with 155 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.