Removed unfinished leftovers of priority voting and polls.

This commit is contained in:
flash 2023-01-01 05:01:18 +00:00
parent cd959b7e55
commit aef7297bee
18 changed files with 23 additions and 642 deletions

View file

@ -4,7 +4,7 @@ var Misuzu = function() {
Misuzu.started = true;
console.log(
"%cMisuzu%c\nhttps://github.com/flashwave/misuzu",
"%cMisuzu%c\nhttps://git.flash.moe/flashii/misuzu",
'font-size: 48px; color: #8559a5; background: #111;'
+ 'border-radius: 5px; padding: 0 10px; text-shadow: 0 0 1em #fff;',
);
@ -19,7 +19,6 @@ var Misuzu = function() {
Misuzu.initQuickSubmit();
Misuzu.Comments.init();
Misuzu.Forum.Editor.init();
Misuzu.Forum.Polls.init();
if(Misuzu.User.isLoggedIn())
console.log(

View file

@ -1,49 +0,0 @@
Misuzu.Forum.Polls = {};
Misuzu.Forum.Polls.init = function() {
var polls = document.getElementsByClassName('js-forum-poll');
if(!polls.length)
return;
for(var i = 0; i < polls.length; ++i)
Misuzu.Forum.Polls.initPoll(polls[i]);
};
Misuzu.Forum.Polls.initPoll = function() {
var options = poll.getElementsByClassName('input__checkbox__input'),
votesRemaining = poll.querySelector('.js-forum-poll-remaining'),
votesRemainingCount = poll.querySelector('.js-forum-poll-remaining-count'),
votesRemainingPlural = poll.querySelector('.js-forum-poll-remaining-plural'),
maxVotes = parseInt(poll.dataset.pollMaxVotes);
if(maxVotes < 2)
return;
var votes = maxVotes;
for(var i = 0; i < options.length; ++i) {
if(options[i].checked) {
if(votes < 1)
options[i].checked = false;
else
votes--;
}
options[i].addEventListener('change', function(ev) {
if(this.checked) {
if(votes < 1) {
this.checked = false;
ev.preventDefault();
return;
}
votes--;
} else
votes++;
votesRemainingCount.textContent = votes.toString();
votesRemainingPlural.hidden = votes == 1;
});
}
votesRemaining.hidden = false;
votesRemainingCount.textContent = votes.toString();
votesRemainingPlural.hidden = votes == 1;
};

View file

@ -0,0 +1,12 @@
<?php
namespace Misuzu\DatabaseMigrations\NukeOldWipForumComponents;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec('ALTER TABLE `msz_forum_topics` DROP COLUMN `poll_id`, DROP INDEX `posts_poll_id_foreign`, DROP FOREIGN KEY `posts_poll_id_foreign`;');
$conn->exec('DROP TABLE msz_forum_polls_answers;');
$conn->exec('DROP TABLE msz_forum_polls_options;');
$conn->exec('DROP TABLE msz_forum_polls;');
$conn->exec('DROP TABLE msz_forum_topics_priority;');
}

View file

@ -63,7 +63,6 @@ require_once 'src/url.php';
require_once 'src/Forum/perms.php';
require_once 'src/Forum/forum.php';
require_once 'src/Forum/leaderboard.php';
require_once 'src/Forum/poll.php';
require_once 'src/Forum/post.php';
require_once 'src/Forum/topic.php';
require_once 'src/Forum/validate.php';

View file

@ -54,8 +54,7 @@ $topics = $forumMayHaveTopics
$forumUserId,
$forumPagination->getOffset(),
$forumPagination->getRange(),
perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST),
forum_has_priority_voting($forum['forum_type'])
perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST)
)
: [];

View file

