добавлен Авторские звезды + права Анонимам на участие в общем голосовании и Авторских звездах
This commit is contained in:
@@ -496,6 +496,11 @@ function commentListShow($tpl_dir)
|
||||
$new_comment['comment_status'] = $comment_status;
|
||||
$new_comment['comment_file'] = $comment_file_name;
|
||||
|
||||
// --- ВОТ ЭТИ ТРИ СТРОЧКИ: ПОЛУЧАЕМ РЕЙТИНГ ИЗ ФОРМЫ ---
|
||||
$user_rating = (int)($_POST['comment_user_rating'] ?? 0);
|
||||
if ($user_rating < 0) $user_rating = 0; if ($user_rating > 5) $user_rating = 5;
|
||||
$new_comment['user_rating'] = $user_rating;
|
||||
|
||||
$comment_text_raw = $_POST['comment_text'] ?? '';
|
||||
$comment_max_chars = $settings['comment_max_chars'];
|
||||
$comment_max_chars = (!empty($comment_max_chars) && $comment_max_chars > 10) ? $comment_max_chars : 200;
|
||||
@@ -648,6 +653,10 @@ function commentPostEdit($comment_id)
|
||||
$new_file_sql = ", comment_file = ''";
|
||||
}
|
||||
|
||||
// --- ВОТ ЭТО ДОБАВИЛ ---
|
||||
$user_rating = isset($_POST['user_rating']) ? (int)$_POST['user_rating'] : (int)$row['user_rating'];
|
||||
// -----------------------
|
||||
|
||||
// 6. Обновление базы данных
|
||||
// Если в настройках стоит "нужна премодерация", после правки статус меняется на 0 (если не админ)
|
||||
$new_status = $is_admin ? (int)$row['comment_status'] : ($row['comment_need_approve'] == '1' ? 0 : 1);
|
||||
@@ -657,7 +666,8 @@ function commentPostEdit($comment_id)
|
||||
SET
|
||||
comment_changed = '" . time() . "',
|
||||
comment_text = '" . addslashes($comment_text_cut) . "',
|
||||
comment_status = '" . $new_status . "'
|
||||
comment_status = '" . $new_status . "',
|
||||
user_rating = '" . $user_rating . "'
|
||||
$new_file_sql
|
||||
WHERE
|
||||
Id = '" . $comment_id . "'
|
||||
@@ -780,6 +790,7 @@ function commentPostDelete($comment_id)
|
||||
/**
|
||||
* Метод для обработки голосования за комментарий
|
||||
* Защита: ID для залогиненных, Пара (Ключ + IP) для анонимов.
|
||||
* Добавлена проверка глобальной настройки прав для анонимов.
|
||||
*/
|
||||
function commentVote()
|
||||
{
|
||||
@@ -807,6 +818,18 @@ function commentPostDelete($comment_id)
|
||||
$user_id = empty($_SESSION['user_id']) ? 0 : (int)$_SESSION['user_id'];
|
||||
$anon_key = $this->_getAnonKey();
|
||||
|
||||
// 1.5 ПРОВЕРКА ПРАВ ГОЛОСОВАНИЯ (Новое)
|
||||
// Получаем настройки модуля, чтобы узнать, разрешено ли анонимам голосовать
|
||||
$settings = $this->_commentSettingsGet();
|
||||
if (empty($user_id) && empty($settings['comment_rating_anon_vote'])) {
|
||||
if ($ajax) {
|
||||
if (ob_get_length()) ob_end_clean();
|
||||
echo 'forbidden_anon'; // Специальный статус для JS
|
||||
exit;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Получаем данные о комментарии, за который голосуют
|
||||
$comment_row = $AVE_DB->Query("
|
||||
SELECT comment_author_id, anon_key, comment_author_ip
|
||||
@@ -1189,82 +1212,92 @@ function commentPostDelete($comment_id)
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
/**
|
||||
* Метод, предназначенный для управления настройками модуля
|
||||
*
|
||||
* @param string $tpl_dir - путь к шаблонам модуля
|
||||
*/
|
||||
function commentAdminSettingsEdit($tpl_dir)
|
||||
{
|
||||
global $AVE_DB, $AVE_Template;
|
||||
* Метод, предназначенный для управления настройками модуля
|
||||
*
|
||||
* @param string $tpl_dir - путь к шаблонам модуля
|
||||
*/
|
||||
function commentAdminSettingsEdit($tpl_dir)
|
||||
{
|
||||
global $AVE_DB, $AVE_Template;
|
||||
|
||||
$request_sub = $_REQUEST['sub'] ?? '';
|
||||
$post_max_chars = $_POST['comment_max_chars'] ?? 0;
|
||||
$post_user_groups = $_POST['comment_user_groups'] ?? array();
|
||||
|
||||
$post_user_groups_read = $_POST['comment_user_groups_read'] ?? array();
|
||||
|
||||
$post_need_approve = $_POST['comment_need_approve'] ?? 0;
|
||||
$post_active = $_POST['comment_active'] ?? 0;
|
||||
$post_use_antispam = $_POST['comment_use_antispam'] ?? 0;
|
||||
$post_use_page_nav = $_POST['comment_use_page_nav'] ?? 0;
|
||||
$post_page_nav_count = $_POST['comment_page_nav_count'] ?? 0;
|
||||
$request_sub = $_REQUEST['sub'] ?? '';
|
||||
$post_max_chars = $_POST['comment_max_chars'] ?? 0;
|
||||
$post_user_groups = $_POST['comment_user_groups'] ?? array();
|
||||
|
||||
$post_user_groups_read = $_POST['comment_user_groups_read'] ?? array();
|
||||
|
||||
$post_need_approve = $_POST['comment_need_approve'] ?? 0;
|
||||
$post_active = $_POST['comment_active'] ?? 0;
|
||||
$post_use_antispam = $_POST['comment_use_antispam'] ?? 0;
|
||||
$post_use_page_nav = $_POST['comment_use_page_nav'] ?? 0;
|
||||
$post_page_nav_count = $_POST['comment_page_nav_count'] ?? 0;
|
||||
|
||||
// НОВОЕ: Настройка разрешения загрузки файлов
|
||||
$post_allow_files = $_POST['comment_allow_files'] ?? 0;
|
||||
// НОВОЕ: Настройка разрешения загрузки файлов
|
||||
$post_allow_files = $_POST['comment_allow_files'] ?? 0;
|
||||
|
||||
// НОВОЕ: Тип рейтинга (0 - звезды, 1 - лайки)
|
||||
$post_rating_type = $_POST['comment_rating_type'] ?? 0;
|
||||
// НОВОЕ: Тип рейтинга (0 - звезды, 1 - лайки)
|
||||
$post_rating_type = $_POST['comment_rating_type'] ?? 0;
|
||||
|
||||
// Данные для универсальных полей
|
||||
$post_show_f1 = $_POST['comment_show_f1'] ?? 0;
|
||||
$post_req_f1 = $_POST['comment_req_f1'] ?? 0;
|
||||
$post_name_f1 = $_POST['comment_name_f1'] ?? '';
|
||||
// НОВОЕ: ВКЛ/ВЫКЛ авторских звезд
|
||||
$post_show_user_rating = $_POST['comment_show_user_rating'] ?? 0;
|
||||
|
||||
$post_show_f2 = $_POST['comment_show_f2'] ?? 0;
|
||||
$post_req_f2 = $_POST['comment_req_f2'] ?? 0;
|
||||
$post_name_f2 = $_POST['comment_name_f2'] ?? '';
|
||||
// НОВОЕ: Разрешение голосования анонимам
|
||||
$post_rating_anon_vote = $_POST['comment_rating_anon_vote'] ?? 0;
|
||||
|
||||
if ($request_sub == 'save')
|
||||
{
|
||||
$max_chars = (empty($post_max_chars) || $post_max_chars < 50) ? 50 : $post_max_chars;
|
||||
// НОВОЕ: Разрешение анонимам ставить звезды (Авторский рейтинг)
|
||||
$post_rating_anon_set = $_POST['comment_rating_anon_set'] ?? 0;
|
||||
|
||||
$clean_name_f1 = htmlspecialchars(stripslashes($post_name_f1), ENT_QUOTES);
|
||||
$clean_name_f2 = htmlspecialchars(stripslashes($post_name_f2), ENT_QUOTES);
|
||||
// Данные для универсальных полей
|
||||
$post_show_f1 = $_POST['comment_show_f1'] ?? 0;
|
||||
$post_req_f1 = $_POST['comment_req_f1'] ?? 0;
|
||||
$post_name_f1 = $_POST['comment_name_f1'] ?? '';
|
||||
|
||||
$AVE_DB->Query("
|
||||
UPDATE " . PREFIX . "_module_comments
|
||||
SET
|
||||
comment_max_chars = '" . (int)$max_chars . "',
|
||||
comment_user_groups = '" . implode(',', $post_user_groups) . "',
|
||||
comment_user_groups_read = '" . implode(',', $post_user_groups_read) . "',
|
||||
comment_need_approve = '" . (int)$post_need_approve . "',
|
||||
comment_active = '" . (int)$post_active . "',
|
||||
comment_use_antispam = '" . (int)$post_use_antispam . "',
|
||||
comment_use_page_nav = '" . (int)$post_use_page_nav . "',
|
||||
comment_page_nav_count = '" . (int)$post_page_nav_count . "',
|
||||
comment_allow_files = '" . (int)$post_allow_files . "',
|
||||
comment_rating_type = '" . (int)$post_rating_type . "',
|
||||
comment_show_f1 = '" . (int)$post_show_f1 . "',
|
||||
comment_req_f1 = '" . (int)$post_req_f1 . "',
|
||||
comment_name_f1 = '" . $clean_name_f1 . "',
|
||||
comment_show_f2 = '" . (int)$post_show_f2 . "',
|
||||
comment_req_f2 = '" . (int)$post_req_f2 . "',
|
||||
comment_name_f2 = '" . $clean_name_f2 . "'
|
||||
WHERE
|
||||
Id = 1
|
||||
");
|
||||
}
|
||||
$post_show_f2 = $_POST['comment_show_f2'] ?? 0;
|
||||
$post_req_f2 = $_POST['comment_req_f2'] ?? 0;
|
||||
$post_name_f2 = $_POST['comment_name_f2'] ?? '';
|
||||
|
||||
$row = $this->_commentSettingsGet();
|
||||
|
||||
$row['comment_user_groups'] = explode(',', $row['comment_user_groups']);
|
||||
$row['comment_user_groups_read'] = explode(',', $row['comment_user_groups_read']);
|
||||
if ($request_sub == 'save')
|
||||
{
|
||||
$max_chars = (empty($post_max_chars) || $post_max_chars < 50) ? 50 : $post_max_chars;
|
||||
|
||||
$AVE_Template->assign($row);
|
||||
$AVE_Template->assign('content', $AVE_Template->fetch($tpl_dir . $this->_admin_settings_tpl));
|
||||
}
|
||||
$clean_name_f1 = htmlspecialchars(stripslashes($post_name_f1), ENT_QUOTES);
|
||||
$clean_name_f2 = htmlspecialchars(stripslashes($post_name_f2), ENT_QUOTES);
|
||||
|
||||
$AVE_DB->Query("
|
||||
UPDATE " . PREFIX . "_module_comments
|
||||
SET
|
||||
comment_max_chars = '" . (int)$max_chars . "',
|
||||
comment_user_groups = '" . implode(',', $post_user_groups) . "',
|
||||
comment_user_groups_read = '" . implode(',', $post_user_groups_read) . "',
|
||||
comment_need_approve = '" . (int)$post_need_approve . "',
|
||||
comment_active = '" . (int)$post_active . "',
|
||||
comment_use_antispam = '" . (int)$post_use_antispam . "',
|
||||
comment_use_page_nav = '" . (int)$post_use_page_nav . "',
|
||||
comment_page_nav_count = '" . (int)$post_page_nav_count . "',
|
||||
comment_allow_files = '" . (int)$post_allow_files . "',
|
||||
comment_rating_type = '" . (int)$post_rating_type . "',
|
||||
comment_show_user_rating = '" . (int)$post_show_user_rating . "',
|
||||
comment_rating_anon_vote = '" . (int)$post_rating_anon_vote . "',
|
||||
comment_rating_anon_set = '" . (int)$post_rating_anon_set . "',
|
||||
comment_show_f1 = '" . (int)$post_show_f1 . "',
|
||||
comment_req_f1 = '" . (int)$post_req_f1 . "',
|
||||
comment_name_f1 = '" . $clean_name_f1 . "',
|
||||
comment_show_f2 = '" . (int)$post_show_f2 . "',
|
||||
comment_req_f2 = '" . (int)$post_req_f2 . "',
|
||||
comment_name_f2 = '" . $clean_name_f2 . "'
|
||||
WHERE
|
||||
Id = 1
|
||||
");
|
||||
}
|
||||
|
||||
$row = $this->_commentSettingsGet();
|
||||
|
||||
$row['comment_user_groups'] = explode(',', $row['comment_user_groups']);
|
||||
$row['comment_user_groups_read'] = explode(',', $row['comment_user_groups_read']);
|
||||
|
||||
$AVE_Template->assign($row);
|
||||
$AVE_Template->assign('content', $AVE_Template->fetch($tpl_dir . $this->_admin_settings_tpl));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
132
js/comment.js
132
js/comment.js
@@ -119,14 +119,77 @@
|
||||
initCommentTimers();
|
||||
var $doc = $(document);
|
||||
|
||||
// --- ЛОГИКА ГОЛОСОВАНИЯ (РЕЙТИНГ) ---
|
||||
// --- ЛОГИКА ВЫБОРА РЕЙТИНГА В ФОРМЕ (НОВОЕ) ---
|
||||
$doc.on('mouseenter', '.star-choice', function() {
|
||||
var val = $(this).data('value');
|
||||
$(this).parent().find('.star-choice').each(function() {
|
||||
if ($(this).data('value') <= val) {
|
||||
$(this).removeClass('bi-star').addClass('bi-star-fill');
|
||||
} else {
|
||||
$(this).removeClass('bi-star-fill').addClass('bi-star');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$doc.on('mouseleave', '.rating-edit-block', function() {
|
||||
var cid = $(this).find('input[type="hidden"]').attr('id').replace('rating_input_', '');
|
||||
var currentRating = parseInt($('#rating_input_' + cid).val()) || 0;
|
||||
$(this).find('.star-choice').each(function() {
|
||||
if ($(this).data('value') <= currentRating) {
|
||||
$(this).removeClass('bi-star').addClass('bi-star-fill');
|
||||
} else {
|
||||
$(this).removeClass('bi-star-fill').addClass('bi-star');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Универсальный обработчик клика по звездам (и в новой форме, и в ред.)
|
||||
$doc.on('click', '.star-choice', function() {
|
||||
var val = $(this).data('value');
|
||||
var $parent = $(this).parent();
|
||||
|
||||
// 1. Ищем инпут для формы редактирования (он находится внутри .rating-edit-block)
|
||||
var ratingInput = $(this).closest('.rating-edit-block').find('input[type="hidden"]');
|
||||
|
||||
if (ratingInput.length) {
|
||||
ratingInput.val(val);
|
||||
} else {
|
||||
// 2. Ищем инпут для основной формы (по ID)
|
||||
$('#comment_user_rating').val(val);
|
||||
}
|
||||
|
||||
// Визуально фиксируем звезды сразу после клика
|
||||
$(this).prevAll().addBack().removeClass('bi-star').addClass('bi-star-fill');
|
||||
$(this).nextAll().removeClass('bi-star-fill').addClass('bi-star');
|
||||
});
|
||||
|
||||
// Сброс звезд при очистке всей формы (кнопка Reset)
|
||||
$doc.on('click', '#buttonReset', function() {
|
||||
$('#comment_user_rating').val(0);
|
||||
$('#user_rating_stars .star-choice').removeClass('bi-star-fill').addClass('bi-star');
|
||||
});
|
||||
|
||||
// Сброс только звезд по кнопке "Сбросить" в основной форме
|
||||
$doc.on('click', '#reset_stars', function(e) {
|
||||
e.preventDefault();
|
||||
$('#comment_user_rating').val(0);
|
||||
$('#user_rating_stars .star-choice').removeClass('bi-star-fill').addClass('bi-star');
|
||||
});
|
||||
|
||||
// Сброс звезд в форме редактирования
|
||||
$doc.on('click', '.reset-edit-stars', function(e) {
|
||||
e.preventDefault();
|
||||
var cid = $(this).data('id');
|
||||
$('#rating_input_' + cid).val(0);
|
||||
$('#user_rating_stars_' + cid + ' .star-choice').removeClass('bi-star-fill').addClass('bi-star');
|
||||
});
|
||||
|
||||
// --- ЛОГИКА ГОЛОСОВАНИЯ (РЕЙТИНГ УЖЕ ОПУБЛИКОВАННЫХ) ---
|
||||
$doc.on('mouseenter', '.star-item', function() {
|
||||
var $parent = $(this).parent();
|
||||
// Если это лайки (сердце)
|
||||
if ($parent.hasClass('comment-like')) {
|
||||
$(this).css('transform', 'scale(1.2)');
|
||||
}
|
||||
// Если это звезды
|
||||
else {
|
||||
$(this).prevAll().addBack().removeClass('bi-star').addClass('bi-star-fill');
|
||||
$(this).nextAll().removeClass('bi-star-fill').addClass('bi-star');
|
||||
@@ -140,10 +203,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
$doc.on('mouseleave', '.comment-stars', function() {
|
||||
// При уходе мыши визуально ничего не меняем до клика или рефреша
|
||||
});
|
||||
|
||||
$doc.on('click', '.star-item', function() {
|
||||
var $container = $(this).closest('.comment-rating-container');
|
||||
var commentId = $container.data('id');
|
||||
@@ -159,7 +218,6 @@
|
||||
},
|
||||
success: function(response) {
|
||||
var res = response.toString().trim();
|
||||
|
||||
if (res.indexOf('success') !== -1) {
|
||||
$container.html('<span class="text-success small fw-bold">Спасибо!</span>');
|
||||
setTimeout(function(){ location.reload(); }, 1000);
|
||||
@@ -167,18 +225,20 @@
|
||||
alert('Вы уже голосовали за этот комментарий.');
|
||||
} else if (res.indexOf('own_comment') !== -1) {
|
||||
alert('Нельзя голосовать за свой собственный комментарий.');
|
||||
} else {
|
||||
console.warn("Server response:", response);
|
||||
}
|
||||
/* НОВОЕ: Обработка запрета голосования для незарегистрированных пользователей */
|
||||
else if (res.indexOf('forbidden_anon') !== -1) {
|
||||
alert('Голосование доступно только зарегистрированным пользователям.');
|
||||
}
|
||||
else {
|
||||
alert('Ошибка при обработке голоса сервером.');
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
console.error("XHR Status:", xhr.status);
|
||||
alert('Ошибка связи с сервером. Статус: ' + xhr.status);
|
||||
}
|
||||
});
|
||||
});
|
||||
// ------------------------------------
|
||||
|
||||
// Глобальные кнопки управления
|
||||
$doc.on('click', '#mod_comment_close', function(e) {
|
||||
@@ -193,13 +253,9 @@
|
||||
e.preventDefault();
|
||||
var cid = $(this).data('id');
|
||||
var $form = $('#mod_comment_new');
|
||||
|
||||
$form.insertAfter('#comment_' + cid).show();
|
||||
$('#parent_id').val(cid);
|
||||
|
||||
$('html, body').animate({
|
||||
scrollTop: $form.offset().top - 150
|
||||
}, 500);
|
||||
$('html, body').animate({ scrollTop: $form.offset().top - 150 }, 500);
|
||||
$('#in_message').focus();
|
||||
});
|
||||
|
||||
@@ -215,7 +271,7 @@
|
||||
cAction(this, $(this).hasClass('mod_comment_lock') ? 'lock' : 'unlock');
|
||||
});
|
||||
|
||||
// Редактирование
|
||||
// --- РЕДАКТИРОВАНИЕ (ОБНОВЛЕННОЕ С ПРОВЕРКОЙ is_my_own) ---
|
||||
$doc.off('click', '.mod_comment_edit').on('click', '.mod_comment_edit', function(e) {
|
||||
e.preventDefault();
|
||||
var cid = $(this).data('id');
|
||||
@@ -224,15 +280,49 @@
|
||||
|
||||
if ($wrapper.find('.edit-form-container').length > 0) return;
|
||||
|
||||
// ПРОВЕРКА АВТОРСТВА: используем флаг is_my_own из атрибута шаблона
|
||||
var isMyOwn = $wrapper.attr('data-is-own') == '1';
|
||||
var currentRating = parseInt($wrapper.attr('data-user-rating')) || 0;
|
||||
|
||||
$('.edit-form-container').remove();
|
||||
$('.mod_comment_text').show();
|
||||
|
||||
var cleanText = $textBlock.html().replace(/<br\s*\/?>/mg, "\n").trim();
|
||||
var currentImg = $wrapper.find('.mod_comment_attached_image img').first().attr('src');
|
||||
|
||||
// Рисуем звезды ТОЛЬКО если настройка включена И это собственный комментарий (is_my_own)
|
||||
var starsEditBlock = '';
|
||||
if (typeof SHOW_USER_RATING !== 'undefined' && SHOW_USER_RATING == '1' && isMyOwn) {
|
||||
|
||||
// ВНЕДРЕНИЕ: Проверка прав группы (Авторизован или разрешено анонимам)
|
||||
if (typeof UGROUP !== 'undefined' && (UGROUP != '2' || RATING_ANON_SET == '1')) {
|
||||
|
||||
var starsHtml = '';
|
||||
for(var i=1; i<=5; i++) {
|
||||
var starClass = (i <= currentRating) ? 'bi-star-fill' : 'bi-star';
|
||||
starsHtml += `<i class="star-choice ${starClass}" data-value="${i}" style="cursor: pointer; color: #ffc107; font-size: 1.2rem; margin-right: 2px;"></i>`;
|
||||
}
|
||||
|
||||
starsEditBlock = `
|
||||
<div class="mb-2 rating-edit-block">
|
||||
<label class="small text-muted d-block mb-1">Ваша оценка:</label>
|
||||
<div class="d-flex align-items-center">
|
||||
<div id="user_rating_stars_${cid}">${starsHtml}</div>
|
||||
<a href="javascript:void(0);" class="reset-edit-stars ms-3 text-decoration-none small text-muted" data-id="${cid}">
|
||||
<i class="bi bi-x-circle"></i> Сбросить
|
||||
</a>
|
||||
</div>
|
||||
<input type="hidden" name="comment_user_rating" id="rating_input_${cid}" value="${currentRating}" />
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
var editHtml = `
|
||||
<div class="edit-form-container border rounded p-3 bg-light mt-2 mb-2">
|
||||
<textarea rows="5" id="ta_${cid}" class="form-control mb-2">${cleanText}</textarea>
|
||||
|
||||
${starsEditBlock}
|
||||
|
||||
${currentImg ? `<div class="form-check mb-2"><input class="form-check-input" type="checkbox" id="del_img_${cid}"><label class="form-check-label small text-danger" for="del_img_${cid}">Удалить фото</label></div>` : ''}
|
||||
<input type="file" id="new_file_${cid}" class="form-control form-control-sm mb-3" accept="image/*">
|
||||
<div class="d-flex gap-2">
|
||||
@@ -258,6 +348,12 @@
|
||||
var fd = new FormData();
|
||||
fd.append('module', 'comment'); fd.append('action', 'edit'); fd.append('Id', cid);
|
||||
fd.append('text', $('#ta_' + cid).val());
|
||||
|
||||
var rInput = $('#rating_input_' + cid);
|
||||
if (rInput.length) {
|
||||
fd.append('user_rating', rInput.val());
|
||||
}
|
||||
|
||||
fd.append('delete_image', $('#del_img_' + cid).is(':checked') ? 1 : 0);
|
||||
var file = $('#new_file_' + cid)[0].files[0];
|
||||
if (file) fd.append('comment_image', file);
|
||||
|
||||
86
sql.php
86
sql.php
@@ -5,6 +5,8 @@
|
||||
*
|
||||
* Обновленная структура с поддержкой выбора типа рейтинга (звезды/лайки),
|
||||
* идентификации анонимных пользователей, загрузки файлов и защиты по IP.
|
||||
* Добавлена поддержка "Авторских звезд" (user_rating) и настройки их отображения.
|
||||
* ДОБАВЛЕНО: Настройка разрешения голосования для анонимов и выставления ими звезд.
|
||||
*/
|
||||
|
||||
$module_sql_install = array();
|
||||
@@ -36,7 +38,10 @@ $module_sql_install[] = "CREATE TABLE `%%PRFX%%_module_comments` (
|
||||
`comment_name_f2` varchar(255) NOT NULL default '',
|
||||
`comment_allow_files` tinyint(1) NOT NULL default '0',
|
||||
`comment_file_max_size` int(10) NOT NULL default '2048',
|
||||
`comment_rating_type` tinyint(1) NOT NULL default '0', /* 0 - звезды, 1 - лайки */
|
||||
`comment_rating_type` tinyint(1) NOT NULL default '0', /* 0 - звезды, 1 - лайки, 2 - выключен */
|
||||
`comment_show_user_rating` tinyint(1) NOT NULL default '0', /* ВКЛ/ВЫКЛ авторских звезд */
|
||||
`comment_rating_anon_vote` tinyint(1) NOT NULL default '0', /* РАЗРЕШИТЬ АНОНИМАМ ГОЛОСОВАТЬ (лайк/дизлайк) */
|
||||
`comment_rating_anon_set` tinyint(1) NOT NULL default '0', /* РАЗРЕШИТЬ АНОНИМАМ СТАВИТЬ ЗВЕЗДЫ ПРИ СОЗДАНИИ */
|
||||
PRIMARY KEY (`Id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
|
||||
|
||||
@@ -50,40 +55,41 @@ $module_sql_install[] = "CREATE TABLE `%%PRFX%%_module_comment_info` (
|
||||
`comment_author_city` varchar(255) NOT NULL,
|
||||
`comment_author_website` varchar(255) NOT NULL,
|
||||
`comment_author_ip` varchar(45) NOT NULL,
|
||||
`anon_key` varchar(32) DEFAULT NULL,
|
||||
`anon_key` varchar(32) DEFAULT NULL,
|
||||
`comment_published` int(10) unsigned NOT NULL default '0',
|
||||
`comment_changed` int(10) unsigned NOT NULL default '0',
|
||||
`comment_text` text NOT NULL,
|
||||
`comment_status` tinyint(1) unsigned NOT NULL default '1',
|
||||
`comments_close` tinyint(1) unsigned NOT NULL default '0',
|
||||
`comment_file` varchar(255) NOT NULL default '',
|
||||
/* ПОЛЯ РЕЙТИНГА */
|
||||
`rating_sum` int(10) NOT NULL default '0',
|
||||
`rating_count` int(10) NOT NULL default '0',
|
||||
`user_rating` tinyint(1) NOT NULL default '0', /* ЛИЧНАЯ ОЦЕНКА АВТОРА (1-5) */
|
||||
/* ПОЛЯ ОБЩЕГО РЕЙТИНГА (ГОЛОСОВАНИЕ) */
|
||||
`rating_sum` int(10) NOT NULL default '0',
|
||||
`rating_count` int(10) NOT NULL default '0',
|
||||
PRIMARY KEY (`Id`),
|
||||
KEY `document_id` (`document_id`),
|
||||
KEY `parent_id` (`parent_id`),
|
||||
KEY `comment_status` (`comment_status`),
|
||||
KEY `anon_key` (`anon_key`)
|
||||
KEY `anon_key` (`anon_key`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0;";
|
||||
|
||||
$module_sql_install[] = "CREATE TABLE `%%PRFX%%_module_comment_votes` (
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`comment_id` int(10) unsigned NOT NULL,
|
||||
`user_id` int(10) unsigned DEFAULT '0',
|
||||
`anon_key` varchar(32) DEFAULT '',
|
||||
`remote_addr` varchar(45) DEFAULT '',
|
||||
`vote_value` tinyint(1) NOT NULL,
|
||||
`date_voted` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `comment_id` (`comment_id`),
|
||||
KEY `anon_key` (`anon_key`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `remote_addr` (`remote_addr`)
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`comment_id` int(10) unsigned NOT NULL,
|
||||
`user_id` int(10) unsigned DEFAULT '0',
|
||||
`anon_key` varchar(32) DEFAULT '',
|
||||
`remote_addr` varchar(45) DEFAULT '',
|
||||
`vote_value` tinyint(1) NOT NULL,
|
||||
`date_voted` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `comment_id` (`comment_id`),
|
||||
KEY `anon_key` (`anon_key`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `remote_addr` (`remote_addr`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
|
||||
|
||||
/* Добавили 0 в конце для comment_rating_type */
|
||||
$module_sql_install[] = "INSERT INTO `%%PRFX%%_module_comments` VALUES (1, 1000, '1,3', '1,2,3,4', '0', '1', '1' , '0', '', 1, 0, '', 1, 0, '', 0, 2048, 0);";
|
||||
/* Настройки по умолчанию (добавлен еще один 0 в конце для comment_rating_anon_set) */
|
||||
$module_sql_install[] = "INSERT INTO `%%PRFX%%_module_comments` VALUES (1, 1000, '1,3', '1,2,3,4', '0', '1', '1' , '0', '', 1, 0, '', 1, 0, '', 0, 2048, 0, 1, 0, 0);";
|
||||
|
||||
// =================================================================================
|
||||
// 2. ОБНОВЛЕНИЕ МОДУЛЯ (ALTER TABLE)
|
||||
@@ -99,28 +105,34 @@ $module_sql_update[] = "
|
||||
LIMIT 1;
|
||||
";
|
||||
|
||||
/* Добавляем переключатель типа рейтинга, если его нет */
|
||||
/* Добавляем настройки рейтинга в таблицу конфигурации */
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comments` ADD COLUMN IF NOT EXISTS `comment_rating_type` TINYINT(1) NOT NULL DEFAULT '0';";
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comments` ADD COLUMN IF NOT EXISTS `comment_show_user_rating` TINYINT(1) NOT NULL DEFAULT '0';";
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comments` ADD COLUMN IF NOT EXISTS `comment_rating_anon_vote` TINYINT(1) NOT NULL DEFAULT '0';";
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comments` ADD COLUMN IF NOT EXISTS `comment_rating_anon_set` TINYINT(1) NOT NULL DEFAULT '0';";
|
||||
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comment_info` ADD `rating_sum` INT(10) NOT NULL DEFAULT '0';";
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comment_info` ADD `rating_count` INT(10) NOT NULL DEFAULT '0';";
|
||||
/* Добавляем поля для оценки и голосования в таблицу инфо */
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comment_info` ADD COLUMN IF NOT EXISTS `user_rating` TINYINT(1) NOT NULL DEFAULT '0' AFTER `comment_file`;";
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comment_info` ADD COLUMN IF NOT EXISTS `rating_sum` INT(10) NOT NULL DEFAULT '0';";
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comment_info` ADD COLUMN IF NOT EXISTS `rating_count` INT(10) NOT NULL DEFAULT '0';";
|
||||
|
||||
/* Обновляем типы полей */
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comment_info` MODIFY `comment_author_ip` VARCHAR(45) NOT NULL;";
|
||||
|
||||
/* Создаем таблицу голосов, если обновляемся со старой версии */
|
||||
$module_sql_update[] = "CREATE TABLE IF NOT EXISTS `%%PRFX%%_module_comment_votes` (
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`comment_id` int(10) unsigned NOT NULL,
|
||||
`user_id` int(10) unsigned DEFAULT '0',
|
||||
`anon_key` varchar(32) DEFAULT '',
|
||||
`remote_addr` varchar(45) DEFAULT '',
|
||||
`vote_value` tinyint(1) NOT NULL,
|
||||
`date_voted` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `comment_id` (`comment_id`),
|
||||
KEY `anon_key` (`anon_key`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `remote_addr` (`remote_addr`)
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`comment_id` int(10) unsigned NOT NULL,
|
||||
`user_id` int(10) unsigned DEFAULT '0',
|
||||
`anon_key` varchar(32) DEFAULT '',
|
||||
`remote_addr` varchar(45) DEFAULT '',
|
||||
`vote_value` tinyint(1) NOT NULL,
|
||||
`date_voted` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `comment_id` (`comment_id`),
|
||||
KEY `anon_key` (`anon_key`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `remote_addr` (`remote_addr`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
|
||||
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comment_votes` ADD COLUMN IF NOT EXISTS `remote_addr` VARCHAR(45) DEFAULT '' AFTER `anon_key`;";
|
||||
|
||||
?>
|
||||
@@ -94,7 +94,7 @@
|
||||
<tr>
|
||||
<td>Заголовок поля 1:</td>
|
||||
<td style="border-right: 1px solid #ddd;">
|
||||
<input name="comment_name_f1" type="text" value="{$comment_name_f1|escape}" style="width: 90%;" placeholder="Напр: Веб-сайт" />
|
||||
<input name="comment_name_f1" type="text" value="{$comment_name_f1|escape}" style="width: 90%;" placeholder="Введите название поля" />
|
||||
<div style="margin-top: 5px;">
|
||||
<label><input name="comment_show_f1" type="checkbox" value="1" {if $comment_show_f1=='1'}checked{/if} /> Показывать</label>
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
</td>
|
||||
<td>Заголовок поля 2:</td>
|
||||
<td>
|
||||
<input name="comment_name_f2" type="text" value="{$comment_name_f2|escape}" style="width: 90%;" placeholder="Напр: Город" />
|
||||
<input name="comment_name_f2" type="text" value="{$comment_name_f2|escape}" style="width: 90%;" placeholder="Введите название поля" />
|
||||
<div style="margin-top: 5px;">
|
||||
<label><input name="comment_show_f2" type="checkbox" value="1" {if $comment_show_f2=='1'}checked{/if} /> Показывать</label>
|
||||
|
||||
@@ -113,11 +113,11 @@
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="4" style="background: #f9f9f9; font-weight: bold; text-align: center;">Система оценки комментариев</td>
|
||||
<td colspan="4" style="background: #f9f9f9; font-weight: bold; text-align: center;">Настройка общего рейтинга</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Тип рейтинга:</td>
|
||||
<td colspan="3">
|
||||
<td>Тип общего рейтинга:</td>
|
||||
<td style="border-right: 1px solid #ddd;">
|
||||
<div style="display: flex; gap: 20px;">
|
||||
<span style="display: flex; align-items: center;">
|
||||
<input type="radio" name="comment_rating_type" id="type_stars" value="0" {if $comment_rating_type == '0'}checked="checked"{/if} style="margin-right: 5px; cursor: pointer;" />
|
||||
@@ -133,6 +133,32 @@
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>Права на голосование:</td>
|
||||
<td>
|
||||
<label style="cursor: pointer; display: flex; align-items: center; font-weight: normal;">
|
||||
<input name="comment_rating_anon_vote" type="checkbox" value="1" {if $comment_rating_anon_vote=='1'}checked{/if} style="margin-right: 10px;" />
|
||||
Разрешить анонимам голосовать
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4" style="background: #f9f9f9; font-weight: bold; text-align: center;">Настройка авторского рейтинга</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Авторская оценка:</td>
|
||||
<td style="border-right: 1px solid #ddd;">
|
||||
<label style="cursor: pointer; display: flex; align-items: center; font-weight: normal;">
|
||||
<input name="comment_show_user_rating" type="checkbox" value="1" {if $comment_show_user_rating=='1'}checked{/if} style="margin-right: 10px;" />
|
||||
Включить "Авторские звезды"
|
||||
</label>
|
||||
</td>
|
||||
<td>Права на оценку:</td>
|
||||
<td>
|
||||
<label style="cursor: pointer; display: flex; align-items: center; font-weight: normal;">
|
||||
<input name="comment_rating_anon_set" type="checkbox" value="1" {if $comment_rating_anon_set=='1'}checked{/if} style="margin-right: 10px;" />
|
||||
Разрешить анонимам ставить звезды
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
@@ -123,6 +123,31 @@
|
||||
<textarea rows="8" name="comment_text" id="in_message" class="form-control" placeholder="{#COMMENT_YOUR_TEXT#}"></textarea>
|
||||
</div>
|
||||
|
||||
{* --- ВНЕДРЕНИЕ: ВЫБОР РЕЙТИНГА АВТОРОМ С ПРОВЕРКОЙ НАСТРОЙКИ --- *}
|
||||
{if $comment_show_user_rating == 1}
|
||||
{* Показываем только если не гость ИЛИ если гостям разрешено в настройках *}
|
||||
{if $smarty.session.user_group != '2' || $comment_rating_anon_set == 1}
|
||||
<div class="mb-3">
|
||||
<label class="form-label d-block small fw-bold text-muted text-uppercase mb-1">Оцените материал:</label>
|
||||
<div class="d-flex align-items-center">
|
||||
<div id="user_rating_stars" class="fs-4" style="color: #ffc107; display: inline-block;">
|
||||
<i class="star-choice bi bi-star" data-value="1" title="Ужасно" style="cursor: pointer;"></i>
|
||||
<i class="star-choice bi bi-star" data-value="2" title="Плохо" style="cursor: pointer;"></i>
|
||||
<i class="star-choice bi bi-star" data-value="3" title="Нормально" style="cursor: pointer;"></i>
|
||||
<i class="star-choice bi bi-star" data-value="4" title="Хорошо" style="cursor: pointer;"></i>
|
||||
<i class="star-choice bi bi-star" data-value="5" title="Отлично" style="cursor: pointer;"></i>
|
||||
</div>
|
||||
<a href="javascript:void(0);" id="reset_stars" class="ms-3 text-decoration-none small text-muted" title="Убрать оценку">
|
||||
<i class="bi bi-x-circle"></i> Сбросить
|
||||
</a>
|
||||
</div>
|
||||
{* Скрытое поле, куда JS запишет выбранное число *}
|
||||
<input name="comment_user_rating" type="hidden" id="comment_user_rating" value="0" />
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{* --- КОНЕЦ ВНЕДРЕНИЯ --- *}
|
||||
|
||||
{* Оставшиеся символы *}
|
||||
<p class="text-end text-muted small">
|
||||
{#COMMENT_CHARS_LEFT#} <span class="charsLeft fw-bold" id="charsLeft_new"></span>
|
||||
@@ -249,6 +274,10 @@
|
||||
var DOC_ID = '{$doc_id}';
|
||||
var MAX_CHARS = '{$comment_max_chars}';
|
||||
var aveabspath = '{$ABS_PATH}';
|
||||
|
||||
// Глобальная переменная для JS
|
||||
var SHOW_USER_RATING = '{$comment_show_user_rating|default:0}';
|
||||
var RATING_ANON_SET = '{$comment_rating_anon_set|default:0}';
|
||||
</script>
|
||||
<script src="{$ABS_PATH}modules/comment/js/comment.js" type="text/javascript"></script>
|
||||
<style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{foreach from=$subcomments item=c}
|
||||
|
||||
<div class="card mb-3 mod_comment_comment{if $c.parent_id} ms-4{/if}" id="comment_wrapper_{$c.Id}">
|
||||
<div class="card mb-3 mod_comment_comment{if $c.parent_id} ms-4{/if}" id="comment_wrapper_{$c.Id}" data-user-rating="{$c.user_rating|default:0}" data-is-own="{if $c.is_my_own}1{else}0{/if}">
|
||||
|
||||
{if isset($smarty.request.subaction) && $smarty.request.subaction=='showonly' && isset($smarty.request.comment_id) && $smarty.request.comment_id==$c.Id}
|
||||
<div class="border border-warning border-3 rounded p-0">
|
||||
@@ -28,42 +28,6 @@
|
||||
|
||||
<span class="me-2"><i class="bi bi-clock me-1"></i> {$c.comment_published}</span>
|
||||
|
||||
{* ----- БЛОК РЕЙТИНГА (ЗВЕЗДЫ ИЛИ ЛАЙКИ) ----- *}
|
||||
{* Добавлена проверка на полное отключение (значение 2) *}
|
||||
{if $comment_rating_type != 2}
|
||||
<div class="comment-rating-container d-inline-flex align-items-center ms-2 py-1 px-2 bg-light rounded border" data-id="{$c.Id}" style="line-height: 1;">
|
||||
{if $comment_rating_type == 1}
|
||||
{* РЕЖИМ ЛАЙКОВ (СЕРДЕЧКО) *}
|
||||
<div class="comment-like d-inline-flex align-items-center" style="cursor: pointer; color: #dc3545; font-size: 0.95rem;">
|
||||
<i class="star-item bi bi-heart-fill me-1"
|
||||
data-value="5"
|
||||
title="Мне нравится"></i>
|
||||
</div>
|
||||
{if isset($c.rating_count)}
|
||||
<span class="ms-1 text-muted fw-bold" style="font-size: 0.8rem;">{$c.rating_count}</span>
|
||||
{/if}
|
||||
{else}
|
||||
{* РЕЖИМ ЗВЕЗД (1-5) - ПО УМОЛЧАНИЮ ПРИ 0 *}
|
||||
<div class="comment-stars d-inline-flex" style="cursor: pointer; color: #ffc107; font-size: 0.9rem;">
|
||||
{assign var="avg_rating" value=0}
|
||||
{if isset($c.rating_count) && $c.rating_count > 0}
|
||||
{math equation="round(x / y)" x=$c.rating_sum y=$c.rating_count assign="avg_rating"}
|
||||
{/if}
|
||||
|
||||
{section name=star start=1 loop=6}
|
||||
<i class="star-item bi {if $smarty.section.star.index <= $avg_rating}bi-star-fill{else}bi-star{/if} {if !$smarty.section.star.last}me-1{/if}"
|
||||
data-value="{$smarty.section.star.index}"
|
||||
title="Оценить на {$smarty.section.star.index}"></i>
|
||||
{/section}
|
||||
</div>
|
||||
{if isset($c.rating_count)}
|
||||
<span class="ms-2 text-muted fw-bold" style="font-size: 0.8rem;">({$c.rating_count})</span>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{* --------------------------------- *}
|
||||
|
||||
{if $comment_show_f1 == 1 && $c.comment_author_website}
|
||||
<span class="ms-2 d-inline-block">
|
||||
<i class="bi bi-link-45deg"></i> <strong>{$comment_name_f1|default:#COMMENT_YOUR_SITE#}:</strong> {$c.comment_author_website|stripslashes|escape}
|
||||
@@ -89,28 +53,71 @@
|
||||
{* Текст комментария *}
|
||||
<div class="mod_comment_text comment-text-content">{$c.comment_text|stripslashes|nl2br}</div>
|
||||
|
||||
{* ВЫВОД ПРИКРЕПЛЕННОГО ИЗОБРАЖЕНИЯ *}
|
||||
{* Вывод изображения *}
|
||||
{if !empty($c.comment_file)}
|
||||
<div class="mod_comment_attached_image mt-3" id="image_container_{$c.Id}">
|
||||
<a href="{$ABS_PATH}uploads/comments/{$c.comment_file}" target="_blank" class="comment-img-link">
|
||||
<img src="{$ABS_PATH}uploads/comments/{$c.comment_file}"
|
||||
class="img-fluid rounded border shadow-sm"
|
||||
style="max-width: 300px; max-height: 400px; cursor: zoom-in;"
|
||||
alt="Изображение к комментарию" />
|
||||
<img src="{$ABS_PATH}uploads/comments/{$c.comment_file}" class="img-fluid rounded border shadow-sm" style="max-width: 300px; max-height: 400px; cursor: zoom-in;" alt="Изображение" />
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-footer mod_comment_actions d-flex justify-content-between align-items-center bg-white border-top p-2">
|
||||
|
||||
{* ЛЕВАЯ ЧАСТЬ: Таймер (если доступно редактирование) *}
|
||||
<div class="edit-timer-zone px-2">
|
||||
{* ЛЕВАЯ ЧАСТЬ: РЕЙТИНГИ И ТАЙМЕР *}
|
||||
<div class="d-flex align-items-center flex-wrap">
|
||||
|
||||
{* 1. Оценка автора (звезды) *}
|
||||
{if isset($c.user_rating) && $c.user_rating > 0}
|
||||
<div class="badge bg-warning text-dark me-3 d-inline-flex align-items-center" title="Оценка автора: {$c.user_rating} из 5" style="font-size: 0.75rem; padding: 0.4rem 0.6rem; gap: 4px;">
|
||||
<span style="line-height: 1;">Оценка автора:</span>
|
||||
<div class="d-flex align-items-center" style="line-height: 1;">
|
||||
{section name=r_star start=1 loop=6}
|
||||
{if $smarty.section.r_star.index <= $c.user_rating}
|
||||
<i class="bi bi-star-fill" style="font-size: 0.7rem;"></i>
|
||||
{else}
|
||||
<i class="bi bi-star text-white" style="font-size: 0.7rem;"></i>
|
||||
{/if}
|
||||
{/section}
|
||||
</div>
|
||||
<span class="fw-bold" style="line-height: 1;">{$c.user_rating}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{* 2. Общий рейтинг комментария (лайки/звезды для голосования) *}
|
||||
{if $comment_rating_type != 2}
|
||||
<div class="comment-rating-container d-inline-flex align-items-center me-3 py-1 px-2 bg-light rounded border" data-id="{$c.Id}" style="line-height: 1;">
|
||||
{if $comment_rating_type == 1}
|
||||
{* Лайки *}
|
||||
<div class="comment-like d-inline-flex align-items-center" style="cursor: pointer; color: #dc3545; font-size: 0.95rem;">
|
||||
<i class="star-item bi bi-heart-fill me-1" data-value="5" title="Мне нравится"></i>
|
||||
</div>
|
||||
{if isset($c.rating_count)}
|
||||
<span class="ms-1 text-muted fw-bold" style="font-size: 0.8rem;">{$c.rating_count}</span>
|
||||
{/if}
|
||||
{else}
|
||||
{* Звезды для голосования *}
|
||||
<div class="comment-stars d-inline-flex" style="cursor: pointer; color: #ffc107; font-size: 0.9rem;">
|
||||
{assign var="avg_rating" value=0}
|
||||
{if isset($c.rating_count) && $c.rating_count > 0}
|
||||
{math equation="round(x / y)" x=$c.rating_sum y=$c.rating_count assign="avg_rating"}
|
||||
{/if}
|
||||
{section name=star start=1 loop=6}
|
||||
<i class="star-item bi {if $smarty.section.star.index <= $avg_rating}bi-star-fill{else}bi-star{/if} {if !$smarty.section.star.last}me-1{/if}" data-value="{$smarty.section.star.index}" title="Оценить"></i>
|
||||
{/section}
|
||||
</div>
|
||||
{if isset($c.rating_count)}
|
||||
<span class="ms-2 text-muted fw-bold" style="font-size: 0.8rem;">({$c.rating_count})</span>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{* 3. Таймер редактирования *}
|
||||
{if $c.can_edit && isset($c.edit_time_left) && $c.edit_time_left > 0}
|
||||
<div class="edit-timer-wrapper text-muted small" id="timer_container_{$c.Id}" title="Время на редактирование">
|
||||
<div class="edit-timer-wrapper text-muted small" id="timer_container_{$c.Id}" title="Осталось времени">
|
||||
<i class="bi bi-hourglass-split text-primary"></i>
|
||||
<span class="timer-count fw-bold" data-left="{$c.edit_time_left}" id="timer_{$c.Id}">
|
||||
{math equation="floor(x/60)" x=$c.edit_time_left}:{if ($c.edit_time_left%60) < 10}0{/if}{math equation="x%60" x=$c.edit_time_left}
|
||||
@@ -119,41 +126,31 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{* ПРАВАЯ ЧАСТЬ: Кнопки действий *}
|
||||
<div class="actions-buttons">
|
||||
{* Кнопка ответа *}
|
||||
{* ПРАВАЯ ЧАСТЬ: КНОПКИ ДЕЙСТВИЙ *}
|
||||
<div class="actions-buttons d-flex align-items-center">
|
||||
{if ($cancomment==1 && $closed!=1) || $smarty.const.UGROUP==1}
|
||||
{if !(isset($c.is_my_own) && $c.is_my_own)}
|
||||
<a class="mod_comment_answer p-2 text-primary text-decoration-none" href="javascript:void(0);" data-id="{$c.Id}" title="{#COMMENT_ANSWER_LINK#}">
|
||||
<a class="mod_comment_answer p-2 text-primary text-decoration-none" href="javascript:void(0);" data-id="{$c.Id}">
|
||||
<i class="bi bi-reply-fill me-1"></i> {#COMMENT_ANSWER_LINK#}
|
||||
</a>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{* ПРАВА НА РЕДАКТИРОВАНИЕ *}
|
||||
{if $c.can_edit}
|
||||
<span id="controls_{$c.Id}">
|
||||
<a class="p-2 text-warning text-decoration-none mod_comment_edit" href="javascript:void(0);" data-id="{$c.Id}" title="{#COMMENT_EDIT_LINK#}">
|
||||
<span id="controls_{$c.Id}" class="d-flex">
|
||||
<a class="p-2 text-warning text-decoration-none mod_comment_edit" href="javascript:void(0);" data-id="{$c.Id}">
|
||||
<i class="bi bi-pencil-square me-1"></i> Редактировать
|
||||
</a>
|
||||
|
||||
<a class="p-2 text-danger text-decoration-none mod_comment_delete" href="javascript:void(0);" data-id="{$c.Id}" title="{#COMMENT_DELETE_LINK#}">
|
||||
<a class="p-2 text-danger text-decoration-none mod_comment_delete" href="javascript:void(0);" data-id="{$c.Id}">
|
||||
<i class="bi bi-trash me-1"></i> Удалить
|
||||
</a>
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
{* УПРАВЛЕНИЕ СТАТУСОМ (ТОЛЬКО ДЛЯ АДМИНА) *}
|
||||
{if $smarty.const.UGROUP==1}
|
||||
{if $c.comment_status!=1}
|
||||
<a class="mod_comment_unlock p-2 text-success" href="javascript:void(0);" data-id="{$c.Id}" title="{#COMMENT_UNLOCK_LINK#}">
|
||||
<i class="bi bi-unlock-fill me-1"></i>
|
||||
</a>
|
||||
{else}
|
||||
<a class="mod_comment_lock p-2 text-dark" href="javascript:void(0);" data-id="{$c.Id}" title="{#COMMENT_LOCK_LINK#}">
|
||||
<i class="bi bi-lock-fill me-1"></i>
|
||||
</a>
|
||||
{/if}
|
||||
<a class="mod_comment_{if $c.comment_status!=1}unlock{else}lock{/if} p-2 text-dark" href="javascript:void(0);" data-id="{$c.Id}">
|
||||
<i class="bi bi-{if $c.comment_status!=1}unlock-fill{else}lock-fill{/if}"></i>
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user