diff --git a/README.md b/README.md index 4fd82fe..2e0c576 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,17 @@ ### poll -## Модуль Опросы/Голосование v1.26.1a +## Модуль Опросы/Голосование v3.31 +### для AVE.CMS ALT ≥ v3.31 -### Данный модуль предназачен для организации системы опросов на сайте. +### Данный модуль предназачен для организации системы опросов на сайте с возможностью оставлять комментарии. * Возможности модуля позволяют создавать неограниченное количество опросных листов, а также неограниченное количество вопросов. - * Добавить в .htaccess (вне секции | Rewrite engine )
- - ### Poll
- RewriteRule ^poll-([0-9]+).html$ index.php?module=poll&action=result&pid=$1
- RewriteRule ^pollcomment-([0-9]+).html$ index.php?module=poll&action=form&pop=1&pid=$1
- RewriteRule ^poll-archive.html$ index.php?module=poll&action=archive
+ ### Changelog: +29.03.2026 - обновление модуля - версия 3.31 - рефакторинг кода для работы в ave.cms ALT v3.31. Добавлена Captcha. Реализована поддержка ЧПУ-алиасов для внутренних ссылок модуля. + 04.09.2019 - версия 1.26.1а - адаптация для ave.cms 3.26 22.09.2013 - версия 1.1a \ No newline at end of file diff --git a/ReadMe.txt b/ReadMe.txt deleted file mode 100644 index a1834cf..0000000 --- a/ReadMe.txt +++ /dev/null @@ -1,7 +0,0 @@ - .htaccess - - - ## Poll - RewriteRule ^poll-([0-9]+).html$ index.php?module=poll&action=result&pid=$1 - RewriteRule ^pollcomment-([0-9]+).html$ index.php?module=poll&action=form&pop=1&pid=$1 - RewriteRule ^poll-archive.html$ index.php?module=poll&action=archive \ No newline at end of file diff --git a/admin/admin_comments.tpl b/admin/admin_comments.tpl index 699aea4..394900a 100644 --- a/admin/admin_comments.tpl +++ b/admin/admin_comments.tpl @@ -24,7 +24,7 @@
{#POLL_NEW_LINK#}
-
+ @@ -35,36 +35,39 @@ - - {foreach from=$items item=item} - - - - - - {/foreach} - - - - + +{foreach from=$items item=item} + + + + + + + +{/foreach} + + + +
{#POLL_COMMENT_TITLE#}
- - - {#POLL_COMMENT_AUTHOR#}
- {$item->poll_comment_author|escape} -
-
- {#POLL_COMMENT_DATE#}
- {$item->poll_comment_time|date_format:$DATE_FORMAT|pretty_date} -
-
- Тема -
- Комментарий - -
-
- -
+ + + {#POLL_COMMENT_AUTHOR#}
+ {$item->poll_comment_author|escape} +
+
+ {#POLL_COMMENT_DATE#}
+ {$item->poll_comment_time|date_format:$DATE_FORMAT|pretty_date} +
+
+ Тема
+
+ + Комментарий
+ +
+
+ +
diff --git a/admin/admin_fields.tpl b/admin/admin_fields.tpl index 5b2abf0..55a4df5 100644 --- a/admin/admin_fields.tpl +++ b/admin/admin_fields.tpl @@ -114,7 +114,7 @@ $(document).ready(function(){ldelim} -{if $smarty.request.moduleaction == 'new'} +{if isset($smarty.request.moduleaction) && $smarty.request.moduleaction == 'new'}
{#POLL_ADD_POLL#}
@@ -138,7 +138,7 @@ $(document).ready(function(){ldelim}
  • {#MAIN_PAGE#}
  • {#MODULES_SUB_TITLE#}
  • {#POLL_MODULE_NAME#}
  • - {if $smarty.request.moduleaction == 'new'} + {if isset($smarty.request.moduleaction) && $smarty.request.moduleaction == 'new'}
  • {#POLL_ADD_POLL#}
  • {else}
  • {#POLL_EDIT#}
  • @@ -153,7 +153,7 @@ $(document).ready(function(){ldelim}
    -
    {if $smarty.request.id != ''}{#POLL_EDIT#}{else}{#POLL_ADD_POLL#}{/if}
    +
    {if isset($smarty.request.id) && $smarty.request.id != ''}{#POLL_EDIT#}{else}{#POLL_ADD_POLL#}{/if}
    @@ -164,28 +164,44 @@ $(document).ready(function(){ldelim}
    - + + + + + @@ -198,7 +214,7 @@ $(document).ready(function(){ldelim}
    {#POLL_STATUS#}? - poll_status==1}checked{/if} value="1"/> - poll_status==0}checked{/if} value="0" /> + poll_status) && $row->poll_status == 1}checked{/if} value="1"/> + + + poll_status) || $row->poll_status == 0}checked{/if} value="0" /> +
    {#POLL_CAN_COMMENT#} - poll_can_comment==1}checked{/if} /> - poll_can_comment==0}checked{/if} /> + poll_can_comment) && $row->poll_can_comment == 1}checked{/if} /> + + + poll_can_comment) || $row->poll_can_comment == 0}checked{/if} /> + +
    {#POLL_ANTISPAM#} + poll_anti_spam) && $row->poll_anti_spam == 1}checked{/if} /> + + + poll_anti_spam) || $row->poll_anti_spam == 0}checked{/if} /> +
    {#POLL_START_TIME#} - + {#POLL_END_TIME#} - +
    - {if $smarty.request.id != ''} + {if isset($smarty.request.id) && $smarty.request.id != ''}
    @@ -221,7 +237,7 @@ $(document).ready(function(){ldelim} - {if $items} + {if isset($items) && $items} {foreach from=$items item=item} @@ -260,7 +276,7 @@ $(document).ready(function(){ldelim}
    -{if $smarty.request.id != ''} +{if isset($smarty.request.id) && $smarty.request.id != ''}
    {#POLL_QUESTIONS_ADD#}
    diff --git a/admin/admin_forms.tpl b/admin/admin_forms.tpl index 100de9a..d0421fe 100644 --- a/admin/admin_forms.tpl +++ b/admin/admin_forms.tpl @@ -27,7 +27,7 @@ - + @@ -58,7 +58,10 @@ + + @@ -99,4 +108,6 @@ {$page_nav} -{/if} \ No newline at end of file +{/if} + + \ No newline at end of file diff --git a/class/poll.php b/class/poll.php index 67d1bc2..0291ce3 100644 --- a/class/poll.php +++ b/class/poll.php @@ -115,7 +115,7 @@ class Poll } } - /** +/** * Учет результатов опроса * * @param int $pid идентификатор опроса @@ -124,56 +124,86 @@ class Poll { global $AVE_DB; + $pid = (int)$pid; $row = $AVE_DB->Query(" SELECT * FROM " . PREFIX . "_module_poll WHERE id = '" . $pid . "' ")->FetchRow(); + if (!$row) return; + + // Проверяем: если дата окончания установлена и она уже прошла + if ($row->poll_end > 0 && $row->poll_end < time()) + { + // перенаправляем на страницу результатов, ничего не записывая в базу + header('Location: ' . $this->_pollLinkRewrite('index.php?module=poll&action=result&pid=' . $pid)); + exit; + } + $poll_groups_id = empty($row->poll_groups_id) ? array() : explode(',', $row->poll_groups_id); $poll_users_id = empty($row->poll_users_id) ? array() : explode(',', $row->poll_users_id); $poll_users_ip = empty($row->poll_users_ip) ? array() : explode(',', $row->poll_users_ip); - $current_user_ip = empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR']; + $current_user_ip = $_SERVER['REMOTE_ADDR'] ?? ''; - $back = $this->_pollLinkRewrite('index.php?module=poll&action=result&pid=' . $pid); + // убрал & из ссылки редиректа + $back = $this->_pollLinkRewrite('index.php?module=poll&action=result&pid=' . $pid); - if (!(@in_array(UGROUP, $poll_groups_id))) + // Проверка прав группы + if (!in_array(UGROUP, $poll_groups_id)) { - header('Location:' . $back); + header('Location: ' . $back); exit; } - if (@in_array($current_user_ip, $poll_users_ip) || - @in_array($_SESSION['user_id'], $poll_users_id) || - $_COOKIE['poll_' . $pid] == '1') + // Проверка: голосовал ли уже + $already_voted = false; + if (in_array($current_user_ip, $poll_users_ip)) $already_voted = true; + if (isset($_SESSION['user_id']) && in_array($_SESSION['user_id'], $poll_users_id)) $already_voted = true; + if (isset($_COOKIE['poll_' . $pid]) && $_COOKIE['poll_' . $pid] == '1') $already_voted = true; + + if ($already_voted) { - header('Location:' . $back); + header('Location: ' . $back); exit; } - setcookie('poll_' . $pid, '1', time() + 3600 * 3600); + // Устанавливаем куку + setcookie('poll_' . $pid, '1', time() + 3600 * 3600, '/'); - $AVE_DB->Query(" - UPDATE " . PREFIX . "_module_poll_items - SET poll_item_hits = poll_item_hits + 1 - WHERE id = '" . (int)$_POST['p_item'] . "' - "); + $p_item = (int)($_POST['p_item'] ?? 0); - $AVE_DB->Query(" - UPDATE " . PREFIX . "_module_poll - SET - poll_users_ip = CONCAT_WS(',', poll_users_ip, '" . $current_user_ip . "') - " . ((UGROUP != 2) ? ", poll_users_id = CONCAT_WS(',', poll_users_id, '" . $_SESSION['user_id'] . "')" : '') . " - WHERE - id = '" . $pid . "' - "); + if ($p_item > 0) + { + $AVE_DB->Query(" + UPDATE " . PREFIX . "_module_poll_items + SET poll_item_hits = poll_item_hits + 1 + WHERE id = '" . $p_item . "' + "); - header('Location:' . $back); + // Обновляем список проголосовавших (IP и ID) + $sql_user_update = ""; + if (UGROUP != 2 && isset($_SESSION['user_id'])) { + $sql_user_update = ", poll_users_id = CONCAT_WS(',', poll_users_id, '" . (int)$_SESSION['user_id'] . "')"; + } + + $AVE_DB->Query(" + UPDATE " . PREFIX . "_module_poll + SET + poll_users_ip = CONCAT_WS(',', poll_users_ip, '" . addslashes($current_user_ip) . "') + $sql_user_update + WHERE + id = '" . $pid . "' + "); + } + + // редирект + header('Location: ' . $back); exit; } - /** +/** * Подробная информация и статистика опроса, комментарии пользователей * * @param string $tpl_dir путь к папке с шаблонами модуля @@ -184,21 +214,37 @@ class Poll { global $AVE_DB, $AVE_Template; + if (empty($pid) && isset($_GET['pid'])) $pid = (int)$_GET['pid']; + + if (empty($pid) && isset($_SERVER['REQUEST_URI'])) { + if (preg_match('/poll-(\d+)/', $_SERVER['REQUEST_URI'], $matches)) { + $pid = (int)$matches[1]; + } + } + $pid = (int)$pid; + $AVE_Template->config_load($lang_file, 'showresult'); + $AVE_Template->assign('comment_title', ''); + $AVE_Template->assign('comment_text', ''); + $AVE_Template->assign('errors', array()); + + // Обработка нового комментария if (isset($_REQUEST['sub']) && $_REQUEST['sub'] == 'new') { $errors = $this->pollCommentNew($pid); - if (sizeof($errors) == 0) + if (empty($errors)) { - header('Location:' . $this->_pollLinkRewrite('index.php?module=poll&action=result&pid=' . $pid)); + $redirect_url = 'index.php?module=poll&action=result&pid=' . $pid; + header('Location:' . $this->_pollLinkRewrite($redirect_url)); exit; } $AVE_Template->assign('errors', $errors); } + // Основной запрос данных опроса $poll = $AVE_DB->Query(" SELECT poll.*, @@ -207,7 +253,7 @@ class Poll " . PREFIX . "_module_poll AS poll LEFT JOIN " . PREFIX . "_module_poll_items AS itm - ON poll_id = poll.id + ON itm.poll_id = poll.id WHERE poll.id = '" . $pid . "' AND poll.poll_title != '' AND @@ -216,32 +262,33 @@ class Poll GROUP BY poll.id ")->FetchRow(); - if ($poll === false) return; + if (!$poll) return; + // Варианты ответов $items = array(); + $votes_total = (int)$poll->votes; $sql = $AVE_DB->Query(" SELECT *, - " . ($poll->votes > 0 ? 'ROUND(poll_item_hits*100/' . $poll->votes . ')' : 0) . " AS sum + " . ($votes_total > 0 ? 'ROUND(poll_item_hits*100/' . $votes_total . ')' : 0) . " AS sum FROM " . PREFIX . "_module_poll_items WHERE poll_id = '" . $pid . "' ORDER BY poll_item_position ASC "); while ($row_items = $sql->FetchRow()) { - array_push($items, $row_items); + $items[] = $row_items; } + // Комментарии + $comments = array(); if ($poll->poll_can_comment == 1) { - //include_once(BASE_DIR . '/lib/markitup/sets/bbcode/markitup.bbcode-parser.php'); - - $comments = array(); $sql = $AVE_DB->Query(" SELECT cmnt.*, - IFNULL(firstname, '') AS firstname, - IFNULL(lastname, '" . $AVE_Template->get_config_vars('POLL_GUEST') . "') AS lastname + IFNULL(usr.firstname, '') AS firstname, + IFNULL(usr.lastname, '" . addslashes($AVE_Template->get_config_vars('POLL_GUEST')) . "') AS lastname FROM " . PREFIX . "_module_poll_comments AS cmnt LEFT JOIN @@ -252,66 +299,65 @@ class Poll "); while ($row_comments = $sql->FetchRow()) { - $row_comments->poll_comment_text = $row_comments->poll_comment_text; - - array_push($comments, $row_comments); + $comments[] = $row_comments; } - $poll->count_comments = $sql->NumRows(); } + // Проверка прав и кук $poll_users_id = empty($poll->poll_users_id) ? array() : explode(',', $poll->poll_users_id); $poll_users_ip = empty($poll->poll_users_ip) ? array() : explode(',', $poll->poll_users_ip); - - $current_user_ip = empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR']; + $current_user_id = isset($_SESSION['user_id']) ? (int)$_SESSION['user_id'] : 0; + $current_user_ip = $_SERVER['REMOTE_ADDR'] ?? ''; $is_vote = 1; - if (@in_array($current_user_ip, $poll_users_ip) || - @in_array($_SESSION['user_id'], $poll_users_id) || + if (in_array($current_user_ip, $poll_users_ip) || + ($current_user_id > 0 && in_array($current_user_id, $poll_users_id)) || (isset($_COOKIE['poll_' . $pid]) && $_COOKIE['poll_' . $pid] == '1')) { $is_vote = 0; } $rights = 0; - $groups = array(); - if ($poll->poll_groups_id != '') + $groups_names = array(); + if (!empty($poll->poll_groups_id)) { + // фильтр ID групп (только цифры и запятые) + $safe_groups = preg_replace('/[^0-9,]/', '', $poll->poll_groups_id); $sql = $AVE_DB->Query(" - SELECT - user_group, - user_group_name - FROM - " . PREFIX . "_user_groups - WHERE - user_group IN(" . $poll->poll_groups_id . ") + SELECT user_group, user_group_name + FROM " . PREFIX . "_user_groups + WHERE user_group IN(" . $safe_groups . ") "); while ($row_g = $sql->FetchRow()) { if (UGROUP == $row_g->user_group) $rights = 1; - array_push($groups, $row_g->user_group_name); + $groups_names[] = $row_g->user_group_name; } } - $poll->can_vote = ($is_vote == 1 && $rights == 1) ? 1 : 0; - $poll->groups = implode(', ', $groups); + // Наполнение объекта для шаблона + $is_expired = ($poll->poll_end > 0 && $poll->poll_end < time()) ? 1 : 0; + $poll->can_vote = ($is_vote == 1 && $rights == 1 && $is_expired == 0) ? 1 : 0; + $poll->is_expired = $is_expired; + $poll->groups = implode(', ', $groups_names); $poll->can_comment = ($poll->poll_status == 1 && $poll->poll_can_comment == 1 && $rights == 1) ? 1 : 0; - $poll->anti_spam = ($this->_antispam == 1 && function_exists('imagettftext') && function_exists('imagejpeg')) ? 1 : 0; - $poll->comment_max_chars = $this->_commentwords; + $poll->anti_spam = ($poll->poll_anti_spam == 1 && function_exists('imagettftext')) ? 1 : 0; + $poll->comment_max_chars = (int)$this->_commentwords; $poll->items = $items; $poll->comments = $comments; - $poll->formaction = 'index.php?module=poll&action=vote&pid=' . $pid; - $poll->link_result = $this->_pollLinkRewrite('index.php?module=poll&action=result&pid=' . $pid); -// $poll->link_archive = $this->_pollLinkRewrite('index.php?module=poll&action=archive'); -// $poll->link_comment = $this->_pollLinkRewrite('index.php?module=poll&action=form&pop=1&pid=' . $pid); + + // Ссылки + $poll->formaction = 'index.php?module=poll&action=vote&pid=' . $pid; + $poll->link_result = $this->_pollLinkRewrite('index.php?module=poll&action=result&pid=' . $pid); $AVE_Template->assign('poll', $poll); - define('MODULE_SITE', $AVE_Template->get_config_vars('POLL_PAGE_TITLE_PREFIX') . $poll->poll_title); - define('MODULE_CONTENT', $AVE_Template->fetch($tpl_dir . 'result.tpl')); + if (!defined('MODULE_SITE')) define('MODULE_SITE', $AVE_Template->get_config_vars('POLL_PAGE_TITLE_PREFIX') . $poll->poll_title); + if (!defined('MODULE_CONTENT')) define('MODULE_CONTENT', $AVE_Template->fetch($tpl_dir . 'result.tpl')); } - /** +/** * Список завершенных и действующих опросов * * @param string $tpl_dir путь к папке с шаблонами модуля @@ -321,13 +367,17 @@ class Poll { global $AVE_DB, $AVE_Template; - if (empty($_REQUEST['order'])) + // Добавляем инициализацию для Smarty, чтобы убрать Warning в шаблоне + $req_order = isset($_REQUEST['order']) ? $_REQUEST['order'] : ''; + $req_by = isset($_REQUEST['by']) ? $_REQUEST['by'] : ''; + + if (empty($req_order)) { $order = 'poll_title'; } else { - switch ($_REQUEST['order']) + switch ($req_order) { case 'title': $order = 'poll_title'; @@ -351,7 +401,7 @@ class Poll } } - if (isset($_REQUEST['by']) && $_REQUEST['by'] == 'desc') + if ($req_by == 'desc') { $order .= ' DESC'; } @@ -372,25 +422,29 @@ class Poll " . PREFIX . "_module_poll AS poll LEFT JOIN " . PREFIX . "_module_poll_items AS itm - ON poll_id = poll.id + ON itm.poll_id = poll.id WHERE poll.poll_title != '' AND poll.poll_status = '1' AND - poll.poll_start < '" . time() . "' + poll.poll_start < '" . (int)time() . "' GROUP BY poll.id ORDER BY " . $order ); + while ($row = $sql->FetchRow()) { - $row->plink = $this->_pollLinkRewrite('index.php?module=poll&action=result&pid=' . $row->id); + $row->plink = $this->_pollLinkRewrite('index.php?module=poll&action=result&pid=' . (int)$row->id); array_push($items, $row); } $AVE_Template->assign('items', $items); + $AVE_Template->assign('order', $req_order); + $AVE_Template->assign('by', $req_by); + $AVE_Template->config_load($lang_file, 'showarchive'); - define('MODULE_SITE', $AVE_Template->get_config_vars('POLL_ARCHIVE_TITLE')); - define('MODULE_CONTENT', $AVE_Template->fetch($tpl_dir . 'archive.tpl')); + if (!defined('MODULE_SITE')) define('MODULE_SITE', $AVE_Template->get_config_vars('POLL_ARCHIVE_TITLE')); + if (!defined('MODULE_CONTENT')) define('MODULE_CONTENT', $AVE_Template->fetch($tpl_dir . 'archive.tpl')); } /** @@ -424,7 +478,7 @@ class Poll } $AVE_Template->assign('max_chars', $this->_commentwords); - if ($this->_antispam == 1 && function_exists('imagettftext') && function_exists('imagejpeg')) + if (isset($row->poll_anti_spam) && $row->poll_anti_spam == 1 && function_exists('imagettftext') && function_exists('imagejpeg')) { $AVE_Template->assign('anti_spam', 1); } @@ -437,82 +491,96 @@ class Poll $AVE_Template->display($tpl_dir . 'poll_form.tpl'); } - /** - * Метод создания нового комментария +/** + * Метод создания нового комментария (UTF-8 Only) * - * @param string $tpl_dir путь к папке с шаблонами модуля - * @param string $lang_file путь к языковому файлу модуля - * @param int $pid идентификатор опроса + * @param int $pid идентификатор опроса */ - function pollCommentNew($pid) - { - global $AVE_DB, $AVE_Template; +function pollCommentNew($pid) +{ + global $AVE_DB, $AVE_Template; - $errors = array(); + $errors = array(); + $pid = (int)$pid; - if (isset($_REQUEST['ajax']) && $_REQUEST['ajax'] == 1) - { - $comment_title = iconv('utf-8', 'cp1251', $_POST['comment_title']); - $comment_text = iconv('utf-8', 'cp1251', $_POST['comment_text']); - } - else - { - $comment_title = $_POST['comment_title']; - $comment_text = $_POST['comment_text']; - } + $poll_settings = $AVE_DB->Query(" + SELECT poll_anti_spam, poll_groups_id + FROM " . PREFIX . "_module_poll + WHERE id = '" . $pid . "' + AND poll_status = '1' + AND poll_can_comment = '1' + LIMIT 1 + ")->FetchRow(); - $text = (mb_strlen($comment_text) > $this->_commentwords) - ? mb_substr($comment_text, 0, $this->_commentwords) . '...' - : $comment_text; + if (!$poll_settings) { + $errors[] = $AVE_Template->get_config_vars('POLL_ERROR_PERM'); + // Если это AJAX, отдаем ошибку сразу + if (isset($_REQUEST['ajax'])) { @ob_clean(); die('###ERR###' . end($errors)); } + return $errors; + } - if (mb_strlen($text) <= 10) $errors[] = $AVE_Template->get_config_vars('POLL_ENTER_TEXT'); - if (empty($comment_title)) $errors[] = $AVE_Template->get_config_vars('POLL_ENTER_TITLE'); + $comment_title = isset($_POST['comment_title']) ? trim(addslashes($_POST['comment_title'])) : ''; + $comment_text = isset($_POST['comment_text']) ? trim(addslashes($_POST['comment_text'])) : ''; - if ($this->_antispam == 1) - { - if (! (isset($_SESSION['captcha_keystring']) && isset($_POST['securecode']) - && $_SESSION['captcha_keystring'] == $_POST['securecode'])) - { - $errors[] = $AVE_Template->get_config_vars('POLL_ENTER_CODE'); - } + $max_len = (int)$this->_commentwords; + $text = (mb_strlen($comment_text) > $max_len) + ? mb_substr($comment_text, 0, $max_len) . '...' + : $comment_text; - unset($_SESSION['captcha_keystring']); - } + if (mb_strlen($text) < 5) $errors[] = $AVE_Template->get_config_vars('POLL_ENTER_TEXT'); + if (empty($comment_title)) $errors[] = $AVE_Template->get_config_vars('POLL_ENTER_TITLE'); - if (sizeof($errors) == 0) - { - $poll_groups_id = $AVE_DB->Query(" - SELECT poll_groups_id - FROM " . PREFIX . "_module_poll - WHERE id = '" . $pid . "' - AND poll_status = '1' - AND poll_can_comment = '1' - ")->GetCell(); + if ($poll_settings->poll_anti_spam == 1 && function_exists('imagettftext')) + { + $session_captcha = $_SESSION['captcha_keystring'] ?? ''; + $post_captcha = $_POST['securecode'] ?? ''; - if (!empty($poll_groups_id) && in_array(UGROUP, explode(',', $poll_groups_id))) - { - $author_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : 0; - $author_ip = empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR']; + if (empty($post_captcha) || $session_captcha !== $post_captcha) + { + $errors[] = $AVE_Template->get_config_vars('POLL_ENTER_CODE_ERR'); + } + + if (empty($errors)) { + unset($_SESSION['captcha_keystring']); + } + } - $AVE_DB->Query(" - INSERT " . PREFIX . "_module_poll_comments - SET - poll_id = '" . $pid . "', - poll_comment_time = '" . time() . "', - poll_comment_author_id = '" . $author_id . "', - poll_comment_author_ip = '" . $author_ip . "', - poll_comment_title = '" . $comment_title . "', - poll_comment_text = '" . $text . "' - "); + if (empty($errors)) + { + $allowed_groups = explode(',', $poll_settings->poll_groups_id); + if (in_array(UGROUP, $allowed_groups)) + { + $author_id = (int)($_SESSION['user_id'] ?? 0); + $author_ip = addslashes($_SERVER['REMOTE_ADDR'] ?? ''); - return $errors; - } + $AVE_DB->Query(" + INSERT INTO " . PREFIX . "_module_poll_comments + SET + poll_id = '" . $pid . "', + poll_comment_time = '" . time() . "', + poll_comment_author_id = '" . $author_id . "', + poll_comment_author_ip = '" . $author_ip . "', + poll_comment_title = '" . $comment_title . "', + poll_comment_text = '" . $text . "' + "); - $errors[] = $AVE_Template->get_config_vars('POLL_ERROR_PERM'); - } + if (isset($_REQUEST['ajax'])) { @ob_clean(); die('###OK###'); } + return array(); + } + else + { + $errors[] = $AVE_Template->get_config_vars('POLL_ERROR_PERM'); + } + } - return $errors; - } + // Если мы здесь и это AJAX — значит есть ошибки. Выплевываем их. + if (isset($_REQUEST['ajax'])) { + @ob_clean(); + die('###ERR###' . implode('
    ', $errors)); + } + + return $errors; +} /** * Методы административной части @@ -573,7 +641,7 @@ class Poll $AVE_Template->assign('content', $AVE_Template->fetch($adm_dir . 'admin_forms.tpl')); } - /** +/** * Метод создания нового опроса * * @param string $adm_dir путь к папке с шаблонами модуля @@ -618,25 +686,35 @@ class Poll $_REQUEST['poll_expire'] = $this->_mktime($_REQUEST['poll_expire']); $_REQUEST['poll_status'] = (!empty($_REQUEST['poll_status'])) ? (int)$_REQUEST['poll_status'] : '0'; $_REQUEST['poll_can_comment'] = (!empty($_REQUEST['poll_can_comment'])) ? (int)$_REQUEST['poll_can_comment'] : '0'; + $_REQUEST['poll_anti_spam'] = (!empty($_REQUEST['poll_anti_spam'])) ? (int)$_REQUEST['poll_anti_spam'] : '0'; $AVE_DB->Query(" INSERT INTO " . PREFIX . "_module_poll SET - id = '', - poll_title = '" . $_REQUEST['poll_name'] . "', - poll_status = '" . $_REQUEST['poll_status'] . "', - poll_groups_id = '" . @implode(',', $_REQUEST['groups']) . "', - poll_users_id = '0', - poll_users_ip = '0', + id = '', + poll_title = '" . addslashes($_REQUEST['poll_name']) . "', + poll_status = '" . $_REQUEST['poll_status'] . "', + poll_groups_id = '" . @implode(',', $_REQUEST['groups']) . "', + poll_users_id = '0', + poll_users_ip = '0', poll_can_comment = '" . $_REQUEST['poll_can_comment'] . "', - poll_start = '" . $_REQUEST['poll_published'] . "', - poll_end = '" . $_REQUEST['poll_expire'] . "' + poll_anti_spam = '" . $_REQUEST['poll_anti_spam'] . "', + poll_start = '" . $_REQUEST['poll_published'] . "', + poll_end = '" . $_REQUEST['poll_expire'] . "' "); $iid = $AVE_DB->InsertId(); - reportLog($_SESSION['user_name'] . ' - Добавил новый опрос (' . stripslashes($_REQUEST['poll_name']) . ')'); + // ШТАТНОЕ ЧПУ + $AVE_DB->Query("INSERT INTO " . PREFIX . "_modules_aliases + (module_name, module_action, module_link, module_url, module_admin) + VALUES + ('poll', 'result', 'index.php?module=poll&action=result&pid={$iid}', 'poll-{$iid}', '0'), + ('poll', 'form', 'index.php?module=poll&action=form&pop=1&pid={$iid}', 'pollcomment-{$iid}', '0') + "); + + reportLog($_SESSION['user_name'] . ' - Добавил новый опрос (' . addslashes($_REQUEST['poll_name']) . ')'); header('Location:index.php?do=modules&action=modedit&mod=poll&moduleaction=edit&id=' . $iid . '&cp=' . SESSION); exit; @@ -753,61 +831,95 @@ class Poll } - /** - * Метод записи изменений в опросе - * - * @param int $pid идентификатор опроса - */ - function pollSave($pid) +/** + * Метод записи изменений в опросе + * + * @param int $pid идентификатор опроса + */ +function pollSave($pid) +{ + global $AVE_DB; + + // Обработка основных полей опроса с экранированием и проверкой на существование + $poll_name = isset($_REQUEST['poll_name']) ? addslashes($_REQUEST['poll_name']) : ''; + $poll_status = (int)($_REQUEST['poll_status'] ?? 0); + $poll_can_comment = (int)($_REQUEST['poll_can_comment'] ?? 0); + // НАША КАПЧА + $poll_anti_spam = (int)($_REQUEST['poll_anti_spam'] ?? 0); + + $poll_published = $_REQUEST['poll_published'] ?? ''; + $poll_expire = $_REQUEST['poll_expire'] ?? ''; + + // Обработка групп (приведение к массиву и склейка) + $groups = isset($_REQUEST['groups']) ? (array)$_REQUEST['groups'] : []; + $groups_list = addslashes(@implode(',', $groups)); + + $AVE_DB->Query(" + UPDATE " . PREFIX . "_module_poll + SET + poll_title = '" . $poll_name . "', + poll_status = '" . $poll_status . "', + poll_can_comment = '" . $poll_can_comment . "', + poll_anti_spam = '" . $poll_anti_spam . "', + poll_start = '" . $this->_mktime($poll_published) . "', + poll_end = '" . $this->_mktime($poll_expire) . "', + poll_groups_id = '" . $groups_list . "' + WHERE + id = '" . (int)$pid . "' + "); + + // Удаление отмеченных вариантов + if (!empty($_POST['del']) && is_array($_POST['del'])) { - global $AVE_DB; - - $AVE_DB->Query(" - UPDATE " . PREFIX . "_module_poll - SET - poll_title = '" . $_REQUEST['poll_name'] . "', - poll_status = '" . $_REQUEST['poll_status'] . "', - poll_can_comment = '" . $_REQUEST['poll_can_comment'] . "', - poll_start = '" . $this->_mktime($_REQUEST['poll_published']) . "', - poll_end = '" . $this->_mktime($_REQUEST['poll_expire']). "', - poll_groups_id = '" . @implode(',', (array)$_REQUEST['groups']) . "' - WHERE - id = '" . $pid . "' - "); - - if (!empty($_POST['del'])) + foreach ($_POST['del'] as $id => $field) { - foreach ($_POST['del'] as $id => $field) - { - $AVE_DB->Query(" - DELETE - FROM " . PREFIX . "_module_poll_items - WHERE id = '" . $id . "' - "); - } + $AVE_DB->Query(" + DELETE + FROM " . PREFIX . "_module_poll_items + WHERE id = '" . (int)$id . "' + "); } + } + // Обновление существующих вариантов ответов + if (!empty($_POST['item_title']) && is_array($_POST['item_title'])) + { foreach ($_POST['item_title'] as $id => $field) { if (!empty($field)) { + $item_title = addslashes($field); + $item_hits = (int)($_POST['poll_item_hits'][$id] ?? 0); + $item_color = addslashes($_POST['line_color'][$id] ?? ''); + $AVE_DB->Query(" UPDATE " . PREFIX . "_module_poll_items SET - poll_item_title = '" . $field . "', - poll_item_hits = '" . $_POST['poll_item_hits'][$id] . "', - poll_item_color = '" . $_POST['line_color'][$id] . "' + poll_item_title = '" . $item_title . "', + poll_item_hits = '" . $item_hits . "', + poll_item_color = '" . $item_color . "' WHERE - id = '" . $id . "' + id = '" . (int)$id . "' "); } } - - header('Location:index.php?do=modules&action=modedit&mod=poll&moduleaction=edit&id=' . $pid . '&cp=' . SESSION); - exit; } - /** + // ШТАТНОЕ ЧПУ + $AVE_DB->Query("INSERT IGNORE INTO " . PREFIX . "_modules_aliases + (module_name, module_action, module_link, module_url, module_admin) + VALUES + ('poll', 'result', 'index.php?module=poll&action=result&pid=" . (int)$pid . "', 'poll-" . (int)$pid . "', '0'), + ('poll', 'form', 'index.php?module=poll&action=form&pop=1&pid=" . (int)$pid . "', 'pollcomment-" . (int)$pid . "', '0') + "); + + reportLog($_SESSION['user_name'] . ' - Сохранил изменения в опросе (ID: ' . (int)$pid . ')'); + + header('Location:index.php?do=modules&action=modedit&mod=poll&moduleaction=edit&id=' . (int)$pid . '&cp=' . SESSION); + exit; +} + +/** * Метод удаления опроса * * @param int $pid идентификатор опроса @@ -816,19 +928,33 @@ class Poll { global $AVE_DB; + $pid = (int)$pid; + + // Удаляем все ЧПУ-ссылки опроса $AVE_DB->Query(" - DELETE - FROM " . PREFIX . "_module_poll + DELETE FROM " . PREFIX . "_modules_aliases + WHERE module_name = 'poll' + AND module_link IN ( + 'index.php?module=poll&action=result&pid=" . $pid . "', + 'index.php?module=poll&action=form&pop=1&pid=" . $pid . "' + ) + "); + + // Удаляем сам опрос + $AVE_DB->Query(" + DELETE FROM " . PREFIX . "_module_poll WHERE id = '" . $pid . "' "); + + // Удаляем варианты ответов $AVE_DB->Query(" - DELETE - FROM " . PREFIX . "_module_poll_items + DELETE FROM " . PREFIX . "_module_poll_items WHERE poll_id = '" . $pid . "' "); + + // Удаляем комментарии к опросу $AVE_DB->Query(" - DELETE - FROM " . PREFIX . "_module_poll_comments + DELETE FROM " . PREFIX . "_module_poll_comments WHERE poll_id = '" . $pid . "' "); @@ -905,31 +1031,39 @@ class Poll } } - /** - * Формитрование метки времени по данным полученным из выпадающих списков - * сформированных Smarty {html_select_date} и {html_select_time} +/** + * Формирование метки времени по данным полученным из строки даты и времени * - * @param string $date имя массива с значениями даты - * @param string $time имя массива с значениями времени - * @return unknown timestamp + * @param string $data строка вида "дд.мм.гггг чч:мм" + * @return int timestamp */ - function _mktime($data=0) + function _mktime($data = '') { - $data = explode(" ", $data); - $stamp[day] = explode(".", $data[0]); - $stamp[time] = explode(":", $data[1]); + if (empty($data)) return time(); - if (!empty($stamp)) + $data = explode(" ", $data); + + // Инициализируем массив + $stamp = ['day' => [], 'time' => []]; + + $stamp['day'] = explode(".", $data[0]); + $stamp['time'] = isset($data[1]) ? explode(":", $data[1]) : [0, 0]; + + if (!empty($stamp['day']) && count($stamp['day']) == 3) { $timestamp = mktime( - $stamp[time][0], - $stamp[time][1], + (int)($stamp['time'][0] ?? 0), + (int)($stamp['time'][1] ?? 0), 0, - $stamp[day][1], - $stamp[day][0], - $stamp[day][2] + (int)$stamp['day'][1], // месяц + (int)$stamp['day'][0], // день + (int)$stamp['day'][2] // год ); } + else + { + $timestamp = time(); + } return $timestamp; } diff --git a/funcs/func.rewrite.php b/funcs/func.rewrite.php index 003eaa8..acdb376 100644 --- a/funcs/func.rewrite.php +++ b/funcs/func.rewrite.php @@ -2,12 +2,25 @@ function PollRewrite($print_out) { - $print_out = preg_replace('/index.php([?])module=poll&action=result&pid=(\d+)/', ABS_PATH . 'poll-\\2.html', $print_out); - $print_out = preg_replace('/index.php([?])module=poll&action=form&pop=1&pid=(\d+)/', ABS_PATH . 'pollcomment-\\2.html', $print_out); - $print_out = preg_replace('/index.php([?])module=poll&action=archive/', ABS_PATH . 'poll-archive.html', $print_out); - $print_out = str_replace(".html&print=1", "-print.html", $print_out); + // учитываем суффикс из настроек + $suff = (defined('URL_SUFF')) ? URL_SUFF : ''; - return $print_out; + // регулярка для Результатов (pid) + $print_out = preg_replace('/index\.php\?module=poll[&|&]+action=result[&|&]+pid=(\d+)/i', 'poll-$1' . $suff, $print_out); + + // регулярка для Формы (pollcomment) + $print_out = preg_replace('/index\.php\?module=poll[&|&]+action=form[&|&]+pop=1[&|&]+pid=(\d+)/i', 'pollcomment-$1' . $suff, $print_out); + + // замена для Архива (учитываем оба варианта разделителя) + $print_out = preg_replace('/index\.php\?module=poll[&|&]+action=archive/i', 'poll-archive' . $suff, $print_out); + + // если есть ссылки на печать + if ($suff != '') { + $print_out = str_replace($suff . '&print=1', '-print' . $suff, $print_out); + $print_out = str_replace($suff . '&print=1', '-print' . $suff, $print_out); + } + + return $print_out; } ?> \ No newline at end of file diff --git a/info.php b/info.php index c6b41e6..04ce198 100644 --- a/info.php +++ b/info.php @@ -4,7 +4,7 @@ $module = array( 'ModuleSysName' => 'poll', - 'ModuleVersion' => '1.26.1a', + 'ModuleVersion' => '3.31', 'ModuleAutor' => 'AVE.cms Team', 'ModuleCopyright' => '© 2007-' . date('Y') . ' AVE.cms', 'ModuleStatus' => 1, diff --git a/lang/ru.txt b/lang/ru.txt index 033aa3f..4e7ddee 100644 --- a/lang/ru.txt +++ b/lang/ru.txt @@ -1,6 +1,6 @@ [name] MODULE_NAME = "Опросы" -MODULE_DESCRIPTION = "Данный модуль предназачен для организации системы опросов на сайте. Возможности модуля позволяют создавать неограниченное количество опросных листов, а также неограниченное количество вопросов.
    Внимание! Для работы корректной работы модуля необходимо добавить в корневой .htaccess следующие строки
    RewriteRule ^poll-([0-9]+).html$ index.php?module=poll&action=result&pid=$1

    RewriteRule ^pollcomment-([0-9]+).html$ index.php?module=poll&action=form&pop=1&pid=$1

    RewriteRule ^poll-archive.html$ index.php?module=poll&action=archive " +MODULE_DESCRIPTION = "Данный модуль предназачен для организации системы опросов на сайте. Возможности модуля позволяют создавать неограниченное количество опросных листов, а также неограниченное количество вопросов." [showpoll] @@ -36,9 +36,16 @@ POLL_BUTTON_ADD_C = "Добавить" POLL_CHARSET_LEFT = "осталось символов" POLL_YOUR_NAME = "Имя" POLL_SECURE_CODE = "Защитный код" -POLL_ERROR_NO_TITLE = "Пожалуйста, укажите заголовок комментария" -POLL_ERROR_NO_TEXT = "Пожалуйста, напишите комментарий длинной не менее 10 символов" -POLL_ERROR_NO_SCODE = "Пожалуйста, укажите защитный код" +POLL_ERROR_NO_TITLE = "Укажите заголовок комментария" +POLL_ERROR_NO_TEXT = "Текст комментария должен быть не менее 10 символов" +POLL_ERROR_NO_SCODE = "Введите защитный код с картинки" +POLL_ENTER_CODE_ERR = "Неверный защитный код! +POLL_COMMENT_TITEL = "Заголовок" +POLL_COMMENT_TITEL_PL = "Введите заголовок..." +POLL_COMMENT_TITEL_PLS = "Текст вашего сообщения..." +POLL_CAPTCHA_UPD_IMG = "Нажмите, чтобы обновить" +POLL_CAPTCHA_PL = "Код..." +POLL_CAPTCHA_P_ERR = "Ошибка:" [showarchive] POLL_ARCHIVE_HITS = "Мнений" @@ -61,6 +68,8 @@ POLL_ENTER_CODE = "Пожалуйста, укажите защитны POLL_ENTER_TEXT = "Пожалуйста, напишите комментарий длинной не менее 10 символов" POLL_ENTER_TITLE = "Пожалуйста, укажите заголовок комментария" POLL_SECURE_CODE = "Защитный код" +POLL_ENTER_CODE_ERR = "Вы ввели неверный защитный код! +POLL_ERROR_PERM = "У вас недостаточно прав для комментирования" [showpolls] POLL_ACTIONS = "Действия" @@ -70,9 +79,10 @@ POLL_DELETE = "Удалить данный опрос" POLL_DELETE_CONFIRM = "Вы уверены, что хотите удалить данный опрос?" POLL_EDIT_POLL = "Редактировать данный опрос" POLL_HITS_CMMENT = "Мнений/Комментариев" +POLL_EDIT_CMMENT = "Редактировать комментарий" POLL_INACTIVE = "Опрос неактивен" POLL_MODULE_NAME = "Опросы" -POLL_MODULE_TITLE = "В данном разделе представлены все существующие опросы в системе.
    Внимание! Для работы корректной работы модуля необходимо добавить в корневой .htaccess следующие строки
    RewriteRule ^poll-([0-9]+).html$ index.php?module=poll&action=result&pid=$1
    RewriteRule ^pollcomment-([0-9]+).html$ index.php?module=poll&action=form&pop=1&pid=$1
    RewriteRule ^poll-archive.html$ index.php?module=poll&action=archive " +POLL_MODULE_TITLE = "В данном разделе представлены все существующие опросы в системе." POLL_MODULE_ALL = "Список опросов" POLL_NAME = "Тема опроса" POLL_NEW_LINK = "Создать новый опрос" @@ -107,6 +117,7 @@ POLL_QUESTIONS = "Варианты ответа" POLL_QUESTIONS_ADD = "Добавить вариант" POLL_QUESTION_NO_ITEMS = "Нет вариантов ответа" POLL_POSITION_SUCCES = "Порядок сохранён" +POLL_ANTISPAM = "Использовать защитный код (Captcha)?" [newpolls] POLL_ADD_POLL = "Создание нового опроса" @@ -131,6 +142,7 @@ POLL_STATUS = "Активный" POLL_USER_GROUPS = "Группы пользователей, участвующие в опросе:" POLL_YES = "Да" POLL_MODULE_NAME = "Опросы" +POLL_ANTISPAM = "Использовать защитный код (Captcha)?" [showcomments] POLL_BUTTON_CLOSE = "Закрыть окно" @@ -143,3 +155,4 @@ POLL_COMMENT_INFO = "Информация" POLL_COMMENT_TITLE = "Содержимое комментария" POLL_MARK_DELETE = "Отметить для удаления" POLL_MODULE_NAME = "Опросы" +POLL_NEW_LINK = "Создать новый опрос" diff --git a/module.php b/module.php index ccb6400..dc6587f 100644 --- a/module.php +++ b/module.php @@ -2,7 +2,6 @@ if(!defined('BASE_DIR')) exit; - function mod_poll($poll_id) { require_once(BASE_DIR . '/modules/poll/class/poll.php'); @@ -28,14 +27,17 @@ if (!defined('ACP') $tpl_dir = BASE_DIR . '/modules/poll/templates/'; $lang_file = BASE_DIR . '/modules/poll/lang/' . $_SESSION['user_language'] . '.txt'; + // получение PID для публичной части + $pid = (int)($_REQUEST['pid'] ?? 0); + switch ($_REQUEST['action']) { case 'result': - $poll->pollResultShow($tpl_dir, $lang_file, (int)$_REQUEST['pid']); + $poll->pollResultShow($tpl_dir, $lang_file, $pid); break; case 'vote': - $poll->pollVote((int)$_REQUEST['pid']); + $poll->pollVote($pid); break; case 'archive': @@ -43,11 +45,11 @@ if (!defined('ACP') break; case 'form': - $poll->pollCommentShow($tpl_dir, $lang_file, (int)$_REQUEST['pid'], THEME_FOLDER); + $poll->pollCommentShow($tpl_dir, $lang_file, $pid, THEME_FOLDER); break; case 'comment': - $poll->pollCommentNew($tpl_dir, $lang_file, (int)$_REQUEST['pid']); + $poll->pollCommentNew($tpl_dir, $lang_file, $pid); break; } } @@ -62,6 +64,9 @@ if (defined('ACP') && !empty($_REQUEST['moduleaction'])) $adm_dir = BASE_DIR . '/modules/poll/admin/'; $lang_file = BASE_DIR . '/modules/poll/lang/' . $_SESSION['user_language'] . '.txt'; + // получение ID для админки + $id = (int)($_REQUEST['id'] ?? 0); + switch ($_REQUEST['moduleaction']) { case '1': @@ -73,29 +78,28 @@ if (defined('ACP') && !empty($_REQUEST['moduleaction'])) break; case 'save_new': - $poll->pollNewItemSave((int)$_REQUEST['id']); + $poll->pollNewItemSave($id); break; case 'edit': - $poll->pollEdit($adm_dir, $lang_file, (int)$_REQUEST['id']); + $poll->pollEdit($adm_dir, $lang_file, $id); break; case 'save': - $poll->pollSave((int)$_REQUEST['id']); + $poll->pollSave($id); break; case 'delete': - $poll->pollDelete((int)$_REQUEST['id']); + $poll->pollDelete($id); break; case 'comments': - $poll->pollCommentEdit($adm_dir, $lang_file, (int)$_REQUEST['id']); + $poll->pollCommentEdit($adm_dir, $lang_file, $id); break; case 'sort': - $poll->pollSort((array)$_REQUEST['sort']); + $poll->pollSort((array)($_REQUEST['sort'] ?? [])); exit; } } - ?> \ No newline at end of file diff --git a/sql.php b/sql.php index 39952fa..b6325af 100644 --- a/sql.php +++ b/sql.php @@ -5,7 +5,7 @@ * * @package AVE.cms * @subpackage mod_poll - * @since 1.1 + * @since 3.31 * @filesource */ @@ -17,77 +17,82 @@ $module_sql_install = array(); $module_sql_deinstall = array(); $module_sql_update = array(); -// Удаление модуля -$module_sql_deinstall[] = "DROP TABLE IF EXISTS %%PRFX%%_module_poll;"; -$module_sql_deinstall[] = "DROP TABLE IF EXISTS %%PRFX%%_module_poll_comments;"; -$module_sql_deinstall[] = "DROP TABLE IF EXISTS %%PRFX%%_module_poll_items;"; +// --- 1. УДАЛЕНИЕ МОДУЛЯ --- +$module_sql_deinstall[] = "DROP TABLE IF EXISTS `%%PRFX%%_module_poll`;"; +$module_sql_deinstall[] = "DROP TABLE IF EXISTS `%%PRFX%%_module_poll_comments`;"; +$module_sql_deinstall[] = "DROP TABLE IF EXISTS `%%PRFX%%_module_poll_items`;"; -// Установка модуля -$module_sql_install[] = "CREATE TABLE %%PRFX%%_module_poll ( - id int(10) unsigned NOT NULL auto_increment, - poll_title varchar(255) NOT NULL default '', - poll_status enum('1','0') NOT NULL default '1', - poll_can_comment enum('0','1') NOT NULL default '0', - poll_groups_id tinytext, - poll_start int(10) unsigned NOT NULL default '0', - poll_end int(10) unsigned NOT NULL default '0', - poll_users_id text NOT NULL default '', - poll_users_ip text NOT NULL default '', - PRIMARY KEY (id) -) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; +// При удалении модуля чистим ВСЕ алиасы, связанные с ним +$module_sql_deinstall[] = "DELETE FROM `%%PRFX%%_modules_aliases` WHERE module_name = 'poll';"; -$module_sql_install[] = "CREATE TABLE %%PRFX%%_module_poll_comments ( - id int(10) unsigned NOT NULL auto_increment, - poll_id int(10) NOT NULL, - poll_comment_author_id int(10) NOT NULL, - poll_comment_author_ip text NOT NULL default '', - poll_comment_time int(10) unsigned NOT NULL default '0', - poll_comment_title varchar(250) NOT NULL default '', - poll_comment_text text NOT NULL default '', - PRIMARY KEY (id) -) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; -$module_sql_install[] = "CREATE TABLE %%PRFX%%_module_poll_items ( - id int(10) unsigned NOT NULL auto_increment, - poll_id int(10) NOT NULL, - poll_item_title varchar(250) NOT NULL default '', - poll_item_hits int(10) NOT NULL default '0', - poll_item_color varchar(10) NOT NULL default '', - poll_item_position int(2) NOT NULL, - PRIMARY KEY (id) -) ENGINE=MyISAM DEFAULT CHARSET=utf8;"; +// --- 2. УСТАНОВКА МОДУЛЯ --- +$module_sql_install[] = " +CREATE TABLE IF NOT EXISTS `%%PRFX%%_module_poll` ( + `id` int(10) unsigned NOT NULL auto_increment, + `poll_title` varchar(255) NOT NULL default '', + `poll_status` enum('1','0') NOT NULL default '1', + `poll_can_comment` enum('0','1') NOT NULL default '0', + `poll_anti_spam` enum('0','1') NOT NULL default '0', + `poll_groups_id` tinytext, + `poll_start` int(10) unsigned NOT NULL default '0', + `poll_end` int(10) unsigned NOT NULL default '0', + `poll_users_id` text NOT NULL default '', + `poll_users_ip` text NOT NULL default '', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +"; -// Обновление модуля +$module_sql_install[] = " +CREATE TABLE IF NOT EXISTS `%%PRFX%%_module_poll_comments` ( + `id` int(10) unsigned NOT NULL auto_increment, + `poll_id` int(10) NOT NULL, + `poll_comment_author_id` int(10) NOT NULL, + `poll_comment_author_ip` text NOT NULL default '', + `poll_comment_time` int(10) unsigned NOT NULL default '0', + `poll_comment_title` varchar(250) NOT NULL default '', + `poll_comment_text` text NOT NULL default '', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +"; + +$module_sql_install[] = " +CREATE TABLE IF NOT EXISTS `%%PRFX%%_module_poll_items` ( + `id` int(10) unsigned NOT NULL auto_increment, + `poll_id` int(10) NOT NULL, + `poll_item_title` varchar(250) NOT NULL default '', + `poll_item_hits` int(10) NOT NULL default '0', + `poll_item_color` varchar(10) NOT NULL default '', + `poll_item_position` int(2) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +"; + +// ШТАТНОЕ ЧПУ +$module_sql_install[] = " +INSERT INTO `%%PRFX%%_modules_aliases` + SET module_name = 'poll', + module_action = 'archive', + module_link = 'index.php?module=poll&action=archive', + module_url = 'poll-archive', + module_admin = '0'; +"; + + +// --- 3. ОБНОВЛЕНИЕ МОДУЛЯ --- $module_sql_update[] = " UPDATE `%%PRFX%%_module` SET - ModuleAveTag = '" . $modul['ModuleAveTag'] . "', - ModulePHPTag = '" . $modul['ModulePHPTag'] . "', - ModuleVersion = '" . $modul['ModuleVersion'] . "' + ModuleAveTag = '" . (isset($module['ModuleAveTag']) ? $module['ModuleAveTag'] : '') . "', + ModulePHPTag = '" . (isset($module['ModulePHPTag']) ? $module['ModulePHPTag'] : '') . "', + ModuleVersion = '" . (isset($module['ModuleVersion']) ? $module['ModuleVersion'] : '') . "' WHERE - ModuleSysName = '" . $modul['ModuleSysName'] . "' + ModuleSysName = 'poll' LIMIT 1; "; -$module_sql_update[] = " - RENAME TABLE - `%%PRFX%%_modul_poll` - TO - `%%PRFX%%_module_poll` -"; +// Добавляем поле poll_anti_spam, если его еще нет +$module_sql_update[] = "ALTER TABLE `%%PRFX%%_module_poll` ADD IF NOT EXISTS `poll_anti_spam` enum('0','1') NOT NULL DEFAULT '0' AFTER `poll_can_comment`"; -$module_sql_update[] = " - RENAME TABLE - `%%PRFX%%_modul_poll_comments` - TO - `%%PRFX%%_module_poll_comments` -"; - -$module_sql_update[] = " - RENAME TABLE - `%%PRFX%%_modul_poll_items` - TO - `%%PRFX%%_module_poll_items` -"; ?> \ No newline at end of file diff --git a/templates/archive.tpl b/templates/archive.tpl index c45a8f8..056a022 100644 --- a/templates/archive.tpl +++ b/templates/archive.tpl @@ -1,24 +1,75 @@ -

    {#POLL_ARCHIVE_TITLE#}


    -
    +
    +
    +

    {#POLL_ARCHIVE_TITLE#}

    +
    -
    -
    +
    + + +
    @@ -75,6 +78,12 @@ + + + +
    - - - - - - - - - - - {foreach from=$items item=item} - - - - - - - {/foreach} -
    {#POLL_PUB_TITLE#}{#POLL_PUB_START#}{#POLL_PUB_END#}{#POLL_ARCHIVE_HITS#}
    {$item->poll_title}{$item->poll_start|date_format:$DATE_FORMAT|pretty_date}{$item->poll_end|date_format:$DATE_FORMAT|pretty_date}{$item->votes}

    -
    \ No newline at end of file +
    +
    + + + + + + + + + + + + + + {foreach from=$items item=item} + + + + + + + {foreachelse} + + {/foreach} + +
    + + {#POLL_PUB_TITLE#} + {if $order=='title'}{/if} + + + + {#POLL_PUB_START#} + {if $order=='start'}{/if} + + + + {#POLL_PUB_END#} + {if $order=='end'}{/if} + + + + {#POLL_ARCHIVE_HITS#} + {if $order=='votes'}{/if} + +
    + + {$item->poll_title|escape} + + + {$item->poll_start|date_format:$DATE_FORMAT|pretty_date} + + {$item->poll_end|date_format:$DATE_FORMAT|pretty_date} + + {$item->votes} +
    Архив пока пуст
    +
    +
    +
    + + \ No newline at end of file diff --git a/templates/js/common.js b/templates/js/common.js index 5e3441e..f74e656 100644 --- a/templates/js/common.js +++ b/templates/js/common.js @@ -1 +1,31 @@ -(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); \ No newline at end of file +(function initLimit() { + // Ждем, пока jQuery (или $) появится в глобальном окне + if (window.jQuery || window.$) { + var $ = window.jQuery || window.$; + + $.fn.extend({ + limit: function (limit, element) { + var self = $(this); + var $element = $(element); + var doSubstring = function () { + var val = self.val(); + var length = val.length; + if (length > limit) { + self.val(val.substring(0, limit)); + length = limit; + } + if ($element.length) { + var remaining = limit - length; + $element.html(remaining <= 0 ? '0' : remaining); + } + }; + this.on('input focus blur keyup', doSubstring); + doSubstring(); + } + }); + + } else { + // Если jQuery еще нет, проверяем снова через 50мс + setTimeout(initLimit, 50); + } +})(); \ No newline at end of file diff --git a/templates/poll_nav.tpl b/templates/poll_nav.tpl index 7381461..8198ada 100644 --- a/templates/poll_nav.tpl +++ b/templates/poll_nav.tpl @@ -1,10 +1,29 @@ -

    {$poll->poll_title}

    -
    -

    - {foreach from=$items item=item} -  {$item->poll_item_title}
    - {/foreach} -

    -   - -
    \ No newline at end of file +
    +
    +
    + {$poll->poll_title|escape} +
    +
    + +
    +
    +
    + {foreach from=$items item=item} + + {/foreach} +
    + +
    + + +
    +
    +
    +
    \ No newline at end of file diff --git a/templates/poll_nav_result.tpl b/templates/poll_nav_result.tpl index b94079e..d5d57fb 100644 --- a/templates/poll_nav_result.tpl +++ b/templates/poll_nav_result.tpl @@ -1,15 +1,49 @@ -

    {$poll->poll_title}

    -

    - {foreach from=$items item=item} -

    {$item->poll_item_title}
    -
    -
    -
    - {#POLL_VOTES#} {$item->poll_item_hits} ({$item->sum|default:'0'}%) - {/foreach} -

    -{if $poll->message != ''}

    {$poll->message}

    {/if} -
    -   - -
    \ No newline at end of file +
    +
    +
    {$poll->poll_title}
    +
    + +
    +
    + {foreach from=$items item=item} +
    +
    + {$item->poll_item_title} + {$item->sum|default:'0'}% +
    + +
    +
    +
    +
    + +
    + + {#POLL_VOTES#} {$item->poll_item_hits} + +
    +
    + {/foreach} +
    + + {if $poll->message != ''} +
    + {$poll->message} +
    + {/if} + +
    + + +
    +
    +
    \ No newline at end of file diff --git a/templates/result.tpl b/templates/result.tpl index 1a3d39a..aa507a4 100644 --- a/templates/result.tpl +++ b/templates/result.tpl @@ -1,181 +1,197 @@ -{literal} - -{/literal} - +
    +
    + captcha +
    + +
    +{/if} + +
    + +
    +
    + {/if} + + {/if} + -

    {$poll->poll_title|escape}

    +
    +
    +
    {#POLL_INFOS#}
    +
    + + + + + +
    {#POLL_ALL_HITS#}{$poll->votes}
    {#POLL_PUB_STATUS#}{if $poll->poll_end > $smarty.now}{#POLL_ACTIVE_INFO#}{else}{#POLL_INACTIVE_INFO#}{/if}
    {#POLL_STARTED#}{$poll->poll_start|date_format:$TIME_FORMAT|pretty_date}
    {#POLL_ENDED#}{$poll->poll_end|date_format:$TIME_FORMAT|pretty_date}
    +
    +
    -
    - - - - - - - - - - - - {foreach from=$poll->items item=item} - - - - - - - {/foreach} -
    {#POLL_QUESTION_LIST#}{#POLL_RESULT_INFO#}
    {$item->poll_item_title|escape}
    {$item->poll_item_hits}
    -
    -
    sum}%{else}1%{/if};height:12px;background-color:{$item->poll_item_color}"> - -
    -
    -
    {$item->sum} %
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {#POLL_INFOS#}
    {#POLL_ALL_HITS#}{$poll->votes}
    {#POLL_PUB_STATUS#}{if $poll->poll_end > $smarty.now}{#POLL_ACTIVE_INFO#}{else}{#POLL_INACTIVE_INFO#}{/if}
    {#POLL_STARTED#}{$poll->poll_start|date_format:$TIME_FORMAT|pretty_date}
    {#POLL_ENDED#}{$poll->poll_end|date_format:$TIME_FORMAT|pretty_date}
    {#POLL_GROUPS_PERM#}{$poll->groups|escape}
    - - {if $poll->can_vote == 1} -
    -
    {$poll->poll_title|escape}
    -
    - {foreach from=$poll->items item=item} -
    {$item->poll_item_title|escape}
    - {/foreach} -
    -
    - {/if} + {if $poll->can_vote == 1} +
    +
    +
    {#POLL_BUTTON_VOTE#}
    +
    + {foreach from=$poll->items item=item} +
    + + +
    + {/foreach} + +
    +
    +
    + {/if} +
    +
    -{if $poll->poll_can_comment == 1} -
    -
    {#POLL_PUB_COMMENTS#}
    + - {/if} -{/if} \ No newline at end of file + return false; + {rdelim}); + {rdelim}); + {rdelim} else {ldelim} + setTimeout(waitJQ, 50); + {rdelim} +{rdelim})(); + \ No newline at end of file