mirror of
https://github.com/torrentpier/torrentpier
synced 2025-07-05 12:36:12 -07:00
- Add Language singleton class (src/Language.php) following TorrentPier patterns - Implement automatic source language fallback loading - Add dot notation support for nested language arrays - Provide convenient shorthand functions __() and _e() in common.php - Maintain 100% backward compatibility with global $lang variable - Replace manual language file loading in bb_die() and bb_date() functions - Update poll.php as modern usage example with __() shorthand - Integrate with User.php initialization via lang()->initializeLanguage() - Clean up Template.php compilation removing legacy source language logic - Add comprehensive UPGRADE_GUIDE.md documentation section BREAKING CHANGE: None - full backward compatibility maintained
179 lines
5.2 KiB
PHP
179 lines
5.2 KiB
PHP
<?php
|
||
/**
|
||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||
*
|
||
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||
*/
|
||
|
||
define('BB_SCRIPT', 'vote');
|
||
|
||
require __DIR__ . '/common.php';
|
||
|
||
// Start session management
|
||
$user->session_start(['req_login' => true]);
|
||
|
||
$mode = (string)$_POST['mode'];
|
||
$topic_id = (int)$_POST['topic_id'];
|
||
$forum_id = (int)$_POST['forum_id'];
|
||
$vote_id = (int)$_POST['vote_id'];
|
||
|
||
$return_topic_url = TOPIC_URL . $topic_id;
|
||
$return_topic_url .= !empty($_POST['start']) ? "&start=" . (int)$_POST['start'] : '';
|
||
|
||
set_die_append_msg($forum_id, $topic_id);
|
||
|
||
$poll = new TorrentPier\Legacy\Poll();
|
||
|
||
// Checking $topic_id
|
||
if (!$topic_id) {
|
||
bb_die(__('INVALID_TOPIC_ID'));
|
||
}
|
||
|
||
// Getting topic data if present
|
||
if (!$t_data = DB()->table(BB_TOPICS)->where('topic_id', $topic_id)->fetch()?->toArray()) {
|
||
bb_die(__('INVALID_TOPIC_ID_DB'));
|
||
}
|
||
|
||
// Checking the rights
|
||
if ($mode != 'poll_vote') {
|
||
if ($t_data['topic_poster'] != $userdata['user_id']) {
|
||
if (!IS_AM) {
|
||
bb_die(__('NOT_AUTHORISED'));
|
||
}
|
||
}
|
||
}
|
||
|
||
// Checking the ability to make changes
|
||
if ($mode == 'poll_delete') {
|
||
if ($t_data['topic_time'] < TIMENOW - config()->get('poll_max_days') * 86400) {
|
||
bb_die(sprintf(__('NEW_POLL_DAYS'), config()->get('poll_max_days')));
|
||
}
|
||
if (!IS_ADMIN && ($t_data['topic_vote'] != POLL_FINISHED)) {
|
||
bb_die(__('CANNOT_DELETE_POLL'));
|
||
}
|
||
}
|
||
|
||
switch ($mode) {
|
||
case 'poll_vote':
|
||
// Checking for poll existence
|
||
if (!$t_data['topic_vote']) {
|
||
bb_die(__('POST_HAS_NO_POLL'));
|
||
}
|
||
|
||
// Checking that the topic has not been locked
|
||
if ($t_data['topic_status'] == TOPIC_LOCKED) {
|
||
bb_die(__('TOPIC_LOCKED_SHORT'));
|
||
}
|
||
|
||
// Checking that poll has not been finished
|
||
if (!\TorrentPier\Legacy\Poll::pollIsActive($t_data)) {
|
||
bb_die(__('NEW_POLL_ENDED'));
|
||
}
|
||
|
||
if (!$vote_id) {
|
||
bb_die(__('NO_VOTE_OPTION'));
|
||
}
|
||
|
||
if (\TorrentPier\Legacy\Poll::userIsAlreadyVoted($topic_id, (int)$userdata['user_id'])) {
|
||
bb_die(__('ALREADY_VOTED'));
|
||
}
|
||
|
||
$affected_rows = DB()->table(BB_POLL_VOTES)
|
||
->where('topic_id', $topic_id)
|
||
->where('vote_id', $vote_id)
|
||
->update(['vote_result' => new \Nette\Database\SqlLiteral('vote_result + 1')]);
|
||
|
||
if ($affected_rows != 1) {
|
||
bb_die(__('NO_VOTE_OPTION'));
|
||
}
|
||
|
||
// Voting process
|
||
try {
|
||
DB()->table(BB_POLL_USERS)->insert([
|
||
'topic_id' => $topic_id,
|
||
'user_id' => $userdata['user_id'],
|
||
'vote_ip' => USER_IP,
|
||
'vote_dt' => TIMENOW
|
||
]);
|
||
} catch (\Nette\Database\UniqueConstraintViolationException $e) {
|
||
// Ignore duplicate entry (equivalent to INSERT IGNORE)
|
||
}
|
||
CACHE('bb_poll_data')->rm("poll_$topic_id");
|
||
bb_die(__('VOTE_CAST'));
|
||
break;
|
||
case 'poll_start':
|
||
// Checking for poll existence
|
||
if (!$t_data['topic_vote']) {
|
||
bb_die(__('POST_HAS_NO_POLL'));
|
||
}
|
||
|
||
// Starting the poll
|
||
DB()->table(BB_TOPICS)
|
||
->where('topic_id', $topic_id)
|
||
->update(['topic_vote' => 1]);
|
||
bb_die(__('NEW_POLL_START'));
|
||
break;
|
||
case 'poll_finish':
|
||
// Checking for poll existence
|
||
if (!$t_data['topic_vote']) {
|
||
bb_die(__('POST_HAS_NO_POLL'));
|
||
}
|
||
|
||
// Finishing the poll
|
||
DB()->table(BB_TOPICS)
|
||
->where('topic_id', $topic_id)
|
||
->update(['topic_vote' => POLL_FINISHED]);
|
||
bb_die(__('NEW_POLL_END'));
|
||
break;
|
||
case 'poll_delete':
|
||
// Checking for poll existence
|
||
if (!$t_data['topic_vote']) {
|
||
bb_die(__('POST_HAS_NO_POLL'));
|
||
}
|
||
|
||
// Removing poll from database
|
||
$poll->delete_poll($topic_id);
|
||
bb_die(__('NEW_POLL_DELETE'));
|
||
break;
|
||
case 'poll_add':
|
||
// Checking that no other poll exists
|
||
if ($t_data['topic_vote']) {
|
||
bb_die(__('NEW_POLL_ALREADY'));
|
||
}
|
||
|
||
// Make a poll from $_POST data
|
||
$poll->build_poll_data($_POST);
|
||
|
||
// Showing errors if present
|
||
if ($poll->err_msg) {
|
||
bb_die($poll->err_msg);
|
||
}
|
||
|
||
// Adding poll info to the database
|
||
$poll->insert_votes_into_db($topic_id);
|
||
bb_die(__('NEW_POLL_ADDED'));
|
||
break;
|
||
case 'poll_edit':
|
||
// Checking for poll existence
|
||
if (!$t_data['topic_vote']) {
|
||
bb_die(__('POST_HAS_NO_POLL'));
|
||
}
|
||
|
||
// Make a poll from $_POST data
|
||
$poll->build_poll_data($_POST);
|
||
|
||
// Showing errors if present
|
||
if ($poll->err_msg) {
|
||
bb_die($poll->err_msg);
|
||
}
|
||
|
||
// Updating poll info to the database
|
||
$poll->insert_votes_into_db($topic_id);
|
||
CACHE('bb_poll_data')->rm("poll_$topic_id");
|
||
bb_die(__('NEW_POLL_RESULTS'));
|
||
break;
|
||
default:
|
||
bb_die('Invalid mode: ' . htmlCHR($mode));
|
||
}
|