diff --git a/composer.json b/composer.json index 5d234b1..b6a44e8 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ "psr/cache": "^1.0.0" }, "require-dev": { + "yii1tech/tagged-cache": "^1.0.0", "phpunit/phpunit": "^6.0 || ^7.0 || ^8.0 || ^9.3 || ^10.0.7" }, "autoload": { diff --git a/src/CacheItem.php b/src/CacheItem.php index 75a6fce..eca2969 100644 --- a/src/CacheItem.php +++ b/src/CacheItem.php @@ -5,6 +5,10 @@ use CComponent; /** + * CacheItem represents cache item used for interaction with {@see \yii1tech\psr\cache\CacheItemPool}. + * + * @see \yii1tech\psr\cache\CacheItemPool + * * @author Paul Klimov * @since 1.0 */ @@ -14,21 +18,22 @@ class CacheItem extends CComponent implements CacheItemContract * @var string cache item key (ID). */ private $_key; - /** * @var mixed cache item value. */ private $_value; - /** * @var int|null cache item expire. */ private $_expire; - /** * @var \ICacheDependency|null dependency of the cache item. */ private $_dependency; + /** + * @var string[] list of cache item tags. + */ + private $_tags = []; /** * Sets the key for the current cache item. @@ -70,6 +75,14 @@ public function setDependency(?\ICacheDependency $dependency): self return $this; } + /** + * @return string[] list of associated tags. + */ + public function getTags(): array + { + return $this->_tags; + } + /** * {@inheritdoc} */ @@ -146,4 +159,18 @@ public function depends(?\ICacheDependency $dependency): self { return $this->setDependency($dependency); } + + /** + * {@inheritdoc} + */ + public function tag($tags): self + { + if (!is_array($tags)) { + $tags = [$tags]; + } + + $this->_tags = $tags; + + return $this; + } } \ No newline at end of file diff --git a/src/CacheItemContract.php b/src/CacheItemContract.php index 2cb7bf6..59ecc75 100644 --- a/src/CacheItemContract.php +++ b/src/CacheItemContract.php @@ -23,4 +23,12 @@ interface CacheItemContract extends CacheItemInterface * @return static self reference. */ public function depends(?\ICacheDependency $dependency); + + /** + * Adds one or multiple tags to the item. + * + * @param string|string[] $tags tag or list of tags. + * @return static self reference. + */ + public function tag($tags); } \ No newline at end of file diff --git a/src/CacheItemPool.php b/src/CacheItemPool.php index 7472533..5f5675a 100644 --- a/src/CacheItemPool.php +++ b/src/CacheItemPool.php @@ -30,6 +30,13 @@ * ]; * ``` * + * > Note: for the cache item tags feature this class rely on wrapped Yii cache component, saving item tags + * will silently fail if such support is not provided. You'll need to install and use "yii1tech/tagged-cache" + * extension in order to make tags feature function. + * + * @see https://github.com/yii1tech/tagged-cache + * @see \yii1tech\psr\cache\CacheItem + * * @author Paul Klimov * @since 1.0 */ @@ -198,7 +205,8 @@ public function save(CacheItemInterface $item): bool $item->getKey(), $item->get(), $item->getExpire(), - $item->getDependency() + $item->getDependency(), + $item->getTags() ); } @@ -249,4 +257,12 @@ public function get(string $key, callable $callback) return $value; } + + /** + * {@inheritdoc} + */ + public function invalidateTags(array $tags): bool + { + return $this->getCache()->invalidateTags($tags); + } } \ No newline at end of file diff --git a/src/CacheItemPoolContract.php b/src/CacheItemPoolContract.php index 7532b65..9158ed3 100644 --- a/src/CacheItemPoolContract.php +++ b/src/CacheItemPoolContract.php @@ -50,5 +50,11 @@ public function getItems(array $keys = []); */ public function get(string $key, callable $callback); - //public function invalidateTags(array $tags); + /** + * Deletes cached entries, associated with given tags. + * + * @param string[] $tags tags, which associated with items should be deleted. + * @return bool whether cache entries have been successfully deleted or not. + */ + public function invalidateTags(array $tags): bool; } \ No newline at end of file diff --git a/tests/CacheItemPoolTest.php b/tests/CacheItemPoolTest.php index 6e9c253..8bde9d3 100644 --- a/tests/CacheItemPoolTest.php +++ b/tests/CacheItemPoolTest.php @@ -5,6 +5,7 @@ use CDummyCache; use DateInterval; use ICache; +use yii1tech\cache\tagged\ArrayCache; use yii1tech\psr\cache\CacheItemContract; use yii1tech\psr\cache\CacheItemPool; @@ -264,4 +265,32 @@ public function testGetCallback(): void $this->assertSame('test-value', $value); $this->assertSame('test-value', $pool->getItem($key)->get()); } + + /** + * @depends testSave + */ + public function testSaveWithTags(): void + { + $pool = new CacheItemPool(); + $pool->setCache(new ArrayCache()); + + $item = $pool->getItem('test-1'); + $item->set('test-value-1'); + $item->expiresAfter(DateInterval::createFromDateString('1 hour')); + $item->tag('tag-1'); + + $this->assertTrue($pool->save($item)); + + $item = $pool->getItem('test-2'); + $item->set('test-value-2'); + $item->expiresAfter(DateInterval::createFromDateString('1 hour')); + $item->tag('tag-2'); + + $this->assertTrue($pool->save($item)); + + $this->assertTrue($pool->invalidateTags(['tag-1'])); + + $this->assertFalse($pool->hasItem('test-1')); + $this->assertTrue($pool->hasItem('test-2')); + } } \ No newline at end of file