Full Code of doctrine/cache for AI

2.2.x e0a9919443c1 cached
38 files
82.2 KB
21.2k tokens
155 symbols
1 requests
Download .txt
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

[![Build Status](https://github.com/doctrine/cache/workflows/Continuous%20Integration/badge.svg)](https://github.com/doctrine/cache/actions)
[![Code Coverage](https://codecov.io/gh/doctrine/cache/branch/1.10.x/graph/badge.svg)](https://codecov.io/gh/doctrine/cache/branch/1.10.x)

[![Latest Stable Version](https://img.shields.io/packagist/v/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache)
[![Total Downloads](https://img.shields.io/packagist/dt/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache)

Cache component extracted from the Doctrine Common project. [Documentation](https://www.doctrine-project.org/projects/doctrine-cache/en/current/index.html)

This library is deprecated and will no longer receive bug fixes from the
Doctrine Project. Please use a different cache library, preferably PSR-6 or
PSR-16 instead.


================================================
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
Download .txt
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
Download .txt
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[![Build Status](https://github.com/doctrine/cache/workflows/Continuous%20Integration/badge.svg)](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.

Copied to clipboard!