diff --git a/README.md b/README.md
index 162b571..dfc4e03 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,22 @@
-# comment
+### comment
-Модуль Комментарии Только для AVE.CMS ALT
\ No newline at end of file
+## Модуль Комментарии v1.26.2a
+
+
+### Данный модуль предназначен для организации системы комментариев для документов на сайте.
+
+ * Для того, чтобы использовать данный модуль, разместите системный тег [mod_comment] в нужном месте шаблона рубрики.
+ * Назначение перемнных в шаблоне
+
+
+
+ * Нужен плагин для jQuery - jquery.form http://malsup.com/jquery/form/
+
+
+### Changelog:
+
+05.09.2019 - версия 1.26.2a - адаптация для версии ave.cms 3.26, fix редиректа при добавлении комментария
+28.05.2015 - версия 1.2.2a
\ No newline at end of file
diff --git a/ReadMe.txt b/ReadMe.txt
new file mode 100644
index 0000000..0777ff6
--- /dev/null
+++ b/ReadMe.txt
@@ -0,0 +1,10 @@
+Шаг 1: Назначение перемнных в шаблоне
+
+
+
+Шаг 2: Нужен плагин для jQuery - jquery.form
+http://malsup.com/jquery/form/
+
diff --git a/class/comment.php b/class/comment.php
new file mode 100644
index 0000000..a8e317a
--- /dev/null
+++ b/class/comment.php
@@ -0,0 +1,874 @@
+Query("
+ SELECT *
+ FROM " . PREFIX . "_module_comments
+ WHERE Id = '" . $this->_config_id . "'
+ ")->FetchAssocArray();
+ }
+
+ if ($param == '')
+ return $settings;
+
+ // В противном случае возвращаем уже имеющиеся значения
+ return (isset($settings[$param])
+ ? $settings[$param]
+ : null);
+ }
+
+ /**
+ * Метод, предназначенный для получения количества комментариев для определенного документа.
+ *
+ * @param int $document_id - идентификатор документа
+ * @return int - количество комментариев
+ */
+ function _commentPostCountGet($document_id)
+ {
+ global $AVE_DB;
+
+ // Определяем статический массив, который будет хранить количество комментариев для документов на
+ // протяжении всего срока жизни объекта.
+ static $comments = array();
+
+ // Если в массиве не найден ключ, который соответствует запрашиваемому документу, тогда выполняем
+ // запрос к БД на получение количества комментариев
+ if (! isset($comments[$document_id]))
+ {
+ $comments[$document_id] = $AVE_DB->Query("
+ SELECT COUNT(*)
+ FROM " . PREFIX . "_module_comment_info
+ WHERE document_id = '" . $document_id . "'
+ ")->GetCell();
+ }
+
+ // Возвращаем количество комментариев для запрашиваемого документа
+ return $comments[$document_id];
+ }
+
+/**
+ * Внешние методы класса
+ */
+
+ /**
+ * Следующие методы описывают работу модуля в Публичной части сайта.
+ */
+
+ /**
+ * Метод, предназначенный для получения из БД всех комментариев, относящихся к указанному
+ * документу с последующим выводом в Публичной части.
+ *
+ * @param string $tpl_dir - путь к шаблонам модуля
+ *
+ * @todo Вывод информации о авторе комментария
+ */
+ function commentListShow($tpl_dir)
+ {
+ global $AVE_DB, $AVE_Template, $AVE_Core;
+
+
+
+ // Проверяем, что в настройках модуля разрешено комментирование документов
+ if ($this->_commentSettingsGet('comment_active') == 1)
+ {
+ $assign['display_comments'] = 1;
+
+ // Если группа пользователя, который в текущий момент просматривает документ попадает в список
+ // разрешенных (в настройках модуля), тогда создаем флаг, который будет разрешать к показу
+ // форму для добавления нового комментария
+ if (in_array(UGROUP, explode(',', $this->_commentSettingsGet('comment_user_groups'))))
+ {
+ $assign['cancomment'] = 1;
+ }
+
+ $assign['comment_max_chars'] = $this->_commentSettingsGet('comment_max_chars');
+ $assign['im'] = $this->_commentSettingsGet('comment_use_antispam');
+
+ // Выполняем запрос к БД на получение количества комментариев для текущего документа
+ $comments = array();
+
+ if ($this->_commentSettingsGet('comment_use_page_nav') == 1)
+ {
+ $limit = $this->_commentSettingsGet('comment_page_nav_count');
+ $start = get_current_page() * $limit - $limit;
+
+ $num = $AVE_DB->Query("
+ SELECT COUNT(*)
+ FROM " . PREFIX . "_module_comment_info
+ WHERE document_id = '" . (int)$_REQUEST['id'] . "'
+ ")->GetCell();
+
+ $sql = $AVE_DB->Query("
+ SELECT *
+ FROM " . PREFIX . "_module_comment_info
+ WHERE document_id = '" . (int)$_REQUEST['id'] . "'
+ " . (UGROUP == 1 ? '' : "AND comment_status = '1'") . "
+ ORDER BY comment_published ASC
+ LIMIT " . $start . "," . $limit . "
+ ");
+
+ $pages = @ceil($num / $limit);
+
+ if ($num > $limit)
+ {
+ $page_nav = '{t} ';
+ $page_nav = get_pagination(ceil($num / $limit), 'page', $page_nav, get_settings('navi_box'));
+ $page_nav = rewrite_link($page_nav);
+ $GLOBALS['page_id'][$_REQUEST['id']]['page']=($GLOBALS['page_id'][$_REQUEST['id']]['page']>ceil($num / $limit) ? $GLOBALS['page_id'][$_REQUEST['id']]['page'] : ceil($num / $limit));
+ }
+ else
+ {
+ $page_nav = '';
+ }
+
+ }
+ else
+ {
+ $sql = $AVE_DB->Query("
+ SELECT *
+ FROM " . PREFIX . "_module_comment_info
+ WHERE document_id = '" . (int)$_REQUEST['id'] . "'
+ " . (UGROUP == 1 ? '' : "AND comment_status = '1'") . "
+ ORDER BY comment_published ASC
+ ");
+
+ $page_nav = '';
+ }
+
+ // Получаем формат даты, который указан в общих настройках системы и
+ // приводим дату создания комментария и дату редактирования к этому формату
+ $date_time_format = $AVE_Template->get_config_vars('COMMENT_DATE_TIME_FORMAT');
+ while ($row = $sql->FetchAssocArray())
+ {
+ $row['comment_published'] = strftime($date_time_format, $row['comment_published']);
+ $row['comment_changed'] = strftime($date_time_format, $row['comment_changed']);
+// if ($row['parent_id'] == 0)
+// $row['comment_text'] = nl2br(wordwrap($row['comment_text'], 100, "\n", true));
+// else
+// $row['comment_text'] = nl2br(wordwrap($row['comment_text'], 90, "\n", true));
+// $row['comment_text'] = nl2br($row['comment_text']);
+
+ $comments[$row['parent_id']][] = $row;
+ }
+
+
+
+ // Формируем ряд переменных для использования в шаблоне
+ $assign['closed'] = @$comments[0][0]['comments_close'];
+ $assign['comments'] = $comments;
+ $assign['theme'] = defined('THEME_FOLDER') ? THEME_FOLDER : DEFAULT_THEME_FOLDER;
+ $assign['doc_id'] = (int)$_REQUEST['id'];
+ $assign['page'] = base64_encode(get_redirect_link());
+ $assign['subtpl'] = $tpl_dir . $this->_comments_tree_sub_tpl;
+
+ $AVE_Template->assign($assign);
+
+ $AVE_Template->assign('page_nav', $page_nav);
+
+ // Отображаем шаблон
+ $AVE_Template->display($tpl_dir . $this->_comments_tree_tpl);
+ }
+ }
+
+ /**
+ * Метод, предназначенный для отображения формы при добавлении нового комментария.
+ *
+ * @param string $tpl_dir - путь к шаблонам модуля
+ */
+ function commentPostFormShow($tpl_dir)
+ {
+ global $AVE_DB, $AVE_Template;
+
+ // Получаем список комментариев на которые запрещены ответы
+ $geschlossen = $AVE_DB->Query("
+ SELECT comments_close
+ FROM " . PREFIX . "_module_comment_info
+ WHERE document_id = '" . (int)$_REQUEST['docid'] . "'
+ LIMIT 1
+ ")->GetCell();
+
+ // Формируем ряд переменных для использования в шаблоне
+ $AVE_Template->assign('closed', $geschlossen);
+ $AVE_Template->assign('cancomment', ($this->_commentSettingsGet('comment_active') == 1 && in_array(UGROUP, explode(',', $this->_commentSettingsGet('comment_user_groups')))));
+ $AVE_Template->assign('comment_max_chars', $this->_commentSettingsGet('comment_max_chars'));
+ $AVE_Template->assign('theme', defined('THEME_FOLDER') ? THEME_FOLDER : DEFAULT_THEME_FOLDER);
+
+ // Отображаем форму для добавления комментария
+ $AVE_Template->display($tpl_dir . $this->_comment_form_tpl);
+ }
+
+ /**
+ * Метод, предназначенный для записи в БД нового комментария.
+ *
+ * @param string $tpl_dir - путь к шаблонам модуля
+ *
+ * @todo Вывод сообщения о результате добавления комментария, а также
+ * рассмотреть вопрос о добавлении еще одного параметра настройки модуля, который будет определять
+ * необходимость отправки уведомления на e-mail о новом комментарии. Возможно не всем хочется получать
+ * уведомления.
+ *
+ */
+ function commentPostNew($tpl_dir)
+ {
+ global $AVE_DB, $AVE_Template;
+ // Если запрос пришел не ajax запросом, тогда формируем ссылку для последующего редиректа
+ if (! $ajax = (isset($_REQUEST['ajax']) && $_REQUEST['ajax'] == 1))
+ {
+ $link = rewrite_link(base64_decode($_REQUEST['page']));
+ }
+
+ // Если в настройках модуля включено использование защитного кода, тогда
+ if ($this->_commentSettingsGet('comment_use_antispam') == 1)
+ {
+ // Если введенный пользователем защитный код неверен, тогда выполняем обновление кода
+ if (! (isset($_SESSION['captcha_keystring']) && isset($_POST['securecode'])
+ && $_SESSION['captcha_keystring'] == $_POST['securecode']))
+ {
+ unset($_SESSION['captcha_keystring']);
+
+ if ($ajax)
+ {
+ echo 'wrong_securecode';
+ }
+ else
+ {
+ if(isset($GLOBALS['tmpl']))$GLOBALS['tmpl']->assign("wrongSecureCode", 1);
+ header('Location:' . $link . '#end');
+ }
+ exit;
+ }
+ unset($_SESSION['captcha_keystring']);
+ }
+
+ // Определяем флаг модерации комментариев
+ $comment_status = ($this->_commentSettingsGet('comment_need_approve') == 1) ? 0 : 1;
+
+ // Если комментарии разрешены, тогда получаем все данные, который пользователь указал в форме
+ if ($this->_commentSettingsGet('comment_active') == 1
+ && !empty($_POST['comment_text'])
+ && !empty($_POST['comment_author_name'])
+ && in_array(UGROUP, explode(',', $this->_commentSettingsGet('comment_user_groups'))))
+ {
+ $new_comment['parent_id'] = (int)$_POST['parent_id'];
+ $new_comment['document_id'] = (int)$_POST['doc_id'];
+ $new_comment['comment_author_name'] = $_POST['comment_author_name'];
+ $new_comment['comment_author_id'] = empty($_SESSION['user_id']) ? '' : $_SESSION['user_id'];
+ $new_comment['comment_author_email'] = $_POST['comment_author_email'];
+ $new_comment['comment_author_city'] = $_POST['comment_author_city'];
+ $new_comment['comment_author_website'] = $_POST['comment_author_website'];
+ $new_comment['comment_author_ip'] = $_SERVER['REMOTE_ADDR'];
+ $new_comment['comment_published'] = time();
+ $new_comment['comment_text'] = $_POST['comment_text'];
+ $new_comment['comment_status'] = $comment_status;
+
+ // Определяем максимальную длину символов для комментария
+ $comment_max_chars = $this->_commentSettingsGet('comment_max_chars');
+ $comment_max_chars = (!empty($comment_max_chars) && $comment_max_chars > 10) ? $comment_max_chars : 200;
+
+ // Если длина комментария превышает максимально допустимую, обрезаем текст, до максимального значения
+ $new_comment['comment_text'] = mb_substr(stripslashes($new_comment['comment_text']), 0, $comment_max_chars);
+ $new_comment['comment_text'] .= (mb_strlen($new_comment['comment_text']) > $comment_max_chars) ? '…' : '';
+// $new_comment['comment_text'] = htmlspecialchars($new_comment['comment_text'], ENT_QUOTES);
+ $new_comment['comment_text'] = pretty_chars($new_comment['comment_text']);
+
+ // Выполняем запрос к БД на добавление комментария
+ $AVE_DB->Query("
+ INSERT INTO " . PREFIX . "_module_comment_info
+ (" . implode(',', array_keys($new_comment)) .")
+ VALUES
+ ('" . implode("','", $new_comment) . "')
+ ");
+ $new_comment['Id'] = $AVE_DB->InsertId();
+
+ // Получаем e-mail адрес из Общих настроек системы и формируем ссылку на комментарий в Публичной части
+ $mail_from = get_settings('mail_from');
+ $mail_from_name = get_settings('mail_from_name');
+ $page = get_home_link() . urldecode(base64_decode($_REQUEST['page'])) . '&subaction=showonly&comment_id=' . $new_comment['Id'] . '#' . $new_comment['Id'];
+
+ // Формируем текст уведомления для отправки на e-mail
+ $mail_text = $AVE_Template->get_config_vars('COMMENT_MESSAGE_ADMIN');
+ $mail_text = str_replace('%COMMENT%', stripslashes($new_comment['comment_text']), $mail_text);
+ $mail_text = str_replace('%N%', "\n", $mail_text);
+ $mail_text = str_replace('%PAGE%', $page, $mail_text);
+ $mail_text = str_replace('&', '&', $mail_text);
+
+ // Отправляем уведомление
+ send_mail(
+ $mail_from,
+ $mail_text,
+ $AVE_Template->get_config_vars('COMMENT_SUBJECT_MAIL'),
+ $mail_from,
+ $mail_from_name,
+ 'text'
+ );
+
+ // Если данные были отправлены ajax-запросом, тогда выполняем автоматический показ комментария
+ // на странице.
+ if ($ajax)
+ {
+ $new_comment['comment_published'] = strftime($AVE_Template->get_config_vars('COMMENT_DATE_TIME_FORMAT'), $new_comment['comment_published']);
+ $subcomments[] = $new_comment;
+ $AVE_Template->assign('subcomments', $subcomments);
+ $AVE_Template->assign('theme', defined('THEME_FOLDER') ? THEME_FOLDER : DEFAULT_THEME_FOLDER);
+ $AVE_Template->display($tpl_dir . $this->_comments_tree_sub_tpl);
+ }
+ }
+
+// $JsAfter = ($comment_status == 0) ? $AVE_Template->get_config_vars('COMMENT_AFTER_MODER') : $AVE_Template->get_config_vars('COMMENT_THANKYOU_TEXT');
+// $AVE_Template->assign('JsAfter', $JsAfter);
+// $AVE_Template->display($tpl_dir . $this->_comment_thankyou_tpl);
+
+ // Если же данные пришли НЕ ajax-запросом, тогда полностью обновляем страницу.
+ if (! $ajax) header('Location:' . str_replace("//", "", $link) . '#end');
+ exit;
+ }
+
+ /**
+ * Метод, предназначенный для редактирования комментария в Публичной части
+ *
+ * @param int $comment_id - идентификатор комментария
+ */
+ function commentPostEdit($comment_id)
+ {
+ global $AVE_DB;
+
+ if (empty($_SESSION['user_id'])) exit;
+
+ $comment_id = intval(preg_replace('/\D/', '', $comment_id));
+
+ // Выполняем запрос к БД и получаем всю информацию о комментарии, а также ряд значений из настроек модуля
+ $row = $AVE_DB->Query("
+ SELECT
+ -- msg.Id,
+ -- msg.document_id,
+ -- msg.comment_author_name,
+ -- msg.comment_author_email,
+ -- msg.comment_author_city,
+ -- msg.comment_author_website,
+ msg.parent_id,
+ msg.comment_text,
+ cmnt.comment_user_groups,
+ cmnt.comment_max_chars,
+ cmnt.comment_need_approve
+ FROM
+ " . PREFIX . "_module_comment_info AS msg,
+ " . PREFIX . "_module_comments AS cmnt
+ WHERE comment_active = '1'
+ AND msg.Id = '" . $comment_id . "'
+ " . ((UGROUP != 1) ? "AND comment_author_id = " . $_SESSION['user_id'] : '') . "
+ ")->FetchAssocArray();
+
+ // Если данные получены
+ if ($row !== false)
+ {
+
+ $comment_max_chars = ($row['comment_max_chars'] != '' && $row['comment_max_chars'] > 10) ? $row['comment_max_chars'] : 20;
+
+ $comment_text = iconv('utf-8', 'cp1251', $_POST['text']);
+
+ // Преобразуем все HTML сущности к числовым аналогам
+ $comment_text = preg_replace_callback('/&([a-zA-Z][a-zA-Z0-9]{1,7});/', 'convert_entity', $comment_text);
+
+ // Форматируем текст сообщения
+ $comment_text = preg_replace('/([0-9a-f]{1,7});/ei', 'chr(hexdec("\\1"))', $comment_text);
+ $comment_text = preg_replace('/([0-9]{1,7});/e', 'chr("\\1")', $comment_text);
+
+ $comment_text = stripslashes($comment_text);
+ $comment_text = str_replace(array("
\n", "
\n", "
\n"), "\n", $comment_text);
+// $comment_text = strip_tags($comment_text);
+ $comment_text = mb_substr($comment_text, 0, $comment_max_chars-1);
+ $message_length = mb_strlen($comment_text);
+ $comment_text .= ($message_length > $comment_max_chars) ? '…' : '';
+// $comment_text = pretty_chars(htmlspecialchars($comment_text, ENT_QUOTES));
+
+ // Если группа текущего пользователя совпадает с разрешенной группой в настройках модуля, тогда
+ // выполняем запрос к БД на обновление информации.
+ if (in_array(UGROUP, explode(',', $row['comment_user_groups'])) && $message_length > 3)
+ {
+ $AVE_DB->Query("
+ UPDATE " . PREFIX . "_module_comment_info
+ SET
+ -- comment_author_name = '" . (empty($_POST['comment_author_name']) ? @addslashes($row['comment_author_name']) : $_POST['comment_author_name']) . "',
+ -- comment_author_email = '" . (empty($_POST['comment_author_email']) ? @addslashes($row['comment_author_email']) : $_POST['comment_author_email']) . "',
+ -- comment_author_city = '" . (empty($_POST['comment_author_city']) ? @addslashes($row['comment_author_city']) : $_POST['comment_author_city']) . "',
+ -- comment_author_website = '" . (empty($_POST['comment_author_website']) ? @addslashes($row['comment_author_website']) : $_POST['comment_author_website']) . "',
+ comment_changed = '" . time() . "',
+ comment_status = '" . intval(!(bool)$row['comment_need_approve']) . "',
+ comment_text = '" . addslashes($comment_text) . "'
+ WHERE
+ Id = '" . $comment_id . "'
+ ");
+
+// if ($row['parent_id'] == 0)
+// echo nl2br(wordwrap($comment_text, 100, "\n", true));
+// else
+// echo nl2br(wordwrap($comment_text, 90, "\n", true));
+// echo nl2br(htmlspecialchars($comment_text, ENT_QUOTES));
+
+ // Преобразуем HTML теги в HTML сущности
+ echo htmlspecialchars($comment_text, ENT_QUOTES);
+ exit;
+ }
+
+// if ($row['parent_id'] == 0)
+// echo nl2br(wordwrap($row['comment_text'], 100, "\n", true));
+// else
+// echo nl2br(wordwrap($row['comment_text'], 90, "\n", true));
+// echo nl2br(htmlspecialchars($row['comment_text'], ENT_QUOTES));
+
+ // Преобразуем HTML теги в HTML сущности
+ echo htmlspecialchars($row['comment_text'], ENT_QUOTES);
+ }
+ exit;
+ }
+
+ /**
+ * Метод, предназначенный для удаления комментария. Если комментарий содержал какие-либо ответы на него,
+ * то все ответы также будут удалены вместе с родительским комментарием.
+ *
+ * @param int $comment_id - идентификатор комментария
+ */
+ function commentPostDelete($comment_id)
+ {
+ global $AVE_DB;
+
+ // Выполняем запрос к БД на удаление родительского комментария
+ $AVE_DB->Query("
+ DELETE
+ FROM " . PREFIX . "_module_comment_info
+ WHERE Id = '" . $comment_id . "'
+ ");
+
+ // Выполняем запрос к БД на удаление дочерних комментариев (ответов)
+ $AVE_DB->Query("
+ DELETE
+ FROM " . PREFIX . "_module_comment_info
+ WHERE parent_id = '" . $comment_id . "'
+ AND parent_id != 0
+ ");
+
+ exit;
+ }
+ function commentAdminDelete($comment_id)
+ {
+ global $AVE_DB;
+
+ // Выполняем запрос к БД на удаление родительского комментария
+ $AVE_DB->Query("
+ DELETE
+ FROM " . PREFIX . "_module_comment_info
+ WHERE Id = '" . $comment_id . "'
+ ");
+
+ // Выполняем запрос к БД на удаление дочерних комментариев (ответов)
+ $AVE_DB->Query("
+ DELETE
+ FROM " . PREFIX . "_module_comment_info
+ WHERE parent_id = '" . $comment_id . "'
+ AND parent_id != 0
+ ");
+ header('Location:index.php?do=modules&action=modedit&mod=comment&moduleaction=1&cp= . SESSION');
+ exit;
+ }
+
+ /**
+ * Метод, предназначенный для вывода детальной информации об авторе комментария
+ *
+ * @param string $tpl_dir - путь к шаблонам модуля
+ */
+ function commentPostInfoShow($tpl_dir)
+ {
+ global $AVE_DB, $AVE_Template;
+
+ // Получаем полную информацию о комментарии
+ $row = $AVE_DB->Query("
+ SELECT *
+ FROM " . PREFIX . "_module_comment_info
+ WHERE Id = '" . (int)$_REQUEST['Id'] . "'
+ ")->FetchAssocArray();
+
+ // Преобразуем адрес сайта к формату ссылки
+ $row['comment_author_website'] = str_replace('http://', '', $row['comment_author_website']);
+ $row['comment_author_website'] = ($row['comment_author_website'] != '') ? '' . $row['comment_author_website'] .'' : '';
+
+ // Выполняем запрос к БД на получение количества всех комментариев, оставленных данным пользователем
+ $row['num'] = $AVE_DB->Query("
+ SELECT COUNT(*)
+ FROM " . PREFIX . "_module_comment_info
+ WHERE comment_author_id = '" . $row['comment_author_id'] . "'
+ AND comment_author_id != 0
+ ")->GetCell();
+
+ // Отображаем окно с информацией
+ $AVE_Template->assign('c', $row);
+ $AVE_Template->display($tpl_dir . $this->_postinfo_tpl);
+ }
+
+ /**
+ * Метод, предназначенный для управления запретом или разрешением отвечать на комментарии
+ *
+ * @param int $comment_id - идентификатор комментария
+ * @param string $comment_status - {lock|unlock} признак запрета/разрешения
+ */
+ function commentReplyStatusSet($comment_id, $comment_status = 'lock')
+ {
+ global $AVE_DB;
+
+ $AVE_DB->Query("
+ UPDATE " . PREFIX . "_module_comment_info
+ SET comment_status = '" . (($comment_status == 'lock') ? 0 : 1) . "'
+ WHERE Id = '" . $comment_id . "'
+ ");
+
+ exit;
+ }
+
+ /**
+ * Метод, предназначенный для управления запретом или разрешением комментировать документ
+ *
+ * @param int $document_id - идентификатор документа
+ * @param string $comment_status - {close|open} признак запрета/разрешения
+ */
+ function commentStatusSet($document_id, $comment_status = 'open')
+ {
+ global $AVE_DB;
+
+ $AVE_DB->Query("
+ UPDATE " . PREFIX . "_module_comment_info
+ SET comments_close = '" . (($comment_status == 'open') ? 0 : 1) . "'
+ WHERE document_id = '" . $document_id . "'
+ ");
+
+ exit;
+ }
+
+ /**
+ * Следующие методы описывают работу модуля в Административной части сайта.
+ */
+
+ /**
+ * Метод, предназначенный для вывода списка всех комментариев в Административной части.
+ *
+ * @param string $tpl_dir - путь к шаблонам модуля
+ */
+ function commentAdminListShow($tpl_dir)
+ {
+ global $AVE_DB, $AVE_Template;
+
+ // Получаем общее количество комментариев
+ $num = $AVE_DB->Query("SELECT COUNT(*) FROM " . PREFIX . "_module_comment_info")->GetCell();
+
+ // Определяем количество страниц, учитывая параметр _limit, который опроеделяет количество
+ // комментариев отображаемых на одной странице
+ @$seiten = @ceil($num / $this->_limit);
+ $start = get_current_page() * $this->_limit - $this->_limit;
+
+ $docs = array();
+
+ $def_sort = 'ORDER BY doc.Id DESC';
+ $def_nav = '';
+
+ // Определяем условия сортировки комментариев
+ if (!empty($_REQUEST['sort']))
+ {
+ switch ($_REQUEST['sort'])
+ {
+ case 'document_desc':
+ $def_sort = 'ORDER BY CId ASC';
+ $def_nav = '&sort=document_desc';
+ break;
+
+ case 'document':
+ $def_sort = 'ORDER BY CId DESC';
+ $def_nav = '&sort=document';
+ break;
+
+ case 'comment_desc':
+ $def_sort = 'ORDER BY cmnt.comment_text ASC';
+ $def_nav = '&sort=comment_desc';
+ break;
+
+ case 'comment':
+ $def_sort = 'ORDER BY cmnt.comment_text DESC';
+ $def_nav = '&sort=comment';
+ break;
+
+ case 'created_desc':
+ $def_sort = 'ORDER BY cmnt.comment_published ASC';
+ $def_nav = '&sort=created_desc';
+ break;
+
+ case 'created':
+ $def_sort = 'ORDER BY cmnt.comment_published DESC';
+ $def_nav = '&sort=created';
+ break;
+ }
+ }
+
+ // Выполняем запрос к БД на получение комметариев с учетом параметров сортировки и лимита.
+ $sql = $AVE_DB->Query("
+ SELECT
+ doc.Id,
+ doc.document_title,
+ cmnt.Id AS CId,
+ cmnt.document_id,
+ cmnt.comment_text,
+ cmnt.comment_published,
+ cmnt.comment_status
+ FROM
+ " . PREFIX . "_module_comment_info AS cmnt
+ JOIN
+ " . PREFIX . "_documents AS doc
+ ON doc.Id = cmnt.document_id
+ " . $def_sort . "
+ LIMIT " . $start . "," . $this->_limit
+ );
+
+ while ($row = $sql->FetchAssocArray())
+ {
+ $row['Comments'] = $this->_commentPostCountGet($row['Id']);
+ array_push($docs, $row);
+ }
+
+ // Если количество комментариев полученных из БД превышает допустимое на странице, тогда формируем
+ // меню постраницной навигации
+ if ($num > $this->_limit)
+ {
+ $page_nav = ' {t} ';
+ $page_nav = get_pagination($seiten, 'page', $page_nav);
+ $AVE_Template->assign('page_nav', $page_nav);
+ }
+
+ // Передаем данные в шаблон для вывода и отображаем шаблон
+ $AVE_Template->assign('docs', $docs);
+ $AVE_Template->assign('content', $AVE_Template->fetch($tpl_dir . $this->_admin_comments_tpl));
+ }
+
+ /**
+ * Метод, предназначенный для редактирования комментариев в Административной части.
+ *
+ * @param string $tpl_dir - путь к шаблонам модуля
+ */
+ function commentAdminPostEdit($tpl_dir)
+ {
+ global $AVE_DB, $AVE_Template;
+
+ // Выполняем запрос к БД на получение информации о редактируемом комментарии
+ $row = $AVE_DB->Query("
+ SELECT *
+ FROM " . PREFIX . "_module_comment_info
+ WHERE Id = '" . (int)$_REQUEST['Id'] . "'
+ LIMIT 1
+ ")->FetchAssocArray();
+
+ // Если в запросе содержится подзапрос на сохранение данных (пользователь уже отредактировал комментарий
+ // и нажал кнопку сохранить изменения), тогда выполняем запрос к БД на обновление информации.
+ if (isset($_POST['sub']) && $_POST['sub'] == 'send' && false != $row)
+ {
+ $AVE_DB->Query("
+ UPDATE " . PREFIX . "_module_comment_info
+ SET
+ comment_author_name = '" . htmlspecialchars($_POST['comment_author_name']) . "',
+ comment_author_email = '" . htmlspecialchars($_POST['comment_author_email']) . "',
+ comment_author_city = '" . htmlspecialchars($_POST['comment_author_city']) . "',
+ comment_author_website = '" . htmlspecialchars($_POST['comment_author_website']) . "',
+ comment_text = '" . htmlspecialchars($_POST['comment_text']) . "',
+ comment_changed = '" . time() . "'
+ WHERE
+ Id = '" . (int)$_POST['Id'] . "'
+ ");
+
+ echo '';
+
+ return;
+ }
+
+ // Если в первой выборке из БД мы получили нулевой результат, тогда генерируем сообщение с ошибкой
+ if ($row == false)
+ {
+ $AVE_Template->assign('editfalse', 1);
+ }
+ // в противном случае получаем список комментариев, у которых стоит запрет на ответы
+ else
+ {
+ $closed = $AVE_DB->Query("
+ SELECT comments_close
+ FROM " . PREFIX . "_module_comment_info
+ WHERE document_id = '" . (int)$_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));
+ }
+
+ /**
+ * Метод, предназначенный для управления настройками модуля
+ *
+ * @param string $tpl_dir - путь к шаблонам модуля
+ */
+ function commentAdminSettingsEdit($tpl_dir)
+ {
+ global $AVE_DB, $AVE_Template;
+
+ // Если в запросе содержится подзапрос на сохранение данных (пользователь нажал кнопку
+ // сохранить изменения), тогда выполняем запрос к БД на обновление информации.
+
+ if (isset($_REQUEST['sub']) && $_REQUEST['sub'] == 'save')
+ {
+ $_POST['comment_max_chars'] = (empty($_POST['comment_max_chars']) || $_POST['comment_max_chars'] < 50) ? 50 : $_POST['comment_max_chars'];
+
+ $AVE_DB->Query("
+ UPDATE " . PREFIX . "_module_comments
+ SET
+ comment_max_chars = '" . @(int)$_POST['comment_max_chars'] . "',
+ comment_user_groups = '" . @implode(',', $_POST['comment_user_groups']) . "',
+ comment_need_approve = '" . @(int)$_POST['comment_need_approve'] . "',
+ comment_active = '" . @(int)$_POST['comment_active'] . "',
+ comment_use_antispam = '" . @(int)$_POST['comment_use_antispam'] . "',
+ comment_use_page_nav = '" . @(int)$_POST['comment_use_page_nav'] . "',
+ comment_page_nav_count = '" . @(int)$_POST['comment_page_nav_count'] . "'
+ WHERE
+ Id = 1
+ ");
+ }
+
+ // Получаем список всех настроек модуля
+ $row = $this->_commentSettingsGet();
+ $row['comment_user_groups'] = explode(',', $row['comment_user_groups']);
+
+ // Передаем данные в шаблон и показываем страницу с настройками модуля
+ $AVE_Template->assign($row);
+ $AVE_Template->assign('content', $AVE_Template->fetch($tpl_dir . $this->_admin_settings_tpl));
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..9c20174
--- /dev/null
+++ b/index.php
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/info.php b/info.php
new file mode 100644
index 0000000..f2f2cfa
--- /dev/null
+++ b/info.php
@@ -0,0 +1,20 @@
+ 'comment',
+ 'ModuleVersion' => '1.26.2a',
+ 'ModuleAutor' => 'AVE.cms Team',
+ 'ModuleCopyright' => '© 2007-' . date('Y') . ' AVE.cms',
+ 'ModuleStatus' => 1,
+ 'ModuleIsFunction' => 1,
+ 'ModuleTemplate' => 0,
+ 'ModuleAdminEdit' => 1,
+ 'ModuleFunction' => 'mod_comment',
+ 'ModuleTag' => '[mod_comment]',
+ 'ModuleTagLink' => null,
+ 'ModuleAveTag' => '#\\\[mod_comment]#',
+ 'ModulePHPTag' => ''
+ );
+?>
\ No newline at end of file
diff --git a/js/comment.js b/js/comment.js
new file mode 100644
index 0000000..c152b4e
--- /dev/null
+++ b/js/comment.js
@@ -0,0 +1,162 @@
+/*Limit symbols*/
+(function($){$.fn.extend({limit:function(limit,element){var interval,f;var self=$(this);$(this).focus(function(){interval=window.setInterval(substring,100)});$(this).blur(function(){clearInterval(interval);substring()});substringFunction="function substring(){ var val = $(self).val();var length = val.length;if(length > limit){$(self).val($(self).val().substring(0,limit));}";if(typeof element!='undefined')substringFunction+="if($(element).html() != limit-length){$(element).html((limit-length<=0)?'0':limit-length);}";substringFunction+="}";eval(substringFunction);substring()}})})(jQuery);
+
+function getCaptha(){
+ now = new Date();
+ $('#captcha img').attr('src', aveabspath+'inc/captcha.php?cd=' + now);
+};
+
+function cAction(obj,action){
+ var cid = $(obj).parents('.mod_comment_box').attr('id');
+ if (action=='answer'){
+ $('#parent_id').val(cid);
+ $('#mod_comment_new').insertAfter('#'+cid);
+ return;
+ }
+ if (UGROUP==1){
+ $.get(aveabspath+'index.php',{
+ module: 'comment',
+ action: action,
+ docid: DOC_ID,
+ Id: cid
+ },function(){
+ if (action=='delete'){
+ $(obj).parents('.mod_comment_comment').eq(0).remove();
+ }
+ if (action=='open'){
+ $(obj).unbind('click')
+ .click(function(){cAction(obj,'close');})
+ .html(COMMENT_SITE_CLOSE);
+ }
+ if (action=='close'){
+ $(obj).unbind('click')
+ .click(function(){cAction(obj,'open');})
+ .html(COMMENT_SITE_OPEN);
+ }
+ if (action=='unlock'){
+ $(obj).unbind('click')
+ .click(function(){cAction(obj,'lock');})
+ .attr('title',COMMENT_LOCK_LINK)
+ .find('img').attr('src',aveabspath+'modules/comment/templates/images/lock.gif');
+ }
+ if (action=='lock'){
+ $(obj).unbind('click')
+ .click(function(){cAction(obj,'unlock');})
+ .attr('title',COMMENT_UNLOCK_LINK)
+ .find('img').attr('src',aveabspath+'modules/comment/templates/images/unlock.gif');
+ }
+ });
+ }
+};
+
+function validate(formData,jqForm,options){
+ $('.alert').remove();
+ var form = jqForm[0];
+ if (!form.comment_author_name.value){
+ alert(COMMENT_ERROR_AUTHOR);
+ $(form.comment_author_name).focus();
+ return false;
+ }
+ if (!form.comment_author_email.value){
+ alert(COMMENT_ERROR_EMAIL);
+ $(form.comment_author_email).focus();
+ return false;
+ }
+ if (!form.comment_text.value){
+ alert(COMMENT_ERROR_TEXT);
+ $(form.comment_text).focus();
+ return false;
+ }
+ if (IS_IM && !form.securecode.value){
+ alert(COMMENT_ERROR_CAPTCHA);
+ $(form.securecode).focus();
+ return false;
+ }
+ return true;
+};
+
+function setClickable(){
+ $('.editable_text').click(function(){
+ var cid = $(this).parents('.mod_comment_box').attr('id');
+ var revert = $(this).html();
+ var textarea = '
'+COMMENT_CHARS_LEFT+'
'; + var buttonSave = ' '; + var buttonReset = ''; + $(this).after('+ + {else} + {if $editfalse==1} + {#COMMENT_EDIT_FALSE#} + {else} + + {/if} + {/if} +
+ + {else} + {if !$cancomment} +
{#COMMENT_NEW_FALSE#}
++ + {else} + + {/if} + {/if} +
| {#COMMENT_USER_NAME#} | +{$c.comment_author_name|stripslashes|escape} | +
| {#COMMENT_DATE_CREATE#} | +{$c.comment_published|date_format:$TIME_FORMAT|pretty_date} | +
| {#COMMENT_USER_EMAIL#} | ++ {assign var=comment_author_email value=$c.comment_author_email} + {mailto address="$comment_author_email" encode="javascript_charcode"} + | +
| {#COMMENT_USER_SITE#} | +{$c.comment_author_website|default:'-'} | +
| {#COMMENT_USER_FROM#} | +{$c.comment_author_city|stripslashes|escape|default:'-'} | +
| {#COMMENT_USER_COMMENTS#} | +{$c.num|default:'-'} | +
| + + + {if $smarty.const.UGROUP==1} + + {/if} + | +
| {$comment_text} | +
{$JsAfter}
+ +|
+
+
+
+
+
+ {#COMMENT_ANSWER_LINK#}
+
+
+ {if $smarty.const.UGROUP==1 || $c.comment_author_id==$smarty.session.user_id}
+
+ {#COMMENT_EDIT_LINK#}
+ {/if}
+
+ {if $smarty.const.UGROUP==1}
+
+ {#COMMENT_DELETE_LINK#}
+
+ {if $c.comment_status!=1}
+
+ {#COMMENT_UNLOCK_LINK#}
+
+ {else}
+
+ {#COMMENT_LOCK_LINK#}
+
+ {/if}
+ {/if}
+ |
+
|
+ {$c.comment_text}
+ {if $c.comment_changed > 1} {#COMMENT_TEXT_CHANGED#} {$c.comment_changed}{/if} + |
+
| + + + + | +
|
+ {$sc.comment_text}
+ {if $sc.comment_changed > 1} {#COMMENT_TEXT_CHANGED#} {$sc.comment_changed}{/if} + |
+
{#COMMENT_NEW_CLOSED#}
+{elseif $cancomment!=1 && $smarty.const.UGROUP!=1} +{#COMMENT_NEW_FALSE#}
+{else} +