@ -1,102 +0,0 @@
<?php
namespace Misuzu;
use Misuzu\Users\User;
require_once '../../misuzu.php';
$redirect = !empty($_SERVER['HTTP_REFERER']) && empty($_SERVER['HTTP_X_MISUZU_XHR']) ? $_SERVER['HTTP_REFERER'] : '';
$isXHR = !$redirect;
if($isXHR) {
header('Content-Type: application/json; charset=utf-8');
} elseif(!is_local_url($redirect)) {
echo render_info('Possible request forgery detected.', 403);
return;
}
if(!CSRF::validateRequest()) {
echo render_info_or_json($isXHR, "Couldn't verify this request, please refresh the page and try again.", 403);
return;
}
$currentUser = User::getCurrent();
if($currentUser === null) {
echo render_info_or_json($isXHR, 'You must be logged in to vote on polls.', 401);
return;
}
$currentUserId = $currentUser->getId();
if($currentUser->isBanned()) {
echo render_info_or_json($isXHR, 'You have been banned, check your profile for more information.', 403);
return;
}
if($currentUser->isSilenced()) {
echo render_info_or_json($isXHR, 'You have been silenced, check your profile for more information.', 403);
return;
}
header(CSRF::header());
if(empty($_POST['poll']['id']) || !ctype_digit($_POST['poll']['id'])) {
echo render_info_or_json($isXHR, "Invalid request.", 400);
return;
}
$poll = forum_poll_get($_POST['poll']['id']);
if(empty($poll)) {
echo "Poll {$poll['poll_id']} doesn't exist.<br>";
return;
}
$topicInfo = forum_poll_get_topic($poll['poll_id']);
if(!is_null($topicInfo['topic_locked'])) {
echo "The topic associated with this poll has been locked.<br>";
return;
}
if(!forum_perms_check_user(
MSZ_FORUM_PERMS_GENERAL, $topicInfo['forum_id'],
$currentUserId, MSZ_FORUM_PERM_SET_READ
)) {
echo "You aren't allowed to vote on this poll.<br>";
return;
}
if($poll['poll_expired']) {
echo "Voting for poll {$poll['poll_id']} has closed.<br>";
return;
}
if(!$poll['poll_change_vote'] && forum_poll_has_voted($currentUserId, $poll['poll_id'])) {
echo "Can't change vote for {$poll['poll_id']}<br>";
return;
}
$answers = !empty($_POST['poll']['answers'])
&& is_array($_POST['poll']['answers'])
? $_POST['poll']['answers']
: [];
if(count($answers) > $poll['poll_max_votes']) {
echo "Too many votes for poll {$poll['poll_id']}<br>";
return;
}
forum_poll_vote_remove($currentUserId, $poll['poll_id']);
foreach($answers as $answerId) {
if(!is_string($answerId) || !ctype_digit($answerId)
|| !forum_poll_validate_option($poll['poll_id'], (int)$answerId)) {
echo "Vote {$answerId} was invalid for {$poll['poll_id']}<br>";
continue;
}
forum_poll_vote_cast($currentUserId, $poll['poll_id'], (int)$answerId);
}
url_redirect('forum-topic', ['topic' => $topicInfo['topic_id']]);

View file

@ -1,55 +0,0 @@
<?php
namespace Misuzu;
use Misuzu\Users\User;
use Misuzu\Users\UserNotFoundException;
require_once '../../misuzu.php';
if(!MSZ_DEBUG)
return;
$topicId = !empty($_GET['t']) && is_string($_GET['t']) ? (int)$_GET['t'] : 0;
$topicUser = User::getCurrent();
$topicUserId = $topicUser === null ? 0 : $topicUser->getId();
if($topicUserId < 1) {
echo render_error(403);
return;
}
$topic = forum_topic_get($topicId, true);
$perms = $topic
? forum_perms_get_user($topic['forum_id'], $topicUserId)[MSZ_FORUM_PERMS_GENERAL]
: 0;
if(isset($topicUser) && $topicUser->hasActiveWarning())
$perms &= ~MSZ_FORUM_PERM_SET_WRITE;
$topicIsDeleted = !empty($topic['topic_deleted']);
$canDeleteAny = perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST);
if(!$topic || ($topicIsDeleted && !$canDeleteAny)) {
echo render_error(404);
return;
}
if(!perms_check($perms, MSZ_FORUM_PERM_VIEW_FORUM, true) // | MSZ_FORUM_PERM_PRIORITY_VOTE
|| !$canDeleteAny
&& (
!empty($topic['topic_locked'])
|| !empty($topic['topic_archived'])
)
) {
echo render_error(403);
return;
}
if(!forum_has_priority_voting($topic['forum_type'])) {
echo render_error(400);
return;
}
forum_topic_priority_increase($topicId, $topicUserId);
url_redirect('forum-topic', ['topic' => $topicId]);

View file

@ -44,15 +44,6 @@ if(!perms_check($perms, MSZ_FORUM_PERM_VIEW_FORUM)) {
return;
}
if(!empty($topic['poll_id'])) {
$pollOptions = forum_poll_get_options($topic['poll_id']);
$pollUserAnswers = forum_poll_get_user_answers($topic['poll_id'], $topicUserId);
}
if(forum_has_priority_voting($topic['forum_type'])) {
$topicPriority = forum_topic_priority($topic['topic_id']);
}
$topicIsLocked = !empty($topic['topic_locked']);
$topicIsArchived = !empty($topic['topic_archived']);
$topicPostsTotal = (int)($topic['topic_count_posts'] + $topic['topic_count_posts_deleted']);
@ -382,7 +373,4 @@ Template::render('forum.topic', [
'topic_can_nuke_or_restore' => $canNukeOrRestore,
'topic_can_bump' => $canBumpTopic,
'topic_can_lock' => $canLockTopic,
'topic_poll_options' => $pollOptions ?? [],
'topic_poll_user_answers' => $pollUserAnswers ?? [],
'topic_priority_votes' => $topicPriority ?? [],
]);

