commit 05b586c05052256b58be82d67fe1a70d2782b56c Author: Сергей Варламов Date: Fri Jun 10 23:16:09 2016 +0300 Добавлен модуль Комментарии diff --git a/README.md b/README.md new file mode 100644 index 0000000..96fd3f6 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +## comment + +# Модуль Комментарии v1.2.2a + + +## Данный модуль предназначен для организации системы комментариев для документов на сайте. + + * Для того, чтобы использовать данный модуль, разместите системный тег [mod_comment] в нужном месте шаблона рубрики. + * Назначение перемнных в шаблоне + + + + * Нужен плагин для jQuery - jquery.form http://malsup.com/jquery/form/ + + +## Перед копированием модуля в папку modules, удалите файл README.md, копируйте только корневую папку sitemap со всем ее содержимым внутри! + +## Changelog: + +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..5258102 --- /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:' . $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('/&#x([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/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 = '

'; + var charsLeft = '

'+COMMENT_CHARS_LEFT+'

'; + var buttonSave = ' '; + var buttonReset = ''; + $(this).after('
'+COMMENT_EDIT_TITLE + +''+textarea+buttonSave+buttonReset+charsLeft+'
').remove(); + $('.saveButton').click(function(){saveChanges(this,false,cid);}); + $('.cancelButton').click(function(){saveChanges(this,revert,cid);}); + $('#ta_'+cid).limit(MAX_CHARS,'#charsLeft_'+cid); + }) + /*.addClass('tooltip')*/ + .attr('title',COMMENT_EDIT_LINK) + .mouseover(function(){$(this).addClass('editable');}) + .mouseout(function(){$(this).removeClass('editable');}); + $('#in_message').limit(MAX_CHARS,'#charsLeft_new'); + $('.mod_comment_answer').click(function(){cAction(this,'answer');}); + if (UGROUP == 1){ + $('.mod_comment_delete').click(function(){cAction(this,'delete');}); + $('.mod_comment_lock').click(function(){cAction(this,'lock');}); + $('.mod_comment_unlock').click(function(){cAction(this,'unlock');}); + } +}; + +function saveChanges(obj,cancel,cid){ + if (!cancel){ + var t = $(obj).parent().children().children().val(); + $.post(aveabspath+'index.php',{ + module: 'comment', + action: 'edit', + Id: cid, + text: t + }, + function(txt){ + $(obj).parent().parent().parent().after('
'+txt+'
').remove(); + var now = new Date(); + var date = now.toLocaleFormat(COMMENT_DATE_TIME_FORMAT); + $('#'+cid).find('.mod_comment_changed').html(' ('+COMMENT_TEXT_CHANGED+' '+date+')'); + setClickable(); + }); + } + else { + $(obj).parent().parent().parent().after('
'+cancel+'
').remove(); + setClickable(); + } +}; + +function displayNewComment(data){ + if (data=='wrong_securecode'){ + $('#captcha').after('
'+COMMENT_WRONG_CODE+'
'); + $('#securecode').focus(); + } + else { + $('#end'+$('#parent_id').val()).before(data); + $('#parent_id').val(''); + $('#mod_comment_new').insertAfter('#end').resetForm(); + setClickable(); + } + getCaptha(); +}; + +$(document).ready(function(){ + $('#captcha img').click(function(){getCaptha();}); + setClickable(); + $('#mod_comment_new form').submit(function(){ + $(this).ajaxSubmit({ + url: aveabspath+'index.php?ajax=1', + beforeSubmit: validate, + success: displayNewComment, + timeout: 3000 + }); + return false; + }); + $('#buttonReset').click(function(){ + $('#parent_id').val(''); + $('#mod_comment_new').insertAfter('#end').resetForm(); + }); + if (UGROUP==1){ + $('#mod_comment_open').click(function(){cAction(this,'open');}); + $('#mod_comment_close').click(function(){cAction(this,'close');}); + } +}); \ No newline at end of file diff --git a/lang/index.php b/lang/index.php new file mode 100644 index 0000000..5ca71c3 --- /dev/null +++ b/lang/index.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/lang/ru.txt b/lang/ru.txt new file mode 100644 index 0000000..1a08874 --- /dev/null +++ b/lang/ru.txt @@ -0,0 +1,71 @@ +COMMENT_EDIT_TITLE = "Редактирование комментария" +COMMENT_IS_CLOSED = "Редактирование не возможно, поскольку обсуждение закрыто." +COMMENT_CLOSE_BUTTON = "Закрыть окно" +COMMENT_EDIT_FALSE = "Извините, но вы не имеете прав для редактирования." +COMMENT_YOUR_NAME = "* Имя:" +COMMENT_YOUR_EMAIL = "* E-mail:" +COMMENT_YOUR_SITE = "Веб-сайт:" +COMMENT_YOUR_FROM = "Город:" +COMMENT_YOUR_TEXT = "* Комментарий:" +COMMENT_BUTTON_EDIT = "Сохранить изменения" +COMMENT_BUTTON_CANCEL = "Отменить" +COMMENT_BUTTON_RESET = "Очистить" +COMMENT_NEW_TITLE = "Написать комментарий" +COMMENT_NEW_CLOSED = "Извините, но Вы не можете добавить комментарий, поскольку обсуждение закрыто." +COMMENT_NEW_FALSE = "Извините, но у Вас не достаточно прав для добавления комментария." +COMMENT_CHARS_LEFT = "Количество оставшихся символов" +COMMENT_BUTTON_ADD = "Добавить комментарий" +COMMENT_INFO = "Информация о пользователе" +COMMENT_USER_NAME = "Имя пользователя:" +COMMENT_DATE_CREATE = "Опубликовано:" +COMMENT_USER_EMAIL = "E-mail пользователя:" +COMMENT_USER_SITE = "Личный сайт:" +COMMENT_USER_FROM = "Откуда:" +COMMENT_USER_COMMENTS = "Оставил комментариев:" +COMMENT_THANKYOU_TITLE = "Спасибо за комментарий" +COMMENT_THANKYOU_TEXT = "Ваш комментарий успешно добавлен." +COMMENT_SITE_TITLE = "Комментарии пользователей" +COMMENT_SITE_CLOSED = "(комментирование временно отключено)" +COMMENT_SITE_ADD = "Добавить комментарий" +COMMENT_LAST_COMMENT = "Последний комментарий" +COMMENT_SITE_CLOSE = "Запретить комментирование" +COMMENT_SITE_OPEN = "Разрешить комментирование" +COMMENT_USER_ADD = "Опубликовано:" +COMMENT_USER_TIME = "в" +COMMENT_ANSWER_LINK = "Ответить на этот комментарий" +COMMENT_EDIT_LINK = "Редактировать комментарий" +COMMENT_LOCK_LINK = "Заблокировать ответы" +COMMENT_DELETE_LINK = "Удалить комментарий" +COMMENT_UNLOCK_LINK = "Разрешить ответы" +COMMENT_TEXT_CHANGED = "Изменено:" +COMMENT_TEXT_ANSWER = "» Ответил(а):" +COMMENT_AFTER_MODER = "Ваш комментарий добавлен.
Прежде чем, он будет опубликован, он должен пройти проверку Администрацией сайта." +COMMENT_MESSAGE_ADMIN = "На Вашем сайте добавлен новый комментарий:%N%%N%%COMMENT% %N%%N%Для просмотра комментария, перейдите по ссылке:%N%%PAGE%" +COMMENT_SUBJECT_MAIL = "Добавлен новый комментарий" +COMMENT_CHARSET_LEFT = "осталось символов" +COMMENT_FORM_CODE = "Защитный код:" +COMMENT_FORM_CODE_ENTER = "Введите код:" +COMMENT_WRONG_CODE = "Указанный защитный код неверен." +COMMENT_DATE_TIME_FORMAT = "%d-%m-%Y %H:%M" +COMMENT_ERROR_AUTHOR = "Укажите Имя!" +COMMENT_ERROR_EMAIL = "Укажите eMail!" +COMMENT_ERROR_TEXT = "Напишите комментарий!" +COMMENT_ERROR_CAPTCHA = "Укажите защитный код!" + +[admin] +COMMENT_MODULE_NAME = "Комментарии" +COMMENT_MODULE_COMENTS = "Список комментариев" +COMMENT_MODULE_SETTINGS = "Настройки модуля" +COMMENT_TEXT_COMMENT = "Комментарий" +COMMENT_DATE_CREATE = "Дата создания" +COMMENT_DOC_TITLE = "Документ" +COMMENT_DATE_FORMAT = "%d/%m/%Y %H:%M" +COMMENT_ENABLE_COMMENT = "Разрешить комментарии?" +COMMENT_CHECK_ADMIN = "Опубликовывать только после проверки?" +COMMENT_FOR_GROUPS = "Группы пользователей, которым разрешены комментарии:" +COMMENT_MAX_CHARS = "Максимальное количество символов:" +COMMENT_BUTTON_SAVE = "Сохранить настройки" +COMMENT_EDIT = "Редактировать комментарий" +COMMENT_SPAMPROTECT = "Защита от спама" +COMMENT_USE_PAGE_NAV = "Использовать постраничную навигацию" +COMMENT_PAGE_NAV_COUNT = "Кол-во комментариев на странице" diff --git a/module.php b/module.php new file mode 100644 index 0000000..67c0a59 --- /dev/null +++ b/module.php @@ -0,0 +1,169 @@ +[mod_comment] в нужном месте шаблона рубрики.'; + $modul['ModuleAutor'] = 'AVE.CMS Team'; + $modul['ModuleCopyright'] = '© 2007-2013 AVE.CMS'; + $modul['ModuleIsFunction'] = 1; + $modul['ModuleTemplate'] = 0; + $modul['ModuleAdminEdit'] = 1; + $modul['ModuleFunction'] = 'mod_comment'; + $modul['ModuleTag'] = '[mod_comment]'; + $modul['ModuleTagLink'] = null; + $modul['ModuleAveTag'] = '#\\\[mod_comment]#'; + $modul['ModulePHPTag'] = ''; +} + +/** + * Функция, предназначенная для вывода списка комментариев к данному документу. + * Она будет выполнена при парсинге шаблона вместо системного тега [mod_comment]. + */ +function mod_comment() +{ + global $AVE_Template; + + // Подключаем класс и создаем объект дял работы + require_once(BASE_DIR . '/modules/comment/class.comment.php'); + $comment = new Comment; + + // Подключаем языковые файлы + $tpl_dir = BASE_DIR . '/modules/comment/templates/'; + $lang_file = BASE_DIR . '/modules/comment/lang/' . $_SESSION['user_language'] . '.txt'; + $AVE_Template->config_load($lang_file); + + // Обращаемся к методу commentListShow() и отображаем список комментариев + $comment->commentListShow($tpl_dir); +} + +/** + * Следующий раздел описывает правила поведения модуля и его функциональные возможности + * только при работе в Публичной части сайта. + */ + + +// Определяем, что мы не находимся в Панели управления и в строке запроса происходит обращение именно к данному модулю +if (!defined('ACP') && isset($_REQUEST['module']) && $_REQUEST['module'] == 'comment' && isset($_REQUEST['action'])) +{ + // Подключаем основной класс и создаем объект + require_once(BASE_DIR . '/modules/comment/class.comment.php'); + $comment = new Comment; + + // Определяем директори, где хранятся файлы с шаблонами модуля и подключаем языковые переменные + $tpl_dir = BASE_DIR . '/modules/comment/templates/'; + $lang_file = BASE_DIR . '/modules/comment/lang/' . $_SESSION['user_language'] . '.txt'; + $AVE_Template->config_load($lang_file); + + // Определяем, какой параметр пришел из строки запроса браузера + switch($_REQUEST['action']) + { + // Если form, тогда отображаем форму для добавления нового комментария + case 'form': + $comment->commentPostFormShow($tpl_dir); + break; + + // Если comment, тогда производим запись нового комментария в БД + case 'comment': + $comment->commentPostNew($tpl_dir); + break; + + // Если edit, тогда открываем форму для редактирования текста комментария + case 'edit': + $comment->commentPostEdit((int)$_REQUEST['Id']); + break; + + + // Если delete, тогда удаляем комментарий + case 'delete': + if (UGROUP==1) + { + $comment->commentPostDelete((int)$_REQUEST['Id']); + } + break; + + // Если postinfo, тогда отображаем окно с информацией об авторе комментария + case 'postinfo': + $comment->commentPostInfoShow($tpl_dir); + break; + + // Если lock или unlock, тогда запрещаем или разрешаем оставлять ответы для имеющихся комментариев + case 'lock': + case 'unlock': + if (UGROUP==1) + { + $comment->commentReplyStatusSet((int)$_REQUEST['Id'], $_REQUEST['action']); + } + break; + + + // Если open или close, тогда разрешаем или запрещаем полное комментирование документа + case 'open': + case 'close': + if (UGROUP==1) + { + $comment->commentStatusSet((int)$_REQUEST['docid'], $_REQUEST['action']); + } + break; + } +} + +/** + * Следующий раздел описывает правила поведения модуля и его функциональные возможности + * только при работе в Административной части сайта. + */ +if (defined('ACP') && !empty($_REQUEST['moduleaction'])) +{ + // Подключаем основной класс и создаем объект + require_once(BASE_DIR . '/modules/comment/class.comment.php'); + $comment = new Comment; + + // Определяем директори, где хранятся файлы с шаблонами модуля и подключаем языковые переменные + $tpl_dir = BASE_DIR . '/modules/comment/templates/'; + $lang_file = BASE_DIR . '/modules/comment/lang/' . $_SESSION['admin_language'] . '.txt'; + $AVE_Template->config_load($lang_file, 'admin'); + + + // Определяем, какой параметр пришел из строки запроса браузера + switch ($_REQUEST['moduleaction']) + { + + // Если 1, тогда отображаем список всех комментариев с постраничной навигацией + case '1': + $comment->commentAdminListShow($tpl_dir); + break; + + // Если admin_edit, тогда открываем форму для редактирования выбранного комментария + case 'admin_edit': + $comment->commentAdminPostEdit($tpl_dir); + break; + + // Если settings, тогда открываем страницу с настройками данного модуля + case 'settings': + // Подключаем файл класса для работы с пользователями, создаем объект и получаем список + // всех групп пользователей, имеющихся в системе. + require_once(BASE_DIR . '/class/class.user.php'); + $AVE_User = new AVE_User; + $AVE_Template->assign('groups', $AVE_User->userGroupListGet()); + + $comment->commentAdminSettingsEdit($tpl_dir); + break; + case 'admin_del': + $comment->commentAdminDelete((int)$_REQUEST['Id']); + break; + } +} + +?> \ No newline at end of file diff --git a/sql.php b/sql.php new file mode 100644 index 0000000..e9efa1d --- /dev/null +++ b/sql.php @@ -0,0 +1,87 @@ + \ No newline at end of file diff --git a/templates/admin_comments.tpl b/templates/admin_comments.tpl new file mode 100644 index 0000000..3266559 --- /dev/null +++ b/templates/admin_comments.tpl @@ -0,0 +1,83 @@ + + +
{#COMMENT_MODULE_NAME#}
+ +
+
+ {#COMMENT_MODULE_COMENTS#} +
+
+ + + + + +
+
+
{#COMMENT_MODULE_COMENTS#}
+ +
+ + + + + + + + + + + + + + + + + + + {if $docs} + {foreach from=$docs item=doc} + + + + + + + + + {/foreach} + {else} + + + + {/if} + +
{#COMMENT_TEXT_COMMENT#} {#COMMENT_DATE_CREATE#} {#COMMENT_DOC_TITLE#} Действия
{if $doc.comment_status != "0"}{else}{/if}{$doc.comment_text|escape|truncate:'100'}{$doc.comment_published|date_format:$TIME_FORMAT|pretty_date}{$doc.document_title|escape} ({$doc.Comments})
+
    +
  • Сообщение:
    Нет комментариев.
  • +
+
+
+ +{if $page_nav} + +{/if} diff --git a/templates/admin_edit.tpl b/templates/admin_edit.tpl new file mode 100644 index 0000000..487ceae --- /dev/null +++ b/templates/admin_edit.tpl @@ -0,0 +1,112 @@ + + +
+ +
{#COMMENT_MODULE_NAME#}
+ +
+
+ {#COMMENT_EDIT_TITLE#} +
+
+ + + +
+ {if $closed == 1 && $smarty.const.UGROUP != 1} + + {#COMMENT_IS_CLOSED#} + +

+ {else} + {if $editfalse==1} + {#COMMENT_EDIT_FALSE#} + {else} +
+ + + {if $smarty.const.UGROUP == 1} + + + + + + + + + + {else} + + + {/if} + + + + + + + + + + + + + + + + + + + + + + + + + + +
{#COMMENT_YOUR_NAME#}
{#COMMENT_YOUR_EMAIL#}
{#COMMENT_YOUR_SITE#}
{#COMMENT_YOUR_FROM#}
{#COMMENT_YOUR_TEXT#} +
+  {#COMMENT_CHARS_LEFT#} +
+   + +
+ + +
+ {/if} + {/if} + +
\ No newline at end of file diff --git a/templates/admin_settings.tpl b/templates/admin_settings.tpl new file mode 100644 index 0000000..22db60b --- /dev/null +++ b/templates/admin_settings.tpl @@ -0,0 +1,88 @@ +
{#COMMENT_MODULE_NAME#}
+ +
+
+ {#COMMENT_MODULE_SETTINGS#} +
+
+ + + + +
+
+
{#COMMENT_MODULE_SETTINGS#}
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{#COMMENT_ENABLE_COMMENT#}
{#COMMENT_CHECK_ADMIN#} + +
{#COMMENT_SPAMPROTECT#} + +
{#COMMENT_USE_PAGE_NAV#} + +
{#COMMENT_PAGE_NAV_COUNT#} + +
{#COMMENT_FOR_GROUPS#} + +
{#COMMENT_MAX_CHARS#}
+ +
+
\ No newline at end of file diff --git a/templates/comment_edit.tpl b/templates/comment_edit.tpl new file mode 100644 index 0000000..612a07d --- /dev/null +++ b/templates/comment_edit.tpl @@ -0,0 +1,71 @@ + + + + + +{#COMMENT_EDIT_TITLE#} + + + + + +

{#COMMENT_EDIT_TITLE#}

+ +
+ {if $closed == 1 && $smarty.const.UGROUP != 1} + {#COMMENT_IS_CLOSED#} +

 

+

+ {else} + {if $editfalse==1} + {#COMMENT_EDIT_FALSE#} + {else} +
+ {if $smarty.const.UGROUP==1} +
+ + +
+ +
+ + +
+ {else} + + + {/if} + +
+ + +
+ +
+ + +
+ +
+ + + {#COMMENT_CHARS_LEFT#} +
+ + + + + + + + +

+   + +

+
+ {/if} + {/if} +
+ + \ No newline at end of file diff --git a/templates/comment_form.tpl b/templates/comment_form.tpl new file mode 100644 index 0000000..1fdf808 --- /dev/null +++ b/templates/comment_form.tpl @@ -0,0 +1,84 @@ + + + + + +{#COMMENT_NEW_TITLE#} + + + + + + +

{#COMMENT_NEW_TITLE#}

+ +
+ {if $closed==1} + {#COMMENT_NEW_CLOSED#} +

 

+

+ {else} + {if !$cancomment} +

{#COMMENT_NEW_FALSE#}

+

 

+

+ {else} +
+ {if $smarty.session.user_name != ''} + + {else} +
+ + +
+
+ {/if} + + {if $smarty.session.user_email != ''} + + {else} +
+ + +
+
+ {/if} + +
+ + +
+
+ +
+ + +
+
+ +
+ + + {#COMMENT_CHARSET_LEFT#} +
+ + + + + + + + + + +

+   + +

+
+ {/if} + {/if} +
+ + + \ No newline at end of file diff --git a/templates/comment_info.tpl b/templates/comment_info.tpl new file mode 100644 index 0000000..86a5777 --- /dev/null +++ b/templates/comment_info.tpl @@ -0,0 +1,54 @@ + + + + + +{#COMMENT_INFO#} + + + + + +

{#COMMENT_INFO#}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{#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:'-'}
+ +

+
+ + + \ No newline at end of file diff --git a/templates/comment_new.tpl b/templates/comment_new.tpl new file mode 100644 index 0000000..6a7d8d8 --- /dev/null +++ b/templates/comment_new.tpl @@ -0,0 +1,24 @@ + + + + + + + + +
+
+ {#COMMENT_USER_ADD#} {$comment_author_name} • {$smarty.now|date_format:$TIME_FORMAT|pretty_date}{if $smarty.const.UGROUP==1} • IP:{$comment_author_ip}{/if} +
+ + {if $smarty.const.UGROUP==1} +
+   + {if $comment_status!=1} +   + {else} +   + {/if} +
+ {/if} +
{$comment_text}
\ No newline at end of file diff --git a/templates/comment_thankyou.tpl b/templates/comment_thankyou.tpl new file mode 100644 index 0000000..4856327 --- /dev/null +++ b/templates/comment_thankyou.tpl @@ -0,0 +1,15 @@ + + + + +{#COMMENT_THANKYOU_TITLE#} + + + +

{#COMMENT_THANKYOU_TITLE#}

+
+

{$JsAfter}

+ +
+ + \ No newline at end of file diff --git a/templates/comments_show.tpl b/templates/comments_show.tpl new file mode 100644 index 0000000..cb448c8 --- /dev/null +++ b/templates/comments_show.tpl @@ -0,0 +1,122 @@ +{if $display_comments==1}
+ +
{#COMMENT_SITE_TITLE#}{if $closed==1} {#COMMENT_SITE_CLOSED#}{/if}
+ +{if $cancomment==1 && $closed!=1} + {#COMMENT_SITE_ADD#} |  +{/if} + +{#COMMENT_LAST_COMMENT#} + +{if $smarty.const.UGROUP == 1} +  |  + {if $closed==1} + {#COMMENT_SITE_OPEN#} + {else} + {#COMMENT_SITE_CLOSE#} + {/if} +{/if}
+
+ +{foreach from=$comments.0 item=c name=co} + {if $smarty.request.subaction=='showonly' && $smarty.request.comment_id==$c.Id} +
+ {/if} + + + + + + + + + +
+
+ {#COMMENT_USER_ADD#} {$c.comment_author_name}{*|stripslashes|escape:html*} • {$c.comment_published}{if $smarty.const.UGROUP==1} • IP:{$c.comment_author_ip}{/if} +
+ +
+ + {#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} +
+ + {if $smarty.request.subaction=='showonly' && $smarty.request.comment_id==$c.Id} +
+ {/if} + + {foreach from=$comments[$c.Id] item=sc} +
+ {if $smarty.request.subaction=='showonly' && $smarty.request.comment_id==$sc.Id} +
+ {/if} + + + + + + + + + +
+
+ {#COMMENT_TEXT_ANSWER#} {$sc.comment_author_name}{*|stripslashes|escape:html*} ({$sc.comment_published}){if $smarty.const.UGROUP==1} IP:{$sc.comment_author_ip}{/if} +
+ +
+ {if $smarty.const.UGROUP==1 || $sc.comment_author_id==$smarty.session.user_id} + + {/if} + + {if $smarty.const.UGROUP==1} + + {if $sc.comment_status!=1} + + {else} + + {/if} + {else} +   + {/if} +
+
+ {$sc.comment_text} + {if $sc.comment_changed > 1}
{#COMMENT_TEXT_CHANGED#} {$sc.comment_changed}{/if} +
+ + {if $smarty.request.subaction=='showonly' && $smarty.request.comment_id==$sc.Id} +
+ {/if} +
+ {/foreach} +{/foreach} + +{if $smarty.foreach.co.last}{/if} + +{/if} \ No newline at end of file diff --git a/templates/comments_tree.tpl b/templates/comments_tree.tpl new file mode 100644 index 0000000..73d8cf8 --- /dev/null +++ b/templates/comments_tree.tpl @@ -0,0 +1,110 @@ +{if $display_comments==1} +

{#COMMENT_SITE_TITLE#}{if $closed==1 && $smarty.const.UGROUP!=1} {#COMMENT_SITE_CLOSED#}{/if}

+ +{#COMMENT_SITE_ADD#} + +{if $smarty.const.UGROUP==1} +  |  + {if $closed==1} + {#COMMENT_SITE_OPEN#} + {else} + {#COMMENT_SITE_CLOSE#} + {/if}
+{/if} + +{if $comments[0]} + {include file="$subtpl" subcomments=$comments[0]} +{/if} + + + +{if $closed==1 && $smarty.const.UGROUP!=1} +

{#COMMENT_NEW_CLOSED#}

+{elseif $cancomment!=1 && $smarty.const.UGROUP!=1} +

{#COMMENT_NEW_FALSE#}

+{else} +
+

{#COMMENT_NEW_TITLE#}

+ +
+
+
+ {if $smarty.session.user_group != '2'} + + {else} +

+ +   +

+ {/if} + {if $smarty.session.user_email != ''} + + {else} + + {/if} + + + + + + + +

+ + {#COMMENT_CHARS_LEFT#} - +

+ {if $im} +

+ + +

+

+ + +

+ {/if} +

+ + +

+ + + + + + + +
+
+
+
+ +{if $page_nav} + +{/if} + + + +{/if} +{/if} \ No newline at end of file diff --git a/templates/comments_tree_sub.tpl b/templates/comments_tree_sub.tpl new file mode 100644 index 0000000..1f9129f --- /dev/null +++ b/templates/comments_tree_sub.tpl @@ -0,0 +1,41 @@ +{foreach from=$subcomments item=c} +
+ + {if $smarty.request.subaction=='showonly' && $smarty.request.comment_id==$c.Id} +
+ {/if} + +
+
+
+ {#COMMENT_USER_ADD#} {$c.comment_author_name|stripslashes|escape} • {$c.comment_published}{if $smarty.const.UGROUP==1} • IP:{$c.comment_author_ip}{/if} + {if $c.comment_changed > 1} ({#COMMENT_TEXT_CHANGED#} {$c.comment_changed}){/if} +
+ +
+ {if $c.comment_author_id!=$smarty.session.user_id|default:'*' && (($cancomment==1 && $closed!=1) || $smarty.const.UGROUP==1)} + + {/if} + {if $smarty.const.UGROUP==1} + {if $c.comment_status!=1}  + {else}  + {/if}  + {/if} +
+
+ +
{$c.comment_text|escape}
+
+ + {if $smarty.request.subaction=='showonly' && $smarty.request.comment_id==$c.Id} +
+ {/if} + + {if $comments[$c.Id]} + {include file="$subtpl" subcomments=$comments[$c.Id] sub=1} + {/if} + + + +
+{/foreach} \ No newline at end of file diff --git a/templates/images/edit.gif b/templates/images/edit.gif new file mode 100644 index 0000000..1e024c1 Binary files /dev/null and b/templates/images/edit.gif differ diff --git a/templates/images/lock.gif b/templates/images/lock.gif new file mode 100644 index 0000000..7d2e8a9 Binary files /dev/null and b/templates/images/lock.gif differ diff --git a/templates/images/reply.gif b/templates/images/reply.gif new file mode 100644 index 0000000..16b6c61 Binary files /dev/null and b/templates/images/reply.gif differ diff --git a/templates/images/trash.gif b/templates/images/trash.gif new file mode 100644 index 0000000..f1b4afd Binary files /dev/null and b/templates/images/trash.gif differ diff --git a/templates/images/unlock.gif b/templates/images/unlock.gif new file mode 100644 index 0000000..edcaadd Binary files /dev/null and b/templates/images/unlock.gif differ diff --git a/templates/index.php b/templates/index.php new file mode 100644 index 0000000..4ca25aa --- /dev/null +++ b/templates/index.php @@ -0,0 +1,4 @@ + \ No newline at end of file