(dev/core#174) CRM_Utils_Cache_Interface - Add `has()` (PSR-16)
[civicrm-core.git] / CRM / Utils / Cache / Redis.php
index 07279d530de987f039fc4f9e3e56a1f6c76bf04f..01fc538c9355cd38af7dd5b35bbd5a3ae4c2dcaf 100644 (file)
  *
  */
 class CRM_Utils_Cache_Redis implements CRM_Utils_Cache_Interface {
+
+  use CRM_Utils_Cache_NaiveMultipleTrait; // TODO Consider native implementation.
+  use CRM_Utils_Cache_NaiveHasTrait; // TODO Native implementation
+
   const DEFAULT_HOST    = 'localhost';
   const DEFAULT_PORT    = 6379;
   const DEFAULT_TIMEOUT = 3600;
@@ -105,19 +109,31 @@ class CRM_Utils_Cache_Redis implements CRM_Utils_Cache_Interface {
       echo 'Could not connect to redisd server';
       CRM_Utils_System::civiExit();
     }
-    $this->_cache->auth(CIVICRM_DB_CACHE_PASSWORD);
+    if (CRM_Utils_Constant::value('CIVICRM_DB_CACHE_PASSWORD')) {
+      $this->_cache->auth(CIVICRM_DB_CACHE_PASSWORD);
+    }
   }
 
   /**
    * @param $key
    * @param $value
+   * @param null|int|\DateInterval $ttl
    *
    * @return bool
    * @throws Exception
    */
-  public function set($key, &$value) {
+  public function set($key, $value, $ttl = NULL) {
+    if ($ttl !== NULL) {
+      throw new \RuntimeException("FIXME: " . __CLASS__ . "::set() should support non-NULL TTL");
+    }
     if (!$this->_cache->set($this->_prefix . $key, serialize($value), $this->_timeout)) {
-      CRM_Core_Error::fatal("Redis set failed, wondering why?, $key", $value);
+      if (PHP_SAPI === 'cli' || (Civi\Core\Container::isContainerBooted() && CRM_Core_Permission::check('view debug output'))) {
+        CRM_Core_Error::fatal("Redis set ($key) failed: " . $this->_cache->getLastError());
+      }
+      else {
+        Civi::log()->error("Redis set ($key) failed: " . $this->_cache->getLastError());
+        CRM_Core_Error::fatal("Redis set ($key) failed");
+      }
       return FALSE;
     }
     return TRUE;
@@ -125,28 +141,40 @@ class CRM_Utils_Cache_Redis implements CRM_Utils_Cache_Interface {
 
   /**
    * @param $key
+   * @param mixed $default
    *
    * @return mixed
    */
-  public function get($key) {
+  public function get($key, $default = NULL) {
     $result = $this->_cache->get($this->_prefix . $key);
-    return unserialize($result);
+    return ($result === FALSE) ? $default : unserialize($result);
   }
 
   /**
    * @param $key
    *
-   * @return mixed
+   * @return bool
    */
   public function delete($key) {
-    return $this->_cache->delete($this->_prefix . $key);
+    $this->_cache->delete($this->_prefix . $key);
+    return TRUE;
   }
 
   /**
-   * @return mixed
+   * @return bool
    */
   public function flush() {
-    return $this->_cache->flushDB();
+    // FIXME: Ideally, we'd map each prefix to a different 'hash' object in Redis,
+    // and this would be simpler. However, that needs to go in tandem with a
+    // more general rethink of cache expiration/TTL.
+
+    $keys = $this->_cache->keys($this->_prefix . '*');
+    $this->_cache->del($keys);
+    return TRUE;
+  }
+
+  public function clear() {
+    return $this->flush();
   }
 
 }