3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * Class CRM_Utils_Cache_ArrayDecorator
21 * This creates a two-tier cache-hierarchy: a thread-local, array-based cache
22 * combined with some third-party cache driver.
24 * Ex: $cache = new CRM_Utils_Cache_ArrayDecorator(new CRM_Utils_Cache_Redis(...));
26 class CRM_Utils_Cache_ArrayDecorator
implements CRM_Utils_Cache_Interface
{
28 // TODO Consider native implementation.
29 use CRM_Utils_Cache_NaiveMultipleTrait
;
33 * Default time-to-live (seconds) for cache items that don't have a TTL.
35 protected $defaultTimeout;
38 * @var CRM_Utils_Cache_Interface
44 * Array(string $cacheKey => mixed $cacheValue).
50 * Array(string $cacheKey => int $expirationTime).
52 private $expires = [];
55 * CRM_Utils_Cache_ArrayDecorator constructor.
56 * @param \CRM_Utils_Cache_Interface $delegate
57 * @param int $defaultTimeout
58 * Default number of seconds each cache-item should endure.
60 public function __construct(\CRM_Utils_Cache_Interface
$delegate, $defaultTimeout = 3600) {
61 $this->defaultTimeout
= $defaultTimeout;
62 $this->delegate
= $delegate;
65 public function set($key, $value, $ttl = NULL) {
66 if (is_int($ttl) && $ttl <= 0) {
67 return $this->delete($key);
70 $expiresAt = CRM_Utils_Date
::convertCacheTtlToExpires($ttl, $this->defaultTimeout
);
71 if ($this->delegate
->set($key, [$expiresAt, $value], $ttl)) {
72 $this->values
[$key] = $this->reobjectify($value);
73 $this->expires
[$key] = $expiresAt;
81 public function get($key, $default = NULL) {
82 CRM_Utils_Cache
::assertValidKey($key);
83 if (array_key_exists($key, $this->values
) && $this->expires
[$key] > CRM_Utils_Time
::getTimeRaw()) {
84 return $this->reobjectify($this->values
[$key]);
87 $nack = CRM_Utils_Cache
::nack();
88 $value = $this->delegate
->get($key, $nack);
89 if ($value === $nack) {
93 $this->expires
[$key] = $value[0];
94 $this->values
[$key] = $value[1];
95 return $this->reobjectify($this->values
[$key]);
98 public function delete($key) {
99 CRM_Utils_Cache
::assertValidKey($key);
100 unset($this->values
[$key]);
101 unset($this->expires
[$key]);
102 return $this->delegate
->delete($key);
105 public function flush() {
106 return $this->clear();
109 public function clear() {
112 return $this->delegate
->clear();
115 public function has($key) {
116 CRM_Utils_Cache
::assertValidKey($key);
117 if (array_key_exists($key, $this->values
) && $this->expires
[$key] > CRM_Utils_Time
::getTimeRaw()) {
120 return $this->delegate
->has($key);
123 private function reobjectify($value) {
124 return is_object($value) ?
unserialize(serialize($value)) : $value;