[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Cache/Storage/ -> RedisStorage.php (source)

   1  <?php
   2  /**
   3   * Joomla! Content Management System
   4   *
   5   * @copyright  (C) 2014 Open Source Matters, Inc. <https://www.joomla.org>
   6   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   7   */
   8  
   9  namespace Joomla\CMS\Cache\Storage;
  10  
  11  \defined('JPATH_PLATFORM') or die;
  12  
  13  use Joomla\CMS\Cache\CacheStorage;
  14  use Joomla\CMS\Cache\Exception\CacheConnectingException;
  15  use Joomla\CMS\Factory;
  16  use Joomla\CMS\Log\Log;
  17  
  18  /**
  19   * Redis cache storage handler for PECL
  20   *
  21   * @since  3.4
  22   */
  23  class RedisStorage extends CacheStorage
  24  {
  25      /**
  26       * Redis connection object
  27       *
  28       * @var    \Redis
  29       * @since  3.4
  30       */
  31      protected static $_redis = null;
  32  
  33      /**
  34       * Persistent session flag
  35       *
  36       * @var    boolean
  37       * @since  3.4
  38       */
  39      protected $_persistent = false;
  40  
  41      /**
  42       * Constructor
  43       *
  44       * @param   array  $options  Optional parameters.
  45       *
  46       * @since   3.4
  47       */
  48  	public function __construct($options = array())
  49      {
  50          parent::__construct($options);
  51  
  52          if (static::$_redis === null)
  53          {
  54              $this->getConnection();
  55          }
  56      }
  57  
  58      /**
  59       * Create the Redis connection
  60       *
  61       * @return  \Redis|boolean  Redis connection object on success, boolean on failure
  62       *
  63       * @since   3.4
  64       * @note    As of 4.0 this method will throw a JCacheExceptionConnecting object on connection failure
  65       */
  66  	protected function getConnection()
  67      {
  68          if (static::isSupported() == false)
  69          {
  70              return false;
  71          }
  72  
  73          $app = Factory::getApplication();
  74  
  75          $this->_persistent = $app->get('redis_persist', true);
  76  
  77          $server = array(
  78              'host' => $app->get('redis_server_host', 'localhost'),
  79              'port' => $app->get('redis_server_port', 6379),
  80              'auth' => $app->get('redis_server_auth', null),
  81              'db'   => (int) $app->get('redis_server_db', null),
  82          );
  83  
  84          // If you are trying to connect to a socket file, ignore the supplied port
  85          if ($server['host'][0] === '/')
  86          {
  87              $server['port'] = 0;
  88          }
  89  
  90          static::$_redis = new \Redis;
  91  
  92          try
  93          {
  94              if ($this->_persistent)
  95              {
  96                  $connection = static::$_redis->pconnect($server['host'], $server['port']);
  97              }
  98              else
  99              {
 100                  $connection = static::$_redis->connect($server['host'], $server['port']);
 101              }
 102          }
 103          catch (\RedisException $e)
 104          {
 105              $connection = false;
 106              Log::add($e->getMessage(), Log::DEBUG);
 107          }
 108  
 109          if ($connection == false)
 110          {
 111              static::$_redis = null;
 112  
 113              throw new CacheConnectingException('Redis connection failed', 500);
 114          }
 115  
 116          try
 117          {
 118              $auth = $server['auth'] ? static::$_redis->auth($server['auth']) : true;
 119          }
 120          catch (\RedisException $e)
 121          {
 122              $auth = false;
 123              Log::add($e->getMessage(), Log::DEBUG);
 124          }
 125  
 126          if ($auth === false)
 127          {
 128              static::$_redis = null;
 129  
 130              throw new CacheConnectingException('Redis authentication failed', 500);
 131          }
 132  
 133          $select = static::$_redis->select($server['db']);
 134  
 135          if ($select == false)
 136          {
 137              static::$_redis = null;
 138  
 139              throw new CacheConnectingException('Redis failed to select database', 500);
 140          }
 141  
 142          try
 143          {
 144              static::$_redis->ping();
 145          }
 146          catch (\RedisException $e)
 147          {
 148              static::$_redis = null;
 149  
 150              throw new CacheConnectingException('Redis ping failed', 500);
 151          }
 152  
 153          return static::$_redis;
 154      }
 155  
 156      /**
 157       * Check if the cache contains data stored by ID and group
 158       *
 159       * @param   string  $id     The cache data ID
 160       * @param   string  $group  The cache data group
 161       *
 162       * @return  boolean
 163       *
 164       * @since   3.7.0
 165       */
 166  	public function contains($id, $group)
 167      {
 168          if (static::isConnected() == false)
 169          {
 170              return false;
 171          }
 172  
 173          // Redis exists returns integer values lets convert that to boolean see: https://redis.io/commands/exists
 174          return (bool) static::$_redis->exists($this->_getCacheId($id, $group));
 175      }
 176  
 177      /**
 178       * Get cached data by ID and group
 179       *
 180       * @param   string   $id         The cache data ID
 181       * @param   string   $group      The cache data group
 182       * @param   boolean  $checkTime  True to verify cache time expiration threshold
 183       *
 184       * @return  mixed  Boolean false on failure or a cached data object
 185       *
 186       * @since   3.4
 187       */
 188  	public function get($id, $group, $checkTime = true)
 189      {
 190          if (static::isConnected() == false)
 191          {
 192              return false;
 193          }
 194  
 195          return static::$_redis->get($this->_getCacheId($id, $group));
 196      }
 197  
 198      /**
 199       * Get all cached data
 200       *
 201       * @return  mixed  Boolean false on failure or a cached data object
 202       *
 203       * @since   3.4
 204       */
 205  	public function getAll()
 206      {
 207          if (static::isConnected() == false)
 208          {
 209              return false;
 210          }
 211  
 212          $allKeys = static::$_redis->keys('*');
 213          $data    = array();
 214          $secret  = $this->_hash;
 215  
 216          if (!empty($allKeys))
 217          {
 218              foreach ($allKeys as $key)
 219              {
 220                  $namearr = explode('-', $key);
 221  
 222                  if ($namearr !== false && $namearr[0] == $secret && $namearr[1] === 'cache')
 223                  {
 224                      $group = $namearr[2];
 225  
 226                      if (!isset($data[$group]))
 227                      {
 228                          $item = new CacheStorageHelper($group);
 229                      }
 230                      else
 231                      {
 232                          $item = $data[$group];
 233                      }
 234  
 235                      $item->updateSize(\strlen($key)*8);
 236                      $data[$group] = $item;
 237                  }
 238              }
 239          }
 240  
 241          return $data;
 242      }
 243  
 244      /**
 245       * Store the data to cache by ID and group
 246       *
 247       * @param   string  $id     The cache data ID
 248       * @param   string  $group  The cache data group
 249       * @param   string  $data   The data to store in cache
 250       *
 251       * @return  boolean
 252       *
 253       * @since   3.4
 254       */
 255  	public function store($id, $group, $data)
 256      {
 257          if (static::isConnected() == false)
 258          {
 259              return false;
 260          }
 261  
 262          static::$_redis->setex($this->_getCacheId($id, $group), $this->_lifetime, $data);
 263  
 264          return true;
 265      }
 266  
 267      /**
 268       * Remove a cached data entry by ID and group
 269       *
 270       * @param   string  $id     The cache data ID
 271       * @param   string  $group  The cache data group
 272       *
 273       * @return  boolean
 274       *
 275       * @since   3.4
 276       */
 277  	public function remove($id, $group)
 278      {
 279          if (static::isConnected() == false)
 280          {
 281              return false;
 282          }
 283  
 284          return (bool) static::$_redis->del($this->_getCacheId($id, $group));
 285      }
 286  
 287      /**
 288       * Clean cache for a group given a mode.
 289       *
 290       * group mode    : cleans all cache in the group
 291       * notgroup mode : cleans all cache not in the group
 292       *
 293       * @param   string  $group  The cache data group
 294       * @param   string  $mode   The mode for cleaning cache [group|notgroup]
 295       *
 296       * @return  boolean
 297       *
 298       * @since   3.4
 299       */
 300  	public function clean($group, $mode = null)
 301      {
 302          if (static::isConnected() == false)
 303          {
 304              return false;
 305          }
 306  
 307          $allKeys = static::$_redis->keys('*');
 308  
 309          if ($allKeys === false)
 310          {
 311              $allKeys = array();
 312          }
 313  
 314          $secret = $this->_hash;
 315  
 316          foreach ($allKeys as $key)
 317          {
 318              if (strpos($key, $secret . '-cache-' . $group . '-') === 0 && $mode === 'group')
 319              {
 320                  static::$_redis->del($key);
 321              }
 322  
 323              if (strpos($key, $secret . '-cache-' . $group . '-') !== 0 && $mode !== 'group')
 324              {
 325                  static::$_redis->del($key);
 326              }
 327          }
 328  
 329          return true;
 330      }
 331  
 332      /**
 333       * Test to see if the storage handler is available.
 334       *
 335       * @return  boolean
 336       *
 337       * @since   3.4
 338       */
 339  	public static function isSupported()
 340      {
 341          return class_exists('\\Redis');
 342      }
 343  
 344      /**
 345       * Test to see if the Redis connection is available.
 346       *
 347       * @return  boolean
 348       *
 349       * @since   3.4
 350       */
 351  	public static function isConnected()
 352      {
 353          return static::$_redis instanceof \Redis;
 354      }
 355  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer