From 491b27349bd6148492aadd2c50a8b7a570b90461 Mon Sep 17 00:00:00 2001 From: Repellent Date: Sat, 17 Jan 2026 18:32:02 +0500 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=B2=D0=BE=D0=B4=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D0=B8=D0=B5=D0=B2=20=D0=B2=20=D0=B0=D0=B4?= =?UTF-8?q?=D0=BC=D0=B8=D0=BD=D0=BA=D0=B5=20,=20=D0=BC=D0=B0=D1=81=D1=81?= =?UTF-8?q?=D0=BE=D0=B2=D0=BE=D0=B5=20=D0=B8=20=D0=BE=D0=B1=D1=8B=D1=87?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +- class/comment.php | 89 +++++--- lang/ru.txt | 5 +- module.php | 9 +- templates/admin_comments.tpl | 418 ++++++++++++++++++++++------------- 5 files changed, 345 insertions(+), 184 deletions(-) diff --git a/README.md b/README.md index 26706b6..5d295c9 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,13 @@ * Два дополнительных поля, их названия и обязательные или нет, настраивааются в Админпанели * Валидация обязательных полей на заполненность + проверка на разрешения для файлов * Комментарий - родитель (ветка комментариев) - * Если на комментарий Автора другие Пользователи сделали ответ, то удалить такой комментарий Автору будет невозможно, за исключением Администратора, вместо этого текст комментария будет заменен на текст Комментарий удален автором. + * Если на комментарий Автора другие Пользователи сделали ответ, то удалить такой комментарий Автору или Администратору в публичной части сайта будет невозможно, вместо этого будет произведено мягкое удаление - удалится все , что относится к данному комментарию (Рейтинги, файлы , текст) и вместо этого будет выводится специальный аватар и текст: Комментарий удален автором либо Комментарий удален администратором. Восстановить данные такого комментария невозможно. +* Удаление комментариев в Админке + * Одиночные комментарии (не имеющие ответов) удаляются сразу и навсегда. + * Комментарии родители (имеющие ответы/ветку ответов) получают два варианта одиночного удаления: + * Мягкое удаление (удалится все , что относится к данному комментарию (Рейтинги, файлы , текст) и вместо этого будет выводится специальный аватар и текст: Комментарий удален администратором. Восстановить данные такого комментария невозможно, + * Жесткое удаление самого комментария и всей ветки ответов на этот комментарий. Администратор выбирает сам какой вариант ему необходим. + * Массовое удаление - одиночные комментарии удаляются сразу, комментарии-родители удаляются Мягким вариантом (с подстановкой текста Комментарий удален Администратором). * Контроль Имен Анонима * Если Анонимный пользователь, в течении жизни куки, сменит имя под которым он опубликовал свой первый комментарий, рядом с именем появится плашка с тултипом в котором будут перечислены все его имена. * Пагинация diff --git a/class/comment.php b/class/comment.php index 9d7aba8..347787a 100644 --- a/class/comment.php +++ b/class/comment.php @@ -1222,33 +1222,68 @@ function commentPostDelete($comment_id) } } - function commentAdminDelete($comment_id) - { - global $AVE_DB; +function commentAdminDelete($comment_id) +{ + global $AVE_DB; + + // 1. Собираем ID в массив (поддерживаем и одиночное, и массовое удаление) + if (is_array($comment_id)) { + $ids = array_map('intval', $comment_id); + } else { + $ids = [(int)$comment_id]; + } + + if (empty($ids)) return; - $comment_id = (int)$comment_id; // Убедимся, что это целое число + // Читаем тип удаления из запроса (для одиночных кликов по иконкам) + // Для массового удаления через кнопку "Применить" этот параметр обычно не передается + $delete_type = $_REQUEST['admin_action_type'] ?? 'auto'; - // Выполняем запрос к БД на удаление родительского комментария - $AVE_DB->Query(" - DELETE - FROM " . PREFIX . "_module_comment_info - WHERE Id = '" . $comment_id . "' - "); + foreach ($ids as $id) { + if ($id <= 0) continue; - // Выполняем запрос к БД на удаление дочерних комментариев (ответов) - $AVE_DB->Query(" - DELETE - FROM " . PREFIX . "_module_comment_info - WHERE parent_id = '" . $comment_id . "' - AND parent_id != 0 - "); - - // Используем оператор объединения с null для PHP 8.4 - $session_id = SESSION ?? ''; - - header('Location:index.php?do=modules&action=modedit&mod=comment&moduleaction=1&cp=' . $session_id); - exit; - } + // Проверяем наличие детей + $has_children = $AVE_DB->Query("SELECT COUNT(*) FROM " . PREFIX . "_module_comment_info WHERE parent_id = '$id'")->GetCell(); + + // ЛОГИКА СОГЛАСНО ДОГОВОРУ: + // Если тип 'soft' ИЛИ (тип 'auto' и есть дети) — делаем мягкое удаление + if (($delete_type == 'soft') || ($delete_type == 'auto' && $has_children > 0)) { + $AVE_DB->Query(" + UPDATE " . PREFIX . "_module_comment_info + SET comment_text = '__DEL_BY_ADM__', + comment_author_name = '__DELETED__', + comment_author_id = '0', + comment_file = '', + comment_status = '1', + comment_changed = '" . time() . "' + WHERE Id = '$id' + "); + } + // Если детей нет или принудительно выбран 'full' — удаляем физически + else { + // Собираем дерево (на случай если это Full Delete для родителя) + $all_tree_ids = [$id]; + $parents = [$id]; + while (!empty($parents)) { + $p_str = implode(',', $parents); + $res = $AVE_DB->Query("SELECT Id FROM " . PREFIX . "_module_comment_info WHERE parent_id IN ($p_str)"); + $parents = []; + if ($res) { + while ($r = $res->FetchAssocArray()) { + $all_tree_ids[] = (int)$r['Id']; + $parents[] = (int)$r['Id']; + } + } + } + $final_ids_str = implode(',', array_unique($all_tree_ids)); + $AVE_DB->Query("DELETE FROM " . PREFIX . "_module_comment_info WHERE Id IN ($final_ids_str)"); + } + } + + $session_id = SESSION ?? ''; + header("Location: index.php?do=modules&action=modedit&mod=comment&moduleaction=1&cp=" . $session_id); + exit; +} /** * Метод, предназначенный для вывода детальной информации об авторе комментария @@ -1396,9 +1431,9 @@ function commentAdminListShow($tpl_dir) case 'set_status_0': $AVE_DB->Query("UPDATE " . PREFIX . "_module_comment_info SET comment_status = '0' WHERE Id IN ($final_id_list)"); break; - case 'delete': - $AVE_DB->Query("DELETE FROM " . PREFIX . "_module_comment_info WHERE Id IN ($final_id_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; diff --git a/lang/ru.txt b/lang/ru.txt index ceeaaee..b4e44bf 100644 --- a/lang/ru.txt +++ b/lang/ru.txt @@ -215,4 +215,7 @@ COMMENT_SET_MAIN_TAG = "Основной тег (выводит форму COMMENT_SET_ADDIT_TAG = "Доп. тег (выводит X последних комментариев):" COMMENT_SET_ADDIT_TAG_NUM = "(X - число выводимых комментариев)" COMMENT_SET_COPY = "Скопировать в буфер обмена" -COMMENT_SET_GEN = "Общие настройки" \ No newline at end of file +COMMENT_SET_GEN = "Общие настройки" +COMMENT_TEXT_DEL_BY_ADMIN = "Комментарий удален администратором." +COMMENT_TEXT_DEL_BY_AUTHOR = "Комментарий удален автором." +COMMENT_STATUS_DELETED = "Удалено" diff --git a/module.php b/module.php index 25c582c..349ee53 100644 --- a/module.php +++ b/module.php @@ -171,10 +171,11 @@ if (defined('ACP') && !empty($_REQUEST['moduleaction'])) $comment->commentAdminSettingsEdit($tpl_dir); break; - case 'admin_del': - $comment->commentAdminDelete((int)$_REQUEST['Id']); - break; - } + case 'admin_del': + $comment_id = $_REQUEST['id'] ?? $_REQUEST['Id']; + $comment->commentAdminDelete($comment_id); + break; + } } ?> \ No newline at end of file diff --git a/templates/admin_comments.tpl b/templates/admin_comments.tpl index 2f2548d..f6fda65 100644 --- a/templates/admin_comments.tpl +++ b/templates/admin_comments.tpl @@ -1,32 +1,18 @@
{#COMMENT_MODULE_NAME#} (Всего: {$docs|count})
@@ -81,125 +143,157 @@ - - - - + + + + + + + + + {if $docs} {foreach from=$docs item=row name=zebraloop} - + {assign var="is_deleted" value=false} + {if $row.comment_author_name == '__DELETED__' || $row.comment_author_name == 'Удалено'}{assign var="is_deleted" value=true}{/if} + + + + - + + - -
{$row.comment_text|nl2br}
+ - {if $row.images || $row.files} -
- {foreach from=$row.images item=img} -
-
- - - -
- {$img.clean_name|truncate:15:"...":true} -
- {/foreach} - {foreach from=$row.files item=f} -
- - {$f.ext|upper} - - {$f.clean_name|truncate:15:"...":true} -
- {/foreach} -
+ {/foreach} {else} - - - + + + {/if}
IDДанные АвтораТекст комментария и файлыIDСтатусАвтор и РейтингIP адресДата Создания / РедактированияТекст комментарияФайлыДействия
{$row.CId} + {if $row.comment_status == '1'} + + {else} + + {/if} + -
-
-
- {if $row.avatar}{else} -
{$row.first_letter}
{/if} -
- {$row.comment_author_name|escape} -
-
-
- {section name=s start=1 loop=6}{if $smarty.section.s.index <= $row.user_rating}★{else}{/if}{/section} -
-
📅 {$row.date_pub}
- {if $row.date_edit}
📝 ред. {$row.date_edit}
{/if} -
🌐 {$row.comment_author_ip}
-
+
+
+
+ {if $is_deleted} +
?
+ {else} + {if $row.avatar}{else} +
{$row.first_letter}
{/if} + {/if} +
+
+ + {if $is_deleted}Пользователь удален{else}{$row.comment_author_name|escape}{/if} + + {if !$is_deleted} + + {section name=s start=1 loop=6}{if $smarty.section.s.index <= $row.user_rating}★{else}{/if}{/section} + + {/if} +
+
+
+
{$row.comment_author_ip}
+
+
+
{$row.date_pub}
+ {if $row.date_edit} +
ред. {$row.date_edit}
+ {/if}
-
-
- {if $row.parent_id > 0} - ОТВЕТ НА #{$row.parent_id} - {/if} - - {$row.document_title|default:"Документ"|truncate:35} - - [#] Посмотреть - -
- - {if $row.comment_status=='1'}Одобрен{else}Скрыт{/if} - - - {if $row.comment_status == '1'} - +
+
+ +
+ {if $row.parent_id > 0} + Ответ на комментарий #{$row.parent_id} » + {/if} +
+ {if $row.comment_text == '__DEL_BY_ADM__'} +
+ 🚫 Комментарий удален администратором +
+ {elseif $row.comment_text == '__DEL_BY_AUT__'} +
+ 🗑️ Автор удалил свой комментарий +
{else} - - {/if} - - - - - - {if $row.has_children} - + {$row.comment_text|strip_tags|truncate:130} {/if}
-
+
+ +
+
+ {if $row.images} + {foreach from=$row.images item=img name=img_loop} + {if $smarty.foreach.img_loop.iteration < 5} {* Показываем максимум 4 превью в стопке *} + + + + {/if} + {/foreach} + {if $row.images|count >= 5} + +{$row.images|count - 4} + {/if} + {/if} + + {if $row.files} + {foreach from=$row.files item=f} + + {$f.ext|upper} + + {/foreach} + {/if} +
+
+
+ {if !$is_deleted} + {if $row.comment_status == '1'} + + {else} + + {/if} + + {if $row.has_children} + + {/if} {/if} - -
-
- {section name=s start=1 loop=6}{if $smarty.section.s.index <= $row.star_public}★{else}{/if}{/section} -
- (Голосов: {$row.r_count|default:0}) -
+
-
    -
  • Сообщение:
    Нет комментариев.
  • -
-
+
    +
  • Сообщение:
    Нет комментариев.
  • +
+
- @@ -211,11 +305,7 @@
{if $page_nav} - + {/if} \ No newline at end of file