при голосовании добавлена проверка связкой имя+IP
This commit is contained in:
@@ -779,16 +779,21 @@ function commentPostDelete($comment_id)
|
||||
|
||||
/**
|
||||
* Метод для обработки голосования за комментарий
|
||||
* Защита: ID для залогиненных, Пара (Ключ + IP) для анонимов.
|
||||
*/
|
||||
function commentVote()
|
||||
{
|
||||
global $AVE_DB;
|
||||
|
||||
// Принимаем данные
|
||||
$comment_id = (int)($_POST['comment_id'] ?? 0);
|
||||
$vote_value = (int)($_POST['vote'] ?? 0);
|
||||
$ajax = (isset($_POST['ajax']) && $_POST['ajax'] == 1);
|
||||
|
||||
// IP пользователя
|
||||
$user_ip = $_SERVER['REMOTE_ADDR'] ?? '';
|
||||
|
||||
// Базовая проверка значения (от 1 до 5 звезд)
|
||||
// Базовая валидация
|
||||
if ($comment_id <= 0 || $vote_value < 1 || $vote_value > 5) {
|
||||
if ($ajax) {
|
||||
if (ob_get_length()) ob_end_clean();
|
||||
@@ -798,18 +803,18 @@ function commentPostDelete($comment_id)
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. Идентификация пользователя
|
||||
// 1. Идентификация текущего голосующего
|
||||
$user_id = empty($_SESSION['user_id']) ? 0 : (int)$_SESSION['user_id'];
|
||||
$anon_key = $this->_getAnonKey();
|
||||
|
||||
// 2. Получаем данные о комментарии (FetchRow исправлен)
|
||||
$comment_data = $AVE_DB->Query("
|
||||
SELECT comment_author_id, anon_key
|
||||
// 2. Получаем данные о комментарии, за который голосуют
|
||||
$comment_row = $AVE_DB->Query("
|
||||
SELECT comment_author_id, anon_key, comment_author_ip
|
||||
FROM " . PREFIX . "_module_comment_info
|
||||
WHERE Id = '" . $comment_id . "'
|
||||
")->FetchRow();
|
||||
|
||||
if (!$comment_data) {
|
||||
if (!$comment_row) {
|
||||
if ($ajax) {
|
||||
if (ob_get_length()) ob_end_clean();
|
||||
echo 'error';
|
||||
@@ -818,10 +823,25 @@ function commentPostDelete($comment_id)
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Запрет голосовать за свой же комментарий
|
||||
$c_author_id = (int)$comment_row->comment_author_id;
|
||||
|
||||
// 3. ПРОВЕРКА АВТОРСТВА (Запрет голосовать за свой же комментарий)
|
||||
$is_author = false;
|
||||
if ($user_id > 0 && $user_id == $comment_data->comment_author_id) $is_author = true;
|
||||
if ($user_id == 0 && $anon_key == $comment_data->anon_key) $is_author = true;
|
||||
|
||||
if ($user_id > 0) {
|
||||
// Если залогинен — проверяем только по ID
|
||||
if ($user_id === $c_author_id) {
|
||||
$is_author = true;
|
||||
}
|
||||
} else {
|
||||
// Если аноним — проверяем парой (Ключ + IP)
|
||||
// И только если автор комментария тоже был анонимом
|
||||
if ($c_author_id === 0 &&
|
||||
$anon_key === $comment_row->anon_key &&
|
||||
$user_ip === $comment_row->comment_author_ip) {
|
||||
$is_author = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_author) {
|
||||
if ($ajax) {
|
||||
@@ -832,12 +852,19 @@ function commentPostDelete($comment_id)
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Проверка на повторное голосование
|
||||
$sql_check = "SELECT id FROM " . PREFIX . "_module_comment_votes WHERE comment_id = '" . $comment_id . "' AND ";
|
||||
// 4. ПРОВЕРКА ПОВТОРНОГО ГОЛОСОВАНИЯ
|
||||
// Ищем в истории, голосовал ли уже этот человек
|
||||
if ($user_id > 0) {
|
||||
$sql_check .= "user_id = '" . $user_id . "'";
|
||||
// Для авторизованных поиск по ID
|
||||
$sql_check = "SELECT id FROM " . PREFIX . "_module_comment_votes
|
||||
WHERE comment_id = '" . $comment_id . "'
|
||||
AND user_id = '" . $user_id . "'";
|
||||
} else {
|
||||
$sql_check .= "anon_key = '" . $anon_key . "'";
|
||||
// Для анонимов поиск по связке Ключ + IP
|
||||
$sql_check = "SELECT id FROM " . PREFIX . "_module_comment_votes
|
||||
WHERE comment_id = '" . $comment_id . "'
|
||||
AND anon_key = '" . $anon_key . "'
|
||||
AND remote_addr = '" . $user_ip . "'";
|
||||
}
|
||||
|
||||
if ($AVE_DB->Query($sql_check)->GetCell()) {
|
||||
@@ -849,15 +876,20 @@ function commentPostDelete($comment_id)
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. Записываем голос в лог
|
||||
// 5. ЗАПИСЬ ГОЛОСА В ЛОГ
|
||||
$AVE_DB->Query("
|
||||
INSERT INTO " . PREFIX . "_module_comment_votes
|
||||
(comment_id, user_id, anon_key, vote_value, date_voted)
|
||||
(comment_id, user_id, anon_key, remote_addr, vote_value, date_voted)
|
||||
VALUES
|
||||
('" . $comment_id . "', '" . $user_id . "', '" . $anon_key . "', '" . $vote_value . "', '" . time() . "')
|
||||
('" . $comment_id . "',
|
||||
'" . $user_id . "',
|
||||
'" . $AVE_DB->escape($anon_key) . "',
|
||||
'" . $AVE_DB->escape($user_ip) . "',
|
||||
'" . $vote_value . "',
|
||||
'" . time() . "')
|
||||
");
|
||||
|
||||
// 6. Обновляем агрегированные данные
|
||||
// 6. ОБНОВЛЕНИЕ АГРЕГАТОВ В ТАБЛИЦЕ INFO
|
||||
$AVE_DB->Query("
|
||||
UPDATE " . PREFIX . "_module_comment_info
|
||||
SET rating_sum = rating_sum + " . $vote_value . ",
|
||||
@@ -865,9 +897,9 @@ function commentPostDelete($comment_id)
|
||||
WHERE Id = '" . $comment_id . "'
|
||||
");
|
||||
|
||||
// 7. ФИНАЛ: Очищаем мусор и отдаем чистый ответ
|
||||
// 7. ФИНАЛ: Чистый ответ для JS
|
||||
if ($ajax) {
|
||||
if (ob_get_length()) ob_end_clean(); // Выбрасываем все Warning-и и HTML
|
||||
if (ob_get_length()) ob_end_clean();
|
||||
echo 'success';
|
||||
exit;
|
||||
}
|
||||
|
||||
20
sql.php
20
sql.php
@@ -4,7 +4,7 @@
|
||||
* AVE.cms - Модуль Комментарии
|
||||
*
|
||||
* Обновленная структура с поддержкой рейтинга (звезд),
|
||||
* идентификации анонимных пользователей и загрузки файлов.
|
||||
* идентификации анонимных пользователей, загрузки файлов и защиты по IP.
|
||||
*/
|
||||
|
||||
$module_sql_install = array();
|
||||
@@ -48,7 +48,7 @@ $module_sql_install[] = "CREATE TABLE `%%PRFX%%_module_comment_info` (
|
||||
`comment_author_email` varchar(255) NOT NULL,
|
||||
`comment_author_city` varchar(255) NOT NULL,
|
||||
`comment_author_website` varchar(255) NOT NULL,
|
||||
`comment_author_ip` varchar(15) NOT NULL,
|
||||
`comment_author_ip` varchar(45) NOT NULL, /* Увеличено для поддержки IPv6 */
|
||||
`anon_key` varchar(32) DEFAULT NULL,
|
||||
`comment_published` int(10) unsigned NOT NULL default '0',
|
||||
`comment_changed` int(10) unsigned NOT NULL default '0',
|
||||
@@ -66,18 +66,20 @@ $module_sql_install[] = "CREATE TABLE `%%PRFX%%_module_comment_info` (
|
||||
KEY `anon_key` (`anon_key`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0;";
|
||||
|
||||
// Таблица для хранения истории голосов (защита от повторов)
|
||||
// Таблица для хранения истории голосов (Добавлено поле remote_addr для защиты по IP)
|
||||
$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 '', /* Поле для хранения IP проголосовавшего */
|
||||
`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 `user_id` (`user_id`),
|
||||
KEY `remote_addr` (`remote_addr`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
|
||||
|
||||
$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);";
|
||||
@@ -99,19 +101,25 @@ $module_sql_update[] = "
|
||||
// Добавляем поля рейтинга в существующую таблицу
|
||||
$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` MODIFY `comment_author_ip` VARCHAR(45) NOT NULL;";
|
||||
|
||||
// Создаем таблицу голосов, если её еще нет
|
||||
// Создаем таблицу голосов с полем IP, если её еще нет
|
||||
$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 `user_id` (`user_id`),
|
||||
KEY `remote_addr` (`remote_addr`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
|
||||
|
||||
// Если таблица уже была, но поля remote_addr в ней нет — добавляем его
|
||||
$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_comment_votes` ADD COLUMN IF NOT EXISTS `remote_addr` VARCHAR(45) DEFAULT '' AFTER `anon_key`;";
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user