* @copyright Copyright 2020-2023 © Teamwant Mateusz Szymański All right reserved * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) * @category Teamwant * @package Teamwant */ namespace Teamwant\Prestashop17\Redis\Classes\Cache; use CacheCore; use Context; use Predis\Client; use Teamwant\Prestashop17\Redis\Classes\FileManager; use Teamwant\Prestashop17\Redis\Classes\Validator; use Throwable; use Tools; abstract class CacheRedis extends CacheCore { /** * @var bool */ protected $is_connected = false; /** * @var Client */ private $client; /** * @var Validator */ private $validator; /** * @var bool */ private $usePrefix = false; /** * @var bool */ private $useCacheAdmin = true; /** * @var null|string */ private $prefix; /** * @var string */ private $controller_type; public function __construct() { $this->validator = new Validator(); $c = Context::getContext(); if (!empty($c) && !empty($c->controller) && !empty($c->controller->controller_type)) { $this->controller_type = $c->controller->controller_type; } $this->connect(); } public function connect() { if (class_exists('\Predis\Client')) { $this->is_connected = false; try { $connectConfiguration = $this->parseConnectionConfigFile(); if (1 === count($connectConfiguration) && isset($connectConfiguration[0])) { $this->client = new Client( $connectConfiguration[0], ['cluster' => 'redis'] ); } else { $this->client = new Client( $connectConfiguration, ['cluster' => 'redis'] ); } $this->client->connect(); $this->is_connected = $this->client->isConnected(); } catch (\InvalidArgumentException $iae) { if (defined('_PS_MODE_DEV_') && _PS_MODE_DEV_) { @trigger_error("Redis InvalidArgumentException, please check your server configuration. Turn off debug to hide this!", E_USER_NOTICE); } } catch (Throwable $thr) { if (defined('_PS_MODE_DEV_') && _PS_MODE_DEV_) { @trigger_error("Redis Error, please check your server configuration. Turn off debug to hide this!", E_USER_NOTICE); if (Tools::getIsset('redis_healthcheck_key')) { echo '

' . $thr->getMessage() . '

'; } } } } else { $this->is_connected = false; } } private function parseConnectionConfigFile() { $fileManager = new FileManager(); /** @var array $content */ $config = json_decode($fileManager->parseConfigFile('_RedisConfiguration.php'), true); if (isset($config['_config']['use_cache_admin'])) { $this->useCacheAdmin = (bool)$config['_config']['use_cache_admin']; } if (isset($config['_config']['use_prefix']) && !empty($config['_config']['prefix'])) { $this->usePrefix = (bool)$config['_config']['use_prefix']; $this->prefix = (string)$config['_config']['prefix']; } if (!empty($config['_servers'])) { $redis_arr = []; foreach ($config['_servers'] as $item) { $item = $this->validator->validateRedisRow($item); if (!$item) { continue; } if ($item['scheme'] === 'unix') { $item['path'] = $item['host']; unset($item['host']); } $redis_arr[$item['alias']] = $item; } return array_values($redis_arr); } return null; } public static function flushAllDb() { $fileManager = new FileManager(); $validator = new Validator(); /** @var array $content */ $config = json_decode($fileManager->parseConfigFile('_RedisConfiguration.php'), true); if (!empty($config['_servers'])) { foreach ($config['_servers'] as $item) { $item = $validator->validateRedisRow($item); if (!$item) { continue; } if ($item['scheme'] === 'unix') { $item['path'] = $item['host']; unset($item['host']); } $client = new Client($item); $client->connect(); if ($client->isConnected()) { $client->flushdb(); } } } return true; } protected function _delete($key) { if ($this->isDisabled()) { return false; } try { return $this->client->del( $this->getKey($key) ); } catch (Throwable $thr) { if (defined('_PS_MODE_DEV_') && _PS_MODE_DEV_) { @trigger_error("Redis Error, please check your server configuration. Turn off debug to hide this!", E_USER_NOTICE); if (Tools::getIsset('redis_healthcheck_key')) { echo '

' . $thr->getMessage() . '

'; } } return false; } } private function getKey(string $key) { if ($this->usePrefix) { if (substr($key, 0, strlen($this->prefix)) === $this->prefix) { return $key; } return $this->prefix . $key; } return $key; } protected function _set($key, $value, $ttl = 0) { if ($this->isDisabled()) { return false; } try { $result = $this->client->set($this->getKey($key), serialize($value), 'ex', strtotime('now +' . $ttl . 'min')); } catch (Throwable $thr) { if (defined('_PS_MODE_DEV_') && _PS_MODE_DEV_) { @trigger_error("Redis Error, please check your server configuration. Turn off debug to hide this!", E_USER_NOTICE); if (Tools::getIsset('redis_healthcheck_key')) { echo '

' . $thr->getMessage() . '

'; } } $result = false; } if ($result === false) { $this->setAdjustTableCacheSize(true); } return $result; } protected function _get($key) { if ($this->isDisabled()) { return false; } return unserialize($this->client->get( $this->getKey($key) )); } protected function _exists($key) { if ($this->isDisabled()) { return false; } return $this->client->exists($this->getKey($key)); } protected function _writeKeys() { if (!$this->is_connected) { return false; } return true; } protected function _flush() { if ($this->isDisabled()) { return false; } return $this->client->flushall(); } /** * Metoda sprawdza czy redis faktycznie ma zostac uruchomiony po warunkach, np. w adminie * * @return bool */ private function isDisabled() { if (false === $this->useCacheAdmin) { if ( $this->controller_type && 'admin' === $this->controller_type || defined('_PS_ADMIN_DIR_') ) { return true; } } return false; } }