pax_global_header00006660000000000000000000000064135706515710014524gustar00rootroot0000000000000052 comment=23bdec448e314042a491ae18fd07026e9933ac14 php-doctrine-cache-1.10.0/000077500000000000000000000000001357065157100152405ustar00rootroot00000000000000php-doctrine-cache-1.10.0/.doctrine-project.json000066400000000000000000000005711357065157100214670ustar00rootroot00000000000000{ "active": true, "name": "Cache", "slug": "cache", "docsSlug": "doctrine-cache", "versions": [ { "name": "master", "branchName": "master", "slug": "latest" }, { "name": "1.8", "branchName": "1.8.x", "slug": "1.8", "current": true } ] } php-doctrine-cache-1.10.0/.github/000077500000000000000000000000001357065157100166005ustar00rootroot00000000000000php-doctrine-cache-1.10.0/.github/FUNDING.yml000066400000000000000000000001641357065157100204160ustar00rootroot00000000000000patreon: phpdoctrine tidelift: packagist/doctrine%2Fcache custom: https://www.doctrine-project.org/sponsorship.html php-doctrine-cache-1.10.0/.gitignore000066400000000000000000000000751357065157100172320ustar00rootroot00000000000000vendor/ build/ phpunit.xml clover.xml .phpcs-cache phpcs.xml php-doctrine-cache-1.10.0/.scrutinizer.yml000066400000000000000000000015461357065157100204300ustar00rootroot00000000000000build: environment: php: version: 7.1.0 tests: override: - php-scrutinizer-run - phpcs-run dependencies: before: - pecl install mongodb override: - rm composer.lock - composer update --no-interaction --prefer-dist tools: external_code_coverage: timeout: 1800 php_code_coverage: enabled: true php_cpd: enabled: true excluded_dirs: ["vendor"] php_loc: enabled: true excluded_dirs: ["vendor"] php_mess_detector: enabled: true filter: paths: ["lib/*"] php_pdepend: enabled: true excluded_dirs: ["vendor"] php_analyzer: enabled: true filter: paths: ["lib/*", "tests/*"] sensiolabs_security_checker: true php-doctrine-cache-1.10.0/.travis.yml000066400000000000000000000025301357065157100173510ustar00rootroot00000000000000dist: xenial sudo: false language: php cache: directories: - $HOME/.composer/cache php: - 7.1 - 7.2 - 7.3 - 7.4snapshot services: - mongodb - memcached - redis-server - docker before_install: - pecl channel-update pecl.php.net - pecl config-set preferred_state beta - echo yes | pecl upgrade apcu - mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{,.disabled} || echo "xdebug not available" - phpenv config-add ./tests/travis/php.ini install: - rm composer.lock - travis_retry composer update --no-interaction --prefer-dist script: ./vendor/bin/phpunit --exclude-group performance jobs: include: - stage: Coding standard install: - travis_retry composer install --no-interaction --prefer-dist --ignore-platform-reqs script: - ./vendor/bin/phpcs - stage: Coverage before_script: - mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{.disabled,} - if [[ ! $(php -m | grep -si xdebug) ]]; then echo "xdebug required for coverage"; exit 1; fi script: - ./vendor/bin/phpunit --exclude-group performance --coverage-clover clover.xml after_script: - wget https://scrutinizer-ci.com/ocular.phar - php ocular.phar code-coverage:upload --format=php-clover clover.xml php-doctrine-cache-1.10.0/LICENSE000066400000000000000000000020511357065157100162430ustar00rootroot00000000000000Copyright (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. php-doctrine-cache-1.10.0/README.md000066400000000000000000000016651357065157100165270ustar00rootroot00000000000000# Doctrine Cache [![Build Status](https://img.shields.io/travis/doctrine/cache/master.svg?style=flat-square)](http://travis-ci.org/doctrine/cache) [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/doctrine/cache/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/doctrine/cache/?branch=master) [![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/doctrine/cache/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/doctrine/cache/?branch=master) [![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-orm/en/current/reference/caching.html) php-doctrine-cache-1.10.0/UPGRADE.md000066400000000000000000000013261357065157100166530ustar00rootroot00000000000000# 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. php-doctrine-cache-1.10.0/build.properties000066400000000000000000000002171357065157100204550ustar00rootroot00000000000000# Version class and file project.version_class = Doctrine\\Common\\Cache\\Version project.version_file = lib/Doctrine/Common/Cache/Version.php php-doctrine-cache-1.10.0/build.xml000066400000000000000000000100441357065157100170600ustar00rootroot00000000000000 php-doctrine-cache-1.10.0/composer.json000066400000000000000000000031121357065157100177570ustar00rootroot00000000000000{ "name": "doctrine/cache", "type": "library", "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", "keywords": [ "php", "cache", "caching", "abstraction", "redis", "memcached", "couchdb", "xcache", "apcu" ], "homepage": "https://www.doctrine-project.org/projects/cache.html", "license": "MIT", "authors": [ {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, {"name": "Roman Borschel", "email": "roman@code-factory.org"}, {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, {"name": "Jonathan Wage", "email": "jonwage@gmail.com"}, {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} ], "require": { "php": "~7.1" }, "require-dev": { "alcaeus/mongo-php-adapter": "^1.1", "mongodb/mongodb": "^1.1", "phpunit/phpunit": "^7.0", "predis/predis": "~1.0", "doctrine/coding-standard": "^6.0" }, "suggest": { "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" }, "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" } }, "extra": { "branch-alias": { "dev-master": "1.9.x-dev" } } } php-doctrine-cache-1.10.0/composer.lock000066400000000000000000002012771357065157100177520ustar00rootroot00000000000000{ "_readme": [ "This file locks the dependencies of your project to a known state", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], "content-hash": "743f7be1cafff709ad2e18acea708bd7", "packages": [], "packages-dev": [ { "name": "alcaeus/mongo-php-adapter", "version": "1.1.5", "source": { "type": "git", "url": "https://github.com/alcaeus/mongo-php-adapter.git", "reference": "4f21e1fdc21eee0e35bdaf854ecc3c58179d1ef7" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/alcaeus/mongo-php-adapter/zipball/4f21e1fdc21eee0e35bdaf854ecc3c58179d1ef7", "reference": "4f21e1fdc21eee0e35bdaf854ecc3c58179d1ef7", "shasum": "" }, "require": { "ext-hash": "*", "ext-mongodb": "^1.2.0", "mongodb/mongodb": "^1.0.1", "php": "^5.6 || ^7.0" }, "provide": { "ext-mongo": "1.6.14" }, "require-dev": { "phpunit/phpunit": "^5.7.27 || ^6.0 || ^7.0", "squizlabs/php_codesniffer": "^3.2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1.x-dev" } }, "autoload": { "psr-0": { "Mongo": "lib/Mongo" }, "psr-4": { "Alcaeus\\MongoDbAdapter\\": "lib/Alcaeus/MongoDbAdapter" }, "files": [ "lib/Mongo/functions.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "alcaeus", "email": "alcaeus@alcaeus.org" }, { "name": "Olivier Lechevalier", "email": "olivier.lechevalier@gmail.com" } ], "description": "Adapter to provide ext-mongo interface on top of mongo-php-libary", "keywords": [ "database", "mongodb" ], "time": "2018-03-05T20:40:55+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", "version": "v0.5.0", "source": { "type": "git", "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", "reference": "e749410375ff6fb7a040a68878c656c2e610b132" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132", "reference": "e749410375ff6fb7a040a68878c656c2e610b132", "shasum": "" }, "require": { "composer-plugin-api": "^1.0", "php": "^5.3|^7", "squizlabs/php_codesniffer": "^2|^3" }, "require-dev": { "composer/composer": "*", "phpcompatibility/php-compatibility": "^9.0", "sensiolabs/security-checker": "^4.1.0" }, "type": "composer-plugin", "extra": { "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" }, "autoload": { "psr-4": { "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Franck Nijhof", "email": "franck.nijhof@dealerdirect.com", "homepage": "http://www.frenck.nl", "role": "Developer / IT Manager" } ], "description": "PHP_CodeSniffer Standards Composer Installer Plugin", "homepage": "http://www.dealerdirect.com", "keywords": [ "PHPCodeSniffer", "PHP_CodeSniffer", "code quality", "codesniffer", "composer", "installer", "phpcs", "plugin", "qa", "quality", "standard", "standards", "style guide", "stylecheck", "tests" ], "time": "2018-10-26T13:21:45+00:00" }, { "name": "doctrine/coding-standard", "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/coding-standard.git", "reference": "d33f69eb98b25aa51ffe3a909f0ec77000af4701" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/coding-standard/zipball/d33f69eb98b25aa51ffe3a909f0ec77000af4701", "reference": "d33f69eb98b25aa51ffe3a909f0ec77000af4701", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", "php": "^7.1", "slevomat/coding-standard": "^5.0", "squizlabs/php_codesniffer": "^3.4.0" }, "type": "phpcodesniffer-standard", "extra": { "branch-alias": { "dev-master": "6.0.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Sniffs\\": "lib/Doctrine/Sniffs" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Steve Müller", "email": "st.mueller@dzh-online.de" } ], "description": "The Doctrine Coding Standard is a set of PHPCS rules applied to all Doctrine projects.", "homepage": "https://www.doctrine-project.org/projects/coding-standard.html", "keywords": [ "checks", "code", "coding", "cs", "doctrine", "rules", "sniffer", "sniffs", "standard", "style" ], "time": "2019-03-15T12:45:47+00:00" }, { "name": "doctrine/instantiator", "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "athletic/athletic": "~0.1.8", "ext-pdo": "*", "ext-phar": "*", "phpunit/phpunit": "^6.2.3", "squizlabs/php_codesniffer": "^3.0.2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.2.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", "homepage": "http://ocramius.github.com/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", "homepage": "https://github.com/doctrine/instantiator", "keywords": [ "constructor", "instantiate" ], "time": "2017-07-22T11:58:36+00:00" }, { "name": "mongodb/mongodb", "version": "1.3.2", "source": { "type": "git", "url": "https://github.com/mongodb/mongo-php-library.git", "reference": "b9f35916125976533f4b1e67a4a0ee7baf1d3bb9" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/b9f35916125976533f4b1e67a4a0ee7baf1d3bb9", "reference": "b9f35916125976533f4b1e67a4a0ee7baf1d3bb9", "shasum": "" }, "require": { "ext-hash": "*", "ext-json": "*", "ext-mongodb": "^1.4.0", "php": ">=5.5" }, "require-dev": { "phpunit/phpunit": "^4.8.36 || ^6.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.3.x-dev" } }, "autoload": { "psr-4": { "MongoDB\\": "src/" }, "files": [ "src/functions.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "authors": [ { "name": "Jeremy Mikola", "email": "jmikola@gmail.com" }, { "name": "Derick Rethans", "email": "github@derickrethans.nl" }, { "name": "Katherine Walker", "email": "katherine.walker@mongodb.com" } ], "description": "MongoDB driver library", "homepage": "https://jira.mongodb.org/browse/PHPLIB", "keywords": [ "database", "driver", "mongodb", "persistence" ], "time": "2018-04-19T17:20:30+00:00" }, { "name": "myclabs/deep-copy", "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", "reference": "478465659fd987669df0bd8a9bf22a8710e5f1b6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/478465659fd987669df0bd8a9bf22a8710e5f1b6", "reference": "478465659fd987669df0bd8a9bf22a8710e5f1b6", "shasum": "" }, "require": { "php": "^7.1" }, "replace": { "myclabs/deep-copy": "self.version" }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", "phpunit/phpunit": "^7.1" }, "type": "library", "autoload": { "psr-4": { "DeepCopy\\": "src/DeepCopy/" }, "files": [ "src/DeepCopy/deep_copy.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Create deep copies (clones) of your objects", "keywords": [ "clone", "copy", "duplicate", "object", "object graph" ], "time": "2018-05-29T17:25:09+00:00" }, { "name": "phar-io/manifest", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", "phar-io/version": "^1.0.1", "php": "^5.6 || ^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" }, { "name": "Sebastian Heuer", "email": "sebastian@phpeople.de", "role": "Developer" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "Developer" } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "time": "2017-03-05T18:14:27+00:00" }, { "name": "phar-io/version", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", "shasum": "" }, "require": { "php": "^5.6 || ^7.0" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" }, { "name": "Sebastian Heuer", "email": "sebastian@phpeople.de", "role": "Developer" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "Developer" } ], "description": "Library for handling version information and constraints", "time": "2017-03-05T17:38:23+00:00" }, { "name": "phpdocumentor/reflection-common", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", "shasum": "" }, "require": { "php": ">=5.5" }, "require-dev": { "phpunit/phpunit": "^4.6" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ "src" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Jaap van Otterdijk", "email": "opensource@ijaap.nl" } ], "description": "Common reflection classes used by phpdocumentor to reflect the code structure", "homepage": "http://www.phpdoc.org", "keywords": [ "FQSEN", "phpDocumentor", "phpdoc", "reflection", "static analysis" ], "time": "2017-09-11T18:02:19+00:00" }, { "name": "phpdocumentor/reflection-docblock", "version": "4.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", "reference": "94fd0001232e47129dd3504189fa1c7225010d08" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", "reference": "94fd0001232e47129dd3504189fa1c7225010d08", "shasum": "" }, "require": { "php": "^7.0", "phpdocumentor/reflection-common": "^1.0.0", "phpdocumentor/type-resolver": "^0.4.0", "webmozart/assert": "^1.0" }, "require-dev": { "doctrine/instantiator": "~1.0.5", "mockery/mockery": "^1.0", "phpunit/phpunit": "^6.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ "src/" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "time": "2017-11-30T07:14:17+00:00" }, { "name": "phpdocumentor/type-resolver", "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", "shasum": "" }, "require": { "php": "^5.5 || ^7.0", "phpdocumentor/reflection-common": "^1.0" }, "require-dev": { "mockery/mockery": "^0.9.4", "phpunit/phpunit": "^5.2||^4.8.24" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ "src/" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" } ], "time": "2017-07-14T14:27:02+00:00" }, { "name": "phpspec/prophecy", "version": "1.7.6", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", "sebastian/comparator": "^1.1|^2.0|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.7.x-dev" } }, "autoload": { "psr-0": { "Prophecy\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Konstantin Kudryashov", "email": "ever.zet@gmail.com", "homepage": "http://everzet.com" }, { "name": "Marcello Duarte", "email": "marcello.duarte@gmail.com" } ], "description": "Highly opinionated mocking framework for PHP 5.3+", "homepage": "https://github.com/phpspec/prophecy", "keywords": [ "Double", "Dummy", "fake", "mock", "spy", "stub" ], "time": "2018-04-18T13:57:24+00:00" }, { "name": "phpstan/phpdoc-parser", "version": "0.3.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/2cc49f47c69b023eaf05b48e6529389893b13d74", "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74", "shasum": "" }, "require": { "php": "~7.1" }, "require-dev": { "consistence/coding-standard": "^2.0.0", "jakub-onderka/php-parallel-lint": "^0.9.2", "phing/phing": "^2.16.0", "phpstan/phpstan": "^0.10", "phpunit/phpunit": "^6.3", "slevomat/coding-standard": "^3.3.0", "symfony/process": "^3.4 || ^4.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "0.3-dev" } }, "autoload": { "psr-4": { "PHPStan\\PhpDocParser\\": [ "src/" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "PHPDoc parser with support for nullable, intersection and generic types", "time": "2019-01-14T12:26:23+00:00" }, { "name": "phpunit/php-code-coverage", "version": "6.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a", "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", "php": "^7.1", "phpunit/php-file-iterator": "^2.0", "phpunit/php-text-template": "^1.2.1", "phpunit/php-token-stream": "^3.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", "sebastian/environment": "^3.1", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, "require-dev": { "phpunit/phpunit": "^7.0" }, "suggest": { "ext-xdebug": "^2.6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "6.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ "coverage", "testing", "xunit" ], "time": "2018-06-01T07:51:50+00:00" }, { "name": "phpunit/php-file-iterator", "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", "reference": "e20525b0c2945c7c317fff95660698cb3d2a53bc" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/e20525b0c2945c7c317fff95660698cb3d2a53bc", "reference": "e20525b0c2945c7c317fff95660698cb3d2a53bc", "shasum": "" }, "require": { "php": "^7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "FilterIterator implementation that filters files based on a list of suffixes.", "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ "filesystem", "iterator" ], "time": "2018-05-28T12:13:49+00:00" }, { "name": "phpunit/php-text-template", "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "shasum": "" }, "require": { "php": ">=5.3.3" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Simple template engine.", "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ "template" ], "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Utility class for timing", "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ "timer" ], "time": "2018-02-01T13:07:23+00:00" }, { "name": "phpunit/php-token-stream", "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Wrapper around PHP's tokenizer extension.", "homepage": "https://github.com/sebastianbergmann/php-token-stream/", "keywords": [ "tokenizer" ], "time": "2018-02-01T13:16:43+00:00" }, { "name": "phpunit/phpunit", "version": "7.2.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", "reference": "42bb8f5b2cb36483907a20f45e4cd1665c24d8a7" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/42bb8f5b2cb36483907a20f45e4cd1665c24d8a7", "reference": "42bb8f5b2cb36483907a20f45e4cd1665c24d8a7", "shasum": "" }, "require": { "doctrine/instantiator": "^1.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "myclabs/deep-copy": "^1.7", "phar-io/manifest": "^1.0.1", "phar-io/version": "^1.0", "php": "^7.1", "phpspec/prophecy": "^1.7", "phpunit/php-code-coverage": "^6.0.7", "phpunit/php-file-iterator": "^2.0", "phpunit/php-text-template": "^1.2.1", "phpunit/php-timer": "^2.0", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", "sebastian/environment": "^3.1", "sebastian/exporter": "^3.1", "sebastian/global-state": "^2.0", "sebastian/object-enumerator": "^3.0.3", "sebastian/resource-operations": "^1.0", "sebastian/version": "^2.0.1" }, "conflict": { "phpunit/phpunit-mock-objects": "*" }, "require-dev": { "ext-pdo": "*" }, "suggest": { "ext-soap": "*", "ext-xdebug": "*", "phpunit/php-invoker": "^2.0" }, "bin": [ "phpunit" ], "type": "library", "extra": { "branch-alias": { "dev-master": "7.2-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "The PHP Unit Testing framework.", "homepage": "https://phpunit.de/", "keywords": [ "phpunit", "testing", "xunit" ], "time": "2018-06-03T06:05:05+00:00" }, { "name": "predis/predis", "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/nrk/predis.git", "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nrk/predis/zipball/f0210e38881631afeafb56ab43405a92cafd9fd1", "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1", "shasum": "" }, "require": { "php": ">=5.3.9" }, "require-dev": { "phpunit/phpunit": "~4.8" }, "suggest": { "ext-curl": "Allows access to Webdis when paired with phpiredis", "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol" }, "type": "library", "autoload": { "psr-4": { "Predis\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Daniele Alessandri", "email": "suppakilla@gmail.com", "homepage": "http://clorophilla.net" } ], "description": "Flexible and feature-complete Redis client for PHP and HHVM", "homepage": "http://github.com/nrk/predis", "keywords": [ "nosql", "predis", "redis" ], "time": "2016-06-16T16:22:20+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", "shasum": "" }, "require": { "php": "^5.6 || ^7.0" }, "require-dev": { "phpunit/phpunit": "^5.7 || ^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "time": "2017-03-04T06:30:41+00:00" }, { "name": "sebastian/comparator", "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ed5fd2281113729f1ebcc64d101ad66028aeb3d5", "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5", "shasum": "" }, "require": { "php": "^7.1", "sebastian/diff": "^3.0", "sebastian/exporter": "^3.1" }, "require-dev": { "phpunit/phpunit": "^7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", "equality" ], "time": "2018-04-18T13:33:00+00:00" }, { "name": "sebastian/diff", "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/e09160918c66281713f1c324c1f4c4c3037ba1e8", "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.0", "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Kore Nordmann", "email": "mail@kore-nordmann.de" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff", "udiff", "unidiff", "unified diff" ], "time": "2018-02-01T13:45:15+00:00" }, { "name": "sebastian/environment", "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", "shasum": "" }, "require": { "php": "^7.0" }, "require-dev": { "phpunit/phpunit": "^6.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.1.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides functionality to handle HHVM/PHP environments", "homepage": "http://www.github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", "hhvm" ], "time": "2017-07-01T08:51:00+00:00" }, { "name": "sebastian/exporter", "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", "shasum": "" }, "require": { "php": "^7.0", "sebastian/recursion-context": "^3.0" }, "require-dev": { "ext-mbstring": "*", "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.1.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Adam Harvey", "email": "aharvey@php.net" } ], "description": "Provides the functionality to export PHP variables for visualization", "homepage": "http://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "time": "2017-04-03T13:19:02+00:00" }, { "name": "sebastian/global-state", "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "shasum": "" }, "require": { "php": "^7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "suggest": { "ext-uopz": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Snapshotting of global state", "homepage": "http://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "time": "2017-04-27T15:39:26+00:00" }, { "name": "sebastian/object-enumerator", "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", "shasum": "" }, "require": { "php": "^7.0", "sebastian/object-reflector": "^1.1.1", "sebastian/recursion-context": "^3.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "time": "2017-08-03T12:35:26+00:00" }, { "name": "sebastian/object-reflector", "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", "reference": "773f97c67f28de00d397be301821b06708fca0be" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", "reference": "773f97c67f28de00d397be301821b06708fca0be", "shasum": "" }, "require": { "php": "^7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", "time": "2017-03-29T09:07:27+00:00" }, { "name": "sebastian/recursion-context", "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", "shasum": "" }, "require": { "php": "^7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Adam Harvey", "email": "aharvey@php.net" } ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "time": "2017-03-03T06:23:57+00:00" }, { "name": "sebastian/resource-operations", "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", "shasum": "" }, "require": { "php": ">=5.6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "time": "2015-07-28T20:34:47+00:00" }, { "name": "sebastian/version", "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, "require": { "php": ">=5.6" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03T07:35:21+00:00" }, { "name": "slevomat/coding-standard", "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", "reference": "223f02b6193fe47b7b483bfa5bf75693535482dd" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/223f02b6193fe47b7b483bfa5bf75693535482dd", "reference": "223f02b6193fe47b7b483bfa5bf75693535482dd", "shasum": "" }, "require": { "php": "^7.1", "phpstan/phpdoc-parser": "^0.3.1", "squizlabs/php_codesniffer": "^3.4.0" }, "require-dev": { "jakub-onderka/php-parallel-lint": "1.0.0", "phing/phing": "2.16.1", "phpstan/phpstan": "0.11.1", "phpstan/phpstan-phpunit": "0.11", "phpstan/phpstan-strict-rules": "0.11", "phpunit/phpunit": "8.0.0" }, "type": "phpcodesniffer-standard", "autoload": { "psr-4": { "SlevomatCodingStandard\\": "SlevomatCodingStandard" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", "time": "2019-03-12T20:26:36+00:00" }, { "name": "squizlabs/php_codesniffer", "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", "reference": "379deb987e26c7cd103a7b387aea178baec96e48" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/379deb987e26c7cd103a7b387aea178baec96e48", "reference": "379deb987e26c7cd103a7b387aea178baec96e48", "shasum": "" }, "require": { "ext-simplexml": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", "php": ">=5.4.0" }, "require-dev": { "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "bin": [ "bin/phpcs", "bin/phpcbf" ], "type": "library", "extra": { "branch-alias": { "dev-master": "3.x-dev" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Greg Sherwood", "role": "lead" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", "homepage": "http://www.squizlabs.com/php-codesniffer", "keywords": [ "phpcs", "standards" ], "time": "2018-12-19T23:57:18+00:00" }, { "name": "theseer/tokenizer", "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", "php": "^7.0" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "time": "2017-04-07T12:08:54+00:00" }, { "name": "webmozart/assert", "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", "reference": "0df1908962e7a3071564e857d86874dad1ef204a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", "reference": "0df1908962e7a3071564e857d86874dad1ef204a", "shasum": "" }, "require": { "php": "^5.3.3 || ^7.0" }, "require-dev": { "phpunit/phpunit": "^4.6", "sebastian/version": "^1.0.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.3-dev" } }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "Assertions to validate method input/output with nice error messages.", "keywords": [ "assert", "check", "validate" ], "time": "2018-01-29T19:49:41+00:00" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { "php": "~7.1" }, "platform-dev": [] } php-doctrine-cache-1.10.0/docs/000077500000000000000000000000001357065157100161705ustar00rootroot00000000000000php-doctrine-cache-1.10.0/docs/en/000077500000000000000000000000001357065157100165725ustar00rootroot00000000000000php-doctrine-cache-1.10.0/docs/en/index.rst000066400000000000000000000151461357065157100204420ustar00rootroot00000000000000Introduction ============ Doctrine Cache is a library that provides an interface for caching data. It comes with implementations for some of the most popular caching data stores. 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(); } Here is an example that uses Memcache. .. code-block:: php use Doctrine\Common\Cache\MemcacheCache; $memcache = new Memcache(); $cache = new MemcacheCache(); $cache->setMemcache($memcache); $cache->set('key', 'value'); echo $cache->get('key') // prints "value" Drivers ======= Doctrine ships with several common drivers that you can easily use. Below you can find information about all the available drivers. ApcCache -------- The ``ApcCache`` driver uses the ``apc_fetch``, ``apc_exists``, etc. functions that come with PHP so no additional setup is required in order to use it. .. code-block:: php $cache = new ApcCache(); ApcuCache --------- The ``ApcuCache`` driver uses the ``apcu_fetch``, ``apcu_exists``, etc. functions that come with PHP so no additional setup is required in order to use it. .. code-block:: php $cache = new ApcuCache(); ArrayCache ---------- The ``ArrayCache`` driver stores the cache data in PHPs memory and is not persisted anywhere. This can be useful for caching things in memory for a single process when you don't need the cache to be persistent across processes. .. code-block:: php $cache = new ArrayCache(); ChainCache ---------- The ``ChainCache`` driver lets you chain multiple other drivers together easily. .. code-block:: php $arrayCache = new ArrayCache(); $apcuCache = new ApcuCache(); $cache = new ChainCache([$arrayCache, $apcuCache]); CouchbaseBucketCache -------------------- The ``CouchbaseBucketCache`` driver uses Couchbase to store the cache data. .. code-block:: php $bucketName = 'bucket-name'; $authenticator = new Couchbase\PasswordAuthenticator(); $authenticator->username('username')->password('password'); $cluster = new CouchbaseCluster('couchbase://127.0.0.1'); $cluster->authenticate($authenticator); $bucket = $cluster->openBucket($bucketName); $cache = new CouchbaseBucketCache($bucket); FilesystemCache --------------- The ``FilesystemCache`` driver stores the cache data on the local filesystem. .. code-block:: php $cache = new FilesystemCache('/path/to/cache/directory'); MemcacheCache ------------- The ``MemcacheCache`` drivers stores the cache data in Memcache. .. code-block:: php $memcache = new Memcache(); $memcache->connect('localhost', 11211); $cache = new MemcacheCache(); $cache->setMemcache($memcache); MemcachedCache -------------- The ``MemcachedCache`` drivers stores the cache data in Memcached. .. code-block:: php $memcached = new Memcached(); $cache = new MemcachedCache(); $cache->setMemcached($memcached); MongoDBCache ------------ The ``MongoDBCache`` drivers stores the cache data in a MongoDB collection. .. code-block:: php $manager = new MongoDB\Driver\Manager("mongodb://localhost:27017"); $collection = new MongoDB\Collection($manager, 'database_name', 'collection_name'); $cache = new MongoDBCache($collection); PhpFileCache ------------ The ``PhpFileCache`` driver stores the cache data on the local filesystem like the ``FilesystemCache`` driver except the data is serialized using the ``serialize()`` and ``unserialize()`` functions available in PHP. The files are included so this means that the data can be cached in PHPs opcache. .. code-block:: php $cache = new PhpFileCache('/path/to/cache/directory'); PredisCache ----------- The ``PredisCache`` driver stores the cache data in Redis and depends on the ``predis/predis`` package which can be installed with composer. .. code-block:: bash $ composer require predis/predis Then you can use the ``Predis\Client`` class to pass to the ``PredisCache`` class. .. code-block:: php $client = new Predis\Client(); $cache = new PredisCache($client); RedisCache ---------- The ``RedisCache`` driver stores the cache data in Redis and depends on the ``phpredis`` extension which can be found `here `_. .. code-block:: php $redis = new Redis(); $cache = new RedisCache($redis); SQLite3Cache ------------ The ``SQLite3Cache`` driver stores the cache data in a SQLite database and depends on the ``sqlite3`` extension which can be found `here `_. .. code-block:: php $db = new SQLite3('mydatabase.db'); $cache = new SQLite3Cache($db, 'table_name'); VoidCache --------- The ``VoidCache`` driver does not store the cache data anywhere. This can be useful for test environments where you don't want to cache the data anywhere but need to satisfy the dependency for the ``Doctrine\Common\Cache\Cache`` interface. .. code-block:: php $cache = new VoidCache(); WinCacheCache ------------- The ``WinCacheCache`` driver uses the ``wincache_ucache_get``, ``wincache_ucache_exists``, etc. functions that come with the ``wincache`` extension which can be found `here `_. .. code-block:: php $cache = new WinCacheCache(); XcacheCache ----------- The ``XcacheCache`` driver uses functions that come with the ``xcache`` extension which can be found `here `_. .. code-block:: php $cache = new XcacheCache(); ZendDataCache ------------- The ``ZendDataCache`` driver uses the Zend Data Cache API available in the Zend Platform. .. code-block:: php $cache = new ZendDataCache(); Custom Drivers ============== If you want to implement your own cache driver, you just need to implement the ``Doctrine\Common\Cache\Cache`` interface. Here is an example implementation skeleton. .. code-block:: php use Doctrine\Common\Cache\Cache; class MyCacheDriver implements Cache { public function fetch($id) { // fetch $id from the cache } public function contains($id) { // check if $id exists in the cache } public function save($id, $data, $lifeTime = 0) { // save $data under $id in the cache for $lifetime } public function delete($id) { // delete $id from the cache } public function getStats() { // get cache stats } } php-doctrine-cache-1.10.0/lib/000077500000000000000000000000001357065157100160065ustar00rootroot00000000000000php-doctrine-cache-1.10.0/lib/Doctrine/000077500000000000000000000000001357065157100175555ustar00rootroot00000000000000php-doctrine-cache-1.10.0/lib/Doctrine/Common/000077500000000000000000000000001357065157100210055ustar00rootroot00000000000000php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/000077500000000000000000000000001357065157100220105ustar00rootroot00000000000000php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/ApcCache.php000066400000000000000000000045201357065157100241510ustar00rootroot00000000000000= 50500) { $info['num_hits'] = $info['num_hits'] ?? $info['nhits']; $info['num_misses'] = $info['num_misses'] ?? $info['nmisses']; $info['start_time'] = $info['start_time'] ?? $info['stime']; } return [ Cache::STATS_HITS => $info['num_hits'], Cache::STATS_MISSES => $info['num_misses'], Cache::STATS_UPTIME => $info['start_time'], Cache::STATS_MEMORY_USAGE => $info['mem_size'], Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'], ]; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/ApcuCache.php000066400000000000000000000041701357065157100243370ustar00rootroot00000000000000 $info['num_hits'], Cache::STATS_MISSES => $info['num_misses'], Cache::STATS_UPTIME => $info['start_time'], Cache::STATS_MEMORY_USAGE => $info['mem_size'], Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'], ]; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/ArrayCache.php000066400000000000000000000040351357065157100245250ustar00rootroot00000000000000upTime = 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, ]; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/Cache.php000066400000000000000000000053551357065157100235340ustar00rootroot00000000000000hits * Number of keys that have been requested and found present. * * - misses * Number of items that have been requested and not found. * * - uptime * Time that the server is running. * * - memory_usage * Memory used by this server to store items. * * - memory_available * Memory allowed to use for storage. * * @return array|null An associative array with server's statistics if available, NULL otherwise. */ public function getStats(); } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/CacheProvider.php000066400000000000000000000204161357065157100252420ustar00rootroot00000000000000namespace = (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 array $keys Array of keys to retrieve from cache * * @return array 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 array $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 array $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 array|null An associative array with server's statistics if available, NULL otherwise. */ abstract protected function doGetStats(); } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/ChainCache.php000066400000000000000000000105071357065157100244720ustar00rootroot00000000000000cacheProviders = $cacheProviders instanceof Traversable ? iterator_to_array($cacheProviders, false) : array_values($cacheProviders); } /** * {@inheritDoc} */ public function setNamespace($namespace) { parent::setNamespace($namespace); foreach ($this->cacheProviders as $cacheProvider) { $cacheProvider->setNamespace($namespace); } } /** * {@inheritDoc} */ protected function doFetch($id) { foreach ($this->cacheProviders as $key => $cacheProvider) { if ($cacheProvider->doContains($id)) { $value = $cacheProvider->doFetch($id); // We populate all the previous cache layers (that are assumed to be faster) for ($subKey = $key - 1; $subKey >= 0; $subKey--) { $this->cacheProviders[$subKey]->doSave($id, $value); } return $value; } } return false; } /** * {@inheritdoc} */ protected function doFetchMultiple(array $keys) { /** @var CacheProvider[] $traversedProviders */ $traversedProviders = []; $keysCount = count($keys); $fetchedValues = []; foreach ($this->cacheProviders as $key => $cacheProvider) { $fetchedValues = $cacheProvider->doFetchMultiple($keys); // We populate all the previous cache layers (that are assumed to be faster) if (count($fetchedValues) === $keysCount) { foreach ($traversedProviders as $previousCacheProvider) { $previousCacheProvider->doSaveMultiple($fetchedValues); } return $fetchedValues; } $traversedProviders[] = $cacheProvider; } return $fetchedValues; } /** * {@inheritDoc} */ protected function doContains($id) { foreach ($this->cacheProviders as $cacheProvider) { if ($cacheProvider->doContains($id)) { return true; } } return false; } /** * {@inheritDoc} */ protected function doSave($id, $data, $lifeTime = 0) { $stored = true; foreach ($this->cacheProviders as $cacheProvider) { $stored = $cacheProvider->doSave($id, $data, $lifeTime) && $stored; } return $stored; } /** * {@inheritdoc} */ protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) { $stored = true; foreach ($this->cacheProviders as $cacheProvider) { $stored = $cacheProvider->doSaveMultiple($keysAndValues, $lifetime) && $stored; } return $stored; } /** * {@inheritDoc} */ protected function doDelete($id) { $deleted = true; foreach ($this->cacheProviders as $cacheProvider) { $deleted = $cacheProvider->doDelete($id) && $deleted; } return $deleted; } /** * {@inheritdoc} */ protected function doDeleteMultiple(array $keys) { $deleted = true; foreach ($this->cacheProviders as $cacheProvider) { $deleted = $cacheProvider->doDeleteMultiple($keys) && $deleted; } return $deleted; } /** * {@inheritDoc} */ protected function doFlush() { $flushed = true; foreach ($this->cacheProviders as $cacheProvider) { $flushed = $cacheProvider->doFlush() && $flushed; } return $flushed; } /** * {@inheritDoc} */ protected function doGetStats() { // We return all the stats from all adapters $stats = []; foreach ($this->cacheProviders as $cacheProvider) { $stats[] = $cacheProvider->doGetStats(); } return $stats; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/ClearableCache.php000066400000000000000000000007651357065157100253270ustar00rootroot00000000000000bucket = $bucket; } /** * {@inheritdoc} */ protected function doFetch($id) { $id = $this->normalizeKey($id); try { $document = $this->bucket->get($id); } catch (Exception $e) { return false; } if ($document instanceof Document && $document->value !== false) { return unserialize($document->value); } return false; } /** * {@inheritdoc} */ protected function doContains($id) { $id = $this->normalizeKey($id); try { $document = $this->bucket->get($id); } catch (Exception $e) { return false; } if ($document instanceof Document) { return ! $document->error; } return false; } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { $id = $this->normalizeKey($id); $lifeTime = $this->normalizeExpiry($lifeTime); try { $encoded = serialize($data); $document = $this->bucket->upsert($id, $encoded, [ 'expiry' => (int) $lifeTime, ]); } catch (Exception $e) { return false; } if ($document instanceof Document) { return ! $document->error; } return false; } /** * {@inheritdoc} */ protected function doDelete($id) { $id = $this->normalizeKey($id); try { $document = $this->bucket->remove($id); } catch (Exception $e) { return $e->getCode() === self::KEY_NOT_FOUND; } if ($document instanceof Document) { return ! $document->error; } return false; } /** * {@inheritdoc} */ protected function doFlush() { $manager = $this->bucket->manager(); // Flush does not return with success or failure, and must be enabled per bucket on the server. // Store a marker item so that we will know if it was successful. $this->doSave(__METHOD__, true, 60); $manager->flush(); if ($this->doContains(__METHOD__)) { $this->doDelete(__METHOD__); return false; } return true; } /** * {@inheritdoc} */ protected function doGetStats() { $manager = $this->bucket->manager(); $stats = $manager->info(); $nodes = $stats['nodes']; $node = $nodes[0]; $interestingStats = $node['interestingStats']; return [ Cache::STATS_HITS => $interestingStats['get_hits'], Cache::STATS_MISSES => $interestingStats['cmd_get'] - $interestingStats['get_hits'], Cache::STATS_UPTIME => $node['uptime'], Cache::STATS_MEMORY_USAGE => $interestingStats['mem_used'], Cache::STATS_MEMORY_AVAILABLE => $node['memoryFree'], ]; } private function normalizeKey(string $id) : string { $normalized = substr($id, 0, self::MAX_KEY_LENGTH); if ($normalized === false) { return $id; } return $normalized; } /** * Expiry treated as a unix timestamp instead of an offset if expiry is greater than 30 days. * * @src https://developer.couchbase.com/documentation/server/4.1/developer-guide/expiry.html */ private function normalizeExpiry(int $expiry) : int { if ($expiry > self::THIRTY_DAYS_IN_SECONDS) { return time() + $expiry; } return $expiry; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/CouchbaseCache.php000066400000000000000000000044201357065157100253410ustar00rootroot00000000000000couchbase = $couchbase; } /** * Gets the Couchbase instance used by the cache. * * @return Couchbase|null */ public function getCouchbase() { return $this->couchbase; } /** * {@inheritdoc} */ protected function doFetch($id) { return $this->couchbase->get($id) ?: false; } /** * {@inheritdoc} */ protected function doContains($id) { return $this->couchbase->get($id) !== null; } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { if ($lifeTime > 30 * 24 * 3600) { $lifeTime = time() + $lifeTime; } return $this->couchbase->set($id, $data, (int) $lifeTime); } /** * {@inheritdoc} */ protected function doDelete($id) { return $this->couchbase->delete($id); } /** * {@inheritdoc} */ protected function doFlush() { return $this->couchbase->flush(); } /** * {@inheritdoc} */ protected function doGetStats() { $stats = $this->couchbase->getStats(); $servers = $this->couchbase->getServers(); $server = explode(':', $servers[0]); $key = $server[0] . ':11210'; $stats = $stats[$key]; return [ Cache::STATS_HITS => $stats['get_hits'], Cache::STATS_MISSES => $stats['get_misses'], Cache::STATS_UPTIME => $stats['uptime'], Cache::STATS_MEMORY_USAGE => $stats['bytes'], Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'], ]; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/ExtMongoDBCache.php000066400000000000000000000123031357065157100254120ustar00rootroot00000000000000collection = $collection->withOptions(['typeMap' => null]); $this->database = new Database($collection->getManager(), $collection->getDatabaseName()); } /** * {@inheritdoc} */ protected function doFetch($id) { $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::DATA_FIELD, MongoDBCache::EXPIRATION_FIELD]); if ($document === null) { return false; } if ($this->isExpired($document)) { $this->createExpirationIndex(); $this->doDelete($id); return false; } return unserialize($document[MongoDBCache::DATA_FIELD]->getData()); } /** * {@inheritdoc} */ protected function doContains($id) { $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::EXPIRATION_FIELD]); if ($document === null) { return false; } if ($this->isExpired($document)) { $this->createExpirationIndex(); $this->doDelete($id); return false; } return true; } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { try { $this->collection->updateOne( ['_id' => $id], [ '$set' => [ MongoDBCache::EXPIRATION_FIELD => ($lifeTime > 0 ? new UTCDateTime((time() + $lifeTime) * 1000): null), MongoDBCache::DATA_FIELD => new Binary(serialize($data), Binary::TYPE_GENERIC), ], ], ['upsert' => true] ); } catch (Exception $e) { return false; } return true; } /** * {@inheritdoc} */ protected function doDelete($id) { try { $this->collection->deleteOne(['_id' => $id]); } catch (Exception $e) { return false; } return true; } /** * {@inheritdoc} */ protected function doFlush() { try { // Use remove() in lieu of drop() to maintain any collection indexes $this->collection->deleteMany([]); } catch (Exception $e) { return false; } return true; } /** * {@inheritdoc} */ protected function doGetStats() { $uptime = null; $memoryUsage = null; try { $serverStatus = $this->database->command([ 'serverStatus' => 1, 'locks' => 0, 'metrics' => 0, 'recordStats' => 0, 'repl' => 0, ])->toArray()[0]; $uptime = $serverStatus['uptime'] ?? null; } catch (Exception $e) { } try { $collStats = $this->database->command(['collStats' => $this->collection->getCollectionName()])->toArray()[0]; $memoryUsage = $collStats['size'] ?? null; } catch (Exception $e) { } return [ Cache::STATS_HITS => null, Cache::STATS_MISSES => null, Cache::STATS_UPTIME => $uptime, Cache::STATS_MEMORY_USAGE => $memoryUsage, Cache::STATS_MEMORY_AVAILABLE => null, ]; } /** * Check if the document is expired. */ private function isExpired(BSONDocument $document) : bool { return isset($document[MongoDBCache::EXPIRATION_FIELD]) && $document[MongoDBCache::EXPIRATION_FIELD] instanceof UTCDateTime && $document[MongoDBCache::EXPIRATION_FIELD]->toDateTime() < new DateTime(); } private function createExpirationIndex() : void { if ($this->expirationIndexCreated) { return; } $this->collection->createIndex([MongoDBCache::EXPIRATION_FIELD => 1], ['background' => true, 'expireAfterSeconds' => 0]); } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/FileCache.php000066400000000000000000000174371357065157100243400ustar00rootroot00000000000000umask = $umask; if (! $this->createPathIfNeeded($directory)) { throw new InvalidArgumentException(sprintf( 'The directory "%s" does not exist and could not be created.', $directory )); } if (! is_writable($directory)) { throw new InvalidArgumentException(sprintf( 'The directory "%s" is not writable.', $directory )); } // YES, this needs to be *after* createPathIfNeeded() $this->directory = realpath($directory); $this->extension = (string) $extension; $this->directoryStringLength = strlen($this->directory); $this->extensionStringLength = strlen($this->extension); $this->isRunningOnWindows = defined('PHP_WINDOWS_VERSION_BUILD'); } /** * Gets the cache directory. * * @return string */ public function getDirectory() { return $this->directory; } /** * Gets the cache file extension. * * @return string */ public function getExtension() { return $this->extension; } /** * @param string $id * * @return string */ protected function getFilename($id) { $hash = hash('sha256', $id); // This ensures that the filename is unique and that there are no invalid chars in it. if ($id === '' || ((strlen($id) * 2 + $this->extensionStringLength) > 255) || ($this->isRunningOnWindows && ($this->directoryStringLength + 4 + strlen($id) * 2 + $this->extensionStringLength) > 258) ) { // Most filesystems have a limit of 255 chars for each path component. On Windows the the whole path is limited // to 260 chars (including terminating null char). Using long UNC ("\\?\" prefix) does not work with the PHP API. // And there is a bug in PHP (https://bugs.php.net/bug.php?id=70943) with path lengths of 259. // So if the id in hex representation would surpass the limit, we use the hash instead. The prefix prevents // collisions between the hash and bin2hex. $filename = '_' . $hash; } else { $filename = bin2hex($id); } return $this->directory . DIRECTORY_SEPARATOR . substr($hash, 0, 2) . DIRECTORY_SEPARATOR . $filename . $this->extension; } /** * {@inheritdoc} */ protected function doDelete($id) { $filename = $this->getFilename($id); return @unlink($filename) || ! file_exists($filename); } /** * {@inheritdoc} */ protected function doFlush() { foreach ($this->getIterator() as $name => $file) { if ($file->isDir()) { // Remove the intermediate directories which have been created to balance the tree. It only takes effect // if the directory is empty. If several caches share the same directory but with different file extensions, // the other ones are not removed. @rmdir($name); } elseif ($this->isFilenameEndingWithExtension($name)) { // If an extension is set, only remove files which end with the given extension. // If no extension is set, we have no other choice than removing everything. @unlink($name); } } return true; } /** * {@inheritdoc} */ protected function doGetStats() { $usage = 0; foreach ($this->getIterator() as $name => $file) { if ($file->isDir() || ! $this->isFilenameEndingWithExtension($name)) { continue; } $usage += $file->getSize(); } $free = disk_free_space($this->directory); return [ Cache::STATS_HITS => null, Cache::STATS_MISSES => null, Cache::STATS_UPTIME => null, Cache::STATS_MEMORY_USAGE => $usage, Cache::STATS_MEMORY_AVAILABLE => $free, ]; } /** * Create path if needed. * * @return bool TRUE on success or if path already exists, FALSE if path cannot be created. */ private function createPathIfNeeded(string $path) : bool { if (! is_dir($path)) { if (@mkdir($path, 0777 & (~$this->umask), true) === false && ! is_dir($path)) { return false; } } return true; } /** * Writes a string content to file in an atomic way. * * @param string $filename Path to the file where to write the data. * @param string $content The content to write * * @return bool TRUE on success, FALSE if path cannot be created, if path is not writable or an any other error. */ protected function writeFile(string $filename, string $content) : bool { $filepath = pathinfo($filename, PATHINFO_DIRNAME); if (! $this->createPathIfNeeded($filepath)) { return false; } if (! is_writable($filepath)) { return false; } $tmpFile = tempnam($filepath, 'swap'); @chmod($tmpFile, 0666 & (~$this->umask)); if (file_put_contents($tmpFile, $content) !== false) { @chmod($tmpFile, 0666 & (~$this->umask)); if (@rename($tmpFile, $filename)) { return true; } @unlink($tmpFile); } return false; } private function getIterator() : Iterator { return new RecursiveIteratorIterator( new RecursiveDirectoryIterator($this->directory, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST ); } /** * @param string $name The filename */ private function isFilenameEndingWithExtension(string $name) : bool { return $this->extension === '' || strrpos($name, $this->extension) === (strlen($name) - $this->extensionStringLength); } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/FilesystemCache.php000066400000000000000000000040151357065157100255710ustar00rootroot00000000000000getFilename($id); if (! is_file($filename)) { return false; } $resource = fopen($filename, 'r'); $line = fgets($resource); if ($line !== false) { $lifetime = (int) $line; } if ($lifetime !== 0 && $lifetime < time()) { fclose($resource); return false; } while (($line = fgets($resource)) !== false) { $data .= $line; } fclose($resource); return unserialize($data); } /** * {@inheritdoc} */ protected function doContains($id) { $lifetime = -1; $filename = $this->getFilename($id); if (! is_file($filename)) { return false; } $resource = fopen($filename, 'r'); $line = fgets($resource); if ($line !== false) { $lifetime = (int) $line; } fclose($resource); return $lifetime === 0 || $lifetime > time(); } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { if ($lifeTime > 0) { $lifeTime = time() + $lifeTime; } $data = serialize($data); $filename = $this->getFilename($id); return $this->writeFile($filename, $lifeTime . PHP_EOL . $data); } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/FlushableCache.php000066400000000000000000000005361357065157100253560ustar00rootroot00000000000000collection = $collection; } /** * {@inheritdoc} */ protected function doFetch($id) { $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::DATA_FIELD, MongoDBCache::EXPIRATION_FIELD]); if ($document === null) { return false; } if ($this->isExpired($document)) { $this->createExpirationIndex(); $this->doDelete($id); return false; } return unserialize($document[MongoDBCache::DATA_FIELD]->bin); } /** * {@inheritdoc} */ protected function doContains($id) { $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::EXPIRATION_FIELD]); if ($document === null) { return false; } if ($this->isExpired($document)) { $this->createExpirationIndex(); $this->doDelete($id); return false; } return true; } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { try { $result = $this->collection->update( ['_id' => $id], [ '$set' => [ MongoDBCache::EXPIRATION_FIELD => ($lifeTime > 0 ? new MongoDate(time() + $lifeTime) : null), MongoDBCache::DATA_FIELD => new MongoBinData(serialize($data), MongoBinData::BYTE_ARRAY), ], ], ['upsert' => true, 'multiple' => false] ); } catch (MongoCursorException $e) { return false; } return ($result['ok'] ?? 1) == 1; } /** * {@inheritdoc} */ protected function doDelete($id) { $result = $this->collection->remove(['_id' => $id]); return ($result['ok'] ?? 1) == 1; } /** * {@inheritdoc} */ protected function doFlush() { // Use remove() in lieu of drop() to maintain any collection indexes $result = $this->collection->remove(); return ($result['ok'] ?? 1) == 1; } /** * {@inheritdoc} */ protected function doGetStats() { $serverStatus = $this->collection->db->command([ 'serverStatus' => 1, 'locks' => 0, 'metrics' => 0, 'recordStats' => 0, 'repl' => 0, ]); $collStats = $this->collection->db->command(['collStats' => 1]); return [ Cache::STATS_HITS => null, Cache::STATS_MISSES => null, Cache::STATS_UPTIME => $serverStatus['uptime'] ?? null, Cache::STATS_MEMORY_USAGE => $collStats['size'] ?? null, Cache::STATS_MEMORY_AVAILABLE => null, ]; } /** * Check if the document is expired. * * @param array $document */ private function isExpired(array $document) : bool { return isset($document[MongoDBCache::EXPIRATION_FIELD]) && $document[MongoDBCache::EXPIRATION_FIELD] instanceof MongoDate && $document[MongoDBCache::EXPIRATION_FIELD]->sec < time(); } private function createExpirationIndex() : void { if ($this->expirationIndexCreated) { return; } $this->expirationIndexCreated = true; $this->collection->createIndex([MongoDBCache::EXPIRATION_FIELD => 1], ['background' => true, 'expireAfterSeconds' => 0]); } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/MemcacheCache.php000066400000000000000000000041101357065157100251430ustar00rootroot00000000000000memcache = $memcache; } /** * Gets the memcache instance used by the cache. * * @return Memcache|null */ public function getMemcache() { return $this->memcache; } /** * {@inheritdoc} */ protected function doFetch($id) { return $this->memcache->get($id); } /** * {@inheritdoc} */ protected function doContains($id) { $flags = null; $this->memcache->get($id, $flags); //if memcache has changed the value of "flags", it means the value exists return $flags !== null; } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { if ($lifeTime > 30 * 24 * 3600) { $lifeTime = time() + $lifeTime; } return $this->memcache->set($id, $data, 0, (int) $lifeTime); } /** * {@inheritdoc} */ protected function doDelete($id) { // Memcache::delete() returns false if entry does not exist return $this->memcache->delete($id) || ! $this->doContains($id); } /** * {@inheritdoc} */ protected function doFlush() { return $this->memcache->flush(); } /** * {@inheritdoc} */ protected function doGetStats() { $stats = $this->memcache->getStats(); return [ Cache::STATS_HITS => $stats['get_hits'], Cache::STATS_MISSES => $stats['get_misses'], Cache::STATS_UPTIME => $stats['uptime'], Cache::STATS_MEMORY_USAGE => $stats['bytes'], Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'], ]; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/MemcachedCache.php000066400000000000000000000074101357065157100253150ustar00rootroot00000000000000memcached = $memcached; } /** * Gets the memcached instance used by the cache. * * @return Memcached|null */ public function getMemcached() { return $this->memcached; } /** * {@inheritdoc} */ protected function doFetch($id) { return $this->memcached->get($id); } /** * {@inheritdoc} */ protected function doFetchMultiple(array $keys) { return $this->memcached->getMulti($keys) ?: []; } /** * {@inheritdoc} */ protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) { foreach (array_keys($keysAndValues) as $id) { $this->validateCacheId($id); } if ($lifetime > 30 * 24 * 3600) { $lifetime = time() + $lifetime; } return $this->memcached->setMulti($keysAndValues, $lifetime); } /** * {@inheritdoc} */ protected function doContains($id) { $this->memcached->get($id); return $this->memcached->getResultCode() === Memcached::RES_SUCCESS; } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { $this->validateCacheId($id); if ($lifeTime > 30 * 24 * 3600) { $lifeTime = time() + $lifeTime; } return $this->memcached->set($id, $data, (int) $lifeTime); } /** * {@inheritdoc} */ protected function doDeleteMultiple(array $keys) { return $this->memcached->deleteMulti($keys) || $this->memcached->getResultCode() === Memcached::RES_NOTFOUND; } /** * {@inheritdoc} */ protected function doDelete($id) { return $this->memcached->delete($id) || $this->memcached->getResultCode() === Memcached::RES_NOTFOUND; } /** * {@inheritdoc} */ protected function doFlush() { return $this->memcached->flush(); } /** * {@inheritdoc} */ protected function doGetStats() { $stats = $this->memcached->getStats(); $servers = $this->memcached->getServerList(); $key = $servers[0]['host'] . ':' . $servers[0]['port']; $stats = $stats[$key]; return [ Cache::STATS_HITS => $stats['get_hits'], Cache::STATS_MISSES => $stats['get_misses'], Cache::STATS_UPTIME => $stats['uptime'], Cache::STATS_MEMORY_USAGE => $stats['bytes'], Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'], ]; } /** * Validate the cache id * * @see https://github.com/memcached/memcached/blob/1.5.12/doc/protocol.txt#L41-L49 * * @param string $id * * @return void * * @throws InvalidCacheId */ private function validateCacheId($id) { if (strlen($id) > self::CACHE_ID_MAX_LENGTH) { throw InvalidCacheId::exceedsMaxLength($id, self::CACHE_ID_MAX_LENGTH); } if (strpos($id, ' ') !== false) { throw InvalidCacheId::containsUnauthorizedCharacter($id, ' '); } if (preg_match('/[\t\r\n]/', $id) === 1) { throw InvalidCacheId::containsControlCharacter($id); } } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/MongoDBCache.php000066400000000000000000000061761357065157100247440ustar00rootroot00000000000000provider = new LegacyMongoDBCache($collection); } elseif ($collection instanceof Collection) { $this->provider = new ExtMongoDBCache($collection); } else { throw new InvalidArgumentException('Invalid collection given - expected a MongoCollection or MongoDB\Collection instance'); } } /** * {@inheritdoc} */ protected function doFetch($id) { return $this->provider->doFetch($id); } /** * {@inheritdoc} */ protected function doContains($id) { return $this->provider->doContains($id); } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { return $this->provider->doSave($id, $data, $lifeTime); } /** * {@inheritdoc} */ protected function doDelete($id) { return $this->provider->doDelete($id); } /** * {@inheritdoc} */ protected function doFlush() { return $this->provider->doFlush(); } /** * {@inheritdoc} */ protected function doGetStats() { return $this->provider->doGetStats(); } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/MultiDeleteCache.php000066400000000000000000000007221357065157100256630ustar00rootroot00000000000000 infinite lifeTime). * * @return bool TRUE if the operation was successful, FALSE if it wasn't. */ public function saveMultiple(array $keysAndValues, $lifetime = 0); } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/PhpFileCache.php000066400000000000000000000051631357065157100250010ustar00rootroot00000000000000includeFileForId($id); if ($value === null) { return false; } if ($value['lifetime'] !== 0 && $value['lifetime'] < time()) { return false; } return $value['data']; } /** * {@inheritdoc} */ protected function doContains($id) { $value = $this->includeFileForId($id); if ($value === null) { return false; } return $value['lifetime'] === 0 || $value['lifetime'] > time(); } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { if ($lifeTime > 0) { $lifeTime = time() + $lifeTime; } $filename = $this->getFilename($id); $value = [ 'lifetime' => $lifeTime, 'data' => $data, ]; if (is_object($data) && method_exists($data, '__set_state')) { $value = var_export($value, true); $code = sprintf('writeFile($filename, $code); } /** * @return array|null */ private function includeFileForId(string $id) : ?array { $fileName = $this->getFilename($id); // note: error suppression is still faster than `file_exists`, `is_file` and `is_readable` set_error_handler(self::$emptyErrorHandler); $value = include $fileName; restore_error_handler(); if (! isset($value['lifetime'])) { return null; } return $value; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/PredisCache.php000066400000000000000000000063261357065157100247020ustar00rootroot00000000000000client = $client; } /** * {@inheritdoc} */ protected function doFetch($id) { $result = $this->client->get($id); if ($result === null) { return false; } return unserialize($result); } /** * {@inheritdoc} */ protected function doFetchMultiple(array $keys) { $fetchedItems = call_user_func_array([$this->client, 'mget'], $keys); return array_map('unserialize', array_filter(array_combine($keys, $fetchedItems))); } /** * {@inheritdoc} */ protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) { if ($lifetime) { $success = true; // Keys have lifetime, use SETEX for each of them foreach ($keysAndValues as $key => $value) { $response = (string) $this->client->setex($key, $lifetime, serialize($value)); if ($response == 'OK') { continue; } $success = false; } return $success; } // No lifetime, use MSET $response = $this->client->mset(array_map(static function ($value) { return serialize($value); }, $keysAndValues)); return (string) $response == 'OK'; } /** * {@inheritdoc} */ protected function doContains($id) { return (bool) $this->client->exists($id); } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { $data = serialize($data); if ($lifeTime > 0) { $response = $this->client->setex($id, $lifeTime, $data); } else { $response = $this->client->set($id, $data); } return $response === true || $response == 'OK'; } /** * {@inheritdoc} */ protected function doDelete($id) { return $this->client->del($id) >= 0; } /** * {@inheritdoc} */ protected function doDeleteMultiple(array $keys) { return $this->client->del($keys) >= 0; } /** * {@inheritdoc} */ protected function doFlush() { $response = $this->client->flushdb(); return $response === true || $response == 'OK'; } /** * {@inheritdoc} */ protected function doGetStats() { $info = $this->client->info(); return [ Cache::STATS_HITS => $info['Stats']['keyspace_hits'], Cache::STATS_MISSES => $info['Stats']['keyspace_misses'], Cache::STATS_UPTIME => $info['Server']['uptime_in_seconds'], Cache::STATS_MEMORY_USAGE => $info['Memory']['used_memory'], Cache::STATS_MEMORY_AVAILABLE => false, ]; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/RedisCache.php000066400000000000000000000104031357065157100245110ustar00rootroot00000000000000setOption(Redis::OPT_SERIALIZER, $this->getSerializerValue()); $this->redis = $redis; } /** * Gets the redis instance used by the cache. * * @return Redis|null */ public function getRedis() { return $this->redis; } /** * {@inheritdoc} */ protected function doFetch($id) { return $this->redis->get($id); } /** * {@inheritdoc} */ protected function doFetchMultiple(array $keys) { $fetchedItems = array_combine($keys, $this->redis->mget($keys)); // Redis mget returns false for keys that do not exist. So we need to filter those out unless it's the real data. $keysToFilter = array_keys(array_filter($fetchedItems, static function ($item) : bool { return $item === false; })); if ($keysToFilter) { $multi = $this->redis->multi(Redis::PIPELINE); foreach ($keysToFilter as $key) { $multi->exists($key); } $existItems = array_filter($multi->exec()); $missedItemKeys = array_diff_key($keysToFilter, $existItems); $fetchedItems = array_diff_key($fetchedItems, array_fill_keys($missedItemKeys, true)); } return $fetchedItems; } /** * {@inheritdoc} */ protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) { if ($lifetime) { // Keys have lifetime, use SETEX for each of them $multi = $this->redis->multi(Redis::PIPELINE); foreach ($keysAndValues as $key => $value) { $multi->setex($key, $lifetime, $value); } $succeeded = array_filter($multi->exec()); return count($succeeded) == count($keysAndValues); } // No lifetime, use MSET return (bool) $this->redis->mset($keysAndValues); } /** * {@inheritdoc} */ protected function doContains($id) { $exists = $this->redis->exists($id); if (is_bool($exists)) { return $exists; } return $exists > 0; } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { if ($lifeTime > 0) { return $this->redis->setex($id, $lifeTime, $data); } return $this->redis->set($id, $data); } /** * {@inheritdoc} */ protected function doDelete($id) { return $this->redis->del($id) >= 0; } /** * {@inheritdoc} */ protected function doDeleteMultiple(array $keys) { return $this->redis->del($keys) >= 0; } /** * {@inheritdoc} */ protected function doFlush() { return $this->redis->flushDB(); } /** * {@inheritdoc} */ protected function doGetStats() { $info = $this->redis->info(); return [ Cache::STATS_HITS => $info['keyspace_hits'], Cache::STATS_MISSES => $info['keyspace_misses'], Cache::STATS_UPTIME => $info['uptime_in_seconds'], Cache::STATS_MEMORY_USAGE => $info['used_memory'], Cache::STATS_MEMORY_AVAILABLE => false, ]; } /** * Returns the serializer constant to use. If Redis is compiled with * igbinary support, that is used. Otherwise the default PHP serializer is * used. * * @return int One of the Redis::SERIALIZER_* constants */ protected function getSerializerValue() { if (defined('Redis::SERIALIZER_IGBINARY') && extension_loaded('igbinary')) { return Redis::SERIALIZER_IGBINARY; } return Redis::SERIALIZER_PHP; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/SQLite3Cache.php000066400000000000000000000110331357065157100246670ustar00rootroot00000000000000sqlite = $sqlite; $this->table = (string) $table; $this->ensureTableExists(); } private function ensureTableExists() : void { $this->sqlite->exec( sprintf( 'CREATE TABLE IF NOT EXISTS %s(%s TEXT PRIMARY KEY NOT NULL, %s BLOB, %s INTEGER)', $this->table, static::ID_FIELD, static::DATA_FIELD, static::EXPIRATION_FIELD ) ); } /** * {@inheritdoc} */ protected function doFetch($id) { $item = $this->findById($id); if (! $item) { return false; } return unserialize($item[self::DATA_FIELD]); } /** * {@inheritdoc} */ protected function doContains($id) { return $this->findById($id, false) !== null; } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { $statement = $this->sqlite->prepare(sprintf( 'INSERT OR REPLACE INTO %s (%s) VALUES (:id, :data, :expire)', $this->table, implode(',', $this->getFields()) )); $statement->bindValue(':id', $id); $statement->bindValue(':data', serialize($data), SQLITE3_BLOB); $statement->bindValue(':expire', $lifeTime > 0 ? time() + $lifeTime : null); return $statement->execute() instanceof SQLite3Result; } /** * {@inheritdoc} */ protected function doDelete($id) { [$idField] = $this->getFields(); $statement = $this->sqlite->prepare(sprintf( 'DELETE FROM %s WHERE %s = :id', $this->table, $idField )); $statement->bindValue(':id', $id); return $statement->execute() instanceof SQLite3Result; } /** * {@inheritdoc} */ protected function doFlush() { return $this->sqlite->exec(sprintf('DELETE FROM %s', $this->table)); } /** * {@inheritdoc} */ protected function doGetStats() { // no-op. } /** * Find a single row by ID. * * @param mixed $id * * @return array|null */ private function findById($id, bool $includeData = true) : ?array { [$idField] = $fields = $this->getFields(); if (! $includeData) { $key = array_search(static::DATA_FIELD, $fields); unset($fields[$key]); } $statement = $this->sqlite->prepare(sprintf( 'SELECT %s FROM %s WHERE %s = :id LIMIT 1', implode(',', $fields), $this->table, $idField )); $statement->bindValue(':id', $id, SQLITE3_TEXT); $item = $statement->execute()->fetchArray(SQLITE3_ASSOC); if ($item === false) { return null; } if ($this->isExpired($item)) { $this->doDelete($id); return null; } return $item; } /** * Gets an array of the fields in our table. * * @return array */ private function getFields() : array { return [static::ID_FIELD, static::DATA_FIELD, static::EXPIRATION_FIELD]; } /** * Check if the item is expired. * * @param array $item */ private function isExpired(array $item) : bool { return isset($item[static::EXPIRATION_FIELD]) && $item[self::EXPIRATION_FIELD] !== null && $item[self::EXPIRATION_FIELD] < time(); } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/Version.php000066400000000000000000000001431357065157100241440ustar00rootroot00000000000000 $info['total_hit_count'], Cache::STATS_MISSES => $info['total_miss_count'], Cache::STATS_UPTIME => $info['total_cache_uptime'], Cache::STATS_MEMORY_USAGE => $meminfo['memory_total'], Cache::STATS_MEMORY_AVAILABLE => $meminfo['memory_free'], ]; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/XcacheCache.php000066400000000000000000000042421357065157100246420ustar00rootroot00000000000000doContains($id) ? unserialize(xcache_get($id)) : false; } /** * {@inheritdoc} */ protected function doContains($id) { return xcache_isset($id); } /** * {@inheritdoc} */ protected function doSave($id, $data, $lifeTime = 0) { return xcache_set($id, serialize($data), (int) $lifeTime); } /** * {@inheritdoc} */ protected function doDelete($id) { return xcache_unset($id); } /** * {@inheritdoc} */ protected function doFlush() { $this->checkAuthorization(); xcache_clear_cache(XC_TYPE_VAR); return true; } /** * Checks that xcache.admin.enable_auth is Off. * * @return void * * @throws BadMethodCallException When xcache.admin.enable_auth is On. */ protected function checkAuthorization() { if (ini_get('xcache.admin.enable_auth')) { throw new BadMethodCallException( 'To use all features of \Doctrine\Common\Cache\XcacheCache, ' . 'you must set "xcache.admin.enable_auth" to "Off" in your php.ini.' ); } } /** * {@inheritdoc} */ protected function doGetStats() { $this->checkAuthorization(); $info = xcache_info(XC_TYPE_VAR, 0); return [ Cache::STATS_HITS => $info['hits'], Cache::STATS_MISSES => $info['misses'], Cache::STATS_UPTIME => null, Cache::STATS_MEMORY_USAGE => $info['size'], Cache::STATS_MEMORY_AVAILABLE => $info['avail'], ]; } } php-doctrine-cache-1.10.0/lib/Doctrine/Common/Cache/ZendDataCache.php000066400000000000000000000023341357065157100251410ustar00rootroot00000000000000getNamespace(); if (empty($namespace)) { return zend_shm_cache_clear(); } return zend_shm_cache_clear($namespace); } /** * {@inheritdoc} */ protected function doGetStats() { return null; } } php-doctrine-cache-1.10.0/phpcs.xml.dist000066400000000000000000000026051357065157100200440ustar00rootroot00000000000000 Coding Standards for doctrine. lib tests tests/Doctrine/Tests/Common/Cache/PhpFileCacheTest.php tests/Doctrine/Tests/Common/Cache/PhpFileCacheTest.php php-doctrine-cache-1.10.0/phpunit.xml.dist000066400000000000000000000020671357065157100204200ustar00rootroot00000000000000 ./tests/Doctrine/ ./lib/Doctrine/ lib/Doctrine/Common/Cache/ApcCache.php lib/Doctrine/Common/Cache/CouchbaseCache.php lib/Doctrine/Common/Cache/MemcacheCache.php lib/Doctrine/Common/Cache/XcacheCache.php php-doctrine-cache-1.10.0/tests/000077500000000000000000000000001357065157100164025ustar00rootroot00000000000000php-doctrine-cache-1.10.0/tests/Doctrine/000077500000000000000000000000001357065157100201515ustar00rootroot00000000000000php-doctrine-cache-1.10.0/tests/Doctrine/Tests/000077500000000000000000000000001357065157100212535ustar00rootroot00000000000000php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/000077500000000000000000000000001357065157100225035ustar00rootroot00000000000000php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/000077500000000000000000000000001357065157100235065ustar00rootroot00000000000000php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/ApcCacheTest.php000066400000000000000000000013511357065157100265060ustar00rootroot00000000000000markTestSkipped('APC must be enabled for the CLI with the ini setting apc.enable_cli=1'); } protected function _getCacheDriver() : CacheProvider { return new ApcCache(); } public function testLifetime() : void { $this->markTestSkipped('The APC cache TTL is not working in a single process/request. See https://bugs.php.net/bug.php?id=58084'); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/ApcuCacheTest.php000066400000000000000000000013551357065157100266770ustar00rootroot00000000000000markTestSkipped('APC must be enabled for the CLI with the ini setting apc.enable_cli=1'); } protected function _getCacheDriver() : CacheProvider { return new ApcuCache(); } public function testLifetime() : void { $this->markTestSkipped('The APC cache TTL is not working in a single process/request. See https://bugs.php.net/bug.php?id=58084'); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/ArrayCacheTest.php000066400000000000000000000027561357065157100270730ustar00rootroot00000000000000_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; } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/BaseFileCacheTest.php000066400000000000000000000122231357065157100274550ustar00rootroot00000000000000directory = sys_get_temp_dir() . '/doctrine_cache_' . uniqid(); } while (file_exists($this->directory)); } protected function tearDown() : void { if (! is_dir($this->directory)) { return; } $iterator = new RecursiveDirectoryIterator($this->directory); foreach (new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST) as $file) { if ($file->isFile()) { @unlink($file->getRealPath()); } elseif ($file->isDir()) { @rmdir($file->getRealPath()); } } @rmdir($this->directory); } public function testFlushAllRemovesBalancingDirectories() : void { $cache = $this->_getCacheDriver(); self::assertTrue($cache->save('key1', 1)); self::assertTrue($cache->save('key2', 2)); self::assertTrue($cache->flushAll()); $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->directory, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST); self::assertCount(0, $iterator); } protected function isSharedStorage() : bool { return false; } public function getPathLengthsToTest() : array { // Windows officially supports 260 bytes including null terminator // 258 bytes available to use due to php bug #70943 // Windows officially supports 260 bytes including null terminator // 259 characters is too large due to PHP bug (https://bugs.php.net/bug.php?id=70943) // 260 characters is too large - null terminator is included in allowable length return [ [257, false], [258, false], [259, true], [260, true], ]; } private static function getBasePathForWindowsPathLengthTests(int $pathLength) : string { return FileCacheTest::getBasePathForWindowsPathLengthTests($pathLength); } private static function getKeyAndPathFittingLength(int $length, string $basePath) : array { $baseDirLength = strlen($basePath); $extensionLength = strlen('.doctrine.cache'); $directoryLength = strlen(DIRECTORY_SEPARATOR . 'aa' . DIRECTORY_SEPARATOR); $namespaceAndBracketLength = strlen(bin2hex('[][1]')); $keyLength = $length - ($baseDirLength + $extensionLength + $directoryLength + $namespaceAndBracketLength); $key = str_repeat('a', floor($keyLength / 2)); $namespacedKey = '[' . $key . '][1]'; $keyHash = hash('sha256', $namespacedKey); $keyPath = $basePath . DIRECTORY_SEPARATOR . substr($keyHash, 0, 2) . DIRECTORY_SEPARATOR . bin2hex($namespacedKey) . '.doctrine.cache'; $hashedKeyPath = $basePath . DIRECTORY_SEPARATOR . substr($keyHash, 0, 2) . DIRECTORY_SEPARATOR . '_' . $keyHash . '.doctrine.cache'; return [$key, $keyPath, $hashedKeyPath]; } /** * @dataProvider getPathLengthsToTest */ public function testWindowsPathLengthLimitIsCorrectlyHandled(int $length, bool $pathShouldBeHashed) : void { $this->directory = self::getBasePathForWindowsPathLengthTests($length); [$key, $keyPath, $hashedKeyPath] = self::getKeyAndPathFittingLength($length, $this->directory); self::assertEquals($length, strlen($keyPath), 'Unhashed path should be of correct length.'); $cacheClass = get_class($this->_getCacheDriver()); /** @var FileCache $cache */ $cache = new $cacheClass($this->directory, '.doctrine.cache'); // Trick it into thinking this is windows. $reflClass = new ReflectionClass(FileCache::class); $reflProp = $reflClass->getProperty('isRunningOnWindows'); $reflProp->setAccessible(true); $reflProp->setValue($cache, true); $reflProp->setAccessible(false); $value = uniqid('value', true); $cache->save($key, $value); self::assertEquals($value, $cache->fetch($key)); if ($pathShouldBeHashed) { self::assertFileExists($hashedKeyPath, 'Path generated for key should be hashed.'); unlink($hashedKeyPath); } else { self::assertFileExists($keyPath, 'Path generated for key should not be hashed.'); unlink($keyPath); } } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/CacheProviderTest.php000066400000000000000000000106051357065157100275770ustar00rootroot00000000000000getMockForAbstractClass( CacheProvider::class, [], '', true, true, true, ['doFetchMultiple'] ); $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 { /** @var CacheProvider|PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->getMockForAbstractClass( CacheProvider::class, [], '', true, true, true, ['doFetch', 'doSave', 'doContains'] ); $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 { /** @var CacheProvider|PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->getMockForAbstractClass( CacheProvider::class, [], '', true, true, true, ['doSave'] ); $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 { /** @var CacheProvider|PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this ->getMockBuilder(CacheProvider::class) ->setMethods(['doDelete']) ->getMockForAbstractClass(); $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 { /** @var CacheProvider|PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->getMockForAbstractClass(CacheProvider::class); $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()); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/CacheTest.php000066400000000000000000000415471357065157100260750ustar00rootroot00000000000000_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')); } /** * @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)); } 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')); 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($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. */ 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; } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/ChainCacheTest.php000066400000000000000000000117451357065157100270350ustar00rootroot00000000000000_getCacheDriver(); $stats = $cache->getStats(); self::assertInternalType('array', $stats); } public function testOnlyFetchFirstOne() : void { $cache1 = new ArrayCache(); $cache2 = $this->getMockForAbstractClass(CacheProvider::class); $cache2->expects($this->never())->method('doFetch'); $chainCache = new ChainCache([$cache1, $cache2]); $chainCache->save('id', 'bar'); self::assertEquals('bar', $chainCache->fetch('id')); } public function testOnlyFetchFirstCompleteSet() : void { $cache1 = new ArrayCache(); $cache2 = $this ->getMockBuilder(CacheProvider::class) ->setMethods(['doFetchMultiple']) ->getMockForAbstractClass(); $cache2->expects($this->never())->method('doFetchMultiple'); $chainCache = new ChainCache([$cache1, $cache2]); $chainCache->saveMultiple(['bar' => 'Bar', 'foo' => 'Foo']); self::assertEquals(['bar' => 'Bar', 'foo' => 'Foo'], $chainCache->fetchMultiple(['bar', 'foo'])); } public function testFetchPropagateToFastestCache() : void { $cache1 = new ArrayCache(); $cache2 = new ArrayCache(); $cache2->save('bar', 'value'); $chainCache = new ChainCache([$cache1, $cache2]); self::assertFalse($cache1->contains('bar')); $result = $chainCache->fetch('bar'); self::assertEquals('value', $result); self::assertTrue($cache1->contains('bar')); } public function testFetchMultiplePropagateToFastestCache() : void { $cache1 = new ArrayCache(); $cache2 = new ArrayCache(); $cache1->save('bar', 'Bar'); $cache2->saveMultiple(['bar' => 'Bar', 'foo' => 'Foo']); $chainCache = new ChainCache([$cache1, $cache2]); self::assertTrue($cache1->contains('bar')); self::assertFalse($cache1->contains('foo')); $result = $chainCache->fetchMultiple(['bar', 'foo']); self::assertEquals(['bar' => 'Bar', 'foo' => 'Foo'], $result); self::assertTrue($cache1->contains('foo')); } public function testNamespaceIsPropagatedToAllProviders() : void { $cache1 = new ArrayCache(); $cache2 = new ArrayCache(); $chainCache = new ChainCache([$cache1, $cache2]); $chainCache->setNamespace('bar'); self::assertEquals('bar', $cache1->getNamespace()); self::assertEquals('bar', $cache2->getNamespace()); } public function testDeleteToAllProviders() : void { $cache1 = $this->getMockForAbstractClass('Doctrine\Common\Cache\CacheProvider'); $cache2 = $this->getMockForAbstractClass('Doctrine\Common\Cache\CacheProvider'); $cache1->expects($this->once())->method('doDelete'); $cache2->expects($this->once())->method('doDelete'); $chainCache = new ChainCache([$cache1, $cache2]); $chainCache->delete('bar'); } public function testDeleteMultipleToAllProviders() : void { $cache1 = $this ->getMockBuilder(CacheProvider::class) ->setMethods(['doDeleteMultiple']) ->getMockForAbstractClass(); $cache2 = $this ->getMockBuilder(CacheProvider::class) ->setMethods(['doDeleteMultiple']) ->getMockForAbstractClass(); $cache1->expects($this->once())->method('doDeleteMultiple')->willReturn(true); $cache2->expects($this->once())->method('doDeleteMultiple')->willReturn(true); $chainCache = new ChainCache([$cache1, $cache2]); $chainCache->deleteMultiple(['bar', 'foo']); } public function testFlushToAllProviders() : void { $cache1 = $this->getMockForAbstractClass('Doctrine\Common\Cache\CacheProvider'); $cache2 = $this->getMockForAbstractClass('Doctrine\Common\Cache\CacheProvider'); $cache1->expects($this->once())->method('doFlush'); $cache2->expects($this->once())->method('doFlush'); $chainCache = new ChainCache([$cache1, $cache2]); $chainCache->flushAll(); } /** * @group 155 */ public function testChainCacheAcceptsArrayIteratorsAsDependency() : void { $cache1 = $this->getMockForAbstractClass(CacheProvider::class); $cache2 = $this->getMockForAbstractClass(CacheProvider::class); $cache1->expects($this->once())->method('doFlush'); $cache2->expects($this->once())->method('doFlush'); (new ChainCache(new ArrayIterator([$cache1, $cache2])))->flushAll(); } protected function isSharedStorage() : bool { return false; } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/CouchbaseBucketCacheTest.php000066400000000000000000000012021357065157100310300ustar00rootroot00000000000000=2.3 */ class CouchbaseBucketCacheTest extends CacheTest { /** @var Bucket */ private $bucket; protected function setUp() : void { $cluster = new Cluster('couchbase://localhost?detailed_errcodes=1'); $this->bucket = $cluster->openBucket('default'); } protected function _getCacheDriver() : CacheProvider { return new CouchbaseBucketCache($this->bucket); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/CouchbaseCacheTest.php000066400000000000000000000014521357065157100277010ustar00rootroot00000000000000=1.0 * @requires extension couchbase <2.0 */ class CouchbaseCacheTest extends CacheTest { private $couchbase; protected function setUp() : void { try { $this->couchbase = new Couchbase('127.0.0.1', 'Administrator', 'password', 'default'); } catch (Throwable $ex) { $this->markTestSkipped('Could not instantiate the Couchbase cache because of: ' . $ex); } } protected function _getCacheDriver() : CacheProvider { $driver = new CouchbaseCache(); $driver->setCouchbase($this->couchbase); return $driver; } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/ExtMongoDBCacheTest.php000066400000000000000000000037671357065157100277660ustar00rootroot00000000000000listDatabases(); } catch (Exception $e) { $this->markTestSkipped('Cannot connect to MongoDB because of: ' . $e); } $this->collection = $mongo->selectCollection('doctrine_common_cache', 'test'); } protected function tearDown() : void { if (! ($this->collection instanceof Collection)) { return; } $this->collection->drop(); } public function testGetStats() : void { $cache = $this->_getCacheDriver(); // Run a query to create the collection $this->collection->find([]); $stats = $cache->getStats(); self::assertNull($stats[Cache::STATS_HITS]); self::assertNull($stats[Cache::STATS_MISSES]); self::assertGreaterThan(0, $stats[Cache::STATS_UPTIME]); self::assertEquals(0, $stats[Cache::STATS_MEMORY_USAGE]); self::assertNull($stats[Cache::STATS_MEMORY_AVAILABLE]); } public function testLifetime() : void { $cache = $this->_getCacheDriver(); $cache->save('expire', 'value', 2); self::assertCount(1, $this->collection->listIndexes()); self::assertTrue($cache->contains('expire'), 'Data should not be expired yet'); sleep(3); self::assertFalse($cache->contains('expire'), 'Data should be expired'); self::assertCount(2, $this->collection->listIndexes()); } protected function _getCacheDriver() : CacheProvider { return new MongoDBCache($this->collection); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/FileCacheTest.php000066400000000000000000000216141357065157100266660ustar00rootroot00000000000000driver = $this ->getMockBuilder(FileCache::class) ->setMethods(['doFetch', 'doContains', 'doSave']) ->disableOriginalConstructor() ->getMock(); } public function testFilenameShouldCreateThePathWithOneSubDirectory() : void { $cache = $this->driver; $method = new ReflectionMethod($cache, 'getFilename'); $key = 'item-key'; $expectedDir = '84'; $method->setAccessible(true); $path = $method->invoke($cache, $key); $dirname = pathinfo($path, PATHINFO_DIRNAME); self::assertEquals(DIRECTORY_SEPARATOR . $expectedDir, $dirname); } public function testFileExtensionCorrectlyEscaped() : void { $driver1 = $this ->getMockBuilder(FileCache::class) ->setMethods(['doFetch', 'doContains', 'doSave']) ->setConstructorArgs([__DIR__, '.*']) ->getMock(); $driver2 = $this ->getMockBuilder(FileCache::class) ->setMethods(['doFetch', 'doContains', 'doSave']) ->setConstructorArgs([__DIR__, '.php']) ->getMock(); $doGetStats = new ReflectionMethod($driver1, 'doGetStats'); $doGetStats->setAccessible(true); $stats1 = $doGetStats->invoke($driver1); $stats2 = $doGetStats->invoke($driver2); self::assertSame(0, $stats1[Cache::STATS_MEMORY_USAGE]); self::assertGreaterThan(0, $stats2[Cache::STATS_MEMORY_USAGE]); } /** * @group DCOM-266 */ public function testFileExtensionSlashCorrectlyEscaped() : void { $driver = $this ->getMockBuilder(FileCache::class) ->setMethods(['doFetch', 'doContains', 'doSave']) ->setConstructorArgs([__DIR__ . '/../', DIRECTORY_SEPARATOR . basename(__FILE__)]) ->getMock(); $doGetStats = new ReflectionMethod($driver, 'doGetStats'); $doGetStats->setAccessible(true); $stats = $doGetStats->invoke($driver); self::assertGreaterThan(0, $stats[Cache::STATS_MEMORY_USAGE]); } public function testNonIntUmaskThrowsInvalidArgumentException() : void { $this->expectException(InvalidArgumentException::class); $this ->getMockBuilder(FileCache::class) ->setMethods(['doFetch', 'doContains', 'doSave']) ->setConstructorArgs(['', '', 'invalid']) ->getMock(); } public function testGetDirectoryReturnsRealpathDirectoryString() : void { $directory = __DIR__ . '/../'; $driver = $this ->getMockBuilder(FileCache::class) ->setMethods(['doFetch', 'doContains', 'doSave']) ->setConstructorArgs([$directory]) ->getMock(); $doGetDirectory = new ReflectionMethod($driver, 'getDirectory'); $actualDirectory = $doGetDirectory->invoke($driver); $expectedDirectory = realpath($directory); self::assertEquals($expectedDirectory, $actualDirectory); } public function testGetExtensionReturnsExtensionString() : void { $directory = __DIR__ . '/../'; $extension = DIRECTORY_SEPARATOR . basename(__FILE__); $driver = $this ->getMockBuilder(FileCache::class) ->setMethods(['doFetch', 'doContains', 'doSave']) ->setConstructorArgs([$directory, $extension]) ->getMock(); $doGetExtension = new ReflectionMethod($driver, 'getExtension'); $actualExtension = $doGetExtension->invoke($driver); self::assertEquals($extension, $actualExtension); } public const WIN_MAX_PATH_LEN = 258; public static function getBasePathForWindowsPathLengthTests(int $pathLength) : string { // Not using __DIR__ because it can get screwed up when xdebug debugger is attached. $basePath = realpath(sys_get_temp_dir()) . '/' . uniqid('doctrine-cache', true); /** @noinspection MkdirRaceConditionInspection */ @mkdir($basePath); $basePath = realpath($basePath); // Test whether the desired path length is odd or even. $desiredPathLengthIsOdd = $pathLength % 2 == 1; // If the cache key is not too long, the filecache codepath will add // a slash and bin2hex($key). The length of the added portion will be an odd number. // len(desired) = len(base path) + len(slash . bin2hex($key)) // odd = even + odd // even = odd + odd $basePathLengthShouldBeOdd = ! $desiredPathLengthIsOdd; $basePathLengthIsOdd = strlen($basePath) % 2 == 1; // If the base path needs to be odd or even where it is not, we add an odd number of // characters as a pad. In this case, we're adding '\aa' (or '/aa' depending on platform) // This is all to make it so that the key we're testing would result in // a path that is exactly the length we want to test IF the path length limit // were not in place in FileCache. if ($basePathLengthIsOdd != $basePathLengthShouldBeOdd) { $basePath .= DIRECTORY_SEPARATOR . 'aa'; } return $basePath; } public static function getKeyAndPathFittingLength(int $length, string $basePath) : array { $baseDirLength = strlen($basePath); $extensionLength = strlen('.doctrine.cache'); $directoryLength = strlen(DIRECTORY_SEPARATOR . 'aa' . DIRECTORY_SEPARATOR); $keyLength = $length - ($baseDirLength + $extensionLength + $directoryLength); // - 1 because of slash $key = str_repeat('a', floor($keyLength / 2)); $keyHash = hash('sha256', $key); $keyPath = $basePath . DIRECTORY_SEPARATOR . substr($keyHash, 0, 2) . DIRECTORY_SEPARATOR . bin2hex($key) . '.doctrine.cache'; $hashedKeyPath = $basePath . DIRECTORY_SEPARATOR . substr($keyHash, 0, 2) . DIRECTORY_SEPARATOR . '_' . $keyHash . '.doctrine.cache'; return [$key, $keyPath, $hashedKeyPath]; } public function getPathLengthsToTest() : array { // Windows officially supports 260 bytes including null terminator // 259 characters is too large due to PHP bug (https://bugs.php.net/bug.php?id=70943) // 260 characters is too large - null terminator is included in allowable length return [ [257, false], [258, false], [259, true], [260, true], ]; } /** * @dataProvider getPathLengthsToTest * @covers \Doctrine\Common\Cache\FileCache::getFilename */ public function testWindowsPathLengthLimitationsAreCorrectlyRespected(int $length, bool $pathShouldBeHashed) : void { if (! defined('PHP_WINDOWS_VERSION_BUILD')) { define('PHP_WINDOWS_VERSION_BUILD', 'Yes, this is the "usual suspect", with the usual limitations'); } $basePath = self::getBasePathForWindowsPathLengthTests($length); $fileCache = $this->getMockForAbstractClass( 'Doctrine\Common\Cache\FileCache', [$basePath, '.doctrine.cache'] ); [$key, $keyPath, $hashedKeyPath] = self::getKeyAndPathFittingLength($length, $basePath); $getFileName = new ReflectionMethod($fileCache, 'getFilename'); $getFileName->setAccessible(true); self::assertEquals( $length, strlen($keyPath), sprintf('Path expected to be %d characters long is %d characters long', $length, strlen($keyPath)) ); if ($pathShouldBeHashed) { $keyPath = $hashedKeyPath; } if ($pathShouldBeHashed) { self::assertSame( $hashedKeyPath, $getFileName->invoke($fileCache, $key), 'Keys should be hashed correctly if they are over the limit.' ); } else { self::assertSame( $keyPath, $getFileName->invoke($fileCache, $key), 'Keys below limit of the allowed length are used directly, unhashed' ); } } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/FilesystemCacheTest.php000066400000000000000000000043031357065157100301270ustar00rootroot00000000000000_getCacheDriver(); $stats = $cache->getStats(); self::assertNull($stats[Cache::STATS_HITS]); self::assertNull($stats[Cache::STATS_MISSES]); self::assertNull($stats[Cache::STATS_UPTIME]); self::assertEquals(0, $stats[Cache::STATS_MEMORY_USAGE]); self::assertGreaterThan(0, $stats[Cache::STATS_MEMORY_AVAILABLE]); } public function testCacheInSharedDirectoryIsPerExtension() : void { $cache1 = new FilesystemCache($this->directory, '.foo'); $cache2 = new FilesystemCache($this->directory, '.bar'); self::assertTrue($cache1->save('key1', 11)); self::assertTrue($cache1->save('key2', 12)); self::assertTrue($cache2->save('key1', 21)); self::assertTrue($cache2->save('key2', 22)); self::assertSame(11, $cache1->fetch('key1'), 'Cache value must not be influenced by a different cache in the same directory but different extension'); self::assertSame(12, $cache1->fetch('key2')); self::assertTrue($cache1->flushAll()); self::assertFalse($cache1->fetch('key1'), 'flushAll() must delete all items with the current extension'); self::assertFalse($cache1->fetch('key2')); self::assertSame(21, $cache2->fetch('key1'), 'flushAll() must not remove items with a different extension in a shared directory'); self::assertSame(22, $cache2->fetch('key2')); } public function testFlushAllWithNoExtension() : void { $cache = new FilesystemCache($this->directory, ''); 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')); } protected function _getCacheDriver() : CacheProvider { return new FilesystemCache($this->directory); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/LegacyMongoDBCacheTest.php000066400000000000000000000051421357065157100304170ustar00rootroot00000000000000listDBs(); } catch (MongoConnectionException $e) { $this->markTestSkipped('Cannot connect to MongoDB because of: ' . $e); } $this->collection = $mongo->selectCollection('doctrine_common_cache', 'test'); } protected function tearDown() : void { if (! ($this->collection instanceof MongoCollection)) { return; } $this->collection->drop(); } public function testGetStats() : void { $cache = $this->_getCacheDriver(); $stats = $cache->getStats(); self::assertNull($stats[Cache::STATS_HITS]); self::assertNull($stats[Cache::STATS_MISSES]); self::assertGreaterThan(0, $stats[Cache::STATS_UPTIME]); self::assertEquals(0, $stats[Cache::STATS_MEMORY_USAGE]); self::assertNull($stats[Cache::STATS_MEMORY_AVAILABLE]); } /** * @group 108 */ public function testMongoCursorExceptionsDoNotBubbleUp() : void { /** @var MongoCollection|PHPUnit_Framework_MockObject_MockObject $collection */ $collection = $this ->getMockBuilder(MongoCollection::class) ->disableOriginalConstructor() ->getMock(); $collection->expects(self::once())->method('update')->willThrowException(new MongoCursorException()); $cache = new LegacyMongoDBCache($collection); self::assertFalse($cache->save('foo', 'bar')); } public function testLifetime() : void { $cache = $this->_getCacheDriver(); $cache->save('expire', 'value', 1); self::assertCount(1, $this->collection->getIndexInfo()); self::assertTrue($cache->contains('expire'), 'Data should not be expired yet'); sleep(2); self::assertFalse($cache->contains('expire'), 'Data should be expired'); self::assertCount(2, $this->collection->getIndexInfo()); } protected function _getCacheDriver() : CacheProvider { return new MongoDBCache($this->collection); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/MemcacheCacheTest.php000066400000000000000000000025661357065157100275160ustar00rootroot00000000000000memcache = new Memcache(); if (@$this->memcache->connect('localhost', 11211) !== false) { return; } unset($this->memcache); $this->markTestSkipped('Cannot connect to Memcache.'); } protected function tearDown() : void { if (! ($this->memcache instanceof Memcache)) { return; } $this->memcache->flush(); } /** * {@inheritdoc} * * Memcache does not support " " and null byte as key so we remove them from the tests. */ public function provideCacheIds() : array { $ids = parent::provideCacheIds(); unset($ids[21], $ids[22]); return $ids; } public function testGetMemcacheReturnsInstanceOfMemcache() : void { self::assertInstanceOf('Memcache', $this->_getCacheDriver()->getMemcache()); } /** * {@inheritDoc} */ protected function _getCacheDriver() : CacheProvider { $driver = new MemcacheCache(); $driver->setMemcache($this->memcache); return $driver; } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/MemcachedCacheTest.php000066400000000000000000000075031357065157100276560ustar00rootroot00000000000000memcached = new Memcached(); $this->memcached->setOption(Memcached::OPT_COMPRESSION, false); $this->memcached->addServer('127.0.0.1', 11211); if (@fsockopen('127.0.0.1', 11211) !== false) { return; } unset($this->memcached); $this->markTestSkipped('Cannot connect to Memcached.'); } protected function tearDown() : void { if (! ($this->memcached instanceof Memcached)) { return; } $this->memcached->flush(); } /** * {@inheritdoc} * * Memcached does not support " ", null byte and very long keys so we remove them from the tests. */ public function provideCacheIds() : array { $ids = parent::provideCacheIds(); unset($ids[21], $ids[22], $ids[24]); return $ids; } /** * @dataProvider provideInvalidCacheIds */ public function testSaveInvalidCacheId($id) : void { $this->expectException(InvalidCacheId::class); $this->_getCacheDriver()->save($id, 1); } /** * @dataProvider provideInvalidCacheIdSets */ public function testSaveMultipleInvalidCacheIds(array $ids) : void { $this->expectException(InvalidCacheId::class); $this->_getCacheDriver()->saveMultiple($ids); } public function provideInvalidCacheIds() : Generator { yield 'contains space' => ['foo bar']; yield 'contains control characters' => ["\tfoo\n\r"]; yield 'exceeds max length' => [str_repeat('a', MemcachedCache::CACHE_ID_MAX_LENGTH + 1)]; } public function provideInvalidCacheIdSets() : Generator { yield 'contains space' => [['foo' => 1, 'foo bar' => 2, 'bar' => 3]]; yield 'contains control characters' => [['foo' => 1, "\tfoo\n\r" => 2, 'bar' => 3]]; yield 'exceeds max length' => [['foo' => 1, str_repeat('a', MemcachedCache::CACHE_ID_MAX_LENGTH + 1) => 2, 'bar' => 3]]; } public function testGetMemcachedReturnsInstanceOfMemcached() : void { self::assertInstanceOf('Memcached', $this->_getCacheDriver()->getMemcached()); } public function testContainsWithKeyWithFalseAsValue() { $testKey = __METHOD__; $driver = $this->_getCacheDriver(); $reflection = new ReflectionClass($driver); $method = $reflection->getMethod('getNamespacedId'); $method->setAccessible(true); $testKeyNS = $method->invokeArgs($driver, [$testKey]); $this->memcached->set($testKeyNS, false); self::assertTrue($driver->contains($testKey), sprintf('Expected key "%s" to be found in cache.', $testKey)); self::assertFalse($driver->contains($testKey . '1'), 'No set key should not be found.'); } public function testContainsWithKeyOnNonReachableCache() { $testKey = __METHOD__; $memcached = new Memcached(); $memcached->addServer('0.0.0.1', 11211); // fake server is not available $driver = new MemcachedCache(); $driver->setMemcached($memcached); self::assertFalse($driver->contains($testKey), sprintf('Expected key "%s" not to be found in cache.', $testKey)); } /** * {@inheritDoc} */ protected function _getCacheDriver() : CacheProvider { $driver = new MemcachedCache(); $driver->setMemcached($this->memcached); return $driver; } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/PhpFileCacheTest.php000066400000000000000000000060411357065157100273330ustar00rootroot00000000000000_getCacheDriver(); // Test save $cache->save('test_set_state', new SetStateClass([1, 2, 3])); //Test __set_state call self::assertCount(0, SetStateClass::$values); // Test fetch $value = $cache->fetch('test_set_state'); self::assertInstanceOf(SetStateClass::class, $value); self::assertEquals([1, 2, 3], $value->getValue()); //Test __set_state call self::assertCount(1, SetStateClass::$values); // Test contains self::assertTrue($cache->contains('test_set_state')); } /** * @group 154 */ public function testNotImplementsSetState() : void { $cache = $this->_getCacheDriver(); $cache->save('test_not_set_state', new NotSetStateClass([5, 6, 7])); self::assertEquals(new NotSetStateClass([5, 6, 7]), $cache->fetch('test_not_set_state')); } /** * @group 154 */ public function testNotImplementsSetStateInArray() : void { $cache = $this->_getCacheDriver(); $cache->save('test_not_set_state_in_array', [new NotSetStateClass([4, 3, 2])]); self::assertEquals([new NotSetStateClass([4, 3, 2])], $cache->fetch('test_not_set_state_in_array')); self::assertTrue($cache->contains('test_not_set_state_in_array')); } public function testGetStats() : void { $cache = $this->_getCacheDriver(); $stats = $cache->getStats(); self::assertNull($stats[Cache::STATS_HITS]); self::assertNull($stats[Cache::STATS_MISSES]); self::assertNull($stats[Cache::STATS_UPTIME]); self::assertEquals(0, $stats[Cache::STATS_MEMORY_USAGE]); self::assertGreaterThan(0, $stats[Cache::STATS_MEMORY_AVAILABLE]); } protected function _getCacheDriver() : CacheProvider { return new PhpFileCache($this->directory); } } class NotSetStateClass { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } class SetStateClass extends NotSetStateClass { public static $values = []; public static function __set_state($data) { self::$values = $data; return new self($data['value']); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/PredisCacheTest.php000066400000000000000000000045351357065157100272400ustar00rootroot00000000000000markTestSkipped('Predis\Client is missing. Make sure to "composer install" to have all dev dependencies.'); } $this->client = new Client(); try { $this->client->connect(); } catch (ConnectionException $e) { $this->markTestSkipped('Cannot connect to Redis because of: ' . $e); } } public function testHitMissesStatsAreProvided() : void { $cache = $this->_getCacheDriver(); $stats = $cache->getStats(); self::assertNotNull($stats[Cache::STATS_HITS]); self::assertNotNull($stats[Cache::STATS_MISSES]); } /** * @return PredisCache */ protected function _getCacheDriver() : CacheProvider { return new PredisCache($this->client); } /** * {@inheritDoc} * * @dataProvider provideDataToCache */ public function testSetContainsFetchDelete($value) : void { if ($value === []) { $this->markTestIncomplete( 'Predis currently doesn\'t support saving empty array values. ' . 'See https://github.com/nrk/predis/issues/241' ); } parent::testSetContainsFetchDelete($value); } /** * {@inheritDoc} * * @dataProvider provideDataToCache */ public function testUpdateExistingEntry($value) : void { if ($value === []) { $this->markTestIncomplete( 'Predis currently doesn\'t support saving empty array values. ' . 'See https://github.com/nrk/predis/issues/241' ); } parent::testUpdateExistingEntry($value); } public function testAllowsGenericPredisClient() : void { /** @var ClientInterface $predisClient */ $predisClient = $this->createMock(ClientInterface::class); self::assertInstanceOf(PredisCache::class, new PredisCache($predisClient)); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/RedisCacheTest.php000066400000000000000000000031401357065157100270470ustar00rootroot00000000000000_redis = new Redis(); $ok = @$this->_redis->connect('127.0.0.1'); if ($ok) { return; } $this->markTestSkipped('Cannot connect to Redis.'); } public function testHitMissesStatsAreProvided() : void { $cache = $this->_getCacheDriver(); $stats = $cache->getStats(); self::assertNotNull($stats[Cache::STATS_HITS]); self::assertNotNull($stats[Cache::STATS_MISSES]); } public function testGetRedisReturnsInstanceOfRedis() : void { self::assertInstanceOf(Redis::class, $this->_getCacheDriver()->getRedis()); } public function testSerializerOptionWithOutIgbinaryExtension() : void { if (defined('Redis::SERIALIZER_IGBINARY') && extension_loaded('igbinary')) { $this->markTestSkipped('Extension igbinary is loaded.'); } self::assertEquals( Redis::SERIALIZER_PHP, $this->_getCacheDriver()->getRedis()->getOption(Redis::OPT_SERIALIZER) ); } /** * {@inheritDoc} */ protected function _getCacheDriver() : CacheProvider { $driver = new RedisCache(); $driver->setRedis($this->_redis); return $driver; } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/SQLite3CacheTest.php000066400000000000000000000016471357065157100272370ustar00rootroot00000000000000= 3 */ class SQLite3CacheTest extends CacheTest { private $file; private $sqlite; protected function setUp() : void { $this->file = tempnam(null, 'doctrine-cache-test-'); unlink($this->file); $this->sqlite = new SQLite3($this->file); } protected function tearDown() : void { $this->sqlite = null; // DB must be closed before unlink($this->file); } public function testGetStats() : void { self::assertNull($this->_getCacheDriver()->getStats()); } /** * {@inheritDoc} */ protected function _getCacheDriver() : CacheProvider { return new SQLite3Cache($this->sqlite, 'test_table'); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/VoidCacheTest.php000066400000000000000000000026121357065157100267050ustar00rootroot00000000000000contains('foo')); self::assertFalse($cache->contains('bar')); } public function testShouldAlwaysReturnFalseOnFetch() : void { $cache = new VoidCache(); self::assertFalse($cache->fetch('foo')); self::assertFalse($cache->fetch('bar')); } public function testShouldAlwaysReturnTrueOnSaveButNotStoreAnything() : void { $cache = new VoidCache(); self::assertTrue($cache->save('foo', 'fooVal')); self::assertFalse($cache->contains('foo')); self::assertFalse($cache->fetch('foo')); } public function testShouldAlwaysReturnTrueOnDelete() : void { $cache = new VoidCache(); self::assertTrue($cache->delete('foo')); } public function testShouldAlwaysReturnNullOnGetStatus() : void { $cache = new VoidCache(); self::assertNull($cache->getStats()); } public function testShouldAlwaysReturnTrueOnFlush() : void { $cache = new VoidCache(); self::assertTrue($cache->flushAll()); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/Common/Cache/WinCacheCacheTest.php000066400000000000000000000005011357065157100274600ustar00rootroot00000000000000markTestSkipped('Zend Data Cache only works in apache2handler SAPI.'); } public function testGetStats() : void { $cache = $this->_getCacheDriver(); $stats = $cache->getStats(); self::assertNull($stats); } protected function _getCacheDriver() : CacheProvider { return new ZendDataCache(); } } php-doctrine-cache-1.10.0/tests/Doctrine/Tests/DoctrineTestCase.php000066400000000000000000000002631357065157100251700ustar00rootroot00000000000000