redis = new Redis(); $this->redis->connect('127.0.0.1', 6379); $this->redis->auth('CRM_Redis_Pass_2025_Secure!'); $this->enabled = true; } else { // Используем Predis require_once __DIR__ . '/../vendor/autoload.php'; $this->redis = new Predis\Client([ 'scheme' => 'tcp', 'host' => '127.0.0.1', 'port' => 6379, 'password' => 'CRM_Redis_Pass_2025_Secure!', ]); $this->enabled = true; } } catch (Exception $e) { error_log("Redis cache disabled: " . $e->getMessage()); $this->enabled = false; } } /** * Получить значение из кеша */ public function get($key) { if (!$this->enabled) { return null; } try { $value = $this->redis->get($this->prefix . $key); if ($value === false || $value === null) { return null; } return json_decode($value, true); } catch (Exception $e) { error_log("Redis get error: " . $e->getMessage()); return null; } } /** * Сохранить значение в кеш */ public function set($key, $value, $ttl = null) { if (!$this->enabled) { return false; } try { $ttl = $ttl ?? $this->defaultTTL; $this->redis->setex( $this->prefix . $key, $ttl, json_encode($value) ); return true; } catch (Exception $e) { error_log("Redis set error: " . $e->getMessage()); return false; } } /** * Удалить значение из кеша */ public function delete($key) { if (!$this->enabled) { return false; } try { $this->redis->del($this->prefix . $key); return true; } catch (Exception $e) { error_log("Redis delete error: " . $e->getMessage()); return false; } } /** * Очистить весь кеш */ public function flush() { if (!$this->enabled) { return false; } try { // Удаляем все ключи с нашим префиксом $keys = $this->redis->keys($this->prefix . '*'); if (!empty($keys)) { $this->redis->del($keys); } return true; } catch (Exception $e) { error_log("Redis flush error: " . $e->getMessage()); return false; } } /** * Получить или установить значение (если не существует) */ public function remember($key, $callback, $ttl = null) { $value = $this->get($key); if ($value !== null) { return $value; } // Вызываем callback для получения значения $value = $callback(); $this->set($key, $value, $ttl); return $value; } /** * Кешировать результат SQL запроса */ public function cacheQuery($key, $query, $params = [], $ttl = null) { return $this->remember($key, function() use ($query, $params) { global $adb; $result = $adb->pquery($query, $params); $data = []; while ($row = $adb->fetch_array($result)) { $data[] = $row; } return $data; }, $ttl); } /** * Кешировать tabid модуля */ public function getTabId($moduleName) { return $this->remember("tabid:{$moduleName}", function() use ($moduleName) { global $adb; $result = $adb->pquery("SELECT tabid FROM vtiger_tab WHERE name=?", [$moduleName]); return $adb->query_result($result, 0, 'tabid'); }, 86400); // 24 часа } /** * Кешировать поля модуля */ public function getModuleFields($moduleName) { return $this->remember("fields:{$moduleName}", function() use ($moduleName) { global $adb; $tabid = getTabid($moduleName); $query = "SELECT fieldname, fieldlabel, uitype, columnname, tablename, typeofdata FROM vtiger_field WHERE tabid=? AND presence IN (0,2) ORDER BY sequence"; $result = $adb->pquery($query, [$tabid]); $fields = []; while ($row = $adb->fetch_array($result)) { $fields[] = $row; } return $fields; }, 3600); // 1 час } /** * Кешировать picklist значения */ public function getPicklistValues($fieldName) { return $this->remember("picklist:{$fieldName}", function() use ($fieldName) { global $adb; $query = "SELECT DISTINCT vtiger_$fieldName.* FROM vtiger_$fieldName ORDER BY sortorderid"; $result = $adb->query($query); $values = []; while ($row = $adb->fetch_array($result)) { $values[] = $row; } return $values; }, 3600); // 1 час } /** * Кешировать права доступа пользователя */ public function getUserPrivileges($userId) { return $this->remember("privileges:user:{$userId}", function() use ($userId) { require_once('include/utils/UserInfoUtil.php'); $privileges = getAllUserPrivileges($userId); return $privileges; }, 1800); // 30 минут } /** * Проверить включен ли кеш */ public function isEnabled() { return $this->enabled; } /** * Получить статистику кеша */ public function getStats() { if (!$this->enabled) { return ['enabled' => false]; } try { $info = $this->redis->info(); return [ 'enabled' => true, 'keys' => $this->redis->dbsize(), 'memory' => $info['used_memory_human'] ?? 'unknown', 'hits' => $info['keyspace_hits'] ?? 0, 'misses' => $info['keyspace_misses'] ?? 0, ]; } catch (Exception $e) { return ['enabled' => false, 'error' => $e->getMessage()]; } } }