View file

@ -51,10 +51,8 @@ if(isset($_POST['action']) && is_string($_POST['action'])) {
db_to_zip($archive, $currentUserId, 'comments_posts.json', 'SELECT * FROM `msz_comments_posts` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'comments_votes.json', 'SELECT * FROM `msz_comments_votes` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'forum_permissions.json', 'SELECT * FROM `msz_forum_permissions` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'forum_polls_answers.json', 'SELECT * FROM `msz_forum_polls_answers` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'forum_posts.json', 'SELECT *, INET6_NTOA(`post_ip`) AS `post_ip` FROM `msz_forum_posts` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'forum_topics.json', 'SELECT * FROM `msz_forum_topics` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'forum_topics_priority.json', 'SELECT * FROM `msz_forum_topics_priority` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'forum_topics_track.json', 'SELECT * FROM `msz_forum_topics_track` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'login_attempts.json', 'SELECT *, INET6_NTOA(`attempt_ip`) AS `attempt_ip` FROM `msz_login_attempts` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'news_posts.json', 'SELECT * FROM `msz_news_posts` WHERE `user_id` = :user_id');

View file

@ -2,27 +2,19 @@
define('MSZ_FORUM_TYPE_DISCUSSION', 0);
define('MSZ_FORUM_TYPE_CATEGORY', 1);
define('MSZ_FORUM_TYPE_LINK', 2);
define('MSZ_FORUM_TYPE_FEATURE', 3);
define('MSZ_FORUM_TYPES', [
MSZ_FORUM_TYPE_DISCUSSION,
MSZ_FORUM_TYPE_CATEGORY,
MSZ_FORUM_TYPE_LINK,
MSZ_FORUM_TYPE_FEATURE,
]);
define('MSZ_FORUM_MAY_HAVE_CHILDREN', [
MSZ_FORUM_TYPE_DISCUSSION,
MSZ_FORUM_TYPE_CATEGORY,
MSZ_FORUM_TYPE_FEATURE,
]);
define('MSZ_FORUM_MAY_HAVE_TOPICS', [
MSZ_FORUM_TYPE_DISCUSSION,
MSZ_FORUM_TYPE_FEATURE,
]);
define('MSZ_FORUM_HAS_PRIORITY_VOTING', [
MSZ_FORUM_TYPE_FEATURE,
]);
define('MSZ_FORUM_ROOT', 0);
@ -47,10 +39,6 @@ function forum_may_have_topics(int $forumType): bool {
return in_array($forumType, MSZ_FORUM_MAY_HAVE_TOPICS);
}
function forum_has_priority_voting(int $forumType): bool {
return in_array($forumType, MSZ_FORUM_HAS_PRIORITY_VOTING);
}
function forum_get(int $forumId, bool $showDeleted = false): array {
$getForum = \Misuzu\DB::prepare(sprintf(
'

View file

@ -12,7 +12,7 @@ define('MSZ_FORUM_PERM_STICKY_TOPIC', 1 << 14);
define('MSZ_FORUM_PERM_ANNOUNCE_TOPIC', 1 << 15);
define('MSZ_FORUM_PERM_GLOBAL_ANNOUNCE_TOPIC', 1 << 16);
define('MSZ_FORUM_PERM_BUMP_TOPIC', 1 << 17);
define('MSZ_FORUM_PERM_PRIORITY_VOTE', 1 << 18);
//define('MSZ_FORUM_PERM_PRIORITY_VOTE', 1 << 18); // feature postponed, perhaps reuse if it makes sense to
define('MSZ_FORUM_PERM_CREATE_POST', 1 << 20);
define('MSZ_FORUM_PERM_EDIT_POST', 1 << 21);
@ -36,7 +36,6 @@ define(
| MSZ_FORUM_PERM_DELETE_POST
| MSZ_FORUM_PERM_DELETE_ANY_POST
| MSZ_FORUM_PERM_BUMP_TOPIC
| MSZ_FORUM_PERM_PRIORITY_VOTE
);
define('MSZ_FORUM_PERM_MODES', [

View file

@ -1,200 +0,0 @@
<?php
function forum_poll_get(int $poll): array {
if($poll < 1) {
return [];
}
$getPoll = \Misuzu\DB::prepare("
SELECT fp.`poll_id`, fp.`poll_max_votes`, fp.`poll_expires`, fp.`poll_preview_results`, fp.`poll_change_vote`,
(fp.`poll_expires` < CURRENT_TIMESTAMP) AS `poll_expired`,
(
SELECT COUNT(*)
FROM `msz_forum_polls_answers`
WHERE `poll_id` = fp.`poll_id`
) AS `poll_votes`
FROM `msz_forum_polls` AS fp
WHERE fp.`poll_id` = :poll
");
$getPoll->bind('poll', $poll);
return $getPoll->fetch();
}
function forum_poll_create(int $maxVotes = 1): int {
if($maxVotes < 1) {
return -1;
}
$createPoll = \Misuzu\DB::prepare("
INSERT INTO `msz_forum_polls`
(`poll_max_votes`)
VALUES
(:max_votes)
");
$createPoll->bind('max_votes', $maxVotes);
return $createPoll->execute() ? \Misuzu\DB::lastId() : -1;
}
function forum_poll_get_options(int $poll): array {
if($poll < 1) {
return [];
}
static $polls = [];
if(array_key_exists($poll, $polls)) {
return $polls[$poll];
}
$getOptions = \Misuzu\DB::prepare('
SELECT `option_id`, `option_text`,
(
SELECT COUNT(*)
FROM `msz_forum_polls_answers`
WHERE `option_id` = fpo.`option_id`
) AS `option_votes`
FROM `msz_forum_polls_options` AS fpo
WHERE `poll_id` = :poll
');
$getOptions->bind('poll', $poll);
return $polls[$poll] = $getOptions->fetchAll();
}
function forum_poll_get_user_answers(int $poll, int $user): array {
if($poll < 1 || $user < 1) {
return [];
}
$getAnswers = \Misuzu\DB::prepare("
SELECT `option_id`
FROM `msz_forum_polls_answers`
WHERE `poll_id` = :poll
AND `user_id` = :user
");
$getAnswers->bind('poll', $poll);
$getAnswers->bind('user', $user);
return array_column($getAnswers->fetchAll(), 'option_id');
}
function forum_poll_reset_answers(int $poll): void {
if($poll < 1) {
return;
}
$resetAnswers = \Misuzu\DB::prepare("
DELETE FROM `msz_forum_polls_answers`
WHERE `poll_id` = :poll
");
$resetAnswers->bind('poll', $poll);
$resetAnswers->execute();
}
function forum_poll_option_add(int $poll, string $text): int {
if($poll < 1 || empty($text) || strlen($text) > 0xFF) {
return -1;
}
$addOption = \Misuzu\DB::prepare("
INSERT INTO `msz_forum_polls_options`
(`poll_id`, `option_text`)
VALUES
(:poll, :text)
");
$addOption->bind('poll', $poll);
$addOption->bind('text', $text);
return $addOption->execute() ? \Misuzu\DB::lastId() : -1;
}
function forum_poll_option_remove(int $option): void {
if($option < 1) {
return;
}
$removeOption = \Misuzu\DB::prepare("
DELETE FROM `msz_forum_polls_options`
WHERE `option_id` = :option
");
$removeOption->bind('option', $option);
$removeOption->execute();
}
function forum_poll_vote_remove(int $user, int $poll): void {
if($user < 1 || $poll < 1) {
return;
}
$purgeVote = \Misuzu\DB::prepare("
DELETE FROM `msz_forum_polls_answers`
WHERE `user_id` = :user
AND `poll_id` = :poll
");
$purgeVote->bind('user', $user);
$purgeVote->bind('poll', $poll);
$purgeVote->execute();
}
function forum_poll_vote_cast(int $user, int $poll, int $option): void {
if($user < 1 || $poll < 1 || $option < 1) {
return;
}
$castVote = \Misuzu\DB::prepare("
INSERT INTO `msz_forum_polls_answers`
(`user_id`, `poll_id`, `option_id`)
VALUES
(:user, :poll, :option)
");
$castVote->bind('user', $user);
$castVote->bind('poll', $poll);
$castVote->bind('option', $option);
$castVote->execute();
}
function forum_poll_validate_option(int $poll, int $option): bool {
if($poll < 1 || $option < 1) {
return false;
}
$checkVote = \Misuzu\DB::prepare("
SELECT COUNT(`option_id`) > 0
FROM `msz_forum_polls_options`
WHERE `poll_id` = :poll
AND `option_id` = :option
");
$checkVote->bind('poll', $poll);
$checkVote->bind('option', $option);
return (bool)$checkVote->fetchColumn();
}
function forum_poll_has_voted(int $user, int $poll): bool {
if($user < 1 || $poll < 1) {
return false;
}
$getAnswers = \Misuzu\DB::prepare("
SELECT COUNT(`user_id`) > 0
FROM `msz_forum_polls_answers`
WHERE `poll_id` = :poll
AND `user_id` = :user
");
$getAnswers->bind('poll', $poll);
$getAnswers->bind('user', $user);
return (bool)$getAnswers->fetchColumn();
}
function forum_poll_get_topic(int $poll): array {
if($poll < 1) {
return [];
}
$getTopic = \Misuzu\DB::prepare("
SELECT `forum_id`, `topic_id`, `topic_locked`
FROM `msz_forum_topics`
WHERE `poll_id` = :poll
");
$getTopic->bind('poll', $poll);
return $getTopic->fetch();
}

View file

@ -77,8 +77,6 @@ function forum_topic_get(int $topicId, bool $allowDeleted = false): array {
SELECT
t.`topic_id`, t.`forum_id`, t.`topic_title`, t.`topic_type`, t.`topic_locked`, t.`topic_created`,
f.`forum_archived` AS `topic_archived`, t.`topic_deleted`, t.`topic_bumped`, f.`forum_type`,
tp.`poll_id`, tp.`poll_max_votes`, tp.`poll_expires`, tp.`poll_preview_results`, tp.`poll_change_vote`,
(tp.`poll_expires` < CURRENT_TIMESTAMP) AS `poll_expired`,
fp.`topic_id` AS `author_post_id`, fp.`user_id` AS `author_user_id`,
(
SELECT COUNT(`post_id`)
@ -91,12 +89,7 @@ function forum_topic_get(int $topicId, bool $allowDeleted = false): array {
FROM `msz_forum_posts`
WHERE `topic_id` = t.`topic_id`
AND `post_deleted` IS NOT NULL
) AS `topic_count_posts_deleted`,
(
SELECT COUNT(*)
FROM `msz_forum_polls_answers`
WHERE `poll_id` = tp.`poll_id`
) AS `poll_votes`
) AS `topic_count_posts_deleted`
FROM `msz_forum_topics` AS t
LEFT JOIN `msz_forum_categories` AS f
ON f.`forum_id` = t.`forum_id`
@ -106,8 +99,6 @@ function forum_topic_get(int $topicId, bool $allowDeleted = false): array {
FROM `msz_forum_posts`
WHERE `topic_id` = t.`topic_id`
)
LEFT JOIN `msz_forum_polls` AS tp
ON tp.`poll_id` = t.`poll_id`
WHERE t.`topic_id` = :topic_id
%s
',
@ -195,7 +186,6 @@ function forum_topic_listing(
:user_id AS `target_user_id`,
t.`topic_id`, t.`topic_title`, t.`topic_locked`, t.`topic_type`, t.`topic_created`,
t.`topic_bumped`, t.`topic_deleted`, t.`topic_count_views`, f.`forum_type`,
COALESCE(SUM(tp.`topic_priority`), 0) AS `topic_priority`,
au.`user_id` AS `author_id`, au.`username` AS `author_name`,
COALESCE(au.`user_colour`, ar.`role_colour`) AS `author_colour`,
lp.`post_id` AS `response_id`,
@ -238,8 +228,6 @@ function forum_topic_listing(
LIMIT 1
) AS `topic_participated`
FROM `msz_forum_topics` AS t
LEFT JOIN `msz_forum_topics_priority` AS tp
ON tp.`topic_id` = t.`topic_id`
LEFT JOIN `msz_forum_categories` AS f
ON f.`forum_id` = t.`forum_id`
LEFT JOIN `msz_users` AS au
@ -265,7 +253,7 @@ function forum_topic_listing(
)
%1$s
GROUP BY t.`topic_id`
ORDER BY FIELD(t.`topic_type`, %4$s) DESC, %7$s t.`topic_bumped` DESC
ORDER BY FIELD(t.`topic_type`, %4$s) DESC, t.`topic_bumped` DESC
%2$s
',
$showDeleted ? '' : 'AND t.`topic_deleted` IS NULL',
@ -273,8 +261,7 @@ function forum_topic_listing(
MSZ_TOPIC_TYPE_GLOBAL_ANNOUNCEMENT,
implode(',', array_reverse(MSZ_TOPIC_TYPE_ORDER)),
$showDeleted ? '' : 'AND `post_deleted` IS NULL',
MSZ_FORUM_POSTS_PER_PAGE,
$sortByPriority ? '`topic_priority` DESC,' : ''
MSZ_FORUM_POSTS_PER_PAGE
));
$getTopics->bind('forum_id', $forumId);
$getTopics->bind('user_id', $userId);
@ -665,45 +652,3 @@ function forum_topic_nuke(int $topicId): bool {
$nukeTopic->bind('topic', $topicId);
return $nukeTopic->execute();
}
function forum_topic_priority(int $topic): array {
if($topic < 1) {
return [];
}
$getPriority = \Misuzu\DB::prepare('
SELECT
tp.`topic_id`, tp.`topic_priority`,
u.`user_id`, u.`username`,
COALESCE(u.`user_colour`, r.`role_colour`) AS `user_colour`
FROM `msz_forum_topics_priority` AS tp
LEFT JOIN `msz_users` AS u
ON u.`user_id` = tp.`user_id`
LEFT JOIN `msz_roles` AS r
ON u.`display_role` = r.`role_id`
WHERE `topic_id` = :topic
');
$getPriority->bind('topic', $topic);
return $getPriority->fetchAll();
}
function forum_topic_priority_increase(int $topic, int $user, int $bump = 1): void {
if($topic < 1 || $user < 1 || $bump === 0) {
return;
}
$bumpPriority = \Misuzu\DB::prepare('
INSERT INTO `msz_forum_topics_priority`
(`topic_id`, `user_id`, `topic_priority`)
VALUES
(:topic, :user, :bump1)
ON DUPLICATE KEY UPDATE
`topic_priority` = `topic_priority` + :bump2
');
$bumpPriority->bind('topic', $topic);
$bumpPriority->bind('user', $user);
$bumpPriority->bind('bump1', $bump);
$bumpPriority->bind('bump2', $bump);
$bumpPriority->execute();
}

View file

@ -29,7 +29,6 @@ final class TwigMisuzu extends AbstractExtension {
new TwigFunction('html_avatar', 'html_avatar'),
new TwigFunction('forum_may_have_children', 'forum_may_have_children'),
new TwigFunction('forum_may_have_topics', 'forum_may_have_topics'),
new TwigFunction('forum_has_priority_voting', 'forum_has_priority_voting'),
new TwigFunction('csrf_token', fn() => CSRF::token()),
new TwigFunction('git_commit_hash', fn(bool $long = false) => GitInfo::hash($long)),
new TwigFunction('git_tag', fn() => GitInfo::tag()),

View file

@ -348,11 +348,6 @@ function manage_forum_perms_list(array $rawPerms): array {
'title' => 'Can bump topics without posting a reply.',
'perm' => MSZ_FORUM_PERM_BUMP_TOPIC,
],
[
'section' => 'can-priority-vote',
'title' => 'Can vote on topic priority.',
'perm' => MSZ_FORUM_PERM_PRIORITY_VOTE,
],
[
'section' => 'can-create-post',
'title' => 'Can make posts (reply only, if create topic is disallowed).',

View file

@ -54,7 +54,6 @@ define('MSZ_URLS', [
'forum-topic-delete' => ['/forum/topic.php', ['t' => '<topic>', 'm' => 'delete', 'csrf' => '{csrf}']],
'forum-topic-restore' => ['/forum/topic.php', ['t' => '<topic>', 'm' => 'restore', 'csrf' => '{csrf}']],
'forum-topic-nuke' => ['/forum/topic.php', ['t' => '<topic>', 'm' => 'nuke', 'csrf' => '{csrf}']],
'forum-topic-priority' => ['/forum/topic-priority.php', ['t' => '<topic>', 'b' => '<bump>']],
'forum-post' => ['/forum/topic.php', ['p' => '<post>'], '<post_fragment>'],
'forum-post-create' => ['/forum/posting.php', ['t' => '<topic>']],
'forum-post-delete' => ['/forum/post.php', ['p' => '<post>', 'm' => 'delete']],
@ -62,7 +61,6 @@ define('MSZ_URLS', [
'forum-post-nuke' => ['/forum/post.php', ['p' => '<post>', 'm' => 'nuke']],
'forum-post-quote' => ['/forum/posting.php', ['q' => '<post>']],
'forum-post-edit' => ['/forum/posting.php', ['p' => '<post>', 'm' => 'edit']],
'forum-poll-vote' => ['/forum/poll.php'],
'user-list' => ['/members.php', ['r' => '<role>', 'ss' => '<sort>', 'sd' => '<direction>', 'p' => '<page>']],

View file

@ -76,7 +76,7 @@
<div class="container forum__actions">
<div class="forum__actions__buttons">
{% if can_topic %}
<a href="{{ url('forum-topic-new', {'forum': info.forum_id}) }}" class="input__button forum__actions__button">{{ info.forum_type == constant('MSZ_FORUM_TYPE_FEATURE') ? 'New Request' : 'New Topic' }}</a>
<a href="{{ url('forum-topic-new', {'forum': info.forum_id}) }}" class="input__button forum__actions__button">New Topic</a>
{% endif %}
</div>
@ -117,9 +117,7 @@
{% elseif forum.forum_archived is defined and forum.forum_archived %}
{% set forum_icon = 'fas fa-archive fa-fw' %}
{% elseif forum.forum_type is defined and forum.forum_type != constant('MSZ_FORUM_TYPE_DISCUSSION') %}
{% if forum.forum_type == constant('MSZ_FORUM_TYPE_FEATURE') %}
{% set forum_icon = 'fas fa-star fa-fw' %}
{% elseif forum.forum_type == constant('MSZ_FORUM_TYPE_LINK') %}
{% if forum.forum_type == constant('MSZ_FORUM_TYPE_LINK') %}
{% set forum_icon = 'fas fa-link fa-fw' %}
{% elseif forum.forum_type == constant('MSZ_FORUM_TYPE_CATEGORY') %}
{% set forum_icon = 'fas fa-folder fa-fw' %}
@ -257,7 +255,6 @@
{% from 'macros.twig' import avatar %}
{% set topic_unread = topic_unread|default(topic.topic_unread|default(false)) %}
{% set topic_important = topic.topic_type == constant('MSZ_TOPIC_TYPE_STICKY') or topic.topic_type == constant('MSZ_TOPIC_TYPE_ANNOUNCEMENT') or topic.topic_type == constant('MSZ_TOPIC_TYPE_GLOBAL_ANNOUNCEMENT') %}
{% set has_priority_voting = forum_has_priority_voting(topic.forum_type) %}
{% if topic_icon is null %}
{% if topic.topic_deleted is defined and topic.topic_deleted is not null %}
@ -270,8 +267,6 @@
{% endif %}
{% elseif topic.topic_locked is defined and topic.topic_locked is not null %}
{% set topic_icon = 'fas fa-lock' %}
{% elseif has_priority_voting %}
{% set topic_icon = 'far fa-star' %}
{% else %}
{% set topic_icon = (topic_unread ? 'fas' : 'far') ~ ' fa-comment' %}
{% endif %}
@ -281,12 +276,8 @@
<a href="{{ url('forum-topic', {'topic': topic.topic_id}) }}" class="forum__topic__link"></a>
<div class="forum__topic__container">
<div class="forum__topic__icon forum__topic__icon--{{ topic_unread ? 'unread' : 'read' }}{% if has_priority_voting %} forum__topic__icon--wide{% endif %}">
<i class="{{ topic_icon }} fa-fw{% if has_priority_voting %} forum__topic__icon--faded{% endif %}"></i>
{% if has_priority_voting %}
<div class="forum__topic__icon__priority">{{ topic.topic_priority|number_format }}</div>
{% endif %}
<div class="forum__topic__icon forum__topic__icon--{{ topic_unread ? 'unread' : 'read' }}">
<i class="{{ topic_icon }} fa-fw"></i>
{% if topic.topic_participated %}
<div class="forum__topic__icon__participated" title="You have posted in this topic"></div>
@ -471,120 +462,3 @@
</div>
</div>
{% endmacro %}
{% macro forum_poll(poll, options, user_answers, topic_id, can_vote, preview_results) %}
{% from '_layout/input.twig' import input_csrf, input_hidden, input_checkbox, input_checkbox_raw %}
{% set user_answers = user_answers is empty or user_answers is not iterable ? [] : user_answers %}
{% set user_answered = user_answers|length > 0 %}
{% set results_available = preview_results or user_answered or poll.poll_expired or poll.poll_preview_results %}
{% set options_available = not poll.poll_expired and (poll.poll_change_vote or not user_answered) %}
{% set display_results = user_answered or poll.poll_expired %}
{% if options is iterable and options|length > 0 %}
<div class="forum__poll">
{% if results_available %}
{% if options_available %}
{{ input_checkbox_raw('', display_results, 'forum__poll__toggle', '', false, {'id':'forum-poll-toggle'}) }}
{% endif %}
<div class="container forum__poll__container forum__poll__container--results">
<div class="forum__poll__results">
{% for option in options %}
{% set percent = poll.poll_votes < 1 ? 0 : (option.option_votes / poll.poll_votes) * 100 %}
<div class="forum__poll__result{% if option.option_id in user_answers %} forum__poll__result--voted{% endif %}">
<div class="forum__poll__result__background" style="width: {{ percent }}%">
</div>
<div class="forum__poll__result__container">
<div class="forum__poll__result__text">{{ option.option_text }}</div>
<div class="forum__poll__result__votes">{{ option.option_votes|number_format }}</div>
<div class="forum__poll__result__percent">{{ percent|number_format(2) }}%</div>
</div>
</div>
{% endfor %}
</div>
<div class="forum__poll__remaining">
This poll got <span class="forum__poll__remaining__num">{{ poll.poll_votes|number_format }} vote{{ poll.poll_votes == 1 ? '' : 's' }}</span>
</div>
{% if poll.poll_expires is not null %}
<div class="forum__poll__expires">
Polling {{ poll.poll_expired ? 'closed' : 'will close' }} <time class="forum__poll__expires__datetime" datetime="{{ poll.poll_expires|date('c') }}" title="{{ poll.poll_expires|date('r') }}">{{ poll.poll_expires|time_diff }}</time>.
</div>
{% endif %}
{% if options_available %}
<div class="forum__poll__buttons">
<label class="input__button forum__poll__button" for="forum-poll-toggle">Vote</label>
</div>
{% endif %}
</div>
{% endif %}
{% if options_available %}
<form method="post" action="{{ url('forum-poll-vote') }}" class="container forum__poll__container forum__poll__container--poll js-forum-poll"
data-poll-id="{{ poll.poll_id }}" data-poll-max-votes="{{ poll.poll_max_votes }}">
{{ input_csrf() }}
{{ input_hidden('poll[id]', poll.poll_id) }}
<div class="forum__poll__options">
{% for option in options %}
{{ input_checkbox(
'poll[answers][]',
option.option_text, option.option_id in user_answers, 'forum__poll__option',
option.option_id, poll.poll_max_votes <= 1,
null, not can_vote
) }}
{% endfor %}
</div>
{% if can_vote and poll.poll_max_votes > 1 %}
<div class="forum__poll__remaining js-forum-poll-remaining">
You have <span class="forum__poll__remaining__num">
<span class="js-forum-poll-remaining-count">{{ poll.poll_max_votes }}</span> vote<span class="js-forum-poll-remaining-plural">s</span>
</span> remaining.
</div>
{% endif %}
{% if poll.poll_expires is not null %}
<div class="forum__poll__expires">
Polling {{ poll.poll_expired ? 'closed' : 'will close' }} <time class="forum__poll__expires__datetime" datetime="{{ poll.poll_expires|date('c') }}" title="{{ poll.poll_expires|date('r') }}">{{ poll.poll_expires|time_diff }}</time>.
</div>
{% endif %}
<div class="forum__poll__buttons">
{% if can_vote %}
<button class="input__button forum__poll__button">Vote</button>
{% endif %}
{% if results_available %}
<label class="input__button forum__poll__button" for="forum-poll-toggle">Results</label>
{% endif %}
</div>
</form>
{% endif %}
</div>
{% endif %}
{% endmacro %}
{% macro forum_priority_votes(topic, votes, can_vote) %}
<div class="container forum__priority">
<div class="forum__priority__votes">
{% for vote in votes %}
<div title="{{ vote.username }} ({{ vote.topic_priority|number_format }})" class="forum__priority__vote" style="{{ vote.user_colour|html_colour }}">
{% for i in 1..vote.topic_priority %}
<span class="forum__priority__star fas fa-star fa-fw"></span>
{% endfor %}
</div>
{% endfor %}
</div>
{% if can_vote %}
<div class="forum__priority__input">
<a class="input__button" href="{{ url('forum-topic-priority', {'topic':topic.topic_id}) }}">
Vote for this feature
</a>
</div>
{% endif %}
</div>
{% endmacro %}

View file

@ -7,9 +7,7 @@
forum_topic_buttons,
forum_topic_locked,
forum_header,
forum_topic_tools,
forum_poll,
forum_priority_votes
forum_topic_tools
%}
{% set title = topic_info.topic_title %}
@ -57,10 +55,6 @@
{% block content %}
{{ forum_header(topic_info.topic_title, topic_breadcrumbs, false, canonical_url, topic_actions) }}
{{ topic_notice }}
{% if forum_has_priority_voting(topic_info.forum_type) %}
{{ forum_priority_votes(topic_info, topic_priority_votes, true) }} {# replace true this with perms check #}
{% endif %}
{{ forum_poll(topic_info, topic_poll_options, topic_poll_user_answers, topic_info.topic_id, current_user.id|default(0) > 0, topic_info.author_user_id == current_user.id|default(0)) }}
{{ topic_tools }}
{{ forum_post_listing(topic_posts, current_user.id|default(0), topic_perms) }}
{{ topic_tools }}