Files
b2b.redline.com.pl/modules/teamwant_redis/classes/TeamwantRedis.php
2025-06-24 14:14:35 +02:00

684 lines
25 KiB
PHP

<?php
/**
* Redis Cache
* Version: 2.1.1
* Copyright (c) 2020-2022. Mateusz Szymański Teamwant
* https://teamwant.pl
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @author Teamwant <kontakt@teamwant.pl>
* @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;
use Db;
use DbQuery;
use Exception;
use Language;
use Media;
use Tab;
use Teamwant\Prestashop17\Redis\Classes\Cache\Redis;
use Teamwant_redis\OverrideSrc\OverrideHookFile;
use Teamwant_redis\OverrideSrc\OverrideSrcCachingType;
use Teamwant_redis\OverrideSrc\OverrideSrcParametersFile;
use Tools;
use Translate;
trait TeamwantRedis
{
public $prestashopVersion = 1760;
protected $config_form = false;
public function initRawTranslations()
{
$this->l("Can't write file %s, please check \"rw\" permissions on this file");
$this->l('Actions');
$this->l('Add server');
$this->l('Alias');
$this->l('Any record is not valid');
$this->l('Connection failed');
$this->l('Error!');
$this->l('Host');
$this->l('Password');
$this->l('Please enter required fields, Host and port');
$this->l('Please input any record');
$this->l('Port');
$this->l('Remove row');
$this->l('Save success.');
$this->l('Save');
$this->l('Scheme');
$this->l('Test connection');
$this->l('Url to healthcheck:');
$this->l('Username');
$this->l('Wrong method, allowed: %s');
$this->l('You need administrator rights to make changes on this page.');
$this->l('Are you sure to save the changes? The redis configuration has not been saved.');
$this->l('Server %d is duplicated');
$this->l('File %s must be writable.');
$this->l('File %s must be readable.');
$this->l('Can\'t create file %s.');
$this->l('File %s must be writable. Please change permissions on this file and reinstal Redis cache module.');
$this->l('File %s must be readable. Please change permissions on this file and reinstal Redis cache module.');
$this->l('Show More');
$this->l('Show Less');
$this->l('Index');
//1.3.0
$this->l('Payload is invalid.');
$this->l('Configuration is not valid');
$this->l('Field %s is required');
$this->l('Field %s must be true or false');
$this->l('Additional configuration');
$this->l('Use cache in admin panel?');
$this->l('Use prefix for keys?');
$this->l('Key prefix');
$this->l('Leave blank to generate automatically');
}
public function validateFilePrivilagesForTeamwantRedisModule()
{
load_Teamwant_redis_OverrideSrc();
if (!is_writable(OverrideSrcCachingType::FILE)) {
$this->adminDisplayWarning(self::staticModuleTranslate('File %s must be writable. Please change permissions on this file and reinstal Redis cache module.', [
OverrideSrcCachingType::FILE
]));
}
if (!is_readable(OverrideSrcCachingType::FILE)) {
$this->adminDisplayWarning(self::staticModuleTranslate('File %s must be readable. Please change permissions on this file and reinstal Redis cache module.', [
OverrideSrcCachingType::FILE
]));
}
if (!is_writable(OverrideSrcParametersFile::FILE)) {
$this->adminDisplayWarning(self::staticModuleTranslate('File %s must be writable. Please change permissions on this file and reinstal Redis cache module.', [
OverrideSrcParametersFile::FILE
]));
}
if (!is_readable(OverrideSrcParametersFile::FILE)) {
$this->adminDisplayWarning(self::staticModuleTranslate('File %s must be readable. Please change permissions on this file and reinstal Redis cache module.', [
OverrideSrcParametersFile::FILE
]));
}
if (!is_writable(OverrideHookFile::FILE)) {
$this->adminDisplayWarning(self::staticModuleTranslate('File %s must be writable. Please change permissions on this file and reinstal Redis cache module.', [
OverrideHookFile::FILE
]));
}
if (!is_readable(OverrideHookFile::FILE)) {
$this->adminDisplayWarning(self::staticModuleTranslate('File %s must be readable. Please change permissions on this file and reinstal Redis cache module.', [
OverrideHookFile::FILE
]));
}
if (!file_exists(TEAMWANT_REDIS_ROOT_DIR . '/config/_RedisConfiguration.php')) {
@file_put_contents(TEAMWANT_REDIS_ROOT_DIR . '/config/_RedisConfiguration.php', '');
}
if (file_exists(TEAMWANT_REDIS_ROOT_DIR . '/config/_RedisConfiguration.php')) {
if (!is_writable(TEAMWANT_REDIS_ROOT_DIR . '/config/_RedisConfiguration.php')) {
$this->adminDisplayWarning(self::staticModuleTranslate('File %s must be writable.', [
TEAMWANT_REDIS_ROOT_DIR . '/config/_RedisConfiguration.php'
]));
}
if (!is_readable(TEAMWANT_REDIS_ROOT_DIR . '/config/_RedisConfiguration.php')) {
$this->adminDisplayWarning(self::staticModuleTranslate('File %s must be readable.', [
TEAMWANT_REDIS_ROOT_DIR . '/config/_RedisConfiguration.php'
]));
}
} else {
$this->adminDisplayWarning(self::staticModuleTranslate('Can\'t create file %s.', [
TEAMWANT_REDIS_ROOT_DIR . '/config/_RedisConfiguration.php'
]));
}
}
public static function staticModuleTranslate($string, $sprintf = null)
{
$r = Translate::getModuleTranslation(
'teamwant_redis',
$string,
'teamwant_redis'
);
if (!$sprintf) {
return $r;
}
if (is_array($sprintf)) {
return vsprintf($r, $sprintf);
}
return sprintf($r, $sprintf);
}
public function install()
{
$this->createCustomOverride($this->prestashopVersion);
//custom override presta files
load_Teamwant_redis_OverrideSrc();
$out = parent::install()
&& $this->registerHook('backOfficeHeader')
&& $this->registerHook('actionClearCompileCache');
//custom override presta files
OverrideSrcCachingType::install();
$this->registerAdminControllers();
//tworzenie startowego pliku
$this->createDefaultConfigFile();
//from 1.6.2
OverrideHookFile::install();
return $out;
}
public function createCustomOverride($version)
{
if (!file_exists(TEAMWANT_REDIS_ROOT_DIR . '/override')) {
mkdir(TEAMWANT_REDIS_ROOT_DIR . '/override');
$this->dirCopy(
TEAMWANT_REDIS_ROOT_DIR . '/overrideVersions/' . $version . '/',
TEAMWANT_REDIS_ROOT_DIR . '/override/'
);
}
}
public function dirCopy(string $src, string $dest)
{
foreach (scandir($src) as $file) {
if ($file === '.' || $file === '..') {
continue;
}
$newFile = $src . '/' . $file;
if (!is_readable($newFile)) {
continue;
}
if (is_dir($newFile)) {
if (!file_exists($dest . '/' . $file)) {
mkdir($dest . '/' . $file);
}
$this->dirCopy($newFile . '/', $dest . '/' . $file . '/');
} else {
copy($newFile, $dest . '/' . $file);
}
}
}
public function registerAdminControllers()
{
$sql = new DbQuery();
$sql->select('*');
$sql->from('tab', 't');
$sql->where('t.class_name = "AdminRedisConfiguration"');
$sql->orderBy('position');
if (!Db::getInstance()->executeS($sql)) {
$tab = new Tab();
$tab->active = true;
$tab->class_name = 'AdminRedisConfiguration';
$tab->id_parent = -1;
$tab->module = $this->name;
$tab->name = [];
foreach (Language::getLanguages(true) as $lang) {
$tab->name[$lang['id_lang']] = 'AdminRedisConfiguration';
}
$tab->add();
}
}
private function createDefaultConfigFile()
{
$template_file = TEAMWANT_REDIS_ROOT_DIR . 'config/_RedisConfiguration.php';
if (
!file_exists($template_file)
|| (file_exists($template_file) && Tools::file_get_contents($template_file) === '')
) {
$fileManager = new FileManager();
$validator = new Validator();
$payload = [
'teamwant_redis_row' => [
[
'host' => '127.0.0.1',
'port' => '6379',
'scheme' => 'tcp',
],
],
'twredis' => [
'use_cache_admin' => false,
'prefix' => 'default',
'use_prefix' => false,
'use_multistore' => false,
],
];
$items = $validator->validateAjaxProcessSaveConfigurationTable($payload);
if ($items['result']) {
$newConfig = json_encode(
$items['items'],
JSON_UNESCAPED_UNICODE
);
$fileManager->saveConfigFile('_RedisConfiguration.php', $newConfig);
}
}
return true;
}
public function uninstall()
{
//custom override presta files
load_Teamwant_redis_OverrideSrc();
OverrideSrcCachingType::uninstall();
OverrideSrcParametersFile::uninstall();
//from 1.6.2
OverrideHookFile::uninstall();
$this->uninstallAdminControllers();
$this->removeCustomOverride();
return parent::uninstall();
}
public function uninstallAdminControllers()
{
return Db::getInstance()->query("
DELETE FROM `" . _DB_PREFIX_ . "tab` WHERE `module` = 'teamwant_redis'
");
}
public function removeCustomOverride()
{
if (file_exists(TEAMWANT_REDIS_ROOT_DIR . '/override')) {
$this->deleteDirectory(TEAMWANT_REDIS_ROOT_DIR . '/override');
}
}
private function deleteDirectory($dir)
{
if (file_exists($dir)) {
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file) {
if ($file === '.' || $file === '..') {
continue;
}
$this->deleteDirectory($dir . '/' . $file);
}
rmdir($dir);
} elseif (is_file($dir)) {
unlink($dir);
}
}
}
public function enable($force_all = false)
{
$this->createCustomOverride($this->prestashopVersion);
//custom override presta files
load_Teamwant_redis_OverrideSrc();
OverrideSrcCachingType::install();
$this->registerHook('backOfficeHeader');
$this->registerHook('actionClearCompileCache');
$this->registerAdminControllers();
//from 1.6.2
OverrideHookFile::install();
return parent::enable($force_all);
}
public function disable($force_all = false)
{
//custom override presta files
load_Teamwant_redis_OverrideSrc();
OverrideSrcCachingType::uninstall();
OverrideSrcParametersFile::uninstall();
$this->uninstallAdminControllers();
$this->removeCustomOverride();
//from 1.6.2
OverrideHookFile::uninstall();
return parent::disable($force_all);
}
public function hookBackOfficeHeader()
{
//custom js variables
Media::addJsDef([
'token_AdminRedisConfiguration' => Tools::getAdminTokenLite('AdminRedisConfiguration'),
]);
$controller = Tools::getValue('controller', '');
if ($controller === 'AdminPerformance') {
//custom js variables
Media::addJsDef([
'tw_redis_lang_save_change_on_performance' => $this->l('Are you sure to save the changes? The redis configuration has not been saved.')
]);
}
$this->context->controller->addJquery();
//custom js
$this->context->controller->addJs($this->_path . 'views/js/redis-admin.js');
//custom css
$this->context->controller->addCSS($this->_path . 'views/css/redis-admin.css');
}
public function hookActionClearCompileCache()
{
if (
defined('_PS_CACHE_ENABLED_') && _PS_CACHE_ENABLED_
&& defined('_PS_CACHING_SYSTEM_') && _PS_CACHING_SYSTEM_ === 'Redis'
) {
if (!class_exists(Redis::class)) {
require_once _PS_MODULE_DIR_ . 'teamwant_redis/vendor/autoload.php';
}
try {
Redis::flushAllDb();
} catch (Exception $e) {
if (_PS_MODE_DEV_) {
die('Warning: Failed to clear the Redis Cache. The error was: ' . $e->getMessage());
}
}
}
}
public function getBackofficeConfigurationContentData() {
$redis_healthcheck_key = \Configuration::get(Redis::REDIS_HEALTHCHECK_KEY);
if (!$redis_healthcheck_key) {
$length = 32;
if (function_exists('random_bytes')) {
try {
$redis_healthcheck_key = bin2hex(random_bytes($length));
} catch (Exception $e) {
if (defined('_PS_MODE_DEV_') && _PS_MODE_DEV_) {
@trigger_error($e, E_USER_NOTICE);
}
}
}
if (function_exists('openssl_random_pseudo_bytes')) {
$redis_healthcheck_key = bin2hex(openssl_random_pseudo_bytes($length));
}
if (version_compare(PHP_VERSION, '7.2.0') >= 0) {
$redis_healthcheck_key = bin2hex(Tools::getBytes($length));
} else {
if (function_exists('mcrypt_create_iv')) {
$redis_healthcheck_key = bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));
}
}
\Configuration::updateValue(Redis::REDIS_HEALTHCHECK_KEY, $redis_healthcheck_key);
}
return [
// Use cache for stock manager
'twredis_use_cache_for_stock_manager' => Tools::getValue(
'twredis_use_cache_for_stock_manager',
\Configuration::get('twredis_use_cache_for_stock_manager', null, null, null, 1)
),
// Use cache for hook list
'twredis_use_cache_for_hook_list' => Tools::getValue(
'twredis_use_cache_for_hook_list',
\Configuration::get('twredis_use_cache_for_hook_list', null, null, null, 1)
),
// twredis_disable_product_price_cache
'twredis_disable_product_price_cache' => Tools::getValue(
'twredis_disable_product_price_cache',
\Configuration::get('twredis_disable_product_price_cache', null, null, null, 0)
),
// twredis_disable_cache_for_order_page
'twredis_disable_cache_for_order_page' => Tools::getValue(
'twredis_disable_cache_for_order_page',
\Configuration::get('twredis_disable_cache_for_order_page', null, null, null, 0)
),
// twredis_disable_cache_for_address_payment_and_carrier
'twredis_disable_cache_for_address_payment_and_carrier' => Tools::getValue(
'twredis_disable_cache_for_address_payment_and_carrier',
\Configuration::get('twredis_disable_cache_for_address_payment_and_carrier', null, null, null, 0)
),
'cron-for-categories' => '/usr/bin/curl -k -L --max-redirs 10000 "' . $this->context->link->getModuleLink(
'teamwant_redis',
'cron',
[
'redis_healthcheck_key' => $redis_healthcheck_key,
'redis_cron_type' => 'categories',
],
\Configuration::get('PS_SSL_ENABLED')
) . '" ',
'cron-for-products' => '/usr/bin/curl -k -L --max-redirs 10000 "' . $this->context->link->getModuleLink(
'teamwant_redis',
'cron',
[
'redis_healthcheck_key' => $redis_healthcheck_key,
'redis_cron_type' => 'products',
],
\Configuration::get('PS_SSL_ENABLED')
) . '" ',
];
}
/**
* @return string
*
* @throws PrestaShopException
*/
public function getBackofficeConfigurationContent()
{
$this->bootstrap = true;
$fieldsValue = $this->getBackofficeConfigurationContentData();
$form = [
'form' => [
'legend' => [
'title' => $this->l('Cache configuration'),
'icon' => 'icon-cogs'
],
'input' => [
[
'type' => 'switch',
'label' => $this->l('Use cache for stock manager'),
'name' => 'twredis_use_cache_for_stock_manager',
'is_bool' => true,
'required' => true,
'values' => [
[
'id' => 'use_cache_for_stock_manager_on',
'value' => 1,
'label' => $this->trans('Enabled', [], 'Admin.Global')
],
[
'id' => 'use_cache_for_stock_manager_off',
'value' => 0,
'label' => $this->trans('Disabled', [], 'Admin.Global')
]
]
],
[
'type' => 'switch',
'label' => $this->l('Use cache for hook list'),
'name' => 'twredis_use_cache_for_hook_list',
'is_bool' => true,
'required' => true,
'values' => [
[
'id' => 'use_cache_for_hook_list_on',
'value' => 1,
'label' => $this->trans('Enabled', [], 'Admin.Global')
],
[
'id' => 'use_cache_for_hook_list_off',
'value' => 0,
'label' => $this->trans('Disabled', [], 'Admin.Global')
]
]
],
[
'type' => 'switch',
'label' => $this->l('Disable product price cache'),
'name' => 'twredis_disable_product_price_cache',
'is_bool' => true,
'required' => true,
'values' => [
[
'id' => 'twredis_disable_product_price_cache_on',
'value' => 1,
'label' => $this->trans('Enabled', [], 'Admin.Global')
],
[
'id' => 'twredis_disable_product_price_cache_off',
'value' => 0,
'label' => $this->trans('Disabled', [], 'Admin.Global')
]
]
],
[
'type' => 'switch',
'label' => $this->l('Disable cache for order page'),
'name' => 'twredis_disable_cache_for_order_page',
'is_bool' => true,
'required' => true,
'values' => [
[
'id' => 'twredis_disable_cache_for_order_page_on',
'value' => 1,
'label' => $this->trans('Enabled', [], 'Admin.Global')
],
[
'id' => 'twredis_disable_cache_for_order_page_off',
'value' => 0,
'label' => $this->trans('Disabled', [], 'Admin.Global')
]
]
],
[
'type' => 'switch',
'label' => $this->l('Disable cache for address, payment methods and carriers'),
'name' => 'twredis_disable_cache_for_address_payment_and_carrier',
'is_bool' => true,
'required' => true,
'values' => [
[
'id' => 'twredis_disable_cache_for_address_payment_and_carrier_on',
'value' => 1,
'label' => $this->trans('Enabled', [], 'Admin.Global')
],
[
'id' => 'twredis_disable_cache_for_address_payment_and_carrier_off',
'value' => 0,
'label' => $this->trans('Disabled', [], 'Admin.Global')
]
]
],
[
'type' => 'text',
'label' => $this->l('CRON for categories'),
'name' => 'cron-for-categories',
'required' => false,
'disabled' => true,
'value' => 'asd'
],
[
'type' => 'text',
'label' => $this->l('CRON for products'),
'name' => 'cron-for-products',
'required' => false,
'disabled' => true,
],
],
'submit' => [
'name' => 'twredis_cache_config',
'title' => $this->trans('Save', [], 'Admin.Actions'),
],
'buttons' => []
],
];
$helper = new \HelperForm();
$helper->show_toolbar = false;
$helper->table = $this->table;
$helper->module = $this;
$helper->default_form_language = $this->context->language->id;
$helper->identifier = $this->identifier;
$helper->submit_action = 'submit_twredis_cache_config';
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false)
.'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->tpl_vars = [
'fields_value' => $fieldsValue,
];
$sfContainer = \PrestaShop\PrestaShop\Adapter\SymfonyContainer::getInstance();
if (null !== $sfContainer) {
/** @var UrlGeneratorInterface $sfRouter */
$sfRouter = $sfContainer->get('router');
//$this->context->smarty->assign([
// 'performance_url' => $sfRouter->generate('admin_performance', []),
//]);
$form['form']['buttons'][] = [
'href' => $sfRouter->generate('admin_performance', []),
'title' => $this->l('Edit redis configuration'),
];
}
$this->context->smarty->assign([
'cache_config' => $helper->generateForm([$form]),
]);
return $this->context->smarty->fetch(TEAMWANT_REDIS_ROOT_DIR . 'views/templates/admin/configuration1760.tpl');
}
/**
* @return false|array
*/
public static function getCacheConfiguration() {
if (method_exists(self::class, 'getCacheConfigurationData')) {
return self::getCacheConfigurationData();
}
return false;
}
}