forked from friendica/friendica-addons
Compare commits
No commits in common. "9153ca05fdf45fb94f30fda6abba3f14fb1da8bd" and "2452b05cc51e56836306f0d8b82062e4d0833b8e" have entirely different histories.
9153ca05fd
...
2452b05cc5
|
@ -27,6 +27,3 @@ indent_size = 2
|
|||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[composer.json]
|
||||
indent_size = 4
|
||||
|
|
|
@ -13,7 +13,7 @@ pipeline:
|
|||
commands:
|
||||
- git config --global user.email "no-reply@friendi.ca"
|
||||
- git config --global user.name "Friendica"
|
||||
- git clone $CI_REPO_CLONE_URL addon
|
||||
- git clone $CI_REPO_LINK addon
|
||||
- cd addon/
|
||||
- git checkout $CI_COMMIT_BRANCH
|
||||
- git fetch origin $CI_COMMIT_REF
|
||||
|
|
|
@ -20,7 +20,7 @@ pipeline:
|
|||
commands:
|
||||
- git config --global user.email "no-reply@friendi.ca"
|
||||
- git config --global user.name "Friendica"
|
||||
- git clone $CI_REPO_CLONE_URL addon
|
||||
- git clone $CI_REPO_LINK addon
|
||||
- cd addon/
|
||||
- git checkout $CI_COMMIT_BRANCH
|
||||
- git fetch origin $CI_COMMIT_REF
|
||||
|
@ -45,7 +45,7 @@ pipeline:
|
|||
branch: [ develop, '*-rc' ]
|
||||
event: push
|
||||
composer_install:
|
||||
image: friendicaci/php8.2:php8.2.16
|
||||
image: friendicaci/php7.4:php7.4.33
|
||||
commands:
|
||||
- export COMPOSER_HOME=.composer
|
||||
- composer validate
|
||||
|
|
|
@ -13,7 +13,7 @@ pipeline:
|
|||
commands:
|
||||
- git config --global user.email "no-reply@friendi.ca"
|
||||
- git config --global user.name "Friendica"
|
||||
- git clone $CI_REPO_CLONE_URL addon
|
||||
- git clone $CI_REPO_LINK addon
|
||||
- cd addon/
|
||||
- git checkout $CI_COMMIT_BRANCH
|
||||
- git fetch origin $CI_COMMIT_REF
|
||||
|
|
|
@ -5,11 +5,9 @@ matrix:
|
|||
- PHP_MAJOR_VERSION: 8.0
|
||||
PHP_VERSION: 8.0.30
|
||||
- PHP_MAJOR_VERSION: 8.1
|
||||
PHP_VERSION: 8.1.27
|
||||
PHP_VERSION: 8.1.23
|
||||
- PHP_MAJOR_VERSION: 8.2
|
||||
PHP_VERSION: 8.2.16
|
||||
- PHP_MAJOR_VERSION: 8.3
|
||||
PHP_VERSION: 8.3.3
|
||||
PHP_VERSION: 8.2.11
|
||||
|
||||
# This forces PHP Unit executions at the "opensocial" labeled location (because of much more power...)
|
||||
labels:
|
||||
|
@ -28,7 +26,7 @@ pipeline:
|
|||
commands:
|
||||
- git config --global user.email "no-reply@friendi.ca"
|
||||
- git config --global user.name "Friendica"
|
||||
- git clone $CI_REPO_CLONE_URL addon
|
||||
- git clone $CI_REPO_LINK addon
|
||||
- cd addon/
|
||||
- git checkout $CI_COMMIT_BRANCH
|
||||
- git fetch origin $CI_COMMIT_REF
|
||||
|
@ -78,7 +76,7 @@ pipeline:
|
|||
- cp config/local-sample.config.php config/local.config.php
|
||||
- if ! bin/wait-for-connection $MYSQL_HOST $MYSQL_PORT 300; then echo "[ERROR] Waited 300 seconds, no response" >&2; exit 1; fi
|
||||
- mysql -h$MYSQL_HOST -P$MYSQL_PORT -p$MYSQL_PASSWORD -u$MYSQL_USER $MYSQL_DATABASE < database.sql
|
||||
- if [ "${PHP_MAJOR_VERSION}" = "8.2" -a "${CI_REPO}" = "friendica/friendica-addons" ]; then
|
||||
- if [ "${PHP_MAJOR_VERSION}" = "7.4" -a "${CI_REPO}" = "friendica/friendica-addons" ]; then
|
||||
phpenmod xdebug;
|
||||
export XDEBUG_MODE=coverage;
|
||||
phpunit --configuration tests/phpunit-addons.xml --coverage-clover clover.xml;
|
||||
|
@ -89,8 +87,8 @@ pipeline:
|
|||
image: friendicaci/codecov
|
||||
when:
|
||||
matrix:
|
||||
PHP_MAJOR_VERSION: 8.2
|
||||
PHP_VERSION: 8.2.16
|
||||
PHP_MAJOR_VERSION: 7.4
|
||||
PHP_VERSION: 7.4.33
|
||||
repo:
|
||||
- friendica/friendica-addons
|
||||
commands:
|
||||
|
|
|
@ -19,7 +19,7 @@ pipeline:
|
|||
commands:
|
||||
- git config --global user.email "no-reply@friendi.ca"
|
||||
- git config --global user.name "Friendica"
|
||||
- git clone $CI_REPO_CLONE_URL addon
|
||||
- git clone $CI_REPO_LINK addon
|
||||
- cd addon/
|
||||
- git checkout $CI_COMMIT_BRANCH
|
||||
- git fetch origin $CI_COMMIT_REF
|
||||
|
@ -42,7 +42,7 @@ pipeline:
|
|||
repo: friendica/friendica-addons
|
||||
event: tag
|
||||
composer_install:
|
||||
image: friendicaci/php8.2:php8.2.16
|
||||
image: friendicaci/php7.4:php7.4.33
|
||||
commands:
|
||||
- export COMPOSER_HOME=.composer
|
||||
- composer validate
|
||||
|
|
|
@ -54,7 +54,7 @@ new Vue({
|
|||
self.rules.push(responseJSON.rule);
|
||||
self.resetForm();
|
||||
}, function (response) {
|
||||
self.errorMessage = response.responseJSON.exception[0].message;
|
||||
self.errorMessage = response.responseJSON.message;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -74,7 +74,7 @@ new Vue({
|
|||
self.rules[self.editedIndex] = rule;
|
||||
self.resetForm();
|
||||
}, function (response) {
|
||||
self.errorMessage = response.responseJSON.exception[0].message;
|
||||
self.errorMessage = response.responseJSON.message;
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -253,7 +253,7 @@ function advancedcontentfilter_content()
|
|||
'cancel' => DI::l10n()->t('Cancel'),
|
||||
],
|
||||
'$current_theme' => DI::app()->getCurrentTheme(),
|
||||
'$rules' => DBA::toArray(DBA::select('advancedcontentfilter_rules', [], ['uid' => DI::userSession()->getLocalUserId()])),
|
||||
'$rules' => advancedcontentfilter_get_rules(),
|
||||
'$form_security_token' => BaseModule::getFormSecurityToken()
|
||||
]);
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ function advancedcontentfilter_build_fields($data)
|
|||
* API
|
||||
*/
|
||||
|
||||
function advancedcontentfilter_get_rules(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
||||
function advancedcontentfilter_get_rules(ServerRequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
if (!DI::userSession()->getLocalUserId()) {
|
||||
throw new HTTPException\UnauthorizedException(DI::l10n()->t('You must be logged in to use this method'));
|
||||
|
|
|
@ -17,9 +17,6 @@
|
|||
"license": "3-clause BSD license",
|
||||
"minimum-stability": "stable",
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.4"
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"autoloader-suffix": "AdvancedContentFilterAddon",
|
||||
"preferred-install": "dist"
|
||||
|
|
675
advancedcontentfilter/composer.lock
generated
675
advancedcontentfilter/composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "a7276eb2d2108a26699f69c750d02d27",
|
||||
"content-hash": "3e87f0369e4799fc35d98f399c67f1e9",
|
||||
"packages": [
|
||||
{
|
||||
"name": "nikic/fast-route",
|
||||
|
@ -100,22 +100,27 @@
|
|||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "1.1.2",
|
||||
"version": "2.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/container.git",
|
||||
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
|
||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
|
||||
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
|
@ -140,7 +145,7 @@
|
|||
"container-interop",
|
||||
"psr"
|
||||
],
|
||||
"time": "2021-11-05T16:50:12+00:00"
|
||||
"time": "2021-11-05T16:47:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-factory",
|
||||
|
@ -196,16 +201,16 @@
|
|||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"version": "2.0",
|
||||
"version": "1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-message.git",
|
||||
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
|
||||
"reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
|
||||
"reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -214,7 +219,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -229,7 +234,7 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP messages",
|
||||
|
@ -242,7 +247,7 @@
|
|||
"request",
|
||||
"response"
|
||||
],
|
||||
"time": "2023-04-04T09:54:51+00:00"
|
||||
"time": "2023-04-04T09:50:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-server-handler",
|
||||
|
@ -398,17 +403,65 @@
|
|||
"time": "2021-05-03T11:20:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "slim/slim",
|
||||
"version": "4.13.0",
|
||||
"name": "psr/simple-cache",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slimphp/Slim.git",
|
||||
"reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17"
|
||||
"url": "https://github.com/php-fig/simple-cache.git",
|
||||
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/038fd5713d5a41636fdff0e8dcceedecdd17fc17",
|
||||
"reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17",
|
||||
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
|
||||
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\SimpleCache\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interfaces for simple caching",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching",
|
||||
"psr",
|
||||
"psr-16",
|
||||
"simple-cache"
|
||||
],
|
||||
"time": "2017-10-23T01:57:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "slim/slim",
|
||||
"version": "4.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slimphp/Slim.git",
|
||||
"reference": "e9e99c2b24398b967841c6c4c3048622cc7e2b18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/e9e99c2b24398b967841c6c4c3048622cc7e2b18",
|
||||
"reference": "e9e99c2b24398b967841c6c4c3048622cc7e2b18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -417,7 +470,7 @@
|
|||
"php": "^7.4 || ^8.0",
|
||||
"psr/container": "^1.0 || ^2.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.1 || ^2.0",
|
||||
"psr/http-message": "^1.1",
|
||||
"psr/http-server-handler": "^1.0",
|
||||
"psr/http-server-middleware": "^1.0",
|
||||
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
||||
|
@ -425,19 +478,19 @@
|
|||
"require-dev": {
|
||||
"adriansuter/php-autoload-override": "^1.4",
|
||||
"ext-simplexml": "*",
|
||||
"guzzlehttp/psr7": "^2.6",
|
||||
"guzzlehttp/psr7": "^2.5",
|
||||
"httpsoft/http-message": "^1.1",
|
||||
"httpsoft/http-server-request": "^1.1",
|
||||
"laminas/laminas-diactoros": "^2.17 || ^3",
|
||||
"laminas/laminas-diactoros": "^2.17",
|
||||
"nyholm/psr7": "^1.8",
|
||||
"nyholm/psr7-server": "^1.1",
|
||||
"phpspec/prophecy": "^1.19",
|
||||
"phpspec/prophecy-phpunit": "^2.1",
|
||||
"nyholm/psr7-server": "^1.0",
|
||||
"phpspec/prophecy": "^1.17",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^9.6",
|
||||
"slim/http": "^1.3",
|
||||
"slim/psr7": "^1.6",
|
||||
"squizlabs/php_codesniffer": "^3.9"
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-simplexml": "Needed to support XML format in BodyParsingMiddleware",
|
||||
|
@ -500,54 +553,41 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-03T21:25:30+00:00"
|
||||
"time": "2023-07-23T04:54:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/cache",
|
||||
"version": "v4.4.48",
|
||||
"version": "v3.4.47",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/cache.git",
|
||||
"reference": "3b98ed664887ad197b8ede3da2432787212eb915"
|
||||
"reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/cache/zipball/3b98ed664887ad197b8ede3da2432787212eb915",
|
||||
"reference": "3b98ed664887ad197b8ede3da2432787212eb915",
|
||||
"url": "https://api.github.com/repos/symfony/cache/zipball/a7a14c4832760bd1fbd31be2859ffedc9b6ff813",
|
||||
"reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.3",
|
||||
"psr/cache": "^1.0|^2.0",
|
||||
"psr/log": "^1|^2|^3",
|
||||
"symfony/cache-contracts": "^1.1.7|^2",
|
||||
"symfony/polyfill-php73": "^1.9",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/service-contracts": "^1.1|^2",
|
||||
"symfony/var-exporter": "^4.2|^5.0"
|
||||
"php": "^5.5.9|>=7.0.8",
|
||||
"psr/cache": "~1.0",
|
||||
"psr/log": "~1.0",
|
||||
"psr/simple-cache": "^1.0",
|
||||
"symfony/polyfill-apcu": "~1.1"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/dbal": "<2.7",
|
||||
"symfony/dependency-injection": "<3.4",
|
||||
"symfony/http-kernel": "<4.4|>=5.0",
|
||||
"symfony/var-dumper": "<4.4"
|
||||
"symfony/var-dumper": "<3.3"
|
||||
},
|
||||
"provide": {
|
||||
"psr/cache-implementation": "1.0|2.0",
|
||||
"psr/simple-cache-implementation": "1.0|2.0",
|
||||
"symfony/cache-implementation": "1.0|2.0"
|
||||
"psr/cache-implementation": "1.0",
|
||||
"psr/simple-cache-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cache/integration-tests": "dev-master",
|
||||
"doctrine/cache": "^1.6|^2.0",
|
||||
"doctrine/dbal": "^2.7|^3.0",
|
||||
"predis/predis": "^1.1",
|
||||
"psr/simple-cache": "^1.0|^2.0",
|
||||
"symfony/config": "^4.2|^5.0",
|
||||
"symfony/dependency-injection": "^3.4|^4.1|^5.0",
|
||||
"symfony/filesystem": "^4.4|^5.0",
|
||||
"symfony/http-kernel": "^4.4",
|
||||
"symfony/var-dumper": "^4.4|^5.0"
|
||||
"doctrine/cache": "^1.6",
|
||||
"doctrine/dbal": "^2.4|^3.0",
|
||||
"predis/predis": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -572,7 +612,7 @@
|
|||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides extended PSR-6, PSR-16 (and tags) implementations",
|
||||
"description": "Symfony Cache component with PSR-6, PSR-16, and tags",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"caching",
|
||||
|
@ -592,147 +632,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-10-17T20:21:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/cache-contracts",
|
||||
"version": "v2.5.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/cache-contracts.git",
|
||||
"reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/cache-contracts/zipball/64be4a7acb83b6f2bf6de9a02cee6dad41277ebc",
|
||||
"reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"psr/cache": "^1.0|^2.0|^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/cache-implementation": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\Cache\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Generic abstractions related to caching",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"abstractions",
|
||||
"contracts",
|
||||
"decoupling",
|
||||
"interfaces",
|
||||
"interoperability",
|
||||
"standards"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-02T09:53:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v2.5.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
|
||||
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"function.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-02T09:53:40+00:00"
|
||||
"time": "2020-10-24T10:57:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/expression-language",
|
||||
|
@ -794,6 +694,80 @@
|
|||
],
|
||||
"time": "2020-10-24T10:57:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-apcu",
|
||||
"version": "v1.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-apcu.git",
|
||||
"reference": "c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899",
|
||||
"reference": "c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Apcu\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting apcu_* functions to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"apcu",
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-26T09:26:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php70",
|
||||
"version": "v1.20.0",
|
||||
|
@ -858,306 +832,6 @@
|
|||
}
|
||||
],
|
||||
"time": "2020-10-23T14:02:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php73",
|
||||
"version": "v1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php73.git",
|
||||
"reference": "21bd091060673a1177ae842c0ef8fe30893114d2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2",
|
||||
"reference": "21bd091060673a1177ae842c0ef8fe30893114d2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php73\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php80\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ion Bazan",
|
||||
"email": "ion.bazan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
"version": "v2.5.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/service-contracts.git",
|
||||
"reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
|
||||
"reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"psr/container": "^1.1",
|
||||
"symfony/deprecation-contracts": "^2.1|^3"
|
||||
},
|
||||
"conflict": {
|
||||
"ext-psr": "<1.1|>=2"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/service-implementation": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\Service\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Generic abstractions related to writing services",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"abstractions",
|
||||
"contracts",
|
||||
"decoupling",
|
||||
"interfaces",
|
||||
"interoperability",
|
||||
"standards"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-30T19:17:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-exporter",
|
||||
"version": "v5.4.35",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-exporter.git",
|
||||
"reference": "abb0a151b62d6b07e816487e20040464af96cae7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/abb0a151b62d6b07e816487e20040464af96cae7",
|
||||
"reference": "abb0a151b62d6b07e816487e20040464af96cae7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": "^4.4.9|^5.0.9|^6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\VarExporter\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Allows exporting any serializable PHP data structure to plain PHP code",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"clone",
|
||||
"construct",
|
||||
"export",
|
||||
"hydrate",
|
||||
"instantiate",
|
||||
"serialize"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-23T13:51:25+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
@ -1166,10 +840,9 @@
|
|||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"platform-overrides": {
|
||||
"php": "7.4"
|
||||
"platform": {
|
||||
"php": ">=5.6.0"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "1.1.0"
|
||||
}
|
||||
|
|
|
@ -29,4 +29,4 @@ use Friendica\DI;
|
|||
*/
|
||||
$slim->addRoutingMiddleware();
|
||||
|
||||
$errorMiddleware = $slim->addErrorMiddleware(true, true, true, DI::logger());
|
||||
$errorMiddleware = $slim->addErrorMiddleware(true, true, true);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div id="rules"></div>
|
||||
|
||||
<script>
|
||||
var existingRules = {{$rules|json_encode nofilter}};
|
||||
var existingRules = {{$rules nofilter}};
|
||||
|
||||
var messages = {
|
||||
{{foreach $messages as $key => $value}}
|
||||
|
|
|
@ -6,7 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'FastRoute\\BadRouteException' => $vendorDir . '/nikic/fast-route/src/BadRouteException.php',
|
||||
'FastRoute\\DataGenerator' => $vendorDir . '/nikic/fast-route/src/DataGenerator.php',
|
||||
'FastRoute\\DataGenerator\\CharCountBased' => $vendorDir . '/nikic/fast-route/src/DataGenerator/CharCountBased.php',
|
||||
|
@ -24,8 +23,6 @@ return array(
|
|||
'FastRoute\\RouteCollector' => $vendorDir . '/nikic/fast-route/src/RouteCollector.php',
|
||||
'FastRoute\\RouteParser' => $vendorDir . '/nikic/fast-route/src/RouteParser.php',
|
||||
'FastRoute\\RouteParser\\Std' => $vendorDir . '/nikic/fast-route/src/RouteParser/Std.php',
|
||||
'JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
|
||||
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||
'Psr\\Cache\\CacheException' => $vendorDir . '/psr/cache/src/CacheException.php',
|
||||
'Psr\\Cache\\CacheItemInterface' => $vendorDir . '/psr/cache/src/CacheItemInterface.php',
|
||||
'Psr\\Cache\\CacheItemPoolInterface' => $vendorDir . '/psr/cache/src/CacheItemPoolInterface.php',
|
||||
|
@ -59,6 +56,9 @@ return array(
|
|||
'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/DummyTest.php',
|
||||
'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
|
||||
'Psr\\Log\\Test\\TestLogger' => $vendorDir . '/psr/log/Psr/Log/Test/TestLogger.php',
|
||||
'Psr\\SimpleCache\\CacheException' => $vendorDir . '/psr/simple-cache/src/CacheException.php',
|
||||
'Psr\\SimpleCache\\CacheInterface' => $vendorDir . '/psr/simple-cache/src/CacheInterface.php',
|
||||
'Psr\\SimpleCache\\InvalidArgumentException' => $vendorDir . '/psr/simple-cache/src/InvalidArgumentException.php',
|
||||
'Slim\\App' => $vendorDir . '/slim/slim/Slim/App.php',
|
||||
'Slim\\CallableResolver' => $vendorDir . '/slim/slim/Slim/CallableResolver.php',
|
||||
'Slim\\Error\\AbstractErrorRenderer' => $vendorDir . '/slim/slim/Slim/Error/AbstractErrorRenderer.php',
|
||||
|
@ -75,7 +75,6 @@ return array(
|
|||
'Slim\\Exception\\HttpNotFoundException' => $vendorDir . '/slim/slim/Slim/Exception/HttpNotFoundException.php',
|
||||
'Slim\\Exception\\HttpNotImplementedException' => $vendorDir . '/slim/slim/Slim/Exception/HttpNotImplementedException.php',
|
||||
'Slim\\Exception\\HttpSpecializedException' => $vendorDir . '/slim/slim/Slim/Exception/HttpSpecializedException.php',
|
||||
'Slim\\Exception\\HttpTooManyRequestsException' => $vendorDir . '/slim/slim/Slim/Exception/HttpTooManyRequestsException.php',
|
||||
'Slim\\Exception\\HttpUnauthorizedException' => $vendorDir . '/slim/slim/Slim/Exception/HttpUnauthorizedException.php',
|
||||
'Slim\\Factory\\AppFactory' => $vendorDir . '/slim/slim/Slim/Factory/AppFactory.php',
|
||||
'Slim\\Factory\\Psr17\\GuzzlePsr17Factory' => $vendorDir . '/slim/slim/Slim/Factory/Psr17/GuzzlePsr17Factory.php',
|
||||
|
@ -131,25 +130,20 @@ return array(
|
|||
'Slim\\Routing\\RouteResolver' => $vendorDir . '/slim/slim/Slim/Routing/RouteResolver.php',
|
||||
'Slim\\Routing\\RouteRunner' => $vendorDir . '/slim/slim/Slim/Routing/RouteRunner.php',
|
||||
'Slim\\Routing\\RoutingResults' => $vendorDir . '/slim/slim/Slim/Routing/RoutingResults.php',
|
||||
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\AbstractAdapter' => $vendorDir . '/symfony/cache/Adapter/AbstractAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\AbstractTagAwareAdapter' => $vendorDir . '/symfony/cache/Adapter/AbstractTagAwareAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\AdapterInterface' => $vendorDir . '/symfony/cache/Adapter/AdapterInterface.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\ApcuAdapter' => $vendorDir . '/symfony/cache/Adapter/ApcuAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\ArrayAdapter' => $vendorDir . '/symfony/cache/Adapter/ArrayAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\ChainAdapter' => $vendorDir . '/symfony/cache/Adapter/ChainAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\DoctrineAdapter' => $vendorDir . '/symfony/cache/Adapter/DoctrineAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter' => $vendorDir . '/symfony/cache/Adapter/FilesystemAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\FilesystemTagAwareAdapter' => $vendorDir . '/symfony/cache/Adapter/FilesystemTagAwareAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\MemcachedAdapter' => $vendorDir . '/symfony/cache/Adapter/MemcachedAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\NullAdapter' => $vendorDir . '/symfony/cache/Adapter/NullAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\PdoAdapter' => $vendorDir . '/symfony/cache/Adapter/PdoAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\PhpArrayAdapter' => $vendorDir . '/symfony/cache/Adapter/PhpArrayAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\PhpFilesAdapter' => $vendorDir . '/symfony/cache/Adapter/PhpFilesAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\ProxyAdapter' => $vendorDir . '/symfony/cache/Adapter/ProxyAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\Psr16Adapter' => $vendorDir . '/symfony/cache/Adapter/Psr16Adapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\RedisAdapter' => $vendorDir . '/symfony/cache/Adapter/RedisAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\RedisTagAwareAdapter' => $vendorDir . '/symfony/cache/Adapter/RedisTagAwareAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\SimpleCacheAdapter' => $vendorDir . '/symfony/cache/Adapter/SimpleCacheAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter' => $vendorDir . '/symfony/cache/Adapter/TagAwareAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapterInterface' => $vendorDir . '/symfony/cache/Adapter/TagAwareAdapterInterface.php',
|
||||
|
@ -158,21 +152,10 @@ return array(
|
|||
'Symfony\\Component\\Cache\\Adapter\\TraceableTagAwareAdapter' => $vendorDir . '/symfony/cache/Adapter/TraceableTagAwareAdapter.php',
|
||||
'Symfony\\Component\\Cache\\CacheItem' => $vendorDir . '/symfony/cache/CacheItem.php',
|
||||
'Symfony\\Component\\Cache\\DataCollector\\CacheDataCollector' => $vendorDir . '/symfony/cache/DataCollector/CacheDataCollector.php',
|
||||
'Symfony\\Component\\Cache\\DependencyInjection\\CacheCollectorPass' => $vendorDir . '/symfony/cache/DependencyInjection/CacheCollectorPass.php',
|
||||
'Symfony\\Component\\Cache\\DependencyInjection\\CachePoolClearerPass' => $vendorDir . '/symfony/cache/DependencyInjection/CachePoolClearerPass.php',
|
||||
'Symfony\\Component\\Cache\\DependencyInjection\\CachePoolPass' => $vendorDir . '/symfony/cache/DependencyInjection/CachePoolPass.php',
|
||||
'Symfony\\Component\\Cache\\DependencyInjection\\CachePoolPrunerPass' => $vendorDir . '/symfony/cache/DependencyInjection/CachePoolPrunerPass.php',
|
||||
'Symfony\\Component\\Cache\\DoctrineProvider' => $vendorDir . '/symfony/cache/DoctrineProvider.php',
|
||||
'Symfony\\Component\\Cache\\Exception\\CacheException' => $vendorDir . '/symfony/cache/Exception/CacheException.php',
|
||||
'Symfony\\Component\\Cache\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/cache/Exception/InvalidArgumentException.php',
|
||||
'Symfony\\Component\\Cache\\Exception\\LogicException' => $vendorDir . '/symfony/cache/Exception/LogicException.php',
|
||||
'Symfony\\Component\\Cache\\LockRegistry' => $vendorDir . '/symfony/cache/LockRegistry.php',
|
||||
'Symfony\\Component\\Cache\\Marshaller\\DefaultMarshaller' => $vendorDir . '/symfony/cache/Marshaller/DefaultMarshaller.php',
|
||||
'Symfony\\Component\\Cache\\Marshaller\\DeflateMarshaller' => $vendorDir . '/symfony/cache/Marshaller/DeflateMarshaller.php',
|
||||
'Symfony\\Component\\Cache\\Marshaller\\MarshallerInterface' => $vendorDir . '/symfony/cache/Marshaller/MarshallerInterface.php',
|
||||
'Symfony\\Component\\Cache\\Marshaller\\TagAwareMarshaller' => $vendorDir . '/symfony/cache/Marshaller/TagAwareMarshaller.php',
|
||||
'Symfony\\Component\\Cache\\PruneableInterface' => $vendorDir . '/symfony/cache/PruneableInterface.php',
|
||||
'Symfony\\Component\\Cache\\Psr16Cache' => $vendorDir . '/symfony/cache/Psr16Cache.php',
|
||||
'Symfony\\Component\\Cache\\ResettableInterface' => $vendorDir . '/symfony/cache/ResettableInterface.php',
|
||||
'Symfony\\Component\\Cache\\Simple\\AbstractCache' => $vendorDir . '/symfony/cache/Simple/AbstractCache.php',
|
||||
'Symfony\\Component\\Cache\\Simple\\ApcuCache' => $vendorDir . '/symfony/cache/Simple/ApcuCache.php',
|
||||
|
@ -189,22 +172,17 @@ return array(
|
|||
'Symfony\\Component\\Cache\\Simple\\RedisCache' => $vendorDir . '/symfony/cache/Simple/RedisCache.php',
|
||||
'Symfony\\Component\\Cache\\Simple\\TraceableCache' => $vendorDir . '/symfony/cache/Simple/TraceableCache.php',
|
||||
'Symfony\\Component\\Cache\\Simple\\TraceableCacheEvent' => $vendorDir . '/symfony/cache/Simple/TraceableCache.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\AbstractAdapterTrait' => $vendorDir . '/symfony/cache/Traits/AbstractAdapterTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\AbstractTrait' => $vendorDir . '/symfony/cache/Traits/AbstractTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\ApcuTrait' => $vendorDir . '/symfony/cache/Traits/ApcuTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\ArrayTrait' => $vendorDir . '/symfony/cache/Traits/ArrayTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\ContractsTrait' => $vendorDir . '/symfony/cache/Traits/ContractsTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\DoctrineTrait' => $vendorDir . '/symfony/cache/Traits/DoctrineTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\FilesystemCommonTrait' => $vendorDir . '/symfony/cache/Traits/FilesystemCommonTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\FilesystemTrait' => $vendorDir . '/symfony/cache/Traits/FilesystemTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\LazyValue' => $vendorDir . '/symfony/cache/Traits/PhpFilesTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\MemcachedTrait' => $vendorDir . '/symfony/cache/Traits/MemcachedTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\PdoTrait' => $vendorDir . '/symfony/cache/Traits/PdoTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\PhpArrayTrait' => $vendorDir . '/symfony/cache/Traits/PhpArrayTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\PhpFilesTrait' => $vendorDir . '/symfony/cache/Traits/PhpFilesTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\ProxyTrait' => $vendorDir . '/symfony/cache/Traits/ProxyTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\RedisClusterNodeProxy' => $vendorDir . '/symfony/cache/Traits/RedisClusterNodeProxy.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\RedisClusterProxy' => $vendorDir . '/symfony/cache/Traits/RedisClusterProxy.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\RedisProxy' => $vendorDir . '/symfony/cache/Traits/RedisProxy.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\RedisTrait' => $vendorDir . '/symfony/cache/Traits/RedisTrait.php',
|
||||
'Symfony\\Component\\ExpressionLanguage\\Compiler' => $vendorDir . '/symfony/expression-language/Compiler.php',
|
||||
|
@ -232,32 +210,5 @@ return array(
|
|||
'Symfony\\Component\\ExpressionLanguage\\SyntaxError' => $vendorDir . '/symfony/expression-language/SyntaxError.php',
|
||||
'Symfony\\Component\\ExpressionLanguage\\Token' => $vendorDir . '/symfony/expression-language/Token.php',
|
||||
'Symfony\\Component\\ExpressionLanguage\\TokenStream' => $vendorDir . '/symfony/expression-language/TokenStream.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ClassNotFoundException' => $vendorDir . '/symfony/var-exporter/Exception/ClassNotFoundException.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/var-exporter/Exception/ExceptionInterface.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\NotInstantiableTypeException' => $vendorDir . '/symfony/var-exporter/Exception/NotInstantiableTypeException.php',
|
||||
'Symfony\\Component\\VarExporter\\Instantiator' => $vendorDir . '/symfony/var-exporter/Instantiator.php',
|
||||
'Symfony\\Component\\VarExporter\\Internal\\Exporter' => $vendorDir . '/symfony/var-exporter/Internal/Exporter.php',
|
||||
'Symfony\\Component\\VarExporter\\Internal\\Hydrator' => $vendorDir . '/symfony/var-exporter/Internal/Hydrator.php',
|
||||
'Symfony\\Component\\VarExporter\\Internal\\Reference' => $vendorDir . '/symfony/var-exporter/Internal/Reference.php',
|
||||
'Symfony\\Component\\VarExporter\\Internal\\Registry' => $vendorDir . '/symfony/var-exporter/Internal/Registry.php',
|
||||
'Symfony\\Component\\VarExporter\\Internal\\Values' => $vendorDir . '/symfony/var-exporter/Internal/Values.php',
|
||||
'Symfony\\Component\\VarExporter\\VarExporter' => $vendorDir . '/symfony/var-exporter/VarExporter.php',
|
||||
'Symfony\\Contracts\\Cache\\CacheInterface' => $vendorDir . '/symfony/cache-contracts/CacheInterface.php',
|
||||
'Symfony\\Contracts\\Cache\\CacheTrait' => $vendorDir . '/symfony/cache-contracts/CacheTrait.php',
|
||||
'Symfony\\Contracts\\Cache\\CallbackInterface' => $vendorDir . '/symfony/cache-contracts/CallbackInterface.php',
|
||||
'Symfony\\Contracts\\Cache\\ItemInterface' => $vendorDir . '/symfony/cache-contracts/ItemInterface.php',
|
||||
'Symfony\\Contracts\\Cache\\TagAwareCacheInterface' => $vendorDir . '/symfony/cache-contracts/TagAwareCacheInterface.php',
|
||||
'Symfony\\Contracts\\Service\\Attribute\\Required' => $vendorDir . '/symfony/service-contracts/Attribute/Required.php',
|
||||
'Symfony\\Contracts\\Service\\Attribute\\SubscribedService' => $vendorDir . '/symfony/service-contracts/Attribute/SubscribedService.php',
|
||||
'Symfony\\Contracts\\Service\\ResetInterface' => $vendorDir . '/symfony/service-contracts/ResetInterface.php',
|
||||
'Symfony\\Contracts\\Service\\ServiceLocatorTrait' => $vendorDir . '/symfony/service-contracts/ServiceLocatorTrait.php',
|
||||
'Symfony\\Contracts\\Service\\ServiceProviderInterface' => $vendorDir . '/symfony/service-contracts/ServiceProviderInterface.php',
|
||||
'Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => $vendorDir . '/symfony/service-contracts/ServiceSubscriberInterface.php',
|
||||
'Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => $vendorDir . '/symfony/service-contracts/ServiceSubscriberTrait.php',
|
||||
'Symfony\\Contracts\\Service\\Test\\ServiceLocatorTest' => $vendorDir . '/symfony/service-contracts/Test/ServiceLocatorTest.php',
|
||||
'Symfony\\Polyfill\\Php73\\Php73' => $vendorDir . '/symfony/polyfill-php73/Php73.php',
|
||||
'Symfony\\Polyfill\\Php80\\Php80' => $vendorDir . '/symfony/polyfill-php80/Php80.php',
|
||||
'Symfony\\Polyfill\\Php80\\PhpToken' => $vendorDir . '/symfony/polyfill-php80/PhpToken.php',
|
||||
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
'Symfony\\Polyfill\\Apcu\\Apcu' => $vendorDir . '/symfony/polyfill-apcu/Apcu.php',
|
||||
);
|
||||
|
|
|
@ -6,8 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||
'0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',
|
||||
'32dcc8afd4335739640db7d200c1971d' => $vendorDir . '/symfony/polyfill-apcu/bootstrap.php',
|
||||
'253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php',
|
||||
);
|
||||
|
|
|
@ -6,14 +6,11 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
|
||||
'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'),
|
||||
'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'),
|
||||
'Symfony\\Contracts\\Cache\\' => array($vendorDir . '/symfony/cache-contracts'),
|
||||
'Symfony\\Component\\VarExporter\\' => array($vendorDir . '/symfony/var-exporter'),
|
||||
'Symfony\\Polyfill\\Apcu\\' => array($vendorDir . '/symfony/polyfill-apcu'),
|
||||
'Symfony\\Component\\ExpressionLanguage\\' => array($vendorDir . '/symfony/expression-language'),
|
||||
'Symfony\\Component\\Cache\\' => array($vendorDir . '/symfony/cache'),
|
||||
'Slim\\' => array($vendorDir . '/slim/slim/Slim'),
|
||||
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
|
||||
'Psr\\Http\\Server\\' => array($vendorDir . '/psr/http-server-handler/src', $vendorDir . '/psr/http-server-middleware/src'),
|
||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
|
||||
|
|
|
@ -7,26 +7,21 @@ namespace Composer\Autoload;
|
|||
class ComposerStaticInitAdvancedContentFilterAddon
|
||||
{
|
||||
public static $files = array (
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
||||
'0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php',
|
||||
'32dcc8afd4335739640db7d200c1971d' => __DIR__ . '/..' . '/symfony/polyfill-apcu/bootstrap.php',
|
||||
'253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'S' =>
|
||||
array (
|
||||
'Symfony\\Polyfill\\Php80\\' => 23,
|
||||
'Symfony\\Polyfill\\Php73\\' => 23,
|
||||
'Symfony\\Contracts\\Service\\' => 26,
|
||||
'Symfony\\Contracts\\Cache\\' => 24,
|
||||
'Symfony\\Component\\VarExporter\\' => 30,
|
||||
'Symfony\\Polyfill\\Apcu\\' => 22,
|
||||
'Symfony\\Component\\ExpressionLanguage\\' => 37,
|
||||
'Symfony\\Component\\Cache\\' => 24,
|
||||
'Slim\\' => 5,
|
||||
),
|
||||
'P' =>
|
||||
array (
|
||||
'Psr\\SimpleCache\\' => 16,
|
||||
'Psr\\Log\\' => 8,
|
||||
'Psr\\Http\\Server\\' => 16,
|
||||
'Psr\\Http\\Message\\' => 17,
|
||||
|
@ -40,25 +35,9 @@ class ComposerStaticInitAdvancedContentFilterAddon
|
|||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'Symfony\\Polyfill\\Php80\\' =>
|
||||
'Symfony\\Polyfill\\Apcu\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
|
||||
),
|
||||
'Symfony\\Polyfill\\Php73\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-php73',
|
||||
),
|
||||
'Symfony\\Contracts\\Service\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/service-contracts',
|
||||
),
|
||||
'Symfony\\Contracts\\Cache\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/cache-contracts',
|
||||
),
|
||||
'Symfony\\Component\\VarExporter\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/var-exporter',
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-apcu',
|
||||
),
|
||||
'Symfony\\Component\\ExpressionLanguage\\' =>
|
||||
array (
|
||||
|
@ -72,6 +51,10 @@ class ComposerStaticInitAdvancedContentFilterAddon
|
|||
array (
|
||||
0 => __DIR__ . '/..' . '/slim/slim/Slim',
|
||||
),
|
||||
'Psr\\SimpleCache\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/simple-cache/src',
|
||||
),
|
||||
'Psr\\Log\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
|
||||
|
@ -101,7 +84,6 @@ class ComposerStaticInitAdvancedContentFilterAddon
|
|||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'FastRoute\\BadRouteException' => __DIR__ . '/..' . '/nikic/fast-route/src/BadRouteException.php',
|
||||
'FastRoute\\DataGenerator' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator.php',
|
||||
'FastRoute\\DataGenerator\\CharCountBased' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator/CharCountBased.php',
|
||||
|
@ -119,8 +101,6 @@ class ComposerStaticInitAdvancedContentFilterAddon
|
|||
'FastRoute\\RouteCollector' => __DIR__ . '/..' . '/nikic/fast-route/src/RouteCollector.php',
|
||||
'FastRoute\\RouteParser' => __DIR__ . '/..' . '/nikic/fast-route/src/RouteParser.php',
|
||||
'FastRoute\\RouteParser\\Std' => __DIR__ . '/..' . '/nikic/fast-route/src/RouteParser/Std.php',
|
||||
'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
|
||||
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||
'Psr\\Cache\\CacheException' => __DIR__ . '/..' . '/psr/cache/src/CacheException.php',
|
||||
'Psr\\Cache\\CacheItemInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemInterface.php',
|
||||
'Psr\\Cache\\CacheItemPoolInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemPoolInterface.php',
|
||||
|
@ -154,6 +134,9 @@ class ComposerStaticInitAdvancedContentFilterAddon
|
|||
'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/DummyTest.php',
|
||||
'Psr\\Log\\Test\\LoggerInterfaceTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
|
||||
'Psr\\Log\\Test\\TestLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/TestLogger.php',
|
||||
'Psr\\SimpleCache\\CacheException' => __DIR__ . '/..' . '/psr/simple-cache/src/CacheException.php',
|
||||
'Psr\\SimpleCache\\CacheInterface' => __DIR__ . '/..' . '/psr/simple-cache/src/CacheInterface.php',
|
||||
'Psr\\SimpleCache\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/simple-cache/src/InvalidArgumentException.php',
|
||||
'Slim\\App' => __DIR__ . '/..' . '/slim/slim/Slim/App.php',
|
||||
'Slim\\CallableResolver' => __DIR__ . '/..' . '/slim/slim/Slim/CallableResolver.php',
|
||||
'Slim\\Error\\AbstractErrorRenderer' => __DIR__ . '/..' . '/slim/slim/Slim/Error/AbstractErrorRenderer.php',
|
||||
|
@ -170,7 +153,6 @@ class ComposerStaticInitAdvancedContentFilterAddon
|
|||
'Slim\\Exception\\HttpNotFoundException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpNotFoundException.php',
|
||||
'Slim\\Exception\\HttpNotImplementedException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpNotImplementedException.php',
|
||||
'Slim\\Exception\\HttpSpecializedException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpSpecializedException.php',
|
||||
'Slim\\Exception\\HttpTooManyRequestsException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpTooManyRequestsException.php',
|
||||
'Slim\\Exception\\HttpUnauthorizedException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpUnauthorizedException.php',
|
||||
'Slim\\Factory\\AppFactory' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/AppFactory.php',
|
||||
'Slim\\Factory\\Psr17\\GuzzlePsr17Factory' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/Psr17/GuzzlePsr17Factory.php',
|
||||
|
@ -226,25 +208,20 @@ class ComposerStaticInitAdvancedContentFilterAddon
|
|||
'Slim\\Routing\\RouteResolver' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/RouteResolver.php',
|
||||
'Slim\\Routing\\RouteRunner' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/RouteRunner.php',
|
||||
'Slim\\Routing\\RoutingResults' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/RoutingResults.php',
|
||||
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\AbstractAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/AbstractAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\AbstractTagAwareAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/AbstractTagAwareAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\AdapterInterface' => __DIR__ . '/..' . '/symfony/cache/Adapter/AdapterInterface.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\ApcuAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/ApcuAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\ArrayAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/ArrayAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\ChainAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/ChainAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\DoctrineAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/DoctrineAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/FilesystemAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\FilesystemTagAwareAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/FilesystemTagAwareAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\MemcachedAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/MemcachedAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\NullAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/NullAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\PdoAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/PdoAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\PhpArrayAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/PhpArrayAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\PhpFilesAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/PhpFilesAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\ProxyAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/ProxyAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\Psr16Adapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/Psr16Adapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\RedisAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/RedisAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\RedisTagAwareAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/RedisTagAwareAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\SimpleCacheAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/SimpleCacheAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/TagAwareAdapter.php',
|
||||
'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapterInterface' => __DIR__ . '/..' . '/symfony/cache/Adapter/TagAwareAdapterInterface.php',
|
||||
|
@ -253,21 +230,10 @@ class ComposerStaticInitAdvancedContentFilterAddon
|
|||
'Symfony\\Component\\Cache\\Adapter\\TraceableTagAwareAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/TraceableTagAwareAdapter.php',
|
||||
'Symfony\\Component\\Cache\\CacheItem' => __DIR__ . '/..' . '/symfony/cache/CacheItem.php',
|
||||
'Symfony\\Component\\Cache\\DataCollector\\CacheDataCollector' => __DIR__ . '/..' . '/symfony/cache/DataCollector/CacheDataCollector.php',
|
||||
'Symfony\\Component\\Cache\\DependencyInjection\\CacheCollectorPass' => __DIR__ . '/..' . '/symfony/cache/DependencyInjection/CacheCollectorPass.php',
|
||||
'Symfony\\Component\\Cache\\DependencyInjection\\CachePoolClearerPass' => __DIR__ . '/..' . '/symfony/cache/DependencyInjection/CachePoolClearerPass.php',
|
||||
'Symfony\\Component\\Cache\\DependencyInjection\\CachePoolPass' => __DIR__ . '/..' . '/symfony/cache/DependencyInjection/CachePoolPass.php',
|
||||
'Symfony\\Component\\Cache\\DependencyInjection\\CachePoolPrunerPass' => __DIR__ . '/..' . '/symfony/cache/DependencyInjection/CachePoolPrunerPass.php',
|
||||
'Symfony\\Component\\Cache\\DoctrineProvider' => __DIR__ . '/..' . '/symfony/cache/DoctrineProvider.php',
|
||||
'Symfony\\Component\\Cache\\Exception\\CacheException' => __DIR__ . '/..' . '/symfony/cache/Exception/CacheException.php',
|
||||
'Symfony\\Component\\Cache\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/cache/Exception/InvalidArgumentException.php',
|
||||
'Symfony\\Component\\Cache\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/cache/Exception/LogicException.php',
|
||||
'Symfony\\Component\\Cache\\LockRegistry' => __DIR__ . '/..' . '/symfony/cache/LockRegistry.php',
|
||||
'Symfony\\Component\\Cache\\Marshaller\\DefaultMarshaller' => __DIR__ . '/..' . '/symfony/cache/Marshaller/DefaultMarshaller.php',
|
||||
'Symfony\\Component\\Cache\\Marshaller\\DeflateMarshaller' => __DIR__ . '/..' . '/symfony/cache/Marshaller/DeflateMarshaller.php',
|
||||
'Symfony\\Component\\Cache\\Marshaller\\MarshallerInterface' => __DIR__ . '/..' . '/symfony/cache/Marshaller/MarshallerInterface.php',
|
||||
'Symfony\\Component\\Cache\\Marshaller\\TagAwareMarshaller' => __DIR__ . '/..' . '/symfony/cache/Marshaller/TagAwareMarshaller.php',
|
||||
'Symfony\\Component\\Cache\\PruneableInterface' => __DIR__ . '/..' . '/symfony/cache/PruneableInterface.php',
|
||||
'Symfony\\Component\\Cache\\Psr16Cache' => __DIR__ . '/..' . '/symfony/cache/Psr16Cache.php',
|
||||
'Symfony\\Component\\Cache\\ResettableInterface' => __DIR__ . '/..' . '/symfony/cache/ResettableInterface.php',
|
||||
'Symfony\\Component\\Cache\\Simple\\AbstractCache' => __DIR__ . '/..' . '/symfony/cache/Simple/AbstractCache.php',
|
||||
'Symfony\\Component\\Cache\\Simple\\ApcuCache' => __DIR__ . '/..' . '/symfony/cache/Simple/ApcuCache.php',
|
||||
|
@ -284,22 +250,17 @@ class ComposerStaticInitAdvancedContentFilterAddon
|
|||
'Symfony\\Component\\Cache\\Simple\\RedisCache' => __DIR__ . '/..' . '/symfony/cache/Simple/RedisCache.php',
|
||||
'Symfony\\Component\\Cache\\Simple\\TraceableCache' => __DIR__ . '/..' . '/symfony/cache/Simple/TraceableCache.php',
|
||||
'Symfony\\Component\\Cache\\Simple\\TraceableCacheEvent' => __DIR__ . '/..' . '/symfony/cache/Simple/TraceableCache.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\AbstractAdapterTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/AbstractAdapterTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\AbstractTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/AbstractTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\ApcuTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ApcuTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\ArrayTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ArrayTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\ContractsTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ContractsTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\DoctrineTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/DoctrineTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\FilesystemCommonTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/FilesystemCommonTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\FilesystemTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/FilesystemTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\LazyValue' => __DIR__ . '/..' . '/symfony/cache/Traits/PhpFilesTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\MemcachedTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/MemcachedTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\PdoTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/PdoTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\PhpArrayTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/PhpArrayTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\PhpFilesTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/PhpFilesTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ProxyTrait.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\RedisClusterNodeProxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisClusterNodeProxy.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\RedisClusterProxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisClusterProxy.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\RedisProxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisProxy.php',
|
||||
'Symfony\\Component\\Cache\\Traits\\RedisTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisTrait.php',
|
||||
'Symfony\\Component\\ExpressionLanguage\\Compiler' => __DIR__ . '/..' . '/symfony/expression-language/Compiler.php',
|
||||
|
@ -327,34 +288,7 @@ class ComposerStaticInitAdvancedContentFilterAddon
|
|||
'Symfony\\Component\\ExpressionLanguage\\SyntaxError' => __DIR__ . '/..' . '/symfony/expression-language/SyntaxError.php',
|
||||
'Symfony\\Component\\ExpressionLanguage\\Token' => __DIR__ . '/..' . '/symfony/expression-language/Token.php',
|
||||
'Symfony\\Component\\ExpressionLanguage\\TokenStream' => __DIR__ . '/..' . '/symfony/expression-language/TokenStream.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ClassNotFoundException' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/ClassNotFoundException.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/ExceptionInterface.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\NotInstantiableTypeException' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/NotInstantiableTypeException.php',
|
||||
'Symfony\\Component\\VarExporter\\Instantiator' => __DIR__ . '/..' . '/symfony/var-exporter/Instantiator.php',
|
||||
'Symfony\\Component\\VarExporter\\Internal\\Exporter' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/Exporter.php',
|
||||
'Symfony\\Component\\VarExporter\\Internal\\Hydrator' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/Hydrator.php',
|
||||
'Symfony\\Component\\VarExporter\\Internal\\Reference' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/Reference.php',
|
||||
'Symfony\\Component\\VarExporter\\Internal\\Registry' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/Registry.php',
|
||||
'Symfony\\Component\\VarExporter\\Internal\\Values' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/Values.php',
|
||||
'Symfony\\Component\\VarExporter\\VarExporter' => __DIR__ . '/..' . '/symfony/var-exporter/VarExporter.php',
|
||||
'Symfony\\Contracts\\Cache\\CacheInterface' => __DIR__ . '/..' . '/symfony/cache-contracts/CacheInterface.php',
|
||||
'Symfony\\Contracts\\Cache\\CacheTrait' => __DIR__ . '/..' . '/symfony/cache-contracts/CacheTrait.php',
|
||||
'Symfony\\Contracts\\Cache\\CallbackInterface' => __DIR__ . '/..' . '/symfony/cache-contracts/CallbackInterface.php',
|
||||
'Symfony\\Contracts\\Cache\\ItemInterface' => __DIR__ . '/..' . '/symfony/cache-contracts/ItemInterface.php',
|
||||
'Symfony\\Contracts\\Cache\\TagAwareCacheInterface' => __DIR__ . '/..' . '/symfony/cache-contracts/TagAwareCacheInterface.php',
|
||||
'Symfony\\Contracts\\Service\\Attribute\\Required' => __DIR__ . '/..' . '/symfony/service-contracts/Attribute/Required.php',
|
||||
'Symfony\\Contracts\\Service\\Attribute\\SubscribedService' => __DIR__ . '/..' . '/symfony/service-contracts/Attribute/SubscribedService.php',
|
||||
'Symfony\\Contracts\\Service\\ResetInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ResetInterface.php',
|
||||
'Symfony\\Contracts\\Service\\ServiceLocatorTrait' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceLocatorTrait.php',
|
||||
'Symfony\\Contracts\\Service\\ServiceProviderInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceProviderInterface.php',
|
||||
'Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceSubscriberInterface.php',
|
||||
'Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceSubscriberTrait.php',
|
||||
'Symfony\\Contracts\\Service\\Test\\ServiceLocatorTest' => __DIR__ . '/..' . '/symfony/service-contracts/Test/ServiceLocatorTest.php',
|
||||
'Symfony\\Polyfill\\Php73\\Php73' => __DIR__ . '/..' . '/symfony/polyfill-php73/Php73.php',
|
||||
'Symfony\\Polyfill\\Php80\\Php80' => __DIR__ . '/..' . '/symfony/polyfill-php80/Php80.php',
|
||||
'Symfony\\Polyfill\\Php80\\PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/PhpToken.php',
|
||||
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
'Symfony\\Polyfill\\Apcu\\Apcu' => __DIR__ . '/..' . '/symfony/polyfill-apcu/Apcu.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
|
|
690
advancedcontentfilter/vendor/composer/installed.json
vendored
690
advancedcontentfilter/vendor/composer/installed.json
vendored
|
@ -97,24 +97,29 @@
|
|||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "1.1.2",
|
||||
"version_normalized": "1.1.2.0",
|
||||
"version": "2.0.2",
|
||||
"version_normalized": "2.0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/container.git",
|
||||
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
|
||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
|
||||
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4.0"
|
||||
},
|
||||
"time": "2021-11-05T16:50:12+00:00",
|
||||
"time": "2021-11-05T16:47:00+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
@ -197,27 +202,27 @@
|
|||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"version": "2.0",
|
||||
"version_normalized": "2.0.0.0",
|
||||
"version": "1.1",
|
||||
"version_normalized": "1.1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-message.git",
|
||||
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
|
||||
"reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
|
||||
"reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"time": "2023-04-04T09:54:51+00:00",
|
||||
"time": "2023-04-04T09:50:52+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
|
@ -233,7 +238,7 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP messages",
|
||||
|
@ -407,18 +412,68 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "slim/slim",
|
||||
"version": "4.13.0",
|
||||
"version_normalized": "4.13.0.0",
|
||||
"name": "psr/simple-cache",
|
||||
"version": "1.0.1",
|
||||
"version_normalized": "1.0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slimphp/Slim.git",
|
||||
"reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17"
|
||||
"url": "https://github.com/php-fig/simple-cache.git",
|
||||
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/038fd5713d5a41636fdff0e8dcceedecdd17fc17",
|
||||
"reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17",
|
||||
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
|
||||
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2017-10-23T01:57:42+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\SimpleCache\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interfaces for simple caching",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching",
|
||||
"psr",
|
||||
"psr-16",
|
||||
"simple-cache"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "slim/slim",
|
||||
"version": "4.12.0",
|
||||
"version_normalized": "4.12.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slimphp/Slim.git",
|
||||
"reference": "e9e99c2b24398b967841c6c4c3048622cc7e2b18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/e9e99c2b24398b967841c6c4c3048622cc7e2b18",
|
||||
"reference": "e9e99c2b24398b967841c6c4c3048622cc7e2b18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -427,7 +482,7 @@
|
|||
"php": "^7.4 || ^8.0",
|
||||
"psr/container": "^1.0 || ^2.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.1 || ^2.0",
|
||||
"psr/http-message": "^1.1",
|
||||
"psr/http-server-handler": "^1.0",
|
||||
"psr/http-server-middleware": "^1.0",
|
||||
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
||||
|
@ -435,19 +490,19 @@
|
|||
"require-dev": {
|
||||
"adriansuter/php-autoload-override": "^1.4",
|
||||
"ext-simplexml": "*",
|
||||
"guzzlehttp/psr7": "^2.6",
|
||||
"guzzlehttp/psr7": "^2.5",
|
||||
"httpsoft/http-message": "^1.1",
|
||||
"httpsoft/http-server-request": "^1.1",
|
||||
"laminas/laminas-diactoros": "^2.17 || ^3",
|
||||
"laminas/laminas-diactoros": "^2.17",
|
||||
"nyholm/psr7": "^1.8",
|
||||
"nyholm/psr7-server": "^1.1",
|
||||
"phpspec/prophecy": "^1.19",
|
||||
"phpspec/prophecy-phpunit": "^2.1",
|
||||
"nyholm/psr7-server": "^1.0",
|
||||
"phpspec/prophecy": "^1.17",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^9.6",
|
||||
"slim/http": "^1.3",
|
||||
"slim/psr7": "^1.6",
|
||||
"squizlabs/php_codesniffer": "^3.9"
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-simplexml": "Needed to support XML format in BodyParsingMiddleware",
|
||||
|
@ -455,7 +510,7 @@
|
|||
"php-di/php-di": "PHP-DI is the recommended container library to be used with Slim",
|
||||
"slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information."
|
||||
},
|
||||
"time": "2024-03-03T21:25:30+00:00",
|
||||
"time": "2023-07-23T04:54:29+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
|
@ -515,53 +570,40 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/cache",
|
||||
"version": "v4.4.48",
|
||||
"version_normalized": "4.4.48.0",
|
||||
"version": "v3.4.47",
|
||||
"version_normalized": "3.4.47.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/cache.git",
|
||||
"reference": "3b98ed664887ad197b8ede3da2432787212eb915"
|
||||
"reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/cache/zipball/3b98ed664887ad197b8ede3da2432787212eb915",
|
||||
"reference": "3b98ed664887ad197b8ede3da2432787212eb915",
|
||||
"url": "https://api.github.com/repos/symfony/cache/zipball/a7a14c4832760bd1fbd31be2859ffedc9b6ff813",
|
||||
"reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.3",
|
||||
"psr/cache": "^1.0|^2.0",
|
||||
"psr/log": "^1|^2|^3",
|
||||
"symfony/cache-contracts": "^1.1.7|^2",
|
||||
"symfony/polyfill-php73": "^1.9",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/service-contracts": "^1.1|^2",
|
||||
"symfony/var-exporter": "^4.2|^5.0"
|
||||
"php": "^5.5.9|>=7.0.8",
|
||||
"psr/cache": "~1.0",
|
||||
"psr/log": "~1.0",
|
||||
"psr/simple-cache": "^1.0",
|
||||
"symfony/polyfill-apcu": "~1.1"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/dbal": "<2.7",
|
||||
"symfony/dependency-injection": "<3.4",
|
||||
"symfony/http-kernel": "<4.4|>=5.0",
|
||||
"symfony/var-dumper": "<4.4"
|
||||
"symfony/var-dumper": "<3.3"
|
||||
},
|
||||
"provide": {
|
||||
"psr/cache-implementation": "1.0|2.0",
|
||||
"psr/simple-cache-implementation": "1.0|2.0",
|
||||
"symfony/cache-implementation": "1.0|2.0"
|
||||
"psr/cache-implementation": "1.0",
|
||||
"psr/simple-cache-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cache/integration-tests": "dev-master",
|
||||
"doctrine/cache": "^1.6|^2.0",
|
||||
"doctrine/dbal": "^2.7|^3.0",
|
||||
"predis/predis": "^1.1",
|
||||
"psr/simple-cache": "^1.0|^2.0",
|
||||
"symfony/config": "^4.2|^5.0",
|
||||
"symfony/dependency-injection": "^3.4|^4.1|^5.0",
|
||||
"symfony/filesystem": "^4.4|^5.0",
|
||||
"symfony/http-kernel": "^4.4",
|
||||
"symfony/var-dumper": "^4.4|^5.0"
|
||||
"doctrine/cache": "^1.6",
|
||||
"doctrine/dbal": "^2.4|^3.0",
|
||||
"predis/predis": "^1.0"
|
||||
},
|
||||
"time": "2022-10-17T20:21:54+00:00",
|
||||
"time": "2020-10-24T10:57:07+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
|
@ -586,7 +628,7 @@
|
|||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides extended PSR-6, PSR-16 (and tags) implementations",
|
||||
"description": "Symfony Cache component with PSR-6, PSR-16, and tags",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"caching",
|
||||
|
@ -607,150 +649,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/cache-contracts",
|
||||
"version": "v2.5.2",
|
||||
"version_normalized": "2.5.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/cache-contracts.git",
|
||||
"reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/cache-contracts/zipball/64be4a7acb83b6f2bf6de9a02cee6dad41277ebc",
|
||||
"reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"psr/cache": "^1.0|^2.0|^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/cache-implementation": ""
|
||||
},
|
||||
"time": "2022-01-02T09:53:40+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\Cache\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Generic abstractions related to caching",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"abstractions",
|
||||
"contracts",
|
||||
"decoupling",
|
||||
"interfaces",
|
||||
"interoperability",
|
||||
"standards"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v2.5.2",
|
||||
"version_normalized": "2.5.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
|
||||
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"time": "2022-01-02T09:53:40+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"function.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/expression-language",
|
||||
"version": "v3.4.47",
|
||||
|
@ -813,6 +711,82 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-apcu",
|
||||
"version": "v1.28.0",
|
||||
"version_normalized": "1.28.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-apcu.git",
|
||||
"reference": "c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899",
|
||||
"reference": "c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"time": "2023-01-26T09:26:14+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Apcu\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting apcu_* functions to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"apcu",
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php70",
|
||||
"version": "v1.20.0",
|
||||
|
@ -878,313 +852,5 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php73",
|
||||
"version": "v1.29.0",
|
||||
"version_normalized": "1.29.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php73.git",
|
||||
"reference": "21bd091060673a1177ae842c0ef8fe30893114d2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2",
|
||||
"reference": "21bd091060673a1177ae842c0ef8fe30893114d2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"time": "2024-01-29T20:11:03+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php73\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.29.0",
|
||||
"version_normalized": "1.29.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"time": "2024-01-29T20:11:03+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php80\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ion Bazan",
|
||||
"email": "ion.bazan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
"version": "v2.5.2",
|
||||
"version_normalized": "2.5.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/service-contracts.git",
|
||||
"reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
|
||||
"reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"psr/container": "^1.1",
|
||||
"symfony/deprecation-contracts": "^2.1|^3"
|
||||
},
|
||||
"conflict": {
|
||||
"ext-psr": "<1.1|>=2"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/service-implementation": ""
|
||||
},
|
||||
"time": "2022-05-30T19:17:29+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\Service\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Generic abstractions related to writing services",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"abstractions",
|
||||
"contracts",
|
||||
"decoupling",
|
||||
"interfaces",
|
||||
"interoperability",
|
||||
"standards"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-exporter",
|
||||
"version": "v5.4.35",
|
||||
"version_normalized": "5.4.35.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-exporter.git",
|
||||
"reference": "abb0a151b62d6b07e816487e20040464af96cae7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/abb0a151b62d6b07e816487e20040464af96cae7",
|
||||
"reference": "abb0a151b62d6b07e816487e20040464af96cae7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": "^4.4.9|^5.0.9|^6.0"
|
||||
},
|
||||
"time": "2024-01-23T13:51:25+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\VarExporter\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Allows exporting any serializable PHP data structure to plain PHP code",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"clone",
|
||||
"construct",
|
||||
"export",
|
||||
"hydrate",
|
||||
"instantiate",
|
||||
"serialize"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -18,5 +18,10 @@
|
|||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,5 +32,5 @@ interface ContainerInterface
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $id);
|
||||
public function has(string $id): bool;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
|
@ -20,7 +20,7 @@
|
|||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
|
@ -23,7 +25,7 @@ interface MessageInterface
|
|||
*
|
||||
* @return string HTTP protocol version.
|
||||
*/
|
||||
public function getProtocolVersion(): string;
|
||||
public function getProtocolVersion();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified HTTP protocol version.
|
||||
|
@ -38,7 +40,7 @@ interface MessageInterface
|
|||
* @param string $version HTTP protocol version
|
||||
* @return static
|
||||
*/
|
||||
public function withProtocolVersion(string $version): MessageInterface;
|
||||
public function withProtocolVersion(string $version);
|
||||
|
||||
/**
|
||||
* Retrieves all message header values.
|
||||
|
@ -65,7 +67,7 @@ interface MessageInterface
|
|||
* key MUST be a header name, and each value MUST be an array of strings
|
||||
* for that header.
|
||||
*/
|
||||
public function getHeaders(): array;
|
||||
public function getHeaders();
|
||||
|
||||
/**
|
||||
* Checks if a header exists by the given case-insensitive name.
|
||||
|
@ -75,7 +77,7 @@ interface MessageInterface
|
|||
* name using a case-insensitive string comparison. Returns false if
|
||||
* no matching header name is found in the message.
|
||||
*/
|
||||
public function hasHeader(string $name): bool;
|
||||
public function hasHeader(string $name);
|
||||
|
||||
/**
|
||||
* Retrieves a message header value by the given case-insensitive name.
|
||||
|
@ -91,7 +93,7 @@ interface MessageInterface
|
|||
* header. If the header does not appear in the message, this method MUST
|
||||
* return an empty array.
|
||||
*/
|
||||
public function getHeader(string $name): array;
|
||||
public function getHeader(string $name);
|
||||
|
||||
/**
|
||||
* Retrieves a comma-separated string of the values for a single header.
|
||||
|
@ -112,7 +114,7 @@ interface MessageInterface
|
|||
* concatenated together using a comma. If the header does not appear in
|
||||
* the message, this method MUST return an empty string.
|
||||
*/
|
||||
public function getHeaderLine(string $name): string;
|
||||
public function getHeaderLine(string $name);
|
||||
|
||||
/**
|
||||
* Return an instance with the provided value replacing the specified header.
|
||||
|
@ -129,7 +131,7 @@ interface MessageInterface
|
|||
* @return static
|
||||
* @throws \InvalidArgumentException for invalid header names or values.
|
||||
*/
|
||||
public function withHeader(string $name, $value): MessageInterface;
|
||||
public function withHeader(string $name, $value);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified header appended with the given value.
|
||||
|
@ -147,7 +149,7 @@ interface MessageInterface
|
|||
* @return static
|
||||
* @throws \InvalidArgumentException for invalid header names or values.
|
||||
*/
|
||||
public function withAddedHeader(string $name, $value): MessageInterface;
|
||||
public function withAddedHeader(string $name, $value);
|
||||
|
||||
/**
|
||||
* Return an instance without the specified header.
|
||||
|
@ -161,14 +163,14 @@ interface MessageInterface
|
|||
* @param string $name Case-insensitive header field name to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function withoutHeader(string $name): MessageInterface;
|
||||
public function withoutHeader(string $name);
|
||||
|
||||
/**
|
||||
* Gets the body of the message.
|
||||
*
|
||||
* @return StreamInterface Returns the body as a stream.
|
||||
*/
|
||||
public function getBody(): StreamInterface;
|
||||
public function getBody();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified message body.
|
||||
|
@ -183,5 +185,5 @@ interface MessageInterface
|
|||
* @return static
|
||||
* @throws \InvalidArgumentException When the body is not valid.
|
||||
*/
|
||||
public function withBody(StreamInterface $body): MessageInterface;
|
||||
public function withBody(StreamInterface $body);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
|
@ -39,7 +41,7 @@ interface RequestInterface extends MessageInterface
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRequestTarget(): string;
|
||||
public function getRequestTarget();
|
||||
|
||||
/**
|
||||
* Return an instance with the specific request-target.
|
||||
|
@ -58,15 +60,14 @@ interface RequestInterface extends MessageInterface
|
|||
* @param string $requestTarget
|
||||
* @return static
|
||||
*/
|
||||
public function withRequestTarget(string $requestTarget): RequestInterface;
|
||||
|
||||
public function withRequestTarget(string $requestTarget);
|
||||
|
||||
/**
|
||||
* Retrieves the HTTP method of the request.
|
||||
*
|
||||
* @return string Returns the request method.
|
||||
*/
|
||||
public function getMethod(): string;
|
||||
public function getMethod();
|
||||
|
||||
/**
|
||||
* Return an instance with the provided HTTP method.
|
||||
|
@ -83,7 +84,7 @@ interface RequestInterface extends MessageInterface
|
|||
* @return static
|
||||
* @throws \InvalidArgumentException for invalid HTTP methods.
|
||||
*/
|
||||
public function withMethod(string $method): RequestInterface;
|
||||
public function withMethod(string $method);
|
||||
|
||||
/**
|
||||
* Retrieves the URI instance.
|
||||
|
@ -94,7 +95,7 @@ interface RequestInterface extends MessageInterface
|
|||
* @return UriInterface Returns a UriInterface instance
|
||||
* representing the URI of the request.
|
||||
*/
|
||||
public function getUri(): UriInterface;
|
||||
public function getUri();
|
||||
|
||||
/**
|
||||
* Returns an instance with the provided URI.
|
||||
|
@ -126,5 +127,5 @@ interface RequestInterface extends MessageInterface
|
|||
* @param bool $preserveHost Preserve the original state of the Host header.
|
||||
* @return static
|
||||
*/
|
||||
public function withUri(UriInterface $uri, bool $preserveHost = false): RequestInterface;
|
||||
public function withUri(UriInterface $uri, bool $preserveHost = false);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
|
@ -27,7 +29,7 @@ interface ResponseInterface extends MessageInterface
|
|||
*
|
||||
* @return int Status code.
|
||||
*/
|
||||
public function getStatusCode(): int;
|
||||
public function getStatusCode();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified status code and, optionally, reason phrase.
|
||||
|
@ -49,7 +51,7 @@ interface ResponseInterface extends MessageInterface
|
|||
* @return static
|
||||
* @throws \InvalidArgumentException For invalid status code arguments.
|
||||
*/
|
||||
public function withStatus(int $code, string $reasonPhrase = ''): ResponseInterface;
|
||||
public function withStatus(int $code, string $reasonPhrase = '');
|
||||
|
||||
/**
|
||||
* Gets the response reason phrase associated with the status code.
|
||||
|
@ -64,5 +66,5 @@ interface ResponseInterface extends MessageInterface
|
|||
* @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
||||
* @return string Reason phrase; must return an empty string if none present.
|
||||
*/
|
||||
public function getReasonPhrase(): string;
|
||||
public function getReasonPhrase();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
|
@ -51,7 +53,7 @@ interface ServerRequestInterface extends RequestInterface
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getServerParams(): array;
|
||||
public function getServerParams();
|
||||
|
||||
/**
|
||||
* Retrieve cookies.
|
||||
|
@ -63,7 +65,7 @@ interface ServerRequestInterface extends RequestInterface
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCookieParams(): array;
|
||||
public function getCookieParams();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified cookies.
|
||||
|
@ -82,7 +84,7 @@ interface ServerRequestInterface extends RequestInterface
|
|||
* @param array $cookies Array of key/value pairs representing cookies.
|
||||
* @return static
|
||||
*/
|
||||
public function withCookieParams(array $cookies): ServerRequestInterface;
|
||||
public function withCookieParams(array $cookies);
|
||||
|
||||
/**
|
||||
* Retrieve query string arguments.
|
||||
|
@ -96,7 +98,7 @@ interface ServerRequestInterface extends RequestInterface
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueryParams(): array;
|
||||
public function getQueryParams();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified query string arguments.
|
||||
|
@ -120,7 +122,7 @@ interface ServerRequestInterface extends RequestInterface
|
|||
* $_GET.
|
||||
* @return static
|
||||
*/
|
||||
public function withQueryParams(array $query): ServerRequestInterface;
|
||||
public function withQueryParams(array $query);
|
||||
|
||||
/**
|
||||
* Retrieve normalized file upload data.
|
||||
|
@ -134,7 +136,7 @@ interface ServerRequestInterface extends RequestInterface
|
|||
* @return array An array tree of UploadedFileInterface instances; an empty
|
||||
* array MUST be returned if no data is present.
|
||||
*/
|
||||
public function getUploadedFiles(): array;
|
||||
public function getUploadedFiles();
|
||||
|
||||
/**
|
||||
* Create a new instance with the specified uploaded files.
|
||||
|
@ -147,7 +149,7 @@ interface ServerRequestInterface extends RequestInterface
|
|||
* @return static
|
||||
* @throws \InvalidArgumentException if an invalid structure is provided.
|
||||
*/
|
||||
public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface;
|
||||
public function withUploadedFiles(array $uploadedFiles);
|
||||
|
||||
/**
|
||||
* Retrieve any parameters provided in the request body.
|
||||
|
@ -194,7 +196,7 @@ interface ServerRequestInterface extends RequestInterface
|
|||
* @throws \InvalidArgumentException if an unsupported argument type is
|
||||
* provided.
|
||||
*/
|
||||
public function withParsedBody($data): ServerRequestInterface;
|
||||
public function withParsedBody($data);
|
||||
|
||||
/**
|
||||
* Retrieve attributes derived from the request.
|
||||
|
@ -207,7 +209,7 @@ interface ServerRequestInterface extends RequestInterface
|
|||
*
|
||||
* @return array Attributes derived from the request.
|
||||
*/
|
||||
public function getAttributes(): array;
|
||||
public function getAttributes();
|
||||
|
||||
/**
|
||||
* Retrieve a single derived request attribute.
|
||||
|
@ -241,7 +243,7 @@ interface ServerRequestInterface extends RequestInterface
|
|||
* @param mixed $value The value of the attribute.
|
||||
* @return static
|
||||
*/
|
||||
public function withAttribute(string $name, $value): ServerRequestInterface;
|
||||
public function withAttribute(string $name, $value);
|
||||
|
||||
/**
|
||||
* Return an instance that removes the specified derived request attribute.
|
||||
|
@ -257,5 +259,5 @@ interface ServerRequestInterface extends RequestInterface
|
|||
* @param string $name The attribute name.
|
||||
* @return static
|
||||
*/
|
||||
public function withoutAttribute(string $name): ServerRequestInterface;
|
||||
public function withoutAttribute(string $name);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
|
@ -25,14 +27,14 @@ interface StreamInterface
|
|||
* @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string;
|
||||
public function __toString();
|
||||
|
||||
/**
|
||||
* Closes the stream and any underlying resources.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close(): void;
|
||||
public function close();
|
||||
|
||||
/**
|
||||
* Separates any underlying resources from the stream.
|
||||
|
@ -48,7 +50,7 @@ interface StreamInterface
|
|||
*
|
||||
* @return int|null Returns the size in bytes if known, or null if unknown.
|
||||
*/
|
||||
public function getSize(): ?int;
|
||||
public function getSize();
|
||||
|
||||
/**
|
||||
* Returns the current position of the file read/write pointer
|
||||
|
@ -56,21 +58,21 @@ interface StreamInterface
|
|||
* @return int Position of the file pointer
|
||||
* @throws \RuntimeException on error.
|
||||
*/
|
||||
public function tell(): int;
|
||||
public function tell();
|
||||
|
||||
/**
|
||||
* Returns true if the stream is at the end of the stream.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function eof(): bool;
|
||||
public function eof();
|
||||
|
||||
/**
|
||||
* Returns whether or not the stream is seekable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSeekable(): bool;
|
||||
public function isSeekable();
|
||||
|
||||
/**
|
||||
* Seek to a position in the stream.
|
||||
|
@ -84,7 +86,7 @@ interface StreamInterface
|
|||
* SEEK_END: Set position to end-of-stream plus offset.
|
||||
* @throws \RuntimeException on failure.
|
||||
*/
|
||||
public function seek(int $offset, int $whence = SEEK_SET): void;
|
||||
public function seek(int $offset, int $whence = SEEK_SET);
|
||||
|
||||
/**
|
||||
* Seek to the beginning of the stream.
|
||||
|
@ -96,14 +98,14 @@ interface StreamInterface
|
|||
* @link http://www.php.net/manual/en/function.fseek.php
|
||||
* @throws \RuntimeException on failure.
|
||||
*/
|
||||
public function rewind(): void;
|
||||
public function rewind();
|
||||
|
||||
/**
|
||||
* Returns whether or not the stream is writable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isWritable(): bool;
|
||||
public function isWritable();
|
||||
|
||||
/**
|
||||
* Write data to the stream.
|
||||
|
@ -112,14 +114,14 @@ interface StreamInterface
|
|||
* @return int Returns the number of bytes written to the stream.
|
||||
* @throws \RuntimeException on failure.
|
||||
*/
|
||||
public function write(string $string): int;
|
||||
public function write(string $string);
|
||||
|
||||
/**
|
||||
* Returns whether or not the stream is readable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadable(): bool;
|
||||
public function isReadable();
|
||||
|
||||
/**
|
||||
* Read data from the stream.
|
||||
|
@ -131,7 +133,7 @@ interface StreamInterface
|
|||
* if no bytes are available.
|
||||
* @throws \RuntimeException if an error occurs.
|
||||
*/
|
||||
public function read(int $length): string;
|
||||
public function read(int $length);
|
||||
|
||||
/**
|
||||
* Returns the remaining contents in a string
|
||||
|
@ -140,7 +142,7 @@ interface StreamInterface
|
|||
* @throws \RuntimeException if unable to read or an error occurs while
|
||||
* reading.
|
||||
*/
|
||||
public function getContents(): string;
|
||||
public function getContents();
|
||||
|
||||
/**
|
||||
* Get stream metadata as an associative array or retrieve a specific key.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
|
@ -28,7 +30,7 @@ interface UploadedFileInterface
|
|||
* @throws \RuntimeException in cases when no stream is available or can be
|
||||
* created.
|
||||
*/
|
||||
public function getStream(): StreamInterface;
|
||||
public function getStream();
|
||||
|
||||
/**
|
||||
* Move the uploaded file to a new location.
|
||||
|
@ -62,7 +64,7 @@ interface UploadedFileInterface
|
|||
* @throws \RuntimeException on any error during the move operation, or on
|
||||
* the second or subsequent call to the method.
|
||||
*/
|
||||
public function moveTo(string $targetPath): void;
|
||||
public function moveTo(string $targetPath);
|
||||
|
||||
/**
|
||||
* Retrieve the file size.
|
||||
|
@ -73,7 +75,7 @@ interface UploadedFileInterface
|
|||
*
|
||||
* @return int|null The file size in bytes or null if unknown.
|
||||
*/
|
||||
public function getSize(): ?int;
|
||||
public function getSize();
|
||||
|
||||
/**
|
||||
* Retrieve the error associated with the uploaded file.
|
||||
|
@ -89,7 +91,7 @@ interface UploadedFileInterface
|
|||
* @see http://php.net/manual/en/features.file-upload.errors.php
|
||||
* @return int One of PHP's UPLOAD_ERR_XXX constants.
|
||||
*/
|
||||
public function getError(): int;
|
||||
public function getError();
|
||||
|
||||
/**
|
||||
* Retrieve the filename sent by the client.
|
||||
|
@ -104,7 +106,7 @@ interface UploadedFileInterface
|
|||
* @return string|null The filename sent by the client or null if none
|
||||
* was provided.
|
||||
*/
|
||||
public function getClientFilename(): ?string;
|
||||
public function getClientFilename();
|
||||
|
||||
/**
|
||||
* Retrieve the media type sent by the client.
|
||||
|
@ -119,5 +121,5 @@ interface UploadedFileInterface
|
|||
* @return string|null The media type sent by the client or null if none
|
||||
* was provided.
|
||||
*/
|
||||
public function getClientMediaType(): ?string;
|
||||
public function getClientMediaType();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
|
@ -38,7 +40,7 @@ interface UriInterface
|
|||
* @see https://tools.ietf.org/html/rfc3986#section-3.1
|
||||
* @return string The URI scheme.
|
||||
*/
|
||||
public function getScheme(): string;
|
||||
public function getScheme();
|
||||
|
||||
/**
|
||||
* Retrieve the authority component of the URI.
|
||||
|
@ -58,7 +60,7 @@ interface UriInterface
|
|||
* @see https://tools.ietf.org/html/rfc3986#section-3.2
|
||||
* @return string The URI authority, in "[user-info@]host[:port]" format.
|
||||
*/
|
||||
public function getAuthority(): string;
|
||||
public function getAuthority();
|
||||
|
||||
/**
|
||||
* Retrieve the user information component of the URI.
|
||||
|
@ -75,7 +77,7 @@ interface UriInterface
|
|||
*
|
||||
* @return string The URI user information, in "username[:password]" format.
|
||||
*/
|
||||
public function getUserInfo(): string;
|
||||
public function getUserInfo();
|
||||
|
||||
/**
|
||||
* Retrieve the host component of the URI.
|
||||
|
@ -88,7 +90,7 @@ interface UriInterface
|
|||
* @see http://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
* @return string The URI host.
|
||||
*/
|
||||
public function getHost(): string;
|
||||
public function getHost();
|
||||
|
||||
/**
|
||||
* Retrieve the port component of the URI.
|
||||
|
@ -105,7 +107,7 @@ interface UriInterface
|
|||
*
|
||||
* @return null|int The URI port.
|
||||
*/
|
||||
public function getPort(): ?int;
|
||||
public function getPort();
|
||||
|
||||
/**
|
||||
* Retrieve the path component of the URI.
|
||||
|
@ -132,7 +134,7 @@ interface UriInterface
|
|||
* @see https://tools.ietf.org/html/rfc3986#section-3.3
|
||||
* @return string The URI path.
|
||||
*/
|
||||
public function getPath(): string;
|
||||
public function getPath();
|
||||
|
||||
/**
|
||||
* Retrieve the query string of the URI.
|
||||
|
@ -154,7 +156,7 @@ interface UriInterface
|
|||
* @see https://tools.ietf.org/html/rfc3986#section-3.4
|
||||
* @return string The URI query string.
|
||||
*/
|
||||
public function getQuery(): string;
|
||||
public function getQuery();
|
||||
|
||||
/**
|
||||
* Retrieve the fragment component of the URI.
|
||||
|
@ -172,7 +174,7 @@ interface UriInterface
|
|||
* @see https://tools.ietf.org/html/rfc3986#section-3.5
|
||||
* @return string The URI fragment.
|
||||
*/
|
||||
public function getFragment(): string;
|
||||
public function getFragment();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified scheme.
|
||||
|
@ -189,7 +191,7 @@ interface UriInterface
|
|||
* @return static A new instance with the specified scheme.
|
||||
* @throws \InvalidArgumentException for invalid or unsupported schemes.
|
||||
*/
|
||||
public function withScheme(string $scheme): UriInterface;
|
||||
public function withScheme(string $scheme);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified user information.
|
||||
|
@ -205,7 +207,7 @@ interface UriInterface
|
|||
* @param null|string $password The password associated with $user.
|
||||
* @return static A new instance with the specified user information.
|
||||
*/
|
||||
public function withUserInfo(string $user, ?string $password = null): UriInterface;
|
||||
public function withUserInfo(string $user, ?string $password = null);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified host.
|
||||
|
@ -219,7 +221,7 @@ interface UriInterface
|
|||
* @return static A new instance with the specified host.
|
||||
* @throws \InvalidArgumentException for invalid hostnames.
|
||||
*/
|
||||
public function withHost(string $host): UriInterface;
|
||||
public function withHost(string $host);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified port.
|
||||
|
@ -238,7 +240,7 @@ interface UriInterface
|
|||
* @return static A new instance with the specified port.
|
||||
* @throws \InvalidArgumentException for invalid ports.
|
||||
*/
|
||||
public function withPort(?int $port): UriInterface;
|
||||
public function withPort(?int $port);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified path.
|
||||
|
@ -262,7 +264,7 @@ interface UriInterface
|
|||
* @return static A new instance with the specified path.
|
||||
* @throws \InvalidArgumentException for invalid paths.
|
||||
*/
|
||||
public function withPath(string $path): UriInterface;
|
||||
public function withPath(string $path);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified query string.
|
||||
|
@ -279,7 +281,7 @@ interface UriInterface
|
|||
* @return static A new instance with the specified query string.
|
||||
* @throws \InvalidArgumentException for invalid query strings.
|
||||
*/
|
||||
public function withQuery(string $query): UriInterface;
|
||||
public function withQuery(string $query);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified URI fragment.
|
||||
|
@ -295,7 +297,7 @@ interface UriInterface
|
|||
* @param string $fragment The fragment to use with the new instance.
|
||||
* @return static A new instance with the specified fragment.
|
||||
*/
|
||||
public function withFragment(string $fragment): UriInterface;
|
||||
public function withFragment(string $fragment);
|
||||
|
||||
/**
|
||||
* Return the string representation as a URI reference.
|
||||
|
@ -320,5 +322,5 @@ interface UriInterface
|
|||
* @see http://tools.ietf.org/html/rfc3986#section-4.1
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string;
|
||||
public function __toString();
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Slim Framework (https://slimframework.com)
|
||||
*
|
||||
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Slim\Exception;
|
||||
|
||||
class HttpTooManyRequestsException extends HttpSpecializedException
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $code = 429;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $message = 'Too many requests.';
|
||||
|
||||
protected string $title = '429 Too Many Requests';
|
||||
protected string $description = 'The client application has surpassed its rate limit, ' .
|
||||
'or number of requests they can send in a given period of time.';
|
||||
}
|
|
@ -48,7 +48,7 @@
|
|||
"nikic/fast-route": "^1.3",
|
||||
"psr/container": "^1.0 || ^2.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.1 || ^2.0",
|
||||
"psr/http-message": "^1.1",
|
||||
"psr/http-server-handler": "^1.0",
|
||||
"psr/http-server-middleware": "^1.0",
|
||||
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
||||
|
@ -56,19 +56,19 @@
|
|||
"require-dev": {
|
||||
"ext-simplexml": "*",
|
||||
"adriansuter/php-autoload-override": "^1.4",
|
||||
"guzzlehttp/psr7": "^2.6",
|
||||
"guzzlehttp/psr7": "^2.5",
|
||||
"httpsoft/http-message": "^1.1",
|
||||
"httpsoft/http-server-request": "^1.1",
|
||||
"laminas/laminas-diactoros": "^2.17 || ^3",
|
||||
"laminas/laminas-diactoros": "^2.17",
|
||||
"nyholm/psr7": "^1.8",
|
||||
"nyholm/psr7-server": "^1.1",
|
||||
"phpspec/prophecy": "^1.19",
|
||||
"phpspec/prophecy-phpunit": "^2.1",
|
||||
"nyholm/psr7-server": "^1.0",
|
||||
"phpspec/prophecy": "^1.17",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^9.6",
|
||||
"slim/http": "^1.3",
|
||||
"slim/psr7": "^1.6",
|
||||
"squizlabs/php_codesniffer": "^3.9"
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
|
@ -1,5 +0,0 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
|
||||
The changelog is maintained for all Symfony contracts at the following URL:
|
||||
https://github.com/symfony/contracts/blob/main/CHANGELOG.md
|
|
@ -1,57 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Contracts\Cache;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Covers most simple to advanced caching needs.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
interface CacheInterface
|
||||
{
|
||||
/**
|
||||
* Fetches a value from the pool or computes it if not found.
|
||||
*
|
||||
* On cache misses, a callback is called that should return the missing value.
|
||||
* This callback is given a PSR-6 CacheItemInterface instance corresponding to the
|
||||
* requested key, that could be used e.g. for expiration control. It could also
|
||||
* be an ItemInterface instance when its additional features are needed.
|
||||
*
|
||||
* @param string $key The key of the item to retrieve from the cache
|
||||
* @param callable|CallbackInterface $callback Should return the computed value for the given key/item
|
||||
* @param float|null $beta A float that, as it grows, controls the likeliness of triggering
|
||||
* early expiration. 0 disables it, INF forces immediate expiration.
|
||||
* The default (or providing null) is implementation dependent but should
|
||||
* typically be 1.0, which should provide optimal stampede protection.
|
||||
* See https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration
|
||||
* @param array &$metadata The metadata of the cached item {@see ItemInterface::getMetadata()}
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws InvalidArgumentException When $key is not valid or when $beta is negative
|
||||
*/
|
||||
public function get(string $key, callable $callback, float $beta = null, array &$metadata = null);
|
||||
|
||||
/**
|
||||
* Removes an item from the pool.
|
||||
*
|
||||
* @param string $key The key to delete
|
||||
*
|
||||
* @throws InvalidArgumentException When $key is not valid
|
||||
*
|
||||
* @return bool True if the item was successfully removed, false if there was any error
|
||||
*/
|
||||
public function delete(string $key): bool;
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Contracts\Cache;
|
||||
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
// Help opcache.preload discover always-needed symbols
|
||||
class_exists(InvalidArgumentException::class);
|
||||
|
||||
/**
|
||||
* An implementation of CacheInterface for PSR-6 CacheItemPoolInterface classes.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
trait CacheTrait
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
|
||||
{
|
||||
return $this->doGet($this, $key, $callback, $beta, $metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete(string $key): bool
|
||||
{
|
||||
return $this->deleteItem($key);
|
||||
}
|
||||
|
||||
private function doGet(CacheItemPoolInterface $pool, string $key, callable $callback, ?float $beta, array &$metadata = null, LoggerInterface $logger = null)
|
||||
{
|
||||
if (0 > $beta = $beta ?? 1.0) {
|
||||
throw new class(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta)) extends \InvalidArgumentException implements InvalidArgumentException { };
|
||||
}
|
||||
|
||||
$item = $pool->getItem($key);
|
||||
$recompute = !$item->isHit() || \INF === $beta;
|
||||
$metadata = $item instanceof ItemInterface ? $item->getMetadata() : [];
|
||||
|
||||
if (!$recompute && $metadata) {
|
||||
$expiry = $metadata[ItemInterface::METADATA_EXPIRY] ?? false;
|
||||
$ctime = $metadata[ItemInterface::METADATA_CTIME] ?? false;
|
||||
|
||||
if ($recompute = $ctime && $expiry && $expiry <= ($now = microtime(true)) - $ctime / 1000 * $beta * log(random_int(1, \PHP_INT_MAX) / \PHP_INT_MAX)) {
|
||||
// force applying defaultLifetime to expiry
|
||||
$item->expiresAt(null);
|
||||
$logger && $logger->info('Item "{key}" elected for early recomputation {delta}s before its expiration', [
|
||||
'key' => $key,
|
||||
'delta' => sprintf('%.1f', $expiry - $now),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($recompute) {
|
||||
$save = true;
|
||||
$item->set($callback($item, $save));
|
||||
if ($save) {
|
||||
$pool->save($item);
|
||||
}
|
||||
}
|
||||
|
||||
return $item->get();
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Contracts\Cache;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
|
||||
/**
|
||||
* Computes and returns the cached value of an item.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
interface CallbackInterface
|
||||
{
|
||||
/**
|
||||
* @param CacheItemInterface|ItemInterface $item The item to compute the value for
|
||||
* @param bool &$save Should be set to false when the value should not be saved in the pool
|
||||
*
|
||||
* @return mixed The computed value for the passed item
|
||||
*/
|
||||
public function __invoke(CacheItemInterface $item, bool &$save);
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Contracts\Cache;
|
||||
|
||||
use Psr\Cache\CacheException;
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Augments PSR-6's CacheItemInterface with support for tags and metadata.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
interface ItemInterface extends CacheItemInterface
|
||||
{
|
||||
/**
|
||||
* References the Unix timestamp stating when the item will expire.
|
||||
*/
|
||||
public const METADATA_EXPIRY = 'expiry';
|
||||
|
||||
/**
|
||||
* References the time the item took to be created, in milliseconds.
|
||||
*/
|
||||
public const METADATA_CTIME = 'ctime';
|
||||
|
||||
/**
|
||||
* References the list of tags that were assigned to the item, as string[].
|
||||
*/
|
||||
public const METADATA_TAGS = 'tags';
|
||||
|
||||
/**
|
||||
* Reserved characters that cannot be used in a key or tag.
|
||||
*/
|
||||
public const RESERVED_CHARACTERS = '{}()/\@:';
|
||||
|
||||
/**
|
||||
* Adds a tag to a cache item.
|
||||
*
|
||||
* Tags are strings that follow the same validation rules as keys.
|
||||
*
|
||||
* @param string|string[] $tags A tag or array of tags
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException When $tag is not valid
|
||||
* @throws CacheException When the item comes from a pool that is not tag-aware
|
||||
*/
|
||||
public function tag($tags): self;
|
||||
|
||||
/**
|
||||
* Returns a list of metadata info that were saved alongside with the cached value.
|
||||
*
|
||||
* See ItemInterface::METADATA_* consts for keys potentially found in the returned array.
|
||||
*/
|
||||
public function getMetadata(): array;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
Copyright (c) 2018-2022 Fabien Potencier
|
||||
|
||||
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.
|
|
@ -1,9 +0,0 @@
|
|||
Symfony Cache Contracts
|
||||
=======================
|
||||
|
||||
A set of abstractions extracted out of the Symfony components.
|
||||
|
||||
Can be used to build on semantics that the Symfony components proved useful - and
|
||||
that already have battle tested implementations.
|
||||
|
||||
See https://github.com/symfony/contracts/blob/main/README.md for more information.
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Contracts\Cache;
|
||||
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Allows invalidating cached items using tags.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
interface TagAwareCacheInterface extends CacheInterface
|
||||
{
|
||||
/**
|
||||
* Invalidates cached items using tags.
|
||||
*
|
||||
* When implemented on a PSR-6 pool, invalidation should not apply
|
||||
* to deferred items. Instead, they should be committed as usual.
|
||||
* This allows replacing old tagged values by new ones without
|
||||
* race conditions.
|
||||
*
|
||||
* @param string[] $tags An array of tags to invalidate
|
||||
*
|
||||
* @return bool True on success
|
||||
*
|
||||
* @throws InvalidArgumentException When $tags is not valid
|
||||
*/
|
||||
public function invalidateTags(array $tags);
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
{
|
||||
"name": "symfony/cache-contracts",
|
||||
"type": "library",
|
||||
"description": "Generic abstractions related to caching",
|
||||
"keywords": ["abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards"],
|
||||
"homepage": "https://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"psr/cache": "^1.0|^2.0|^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/cache-implementation": ""
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Contracts\\Cache\\": "" }
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,32 +11,37 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\AbstractAdapterTrait;
|
||||
use Symfony\Component\Cache\Traits\ContractsTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Component\Cache\Traits\AbstractTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
abstract class AbstractAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface
|
||||
abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
use AbstractAdapterTrait;
|
||||
use ContractsTrait;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected const NS_SEPARATOR = ':';
|
||||
const NS_SEPARATOR = ':';
|
||||
|
||||
use AbstractTrait;
|
||||
|
||||
private static $apcuSupported;
|
||||
private static $phpFilesSupported;
|
||||
|
||||
protected function __construct(string $namespace = '', int $defaultLifetime = 0)
|
||||
private $createCacheItem;
|
||||
private $mergeByLifetime;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
protected function __construct($namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::NS_SEPARATOR;
|
||||
if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) {
|
||||
|
@ -46,45 +51,31 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
|
|||
static function ($key, $value, $isHit) {
|
||||
$item = new CacheItem();
|
||||
$item->key = $key;
|
||||
$item->value = $v = $value;
|
||||
$item->value = $value;
|
||||
$item->isHit = $isHit;
|
||||
// Detect wrapped values that encode for their expiry and creation duration
|
||||
// For compactness, these values are packed in the key of an array using
|
||||
// magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
|
||||
if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = (string) array_key_first($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) {
|
||||
$item->value = $v[$k];
|
||||
$v = unpack('Ve/Nc', substr($k, 1, -1));
|
||||
$item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET;
|
||||
$item->metadata[CacheItem::METADATA_CTIME] = $v['c'];
|
||||
}
|
||||
|
||||
return $item;
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
$getId = \Closure::fromCallable([$this, 'getId']);
|
||||
$getId = function ($key) { return $this->getId((string) $key); };
|
||||
$this->mergeByLifetime = \Closure::bind(
|
||||
static function ($deferred, $namespace, &$expiredIds) use ($getId, $defaultLifetime) {
|
||||
$byLifetime = [];
|
||||
$now = microtime(true);
|
||||
$now = time();
|
||||
$expiredIds = [];
|
||||
|
||||
foreach ($deferred as $key => $item) {
|
||||
$key = (string) $key;
|
||||
if (null === $item->expiry) {
|
||||
$ttl = 0 < $defaultLifetime ? $defaultLifetime : 0;
|
||||
} elseif (!$item->expiry) {
|
||||
$ttl = 0;
|
||||
} elseif (0 >= $ttl = (int) (0.1 + $item->expiry - $now)) {
|
||||
$byLifetime[0 < $defaultLifetime ? $defaultLifetime : 0][$getId($key)] = $item->value;
|
||||
} elseif (0 === $item->expiry) {
|
||||
$byLifetime[0][$getId($key)] = $item->value;
|
||||
} elseif ($item->expiry > $now) {
|
||||
$byLifetime[$item->expiry - $now][$getId($key)] = $item->value;
|
||||
} else {
|
||||
$expiredIds[] = $getId($key);
|
||||
continue;
|
||||
}
|
||||
if (isset(($metadata = $item->newMetadata)[CacheItem::METADATA_TAGS])) {
|
||||
unset($metadata[CacheItem::METADATA_TAGS]);
|
||||
}
|
||||
// For compactness, expiry and creation duration are packed in the key of an array, using magic numbers as separators
|
||||
$byLifetime[$ttl][$getId($key)] = $metadata ? ["\x9D".pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME])."\x5F" => $item->value] : $item->value;
|
||||
}
|
||||
|
||||
return $byLifetime;
|
||||
|
@ -95,10 +86,6 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the best possible adapter that your runtime supports.
|
||||
*
|
||||
* Using ApcuAdapter makes system caches compatible with read-only filesystems.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string $version
|
||||
|
@ -108,25 +95,37 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
|
|||
*/
|
||||
public static function createSystemCache($namespace, $defaultLifetime, $version, $directory, LoggerInterface $logger = null)
|
||||
{
|
||||
$opcache = new PhpFilesAdapter($namespace, $defaultLifetime, $directory, true);
|
||||
if (null === self::$apcuSupported) {
|
||||
self::$apcuSupported = ApcuAdapter::isSupported();
|
||||
}
|
||||
|
||||
if (!self::$apcuSupported && null === self::$phpFilesSupported) {
|
||||
self::$phpFilesSupported = PhpFilesAdapter::isSupported();
|
||||
}
|
||||
|
||||
if (self::$phpFilesSupported) {
|
||||
$opcache = new PhpFilesAdapter($namespace, $defaultLifetime, $directory);
|
||||
if (null !== $logger) {
|
||||
$opcache->setLogger($logger);
|
||||
}
|
||||
|
||||
if (!self::$apcuSupported = self::$apcuSupported ?? ApcuAdapter::isSupported()) {
|
||||
return $opcache;
|
||||
}
|
||||
|
||||
if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && !filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) {
|
||||
return $opcache;
|
||||
$fs = new FilesystemAdapter($namespace, $defaultLifetime, $directory);
|
||||
if (null !== $logger) {
|
||||
$fs->setLogger($logger);
|
||||
}
|
||||
if (!self::$apcuSupported || (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) {
|
||||
return $fs;
|
||||
}
|
||||
|
||||
$apcu = new ApcuAdapter($namespace, intdiv($defaultLifetime, 5), $version);
|
||||
$apcu = new ApcuAdapter($namespace, (int) $defaultLifetime / 5, $version);
|
||||
if (null !== $logger) {
|
||||
$apcu->setLogger($logger);
|
||||
}
|
||||
|
||||
return new ChainAdapter([$apcu, $opcache]);
|
||||
return new ChainAdapter([$apcu, $fs]);
|
||||
}
|
||||
|
||||
public static function createConnection($dsn, array $options = [])
|
||||
|
@ -134,10 +133,10 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
|
|||
if (!\is_string($dsn)) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s()" method expect argument #1 to be string, "%s" given.', __METHOD__, \gettype($dsn)));
|
||||
}
|
||||
if (str_starts_with($dsn, 'redis:') || str_starts_with($dsn, 'rediss:')) {
|
||||
if (0 === strpos($dsn, 'redis://')) {
|
||||
return RedisAdapter::createConnection($dsn, $options);
|
||||
}
|
||||
if (str_starts_with($dsn, 'memcached:')) {
|
||||
if (0 === strpos($dsn, 'memcached://')) {
|
||||
return MemcachedAdapter::createConnection($dsn, $options);
|
||||
}
|
||||
|
||||
|
@ -146,8 +145,81 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getItem($key)
|
||||
{
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
$id = $this->getId($key);
|
||||
|
||||
$f = $this->createCacheItem;
|
||||
$isHit = false;
|
||||
$value = null;
|
||||
|
||||
try {
|
||||
foreach ($this->doFetch([$id]) as $value) {
|
||||
$isHit = true;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
}
|
||||
|
||||
return $f($key, $value, $isHit);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItems(array $keys = [])
|
||||
{
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
$ids = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$ids[] = $this->getId($key);
|
||||
}
|
||||
try {
|
||||
$items = $this->doFetch($ids);
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => $keys, 'exception' => $e]);
|
||||
$items = [];
|
||||
}
|
||||
$ids = array_combine($ids, $keys);
|
||||
|
||||
return $this->generateItems($items, $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
if (!$item instanceof CacheItem) {
|
||||
return false;
|
||||
}
|
||||
$this->deferred[$item->getKey()] = $item;
|
||||
|
||||
return $this->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
if (!$item instanceof CacheItem) {
|
||||
return false;
|
||||
}
|
||||
$this->deferred[$item->getKey()] = $item;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
|
@ -157,12 +229,7 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
|
|||
$retry = $this->deferred = [];
|
||||
|
||||
if ($expiredIds) {
|
||||
try {
|
||||
$this->doDelete($expiredIds);
|
||||
} catch (\Exception $e) {
|
||||
$ok = false;
|
||||
CacheItem::log($this->logger, 'Failed to delete expired items: '.$e->getMessage(), ['exception' => $e, 'cache-adapter' => get_debug_type($this)]);
|
||||
}
|
||||
}
|
||||
foreach ($byLifetime as $lifetime => $values) {
|
||||
try {
|
||||
|
@ -177,8 +244,7 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
|
|||
$ok = false;
|
||||
$v = $values[$id];
|
||||
$type = \is_object($v) ? \get_class($v) : \gettype($v);
|
||||
$message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => substr($id, \strlen($this->namespace)), 'type' => $type, 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
}
|
||||
} else {
|
||||
foreach ($values as $id => $v) {
|
||||
|
@ -200,11 +266,49 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
|
|||
}
|
||||
$ok = false;
|
||||
$type = \is_object($v) ? \get_class($v) : \gettype($v);
|
||||
$message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => substr($id, \strlen($this->namespace)), 'type' => $type, 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
}
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
}
|
||||
|
||||
private function generateItems($items, &$keys)
|
||||
{
|
||||
$f = $this->createCacheItem;
|
||||
|
||||
try {
|
||||
foreach ($items as $id => $value) {
|
||||
if (!isset($keys[$id])) {
|
||||
$id = key($keys);
|
||||
}
|
||||
$key = $keys[$id];
|
||||
unset($keys[$id]);
|
||||
yield $key => $f($key, $value, true);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => array_values($keys), 'exception' => $e]);
|
||||
}
|
||||
|
||||
foreach ($keys as $key) {
|
||||
yield $key => $f($key, null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,334 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\AbstractAdapterTrait;
|
||||
use Symfony\Component\Cache\Traits\ContractsTrait;
|
||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||
|
||||
/**
|
||||
* Abstract for native TagAware adapters.
|
||||
*
|
||||
* To keep info on tags, the tags are both serialized as part of cache value and provided as tag ids
|
||||
* to Adapters on operations when needed for storage to doSave(), doDelete() & doInvalidate().
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
* @author André Rømcke <andre.romcke+symfony@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
use AbstractAdapterTrait;
|
||||
use ContractsTrait;
|
||||
|
||||
private const TAGS_PREFIX = "\0tags\0";
|
||||
|
||||
protected function __construct(string $namespace = '', int $defaultLifetime = 0)
|
||||
{
|
||||
$this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':';
|
||||
if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) {
|
||||
throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace));
|
||||
}
|
||||
$this->createCacheItem = \Closure::bind(
|
||||
static function ($key, $value, $isHit) {
|
||||
$item = new CacheItem();
|
||||
$item->key = $key;
|
||||
$item->isTaggable = true;
|
||||
// If structure does not match what we expect return item as is (no value and not a hit)
|
||||
if (!\is_array($value) || !\array_key_exists('value', $value)) {
|
||||
return $item;
|
||||
}
|
||||
$item->isHit = $isHit;
|
||||
// Extract value, tags and meta data from the cache value
|
||||
$item->value = $value['value'];
|
||||
$item->metadata[CacheItem::METADATA_TAGS] = $value['tags'] ?? [];
|
||||
if (isset($value['meta'])) {
|
||||
// For compactness these values are packed, & expiry is offset to reduce size
|
||||
$v = unpack('Ve/Nc', $value['meta']);
|
||||
$item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET;
|
||||
$item->metadata[CacheItem::METADATA_CTIME] = $v['c'];
|
||||
}
|
||||
|
||||
return $item;
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
$getId = \Closure::fromCallable([$this, 'getId']);
|
||||
$tagPrefix = self::TAGS_PREFIX;
|
||||
$this->mergeByLifetime = \Closure::bind(
|
||||
static function ($deferred, &$expiredIds) use ($getId, $tagPrefix, $defaultLifetime) {
|
||||
$byLifetime = [];
|
||||
$now = microtime(true);
|
||||
$expiredIds = [];
|
||||
|
||||
foreach ($deferred as $key => $item) {
|
||||
$key = (string) $key;
|
||||
if (null === $item->expiry) {
|
||||
$ttl = 0 < $defaultLifetime ? $defaultLifetime : 0;
|
||||
} elseif (!$item->expiry) {
|
||||
$ttl = 0;
|
||||
} elseif (0 >= $ttl = (int) (0.1 + $item->expiry - $now)) {
|
||||
$expiredIds[] = $getId($key);
|
||||
continue;
|
||||
}
|
||||
// Store Value and Tags on the cache value
|
||||
if (isset(($metadata = $item->newMetadata)[CacheItem::METADATA_TAGS])) {
|
||||
$value = ['value' => $item->value, 'tags' => $metadata[CacheItem::METADATA_TAGS]];
|
||||
unset($metadata[CacheItem::METADATA_TAGS]);
|
||||
} else {
|
||||
$value = ['value' => $item->value, 'tags' => []];
|
||||
}
|
||||
|
||||
if ($metadata) {
|
||||
// For compactness, expiry and creation duration are packed, using magic numbers as separators
|
||||
$value['meta'] = pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME]);
|
||||
}
|
||||
|
||||
// Extract tag changes, these should be removed from values in doSave()
|
||||
$value['tag-operations'] = ['add' => [], 'remove' => []];
|
||||
$oldTags = $item->metadata[CacheItem::METADATA_TAGS] ?? [];
|
||||
foreach (array_diff($value['tags'], $oldTags) as $addedTag) {
|
||||
$value['tag-operations']['add'][] = $getId($tagPrefix.$addedTag);
|
||||
}
|
||||
foreach (array_diff($oldTags, $value['tags']) as $removedTag) {
|
||||
$value['tag-operations']['remove'][] = $getId($tagPrefix.$removedTag);
|
||||
}
|
||||
|
||||
$byLifetime[$ttl][$getId($key)] = $value;
|
||||
$item->metadata = $item->newMetadata;
|
||||
}
|
||||
|
||||
return $byLifetime;
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists several cache items immediately.
|
||||
*
|
||||
* @param array $values The values to cache, indexed by their cache identifier
|
||||
* @param int $lifetime The lifetime of the cached values, 0 for persisting until manual cleaning
|
||||
* @param array[] $addTagData Hash where key is tag id, and array value is list of cache id's to add to tag
|
||||
* @param array[] $removeTagData Hash where key is tag id, and array value is list of cache id's to remove to tag
|
||||
*
|
||||
* @return array The identifiers that failed to be cached or a boolean stating if caching succeeded or not
|
||||
*/
|
||||
abstract protected function doSave(array $values, int $lifetime, array $addTagData = [], array $removeTagData = []): array;
|
||||
|
||||
/**
|
||||
* Removes multiple items from the pool and their corresponding tags.
|
||||
*
|
||||
* @param array $ids An array of identifiers that should be removed from the pool
|
||||
*
|
||||
* @return bool True if the items were successfully removed, false otherwise
|
||||
*/
|
||||
abstract protected function doDelete(array $ids);
|
||||
|
||||
/**
|
||||
* Removes relations between tags and deleted items.
|
||||
*
|
||||
* @param array $tagData Array of tag => key identifiers that should be removed from the pool
|
||||
*/
|
||||
abstract protected function doDeleteTagRelations(array $tagData): bool;
|
||||
|
||||
/**
|
||||
* Invalidates cached items using tags.
|
||||
*
|
||||
* @param string[] $tagIds An array of tags to invalidate, key is tag and value is tag id
|
||||
*
|
||||
* @return bool True on success
|
||||
*/
|
||||
abstract protected function doInvalidate(array $tagIds): bool;
|
||||
|
||||
/**
|
||||
* Delete items and yields the tags they were bound to.
|
||||
*/
|
||||
protected function doDeleteYieldTags(array $ids): iterable
|
||||
{
|
||||
foreach ($this->doFetch($ids) as $id => $value) {
|
||||
yield $id => \is_array($value) && \is_array($value['tags'] ?? null) ? $value['tags'] : [];
|
||||
}
|
||||
|
||||
$this->doDelete($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function commit(): bool
|
||||
{
|
||||
$ok = true;
|
||||
$byLifetime = $this->mergeByLifetime;
|
||||
$byLifetime = $byLifetime($this->deferred, $expiredIds);
|
||||
$retry = $this->deferred = [];
|
||||
|
||||
if ($expiredIds) {
|
||||
// Tags are not cleaned up in this case, however that is done on invalidateTags().
|
||||
try {
|
||||
$this->doDelete($expiredIds);
|
||||
} catch (\Exception $e) {
|
||||
$ok = false;
|
||||
CacheItem::log($this->logger, 'Failed to delete expired items: '.$e->getMessage(), ['exception' => $e, 'cache-adapter' => get_debug_type($this)]);
|
||||
}
|
||||
}
|
||||
foreach ($byLifetime as $lifetime => $values) {
|
||||
try {
|
||||
$values = $this->extractTagData($values, $addTagData, $removeTagData);
|
||||
$e = $this->doSave($values, $lifetime, $addTagData, $removeTagData);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
if (true === $e || [] === $e) {
|
||||
continue;
|
||||
}
|
||||
if (\is_array($e) || 1 === \count($values)) {
|
||||
foreach (\is_array($e) ? $e : array_keys($values) as $id) {
|
||||
$ok = false;
|
||||
$v = $values[$id];
|
||||
$type = \is_object($v) ? \get_class($v) : \gettype($v);
|
||||
$message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
}
|
||||
} else {
|
||||
foreach ($values as $id => $v) {
|
||||
$retry[$lifetime][] = $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When bulk-save failed, retry each item individually
|
||||
foreach ($retry as $lifetime => $ids) {
|
||||
foreach ($ids as $id) {
|
||||
try {
|
||||
$v = $byLifetime[$lifetime][$id];
|
||||
$values = $this->extractTagData([$id => $v], $addTagData, $removeTagData);
|
||||
$e = $this->doSave($values, $lifetime, $addTagData, $removeTagData);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
if (true === $e || [] === $e) {
|
||||
continue;
|
||||
}
|
||||
$ok = false;
|
||||
$type = \is_object($v) ? \get_class($v) : \gettype($v);
|
||||
$message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
}
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteItems(array $keys): bool
|
||||
{
|
||||
if (!$keys) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$ok = true;
|
||||
$ids = [];
|
||||
$tagData = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$ids[$key] = $this->getId($key);
|
||||
unset($this->deferred[$key]);
|
||||
}
|
||||
|
||||
try {
|
||||
foreach ($this->doDeleteYieldTags(array_values($ids)) as $id => $tags) {
|
||||
foreach ($tags as $tag) {
|
||||
$tagData[$this->getId(self::TAGS_PREFIX.$tag)][] = $id;
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$ok = false;
|
||||
}
|
||||
|
||||
try {
|
||||
if ((!$tagData || $this->doDeleteTagRelations($tagData)) && $ok) {
|
||||
return true;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
// When bulk-delete failed, retry each item individually
|
||||
foreach ($ids as $key => $id) {
|
||||
try {
|
||||
$e = null;
|
||||
if ($this->doDelete([$id])) {
|
||||
continue;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
$message = 'Failed to delete key "{key}"'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e]);
|
||||
$ok = false;
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function invalidateTags(array $tags)
|
||||
{
|
||||
if (empty($tags)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tagIds = [];
|
||||
foreach (array_unique($tags) as $tag) {
|
||||
$tagIds[] = $this->getId(self::TAGS_PREFIX.$tag);
|
||||
}
|
||||
|
||||
try {
|
||||
if ($this->doInvalidate($tagIds)) {
|
||||
return true;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to invalidate tags: '.$e->getMessage(), ['exception' => $e, 'cache-adapter' => get_debug_type($this)]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts tags operation data from $values set in mergeByLifetime, and returns values without it.
|
||||
*/
|
||||
private function extractTagData(array $values, ?array &$addTagData, ?array &$removeTagData): array
|
||||
{
|
||||
$addTagData = $removeTagData = [];
|
||||
foreach ($values as $id => $value) {
|
||||
foreach ($value['tag-operations']['add'] as $tag => $tagId) {
|
||||
$addTagData[$tagId][] = $id;
|
||||
}
|
||||
|
||||
foreach ($value['tag-operations']['remove'] as $tag => $tagId) {
|
||||
$removeTagData[$tagId][] = $id;
|
||||
}
|
||||
|
||||
unset($values[$id]['tag-operations']);
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
}
|
|
@ -14,9 +14,6 @@ namespace Symfony\Component\Cache\Adapter;
|
|||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
|
||||
// Help opcache.preload discover always-needed symbols
|
||||
class_exists(CacheItem::class);
|
||||
|
||||
/**
|
||||
* Interface for adapters managing instances of Symfony's CacheItem.
|
||||
*
|
||||
|
@ -37,13 +34,4 @@ interface AdapterInterface extends CacheItemPoolInterface
|
|||
* @return \Traversable|CacheItem[]
|
||||
*/
|
||||
public function getItems(array $keys = []);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear(/* string $prefix = '' */);
|
||||
}
|
||||
|
|
|
@ -18,9 +18,13 @@ class ApcuAdapter extends AbstractAdapter
|
|||
use ApcuTrait;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $version
|
||||
*
|
||||
* @throws CacheException if APCu is not enabled
|
||||
*/
|
||||
public function __construct(string $namespace = '', int $defaultLifetime = 0, string $version = null)
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $version = null)
|
||||
{
|
||||
$this->init($namespace, $defaultLifetime, $version);
|
||||
}
|
||||
|
|
|
@ -16,12 +16,11 @@ use Psr\Log\LoggerAwareInterface;
|
|||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ArrayTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface
|
||||
class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
use ArrayTrait;
|
||||
|
||||
|
@ -29,9 +28,10 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
|
|||
private $defaultLifetime;
|
||||
|
||||
/**
|
||||
* @param int $defaultLifetime
|
||||
* @param bool $storeSerialized Disabling serialization can lead to cache corruptions when storing mutable values but increases performance otherwise
|
||||
*/
|
||||
public function __construct(int $defaultLifetime = 0, bool $storeSerialized = true)
|
||||
public function __construct($defaultLifetime = 0, $storeSerialized = true)
|
||||
{
|
||||
$this->defaultLifetime = $defaultLifetime;
|
||||
$this->storeSerialized = $storeSerialized;
|
||||
|
@ -49,35 +49,27 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
|
||||
{
|
||||
$item = $this->getItem($key);
|
||||
$metadata = $item->getMetadata();
|
||||
|
||||
// ArrayAdapter works in memory, we don't care about stampede protection
|
||||
if (\INF === $beta || !$item->isHit()) {
|
||||
$save = true;
|
||||
$item->set($callback($item, $save));
|
||||
if ($save) {
|
||||
$this->save($item);
|
||||
}
|
||||
}
|
||||
|
||||
return $item->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItem($key)
|
||||
{
|
||||
if (!$isHit = $this->hasItem($key)) {
|
||||
$isHit = $this->hasItem($key);
|
||||
try {
|
||||
if (!$isHit) {
|
||||
$this->values[$key] = $value = null;
|
||||
} else {
|
||||
$value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key];
|
||||
} elseif (!$this->storeSerialized) {
|
||||
$value = $this->values[$key];
|
||||
} elseif ('b:0;' === $value = $this->values[$key]) {
|
||||
$value = false;
|
||||
} elseif (false === $value = unserialize($value)) {
|
||||
$this->values[$key] = $value = null;
|
||||
$isHit = false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
$this->values[$key] = $value = null;
|
||||
$isHit = false;
|
||||
}
|
||||
$f = $this->createCacheItem;
|
||||
|
||||
|
@ -90,18 +82,14 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
|
|||
public function getItems(array $keys = [])
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
if (!\is_string($key) || !isset($this->expiries[$key])) {
|
||||
CacheItem::validateKey($key);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->generateItems($keys, microtime(true), $this->createCacheItem);
|
||||
return $this->generateItems($keys, time(), $this->createCacheItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
|
@ -114,8 +102,6 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -127,32 +113,37 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
|
|||
$value = $item["\0*\0value"];
|
||||
$expiry = $item["\0*\0expiry"];
|
||||
|
||||
if (null !== $expiry) {
|
||||
if (!$expiry) {
|
||||
if (0 === $expiry) {
|
||||
$expiry = \PHP_INT_MAX;
|
||||
} elseif ($expiry <= microtime(true)) {
|
||||
}
|
||||
|
||||
if (null !== $expiry && $expiry <= time()) {
|
||||
$this->deleteItem($key);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if ($this->storeSerialized && null === $value = $this->freeze($value, $key)) {
|
||||
if ($this->storeSerialized) {
|
||||
try {
|
||||
$value = serialize($value);
|
||||
} catch (\Exception $e) {
|
||||
$type = \is_object($value) ? \get_class($value) : \gettype($value);
|
||||
CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => $key, 'type' => $type, 'exception' => $e]);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (null === $expiry && 0 < $this->defaultLifetime) {
|
||||
$expiry = microtime(true) + $this->defaultLifetime;
|
||||
$expiry = time() + $this->defaultLifetime;
|
||||
}
|
||||
|
||||
$this->values[$key] = $value;
|
||||
$this->expiries[$key] = $expiry ?? \PHP_INT_MAX;
|
||||
$this->expiries[$key] = null !== $expiry ? $expiry : \PHP_INT_MAX;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -161,19 +152,9 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete(string $key): bool
|
||||
{
|
||||
return $this->deleteItem($key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,6 @@ use Symfony\Component\Cache\CacheItem;
|
|||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ContractsTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
|
||||
/**
|
||||
* Chains several adapters together.
|
||||
|
@ -29,10 +26,8 @@ use Symfony\Contracts\Service\ResetInterface;
|
|||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
|
||||
class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use ContractsTrait;
|
||||
|
||||
private $adapters = [];
|
||||
private $adapterCount;
|
||||
private $syncItem;
|
||||
|
@ -41,7 +36,7 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
* @param CacheItemPoolInterface[] $adapters The ordered list of adapters used to fetch cached items
|
||||
* @param int $defaultLifetime The default lifetime of items propagated from lower adapters to upper ones
|
||||
*/
|
||||
public function __construct(array $adapters, int $defaultLifetime = 0)
|
||||
public function __construct(array $adapters, $defaultLifetime = 0)
|
||||
{
|
||||
if (!$adapters) {
|
||||
throw new InvalidArgumentException('At least one adapter must be specified.');
|
||||
|
@ -51,7 +46,7 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
if (!$adapter instanceof CacheItemPoolInterface) {
|
||||
throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($adapter), CacheItemPoolInterface::class));
|
||||
}
|
||||
if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && $adapter instanceof ApcuAdapter && !filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) {
|
||||
if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && $adapter instanceof ApcuAdapter && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) {
|
||||
continue; // skip putting APCu in the chain when the backend is disabled
|
||||
}
|
||||
|
||||
|
@ -64,18 +59,11 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
$this->adapterCount = \count($this->adapters);
|
||||
|
||||
$this->syncItem = \Closure::bind(
|
||||
static function ($sourceItem, $item, $sourceMetadata = null) use ($defaultLifetime) {
|
||||
$sourceItem->isTaggable = false;
|
||||
$sourceMetadata = $sourceMetadata ?? $sourceItem->metadata;
|
||||
unset($sourceMetadata[CacheItem::METADATA_TAGS]);
|
||||
|
||||
static function ($sourceItem, $item) use ($defaultLifetime) {
|
||||
$item->value = $sourceItem->value;
|
||||
$item->isHit = $sourceItem->isHit;
|
||||
$item->metadata = $item->newMetadata = $sourceItem->metadata = $sourceMetadata;
|
||||
|
||||
if (isset($item->metadata[CacheItem::METADATA_EXPIRY])) {
|
||||
$item->expiresAt(\DateTime::createFromFormat('U.u', sprintf('%.6F', $item->metadata[CacheItem::METADATA_EXPIRY])));
|
||||
} elseif (0 < $defaultLifetime) {
|
||||
if (0 < $defaultLifetime) {
|
||||
$item->expiresAfter($defaultLifetime);
|
||||
}
|
||||
|
||||
|
@ -86,43 +74,6 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
|
||||
{
|
||||
$doSave = true;
|
||||
$callback = static function (CacheItem $item, bool &$save) use ($callback, &$doSave) {
|
||||
$value = $callback($item, $save);
|
||||
$doSave = $save;
|
||||
|
||||
return $value;
|
||||
};
|
||||
|
||||
$lastItem = null;
|
||||
$i = 0;
|
||||
$wrap = function (CacheItem $item = null, bool &$save = true) use ($key, $callback, $beta, &$wrap, &$i, &$doSave, &$lastItem, &$metadata) {
|
||||
$adapter = $this->adapters[$i];
|
||||
if (isset($this->adapters[++$i])) {
|
||||
$callback = $wrap;
|
||||
$beta = \INF === $beta ? \INF : 0;
|
||||
}
|
||||
if ($adapter instanceof CacheInterface) {
|
||||
$value = $adapter->get($key, $callback, $beta, $metadata);
|
||||
} else {
|
||||
$value = $this->doGet($adapter, $key, $callback, $beta, $metadata);
|
||||
}
|
||||
if (null !== $item) {
|
||||
($this->syncItem)($lastItem = $lastItem ?? $item, $item, $metadata);
|
||||
}
|
||||
$save = $doSave;
|
||||
|
||||
return $value;
|
||||
};
|
||||
|
||||
return $wrap();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -156,12 +107,12 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
return $this->generateItems($this->adapters[0]->getItems($keys), 0);
|
||||
}
|
||||
|
||||
private function generateItems(iterable $items, int $adapterIndex)
|
||||
private function generateItems($items, $adapterIndex)
|
||||
{
|
||||
$missing = [];
|
||||
$misses = [];
|
||||
$nextAdapterIndex = $adapterIndex + 1;
|
||||
$nextAdapter = $this->adapters[$nextAdapterIndex] ?? null;
|
||||
$nextAdapter = isset($this->adapters[$nextAdapterIndex]) ? $this->adapters[$nextAdapterIndex] : null;
|
||||
|
||||
foreach ($items as $k => $item) {
|
||||
if (!$nextAdapter || $item->isHit()) {
|
||||
|
@ -189,8 +140,6 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
|
@ -205,32 +154,21 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear(/* string $prefix = '' */)
|
||||
public function clear()
|
||||
{
|
||||
$prefix = 0 < \func_num_args() ? (string) func_get_arg(0) : '';
|
||||
$cleared = true;
|
||||
$i = $this->adapterCount;
|
||||
|
||||
while ($i--) {
|
||||
if ($this->adapters[$i] instanceof AdapterInterface) {
|
||||
$cleared = $this->adapters[$i]->clear($prefix) && $cleared;
|
||||
} else {
|
||||
$cleared = $this->adapters[$i]->clear() && $cleared;
|
||||
}
|
||||
}
|
||||
|
||||
return $cleared;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItem($key)
|
||||
{
|
||||
|
@ -246,8 +184,6 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
|
@ -263,8 +199,6 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -280,8 +214,6 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -297,8 +229,6 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
|
@ -334,7 +264,7 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
public function reset()
|
||||
{
|
||||
foreach ($this->adapters as $adapter) {
|
||||
if ($adapter instanceof ResetInterface) {
|
||||
if ($adapter instanceof ResettableInterface) {
|
||||
$adapter->reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,11 @@ class DoctrineAdapter extends AbstractAdapter
|
|||
{
|
||||
use DoctrineTrait;
|
||||
|
||||
public function __construct(CacheProvider $provider, string $namespace = '', int $defaultLifetime = 0)
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
public function __construct(CacheProvider $provider, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->provider = $provider;
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
|
||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\FilesystemTrait;
|
||||
|
||||
|
@ -20,9 +18,13 @@ class FilesystemAdapter extends AbstractAdapter implements PruneableInterface
|
|||
{
|
||||
use FilesystemTrait;
|
||||
|
||||
public function __construct(string $namespace = '', int $defaultLifetime = 0, string $directory = null, MarshallerInterface $marshaller = null)
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $directory
|
||||
*/
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $directory = null)
|
||||
{
|
||||
$this->marshaller = $marshaller ?? new DefaultMarshaller();
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->init($namespace, $directory);
|
||||
}
|
||||
|
|
|
@ -1,239 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||
use Symfony\Component\Cache\Marshaller\TagAwareMarshaller;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\FilesystemTrait;
|
||||
|
||||
/**
|
||||
* Stores tag id <> cache id relationship as a symlink, and lookup on invalidation calls.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
* @author André Rømcke <andre.romcke+symfony@gmail.com>
|
||||
*/
|
||||
class FilesystemTagAwareAdapter extends AbstractTagAwareAdapter implements PruneableInterface
|
||||
{
|
||||
use FilesystemTrait {
|
||||
doClear as private doClearCache;
|
||||
doSave as private doSaveCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Folder used for tag symlinks.
|
||||
*/
|
||||
private const TAG_FOLDER = 'tags';
|
||||
|
||||
public function __construct(string $namespace = '', int $defaultLifetime = 0, string $directory = null, MarshallerInterface $marshaller = null)
|
||||
{
|
||||
$this->marshaller = new TagAwareMarshaller($marshaller);
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->init($namespace, $directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doClear($namespace)
|
||||
{
|
||||
$ok = $this->doClearCache($namespace);
|
||||
|
||||
if ('' !== $namespace) {
|
||||
return $ok;
|
||||
}
|
||||
|
||||
set_error_handler(static function () {});
|
||||
$chars = '+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
|
||||
try {
|
||||
foreach ($this->scanHashDir($this->directory.self::TAG_FOLDER.\DIRECTORY_SEPARATOR) as $dir) {
|
||||
if (rename($dir, $renamed = substr_replace($dir, bin2hex(random_bytes(4)), -8))) {
|
||||
$dir = $renamed.\DIRECTORY_SEPARATOR;
|
||||
} else {
|
||||
$dir .= \DIRECTORY_SEPARATOR;
|
||||
$renamed = null;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 38; ++$i) {
|
||||
if (!file_exists($dir.$chars[$i])) {
|
||||
continue;
|
||||
}
|
||||
for ($j = 0; $j < 38; ++$j) {
|
||||
if (!file_exists($d = $dir.$chars[$i].\DIRECTORY_SEPARATOR.$chars[$j])) {
|
||||
continue;
|
||||
}
|
||||
foreach (scandir($d, \SCANDIR_SORT_NONE) ?: [] as $link) {
|
||||
if ('.' !== $link && '..' !== $link && (null !== $renamed || !realpath($d.\DIRECTORY_SEPARATOR.$link))) {
|
||||
unlink($d.\DIRECTORY_SEPARATOR.$link);
|
||||
}
|
||||
}
|
||||
null === $renamed ?: rmdir($d);
|
||||
}
|
||||
null === $renamed ?: rmdir($dir.$chars[$i]);
|
||||
}
|
||||
null === $renamed ?: rmdir($renamed);
|
||||
}
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doSave(array $values, int $lifetime, array $addTagData = [], array $removeTagData = []): array
|
||||
{
|
||||
$failed = $this->doSaveCache($values, $lifetime);
|
||||
|
||||
// Add Tags as symlinks
|
||||
foreach ($addTagData as $tagId => $ids) {
|
||||
$tagFolder = $this->getTagFolder($tagId);
|
||||
foreach ($ids as $id) {
|
||||
if ($failed && \in_array($id, $failed, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$file = $this->getFile($id);
|
||||
|
||||
if (!@symlink($file, $tagLink = $this->getFile($id, true, $tagFolder)) && !is_link($tagLink)) {
|
||||
@unlink($file);
|
||||
$failed[] = $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unlink removed Tags
|
||||
foreach ($removeTagData as $tagId => $ids) {
|
||||
$tagFolder = $this->getTagFolder($tagId);
|
||||
foreach ($ids as $id) {
|
||||
if ($failed && \in_array($id, $failed, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@unlink($this->getFile($id, false, $tagFolder));
|
||||
}
|
||||
}
|
||||
|
||||
return $failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doDeleteYieldTags(array $ids): iterable
|
||||
{
|
||||
foreach ($ids as $id) {
|
||||
$file = $this->getFile($id);
|
||||
if (!file_exists($file) || !$h = @fopen($file, 'r')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((\PHP_VERSION_ID >= 70300 || '\\' !== \DIRECTORY_SEPARATOR) && !@unlink($file)) {
|
||||
fclose($h);
|
||||
continue;
|
||||
}
|
||||
|
||||
$meta = explode("\n", fread($h, 4096), 3)[2] ?? '';
|
||||
|
||||
// detect the compact format used in marshall() using magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
|
||||
if (13 < \strlen($meta) && "\x9D" === $meta[0] && "\0" === $meta[5] && "\x5F" === $meta[9]) {
|
||||
$meta[9] = "\0";
|
||||
$tagLen = unpack('Nlen', $meta, 9)['len'];
|
||||
$meta = substr($meta, 13, $tagLen);
|
||||
|
||||
if (0 < $tagLen -= \strlen($meta)) {
|
||||
$meta .= fread($h, $tagLen);
|
||||
}
|
||||
|
||||
try {
|
||||
yield $id => '' === $meta ? [] : $this->marshaller->unmarshall($meta);
|
||||
} catch (\Exception $e) {
|
||||
yield $id => [];
|
||||
}
|
||||
}
|
||||
|
||||
fclose($h);
|
||||
|
||||
if (\PHP_VERSION_ID < 70300 && '\\' === \DIRECTORY_SEPARATOR) {
|
||||
@unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doDeleteTagRelations(array $tagData): bool
|
||||
{
|
||||
foreach ($tagData as $tagId => $idList) {
|
||||
$tagFolder = $this->getTagFolder($tagId);
|
||||
foreach ($idList as $id) {
|
||||
@unlink($this->getFile($id, false, $tagFolder));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doInvalidate(array $tagIds): bool
|
||||
{
|
||||
foreach ($tagIds as $tagId) {
|
||||
if (!file_exists($tagFolder = $this->getTagFolder($tagId))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
set_error_handler(static function () {});
|
||||
|
||||
try {
|
||||
if (rename($tagFolder, $renamed = substr_replace($tagFolder, bin2hex(random_bytes(4)), -9))) {
|
||||
$tagFolder = $renamed.\DIRECTORY_SEPARATOR;
|
||||
} else {
|
||||
$renamed = null;
|
||||
}
|
||||
|
||||
foreach ($this->scanHashDir($tagFolder) as $itemLink) {
|
||||
unlink(realpath($itemLink) ?: $itemLink);
|
||||
unlink($itemLink);
|
||||
}
|
||||
|
||||
if (null === $renamed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$chars = '+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
|
||||
for ($i = 0; $i < 38; ++$i) {
|
||||
for ($j = 0; $j < 38; ++$j) {
|
||||
rmdir($tagFolder.$chars[$i].\DIRECTORY_SEPARATOR.$chars[$j]);
|
||||
}
|
||||
rmdir($tagFolder.$chars[$i]);
|
||||
}
|
||||
rmdir($renamed);
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getTagFolder(string $tagId): string
|
||||
{
|
||||
return $this->getFile($tagId, false, $this->directory.self::TAG_FOLDER.\DIRECTORY_SEPARATOR).\DIRECTORY_SEPARATOR;
|
||||
}
|
||||
}
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||
use Symfony\Component\Cache\Traits\MemcachedTrait;
|
||||
|
||||
class MemcachedAdapter extends AbstractAdapter
|
||||
|
@ -30,8 +29,8 @@ class MemcachedAdapter extends AbstractAdapter
|
|||
*
|
||||
* Using a MemcachedAdapter as a pure items store is fine.
|
||||
*/
|
||||
public function __construct(\Memcached $client, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
|
||||
public function __construct(\Memcached $client, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->init($client, $namespace, $defaultLifetime, $marshaller);
|
||||
$this->init($client, $namespace, $defaultLifetime);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,11 @@ namespace Symfony\Component\Cache\Adapter;
|
|||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
/**
|
||||
* @author Titouan Galopin <galopintitouan@gmail.com>
|
||||
*/
|
||||
class NullAdapter implements AdapterInterface, CacheInterface
|
||||
class NullAdapter implements AdapterInterface
|
||||
{
|
||||
private $createCacheItem;
|
||||
|
||||
|
@ -37,16 +36,6 @@ class NullAdapter implements AdapterInterface, CacheInterface
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
|
||||
{
|
||||
$save = true;
|
||||
|
||||
return $callback(($this->createCacheItem)($key), $save);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -67,8 +56,6 @@ class NullAdapter implements AdapterInterface, CacheInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
|
@ -77,20 +64,14 @@ class NullAdapter implements AdapterInterface, CacheInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear(/* string $prefix = '' */)
|
||||
public function clear()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItem($key)
|
||||
{
|
||||
|
@ -99,8 +80,6 @@ class NullAdapter implements AdapterInterface, CacheInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
|
@ -109,40 +88,26 @@ class NullAdapter implements AdapterInterface, CacheInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete(string $key): bool
|
||||
{
|
||||
return $this->deleteItem($key);
|
||||
return false;
|
||||
}
|
||||
|
||||
private function generateItems(array $keys)
|
||||
|
|
|
@ -13,7 +13,6 @@ namespace Symfony\Component\Cache\Adapter;
|
|||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\PdoTrait;
|
||||
|
||||
|
@ -28,9 +27,6 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface
|
|||
* a Doctrine DBAL Connection or a DSN string that will be used to
|
||||
* lazy-connect to the database when the cache is actually used.
|
||||
*
|
||||
* When a Doctrine DBAL Connection is passed, the cache table is created
|
||||
* automatically when possible. Otherwise, use the createTable() method.
|
||||
*
|
||||
* List of available options:
|
||||
* * db_table: The name of the table [default: cache_items]
|
||||
* * db_id_col: The column where to store the cache id [default: item_id]
|
||||
|
@ -41,14 +37,17 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface
|
|||
* * db_password: The password when lazy-connect [default: '']
|
||||
* * db_connection_options: An array of driver-specific connection options [default: []]
|
||||
*
|
||||
* @param \PDO|Connection|string $connOrDsn a \PDO or Connection instance or DSN string or null
|
||||
* @param \PDO|Connection|string $connOrDsn A \PDO or Connection instance or DSN string or null
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param array $options An associative array of options
|
||||
*
|
||||
* @throws InvalidArgumentException When first argument is not PDO nor Connection nor string
|
||||
* @throws InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION
|
||||
* @throws InvalidArgumentException When namespace contains invalid characters
|
||||
*/
|
||||
public function __construct($connOrDsn, string $namespace = '', int $defaultLifetime = 0, array $options = [], MarshallerInterface $marshaller = null)
|
||||
public function __construct($connOrDsn, $namespace = '', $defaultLifetime = 0, array $options = [])
|
||||
{
|
||||
$this->init($connOrDsn, $namespace, $defaultLifetime, $options, $marshaller);
|
||||
$this->init($connOrDsn, $namespace, $defaultLifetime, $options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,7 @@ use Symfony\Component\Cache\CacheItem;
|
|||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ContractsTrait;
|
||||
use Symfony\Component\Cache\Traits\PhpArrayTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
/**
|
||||
* Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0.
|
||||
|
@ -28,9 +26,8 @@ use Symfony\Contracts\Cache\CacheInterface;
|
|||
* @author Titouan Galopin <galopintitouan@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
|
||||
class PhpArrayAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use ContractsTrait;
|
||||
use PhpArrayTrait;
|
||||
|
||||
private $createCacheItem;
|
||||
|
@ -39,10 +36,11 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
* @param string $file The PHP file were values are cached
|
||||
* @param AdapterInterface $fallbackPool A pool to fallback on when an item is not hit
|
||||
*/
|
||||
public function __construct(string $file, AdapterInterface $fallbackPool)
|
||||
public function __construct($file, AdapterInterface $fallbackPool)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->pool = $fallbackPool;
|
||||
$this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN);
|
||||
$this->createCacheItem = \Closure::bind(
|
||||
static function ($key, $value, $isHit) {
|
||||
$item = new CacheItem();
|
||||
|
@ -58,7 +56,9 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
}
|
||||
|
||||
/**
|
||||
* This adapter takes advantage of how PHP stores arrays in its latest versions.
|
||||
* This adapter should only be used on PHP 7.0+ to take advantage of how PHP
|
||||
* stores arrays in its latest versions. This factory method decorates the given
|
||||
* fallback pool with this adapter only if the current PHP version is supported.
|
||||
*
|
||||
* @param string $file The PHP file were values are cached
|
||||
* @param CacheItemPoolInterface $fallbackPool A pool to fallback on when an item is not hit
|
||||
|
@ -67,6 +67,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
*/
|
||||
public static function create($file, CacheItemPoolInterface $fallbackPool)
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
if (!$fallbackPool instanceof AdapterInterface) {
|
||||
$fallbackPool = new ProxyAdapter($fallbackPool);
|
||||
}
|
||||
|
@ -74,37 +75,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
return new static($file, $fallbackPool);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
|
||||
{
|
||||
if (null === $this->values) {
|
||||
$this->initialize();
|
||||
}
|
||||
if (!isset($this->keys[$key])) {
|
||||
get_from_pool:
|
||||
if ($this->pool instanceof CacheInterface) {
|
||||
return $this->pool->get($key, $callback, $beta, $metadata);
|
||||
}
|
||||
|
||||
return $this->doGet($this->pool, $key, $callback, $beta, $metadata);
|
||||
}
|
||||
$value = $this->values[$this->keys[$key]];
|
||||
|
||||
if ('N;' === $value) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
if ($value instanceof \Closure) {
|
||||
return $value();
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
unset($this->keys[$key]);
|
||||
goto get_from_pool;
|
||||
}
|
||||
|
||||
return $value;
|
||||
return $fallbackPool;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,19 +89,23 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
if (null === $this->values) {
|
||||
$this->initialize();
|
||||
}
|
||||
if (!isset($this->keys[$key])) {
|
||||
if (!isset($this->values[$key])) {
|
||||
return $this->pool->getItem($key);
|
||||
}
|
||||
|
||||
$value = $this->values[$this->keys[$key]];
|
||||
$value = $this->values[$key];
|
||||
$isHit = true;
|
||||
|
||||
if ('N;' === $value) {
|
||||
$value = null;
|
||||
} elseif ($value instanceof \Closure) {
|
||||
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||
try {
|
||||
$value = $value();
|
||||
} catch (\Throwable $e) {
|
||||
$e = null;
|
||||
$value = unserialize($value);
|
||||
} catch (\Error $e) {
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
if (null !== $e) {
|
||||
$value = null;
|
||||
$isHit = false;
|
||||
}
|
||||
|
@ -160,8 +135,6 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
|
@ -172,13 +145,11 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
$this->initialize();
|
||||
}
|
||||
|
||||
return isset($this->keys[$key]) || $this->pool->hasItem($key);
|
||||
return isset($this->values[$key]) || $this->pool->hasItem($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItem($key)
|
||||
{
|
||||
|
@ -189,13 +160,11 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
$this->initialize();
|
||||
}
|
||||
|
||||
return !isset($this->keys[$key]) && $this->pool->deleteItem($key);
|
||||
return !isset($this->values[$key]) && $this->pool->deleteItem($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
|
@ -207,7 +176,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
|
||||
}
|
||||
|
||||
if (isset($this->keys[$key])) {
|
||||
if (isset($this->values[$key])) {
|
||||
$deleted = false;
|
||||
} else {
|
||||
$fallbackKeys[] = $key;
|
||||
|
@ -226,8 +195,6 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -235,13 +202,11 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
$this->initialize();
|
||||
}
|
||||
|
||||
return !isset($this->keys[$item->getKey()]) && $this->pool->save($item);
|
||||
return !isset($this->values[$item->getKey()]) && $this->pool->save($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -249,34 +214,37 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
$this->initialize();
|
||||
}
|
||||
|
||||
return !isset($this->keys[$item->getKey()]) && $this->pool->saveDeferred($item);
|
||||
return !isset($this->values[$item->getKey()]) && $this->pool->saveDeferred($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return $this->pool->commit();
|
||||
}
|
||||
|
||||
private function generateItems(array $keys): \Generator
|
||||
/**
|
||||
* @return \Generator
|
||||
*/
|
||||
private function generateItems(array $keys)
|
||||
{
|
||||
$f = $this->createCacheItem;
|
||||
$fallbackKeys = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (isset($this->keys[$key])) {
|
||||
$value = $this->values[$this->keys[$key]];
|
||||
if (isset($this->values[$key])) {
|
||||
$value = $this->values[$key];
|
||||
|
||||
if ('N;' === $value) {
|
||||
yield $key => $f($key, null, true);
|
||||
} elseif ($value instanceof \Closure) {
|
||||
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||
try {
|
||||
yield $key => $f($key, $value(), true);
|
||||
} catch (\Throwable $e) {
|
||||
yield $key => $f($key, unserialize($value), true);
|
||||
} catch (\Error $e) {
|
||||
yield $key => $f($key, null, false);
|
||||
} catch (\Exception $e) {
|
||||
yield $key => $f($key, null, false);
|
||||
}
|
||||
} else {
|
||||
|
@ -288,7 +256,9 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
|
|||
}
|
||||
|
||||
if ($fallbackKeys) {
|
||||
yield from $this->pool->getItems($fallbackKeys);
|
||||
foreach ($this->pool->getItems($fallbackKeys) as $key => $item) {
|
||||
yield $key => $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,19 +20,22 @@ class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface
|
|||
use PhpFilesTrait;
|
||||
|
||||
/**
|
||||
* @param $appendOnly Set to `true` to gain extra performance when the items stored in this pool never expire.
|
||||
* Doing so is encouraged because it fits perfectly OPcache's memory model.
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $directory
|
||||
*
|
||||
* @throws CacheException if OPcache is not enabled
|
||||
*/
|
||||
public function __construct(string $namespace = '', int $defaultLifetime = 0, string $directory = null, bool $appendOnly = false)
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $directory = null)
|
||||
{
|
||||
$this->appendOnly = $appendOnly;
|
||||
self::$startTime = self::$startTime ?? $_SERVER['REQUEST_TIME'] ?? time();
|
||||
if (!static::isSupported()) {
|
||||
throw new CacheException('OPcache is not enabled.');
|
||||
}
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->init($namespace, $directory);
|
||||
$this->includeHandler = static function ($type, $msg, $file, $line) {
|
||||
throw new \ErrorException($msg, 0, $type, $file, $line);
|
||||
};
|
||||
|
||||
$e = new \Exception();
|
||||
$this->includeHandler = function () use ($e) { throw $e; };
|
||||
$this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,26 +16,26 @@ use Psr\Cache\CacheItemPoolInterface;
|
|||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ContractsTrait;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
|
||||
class ProxyAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use ContractsTrait;
|
||||
use ProxyTrait;
|
||||
|
||||
private $namespace;
|
||||
private $namespaceLen;
|
||||
private $createCacheItem;
|
||||
private $setInnerItem;
|
||||
private $poolHash;
|
||||
private $defaultLifetime;
|
||||
|
||||
public function __construct(CacheItemPoolInterface $pool, string $namespace = '', int $defaultLifetime = 0)
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
public function __construct(CacheItemPoolInterface $pool, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->pool = $pool;
|
||||
$this->poolHash = $poolHash = spl_object_hash($pool);
|
||||
|
@ -46,71 +46,20 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
static function ($key, $innerItem) use ($poolHash) {
|
||||
$item = new CacheItem();
|
||||
$item->key = $key;
|
||||
|
||||
if (null === $innerItem) {
|
||||
return $item;
|
||||
}
|
||||
|
||||
$item->value = $v = $innerItem->get();
|
||||
$item->isHit = $innerItem->isHit();
|
||||
$item->innerItem = $innerItem;
|
||||
$item->poolHash = $poolHash;
|
||||
|
||||
// Detect wrapped values that encode for their expiry and creation duration
|
||||
// For compactness, these values are packed in the key of an array using
|
||||
// magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
|
||||
if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = (string) array_key_first($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) {
|
||||
$item->value = $v[$k];
|
||||
$v = unpack('Ve/Nc', substr($k, 1, -1));
|
||||
$item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET;
|
||||
$item->metadata[CacheItem::METADATA_CTIME] = $v['c'];
|
||||
} elseif ($innerItem instanceof CacheItem) {
|
||||
$item->metadata = $innerItem->metadata;
|
||||
}
|
||||
if (null !== $innerItem) {
|
||||
$item->value = $innerItem->get();
|
||||
$item->isHit = $innerItem->isHit();
|
||||
$item->innerItem = $innerItem;
|
||||
$innerItem->set(null);
|
||||
}
|
||||
|
||||
return $item;
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
$this->setInnerItem = \Closure::bind(
|
||||
/**
|
||||
* @param array $item A CacheItem cast to (array); accessing protected properties requires adding the "\0*\0" PHP prefix
|
||||
*/
|
||||
static function (CacheItemInterface $innerItem, array $item) {
|
||||
// Tags are stored separately, no need to account for them when considering this item's newly set metadata
|
||||
if (isset(($metadata = $item["\0*\0newMetadata"])[CacheItem::METADATA_TAGS])) {
|
||||
unset($metadata[CacheItem::METADATA_TAGS]);
|
||||
}
|
||||
if ($metadata) {
|
||||
// For compactness, expiry and creation duration are packed in the key of an array, using magic numbers as separators
|
||||
$item["\0*\0value"] = ["\x9D".pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME])."\x5F" => $item["\0*\0value"]];
|
||||
}
|
||||
$innerItem->set($item["\0*\0value"]);
|
||||
$innerItem->expiresAt(null !== $item["\0*\0expiry"] ? \DateTime::createFromFormat('U.u', sprintf('%.6F', $item["\0*\0expiry"])) : null);
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
|
||||
{
|
||||
if (!$this->pool instanceof CacheInterface) {
|
||||
return $this->doGet($this, $key, $callback, $beta, $metadata);
|
||||
}
|
||||
|
||||
return $this->pool->get($this->getId($key), function ($innerItem, bool &$save) use ($key, $callback) {
|
||||
$item = ($this->createCacheItem)($key, $innerItem);
|
||||
$item->set($value = $callback($item, $save));
|
||||
($this->setInnerItem)($innerItem, (array) $item);
|
||||
|
||||
return $value;
|
||||
}, $beta, $metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,8 +89,6 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
|
@ -150,26 +97,14 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear(/* string $prefix = '' */)
|
||||
public function clear()
|
||||
{
|
||||
$prefix = 0 < \func_num_args() ? (string) func_get_arg(0) : '';
|
||||
|
||||
if ($this->pool instanceof AdapterInterface) {
|
||||
return $this->pool->clear($this->namespace.$prefix);
|
||||
}
|
||||
|
||||
return $this->pool->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItem($key)
|
||||
{
|
||||
|
@ -178,8 +113,6 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
|
@ -194,8 +127,6 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -204,8 +135,6 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -214,22 +143,21 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return $this->pool->commit();
|
||||
}
|
||||
|
||||
private function doSave(CacheItemInterface $item, string $method)
|
||||
private function doSave(CacheItemInterface $item, $method)
|
||||
{
|
||||
if (!$item instanceof CacheItem) {
|
||||
return false;
|
||||
}
|
||||
$item = (array) $item;
|
||||
if (null === $item["\0*\0expiry"] && 0 < $this->defaultLifetime) {
|
||||
$item["\0*\0expiry"] = microtime(true) + $this->defaultLifetime;
|
||||
$expiry = $item["\0*\0expiry"];
|
||||
if (null === $expiry && 0 < $this->defaultLifetime) {
|
||||
$expiry = time() + $this->defaultLifetime;
|
||||
}
|
||||
|
||||
if ($item["\0*\0poolHash"] === $this->poolHash && $item["\0*\0innerItem"]) {
|
||||
|
@ -243,12 +171,13 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
$innerItem = $this->pool->getItem($this->namespace.$item["\0*\0key"]);
|
||||
}
|
||||
|
||||
($this->setInnerItem)($innerItem, $item);
|
||||
$innerItem->set($item["\0*\0value"]);
|
||||
$innerItem->expiresAt(null !== $expiry ? \DateTime::createFromFormat('U', $expiry) : null);
|
||||
|
||||
return $this->pool->$method($innerItem);
|
||||
}
|
||||
|
||||
private function generateItems(iterable $items)
|
||||
private function generateItems($items)
|
||||
{
|
||||
$f = $this->createCacheItem;
|
||||
|
||||
|
@ -261,7 +190,7 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
|
|||
}
|
||||
}
|
||||
|
||||
private function getId($key): string
|
||||
private function getId($key)
|
||||
{
|
||||
CacheItem::validateKey($key);
|
||||
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
|
||||
/**
|
||||
* Turns a PSR-16 cache into a PSR-6 one.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class Psr16Adapter extends AbstractAdapter implements PruneableInterface, ResettableInterface
|
||||
{
|
||||
use ProxyTrait;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected const NS_SEPARATOR = '_';
|
||||
|
||||
private $miss;
|
||||
|
||||
public function __construct(CacheInterface $pool, string $namespace = '', int $defaultLifetime = 0)
|
||||
{
|
||||
parent::__construct($namespace, $defaultLifetime);
|
||||
|
||||
$this->pool = $pool;
|
||||
$this->miss = new \stdClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doFetch(array $ids)
|
||||
{
|
||||
foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) {
|
||||
if ($this->miss !== $value) {
|
||||
yield $key => $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doHave($id)
|
||||
{
|
||||
return $this->pool->has($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doClear($namespace)
|
||||
{
|
||||
return $this->pool->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doDelete(array $ids)
|
||||
{
|
||||
return $this->pool->deleteMultiple($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doSave(array $values, int $lifetime)
|
||||
{
|
||||
return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime);
|
||||
}
|
||||
}
|
|
@ -11,9 +11,6 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||
use Symfony\Component\Cache\Traits\RedisClusterProxy;
|
||||
use Symfony\Component\Cache\Traits\RedisProxy;
|
||||
use Symfony\Component\Cache\Traits\RedisTrait;
|
||||
|
||||
class RedisAdapter extends AbstractAdapter
|
||||
|
@ -21,12 +18,12 @@ class RedisAdapter extends AbstractAdapter
|
|||
use RedisTrait;
|
||||
|
||||
/**
|
||||
* @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy $redis The redis client
|
||||
* @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient The redis client
|
||||
* @param string $namespace The default namespace
|
||||
* @param int $defaultLifetime The default lifetime
|
||||
*/
|
||||
public function __construct($redis, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
|
||||
public function __construct($redisClient, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->init($redis, $namespace, $defaultLifetime, $marshaller);
|
||||
$this->init($redisClient, $namespace, $defaultLifetime);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,321 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Predis\Connection\Aggregate\ClusterInterface;
|
||||
use Predis\Connection\Aggregate\PredisCluster;
|
||||
use Predis\Connection\Aggregate\ReplicationInterface;
|
||||
use Predis\Response\ErrorInterface;
|
||||
use Predis\Response\Status;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\Exception\LogicException;
|
||||
use Symfony\Component\Cache\Marshaller\DeflateMarshaller;
|
||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||
use Symfony\Component\Cache\Marshaller\TagAwareMarshaller;
|
||||
use Symfony\Component\Cache\Traits\RedisClusterProxy;
|
||||
use Symfony\Component\Cache\Traits\RedisProxy;
|
||||
use Symfony\Component\Cache\Traits\RedisTrait;
|
||||
|
||||
/**
|
||||
* Stores tag id <> cache id relationship as a Redis Set.
|
||||
*
|
||||
* Set (tag relation info) is stored without expiry (non-volatile), while cache always gets an expiry (volatile) even
|
||||
* if not set by caller. Thus if you configure redis with the right eviction policy you can be safe this tag <> cache
|
||||
* relationship survives eviction (cache cleanup when Redis runs out of memory).
|
||||
*
|
||||
* Redis server 2.8+ with any `volatile-*` eviction policy, OR `noeviction` if you're sure memory will NEVER fill up
|
||||
*
|
||||
* Design limitations:
|
||||
* - Max 4 billion cache keys per cache tag as limited by Redis Set datatype.
|
||||
* E.g. If you use a "all" items tag for expiry instead of clear(), that limits you to 4 billion cache items also.
|
||||
*
|
||||
* @see https://redis.io/topics/lru-cache#eviction-policies Documentation for Redis eviction policies.
|
||||
* @see https://redis.io/topics/data-types#sets Documentation for Redis Set datatype.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
* @author André Rømcke <andre.romcke+symfony@gmail.com>
|
||||
*/
|
||||
class RedisTagAwareAdapter extends AbstractTagAwareAdapter
|
||||
{
|
||||
use RedisTrait;
|
||||
|
||||
/**
|
||||
* On cache items without a lifetime set, we set it to 100 days. This is to make sure cache items are
|
||||
* preferred to be evicted over tag Sets, if eviction policy is configured according to requirements.
|
||||
*/
|
||||
private const DEFAULT_CACHE_TTL = 8640000;
|
||||
|
||||
/**
|
||||
* @var string|null detected eviction policy used on Redis server
|
||||
*/
|
||||
private $redisEvictionPolicy;
|
||||
private $namespace;
|
||||
|
||||
/**
|
||||
* @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy $redis The redis client
|
||||
* @param string $namespace The default namespace
|
||||
* @param int $defaultLifetime The default lifetime
|
||||
*/
|
||||
public function __construct($redis, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
|
||||
{
|
||||
if ($redis instanceof \Predis\ClientInterface && $redis->getConnection() instanceof ClusterInterface && !$redis->getConnection() instanceof PredisCluster) {
|
||||
throw new InvalidArgumentException(sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, \get_class($redis->getConnection())));
|
||||
}
|
||||
|
||||
if (\defined('Redis::OPT_COMPRESSION') && ($redis instanceof \Redis || $redis instanceof \RedisArray || $redis instanceof \RedisCluster)) {
|
||||
$compression = $redis->getOption(\Redis::OPT_COMPRESSION);
|
||||
|
||||
foreach (\is_array($compression) ? $compression : [$compression] as $c) {
|
||||
if (\Redis::COMPRESSION_NONE !== $c) {
|
||||
throw new InvalidArgumentException(sprintf('phpredis compression must be disabled when using "%s", use "%s" instead.', static::class, DeflateMarshaller::class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->init($redis, $namespace, $defaultLifetime, new TagAwareMarshaller($marshaller));
|
||||
$this->namespace = $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doSave(array $values, int $lifetime, array $addTagData = [], array $delTagData = []): array
|
||||
{
|
||||
$eviction = $this->getRedisEvictionPolicy();
|
||||
if ('noeviction' !== $eviction && !str_starts_with($eviction, 'volatile-')) {
|
||||
throw new LogicException(sprintf('Redis maxmemory-policy setting "%s" is *not* supported by RedisTagAwareAdapter, use "noeviction" or "volatile-*" eviction policies.', $eviction));
|
||||
}
|
||||
|
||||
// serialize values
|
||||
if (!$serialized = $this->marshaller->marshall($values, $failed)) {
|
||||
return $failed;
|
||||
}
|
||||
|
||||
// While pipeline isn't supported on RedisCluster, other setups will at least benefit from doing this in one op
|
||||
$results = $this->pipeline(static function () use ($serialized, $lifetime, $addTagData, $delTagData, $failed) {
|
||||
// Store cache items, force a ttl if none is set, as there is no MSETEX we need to set each one
|
||||
foreach ($serialized as $id => $value) {
|
||||
yield 'setEx' => [
|
||||
$id,
|
||||
0 >= $lifetime ? self::DEFAULT_CACHE_TTL : $lifetime,
|
||||
$value,
|
||||
];
|
||||
}
|
||||
|
||||
// Add and Remove Tags
|
||||
foreach ($addTagData as $tagId => $ids) {
|
||||
if (!$failed || $ids = array_diff($ids, $failed)) {
|
||||
yield 'sAdd' => array_merge([$tagId], $ids);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($delTagData as $tagId => $ids) {
|
||||
if (!$failed || $ids = array_diff($ids, $failed)) {
|
||||
yield 'sRem' => array_merge([$tagId], $ids);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
foreach ($results as $id => $result) {
|
||||
// Skip results of SADD/SREM operations, they'll be 1 or 0 depending on if set value already existed or not
|
||||
if (is_numeric($result)) {
|
||||
continue;
|
||||
}
|
||||
// setEx results
|
||||
if (true !== $result && (!$result instanceof Status || Status::get('OK') !== $result)) {
|
||||
$failed[] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
return $failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doDeleteYieldTags(array $ids): iterable
|
||||
{
|
||||
$lua = <<<'EOLUA'
|
||||
local v = redis.call('GET', KEYS[1])
|
||||
redis.call('DEL', KEYS[1])
|
||||
|
||||
if not v or v:len() <= 13 or v:byte(1) ~= 0x9D or v:byte(6) ~= 0 or v:byte(10) ~= 0x5F then
|
||||
return ''
|
||||
end
|
||||
|
||||
return v:sub(14, 13 + v:byte(13) + v:byte(12) * 256 + v:byte(11) * 65536)
|
||||
EOLUA;
|
||||
|
||||
$results = $this->pipeline(function () use ($ids, $lua) {
|
||||
foreach ($ids as $id) {
|
||||
yield 'eval' => $this->redis instanceof \Predis\ClientInterface ? [$lua, 1, $id] : [$lua, [$id], 1];
|
||||
}
|
||||
});
|
||||
|
||||
foreach ($results as $id => $result) {
|
||||
if ($result instanceof \RedisException || $result instanceof ErrorInterface) {
|
||||
CacheItem::log($this->logger, 'Failed to delete key "{key}": '.$result->getMessage(), ['key' => substr($id, \strlen($this->namespace)), 'exception' => $result]);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
yield $id => !\is_string($result) || '' === $result ? [] : $this->marshaller->unmarshall($result);
|
||||
} catch (\Exception $e) {
|
||||
yield $id => [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doDeleteTagRelations(array $tagData): bool
|
||||
{
|
||||
$results = $this->pipeline(static function () use ($tagData) {
|
||||
foreach ($tagData as $tagId => $idList) {
|
||||
array_unshift($idList, $tagId);
|
||||
yield 'sRem' => $idList;
|
||||
}
|
||||
});
|
||||
foreach ($results as $result) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doInvalidate(array $tagIds): bool
|
||||
{
|
||||
// This script scans the set of items linked to tag: it empties the set
|
||||
// and removes the linked items. When the set is still not empty after
|
||||
// the scan, it means we're in cluster mode and that the linked items
|
||||
// are on other nodes: we move the links to a temporary set and we
|
||||
// garbage collect that set from the client side.
|
||||
|
||||
$lua = <<<'EOLUA'
|
||||
redis.replicate_commands()
|
||||
|
||||
local cursor = '0'
|
||||
local id = KEYS[1]
|
||||
repeat
|
||||
local result = redis.call('SSCAN', id, cursor, 'COUNT', 5000);
|
||||
cursor = result[1];
|
||||
local rems = {}
|
||||
|
||||
for _, v in ipairs(result[2]) do
|
||||
local ok, _ = pcall(redis.call, 'DEL', ARGV[1]..v)
|
||||
if ok then
|
||||
table.insert(rems, v)
|
||||
end
|
||||
end
|
||||
if 0 < #rems then
|
||||
redis.call('SREM', id, unpack(rems))
|
||||
end
|
||||
until '0' == cursor;
|
||||
|
||||
redis.call('SUNIONSTORE', '{'..id..'}'..id, id)
|
||||
redis.call('DEL', id)
|
||||
|
||||
return redis.call('SSCAN', '{'..id..'}'..id, '0', 'COUNT', 5000)
|
||||
EOLUA;
|
||||
|
||||
$results = $this->pipeline(function () use ($tagIds, $lua) {
|
||||
if ($this->redis instanceof \Predis\ClientInterface) {
|
||||
$prefix = $this->redis->getOptions()->prefix ? $this->redis->getOptions()->prefix->getPrefix() : '';
|
||||
} elseif (\is_array($prefix = $this->redis->getOption(\Redis::OPT_PREFIX) ?? '')) {
|
||||
$prefix = current($prefix);
|
||||
}
|
||||
|
||||
foreach ($tagIds as $id) {
|
||||
yield 'eval' => $this->redis instanceof \Predis\ClientInterface ? [$lua, 1, $id, $prefix] : [$lua, [$id, $prefix], 1];
|
||||
}
|
||||
});
|
||||
|
||||
$lua = <<<'EOLUA'
|
||||
redis.replicate_commands()
|
||||
|
||||
local id = KEYS[1]
|
||||
local cursor = table.remove(ARGV)
|
||||
redis.call('SREM', '{'..id..'}'..id, unpack(ARGV))
|
||||
|
||||
return redis.call('SSCAN', '{'..id..'}'..id, cursor, 'COUNT', 5000)
|
||||
EOLUA;
|
||||
|
||||
$success = true;
|
||||
foreach ($results as $id => $values) {
|
||||
if ($values instanceof \RedisException || $values instanceof ErrorInterface) {
|
||||
CacheItem::log($this->logger, 'Failed to invalidate key "{key}": '.$values->getMessage(), ['key' => substr($id, \strlen($this->namespace)), 'exception' => $values]);
|
||||
$success = false;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
[$cursor, $ids] = $values;
|
||||
|
||||
while ($ids || '0' !== $cursor) {
|
||||
$this->doDelete($ids);
|
||||
|
||||
$evalArgs = [$id, $cursor];
|
||||
array_splice($evalArgs, 1, 0, $ids);
|
||||
|
||||
if ($this->redis instanceof \Predis\ClientInterface) {
|
||||
array_unshift($evalArgs, $lua, 1);
|
||||
} else {
|
||||
$evalArgs = [$lua, $evalArgs, 1];
|
||||
}
|
||||
|
||||
$results = $this->pipeline(function () use ($evalArgs) {
|
||||
yield 'eval' => $evalArgs;
|
||||
});
|
||||
|
||||
foreach ($results as [$cursor, $ids]) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
private function getRedisEvictionPolicy(): string
|
||||
{
|
||||
if (null !== $this->redisEvictionPolicy) {
|
||||
return $this->redisEvictionPolicy;
|
||||
}
|
||||
|
||||
$hosts = $this->getHosts();
|
||||
$host = reset($hosts);
|
||||
if ($host instanceof \Predis\Client && $host->getConnection() instanceof ReplicationInterface) {
|
||||
// Predis supports info command only on the master in replication environments
|
||||
$hosts = [$host->getClientFor('master')];
|
||||
}
|
||||
|
||||
foreach ($hosts as $host) {
|
||||
$info = $host->info('Memory');
|
||||
|
||||
if ($info instanceof ErrorInterface) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$info = $info['Memory'] ?? $info;
|
||||
|
||||
return $this->redisEvictionPolicy = $info['maxmemory_policy'];
|
||||
}
|
||||
|
||||
return $this->redisEvictionPolicy = '';
|
||||
}
|
||||
}
|
|
@ -11,11 +11,73 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is @deprecated since Symfony 4.3, use "Psr16Adapter" instead.', SimpleCacheAdapter::class), \E_USER_DEPRECATED);
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use Psr16Adapter instead.
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class SimpleCacheAdapter extends Psr16Adapter
|
||||
class SimpleCacheAdapter extends AbstractAdapter implements PruneableInterface
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const NS_SEPARATOR = '_';
|
||||
|
||||
use ProxyTrait;
|
||||
|
||||
private $miss;
|
||||
|
||||
public function __construct(CacheInterface $pool, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
parent::__construct($namespace, $defaultLifetime);
|
||||
|
||||
$this->pool = $pool;
|
||||
$this->miss = new \stdClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doFetch(array $ids)
|
||||
{
|
||||
foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) {
|
||||
if ($this->miss !== $value) {
|
||||
yield $key => $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doHave($id)
|
||||
{
|
||||
return $this->pool->has($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doClear($namespace)
|
||||
{
|
||||
return $this->pool->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doDelete(array $ids)
|
||||
{
|
||||
return $this->pool->deleteMultiple($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doSave(array $values, $lifetime)
|
||||
{
|
||||
return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,25 +13,19 @@ namespace Symfony\Component\Cache\Adapter;
|
|||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ContractsTrait;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, PruneableInterface, ResettableInterface, LoggerAwareInterface
|
||||
class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use ContractsTrait;
|
||||
use LoggerAwareTrait;
|
||||
use ProxyTrait;
|
||||
const TAGS_PREFIX = "\0tags\0";
|
||||
|
||||
public const TAGS_PREFIX = "\0tags\0";
|
||||
use ProxyTrait;
|
||||
|
||||
private $deferred = [];
|
||||
private $createCacheItem;
|
||||
|
@ -42,7 +36,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
private $knownTagVersions = [];
|
||||
private $knownTagVersionsTtl;
|
||||
|
||||
public function __construct(AdapterInterface $itemsPool, AdapterInterface $tagsPool = null, float $knownTagVersionsTtl = 0.15)
|
||||
public function __construct(AdapterInterface $itemsPool, AdapterInterface $tagsPool = null, $knownTagVersionsTtl = 0.15)
|
||||
{
|
||||
$this->pool = $itemsPool;
|
||||
$this->tags = $tagsPool ?: $itemsPool;
|
||||
|
@ -62,13 +56,12 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
);
|
||||
$this->setCacheItemTags = \Closure::bind(
|
||||
static function (CacheItem $item, $key, array &$itemTags) {
|
||||
$item->isTaggable = true;
|
||||
if (!$item->isHit) {
|
||||
return $item;
|
||||
}
|
||||
if (isset($itemTags[$key])) {
|
||||
foreach ($itemTags[$key] as $tag => $version) {
|
||||
$item->metadata[CacheItem::METADATA_TAGS][$tag] = $tag;
|
||||
$item->prevTags[$tag] = $tag;
|
||||
}
|
||||
unset($itemTags[$key]);
|
||||
} else {
|
||||
|
@ -85,8 +78,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
static function ($deferred) {
|
||||
$tagsByKey = [];
|
||||
foreach ($deferred as $key => $item) {
|
||||
$tagsByKey[$key] = $item->newMetadata[CacheItem::METADATA_TAGS] ?? [];
|
||||
$item->metadata = $item->newMetadata;
|
||||
$tagsByKey[$key] = $item->tags;
|
||||
}
|
||||
|
||||
return $tagsByKey;
|
||||
|
@ -153,15 +145,12 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
if (\is_string($key) && isset($this->deferred[$key])) {
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
|
||||
if (!$this->pool->hasItem($key)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -177,12 +166,10 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
}
|
||||
|
||||
foreach ($this->getTagVersions([$itemTags]) as $tag => $version) {
|
||||
if ($itemTags[$tag] === $version || \is_int($itemTags[$tag]) && \is_int($version) && 1 === $itemTags[$tag] - $version) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($itemTags[$tag] !== $version && 1 !== $itemTags[$tag] - $version) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -204,21 +191,18 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
*/
|
||||
public function getItems(array $keys = [])
|
||||
{
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
$tagKeys = [];
|
||||
$commit = false;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if ('' !== $key && \is_string($key)) {
|
||||
$commit = $commit || isset($this->deferred[$key]);
|
||||
$key = static::TAGS_PREFIX.$key;
|
||||
$tagKeys[$key] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
if ($commit) {
|
||||
$this->commit();
|
||||
}
|
||||
|
||||
try {
|
||||
$items = $this->pool->getItems($tagKeys + $keys);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
|
@ -232,36 +216,16 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear(/* string $prefix = '' */)
|
||||
public function clear()
|
||||
{
|
||||
$prefix = 0 < \func_num_args() ? (string) func_get_arg(0) : '';
|
||||
|
||||
if ('' !== $prefix) {
|
||||
foreach ($this->deferred as $key => $item) {
|
||||
if (str_starts_with($key, $prefix)) {
|
||||
unset($this->deferred[$key]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->deferred = [];
|
||||
}
|
||||
|
||||
if ($this->pool instanceof AdapterInterface) {
|
||||
return $this->pool->clear($prefix);
|
||||
}
|
||||
|
||||
return $this->pool->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItem($key)
|
||||
{
|
||||
|
@ -270,8 +234,6 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
|
@ -286,8 +248,6 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -301,8 +261,6 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -316,17 +274,12 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return $this->invalidateTags([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
|
@ -342,7 +295,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
$this->commit();
|
||||
}
|
||||
|
||||
private function generateItems(iterable $items, array $tagKeys)
|
||||
private function generateItems($items, array $tagKeys)
|
||||
{
|
||||
$bufferedItems = $itemTags = [];
|
||||
$f = $this->setCacheItemTags;
|
||||
|
@ -368,13 +321,12 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
|
||||
foreach ($itemTags as $key => $tags) {
|
||||
foreach ($tags as $tag => $version) {
|
||||
if ($tagVersions[$tag] === $version || \is_int($version) && \is_int($tagVersions[$tag]) && 1 === $version - $tagVersions[$tag]) {
|
||||
continue;
|
||||
}
|
||||
if ($tagVersions[$tag] !== $version && 1 !== $version - $tagVersions[$tag]) {
|
||||
unset($itemTags[$key]);
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
$tagVersions = $tagKeys = null;
|
||||
|
||||
foreach ($bufferedItems as $key => $item) {
|
||||
|
@ -411,7 +363,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
$tags = [];
|
||||
foreach ($tagVersions as $tag => $version) {
|
||||
$tags[$tag.static::TAGS_PREFIX] = $tag;
|
||||
if ($fetchTagVersions || !isset($this->knownTagVersions[$tag]) || !\is_int($version)) {
|
||||
if ($fetchTagVersions || !isset($this->knownTagVersions[$tag])) {
|
||||
$fetchTagVersions = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -433,10 +385,6 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
|
|||
if (isset($invalidatedTags[$tag])) {
|
||||
$invalidatedTags[$tag] = $version->set(++$tagVersions[$tag]);
|
||||
}
|
||||
if (!\is_int($tagVersions[$tag])) {
|
||||
unset($this->knownTagVersions[$tag]);
|
||||
continue;
|
||||
}
|
||||
$this->knownTagVersions[$tag] = [$now, $tagVersions[$tag]];
|
||||
}
|
||||
|
||||
|
|
|
@ -12,11 +12,8 @@
|
|||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
|
||||
/**
|
||||
* An adapter that collects data about all cache calls.
|
||||
|
@ -25,7 +22,7 @@ use Symfony\Contracts\Service\ResetInterface;
|
|||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
|
||||
class TraceableAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
protected $pool;
|
||||
private $calls = [];
|
||||
|
@ -35,38 +32,6 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt
|
|||
$this->pool = $pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
|
||||
{
|
||||
if (!$this->pool instanceof CacheInterface) {
|
||||
throw new \BadMethodCallException(sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', \get_class($this->pool), CacheInterface::class));
|
||||
}
|
||||
|
||||
$isHit = true;
|
||||
$callback = function (CacheItem $item, bool &$save) use ($callback, &$isHit) {
|
||||
$isHit = $item->isHit();
|
||||
|
||||
return $callback($item, $save);
|
||||
};
|
||||
|
||||
$event = $this->start(__FUNCTION__);
|
||||
try {
|
||||
$value = $this->pool->get($key, $callback, $beta, $metadata);
|
||||
$event->result[$key] = \is_object($value) ? \get_class($value) : \gettype($value);
|
||||
} finally {
|
||||
$event->end = microtime(true);
|
||||
}
|
||||
if ($isHit) {
|
||||
++$event->hits;
|
||||
} else {
|
||||
++$event->misses;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -89,8 +54,6 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
|
@ -104,8 +67,6 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItem($key)
|
||||
{
|
||||
|
@ -119,8 +80,6 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -134,8 +93,6 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
|
@ -175,20 +132,11 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear(/* string $prefix = '' */)
|
||||
public function clear()
|
||||
{
|
||||
$prefix = 0 < \func_num_args() ? (string) func_get_arg(0) : '';
|
||||
$event = $this->start(__FUNCTION__);
|
||||
try {
|
||||
if ($this->pool instanceof AdapterInterface) {
|
||||
return $event->result = $this->pool->clear($prefix);
|
||||
}
|
||||
|
||||
return $event->result = $this->pool->clear();
|
||||
} finally {
|
||||
$event->end = microtime(true);
|
||||
|
@ -197,8 +145,6 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
|
@ -213,8 +159,6 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
|
@ -247,26 +191,13 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt
|
|||
*/
|
||||
public function reset()
|
||||
{
|
||||
if ($this->pool instanceof ResetInterface) {
|
||||
if ($this->pool instanceof ResettableInterface) {
|
||||
$this->pool->reset();
|
||||
}
|
||||
|
||||
$this->clearCalls();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete(string $key): bool
|
||||
{
|
||||
$event = $this->start(__FUNCTION__);
|
||||
try {
|
||||
return $event->result[$key] = $this->pool->deleteItem($key);
|
||||
} finally {
|
||||
$event->end = microtime(true);
|
||||
}
|
||||
}
|
||||
|
||||
public function getCalls()
|
||||
{
|
||||
return $this->calls;
|
||||
|
|
|
@ -11,12 +11,10 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||
|
||||
/**
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*/
|
||||
class TraceableTagAwareAdapter extends TraceableAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface
|
||||
class TraceableTagAwareAdapter extends TraceableAdapter implements TagAwareAdapterInterface
|
||||
{
|
||||
public function __construct(TagAwareAdapterInterface $pool)
|
||||
{
|
||||
|
|
|
@ -1,43 +1,6 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
|
||||
4.4.0
|
||||
-----
|
||||
|
||||
* added support for connecting to Redis Sentinel clusters
|
||||
* added argument `$prefix` to `AdapterInterface::clear()`
|
||||
* improved `RedisTagAwareAdapter` to support Redis server >= 2.8 and up to 4B items per tag
|
||||
* added `TagAwareMarshaller` for optimized data storage when using `AbstractTagAwareAdapter`
|
||||
* added `DeflateMarshaller` to compress serialized values
|
||||
* removed support for phpredis 4 `compression`
|
||||
* [BC BREAK] `RedisTagAwareAdapter` is not compatible with `RedisCluster` from `Predis` anymore, use `phpredis` instead
|
||||
* Marked the `CacheDataCollector` class as `@final`.
|
||||
|
||||
4.3.0
|
||||
-----
|
||||
|
||||
* removed `psr/simple-cache` dependency, run `composer require psr/simple-cache` if you need it
|
||||
* deprecated all PSR-16 adapters, use `Psr16Cache` or `Symfony\Contracts\Cache\CacheInterface` implementations instead
|
||||
* deprecated `SimpleCacheAdapter`, use `Psr16Adapter` instead
|
||||
|
||||
4.2.0
|
||||
-----
|
||||
|
||||
* added support for connecting to Redis clusters via DSN
|
||||
* added support for configuring multiple Memcached servers via DSN
|
||||
* added `MarshallerInterface` and `DefaultMarshaller` to allow changing the serializer and provide one that automatically uses igbinary when available
|
||||
* implemented `CacheInterface`, which provides stampede protection via probabilistic early expiration and should become the preferred way to use a cache
|
||||
* added sub-second expiry accuracy for backends that support it
|
||||
* added support for phpredis 4 `compression` and `tcp_keepalive` options
|
||||
* added automatic table creation when using Doctrine DBAL with PDO-based backends
|
||||
* throw `LogicException` when `CacheItem::tag()` is called on an item coming from a non tag-aware pool
|
||||
* deprecated `CacheItem::getPreviousTags()`, use `CacheItem::getMetadata()` instead
|
||||
* deprecated the `AbstractAdapter::unserialize()` and `AbstractCache::unserialize()` methods
|
||||
* added `CacheCollectorPass` (originally in `FrameworkBundle`)
|
||||
* added `CachePoolClearerPass` (originally in `FrameworkBundle`)
|
||||
* added `CachePoolPass` (originally in `FrameworkBundle`)
|
||||
* added `CachePoolPrunerPass` (originally in `FrameworkBundle`)
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
|
@ -50,7 +13,7 @@ CHANGELOG
|
|||
3.3.0
|
||||
-----
|
||||
|
||||
* added CacheItem::getPreviousTags() to get bound tags coming from the pool storage if any
|
||||
* [EXPERIMENTAL] added CacheItem::getPreviousTags() to get bound tags coming from the pool storage if any
|
||||
* added PSR-16 "Simple Cache" implementations for all existing PSR-6 adapters
|
||||
* added Psr6Cache and SimpleCacheAdapter for bidirectional interoperability between PSR-6 and PSR-16
|
||||
* added MemcachedAdapter (PSR-6) and MemcachedCache (PSR-16)
|
||||
|
|
|
@ -11,40 +11,34 @@
|
|||
|
||||
namespace Symfony\Component\Cache;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\Exception\LogicException;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
final class CacheItem implements ItemInterface
|
||||
final class CacheItem implements CacheItemInterface
|
||||
{
|
||||
private const METADATA_EXPIRY_OFFSET = 1527506807;
|
||||
|
||||
protected $key;
|
||||
protected $value;
|
||||
protected $isHit = false;
|
||||
protected $expiry;
|
||||
protected $metadata = [];
|
||||
protected $newMetadata = [];
|
||||
protected $tags = [];
|
||||
protected $prevTags = [];
|
||||
protected $innerItem;
|
||||
protected $poolHash;
|
||||
protected $isTaggable = false;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getKey(): string
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
|
@ -54,7 +48,7 @@ final class CacheItem implements ItemInterface
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isHit(): bool
|
||||
public function isHit()
|
||||
{
|
||||
return $this->isHit;
|
||||
}
|
||||
|
@ -64,7 +58,7 @@ final class CacheItem implements ItemInterface
|
|||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set($value): self
|
||||
public function set($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
|
||||
|
@ -76,12 +70,12 @@ final class CacheItem implements ItemInterface
|
|||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function expiresAt($expiration): self
|
||||
public function expiresAt($expiration)
|
||||
{
|
||||
if (null === $expiration) {
|
||||
$this->expiry = null;
|
||||
} elseif ($expiration instanceof \DateTimeInterface) {
|
||||
$this->expiry = (float) $expiration->format('U.u');
|
||||
$this->expiry = (int) $expiration->format('U');
|
||||
} else {
|
||||
throw new InvalidArgumentException(sprintf('Expiration date must implement DateTimeInterface or be null, "%s" given.', \is_object($expiration) ? \get_class($expiration) : \gettype($expiration)));
|
||||
}
|
||||
|
@ -94,14 +88,14 @@ final class CacheItem implements ItemInterface
|
|||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function expiresAfter($time): self
|
||||
public function expiresAfter($time)
|
||||
{
|
||||
if (null === $time) {
|
||||
$this->expiry = null;
|
||||
} elseif ($time instanceof \DateInterval) {
|
||||
$this->expiry = microtime(true) + \DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
|
||||
$this->expiry = (int) \DateTime::createFromFormat('U', time())->add($time)->format('U');
|
||||
} elseif (\is_int($time)) {
|
||||
$this->expiry = $time + microtime(true);
|
||||
$this->expiry = $time + time();
|
||||
} else {
|
||||
throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', \is_object($time) ? \get_class($time) : \gettype($time)));
|
||||
}
|
||||
|
@ -110,64 +104,58 @@ final class CacheItem implements ItemInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Adds a tag to a cache item.
|
||||
*
|
||||
* @param string|string[] $tags A tag or array of tags
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException When $tag is not valid
|
||||
*/
|
||||
public function tag($tags): ItemInterface
|
||||
public function tag($tags)
|
||||
{
|
||||
if (!$this->isTaggable) {
|
||||
throw new LogicException(sprintf('Cache item "%s" comes from a non tag-aware pool: you cannot tag it.', $this->key));
|
||||
}
|
||||
if (!is_iterable($tags)) {
|
||||
if (!\is_array($tags)) {
|
||||
$tags = [$tags];
|
||||
}
|
||||
foreach ($tags as $tag) {
|
||||
if (!\is_string($tag) && !(\is_object($tag) && method_exists($tag, '__toString'))) {
|
||||
throw new InvalidArgumentException(sprintf('Cache tag must be string or object that implements __toString(), "%s" given.', \is_object($tag) ? \get_class($tag) : \gettype($tag)));
|
||||
if (!\is_string($tag)) {
|
||||
throw new InvalidArgumentException(sprintf('Cache tag must be string, "%s" given.', \is_object($tag) ? \get_class($tag) : \gettype($tag)));
|
||||
}
|
||||
$tag = (string) $tag;
|
||||
if (isset($this->newMetadata[self::METADATA_TAGS][$tag])) {
|
||||
if (isset($this->tags[$tag])) {
|
||||
continue;
|
||||
}
|
||||
if ('' === $tag) {
|
||||
throw new InvalidArgumentException('Cache tag length must be greater than zero.');
|
||||
}
|
||||
if (false !== strpbrk($tag, self::RESERVED_CHARACTERS)) {
|
||||
throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters "%s".', $tag, self::RESERVED_CHARACTERS));
|
||||
if (false !== strpbrk($tag, '{}()/\@:')) {
|
||||
throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters {}()/\@:.', $tag));
|
||||
}
|
||||
$this->newMetadata[self::METADATA_TAGS][$tag] = $tag;
|
||||
$this->tags[$tag] = $tag;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadata(): array
|
||||
{
|
||||
return $this->metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of tags bound to the value coming from the pool storage if any.
|
||||
*
|
||||
* @deprecated since Symfony 4.2, use the "getMetadata()" method instead.
|
||||
* @return array
|
||||
*/
|
||||
public function getPreviousTags(): array
|
||||
public function getPreviousTags()
|
||||
{
|
||||
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the "getMetadata()" method instead.', __METHOD__), \E_USER_DEPRECATED);
|
||||
|
||||
return $this->metadata[self::METADATA_TAGS] ?? [];
|
||||
return $this->prevTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a cache key according to PSR-6.
|
||||
*
|
||||
* @param mixed $key The key to validate
|
||||
* @param string $key The key to validate
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws InvalidArgumentException When $key is not valid
|
||||
*/
|
||||
public static function validateKey($key): string
|
||||
public static function validateKey($key)
|
||||
{
|
||||
if (!\is_string($key)) {
|
||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
|
||||
|
@ -175,8 +163,8 @@ final class CacheItem implements ItemInterface
|
|||
if ('' === $key) {
|
||||
throw new InvalidArgumentException('Cache key length must be greater than zero.');
|
||||
}
|
||||
if (false !== strpbrk($key, self::RESERVED_CHARACTERS)) {
|
||||
throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS));
|
||||
if (false !== strpbrk($key, '{}()/\@:')) {
|
||||
throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters {}()/\@:.', $key));
|
||||
}
|
||||
|
||||
return $key;
|
||||
|
@ -187,14 +175,14 @@ final class CacheItem implements ItemInterface
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function log(?LoggerInterface $logger, string $message, array $context = [])
|
||||
public static function log(LoggerInterface $logger = null, $message, $context = [])
|
||||
{
|
||||
if ($logger) {
|
||||
$logger->warning($message, $context);
|
||||
} else {
|
||||
$replace = [];
|
||||
foreach ($context as $k => $v) {
|
||||
if (\is_scalar($v)) {
|
||||
if (is_scalar($v)) {
|
||||
$replace['{'.$k.'}'] = $v;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@ use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
|
|||
/**
|
||||
* @author Aaron Scherer <aequasi@gmail.com>
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* @final since Symfony 4.4
|
||||
*/
|
||||
class CacheDataCollector extends DataCollector implements LateDataCollectorInterface
|
||||
{
|
||||
|
@ -41,10 +39,8 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param \Throwable|null $exception
|
||||
*/
|
||||
public function collect(Request $request, Response $response/* , \Throwable $exception = null */)
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
$empty = ['calls' => [], 'config' => [], 'options' => [], 'statistics' => []];
|
||||
$this->data = ['instances' => $empty, 'total' => $empty];
|
||||
|
@ -66,7 +62,7 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter
|
|||
|
||||
public function lateCollect()
|
||||
{
|
||||
$this->data['instances']['calls'] = $this->cloneVar($this->data['instances']['calls']);
|
||||
$this->data = $this->cloneVar($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,7 +103,10 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter
|
|||
return $this->data['instances']['calls'];
|
||||
}
|
||||
|
||||
private function calculateStatistics(): array
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function calculateStatistics()
|
||||
{
|
||||
$statistics = [];
|
||||
foreach ($this->data['instances']['calls'] as $name => $calls) {
|
||||
|
@ -124,15 +123,7 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter
|
|||
foreach ($calls as $call) {
|
||||
++$statistics[$name]['calls'];
|
||||
$statistics[$name]['time'] += $call->end - $call->start;
|
||||
if ('get' === $call->name) {
|
||||
++$statistics[$name]['reads'];
|
||||
if ($call->hits) {
|
||||
++$statistics[$name]['hits'];
|
||||
} else {
|
||||
++$statistics[$name]['misses'];
|
||||
++$statistics[$name]['writes'];
|
||||
}
|
||||
} elseif ('getItem' === $call->name) {
|
||||
if ('getItem' === $call->name) {
|
||||
++$statistics[$name]['reads'];
|
||||
if ($call->hits) {
|
||||
++$statistics[$name]['hits'];
|
||||
|
@ -166,7 +157,10 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter
|
|||
return $statistics;
|
||||
}
|
||||
|
||||
private function calculateTotalStatistics(): array
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function calculateTotalStatistics()
|
||||
{
|
||||
$statistics = $this->getStatistics();
|
||||
$totals = [
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\DependencyInjection;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
|
||||
use Symfony\Component\Cache\Adapter\TraceableAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Inject a data collector to all the cache services to be able to get detailed statistics.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class CacheCollectorPass implements CompilerPassInterface
|
||||
{
|
||||
private $dataCollectorCacheId;
|
||||
private $cachePoolTag;
|
||||
private $cachePoolRecorderInnerSuffix;
|
||||
|
||||
public function __construct(string $dataCollectorCacheId = 'data_collector.cache', string $cachePoolTag = 'cache.pool', string $cachePoolRecorderInnerSuffix = '.recorder_inner')
|
||||
{
|
||||
$this->dataCollectorCacheId = $dataCollectorCacheId;
|
||||
$this->cachePoolTag = $cachePoolTag;
|
||||
$this->cachePoolRecorderInnerSuffix = $cachePoolRecorderInnerSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition($this->dataCollectorCacheId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->cachePoolTag) as $id => $attributes) {
|
||||
$poolName = $attributes[0]['name'] ?? $id;
|
||||
|
||||
$this->addToCollector($id, $poolName, $container);
|
||||
}
|
||||
}
|
||||
|
||||
private function addToCollector(string $id, string $name, ContainerBuilder $container)
|
||||
{
|
||||
$definition = $container->getDefinition($id);
|
||||
if ($definition->isAbstract()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$collectorDefinition = $container->getDefinition($this->dataCollectorCacheId);
|
||||
$recorder = new Definition(is_subclass_of($definition->getClass(), TagAwareAdapterInterface::class) ? TraceableTagAwareAdapter::class : TraceableAdapter::class);
|
||||
$recorder->setTags($definition->getTags());
|
||||
if (!$definition->isPublic() || !$definition->isPrivate()) {
|
||||
$recorder->setPublic($definition->isPublic());
|
||||
}
|
||||
$recorder->setArguments([new Reference($innerId = $id.$this->cachePoolRecorderInnerSuffix)]);
|
||||
|
||||
$definition->setTags([]);
|
||||
$definition->setPublic(false);
|
||||
|
||||
$container->setDefinition($innerId, $definition);
|
||||
$container->setDefinition($id, $recorder);
|
||||
|
||||
// Tell the collector to add the new instance
|
||||
$collectorDefinition->addMethodCall('addInstance', [$name, new Reference($id)]);
|
||||
$collectorDefinition->setPublic(false);
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class CachePoolClearerPass implements CompilerPassInterface
|
||||
{
|
||||
private $cachePoolClearerTag;
|
||||
|
||||
public function __construct(string $cachePoolClearerTag = 'cache.pool.clearer')
|
||||
{
|
||||
$this->cachePoolClearerTag = $cachePoolClearerTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$container->getParameterBag()->remove('cache.prefix.seed');
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->cachePoolClearerTag) as $id => $attr) {
|
||||
$clearer = $container->getDefinition($id);
|
||||
$pools = [];
|
||||
foreach ($clearer->getArgument(0) as $name => $ref) {
|
||||
if ($container->hasDefinition($ref)) {
|
||||
$pools[$name] = new Reference($ref);
|
||||
}
|
||||
}
|
||||
$clearer->replaceArgument(0, $pools);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,228 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\DependencyInjection;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\Cache\Adapter\ChainAdapter;
|
||||
use Symfony\Component\Cache\Adapter\NullAdapter;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class CachePoolPass implements CompilerPassInterface
|
||||
{
|
||||
private $cachePoolTag;
|
||||
private $kernelResetTag;
|
||||
private $cacheClearerId;
|
||||
private $cachePoolClearerTag;
|
||||
private $cacheSystemClearerId;
|
||||
private $cacheSystemClearerTag;
|
||||
|
||||
public function __construct(string $cachePoolTag = 'cache.pool', string $kernelResetTag = 'kernel.reset', string $cacheClearerId = 'cache.global_clearer', string $cachePoolClearerTag = 'cache.pool.clearer', string $cacheSystemClearerId = 'cache.system_clearer', string $cacheSystemClearerTag = 'kernel.cache_clearer')
|
||||
{
|
||||
$this->cachePoolTag = $cachePoolTag;
|
||||
$this->kernelResetTag = $kernelResetTag;
|
||||
$this->cacheClearerId = $cacheClearerId;
|
||||
$this->cachePoolClearerTag = $cachePoolClearerTag;
|
||||
$this->cacheSystemClearerId = $cacheSystemClearerId;
|
||||
$this->cacheSystemClearerTag = $cacheSystemClearerTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if ($container->hasParameter('cache.prefix.seed')) {
|
||||
$seed = '.'.$container->getParameterBag()->resolveValue($container->getParameter('cache.prefix.seed'));
|
||||
} else {
|
||||
$seed = '_'.$container->getParameter('kernel.project_dir');
|
||||
}
|
||||
$seed .= '.'.$container->getParameter('kernel.container_class');
|
||||
|
||||
$allPools = [];
|
||||
$clearers = [];
|
||||
$attributes = [
|
||||
'provider',
|
||||
'name',
|
||||
'namespace',
|
||||
'default_lifetime',
|
||||
'reset',
|
||||
];
|
||||
foreach ($container->findTaggedServiceIds($this->cachePoolTag) as $id => $tags) {
|
||||
$adapter = $pool = $container->getDefinition($id);
|
||||
if ($pool->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
$class = $adapter->getClass();
|
||||
while ($adapter instanceof ChildDefinition) {
|
||||
$adapter = $container->findDefinition($adapter->getParent());
|
||||
$class = $class ?: $adapter->getClass();
|
||||
if ($t = $adapter->getTag($this->cachePoolTag)) {
|
||||
$tags[0] += $t[0];
|
||||
}
|
||||
}
|
||||
$name = $tags[0]['name'] ?? $id;
|
||||
if (!isset($tags[0]['namespace'])) {
|
||||
$namespaceSeed = $seed;
|
||||
if (null !== $class) {
|
||||
$namespaceSeed .= '.'.$class;
|
||||
}
|
||||
|
||||
$tags[0]['namespace'] = $this->getNamespace($namespaceSeed, $name);
|
||||
}
|
||||
if (isset($tags[0]['clearer'])) {
|
||||
$clearer = $tags[0]['clearer'];
|
||||
while ($container->hasAlias($clearer)) {
|
||||
$clearer = (string) $container->getAlias($clearer);
|
||||
}
|
||||
} else {
|
||||
$clearer = null;
|
||||
}
|
||||
unset($tags[0]['clearer'], $tags[0]['name']);
|
||||
|
||||
if (isset($tags[0]['provider'])) {
|
||||
$tags[0]['provider'] = new Reference(static::getServiceProvider($container, $tags[0]['provider']));
|
||||
}
|
||||
|
||||
if (ChainAdapter::class === $class) {
|
||||
$adapters = [];
|
||||
foreach ($adapter->getArgument(0) as $provider => $adapter) {
|
||||
if ($adapter instanceof ChildDefinition) {
|
||||
$chainedPool = $adapter;
|
||||
} else {
|
||||
$chainedPool = $adapter = new ChildDefinition($adapter);
|
||||
}
|
||||
|
||||
$chainedTags = [\is_int($provider) ? [] : ['provider' => $provider]];
|
||||
$chainedClass = '';
|
||||
|
||||
while ($adapter instanceof ChildDefinition) {
|
||||
$adapter = $container->findDefinition($adapter->getParent());
|
||||
$chainedClass = $chainedClass ?: $adapter->getClass();
|
||||
if ($t = $adapter->getTag($this->cachePoolTag)) {
|
||||
$chainedTags[0] += $t[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (ChainAdapter::class === $chainedClass) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid service "%s": chain of adapters cannot reference another chain, found "%s".', $id, $chainedPool->getParent()));
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
|
||||
if (isset($chainedTags[0]['provider'])) {
|
||||
$chainedPool->replaceArgument($i++, new Reference(static::getServiceProvider($container, $chainedTags[0]['provider'])));
|
||||
}
|
||||
|
||||
if (isset($tags[0]['namespace']) && !\in_array($adapter->getClass(), [ArrayAdapter::class, NullAdapter::class], true)) {
|
||||
$chainedPool->replaceArgument($i++, $tags[0]['namespace']);
|
||||
}
|
||||
|
||||
if (isset($tags[0]['default_lifetime'])) {
|
||||
$chainedPool->replaceArgument($i++, $tags[0]['default_lifetime']);
|
||||
}
|
||||
|
||||
$adapters[] = $chainedPool;
|
||||
}
|
||||
|
||||
$pool->replaceArgument(0, $adapters);
|
||||
unset($tags[0]['provider'], $tags[0]['namespace']);
|
||||
$i = 1;
|
||||
} else {
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
foreach ($attributes as $attr) {
|
||||
if (!isset($tags[0][$attr])) {
|
||||
// no-op
|
||||
} elseif ('reset' === $attr) {
|
||||
if ($tags[0][$attr]) {
|
||||
$pool->addTag($this->kernelResetTag, ['method' => $tags[0][$attr]]);
|
||||
}
|
||||
} elseif ('namespace' !== $attr || !\in_array($class, [ArrayAdapter::class, NullAdapter::class], true)) {
|
||||
$pool->replaceArgument($i++, $tags[0][$attr]);
|
||||
}
|
||||
unset($tags[0][$attr]);
|
||||
}
|
||||
if (!empty($tags[0])) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid "%s" tag for service "%s": accepted attributes are "clearer", "provider", "name", "namespace", "default_lifetime" and "reset", found "%s".', $this->cachePoolTag, $id, implode('", "', array_keys($tags[0]))));
|
||||
}
|
||||
|
||||
if (null !== $clearer) {
|
||||
$clearers[$clearer][$name] = new Reference($id, $container::IGNORE_ON_UNINITIALIZED_REFERENCE);
|
||||
}
|
||||
|
||||
$allPools[$name] = new Reference($id, $container::IGNORE_ON_UNINITIALIZED_REFERENCE);
|
||||
}
|
||||
|
||||
$notAliasedCacheClearerId = $this->cacheClearerId;
|
||||
while ($container->hasAlias($this->cacheClearerId)) {
|
||||
$this->cacheClearerId = (string) $container->getAlias($this->cacheClearerId);
|
||||
}
|
||||
if ($container->hasDefinition($this->cacheClearerId)) {
|
||||
$clearers[$notAliasedCacheClearerId] = $allPools;
|
||||
}
|
||||
|
||||
foreach ($clearers as $id => $pools) {
|
||||
$clearer = $container->getDefinition($id);
|
||||
if ($clearer instanceof ChildDefinition) {
|
||||
$clearer->replaceArgument(0, $pools);
|
||||
} else {
|
||||
$clearer->setArgument(0, $pools);
|
||||
}
|
||||
$clearer->addTag($this->cachePoolClearerTag);
|
||||
|
||||
if ($this->cacheSystemClearerId === $id) {
|
||||
$clearer->addTag($this->cacheSystemClearerTag);
|
||||
}
|
||||
}
|
||||
|
||||
if ($container->hasDefinition('console.command.cache_pool_list')) {
|
||||
$container->getDefinition('console.command.cache_pool_list')->replaceArgument(0, array_keys($allPools));
|
||||
}
|
||||
}
|
||||
|
||||
private function getNamespace(string $seed, string $id)
|
||||
{
|
||||
return substr(str_replace('/', '-', base64_encode(hash('sha256', $id.$seed, true))), 0, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function getServiceProvider(ContainerBuilder $container, $name)
|
||||
{
|
||||
$container->resolveEnvPlaceholders($name, null, $usedEnvs);
|
||||
|
||||
if ($usedEnvs || preg_match('#^[a-z]++:#', $name)) {
|
||||
$dsn = $name;
|
||||
|
||||
if (!$container->hasDefinition($name = '.cache_connection.'.ContainerBuilder::hash($dsn))) {
|
||||
$definition = new Definition(AbstractAdapter::class);
|
||||
$definition->setPublic(false);
|
||||
$definition->setFactory([AbstractAdapter::class, 'createConnection']);
|
||||
$definition->setArguments([$dsn, ['lazy' => true]]);
|
||||
$container->setDefinition($name, $definition);
|
||||
}
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\DependencyInjection;
|
||||
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* @author Rob Frawley 2nd <rmf@src.run>
|
||||
*/
|
||||
class CachePoolPrunerPass implements CompilerPassInterface
|
||||
{
|
||||
private $cacheCommandServiceId;
|
||||
private $cachePoolTag;
|
||||
|
||||
public function __construct(string $cacheCommandServiceId = 'console.command.cache_pool_prune', string $cachePoolTag = 'cache.pool')
|
||||
{
|
||||
$this->cacheCommandServiceId = $cacheCommandServiceId;
|
||||
$this->cachePoolTag = $cachePoolTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition($this->cacheCommandServiceId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$services = [];
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->cachePoolTag) as $id => $tags) {
|
||||
$class = $container->getParameterBag()->resolveValue($container->getDefinition($id)->getClass());
|
||||
|
||||
if (!$reflection = $container->getReflectionClass($class)) {
|
||||
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
|
||||
}
|
||||
|
||||
if ($reflection->implementsInterface(PruneableInterface::class)) {
|
||||
$services[$id] = new Reference($id);
|
||||
}
|
||||
}
|
||||
|
||||
$container->getDefinition($this->cacheCommandServiceId)->replaceArgument(0, new IteratorArgument($services));
|
||||
}
|
||||
}
|
|
@ -13,11 +13,6 @@ namespace Symfony\Component\Cache;
|
|||
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
|
||||
if (!class_exists(CacheProvider::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
|
@ -44,7 +39,7 @@ class DoctrineProvider extends CacheProvider implements PruneableInterface, Rese
|
|||
*/
|
||||
public function reset()
|
||||
{
|
||||
if ($this->pool instanceof ResetInterface) {
|
||||
if ($this->pool instanceof ResettableInterface) {
|
||||
$this->pool->reset();
|
||||
}
|
||||
$this->setNamespace($this->getNamespace());
|
||||
|
@ -52,8 +47,6 @@ class DoctrineProvider extends CacheProvider implements PruneableInterface, Rese
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function doFetch($id)
|
||||
{
|
||||
|
@ -64,8 +57,6 @@ class DoctrineProvider extends CacheProvider implements PruneableInterface, Rese
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function doContains($id)
|
||||
{
|
||||
|
@ -74,8 +65,6 @@ class DoctrineProvider extends CacheProvider implements PruneableInterface, Rese
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function doSave($id, $data, $lifeTime = 0)
|
||||
{
|
||||
|
@ -90,8 +79,6 @@ class DoctrineProvider extends CacheProvider implements PruneableInterface, Rese
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function doDelete($id)
|
||||
{
|
||||
|
@ -100,8 +87,6 @@ class DoctrineProvider extends CacheProvider implements PruneableInterface, Rese
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function doFlush()
|
||||
{
|
||||
|
@ -110,8 +95,6 @@ class DoctrineProvider extends CacheProvider implements PruneableInterface, Rese
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
protected function doGetStats()
|
||||
{
|
||||
|
|
|
@ -14,12 +14,6 @@ namespace Symfony\Component\Cache\Exception;
|
|||
use Psr\Cache\CacheException as Psr6CacheInterface;
|
||||
use Psr\SimpleCache\CacheException as SimpleCacheInterface;
|
||||
|
||||
if (interface_exists(SimpleCacheInterface::class)) {
|
||||
class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface
|
||||
{
|
||||
}
|
||||
} else {
|
||||
class CacheException extends \Exception implements Psr6CacheInterface
|
||||
{
|
||||
}
|
||||
class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface
|
||||
{
|
||||
}
|
||||
|
|
|
@ -14,12 +14,6 @@ namespace Symfony\Component\Cache\Exception;
|
|||
use Psr\Cache\InvalidArgumentException as Psr6CacheInterface;
|
||||
use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInterface;
|
||||
|
||||
if (interface_exists(SimpleCacheInterface::class)) {
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface
|
||||
{
|
||||
}
|
||||
} else {
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface
|
||||
{
|
||||
}
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Exception;
|
||||
|
||||
use Psr\Cache\CacheException as Psr6CacheInterface;
|
||||
use Psr\SimpleCache\CacheException as SimpleCacheInterface;
|
||||
|
||||
if (interface_exists(SimpleCacheInterface::class)) {
|
||||
class LogicException extends \LogicException implements Psr6CacheInterface, SimpleCacheInterface
|
||||
{
|
||||
}
|
||||
} else {
|
||||
class LogicException extends \LogicException implements Psr6CacheInterface
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2016-2022 Fabien Potencier
|
||||
Copyright (c) 2016-2020 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,161 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
/**
|
||||
* LockRegistry is used internally by existing adapters to protect against cache stampede.
|
||||
*
|
||||
* It does so by wrapping the computation of items in a pool of locks.
|
||||
* Foreach each apps, there can be at most 20 concurrent processes that
|
||||
* compute items at the same time and only one per cache-key.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
final class LockRegistry
|
||||
{
|
||||
private static $openedFiles = [];
|
||||
private static $lockedFiles;
|
||||
private static $signalingException;
|
||||
private static $signalingCallback;
|
||||
|
||||
/**
|
||||
* The number of items in this list controls the max number of concurrent processes.
|
||||
*/
|
||||
private static $files = [
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AbstractAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AbstractTagAwareAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AdapterInterface.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ApcuAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ArrayAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ChainAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'DoctrineAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'FilesystemAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'FilesystemTagAwareAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'MemcachedAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'NullAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PdoAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpArrayAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpFilesAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ProxyAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'Psr16Adapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'RedisAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'RedisTagAwareAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'SimpleCacheAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapterInterface.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TraceableAdapter.php',
|
||||
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TraceableTagAwareAdapter.php',
|
||||
];
|
||||
|
||||
/**
|
||||
* Defines a set of existing files that will be used as keys to acquire locks.
|
||||
*
|
||||
* @return array The previously defined set of files
|
||||
*/
|
||||
public static function setFiles(array $files): array
|
||||
{
|
||||
$previousFiles = self::$files;
|
||||
self::$files = $files;
|
||||
|
||||
foreach (self::$openedFiles as $file) {
|
||||
if ($file) {
|
||||
flock($file, \LOCK_UN);
|
||||
fclose($file);
|
||||
}
|
||||
}
|
||||
self::$openedFiles = self::$lockedFiles = [];
|
||||
|
||||
return $previousFiles;
|
||||
}
|
||||
|
||||
public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata = null, LoggerInterface $logger = null)
|
||||
{
|
||||
if ('\\' === \DIRECTORY_SEPARATOR && null === self::$lockedFiles) {
|
||||
// disable locking on Windows by default
|
||||
self::$files = self::$lockedFiles = [];
|
||||
}
|
||||
|
||||
$key = self::$files ? abs(crc32($item->getKey())) % \count(self::$files) : -1;
|
||||
|
||||
if ($key < 0 || self::$lockedFiles || !$lock = self::open($key)) {
|
||||
return $callback($item, $save);
|
||||
}
|
||||
|
||||
self::$signalingException ?? self::$signalingException = unserialize("O:9:\"Exception\":1:{s:16:\"\0Exception\0trace\";a:0:{}}");
|
||||
self::$signalingCallback ?? self::$signalingCallback = function () { throw self::$signalingException; };
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
// race to get the lock in non-blocking mode
|
||||
$locked = flock($lock, \LOCK_EX | \LOCK_NB, $wouldBlock);
|
||||
|
||||
if ($locked || !$wouldBlock) {
|
||||
$logger && $logger->info(sprintf('Lock %s, now computing item "{key}"', $locked ? 'acquired' : 'not supported'), ['key' => $item->getKey()]);
|
||||
self::$lockedFiles[$key] = true;
|
||||
|
||||
$value = $callback($item, $save);
|
||||
|
||||
if ($save) {
|
||||
if ($setMetadata) {
|
||||
$setMetadata($item);
|
||||
}
|
||||
|
||||
$pool->save($item->set($value));
|
||||
$save = false;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
// if we failed the race, retry locking in blocking mode to wait for the winner
|
||||
$logger && $logger->info('Item "{key}" is locked, waiting for it to be released', ['key' => $item->getKey()]);
|
||||
flock($lock, \LOCK_SH);
|
||||
} finally {
|
||||
flock($lock, \LOCK_UN);
|
||||
unset(self::$lockedFiles[$key]);
|
||||
}
|
||||
|
||||
try {
|
||||
$value = $pool->get($item->getKey(), self::$signalingCallback, 0);
|
||||
$logger && $logger->info('Item "{key}" retrieved after lock was released', ['key' => $item->getKey()]);
|
||||
$save = false;
|
||||
|
||||
return $value;
|
||||
} catch (\Exception $e) {
|
||||
if (self::$signalingException !== $e) {
|
||||
throw $e;
|
||||
}
|
||||
$logger && $logger->info('Item "{key}" not found while lock was released, now retrying', ['key' => $item->getKey()]);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function open(int $key)
|
||||
{
|
||||
if (null !== $h = self::$openedFiles[$key] ?? null) {
|
||||
return $h;
|
||||
}
|
||||
set_error_handler(function () {});
|
||||
try {
|
||||
$h = fopen(self::$files[$key], 'r+');
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
return self::$openedFiles[$key] = $h ?: @fopen(self::$files[$key], 'r');
|
||||
}
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Marshaller;
|
||||
|
||||
use Symfony\Component\Cache\Exception\CacheException;
|
||||
|
||||
/**
|
||||
* Serializes/unserializes values using igbinary_serialize() if available, serialize() otherwise.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class DefaultMarshaller implements MarshallerInterface
|
||||
{
|
||||
private $useIgbinarySerialize = true;
|
||||
|
||||
public function __construct(bool $useIgbinarySerialize = null)
|
||||
{
|
||||
if (null === $useIgbinarySerialize) {
|
||||
$useIgbinarySerialize = \extension_loaded('igbinary') && (\PHP_VERSION_ID < 70400 || version_compare('3.1.6', phpversion('igbinary'), '<='));
|
||||
} elseif ($useIgbinarySerialize && (!\extension_loaded('igbinary') || (\PHP_VERSION_ID >= 70400 && version_compare('3.1.6', phpversion('igbinary'), '>')))) {
|
||||
throw new CacheException(\extension_loaded('igbinary') && \PHP_VERSION_ID >= 70400 ? 'Please upgrade the "igbinary" PHP extension to v3.1.6 or higher.' : 'The "igbinary" PHP extension is not loaded.');
|
||||
}
|
||||
$this->useIgbinarySerialize = $useIgbinarySerialize;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function marshall(array $values, ?array &$failed): array
|
||||
{
|
||||
$serialized = $failed = [];
|
||||
|
||||
foreach ($values as $id => $value) {
|
||||
try {
|
||||
if ($this->useIgbinarySerialize) {
|
||||
$serialized[$id] = igbinary_serialize($value);
|
||||
} else {
|
||||
$serialized[$id] = serialize($value);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$failed[] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
return $serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unmarshall(string $value)
|
||||
{
|
||||
if ('b:0;' === $value) {
|
||||
return false;
|
||||
}
|
||||
if ('N;' === $value) {
|
||||
return null;
|
||||
}
|
||||
static $igbinaryNull;
|
||||
if ($value === ($igbinaryNull ?? $igbinaryNull = \extension_loaded('igbinary') ? igbinary_serialize(null) : false)) {
|
||||
return null;
|
||||
}
|
||||
$unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
|
||||
try {
|
||||
if (':' === ($value[1] ?? ':')) {
|
||||
if (false !== $value = unserialize($value)) {
|
||||
return $value;
|
||||
}
|
||||
} elseif (false === $igbinaryNull) {
|
||||
throw new \RuntimeException('Failed to unserialize values, did you forget to install the "igbinary" extension?');
|
||||
} elseif (null !== $value = igbinary_unserialize($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
throw new \DomainException(error_get_last() ? error_get_last()['message'] : 'Failed to unserialize values.');
|
||||
} catch (\Error $e) {
|
||||
throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
|
||||
} finally {
|
||||
ini_set('unserialize_callback_func', $unserializeCallbackHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function handleUnserializeCallback($class)
|
||||
{
|
||||
throw new \DomainException('Class not found: '.$class);
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Marshaller;
|
||||
|
||||
use Symfony\Component\Cache\Exception\CacheException;
|
||||
|
||||
/**
|
||||
* Compresses values using gzdeflate().
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class DeflateMarshaller implements MarshallerInterface
|
||||
{
|
||||
private $marshaller;
|
||||
|
||||
public function __construct(MarshallerInterface $marshaller)
|
||||
{
|
||||
if (!\function_exists('gzdeflate')) {
|
||||
throw new CacheException('The "zlib" PHP extension is not loaded.');
|
||||
}
|
||||
|
||||
$this->marshaller = $marshaller;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function marshall(array $values, ?array &$failed): array
|
||||
{
|
||||
return array_map('gzdeflate', $this->marshaller->marshall($values, $failed));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unmarshall(string $value)
|
||||
{
|
||||
if (false !== $inflatedValue = @gzinflate($value)) {
|
||||
$value = $inflatedValue;
|
||||
}
|
||||
|
||||
return $this->marshaller->unmarshall($value);
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Marshaller;
|
||||
|
||||
/**
|
||||
* Serializes/unserializes PHP values.
|
||||
*
|
||||
* Implementations of this interface MUST deal with errors carefully. They MUST
|
||||
* also deal with forward and backward compatibility at the storage format level.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
interface MarshallerInterface
|
||||
{
|
||||
/**
|
||||
* Serializes a list of values.
|
||||
*
|
||||
* When serialization fails for a specific value, no exception should be
|
||||
* thrown. Instead, its key should be listed in $failed.
|
||||
*/
|
||||
public function marshall(array $values, ?array &$failed): array;
|
||||
|
||||
/**
|
||||
* Unserializes a single value and throws an exception if anything goes wrong.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Exception Whenever unserialization fails
|
||||
*/
|
||||
public function unmarshall(string $value);
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Marshaller;
|
||||
|
||||
/**
|
||||
* A marshaller optimized for data structures generated by AbstractTagAwareAdapter.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class TagAwareMarshaller implements MarshallerInterface
|
||||
{
|
||||
private $marshaller;
|
||||
|
||||
public function __construct(MarshallerInterface $marshaller = null)
|
||||
{
|
||||
$this->marshaller = $marshaller ?? new DefaultMarshaller();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function marshall(array $values, ?array &$failed): array
|
||||
{
|
||||
$failed = $notSerialized = $serialized = [];
|
||||
|
||||
foreach ($values as $id => $value) {
|
||||
if (\is_array($value) && \is_array($value['tags'] ?? null) && \array_key_exists('value', $value) && \count($value) === 2 + (\is_string($value['meta'] ?? null) && 8 === \strlen($value['meta']))) {
|
||||
// if the value is an array with keys "tags", "value" and "meta", use a compact serialization format
|
||||
// magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F allow detecting this format quickly in unmarshall()
|
||||
|
||||
$v = $this->marshaller->marshall($value, $f);
|
||||
|
||||
if ($f) {
|
||||
$f = [];
|
||||
$failed[] = $id;
|
||||
} else {
|
||||
if ([] === $value['tags']) {
|
||||
$v['tags'] = '';
|
||||
}
|
||||
|
||||
$serialized[$id] = "\x9D".($value['meta'] ?? "\0\0\0\0\0\0\0\0").pack('N', \strlen($v['tags'])).$v['tags'].$v['value'];
|
||||
$serialized[$id][9] = "\x5F";
|
||||
}
|
||||
} else {
|
||||
// other arbitratry values are serialized using the decorated marshaller below
|
||||
$notSerialized[$id] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($notSerialized) {
|
||||
$serialized += $this->marshaller->marshall($notSerialized, $f);
|
||||
$failed = array_merge($failed, $f);
|
||||
}
|
||||
|
||||
return $serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unmarshall(string $value)
|
||||
{
|
||||
// detect the compact format used in marshall() using magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
|
||||
if (13 >= \strlen($value) || "\x9D" !== $value[0] || "\0" !== $value[5] || "\x5F" !== $value[9]) {
|
||||
return $this->marshaller->unmarshall($value);
|
||||
}
|
||||
|
||||
// data consists of value, tags and metadata which we need to unpack
|
||||
$meta = substr($value, 1, 12);
|
||||
$meta[8] = "\0";
|
||||
$tagLen = unpack('Nlen', $meta, 8)['len'];
|
||||
$meta = substr($meta, 0, 8);
|
||||
|
||||
return [
|
||||
'value' => $this->marshaller->unmarshall(substr($value, 13 + $tagLen)),
|
||||
'tags' => $tagLen ? $this->marshaller->unmarshall(substr($value, 13, $tagLen)) : [],
|
||||
'meta' => "\0\0\0\0\0\0\0\0" === $meta ? null : $meta,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,284 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache;
|
||||
|
||||
use Psr\Cache\CacheException as Psr6CacheException;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Psr\SimpleCache\CacheException as SimpleCacheException;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\AdapterInterface;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
|
||||
if (null !== (new \ReflectionMethod(CacheInterface::class, 'get'))->getReturnType()) {
|
||||
throw new \LogicException('psr/simple-cache 3.0+ is not compatible with this version of symfony/cache. Please upgrade symfony/cache to 6.0+ or downgrade psr/simple-cache to 1.x or 2.x.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a PSR-6 cache into a PSR-16 one.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class Psr16Cache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use ProxyTrait;
|
||||
|
||||
private const METADATA_EXPIRY_OFFSET = 1527506807;
|
||||
|
||||
private $createCacheItem;
|
||||
private $cacheItemPrototype;
|
||||
|
||||
public function __construct(CacheItemPoolInterface $pool)
|
||||
{
|
||||
$this->pool = $pool;
|
||||
|
||||
if (!$pool instanceof AdapterInterface) {
|
||||
return;
|
||||
}
|
||||
$cacheItemPrototype = &$this->cacheItemPrototype;
|
||||
$createCacheItem = \Closure::bind(
|
||||
static function ($key, $value, $allowInt = false) use (&$cacheItemPrototype) {
|
||||
$item = clone $cacheItemPrototype;
|
||||
$item->poolHash = $item->innerItem = null;
|
||||
$item->key = $allowInt && \is_int($key) ? (string) $key : CacheItem::validateKey($key);
|
||||
$item->value = $value;
|
||||
$item->isHit = false;
|
||||
|
||||
return $item;
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
$this->createCacheItem = function ($key, $value, $allowInt = false) use ($createCacheItem) {
|
||||
if (null === $this->cacheItemPrototype) {
|
||||
$this->get($allowInt && \is_int($key) ? (string) $key : $key);
|
||||
}
|
||||
$this->createCacheItem = $createCacheItem;
|
||||
|
||||
return $createCacheItem($key, null, $allowInt)->set($value);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
try {
|
||||
$item = $this->pool->getItem($key);
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
if (null === $this->cacheItemPrototype) {
|
||||
$this->cacheItemPrototype = clone $item;
|
||||
$this->cacheItemPrototype->set(null);
|
||||
}
|
||||
|
||||
return $item->isHit() ? $item->get() : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
try {
|
||||
if (null !== $f = $this->createCacheItem) {
|
||||
$item = $f($key, $value);
|
||||
} else {
|
||||
$item = $this->pool->getItem($key)->set($value);
|
||||
}
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
if (null !== $ttl) {
|
||||
$item->expiresAfter($ttl);
|
||||
}
|
||||
|
||||
return $this->pool->save($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
try {
|
||||
return $this->pool->deleteItem($key);
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return $this->pool->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return iterable
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
if ($keys instanceof \Traversable) {
|
||||
$keys = iterator_to_array($keys, false);
|
||||
} elseif (!\is_array($keys)) {
|
||||
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
|
||||
}
|
||||
|
||||
try {
|
||||
$items = $this->pool->getItems($keys);
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
$values = [];
|
||||
|
||||
if (!$this->pool instanceof AdapterInterface) {
|
||||
foreach ($items as $key => $item) {
|
||||
$values[$key] = $item->isHit() ? $item->get() : $default;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
foreach ($items as $key => $item) {
|
||||
if (!$item->isHit()) {
|
||||
$values[$key] = $default;
|
||||
continue;
|
||||
}
|
||||
$values[$key] = $item->get();
|
||||
|
||||
if (!$metadata = $item->getMetadata()) {
|
||||
continue;
|
||||
}
|
||||
unset($metadata[CacheItem::METADATA_TAGS]);
|
||||
|
||||
if ($metadata) {
|
||||
$values[$key] = ["\x9D".pack('VN', (int) (0.1 + $metadata[CacheItem::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[CacheItem::METADATA_CTIME])."\x5F" => $values[$key]];
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
$valuesIsArray = \is_array($values);
|
||||
if (!$valuesIsArray && !$values instanceof \Traversable) {
|
||||
throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', \is_object($values) ? \get_class($values) : \gettype($values)));
|
||||
}
|
||||
$items = [];
|
||||
|
||||
try {
|
||||
if (null !== $f = $this->createCacheItem) {
|
||||
$valuesIsArray = false;
|
||||
foreach ($values as $key => $value) {
|
||||
$items[$key] = $f($key, $value, true);
|
||||
}
|
||||
} elseif ($valuesIsArray) {
|
||||
$items = [];
|
||||
foreach ($values as $key => $value) {
|
||||
$items[] = (string) $key;
|
||||
}
|
||||
$items = $this->pool->getItems($items);
|
||||
} else {
|
||||
foreach ($values as $key => $value) {
|
||||
if (\is_int($key)) {
|
||||
$key = (string) $key;
|
||||
}
|
||||
$items[$key] = $this->pool->getItem($key)->set($value);
|
||||
}
|
||||
}
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
$ok = true;
|
||||
|
||||
foreach ($items as $key => $item) {
|
||||
if ($valuesIsArray) {
|
||||
$item->set($values[$key]);
|
||||
}
|
||||
if (null !== $ttl) {
|
||||
$item->expiresAfter($ttl);
|
||||
}
|
||||
$ok = $this->pool->saveDeferred($item) && $ok;
|
||||
}
|
||||
|
||||
return $this->pool->commit() && $ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
if ($keys instanceof \Traversable) {
|
||||
$keys = iterator_to_array($keys, false);
|
||||
} elseif (!\is_array($keys)) {
|
||||
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->pool->deleteItems($keys);
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
try {
|
||||
return $this->pool->hasItem($key);
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,12 @@
|
|||
Symfony PSR-6 implementation for caching
|
||||
========================================
|
||||
|
||||
The Cache component provides extended
|
||||
[PSR-6](https://www.php-fig.org/psr/psr-6/) implementations for adding cache to
|
||||
your applications. It is designed to have a low overhead so that caching is
|
||||
fastest. It ships with adapters for the most widespread caching backends.
|
||||
It also provides a [PSR-16](https://www.php-fig.org/psr/psr-16/) adapter,
|
||||
and implementations for [symfony/cache-contracts](https://github.com/symfony/cache-contracts)'
|
||||
`CacheInterface` and `TagAwareCacheInterface`.
|
||||
This component provides an extended [PSR-6](http://www.php-fig.org/psr/psr-6/)
|
||||
implementation for adding cache to your applications. It is designed to have a
|
||||
low overhead so that caching is fastest. It ships with a few caching adapters
|
||||
for the most widespread and suited to caching backends. It also provides a
|
||||
`doctrine/cache` proxy adapter to cover more advanced caching needs and a proxy
|
||||
adapter for greater interoperability between PSR-6 implementations.
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
|
|
@ -11,11 +11,10 @@
|
|||
|
||||
namespace Symfony\Component\Cache;
|
||||
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
|
||||
/**
|
||||
* Resets a pool's local state.
|
||||
*/
|
||||
interface ResettableInterface extends ResetInterface
|
||||
interface ResettableInterface
|
||||
{
|
||||
public function reset();
|
||||
}
|
||||
|
|
|
@ -12,37 +12,37 @@
|
|||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\AbstractTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', AbstractCache::class, AbstractAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use AbstractAdapter and type-hint for CacheInterface instead.
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterface, ResettableInterface
|
||||
abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const NS_SEPARATOR = ':';
|
||||
|
||||
use AbstractTrait {
|
||||
deleteItems as private;
|
||||
AbstractTrait::deleteItem as delete;
|
||||
AbstractTrait::hasItem as has;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected const NS_SEPARATOR = ':';
|
||||
|
||||
private $defaultLifetime;
|
||||
|
||||
protected function __construct(string $namespace = '', int $defaultLifetime = 0)
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
protected function __construct($namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->defaultLifetime = max(0, $defaultLifetime);
|
||||
$this->defaultLifetime = max(0, (int) $defaultLifetime);
|
||||
$this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':';
|
||||
if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) {
|
||||
throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace));
|
||||
|
@ -61,7 +61,7 @@ abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterfac
|
|||
return $value;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to fetch key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
}
|
||||
|
||||
return $default;
|
||||
|
@ -69,8 +69,6 @@ abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterfac
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
|
@ -81,8 +79,6 @@ abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterfac
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return iterable
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
|
@ -99,7 +95,7 @@ abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterfac
|
|||
try {
|
||||
$values = $this->doFetch($ids);
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch values: '.$e->getMessage(), ['keys' => $keys, 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to fetch requested values', ['keys' => $keys, 'exception' => $e]);
|
||||
$values = [];
|
||||
}
|
||||
$ids = array_combine($ids, $keys);
|
||||
|
@ -109,8 +105,6 @@ abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterfac
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
|
@ -140,16 +134,13 @@ abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterfac
|
|||
foreach (\is_array($e) ? $e : array_keys($valuesById) as $id) {
|
||||
$keys[] = substr($id, \strlen($this->namespace));
|
||||
}
|
||||
$message = 'Failed to save values'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
CacheItem::log($this->logger, 'Failed to save values', ['keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
|
@ -177,19 +168,19 @@ abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterfac
|
|||
throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', \is_object($ttl) ? \get_class($ttl) : \gettype($ttl)));
|
||||
}
|
||||
|
||||
private function generateValues(iterable $values, array &$keys, $default): iterable
|
||||
private function generateValues($values, &$keys, $default)
|
||||
{
|
||||
try {
|
||||
foreach ($values as $id => $value) {
|
||||
if (!isset($keys[$id])) {
|
||||
throw new InvalidArgumentException(sprintf('Could not match value id "%s" to keys "%s".', $id, implode('", "', $keys)));
|
||||
$id = key($keys);
|
||||
}
|
||||
$key = $keys[$id];
|
||||
unset($keys[$id]);
|
||||
yield $key => $value;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch values: '.$e->getMessage(), ['keys' => array_values($keys), 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to fetch requested values', ['keys' => array_values($keys), 'exception' => $e]);
|
||||
}
|
||||
|
||||
foreach ($keys as $key) {
|
||||
|
|
|
@ -11,20 +11,18 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\ApcuAdapter;
|
||||
use Symfony\Component\Cache\Traits\ApcuTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ApcuCache::class, ApcuAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use ApcuAdapter and type-hint for CacheInterface instead.
|
||||
*/
|
||||
class ApcuCache extends AbstractCache
|
||||
{
|
||||
use ApcuTrait;
|
||||
|
||||
public function __construct(string $namespace = '', int $defaultLifetime = 0, string $version = null)
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $version
|
||||
*/
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $version = null)
|
||||
{
|
||||
$this->init($namespace, $defaultLifetime, $version);
|
||||
}
|
||||
|
|
|
@ -12,20 +12,16 @@
|
|||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ArrayTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ArrayCache::class, ArrayAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use ArrayAdapter and type-hint for CacheInterface instead.
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ArrayCache implements Psr16CacheInterface, LoggerAwareInterface, ResettableInterface
|
||||
class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
use ArrayTrait {
|
||||
ArrayTrait::deleteItem as delete;
|
||||
|
@ -35,11 +31,12 @@ class ArrayCache implements Psr16CacheInterface, LoggerAwareInterface, Resettabl
|
|||
private $defaultLifetime;
|
||||
|
||||
/**
|
||||
* @param int $defaultLifetime
|
||||
* @param bool $storeSerialized Disabling serialization can lead to cache corruptions when storing mutable values but increases performance otherwise
|
||||
*/
|
||||
public function __construct(int $defaultLifetime = 0, bool $storeSerialized = true)
|
||||
public function __construct($defaultLifetime = 0, $storeSerialized = true)
|
||||
{
|
||||
$this->defaultLifetime = $defaultLifetime;
|
||||
$this->defaultLifetime = (int) $defaultLifetime;
|
||||
$this->storeSerialized = $storeSerialized;
|
||||
}
|
||||
|
||||
|
@ -48,26 +45,13 @@ class ArrayCache implements Psr16CacheInterface, LoggerAwareInterface, Resettabl
|
|||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if (!\is_string($key) || !isset($this->expiries[$key])) {
|
||||
CacheItem::validateKey($key);
|
||||
foreach ($this->getMultiple([$key], $default) as $v) {
|
||||
return $v;
|
||||
}
|
||||
if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] > microtime(true) || !$this->delete($key))) {
|
||||
$this->values[$key] = null;
|
||||
|
||||
return $default;
|
||||
}
|
||||
if (!$this->storeSerialized) {
|
||||
return $this->values[$key];
|
||||
}
|
||||
$value = $this->unfreeze($key, $isHit);
|
||||
|
||||
return $isHit ? $value : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return iterable
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
|
@ -77,18 +61,14 @@ class ArrayCache implements Psr16CacheInterface, LoggerAwareInterface, Resettabl
|
|||
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
|
||||
}
|
||||
foreach ($keys as $key) {
|
||||
if (!\is_string($key) || !isset($this->expiries[$key])) {
|
||||
CacheItem::validateKey($key);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->generateItems($keys, microtime(true), function ($k, $v, $hit) use ($default) { return $hit ? $v : $default; });
|
||||
return $this->generateItems($keys, time(), function ($k, $v, $hit) use ($default) { return $hit ? $v : $default; });
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
|
@ -104,22 +84,16 @@ class ArrayCache implements Psr16CacheInterface, LoggerAwareInterface, Resettabl
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
if (!\is_string($key)) {
|
||||
CacheItem::validateKey($key);
|
||||
}
|
||||
|
||||
return $this->setMultiple([$key => $value], $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
|
@ -129,20 +103,27 @@ class ArrayCache implements Psr16CacheInterface, LoggerAwareInterface, Resettabl
|
|||
$valuesArray = [];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
if (!\is_int($key) && !(\is_string($key) && isset($this->expiries[$key]))) {
|
||||
CacheItem::validateKey($key);
|
||||
}
|
||||
\is_int($key) || CacheItem::validateKey($key);
|
||||
$valuesArray[$key] = $value;
|
||||
}
|
||||
if (false === $ttl = $this->normalizeTtl($ttl)) {
|
||||
return $this->deleteMultiple(array_keys($valuesArray));
|
||||
}
|
||||
$expiry = 0 < $ttl ? microtime(true) + $ttl : \PHP_INT_MAX;
|
||||
|
||||
if ($this->storeSerialized) {
|
||||
foreach ($valuesArray as $key => $value) {
|
||||
if ($this->storeSerialized && null === $value = $this->freeze($value, $key)) {
|
||||
try {
|
||||
$valuesArray[$key] = serialize($value);
|
||||
} catch (\Exception $e) {
|
||||
$type = \is_object($value) ? \get_class($value) : \gettype($value);
|
||||
CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => $key, 'type' => $type, 'exception' => $e]);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
$expiry = 0 < $ttl ? time() + $ttl : \PHP_INT_MAX;
|
||||
|
||||
foreach ($valuesArray as $key => $value) {
|
||||
$this->values[$key] = $value;
|
||||
$this->expiries[$key] = $expiry;
|
||||
}
|
||||
|
|
|
@ -11,15 +11,10 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\ChainAdapter;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ChainCache::class, ChainAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Chains several caches together.
|
||||
|
@ -27,9 +22,9 @@ use Symfony\Contracts\Service\ResetInterface;
|
|||
* Cached items are fetched from the first cache having them in its data store.
|
||||
* They are saved and deleted in all caches at once.
|
||||
*
|
||||
* @deprecated since Symfony 4.3, use ChainAdapter and type-hint for CacheInterface instead.
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
|
||||
class ChainCache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $miss;
|
||||
private $caches = [];
|
||||
|
@ -37,25 +32,25 @@ class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableI
|
|||
private $cacheCount;
|
||||
|
||||
/**
|
||||
* @param Psr16CacheInterface[] $caches The ordered list of caches used to fetch cached items
|
||||
* @param CacheInterface[] $caches The ordered list of caches used to fetch cached items
|
||||
* @param int $defaultLifetime The lifetime of items propagated from lower caches to upper ones
|
||||
*/
|
||||
public function __construct(array $caches, int $defaultLifetime = 0)
|
||||
public function __construct(array $caches, $defaultLifetime = 0)
|
||||
{
|
||||
if (!$caches) {
|
||||
throw new InvalidArgumentException('At least one cache must be specified.');
|
||||
}
|
||||
|
||||
foreach ($caches as $cache) {
|
||||
if (!$cache instanceof Psr16CacheInterface) {
|
||||
throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), Psr16CacheInterface::class));
|
||||
if (!$cache instanceof CacheInterface) {
|
||||
throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), CacheInterface::class));
|
||||
}
|
||||
}
|
||||
|
||||
$this->miss = new \stdClass();
|
||||
$this->caches = array_values($caches);
|
||||
$this->cacheCount = \count($this->caches);
|
||||
$this->defaultLifetime = 0 < $defaultLifetime ? $defaultLifetime : null;
|
||||
$this->defaultLifetime = 0 < $defaultLifetime ? (int) $defaultLifetime : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,8 +77,6 @@ class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableI
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return iterable
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
|
@ -92,11 +85,11 @@ class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableI
|
|||
return $this->generateItems($this->caches[0]->getMultiple($keys, $miss), 0, $miss, $default);
|
||||
}
|
||||
|
||||
private function generateItems(iterable $values, int $cacheIndex, $miss, $default): iterable
|
||||
private function generateItems($values, $cacheIndex, $miss, $default)
|
||||
{
|
||||
$missing = [];
|
||||
$nextCacheIndex = $cacheIndex + 1;
|
||||
$nextCache = $this->caches[$nextCacheIndex] ?? null;
|
||||
$nextCache = isset($this->caches[$nextCacheIndex]) ? $this->caches[$nextCacheIndex] : null;
|
||||
|
||||
foreach ($values as $k => $value) {
|
||||
if ($miss !== $value) {
|
||||
|
@ -125,8 +118,6 @@ class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableI
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
|
@ -141,8 +132,6 @@ class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableI
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
|
@ -158,8 +147,6 @@ class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableI
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
|
@ -175,8 +162,6 @@ class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableI
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
|
@ -195,8 +180,6 @@ class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableI
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
|
@ -212,8 +195,6 @@ class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableI
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
|
@ -263,7 +244,7 @@ class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableI
|
|||
public function reset()
|
||||
{
|
||||
foreach ($this->caches as $cache) {
|
||||
if ($cache instanceof ResetInterface) {
|
||||
if ($cache instanceof ResettableInterface) {
|
||||
$cache->reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,20 +12,17 @@
|
|||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
use Symfony\Component\Cache\Adapter\DoctrineAdapter;
|
||||
use Symfony\Component\Cache\Traits\DoctrineTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', DoctrineCache::class, DoctrineAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use DoctrineAdapter and type-hint for CacheInterface instead.
|
||||
*/
|
||||
class DoctrineCache extends AbstractCache
|
||||
{
|
||||
use DoctrineTrait;
|
||||
|
||||
public function __construct(CacheProvider $provider, string $namespace = '', int $defaultLifetime = 0)
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
public function __construct(CacheProvider $provider, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->provider = $provider;
|
||||
|
|
|
@ -11,25 +11,20 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
|
||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\FilesystemTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', FilesystemCache::class, FilesystemAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use FilesystemAdapter and type-hint for CacheInterface instead.
|
||||
*/
|
||||
class FilesystemCache extends AbstractCache implements PruneableInterface
|
||||
{
|
||||
use FilesystemTrait;
|
||||
|
||||
public function __construct(string $namespace = '', int $defaultLifetime = 0, string $directory = null, MarshallerInterface $marshaller = null)
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $directory
|
||||
*/
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $directory = null)
|
||||
{
|
||||
$this->marshaller = $marshaller ?? new DefaultMarshaller();
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->init($namespace, $directory);
|
||||
}
|
||||
|
|
|
@ -11,24 +11,20 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
|
||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||
use Symfony\Component\Cache\Traits\MemcachedTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', MemcachedCache::class, MemcachedAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use MemcachedAdapter and type-hint for CacheInterface instead.
|
||||
*/
|
||||
class MemcachedCache extends AbstractCache
|
||||
{
|
||||
use MemcachedTrait;
|
||||
|
||||
protected $maxIdLength = 250;
|
||||
|
||||
public function __construct(\Memcached $client, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
public function __construct(\Memcached $client, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->init($client, $namespace, $defaultLifetime, $marshaller);
|
||||
$this->init($client, $namespace, $defaultLifetime);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,16 +11,12 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\NullAdapter;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', NullCache::class, NullAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use NullAdapter and type-hint for CacheInterface instead.
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class NullCache implements Psr16CacheInterface
|
||||
class NullCache implements CacheInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -32,8 +28,6 @@ class NullCache implements Psr16CacheInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return iterable
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
|
@ -44,8 +38,6 @@ class NullCache implements Psr16CacheInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
|
@ -54,8 +46,6 @@ class NullCache implements Psr16CacheInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
|
@ -64,8 +54,6 @@ class NullCache implements Psr16CacheInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
|
@ -74,8 +62,6 @@ class NullCache implements Psr16CacheInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
|
@ -84,8 +70,6 @@ class NullCache implements Psr16CacheInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
|
@ -94,8 +78,6 @@ class NullCache implements Psr16CacheInterface
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
|
|
|
@ -11,17 +11,9 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\PdoAdapter;
|
||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\PdoTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PdoCache::class, PdoAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use PdoAdapter and type-hint for CacheInterface instead.
|
||||
*/
|
||||
class PdoCache extends AbstractCache implements PruneableInterface
|
||||
{
|
||||
use PdoTrait;
|
||||
|
@ -33,9 +25,6 @@ class PdoCache extends AbstractCache implements PruneableInterface
|
|||
* a Doctrine DBAL Connection or a DSN string that will be used to
|
||||
* lazy-connect to the database when the cache is actually used.
|
||||
*
|
||||
* When a Doctrine DBAL Connection is passed, the cache table is created
|
||||
* automatically when possible. Otherwise, use the createTable() method.
|
||||
*
|
||||
* List of available options:
|
||||
* * db_table: The name of the table [default: cache_items]
|
||||
* * db_id_col: The column where to store the cache id [default: item_id]
|
||||
|
@ -46,14 +35,17 @@ class PdoCache extends AbstractCache implements PruneableInterface
|
|||
* * db_password: The password when lazy-connect [default: '']
|
||||
* * db_connection_options: An array of driver-specific connection options [default: []]
|
||||
*
|
||||
* @param \PDO|Connection|string $connOrDsn a \PDO or Connection instance or DSN string or null
|
||||
* @param \PDO|Connection|string $connOrDsn A \PDO or Connection instance or DSN string or null
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param array $options An associative array of options
|
||||
*
|
||||
* @throws InvalidArgumentException When first argument is not PDO nor Connection nor string
|
||||
* @throws InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION
|
||||
* @throws InvalidArgumentException When namespace contains invalid characters
|
||||
*/
|
||||
public function __construct($connOrDsn, string $namespace = '', int $defaultLifetime = 0, array $options = [], MarshallerInterface $marshaller = null)
|
||||
public function __construct($connOrDsn, $namespace = '', $defaultLifetime = 0, array $options = [])
|
||||
{
|
||||
$this->init($connOrDsn, $namespace, $defaultLifetime, $options, $marshaller);
|
||||
$this->init($connOrDsn, $namespace, $defaultLifetime, $options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,46 +11,53 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\PhpArrayTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PhpArrayCache::class, PhpArrayAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use PhpArrayAdapter and type-hint for CacheInterface instead.
|
||||
* Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0.
|
||||
* Warmed up items are read-only and run-time discovered items are cached using a fallback adapter.
|
||||
*
|
||||
* @author Titouan Galopin <galopintitouan@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
|
||||
class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use PhpArrayTrait;
|
||||
|
||||
/**
|
||||
* @param string $file The PHP file were values are cached
|
||||
* @param Psr16CacheInterface $fallbackPool A pool to fallback on when an item is not hit
|
||||
* @param CacheInterface $fallbackPool A pool to fallback on when an item is not hit
|
||||
*/
|
||||
public function __construct(string $file, Psr16CacheInterface $fallbackPool)
|
||||
public function __construct($file, CacheInterface $fallbackPool)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->pool = $fallbackPool;
|
||||
$this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* This adapter takes advantage of how PHP stores arrays in its latest versions.
|
||||
* This adapter should only be used on PHP 7.0+ to take advantage of how PHP
|
||||
* stores arrays in its latest versions. This factory method decorates the given
|
||||
* fallback pool with this adapter only if the current PHP version is supported.
|
||||
*
|
||||
* @param string $file The PHP file were values are cached
|
||||
* @param CacheInterface $fallbackPool A pool to fallback on when an item is not hit
|
||||
*
|
||||
* @return Psr16CacheInterface
|
||||
* @return CacheInterface
|
||||
*/
|
||||
public static function create($file, Psr16CacheInterface $fallbackPool)
|
||||
public static function create($file, CacheInterface $fallbackPool)
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
return new static($file, $fallbackPool);
|
||||
}
|
||||
|
||||
return $fallbackPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -62,18 +69,22 @@ class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, Resettab
|
|||
if (null === $this->values) {
|
||||
$this->initialize();
|
||||
}
|
||||
if (!isset($this->keys[$key])) {
|
||||
if (!isset($this->values[$key])) {
|
||||
return $this->pool->get($key, $default);
|
||||
}
|
||||
$value = $this->values[$this->keys[$key]];
|
||||
|
||||
$value = $this->values[$key];
|
||||
|
||||
if ('N;' === $value) {
|
||||
return null;
|
||||
}
|
||||
if ($value instanceof \Closure) {
|
||||
$value = null;
|
||||
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||
try {
|
||||
return $value();
|
||||
} catch (\Throwable $e) {
|
||||
$e = null;
|
||||
$value = unserialize($value);
|
||||
} catch (\Error $e) {
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
if (null !== $e) {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
@ -83,8 +94,6 @@ class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, Resettab
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return iterable
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
|
@ -107,8 +116,6 @@ class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, Resettab
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
|
@ -119,13 +126,11 @@ class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, Resettab
|
|||
$this->initialize();
|
||||
}
|
||||
|
||||
return isset($this->keys[$key]) || $this->pool->has($key);
|
||||
return isset($this->values[$key]) || $this->pool->has($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
|
@ -136,13 +141,11 @@ class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, Resettab
|
|||
$this->initialize();
|
||||
}
|
||||
|
||||
return !isset($this->keys[$key]) && $this->pool->delete($key);
|
||||
return !isset($this->values[$key]) && $this->pool->delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
|
@ -158,7 +161,7 @@ class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, Resettab
|
|||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
|
||||
}
|
||||
|
||||
if (isset($this->keys[$key])) {
|
||||
if (isset($this->values[$key])) {
|
||||
$deleted = false;
|
||||
} else {
|
||||
$fallbackKeys[] = $key;
|
||||
|
@ -177,8 +180,6 @@ class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, Resettab
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
|
@ -189,13 +190,11 @@ class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, Resettab
|
|||
$this->initialize();
|
||||
}
|
||||
|
||||
return !isset($this->keys[$key]) && $this->pool->set($key, $value, $ttl);
|
||||
return !isset($this->values[$key]) && $this->pool->set($key, $value, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
|
@ -211,7 +210,7 @@ class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, Resettab
|
|||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
|
||||
}
|
||||
|
||||
if (isset($this->keys[$key])) {
|
||||
if (isset($this->values[$key])) {
|
||||
$saved = false;
|
||||
} else {
|
||||
$fallbackValues[$key] = $value;
|
||||
|
@ -225,20 +224,22 @@ class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, Resettab
|
|||
return $saved;
|
||||
}
|
||||
|
||||
private function generateItems(array $keys, $default): iterable
|
||||
private function generateItems(array $keys, $default)
|
||||
{
|
||||
$fallbackKeys = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (isset($this->keys[$key])) {
|
||||
$value = $this->values[$this->keys[$key]];
|
||||
if (isset($this->values[$key])) {
|
||||
$value = $this->values[$key];
|
||||
|
||||
if ('N;' === $value) {
|
||||
yield $key => null;
|
||||
} elseif ($value instanceof \Closure) {
|
||||
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||
try {
|
||||
yield $key => $value();
|
||||
} catch (\Throwable $e) {
|
||||
yield $key => unserialize($value);
|
||||
} catch (\Error $e) {
|
||||
yield $key => $default;
|
||||
} catch (\Exception $e) {
|
||||
yield $key => $default;
|
||||
}
|
||||
} else {
|
||||
|
@ -250,7 +251,9 @@ class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, Resettab
|
|||
}
|
||||
|
||||
if ($fallbackKeys) {
|
||||
yield from $this->pool->getMultiple($fallbackKeys, $default);
|
||||
foreach ($this->pool->getMultiple($fallbackKeys, $default) as $key => $item) {
|
||||
yield $key => $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,35 +11,31 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
|
||||
use Symfony\Component\Cache\Exception\CacheException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\PhpFilesTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PhpFilesCache::class, PhpFilesAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use PhpFilesAdapter and type-hint for CacheInterface instead.
|
||||
*/
|
||||
class PhpFilesCache extends AbstractCache implements PruneableInterface
|
||||
{
|
||||
use PhpFilesTrait;
|
||||
|
||||
/**
|
||||
* @param $appendOnly Set to `true` to gain extra performance when the items stored in this pool never expire.
|
||||
* Doing so is encouraged because it fits perfectly OPcache's memory model.
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $directory
|
||||
*
|
||||
* @throws CacheException if OPcache is not enabled
|
||||
*/
|
||||
public function __construct(string $namespace = '', int $defaultLifetime = 0, string $directory = null, bool $appendOnly = false)
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $directory = null)
|
||||
{
|
||||
$this->appendOnly = $appendOnly;
|
||||
self::$startTime = self::$startTime ?? $_SERVER['REQUEST_TIME'] ?? time();
|
||||
if (!static::isSupported()) {
|
||||
throw new CacheException('OPcache is not enabled.');
|
||||
}
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->init($namespace, $directory);
|
||||
$this->includeHandler = static function ($type, $msg, $file, $line) {
|
||||
throw new \ErrorException($msg, 0, $type, $file, $line);
|
||||
};
|
||||
|
||||
$e = new \Exception();
|
||||
$this->includeHandler = function () use ($e) { throw $e; };
|
||||
$this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,231 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Psr16Cache;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" instead.', Psr6Cache::class, Psr16Cache::class), \E_USER_DEPRECATED);
|
||||
use Psr\Cache\CacheException as Psr6CacheException;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Psr\SimpleCache\CacheException as SimpleCacheException;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\AdapterInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use Psr16Cache instead.
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class Psr6Cache extends Psr16Cache
|
||||
class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use ProxyTrait;
|
||||
|
||||
private $createCacheItem;
|
||||
private $cacheItemPrototype;
|
||||
|
||||
public function __construct(CacheItemPoolInterface $pool)
|
||||
{
|
||||
$this->pool = $pool;
|
||||
|
||||
if (!$pool instanceof AdapterInterface) {
|
||||
return;
|
||||
}
|
||||
$cacheItemPrototype = &$this->cacheItemPrototype;
|
||||
$createCacheItem = \Closure::bind(
|
||||
static function ($key, $value, $allowInt = false) use (&$cacheItemPrototype) {
|
||||
$item = clone $cacheItemPrototype;
|
||||
$item->key = $allowInt && \is_int($key) ? (string) $key : CacheItem::validateKey($key);
|
||||
$item->value = $value;
|
||||
$item->isHit = false;
|
||||
|
||||
return $item;
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
$this->createCacheItem = function ($key, $value, $allowInt = false) use ($createCacheItem) {
|
||||
if (null === $this->cacheItemPrototype) {
|
||||
$this->get($allowInt && \is_int($key) ? (string) $key : $key);
|
||||
}
|
||||
$this->createCacheItem = $createCacheItem;
|
||||
|
||||
return $createCacheItem($key, $value, $allowInt);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
try {
|
||||
$item = $this->pool->getItem($key);
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
if (null === $this->cacheItemPrototype) {
|
||||
$this->cacheItemPrototype = clone $item;
|
||||
$this->cacheItemPrototype->set(null);
|
||||
}
|
||||
|
||||
return $item->isHit() ? $item->get() : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
try {
|
||||
if (null !== $f = $this->createCacheItem) {
|
||||
$item = $f($key, $value);
|
||||
} else {
|
||||
$item = $this->pool->getItem($key)->set($value);
|
||||
}
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
if (null !== $ttl) {
|
||||
$item->expiresAfter($ttl);
|
||||
}
|
||||
|
||||
return $this->pool->save($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
try {
|
||||
return $this->pool->deleteItem($key);
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return $this->pool->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
if ($keys instanceof \Traversable) {
|
||||
$keys = iterator_to_array($keys, false);
|
||||
} elseif (!\is_array($keys)) {
|
||||
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
|
||||
}
|
||||
|
||||
try {
|
||||
$items = $this->pool->getItems($keys);
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
$values = [];
|
||||
|
||||
foreach ($items as $key => $item) {
|
||||
$values[$key] = $item->isHit() ? $item->get() : $default;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
$valuesIsArray = \is_array($values);
|
||||
if (!$valuesIsArray && !$values instanceof \Traversable) {
|
||||
throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', \is_object($values) ? \get_class($values) : \gettype($values)));
|
||||
}
|
||||
$items = [];
|
||||
|
||||
try {
|
||||
if (null !== $f = $this->createCacheItem) {
|
||||
$valuesIsArray = false;
|
||||
foreach ($values as $key => $value) {
|
||||
$items[$key] = $f($key, $value, true);
|
||||
}
|
||||
} elseif ($valuesIsArray) {
|
||||
$items = [];
|
||||
foreach ($values as $key => $value) {
|
||||
$items[] = (string) $key;
|
||||
}
|
||||
$items = $this->pool->getItems($items);
|
||||
} else {
|
||||
foreach ($values as $key => $value) {
|
||||
if (\is_int($key)) {
|
||||
$key = (string) $key;
|
||||
}
|
||||
$items[$key] = $this->pool->getItem($key)->set($value);
|
||||
}
|
||||
}
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
$ok = true;
|
||||
|
||||
foreach ($items as $key => $item) {
|
||||
if ($valuesIsArray) {
|
||||
$item->set($values[$key]);
|
||||
}
|
||||
if (null !== $ttl) {
|
||||
$item->expiresAfter($ttl);
|
||||
}
|
||||
$ok = $this->pool->saveDeferred($item) && $ok;
|
||||
}
|
||||
|
||||
return $this->pool->commit() && $ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
if ($keys instanceof \Traversable) {
|
||||
$keys = iterator_to_array($keys, false);
|
||||
} elseif (!\is_array($keys)) {
|
||||
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->pool->deleteItems($keys);
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
try {
|
||||
return $this->pool->hasItem($key);
|
||||
} catch (SimpleCacheException $e) {
|
||||
throw $e;
|
||||
} catch (Psr6CacheException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,27 +11,19 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\RedisAdapter;
|
||||
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
|
||||
use Symfony\Component\Cache\Traits\RedisClusterProxy;
|
||||
use Symfony\Component\Cache\Traits\RedisProxy;
|
||||
use Symfony\Component\Cache\Traits\RedisTrait;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', RedisCache::class, RedisAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use RedisAdapter and type-hint for CacheInterface instead.
|
||||
*/
|
||||
class RedisCache extends AbstractCache
|
||||
{
|
||||
use RedisTrait;
|
||||
|
||||
/**
|
||||
* @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy $redis
|
||||
* @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
public function __construct($redis, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
|
||||
public function __construct($redisClient, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->init($redis, $namespace, $defaultLifetime, $marshaller);
|
||||
$this->init($redisClient, $namespace, $defaultLifetime);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,25 +11,22 @@
|
|||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\TraceableAdapter;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
|
||||
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', TraceableCache::class, TraceableAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 4.3, use TraceableAdapter and type-hint for CacheInterface instead.
|
||||
* An adapter that collects data about all cache calls.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class TraceableCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
|
||||
class TraceableCache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $pool;
|
||||
private $miss;
|
||||
private $calls = [];
|
||||
|
||||
public function __construct(Psr16CacheInterface $pool)
|
||||
public function __construct(CacheInterface $pool)
|
||||
{
|
||||
$this->pool = $pool;
|
||||
$this->miss = new \stdClass();
|
||||
|
@ -59,8 +56,6 @@ class TraceableCache implements Psr16CacheInterface, PruneableInterface, Resetta
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
|
@ -74,8 +69,6 @@ class TraceableCache implements Psr16CacheInterface, PruneableInterface, Resetta
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
|
@ -89,8 +82,6 @@ class TraceableCache implements Psr16CacheInterface, PruneableInterface, Resetta
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
|
@ -104,8 +95,6 @@ class TraceableCache implements Psr16CacheInterface, PruneableInterface, Resetta
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
|
@ -133,8 +122,6 @@ class TraceableCache implements Psr16CacheInterface, PruneableInterface, Resetta
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return iterable
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
|
@ -163,8 +150,6 @@ class TraceableCache implements Psr16CacheInterface, PruneableInterface, Resetta
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
|
@ -178,8 +163,6 @@ class TraceableCache implements Psr16CacheInterface, PruneableInterface, Resetta
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
|
@ -217,7 +200,7 @@ class TraceableCache implements Psr16CacheInterface, PruneableInterface, Resetta
|
|||
*/
|
||||
public function reset()
|
||||
{
|
||||
if (!$this->pool instanceof ResetInterface) {
|
||||
if (!$this->pool instanceof ResettableInterface) {
|
||||
return;
|
||||
}
|
||||
$event = $this->start(__FUNCTION__);
|
||||
|
@ -237,7 +220,7 @@ class TraceableCache implements Psr16CacheInterface, PruneableInterface, Resetta
|
|||
}
|
||||
}
|
||||
|
||||
private function start(string $name): TraceableCacheEvent
|
||||
private function start($name)
|
||||
{
|
||||
$this->calls[] = $event = new TraceableCacheEvent();
|
||||
$event->name = $name;
|
||||
|
|
|
@ -1,164 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Traits;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait AbstractAdapterTrait
|
||||
{
|
||||
use AbstractTrait;
|
||||
|
||||
/**
|
||||
* @var \Closure needs to be set by class, signature is function(string <key>, mixed <value>, bool <isHit>)
|
||||
*/
|
||||
private $createCacheItem;
|
||||
|
||||
/**
|
||||
* @var \Closure needs to be set by class, signature is function(array <deferred>, string <namespace>, array <&expiredIds>)
|
||||
*/
|
||||
private $mergeByLifetime;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItem($key)
|
||||
{
|
||||
$id = $this->getId($key);
|
||||
|
||||
if (isset($this->deferred[$key])) {
|
||||
$this->commit();
|
||||
}
|
||||
|
||||
$f = $this->createCacheItem;
|
||||
$isHit = false;
|
||||
$value = null;
|
||||
|
||||
try {
|
||||
foreach ($this->doFetch([$id]) as $value) {
|
||||
$isHit = true;
|
||||
}
|
||||
|
||||
return $f($key, $value, $isHit);
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
|
||||
}
|
||||
|
||||
return $f($key, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItems(array $keys = [])
|
||||
{
|
||||
$ids = [];
|
||||
$commit = false;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$ids[] = $this->getId($key);
|
||||
$commit = $commit || isset($this->deferred[$key]);
|
||||
}
|
||||
|
||||
if ($commit) {
|
||||
$this->commit();
|
||||
}
|
||||
|
||||
try {
|
||||
$items = $this->doFetch($ids);
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => $keys, 'exception' => $e]);
|
||||
$items = [];
|
||||
}
|
||||
$ids = array_combine($ids, $keys);
|
||||
|
||||
return $this->generateItems($items, $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
if (!$item instanceof CacheItem) {
|
||||
return false;
|
||||
}
|
||||
$this->deferred[$item->getKey()] = $item;
|
||||
|
||||
return $this->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
if (!$item instanceof CacheItem) {
|
||||
return false;
|
||||
}
|
||||
$this->deferred[$item->getKey()] = $item;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
}
|
||||
|
||||
private function generateItems(iterable $items, array &$keys): iterable
|
||||
{
|
||||
$f = $this->createCacheItem;
|
||||
|
||||
try {
|
||||
foreach ($items as $id => $value) {
|
||||
if (!isset($keys[$id])) {
|
||||
throw new InvalidArgumentException(sprintf('Could not match value id "%s" to keys "%s".', $id, implode('", "', $keys)));
|
||||
}
|
||||
$key = $keys[$id];
|
||||
unset($keys[$id]);
|
||||
yield $key => $f($key, $value, true);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => array_values($keys), 'exception' => $e]);
|
||||
}
|
||||
|
||||
foreach ($keys as $key) {
|
||||
yield $key => $f($key, null, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,7 +27,6 @@ trait AbstractTrait
|
|||
private $namespaceVersion = '';
|
||||
private $versioningIsEnabled = false;
|
||||
private $deferred = [];
|
||||
private $ids = [];
|
||||
|
||||
/**
|
||||
* @var int|null The maximum length to enforce for identifiers or null when no limit applies
|
||||
|
@ -78,12 +77,10 @@ trait AbstractTrait
|
|||
*
|
||||
* @return array|bool The identifiers that failed to be cached or a boolean stating if caching succeeded or not
|
||||
*/
|
||||
abstract protected function doSave(array $values, int $lifetime);
|
||||
abstract protected function doSave(array $values, $lifetime);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
|
@ -96,7 +93,7 @@ trait AbstractTrait
|
|||
try {
|
||||
return $this->doHave($id);
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached: '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached', ['key' => $key, 'exception' => $e]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -104,43 +101,26 @@ trait AbstractTrait
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear(/* string $prefix = '' */)
|
||||
public function clear()
|
||||
{
|
||||
$this->deferred = [];
|
||||
if ($cleared = $this->versioningIsEnabled) {
|
||||
if ('' === $namespaceVersionToClear = $this->namespaceVersion) {
|
||||
foreach ($this->doFetch([static::NS_SEPARATOR.$this->namespace]) as $v) {
|
||||
$namespaceVersionToClear = $v;
|
||||
}
|
||||
}
|
||||
$namespaceToClear = $this->namespace.$namespaceVersionToClear;
|
||||
$namespaceVersion = self::formatNamespaceVersion(mt_rand());
|
||||
$namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), static::NS_SEPARATOR, 5);
|
||||
try {
|
||||
$e = $this->doSave([static::NS_SEPARATOR.$this->namespace => $namespaceVersion], 0);
|
||||
$cleared = $this->doSave([static::NS_SEPARATOR.$this->namespace => $namespaceVersion], 0);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
if (true !== $e && [] !== $e) {
|
||||
$cleared = false;
|
||||
$message = 'Failed to save the new namespace'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['exception' => $e instanceof \Exception ? $e : null]);
|
||||
} else {
|
||||
$this->namespaceVersion = $namespaceVersion;
|
||||
$this->ids = [];
|
||||
}
|
||||
} else {
|
||||
$prefix = 0 < \func_num_args() ? (string) func_get_arg(0) : '';
|
||||
$namespaceToClear = $this->namespace.$prefix;
|
||||
if ($cleared = true === $cleared || [] === $cleared) {
|
||||
$this->namespaceVersion = $namespaceVersion;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->doClear($namespaceToClear) || $cleared;
|
||||
return $this->doClear($this->namespace) || $cleared;
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to clear the cache: '.$e->getMessage(), ['exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to clear the cache', ['exception' => $e]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -148,8 +128,6 @@ trait AbstractTrait
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItem($key)
|
||||
{
|
||||
|
@ -158,8 +136,6 @@ trait AbstractTrait
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
|
@ -188,8 +164,7 @@ trait AbstractTrait
|
|||
}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
$message = 'Failed to delete key "{key}"'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to delete key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
$ok = false;
|
||||
}
|
||||
|
||||
|
@ -213,7 +188,6 @@ trait AbstractTrait
|
|||
$wasEnabled = $this->versioningIsEnabled;
|
||||
$this->versioningIsEnabled = (bool) $enable;
|
||||
$this->namespaceVersion = '';
|
||||
$this->ids = [];
|
||||
|
||||
return $wasEnabled;
|
||||
}
|
||||
|
@ -227,7 +201,6 @@ trait AbstractTrait
|
|||
$this->commit();
|
||||
}
|
||||
$this->namespaceVersion = '';
|
||||
$this->ids = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -238,13 +211,9 @@ trait AbstractTrait
|
|||
* @return mixed
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @deprecated since Symfony 4.2, use DefaultMarshaller instead.
|
||||
*/
|
||||
protected static function unserialize($value)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s::unserialize()" method is deprecated since Symfony 4.2, use DefaultMarshaller instead.', __CLASS__), \E_USER_DEPRECATED);
|
||||
|
||||
if ('b:0;' === $value) {
|
||||
return false;
|
||||
}
|
||||
|
@ -261,45 +230,29 @@ trait AbstractTrait
|
|||
}
|
||||
}
|
||||
|
||||
private function getId($key): string
|
||||
private function getId($key)
|
||||
{
|
||||
CacheItem::validateKey($key);
|
||||
|
||||
if ($this->versioningIsEnabled && '' === $this->namespaceVersion) {
|
||||
$this->ids = [];
|
||||
$this->namespaceVersion = '1'.static::NS_SEPARATOR;
|
||||
try {
|
||||
foreach ($this->doFetch([static::NS_SEPARATOR.$this->namespace]) as $v) {
|
||||
$this->namespaceVersion = $v;
|
||||
}
|
||||
$e = true;
|
||||
if ('1'.static::NS_SEPARATOR === $this->namespaceVersion) {
|
||||
$this->namespaceVersion = self::formatNamespaceVersion(time());
|
||||
$e = $this->doSave([static::NS_SEPARATOR.$this->namespace => $this->namespaceVersion], 0);
|
||||
$this->namespaceVersion = substr_replace(base64_encode(pack('V', time())), static::NS_SEPARATOR, 5);
|
||||
$this->doSave([static::NS_SEPARATOR.$this->namespace => $this->namespaceVersion], 0);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
if (true !== $e && [] !== $e) {
|
||||
$message = 'Failed to save the new namespace'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['exception' => $e instanceof \Exception ? $e : null]);
|
||||
}
|
||||
}
|
||||
|
||||
if (\is_string($key) && isset($this->ids[$key])) {
|
||||
return $this->namespace.$this->namespaceVersion.$this->ids[$key];
|
||||
}
|
||||
CacheItem::validateKey($key);
|
||||
$this->ids[$key] = $key;
|
||||
|
||||
if (\count($this->ids) > 1000) {
|
||||
$this->ids = \array_slice($this->ids, 500, null, true); // stop memory leak if there are many keys
|
||||
}
|
||||
|
||||
if (null === $this->maxIdLength) {
|
||||
return $this->namespace.$this->namespaceVersion.$key;
|
||||
}
|
||||
if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) {
|
||||
// Use MD5 to favor speed over security, which is not an issue here
|
||||
$this->ids[$key] = $id = substr_replace(base64_encode(hash('md5', $key, true)), static::NS_SEPARATOR, -(\strlen($this->namespaceVersion) + 2));
|
||||
$id = $this->namespace.$this->namespaceVersion.$id;
|
||||
$id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), static::NS_SEPARATOR, -(\strlen($this->namespaceVersion) + 22));
|
||||
}
|
||||
|
||||
return $id;
|
||||
|
@ -312,9 +265,4 @@ trait AbstractTrait
|
|||
{
|
||||
throw new \DomainException('Class not found: '.$class);
|
||||
}
|
||||
|
||||
private static function formatNamespaceVersion(int $value): string
|
||||
{
|
||||
return strtr(substr_replace(base64_encode(pack('V', $value)), static::NS_SEPARATOR, 5), '/', '_');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,10 +23,10 @@ trait ApcuTrait
|
|||
{
|
||||
public static function isSupported()
|
||||
{
|
||||
return \function_exists('apcu_fetch') && filter_var(\ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN);
|
||||
return \function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
|
||||
private function init(string $namespace, int $defaultLifetime, ?string $version)
|
||||
private function init($namespace, $defaultLifetime, $version)
|
||||
{
|
||||
if (!static::isSupported()) {
|
||||
throw new CacheException('APCu is not enabled.');
|
||||
|
@ -51,27 +51,14 @@ trait ApcuTrait
|
|||
*/
|
||||
protected function doFetch(array $ids)
|
||||
{
|
||||
$unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
|
||||
try {
|
||||
$values = [];
|
||||
$ids = array_flip($ids);
|
||||
foreach (apcu_fetch(array_keys($ids), $ok) ?: [] as $k => $v) {
|
||||
if (!isset($ids[$k])) {
|
||||
// work around https://github.com/krakjoe/apcu/issues/247
|
||||
$k = key($ids);
|
||||
}
|
||||
unset($ids[$k]);
|
||||
|
||||
foreach (apcu_fetch($ids, $ok) ?: [] as $k => $v) {
|
||||
if (null !== $v || $ok) {
|
||||
$values[$k] = $v;
|
||||
yield $k => $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
} catch (\Error $e) {
|
||||
throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
|
||||
} finally {
|
||||
ini_set('unserialize_callback_func', $unserializeCallbackHandler);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,8 +75,8 @@ trait ApcuTrait
|
|||
*/
|
||||
protected function doClear($namespace)
|
||||
{
|
||||
return isset($namespace[0]) && class_exists(\APCUIterator::class, false) && ('cli' !== \PHP_SAPI || filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))
|
||||
? apcu_delete(new \APCUIterator(sprintf('/^%s/', preg_quote($namespace, '/')), \APC_ITER_KEY))
|
||||
return isset($namespace[0]) && class_exists('APCuIterator', false) && ('cli' !== \PHP_SAPI || filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))
|
||||
? apcu_delete(new \APCuIterator(sprintf('/^%s/', preg_quote($namespace, '/')), \APC_ITER_KEY))
|
||||
: apcu_clear_cache();
|
||||
}
|
||||
|
||||
|
@ -108,7 +95,7 @@ trait ApcuTrait
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doSave(array $values, int $lifetime)
|
||||
protected function doSave(array $values, $lifetime)
|
||||
{
|
||||
try {
|
||||
if (false === $failures = apcu_store($values, null, $lifetime)) {
|
||||
|
@ -116,13 +103,15 @@ trait ApcuTrait
|
|||
}
|
||||
|
||||
return array_keys($failures);
|
||||
} catch (\Throwable $e) {
|
||||
} catch (\Error $e) {
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
if (1 === \count($values)) {
|
||||
// Workaround https://github.com/krakjoe/apcu/issues/170
|
||||
apcu_delete(array_key_first($values));
|
||||
apcu_delete(key($values));
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,72 +34,36 @@ trait ArrayTrait
|
|||
*/
|
||||
public function getValues()
|
||||
{
|
||||
if (!$this->storeSerialized) {
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
$values = $this->values;
|
||||
foreach ($values as $k => $v) {
|
||||
if (null === $v || 'N;' === $v) {
|
||||
continue;
|
||||
}
|
||||
if (!\is_string($v) || !isset($v[2]) || ':' !== $v[1]) {
|
||||
$values[$k] = serialize($v);
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
if (\is_string($key) && isset($this->expiries[$key]) && $this->expiries[$key] > microtime(true)) {
|
||||
return true;
|
||||
}
|
||||
CacheItem::validateKey($key);
|
||||
|
||||
return isset($this->expiries[$key]) && !$this->deleteItem($key);
|
||||
return isset($this->expiries[$key]) && ($this->expiries[$key] > time() || !$this->deleteItem($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear(/* string $prefix = '' */)
|
||||
public function clear()
|
||||
{
|
||||
$prefix = 0 < \func_num_args() ? (string) func_get_arg(0) : '';
|
||||
|
||||
if ('' !== $prefix) {
|
||||
foreach ($this->values as $key => $value) {
|
||||
if (str_starts_with($key, $prefix)) {
|
||||
unset($this->values[$key], $this->expiries[$key]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->values = $this->expiries = [];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteItem($key)
|
||||
{
|
||||
if (!\is_string($key) || !isset($this->expiries[$key])) {
|
||||
CacheItem::validateKey($key);
|
||||
}
|
||||
|
||||
unset($this->values[$key], $this->expiries[$key]);
|
||||
|
||||
return true;
|
||||
|
@ -113,13 +77,24 @@ trait ArrayTrait
|
|||
$this->clear();
|
||||
}
|
||||
|
||||
private function generateItems(array $keys, float $now, callable $f): iterable
|
||||
private function generateItems(array $keys, $now, $f)
|
||||
{
|
||||
foreach ($keys as $i => $key) {
|
||||
try {
|
||||
if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] > $now || !$this->deleteItem($key))) {
|
||||
$this->values[$key] = $value = null;
|
||||
} else {
|
||||
$value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key];
|
||||
} elseif (!$this->storeSerialized) {
|
||||
$value = $this->values[$key];
|
||||
} elseif ('b:0;' === $value = $this->values[$key]) {
|
||||
$value = false;
|
||||
} elseif (false === $value = unserialize($value)) {
|
||||
$this->values[$key] = $value = null;
|
||||
$isHit = false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
$this->values[$key] = $value = null;
|
||||
$isHit = false;
|
||||
}
|
||||
unset($keys[$i]);
|
||||
|
||||
|
@ -130,55 +105,4 @@ trait ArrayTrait
|
|||
yield $key => $f($key, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
private function freeze($value, $key)
|
||||
{
|
||||
if (null === $value) {
|
||||
return 'N;';
|
||||
}
|
||||
if (\is_string($value)) {
|
||||
// Serialize strings if they could be confused with serialized objects or arrays
|
||||
if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) {
|
||||
return serialize($value);
|
||||
}
|
||||
} elseif (!\is_scalar($value)) {
|
||||
try {
|
||||
$serialized = serialize($value);
|
||||
} catch (\Exception $e) {
|
||||
unset($this->values[$key]);
|
||||
$type = \is_object($value) ? \get_class($value) : \gettype($value);
|
||||
$message = sprintf('Failed to save key "{key}" of type %s: ', $type).$e->getMessage();
|
||||
CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e]);
|
||||
|
||||
return null;
|
||||
}
|
||||
// Keep value serialized if it contains any objects or any internal references
|
||||
if ('C' === $serialized[0] || 'O' === $serialized[0] || preg_match('/;[OCRr]:[1-9]/', $serialized)) {
|
||||
return $serialized;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
private function unfreeze(string $key, bool &$isHit)
|
||||
{
|
||||
if ('N;' === $value = $this->values[$key]) {
|
||||
return null;
|
||||
}
|
||||
if (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||
try {
|
||||
$value = unserialize($value);
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to unserialize key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
|
||||
$value = false;
|
||||
}
|
||||
if (false === $value) {
|
||||
$this->values[$key] = $value = null;
|
||||
$isHit = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Traits;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Cache\Adapter\AdapterInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\LockRegistry;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Cache\CacheTrait;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait ContractsTrait
|
||||
{
|
||||
use CacheTrait {
|
||||
doGet as private contractsGet;
|
||||
}
|
||||
|
||||
private $callbackWrapper;
|
||||
private $computing = [];
|
||||
|
||||
/**
|
||||
* Wraps the callback passed to ->get() in a callable.
|
||||
*
|
||||
* @return callable the previous callback wrapper
|
||||
*/
|
||||
public function setCallbackWrapper(?callable $callbackWrapper): callable
|
||||
{
|
||||
if (!isset($this->callbackWrapper)) {
|
||||
$this->callbackWrapper = \Closure::fromCallable([LockRegistry::class, 'compute']);
|
||||
|
||||
if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
|
||||
$this->setCallbackWrapper(null);
|
||||
}
|
||||
}
|
||||
|
||||
$previousWrapper = $this->callbackWrapper;
|
||||
$this->callbackWrapper = $callbackWrapper ?? static function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger) {
|
||||
return $callback($item, $save);
|
||||
};
|
||||
|
||||
return $previousWrapper;
|
||||
}
|
||||
|
||||
private function doGet(AdapterInterface $pool, string $key, callable $callback, ?float $beta, array &$metadata = null)
|
||||
{
|
||||
if (0 > $beta = $beta ?? 1.0) {
|
||||
throw new InvalidArgumentException(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta));
|
||||
}
|
||||
|
||||
static $setMetadata;
|
||||
|
||||
$setMetadata = $setMetadata ?? \Closure::bind(
|
||||
static function (CacheItem $item, float $startTime, ?array &$metadata) {
|
||||
if ($item->expiry > $endTime = microtime(true)) {
|
||||
$item->newMetadata[CacheItem::METADATA_EXPIRY] = $metadata[CacheItem::METADATA_EXPIRY] = $item->expiry;
|
||||
$item->newMetadata[CacheItem::METADATA_CTIME] = $metadata[CacheItem::METADATA_CTIME] = (int) ceil(1000 * ($endTime - $startTime));
|
||||
} else {
|
||||
unset($metadata[CacheItem::METADATA_EXPIRY], $metadata[CacheItem::METADATA_CTIME]);
|
||||
}
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
|
||||
return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata, $key) {
|
||||
// don't wrap nor save recursive calls
|
||||
if (isset($this->computing[$key])) {
|
||||
$value = $callback($item, $save);
|
||||
$save = false;
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
$this->computing[$key] = $key;
|
||||
$startTime = microtime(true);
|
||||
|
||||
if (!isset($this->callbackWrapper)) {
|
||||
$this->setCallbackWrapper($this->setCallbackWrapper(null));
|
||||
}
|
||||
|
||||
try {
|
||||
$value = ($this->callbackWrapper)($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
|
||||
$setMetadata($item, $startTime, $metadata);
|
||||
}, $this->logger ?? null);
|
||||
$setMetadata($item, $startTime, $metadata);
|
||||
|
||||
return $value;
|
||||
} finally {
|
||||
unset($this->computing[$key]);
|
||||
}
|
||||
}, $beta, $metadata, $this->logger ?? null);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue