', $text);
}
function get_bt_userdata($user_id)
{
if (!$btu = CACHE('bb_cache')->get('btu_' . $user_id)) {
$btu = DB()->fetch_row("
SELECT bt.*, SUM(tr.speed_up) AS speed_up, SUM(tr.speed_down) AS speed_down
FROM " . BB_BT_USERS . " bt
LEFT JOIN " . BB_BT_TRACKER . " tr ON (bt.user_id = tr.user_id)
WHERE bt.user_id = " . (int)$user_id . "
GROUP BY bt.user_id
LIMIT 1
");
CACHE('bb_cache')->set('btu_' . $user_id, $btu, 300);
}
return $btu;
}
function get_bt_ratio($btu)
{
return
(!empty($btu['u_down_total']) && $btu['u_down_total'] > MIN_DL_FOR_RATIO)
? round((($btu['u_up_total'] + $btu['u_up_release'] + $btu['u_up_bonus']) / $btu['u_down_total']), 2)
: null;
}
function show_bt_userdata($user_id)
{
global $lang, $template;
$btu = get_bt_userdata($user_id);
$template->assign_vars(array(
'SHOW_BT_USERDATA' => true,
'UP_TOTAL' => humn_size($btu['u_up_total']),
'UP_BONUS' => humn_size($btu['u_up_bonus']),
'RELEASED' => humn_size($btu['u_up_release']),
'DOWN_TOTAL' => humn_size($btu['u_down_total']),
'DOWN_TOTAL_BYTES' => $btu['u_down_total'],
'USER_RATIO' => get_bt_ratio($btu),
'MIN_DL_FOR_RATIO' => humn_size(MIN_DL_FOR_RATIO),
'MIN_DL_BYTES' => MIN_DL_FOR_RATIO,
'AUTH_KEY' => ($btu['auth_key']) ?: $lang['NONE'],
'TD_DL' => humn_size($btu['down_today']),
'TD_UL' => humn_size($btu['up_today']),
'TD_REL' => humn_size($btu['up_release_today']),
'TD_BONUS' => humn_size($btu['up_bonus_today']),
'TD_POINTS' => ($btu['auth_key']) ? $btu['points_today'] : '0.00',
'YS_DL' => humn_size($btu['down_yesterday']),
'YS_UL' => humn_size($btu['up_yesterday']),
'YS_REL' => humn_size($btu['up_release_yesterday']),
'YS_BONUS' => humn_size($btu['up_bonus_yesterday']),
'YS_POINTS' => ($btu['auth_key']) ? $btu['points_yesterday'] : '0.00',
'SPEED_UP' => humn_size($btu['speed_up'], 0, 'KB') . '/s',
'SPEED_DOWN' => humn_size($btu['speed_down'], 0, 'KB') . '/s',
));
}
function get_attachments_dir($cfg = null)
{
if (!$cfg and !$cfg = $GLOBALS['attach_config']) {
$cfg = bb_get_config(BB_ATTACH_CONFIG, true, false);
}
if ($cfg['upload_dir'][0] == '/' || ($cfg['upload_dir'][0] != '/' && $cfg['upload_dir'][1] == ':')) {
return $cfg['upload_dir'];
}
return BB_ROOT . $cfg['upload_dir'];
}
function bb_get_config($table, $from_db = false, $update_cache = true)
{
if ($from_db or !$cfg = CACHE('bb_config')->get("config_{$table}")) {
$cfg = array();
foreach (DB()->fetch_rowset("SELECT * FROM $table") as $row) {
$cfg[$row['config_name']] = $row['config_value'];
}
if ($update_cache) {
CACHE('bb_config')->set("config_{$table}", $cfg);
}
}
return $cfg;
}
function bb_update_config($params, $table = BB_CONFIG)
{
$updates = array();
foreach ($params as $name => $val) {
$updates[] = array(
'config_name' => $name,
'config_value' => $val,
);
}
$updates = DB()->build_array('MULTI_INSERT', $updates);
DB()->query("REPLACE INTO $table $updates");
// Update cache
bb_get_config($table, true, true);
}
function get_db_stat($mode)
{
switch ($mode) {
case 'usercount':
$sql = "SELECT COUNT(user_id) AS total FROM " . BB_USERS;
break;
case 'newestuser':
$sql = "SELECT user_id, username FROM " . BB_USERS . " WHERE user_id <> " . GUEST_UID . " ORDER BY user_id DESC LIMIT 1";
break;
case 'postcount':
case 'topiccount':
$sql = "SELECT SUM(forum_topics) AS topic_total, SUM(forum_posts) AS post_total FROM " . BB_FORUMS;
break;
}
if (!($result = DB()->sql_query($sql))) {
return false;
}
$row = DB()->sql_fetchrow($result);
switch ($mode) {
case 'usercount':
return $row['total'];
break;
case 'newestuser':
return $row;
break;
case 'postcount':
return $row['post_total'];
break;
case 'topiccount':
return $row['topic_total'];
break;
}
return false;
}
function clean_username($username)
{
$username = mb_substr(htmlspecialchars(str_replace("\'", "'", trim($username))), 0, 25, 'UTF-8');
$username = bb_rtrim($username, "\\");
$username = str_replace("'", "\'", $username);
return $username;
}
function bb_ltrim($str, $charlist = false)
{
if ($charlist === false) {
return ltrim($str);
}
$str = ltrim($str, $charlist);
return $str;
}
function bb_rtrim($str, $charlist = false)
{
if ($charlist === false) {
return rtrim($str);
}
$str = rtrim($str, $charlist);
return $str;
}
// Get Userdata, $u can be username or user_id. If $force_name is true, the username will be forced.
function get_userdata($u, $force_name = false, $allow_guest = false)
{
if (!$u) {
return false;
}
if ((int)$u == GUEST_UID && $allow_guest) {
if ($u_data = CACHE('bb_cache')->get('guest_userdata')) {
return $u_data;
}
}
$u_data = array();
$name_search = false;
$exclude_anon_sql = (!$allow_guest) ? "AND user_id != " . GUEST_UID : '';
if ($force_name || !is_numeric($u)) {
$name_search = true;
$where_sql = "WHERE username = '" . DB()->escape(clean_username($u)) . "'";
} else {
$where_sql = "WHERE user_id = " . (int)$u;
}
$sql = "SELECT * FROM " . BB_USERS . " $where_sql $exclude_anon_sql LIMIT 1";
if (!$u_data = DB()->fetch_row($sql)) {
if (!is_int($u) && !$name_search) {
$where_sql = "WHERE username = '" . DB()->escape(clean_username($u)) . "'";
$sql = "SELECT * FROM " . BB_USERS . " $where_sql $exclude_anon_sql LIMIT 1";
$u_data = DB()->fetch_row($sql);
}
}
if ($u_data['user_id'] == GUEST_UID) {
CACHE('bb_cache')->set('guest_userdata', $u_data);
}
return $u_data;
}
function make_jumpbox($selected = 0)
{
global $datastore, $template;
if (!$jumpbox = $datastore->get('jumpbox')) {
$datastore->update('jumpbox');
$jumpbox = $datastore->get('jumpbox');
}
$template->assign_vars(array(
'JUMPBOX' => (IS_GUEST) ? $jumpbox['guest'] : $jumpbox['user'],
));
}
// $mode: array(not_auth_forum1,not_auth_forum2,..) or (string) 'mode'
function get_forum_select($mode = 'guest', $name = POST_FORUM_URL, $selected = null, $max_length = HTML_SELECT_MAX_LENGTH, $multiple_size = null, $js = '', $all_forums_option = null)
{
global $lang, $datastore;
if (is_array($mode)) {
$not_auth_forums_fary = array_flip($mode);
$mode = 'not_auth_forums';
}
if (null === $max_length) {
$max_length = HTML_SELECT_MAX_LENGTH;
}
$select = null === $all_forums_option ? array() : array($lang['ALL_AVAILABLE'] => $all_forums_option);
if (!$forums = $datastore->get('cat_forums')) {
$datastore->update('cat_forums');
$forums = $datastore->get('cat_forums');
}
foreach ($forums['f'] as $fid => $f) {
switch ($mode) {
case 'guest':
if ($f['auth_view'] != AUTH_ALL) {
continue 2;
}
break;
case 'user':
if ($f['auth_view'] != AUTH_ALL && $f['auth_view'] != AUTH_REG) {
continue 2;
}
break;
case 'not_auth_forums':
if (isset($not_auth_forums_fary[$f['forum_id']])) {
continue 2;
}
break;
case 'admin':
break;
default:
trigger_error(__FUNCTION__ . ": invalid mode '$mode'", E_USER_ERROR);
}
$cat_title = $forums['c'][$f['cat_id']]['cat_title'];
$f_name = ($f['forum_parent']) ? ' |- ' : '';
$f_name .= $f['forum_name'];
while (isset($select[$cat_title][$f_name])) {
$f_name .= ' ';
}
$select[$cat_title][$f_name] = $fid;
if (!$f['forum_parent']) {
$class = 'root_forum';
$class .= isset($f['subforums']) ? ' has_sf' : '';
$select['__attributes'][$cat_title][$f_name]['class'] = $class;
}
}
return build_select($name, $select, $selected, $max_length, $multiple_size, $js);
}
function setup_style()
{
global $bb_cfg, $template, $userdata;
// AdminCP works only with default template
$tpl_dir_name = defined('IN_ADMIN') ? 'default' : basename($bb_cfg['tpl_name']);
$stylesheet = defined('IN_ADMIN') ? 'main.css' : basename($bb_cfg['stylesheet']);
if (!IS_GUEST && !empty($userdata['tpl_name'])) {
foreach ($bb_cfg['templates'] as $folder => $name) {
if ($userdata['tpl_name'] == $folder) {
$tpl_dir_name = basename($userdata['tpl_name']);
}
}
}
$template = new TorrentPier\Legacy\Template(TEMPLATES_DIR . '/' . $tpl_dir_name);
$css_dir = 'styles/' . basename(TEMPLATES_DIR) . '/' . $tpl_dir_name . '/css/';
$template->assign_vars(array(
'BB_ROOT' => BB_ROOT,
'SPACER' => make_url('styles/images/spacer.gif'),
'STYLESHEET' => make_url($css_dir . $stylesheet),
'EXT_LINK_NEW_WIN' => $bb_cfg['ext_link_new_win'],
'TPL_DIR' => make_url($css_dir),
'SITE_URL' => make_url('/'),
));
require TEMPLATES_DIR . '/' . $tpl_dir_name . '/tpl_config.php';
return array('template_name' => $tpl_dir_name);
}
// Create date / time with format and friendly date
function bb_date($gmepoch, $format = false, $friendly_date = true)
{
global $bb_cfg, $lang, $userdata;
$gmepoch = (int)$gmepoch;
if (!$format) {
$format = $bb_cfg['default_dateformat'];
}
if (empty($lang)) {
require_once($bb_cfg['default_lang_dir'] . 'main.php');
}
if (empty($userdata['session_logged_in'])) {
$tz = $bb_cfg['board_timezone'];
} else {
$tz = $userdata['user_timezone'];
}
$date = gmdate($format, $gmepoch + (3600 * $tz));
if ($friendly_date) {
$time_format = ' H:i';
$today = gmdate('d', TIMENOW + (3600 * $tz));
$month = gmdate('m', TIMENOW + (3600 * $tz));
$year = gmdate('Y', TIMENOW + (3600 * $tz));
$date_today = gmdate('d', $gmepoch + (3600 * $tz));
$date_month = gmdate('m', $gmepoch + (3600 * $tz));
$date_year = gmdate('Y', $gmepoch + (3600 * $tz));
if ($date_today == $today && $date_month == $month && $date_year == $year) {
$date = 'today' . gmdate($time_format, $gmepoch + (3600 * $tz));
} elseif ($today != 1 && $date_today == ($today - 1) && $date_month == $month && $date_year == $year) {
$date = 'yesterday' . gmdate($time_format, $gmepoch + (3600 * $tz));
} elseif ($today == 1 && $month != 1) {
$yesterday = date('t', mktime(0, 0, 0, ($month - 1), 1, $year));
if ($date_today == $yesterday && $date_month == ($month - 1) && $date_year == $year) {
$date = 'yesterday' . gmdate($time_format, $gmepoch + (3600 * $tz));
}
} elseif ($today == 1 && $month == 1) {
$yesterday = date('t', mktime(0, 0, 0, 12, 1, ($year - 1)));
if ($date_today == $yesterday && $date_month == 12 && $date_year == ($year - 1)) {
$date = 'yesterday' . gmdate($time_format, $gmepoch + (3600 * $tz));
}
}
}
return ($bb_cfg['translate_dates']) ? strtr(strtoupper($date), $lang['DATETIME']) : $date;
}
function birthday_age($date)
{
global $bb_cfg;
if (!$date) {
return;
}
$tz = TIMENOW + (3600 * $bb_cfg['board_timezone']);
return delta_time(strtotime($date, $tz));
}
//
// Pagination routine, generates
// page number sequence
//
function generate_pagination($base_url, $num_items, $per_page, $start_item, $add_prevnext_text = true)
{
global $lang, $template;
// Pagination Mod
$begin_end = 3;
$from_middle = 1;
/*
By default, $begin_end is 3, and $from_middle is 1, so on page 6 in a 12 page view, it will look like this:
a, d = $begin_end = 3
b, c = $from_middle = 1
"begin" "middle" "end"
| | |
| a b | c d |
| | | | | | |
v v v v v v v
1, 2, 3 ... 5, 6, 7 ... 10, 11, 12
Change $begin_end and $from_middle to suit your needs appropriately
*/
$total_pages = ceil($num_items / $per_page);
if ($total_pages == 1 || $num_items == 0) {
return '';
}
$on_page = floor($start_item / $per_page) + 1;
$page_string = '';
if ($total_pages > ((2 * ($begin_end + $from_middle)) + 2)) {
$init_page_max = ($total_pages > $begin_end) ? $begin_end : $total_pages;
for ($i = 1; $i < $init_page_max + 1; $i++) {
$page_string .= ($i == $on_page) ? '' . $i . '' : '' . $i . '';
if ($i < $init_page_max) {
$page_string .= ", ";
}
}
if ($total_pages > $begin_end) {
if ($on_page > 1 && $on_page < $total_pages) {
$page_string .= ($on_page > ($begin_end + $from_middle + 1)) ? ' ... ' : ', ';
$init_page_min = ($on_page > ($begin_end + $from_middle)) ? $on_page : ($begin_end + $from_middle + 1);
$init_page_max = ($on_page < $total_pages - ($begin_end + $from_middle)) ? $on_page : $total_pages - ($begin_end + $from_middle);
for ($i = $init_page_min - $from_middle; $i < $init_page_max + ($from_middle + 1); $i++) {
$page_string .= ($i == $on_page) ? '' . $i . '' : '' . $i . '';
if ($i < $init_page_max + $from_middle) {
$page_string .= ', ';
}
}
$page_string .= ($on_page < $total_pages - ($begin_end + $from_middle)) ? ' ... ' : ', ';
} else {
$page_string .= ' ... ';
}
for ($i = $total_pages - ($begin_end - 1); $i < $total_pages + 1; $i++) {
$page_string .= ($i == $on_page) ? '' . $i . '' : '' . $i . '';
if ($i < $total_pages) {
$page_string .= ", ";
}
}
}
} else {
for ($i = 1; $i < $total_pages + 1; $i++) {
$page_string .= ($i == $on_page) ? '' . $i . '' : '' . $i . '';
if ($i < $total_pages) {
$page_string .= ', ';
}
}
}
if ($add_prevnext_text) {
if ($on_page > 1) {
$page_string = ' ' . $lang['PREVIOUS_PAGE'] . ' ' . $page_string;
}
if ($on_page < $total_pages) {
$page_string .= ' ' . $lang['NEXT_PAGE'] . '';
}
}
$pagination = ($page_string) ? ' : ' . $page_string : '';
$pagination = str_replace('&start=0', '', $pagination);
$template->assign_vars(array(
'PAGINATION' => $pagination,
'PAGE_NUMBER' => sprintf($lang['PAGE_OF'], (floor($start_item / $per_page) + 1), ceil($num_items / $per_page)),
'PG_BASE_URL' => $base_url,
'PG_PER_PAGE' => $per_page,
));
return $pagination;
}
//
// This does exactly what preg_quote() does in PHP 4-ish
// If you just need the 1-parameter preg_quote call, then don't bother using this.
//
function bb_preg_quote($str, $delimiter)
{
$text = preg_quote($str);
$text = str_replace($delimiter, '\\' . $delimiter, $text);
return $text;
}
//
// Obtain list of naughty words and build preg style replacement arrays for use by the
// calling script, note that the vars are passed as references this just makes it easier
// to return both sets of arrays
//
function obtain_word_list(&$orig_word, &$replacement_word)
{
global $bb_cfg;
if (!$bb_cfg['use_word_censor']) {
return;
}
if (!$sql = CACHE('bb_cache')->get('censored')) {
$sql = DB()->fetch_rowset("SELECT word, replacement FROM " . BB_WORDS);
if (!$sql) {
$sql = array(array('word' => 1, 'replacement' => 1));
}
CACHE('bb_cache')->set('censored', $sql, 7200);
}
foreach ($sql as $row) {
//$orig_word[] = '#(?ajax_die($msg_text);
}
// Check
if (defined('HAS_DIED')) {
trigger_error(__FUNCTION__ . ' was called multiple times', E_USER_ERROR);
}
define('HAS_DIED', 1);
define('DISABLE_CACHING_OUTPUT', true);
// If empty lang
if (empty($lang)) {
require($bb_cfg['default_lang_dir'] . 'main.php');
}
// If empty session
if (empty($userdata)) {
$userdata = \TorrentPier\Legacy\Sessions::session_pagestart();
}
// If the header hasn't been output then do it
if (!defined('PAGE_HEADER_SENT')) {
if (empty($template)) {
$template = new TorrentPier\Legacy\Template(BB_ROOT . "templates/{$bb_cfg['tpl_name']}");
}
if (empty($theme)) {
$theme = setup_style();
}
require(PAGE_HEADER);
}
// Check for lang variable
if (!empty($lang[$msg_text])) {
$msg_text = $lang[$msg_text];
}
$template->assign_vars(array(
'TPL_BB_DIE' => true,
'MESSAGE_TEXT' => $msg_text,
));
$template->set_filenames(array('bb_die' => 'common.tpl'));
$template->pparse('bb_die');
require(PAGE_FOOTER);
exit;
}
function bb_simple_die($txt)
{
global $bb_cfg;
if (!empty($_COOKIE['explain'])) {
bb_die("bb_simple_die:
$txt");
}
header('Content-Type: text/plain; charset=' . $bb_cfg['charset']);
die($txt);
}
function bb_realpath($path)
{
return realpath($path);
}
function login_redirect($url = '')
{
redirect(LOGIN_URL . '?redirect=' . (($url) ?: ($_SERVER['REQUEST_URI'] ?? '/')));
}
function meta_refresh($url, $time = 5)
{
global $template;
$template->assign_var('META', '');
}
function redirect($url)
{
global $bb_cfg;
if (headers_sent($filename, $linenum)) {
trigger_error("Headers already sent in $filename($linenum)", E_USER_ERROR);
}
if (false !== strpos(urldecode($url), "\n") || false !== strpos(urldecode($url), "\r") || false !== strpos(urldecode($url), ';url')) {
bb_die('Tried to redirect to potentially insecure url');
}
$url = trim($url);
$server_protocol = ($bb_cfg['cookie_secure']) ? 'https://' : 'http://';
$server_name = preg_replace('#^\/?(.*?)\/?$#', '\1', trim($bb_cfg['server_name']));
$server_port = ($bb_cfg['server_port'] <> 80) ? ':' . trim($bb_cfg['server_port']) : '';
$script_name = preg_replace('#^\/?(.*?)\/?$#', '\1', trim($bb_cfg['script_path']));
if ($script_name) {
$script_name = "/$script_name";
$url = preg_replace("#^$script_name#", '', $url);
}
$redirect_url = $server_protocol . $server_name . $server_port . $script_name . preg_replace('#^\/?(.*?)\/?$#', '/\1', $url);
// Behave as per HTTP/1.1 spec for others
header('Location: ' . $redirect_url);
exit;
}
// build a list of the sortable fields or return field name
function get_forum_display_sort_option($selected_row = 0, $action = 'list', $list = 'sort')
{
global $lang;
$forum_display_sort = array(
'lang_key' => array('LASTPOST', 'SORT_TOPIC_TITLE', 'SORT_TIME'),
'fields' => array('t.topic_last_post_time', 't.topic_title', 't.topic_time'),
);
$forum_display_order = array(
'lang_key' => array('DESC', 'ASC'),
'fields' => array('DESC', 'ASC'),
);
// get the good list
$list_name = 'forum_display_' . $list;
$listrow = $$list_name;
// init the result
$res = '';
if ($selected_row > count($listrow['lang_key'])) {
$selected_row = 0;
}
// build list
if ($action == 'list') {
foreach ($listrow['lang_key'] as $i => $iValue) {
$selected = ($i == $selected_row) ? ' selected="selected"' : '';
$l_value = $lang[$listrow['lang_key'][$i]] ?? $iValue;
$res .= '';
}
} else {
// field
$res = $listrow['fields'][$selected_row];
}
return $res;
}
function topic_attachment_image($switch_attachment)
{
global $is_auth;
if (!$switch_attachment || !($is_auth['auth_download'] && $is_auth['auth_view'])) {
return '';
}
return '
';
}
function clear_dl_list($topics_csv)
{
DB()->query("DELETE FROM " . BB_BT_DLSTATUS . " WHERE topic_id IN($topics_csv)");
DB()->query("DELETE FROM " . BB_BT_DLSTATUS_SNAP . " WHERE topic_id IN($topics_csv)");
}
// $ids - array(id1,id2,..) or (string) id
function get_id_csv($ids)
{
$ids = array_values((array)$ids);
array_deep($ids, 'intval', 'one-dimensional');
return (string)implode(',', $ids);
}
// $ids - array(id1,id2,..) or (string) id1,id2,..
function get_id_ary($ids)
{
$ids = is_string($ids) ? explode(',', $ids) : array_values((array)$ids);
array_deep($ids, 'intval', 'one-dimensional');
return (array)$ids;
}
function get_topic_title($topic_id)
{
$row = DB()->fetch_row("
SELECT topic_title FROM " . BB_TOPICS . " WHERE topic_id = " . (int)$topic_id . "
");
return $row['topic_title'];
}
function forum_exists($forum_id)
{
return DB()->fetch_row("SELECT forum_id FROM " . BB_FORUMS . " WHERE forum_id = $forum_id LIMIT 1");
}
function cat_exists($cat_id)
{
return DB()->fetch_row("SELECT cat_id FROM " . BB_CATEGORIES . " WHERE cat_id = $cat_id LIMIT 1");
}
function get_topic_icon($topic, $is_unread = null)
{
global $bb_cfg, $images;
$t_hot = ($topic['topic_replies'] >= $bb_cfg['hot_threshold']);
$is_unread = $is_unread ?? is_unread($topic['topic_last_post_time'], $topic['topic_id'], $topic['forum_id']);
if ($topic['topic_status'] == TOPIC_MOVED) {
$folder_image = $images['folder'];
} else {
$folder = ($t_hot) ? $images['folder_hot'] : $images['folder'];
$folder_new = ($t_hot) ? $images['folder_hot_new'] : $images['folder_new'];
if ($topic['topic_type'] == POST_ANNOUNCE) {
$folder = $images['folder_announce'];
$folder_new = $images['folder_announce_new'];
} elseif ($topic['topic_type'] == POST_STICKY) {
$folder = $images['folder_sticky'];
$folder_new = $images['folder_sticky_new'];
} elseif ($topic['topic_status'] == TOPIC_LOCKED) {
$folder = $images['folder_locked'];
$folder_new = $images['folder_locked_new'];
} elseif ($topic['topic_dl_type'] == TOPIC_DL_TYPE_DL) {
$folder = ($t_hot) ? $images['folder_dl_hot'] : $images['folder_dl'];
$folder_new = ($t_hot) ? $images['folder_dl_hot_new'] : $images['folder_dl_new'];
}
$folder_image = ($is_unread) ? $folder_new : $folder;
}
return $folder_image;
}
function build_topic_pagination($url, $replies, $per_page)
{
$pg = '';
if (++$replies > $per_page) {
$total_pages = ceil($replies / $per_page);
for ($j = 0, $page = 1; $j < $replies; $j += $per_page, $page++) {
$href = ($j) ? "$url&start=$j" : $url;
$pg .= '' . $page . '';
if ($page == 1 && $total_pages > 3) {
$pg .= ' .. ';
$page = $total_pages - 2;
$j += ($total_pages - 3) * $per_page;
} elseif ($page < $total_pages) {
$pg .= ', ';
}
}
}
return $pg;
}
//
// Poll
//
function get_poll_data_items_js($topic_id)
{
if (!$topic_id_csv = get_id_csv($topic_id)) {
return is_array($topic_id) ? array() : false;
}
$items = array();
if (!$poll_data = CACHE('bb_poll_data')->get("poll_$topic_id")) {
$poll_data = DB()->fetch_rowset("
SELECT topic_id, vote_id, vote_text, vote_result
FROM " . BB_POLL_VOTES . "
WHERE topic_id IN($topic_id_csv)
ORDER BY topic_id, vote_id
");
CACHE('bb_poll_data')->set("poll_$topic_id", $poll_data);
}
foreach ($poll_data as $row) {
$opt_text_for_js = htmlCHR($row['vote_text']);
$opt_result_for_js = (int)$row['vote_result'];
$items[$row['topic_id']][$row['vote_id']] = array($opt_text_for_js, $opt_result_for_js);
}
foreach ($items as $k => $v) {
$items[$k] = json_encode($v);
}
return is_array($topic_id) ? $items : $items[$topic_id];
}
function poll_is_active($t_data)
{
global $bb_cfg;
return ($t_data['topic_vote'] == 1 && $t_data['topic_time'] > TIMENOW - $bb_cfg['poll_max_days'] * 86400);
}
function print_confirmation($tpl_vars)
{
global $template, $lang;
$template->assign_vars(array(
'TPL_CONFIRM' => true,
'CONFIRM_TITLE' => $lang['CONFIRM'],
'FORM_METHOD' => 'post',
));
$template->assign_vars($tpl_vars);
print_page('common.tpl');
}
/**
* $args = array(
* 'tpl' => 'template file name',
* 'simple' => $gen_simple_header,
* );
* OR (string) 'template_file_name'
*
* $type = '' (common forum page)
* 'admin' (adminCP page)
* 'simple' (simple page without common header)
*
* $mode = 'no_header'
* 'no_footer'
*/
function print_page($args, $type = '', $mode = '')
{
global $template, $gen_simple_header;
$tpl = (is_array($args) && !empty($args['tpl'])) ? $args['tpl'] : $args;
$tpl = ($type === 'admin') ? ADMIN_TPL_DIR . $tpl : $tpl;
$gen_simple_header = (is_array($args) && !empty($args['simple']) or $type === 'simple') ? true : $gen_simple_header;
if ($mode !== 'no_header') {
require(PAGE_HEADER);
}
$template->set_filenames(array('body' => $tpl));
$template->pparse('body');
if ($mode !== 'no_footer') {
require(PAGE_FOOTER);
}
}
function caching_output($enabled, $mode, $cache_var_name, $ttl = 300)
{
if (!$enabled || !CACHE('bb_cache')->used) {
return;
}
if ($mode == 'send') {
if ($cached_contents = CACHE('bb_cache')->get($cache_var_name)) {
bb_exit($cached_contents);
}
} elseif ($mode == 'store') {
if ($output = ob_get_contents()) {
CACHE('bb_cache')->set($cache_var_name, $output, $ttl);
}
}
}
function clean_title($str, $replace_underscore = false)
{
$str = ($replace_underscore) ? str_replace('_', ' ', $str) : $str;
$str = htmlCHR(str_compact($str));
return $str;
}
function clean_text_match($text, $ltrim_star = true, $die_if_empty = false)
{
global $bb_cfg, $lang;
$text = str_compact($text);
$ltrim_chars = ($ltrim_star) ? ' *-!' : ' ';
$wrap_with_quotes = preg_match('#^"[^"]+"$#', $text);
$text = ' ' . str_compact(ltrim($text, $ltrim_chars)) . ' ';
if ($bb_cfg['search_engine_type'] == 'sphinx') {
$text = preg_replace('#(?<=\S)\-#u', ' ', $text); // "1-2-3" -> "1 2 3"
$text = preg_replace('#[^0-9a-zA-Zа-яА-ЯёЁ\-_*|]#u', ' ', $text); // допустимые символы (кроме " которые отдельно)
$text = str_replace(['-', '*'], [' -', '* '], $text); // только в начале / конце слова
$text = preg_replace('#\s*\|\s*#u', '|', $text); // "| " -> "|"
$text = preg_replace('#\|+#u', ' | ', $text); // "||" -> "|"
$text = preg_replace('#(?<=\s)[\-*]+\s#u', ' ', $text); // одиночные " - ", " * "
$text = trim($text, ' -|');
$text = str_compact($text);
$text_match_sql = ($wrap_with_quotes && $text != '') ? '"' . $text . '"' : $text;
} else {
$text_match_sql = DB()->escape(trim($text));
}
if (!$text_match_sql && $die_if_empty) {
bb_die($lang['NO_SEARCH_MATCH']);
}
return $text_match_sql;
}
function init_sphinx()
{
global $sphinx;
if (!isset($sphinx)) {
$sphinx = \Sphinx\SphinxClient::create();
$sphinx->setConnectTimeout(5);
$sphinx->setRankingMode($sphinx::SPH_RANK_NONE);
$sphinx->setMatchMode($sphinx::SPH_MATCH_BOOLEAN);
}
return $sphinx;
}
function log_sphinx_error($err_type, $err_msg, $query = '')
{
$ignore_err_txt = array(
'negation on top level',
'Query word length is less than min prefix length',
);
if (!count($ignore_err_txt) || !preg_match('#' . implode('|', $ignore_err_txt) . '#i', $err_msg)) {
$orig_query = strtr($_REQUEST['nm'], array("\n" => '\n'));
bb_log(date('m-d H:i:s') . " | $err_type | $err_msg | $orig_query | $query" . LOG_LF, 'sphinx_error');
}
}
function get_title_match_topics($title_match_sql, array $forum_ids = [])
{
global $bb_cfg, $sphinx, $userdata, $title_match, $lang;
$where_ids = [];
if ($forum_ids) {
$forum_ids = array_diff($forum_ids, [0 => 0]);
}
$title_match_sql = encode_text_match($title_match_sql);
if ($bb_cfg['search_engine_type'] == 'sphinx') {
$sphinx = init_sphinx();
$where = $title_match ? 'topics' : 'posts';
$sphinx->setServer($bb_cfg['sphinx_topic_titles_host'], $bb_cfg['sphinx_topic_titles_port']);
if ($forum_ids) {
$sphinx->setFilter('forum_id', $forum_ids, false);
}
if (preg_match('#^"[^"]+"$#u', $title_match_sql)) {
$sphinx->setMatchMode($sphinx::SPH_MATCH_PHRASE);
}
if ($result = $sphinx->query($title_match_sql, $where, $userdata['username'] . ' (' . CLIENT_IP . ')')) {
if (!empty($result['matches'])) {
$where_ids = array_keys($result['matches']);
}
} elseif ($error = $sphinx->getLastError()) {
if (strpos($error, 'errno=110')) {
bb_die($lang['SEARCH_ERROR']);
}
log_sphinx_error('ERR', $error, $title_match_sql);
}
if ($warning = $sphinx->getLastWarning()) {
log_sphinx_error('wrn', $warning, $title_match_sql);
}
} elseif ($bb_cfg['search_engine_type'] == 'mysql') {
$where_forum = ($forum_ids) ? "AND forum_id IN(" . implode(',', $forum_ids) . ")" : '';
$search_bool_mode = ($bb_cfg['allow_search_in_bool_mode']) ? ' IN BOOLEAN MODE' : '';
if ($title_match) {
$where_id = 'topic_id';
$sql = "SELECT topic_id FROM " . BB_TOPICS . "
WHERE MATCH (topic_title) AGAINST ('$title_match_sql'$search_bool_mode)
$where_forum";
} else {
$where_id = 'post_id';
$sql = "SELECT p.post_id FROM " . BB_POSTS . " p, " . BB_POSTS_SEARCH . " ps
WHERE ps.post_id = p.post_id
AND MATCH (ps.search_words) AGAINST ('$title_match_sql'$search_bool_mode)
$where_forum";
}
foreach (DB()->fetch_rowset($sql) as $row) {
$where_ids[] = $row[$where_id];
}
} else {
bb_die($lang['SEARCH_OFF']);
}
return $where_ids;
}
// для более корректного поиска по словам содержащим одиночную кавычку
function encode_text_match($txt)
{
return str_replace("'", ''', $txt);
}
function decode_text_match($txt)
{
return str_replace(''', "'", $txt);
}
function pad_with_space($str)
{
return $str ? " $str " : $str;
}
/**
* Create magnet link
*
* @param string $infohash
* @param string|bool $auth_key
*
* @return string
*/
function create_magnet($infohash, $auth_key)
{
global $bb_cfg, $images, $lang, $userdata;
if (IS_GUEST && $bb_cfg['bt_tor_browse_only_reg']) {
$passkey = '';
} elseif (empty($auth_key)) {
if (!$passkey = \TorrentPier\Legacy\Torrent::generate_passkey($userdata['user_id'], true)) {
bb_die($lang['PASSKEY_ERR_EMPTY']);
}
} else {
$passkey = $auth_key;
}
$passkey_url = $passkey ? "?{$bb_cfg['passkey_key']}=$auth_key" : '';
return '
';
}
function set_die_append_msg($forum_id = null, $topic_id = null, $group_id = null)
{
global $lang, $template;
$msg = '';
$msg .= $topic_id ? '' . $lang['TOPIC_RETURN'] . '
' : '';
$msg .= $forum_id ? '' . $lang['FORUM_RETURN'] . '
' : '';
$msg .= $group_id ? '' . $lang['GROUP_RETURN'] . '
' : '';
$msg .= '' . $lang['INDEX_RETURN'] . '
';
$template->assign_var('BB_DIE_APPEND_MSG', $msg);
}
function set_pr_die_append_msg($pr_uid)
{
global $lang, $template;
$template->assign_var('BB_DIE_APPEND_MSG', '
' . $lang['PROFILE_RETURN'] . '
' . $lang['PROFILE_EDIT_RETURN'] . '
' . $lang['INDEX_RETURN'] . '
');
}
function send_pm($user_id, $subject, $message, $poster_id = BOT_UID)
{
global $userdata;
$subject = DB()->escape($subject);
$message = DB()->escape($message);
if ($poster_id == BOT_UID) {
$poster_ip = '7f000001';
} elseif ($row = DB()->fetch_row("SELECT user_reg_ip FROM " . BB_USERS . " WHERE user_id = $poster_id")) {
$poster_ip = $row['user_reg_ip'];
} else {
$poster_id = $userdata['user_id'];
$poster_ip = USER_IP;
}
DB()->query("INSERT INTO " . BB_PRIVMSGS . " (privmsgs_type, privmsgs_subject, privmsgs_from_userid, privmsgs_to_userid, privmsgs_date, privmsgs_ip) VALUES (" . PRIVMSGS_NEW_MAIL . ", '$subject', {$poster_id}, $user_id, " . TIMENOW . ", '$poster_ip')");
$pm_id = DB()->sql_nextid();
DB()->query("INSERT INTO " . BB_PRIVMSGS_TEXT . " (privmsgs_text_id, privmsgs_text) VALUES ($pm_id, '$message')");
DB()->query("UPDATE " . BB_USERS . " SET user_new_privmsg = user_new_privmsg + 1, user_last_privmsg = " . TIMENOW . ", user_newest_pm_id = $pm_id WHERE user_id = $user_id");
}
function profile_url($data)
{
global $bb_cfg, $lang, $datastore;
if (!$ranks = $datastore->get('ranks')) {
$datastore->update('ranks');
$ranks = $datastore->get('ranks');
}
$user_rank = !empty($data['user_rank']) ? $data['user_rank'] : 0;
if (isset($ranks[$user_rank])) {
$title = $ranks[$user_rank]['rank_title'];
$style = $ranks[$user_rank]['rank_style'];
}
if (empty($title)) {
$title = $lang['USER'];
}
if (empty($style)) {
$style = 'colorUser';
}
if (!$bb_cfg['color_nick']) {
$style = '';
}
$username = !empty($data['username']) ? $data['username'] : $lang['GUEST'];
$user_id = (!empty($data['user_id']) && $username != $lang['GUEST']) ? $data['user_id'] : GUEST_UID;
$profile = '' . $username . '';
if (!in_array($user_id, array('', GUEST_UID, BOT_UID)) && $username) {
$profile = '' . $profile . '';
}
return $profile;
}
function get_avatar($user_id, $ext_id, $allow_avatar = true, $size = true, $height = '', $width = '')
{
global $bb_cfg;
$height = !$height ? 'height="' . $height . '"' : '';
$width = !$width ? 'width="' . $width . '"' : '';
$user_avatar = '
';
if ($user_id == BOT_UID && $bb_cfg['avatars']['bot_avatar']) {
$user_avatar = '
';
} elseif ($allow_avatar && $ext_id) {
if (file_exists(get_avatar_path($user_id, $ext_id))) {
$user_avatar = '
';
}
}
return $user_avatar;
}
function gender_image($gender)
{
global $bb_cfg, $lang, $images;
if (!$bb_cfg['gender']) {
$user_gender = '';
return $user_gender;
}
switch ($gender) {
case MALE:
$user_gender = '
';
break;
case FEMALE:
$user_gender = '
';
break;
default:
$user_gender = '
';
break;
}
return $user_gender;
}
function is_gold($type)
{
global $lang, $bb_cfg;
if (!$bb_cfg['tracker']['gold_silver_enabled']) {
$is_gold = '';
return $is_gold;
}
switch ($type) {
case TOR_TYPE_GOLD:
$is_gold = '
';
break;
case TOR_TYPE_SILVER:
$is_gold = '
';
break;
default:
$is_gold = '';
break;
}
return $is_gold;
}
function update_atom($type, $id)
{
switch ($type) {
case 'user':
\TorrentPier\Legacy\Atom::update_user_feed($id, get_username($id));
break;
case 'topic':
$topic_poster = (int)DB()->fetch_row("SELECT topic_poster FROM " . BB_TOPICS . " WHERE topic_id = $id LIMIT 1", 'topic_poster');
\TorrentPier\Legacy\Atom::update_user_feed($topic_poster, get_username($topic_poster));
break;
}
}
function hash_search($hash)
{
global $lang;
$hash = htmlCHR(trim($hash));
if (!isset($hash) || mb_strlen($hash, 'UTF-8') != 40) {
bb_die(sprintf($lang['HASH_INVALID'], $hash));
}
$info_hash = DB()->escape(pack("H*", $hash));
if ($row = DB()->fetch_row("SELECT topic_id FROM " . BB_BT_TORRENTS . " WHERE info_hash = '$info_hash'")) {
redirect(TOPIC_URL . $row['topic_id']);
} else {
bb_die(sprintf($lang['HASH_NOT_FOUND'], $hash));
}
}
/**
* Функция для получения и проверки правильности ответа от Google ReCaptcha.
*
* @param $mode
* @param string $callback
*
* @return bool|string
*/
function bb_captcha($mode, $callback = '')
{
global $bb_cfg, $lang;
$secret = $bb_cfg['captcha']['secret_key'];
$public = $bb_cfg['captcha']['public_key'];
$cp_theme = $bb_cfg['captcha']['theme'];
if (!$public && !$secret) {
bb_die($lang['CAPTCHA_SETTINGS']);
}
$reCaptcha = new \ReCaptcha\ReCaptcha($secret);
switch ($mode) {
case 'get':
return "
";
break;
case 'check':
$resp = $reCaptcha->verify(
request_var('g-recaptcha-response', ''),
$_SERVER["REMOTE_ADDR"]
);
if ($resp->isSuccess()) {
return true;
}
break;
default:
bb_simple_die(__FUNCTION__ . ": invalid mode '$mode'");
}
return false;
}
function clean_tor_dirname($dirname)
{
return str_replace(array('[', ']', '<', '>', "'"), array('[', ']', '<', '>', '''), $dirname);
}
/**
* Get birthday icon
*
* @param $user_birthday
* @param $user_id
* @return string
*/
function user_birthday_icon($user_birthday, $user_id): string
{
global $bb_cfg, $images, $lang;
$current_date = bb_date(TIMENOW, 'md', false);
$user_birthday = ($user_id != GUEST_UID && !empty($user_birthday) && $user_birthday != '1900-01-01')
? date('md', strtotime($user_birthday)) : false;
return ($bb_cfg['birthday_enabled'] && $current_date == $user_birthday) ? '
' : '';
}