diff --git a/class/comment.php b/class/comment.php index 1da207d..ad551e2 100644 --- a/class/comment.php +++ b/class/comment.php @@ -257,6 +257,20 @@ function commentListShow($tpl_dir) $current_user_id = (int)($_SESSION['user_id'] ?? 0); $anon_key = $this->_getAnonKey(); + // --- УСЛОВИЕ ВИДИМОСТИ (Свои неодобренные + Все одобренные) --- + if ($user_group == 1) { + $where_visibility = ""; // Админ видит всё + } else { + $cond = "comment_status = '1'"; + if ($current_user_id > 0) { + $cond .= " OR (comment_status = '0' AND comment_author_id = '$current_user_id')"; + } + if (!empty($anon_key)) { + $cond .= " OR (comment_status = '0' AND anon_key = '$anon_key')"; + } + $where_visibility = "AND (" . $cond . ")"; + } + // Получаем ВСЕ настройки модуля разом (из БД) $settings = $this->_commentSettingsGet(); @@ -291,131 +305,100 @@ function commentListShow($tpl_dir) $assign['ajax_replies_limit'] = (int)($settings['comment_ajax_replies_limit'] ?? 0); $comments = array(); + // --- ВЫБОРКА ИЗ БД --- + if ($settings['comment_use_page_nav'] == 1) + { + $limit = (int)$settings['comment_page_nav_count']; + if ($limit <= 0) + { + $sql = $AVE_DB->Query("SELECT * FROM " . PREFIX . "_module_comment_info WHERE document_id = '" . $document_id . "' " . $where_visibility . " ORDER BY comment_published ASC"); + $page_nav = ''; + } + else + { + $start = get_current_page() * $limit - $limit; + // 1. Считаем только РОДИТЕЛЕЙ для пагинации (с учетом видимости) + $num = $AVE_DB->Query("SELECT COUNT(*) FROM " . PREFIX . "_module_comment_info WHERE document_id = '" . $document_id . "' AND parent_id = '0' " . $where_visibility)->GetCell(); + // 2. Основной запрос + $sql = $AVE_DB->Query(" + SELECT * FROM " . PREFIX . "_module_comment_info + WHERE document_id = '" . $document_id . "' + AND ( + id IN (SELECT id FROM (SELECT id FROM " . PREFIX . "_module_comment_info WHERE document_id = '" . $document_id . "' AND parent_id = '0' " . $where_visibility . " ORDER BY comment_published ASC LIMIT " . (int)$start . "," . (int)$limit . ") as tmp) + OR + parent_id != '0' + ) + " . $where_visibility . " + ORDER BY comment_published ASC + "); - - -if ($settings['comment_use_page_nav'] == 1) -{ - $limit = (int)$settings['comment_page_nav_count']; - - // Если лимит включен, но равен 0 — это то же самое, что лимит выключен - if ($limit <= 0) - { - $sql = $AVE_DB->Query("SELECT * FROM " . PREFIX . "_module_comment_info WHERE document_id = '" . $document_id . "' " . ($user_group == 1 ? '' : "AND comment_status = '1'") . " ORDER BY comment_published ASC"); - $page_nav = ''; - } - else - { - $start = get_current_page() * $limit - $limit; - - // 1. Считаем только РОДИТЕЛЕЙ для пагинации - $num = $AVE_DB->Query("SELECT COUNT(*) FROM " . PREFIX . "_module_comment_info WHERE document_id = '" . $document_id . "' AND parent_id = '0'")->GetCell(); - - // 2. Основной запрос: выбираем ВСЮ ветку (родителя и всё, что под ним) - $sql = $AVE_DB->Query(" - SELECT * FROM " . PREFIX . "_module_comment_info - WHERE document_id = '" . $document_id . "' - AND ( - id IN (SELECT id FROM (SELECT id FROM " . PREFIX . "_module_comment_info WHERE document_id = '" . $document_id . "' AND parent_id = '0' ORDER BY comment_published ASC LIMIT " . (int)$start . "," . (int)$limit . ") as tmp) - OR - parent_id != '0' - ) - " . ($user_group == 1 ? '' : "AND comment_status = '1'") . " - ORDER BY comment_published ASC - "); - - if ($num > $limit) - { - $page_nav = '{t} '; - - // Теперь деление на $limit безопасно, так как мы выше проверили, что он > 0 - $total_pages = ceil($num / $limit); - $page_nav = get_pagination($total_pages, 'page', $page_nav, get_settings('navi_box')); - $page_nav = str_ireplace('"//"', '"/"', str_ireplace('///', '/', rewrite_link($page_nav))); - $page_nav = preg_replace('/(? $total_pages ? $GLOBALS['page_id'][$document_id]['page'] : $total_pages); - } - else { $page_nav = ''; } - } -} -else -{ - $sql = $AVE_DB->Query("SELECT * FROM " . PREFIX . "_module_comment_info WHERE document_id = '" . $document_id . "' " . ($user_group == 1 ? '' : "AND comment_status = '1'") . " ORDER BY comment_published ASC"); - $page_nav = ''; -} - - - - - + if ($num > $limit) + { + $page_nav = '{t} '; + + $total_pages = ceil($num / $limit); + $page_nav = get_pagination($total_pages, 'page', $page_nav, get_settings('navi_box')); + $page_nav = str_ireplace('"//"', '"/"', str_ireplace('///', '/', rewrite_link($page_nav))); + $page_nav = preg_replace('/(? $total_pages ? $GLOBALS['page_id'][$document_id]['page'] : $total_pages); + } + else { $page_nav = ''; } + } + } + else + { + $sql = $AVE_DB->Query("SELECT * FROM " . PREFIX . "_module_comment_info WHERE document_id = '" . $document_id . "' " . $where_visibility . " ORDER BY comment_published ASC"); + $page_nav = ''; + } $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()) { + if ($assign['saved_anon']['exists'] == false && !empty($row['anon_key']) && $row['anon_key'] == $anon_key) { + $assign['saved_anon'] = [ + 'name' => stripslashes($row['comment_author_name']), + 'email' => stripslashes($row['comment_author_email']), + 'exists' => true + ]; + } - if ($assign['saved_anon']['exists'] == false && !empty($row['anon_key']) && $row['anon_key'] == $anon_key) { - $assign['saved_anon'] = [ - 'name' => stripslashes($row['comment_author_name']), - 'email' => stripslashes($row['comment_author_email']), - 'exists' => true - ]; - } + // Аватар + if (isset($row['comment_author_id']) && $row['comment_author_id'] > 0) { + $row['avatar'] = getAvatar($row['comment_author_id'], 48); + } else { + $row['avatar'] = ''; + } - // Получаем аватар через стандартную функцию системы - if (isset($row['comment_author_id']) && $row['comment_author_id'] > 0) - { - $row['avatar'] = getAvatar($row['comment_author_id'], 48); - } - else - { - $row['avatar'] = ''; - } + if (!empty($row['avatar']) && strpos($row['avatar'], 'user.png') !== false) { + $row['avatar'] = ''; + } - // Если функция вернула системную заглушку, считаем, что аватара нет - if (!empty($row['avatar']) && strpos($row['avatar'], 'user.png') !== false) - { - $row['avatar'] = ''; - } + if (empty($row['avatar'])) { + $name = !empty($row['comment_author_name']) ? stripslashes($row['comment_author_name']) : 'Guest'; + $row['first_letter'] = mb_substr(trim($name), 0, 1, 'UTF-8'); + $row['avatar_color_index'] = (abs(crc32($name)) % 12) + 1; + } - // Если аватара нет (пусто или мы его обнулили выше) - if (empty($row['avatar'])) - { - // Берем имя автора (если пусто — 'Guest') - $name = !empty($row['comment_author_name']) ? stripslashes($row['comment_author_name']) : 'Guest'; - - // Получаем первую букву имени (в верхнем регистре) - $row['first_letter'] = mb_substr(trim($name), 0, 1, 'UTF-8'); - - // Вычисляем индекс цвета (от 1 до 8) на основе имени - $row['avatar_color_index'] = (abs(crc32($name)) % 12) + 1; - } - - // --- ТАЙМЕР И ПРАВА (УЧЕТ АДМИНА) --- + // --- ТАЙМЕР И ПРАВА --- $row['can_edit'] = 0; $is_admin = ($user_group === 1); - - // Проверяем авторство $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; - // Для админа таймер не нужен, ставим 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; @@ -426,22 +409,20 @@ else } $row['is_my_own'] = $is_author; - // --- Получаем историю имен для анонима --- - $row['past_names'] = []; - if (!empty($row['anon_key'])) { - $row['past_names'] = $this->_getAnonNamesHistory($row['anon_key'], $row['comment_author_name']); - } + // История имен + $row['past_names'] = []; + if (!empty($row['anon_key'])) { + $row['past_names'] = $this->_getAnonNamesHistory($row['anon_key'], $row['comment_author_name']); + } -$row['comment_published_raw'] = $row['comment_published']; -$row['comment_published'] = ave_date_format($date_time_format, $row['comment_published']); + $row['comment_published_raw'] = $row['comment_published']; + $row['comment_published'] = ave_date_format($date_time_format, $row['comment_published']); -// Если время изменения больше 0, тогда форматируем. -// Иначе — ставим 0, чтобы шаблон не выводил плашку. -if ($row['comment_changed'] > 0) { - $row['comment_changed'] = ave_date_format($date_time_format, $row['comment_changed']); -} else { - $row['comment_changed'] = 0; -} + if ($row['comment_changed'] > 0) { + $row['comment_changed'] = ave_date_format($date_time_format, $row['comment_changed']); + } else { + $row['comment_changed'] = 0; + } $comments[$row['parent_id']][] = $row; } @@ -452,25 +433,21 @@ if ($row['comment_changed'] > 0) { $page_nav = ''; } -// --- НАЧАЛО ВСТАВКИ ДЛЯ AJAX --- -$assign['more_counts'] = []; -// Проверяем, не запросил ли пользователь раскрыть конкретную ветку -$requested_branch = (int)($_REQUEST['ajax_load_branch'] ?? 0); + // --- AJAX ЛИМИТЫ --- + $assign['more_counts'] = []; + $requested_branch = (int)($_REQUEST['ajax_load_branch'] ?? 0); -if ($assign['ajax_replies_limit'] > 0 && !empty($comments)) { - foreach ($comments as $parentId => $subList) { - if ($parentId > 0 && count($subList) > $assign['ajax_replies_limit']) { - - // Если это ТА САМАЯ ветка, которую мы подгружаем по AJAX — НЕ обрезаем её - if ($requested_branch == $parentId) { - continue; + if ($assign['ajax_replies_limit'] > 0 && !empty($comments)) { + foreach ($comments as $parentId => $subList) { + if ($parentId > 0 && count($subList) > $assign['ajax_replies_limit']) { + if ($requested_branch == $parentId) { + continue; + } + $assign['more_counts'][$parentId] = count($subList) - $assign['ajax_replies_limit']; + $comments[$parentId] = array_slice($subList, 0, $assign['ajax_replies_limit']); + } } - - $assign['more_counts'][$parentId] = count($subList) - $assign['ajax_replies_limit']; - $comments[$parentId] = array_slice($subList, 0, $assign['ajax_replies_limit']); } - } -} $assign['closed'] = @$comments[0][0]['comments_close']; $assign['comments'] = $comments; diff --git a/js/comment.js b/js/comment.js index c0dc9a9..adf239b 100644 --- a/js/comment.js +++ b/js/comment.js @@ -208,18 +208,44 @@ if ($fileInput.length && $fileInput[0].files.length > 0) { } // показать / скрыть комментарий + +// показать / скрыть комментарий if (action === 'unlock' || action === 'lock') { var $icon = $btn.find('i'); + var $card = $btn.closest('.mod_comment_comment'); + if (action === 'lock') { - // Статус 0: СКРЫТО. Ставим красный перечеркнутый глаз. + // --- Статус 0: СКРЫТО --- $icon.attr('class', 'bi bi-eye-slash'); $btn.removeClass('text-success text-muted').addClass('text-danger').attr('title', COMMENT_ICON_SHOW); + + $card.addClass('opacity-75 border-warning'); + + // Ищем плашку. Если её нет — создаем один раз. + var $alert = $card.find('.alert-warning'); + if ($alert.length === 0) { + var alertHtml = '
'; + $card.find('.flex-grow-1').prepend(alertHtml); + $alert = $card.find('.alert-warning'); + } + $alert.stop(true, true).fadeIn(300); } else { - // Статус 1: ВИДИМО. Ставим зеленый открытый глаз. + // --- Статус 1: ВИДИМО --- $icon.attr('class', 'bi bi-eye'); $btn.removeClass('text-danger text-muted').addClass('text-success').attr('title', COMMENT_ICON_HIDE); + + $card.removeClass('opacity-75 border-warning'); + + // Надежное скрытие: используем callback, чтобы после анимации точно убрать элемент + $card.find('.alert-warning').stop(true, true).fadeOut(300, function() { + $(this).remove(); // Удаляем плашку из кода совсем, чтобы при следующем "скрыть" она создалась чисто + }); } } + }); } diff --git a/lang/ru.txt b/lang/ru.txt index 92b304c..17ec1f3 100644 --- a/lang/ru.txt +++ b/lang/ru.txt @@ -119,6 +119,7 @@ COMMENT_JS_LOADS_F = "Загрузка:" COMMENT_JS_LOADS_R = "Отправка..." COMMENT_JS_SEC_CODE_WRONG = "Код капчи введен неверно!" COMMENT_JS_ERR_SRV = "Ошибка связи с сервером" +COMMENT_WAITING_MODERATION = "Ваш комментарий на проверке и виден пока только вам." diff --git a/templates/comments_tree.tpl b/templates/comments_tree.tpl index 10a7fa9..4475599 100644 --- a/templates/comments_tree.tpl +++ b/templates/comments_tree.tpl @@ -299,7 +299,7 @@ var COMMENT_JS_LOADS_R = '{#COMMENT_JS_LOADS_R#}'; var COMMENT_JS_SEC_CODE_WRONG = '{#COMMENT_JS_SEC_CODE_WRONG#}'; var COMMENT_JS_ERR_SRV = '{#COMMENT_JS_ERR_SRV#}'; - + var COMMENT_WAITING_MODERATION = '{#COMMENT_WAITING_MODERATION#}'; var REQ_F1 = '{$comment_req_f1}'; var REQ_F2 = '{$comment_req_f2}'; diff --git a/templates/comments_tree_sub.tpl b/templates/comments_tree_sub.tpl index a244006..8226c0f 100644 --- a/templates/comments_tree_sub.tpl +++ b/templates/comments_tree_sub.tpl @@ -1,5 +1,5 @@ {foreach from=$subcomments item=c name=sub_loop} -