* @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; } }