diff --git a/README.md b/README.md
index c016951..b14dcdf 100644
--- a/README.md
+++ b/README.md
@@ -126,7 +126,7 @@ function getCategoriesCount()
```
-### Simplified interface
+### Extended interface
### Using cache tags
diff --git a/src/CacheItemContract.php b/src/CacheItemContract.php
index 76bb956..2cb7bf6 100644
--- a/src/CacheItemContract.php
+++ b/src/CacheItemContract.php
@@ -5,6 +5,12 @@
use Psr\Cache\CacheItemInterface;
/**
+ * CacheItemContract extends {@see \Psr\Cache\CacheItemInterface}, adding extra features.
+ *
+ * It allows managing cache dependencies.
+ *
+ * @see \yii1tech\psr\cache\CacheItemPoolContract
+ *
* @author Paul Klimov
* @since 1.0
*/
diff --git a/src/CacheItemPool.php b/src/CacheItemPool.php
index 9c62a74..7472533 100644
--- a/src/CacheItemPool.php
+++ b/src/CacheItemPool.php
@@ -4,7 +4,6 @@
use CApplicationComponent;
use Psr\Cache\CacheItemInterface;
-use Psr\Cache\CacheItemPoolInterface;
use Yii;
/**
@@ -34,7 +33,7 @@
* @author Paul Klimov
* @since 1.0
*/
-class CacheItemPool extends CApplicationComponent implements CacheItemPoolInterface
+class CacheItemPool extends CApplicationComponent implements CacheItemPoolContract
{
/**
* @var bool whether to automatically commit all deferred items on object destruction.
@@ -230,4 +229,24 @@ public function commit(): bool
return $result;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get(string $key, callable $callback)
+ {
+ $item = $this->getItem($key);
+
+ if ($item->isHit()) {
+ return $item->get();
+ }
+
+ $value = call_user_func($callback, $item);
+
+ $item->set($value);
+
+ $this->save($item);
+
+ return $value;
+ }
}
\ No newline at end of file
diff --git a/src/CacheItemPoolContract.php b/src/CacheItemPoolContract.php
new file mode 100644
index 0000000..7532b65
--- /dev/null
+++ b/src/CacheItemPoolContract.php
@@ -0,0 +1,54 @@
+
+ * @since 1.0
+ */
+interface CacheItemPoolContract extends CacheItemPoolInterface
+{
+ /**
+ * {@inheritdoc}
+ *
+ * @return \yii1tech\psr\cache\CacheItemContract the corresponding Cache Item.
+ */
+ public function getItem($key);
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return \Traversable|array collection of Cache Items keyed by the cache keys of each item.
+ */
+ public function getItems(array $keys = []);
+
+ /**
+ * Fetches a value from the pool or computes it via given callback if not found.
+ * Usage example:
+ *
+ * ```php
+ * $value = $pool->get('example-cache-key', function (CacheItemContract $item) {
+ * $item->expiresAfter(3600);
+ *
+ * // ...
+ *
+ * return $computedValue; // heavy computations result
+ * });
+ * ```
+ *
+ * @template T
+ *
+ * @param string $key the key of the item to retrieve from the cache.
+ * @param (callable(CacheItemContract,bool):T)|(callable(CacheItemContract,bool):T) $callback callback, which computes value to be cached.
+ * @return T cached value or callback result.
+ */
+ public function get(string $key, callable $callback);
+
+ //public function invalidateTags(array $tags);
+}
\ No newline at end of file
diff --git a/tests/CacheItemPoolTest.php b/tests/CacheItemPoolTest.php
index ec6d574..6e9c253 100644
--- a/tests/CacheItemPoolTest.php
+++ b/tests/CacheItemPoolTest.php
@@ -5,6 +5,7 @@
use CDummyCache;
use DateInterval;
use ICache;
+use yii1tech\psr\cache\CacheItemContract;
use yii1tech\psr\cache\CacheItemPool;
class CacheItemPoolTest extends TestCase
@@ -232,4 +233,35 @@ public function testSaveWithDependency(): void
$item = $pool->getItem($key);
$this->assertFalse($item->isHit());
}
+
+ /**
+ * @depends testSave
+ */
+ public function testGetCallback(): void
+ {
+ $pool = new CacheItemPool();
+
+ $key = 'test';
+
+ $value = $pool->get($key, function (CacheItemContract $item) {
+ $item->expiresAfter(DateInterval::createFromDateString('1 hour'));
+
+ return 'test-value';
+ });
+
+ $this->assertSame('test-value', $value);
+
+ $item = $pool->getItem($key);
+ $this->assertTrue($item->isHit());
+ $this->assertSame('test-value', $item->get());
+
+ $value = $pool->get($key, function (CacheItemContract $item) {
+ $item->expiresAfter(DateInterval::createFromDateString('1 hour'));
+
+ return 'new-value';
+ });
+
+ $this->assertSame('test-value', $value);
+ $this->assertSame('test-value', $pool->getItem($key)->get());
+ }
}
\ No newline at end of file