From b72460a7bbcbfdb51213911810982ef8ce180710 Mon Sep 17 00:00:00 2001 From: Herb v/d Dool Date: Mon, 17 Apr 2023 17:35:51 -0400 Subject: [PATCH] dev/core#4243: new APCucache class that supports apcu_* functions --- CRM/Utils/Cache.php | 1 + CRM/Utils/Cache/APCcache.php | 4 +- CRM/Utils/Cache/APCucache.php | 135 ++++++++++++++++++++++ tests/phpunit/E2E/Cache/APCucacheTest.php | 38 ++++++ 4 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 CRM/Utils/Cache/APCucache.php create mode 100644 tests/phpunit/E2E/Cache/APCucacheTest.php diff --git a/CRM/Utils/Cache.php b/CRM/Utils/Cache.php index 1497d323d9..c35c23fe7d 100644 --- a/CRM/Utils/Cache.php +++ b/CRM/Utils/Cache.php @@ -124,6 +124,7 @@ class CRM_Utils_Cache { break; case 'APCcache': + case 'APCucache': $defaults = []; if (defined('CIVICRM_DB_CACHE_TIMEOUT')) { $defaults['timeout'] = CIVICRM_DB_CACHE_TIMEOUT; diff --git a/CRM/Utils/Cache/APCcache.php b/CRM/Utils/Cache/APCcache.php index 74a89c5328..fa98b0b3f6 100644 --- a/CRM/Utils/Cache/APCcache.php +++ b/CRM/Utils/Cache/APCcache.php @@ -34,8 +34,8 @@ class CRM_Utils_Cache_APCcache implements CRM_Utils_Cache_Interface { /** * The prefix prepended to cache keys. * - * If we are using the same memcache instance for multiple CiviCRM - * installs, we must have a unique prefix for each install to prevent + * If we are using the same instance for multiple CiviCRM installs, + * we must have a unique prefix for each install to prevent * the keys from clobbering each other. * * @var string diff --git a/CRM/Utils/Cache/APCucache.php b/CRM/Utils/Cache/APCucache.php new file mode 100644 index 0000000000..af91bfb6a6 --- /dev/null +++ b/CRM/Utils/Cache/APCucache.php @@ -0,0 +1,135 @@ +_timeout = intval($config['timeout']); + } + if (isset($config['prefix'])) { + $this->_prefix = $config['prefix']; + } + } + + /** + * @param $key + * @param $value + * @param null|int|\DateInterval $ttl + * + * @return bool + */ + public function set($key, $value, $ttl = NULL) { + CRM_Utils_Cache::assertValidKey($key); + if (is_int($ttl) && $ttl <= 0) { + return $this->delete($key); + } + + $ttl = CRM_Utils_Date::convertCacheTtl($ttl, $this->_timeout); + $expires = time() + $ttl; + if (!apcu_store($this->_prefix . $key, ['e' => $expires, 'v' => $value], $ttl)) { + return FALSE; + } + return TRUE; + } + + /** + * @param $key + * @param mixed $default + * + * @return mixed + */ + public function get($key, $default = NULL) { + CRM_Utils_Cache::assertValidKey($key); + $result = apcu_fetch($this->_prefix . $key, $success); + if ($success && isset($result['e']) && $result['e'] > time()) { + return $this->reobjectify($result['v']); + } + return $default; + } + + /** + * @param $key + * + * @return bool|string[] + */ + public function delete($key) { + CRM_Utils_Cache::assertValidKey($key); + apcu_delete($this->_prefix . $key); + return TRUE; + } + + public function flush() { + $allinfo = apcu_cache_info(); + $keys = $allinfo['cache_list']; + // Our keys follows this pattern: ([A-Za-z0-9_]+)?CRM_[A-Za-z0-9_]+ + $prefix = $this->_prefix; + // Get prefix length + $lp = strlen($prefix); + + foreach ($keys as $key) { + $name = $key['info']; + if ($prefix == substr($name, 0, $lp)) { + // Ours? + apcu_delete($name); + } + } + return TRUE; + } + + public function clear() { + return $this->flush(); + } + + private function reobjectify($value) { + return is_object($value) ? unserialize(serialize($value)) : $value; + } + +} diff --git a/tests/phpunit/E2E/Cache/APCucacheTest.php b/tests/phpunit/E2E/Cache/APCucacheTest.php new file mode 100644 index 0000000000..6f7fa31342 --- /dev/null +++ b/tests/phpunit/E2E/Cache/APCucacheTest.php @@ -0,0 +1,38 @@ +markTestSkipped('This environment does not have the APCu extension.'); + } + + if (PHP_SAPI === 'cli') { + $c = (string) ini_get('apc.enable_cli'); + if ($c != 1 && strtolower($c) !== 'on') { + $this->markTestSkipped('This environment is not configured to use APCu cache service. Set apc.enable_cli=on'); + } + } + + $config = [ + 'prefix' => 'foozball/', + ]; + $c = new CRM_Utils_Cache_APCucache($config); + return $c; + } + +} -- 2.25.1