diff --git a/composer.json b/composer.json
index 103baca813b..d0f72dce0aa 100644
--- a/composer.json
+++ b/composer.json
@@ -73,6 +73,7 @@
"ext-ctype": "*",
"lib-pcre": "*",
"yiisoft/yii2-composer": "~2.0.4",
+ "psr/simple-cache": "~1.0.0",
"ezyang/htmlpurifier": "~4.6",
"cebe/markdown": "~1.0.0 | ~1.1.0",
"bower-asset/jquery": "2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
diff --git a/composer.lock b/composer.lock
index fb2c6a1460f..6d98a6b25ca 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "content-hash": "1e1c5caae60d6d8d5b4a3d28d9667f31",
+ "hash": "81cb8a6aa01acac345059695e795fd68",
+ "content-hash": "b36161ae5a97ecec89951d7fd5b2aa6a",
"packages": [
{
"name": "bower-asset/inputmask",
@@ -33,18 +34,30 @@
"version": "2.2.4",
"source": {
"type": "git",
- "url": "https://github.com/jquery/jquery-dist.git",
- "reference": "c0185ab7c75aab88762c5aae780b9d83b80eda72"
+ "url": "https://github.com/components/jquery.git",
+ "reference": "981036fcb56668433a7eb0d1e71190324b4574df"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/c0185ab7c75aab88762c5aae780b9d83b80eda72",
- "reference": "c0185ab7c75aab88762c5aae780b9d83b80eda72",
- "shasum": null
+ "url": "https://api.github.com/repos/components/jquery/zipball/981036fcb56668433a7eb0d1e71190324b4574df",
+ "reference": "981036fcb56668433a7eb0d1e71190324b4574df",
+ "shasum": ""
+ },
+ "type": "bower-asset-library",
+ "extra": {
+ "bower-asset-main": "dist/jquery.js",
+ "bower-asset-ignore": [
+ "package.json"
+ ]
},
- "type": "bower-asset",
"license": [
"MIT"
+ ],
+ "keywords": [
+ "browser",
+ "javascript",
+ "jquery",
+ "library"
]
},
{
@@ -59,9 +72,21 @@
"type": "zip",
"url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3",
"reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3",
- "shasum": null
+ "shasum": ""
},
- "type": "bower-asset"
+ "type": "bower-asset-library",
+ "extra": {
+ "bower-asset-main": "punycode.js",
+ "bower-asset-ignore": [
+ "coverage",
+ "tests",
+ ".*",
+ "component.json",
+ "Gruntfile.js",
+ "node_modules",
+ "package.json"
+ ]
+ }
},
{
"name": "bower-asset/yii2-pjax",
@@ -75,12 +100,24 @@
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/60728da6ade5879e807a49ce59ef9a72039b8978",
"reference": "60728da6ade5879e807a49ce59ef9a72039b8978",
- "shasum": null
+ "shasum": ""
},
"require": {
"bower-asset/jquery": ">=1.8"
},
- "type": "bower-asset",
+ "type": "bower-asset-library",
+ "extra": {
+ "bower-asset-main": "./jquery.pjax.js",
+ "bower-asset-ignore": [
+ ".travis.yml",
+ "Gemfile",
+ "Gemfile.lock",
+ "CONTRIBUTING.md",
+ "vendor/",
+ "script/",
+ "test/"
+ ]
+ },
"license": [
"MIT"
]
@@ -143,7 +180,7 @@
"markdown",
"markdown-extra"
],
- "time": "2017-07-16T21:13:23+00:00"
+ "time": "2017-07-16 21:13:23"
},
{
"name": "ezyang/htmlpurifier",
@@ -190,7 +227,55 @@
"keywords": [
"html"
],
- "time": "2017-06-03T02:28:16+00:00"
+ "time": "2017-06-03 02:28:16"
+ },
+ {
+ "name": "psr/simple-cache",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/simple-cache.git",
+ "reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/753fa598e8f3b9966c886fe13f370baa45ef0e24",
+ "reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24",
+ "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-01-02 13:31:39"
},
{
"name": "yiisoft/yii2-composer",
@@ -240,7 +325,7 @@
"extension installer",
"yii2"
],
- "time": "2016-12-20T13:26:02+00:00"
+ "time": "2016-12-20 13:26:02"
}
],
"packages-dev": [
@@ -275,25 +360,25 @@
}
],
"description": "a small tool to convert text file indentation",
- "time": "2014-05-23T14:40:08+00:00"
+ "time": "2014-05-23 14:40:08"
},
{
"name": "doctrine/annotations",
- "version": "v1.4.0",
+ "version": "v1.5.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
- "reference": "54cacc9b81758b14e3ce750f205a393d52339e97"
+ "reference": "5beebb01b025c94e93686b7a0ed3edae81fe3e7f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97",
- "reference": "54cacc9b81758b14e3ce750f205a393d52339e97",
+ "url": "https://api.github.com/repos/doctrine/annotations/zipball/5beebb01b025c94e93686b7a0ed3edae81fe3e7f",
+ "reference": "5beebb01b025c94e93686b7a0ed3edae81fe3e7f",
"shasum": ""
},
"require": {
"doctrine/lexer": "1.*",
- "php": "^5.6 || ^7.0"
+ "php": "^7.1"
},
"require-dev": {
"doctrine/cache": "1.*",
@@ -302,7 +387,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4.x-dev"
+ "dev-master": "1.5.x-dev"
}
},
"autoload": {
@@ -343,36 +428,36 @@
"docblock",
"parser"
],
- "time": "2017-02-24T16:22:25+00:00"
+ "time": "2017-07-22 10:58:02"
},
{
"name": "doctrine/instantiator",
- "version": "1.0.5",
+ "version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
- "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
- "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
"shasum": ""
},
"require": {
- "php": ">=5.3,<8.0-DEV"
+ "php": "^7.1"
},
"require-dev": {
"athletic/athletic": "~0.1.8",
"ext-pdo": "*",
"ext-phar": "*",
- "phpunit/phpunit": "~4.0",
- "squizlabs/php_codesniffer": "~2.0"
+ "phpunit/phpunit": "^6.2.3",
+ "squizlabs/php_codesniffer": "^3.0.2"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "1.2.x-dev"
}
},
"autoload": {
@@ -397,7 +482,7 @@
"constructor",
"instantiate"
],
- "time": "2015-06-14T21:17:01+00:00"
+ "time": "2017-07-22 11:58:36"
},
{
"name": "doctrine/lexer",
@@ -451,7 +536,7 @@
"lexer",
"parser"
],
- "time": "2014-09-09T13:34:57+00:00"
+ "time": "2014-09-09 13:34:57"
},
{
"name": "friendsofphp/php-cs-fixer",
@@ -535,7 +620,7 @@
}
],
"description": "A tool to automatically fix PHP code style",
- "time": "2017-07-18T15:16:38+00:00"
+ "time": "2017-07-18 15:16:38"
},
{
"name": "gecko-packages/gecko-php-unit",
@@ -574,7 +659,7 @@
"filesystem",
"phpunit"
],
- "time": "2017-06-20T11:22:48+00:00"
+ "time": "2017-06-20 11:22:48"
},
{
"name": "ircmaxell/password-compat",
@@ -616,7 +701,7 @@
"hashing",
"password"
],
- "time": "2014-11-20T16:49:30+00:00"
+ "time": "2014-11-20 16:49:30"
},
{
"name": "myclabs/deep-copy",
@@ -658,7 +743,7 @@
"object",
"object graph"
],
- "time": "2017-04-12T18:52:22+00:00"
+ "time": "2017-04-12 18:52:22"
},
{
"name": "paragonie/random_compat",
@@ -706,7 +791,7 @@
"pseudorandom",
"random"
],
- "time": "2017-03-13T16:27:32+00:00"
+ "time": "2017-03-13 16:27:32"
},
{
"name": "phar-io/manifest",
@@ -761,7 +846,7 @@
}
],
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
- "time": "2017-03-05T18:14:27+00:00"
+ "time": "2017-03-05 18:14:27"
},
{
"name": "phar-io/version",
@@ -808,7 +893,7 @@
}
],
"description": "Library for handling version information and constraints",
- "time": "2017-03-05T17:38:23+00:00"
+ "time": "2017-03-05 17:38:23"
},
{
"name": "phpdocumentor/reflection-common",
@@ -862,26 +947,26 @@
"reflection",
"static analysis"
],
- "time": "2015-12-27T11:43:31+00:00"
+ "time": "2015-12-27 11:43:31"
},
{
"name": "phpdocumentor/reflection-docblock",
- "version": "3.2.0",
+ "version": "3.2.2",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "46f7e8bb075036c92695b15a1ddb6971c751e585"
+ "reference": "4aada1f93c72c35e22fb1383b47fee43b8f1d157"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/46f7e8bb075036c92695b15a1ddb6971c751e585",
- "reference": "46f7e8bb075036c92695b15a1ddb6971c751e585",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/4aada1f93c72c35e22fb1383b47fee43b8f1d157",
+ "reference": "4aada1f93c72c35e22fb1383b47fee43b8f1d157",
"shasum": ""
},
"require": {
"php": ">=5.5",
"phpdocumentor/reflection-common": "^1.0@dev",
- "phpdocumentor/type-resolver": "^0.4.0",
+ "phpdocumentor/type-resolver": "^0.3.0",
"webmozart/assert": "^1.0"
},
"require-dev": {
@@ -907,20 +992,20 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
- "time": "2017-07-15T11:38:20+00:00"
+ "time": "2017-08-08 06:39:58"
},
{
"name": "phpdocumentor/type-resolver",
- "version": "0.4.0",
+ "version": "0.3.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
+ "reference": "fb3933512008d8162b3cdf9e18dba9309b7c3773"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
- "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/fb3933512008d8162b3cdf9e18dba9309b7c3773",
+ "reference": "fb3933512008d8162b3cdf9e18dba9309b7c3773",
"shasum": ""
},
"require": {
@@ -954,7 +1039,7 @@
"email": "me@mikevanriel.com"
}
],
- "time": "2017-07-14T14:27:02+00:00"
+ "time": "2017-06-03 08:32:36"
},
{
"name": "phpspec/prophecy",
@@ -1017,32 +1102,32 @@
"spy",
"stub"
],
- "time": "2017-03-02T20:05:34+00:00"
+ "time": "2017-03-02 20:05:34"
},
{
"name": "phpunit/php-code-coverage",
- "version": "5.2.1",
+ "version": "5.2.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "dc421f9ca5082a0c0cb04afb171c765f79add85b"
+ "reference": "8ed1902a57849e117b5651fc1a5c48110946c06b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/dc421f9ca5082a0c0cb04afb171c765f79add85b",
- "reference": "dc421f9ca5082a0c0cb04afb171c765f79add85b",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/8ed1902a57849e117b5651fc1a5c48110946c06b",
+ "reference": "8ed1902a57849e117b5651fc1a5c48110946c06b",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-xmlwriter": "*",
"php": "^7.0",
- "phpunit/php-file-iterator": "^1.3",
- "phpunit/php-text-template": "^1.2",
+ "phpunit/php-file-iterator": "^1.4.2",
+ "phpunit/php-text-template": "^1.2.1",
"phpunit/php-token-stream": "^1.4.11 || ^2.0",
- "sebastian/code-unit-reverse-lookup": "^1.0",
+ "sebastian/code-unit-reverse-lookup": "^1.0.1",
"sebastian/environment": "^3.0",
- "sebastian/version": "^2.0",
+ "sebastian/version": "^2.0.1",
"theseer/tokenizer": "^1.1"
},
"require-dev": {
@@ -1050,7 +1135,7 @@
"phpunit/phpunit": "^6.0"
},
"suggest": {
- "ext-xdebug": "^2.5.3"
+ "ext-xdebug": "^2.5.5"
},
"type": "library",
"extra": {
@@ -1081,7 +1166,7 @@
"testing",
"xunit"
],
- "time": "2017-04-21T08:03:57+00:00"
+ "time": "2017-08-03 12:40:43"
},
{
"name": "phpunit/php-file-iterator",
@@ -1128,7 +1213,7 @@
"filesystem",
"iterator"
],
- "time": "2016-10-03T07:40:28+00:00"
+ "time": "2016-10-03 07:40:28"
},
{
"name": "phpunit/php-text-template",
@@ -1169,7 +1254,7 @@
"keywords": [
"template"
],
- "time": "2015-06-21T13:50:34+00:00"
+ "time": "2015-06-21 13:50:34"
},
{
"name": "phpunit/php-timer",
@@ -1218,33 +1303,33 @@
"keywords": [
"timer"
],
- "time": "2017-02-26T11:10:40+00:00"
+ "time": "2017-02-26 11:10:40"
},
{
"name": "phpunit/php-token-stream",
- "version": "1.4.11",
+ "version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7"
+ "reference": "ecb0b2cdaa0add708fe6f329ef65ae0c5225130b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7",
- "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ecb0b2cdaa0add708fe6f329ef65ae0c5225130b",
+ "reference": "ecb0b2cdaa0add708fe6f329ef65ae0c5225130b",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
- "php": ">=5.3.3"
+ "php": "^7.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.2"
+ "phpunit/phpunit": "^6.2.4"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4-dev"
+ "dev-master": "2.0-dev"
}
},
"autoload": {
@@ -1267,20 +1352,20 @@
"keywords": [
"tokenizer"
],
- "time": "2017-02-27T10:12:30+00:00"
+ "time": "2017-08-03 14:17:41"
},
{
"name": "phpunit/phpunit",
- "version": "6.2.3",
+ "version": "6.2.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "fa5711d0559fc4b64deba0702be52d41434cbcb7"
+ "reference": "ff3a76a58ac293657808aefd58c8aaf05945f4d9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fa5711d0559fc4b64deba0702be52d41434cbcb7",
- "reference": "fa5711d0559fc4b64deba0702be52d41434cbcb7",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ff3a76a58ac293657808aefd58c8aaf05945f4d9",
+ "reference": "ff3a76a58ac293657808aefd58c8aaf05945f4d9",
"shasum": ""
},
"require": {
@@ -1300,7 +1385,7 @@
"phpunit/php-timer": "^1.0.6",
"phpunit/phpunit-mock-objects": "^4.0",
"sebastian/comparator": "^2.0",
- "sebastian/diff": "^1.4.3 || ^2.0",
+ "sebastian/diff": "^1.4.3",
"sebastian/environment": "^3.0.2",
"sebastian/exporter": "^3.1",
"sebastian/global-state": "^1.1 || ^2.0",
@@ -1351,26 +1436,26 @@
"testing",
"xunit"
],
- "time": "2017-07-03T15:54:24+00:00"
+ "time": "2017-08-03 13:59:28"
},
{
"name": "phpunit/phpunit-mock-objects",
- "version": "4.0.2",
+ "version": "4.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
- "reference": "d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4"
+ "reference": "2f789b59ab89669015ad984afa350c4ec577ade0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4",
- "reference": "d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/2f789b59ab89669015ad984afa350c4ec577ade0",
+ "reference": "2f789b59ab89669015ad984afa350c4ec577ade0",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "^1.0.2",
+ "doctrine/instantiator": "^1.0.5",
"php": "^7.0",
- "phpunit/php-text-template": "^1.2",
+ "phpunit/php-text-template": "^1.2.1",
"sebastian/exporter": "^3.0"
},
"conflict": {
@@ -1410,7 +1495,7 @@
"mock",
"xunit"
],
- "time": "2017-06-30T08:15:21+00:00"
+ "time": "2017-08-03 14:08:16"
},
{
"name": "psr/log",
@@ -1457,7 +1542,7 @@
"psr",
"psr-3"
],
- "time": "2016-10-10T12:19:37+00:00"
+ "time": "2016-10-10 12:19:37"
},
{
"name": "sebastian/code-unit-reverse-lookup",
@@ -1502,7 +1587,7 @@
],
"description": "Looks up which function or method a line of code belongs to",
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
- "time": "2017-03-04T06:30:41+00:00"
+ "time": "2017-03-04 06:30:41"
},
{
"name": "sebastian/comparator",
@@ -1566,7 +1651,7 @@
"compare",
"equality"
],
- "time": "2017-03-03T06:26:08+00:00"
+ "time": "2017-03-03 06:26:08"
},
{
"name": "sebastian/diff",
@@ -1618,7 +1703,7 @@
"keywords": [
"diff"
],
- "time": "2017-05-22T07:24:03+00:00"
+ "time": "2017-05-22 07:24:03"
},
{
"name": "sebastian/environment",
@@ -1668,7 +1753,7 @@
"environment",
"hhvm"
],
- "time": "2017-07-01T08:51:00+00:00"
+ "time": "2017-07-01 08:51:00"
},
{
"name": "sebastian/exporter",
@@ -1735,7 +1820,7 @@
"export",
"exporter"
],
- "time": "2017-04-03T13:19:02+00:00"
+ "time": "2017-04-03 13:19:02"
},
{
"name": "sebastian/global-state",
@@ -1786,25 +1871,25 @@
"keywords": [
"global state"
],
- "time": "2017-04-27T15:39:26+00:00"
+ "time": "2017-04-27 15:39:26"
},
{
"name": "sebastian/object-enumerator",
- "version": "3.0.2",
+ "version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
- "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8"
+ "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/31dd3379d16446c5d86dec32ab1ad1f378581ad8",
- "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5",
+ "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5",
"shasum": ""
},
"require": {
"php": "^7.0",
- "sebastian/object-reflector": "^1.0",
+ "sebastian/object-reflector": "^1.1.1",
"sebastian/recursion-context": "^3.0"
},
"require-dev": {
@@ -1833,7 +1918,7 @@
],
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
- "time": "2017-03-12T15:17:29+00:00"
+ "time": "2017-08-03 12:35:26"
},
{
"name": "sebastian/object-reflector",
@@ -1878,7 +1963,7 @@
],
"description": "Allows reflection of object attributes, including inherited and non-public ones",
"homepage": "https://github.com/sebastianbergmann/object-reflector/",
- "time": "2017-03-29T09:07:27+00:00"
+ "time": "2017-03-29 09:07:27"
},
{
"name": "sebastian/recursion-context",
@@ -1931,7 +2016,7 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
- "time": "2017-03-03T06:23:57+00:00"
+ "time": "2017-03-03 06:23:57"
},
{
"name": "sebastian/resource-operations",
@@ -1973,7 +2058,7 @@
],
"description": "Provides a list of PHP built-in functions that operate on resources",
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
- "time": "2015-07-28T20:34:47+00:00"
+ "time": "2015-07-28 20:34:47"
},
{
"name": "sebastian/version",
@@ -2016,20 +2101,20 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
- "time": "2016-10-03T07:35:21+00:00"
+ "time": "2016-10-03 07:35:21"
},
{
"name": "symfony/console",
- "version": "v3.3.5",
+ "version": "v3.3.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "a97e45d98c59510f085fa05225a1acb74dfe0546"
+ "reference": "b0878233cb5c4391347e5495089c7af11b8e6201"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/a97e45d98c59510f085fa05225a1acb74dfe0546",
- "reference": "a97e45d98c59510f085fa05225a1acb74dfe0546",
+ "url": "https://api.github.com/repos/symfony/console/zipball/b0878233cb5c4391347e5495089c7af11b8e6201",
+ "reference": "b0878233cb5c4391347e5495089c7af11b8e6201",
"shasum": ""
},
"require": {
@@ -2085,20 +2170,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2017-07-03T13:19:36+00:00"
+ "time": "2017-07-29 21:27:59"
},
{
"name": "symfony/debug",
- "version": "v3.3.5",
+ "version": "v3.3.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
- "reference": "63b85a968486d95ff9542228dc2e4247f16f9743"
+ "reference": "7c13ae8ce1e2adbbd574fc39de7be498e1284e13"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/63b85a968486d95ff9542228dc2e4247f16f9743",
- "reference": "63b85a968486d95ff9542228dc2e4247f16f9743",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/7c13ae8ce1e2adbbd574fc39de7be498e1284e13",
+ "reference": "7c13ae8ce1e2adbbd574fc39de7be498e1284e13",
"shasum": ""
},
"require": {
@@ -2141,11 +2226,11 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2017-07-05T13:02:37+00:00"
+ "time": "2017-07-28 15:27:31"
},
{
"name": "symfony/event-dispatcher",
- "version": "v3.3.5",
+ "version": "v3.3.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
@@ -2204,11 +2289,11 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2017-06-09T14:53:08+00:00"
+ "time": "2017-06-09 14:53:08"
},
{
"name": "symfony/filesystem",
- "version": "v3.3.5",
+ "version": "v3.3.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
@@ -2253,11 +2338,11 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2017-07-11T07:17:58+00:00"
+ "time": "2017-07-11 07:17:58"
},
{
"name": "symfony/finder",
- "version": "v3.3.5",
+ "version": "v3.3.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
@@ -2302,11 +2387,11 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2017-06-01T21:01:25+00:00"
+ "time": "2017-06-01 21:01:25"
},
{
"name": "symfony/options-resolver",
- "version": "v3.3.5",
+ "version": "v3.3.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
@@ -2356,7 +2441,7 @@
"configuration",
"options"
],
- "time": "2017-04-12T14:14:56+00:00"
+ "time": "2017-04-12 14:14:56"
},
{
"name": "symfony/polyfill-mbstring",
@@ -2415,7 +2500,7 @@
"portable",
"shim"
],
- "time": "2017-06-09T14:24:12+00:00"
+ "time": "2017-06-09 14:24:12"
},
{
"name": "symfony/polyfill-php54",
@@ -2473,7 +2558,7 @@
"portable",
"shim"
],
- "time": "2017-06-09T08:25:21+00:00"
+ "time": "2017-06-09 08:25:21"
},
{
"name": "symfony/polyfill-php55",
@@ -2529,7 +2614,7 @@
"portable",
"shim"
],
- "time": "2017-06-09T08:25:21+00:00"
+ "time": "2017-06-09 08:25:21"
},
{
"name": "symfony/polyfill-php70",
@@ -2588,7 +2673,7 @@
"portable",
"shim"
],
- "time": "2017-06-09T14:24:12+00:00"
+ "time": "2017-06-09 14:24:12"
},
{
"name": "symfony/polyfill-php72",
@@ -2643,11 +2728,11 @@
"portable",
"shim"
],
- "time": "2017-06-09T08:25:21+00:00"
+ "time": "2017-06-09 08:25:21"
},
{
"name": "symfony/process",
- "version": "v3.3.5",
+ "version": "v3.3.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
@@ -2692,11 +2777,11 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2017-07-13T13:05:09+00:00"
+ "time": "2017-07-13 13:05:09"
},
{
"name": "symfony/stopwatch",
- "version": "v3.3.5",
+ "version": "v3.3.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/stopwatch.git",
@@ -2741,7 +2826,7 @@
],
"description": "Symfony Stopwatch Component",
"homepage": "https://symfony.com",
- "time": "2017-04-12T14:14:56+00:00"
+ "time": "2017-04-12 14:14:56"
},
{
"name": "theseer/tokenizer",
@@ -2781,7 +2866,7 @@
}
],
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
- "time": "2017-04-07T12:08:54+00:00"
+ "time": "2017-04-07 12:08:54"
},
{
"name": "webmozart/assert",
@@ -2831,7 +2916,7 @@
"check",
"validate"
],
- "time": "2016-11-23T20:04:58+00:00"
+ "time": "2016-11-23 20:04:58"
}
],
"aliases": [],
diff --git a/docs/guide/caching-data.md b/docs/guide/caching-data.md
index aae0f08f49f..54d789daea6 100644
--- a/docs/guide/caching-data.md
+++ b/docs/guide/caching-data.md
@@ -12,7 +12,7 @@ a [cache component](#cache-components):
// try retrieving $data from cache
$data = $cache->get($key);
-if ($data === false) {
+if ($data === null) {
// $data is not found in cache, calculate it from scratch
$data = $this->calculateSomething();
@@ -58,22 +58,25 @@ such as memory, files, databases.
Cache components are usually registered as [application components](structure-application-components.md) so
that they can be globally configurable
and accessible. The following code shows how to configure the `cache` application component to use
-[memcached](http://memcached.org/) with two cache servers:
+[memcached](http://memcached.org/) handler with two cache servers:
```php
'components' => [
'cache' => [
- 'class' => 'yii\caching\MemCache',
- 'servers' => [
- [
- 'host' => 'server1',
- 'port' => 11211,
- 'weight' => 100,
- ],
- [
- 'host' => 'server2',
- 'port' => 11211,
- 'weight' => 50,
+ 'class' => yii\caching\Cache::class,
+ 'handler' => [
+ 'class' => yii\caching\MemCache::class,
+ 'servers' => [
+ [
+ 'host' => 'server1',
+ 'port' => 11211,
+ 'weight' => 100,
+ ],
+ [
+ 'host' => 'server2',
+ 'port' => 11211,
+ 'weight' => 50,
+ ],
],
],
],
@@ -82,7 +85,7 @@ and accessible. The following code shows how to configure the `cache` applicatio
You can then access the above cache component using the expression `Yii::$app->cache`.
-Because all cache components support the same set of APIs, you can swap the underlying cache component
+Because all cache handlers support the same set of APIs, you can swap the underlying cache component
with a different one by reconfiguring it in the application configuration without modifying the code that uses the cache.
For example, you can modify the above configuration to use [[yii\caching\ApcCache|APC cache]]:
@@ -90,7 +93,10 @@ For example, you can modify the above configuration to use [[yii\caching\ApcCach
```php
'components' => [
'cache' => [
- 'class' => 'yii\caching\ApcCache',
+ 'class' => yii\caching\Cache::class,
+ 'handler' => [
+ 'class' => yii\caching\ApcCache::class,
+ ],
],
],
```
@@ -101,7 +107,7 @@ For example, you can modify the above configuration to use [[yii\caching\ApcCach
### Supported Cache Storage
-Yii supports a wide range of cache storage. The following is a summary:
+Yii supports a wide range of cache handlers. The following is a summary:
* [[yii\caching\ApcCache]]: uses PHP [APC](http://php.net/manual/en/book.apc.php) extension. This option can be
considered as the fastest one when dealing with cache for a centralized thick application (e.g. one
@@ -117,10 +123,9 @@ Yii supports a wide range of cache storage. The following is a summary:
`Yii::$app->cache` might be `null`.
* [[yii\caching\FileCache]]: uses standard files to store cached data. This is particularly suitable
to cache large chunk of data, such as page content.
-* [[yii\caching\MemCache]]: uses PHP [memcache](http://php.net/manual/en/book.memcache.php)
- and [memcached](http://php.net/manual/en/book.memcached.php) extensions. This option can be considered as
- the fastest one when dealing with cache in a distributed applications (e.g. with several servers, load
- balancers, etc.)
+* [[yii\caching\MemCached]]: uses PHP [memcached](http://php.net/manual/en/book.memcached.php) extension.
+ This option can be considered as the fastest one when dealing with cache in a distributed applications
+ (e.g. with several servers, load balancers, etc.)
* [[yii\redis\Cache]]: implements a cache component based on [Redis](http://redis.io/) key-value store
(redis version 2.6.12 or higher is required).
* [[yii\caching\WinCache]]: uses PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension)
@@ -136,27 +141,31 @@ Yii supports a wide range of cache storage. The following is a summary:
All cache components have the same base class [[yii\caching\Cache]] and thus support the following APIs:
-* [[yii\caching\Cache::get()|get()]]: retrieves a data item from cache with a specified key. A `false`
- value will be returned if the data item is not found in the cache or is expired/invalidated.
+* [[yii\caching\Cache::get()|get()]]: retrieves a data item from cache with a specified key. A `null`
+ value will be returned if the data item is not found in the cache or is expired/invalidated. Alternatively you can specify
+ default value to return by passing it as a second argument.
+* [[yii\caching\Cache::getMultiple()|getMultiple()]]: retrieves multiple data items from cache with the specified keys. For each
+ key if the data item is not found in the cache or is expired/invalidated, `null` is returned. Alternatively you can specify
+ default value to return by passing it as a second argument.
* [[yii\caching\Cache::set()|set()]]: stores a data item identified by a key in cache.
+* [[yii\caching\Cache::setMultiple()|setMultiple()]]: stores multiple data items in cache. Each item is identified by a key.
* [[yii\caching\Cache::add()|add()]]: stores a data item identified by a key in cache if the key is not found in the cache.
+* [[yii\caching\Cache::addMultiple()|addMultiple()]]: stores multiple data items in cache. Each item is identified by a key.
+ If a key already exists in the cache, the data item will be skipped.
* [[yii\caching\Cache::getOrSet()|getOrSet()]]: retrieves a data item from cache with a specified key or executes passed
callback, stores return of the callback in a cache by a key and returns that data.
-* [[yii\caching\Cache::multiGet()|multiGet()]]: retrieves multiple data items from cache with the specified keys.
-* [[yii\caching\Cache::multiSet()|multiSet()]]: stores multiple data items in cache. Each item is identified by a key.
-* [[yii\caching\Cache::multiAdd()|multiAdd()]]: stores multiple data items in cache. Each item is identified by a key.
- If a key already exists in the cache, the data item will be skipped.
-* [[yii\caching\Cache::exists()|exists()]]: returns a value indicating whether the specified key is found in the cache.
+* [[yii\caching\Cache::has()|has()]]: returns a value indicating whether the specified key is found in the cache.
* [[yii\caching\Cache::delete()|delete()]]: removes a data item identified by a key from the cache.
-* [[yii\caching\Cache::flush()|flush()]]: removes all data items from the cache.
+* [[yii\caching\Cache::deleteMultiple()|deleteMultiple()]]: removes multiple data items identified by array of keys from cache.
+* [[yii\caching\Cache::clear()|clear()]]: removes all data items from the cache.
-> Note: Do not cache a `false` boolean value directly because the [[yii\caching\Cache::get()|get()]] method uses
-`false` return value to indicate the data item is not found in the cache. You may put `false` in an array and cache
+> Note: Do not cache a `null` value directly because the [[yii\caching\Cache::get()|get()]] method uses
+`null` return value to indicate the data item is not found in the cache. You may put `null` in an array and cache
this array instead to avoid this problem.
Some cache storage, such as MemCache, APC, support retrieving multiple cached values in a batch mode,
-which may reduce the overhead involved in retrieving cached data. The APIs [[yii\caching\Cache::multiGet()|multiGet()]]
-and [[yii\caching\Cache::multiAdd()|multiAdd()]] are provided to exploit this feature. In case the underlying cache storage
+which may reduce the overhead involved in retrieving cached data. The APIs [[yii\caching\Cache::getMultiple()|getMultiple()]]
+and [[yii\caching\Cache::addMultiple()|addMultiple()]] are provided to exploit this feature. In case the underlying cache storage
does not support this feature, it will be simulated.
Because [[yii\caching\Cache]] implements `ArrayAccess`, a cache component can be used like an array. The following
@@ -191,19 +200,22 @@ For example, [[yii\db\Schema]] uses the following key to cache schema informatio
As you can see, the key includes all necessary information needed to uniquely specify a database table.
-> Note: Values stored in cache via [[yii\caching\Cache::multiSet()|multiSet()]] or [[yii\caching\Cache::multiAdd()|multiAdd()]] can
+> Note: Values stored in cache via [[yii\caching\Cache::setMultiple()|setMultiple()]] or [[yii\caching\Cache::addMultiple()|addMultiple()]] can
have only string or integer keys. If you need to set more complex key store the value separately via
[[yii\caching\Cache::set()|set()]] or [[yii\caching\Cache::add()|add()]].
When the same cache storage is used by different applications, you should specify a unique cache key prefix
-for each application to avoid conflicts of cache keys. This can be done by configuring the [[yii\caching\Cache::keyPrefix]]
+for each application to avoid conflicts of cache keys. This can be done by configuring the [[yii\caching\SimpleCache::keyPrefix]]
property. For example, in the application configuration you can write the following code:
```php
'components' => [
'cache' => [
- 'class' => 'yii\caching\ApcCache',
- 'keyPrefix' => 'myapp', // a unique cache key prefix
+ 'class' => 'yii\caching\Cache',
+ 'handler' => [
+ 'class' => 'yii\caching\ApcCache',
+ 'keyPrefix' => 'myapp', // a unique cache key prefix
+ ],
],
],
```
@@ -227,14 +239,13 @@ $cache->set($key, $data, 45);
sleep(50);
$data = $cache->get($key);
-if ($data === false) {
+if ($data === null) {
// $data is expired or is not found in the cache
}
```
-Since 2.0.11 you may set [[yii\caching\Cache::$defaultDuration|defaultDuration]] value in your cache component configuration if you prefer a custom cache duration
-over the default unlimited duration.
-This will allow you not to pass custom `duration` parameter to [[yii\caching\Cache::set()|set()]] each time.
+Since 2.0.11 you may set [[yii\caching\SimpleCache::$defaultTtl|defaultTtl]] value in your cache component handler configuration if you prefer a custom cache duration over the default unlimited duration.
+This will allow you not to pass custom `ttl` parameter to [[yii\caching\Cache::set()|set()]] each time.
### Cache Dependencies
@@ -272,9 +283,9 @@ Below is a summary of the available cache dependencies:
- [[yii\caching\TagDependency]]: associates a cached data item with one or multiple tags. You may invalidate
the cached data items with the specified tag(s) by calling [[yii\caching\TagDependency::invalidate()]].
-> Note: Avoid using [[yii\caching\Cache::exists()|exists()]] method along with dependencies. It does not check whether
+> Note: Avoid using [[yii\caching\Cache::has()|has()]] method along with dependencies. It does not check whether
the dependency associated with the cached data, if there is any, has changed. So a call to
- [[yii\caching\Cache::get()|get()]] may return `false` while [[yii\caching\Cache::exists()|exists()]] returns `true`.
+ [[yii\caching\Cache::get()|get()]] may return `false` while [[yii\caching\Cache::has()|has()]] returns `true`.
## Query Caching
@@ -309,15 +320,15 @@ $result = Customer::getDb()->cache(function ($db) {
and are potentially more efficient.
-### Cache Flushing
+### Clearing Cache
-When you need to invalidate all the stored cache data, you can call [[yii\caching\Cache::flush()]].
+When you need to invalidate all the stored cache data, you can call [[yii\caching\Cache::clear()]].
-You can flush the cache from the console by calling `yii cache/flush` as well.
+You can flush the cache from the console by calling `yii cache/clear` as well.
- `yii cache`: lists the available caches in application
- - `yii cache/flush cache1 cache2`: flushes the cache components `cache1`, `cache2` (you can pass multiple component
+ - `yii cache/clear cache1 cache2`: clears the cache components `cache1`, `cache2` (you can pass multiple component
names separated with space)
- - `yii cache/flush-all`: flushes all cache components in the application
+ - `yii cache/clear-all`: clears all cache components in the application
> Info: Console application uses a separate configuration file by default. Ensure, that you have the same caching
components in your web and console application configs to reach the proper effect.
diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md
index c694f3cd2ae..a47fa3b5b77 100644
--- a/framework/CHANGELOG.md
+++ b/framework/CHANGELOG.md
@@ -4,7 +4,8 @@ Yii Framework 2 Change Log
2.1.0 under development
-----------------------
-- Enh #13799: CAPTCHA rendering logic extracted into `yii\captcha\DriverInterface`, which instance is available via `yii\captcha\CaptchaAction::$driver` field (vladis84, klimov-paul)
+- Enh #879: Caching implementation refactored according to PSR-16 'Simple Cache' specification (klimov-paul)
+- Enh #13799: CAPTCHA rendering logic extracted into `yii\captcha\DriverInterface`, which instance is available via `yii\captcha\CaptchaAction::$driver` field (vladis84, klimov-paul)
- Enh #9260: Mail view rendering encapsulated into `yii\mail\Template` class allowing rendering in isolation and access to `yii\mail\MessageInterface` instance via `$this->context->message` inside the view (klimov-paul)
- Enh #11058: Add `$checkAjax` parameter to method `yii\web\Controller::redirect()` which controls redirection in AJAX and PJAX requests (ivanovyordan)
- Enh #12385: Methods `addHeader()`, `setHeader()`, `getHeader()`, `setHeaders()` have been added to `yii\i18n\MessageInterface` allowing setup of custom message headers (klimov-paul)
diff --git a/framework/UPGRADE.md b/framework/UPGRADE.md
index 27f62deb967..ba53125b768 100644
--- a/framework/UPGRADE.md
+++ b/framework/UPGRADE.md
@@ -73,6 +73,17 @@ Upgrade from Yii 2.0.x
instance is available via `yii\captcha\CaptchaAction::$driver` field. All image settings now should be passed to
the driver fields instead of action. Automatic detection of the rendering driver is no longer supported.
* `yii\captcha\Captcha::checkRequirements()` method has been removed.
+* All cache related classes interface has been changed according to PSR-16 "Simple Cache" specification. Make sure you
+ change your invocations for the cache methods accordingly. The most notable changes affects methods `get()` and `getMultiple()`
+ as they now accept `$default` argument, which value will be returned in case there is no value in the cache. This makes
+ the default return value to be `null` instead of `false`.
+* Particular cache implementation should now be configured as `yii\caching\Cache::$handler` property instead of the
+ component itself. Properties `$defaultTtl`, `$serializer` and `$keyPrefix` has been moved to cache handler and should
+ be configured there. Creating your own cache implementation you should implement `\Psr\SimpleCache\CacheInterface` or
+ extend `yii\caching\SimpleCache` abstract class. Use `yii\caching\CacheInterface` only if you wish to replace `yii\caching\Cache`
+ component providing your own solution for cache dependency handling.
+* Console command used to clear cache now calls related actions "clear" instead of "flush".
+
Upgrade from Yii 2.0.12
-----------------------
diff --git a/framework/caching/ApcCache.php b/framework/caching/ApcCache.php
index b9a2d8171f6..d132e731afb 100644
--- a/framework/caching/ApcCache.php
+++ b/framework/caching/ApcCache.php
@@ -15,14 +15,31 @@
* To use this application component, the [APCu PHP extension](http://www.php.net/apcu) must be loaded.
* In order to enable APCu for CLI you should add "apc.enable_cli = 1" to your php.ini.
*
- * See [[Cache]] for common cache operations that ApcCache supports.
+ * Application configuration example:
+ *
+ * ```php
+ * return [
+ * 'components' => [
+ * 'cache' => [
+ * 'class' => yii\caching\Cache::class,
+ * 'handler' => [
+ * 'class' => yii\caching\ApcCache::class,
+ * ],
+ * ],
+ * // ...
+ * ],
+ * // ...
+ * ];
+ * ```
+ *
+ * See [[\Psr\SimpleCache\CacheInterface]] for common cache operations that ApcCache supports.
*
* For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview).
*
* @author Qiang Xue
* @since 2.0
*/
-class ApcCache extends Cache
+class ApcCache extends SimpleCache
{
/**
* Initializes this application component.
@@ -38,27 +55,15 @@ public function init()
}
/**
- * Checks whether a specified key exists in the cache.
- * This can be faster than getting the value from the cache if the data is big.
- * Note that this method does not check whether the dependency associated
- * with the cached data, if there is any, has changed. So a call to [[get]]
- * may return false while exists returns true.
- * @param mixed $key a key identifying the cached value. This can be a simple string or
- * a complex data structure consisting of factors representing the key.
- * @return bool true if a value exists in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
- public function exists($key)
+ public function has($key)
{
- $key = $this->buildKey($key);
-
- return apcu_exists($key);
+ return apcu_exists($this->normalizeKey($key));
}
/**
- * Retrieves a value from cache with a specified key.
- * This is the implementation of the method declared in the parent class.
- * @param string $key a unique key identifying the cached value
- * @return mixed|false the value stored in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
protected function getValue($key)
{
@@ -66,9 +71,7 @@ protected function getValue($key)
}
/**
- * Retrieves multiple values from cache with the specified keys.
- * @param array $keys a list of keys identifying the cached values
- * @return array a list of cached values indexed by the keys
+ * {@inheritdoc}
*/
protected function getValues($keys)
{
@@ -77,63 +80,24 @@ protected function getValues($keys)
}
/**
- * Stores a value identified by a key in cache.
- * This is the implementation of the method declared in the parent class.
- *
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]],
- * it could be something else.
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise.
- */
- protected function setValue($key, $value, $duration)
- {
- return apcu_store($key, $value, $duration);
- }
-
- /**
- * Stores multiple key-value pairs in cache.
- * @param array $data array where key corresponds to cache key while value
- * @param int $duration the number of seconds in which the cached values will expire. 0 means never expire.
- * @return array array of failed keys
- */
- protected function setValues($data, $duration)
- {
- $result = apcu_store($data, null, $duration);
- return is_array($result) ? array_keys($result) : [];
- }
-
- /**
- * Stores a value identified by a key into cache if the cache does not contain this key.
- * This is the implementation of the method declared in the parent class.
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]],
- * it could be something else.
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
+ * {@inheritdoc}
*/
- protected function addValue($key, $value, $duration)
+ protected function setValue($key, $value, $ttl)
{
- return apcu_add($key, $value, $duration);
+ return apcu_store($key, $value, $ttl);
}
/**
- * Adds multiple key-value pairs to cache.
- * @param array $data array where key corresponds to cache key while value is the value stored
- * @param int $duration the number of seconds in which the cached values will expire. 0 means never expire.
- * @return array array of failed keys
+ * {@inheritdoc}
*/
- protected function addValues($data, $duration)
+ protected function setValues($values, $ttl)
{
- $result = apcu_add($data, null, $duration);
- return is_array($result) ? array_keys($result) : [];
+ $result = apcu_store($values, null, $ttl);
+ return is_array($result);
}
/**
- * Deletes a value with the specified key from cache
- * This is the implementation of the method declared in the parent class.
- * @param string $key the key of the value to be deleted
- * @return bool if no error happens during deletion
+ * {@inheritdoc}
*/
protected function deleteValue($key)
{
@@ -141,11 +105,9 @@ protected function deleteValue($key)
}
/**
- * Deletes all values from cache.
- * This is the implementation of the method declared in the parent class.
- * @return bool whether the flush operation was successful.
+ * {@inheritdoc}
*/
- protected function flushValues()
+ public function clear()
{
return apcu_clear_cache();
}
diff --git a/framework/caching/ArrayCache.php b/framework/caching/ArrayCache.php
index e7de9d40da2..439dd9fa43a 100644
--- a/framework/caching/ArrayCache.php
+++ b/framework/caching/ArrayCache.php
@@ -10,9 +10,26 @@
/**
* ArrayCache provides caching for the current request only by storing the values in an array.
*
- * See [[Cache]] for common cache operations that ArrayCache supports.
+ * Application configuration example:
*
- * Unlike the [[Cache]], ArrayCache allows the expire parameter of [[set]], [[add]], [[multiSet]] and [[multiAdd]] to
+ * ```php
+ * return [
+ * 'components' => [
+ * 'cache' => [
+ * 'class' => yii\caching\Cache::class,
+ * 'handler' => [
+ * 'class' => yii\caching\ArrayCache::class,
+ * ],
+ * ],
+ * // ...
+ * ],
+ * // ...
+ * ];
+ * ```
+ *
+ * See [[\Psr\SimpleCache\CacheInterface]] for common cache operations that ArrayCache supports.
+ *
+ * Unlike the [[Cache]], ArrayCache allows the expire parameter of [[set()]] and [[setMultiple()]] to
* be a floating point number, so you may specify the time in milliseconds (e.g. 0.1 will be 100 milliseconds).
*
* For enhanced performance of ArrayCache, you can disable serialization of the stored data by setting [[$serializer]] to `false`.
@@ -22,17 +39,20 @@
* @author Carsten Brandt
* @since 2.0
*/
-class ArrayCache extends Cache
+class ArrayCache extends SimpleCache
{
- private $_cache;
+ /**
+ * @var array cached values.
+ */
+ private $_cache = [];
/**
* @inheritdoc
*/
- public function exists($key)
+ public function has($key)
{
- $key = $this->buildKey($key);
+ $key = $this->normalizeKey($key);
return isset($this->_cache[$key]) && ($this->_cache[$key][1] === 0 || $this->_cache[$key][1] > microtime(true));
}
@@ -50,21 +70,9 @@ protected function getValue($key)
/**
* @inheritdoc
*/
- protected function setValue($key, $value, $duration)
+ protected function setValue($key, $value, $ttl)
{
- $this->_cache[$key] = [$value, $duration === 0 ? 0 : microtime(true) + $duration];
- return true;
- }
-
- /**
- * @inheritdoc
- */
- protected function addValue($key, $value, $duration)
- {
- if (isset($this->_cache[$key]) && ($this->_cache[$key][1] === 0 || $this->_cache[$key][1] > microtime(true))) {
- return false;
- }
- $this->_cache[$key] = [$value, $duration === 0 ? 0 : microtime(true) + $duration];
+ $this->_cache[$key] = [$value, $ttl === 0 ? 0 : microtime(true) + $ttl];
return true;
}
@@ -80,7 +88,7 @@ protected function deleteValue($key)
/**
* @inheritdoc
*/
- protected function flushValues()
+ public function clear()
{
$this->_cache = [];
return true;
diff --git a/framework/caching/Cache.php b/framework/caching/Cache.php
index f3f5eb81acc..282d1f64315 100644
--- a/framework/caching/Cache.php
+++ b/framework/caching/Cache.php
@@ -9,10 +9,31 @@
use Yii;
use yii\base\Component;
+use yii\di\Instance;
use yii\helpers\StringHelper;
/**
- * Cache is the base class for cache classes supporting different cache storage implementations.
+ * Cache provides support for the data caching, including cache key composition and dependencies.
+ * The actual data caching is performed via [[handler]], which should be configured to be [[\Psr\SimpleCache\CacheInterface]]
+ * instance.
+ *
+ * Application configuration example:
+ *
+ * ```php
+ * return [
+ * 'components' => [
+ * 'cache' => [
+ * 'class' => yii\caching\Cache::class,
+ * 'handler' => [
+ * 'class' => yii\caching\FileCache::class,
+ * 'cachePath' => '@runtime/cache',
+ * ],
+ * ],
+ * // ...
+ * ],
+ * // ...
+ * ];
+ * ```
*
* A data item can be stored in the cache by calling [[set()]] and be retrieved back
* later (in the same or different request) by [[get()]]. In both operations,
@@ -25,7 +46,7 @@
* ```php
* $key = 'demo';
* $data = $cache->get($key);
- * if ($data === false) {
+ * if ($data === null) {
* // ...generate $data here...
* $cache->set($key, $data, $duration, $dependency);
* }
@@ -38,112 +59,79 @@
* echo $cache['foo'];
* ```
*
- * Derived classes should implement the following methods which do the actual cache storage operations:
- *
- * - [[getValue()]]: retrieve the value with a key (if any) from cache
- * - [[setValue()]]: store the value with a key into cache
- * - [[addValue()]]: store the value only if the cache does not have this key before
- * - [[deleteValue()]]: delete the value with the specified key from cache
- * - [[flushValues()]]: delete all values from cache
- *
- * For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview).
+ * For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview)
+ * and [PSR-16 specification](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-16-simple-cache.md).
*
* @author Qiang Xue
* @since 2.0
*/
-abstract class Cache extends Component implements CacheInterface
+class Cache extends Component implements CacheInterface
{
/**
- * @var string a string prefixed to every cache key so that it is unique globally in the whole cache storage.
- * It is recommended that you set a unique cache key prefix for each application if the same cache
- * storage is being used by different applications.
- *
- * To ensure interoperability, only alphanumeric characters should be used.
- */
- public $keyPrefix;
- /**
- * @var null|array|false the functions used to serialize and unserialize cached data. Defaults to null, meaning
- * using the default PHP `serialize()` and `unserialize()` functions. If you want to use some more efficient
- * serializer (e.g. [igbinary](http://pecl.php.net/package/igbinary)), you may configure this property with
- * a two-element array. The first element specifies the serialization function, and the second the deserialization
- * function. If this property is set false, data will be directly sent to and retrieved from the underlying
- * cache component without any serialization or deserialization. You should not turn off serialization if
- * you are using [[Dependency|cache dependency]], because it relies on data serialization. Also, some
- * implementations of the cache can not correctly save and retrieve data different from a string type.
+ * @var \Psr\SimpleCache\CacheInterface|array|\Closure|string actual cache handler or its DI compatible configuration.
+ * After the Cache object is created, if you want to change this property, you should only assign it
+ * with a [[\Psr\SimpleCache\CacheInterface]] instance.
+ * @since 2.1.0
*/
- public $serializer;
+ public $handler;
+
+
/**
- * @var int default duration in seconds before a cache entry will expire. Default value is 0, meaning infinity.
- * This value is used by [[set()]] if the duration is not explicitly given.
- * @since 2.0.11
+ * {@inheritdoc}
*/
- public $defaultDuration = 0;
-
+ public function init()
+ {
+ parent::init();
+ $this->handler = Instance::ensure($this->handler instanceof \Closure ? call_user_func($this->handler) : $this->handler, \Psr\SimpleCache\CacheInterface::class);
+ }
/**
* Builds a normalized cache key from a given key.
*
* If the given key is a string containing alphanumeric characters only and no more than 32 characters,
- * then the key will be returned back prefixed with [[keyPrefix]]. Otherwise, a normalized key
- * is generated by serializing the given key, applying MD5 hashing, and prefixing with [[keyPrefix]].
+ * then the key will be returned back as it is. Otherwise, a normalized key is generated by serializing
+ * the given key and applying MD5 hashing.
*
* @param mixed $key the key to be normalized
* @return string the generated cache key
*/
- public function buildKey($key)
+ protected function buildKey($key)
{
if (is_string($key)) {
- $key = ctype_alnum($key) && StringHelper::byteLength($key) <= 32 ? $key : md5($key);
- } else {
- $key = md5(json_encode($key));
+ return ctype_alnum($key) && StringHelper::byteLength($key) <= 32 ? $key : md5($key);
}
-
- return $this->keyPrefix . $key;
+ return md5(json_encode($key));
}
/**
- * Retrieves a value from cache with a specified key.
- * @param mixed $key a key identifying the cached value. This can be a simple string or
- * a complex data structure consisting of factors representing the key.
- * @return mixed the value stored in cache, false if the value is not in the cache, expired,
- * or the dependency associated with the cached data has changed.
+ * {@inheritdoc}
*/
- public function get($key)
+ public function get($key, $default = null)
{
$key = $this->buildKey($key);
- $value = $this->getValue($key);
- if ($value === false || $this->serializer === false) {
- return $value;
- } elseif ($this->serializer === null) {
- $value = unserialize($value);
- } else {
- $value = call_user_func($this->serializer[1], $value);
+ $value = $this->handler->get($key);
+
+ if ($value === null) {
+ return $default;
}
- if (is_array($value) && !($value[1] instanceof Dependency && $value[1]->isChanged($this))) {
+
+ if (is_array($value) && isset($value[1]) && $value[1] instanceof Dependency) {
+ if ($value[1]->isChanged($this)) {
+ return $default;
+ }
return $value[0];
}
- return false;
+ return $value;
}
/**
- * Checks whether a specified key exists in the cache.
- * This can be faster than getting the value from the cache if the data is big.
- * In case a cache does not support this feature natively, this method will try to simulate it
- * but has no performance improvement over getting it.
- * Note that this method does not check whether the dependency associated
- * with the cached data, if there is any, has changed. So a call to [[get]]
- * may return false while exists returns true.
- * @param mixed $key a key identifying the cached value. This can be a simple string or
- * a complex data structure consisting of factors representing the key.
- * @return bool true if a value exists in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
- public function exists($key)
+ public function has($key)
{
$key = $this->buildKey($key);
- $value = $this->getValue($key);
-
- return $value !== false;
+ return $this->handler->has($key);
}
/**
@@ -152,32 +140,32 @@ public function exists($key)
* which may improve the performance. In case a cache does not support this feature natively,
* this method will try to simulate it.
* @param string[] $keys list of string keys identifying the cached values
+ * @param mixed $default Default value to return for keys that do not exist.
* @return array list of cached values corresponding to the specified keys. The array
* is returned in terms of (key, value) pairs.
* If a value is not cached or expired, the corresponding array value will be false.
* @since 2.0.7
*/
- public function multiGet($keys)
+ public function getMultiple($keys, $default = null)
{
$keyMap = [];
foreach ($keys as $key) {
$keyMap[$key] = $this->buildKey($key);
}
- $values = $this->getValues(array_values($keyMap));
+ $values = $this->handler->getMultiple(array_values($keyMap));
$results = [];
foreach ($keyMap as $key => $newKey) {
- $results[$key] = false;
+ $results[$key] = $default;
if (isset($values[$newKey])) {
- if ($this->serializer === false) {
- $results[$key] = $values[$newKey];
- } else {
- $value = $this->serializer === null ? unserialize($values[$newKey])
- : call_user_func($this->serializer[1], $values[$newKey]);
-
- if (is_array($value) && !($value[1] instanceof Dependency && $value[1]->isChanged($this))) {
- $results[$key] = $value[0];
+ $value = $values[$newKey];
+ if (is_array($value) && isset($value[1]) && $value[1] instanceof Dependency) {
+ if ($value[1]->isChanged($this)) {
+ continue;
+ } else {
+ $value = $value[0];
}
}
+ $results[$key] = $value;
}
}
@@ -192,30 +180,20 @@ public function multiGet($keys)
* @param mixed $key a key identifying the value to be cached. This can be a simple string or
* a complex data structure consisting of factors representing the key.
* @param mixed $value the value to be cached
- * @param int $duration default duration in seconds before the cache will expire. If not set,
- * default [[defaultDuration]] value is used.
+ * @param null|int|\DateInterval $ttl the TTL value of this item. If not set, default value is used.
* @param Dependency $dependency dependency of the cached item. If the dependency changes,
* the corresponding value in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return bool whether the value is successfully stored into cache
*/
- public function set($key, $value, $duration = null, $dependency = null)
+ public function set($key, $value, $ttl = null, $dependency = null)
{
- if ($duration === null) {
- $duration = $this->defaultDuration;
- }
-
- if ($dependency !== null && $this->serializer !== false) {
+ if ($dependency !== null) {
$dependency->evaluateDependency($this);
- }
- if ($this->serializer === null) {
- $value = serialize([$value, $dependency]);
- } elseif ($this->serializer !== false) {
- $value = call_user_func($this->serializer[0], [$value, $dependency]);
+ $value = [$value, $dependency];
}
$key = $this->buildKey($key);
-
- return $this->setValue($key, $value, $duration);
+ return $this->handler->set($key, $value, $ttl);
}
/**
@@ -224,65 +202,79 @@ public function set($key, $value, $duration = null, $dependency = null)
* expiration time will be replaced with the new ones, respectively.
*
* @param array $items the items to be cached, as key-value pairs.
- * @param int $duration default number of seconds in which the cached values will expire. 0 means never expire.
+ * @param null|int|\DateInterval $ttl the TTL value of this item. If not set, default value is used.
* @param Dependency $dependency dependency of the cached items. If the dependency changes,
* the corresponding values in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return array array of failed keys
* @since 2.0.7
*/
- public function multiSet($items, $duration = 0, $dependency = null)
+ public function setMultiple($items, $ttl = 0, $dependency = null)
{
- if ($dependency !== null && $this->serializer !== false) {
+ if ($dependency !== null) {
$dependency->evaluateDependency($this);
}
$data = [];
foreach ($items as $key => $value) {
- if ($this->serializer === null) {
- $value = serialize([$value, $dependency]);
- } elseif ($this->serializer !== false) {
- $value = call_user_func($this->serializer[0], [$value, $dependency]);
+ if ($dependency !== null) {
+ $value = [$value, $dependency];
}
-
$key = $this->buildKey($key);
$data[$key] = $value;
}
- return $this->setValues($data, $duration);
+ return $this->handler->setMultiple($data, $ttl);
+ }
+
+ /**
+ * {@inheritdoc}
+ * @since 2.1
+ */
+ public function deleteMultiple($keys)
+ {
+ $actualKeys = [];
+ foreach ($keys as $key) {
+ $actualKeys[] = $this->buildKey($key);
+ }
+ return $this->handler->deleteMultiple($actualKeys);
}
/**
* Stores multiple items in cache. Each item contains a value identified by a key.
* If the cache already contains such a key, the existing value and expiration time will be preserved.
*
- * @param array $items the items to be cached, as key-value pairs.
- * @param int $duration default number of seconds in which the cached values will expire. 0 means never expire.
+ * @param array $values the items to be cached, as key-value pairs.
+ * @param null|int|\DateInterval $ttl the TTL value of this item. If not set, default value is used.
* @param Dependency $dependency dependency of the cached items. If the dependency changes,
* the corresponding values in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return array array of failed keys
* @since 2.0.7
*/
- public function multiAdd($items, $duration = 0, $dependency = null)
+ public function addMultiple($values, $ttl = 0, $dependency = null)
{
- if ($dependency !== null && $this->serializer !== false) {
+ if ($dependency !== null) {
$dependency->evaluateDependency($this);
}
$data = [];
- foreach ($items as $key => $value) {
- if ($this->serializer === null) {
- $value = serialize([$value, $dependency]);
- } elseif ($this->serializer !== false) {
- $value = call_user_func($this->serializer[0], [$value, $dependency]);
+ foreach ($values as $key => $value) {
+ if ($dependency !== null) {
+ $value = [$value, $dependency];
}
$key = $this->buildKey($key);
$data[$key] = $value;
}
- return $this->addValues($data, $duration);
+ $existingValues = $this->handler->getMultiple(array_keys($data));
+ foreach ($existingValues as $key => $value) {
+ if ($value !== null) {
+ unset($data[$key]);
+ }
+ }
+ return $this->handler->setMultiple($data, $ttl);
}
/**
@@ -291,25 +283,26 @@ public function multiAdd($items, $duration = 0, $dependency = null)
* @param mixed $key a key identifying the value to be cached. This can be a simple string or
* a complex data structure consisting of factors representing the key.
* @param mixed $value the value to be cached
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
+ * @param null|int|\DateInterval $ttl the TTL value of this item. If not set, default value is used.
* @param Dependency $dependency dependency of the cached item. If the dependency changes,
* the corresponding value in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return bool whether the value is successfully stored into cache
*/
- public function add($key, $value, $duration = 0, $dependency = null)
+ public function add($key, $value, $ttl = null, $dependency = null)
{
- if ($dependency !== null && $this->serializer !== false) {
+ if ($dependency !== null) {
$dependency->evaluateDependency($this);
+ $value = [$value, $dependency];
}
- if ($this->serializer === null) {
- $value = serialize([$value, $dependency]);
- } elseif ($this->serializer !== false) {
- $value = call_user_func($this->serializer[0], [$value, $dependency]);
- }
+
$key = $this->buildKey($key);
- return $this->addValue($key, $value, $duration);
+ if ($this->handler->has($key)) {
+ return false;
+ }
+
+ return $this->handler->set($key, $value, $ttl);
}
/**
@@ -322,7 +315,7 @@ public function delete($key)
{
$key = $this->buildKey($key);
- return $this->deleteValue($key);
+ return $this->handler->delete($key);
}
/**
@@ -330,116 +323,9 @@ public function delete($key)
* Be careful of performing this operation if the cache is shared among multiple applications.
* @return bool whether the flush operation was successful.
*/
- public function flush()
- {
- return $this->flushValues();
- }
-
- /**
- * Retrieves a value from cache with a specified key.
- * This method should be implemented by child classes to retrieve the data
- * from specific cache storage.
- * @param string $key a unique key identifying the cached value
- * @return mixed|false the value stored in cache, false if the value is not in the cache or expired. Most often
- * value is a string. If you have disabled [[serializer]], it could be something else.
- */
- abstract protected function getValue($key);
-
- /**
- * Stores a value identified by a key in cache.
- * This method should be implemented by child classes to store the data
- * in specific cache storage.
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]],
- * it could be something else.
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
- */
- abstract protected function setValue($key, $value, $duration);
-
- /**
- * Stores a value identified by a key into cache if the cache does not contain this key.
- * This method should be implemented by child classes to store the data
- * in specific cache storage.
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]],
- * it could be something else.
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
- */
- abstract protected function addValue($key, $value, $duration);
-
- /**
- * Deletes a value with the specified key from cache
- * This method should be implemented by child classes to delete the data from actual cache storage.
- * @param string $key the key of the value to be deleted
- * @return bool if no error happens during deletion
- */
- abstract protected function deleteValue($key);
-
- /**
- * Deletes all values from cache.
- * Child classes may implement this method to realize the flush operation.
- * @return bool whether the flush operation was successful.
- */
- abstract protected function flushValues();
-
- /**
- * Retrieves multiple values from cache with the specified keys.
- * The default implementation calls [[getValue()]] multiple times to retrieve
- * the cached values one by one. If the underlying cache storage supports multiget,
- * this method should be overridden to exploit that feature.
- * @param array $keys a list of keys identifying the cached values
- * @return array a list of cached values indexed by the keys
- */
- protected function getValues($keys)
- {
- $results = [];
- foreach ($keys as $key) {
- $results[$key] = $this->getValue($key);
- }
-
- return $results;
- }
-
- /**
- * Stores multiple key-value pairs in cache.
- * The default implementation calls [[setValue()]] multiple times store values one by one. If the underlying cache
- * storage supports multi-set, this method should be overridden to exploit that feature.
- * @param array $data array where key corresponds to cache key while value is the value stored
- * @param int $duration the number of seconds in which the cached values will expire. 0 means never expire.
- * @return array array of failed keys
- */
- protected function setValues($data, $duration)
+ public function clear()
{
- $failedKeys = [];
- foreach ($data as $key => $value) {
- if ($this->setValue($key, $value, $duration) === false) {
- $failedKeys[] = $key;
- }
- }
-
- return $failedKeys;
- }
-
- /**
- * Adds multiple key-value pairs to cache.
- * The default implementation calls [[addValue()]] multiple times add values one by one. If the underlying cache
- * storage supports multi-add, this method should be overridden to exploit that feature.
- * @param array $data array where key corresponds to cache key while value is the value stored.
- * @param int $duration the number of seconds in which the cached values will expire. 0 means never expire.
- * @return array array of failed keys
- */
- protected function addValues($data, $duration)
- {
- $failedKeys = [];
- foreach ($data as $key => $value) {
- if ($this->addValue($key, $value, $duration) === false) {
- $failedKeys[] = $key;
- }
- }
-
- return $failedKeys;
+ return $this->handler->clear();
}
/**
@@ -506,22 +392,21 @@ public function offsetUnset($key)
* a complex data structure consisting of factors representing the key.
* @param callable|\Closure $callable the callable or closure that will be used to generate a value to be cached.
* In case $callable returns `false`, the value will not be cached.
- * @param int $duration default duration in seconds before the cache will expire. If not set,
- * [[defaultDuration]] value will be used.
+ * @param null|int|\DateInterval $ttl the TTL value of this item. If not set, default value is used.
* @param Dependency $dependency dependency of the cached item. If the dependency changes,
* the corresponding value in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is `false`.
* @return mixed result of $callable execution
* @since 2.0.11
*/
- public function getOrSet($key, $callable, $duration = null, $dependency = null)
+ public function getOrSet($key, $callable, $ttl = null, $dependency = null)
{
- if (($value = $this->get($key)) !== false) {
+ if (($value = $this->get($key)) !== null) {
return $value;
}
$value = call_user_func($callable, $this);
- if (!$this->set($key, $value, $duration, $dependency)) {
+ if (!$this->set($key, $value, $ttl, $dependency)) {
Yii::warning('Failed to set cache value for key ' . json_encode($key), __METHOD__);
}
diff --git a/framework/caching/CacheInterface.php b/framework/caching/CacheInterface.php
index 426724044a0..13eff214fc0 100644
--- a/framework/caching/CacheInterface.php
+++ b/framework/caching/CacheInterface.php
@@ -8,7 +8,8 @@
namespace yii\caching;
/**
- * CacheInterface is the base interface for cache.
+ * CacheInterface defines the common interface to be implemented by cache classes.
+ * It extends [[\Psr\SimpleCache\CacheInterface]] adding ability for cache dependency specification.
*
* A data item can be stored in the cache by calling [[set()]] and be retrieved back
* later (in the same or different request) by [[get()]]. In both operations,
@@ -21,7 +22,7 @@
* ```php
* $key = 'demo';
* $data = $cache->get($key);
- * if ($data === false) {
+ * if ($data === null) {
* // ...generate $data here...
* $cache->set($key, $data, $duration, $dependency);
* }
@@ -34,61 +35,18 @@
* echo $cache['foo'];
* ```
*
- * For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview).
+ * For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview)
+ * and [PSR-16 specification](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-16-simple-cache.md).
+ *
+ * @see \Psr\SimpleCache\CacheInterface
*
* @author Qiang Xue
* @author Dmitry Naumenko
- * @since 2.0.13. Previous framework versions used abstract class [[yii\caching\Cache]] as interface.
+ * @author Paul Klimov
+ * @since 2.0.13. Previous framework versions used abstract class [[\yii\caching\Cache]] as interface.
*/
-interface CacheInterface extends \ArrayAccess
+interface CacheInterface extends \Psr\SimpleCache\CacheInterface, \ArrayAccess
{
- /**
- * Builds a normalized cache key from a given key.
- *
- * If the given key is a string containing alphanumeric characters only and no more than 32 characters,
- * then the key will be returned back prefixed with [[keyPrefix]]. Otherwise, a normalized key
- * is generated by serializing the given key, applying MD5 hashing, and prefixing with [[keyPrefix]].
- *
- * @param mixed $key the key to be normalized
- * @return string the generated cache key
- */
- public function buildKey($key);
-
- /**
- * Retrieves a value from cache with a specified key.
- * @param mixed $key a key identifying the cached value. This can be a simple string or
- * a complex data structure consisting of factors representing the key.
- * @return mixed the value stored in cache, false if the value is not in the cache, expired,
- * or the dependency associated with the cached data has changed.
- */
- public function get($key);
-
- /**
- * Checks whether a specified key exists in the cache.
- * This can be faster than getting the value from the cache if the data is big.
- * In case a cache does not support this feature natively, this method will try to simulate it
- * but has no performance improvement over getting it.
- * Note that this method does not check whether the dependency associated
- * with the cached data, if there is any, has changed. So a call to [[get]]
- * may return false while exists returns true.
- * @param mixed $key a key identifying the cached value. This can be a simple string or
- * a complex data structure consisting of factors representing the key.
- * @return bool true if a value exists in cache, false if the value is not in the cache or expired.
- */
- public function exists($key);
-
- /**
- * Retrieves multiple values from cache with the specified keys.
- * Some caches (such as memcache, apc) allow retrieving multiple cached values at the same time,
- * which may improve the performance. In case a cache does not support this feature natively,
- * this method will try to simulate it.
- * @param string[] $keys list of string keys identifying the cached values
- * @return array list of cached values corresponding to the specified keys. The array
- * is returned in terms of (key, value) pairs.
- * If a value is not cached or expired, the corresponding array value will be false.
- */
- public function multiGet($keys);
-
/**
* Stores a value identified by a key into cache.
* If the cache already contains such a key, the existing value and
@@ -97,14 +55,13 @@ public function multiGet($keys);
* @param mixed $key a key identifying the value to be cached. This can be a simple string or
* a complex data structure consisting of factors representing the key.
* @param mixed $value the value to be cached
- * @param int $duration default duration in seconds before the cache will expire. If not set,
- * default [[defaultDuration]] value is used.
+ * @param null|int|\DateInterval $ttl the TTL value of this item. If not set, default value is used.
* @param Dependency $dependency dependency of the cached item. If the dependency changes,
* the corresponding value in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return bool whether the value is successfully stored into cache
*/
- public function set($key, $value, $duration = null, $dependency = null);
+ public function set($key, $value, $ttl = null, $dependency = null);
/**
* Stores multiple items in cache. Each item contains a value identified by a key.
@@ -112,13 +69,13 @@ public function set($key, $value, $duration = null, $dependency = null);
* expiration time will be replaced with the new ones, respectively.
*
* @param array $items the items to be cached, as key-value pairs.
- * @param int $duration default number of seconds in which the cached values will expire. 0 means never expire.
+ * @param null|int|\DateInterval $ttl the TTL value of this item. If not set, default value is used.
* @param Dependency $dependency dependency of the cached items. If the dependency changes,
* the corresponding values in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return array array of failed keys
*/
- public function multiSet($items, $duration = 0, $dependency = null);
+ public function setMultiple($items, $ttl = null, $dependency = null);
/**
* Stores a value identified by a key into cache if the cache does not contain this key.
@@ -126,41 +83,26 @@ public function multiSet($items, $duration = 0, $dependency = null);
* @param mixed $key a key identifying the value to be cached. This can be a simple string or
* a complex data structure consisting of factors representing the key.
* @param mixed $value the value to be cached
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
+ * @param null|int|\DateInterval $ttl the TTL value of this item. If not set, default value is used.
* @param Dependency $dependency dependency of the cached item. If the dependency changes,
* the corresponding value in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return bool whether the value is successfully stored into cache
*/
- public function add($key, $value, $duration = 0, $dependency = null);
+ public function add($key, $value, $ttl = 0, $dependency = null);
/**
* Stores multiple items in cache. Each item contains a value identified by a key.
* If the cache already contains such a key, the existing value and expiration time will be preserved.
*
- * @param array $items the items to be cached, as key-value pairs.
- * @param int $duration default number of seconds in which the cached values will expire. 0 means never expire.
+ * @param array $values the items to be cached, as key-value pairs.
+ * @param null|int|\DateInterval $ttl the TTL value of this item. If not set, default value is used.
* @param Dependency $dependency dependency of the cached items. If the dependency changes,
* the corresponding values in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return array array of failed keys
*/
- public function multiAdd($items, $duration = 0, $dependency = null);
-
- /**
- * Deletes a value with the specified key from cache
- * @param mixed $key a key identifying the value to be deleted from cache. This can be a simple string or
- * a complex data structure consisting of factors representing the key.
- * @return bool if no error happens during deletion
- */
- public function delete($key);
-
- /**
- * Deletes all values from cache.
- * Be careful of performing this operation if the cache is shared among multiple applications.
- * @return bool whether the flush operation was successful.
- */
- public function flush();
+ public function addMultiple($values, $ttl = 0, $dependency = null);
/**
* Method combines both [[set()]] and [[get()]] methods to retrieve value identified by a $key,
@@ -181,12 +123,11 @@ public function flush();
* a complex data structure consisting of factors representing the key.
* @param callable|\Closure $callable the callable or closure that will be used to generate a value to be cached.
* In case $callable returns `false`, the value will not be cached.
- * @param int $duration default duration in seconds before the cache will expire. If not set,
- * [[defaultDuration]] value will be used.
+ * @param null|int|\DateInterval $ttl the TTL value of this item. If not set, default value is used.
* @param Dependency $dependency dependency of the cached item. If the dependency changes,
* the corresponding value in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is `false`.
* @return mixed result of $callable execution
*/
- public function getOrSet($key, $callable, $duration = null, $dependency = null);
+ public function getOrSet($key, $callable, $ttl = null, $dependency = null);
}
diff --git a/framework/caching/DbCache.php b/framework/caching/DbCache.php
index 3a4ec8002b4..20c1a60c89c 100644
--- a/framework/caching/DbCache.php
+++ b/framework/caching/DbCache.php
@@ -19,16 +19,25 @@
* By default, DbCache stores session data in a DB table named 'cache'. This table
* must be pre-created. The table name can be changed by setting [[cacheTable]].
*
- * Please refer to [[Cache]] for common cache operations that are supported by DbCache.
+ * Please refer to [[\Psr\SimpleCache\CacheInterface]] for common cache operations that are supported by DbCache.
*
* The following example shows how you can configure the application to use DbCache:
*
* ```php
- * 'cache' => [
- * 'class' => \yii\caching\DbCache::class,
- * // 'db' => 'mydb',
- * // 'cacheTable' => 'my_cache',
- * ]
+ * return [
+ * 'components' => [
+ * 'cache' => [
+ * 'class' => yii\caching\Cache:class,
+ * 'handler' => [
+ * 'class' => yii\caching\DbCache::class,
+ * // 'db' => 'mydb',
+ * // 'cacheTable' => 'my_cache',
+ * ],
+ * ],
+ * // ...
+ * ],
+ * // ...
+ * ];
* ```
*
* For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview).
@@ -36,7 +45,7 @@
* @author Qiang Xue
* @since 2.0
*/
-class DbCache extends Cache
+class DbCache extends SimpleCache
{
/**
* @var Connection|array|string the DB connection object or the application component ID of the DB connection.
@@ -88,18 +97,11 @@ public function init()
}
/**
- * Checks whether a specified key exists in the cache.
- * This can be faster than getting the value from the cache if the data is big.
- * Note that this method does not check whether the dependency associated
- * with the cached data, if there is any, has changed. So a call to [[get]]
- * may return false while exists returns true.
- * @param mixed $key a key identifying the cached value. This can be a simple string or
- * a complex data structure consisting of factors representing the key.
- * @return bool true if a value exists in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
- public function exists($key)
+ public function has($key)
{
- $key = $this->buildKey($key);
+ $key = $this->normalizeKey($key);
$query = new Query();
$query->select(['COUNT(*)'])
@@ -118,40 +120,36 @@ public function exists($key)
}
/**
- * Retrieves a value from cache with a specified key.
- * This is the implementation of the method declared in the parent class.
- * @param string $key a unique key identifying the cached value
- * @return string|false the value stored in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
protected function getValue($key)
{
- $query = new Query();
- $query->select(['data'])
+ $query = (new Query())
+ ->select(['data'])
->from($this->cacheTable)
->where('[[id]] = :id AND ([[expire]] = 0 OR [[expire]] >' . time() . ')', [':id' => $key]);
+
if ($this->db->enableQueryCache) {
// temporarily disable and re-enable query caching
$this->db->enableQueryCache = false;
$result = $query->createCommand($this->db)->queryScalar();
$this->db->enableQueryCache = true;
-
return $result;
}
+
return $query->createCommand($this->db)->queryScalar();
}
/**
- * Retrieves multiple values from cache with the specified keys.
- * @param array $keys a list of keys identifying the cached values
- * @return array a list of cached values indexed by the keys
+ * {@inheritdoc}
*/
protected function getValues($keys)
{
if (empty($keys)) {
return [];
}
- $query = new Query();
- $query->select(['id', 'data'])
+ $query = (new Query())
+ ->select(['id', 'data'])
->from($this->cacheTable)
->where(['id' => $keys])
->andWhere('([[expire]] = 0 OR [[expire]] > ' . time() . ')');
@@ -164,10 +162,7 @@ protected function getValues($keys)
$rows = $query->createCommand($this->db)->queryAll();
}
- $results = [];
- foreach ($keys as $key) {
- $results[$key] = false;
- }
+ $results = array_fill_keys($keys, false);
foreach ($rows as $row) {
$results[$row['id']] = $row['data'];
}
@@ -176,20 +171,14 @@ protected function getValues($keys)
}
/**
- * Stores a value identified by a key in cache.
- * This is the implementation of the method declared in the parent class.
- *
- * @param string $key the key identifying the value to be cached
- * @param string $value the value to be cached. Other types (if you have disabled [[serializer]]) cannot be saved.
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
+ * {@inheritdoc}
*/
- protected function setValue($key, $value, $duration)
+ protected function setValue($key, $value, $ttl)
{
- $result = $this->db->noCache(function (Connection $db) use ($key, $value, $duration) {
+ $result = $this->db->noCache(function (Connection $db) use ($key, $value, $ttl) {
$command = $db->createCommand()
->update($this->cacheTable, [
- 'expire' => $duration > 0 ? $duration + time() : 0,
+ 'expire' => $ttl > 0 ? $ttl + time() : 0,
'data' => [$value, \PDO::PARAM_LOB],
], ['id' => $key]);
return $command->execute();
@@ -197,10 +186,9 @@ protected function setValue($key, $value, $duration)
if ($result) {
$this->gc();
-
return true;
}
- return $this->addValue($key, $value, $duration);
+ return $this->addValue($key, $value, $ttl);
}
/**
@@ -233,10 +221,7 @@ protected function addValue($key, $value, $duration)
}
/**
- * Deletes a value with the specified key from cache
- * This is the implementation of the method declared in the parent class.
- * @param string $key the key of the value to be deleted
- * @return bool if no error happens during deletion
+ * {@inheritdoc}
*/
protected function deleteValue($key)
{
@@ -264,11 +249,9 @@ public function gc($force = false)
}
/**
- * Deletes all values from cache.
- * This is the implementation of the method declared in the parent class.
- * @return bool whether the flush operation was successful.
+ * {@inheritdoc}
*/
- protected function flushValues()
+ public function clear()
{
$this->db->createCommand()
->delete($this->cacheTable)
diff --git a/framework/caching/DummyCache.php b/framework/caching/DummyCache.php
index b8db22bc389..a0f23538c16 100644
--- a/framework/caching/DummyCache.php
+++ b/framework/caching/DummyCache.php
@@ -7,9 +7,28 @@
namespace yii\caching;
+use yii\base\Component;
+
/**
* DummyCache is a placeholder cache component.
*
+ * Application configuration example:
+ *
+ * ```php
+ * return [
+ * 'components' => [
+ * 'cache' => [
+ * 'class' => yii\caching\Cache::class,
+ * 'handler' => [
+ * 'class' => yii\caching\DummyCache::class,
+ * ],
+ * ],
+ * // ...
+ * ],
+ * // ...
+ * ];
+ * ```
+ *
* DummyCache does not cache anything. It is provided so that one can always configure
* a 'cache' application component and save the check of existence of `\Yii::$app->cache`.
* By replacing DummyCache with some other cache component, one can quickly switch from
@@ -20,63 +39,68 @@
* @author Qiang Xue
* @since 2.0
*/
-class DummyCache extends Cache
+class DummyCache extends Component implements \Psr\SimpleCache\CacheInterface
{
/**
- * Retrieves a value from cache with a specified key.
- * This is the implementation of the method declared in the parent class.
- * @param string $key a unique key identifying the cached value
- * @return mixed|false the value stored in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
- protected function getValue($key)
+ public function has($key)
{
return false;
}
/**
- * Stores a value identified by a key in cache.
- * This is the implementation of the method declared in the parent class.
- *
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
+ * {@inheritdoc}
+ */
+ public function get($key, $default = null)
+ {
+ return $default;
+ }
+
+ /**
+ * {@inheritdoc}
*/
- protected function setValue($key, $value, $duration)
+ public function set($key, $value, $ttl = null)
{
return true;
}
/**
- * Stores a value identified by a key into cache if the cache does not contain this key.
- * This is the implementation of the method declared in the parent class.
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
+ * {@inheritdoc}
*/
- protected function addValue($key, $value, $duration)
+ public function delete($key)
{
return true;
}
/**
- * Deletes a value with the specified key from cache
- * This is the implementation of the method declared in the parent class.
- * @param string $key the key of the value to be deleted
- * @return bool if no error happens during deletion
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMultiple($keys, $default = null)
+ {
+ return array_fill_keys($keys, $default);
+ }
+
+ /**
+ * {@inheritdoc}
*/
- protected function deleteValue($key)
+ public function setMultiple($values, $ttl = null)
{
return true;
}
/**
- * Deletes all values from cache.
- * This is the implementation of the method declared in the parent class.
- * @return bool whether the flush operation was successful.
+ * {@inheritdoc}
*/
- protected function flushValues()
+ public function deleteMultiple($keys)
{
return true;
}
diff --git a/framework/caching/Exception.php b/framework/caching/Exception.php
new file mode 100644
index 00000000000..5304827e404
--- /dev/null
+++ b/framework/caching/Exception.php
@@ -0,0 +1,25 @@
+
+ * @since 2.1.0
+ */
+class Exception extends \yii\base\Exception implements \Psr\SimpleCache\CacheException
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'Cache Exception';
+ }
+}
\ No newline at end of file
diff --git a/framework/caching/FileCache.php b/framework/caching/FileCache.php
index d884f8097d4..fa83a23d16f 100644
--- a/framework/caching/FileCache.php
+++ b/framework/caching/FileCache.php
@@ -11,29 +11,39 @@
use yii\helpers\FileHelper;
/**
- * FileCache implements a cache component using files.
+ * FileCache implements a cache handler using files.
*
* For each data value being cached, FileCache will store it in a separate file.
* The cache files are placed under [[cachePath]]. FileCache will perform garbage collection
* automatically to remove expired cache files.
*
- * Please refer to [[Cache]] for common cache operations that are supported by FileCache.
+ * Application configuration example:
+ *
+ * ```php
+ * return [
+ * 'components' => [
+ * 'cache' => [
+ * 'class' => yii\caching\Cache::class,
+ * 'handler' => [
+ * 'class' => yii\caching\FileCache::class,
+ * // 'cachePath' => '@runtime/cache',
+ * ],
+ * ],
+ * // ...
+ * ],
+ * // ...
+ * ];
+ * ```
+ *
+ * Please refer to [[\Psr\SimpleCache\CacheInterface]] for common cache operations that are supported by FileCache.
*
* For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview).
*
* @author Qiang Xue
* @since 2.0
*/
-class FileCache extends Cache
+class FileCache extends SimpleCache
{
- /**
- * @var string a string prefixed to every cache key. This is needed when you store
- * cache data under the same [[cachePath]] for different applications to avoid
- * conflict.
- *
- * To ensure interoperability, only alphanumeric characters should be used.
- */
- public $keyPrefix = '';
/**
* @var string the directory to store cache files. You may use [path alias](guide:concept-aliases) here.
* If not set, it will use the "cache" subdirectory under the application runtime path.
@@ -84,27 +94,17 @@ public function init()
}
/**
- * Checks whether a specified key exists in the cache.
- * This can be faster than getting the value from the cache if the data is big.
- * Note that this method does not check whether the dependency associated
- * with the cached data, if there is any, has changed. So a call to [[get]]
- * may return false while exists returns true.
- * @param mixed $key a key identifying the cached value. This can be a simple string or
- * a complex data structure consisting of factors representing the key.
- * @return bool true if a value exists in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
- public function exists($key)
+ public function has($key)
{
- $cacheFile = $this->getCacheFile($this->buildKey($key));
+ $cacheFile = $this->getCacheFile($this->normalizeKey($key));
return @filemtime($cacheFile) > time();
}
/**
- * Retrieves a value from cache with a specified key.
- * This is the implementation of the method declared in the parent class.
- * @param string $key a unique key identifying the cached value
- * @return string|false the value stored in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
protected function getValue($key)
{
@@ -125,16 +125,9 @@ protected function getValue($key)
}
/**
- * Stores a value identified by a key in cache.
- * This is the implementation of the method declared in the parent class.
- *
- * @param string $key the key identifying the value to be cached
- * @param string $value the value to be cached. Other types (If you have disabled [[serializer]]) unable to get is
- * correct in [[getValue()]].
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
+ * {@inheritdoc}
*/
- protected function setValue($key, $value, $duration)
+ protected function setValue($key, $value, $ttl)
{
$this->gc();
$cacheFile = $this->getCacheFile($key);
@@ -145,11 +138,11 @@ protected function setValue($key, $value, $duration)
if ($this->fileMode !== null) {
@chmod($cacheFile, $this->fileMode);
}
- if ($duration <= 0) {
- $duration = 31536000; // 1 year
+ if ($ttl <= 0) {
+ $ttl = 31536000; // 1 year
}
- return @touch($cacheFile, $duration + time());
+ return @touch($cacheFile, $ttl + time());
}
$error = error_get_last();
@@ -158,35 +151,11 @@ protected function setValue($key, $value, $duration)
}
/**
- * Stores a value identified by a key into cache if the cache does not contain this key.
- * This is the implementation of the method declared in the parent class.
- *
- * @param string $key the key identifying the value to be cached
- * @param string $value the value to be cached. Other types (if you have disabled [[serializer]]) unable to get is
- * correct in [[getValue()]].
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
- */
- protected function addValue($key, $value, $duration)
- {
- $cacheFile = $this->getCacheFile($key);
- if (@filemtime($cacheFile) > time()) {
- return false;
- }
-
- return $this->setValue($key, $value, $duration);
- }
-
- /**
- * Deletes a value with the specified key from cache
- * This is the implementation of the method declared in the parent class.
- * @param string $key the key of the value to be deleted
- * @return bool if no error happens during deletion
+ * {@inheritdoc}
*/
protected function deleteValue($key)
{
$cacheFile = $this->getCacheFile($key);
-
return @unlink($cacheFile);
}
@@ -212,14 +181,11 @@ protected function getCacheFile($key)
}
/**
- * Deletes all values from cache.
- * This is the implementation of the method declared in the parent class.
- * @return bool whether the flush operation was successful.
+ * {@inheritdoc}
*/
- protected function flushValues()
+ public function clear()
{
$this->gc(true, false);
-
return true;
}
diff --git a/framework/caching/MemCached.php b/framework/caching/MemCached.php
index 393074c58e5..5b5cc0c6e32 100644
--- a/framework/caching/MemCached.php
+++ b/framework/caching/MemCached.php
@@ -17,7 +17,7 @@
* MemCached can be configured with a list of memcached servers by settings its [[servers]] property.
* By default, MemCached assumes there is a memcached server running on localhost at port 11211.
*
- * See [[Cache]] for common cache operations that MemCached supports.
+ * See [[\Psr\SimpleCache\CacheInterface]] for common cache operations that MemCached supports.
*
* Note, there is no security measure to protected data in memcached.
* All data in memcached can be accessed by any process running in the system.
@@ -28,17 +28,20 @@
* [
* 'components' => [
* 'cache' => [
- * 'class' => \yii\caching\MemCached::class,
- * 'servers' => [
- * [
- * 'host' => 'server1',
- * 'port' => 11211,
- * 'weight' => 60,
- * ],
- * [
- * 'host' => 'server2',
- * 'port' => 11211,
- * 'weight' => 40,
+ * 'class' => \yii\caching\Cache::class,
+ * 'handler' => [
+ * 'class' => \yii\caching\MemCached::class,
+ * 'servers' => [
+ * [
+ * 'host' => 'server1',
+ * 'port' => 11211,
+ * 'weight' => 60,
+ * ],
+ * [
+ * 'host' => 'server2',
+ * 'port' => 11211,
+ * 'weight' => 40,
+ * ],
* ],
* ],
* ],
@@ -59,7 +62,7 @@
* @author Qiang Xue
* @since 2.0
*/
-class MemCached extends Cache
+class MemCached extends SimpleCache
{
/**
* @var string an ID that identifies a Memcached instance.
@@ -187,10 +190,7 @@ public function setServers($config)
}
/**
- * Retrieves a value from cache with a specified key.
- * This is the implementation of the method declared in the parent class.
- * @param string $key a unique key identifying the cached value
- * @return mixed|false the value stored in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
protected function getValue($key)
{
@@ -198,9 +198,7 @@ protected function getValue($key)
}
/**
- * Retrieves multiple values from cache with the specified keys.
- * @param array $keys a list of keys identifying the cached values
- * @return array a list of cached values indexed by the keys
+ * {@inheritdoc}
*/
protected function getValues($keys)
{
@@ -208,65 +206,33 @@ protected function getValues($keys)
}
/**
- * Stores a value identified by a key in cache.
- * This is the implementation of the method declared in the parent class.
- *
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached.
- * @see [Memcached::set()](http://php.net/manual/en/memcached.set.php)
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
+ * {@inheritdoc}
*/
- protected function setValue($key, $value, $duration)
+ protected function setValue($key, $value, $ttl)
{
// Use UNIX timestamp since it doesn't have any limitation
// @see http://php.net/manual/en/memcached.expiration.php
- $expire = $duration > 0 ? $duration + time() : 0;
+ $expire = $ttl > 0 ? $ttl + time() : 0;
return $this->_cache->set($key, $value, $expire);
}
/**
- * Stores multiple key-value pairs in cache.
- * @param array $data array where key corresponds to cache key while value is the value stored
- * @param int $duration the number of seconds in which the cached values will expire. 0 means never expire.
- * @return array array of failed keys.
+ * {@inheritdoc}
*/
- protected function setValues($data, $duration)
+ protected function setValues($values, $ttl)
{
// Use UNIX timestamp since it doesn't have any limitation
// @see http://php.net/manual/en/memcached.expiration.php
- $expire = $duration > 0 ? $duration + time() : 0;
+ $expire = $ttl > 0 ? $ttl + time() : 0;
// Memcached::setMulti() returns boolean
// @see http://php.net/manual/en/memcached.setmulti.php
- return $this->_cache->setMulti($data, $expire) ? [] : array_keys($data);
- }
-
- /**
- * Stores a value identified by a key into cache if the cache does not contain this key.
- * This is the implementation of the method declared in the parent class.
- *
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached
- * @see [Memcached::set()](http://php.net/manual/en/memcached.set.php)
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
- */
- protected function addValue($key, $value, $duration)
- {
- // Use UNIX timestamp since it doesn't have any limitation
- // @see http://php.net/manual/en/memcached.expiration.php
- $expire = $duration > 0 ? $duration + time() : 0;
-
- return $this->_cache->add($key, $value, $expire);
+ return $this->_cache->setMulti($values, $expire) ? [] : array_keys($values);
}
/**
- * Deletes a value with the specified key from cache
- * This is the implementation of the method declared in the parent class.
- * @param string $key the key of the value to be deleted
- * @return bool if no error happens during deletion
+ * {@inheritdoc}
*/
protected function deleteValue($key)
{
@@ -274,11 +240,9 @@ protected function deleteValue($key)
}
/**
- * Deletes all values from cache.
- * This is the implementation of the method declared in the parent class.
- * @return bool whether the flush operation was successful.
+ * {@inheritdoc}
*/
- protected function flushValues()
+ public function clear()
{
return $this->_cache->flush();
}
diff --git a/framework/caching/SimpleCache.php b/framework/caching/SimpleCache.php
new file mode 100644
index 00000000000..60ab5214429
--- /dev/null
+++ b/framework/caching/SimpleCache.php
@@ -0,0 +1,270 @@
+
+ * @since 2.1.0
+ */
+abstract class SimpleCache extends Component implements CacheInterface
+{
+ /**
+ * @var int default TTL for a cache entry. Default value is 0, meaning infinity.
+ * This value is used by [[set()]] and [[setMultiple()]], if the duration is not explicitly given.
+ */
+ public $defaultTtl = 0;
+ /**
+ * @var string a string prefixed to every cache key so that it is unique globally in the whole cache storage.
+ * It is recommended that you set a unique cache key prefix for each application if the same cache
+ * storage is being used by different applications.
+ *
+ * To ensure interoperability, only alphanumeric characters should be used.
+ */
+ public $keyPrefix = '';
+ /**
+ * @var null|array|false the functions used to serialize and unserialize cached data. Defaults to null, meaning
+ * using the default PHP `serialize()` and `unserialize()` functions. If you want to use some more efficient
+ * serializer (e.g. [igbinary](http://pecl.php.net/package/igbinary)), you may configure this property with
+ * a two-element array. The first element specifies the serialization function, and the second the deserialization
+ * function. If this property is set false, data will be directly sent to and retrieved from the underlying
+ * cache component without any serialization or deserialization. You should not turn off serialization if
+ * you are using [[Dependency|cache dependency]], because it relies on data serialization. Also, some
+ * implementations of the cache can not correctly save and retrieve data different from a string type.
+ */
+ public $serializer;
+
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($key, $default = null)
+ {
+ $key = $this->normalizeKey($key);
+ $value = $this->getValue($key);
+ if ($value === false || $this->serializer === false) {
+ return $default;
+ } elseif ($this->serializer === null) {
+ return unserialize($value);
+ }
+
+ return call_user_func($this->serializer[1], $value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMultiple($keys, $default = null)
+ {
+ $keyMap = [];
+ foreach ($keys as $key) {
+ $keyMap[$key] = $this->normalizeKey($key);
+ }
+ $values = $this->getValues(array_values($keyMap));
+ $results = [];
+ foreach ($keyMap as $key => $newKey) {
+ $results[$key] = $default;
+ if (isset($values[$newKey]) && $values[$newKey] !== false) {
+ if ($this->serializer === false) {
+ $results[$key] = $values[$newKey];
+ } else {
+ $results[$key] = $this->serializer === null ? unserialize($values[$newKey])
+ : call_user_func($this->serializer[1], $values[$newKey]);
+ }
+ }
+ }
+ return $results;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($key)
+ {
+ $key = $this->normalizeKey($key);
+ $value = $this->getValue($key);
+ return $value !== false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($key, $value, $ttl = null)
+ {
+ if ($this->serializer === null) {
+ $value = serialize($value);
+ } elseif ($this->serializer !== false) {
+ $value = call_user_func($this->serializer[0], $value);
+ }
+ $key = $this->normalizeKey($key);
+ $ttl = $this->normalizeTtl($ttl);
+ return $this->setValue($key, $value, $ttl);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMultiple($values, $ttl = null)
+ {
+ $data = [];
+ foreach ($values as $key => $value) {
+ if ($this->serializer === null) {
+ $value = serialize($value);
+ } elseif ($this->serializer !== false) {
+ $value = call_user_func($this->serializer[0], $value);
+ }
+ $key = $this->normalizeKey($key);
+ $data[$key] = $value;
+ }
+ return $this->setValues($data, $this->normalizeTtl($ttl));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete($key)
+ {
+ $key = $this->normalizeKey($key);
+ return $this->deleteValue($key);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteMultiple($keys)
+ {
+ $result = true;
+ foreach ($keys as $key) {
+ if (!$this->delete($key)) {
+ $result = false;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Builds a normalized cache key from a given key.
+ *
+ * The given key will be type-casted to string.
+ * If the result string does not contain alphanumeric characters only or has more than 32 characters,
+ * then the hash of the key will be used.
+ * The result key will be returned back prefixed with [[keyPrefix]].
+ *
+ * @param mixed $key the key to be normalized
+ * @return string the generated cache key
+ */
+ protected function normalizeKey($key)
+ {
+ $key = (string)$key;
+ $key = ctype_alnum($key) && StringHelper::byteLength($key) <= 32 ? $key : md5($key);
+ return $this->keyPrefix . $key;
+ }
+
+ /**
+ * Normalizes cache TTL handling `null` value and [[\DateInterval]] objects.
+ * @param int|\DateInterval $ttl raw TTL.
+ * @return int TTL value as UNIX timestamp.
+ */
+ protected function normalizeTtl($ttl)
+ {
+ if ($ttl === null) {
+ return $this->defaultTtl;
+ }
+ if ($ttl instanceof \DateInterval) {
+ return (new \DateTime('@0'))->add($ttl)->getTimestamp();
+ }
+ return (int)$ttl;
+ }
+
+ /**
+ * Retrieves a value from cache with a specified key.
+ * This method should be implemented by child classes to retrieve the data
+ * from specific cache storage.
+ * @param string $key a unique key identifying the cached value
+ * @return mixed|false the value stored in cache, `false` if the value is not in the cache or expired. Most often
+ * value is a string. If you have disabled [[serializer]], it could be something else.
+ */
+ abstract protected function getValue($key);
+
+ /**
+ * Stores a value identified by a key in cache.
+ * This method should be implemented by child classes to store the data
+ * in specific cache storage.
+ * @param string $key the key identifying the value to be cached
+ * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]],
+ * it could be something else.
+ * @param int $ttl the number of seconds in which the cached value will expire.
+ * @return bool true if the value is successfully stored into cache, false otherwise
+ */
+ abstract protected function setValue($key, $value, $ttl);
+
+ /**
+ * Deletes a value with the specified key from cache
+ * This method should be implemented by child classes to delete the data from actual cache storage.
+ * @param string $key the key of the value to be deleted
+ * @return bool if no error happens during deletion
+ */
+ abstract protected function deleteValue($key);
+
+ /**
+ * Retrieves multiple values from cache with the specified keys.
+ * The default implementation calls [[getValue()]] multiple times to retrieve
+ * the cached values one by one. If the underlying cache storage supports multiget,
+ * this method should be overridden to exploit that feature.
+ * @param array $keys a list of keys identifying the cached values
+ * @return array a list of cached values indexed by the keys
+ */
+ protected function getValues($keys)
+ {
+ $results = [];
+ foreach ($keys as $key) {
+ $value = $this->getValue($key);
+ if ($value !== false) {
+ $results[$key] = $value;
+ }
+ }
+ return $results;
+ }
+
+ /**
+ * Stores multiple key-value pairs in cache.
+ * The default implementation calls [[setValue()]] multiple times store values one by one. If the underlying cache
+ * storage supports multi-set, this method should be overridden to exploit that feature.
+ * @param array $values array where key corresponds to cache key while value is the value stored
+ * @param int $ttl the number of seconds in which the cached values will expire.
+ * @return bool `true` on success and `false` on failure.
+ */
+ protected function setValues($values, $ttl)
+ {
+ $result = true;
+ foreach ($values as $key => $value) {
+ if ($this->setValue($key, $value, $ttl) === false) {
+ $result = false;
+ }
+ }
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/framework/caching/TagDependency.php b/framework/caching/TagDependency.php
index 26b286c08ff..e42c01f2326 100644
--- a/framework/caching/TagDependency.php
+++ b/framework/caching/TagDependency.php
@@ -68,21 +68,21 @@ public function isChanged($cache)
/**
* Invalidates all of the cached data items that are associated with any of the specified [[tags]].
- * @param CacheInterface $cache the cache component that caches the data items
+ * @param \Psr\SimpleCache\CacheInterface $cache the cache component that caches the data items
* @param string|array $tags
*/
public static function invalidate($cache, $tags)
{
$keys = [];
foreach ((array) $tags as $tag) {
- $keys[] = $cache->buildKey([__CLASS__, $tag]);
+ $keys[] = static::buildCacheKey($tag);
}
static::touchKeys($cache, $keys);
}
/**
* Generates the timestamp for the specified cache keys.
- * @param CacheInterface $cache
+ * @param \Psr\SimpleCache\CacheInterface $cache
* @param string[] $keys
* @return array the timestamp indexed by cache keys
*/
@@ -93,13 +93,13 @@ protected static function touchKeys($cache, $keys)
foreach ($keys as $key) {
$items[$key] = $time;
}
- $cache->multiSet($items);
+ $cache->setMultiple($items);
return $items;
}
/**
* Returns the timestamps for the specified tags.
- * @param CacheInterface $cache
+ * @param \Psr\SimpleCache\CacheInterface $cache
* @param string[] $tags
* @return array the timestamps indexed by the specified tags.
*/
@@ -111,9 +111,21 @@ protected function getTimestamps($cache, $tags)
$keys = [];
foreach ($tags as $tag) {
- $keys[] = $cache->buildKey([__CLASS__, $tag]);
+ $keys[] = static::buildCacheKey($tag);
}
- return $cache->multiGet($keys);
+ return $cache->getMultiple($keys);
+ }
+
+ /**
+ * Builds a normalized cache key from a given tag, making sure it is short enough and safe
+ * for any particular cache storage.
+ * @param string $tag tag name.
+ * @return string cache key.
+ * @since 2.1.0
+ */
+ protected static function buildCacheKey($tag)
+ {
+ return md5(json_encode([__CLASS__, $tag]));
}
}
diff --git a/framework/caching/WinCache.php b/framework/caching/WinCache.php
index 3201311b15a..2d15e438b07 100644
--- a/framework/caching/WinCache.php
+++ b/framework/caching/WinCache.php
@@ -13,37 +13,42 @@
* To use this application component, the [WinCache PHP extension](http://www.iis.net/expand/wincacheforphp)
* must be loaded. Also note that "wincache.ucenabled" should be set to "On" in your php.ini file.
*
- * See [[Cache]] manual for common cache operations that are supported by WinCache.
+ * Application configuration example:
+ *
+ * ```php
+ * return [
+ * 'components' => [
+ * 'cache' => [
+ * 'class' => yii\caching\Cache::class,
+ * 'handler' => [
+ * 'class' => yii\caching\WinCache::class,
+ * ],
+ * ],
+ * // ...
+ * ],
+ * // ...
+ * ];
+ * ```
+ *
+ * See [[\Psr\SimpleCache\CacheInterface]] for common cache operations that are supported by WinCache.
*
* For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview).
*
* @author Qiang Xue
* @since 2.0
*/
-class WinCache extends Cache
+class WinCache extends SimpleCache
{
/**
- * Checks whether a specified key exists in the cache.
- * This can be faster than getting the value from the cache if the data is big.
- * Note that this method does not check whether the dependency associated
- * with the cached data, if there is any, has changed. So a call to [[get]]
- * may return false while exists returns true.
- * @param mixed $key a key identifying the cached value. This can be a simple string or
- * a complex data structure consisting of factors representing the key.
- * @return bool true if a value exists in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
- public function exists($key)
+ public function has($key)
{
- $key = $this->buildKey($key);
-
- return wincache_ucache_exists($key);
+ return wincache_ucache_exists($this->normalizeKey($key));
}
/**
- * Retrieves a value from cache with a specified key.
- * This is the implementation of the method declared in the parent class.
- * @param string $key a unique key identifying the cached value
- * @return string|bool the value stored in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
protected function getValue($key)
{
@@ -51,9 +56,7 @@ protected function getValue($key)
}
/**
- * Retrieves multiple values from cache with the specified keys.
- * @param array $keys a list of keys identifying the cached values
- * @return array a list of cached values indexed by the keys
+ * {@inheritdoc}
*/
protected function getValues($keys)
{
@@ -61,64 +64,23 @@ protected function getValues($keys)
}
/**
- * Stores a value identified by a key in cache.
- * This is the implementation of the method declared in the parent class.
- *
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]],
- * it could be something else.
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
- */
- protected function setValue($key, $value, $duration)
- {
- return wincache_ucache_set($key, $value, $duration);
- }
-
- /**
- * Stores multiple key-value pairs in cache.
- * @param array $data array where key corresponds to cache key while value is the value stored
- * @param int $duration the number of seconds in which the cached values will expire. 0 means never expire.
- * @return array array of failed keys
- */
- protected function setValues($data, $duration)
- {
- return wincache_ucache_set($data, null, $duration);
- }
-
- /**
- * Stores a value identified by a key into cache if the cache does not contain this key.
- * This is the implementation of the method declared in the parent class.
- *
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]],
- * it could be something else.
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
+ * {@inheritdoc}
*/
- protected function addValue($key, $value, $duration)
+ protected function setValue($key, $value, $ttl)
{
- return wincache_ucache_add($key, $value, $duration);
+ return wincache_ucache_set($key, $value, $ttl);
}
/**
- * Adds multiple key-value pairs to cache.
- * The default implementation calls [[addValue()]] multiple times add values one by one. If the underlying cache
- * storage supports multiadd, this method should be overridden to exploit that feature.
- * @param array $data array where key corresponds to cache key while value is the value stored
- * @param int $duration the number of seconds in which the cached values will expire. 0 means never expire.
- * @return array array of failed keys
+ * {@inheritdoc}
*/
- protected function addValues($data, $duration)
+ protected function setValues($values, $ttl)
{
- return wincache_ucache_add($data, null, $duration);
+ return wincache_ucache_set($values, null, $ttl);
}
/**
- * Deletes a value with the specified key from cache
- * This is the implementation of the method declared in the parent class.
- * @param string $key the key of the value to be deleted
- * @return bool if no error happens during deletion
+ * {@inheritdoc}
*/
protected function deleteValue($key)
{
@@ -126,11 +88,9 @@ protected function deleteValue($key)
}
/**
- * Deletes all values from cache.
- * This is the implementation of the method declared in the parent class.
- * @return bool whether the flush operation was successful.
+ * {@inheritdoc}
*/
- protected function flushValues()
+ public function clear()
{
return wincache_ucache_clear();
}
diff --git a/framework/caching/ZendDataCache.php b/framework/caching/ZendDataCache.php
index 4c5ae9061ca..8cfebf6832f 100644
--- a/framework/caching/ZendDataCache.php
+++ b/framework/caching/ZendDataCache.php
@@ -13,63 +13,51 @@
* To use this application component, the [Zend Data Cache PHP extension](http://www.zend.com/en/products/server/)
* must be loaded.
*
- * See [[Cache]] for common cache operations that ZendDataCache supports.
+ * Application configuration example:
+ *
+ * ```php
+ * return [
+ * 'components' => [
+ * 'cache' => [
+ * 'class' => yii\caching\Cache::class,
+ * 'handler' => [
+ * 'class' => yii\caching\ZendDataCache::class,
+ * ],
+ * ],
+ * // ...
+ * ],
+ * // ...
+ * ];
+ * ```
+ *
+ * See [[\Psr\SimpleCache\CacheInterface]] for common cache operations that ZendDataCache supports.
*
* For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview).
*
* @author Qiang Xue
* @since 2.0
*/
-class ZendDataCache extends Cache
+class ZendDataCache extends SimpleCache
{
/**
- * Retrieves a value from cache with a specified key.
- * This is the implementation of the method declared in the parent class.
- * @param string $key a unique key identifying the cached value
- * @return mixed|false the value stored in cache, false if the value is not in the cache or expired.
+ * {@inheritdoc}
*/
protected function getValue($key)
{
$result = zend_shm_cache_fetch($key);
-
return $result === null ? false : $result;
}
/**
- * Stores a value identified by a key in cache.
- * This is the implementation of the method declared in the parent class.
- *
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]],
- * it could be something else.
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
- */
- protected function setValue($key, $value, $duration)
- {
- return zend_shm_cache_store($key, $value, $duration);
- }
-
- /**
- * Stores a value identified by a key into cache if the cache does not contain this key.
- * This is the implementation of the method declared in the parent class.
- *
- * @param string $key the key identifying the value to be cached
- * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]],
- * it could be something else.
- * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
- * @return bool true if the value is successfully stored into cache, false otherwise
+ * {@inheritdoc}
*/
- protected function addValue($key, $value, $duration)
+ protected function setValue($key, $value, $ttl)
{
- return zend_shm_cache_fetch($key) === null ? $this->setValue($key, $value, $duration) : false;
+ return zend_shm_cache_store($key, $value, $ttl);
}
/**
- * Deletes a value with the specified key from cache
- * This is the implementation of the method declared in the parent class.
- * @param string $key the key of the value to be deleted
- * @return bool if no error happens during deletion
+ * {@inheritdoc}
*/
protected function deleteValue($key)
{
@@ -77,11 +65,9 @@ protected function deleteValue($key)
}
/**
- * Deletes all values from cache.
- * This is the implementation of the method declared in the parent class.
- * @return bool whether the flush operation was successful.
+ * {@inheritdoc}
*/
- protected function flushValues()
+ public function clear()
{
return zend_shm_cache_clear();
}
diff --git a/framework/composer.json b/framework/composer.json
index 861c42e18cd..4dab44a047e 100644
--- a/framework/composer.json
+++ b/framework/composer.json
@@ -68,6 +68,7 @@
"ext-ctype": "*",
"lib-pcre": "*",
"yiisoft/yii2-composer": "~2.0.4",
+ "psr/simple-cache": "~1.0.0",
"ezyang/htmlpurifier": "~4.6",
"cebe/markdown": "~1.0.0 | ~1.1.0",
"bower-asset/jquery": "2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
diff --git a/framework/console/controllers/CacheController.php b/framework/console/controllers/CacheController.php
index 0cfa4e90c02..1e24050d2fd 100644
--- a/framework/console/controllers/CacheController.php
+++ b/framework/console/controllers/CacheController.php
@@ -7,35 +7,36 @@
namespace yii\console\controllers;
+use Psr\SimpleCache\CacheInterface;
use Yii;
use yii\caching\ApcCache;
-use yii\caching\CacheInterface;
+use yii\caching\Cache;
use yii\console\Controller;
use yii\console\Exception;
use yii\console\ExitCode;
use yii\helpers\Console;
/**
- * Allows you to flush cache.
+ * Allows you to clear cache.
*
- * see list of available components to flush:
+ * see list of available components to clear:
*
* yii cache
*
- * flush particular components specified by their names:
+ * clear particular components specified by their names:
*
- * yii cache/flush first second third
+ * yii cache/clear first second third
*
- * flush all cache components that can be found in the system
+ * clear all cache components that can be found in the system
*
- * yii cache/flush-all
+ * yii cache/clear-all
*
* Note that the command uses cache components defined in your console application configuration file. If components
* configured are different from web application, web application cache won't be cleared. In order to fix it please
* duplicate web application cache components in console config. You can use any component names.
*
- * APC is not shared between PHP processes so flushing cache from command line has no effect on web.
- * Flushing web cache could be either done by:
+ * APC is not shared between PHP processes so clearing cache from command line has no effect on web.
+ * Clearing web cache could be either done by:
*
* - Putting a php file under web root and calling it via HTTP
* - Using [Cachetool](http://gordalina.github.io/cachetool/)
@@ -47,29 +48,29 @@
class CacheController extends Controller
{
/**
- * Lists the caches that can be flushed.
+ * Lists the caches that can be cleared.
*/
public function actionIndex()
{
$caches = $this->findCaches();
if (!empty($caches)) {
- $this->notifyCachesCanBeFlushed($caches);
+ $this->notifyCachesCanBeCleared($caches);
} else {
$this->notifyNoCachesFound();
}
}
/**
- * Flushes given cache components.
+ * Clears given cache components.
* For example,
*
* ```
- * # flushes caches specified by their id: "first", "second", "third"
- * yii cache/flush first second third
+ * # clears caches specified by their id: "first", "second", "third"
+ * yii cache/clear first second third
* ```
*/
- public function actionFlush()
+ public function actionClear()
{
$cachesInput = func_get_args();
@@ -92,7 +93,7 @@ public function actionFlush()
return ExitCode::OK;
}
- if (!$this->confirmFlush($foundCaches)) {
+ if (!$this->confirmClear($foundCaches)) {
return ExitCode::OK;
}
@@ -100,17 +101,17 @@ public function actionFlush()
$cachesInfo[] = [
'name' => $name,
'class' => $class,
- 'is_flushed' => $this->canBeFlushed($class) ? Yii::$app->get($name)->flush() : false,
+ 'is_cleared' => $this->canBeCleared($class) ? Yii::$app->get($name)->clear() : false,
];
}
- $this->notifyFlushed($cachesInfo);
+ $this->notifyCleared($cachesInfo);
}
/**
- * Flushes all caches registered in the system.
+ * Clears all caches registered in the system.
*/
- public function actionFlushAll()
+ public function actionClearAll()
{
$caches = $this->findCaches();
$cachesInfo = [];
@@ -124,11 +125,11 @@ public function actionFlushAll()
$cachesInfo[] = [
'name' => $name,
'class' => $class,
- 'is_flushed' => $this->canBeFlushed($class) ? Yii::$app->get($name)->flush() : false,
+ 'is_cleared' => $this->canBeCleared($class) ? Yii::$app->get($name)->clear() : false,
];
}
- $this->notifyFlushed($cachesInfo);
+ $this->notifyCleared($cachesInfo);
}
/**
@@ -136,7 +137,7 @@ public function actionFlushAll()
*
* ```
* # clears cache schema specified by component id: "db"
- * yii cache/flush-schema db
+ * yii cache/clear-schema db
* ```
*
* @param string $db id connection component
@@ -146,7 +147,7 @@ public function actionFlushAll()
*
* @since 2.0.1
*/
- public function actionFlushSchema($db = 'db')
+ public function actionClearSchema($db = 'db')
{
$connection = Yii::$app->get($db, false);
if ($connection === null) {
@@ -157,32 +158,32 @@ public function actionFlushSchema($db = 'db')
if (!$connection instanceof \yii\db\Connection) {
$this->stdout("\"$db\" component doesn't inherit \\yii\\db\\Connection.\n", Console::FG_RED);
return ExitCode::UNSPECIFIED_ERROR;
- } elseif (!$this->confirm("Flush cache schema for \"$db\" connection?")) {
+ } elseif (!$this->confirm("Clear cache schema for \"$db\" connection?")) {
return ExitCode::OK;
}
try {
$schema = $connection->getSchema();
$schema->refresh();
- $this->stdout("Schema cache for component \"$db\", was flushed.\n\n", Console::FG_GREEN);
+ $this->stdout("Schema cache for component \"$db\", was cleared.\n\n", Console::FG_GREEN);
} catch (\Exception $e) {
$this->stdout($e->getMessage() . "\n\n", Console::FG_RED);
}
}
/**
- * Notifies user that given caches are found and can be flushed.
+ * Notifies user that given caches are found and can be cleared.
* @param array $caches array of cache component classes
*/
- private function notifyCachesCanBeFlushed($caches)
+ private function notifyCachesCanBeCleared($caches)
{
$this->stdout("The following caches were found in the system:\n\n", Console::FG_YELLOW);
foreach ($caches as $name => $class) {
- if ($this->canBeFlushed($class)) {
+ if ($this->canBeCleared($class)) {
$this->stdout("\t* $name ($class)\n", Console::FG_GREEN);
} else {
- $this->stdout("\t* $name ($class) - can not be flushed via console\n", Console::FG_YELLOW);
+ $this->stdout("\t* $name ($class) - can not be cleared via console\n", Console::FG_YELLOW);
}
}
@@ -215,15 +216,15 @@ private function notifyNotFoundCaches($cachesNames)
/**
* @param array $caches
*/
- private function notifyFlushed($caches)
+ private function notifyCleared($caches)
{
$this->stdout("The following cache components were processed:\n\n", Console::FG_YELLOW);
foreach ($caches as $cache) {
$this->stdout("\t* " . $cache['name'] . ' (' . $cache['class'] . ')', Console::FG_GREEN);
- if (!$cache['is_flushed']) {
- $this->stdout(" - not flushed\n", Console::FG_RED);
+ if (!$cache['is_cleared']) {
+ $this->stdout(" - not cleared\n", Console::FG_RED);
} else {
$this->stdout("\n");
}
@@ -233,19 +234,19 @@ private function notifyFlushed($caches)
}
/**
- * Prompts user with confirmation if caches should be flushed.
+ * Prompts user with confirmation if caches should be cleared.
* @param array $cachesNames
* @return bool
*/
- private function confirmFlush($cachesNames)
+ private function confirmClear($cachesNames)
{
- $this->stdout("The following cache components will be flushed:\n\n", Console::FG_YELLOW);
+ $this->stdout("The following cache components will be cleared:\n\n", Console::FG_YELLOW);
foreach ($cachesNames as $name) {
$this->stdout("\t* $name \n", Console::FG_GREEN);
}
- return $this->confirm("\nFlush above cache components?");
+ return $this->confirm("\nClear above cache components?");
}
/**
@@ -287,11 +288,11 @@ private function isCacheClass($className)
}
/**
- * Checks if cache of a certain class can be flushed
+ * Checks if cache of a certain class can be cleared
* @param string $className class name.
* @return bool
*/
- private function canBeFlushed($className)
+ private function canBeCleared($className)
{
return !is_a($className, ApcCache::class, true) || php_sapi_name() !== 'cli';
}
diff --git a/framework/web/CacheSession.php b/framework/web/CacheSession.php
index 054f6a0b43f..2289eaf194d 100644
--- a/framework/web/CacheSession.php
+++ b/framework/web/CacheSession.php
@@ -79,7 +79,7 @@ public function readSession($id)
{
$data = $this->cache->get($this->calculateKey($id));
- return $data === false ? '' : $data;
+ return $data === null ? '' : $data;
}
/**
@@ -103,7 +103,7 @@ public function writeSession($id, $data)
public function destroySession($id)
{
$cacheId = $this->calculateKey($id);
- if ($this->cache->exists($cacheId) === false) {
+ if ($this->cache->has($cacheId) === false) {
return true;
}
diff --git a/tests/framework/base/ViewTest.php b/tests/framework/base/ViewTest.php
index c9d7c762e81..6ba0eaa19ce 100644
--- a/tests/framework/base/ViewTest.php
+++ b/tests/framework/base/ViewTest.php
@@ -9,6 +9,7 @@
use Yii;
use yii\base\View;
+use yii\caching\Cache;
use yii\caching\FileCache;
use yii\helpers\FileHelper;
use yiiunit\TestCase;
@@ -71,14 +72,14 @@ public function testExceptionOnRenderFile()
public function testRenderDynamic()
{
- Yii::$app->set('cache', new FileCache(['cachePath' => '@yiiunit/runtime/cache']));
+ Yii::$app->set('cache', new Cache(['handler' => new FileCache(['cachePath' => '@yiiunit/runtime/cache'])]));
$view = new View();
$this->assertEquals(1, $view->renderDynamic('return 1;'));
}
public function testRenderDynamic_DynamicPlaceholders()
{
- Yii::$app->set('cache', new FileCache(['cachePath' => '@yiiunit/runtime/cache']));
+ Yii::$app->set('cache', new Cache(['handler' => new FileCache(['cachePath' => '@yiiunit/runtime/cache'])]));
$statement = "return 1;";
$view = new View();
if ($view->beginCache(__FUNCTION__, ['duration' => 3])) {
diff --git a/tests/framework/caching/ApcCacheTest.php b/tests/framework/caching/ApcCacheTest.php
index 2f31737eae0..8515b9bca08 100644
--- a/tests/framework/caching/ApcCacheTest.php
+++ b/tests/framework/caching/ApcCacheTest.php
@@ -8,6 +8,7 @@
namespace yiiunit\framework\caching;
use yii\caching\ApcCache;
+use yii\caching\Cache;
/**
* Class for testing APC cache backend
@@ -19,7 +20,7 @@ class ApcCacheTest extends CacheTestCase
private $_cacheInstance = null;
/**
- * @return ApcCache
+ * @return Cache
*/
protected function getCacheInstance()
{
@@ -32,7 +33,9 @@ protected function getCacheInstance()
}
if ($this->_cacheInstance === null) {
- $this->_cacheInstance = new ApcCache();
+ $this->_cacheInstance = new Cache([
+ 'handler' => new ApcCache()
+ ]);
}
return $this->_cacheInstance;
diff --git a/tests/framework/caching/ArrayCacheTest.php b/tests/framework/caching/ArrayCacheTest.php
index e6359e5b367..39186b47ef2 100644
--- a/tests/framework/caching/ArrayCacheTest.php
+++ b/tests/framework/caching/ArrayCacheTest.php
@@ -8,6 +8,7 @@
namespace yiiunit\framework\caching;
use yii\caching\ArrayCache;
+use yii\caching\Cache;
/**
* Class for testing file cache backend
@@ -18,12 +19,14 @@ class ArrayCacheTest extends CacheTestCase
private $_cacheInstance = null;
/**
- * @return ArrayCache
+ * @return Cache
*/
protected function getCacheInstance()
{
if ($this->_cacheInstance === null) {
- $this->_cacheInstance = new ArrayCache();
+ $this->_cacheInstance = new Cache([
+ 'handler' => new ArrayCache()
+ ]);
}
return $this->_cacheInstance;
}
@@ -37,7 +40,7 @@ public function testExpire()
static::$microtime++;
$this->assertEquals('expire_test', $cache->get('expire_test'));
static::$microtime++;
- $this->assertFalse($cache->get('expire_test'));
+ $this->assertNull($cache->get('expire_test'));
}
public function testExpireAdd()
@@ -49,6 +52,6 @@ public function testExpireAdd()
static::$microtime++;
$this->assertEquals('expire_testa', $cache->get('expire_testa'));
static::$microtime++;
- $this->assertFalse($cache->get('expire_testa'));
+ $this->assertNull($cache->get('expire_testa'));
}
}
diff --git a/tests/framework/caching/CacheTestCase.php b/tests/framework/caching/CacheTestCase.php
index 71a29f69646..99f08fc474d 100644
--- a/tests/framework/caching/CacheTestCase.php
+++ b/tests/framework/caching/CacheTestCase.php
@@ -73,7 +73,7 @@ public function prepare()
{
$cache = $this->getCacheInstance();
- $cache->flush();
+ $cache->clear();
$cache->set('string_test', 'string_test');
$cache->set('number_test', 42);
$cache->set('array_test', ['array_test' => 'array_test']);
@@ -107,20 +107,20 @@ public function testGet()
/**
* @return array testing multiSet with and without expiry
*/
- public function multiSetExpiry()
+ public function dataProviderSetMultiple()
{
return [[0], [2]];
}
/**
- * @dataProvider multiSetExpiry
+ * @dataProvider dataProviderSetMultiple
*/
- public function testMultiset($expiry)
+ public function testSetMultiple($expiry)
{
$cache = $this->getCacheInstance();
- $cache->flush();
+ $cache->clear();
- $cache->multiSet([
+ $cache->setMultiple([
'string_test' => 'string_test',
'number_test' => 42,
'array_test' => ['array_test' => 'array_test'],
@@ -135,16 +135,16 @@ public function testMultiset($expiry)
$this->assertEquals('array_test', $array['array_test']);
}
- public function testExists()
+ public function testHas()
{
$cache = $this->prepare();
- $this->assertTrue($cache->exists('string_test'));
+ $this->assertTrue($cache->has('string_test'));
// check whether exists affects the value
$this->assertEquals('string_test', $cache->get('string_test'));
- $this->assertTrue($cache->exists('number_test'));
- $this->assertFalse($cache->exists('not_exists'));
+ $this->assertTrue($cache->has('number_test'));
+ $this->assertFalse($cache->has('not_exists'));
}
public function testArrayAccess()
@@ -159,7 +159,7 @@ public function testGetNonExistent()
{
$cache = $this->getCacheInstance();
- $this->assertFalse($cache->get('non_existent_key'));
+ $this->assertNull($cache->get('non_existent_key'));
}
public function testStoreSpecialValues()
@@ -173,21 +173,21 @@ public function testStoreSpecialValues()
$this->assertTrue($cache->get('bool_value'));
}
- public function testMultiGet()
+ public function testGetMultiple()
{
$cache = $this->prepare();
- $this->assertEquals(['string_test' => 'string_test', 'number_test' => 42], $cache->multiGet(['string_test', 'number_test']));
+ $this->assertEquals(['string_test' => 'string_test', 'number_test' => 42], $cache->getMultiple(['string_test', 'number_test']));
// ensure that order does not matter
- $this->assertEquals(['number_test' => 42, 'string_test' => 'string_test'], $cache->multiGet(['number_test', 'string_test']));
- $this->assertEquals(['number_test' => 42, 'non_existent_key' => null], $cache->multiGet(['number_test', 'non_existent_key']));
+ $this->assertEquals(['number_test' => 42, 'string_test' => 'string_test'], $cache->getMultiple(['number_test', 'string_test']));
+ $this->assertEquals(['number_test' => 42, 'non_existent_key' => null], $cache->getMultiple(['number_test', 'non_existent_key']));
}
public function testDefaultTtl()
{
$cache = $this->getCacheInstance();
- $this->assertSame(0, $cache->defaultDuration);
+ $this->assertSame(0, $cache->handler->defaultTtl);
}
public function testExpire()
@@ -198,7 +198,7 @@ public function testExpire()
usleep(500000);
$this->assertEquals('expire_test', $cache->get('expire_test'));
usleep(2500000);
- $this->assertFalse($cache->get('expire_test'));
+ $this->assertNull($cache->get('expire_test'));
}
public function testExpireAdd()
@@ -209,7 +209,7 @@ public function testExpireAdd()
usleep(500000);
$this->assertEquals('expire_testa', $cache->get('expire_testa'));
usleep(2500000);
- $this->assertFalse($cache->get('expire_testa'));
+ $this->assertNull($cache->get('expire_testa'));
}
public function testAdd()
@@ -221,18 +221,18 @@ public function testAdd()
$this->assertEquals(42, $cache->get('number_test'));
// should store data if it's not there yet
- $this->assertFalse($cache->get('add_test'));
+ $this->assertNull($cache->get('add_test'));
$this->assertTrue($cache->add('add_test', 13));
$this->assertEquals(13, $cache->get('add_test'));
}
- public function testMultiAdd()
+ public function testAddMultiple()
{
$cache = $this->prepare();
- $this->assertFalse($cache->get('add_test'));
+ $this->assertNull($cache->get('add_test'));
- $cache->multiAdd([
+ $cache->addMultiple([
'number_test' => 13,
'add_test' => 13,
]);
@@ -247,14 +247,14 @@ public function testDelete()
$this->assertNotNull($cache->get('number_test'));
$this->assertTrue($cache->delete('number_test'));
- $this->assertFalse($cache->get('number_test'));
+ $this->assertNull($cache->get('number_test'));
}
public function testFlush()
{
$cache = $this->prepare();
- $this->assertTrue($cache->flush());
- $this->assertFalse($cache->get('number_test'));
+ $this->assertTrue($cache->clear());
+ $this->assertNull($cache->get('number_test'));
}
public function testGetOrSet()
diff --git a/tests/framework/caching/DbCacheTest.php b/tests/framework/caching/DbCacheTest.php
index 557701c03ab..8efee0e53c9 100644
--- a/tests/framework/caching/DbCacheTest.php
+++ b/tests/framework/caching/DbCacheTest.php
@@ -7,6 +7,7 @@
namespace yiiunit\framework\caching;
+use yii\caching\Cache;
use yii\caching\DbCache;
/**
@@ -38,6 +39,12 @@ protected function setUp()
')->execute();
}
+ protected function tearDown()
+ {
+ $this->getConnection()->createCommand('DROP TABLE IF EXISTS cache')->execute();
+ parent::tearDown();
+ }
+
/**
* @param bool $reset whether to clean up the test database
* @return \yii\db\Connection
@@ -67,12 +74,14 @@ public function getConnection($reset = true)
}
/**
- * @return DbCache
+ * @return Cache
*/
protected function getCacheInstance()
{
if ($this->_cacheInstance === null) {
- $this->_cacheInstance = new DbCache(['db' => $this->getConnection()]);
+ $this->_cacheInstance = new Cache([
+ 'handler' => new DbCache(['db' => $this->getConnection()])
+ ]);
}
return $this->_cacheInstance;
@@ -87,7 +96,7 @@ public function testExpire()
static::$time++;
$this->assertEquals('expire_test', $cache->get('expire_test'));
static::$time++;
- $this->assertFalse($cache->get('expire_test'));
+ $this->assertNull($cache->get('expire_test'));
}
public function testExpireAdd()
@@ -99,6 +108,6 @@ public function testExpireAdd()
static::$time++;
$this->assertEquals('expire_testa', $cache->get('expire_testa'));
static::$time++;
- $this->assertFalse($cache->get('expire_testa'));
+ $this->assertNull($cache->get('expire_testa'));
}
}
diff --git a/tests/framework/caching/DependencyTest.php b/tests/framework/caching/DependencyTest.php
index a31b1bff4af..3c8b239b773 100644
--- a/tests/framework/caching/DependencyTest.php
+++ b/tests/framework/caching/DependencyTest.php
@@ -9,6 +9,7 @@
use yii\caching\Cache;
use yii\caching\Dependency;
+use yii\caching\SimpleCache;
use yiiunit\data\cache\MockDependency;
use yiiunit\TestCase;
@@ -44,8 +45,10 @@ public function testGenerateReusableHash()
public function testIsChanged()
{
+ /* @var $dependency Dependency */
+ /* @var $cache SimpleCache */
$dependency = $this->getMockForAbstractClass(Dependency::class);
- $cache = $this->getMockForAbstractClass(Cache::class);
+ $cache = $this->getMockForAbstractClass(SimpleCache::class);
$result = $dependency->isChanged($cache);
$this->assertFalse($result);
diff --git a/tests/framework/caching/FileCacheTest.php b/tests/framework/caching/FileCacheTest.php
index 7129c880bfd..ce68a0aa699 100644
--- a/tests/framework/caching/FileCacheTest.php
+++ b/tests/framework/caching/FileCacheTest.php
@@ -7,6 +7,7 @@
namespace yiiunit\framework\caching;
+use yii\caching\Cache;
use yii\caching\FileCache;
/**
@@ -18,12 +19,14 @@ class FileCacheTest extends CacheTestCase
private $_cacheInstance = null;
/**
- * @return FileCache
+ * @return Cache
*/
protected function getCacheInstance()
{
if ($this->_cacheInstance === null) {
- $this->_cacheInstance = new FileCache(['cachePath' => '@yiiunit/runtime/cache']);
+ $this->_cacheInstance = new Cache([
+ 'handler' => new FileCache(['cachePath' => '@yiiunit/runtime/cache'])
+ ]);
}
return $this->_cacheInstance;
@@ -38,7 +41,7 @@ public function testExpire()
static::$time++;
$this->assertEquals('expire_test', $cache->get('expire_test'));
static::$time++;
- $this->assertFalse($cache->get('expire_test'));
+ $this->assertNull($cache->get('expire_test'));
}
public function testExpireAdd()
@@ -50,6 +53,6 @@ public function testExpireAdd()
static::$time++;
$this->assertEquals('expire_testa', $cache->get('expire_testa'));
static::$time++;
- $this->assertFalse($cache->get('expire_testa'));
+ $this->assertNull($cache->get('expire_testa'));
}
}
diff --git a/tests/framework/caching/MemCachedTest.php b/tests/framework/caching/MemCachedTest.php
index ab55f10994b..1c0b5ece7a0 100644
--- a/tests/framework/caching/MemCachedTest.php
+++ b/tests/framework/caching/MemCachedTest.php
@@ -7,6 +7,7 @@
namespace yiiunit\framework\caching;
+use yii\caching\Cache;
use yii\caching\MemCached;
/**
@@ -19,7 +20,7 @@ class MemCachedTest extends CacheTestCase
private $_cacheInstance = null;
/**
- * @return MemCached
+ * @return Cache
*/
protected function getCacheInstance()
{
@@ -33,7 +34,9 @@ protected function getCacheInstance()
}
if ($this->_cacheInstance === null) {
- $this->_cacheInstance = new MemCached();
+ $this->_cacheInstance = new Cache([
+ 'handler' => new MemCached()
+ ]);
}
return $this->_cacheInstance;
diff --git a/tests/framework/caching/SimpleCacheTest.php b/tests/framework/caching/SimpleCacheTest.php
new file mode 100644
index 00000000000..101cb4d2c2d
--- /dev/null
+++ b/tests/framework/caching/SimpleCacheTest.php
@@ -0,0 +1,64 @@
+cache = $this->getMockBuilder(SimpleCache::class)->getMockForAbstractClass();
+ }
+
+ /**
+ * Data provider for [[testNormalizeTtl()]]
+ * @return array test data.
+ */
+ public function dataProviderNormalizeTtl()
+ {
+ return [
+ [123, 123],
+ ['123', 123],
+ [null, 9999],
+ [0, 0],
+ [new DateInterval('PT6H8M'), (6 * 3600 + 8 * 60)],
+ [new DateInterval('P2Y4D'), (2 * 365 * 24 * 3600 + 4 * 24 * 3600)],
+ ];
+ }
+
+ /**
+ * @dataProvider dataProviderNormalizeTtl
+ *
+ * @covers \yii\caching\SimpleCache::normalizeTtl()
+ *
+ * @param mixed $ttl
+ * @param int $expectedResult
+ */
+ public function testNormalizeTtl($ttl, $expectedResult)
+ {
+ $this->cache->defaultTtl = 9999;
+ $this->assertEquals($expectedResult, $this->invokeMethod($this->cache, 'normalizeTtl', [$ttl]));
+ }
+}
\ No newline at end of file
diff --git a/tests/framework/caching/TagDependencyTest.php b/tests/framework/caching/TagDependencyTest.php
index b56c91b9955..bb2a74a3945 100644
--- a/tests/framework/caching/TagDependencyTest.php
+++ b/tests/framework/caching/TagDependencyTest.php
@@ -7,6 +7,7 @@
namespace yiiunit\framework\caching;
+use yii\caching\Cache;
use yii\caching\FileCache;
use yii\caching\TagDependency;
use yiiunit\TestCase;
@@ -18,7 +19,7 @@ class TagDependencyTest extends TestCase
{
public function testInvalidate()
{
- $cache = new FileCache(['cachePath' => '@yiiunit/runtime/cache']);
+ $cache = new Cache(['handler' => new FileCache(['cachePath' => '@yiiunit/runtime/cache'])]);
// single tag test
$cache->set('a1', 11, 0, new TagDependency(['tags' => 't1']));
@@ -32,16 +33,16 @@ public function testInvalidate()
$this->assertEquals(22, $cache->get('b2'));
TagDependency::invalidate($cache, 't1');
- $this->assertFalse($cache->get('a1'));
- $this->assertFalse($cache->get('a2'));
+ $this->assertNull($cache->get('a1'));
+ $this->assertNull($cache->get('a2'));
$this->assertEquals(21, $cache->get('b1'));
$this->assertEquals(22, $cache->get('b2'));
TagDependency::invalidate($cache, 't2');
- $this->assertFalse($cache->get('a1'));
- $this->assertFalse($cache->get('a2'));
- $this->assertFalse($cache->get('b1'));
- $this->assertFalse($cache->get('b2'));
+ $this->assertNull($cache->get('a1'));
+ $this->assertNull($cache->get('a2'));
+ $this->assertNull($cache->get('b1'));
+ $this->assertNull($cache->get('b2'));
// multiple tag test
$cache->set('a1', 11, 0, new TagDependency(['tags' => ['t1', 't2']]));
@@ -55,16 +56,16 @@ public function testInvalidate()
$this->assertEquals(22, $cache->get('b2'));
TagDependency::invalidate($cache, 't1');
- $this->assertFalse($cache->get('a1'));
- $this->assertFalse($cache->get('a2'));
- $this->assertFalse($cache->get('b1'));
+ $this->assertNull($cache->get('a1'));
+ $this->assertNull($cache->get('a2'));
+ $this->assertNull($cache->get('b1'));
$this->assertEquals(22, $cache->get('b2'));
TagDependency::invalidate($cache, 't2');
- $this->assertFalse($cache->get('a1'));
- $this->assertFalse($cache->get('a2'));
- $this->assertFalse($cache->get('b1'));
- $this->assertFalse($cache->get('b2'));
+ $this->assertNull($cache->get('a1'));
+ $this->assertNull($cache->get('a2'));
+ $this->assertNull($cache->get('b1'));
+ $this->assertNull($cache->get('b2'));
$cache->set('a1', 11, 0, new TagDependency(['tags' => ['t1', 't2']]));
$cache->set('a2', 12, 0, new TagDependency(['tags' => 't1']));
@@ -77,9 +78,9 @@ public function testInvalidate()
$this->assertEquals(22, $cache->get('b2'));
TagDependency::invalidate($cache, ['t1', 't2']);
- $this->assertFalse($cache->get('a1'));
- $this->assertFalse($cache->get('a2'));
- $this->assertFalse($cache->get('b1'));
- $this->assertFalse($cache->get('b2'));
+ $this->assertNull($cache->get('a1'));
+ $this->assertNull($cache->get('a2'));
+ $this->assertNull($cache->get('b1'));
+ $this->assertNull($cache->get('b2'));
}
}
diff --git a/tests/framework/caching/WinCacheTest.php b/tests/framework/caching/WinCacheTest.php
index e29069225d5..1f45a08afac 100644
--- a/tests/framework/caching/WinCacheTest.php
+++ b/tests/framework/caching/WinCacheTest.php
@@ -7,6 +7,7 @@
namespace yiiunit\framework\caching;
+use yii\caching\Cache;
use yii\caching\WinCache;
/**
@@ -19,7 +20,7 @@ class WinCacheTest extends CacheTestCase
private $_cacheInstance = null;
/**
- * @return WinCache
+ * @return Cache
*/
protected function getCacheInstance()
{
@@ -32,7 +33,9 @@ protected function getCacheInstance()
}
if ($this->_cacheInstance === null) {
- $this->_cacheInstance = new WinCache();
+ $this->_cacheInstance = new Cache([
+ 'handler' => new WinCache()
+ ]);
}
return $this->_cacheInstance;
diff --git a/tests/framework/console/UnkownCommandExceptionTest.php b/tests/framework/console/UnkownCommandExceptionTest.php
index 88897ede55a..32258f51ab1 100644
--- a/tests/framework/console/UnkownCommandExceptionTest.php
+++ b/tests/framework/console/UnkownCommandExceptionTest.php
@@ -38,10 +38,10 @@ public function suggestedCommandsProvider()
['mirgte/up', ['migrate/up']],
['mirgte', ['migrate']],
['hlp', ['help']],
- ['ca', ['cache', 'cache/flush', 'cache/flush-all', 'cache/flush-schema', 'cache/index']],
- ['cach', ['cache', 'cache/flush', 'cache/flush-all', 'cache/flush-schema', 'cache/index']],
- ['cach/fush', ['cache/flush']],
- ['cach/fushall', ['cache/flush-all']],
+ ['ca', ['cache', 'cache/clear', 'cache/clear-all', 'cache/clear-schema', 'cache/index']],
+ ['cach', ['cache', 'cache/clear', 'cache/clear-all', 'cache/clear-schema', 'cache/index']],
+ ['cach/clear', ['cache/clear']],
+ ['cach/clearall', ['cache/clear-all']],
['what?', []],
// test UTF 8 chars
['ёлка', []],
diff --git a/tests/framework/console/controllers/CacheControllerTest.php b/tests/framework/console/controllers/CacheControllerTest.php
index 89496815cd5..ee8e5a144f2 100644
--- a/tests/framework/console/controllers/CacheControllerTest.php
+++ b/tests/framework/console/controllers/CacheControllerTest.php
@@ -50,7 +50,7 @@ protected function setUp()
'components' => [
'firstCache' => 'yii\caching\ArrayCache',
'secondCache' => 'yii\caching\ArrayCache',
- 'session' => 'yii\web\CacheSession', // should be ignored at `actionFlushAll()`
+ 'session' => 'yii\web\CacheSession', // should be ignored at `actionClearAll()`
'db' => [
'class' => isset($config['class']) ? $config['class'] : 'yii\db\Connection',
'dsn' => $config['dsn'],
@@ -79,10 +79,10 @@ public function testFlushOne()
Yii::$app->firstCache->set('secondKey', 'secondValue');
Yii::$app->secondCache->set('thirdKey', 'thirdValue');
- $this->_cacheController->actionFlush('firstCache');
+ $this->_cacheController->actionClear('firstCache');
- $this->assertFalse(Yii::$app->firstCache->get('firstKey'), 'first cache data should be flushed');
- $this->assertFalse(Yii::$app->firstCache->get('secondKey'), 'first cache data should be flushed');
+ $this->assertNull(Yii::$app->firstCache->get('firstKey'), 'first cache data should be flushed');
+ $this->assertNull(Yii::$app->firstCache->get('secondKey'), 'first cache data should be flushed');
$this->assertEquals('thirdValue', Yii::$app->secondCache->get('thirdKey'), 'second cache data should not be flushed');
}
@@ -99,7 +99,7 @@ public function testClearSchema()
$noCacheSchemas = $schema->getTableSchemas('', true);
$this->assertNotEquals($noCacheSchemas, $cacheSchema, 'Schemas should be different.');
- $this->_cacheController->actionFlushSchema('db');
+ $this->_cacheController->actionClearSchema('db');
$cacheSchema = $schema->getTableSchemas('', false);
$this->assertEquals($noCacheSchemas, $cacheSchema, 'Schema cache should be flushed.');
}
@@ -110,18 +110,18 @@ public function testFlushBoth()
Yii::$app->firstCache->set('secondKey', 'secondValue');
Yii::$app->secondCache->set('thirdKey', 'secondValue');
- $this->_cacheController->actionFlush('firstCache', 'secondCache');
+ $this->_cacheController->actionClear('firstCache', 'secondCache');
- $this->assertFalse(Yii::$app->firstCache->get('firstKey'), 'first cache data should be flushed');
- $this->assertFalse(Yii::$app->firstCache->get('secondKey'), 'first cache data should be flushed');
- $this->assertFalse(Yii::$app->secondCache->get('thirdKey'), 'second cache data should be flushed');
+ $this->assertNull(Yii::$app->firstCache->get('firstKey'), 'first cache data should be flushed');
+ $this->assertNull(Yii::$app->firstCache->get('secondKey'), 'first cache data should be flushed');
+ $this->assertNull(Yii::$app->secondCache->get('thirdKey'), 'second cache data should be flushed');
}
public function testNotFoundFlush()
{
Yii::$app->firstCache->set('firstKey', 'firstValue');
- $this->_cacheController->actionFlush('notExistingCache');
+ $this->_cacheController->actionClear('notExistingCache');
$this->assertEquals('firstValue', Yii::$app->firstCache->get('firstKey'), 'first cache data should not be flushed');
}
@@ -131,7 +131,7 @@ public function testNotFoundFlush()
*/
public function testNothingToFlushException()
{
- $this->_cacheController->actionFlush();
+ $this->_cacheController->actionClear();
}
public function testFlushAll()
@@ -139,9 +139,9 @@ public function testFlushAll()
Yii::$app->firstCache->set('firstKey', 'firstValue');
Yii::$app->secondCache->set('thirdKey', 'secondValue');
- $this->_cacheController->actionFlushAll();
+ $this->_cacheController->actionClearAll();
- $this->assertFalse(Yii::$app->firstCache->get('firstKey'), 'first cache data should be flushed');
- $this->assertFalse(Yii::$app->secondCache->get('thirdKey'), 'second cache data should be flushed');
+ $this->assertNull(Yii::$app->firstCache->get('firstKey'), 'first cache data should be flushed');
+ $this->assertNull(Yii::$app->secondCache->get('thirdKey'), 'second cache data should be flushed');
}
}
diff --git a/tests/framework/console/controllers/HelpControllerTest.php b/tests/framework/console/controllers/HelpControllerTest.php
index 708c069ee24..29825f96924 100644
--- a/tests/framework/console/controllers/HelpControllerTest.php
+++ b/tests/framework/console/controllers/HelpControllerTest.php
@@ -65,9 +65,9 @@ public function testActionList()
$result = Console::stripAnsiFormat($this->runControllerAction('list'));
$this->assertEqualsWithoutLE(<<<'STRING'
cache
-cache/flush
-cache/flush-all
-cache/flush-schema
+cache/clear
+cache/clear-all
+cache/clear-schema
cache/index
help
help/index
diff --git a/tests/framework/db/CommandTest.php b/tests/framework/db/CommandTest.php
index ae9d4ca2175..3ff8e1717ba 100644
--- a/tests/framework/db/CommandTest.php
+++ b/tests/framework/db/CommandTest.php
@@ -7,6 +7,8 @@
namespace yiiunit\framework\db;
+use yii\caching\ArrayCache;
+use yii\caching\Cache;
use yii\caching\FileCache;
use yii\db\Connection;
use yii\db\DataReader;
@@ -861,7 +863,7 @@ public function testQueryCache()
{
$db = $this->getConnection();
$db->enableQueryCache = true;
- $db->queryCache = new FileCache(['cachePath' => '@yiiunit/runtime/cache']);
+ $db->queryCache = new Cache(['handler' => new ArrayCache()]);
$command = $db->createCommand('SELECT [[name]] FROM {{customer}} WHERE [[id]] = :id');
$this->assertEquals('user1', $command->bindValue(':id', 1)->queryScalar());
diff --git a/tests/framework/filters/PageCacheTest.php b/tests/framework/filters/PageCacheTest.php
index edf6b20486d..e5ad433d53a 100644
--- a/tests/framework/filters/PageCacheTest.php
+++ b/tests/framework/filters/PageCacheTest.php
@@ -10,6 +10,7 @@
use Yii;
use yii\base\Action;
use yii\caching\ArrayCache;
+use yii\caching\Cache;
use yii\caching\ExpressionDependency;
use yii\filters\PageCache;
use yii\helpers\ArrayHelper;
@@ -153,7 +154,7 @@ public function testCache($testCase)
$controller = new Controller('test', Yii::$app);
$action = new Action('test', $controller);
$filter = new PageCache(array_merge([
- 'cache' => $cache = new ArrayCache(),
+ 'cache' => $cache = new Cache(['handler' => new ArrayCache()]),
'view' => new View(),
], $testCase['properties']));
$this->assertTrue($filter->beforeAction($action), $testCase['name']);
@@ -195,9 +196,9 @@ public function testCache($testCase)
'statusText' => Yii::$app->response->statusText,
];
if ($testCase['cacheable']) {
- $this->assertNotEmpty($this->getInaccessibleProperty($filter->cache, '_cache'), $testCase['name']);
+ $this->assertNotEmpty($this->getInaccessibleProperty($filter->cache->handler, '_cache'), $testCase['name']);
} else {
- $this->assertEmpty($this->getInaccessibleProperty($filter->cache, '_cache'), $testCase['name']);
+ $this->assertEmpty($this->getInaccessibleProperty($filter->cache->handler, '_cache'), $testCase['name']);
return;
}
@@ -251,7 +252,7 @@ public function testExpired()
$controller = new Controller('test', Yii::$app);
$action = new Action('test', $controller);
$filter = new PageCache([
- 'cache' => $cache = new ArrayCache(),
+ 'cache' => $cache = new Cache(['handler' => new ArrayCache()]),
'view' => new View(),
'duration' => 1,
]);
@@ -264,7 +265,7 @@ public function testExpired()
Yii::$app->response->send();
ob_end_clean();
- $this->assertNotEmpty($this->getInaccessibleProperty($filter->cache, '_cache'));
+ $this->assertNotEmpty($this->getInaccessibleProperty($filter->cache->handler, '_cache'));
// mock sleep(2);
CacheTestCase::$time += 2;
@@ -303,7 +304,7 @@ public function testVaryByRoute()
$action = new Action('test', $controller);
Yii::$app->requestedRoute = $action->uniqueId;
$filter = new PageCache([
- 'cache' => $cache = new ArrayCache(),
+ 'cache' => $cache = new Cache(['handler' => new ArrayCache()]),
'view' => new View(),
'varyByRoute' => $enabled,
]);
@@ -316,7 +317,7 @@ public function testVaryByRoute()
Yii::$app->response->send();
ob_end_clean();
- $this->assertNotEmpty($this->getInaccessibleProperty($filter->cache, '_cache'));
+ $this->assertNotEmpty($this->getInaccessibleProperty($filter->cache->handler, '_cache'));
// Verifies the cached response
$this->destroyApplication();
@@ -356,7 +357,7 @@ public function testVariations()
$originalVariations = $testCases[0];
array_shift($originalVariations);
$filter = new PageCache([
- 'cache' => $cache = new ArrayCache(),
+ 'cache' => $cache = new Cache(['handler' => new ArrayCache()]),
'view' => new View(),
'variations' => $originalVariations,
]);
@@ -369,7 +370,7 @@ public function testVariations()
Yii::$app->response->send();
ob_end_clean();
- $this->assertNotEmpty($this->getInaccessibleProperty($filter->cache, '_cache'));
+ $this->assertNotEmpty($this->getInaccessibleProperty($filter->cache->handler, '_cache'));
// Verifies the cached response
$this->destroyApplication();
@@ -405,7 +406,7 @@ public function testDependency()
$controller = new Controller('test', Yii::$app);
$action = new Action('test', $controller);
$filter = new PageCache([
- 'cache' => $cache = new ArrayCache(),
+ 'cache' => $cache = new Cache(['handler' => new ArrayCache()]),
'view' => new View(),
'dependency' => [
'class' => ExpressionDependency::class,
@@ -422,7 +423,7 @@ public function testDependency()
Yii::$app->response->send();
ob_end_clean();
- $this->assertNotEmpty($this->getInaccessibleProperty($filter->cache, '_cache'));
+ $this->assertNotEmpty($this->getInaccessibleProperty($filter->cache->handler, '_cache'));
// Verifies the cached response
$this->destroyApplication();
diff --git a/tests/framework/rbac/MySQLManagerCacheTest.php b/tests/framework/rbac/MySQLManagerCacheTest.php
index bb3ce87331e..8ca698cdc33 100644
--- a/tests/framework/rbac/MySQLManagerCacheTest.php
+++ b/tests/framework/rbac/MySQLManagerCacheTest.php
@@ -7,6 +7,7 @@
namespace yiiunit\framework\rbac;
+use yii\caching\Cache;
use yii\caching\FileCache;
use yii\rbac\DbManager;
@@ -25,7 +26,7 @@ protected function createManager()
{
return new DbManager([
'db' => $this->getConnection(),
- 'cache' => new FileCache(['cachePath' => '@yiiunit/runtime/cache']),
+ 'cache' => new Cache(['handler' => new FileCache(['cachePath' => '@yiiunit/runtime/cache'])]),
'defaultRoles' => ['myDefaultRole'],
]);
}
diff --git a/tests/framework/rbac/PgSQLManagerCacheTest.php b/tests/framework/rbac/PgSQLManagerCacheTest.php
index 7451ba4fd10..c6bc1181452 100644
--- a/tests/framework/rbac/PgSQLManagerCacheTest.php
+++ b/tests/framework/rbac/PgSQLManagerCacheTest.php
@@ -7,6 +7,7 @@
namespace yiiunit\framework\rbac;
+use yii\caching\Cache;
use yii\caching\FileCache;
use yii\rbac\DbManager;
@@ -27,7 +28,7 @@ protected function createManager()
{
return new DbManager([
'db' => $this->getConnection(),
- 'cache' => new FileCache(['cachePath' => '@yiiunit/runtime/cache']),
+ 'cache' => new Cache(['handler' => new FileCache(['cachePath' => '@yiiunit/runtime/cache'])]),
'defaultRoles' => ['myDefaultRole'],
]);
}
diff --git a/tests/framework/web/CacheSessionTest.php b/tests/framework/web/CacheSessionTest.php
index c73a960e02a..cae926ebc3d 100644
--- a/tests/framework/web/CacheSessionTest.php
+++ b/tests/framework/web/CacheSessionTest.php
@@ -8,7 +8,8 @@
namespace yiiunit\framework\web;
use Yii;
-use yii\caching\FileCache;
+use yii\caching\ArrayCache;
+use yii\caching\Cache;
use yii\web\CacheSession;
/**
@@ -20,7 +21,7 @@ protected function setUp()
{
parent::setUp();
$this->mockApplication();
- Yii::$app->set('cache', new FileCache());
+ Yii::$app->set('cache', new Cache(['handler' => new ArrayCache()]));
}
public function testCacheSession()
diff --git a/tests/framework/widgets/FragmentCacheTest.php b/tests/framework/widgets/FragmentCacheTest.php
index 24e0ed5a50e..5a23d4084bc 100644
--- a/tests/framework/widgets/FragmentCacheTest.php
+++ b/tests/framework/widgets/FragmentCacheTest.php
@@ -10,6 +10,7 @@
use Yii;
use yii\base\View;
use yii\caching\ArrayCache;
+use yii\caching\Cache;
/**
* @group widgets
@@ -22,7 +23,8 @@ protected function setUp()
parent::setUp();
$this->mockWebApplication();
Yii::$app->set('cache', [
- 'class' => ArrayCache::class,
+ 'class' => Cache::class,
+ 'handler' => ArrayCache::class,
]);
}