приведена в порядок скрытие видимость комментариев как в паблике так и в админке

This commit is contained in:
2026-01-20 01:19:55 +05:00
parent 540c0c8fe7
commit 979b4b6225
6 changed files with 230 additions and 164 deletions

View File

@@ -31,7 +31,15 @@
* Комментарии родители (имеющие ответы/ветку ответов) получают два варианта одиночного удаления:
* Мягкое удаление (удалится все , что относится к данному комментарию (Рейтинги, файлы , текст) и вместо этого будет выводится специальный аватар и текст: Комментарий удален администратором. Восстановить данные такого комментария невозможно,
* Жесткое удаление самого комментария и всей ветки ответов на этот комментарий. Администратор выбирает сам какой вариант ему необходим.
* Массовое удаление - одиночные комментарии удаляются сразу, комментарии-родители удаляются Мягким вариантом (с подстановкой текста Комментарий удален Администратором).
* Массовое удаление - одиночные комментарии удаляются сразу, комментарии-родители удаляются Мягким вариантом (с подстановкой текста Комментарий удален Администратором).
* Статус Скрыт/Опубликован (иконка глаз)
* Если комментарий родитель и на него есть ответы:
* При клике по иконке Скрыть (как в публичной части сайта так и в Админке) - автоматически будет скрыт как сам комментарий так и все ответы на него (ветка комментариев), при этом у ответов возможность скрытия/публикации будет заблокирована до тех пор, пока родительский комментарий не будет разблокирован (опубликован). Восстановление в ветке статусов - опубликован, происходит персонально, кликом Опубликовать по каждому комментарию в ветке.
* Если комментарий одиночный (на него нет ответов):
* При клике по иконке Скрыть - комментарий будет скрыт. При клике опубликовать - будет опубликован.
* Видимость скрытых комментариев:
* Если комментарий родитель и на него есть ответы и он скрыт - будут также скрыты все ответы на него. Такой комментарий будет видеть только Администратор и Автор комментария с пометкой "На модерации", однако если этот комментарий будет в свою очередь потомком вышестояшего в иерархии комментария-родителя другого Автора и тот в свою очередь будет скрыт - то тогда комментарий будет виден только Администратору.
* Если комментарий одиночный и на него нет ответов и он, в свою очередь, сам не является ответом: если статус Скрыт - то его видит только Администратор и сам Автор. Другие посетители его не видят.
* Контроль Имен Анонима
* Если Анонимный пользователь, в течении жизни куки, сменит имя под которым он опубликовал свой первый комментарий, рядом с именем появится плашка с тултипом в котором будут перечислены все его имена.
* Пагинация

View File

@@ -1326,20 +1326,48 @@ function commentAdminDelete($comment_id)
* @param int $comment_id - идентификатор комментария
* @param string $comment_status - {lock|unlock} признак запрета/разрешения
*/
function commentReplyStatusSet($comment_id, $comment_status = 'lock')
{
global $AVE_DB;
function commentReplyStatusSet($comment_id, $comment_status = 'lock')
{
global $AVE_DB;
$comment_id = (int)$comment_id;
// Определяем цифровой статус: lock -> 0, unlock -> 1
$status_numeric = ($comment_status == 'lock') ? 0 : 1;
$comment_id = (int)$comment_id;
if ($status_numeric == 0) {
// --- ТУДА (Скрываем всю ветку) ---
$all_ids = [$comment_id];
$stack = [$comment_id];
while (!empty($stack)) {
$curr_id = array_shift($stack);
$res = $AVE_DB->Query("SELECT Id FROM " . PREFIX . "_module_comment_info WHERE parent_id = '$curr_id'");
while ($res && $row = $res->FetchAssocArray()) {
$all_ids[] = (int)$row['Id'];
$stack[] = (int)$row['Id'];
}
}
$ids_string = implode(',', $all_ids);
$AVE_DB->Query("UPDATE " . PREFIX . "_module_comment_info SET comment_status = '0' WHERE Id IN ($ids_string)");
echo "OK_LOCKED";
}
else {
// --- ОБРАТНО (Открываем ТОЛЬКО один коммент) ---
// Магия SQL: Обновляем только если (родителя нет) ИЛИ (у родителя статус не 0)
$AVE_DB->Query("
UPDATE " . PREFIX . "_module_comment_info AS child
LEFT JOIN " . PREFIX . "_module_comment_info AS parent ON child.parent_id = parent.Id
SET child.comment_status = '1'
WHERE child.Id = '$comment_id'
AND (child.parent_id = 0 OR parent.comment_status != '0')
");
$AVE_DB->Query("
UPDATE " . PREFIX . "_module_comment_info
SET comment_status = '" . (($comment_status == 'lock') ? 0 : 1) . "'
WHERE Id = '" . $comment_id . "'
");
// Чтобы JS не тупил, всегда отвечаем OK (так как в базе либо уже 1, либо стала 1)
echo "OK_UNLOCKED";
}
exit;
}
exit;
}
/**
* Метод, предназначенный для управления запретом или разрешением комментировать документ
@@ -1387,51 +1415,70 @@ function commentAdminListShow($tpl_dir)
$items = (is_array($_REQUEST['id'])) ? $_REQUEST['id'] : [$_REQUEST['id']];
}
if (!empty($action) && !empty($items)) {
$ids = array_map('intval', $items);
// Проверяем наличие действия И (наличие массива галочек ИЛИ наличие одиночного ID в ссылке)
if (!empty($action) && (!empty($items) || !empty($_REQUEST['id']))) {
// --- СОБИРАЕМ ВСЕ ID ПОТОМКОВ (ЛЮБАЯ ГЛУБИНА) ---
$all_ids_to_process = $ids;
$current_parents = $ids;
while (!empty($current_parents)) {
$parent_list = implode(',', $current_parents);
// Получаем результат запроса
$res = $AVE_DB->Query("SELECT Id FROM " . PREFIX . "_module_comment_info WHERE parent_id IN ($parent_list)");
$found_children = [];
// Перебираем результат построчно
if ($res) {
while ($row_child = $res->FetchAssocArray()) {
$found_children[] = (int)$row_child['Id'];
}
}
if (!empty($found_children)) {
$all_ids_to_process = array_merge($all_ids_to_process, $found_children);
$current_parents = $found_children;
} else {
$current_parents = [];
}
// Формируем единый массив $ids для обработки
if (!empty($items)) {
$ids = array_map('intval', $items);
} else {
// Если пришел одиночный ID (может быть как числом, так и массивом из одного элемента)
$single_id = $_REQUEST['id'];
$ids = is_array($single_id) ? array_map('intval', $single_id) : [(int)$single_id];
}
$all_ids_to_process = array_unique($all_ids_to_process);
$final_id_list = implode(',', $all_ids_to_process);
// ------------------------------------------------
// 1. Для СКРЫТИЯ собираем "паровоз" (всех детей на любую глубину)
$all_related_for_hiding = $ids;
$current_p = $ids;
while (!empty($current_p)) {
$p_str = implode(',', $current_p);
$res = $AVE_DB->Query("SELECT Id FROM " . PREFIX . "_module_comment_info WHERE parent_id IN ($p_str)");
$found = [];
if ($res) {
while ($r = $res->FetchAssocArray()) { $found[] = (int)$r['Id']; }
}
if (!empty($found)) {
$all_related_for_hiding = array_merge($all_related_for_hiding, $found);
$current_p = $found;
} else { $current_p = []; }
}
$final_hide_list = implode(',', array_unique($all_related_for_hiding));
switch ($action) {
case 'approve':
case 'set_status_1':
$AVE_DB->Query("UPDATE " . PREFIX . "_module_comment_info SET comment_status = '1' WHERE Id IN ($final_id_list)");
// ПУБЛИКАЦИЯ: Работаем СТРОГО с теми ID, на которых кликнули или поставили галки
$active_db = [];
$res_act = $AVE_DB->Query("SELECT Id FROM " . PREFIX . "_module_comment_info WHERE comment_status = '1'");
if ($res_act) {
while ($row = $res_act->FetchAssocArray()) { $active_db[] = (int)$row['Id']; }
}
$to_publish = [];
foreach ($ids as $curr_id) {
$p_id = (int)$AVE_DB->Query("SELECT parent_id FROM " . PREFIX . "_module_comment_info WHERE Id = $curr_id")->GetCell();
// Разрешаем включить, только если родитель УЖЕ активен в базе
if ($p_id == 0 || in_array($p_id, $active_db)) {
$to_publish[] = $curr_id;
}
}
if (!empty($to_publish)) {
$pub_str = implode(',', $to_publish);
$AVE_DB->Query("UPDATE " . PREFIX . "_module_comment_info SET comment_status = '1' WHERE Id IN ($pub_str)");
}
break;
case 'unapprove':
case 'set_status_0':
$AVE_DB->Query("UPDATE " . PREFIX . "_module_comment_info SET comment_status = '0' WHERE Id IN ($final_id_list)");
// СКРЫТИЕ: Используем полный список (родители + все дети)
if (!empty($final_hide_list)) {
$AVE_DB->Query("UPDATE " . PREFIX . "_module_comment_info SET comment_status = '0' WHERE Id IN ($final_hide_list)");
}
break;
//case 'delete':
// $AVE_DB->Query("DELETE FROM " . PREFIX . "_module_comment_info WHERE Id IN ($final_id_list)");
//break;
}
header("Location: index.php?do=modules&action=modedit&mod=comment&moduleaction=1&cp=" . $session_id);
exit;
}
@@ -1521,71 +1568,53 @@ function commentAdminListShow($tpl_dir)
if ($p_id > 0) $child_map[$p_id][] = $id;
}
// Проходим по всем элементам и помечаем тех, у кого есть дети в child_map
foreach ($all_items as $id => &$item_for_check) {
$item_for_check['has_children'] = isset($child_map[$id]) ? 1 : 0;
}
unset($item_for_check); // очистка ссылки
unset($item_for_check);
$docs = [];
$processed = [];
$buildTree = function($parent_id, $level) use (&$buildTree, &$docs, &$processed, &$all_items, &$child_map) {
// Универсальная функция с наследованием блокировки parent_locked
$buildTree = function($parent_id, $level, $is_parent_hidden) use (&$buildTree, &$docs, &$processed, &$all_items, &$child_map) {
if (isset($child_map[$parent_id])) {
foreach ($child_map[$parent_id] as $child_id) {
if (!in_array($child_id, $processed)) {
$item = $all_items[$child_id];
$item['depth_level'] = $level;
// has_children уже записан в $all_items выше
// Блокируем ребенка, если скрыт его родитель или кто-то выше по дереву
$item['parent_locked'] = ($is_parent_hidden || $all_items[$parent_id]['comment_status'] == '0') ? 1 : 0;
$docs[] = $item;
$processed[] = $child_id;
$buildTree($child_id, $level + 1);
$buildTree($child_id, $level + 1, $item['parent_locked']);
}
}
}
};
// Собираем дерево, начиная с корней
foreach ($all_items as $id => $item) {
if ($item['parent_id'] == 0 && !in_array($id, $processed)) {
$item['depth_level'] = 0;
$item['parent_locked'] = 0;
$docs[] = $item;
$processed[] = $id;
$buildTree($id, 1);
}
}
$docs = [];
$processed = [];
$buildTree = function($parent_id, $level) use (&$buildTree, &$docs, &$processed, &$all_items, &$child_map) {
if (isset($child_map[$parent_id])) {
foreach ($child_map[$parent_id] as $child_id) {
if (!in_array($child_id, $processed)) {
$item = $all_items[$child_id];
$item['depth_level'] = $level;
$docs[] = $item;
$processed[] = $child_id;
$buildTree($child_id, $level + 1);
}
}
}
};
foreach ($all_items as $id => $item) {
if ($item['parent_id'] == 0 && !in_array($id, $processed)) {
$item['depth_level'] = 0;
$docs[] = $item;
$processed[] = $id;
$buildTree($id, 1);
$buildTree($id, 1, false);
}
}
// Добираем то, что не попало в иерархию (битые связи)
foreach ($all_items as $id => $item) {
if (!in_array($id, $processed)) {
$item['depth_level'] = 0;
$item['parent_locked'] = 0;
$docs[] = $item;
}
}
// --- КОНЕЦ ПОСТРОЕНИЯ ДЕРЕВА ---
$comment_rating_type = $AVE_DB->Query("

View File

@@ -177,7 +177,10 @@ if ($fileInput.length && $fileInput[0].files.length > 0) {
return isValid;
}
/* --- ДЕЙСТВИЯ (DELETE, LOCK, OPEN/CLOSE, VOTE) --- */
/* --- ДЕЙСТВИЯ (DELETE, LOCK, OPEN/CLOSE, VOTE) --- */
function cAction(obj, action) {
var $btn = $(obj);
var cid = $btn.data('id');
@@ -186,75 +189,86 @@ function cAction(obj, action) {
$.get(aveabspath + 'index.php', {
module: 'comment',
action: action,
action: action, // Это для роутинга (какой метод вызвать)
comment_status: action, // что именно сделать: lock или unlock
docid: typeof DOC_ID !== 'undefined' ? DOC_ID : '',
Id: cid ? cid : ''
}, function(data) { // Добавляем аргумент data для получения ответа от PHP
}, function(data) {
if (action === 'close') {
$btn.attr('id', 'mod_comment_open')
.removeClass('btn-outline-danger').addClass('btn-outline-success')
.html('<i class="bi bi-lock-fill me-1"></i> ' + COMMENT_SITE_OPEN);
$('#mod_comment_new').fadeOut(300);
}
else if (action === 'open') {
$btn.attr('id', 'mod_comment_close')
.removeClass('btn-outline-success').addClass('btn-outline-danger')
.html('<i class="bi bi-unlock-fill me-1"></i> ' + COMMENT_SITE_CLOSE);
$('#mod_comment_new').fadeIn(300);
if (action === 'close' || action === 'open') {
location.reload(); // Для глобального закрытия проще обновить
return;
}
// --- ОБНОВЛЕННЫЙ БЛОК УДАЛЕНИЯ ---
if (action === 'delete') {
var response = data ? data.trim() : '';
var $commentBlock = $btn.closest('.mod_comment_comment'); // Вся ветка (включая детей)
var $commentBox = $btn.closest('.mod_comment_box'); // Только текущая карточка
var $commentBlock = $btn.closest('.mod_comment_comment');
if (response === 'OK_SOFT') {
// обновляем страницу
location.reload();
} else {
// удаляем совсем комментарий
$commentBlock.fadeOut(300, function() { $(this).remove(); });
}
}
// показать / скрыть комментарий
if (action === 'unlock' || action === 'lock') {
var $icon = $btn.find('i');
var $commentBox = $btn.closest('.mod_comment_box');
var $card = $btn.closest('.mod_comment_comment');
if (action === 'lock') {
$icon.attr('class', 'bi bi-eye-slash');
$btn.removeClass('text-success text-muted').addClass('text-danger').attr('title', COMMENT_ICON_SHOW);
$commentBox.addClass('opacity-75 border border-warning rounded');
// --- БЛОК LOCK / UNLOCK ---
if (action === 'unlock' || action === 'lock') {
var $mainWrapper = $btn.closest('.mod_comment_comment');
var $currentBox = $btn.closest('.mod_comment_box');
var $alert = $commentBox.find('.alert-warning');
if ($alert.length === 0) {
var alertHtml = '<div class="alert alert-warning py-1 px-2 mb-2 small d-flex align-items-center border-0 shadow-sm" style="border-left: 4px solid #ffc107 !important; display:none;">' +
'<i class="bi bi-clock-history me-2 text-dark"></i>' +
'<span class="text-dark">' + COMMENT_WAITING_MODERATION + '</span>' +
'</div>';
$commentBox.find('.flex-grow-1').first().prepend(alertHtml);
$alert = $commentBox.find('.alert-warning');
}
$alert.stop(true, true).fadeIn(300);
} else {
$icon.attr('class', 'bi bi-eye');
$btn.removeClass('text-danger text-muted').addClass('text-success').attr('title', COMMENT_ICON_HIDE);
var classesToRemove = 'opacity-75 border border-warning rounded';
$commentBox.removeClass(classesToRemove);
$card.removeClass(classesToRemove + ' border-warning');
$commentBox.find('.alert-warning').first().stop(true, true).fadeOut(300, function() {
$(this).remove();
});
if (action === 'lock') {
// --- СКРЫТИЕ (lock) ---
// 1. МЕНЯЕМ ПОДСКАЗКУ НА "ПОКАЗАТЬ"
$btn.attr('title', 'Показать комментарий');
$mainWrapper.find('.mod_comment_box').each(function() {
var $box = $(this);
var $tgl = $box.find('.mod_comment_toggle');
$box.addClass('opacity-75 border border-warning rounded');
$tgl.removeClass('text-success text-muted').addClass('text-danger');
$tgl.find('i').attr('class', 'bi bi-eye-slash');
if ($box.find('.alert-warning').length === 0) {
var alertHtml = '<div class="alert alert-warning py-1 px-2 mb-2 small d-flex align-items-center border-0 shadow-sm">' +
'<i class="bi bi-clock-history me-2 text-dark"></i><span class="text-dark">На модерации</span></div>';
$box.find('.flex-grow-1').first().prepend(alertHtml);
}
});
$mainWrapper.find('.mod_comment_comment .mod_comment_toggle').fadeOut(200);
} else {
// --- РАЗБЛОКИРОВКА (unlock) ---
if (data.trim() === 'ERROR_PARENT_LOCKED') {
alert('Нельзя включить ответ, если родитель скрыт!');
return;
}
// 1. МЕНЯЕМ ПОДСКАЗКУ НА "СКРЫТЬ"
$btn.attr('title', 'Скрыть комментарий');
$btn.find('i').attr('class', 'bi bi-eye');
$btn.removeClass('text-danger text-muted').addClass('text-success');
$currentBox.removeClass('opacity-75 border border-warning rounded');
$currentBox.find('.alert-warning').first().remove();
// 2. ПОКАЗЫВАЕМ ГЛАЗА У ДЕТЕЙ
$mainWrapper.find('.mod_comment_comment').each(function() {
var $child = $(this);
if ($child.data('parent') == cid) {
$child.find('> .mod_comment_box .mod_comment_toggle').fadeIn(300);
}
});
}
}
});
}
/* --- ИНИЦИАЛИЗАЦИЯ --- */
$(document).ready(function() {
initCommentTimers();

View File

@@ -119,7 +119,7 @@ COMMENT_JS_LOADS_F = "Загрузка:"
COMMENT_JS_LOADS_R = "Отправка..."
COMMENT_JS_SEC_CODE_WRONG = "Код капчи введен неверно!"
COMMENT_JS_ERR_SRV = "Ошибка связи с сервером"
COMMENT_WAITING_MODERATION = "Ваш комментарий на проверке и виден пока только вам."
COMMENT_WAITING_MODERATION = "На модерации"
COMMENT_LAST_TITEL = "Последние комментарии"
COMMENT_HIDDEN_BY_MODERATOR = "Комментарий скрыт модератором и находится на проверке."
COMMENT_TEXT_DEL_BY_ADMIN = "Комментарий удален администратором."

View File

@@ -306,31 +306,39 @@
</div>
</td>
<td align="right">
<div style="display: flex; justify-content: flex-end; gap: 6px;">
{if !$is_deleted}
{if $row.comment_status == '1'}
<a class="icon_sprite ico_unlock_no" title="{#COMMENT_ICON_HIDE_ADM#}" href="index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=set_status_0&id={$row.CId}&cp={$sess}"></a>
{else}
<a class="icon_sprite ico_unlock" title="{#COMMENT_ICON_SHOW_ADM#}" href="index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=set_status_1&id={$row.CId}&cp={$sess}"></a>
{/if}
<a data-dialog="edit-comment-{$row.CId}"
href="index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_edit&Id={$row.CId}&cp={$sess}&pop=1&onlycontent=1"
data-width="1180"
data-height="700"
data-modal="true"
data-title="{#COMMENT_ICON_EDIT_ADM#}"
class="openDialog icon_sprite ico_edit"
title="{#COMMENT_ICON_EDIT_ADM#}"></a>
{if $row.has_children}
<a class="icon_sprite ico_delete ConfirmDelete" title="{#COMMENT_ICON_DEL_SOFT#}" dir="{#COMMENT_CONFIRM_ADM_DIR_SOFT#}" name="{#COMMENT_CONFIRM_ADM_NAME_SOFT#}"
href="index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_del&admin_action_type=soft&Id={$row.CId}&cp={$sess}"></a>
{/if}
{/if}
<a class="icon_sprite ico_delete ico_delete_all ConfirmDelete" title="{#COMMENT_ICON_DEL_HARD#}" dir="{#COMMENT_CONFIRM_ADM_DIR#}" name="{#COMMENT_CONFIRM_ADM_NAME#}"
href="index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_del&admin_action_type=full&Id={$row.CId}&cp={$sess}"></a>
</div>
</td>
<td align="right">
<div style="display: flex; justify-content: flex-end; gap: 6px;">
{* --- ИКОНКИ СТАТУСА (ЗАМОЧКИ)*}
{if $row.parent_locked}
{* Если родитель скрыт, показываем серый замок *}
<span class="icon_sprite ico_lock_no" style="opacity: 0.5; filter: grayscale(1); cursor: help;" title="Сначала опубликуйте родителя (ID: {$row.parent_id})"></span>
{else}
{* Обычные кнопки, если родитель активен *}
{if $row.comment_status == '1'}
<a class="icon_sprite ico_unlock_no" title="{#COMMENT_ICON_HIDE_ADM#}" href="index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=set_status_0&id={$row.CId}&cp={$sess}"></a>
{else}
<a class="icon_sprite ico_unlock" title="{#COMMENT_ICON_SHOW_ADM#}" href="index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=set_status_1&id={$row.CId}&cp={$sess}"></a>
{/if}
{/if}
{* --- ОСТАЛЬНЫЕ КНОПКИ ОСТАЮТСЯ ВНУТРИ ПРОВЕРКИ --- *}
{if !$is_deleted}
<a data-dialog="edit-comment-{$row.CId}"
href="index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_edit&Id={$row.CId}&cp={$sess}&pop=1&onlycontent=1"
data-width="1180" data-height="700" data-modal="true" data-title="{#COMMENT_ICON_EDIT_ADM#}"
class="openDialog icon_sprite ico_edit" title="{#COMMENT_ICON_EDIT_ADM#}"></a>
{if $row.has_children}
<a class="icon_sprite ico_delete ConfirmDelete" title="{#COMMENT_ICON_DEL_SOFT#}" dir="{#COMMENT_CONFIRM_ADM_DIR_SOFT#}" name="{#COMMENT_CONFIRM_ADM_NAME_SOFT#}"
href="index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_del&admin_action_type=soft&Id={$row.CId}&cp={$sess}"></a>
{/if}
{/if}
{* Полное удаление всегда снаружи *}
<a class="icon_sprite ico_delete ico_delete_all ConfirmDelete" title="{#COMMENT_ICON_DEL_HARD#}" dir="{#COMMENT_CONFIRM_ADM_DIR#}" name="{#COMMENT_CONFIRM_ADM_NAME#}"
href="index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_del&admin_action_type=full&Id={$row.CId}&cp={$sess}"></a>
</div>
</td>
</tr>
{/foreach}
{else}

View File

@@ -1,10 +1,15 @@
{foreach from=$subcomments item=c name=sub_loop}
{foreach from=$subcomments item=c name=sub_loop}
{* ОПРЕДЕЛЯЕМ СТАТУС УДАЛЕНИЯ *}
{assign var="is_deleted" value=false}
{if $c.comment_author_name == '__DELETED__' || $c.comment_author_name == 'Удалено'}
{assign var="is_deleted" value=true}
{/if}
{assign var="parent_hidden" value=false}
{if isset($parent_status) && $parent_status == 0}
{assign var="parent_hidden" value=true}
{/if}
<div class="card mb-3 mod_comment_comment {if $c.parent_id} ms-2 ms-md-4{/if} {if $is_deleted}opacity-75 bg-light{/if}"
id="comment_wrapper_{$c.Id}"
data-parent="{$c.parent_id|default:0}"
@@ -232,14 +237,16 @@
{/if}
</span>
{if $smarty.const.UGROUP==1}
<a class="btn btn-sm btn-link {if $c.comment_status==1}text-success{else}text-danger{/if} mod_comment_toggle px-2"
href="javascript:void(0);"
data-id="{$c.Id}"
title="{if $c.comment_status==1}{#COMMENT_ICON_HIDE#}{else}{#COMMENT_ICON_SHOW#}{/if}">
<i class="bi bi-{if $c.comment_status==1}eye{else}eye-slash{/if}"></i>
</a>
{/if}
{if $smarty.const.UGROUP==1}
{* Если родитель НЕ скрыт — показываем кнопку управления ребенком *}
<a class="btn btn-sm btn-link {if $c.comment_status==1}text-success{else}text-danger{/if} mod_comment_toggle px-2"
href="javascript:void(0);"
data-id="{$c.Id}"
{if $parent_hidden}style="display: none;"{/if}
title="{if $c.comment_status==1}{#COMMENT_ICON_HIDE#}{else}{#COMMENT_ICON_SHOW#}{/if}">
<i class="bi bi-{if $c.comment_status==1}eye{else}eye-slash{/if}"></i>
</a>
{/if}
{/if}
</div>
</div>
@@ -253,7 +260,7 @@
{if isset($comments) && isset($comments[$c.Id])}
<div class="mt-2">
{include file="$subtpl" subcomments=$comments[$c.Id] sub=1 parentId=$c.Id}
{include file="$subtpl" subcomments=$comments[$c.Id] sub=1 parentId=$c.Id parent_status=$c.comment_status}
</div>
{/if}