фин. правка сортровки: дети всегда от старых к новым.

This commit is contained in:
2026-01-28 20:10:59 +05:00
parent 36ae42b0b3
commit ed6868af17
4 changed files with 67 additions and 9 deletions

View File

@@ -48,6 +48,12 @@
* Пагинация работает только для родительских комментариев, количество ответов (дети и внуки) на родительский комментарий - задается в Админ панели отдельно. Если общее количество ответов превышает лимит ответов, установленный в Админке, будет выведена кнопка Показать еще N ответов, при клике по которой AJAX подгрузит и выведет оставшиеся комментарии на страницу.
* Сортировка
* В админ панели доступен поиск комментария по следующим параметрам: по Имени, IP адресу, по тексту комментария. Сортировка: сначала новые, сначала старые, популярные (согласно Рейтингу пользователей), обсуждаемые - по количеству ответов на комментарий-родитель, оценки Автора (у кого больше всех звезд). Фильтрация: выводить все сообщения, только с файлами, только скрытые. Вывод комментариев по умолчанию - плоский список, но для удобства есть и древовидный список, что позволяет видеть сразу всю ветку. Количество на странице: выводит желаемое количество комментариев на страницу. Период: вам доступен календарь, в котором вы сами выбираете нужный вам период для просмотра - от и до.
* В публичной части также можно менять вывод комментариев (выбирается в Настройках модуля):
* Сначала старые (новые внизу)
* Сначала новые (старые внизу)
* По общему рейтингу (лучшие вверху)
* По оценке Автора (кол-ву звезд)
* Важно! В ветках потомки выводятся по принципу сначала старые (новые внизу), что-бы не рушить визуальную иерархию ответов.
* Эмодзи
* Модуль использует кодировку utf8mb4, что позволяет использовать в тексте комментариев эмодзи, например такие: 😀 😁 😂 🤣 😃 😄 😅 😆 😉 😊 😋 😎 😍 😘 😗 😙 😚 🙂 🤗 🤩
* Шаблоны (файлы .tpl) отвечающие за вывод в публичную часть:
@@ -91,5 +97,4 @@ https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js
https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css
```
```
https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css
```
https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css

View File

@@ -7,7 +7,7 @@
* @author Александр Сальников (Repellent)
* @copyright 2026
* @subpackage module_Comment
* @since 3.33
* @since 3.34
* @filesource
*/
class Comment
@@ -499,7 +499,19 @@ function commentListShow($tpl_dir)
$page_nav = '';
}
// --- AJAX ЛИМИТЫ ---
// --- СНАЧАЛА ДЕТИ ВСЕГДА ОТ СТАРЫХ К НОВЫМ (Причесываем всю очередь) ---
if (!empty($comments)) {
foreach ($comments as $parentId => &$subList) {
if ($parentId > 0) {
usort($subList, function($a, $b) {
return $a['comment_published_raw'] <=> $b['comment_published_raw'];
});
}
}
unset($subList);
}
// --- И ТОЛЬКО ПОТОМ AJAX ЛИМИТЫ (Отрезаем лишнее от уже правильной очереди) ---
$assign['more_counts'] = [];
$requested_branch = (int)($_REQUEST['ajax_load_branch'] ?? 0);
@@ -510,6 +522,7 @@ function commentListShow($tpl_dir)
continue;
}
$assign['more_counts'][$parentId] = count($subList) - $assign['ajax_replies_limit'];
// Теперь array_slice заберет именно ПЕРВЫЕ (старые) ответы
$comments[$parentId] = array_slice($subList, 0, $assign['ajax_replies_limit']);
}
}
@@ -1838,6 +1851,20 @@ if ($res_locked) {
if ($p_id > 0) $child_map[$p_id][] = $id;
}
// --- Сортируем детей внутри карты веток ---
// Делаем это только если вид НЕ линейный
if ($view_mode != 'flat' && !empty($child_map)) {
foreach ($child_map as $p_id => &$children) {
usort($children, function($a, $b) use ($all_items) {
// Сравниваем по дате публикации из основного массива данных
$timeA = (int)$all_items[$a]['comment_published'];
$timeB = (int)$all_items[$b]['comment_published'];
return $timeA <=> $timeB;
});
}
unset($children);
}
foreach ($all_items as $id => &$item_for_check) {
$item_for_check['has_children'] = isset($child_map[$id]) ? 1 : 0;
}

View File

@@ -3,7 +3,7 @@ if (!defined('BASE_DIR')) exit;
$module = array(
'ModuleSysName' => 'comment',
'ModuleVersion' => '3.34',
'ModuleVersion' => '3.35',
'ModuleAutor' => 'Repellent',
'ModuleCopyright' => '&copy; 2025-' . date('Y') . ' ave4cms.ru',
'ModuleStatus' => 1,

View File

@@ -83,6 +83,9 @@
<script type="text/javascript">
{literal}
$(document).ready(function(){
// Флаг для предотвращения повторных перезагрузок
window.is_reloading = false;
// Очистка лога через системный jConfirm
$('#clear_log_btn').off('click').on('click', function(e){
e.preventDefault();
@@ -109,11 +112,35 @@ $(document).ready(function(){
});
});
// Универсальное закрытие (для jQuery UI Dialog и Colorbox)
// Универсальное закрытие с "гашением" желтого кружка
// --- ОБРАБОТКА ЗАКРЫТИЯ ЧЕРЕЗ КРЕСТИК ИЛИ ESC ---
var $dialogContainer = $(".CloseLogDialog").closest('.ui-dialog-content');
if ($dialogContainer.length) {
$dialogContainer.on("dialogclose", function(event, ui) {
// Если мы еще не в процессе перезагрузки, запускаем её
if (!window.is_reloading) {
window.is_reloading = true;
$.ajax({
url: 'index.php?do=modules&action=modedit&mod=comment&moduleaction=mark_log_read&cp={/literal}{$sess}{literal}',
type: 'GET',
complete: function() {
if (window.parent && window.parent.location !== window.location) {
window.parent.location.reload();
} else {
window.location.reload();
}
}
});
}
});
}
// Универсальное закрытие по кнопке "Закрыть окно"
$(".CloseLogDialog").on('click', function(e){
e.preventDefault();
// Устанавливаем флаг, чтобы dialogclose не сработал дублем
window.is_reloading = true;
// Сначала помечаем логи как прочитанные в сессии
$.ajax({
url: 'index.php?do=modules&action=modedit&mod=comment&moduleaction=mark_log_read&cp={/literal}{$sess}{literal}',
@@ -127,8 +154,7 @@ $(document).ready(function(){
if ($dialog.length) $dialog.dialog('close');
}
// Перезагружаем страницу админки, чтобы PHP убрал желтый цвет
// Если лог открыт в модальном окне, обновляем родителя (window.parent)
// Перезагружаем страницу
if (window.parent && window.parent.location !== window.location) {
window.parent.location.reload();
} else {