From: colemanw Date: Sat, 2 Dec 2023 19:08:46 +0000 (+0000) Subject: Add CRM_Utils_CacheWrapper to all caches X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=2b236a709068afd3ffec05d4c18fa46a05859ef1;p=civicrm-core.git Add CRM_Utils_CacheWrapper to all caches This wraps all caches and dispatches a 'civi.cache.clear' event when deleting items from the cache. --- diff --git a/CRM/Utils/Cache.php b/CRM/Utils/Cache.php index c35c23fe7d..bb4bf4560b 100644 --- a/CRM/Utils/Cache.php +++ b/CRM/Utils/Cache.php @@ -168,6 +168,7 @@ class CRM_Utils_Cache { public static function create($params = []) { $types = (array) $params['type']; + // FIXME: When would name ever be empty? if (!empty($params['name'])) { $params['name'] = self::cleanKey($params['name']); } @@ -183,26 +184,30 @@ class CRM_Utils_Cache { if (!empty($params['withArray'])) { $cache = $params['withArray'] === 'fast' ? new CRM_Utils_Cache_FastArrayDecorator($cache) : new CRM_Utils_Cache_ArrayDecorator($cache); } - return $cache; + break 2; } break; case 'SqlGroup': if (defined('CIVICRM_DSN') && CIVICRM_DSN) { - return new CRM_Utils_Cache_SqlGroup([ + $cache = new CRM_Utils_Cache_SqlGroup([ 'group' => $params['name'], 'prefetch' => $params['prefetch'] ?? FALSE, ]); + break 2; } break; case 'Arraycache': case 'ArrayCache': - return new CRM_Utils_Cache_ArrayCache([]); + $cache = new CRM_Utils_Cache_ArrayCache([]); + break 2; } } - + if (isset($cache)) { + return new CRM_Utils_Cache_CacheWrapper($cache, $params['name'] ?? NULL); + } throw new CRM_Core_Exception("Failed to instantiate cache. No supported cache type found. " . print_r($params, 1)); } diff --git a/CRM/Utils/Cache/CacheWrapper.php b/CRM/Utils/Cache/CacheWrapper.php new file mode 100644 index 0000000000..82e7e47c82 --- /dev/null +++ b/CRM/Utils/Cache/CacheWrapper.php @@ -0,0 +1,106 @@ +delegate = $delegate; + $this->cacheName = $cacheName; + } + + public function getMultiple($keys, $default = NULL) { + return $this->delegate->getMultiple($keys, $default); + } + + public function setMultiple($values, $ttl = NULL) { + return $this->delegate->setMultiple($values, $ttl); + } + + public function deleteMultiple($keys) { + $this->dispatchClearEvent($keys); + return $this->delegate->deleteMultiple($keys); + } + + public function set($key, $value, $ttl = NULL) { + return $this->delegate->set($key, $value, $ttl); + } + + public function get($key, $default = NULL) { + return $this->delegate->get($key, $default); + } + + public function delete($key) { + $this->dispatchClearEvent([$key]); + return $this->delegate->delete($key); + } + + /** + * @deprecated + */ + public function flush() { + return $this->clear(); + } + + public function clear() { + $this->dispatchClearEvent(); + return $this->delegate->clear(); + } + + public function has($key) { + return $this->delegate->has($key); + } + + /** + * @param string $key + * @return int|null + */ + public function getExpires($key) { + if (method_exists($this->delegate, 'getExpires')) { + return $this->delegate->getExpires($key); + } + return NULL; + } + + private function dispatchClearEvent($keys = NULL) { + // FIXME: When would name ever be empty? + if ($this->cacheName) { + $hookParams = [ + 'cacheName' => $this->cacheName, + 'items' => $keys, + ]; + $event = \Civi\Core\Event\GenericHookEvent::create($hookParams); + Civi::dispatcher()->dispatch('civi.cache.clear', $event); + } + } + +} diff --git a/CRM/Utils/Cache/SqlGroup.php b/CRM/Utils/Cache/SqlGroup.php index 97df20cb12..dbc24d8772 100644 --- a/CRM/Utils/Cache/SqlGroup.php +++ b/CRM/Utils/Cache/SqlGroup.php @@ -30,7 +30,7 @@ class CRM_Utils_Cache_SqlGroup implements CRM_Utils_Cache_Interface { use CRM_Utils_Cache_NaiveMultipleTrait; /** - * The host name of the memcached server. + * Name of the cache group. * * @var string */ diff --git a/tests/phpunit/Civi/Core/Service/AutoDefinitionTest.php b/tests/phpunit/Civi/Core/Service/AutoDefinitionTest.php index 2947df817d..ba61ab6a13 100644 --- a/tests/phpunit/Civi/Core/Service/AutoDefinitionTest.php +++ b/tests/phpunit/Civi/Core/Service/AutoDefinitionTest.php @@ -101,8 +101,10 @@ class AutoDefinitionTest extends \CiviUnitTestCase { ); $instance = \Civi::service('TestNamedProperty'); - $this->assertInstanceOf(\CRM_Utils_Cache_SqlGroup::class, $instance->cache); - $this->assertEquals('extension_browser', Invasive::get([$instance->cache, 'group'])); + $this->assertInstanceOf(\CRM_Utils_Cache_CacheWrapper::class, $instance->cache); + $cacheClass = Invasive::get([$instance->cache, 'delegate']); + $this->assertInstanceOf(\CRM_Utils_Cache_SqlGroup::class, $cacheClass); + $this->assertEquals('extension_browser', Invasive::get([$instance->cache, 'cacheName'])); } /** @@ -178,8 +180,11 @@ class AutoDefinitionTest extends \CiviUnitTestCase { $instance = \Civi::service('TestInjectConstructor'); $this->assertInstanceOf(LoggerInterface::class, Invasive::get([$instance, 'log'])); - $this->assertInstanceOf(\CRM_Utils_Cache_SqlGroup::class, Invasive::get([$instance, 'cache'])); - $this->assertEquals('extension_browser', Invasive::get([Invasive::get([$instance, 'cache']), 'group'])); + $cacheWrapper = Invasive::get([$instance, 'cache']); + $cacheClass = Invasive::get([$cacheWrapper, 'delegate']); + $this->assertInstanceOf(\CRM_Utils_Cache_SqlGroup::class, $cacheClass); + $this->assertEquals('extension_browser', Invasive::get([$cacheWrapper, 'cacheName'])); + $this->assertEquals('extension_browser', Invasive::get([$cacheClass, 'group'])); } /**