коррекция модуля - уьираем таймер админу фиксим работу таймера для групп и анонимов
This commit is contained in:
@@ -100,12 +100,23 @@ class Comment
|
||||
public $_postinfo_tpl = 'comment_info.tpl';
|
||||
|
||||
/**
|
||||
* Настройки времени (в секундах)
|
||||
* Настройки времени (подгружаются из БД)
|
||||
*/
|
||||
public $conf_edit_time = 600; // 10 минут на редактирование/удаление
|
||||
public $conf_cookie_life = 30; // 30 дней жизни куки для анонима
|
||||
public $conf_edit_time;
|
||||
public $conf_cookie_life;
|
||||
private $_anon_cookie_name = 'ave_anon_comment_key';
|
||||
|
||||
|
||||
/**
|
||||
* Конструктор класса
|
||||
* Срабатывает автоматически при создании объекта Comment
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
// Как только класс создан, мы ПЕРВЫМ ДЕЛОМ лезем в базу за настройками
|
||||
$this->_commentSettingsGet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Внутренние методы класса
|
||||
*/
|
||||
@@ -213,14 +224,13 @@ function commentListShow($tpl_dir)
|
||||
$document_id = (int)($_REQUEST['id'] ?? 0);
|
||||
$artpage = $_REQUEST['artpage'] ?? null;
|
||||
$apage = $_REQUEST['apage'] ?? null;
|
||||
$user_group = UGROUP ?? 0;
|
||||
$user_group = (int)(UGROUP ?? 0);
|
||||
|
||||
// --- НОВАЯ ЛОГИКА: ОПРЕДЕЛЯЕМ ТЕКУЩЕГО ПОЛЬЗОВАТЕЛЯ ---
|
||||
// --- ОПРЕДЕЛЯЕМ ТЕКУЩЕГО ПОЛЬЗОВАТЕЛЯ ---
|
||||
$current_user_id = (int)($_SESSION['user_id'] ?? 0);
|
||||
$anon_key = $this->_getAnonKey();
|
||||
// -----------------------------------------------------
|
||||
|
||||
// Получаем ВСЕ настройки модуля разом
|
||||
// Получаем ВСЕ настройки модуля разом (из БД)
|
||||
$settings = $this->_commentSettingsGet();
|
||||
|
||||
// Проверяем, что в настройках модуля разрешено комментирование
|
||||
@@ -287,6 +297,9 @@ function commentListShow($tpl_dir)
|
||||
|
||||
$date_time_format = $AVE_Template->get_config_vars('COMMENT_DATE_TIME_FORMAT');
|
||||
$now = time();
|
||||
|
||||
// ГАРАНТИРУЕМ получение лимита времени из настроек БД
|
||||
$conf_limit = (int)($settings['comment_edit_time'] ?? 0);
|
||||
|
||||
while ($row = $sql->FetchAssocArray())
|
||||
{
|
||||
@@ -299,31 +312,30 @@ function commentListShow($tpl_dir)
|
||||
$row['avatar'] = '';
|
||||
}
|
||||
|
||||
// --- ИСПРАВЛЕННАЯ ЛОГИКА ТАЙМЕРА И ПРАВ ---
|
||||
// --- ИСПРАВЛЕННАЯ ЛОГИКА ТАЙМЕРА И ПРАВ (УЧЕТ АДМИНА) ---
|
||||
$row['can_edit'] = 0;
|
||||
$is_admin = ($user_group == 1);
|
||||
$is_admin = ($user_group === 1);
|
||||
|
||||
// Рассчитываем остаток времени (в секундах)
|
||||
$elapsed = $now - $row['comment_published'];
|
||||
$time_left = $this->conf_edit_time - $elapsed;
|
||||
|
||||
// Обязательно записываем в массив, чтобы избежать ошибки в шаблоне
|
||||
$row['edit_time_left'] = ($time_left > 0) ? $time_left : 0;
|
||||
|
||||
// Проверяем авторство (зарегистрированный или аноним по ключу)
|
||||
// Проверяем авторство
|
||||
$is_author = ($current_user_id > 0 && $current_user_id == $row['comment_author_id']) ||
|
||||
($row['comment_author_id'] == 0 && !empty($row['anon_key']) && $row['anon_key'] == $anon_key);
|
||||
|
||||
if ($is_admin) {
|
||||
$row['can_edit'] = 1;
|
||||
} elseif ($is_author) {
|
||||
// Автор может править, только если время еще есть
|
||||
if ($row['edit_time_left'] > 0) {
|
||||
// Для админа таймер не нужен, ставим 0, чтобы JS его игнорировал
|
||||
$row['edit_time_left'] = 0;
|
||||
} else {
|
||||
// Рассчитываем остаток времени только для простых смертных
|
||||
$elapsed = $now - (int)$row['comment_published'];
|
||||
$time_left = $conf_limit - $elapsed;
|
||||
$row['edit_time_left'] = ($time_left > 0) ? $time_left : 0;
|
||||
|
||||
if ($is_author && $row['edit_time_left'] > 0) {
|
||||
$row['can_edit'] = 1;
|
||||
}
|
||||
}
|
||||
$row['is_my_own'] = $is_author;
|
||||
// ------------------------------------------
|
||||
// -------------------------------------------------------
|
||||
|
||||
$row['comment_published_raw'] = $row['comment_published'];
|
||||
$row['comment_published'] = ave_date_format($date_time_format, $row['comment_published']);
|
||||
@@ -569,10 +581,6 @@ exit;
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод, предназначенный для редактирования комментария в Публичной части
|
||||
* с поддержкой анонимных пользователей и ограничением по времени.
|
||||
*/
|
||||
function commentPostEdit($comment_id)
|
||||
{
|
||||
global $AVE_DB;
|
||||
@@ -581,18 +589,19 @@ function commentPostEdit($comment_id)
|
||||
$comment_id = (int)$comment_id;
|
||||
$user_id = (int)($_SESSION['user_id'] ?? 0);
|
||||
$user_group = (int)(defined('UGROUP') ? UGROUP : 0);
|
||||
$anon_key = $this->_getAnonKey(); // Наш метод получения куки анонима
|
||||
$anon_key = $this->_getAnonKey();
|
||||
|
||||
if ($comment_id <= 0 || $user_group <= 0) exit('INVALID_ID');
|
||||
|
||||
// 2. Получаем данные комментария и настройки модуля (JOIN)
|
||||
// Нам нужно знать время создания и кто автор, а также лимиты из настроек
|
||||
// ДОБАВИЛ: cmnt.comment_edit_time в выборку SQL
|
||||
$row = $AVE_DB->Query("
|
||||
SELECT
|
||||
msg.*,
|
||||
cmnt.comment_max_chars,
|
||||
cmnt.comment_need_approve,
|
||||
cmnt.comment_user_groups
|
||||
cmnt.comment_user_groups,
|
||||
cmnt.comment_edit_time
|
||||
FROM " . PREFIX . "_module_comment_info AS msg
|
||||
JOIN " . PREFIX . "_module_comments AS cmnt ON cmnt.Id = 1
|
||||
WHERE msg.Id = '" . $comment_id . "'
|
||||
@@ -604,34 +613,30 @@ function commentPostEdit($comment_id)
|
||||
// 3. Проверка прав (БЕЗОПАСНОСТЬ)
|
||||
$is_admin = ($user_group == 1);
|
||||
|
||||
// Проверка на авторство:
|
||||
// Либо совпадает ID зарегистрированного юзера,
|
||||
// Либо совпадает anon_key в базе с кукой текущего анонима
|
||||
$is_author = ($user_id > 0 && $user_id == $row['comment_author_id']) ||
|
||||
($row['comment_author_id'] == 0 && !empty($row['anon_key']) && $row['anon_key'] == $anon_key);
|
||||
|
||||
// Проверка времени: прошло меньше секунд, чем указано в $this->conf_edit_time
|
||||
// ИСПРАВЛЕНО: Теперь берем лимит времени ПРЯМО из БД ($row), а не из переменной класса
|
||||
$time_limit = (isset($row['comment_edit_time'])) ? (int)$row['comment_edit_time'] : 60;
|
||||
$time_passed = time() - (int)$row['comment_published'];
|
||||
$is_time_ok = ($time_passed < $this->conf_edit_time);
|
||||
$is_time_ok = ($time_passed < $time_limit);
|
||||
|
||||
// Если не админ, проверяем: автор ли это и не вышло ли время
|
||||
if (!$is_admin) {
|
||||
if (!$is_author) exit('NOT_AUTHOR');
|
||||
if (!$is_time_ok) {
|
||||
echo "TIME_EXPIRED"; // Этот ответ поймает JS
|
||||
echo "TIME_EXPIRED";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Обработка текста (ТВОИ ОРИГИНАЛЬНЫЕ РЕГУЛЯРКИ)
|
||||
// 4. Обработка текста (без изменений...)
|
||||
$comment_text = $_POST['text'] ?? '';
|
||||
|
||||
// Декодируем HEX и десятичные сущности (твоя логика)
|
||||
$comment_text = preg_replace_callback('/&#x([0-9a-f]{1,7});/i', function($matches) { return chr(hexdec($matches[1])); }, $comment_text);
|
||||
$comment_text = preg_replace_callback('/&#([0-9]{1,7});/', function($matches) { return chr($matches[1]); }, $comment_text);
|
||||
|
||||
$comment_text = stripslashes($comment_text);
|
||||
// Заменяем брейки на переносы строк для корректной работы mb_substr и strip_tags
|
||||
$comment_text = str_replace(array("<br>\n", "<br />\n", "<br/>\n", "<br>", "<br />"), "\n", $comment_text);
|
||||
$comment_text = strip_tags($comment_text);
|
||||
|
||||
@@ -639,15 +644,13 @@ function commentPostEdit($comment_id)
|
||||
$comment_text_cut = mb_substr($comment_text, 0, $max);
|
||||
if (mb_strlen($comment_text) > $max) $comment_text_cut .= '…';
|
||||
|
||||
// 5. Работа с изображениями
|
||||
// 5. Работа с изображениями (без изменений...)
|
||||
$new_file_sql = "";
|
||||
$upload_dir = BASE_DIR . '/uploads/comments/';
|
||||
|
||||
// Вариант А: Загрузка нового файла взамен старого
|
||||
if (isset($_FILES['comment_image']) && $_FILES['comment_image']['error'] == UPLOAD_ERR_OK) {
|
||||
if (!is_dir($upload_dir)) @mkdir($upload_dir, 0775, true);
|
||||
|
||||
// Удаляем старый файл физически
|
||||
if (!empty($row['comment_file']) && file_exists($upload_dir . $row['comment_file'])) {
|
||||
@unlink($upload_dir . $row['comment_file']);
|
||||
}
|
||||
@@ -659,7 +662,6 @@ function commentPostEdit($comment_id)
|
||||
$new_file_sql = ", comment_file = '" . addslashes($new_file_name) . "'";
|
||||
}
|
||||
}
|
||||
// Вариант Б: Просто удаление изображения (если стоит галочка в форме)
|
||||
elseif (isset($_POST['delete_image']) && $_POST['delete_image'] == 1) {
|
||||
if (!empty($row['comment_file']) && file_exists($upload_dir . $row['comment_file'])) {
|
||||
@unlink($upload_dir . $row['comment_file']);
|
||||
@@ -667,12 +669,9 @@ function commentPostEdit($comment_id)
|
||||
$new_file_sql = ", comment_file = ''";
|
||||
}
|
||||
|
||||
// --- ВОТ ЭТО ДОБАВИЛ ---
|
||||
$user_rating = isset($_POST['user_rating']) ? (int)$_POST['user_rating'] : (int)$row['user_rating'];
|
||||
// -----------------------
|
||||
|
||||
// 6. Обновление базы данных
|
||||
// Если в настройках стоит "нужна премодерация", после правки статус меняется на 0 (если не админ)
|
||||
$new_status = $is_admin ? (int)$row['comment_status'] : ($row['comment_need_approve'] == '1' ? 0 : 1);
|
||||
|
||||
$AVE_DB->Query("
|
||||
@@ -687,18 +686,10 @@ function commentPostEdit($comment_id)
|
||||
Id = '" . $comment_id . "'
|
||||
");
|
||||
|
||||
// Возвращаем текст для JS, чтобы он обновил блок без перезагрузки страницы
|
||||
echo htmlspecialchars($comment_text_cut, ENT_QUOTES);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод, предназначенный для удаления комментария.
|
||||
* Реализует логику мягкого удаления (затирки) при наличии ответов
|
||||
* и полную очистку при их отсутствии.
|
||||
*
|
||||
* @param int $comment_id - идентификатор комментария
|
||||
*/
|
||||
function commentPostDelete($comment_id)
|
||||
{
|
||||
global $AVE_DB;
|
||||
@@ -709,6 +700,10 @@ function commentPostDelete($comment_id)
|
||||
if ($comment_id <= 0) die('Ошибка: Неверный ID');
|
||||
|
||||
// --- ШАГ 0. ПОЛУЧЕНИЕ ДАННЫХ И ПРОВЕРКА ПРАВ ---
|
||||
|
||||
// ГАРАНТИРУЕМ, что настройки загружены из БД в свойства класса
|
||||
$this->_commentSettingsGet();
|
||||
|
||||
$comment_data = $AVE_DB->Query("
|
||||
SELECT comment_author_id, anon_key, comment_published, comment_file
|
||||
FROM " . PREFIX . "_module_comment_info
|
||||
@@ -728,7 +723,9 @@ function commentPostDelete($comment_id)
|
||||
} else {
|
||||
$is_author = ($current_user_id > 0 && $current_user_id == $comment_data['comment_author_id']) ||
|
||||
($comment_data['comment_author_id'] == 0 && !empty($comment_data['anon_key']) && $comment_data['anon_key'] == $anon_key);
|
||||
$is_time_ok = (time() - (int)$comment_data['comment_published'] < $this->conf_edit_time);
|
||||
|
||||
// Теперь $this->conf_edit_time точно содержит значение из БД (благодаря вызову выше)
|
||||
$is_time_ok = (time() - (int)$comment_data['comment_published'] < (int)$this->conf_edit_time);
|
||||
|
||||
if ($is_author && $is_time_ok) {
|
||||
$can_delete = true;
|
||||
@@ -740,7 +737,7 @@ function commentPostDelete($comment_id)
|
||||
die('Доступ запрещен');
|
||||
}
|
||||
|
||||
// --- ШАГ 1. ПРОВЕРКА НАЛИЧИЯ ОТВЕТОВ ---
|
||||
// --- ШАГ 1. ПРОВЕРКА НАЛИЧИЯ ОТВЕТОВ (без изменений) ---
|
||||
$has_children = $AVE_DB->Query("SELECT COUNT(*) FROM " . PREFIX . "_module_comment_info WHERE parent_id = '" . $comment_id . "'")->GetCell();
|
||||
$upload_dir = BASE_DIR . '/uploads/comments/';
|
||||
|
||||
@@ -761,20 +758,17 @@ function commentPostDelete($comment_id)
|
||||
else {
|
||||
// --- ВАРИАНТ Б: ПОЛНОЕ УДАЛЕНИЕ (Для админа или если нет детей) ---
|
||||
|
||||
// Собираем массив ID для удаления. Сразу кладем туда родителя.
|
||||
$ids_to_delete = [$comment_id];
|
||||
|
||||
// Если удаляет Админ, ищем ВСЮ ветку (любой вложенности)
|
||||
if ($user_group == 1) {
|
||||
$all_child_ids = [];
|
||||
$parent_ids = [$comment_id];
|
||||
|
||||
// Рекурсивный поиск всех уровней вложенности
|
||||
while (!empty($parent_ids)) {
|
||||
$ids_string = implode(',', array_map('intval', $parent_ids));
|
||||
$res = $AVE_DB->Query("SELECT Id FROM " . PREFIX . "_module_comment_info WHERE parent_id IN ($ids_string)");
|
||||
|
||||
$parent_ids = []; // Сбрасываем для следующего уровня
|
||||
$parent_ids = [];
|
||||
while ($row = $res->FetchAssocArray()) {
|
||||
$all_child_ids[] = (int)$row['Id'];
|
||||
$parent_ids[] = (int)$row['Id'];
|
||||
@@ -783,7 +777,6 @@ function commentPostDelete($comment_id)
|
||||
$ids_to_delete = array_merge($ids_to_delete, $all_child_ids);
|
||||
}
|
||||
|
||||
// 1. Удаляем файлы всех комментариев из списка удаления
|
||||
$final_ids_str = implode(',', $ids_to_delete);
|
||||
$files_res = $AVE_DB->Query("SELECT comment_file FROM " . PREFIX . "_module_comment_info WHERE Id IN ($final_ids_str)");
|
||||
while ($f = $files_res->FetchAssocArray()) {
|
||||
@@ -793,7 +786,6 @@ function commentPostDelete($comment_id)
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Удаляем все записи из БД одним запросом
|
||||
$AVE_DB->Query("DELETE FROM " . PREFIX . "_module_comment_info WHERE Id IN ($final_ids_str)");
|
||||
|
||||
echo "OK";
|
||||
|
||||
@@ -21,12 +21,23 @@
|
||||
|
||||
var countdown = setInterval(function() {
|
||||
timeLeft--;
|
||||
if (timeLeft <= 0) {
|
||||
clearInterval(countdown);
|
||||
$('#controls_' + cid).fadeOut(300);
|
||||
$('#timer_container_' + cid).html('<span class="text-danger small">Время на правку истекло</span>');
|
||||
return;
|
||||
}
|
||||
if (timeLeft <= 0) {
|
||||
clearInterval(countdown);
|
||||
|
||||
// Пытаемся найти блок управления по ID
|
||||
var $controls = $('#controls_' + cid);
|
||||
|
||||
if ($controls.length) {
|
||||
// Скрываем кнопки
|
||||
$controls.fadeOut(300, function() {
|
||||
$(this).remove(); // Полностью удаляем из DOM для надежности
|
||||
});
|
||||
}
|
||||
|
||||
// Обновляем статус таймера
|
||||
$('#timer_container_' + cid).html('<span class="text-danger small"><i class="bi bi-clock-history"></i> Время на правку истекло</span>');
|
||||
return;
|
||||
}
|
||||
var minutes = Math.floor(timeLeft / 60);
|
||||
var seconds = timeLeft % 60;
|
||||
$timer.text(minutes + ':' + (seconds < 10 ? '0' : '') + seconds);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{foreach from=$subcomments item=c}
|
||||
|
||||
<div class="card mb-3 mod_comment_comment{if $c.parent_id} ms-4{/if}" id="comment_wrapper_{$c.Id}" data-user-rating="{$c.user_rating|default:0}" data-is-own="{if isset($c.is_my_own) && $c.is_my_own}1{else}0{/if}">
|
||||
|
||||
{if isset($smarty.request.subaction) && $smarty.request.subaction=='showonly' && isset($smarty.request.comment_id) && $smarty.request.comment_id==$c.Id}
|
||||
@@ -7,7 +6,6 @@
|
||||
{/if}
|
||||
|
||||
<div id="comment_{$c.Id}" class="mod_comment_box">
|
||||
|
||||
<div class="card-body p-3 d-flex align-items-start">
|
||||
|
||||
{* ----- БЛОК АВАТАРА ----- *}
|
||||
@@ -23,9 +21,7 @@
|
||||
<div class="flex-grow-1">
|
||||
{* Информация об авторе и дате *}
|
||||
<div class="mod_comment_meta mb-2 text-muted small d-flex align-items-center flex-wrap">
|
||||
|
||||
<span class="me-2"><i class="bi bi-person me-1"></i> {#COMMENT_USER_ADD#} <a title="{#COMMENT_INFO#}" href="javascript:void(0);" onclick="popup('{$ABS_PATH}index.php?module=comment&action=postinfo&pop=1&Id={$c.Id}&theme={$theme}','comment','500','300','1');" class="fw-bold link-dark">{$c.comment_author_name|stripslashes|escape}</a></span>
|
||||
|
||||
<span class="me-2"><i class="bi bi-clock me-1"></i> {$c.comment_published}</span>
|
||||
|
||||
{if $comment_show_f1 == 1 && $c.comment_author_website}
|
||||
@@ -86,11 +82,10 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{* 2. Общий рейтинг комментария (лайки/звезды для голосования) *}
|
||||
{* 2. Общий рейтинг комментария *}
|
||||
{if $comment_rating_type != 2}
|
||||
<div class="comment-rating-container d-inline-flex align-items-center me-3 py-1 px-2 bg-light rounded border" data-id="{$c.Id}" style="line-height: 1;">
|
||||
{if $comment_rating_type == 1}
|
||||
{* Лайки *}
|
||||
<div class="comment-like d-inline-flex align-items-center" style="cursor: pointer; color: #dc3545; font-size: 0.95rem;">
|
||||
<i class="star-item bi bi-heart-fill me-1" data-value="5" title="Мне нравится"></i>
|
||||
</div>
|
||||
@@ -98,7 +93,6 @@
|
||||
<span class="ms-1 text-muted fw-bold" style="font-size: 0.8rem;">{$c.rating_count}</span>
|
||||
{/if}
|
||||
{else}
|
||||
{* Звезды для голосования *}
|
||||
<div class="comment-stars d-inline-flex" style="cursor: pointer; color: #ffc107; font-size: 0.9rem;">
|
||||
{assign var="avg_rating" value=0}
|
||||
{if isset($c.rating_count) && $c.rating_count > 0}
|
||||
@@ -115,8 +109,8 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{* 3. Таймер редактирования *}
|
||||
{if $c.can_edit && isset($c.edit_time_left) && $c.edit_time_left > 0}
|
||||
{* 3. ТАЙМЕР РЕДАКТИРОВАНИЯ (Добавлена проверка на UGROUP != 1) *}
|
||||
{if $smarty.const.UGROUP != 1 && $c.can_edit && isset($c.edit_time_left) && $c.edit_time_left > 0}
|
||||
<div class="edit-timer-wrapper text-muted small" id="timer_container_{$c.Id}" title="Осталось времени">
|
||||
<i class="bi bi-hourglass-split text-primary"></i>
|
||||
<span class="timer-count fw-bold" data-left="{$c.edit_time_left}" id="timer_{$c.Id}">
|
||||
@@ -153,7 +147,6 @@
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user