diff --git a/class/comment.php b/class/comment.php index 8b98e1e..38ac646 100644 --- a/class/comment.php +++ b/class/comment.php @@ -108,6 +108,10 @@ class Comment public $conf_cookie_life; private $_anon_cookie_name = 'ave_anon_comment_key'; + /** + * Редактирование Авторской оценки (1-разрешено, 0-запрещено) + */ + private $_edit_avtor_rating = 1; /** * Конструктор класса @@ -1751,85 +1755,165 @@ $AVE_Template->assign([ + + + + + /** * Метод, предназначенный для редактирования комментариев в Административной части. * * @param string $tpl_dir - путь к шаблонам модуля */ - function commentAdminPostEdit($tpl_dir) +function commentAdminPostEdit($tpl_dir) +{ + global $AVE_DB, $AVE_Template; + + $post_sub = $_POST['sub'] ?? ''; + $request_id = (int)($_REQUEST['Id'] ?? 0); + $is_ajax = isset($_REQUEST['ajax']); + + // 1. Получаем данные и настройки одним запросом + $row = $AVE_DB->Query(" + SELECT + msg.*, + cmnt.comment_allowed_extensions, + cmnt.comment_max_file_size, + cmnt.comment_max_files, + cmnt.comment_allow_files, + cmnt.comment_show_f1, + cmnt.comment_show_f2, + cmnt.comment_show_user_rating + FROM " . PREFIX . "_module_comment_info AS msg + JOIN " . PREFIX . "_module_comments AS cmnt ON cmnt.Id = 1 + WHERE msg.Id = '" . (int)$request_id . "' + LIMIT 1 + ")->FetchAssocArray(); + + if ($post_sub == 'send' && $row) { - global $AVE_DB, $AVE_Template; + $upload_dir = BASE_DIR . '/uploads/comments/'; + // Получаем массив текущих файлов (разбиваем по запятой) + $current_files = !empty($row['comment_file']) ? explode(',', $row['comment_file']) : []; - // Используем оператор объединения с null для PHP 8.4 - $post_sub = $_POST['sub'] ?? ''; - $request_id = (int)($_REQUEST['Id'] ?? 0); - $request_docid = (int)($_REQUEST['docid'] ?? 0); - $is_ajax = isset($_REQUEST['ajax']); + // --- А. Удаление файлов --- + if (!empty($_POST['delete_files'])) { + $files_to_remove = (array)$_POST['delete_files']; + foreach ($files_to_remove as $rem_file) { + $rem_file = basename(trim($rem_file)); // Очистка имени для безопасности + if (empty($rem_file)) continue; - // Выполняем запрос к БД на получение информации о редактируемом комментарии - $row = $AVE_DB->Query(" - SELECT * - FROM " . PREFIX . "_module_comment_info - WHERE Id = '" . $request_id . "' - LIMIT 1 - ")->FetchAssocArray(); + if (file_exists($upload_dir . $rem_file)) { + @unlink($upload_dir . $rem_file); + } + // Используем стрелочную функцию (PHP 7.4+) + $current_files = array_filter($current_files, fn($v) => trim($v) !== $rem_file); + } + } - // Если в запросе содержится подзапрос на сохранение данных - if ($post_sub == 'send' && false != $row) - { - // Экранирование данных перед сохранением - $AVE_DB->Query(" - UPDATE " . PREFIX . "_module_comment_info - SET - comment_author_name = '" . addslashes(htmlspecialchars($_POST['comment_author_name'] ?? '')) . "', - comment_author_email = '" . addslashes(htmlspecialchars($_POST['comment_author_email'] ?? '')) . "', - comment_author_city = '" . addslashes(htmlspecialchars($_POST['comment_author_city'] ?? '')) . "', - comment_author_website = '" . addslashes(htmlspecialchars($_POST['comment_author_website'] ?? '')) . "', - comment_text = '" . addslashes(htmlspecialchars($_POST['comment_text'] ?? '')) . "', - comment_changed = '" . time() . "' - WHERE - Id = '" . (int)($_POST['Id'] ?? 0) . "' - "); - - // Если это AJAX-запрос (наша новая модалка), отдаем JSON - if ($is_ajax) { - header('Content-Type: application/json'); - echo json_encode([ - 'status' => 'success', - 'theme' => 'success', - 'header' => 'Обновлено', // Можно заменить на переменную из языкового файла - 'message' => 'Изменения успешно сохранены' - ]); - exit; + // --- Б. Загрузка новых файлов --- + if ($row['comment_allow_files'] == 1 && isset($_FILES['comment_image']) && is_array($_FILES['comment_image']['name'])) { + + if (!is_dir($upload_dir)) { + @mkdir($upload_dir, 0775, true); + @file_put_contents($upload_dir . 'index.php', " trim(strtolower($e)), explode(',', $allowed_ext_str)); + $max_file_size_bytes = (int)($row['comment_max_file_size'] ?? 2048) * 1024; + + $processed_hashes = []; + + foreach ($_FILES['comment_image']['name'] as $k => $fname) { + if ($_FILES['comment_image']['error'][$k] == UPLOAD_ERR_OK) { + // Важно: проверяем лимит на каждой итерации + if (count($current_files) >= $max_limit) break; + + $tmp_name = $_FILES['comment_image']['tmp_name'][$k]; + $file_size = $_FILES['comment_image']['size'][$k]; + $file_hash = md5_file($tmp_name); + + if (in_array($file_hash, $processed_hashes)) continue; + + $ext = strtolower(pathinfo($fname, PATHINFO_EXTENSION)); + $is_allowed_ext = in_array($ext, $allowed_extensions); + $is_dangerous = in_array($ext, ['php', 'php3', 'php4', 'php5', 'phtml', 'exe', 'pl', 'cgi', 'html', 'js']); + + if ($is_allowed_ext && !$is_dangerous && $file_size > 0 && $file_size <= $max_file_size_bytes) { + $clean_name = function_exists('prepare_fname') ? prepare_fname(pathinfo($fname, PATHINFO_FILENAME)) : 'file'; + if (empty($clean_name)) $clean_name = 'file'; + + $new_name = $clean_name . '_' . time() . '_' . rand(100,999) . '.' . $ext; + + if (move_uploaded_file($tmp_name, $upload_dir . $new_name)) { + $current_files[] = $new_name; + $processed_hashes[] = $file_hash; + } + } + } + } + } + + // Финальная строка файлов для базы + $final_files_str = implode(',', array_unique(array_filter($current_files))); + + // --- В. Рейтинг --- + $new_rating = ($this->_edit_avtor_rating == 1 && isset($_POST['user_rating'])) + ? (int)$_POST['user_rating'] + : (int)($row['user_rating'] ?? 0); + + if ($new_rating < 0) $new_rating = 0; + if ($new_rating > 5) $new_rating = 5; + + // Обновление БД + $AVE_DB->Query(" + UPDATE " . PREFIX . "_module_comment_info + SET + comment_author_name = '" . addslashes(htmlspecialchars($_POST['comment_author_name'] ?? '')) . "', + comment_author_email = '" . addslashes(htmlspecialchars($_POST['comment_author_email'] ?? '')) . "', + comment_author_city = '" . addslashes(htmlspecialchars($_POST['comment_author_city'] ?? '')) . "', + comment_author_website = '" . addslashes(htmlspecialchars($_POST['comment_author_website'] ?? '')) . "', + comment_text = '" . addslashes(htmlspecialchars($_POST['comment_text'] ?? '')) . "', + user_rating = '" . $new_rating . "', + comment_file = '" . addslashes($final_files_str) . "', + comment_changed = '" . time() . "' + WHERE Id = '" . (int)$request_id . "' + "); + + if ($is_ajax) { + header('Content-Type: application/json'); + echo json_encode([ + 'status' => 'success', + 'theme' => 'success', + 'header' => 'Обновлено', + 'message' => 'Данные успешно сохранены' + ]); exit; } - - // Если в первой выборке из БД получили нулевой результат - if ($row == false) - { - $AVE_Template->assign('editfalse', 1); - } - else - { - $closed = $AVE_DB->Query(" - SELECT comments_close - FROM " . PREFIX . "_module_comment_info - WHERE document_id = '" . $request_docid . "' - LIMIT 1 - ")->GetCell(); - - $AVE_Template->assign('closed', $closed); - $AVE_Template->assign('row', $row); - $AVE_Template->assign('comment_max_chars', $this->_commentSettingsGet('comment_max_chars')); - } - - // Отображаем шаблон - $AVE_Template->assign('content', $AVE_Template->fetch($tpl_dir . $this->_admin_edit_link_tpl)); + exit; } + if (!$row) { + $AVE_Template->assign('editfalse', 1); + } else { + $row['file_list'] = !empty($row['comment_file']) ? explode(',', $row['comment_file']) : []; + $AVE_Template->assign('row', $row); + $AVE_Template->assign('edit_rating_enabled', $this->_edit_avtor_rating); + $AVE_Template->assign('comment_max_chars', (int)$this->_commentSettingsGet('comment_max_chars')); + } + $AVE_Template->assign('content', $AVE_Template->fetch($tpl_dir . $this->_admin_edit_link_tpl)); +} + + + + + + + + + /** * Метод, предназначенный для управления настройками модуля * diff --git a/lang/ru.txt b/lang/ru.txt index 29864dc..d110127 100644 --- a/lang/ru.txt +++ b/lang/ru.txt @@ -230,7 +230,7 @@ COMMENT_ICON_EDIT_ADM = "Редактировать" COMMENT_ICON_DEL_SOFT = "Мягкое удаление/заменяет текст (сохраняет ветку)" COMMENT_ICON_DEL_HARD = "Удалить навсегда (вместе с веткой)" COMMENT_NOT_COOMENTS_MES = "Сообщение:" -COMMENT_NOT_COOMENTS_MES_A = "Нет комментариев." +COMMENT_NOT_COOMENTS_MES_A = "Комментарии не найдены..." COMMENT_ACTION_SELECT = "Выберите действие..." COMMENT_ACTION_SELECT_PUB = "Опубликовать" COMMENT_ACTION_HIDE = "Скрыть" diff --git a/templates/admin_comments.tpl b/templates/admin_comments.tpl index 22c9b42..b4366eb 100644 --- a/templates/admin_comments.tpl +++ b/templates/admin_comments.tpl @@ -521,7 +521,7 @@ {* ИЗМЕНЕНО: Добавлены параметры в href *} {if $row.has_children} diff --git a/templates/admin_edit.tpl b/templates/admin_edit.tpl index df0aaad..66adb33 100644 --- a/templates/admin_edit.tpl +++ b/templates/admin_edit.tpl @@ -1,164 +1,279 @@ -
+
- {if $closed == 1 && $smarty.const.UGROUP != 1} -
- {#COMMENT_IS_CLOSED#} -

- {#COMMENT_CLOSE_BUTTON#} -

-
+ {if $editfalse == 1} +
{#COMMENT_EDIT_FALSE#}
{else} - {if $editfalse == 1} -
{#COMMENT_EDIT_FALSE#}
- {else} -
- - - - {if $smarty.const.UGROUP == 1} - - - - - - - - - {else} - - - {/if} + +
{#COMMENT_YOUR_NAME#}
{#COMMENT_YOUR_EMAIL#}
+ + + + + + + + + + - - - - + {if $row.comment_show_f2 == 1} + + + + + {/if} - - - - + {if $row.comment_show_f1 == 1} + + + + + {/if} - - - + + + + {/if} + + + + - + + {/if} + + - - - - - - + + + + - - + - -
{#COMMENT_YOUR_NAME#}*
{#COMMENT_YOUR_EMAIL#}*
{#COMMENT_YOUR_SITE#}
{#COMMENT_YOUR_SITE#}
{#COMMENT_YOUR_FROM#}
{#COMMENT_YOUR_FROM#}
{#COMMENT_YOUR_TEXT#} -
- + {if $row.comment_show_user_rating == 1} +
{#COMMENT_RATING_TITEL#} +
+ + {section name=r start=1 loop=6} + + {/section} + × +
+
{#COMMENT_FILES#} +
+ {foreach from=$row.file_list item=file} + {assign var="fileExt" value=$file|substr:-3|lower} +
+ + {if $fileExt == 'jpg' || $fileExt == 'png' || $fileExt == 'gif' || $fileExt == 'ebp' || $fileExt == 'peg'} + + {else} +
{$fileExt}
+ {/if} + {$file|regex_replace:"/^[0-9]+_/":""} +
+ {/foreach} +
+ + {if $row.comment_allow_files == 1} +
+ +
+ {#COMMENT_ADD_FILES_ALLOW#}: {$row.comment_allowed_extensions} (max: {$row.comment_max_files})
-  {#COMMENT_CHARS_LEFT#} -
{#COMMENT_YOUR_TEXT#}* + +
+ {#COMMENT_CHARS_LEFT#} +
+
+ + + + + + + +
+
+
-
- {/if} +
+ + + + {/if} \ No newline at end of file