fix в поле "Название cайта:" в системных настройках - теперь можно использовать кавычки в названии

This commit is contained in:
2026-02-05 12:40:34 +05:00
parent d8ac60a675
commit aa7431ac62
3 changed files with 12 additions and 78 deletions

View File

@@ -57,7 +57,7 @@
<tbody>
<tr>
<td>{#SETTINGS_SITE_NAME#}</td>
<td><div class="pr12"><input type="text" name="site_name" id="site_name" value="{$row.site_name}" maxlength="200" class="mousetrap"></div></td>
<td><div class="pr12"><input type="text" name="site_name" id="site_name" value="{$row.site_name|escape}" maxlength="200" class="mousetrap"></div></td>
</tr>
<tr>

View File

@@ -52,52 +52,39 @@ function settingsShow()
'%A, %d %B %Y (%H:%M)'
);
// 1. Получаем настройки (ПАРОЛЬ УЖЕ ДЕШИФРОВАН в кэше get_settings())
$settings_data_array = get_settings();
// 2. Извлекаем строку настроек (обычно это $settings[0])
$row = (isset($settings_data_array[0]) && is_array($settings_data_array[0]))
? $settings_data_array[0]
: (is_array($settings_data_array) ? $settings_data_array : array());
// 3. КРИТИЧЕСКАЯ ЛОГИКА МАСКИРОВКИ: Заменяем дешифрованный пароль на '****' для отображения
if (isset($row['mail_type']) && $row['mail_type'] === 'smtp' && !empty($row['mail_smtp_pass'])) {
// Дешифрованный пароль заменяется на '****' для поля формы
$row['mail_smtp_pass'] = '****';
}
// ОПРЕДЕЛЯЕМ, КАКИЕ ИМЕННО ФУНКЦИИ ЗАБЛОКИРОВАНЫ
$blocked_functions = [];
// Проверяем popen
if (!function_exists('popen')) {
$blocked_functions[] = 'popen()';
}
// Проверяем proc_open
if (!function_exists('proc_open')) {
$blocked_functions[] = 'proc_open()';
}
// Создаем строку для вывода (например: "popen() и proc_open()")
if (count($blocked_functions) > 1) {
// Если заблокированы обе, объединяем их через " и "
$blocked_string = implode(' и ', $blocked_functions);
} elseif (count($blocked_functions) === 1) {
// Если заблокирована одна
$blocked_string = $blocked_functions[0];
} else {
// Ничего не заблокировано
$blocked_string = '';
}
// Передаем строку заблокированных функций в Smarty
$AVE_Template->assign('blocked_sendmail_funcs', $blocked_string);
$AVE_Template->assign('date_formats', $date_formats);
$AVE_Template->assign('time_formats', $time_formats);
// 4. Передаем модифицированный массив с '****' в шаблон
$AVE_Template->assign('row', $row);
$AVE_Template->assign('available_countries', get_country_list(1));
@@ -112,22 +99,18 @@ function settingsShow()
*/
private function _logSwitchEvent($message, $level = 'INFO')
{
// Абсолютный путь к папке логов. BASE_DIR должен быть определен.
// Абсолютный путь к папке логов.
$log_dir = BASE_DIR . '/tmp/logs';
$log_file = $log_dir . '/query_switch.log';
// Форматируем сообщение
$timestamp = date('Y-m-d H:i:s');
$log_entry = "[" . $timestamp . "] [" . $level . "] " . $message . "\n";
// Проверяем существование директории (и права, если есть возможность)
if (!is_dir($log_dir) || !is_writable($log_dir)) {
// Если лог-директория недоступна, пытаемся записать в системный лог CMS, если это возможно.
@reportLog("ОШИБКА ЛОГА: Не удалось записать событие. Директория '{$log_dir}' недоступна.");
return;
}
// Безопасная запись в файл
@file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
}
@@ -157,7 +140,6 @@ private function _switchQueryFiles($use_safe_version, $clear_db_flag)
$source_base = BASE_DIR . '/inc/query_variants/' . $source_dir_name;
$error_count = 0;
// ИТЕРАЦИЯ И КОПИРОВАНИЕ
foreach ($manifest as $relative_path) {
$source_file = $source_base . '/' . $relative_path;
$target_file = BASE_DIR . '/' . $relative_path;
@@ -190,7 +172,6 @@ private function _switchQueryFiles($use_safe_version, $clear_db_flag)
}
}
// ЛОГИКА ОЧИСТКИ БАЗЫ ДАННЫХ
if ($error_count > 0) {
$this->_logSwitchEvent("ПРЕДУПРЕЖДЕНИЕ: Обнаружены ошибки копирования файлов ({$error_count} шт.). Очистка БД не будет выполнена.", 'WARNING');
}
@@ -199,7 +180,6 @@ private function _switchQueryFiles($use_safe_version, $clear_db_flag)
{
$this->_logSwitchEvent("Очистка БД: Обнаружено фактическое переключение версии. Запуск DELETE FROM и ALTER TABLE.", 'INFO');
// 1. Очистка ДОЧЕРНЕЙ таблицы
if (@$AVE_DB->query("DELETE FROM `" . PREFIX . "_request_conditions`")) {
$this->_logSwitchEvent('Очистка `_request_conditions`: Успех.', 'INFO');
} else {
@@ -207,7 +187,6 @@ private function _switchQueryFiles($use_safe_version, $clear_db_flag)
$error_count++;
}
// 2. Очистка РОДИТЕЛЬСКОЙ таблицы
if (@$AVE_DB->query("DELETE FROM `" . PREFIX . "_request`")) {
$this->_logSwitchEvent('Очистка `_request`: Успех.', 'INFO');
} else {
@@ -215,7 +194,6 @@ private function _switchQueryFiles($use_safe_version, $clear_db_flag)
$error_count++;
}
// 3. Сброс СЧЕТЧИКА
if (@$AVE_DB->query("ALTER TABLE `" . PREFIX . "_request` AUTO_INCREMENT = 1")) {
$this->_logSwitchEvent('Сброс AUTO_INCREMENT: Успех.', 'INFO');
} else {
@@ -241,14 +219,10 @@ function settingsCase()
{
global $AVE_Template;
// 1. Читаем ТЕКУЩЕЕ (старое) значение прямо из файла config.inc.php.
// Если файл пуст, мы предполагаем, что используется версия по умолчанию "из коробки" (Safe/TRUE),
// так как файлы Safe-версии уже должны быть на месте после установки.
$old_query_setting = true;
$old_config_content = @file_get_contents(BASE_DIR . '/config/config.inc.php');
if ($old_config_content) {
// НАДЕЖНОЕ РЕГУЛЯРНОЕ ВЫРАЖЕНИЕ: Ищет true, false, '1', '0' (в кавычках или без)
if (preg_match("/define\('REQUEST_USE_VERSION',\s*(true|false|[']?\d+[']?)\s*\);/i", $old_config_content, $matches)) {
$val = strtolower(trim($matches[1], "'"));
@@ -261,21 +235,14 @@ function settingsCase()
}
}
// Сохраняем настройки
if (isset($_REQUEST['more']))
{
// >>> ЗАПУСКАЕМ БУФЕРИЗАЦИЮ ВЫВОДА для чистого JSON-ответа (AJAX)
if (isAjax()) {
ob_start();
}
// --- ИНИЦИАЛИЗАЦИЯ ДЛЯ ОБРАБОТКИ НЕ-AJAX ЗАПРОСОВ ---
// Получаем текущее значение константы из глобального пространства.
// Это необходимо для того, чтобы при клике "Сохранить" (не-AJAX) без изменения чекбокса
// значение REQUEST_USE_VERSION не сбрасывалось и не циклилось.
$current_constant_value = defined('REQUEST_USE_VERSION') ? (REQUEST_USE_VERSION ? '1' : '0') : '0';
$request_use_version_value = $current_constant_value;
// ----------------------------------------------------
$set = '<?php' . "\r\n\r\n";
@@ -283,9 +250,7 @@ function settingsCase()
{
foreach($type as $k => $v)
{
// ИЗВЛЕКАЕМ НОВОЕ ЗНАЧЕНИЕ ДЛЯ ПЕРЕКЛЮЧЕНИЯ ФАЙЛОВ ИЗ ФОРМЫ
if ($k == 'REQUEST_USE_VERSION') {
// Значение из формы всегда приоритетнее, даже если оно '0' (отмечено 'Нет')
$request_use_version_value = $v;
}
@@ -319,10 +284,8 @@ function settingsCase()
{
$new_query_setting = (bool)$request_use_version_value;
// 2. Определяем, произошло ли фактическое переключение версий
$is_a_version_switch = ($new_query_setting !== $old_query_setting);
// 3. Вызываем функцию, передавая НОВОЕ значение и ФЛАГ очистки
$switch_success = $this->_switchQueryFiles($new_query_setting, $is_a_version_switch);
if (!$switch_success) {
@@ -343,7 +306,6 @@ function settingsCase()
if (isAjax())
{
// ОЧИЩАЕМ ВЕСЬ ВЫВОД ПЕРЕД JSON
ob_end_clean();
echo json_encode(array(
@@ -354,17 +316,13 @@ function settingsCase()
}
else
{
// 1. Принудительно очищаем кэш PHP-файлов для главного конфига (если доступно)
// Это обходной путь, который может понадобиться, если сервер использует Opcache
if (function_exists('opcache_invalidate')) {
@opcache_invalidate(BASE_DIR . '/config/config.inc.php', true);
}
// 2. Добавляем "соль" (cache buster) и принудительно сбрасываем состояние
$cache_bust = microtime(true);
$redirect_url = 'Location:index.php?do=settings&sub=case&cp=' . SESSION . '&t=' . $cache_bust . '#settings';
// 3. Добавляем заголовки, запрещающие кэширование прокси/сервером
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
@@ -391,12 +349,8 @@ function settingsSave()
{
global $AVE_DB, $AVE_Template;
// ДОБАВЛЕНО: Принудительно загружаем ключ шифрования.
get_smtp_encryption_key();
// ----------------------------------------------------
// 1. ЛОГИКА ГЕНЕРАЦИИ УНИКАЛЬНОГО КЛЮЧА
// ----------------------------------------------------
if (isset($_REQUEST['mail_type']) && $_REQUEST['mail_type'] === 'smtp' && !file_exists(BASE_DIR . '/inc/smtp_key.php')) {
$new_key = create_smtp_key_file();
@@ -416,33 +370,22 @@ function settingsSave()
}
}
// ----------------------------------------------------
// 2. ОБРАБОТКА И ШИФРОВАНИЕ SMTP ПАРОЛЯ (С ИГНОРОМ ****)
// ----------------------------------------------------
$smtp_pass_encrypted = null; // Используем null, чтобы пропустить поле в SQL, если оно пустое или ****
if (isset($_REQUEST['mail_smtp_pass'])) {
$new_smtp_pass_raw = trim($_REQUEST['mail_smtp_pass']);
// ИСПРАВЛЕНО: Если пароль не пуст И не равен маске
if (!empty($new_smtp_pass_raw) && $new_smtp_pass_raw !== '****') {
// ПАРОЛЬ БЫЛ ВВЕДЕН ИЛИ ИЗМЕНЕН: Шифруем новый пароль
if (isset($_REQUEST['mail_type']) && $_REQUEST['mail_type'] === 'smtp') {
$smtp_pass_encrypted = encrypt_smtp_pass($new_smtp_pass_raw);
} else {
$smtp_pass_encrypted = $new_smtp_pass_raw;
}
}
// Если $new_smtp_pass_raw === '****' ИЛИ ПУСТОЙ, поле mail_smtp_pass не будет добавлено в SQL.
}
// ----------------------------------------------------
// 3. ФОРМИРОВАНИЕ УСЛОВНЫХ И ОБЯЗАТЕЛЬНЫХ ПОЛЕЙ
// ----------------------------------------------------
$mandatory_fields = array(
"mail_smtp_login" => $_REQUEST['mail_smtp_login'],
"mail_smtp_encrypt" => $_REQUEST['mail_smtp_encrypt'],
@@ -465,7 +408,6 @@ $mandatory_fields = array(
"use_doctime" => intval($_REQUEST['use_doctime'])
);
// ДОБАВЛЯЕМ ПАРОЛЬ ТОЛЬКО ЕСЛИ ОН БЫЛ ВВЕДЕН ИЛИ ИЗМЕНЕН
if ($smtp_pass_encrypted !== null) {
$mandatory_fields["mail_smtp_pass"] = addslashes($smtp_pass_encrypted);
}
@@ -482,12 +424,12 @@ $mandatory_fields = array(
$set_clauses = array();
// 1. Формируем обязательные поля
// Формируем обязательные поля
foreach ($mandatory_fields as $key => $value) {
$set_clauses[] = "{$key} = '{$value}'";
}
// 2. Формируем условные поля
// Формируем условные поля
foreach ($conditional_keys as $key) {
if (isset($_REQUEST[$key])) {
$value = $_REQUEST[$key];
@@ -505,7 +447,7 @@ foreach ($conditional_keys as $key) {
$set_string = implode(",\r\n", $set_clauses);
// ----------------------------------------------------
// 4. ВЫПОЛНЕНИЕ SQL-ЗАПРОСА
// ВЫПОЛНЕНИЕ SQL-ЗАПРОСА
// ----------------------------------------------------
$sql = $AVE_DB->Query("
UPDATE
@@ -640,7 +582,7 @@ foreach ($conditional_keys as $key) {
// Инициализируем $items как null, чтобы шаблон работал при добавлении
$items = null;
// Безопасно получаем ID (используем 'id' или 'Id', если что-то передано)
// получаем ID (используем 'id' или 'Id', если что-то передано)
$lang_id = (int)($_REQUEST['id'] ?? $_REQUEST['Id'] ?? 0);
if ($lang_id > 0)
@@ -654,7 +596,7 @@ foreach ($conditional_keys as $key) {
Id = '" . $lang_id . "'
");
// Безопасное получение данных
// получение данных
if (is_object($result)) {
$items = $result->FetchRow();
}
@@ -670,7 +612,7 @@ function settingsLanguageEditSave()
{
global $AVE_DB, $AVE_Template;
// 1. Сохранение/Обновление данных языка в БД (Ваш оригинальный код)
// 1. Сохранение/Обновление данных языка в БД
if (! empty($_REQUEST["Id"]))
{
@@ -700,7 +642,7 @@ function settingsLanguageEditSave()
}
// 2. Логика сохранения загруженного флага (ДОБАВЛЕНО)
// сохранение загруженного флага
$lang_key = $_REQUEST['lang_key'] ?? '';

View File

@@ -289,7 +289,7 @@ function generate_encryption_key() {
}
/**
* Создает файл ключа inc/smtp_key.php с уникальным ключом.
* Создает файл ключа
* @return string Сгенерированный ключ, или пустая строка в случае ошибки.
*/
function create_smtp_key_file() {
@@ -307,7 +307,6 @@ function create_smtp_key_file() {
return '';
}
// @chmod($key_path, 0400); // Была причиной ошибок, оставляем закомментированной
// Определяем константу, чтобы не читать файл снова
if (!defined('SMTP_ENCRYPTION_KEY')) {
@@ -318,7 +317,7 @@ function create_smtp_key_file() {
}
/**
* Получает ключ шифрования SMTP, читая файл inc/smtp_key.php.
* Получает ключ шифрования SMTP
* @return string Ключ шифрования (64 символа), или пустая строка, если ключ отсутствует.
*/
function get_smtp_encryption_key() {
@@ -418,22 +417,16 @@ function get_settings($field = '')
{
get_smtp_encryption_key();
// Включаем параметры кэша (-1, 'settings', true, '.settings').
$result = $AVE_DB->Query("
SELECT * FROM " . PREFIX . "_settings
", -1, 'settings', true, '.settings')->FetchAssocArray();
// 2. НОРМАЛИЗАЦИЯ: Преобразуем результат в одномерный массив $settings.
// Если кэш вернул двумерный массив (Array([0] => Array(...))), берем индекс [0].
if (isset($result[0]) && is_array($result[0])) {
$settings = $result[0];
} else {
// Если вернулся одномерный массив (например, при первом чтении из БД без кэша), используем его напрямую.
$settings = $result;
}
// --- ЛОГИКА ДЕШИФРОВАНИЯ ---
// Теперь $settings гарантированно одномерный массив.
$row = $settings;
if (isset($row['mail_type']) && $row['mail_type'] === 'smtp' && !empty($row['mail_smtp_pass'])) {
@@ -442,9 +435,8 @@ function get_settings($field = '')
$decrypted_pass = decrypt_smtp_pass($pass);
// Если дешифровка сработала, обновляем значение
if ($decrypted_pass !== $pass) {
$settings['mail_smtp_pass'] = $decrypted_pass; // Обновляем в статическом кэше $settings
$settings['mail_smtp_pass'] = $decrypted_pass;
}
}
}