сделан вывод комментариев в админке , массовое и обычное удаление

This commit is contained in:
2026-01-17 18:32:02 +05:00
parent a1ef4c2358
commit 491b27349b
5 changed files with 345 additions and 184 deletions

View File

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

View File

@@ -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;

View File

@@ -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 = "Общие настройки"
COMMENT_SET_GEN = "Общие настройки"
COMMENT_TEXT_DEL_BY_ADMIN = "Комментарий удален администратором."
COMMENT_TEXT_DEL_BY_AUTHOR = "Комментарий удален автором."
COMMENT_STATUS_DELETED = "Удалено"

View File

@@ -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;
}
}
?>

View File

@@ -1,32 +1,18 @@
<style>
/* Глобальный шрифт 13px */
/* Глобальные шрифты */
.tableStatic, .tableStatic tbody td, .author-data-container,
.meta-sub-text, .comment-scroll-box, .cell-top-bar a,
.cell-top-bar span, .asset-name, #mass_action_select{
.cell-top-bar span, .asset-name, #mass_action_select {
font-size: 13px !important;
}
.blueBtn {
font-size: 11px !important;
padding: 2px 10px !important; /* Уменьшаем вертикальный отступ */
height: 28px !important; /* Фиксируем высоту, чтобы она не прыгала */
line-height: 24px !important; /* Центрируем текст по вертикали */
cursor: pointer;
}
/* Верстка таблицы */
.tableStatic tbody td { vertical-align: top !important; padding: 8px 10px !important; }
/* КОЛОНКА АВТОРА */
.author-column { width: 240px !important; min-width: 240px; position: relative; }
.author-data-container { display: flex; flex-direction: column; gap: 8px; }
.author-info-row { display: flex; align-items: center; gap: 12px; }
/* Компактная строка */
.tableStatic tbody td { vertical-align: middle !important; padding: 4px 10px !important; }
/* АВАТАР */
.admin-avatar-box { width: 45px; height: 45px; flex-shrink: 0; }
.admin-avatar-box img { width: 45px; height: 45px; border-radius: 50%; object-fit: cover; border: 1px solid #ddd; }
.mod_comment_avatar_letter { width: 45px; height: 45px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; color: #fff; text-transform: uppercase; font-size: 18px !important; }
.admin-avatar-box { width: 34px; height: 34px; flex-shrink: 0; }
.admin-avatar-box img { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; border: 1px solid #ddd; }
.mod_comment_avatar_letter { width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; color: #fff; text-transform: uppercase; font-size: 14px !important; }
/* Цвета для букв аватара */
.av-c1 { background-color: #6c5ce7; } .av-c2 { background-color: #2ecc71; }
@@ -35,39 +21,115 @@
.av-c7 { background-color: #d63031; } .av-c8 { background-color: #636e72; }
.av-c9 { background-color: #fdcb6e; } .av-c10 { background-color: #fd79a8; }
/* ЗВЕЗДЫ РЕЙТИНГА АВТОРА (Screenshot_13) */
.author-stars { color: #ff9800; font-size: 16px; letter-spacing: 0px; margin: 2px 0; line-height: 1; }
/* ЗВЕЗДЫ РЕЙТИНГА АВТОРА (справа от имени) */
.author-stars { color: #ff9800; font-size: 14px; letter-spacing: 0px; display: inline-block; margin-left: 8px; }
.star-grey { color: #ccc !important; }
/* Мета-данные */
.meta-sub-text { color: #666; line-height: 1.6; }
.meta-ip { color: #999; }
.meta-edit { color: #d35400; font-weight: bold; background: #fff5e6; padding: 0 4px; border-radius: 3px; display: inline-block; }
/* Контент комментария */
.comment-scroll-box { max-height: 200px; overflow-y: auto; line-height: 1.6; color: #333; margin: 10px 0; padding-right: 10px; }
/* Зебра и Hover */
.row-odd { background-color: #ffffff !important; }
.row-even { background-color: #f1f6fa !important; }
.status-badge { font-size: 10px; padding: 1px 4px; border-radius: 3px; font-weight: bold; text-transform: uppercase; border: 1px solid; }
.bg-del-adm { background: #ffebee; color: #c62828; border-color: #ffcdd2; }
.bg-del-aut { background: #f5f5f5; color: #757575; border-color: #e0e0e0; font-style: italic; }
.row-hidden { background-color: #fff4f4 !important; }
.tableStatic tbody tr:hover td { background-color: #edf3f7 !important; transition: background 0.1s ease; }
/* Линия вложенности (Screenshot_14) */
.reply-wrapper { border-left: 3px solid #3498db; padding-left: 15px; position: relative; }
/* Контейнер для веера */
.files-bundle {
display: flex;
align-items: center;
justify-content: center;
height: 34px;
}
/* Панели */
.cell-top-bar { display: flex; align-items: center; gap: 12px; border-bottom: 1px dashed #ddd; padding-bottom: 8px; }
.cell-top-bar > div:last-child { margin-left: auto !important; }
.public-rating-row { display: flex; align-items: center; gap: 8px; margin-top: 10px; border-top: 1px solid #f0f0f0; padding-top: 8px; }
.star-public { color: #FFD700; font-size: 14px; }
/* Базовый стиль для миниатюр в стопке */
.thumb-stack {
width: 28px;
height: 28px;
border: 2px solid #fff;
border-radius: 4px;
object-fit: cover;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
margin-left: -15px; /* Наложение картинок друг на друга */
transition: all 0.2s ease;
cursor: pointer;
position: relative;
}
/* Первая картинка в стопке без отступа */
.thumb-stack:first-child { margin-left: 0; }
/* Эффект при наведении на конкретную картинку */
.thumb-stack:hover {
transform: scale(4.5);
z-index: 999;
margin: 0 40px; /* Раздвигаем соседей, чтобы не перекрывали зум */
box-shadow: 0 5px 15px rgba(0,0,0,0.5);
}
/* Иконка файла в стиле стопки */
.file-stack {
width: 28px; height: 28px; background: #f8f9fa;
display: flex; align-items: center; justify-content: center;
font-size: 8px; font-weight: bold; border: 2px solid #fff;
border-radius: 4px; color: #555; box-shadow: 0 1px 3px rgba(0,0,0,0.2);
margin-left: -15px; transition: all 0.2s ease;
}
.file-stack:hover { transform: scale(1.5); z-index: 100; }
/* Стиль индикатора статуса */
/* Базовый стиль кружка */
.status-dot {
width: 10px;
height: 10px;
border-radius: 50%;
display: inline-block;
}
/* Зеленый - просто светится */
.dot-active {
background-color: #2ecc71;
box-shadow: 0 0 6px #2ecc71;
}
/* Красный - ПУЛЬСИРУЕТ */
.dot-hidden {
background-color: #e74c3c;
animation: pulse-red 1.5s infinite;
}
/* Эффект пульсации */
@keyframes pulse-red {
0% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(231, 76, 60, 0.7);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 10px rgba(231, 76, 60, 0);
}
100% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(231, 76, 60, 0);
}
}
/* Стиль для аватара удаленного пользователя */
.avatar-deleted {
background-color: #bdc3c7 !important; /* Серый цвет */
color: #fff !important;
font-size: 18px !important;
}
/* Плашки для текста удаленных комментариев */
.comment-deleted-info {
display: inline-flex;
align-items: center;
padding: 4px 10px;
border-radius: 4px;
font-size: 12px;
font-weight: 500;
gap: 6px;
}
.del-adm { background: #fff5f5; color: #c0392b; border: 1px solid #fadbd8; }
.del-aut { background: #f8f9fa; color: #7f8c8d; border: 1px solid #e5e8e8; font-style: italic; }
/* Файлы */
.comment-assets-inline { display: flex; flex-wrap: wrap; gap: 15px; margin: 12px 0; }
.asset-item { width: 90px; text-align: center; }
.asset-thumb { width: 90px; height: 70px; border: 1px solid #ccc; border-radius: 5px; background: #fff; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.asset-thumb img { width: 100%; height: 100%; object-fit: cover; }
.asset-name { display: block; width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center; font-size: 12px !important; color: #555; margin-top: 4px; }
</style>
<div class="title"><h5>{#COMMENT_MODULE_NAME#} (Всего: {$docs|count})</h5></div>
@@ -81,125 +143,157 @@
<table cellpadding="0" cellspacing="0" width="100%" class="tableStatic">
<thead>
<tr>
<td width="40"><input type="checkbox" id="selectAll" onclick="checkAll(this)" /></td>
<td width="50">ID</td>
<td class="author-column">Данные Автора</td>
<td>Текст комментария и файлы</td>
<td width="30"><input type="checkbox" id="selectAll" onclick="checkAll(this)" /></td>
<td width="40">ID</td>
<td width="30">Статус</td>
<td width="220">Автор и Рейтинг</td>
<td width="110">IP адрес</td>
<td width="130">Дата Создания / Редактирования</td>
<td>Текст комментария</td>
<td width="100">Файлы</td>
<td width="140" align="right">Действия</td>
</tr>
</thead>
<tbody>
{if $docs}
{foreach from=$docs item=row name=zebraloop}
<tr class="{if $row.comment_status == '0'}row-hidden{elseif $smarty.foreach.zebraloop.iteration % 2 == 0}row-even{else}row-odd{/if}">
{assign var="is_deleted" value=false}
{if $row.comment_author_name == '__DELETED__' || $row.comment_author_name == 'Удалено'}{assign var="is_deleted" value=true}{/if}
<tr class="{if $row.comment_status == '0'}row-hidden deleted-row{elseif $smarty.foreach.zebraloop.iteration % 2 == 0}row-even{else}row-odd{/if}">
<td align="center"><input class="row-checkbox" type="checkbox" value="{$row.CId}" /></td>
<td align="center"><strong>{$row.CId}</strong></td>
<td align="center">
{if $row.comment_status == '1'}
<span class="status-dot dot-active" title="Активен"></span>
{else}
<span class="status-dot dot-hidden" title="Скрыт"></span>
{/if}
</td>
<td class="author-column">
<div class="author-data-container" style="margin-left: {$row.depth_level * 25}px;">
<div class="author-info-row">
<div class="admin-avatar-box">
{if $row.avatar}<img src="{$row.avatar}">{else}
<div class="mod_comment_avatar_letter av-c{$row.avatar_color_index}">{$row.first_letter}</div>{/if}
</div>
<span style="font-weight:bold; color:#2c3e50;">{$row.comment_author_name|escape}</span>
</div>
<div class="meta-sub-text">
<div class="author-stars">
{section name=s start=1 loop=6}{if $smarty.section.s.index <= $row.user_rating}{else}<span class="star-grey">★</span>{/if}{/section}
</div>
<div>📅 {$row.date_pub}</div>
{if $row.date_edit}<div class="meta-edit">📝 ред. {$row.date_edit}</div>{/if}
<div class="meta-ip">🌐 {$row.comment_author_ip}</div>
</div>
<td>
<div style="display: flex; align-items: center; gap: 10px;">
<div class="admin-avatar-box">
{if $is_deleted}
<div class="mod_comment_avatar_letter avatar-deleted">?</div>
{else}
{if $row.avatar}<img src="{$row.avatar}">{else}
<div class="mod_comment_avatar_letter av-c{$row.avatar_color_index}">{$row.first_letter}</div>{/if}
{/if}
</div>
<div style="white-space: nowrap;">
<span style="font-weight:bold; color:{if $is_deleted}#95a5a6{else}#2c3e50{/if};">
{if $is_deleted}Пользователь удален{else}{$row.comment_author_name|escape}{/if}
</span>
{if !$is_deleted}
<span class="author-stars">
{section name=s start=1 loop=6}{if $smarty.section.s.index <= $row.user_rating}{else}<span class="star-grey">★</span>{/if}{/section}
</span>
{/if}
</div>
</div>
</td>
<td align="center" style="color:#666; font-family:monospace;">
<div style="color:#999; font-size:11px; line-height:1.2; font-family:monospace;">{$row.comment_author_ip}</div>
</td>
<td>
<div style="font-size:11px; line-height:1.2;">
<div>{$row.date_pub}</div>
{if $row.date_edit}
<div style="color:#d35400;">ред. {$row.date_edit}</div>
{/if}
</div>
</td>
<td>
<div class="{if $row.depth_level > 0}reply-wrapper{/if}" style="margin-left: {$row.depth_level * 25}px;">
<div class="cell-top-bar">
{if $row.parent_id > 0}
<span style="background:#e1f5fe; color:#0288d1; padding:2px 8px; border-radius:3px; font-weight:bold; font-size: 10px !important;">ОТВЕТ НА #{$row.parent_id}</span>
{/if}
<a href="{$ABS_PATH}index.php?id={$row.document_id}" target="_blank" style="color:#2980b9; font-weight:bold; text-decoration:underline;">
{$row.document_title|default:"Документ"|truncate:35}
</a>
<a href="{$ABS_PATH}index.php?id={$row.document_id}#comment-{$row.CId}" target="_blank" style="color:#27ae60; font-weight:bold;">[#] Посмотреть</a>
<div style="display: flex; gap: 8px; align-items: center; border-left: 1px solid #ddd; padding-left: 10px;">
<span style="font-weight:bold; color:{if $row.comment_status=='1'}#27ae60{else}#e74c3c{/if};">
{if $row.comment_status=='1'}Одобрен{else}Скрыт{/if}
</span>
{if $row.comment_status == '1'}
<a class="icon_sprite ico_unlock_no" title="Скрыть" href="index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=set_status_0&id={$row.CId}&cp={$sess}"></a>
<td>
<div style="display: flex; flex-direction: column; gap: 4px;">
<div style="margin-bottom: 2px;">
<a href="index.php?id={$row.document_id}" target="_blank" style="color:#2980b9; font-weight:bold; text-decoration:none; border-bottom: 1px solid #d1d1d1; font-size: 12px;">
{$row.document_title|default:"Документ #`$row.document_id`"}
</a>
</div>
<div style="display: flex; align-items: center; gap: 8px;">
{if $row.parent_id > 0}
<span style="background:#e1f5fe; color:#0288d1; padding:1px 5px; border-radius:3px; font-weight:bold; font-size: 10px !important;">Ответ на комментарий #{$row.parent_id} »</span>
{/if}
<div class="comment-text-cell">
{if $row.comment_text == '__DEL_BY_ADM__'}
<div class="comment-deleted-info del-adm">
<span style="font-size:14px;">🚫</span> Комментарий удален администратором
</div>
{elseif $row.comment_text == '__DEL_BY_AUT__'}
<div class="comment-deleted-info del-aut">
<span style="font-size:14px;">🗑️</span> Автор удалил свой комментарий
</div>
{else}
<a class="icon_sprite ico_unlock" title="Одобрить" href="index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=set_status_1&id={$row.CId}&cp={$sess}"></a>
{/if}
<a class="icon_sprite ico_edit" title="Редактировать" href="javascript:void(0);" onClick="windowOpen('index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_edit&pop=1&docid={$row.document_id}&Id={$row.CId}','700','700','1');"></a>
<a class="icon_sprite ico_delete ConfirmDelete"
title="{if $row.has_children}Удалить только этот текст (сохранить ветку){else}Удалить физически{/if}"
href="index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=delete&admin_action_type=soft&id={$row.CId}&cp={$sess}"></a>
{if $row.has_children}
<a class="icon_sprite ico_delete ico_delete_all ConfirmDelete"
title="УДАЛИТЬ ВСЮ ВЕТКУ ФИЗИЧЕСКИ (вместе с ответами)"
href="index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=delete&admin_action_type=full&id={$row.CId}&cp={$sess}"></a>
{$row.comment_text|strip_tags|truncate:130}
{/if}
</div>
</div>
</div>
</div>
</td>
<div class="comment-scroll-box">{$row.comment_text|nl2br}</div>
<td align="center">
<div class="files-bundle">
{if $row.images}
{foreach from=$row.images item=img name=img_loop}
{if $smarty.foreach.img_loop.iteration < 5} {* Показываем максимум 4 превью в стопке *}
<a href="{$ABS_PATH}uploads/comments/{$img.orig_name}" target="_blank" style="text-decoration:none;">
<img src="{$ABS_PATH}uploads/comments/{$img.orig_name}" class="thumb-stack" title="{$img.clean_name}">
</a>
{/if}
{/foreach}
{if $row.images|count >= 5}
<span style="font-size:10px; color:#999; margin-left:5px;">+{$row.images|count - 4}</span>
{/if}
{/if}
{if $row.files}
{foreach from=$row.files item=f}
<a href="{$ABS_PATH}uploads/comments/{$f.orig_name}" target="_blank" class="file-stack" title="{$f.clean_name}">
{$f.ext|upper}
</a>
{/foreach}
{/if}
</div>
</td>
{if $row.images || $row.files}
<div class="comment-assets-inline">
{foreach from=$row.images item=img}
<div class="asset-item">
<div class="asset-thumb">
<a href="{$ABS_PATH}uploads/comments/{$img.orig_name}" class="view fancy" rel="gallery-{$row.CId}">
<img src="{$ABS_PATH}uploads/comments/{$img.orig_name}" />
</a>
</div>
<span class="asset-name" title="{$img.clean_name}">{$img.clean_name|truncate:15:"...":true}</span>
</div>
{/foreach}
{foreach from=$row.files item=f}
<div class="asset-item">
<a href="{$ABS_PATH}uploads/comments/{$f.orig_name}" target="_blank" class="asset-thumb" style="flex-direction: column; text-decoration:none; background:#f9f9f9;">
<span style="font-weight: bold; color: #2980b9;">{$f.ext|upper}</span>
</a>
<span class="asset-name" title="{$f.clean_name}">{$f.clean_name|truncate:15:"...":true}</span>
</div>
{/foreach}
</div>
<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="Скрыть" 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="Одобрить" href="index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=set_status_1&id={$row.CId}&cp={$sess}"></a>
{/if}
<a class="icon_sprite ico_edit" title="Редактировать" href="javascript:void(0);" onClick="windowOpen('index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_edit&pop=1&docid={$row.document_id}&Id={$row.CId}','700','700','1');"></a>
{if $row.has_children}
<a class="icon_sprite ico_delete ConfirmDelete" title="Скрыть текст (сохранить ветку)"
href="index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_del&admin_action_type=soft&Id={$row.CId}&cp={$sess}"></a>
{/if}
{/if}
<div class="public-rating-row">
<div class="star-public">
{section name=s start=1 loop=6}{if $smarty.section.s.index <= $row.star_public}{else}<span class="star-grey">☆</span>{/if}{/section}
</div>
<span style="color:#999;">(Голосов: {$row.r_count|default:0})</span>
</div>
<a class="icon_sprite ico_delete ico_delete_all ConfirmDelete" title="УДАЛИТЬ ПОЛНОСТЬЮ"
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}
<tr>
<td colspan="4">
<ul class="messages">
<li class="highlight yellow"><strong>Сообщение:</strong><br />Нет комментариев.</li>
</ul>
</td>
</tr>
<tr>
<td colspan="9">
<ul class="messages">
<li class="highlight yellow"><strong>Сообщение:</strong><br />Нет комментариев.</li>
</ul>
</td>
</tr>
{/if}
</tbody>
</table>
<div class="tfoot">
<div class="left" style="padding:15px;">
<select id="mass_action_select" style="padding:5px;">
<select id="mass_action_select">
<option value="">Выберите действие...</option>
<option value="set_status_1">Опубликовать</option>
<option value="set_status_0">Скрыть</option>
@@ -211,11 +305,7 @@
</div>
{if $page_nav}
<div class="pagination">
<ul class="pages">
{$page_nav}
</ul>
</div>
<div class="pagination"><ul class="pages">{$page_nav}</ul></div>
{/if}
<script type="text/javascript">
@@ -223,16 +313,42 @@ function checkAll(master) {
var checkboxes = document.getElementsByClassName('row-checkbox');
for (var i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = master.checked; }
}
function runMassAction() {
var action = document.getElementById('mass_action_select').value;
if (!action) { jAlert('Выберите действие!', 'Внимание'); return; }
var select = document.getElementById('mass_action_select');
var action = select.value;
// Красивое уведомление, если не выбрали действие
if (!action) {
jAlert('Выберите действие из списка!', 'Внимание');
return;
}
var checkboxes = document.getElementsByClassName('row-checkbox');
var ids = [];
for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) ids.push(checkboxes[i].value); }
if (ids.length === 0) { jAlert('Ничего не выбрано!', 'Ошибка'); return; }
var url = 'index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=' + action + '&ids=' + ids.join(',') + '&cp={$sess}';
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) ids.push(checkboxes[i].value);
}
// Красивое уведомление, если не выбрали чекбоксы
if (ids.length === 0) {
jAlert('Вы не выбрали ни одного комментария для обработки.', 'Ошибка');
return;
}
var cp = '{$sess}';
var url = '';
if (action === 'delete') {
jConfirm('Удалить выбранные элементы?', 'Подтверждение', function(r) { if(r) window.location.href = url; });
} else { window.location.href = url; }
var idParams = ids.map(function(id) { return 'id[]=' + id; }).join('&');
url = 'index.php?do=modules&action=modedit&mod=comment&moduleaction=admin_del&' + idParams + '&cp=' + cp;
} else {
url = 'index.php?do=modules&action=modedit&mod=comment&moduleaction=1&admin_action=' + action + '&ids=' + ids.join(',') + '&cp=' + cp;
}
// Красивое подтверждение
jConfirm('Выполнить выбранное действие для ' + ids.length + ' эл.?', 'Подтверждение', function(r) {
if(r) window.location.href = url;
});
}
</script>