2023-03-11 12:04:29 +03:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
if (!defined('BB_ROOT')) die(basename(__FILE__));
|
|
|
|
|
|
|
|
|
|
function get_path_from_id ($id, $ext_id, $base_path, $first_div, $sec_div)
|
|
|
|
|
{
|
|
|
|
|
global $bb_cfg;
|
|
|
|
|
$ext = isset($bb_cfg['file_id_ext'][$ext_id]) ? $bb_cfg['file_id_ext'][$ext_id] : '';
|
|
|
|
|
return ($base_path ? "$base_path/" : '') . floor($id/$first_div) .'/'. ($id % $sec_div) .'/'. $id . ($ext ? ".$ext" : '');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function get_avatar_path ($id, $ext_id, $base_path = null, $first_div = 10000, $sec_div = 100)
|
|
|
|
|
{
|
|
|
|
|
global $bb_cfg;
|
|
|
|
|
$base_path = isset($base_path) ? $base_path : $bb_cfg['avatars']['upload_path'];
|
|
|
|
|
return get_path_from_id($id, $ext_id, $base_path, $first_div, $sec_div);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function get_attach_path ($id, $ext_id = '', $base_path = null, $first_div = 10000, $sec_div = 100)
|
|
|
|
|
{
|
|
|
|
|
global $bb_cfg;
|
|
|
|
|
$base_path = isset($base_path) ? $base_path : $bb_cfg['attach']['upload_path'];
|
|
|
|
|
return get_path_from_id($id, $ext_id, $base_path, $first_div, $sec_div);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function delete_avatar ($user_id, $avatar_ext_id)
|
|
|
|
|
{
|
|
|
|
|
$avatar_file = ($avatar_ext_id) ? get_avatar_path($user_id, $avatar_ext_id) : '';
|
|
|
|
|
return ($avatar_file && file_exists($avatar_file)) ? @unlink($avatar_file) : false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function get_tracks ($type)
|
|
|
|
|
{
|
|
|
|
|
static $pattern = '#^a:\d+:{[i:;\d]+}$#';
|
|
|
|
|
|
|
|
|
|
switch ($type)
|
|
|
|
|
{
|
|
|
|
|
case 'topic':
|
|
|
|
|
$c_name = COOKIE_TOPIC;
|
|
|
|
|
break;
|
|
|
|
|
case 'forum':
|
|
|
|
|
$c_name = COOKIE_FORUM;
|
|
|
|
|
break;
|
|
|
|
|
case 'pm':
|
|
|
|
|
$c_name = COOKIE_PM;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
trigger_error(__FUNCTION__ .": invalid type '$type'", E_USER_ERROR);
|
|
|
|
|
}
|
|
|
|
|
$tracks = !empty($_COOKIE[$c_name]) ? @unserialize($_COOKIE[$c_name]) : false;
|
|
|
|
|
return ($tracks) ? $tracks : array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function set_tracks ($cookie_name, &$tracking_ary, $tracks = null, $val = TIMENOW)
|
|
|
|
|
{
|
|
|
|
|
global $tracking_topics, $tracking_forums, $user;
|
|
|
|
|
|
|
|
|
|
if (IS_GUEST) return;
|
|
|
|
|
|
|
|
|
|
$prev_tracking_ary = $tracking_ary;
|
|
|
|
|
|
|
|
|
|
if ($tracks)
|
|
|
|
|
{
|
|
|
|
|
if (!is_array($tracks))
|
|
|
|
|
{
|
|
|
|
|
$tracks = array($tracks => $val);
|
|
|
|
|
}
|
|
|
|
|
foreach ($tracks as $key => $val)
|
|
|
|
|
{
|
|
|
|
|
$key = (int) $key;
|
|
|
|
|
$val++;
|
|
|
|
|
$curr_track_val = !empty($tracking_ary[$key]) ? $tracking_ary[$key] : 0;
|
|
|
|
|
|
|
|
|
|
if ($val > max($curr_track_val, $user->data['user_lastvisit']))
|
|
|
|
|
{
|
|
|
|
|
$tracking_ary[$key] = $val;
|
|
|
|
|
}
|
|
|
|
|
elseif ($curr_track_val < $user->data['user_lastvisit'])
|
|
|
|
|
{
|
|
|
|
|
unset($tracking_ary[$key]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$overflow = count($tracking_topics) + count($tracking_forums) - COOKIE_MAX_TRACKS;
|
|
|
|
|
|
|
|
|
|
if ($overflow > 0)
|
|
|
|
|
{
|
|
|
|
|
arsort($tracking_ary);
|
|
|
|
|
for ($i=0; $i < $overflow; $i++)
|
|
|
|
|
{
|
|
|
|
|
array_pop($tracking_ary);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (array_diff($tracking_ary, $prev_tracking_ary))
|
|
|
|
|
{
|
|
|
|
|
bb_setcookie($cookie_name, serialize($tracking_ary));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function get_last_read ($topic_id = 0, $forum_id = 0)
|
|
|
|
|
{
|
|
|
|
|
global $tracking_topics, $tracking_forums, $user;
|
|
|
|
|
|
|
|
|
|
$t = isset($tracking_topics[$topic_id]) ? $tracking_topics[$topic_id] : 0;
|
|
|
|
|
$f = isset($tracking_forums[$forum_id]) ? $tracking_forums[$forum_id] : 0;
|
|
|
|
|
return max($t, $f, $user->data['user_lastvisit']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function is_unread ($ref, $topic_id = 0, $forum_id = 0)
|
|
|
|
|
{
|
|
|
|
|
return (!IS_GUEST && $ref > get_last_read($topic_id, $forum_id));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Ads
|
|
|
|
|
//
|
|
|
|
|
class ads_common
|
|
|
|
|
{
|
|
|
|
|
var $ad_blocks = array();
|
|
|
|
|
var $active_ads = array();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Constructor
|
|
|
|
|
*/
|
|
|
|
|
function ads_common ()
|
|
|
|
|
{
|
|
|
|
|
global $bb_cfg;
|
|
|
|
|
|
|
|
|
|
$this->ad_blocks =& $bb_cfg['ad_blocks'];
|
|
|
|
|
$this->active_ads = !empty($bb_cfg['active_ads']) ? @unserialize($bb_cfg['active_ads']) : array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get ads to show for each block
|
|
|
|
|
*/
|
|
|
|
|
function get ($block_types)
|
|
|
|
|
{
|
|
|
|
|
$ads = array();
|
|
|
|
|
|
|
|
|
|
if ($this->active_ads)
|
|
|
|
|
{
|
|
|
|
|
$block_ids = $this->get_block_ids($block_types);
|
|
|
|
|
|
|
|
|
|
if ($ad_ids = $this->get_ad_ids($block_ids))
|
|
|
|
|
{
|
|
|
|
|
$ad_html = $this->get_ads_html();
|
|
|
|
|
|
|
|
|
|
foreach ($ad_ids as $block_id => $ad_id)
|
|
|
|
|
{
|
|
|
|
|
$ads[$block_id] =& $ad_html[$ad_id];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $ads;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get ads html
|
|
|
|
|
*/
|
|
|
|
|
function get_ads_html ()
|
|
|
|
|
{
|
|
|
|
|
global $datastore;
|
|
|
|
|
if (!$ads_html = $datastore->get('ads'))
|
|
|
|
|
{
|
|
|
|
|
$datastore->update('ads');
|
|
|
|
|
$ads_html = $datastore->get('ads');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $ads_html;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get block_ids for specified block_types
|
|
|
|
|
*/
|
|
|
|
|
function get_block_ids ($block_types)
|
|
|
|
|
{
|
|
|
|
|
$block_ids = array();
|
|
|
|
|
|
|
|
|
|
foreach ($block_types as $block_type)
|
|
|
|
|
{
|
|
|
|
|
if ($blocks =& $this->ad_blocks[$block_type])
|
|
|
|
|
{
|
|
|
|
|
$block_ids = array_merge($block_ids, array_keys($blocks));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $block_ids;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get ad_ids for specified blocks
|
|
|
|
|
*/
|
|
|
|
|
function get_ad_ids ($block_ids)
|
|
|
|
|
{
|
|
|
|
|
$ad_ids = array();
|
|
|
|
|
|
|
|
|
|
foreach ($block_ids as $block_id)
|
|
|
|
|
{
|
|
|
|
|
if ($ads =& $this->active_ads[$block_id])
|
|
|
|
|
{
|
|
|
|
|
shuffle($ads);
|
|
|
|
|
$ad_ids[$block_id] = $ads[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $ad_ids;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Auth
|
|
|
|
|
//
|
|
|
|
|
define('AUTH_LIST_ALL', 0);
|
|
|
|
|
|
|
|
|
|
// forum's ACL types (bb_forums: auth_view, auth_read... values)
|
|
|
|
|
define('AUTH_REG', 1);
|
|
|
|
|
define('AUTH_ACL', 2);
|
|
|
|
|
define('AUTH_ADMIN', 5);
|
|
|
|
|
|
|
|
|
|
// forum_perm bitfields - backward compatible with auth($type)
|
|
|
|
|
define('AUTH_ALL', 0);
|
|
|
|
|
define('AUTH_VIEW', 1);
|
|
|
|
|
define('AUTH_READ', 2);
|
|
|
|
|
define('AUTH_MOD', 3);
|
|
|
|
|
define('AUTH_POST', 4);
|
|
|
|
|
define('AUTH_REPLY', 5);
|
|
|
|
|
define('AUTH_EDIT', 6);
|
|
|
|
|
define('AUTH_DELETE', 7);
|
|
|
|
|
define('AUTH_STICKY', 8);
|
|
|
|
|
define('AUTH_ANNOUNCE', 9);
|
|
|
|
|
define('AUTH_VOTE', 10);
|
|
|
|
|
define('AUTH_POLLCREATE', 11);
|
|
|
|
|
define('AUTH_ATTACH', 12);
|
|
|
|
|
define('AUTH_DOWNLOAD', 13);
|
|
|
|
|
|
|
|
|
|
define('BF_AUTH_MOD', bit2dec(AUTH_MOD));
|
|
|
|
|
|
|
|
|
|
// When defining user permissions, take into account:
|
|
|
|
|
define('UG_PERM_BOTH', 1); // both user and group
|
|
|
|
|
define('UG_PERM_USER_ONLY', 2); // only personal user permissions
|
|
|
|
|
define('UG_PERM_GROUP_ONLY', 3); // only group permissions
|
|
|
|
|
|
|
|
|
|
$bf['forum_perm'] = array(
|
|
|
|
|
'auth_view' => AUTH_VIEW,
|
|
|
|
|
'auth_read' => AUTH_READ,
|
|
|
|
|
'auth_mod' => AUTH_MOD,
|
|
|
|
|
'auth_post' => AUTH_POST,
|
|
|
|
|
'auth_reply' => AUTH_REPLY,
|
|
|
|
|
'auth_edit' => AUTH_EDIT,
|
|
|
|
|
'auth_delete' => AUTH_DELETE,
|
|
|
|
|
'auth_sticky' => AUTH_STICKY,
|
|
|
|
|
'auth_announce' => AUTH_ANNOUNCE,
|
|
|
|
|
'auth_vote' => AUTH_VOTE,
|
|
|
|
|
'auth_pollcreate' => AUTH_POLLCREATE,
|
|
|
|
|
'auth_attachments' => AUTH_ATTACH,
|
|
|
|
|
'auth_download' => AUTH_DOWNLOAD,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$bf['user_opt'] = array(
|
|
|
|
|
# 'dis_opt_name' => ЗАПРЕТЫ используемые администраторами для пользователей
|
|
|
|
|
# 'user_opt_name' => НАСТРОЙКИ используемые пользователями
|
|
|
|
|
'user_viewemail' => 0, // Показывать e-mail
|
|
|
|
|
'dis_sig' => 1, // Запрет на подпись
|
|
|
|
|
'dis_avatar' => 2, // Запрет на аватар
|
|
|
|
|
'dis_pm' => 3, // Запрет на отправку ЛС
|
|
|
|
|
'user_viewonline' => 4, // Скрывать пребывание пользователя
|
|
|
|
|
'user_notify' => 5, // Сообщать об ответах в отслеживаемых темах
|
|
|
|
|
'user_notify_pm' => 6, // Сообщать о новых ЛС
|
|
|
|
|
'dis_passkey' => 7, // Запрет на добавление passkey, он же запрет на скачивание торрентов
|
|
|
|
|
'user_porn_forums' => 8, // Скрывать контент 18+
|
|
|
|
|
'user_callseed' => 9, // Позвать скачавших
|
|
|
|
|
'user_hide_ads' => 10, // Запрет на показ рекламы
|
|
|
|
|
'dis_topic' => 11, // Запрет на создание новых тем
|
|
|
|
|
'dis_post' => 12, // Запрет на отправку сообщений
|
|
|
|
|
'dis_post_edit' => 13, // Запрет на редактирование сообщений
|
|
|
|
|
'user_dls' => 14, // Скрывать список текущих закачек в профиле
|
|
|
|
|
'user_retracker' => 15, // Добавлять ретрекер к скачиваемым торрентам
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
function bit2dec ($bit_num)
|
|
|
|
|
{
|
|
|
|
|
if (is_array($bit_num))
|
|
|
|
|
{
|
|
|
|
|
$dec = 0;
|
|
|
|
|
foreach ($bit_num as $bit)
|
|
|
|
|
{
|
|
|
|
|
$dec |= (1 << $bit);
|
|
|
|
|
}
|
|
|
|
|
return $dec;
|
|
|
|
|
}
|
|
|
|
|
return (1 << $bit_num);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function bf_bit2dec ($bf_array_name, $key)
|
|
|
|
|
{
|
|
|
|
|
global $bf;
|
|
|
|
|
if (!isset($bf[$bf_array_name][$key]))
|
|
|
|
|
{
|
|
|
|
|
trigger_error(__FUNCTION__ .": bitfield '$key' not found", E_USER_ERROR);
|
|
|
|
|
}
|
|
|
|
|
return (1 << $bf[$bf_array_name][$key]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function bf ($int, $bf_array_name, $key)
|
|
|
|
|
{
|
|
|
|
|
return (bf_bit2dec($bf_array_name, $key) & (int) $int);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function setbit (&$int, $bit_num, $on)
|
|
|
|
|
{
|
|
|
|
|
return ($on) ? $int |= (1 << $bit_num) : $int &= ~(1 << $bit_num);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
$type's accepted (pre-pend with AUTH_):
|
|
|
|
|
VIEW, READ, POST, REPLY, EDIT, DELETE, STICKY, ANNOUNCE, VOTE, POLLCREATE
|
|
|
|
|
|
|
|
|
|
Possible options ($type/forum_id combinations):
|
|
|
|
|
|
|
|
|
|
* If you include a type and forum_id then a specific lookup will be done and
|
|
|
|
|
the single result returned
|
|
|
|
|
|
|
|
|
|
* If you set type to AUTH_ALL and specify a forum_id an array of all auth types
|
|
|
|
|
will be returned
|
|
|
|
|
|
|
|
|
|
* If you provide a forum_id a specific lookup on that forum will be done
|
|
|
|
|
|
|
|
|
|
* If you set forum_id to AUTH_LIST_ALL and specify a type an array listing the
|
|
|
|
|
results for all forums will be returned
|
|
|
|
|
|
|
|
|
|
* If you set forum_id to AUTH_LIST_ALL and type to AUTH_ALL a multidimensional
|
|
|
|
|
array containing the auth permissions for all types and all forums for that
|
|
|
|
|
user is returned
|
|
|
|
|
|
|
|
|
|
All results are returned as associative arrays, even when a single auth type is
|
|
|
|
|
specified.
|
|
|
|
|
|
|
|
|
|
If available you can send an array (either one or two dimensional) containing the
|
|
|
|
|
forum auth levels, this will prevent the auth function having to do its own
|
|
|
|
|
lookup
|
|
|
|
|
*/
|
|
|
|
|
function auth ($type, $forum_id, $ug_data, $f_access = array(), $group_perm = UG_PERM_BOTH)
|
|
|
|
|
{
|
|
|
|
|
global $lang, $bf, $datastore;
|
|
|
|
|
|
|
|
|
|
$is_guest = true;
|
|
|
|
|
$is_admin = false;
|
|
|
|
|
$auth = $auth_fields = $u_access = array();
|
|
|
|
|
$add_auth_type_desc = ($forum_id != AUTH_LIST_ALL);
|
|
|
|
|
|
2024-01-17 12:24:38 +03:00
|
|
|
|
// Если форум не существует, то возвращаем пустой массив
|
|
|
|
|
if ($add_auth_type_desc && !forum_exists($forum_id)) return array();
|
|
|
|
|
|
2023-03-11 12:04:29 +03:00
|
|
|
|
//
|
|
|
|
|
// Get $auth_fields
|
|
|
|
|
//
|
|
|
|
|
if ($type == AUTH_ALL)
|
|
|
|
|
{
|
|
|
|
|
$auth_fields = array_keys($bf['forum_perm']);
|
|
|
|
|
}
|
|
|
|
|
else if ($auth_type = array_search($type, $bf['forum_perm']))
|
|
|
|
|
{
|
|
|
|
|
$auth_fields = array($auth_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (empty($auth_fields))
|
|
|
|
|
{
|
|
|
|
|
trigger_error(__FUNCTION__ .'(): empty $auth_fields', E_USER_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Get $f_access
|
|
|
|
|
//
|
|
|
|
|
// If f_access has been passed, or auth is needed to return an array of forums
|
|
|
|
|
// then we need to pull the auth information on the given forum (or all forums)
|
|
|
|
|
if (empty($f_access))
|
|
|
|
|
{
|
|
|
|
|
if (!$forums = $datastore->get('cat_forums'))
|
|
|
|
|
{
|
|
|
|
|
$datastore->update('cat_forums');
|
|
|
|
|
$forums = $datastore->get('cat_forums');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($forum_id == AUTH_LIST_ALL)
|
|
|
|
|
{
|
|
|
|
|
$f_access = $forums['f'];
|
|
|
|
|
}
|
|
|
|
|
else if (isset($forums['f'][$forum_id]))
|
|
|
|
|
{
|
|
|
|
|
$f_access[$forum_id] = $forums['f'][$forum_id];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (isset($f_access['forum_id']))
|
|
|
|
|
{
|
|
|
|
|
// Change passed $f_access format for later using in foreach()
|
|
|
|
|
$f_access = array($f_access['forum_id'] => $f_access);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (empty($f_access))
|
|
|
|
|
{
|
|
|
|
|
trigger_error(__FUNCTION__ .'(): empty $f_access', E_USER_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Get user or group permissions
|
|
|
|
|
//
|
|
|
|
|
$forum_match_sql = ($forum_id != AUTH_LIST_ALL) ? "AND aa.forum_id = ". (int) $forum_id : '';
|
|
|
|
|
|
|
|
|
|
// GROUP mode
|
|
|
|
|
if (!empty($ug_data['group_id']))
|
|
|
|
|
{
|
|
|
|
|
$is_guest = false;
|
|
|
|
|
$is_admin = false;
|
|
|
|
|
|
|
|
|
|
$sql = "SELECT aa.forum_id, aa.forum_perm
|
|
|
|
|
FROM ". BB_AUTH_ACCESS ." aa
|
|
|
|
|
WHERE aa.group_id = ". (int) $ug_data['group_id'] ."
|
|
|
|
|
$forum_match_sql";
|
|
|
|
|
|
|
|
|
|
foreach (DB()->fetch_rowset($sql) as $row)
|
|
|
|
|
{
|
|
|
|
|
$u_access[$row['forum_id']] = $row['forum_perm'];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// USER mode
|
|
|
|
|
else if (!empty($ug_data['user_id']))
|
|
|
|
|
{
|
|
|
|
|
$is_guest = empty($ug_data['session_logged_in']);
|
|
|
|
|
$is_admin = (!$is_guest && $ug_data['user_level'] == ADMIN);
|
|
|
|
|
|
|
|
|
|
if ($group_perm != UG_PERM_BOTH)
|
|
|
|
|
{
|
|
|
|
|
$group_single_user = ($group_perm == UG_PERM_USER_ONLY) ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
$sql = "
|
|
|
|
|
SELECT
|
|
|
|
|
aa.forum_id, BIT_OR(aa.forum_perm) AS forum_perm
|
|
|
|
|
FROM
|
|
|
|
|
". BB_USER_GROUP ." ug,
|
|
|
|
|
". BB_GROUPS ." g,
|
|
|
|
|
". BB_AUTH_ACCESS ." aa
|
|
|
|
|
WHERE
|
|
|
|
|
ug.user_id = ". (int) $ug_data['user_id'] ."
|
|
|
|
|
AND ug.user_pending = 0
|
|
|
|
|
AND g.group_id = ug.group_id
|
|
|
|
|
AND g.group_single_user = $group_single_user
|
|
|
|
|
AND aa.group_id = g.group_id
|
|
|
|
|
$forum_match_sql
|
|
|
|
|
GROUP BY aa.forum_id
|
|
|
|
|
";
|
|
|
|
|
|
|
|
|
|
foreach (DB()->fetch_rowset($sql) as $row)
|
|
|
|
|
{
|
|
|
|
|
$u_access[$row['forum_id']] = $row['forum_perm'];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!$is_guest && !$is_admin)
|
|
|
|
|
{
|
|
|
|
|
$sql = "SELECT SQL_CACHE aa.forum_id, aa.forum_perm
|
|
|
|
|
FROM ". BB_AUTH_ACCESS_SNAP ." aa
|
|
|
|
|
WHERE aa.user_id = ". (int) $ug_data['user_id'] ."
|
|
|
|
|
$forum_match_sql";
|
|
|
|
|
|
|
|
|
|
foreach (DB()->fetch_rowset($sql) as $row)
|
|
|
|
|
{
|
|
|
|
|
$u_access[$row['forum_id']] = $row['forum_perm'];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the user is logged on and the forum type is either ALL or REG then the user has access
|
|
|
|
|
//
|
|
|
|
|
// If the type if ACL, MOD or ADMIN then we need to see if the user has specific permissions
|
|
|
|
|
// to do whatever it is they want to do ... to do this we pull relevant information for the
|
|
|
|
|
// user (and any groups they belong to)
|
|
|
|
|
//
|
|
|
|
|
// Now we compare the users access level against the forums. We assume here that a moderator
|
|
|
|
|
// and admin automatically have access to an ACL forum, similarly we assume admins meet an
|
|
|
|
|
// auth requirement of MOD
|
|
|
|
|
//
|
|
|
|
|
foreach ($f_access as $f_id => $f_data)
|
|
|
|
|
{
|
|
|
|
|
$auth[$f_id]['auth_mod'] = auth_check('forum_perm', 'auth_mod', $u_access, $f_id, $is_admin);
|
|
|
|
|
|
|
|
|
|
foreach ($auth_fields as $auth_type)
|
|
|
|
|
{
|
|
|
|
|
if (!isset($f_data[$auth_type]))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
switch ($f_data[$auth_type])
|
|
|
|
|
{
|
|
|
|
|
case AUTH_ALL:
|
|
|
|
|
$auth[$f_id][$auth_type] = true;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case AUTH_REG:
|
|
|
|
|
$auth[$f_id][$auth_type] = !$is_guest;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case AUTH_ACL:
|
|
|
|
|
$auth[$f_id][$auth_type] = (auth_check('forum_perm', $auth_type, $u_access, $f_id, $is_admin) || $auth[$f_id]['auth_mod']);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case AUTH_MOD:
|
|
|
|
|
$auth[$f_id][$auth_type] = $auth[$f_id]['auth_mod'];
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case AUTH_ADMIN:
|
|
|
|
|
$auth[$f_id][$auth_type] = $is_admin;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
$auth[$f_id][$auth_type] = false;
|
|
|
|
|
}
|
|
|
|
|
if ($add_auth_type_desc)
|
|
|
|
|
{
|
|
|
|
|
$auth[$f_id][$auth_type .'_type'] =& $lang['AUTH_TYPES'][$f_data[$auth_type]];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ($forum_id == AUTH_LIST_ALL) ? $auth : $auth[$forum_id];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function auth_check ($bf_ary, $bf_key, $perm_ary, $perm_key, $is_admin = false)
|
|
|
|
|
{
|
|
|
|
|
if ($is_admin) return true;
|
|
|
|
|
if (!isset($perm_ary[$perm_key])) return false;
|
|
|
|
|
|
|
|
|
|
return bf($perm_ary[$perm_key], $bf_ary, $bf_key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Date_Delta
|
|
|
|
|
{
|
|
|
|
|
var $auto_granularity = array(
|
|
|
|
|
60 => 'seconds', // set granularity to "seconds" if delta less then 1 minute
|
|
|
|
|
10800 => 'minutes', // 3 hours
|
|
|
|
|
259200 => 'hours', // 3 days
|
|
|
|
|
31363200 => 'mday', // 12 months
|
|
|
|
|
311040000 => 'mon', // 10 years
|
|
|
|
|
);
|
|
|
|
|
var $intervals = array();
|
|
|
|
|
var $format = '';
|
|
|
|
|
|
|
|
|
|
// Creates new object.
|
|
|
|
|
function Date_Delta()
|
|
|
|
|
{
|
|
|
|
|
global $lang;
|
|
|
|
|
|
|
|
|
|
$this->intervals = $lang['DELTA_TIME']['INTERVALS'];
|
|
|
|
|
$this->format = $lang['DELTA_TIME']['FORMAT'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Makes the spellable phrase.
|
|
|
|
|
function spellDelta($first, $last, $from = 'auto')
|
|
|
|
|
{
|
|
|
|
|
if ($last < $first)
|
|
|
|
|
{
|
|
|
|
|
$old_first = $first;
|
|
|
|
|
$first = $last;
|
|
|
|
|
$last = $old_first;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($from == 'auto')
|
|
|
|
|
{
|
|
|
|
|
$from = 'year';
|
|
|
|
|
$diff = $last - $first;
|
|
|
|
|
foreach ($this->auto_granularity as $seconds_count => $granule)
|
|
|
|
|
{
|
|
|
|
|
if ($diff < $seconds_count)
|
|
|
|
|
{
|
|
|
|
|
$from = $granule;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Solve data delta.
|
|
|
|
|
$delta = $this->getDelta($first, $last);
|
|
|
|
|
if (!$delta) return false;
|
|
|
|
|
|
|
|
|
|
// Make spellable phrase.
|
|
|
|
|
$parts = array();
|
|
|
|
|
$intervals = $GLOBALS['lang']['DELTA_TIME']['INTERVALS'];
|
|
|
|
|
|
|
|
|
|
foreach (array_reverse($delta) as $k => $n)
|
|
|
|
|
{
|
|
|
|
|
if (!$n)
|
|
|
|
|
{
|
|
|
|
|
if ($k == $from)
|
|
|
|
|
{
|
|
|
|
|
if (!$parts)
|
|
|
|
|
{
|
|
|
|
|
$parts[] = declension($n, $this->intervals[$k], $this->format);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$parts[] = declension($n, $this->intervals[$k], $this->format);
|
|
|
|
|
if ($k == $from) break;
|
|
|
|
|
}
|
|
|
|
|
return join(' ', $parts);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// returns the associative array with date deltas.
|
|
|
|
|
function getDelta($first, $last)
|
|
|
|
|
{
|
|
|
|
|
if ($last < $first) return false;
|
|
|
|
|
|
|
|
|
|
// Solve H:M:S part.
|
|
|
|
|
$hms = ($last - $first) % (3600 * 24);
|
|
|
|
|
$delta['seconds'] = $hms % 60;
|
|
|
|
|
$delta['minutes'] = floor($hms/60) % 60;
|
|
|
|
|
$delta['hours'] = floor($hms/3600) % 60;
|
|
|
|
|
|
|
|
|
|
// Now work only with date, delta time = 0.
|
|
|
|
|
$last -= $hms;
|
|
|
|
|
$f = getdate($first);
|
|
|
|
|
$l = getdate($last); // the same daytime as $first!
|
|
|
|
|
|
|
|
|
|
$dYear = $dMon = $dDay = 0;
|
|
|
|
|
|
|
|
|
|
// Delta day. Is negative, month overlapping.
|
|
|
|
|
$dDay += $l['mday'] - $f['mday'];
|
|
|
|
|
if ($dDay < 0) {
|
|
|
|
|
$monlen = $this->monthLength(date('Y', $first), date('m', $first));
|
|
|
|
|
$dDay += $monlen;
|
|
|
|
|
$dMon--;
|
|
|
|
|
}
|
|
|
|
|
$delta['mday'] = $dDay;
|
|
|
|
|
|
|
|
|
|
// Delta month. If negative, year overlapping.
|
|
|
|
|
$dMon += $l['mon'] - $f['mon'];
|
|
|
|
|
if ($dMon < 0) {
|
|
|
|
|
$dMon += 12;
|
|
|
|
|
$dYear --;
|
|
|
|
|
}
|
|
|
|
|
$delta['mon'] = $dMon;
|
|
|
|
|
|
|
|
|
|
// Delta year.
|
|
|
|
|
$dYear += $l['year'] - $f['year'];
|
|
|
|
|
$delta['year'] = $dYear;
|
|
|
|
|
|
|
|
|
|
return $delta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Returns the length (in days) of the specified month.
|
|
|
|
|
function monthLength($year, $mon)
|
|
|
|
|
{
|
|
|
|
|
$l = 28;
|
|
|
|
|
while (checkdate($mon, $l+1, $year)) $l++;
|
|
|
|
|
return $l;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function delta_time ($timestamp_1, $timestamp_2 = TIMENOW, $granularity = 'auto')
|
|
|
|
|
{
|
|
|
|
|
return $GLOBALS['DeltaTime']->spellDelta($timestamp_1, $timestamp_2, $granularity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function get_select ($select, $selected = null, $return_as = 'html', $first_opt = '»» Выбрать ')
|
|
|
|
|
{
|
|
|
|
|
$select_ary = array();
|
|
|
|
|
|
|
|
|
|
switch ($select)
|
|
|
|
|
{
|
|
|
|
|
case 'groups':
|
|
|
|
|
$sql = "SELECT group_id, group_name FROM ". BB_GROUPS ." WHERE group_single_user = 0 ORDER BY group_name";
|
|
|
|
|
foreach (DB()->fetch_rowset($sql) as $row)
|
|
|
|
|
{
|
|
|
|
|
$select_ary[$row['group_name']] = $row['group_id'];
|
|
|
|
|
}
|
|
|
|
|
$select_name = 'g';
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'forum_tpl':
|
|
|
|
|
$sql = "SELECT tpl_id, tpl_name FROM ". BB_TOPIC_TPL ." ORDER BY tpl_name";
|
|
|
|
|
$select_ary[$first_opt] = 0;
|
|
|
|
|
foreach (DB()->fetch_rowset($sql) as $row)
|
|
|
|
|
{
|
|
|
|
|
$select_ary[$row['tpl_name']] = $row['tpl_id'];
|
|
|
|
|
}
|
|
|
|
|
$select_name = 'forum_tpl_select';
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ($return_as == 'html') ? build_select($select_name, $select_ary, $selected) : $select_ary;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class html_common
|
|
|
|
|
{
|
|
|
|
|
var $options = '';
|
2023-10-22 08:09:08 +03:00
|
|
|
|
var $out = '';
|
2023-03-11 12:04:29 +03:00
|
|
|
|
var $attr = array();
|
|
|
|
|
var $cur_attr = null;
|
|
|
|
|
var $max_length = HTML_SELECT_MAX_LENGTH;
|
|
|
|
|
var $selected = array();
|
|
|
|
|
|
|
|
|
|
function build_select ($name, $params, $selected = null, $max_length = HTML_SELECT_MAX_LENGTH, $multiple_size = null, $js = '')
|
|
|
|
|
{
|
|
|
|
|
if (empty($params)) return '';
|
|
|
|
|
|
|
|
|
|
$this->options = '';
|
|
|
|
|
$this->selected = array_flip((array) $selected);
|
|
|
|
|
$this->max_length = $max_length;
|
|
|
|
|
|
|
|
|
|
$this->attr = array();
|
|
|
|
|
$this->cur_attr =& $this->attr;
|
|
|
|
|
|
|
|
|
|
if (isset($params['__attributes']))
|
|
|
|
|
{
|
|
|
|
|
$this->attr = $params['__attributes'];
|
|
|
|
|
unset($params['__attributes']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->_build_select_rec($params);
|
|
|
|
|
|
|
|
|
|
$select_params = ($js) ? " $js" : '';
|
|
|
|
|
$select_params .= ($multiple_size) ? ' multiple="multiple" size="'. $multiple_size .'"' : '';
|
|
|
|
|
$select_params .= ' name="'. htmlCHR($name) .'"';
|
|
|
|
|
$select_params .= ' id="'. htmlCHR($name) .'"';
|
|
|
|
|
|
|
|
|
|
return "\n<select $select_params>\n". $this->options ."</select>\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _build_select_rec ($params)
|
|
|
|
|
{
|
|
|
|
|
foreach ($params as $opt_name => $opt_val)
|
|
|
|
|
{
|
|
|
|
|
$opt_name = rtrim($opt_name);
|
|
|
|
|
|
|
|
|
|
if (is_array($opt_val))
|
|
|
|
|
{
|
|
|
|
|
$this->cur_attr =& $this->cur_attr[$opt_name];
|
|
|
|
|
|
|
|
|
|
$label = htmlCHR(str_short($opt_name, $this->max_length));
|
|
|
|
|
|
|
|
|
|
$this->options .= "\t<optgroup label=\" ". $label ."\">\n";
|
|
|
|
|
$this->_build_select_rec($opt_val);
|
|
|
|
|
$this->options .= "\t</optgroup>\n";
|
|
|
|
|
|
|
|
|
|
$this->cur_attr =& $this->attr;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$text = htmlCHR(str_short($opt_name, $this->max_length));
|
|
|
|
|
$value = ' value="'. htmlCHR($opt_val) .'"';
|
|
|
|
|
|
|
|
|
|
$class = isset($this->cur_attr[$opt_name]['class']) ? ' class="'. $this->cur_attr[$opt_name]['class'] .'"' : '';
|
|
|
|
|
$style = isset($this->cur_attr[$opt_name]['style']) ? ' style="'. $this->cur_attr[$opt_name]['style'] .'"' : '';
|
|
|
|
|
|
|
|
|
|
$selected = isset($this->selected[$opt_val]) ? HTML_SELECTED : '';
|
|
|
|
|
$disabled = isset($this->cur_attr[$opt_name]['disabled']) ? HTML_DISABLED : '';
|
|
|
|
|
|
|
|
|
|
$this->options .= "\t\t<option". $class . $style . $selected . $disabled . $value .'> '. $text ." </option>\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function array2html ($array, $ul = 'ul', $li = 'li')
|
|
|
|
|
{
|
|
|
|
|
$this->out = '';
|
|
|
|
|
$this->_array2html_rec($array, $ul, $li);
|
|
|
|
|
return "<$ul class=\"tree-root\">{$this->out}</$ul>";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _array2html_rec ($array, $ul, $li)
|
|
|
|
|
{
|
|
|
|
|
foreach ($array as $k => $v)
|
|
|
|
|
{
|
|
|
|
|
if (is_array($v))
|
|
|
|
|
{
|
|
|
|
|
$this->out .= "<$li><span class=\"b\">$k</span><$ul>";
|
|
|
|
|
$this->_array2html_rec($v, $ul, $li);
|
|
|
|
|
$this->out .= "</$ul></$li>";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$this->out .= "<$li><span>$v</span></$li>";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// all arguments should be already htmlspecialchar()d (if needed)
|
|
|
|
|
function build_checkbox ($name, $title, $checked = false, $disabled = false, $class = null, $id = null, $value = 1)
|
|
|
|
|
{
|
|
|
|
|
$name = ' name="'. $name .'" ';
|
|
|
|
|
$value = ' value="'. $value .'" ';
|
|
|
|
|
$title = ($class) ? '<span class="'. $class .'">'. $title .'</span>' : $title;
|
|
|
|
|
$id = ($id) ? " id=\"$id\" " : '';
|
|
|
|
|
$checked = ($checked) ? HTML_CHECKED : '';
|
|
|
|
|
$disabled = ($disabled) ? HTML_DISABLED : '';
|
|
|
|
|
|
|
|
|
|
return '<label><input type="checkbox" '. $id . $name . $value . $checked . $disabled .' /> '. $title .' </label>';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# function build_option ($opt_name, $opt_val, $selected = null, $max_length = false)
|
|
|
|
|
# {
|
|
|
|
|
# return "\t\t<option value=\"". htmlCHR($opt_val) .'"'. (($selected) ? ' selected="selected"' : '') .'>'. htmlCHR(str_short($opt_name, $max_length)) ."</option>\n";
|
|
|
|
|
# }
|
|
|
|
|
|
|
|
|
|
# function build_optgroup ($label, $contents, $max_length = false)
|
|
|
|
|
# {
|
|
|
|
|
# return "\t<optgroup label=\" ". htmlCHR(str_short($label, $max_length)) ."\">\n". $contents ."\t</optgroup>\n";
|
|
|
|
|
# }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function build_select ($name, $params, $selected = null, $max_length = HTML_SELECT_MAX_LENGTH, $multiple_size = null, $js = '')
|
|
|
|
|
{
|
|
|
|
|
global $html;
|
|
|
|
|
return $html->build_select($name, $params, $selected, $max_length, $multiple_size, $js);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function build_checkbox ($name, $title, $checked = false, $disabled = false, $class = null, $id = null, $value = 1)
|
|
|
|
|
{
|
|
|
|
|
global $html;
|
|
|
|
|
return $html->build_checkbox($name, $title, $checked, $disabled, $class, $id, $value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function replace_quote ($str, $double = true, $single = true)
|
|
|
|
|
{
|
|
|
|
|
if ($double) $str = str_replace('"', '"', $str);
|
|
|
|
|
if ($single) $str = str_replace("'", ''', $str);
|
|
|
|
|
return $str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build simple hidden fields from array
|
|
|
|
|
*/
|
|
|
|
|
function build_hidden_fields ($fields_ary)
|
|
|
|
|
{
|
|
|
|
|
$out = "\n";
|
|
|
|
|
|
|
|
|
|
foreach ($fields_ary as $name => $val)
|
|
|
|
|
{
|
|
|
|
|
if (is_array($val))
|
|
|
|
|
{
|
|
|
|
|
foreach ($val as $ary_key => $ary_val)
|
|
|
|
|
{
|
|
|
|
|
$out .= '<input type="hidden" name="'. $name .'['. $ary_key .']" value="'. $ary_val ."\" />\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$out .= '<input type="hidden" name="'. $name .'" value="'. $val ."\" />\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Choost russian word declension based on numeric [from dklab.ru]
|
|
|
|
|
* Example for $expressions: array("ответ", "ответа", "ответов")
|
|
|
|
|
*/
|
|
|
|
|
function declension ($int, $expressions, $format = '%1$s %2$s')
|
|
|
|
|
{
|
|
|
|
|
if (!is_array($expressions))
|
|
|
|
|
{
|
|
|
|
|
$expressions = $GLOBALS['lang']['DECLENSION'][strtoupper($expressions)];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (count($expressions) < 3)
|
|
|
|
|
{
|
|
|
|
|
$expressions[2] = $expressions[1];
|
|
|
|
|
}
|
|
|
|
|
$count = intval($int) % 100;
|
|
|
|
|
|
|
|
|
|
if ($count >= 5 && $count <= 20)
|
|
|
|
|
{
|
|
|
|
|
$result = $expressions['2'];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$count = $count % 10;
|
|
|
|
|
if ($count == 1)
|
|
|
|
|
{
|
|
|
|
|
$result = $expressions['0'];
|
|
|
|
|
}
|
|
|
|
|
elseif ($count >= 2 && $count <= 4)
|
|
|
|
|
{
|
|
|
|
|
$result = $expressions['1'];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$result = $expressions['2'];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ($format) ? sprintf($format, $int, $result) : $result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// http://forum.dklab.ru/php/advises/UrlreplaceargChangesValueOfParameterInUrl.html
|
|
|
|
|
function url_arg ($url, $arg, $value, $amp = '&')
|
|
|
|
|
{
|
|
|
|
|
$arg = preg_quote($arg, '/');
|
|
|
|
|
|
|
|
|
|
// разделяем URL и ANCHOR
|
|
|
|
|
$anchor = '';
|
|
|
|
|
if (preg_match('/(.*)(#.*)/s', $url, $m))
|
|
|
|
|
{
|
|
|
|
|
$url = $m[1];
|
|
|
|
|
$anchor = $m[2];
|
|
|
|
|
}
|
|
|
|
|
// заменяем параметр, если он существует
|
|
|
|
|
if (preg_match("/((\?|&|&)$arg=)[^&]*/s", $url, $m))
|
|
|
|
|
{
|
|
|
|
|
$cur = $m[0];
|
|
|
|
|
$new = is_null($value) ? '' : $m[1] . urlencode($value);
|
|
|
|
|
$url = str_replace($cur, $new, $url);
|
|
|
|
|
}
|
|
|
|
|
// добавляем параметр
|
|
|
|
|
else if (!is_null($value))
|
|
|
|
|
{
|
|
|
|
|
$div = (strpos($url, '?') !== false) ? $amp : '?';
|
|
|
|
|
$url = $url . $div . $arg .'='. urlencode($value);
|
|
|
|
|
}
|
|
|
|
|
return $url . $anchor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds commas between every group of thousands
|
|
|
|
|
*/
|
|
|
|
|
function commify ($number)
|
|
|
|
|
{
|
|
|
|
|
return number_format($number);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a size formatted in a more human-friendly format, rounded to the nearest GB, MB, KB..
|
|
|
|
|
*/
|
|
|
|
|
function humn_size ($size, $rounder = null, $min = null, $space = ' ')
|
|
|
|
|
{
|
|
|
|
|
static $sizes = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
|
|
|
|
|
static $rounders = array(0, 0, 0, 2, 3, 3, 3, 3, 3);
|
|
|
|
|
|
|
|
|
|
$size = (float) $size;
|
|
|
|
|
$ext = $sizes[0];
|
|
|
|
|
$rnd = $rounders[0];
|
|
|
|
|
|
|
|
|
|
if ($min == 'KB' && $size < 1024)
|
|
|
|
|
{
|
|
|
|
|
$size = $size / 1024;
|
|
|
|
|
$ext = 'KB';
|
|
|
|
|
$rounder = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for ($i=1, $cnt=count($sizes); ($i < $cnt && $size >= 1024); $i++)
|
|
|
|
|
{
|
|
|
|
|
$size = $size / 1024;
|
|
|
|
|
$ext = $sizes[$i];
|
|
|
|
|
$rnd = $rounders[$i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!$rounder)
|
|
|
|
|
{
|
|
|
|
|
$rounder = $rnd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return round($size, $rounder) . $space . $ext;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function bt_show_ip ($ip, $port = '')
|
|
|
|
|
{
|
|
|
|
|
global $bb_cfg;
|
|
|
|
|
|
|
|
|
|
if (IS_AM)
|
|
|
|
|
{
|
|
|
|
|
$ip = decode_ip($ip);
|
|
|
|
|
$ip .= ($port) ? ":$port" : '';
|
|
|
|
|
return $ip;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return ($bb_cfg['bt_show_ip_only_moder']) ? false : decode_ip_xx($ip);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function bt_show_port ($port)
|
|
|
|
|
{
|
|
|
|
|
global $bb_cfg;
|
|
|
|
|
|
|
|
|
|
if (IS_AM)
|
|
|
|
|
{
|
|
|
|
|
return $port;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return ($bb_cfg['bt_show_port_only_moder']) ? false : $port;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function decode_ip_xx ($ip)
|
|
|
|
|
{
|
2023-07-03 12:28:51 +03:00
|
|
|
|
$h = explode('.', chunk_split($ip, 2, '.'));
|
|
|
|
|
return hexdec($h[0]) .'.'. hexdec($h[1]) .'.'. hexdec($h[2]) .'.xx';
|
2023-03-11 12:04:29 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkbox_get_val (&$key, &$val, $default = 1, $on = 1, $off = 0)
|
|
|
|
|
{
|
|
|
|
|
global $previous_settings, $search_id;
|
|
|
|
|
|
|
|
|
|
if (isset($_REQUEST[$key]) && is_string($_REQUEST[$key]))
|
|
|
|
|
{
|
|
|
|
|
$val = (int) $_REQUEST[$key];
|
|
|
|
|
}
|
|
|
|
|
else if (!isset($_REQUEST[$key]) && isset($_REQUEST['prev_'. $key]))
|
|
|
|
|
{
|
|
|
|
|
$val = $off;
|
|
|
|
|
}
|
|
|
|
|
else if (isset($previous_settings[$key]) && (!IS_GUEST || !empty($search_id)))
|
|
|
|
|
{
|
|
|
|
|
$val = ($previous_settings[$key]) ? $on : $off;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$val = $default;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function select_get_val ($key, &$val, $options_ary, $default, $num = true)
|
|
|
|
|
{
|
|
|
|
|
global $previous_settings;
|
|
|
|
|
|
|
|
|
|
if (isset($_REQUEST[$key]) && is_string($_REQUEST[$key]))
|
|
|
|
|
{
|
|
|
|
|
if (isset($options_ary[$_REQUEST[$key]]))
|
|
|
|
|
{
|
|
|
|
|
$val = ($num) ? intval($_REQUEST[$key]) : $_REQUEST[$key];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (isset($previous_settings[$key]))
|
|
|
|
|
{
|
|
|
|
|
$val = $previous_settings[$key];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$val = $default;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* set_var
|
|
|
|
|
*
|
|
|
|
|
* Set variable, used by {@link request_var the request_var function}
|
|
|
|
|
*
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
function set_var (&$result, $var, $type, $multibyte = false, $strip = true)
|
|
|
|
|
{
|
|
|
|
|
settype($var, $type);
|
|
|
|
|
$result = $var;
|
|
|
|
|
|
|
|
|
|
if ($type == 'string')
|
|
|
|
|
{
|
|
|
|
|
$result = trim(htmlspecialchars(str_replace(array("\r\n", "\r"), array("\n", "\n"), $result)));
|
|
|
|
|
|
|
|
|
|
if (!empty($result))
|
|
|
|
|
{
|
|
|
|
|
// Make sure multibyte characters are wellformed
|
|
|
|
|
if ($multibyte)
|
|
|
|
|
{
|
|
|
|
|
if (!preg_match('/^./u', $result))
|
|
|
|
|
{
|
|
|
|
|
$result = '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$result = ($strip) ? stripslashes($result) : $result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* request_var
|
|
|
|
|
*
|
|
|
|
|
* Used to get passed variable
|
|
|
|
|
*/
|
|
|
|
|
function request_var ($var_name, $default, $multibyte = false, $cookie = false)
|
|
|
|
|
{
|
|
|
|
|
if (!$cookie && isset($_COOKIE[$var_name]))
|
|
|
|
|
{
|
|
|
|
|
if (!isset($_GET[$var_name]) && !isset($_POST[$var_name]))
|
|
|
|
|
{
|
|
|
|
|
return (is_array($default)) ? array() : $default;
|
|
|
|
|
}
|
|
|
|
|
$_REQUEST[$var_name] = isset($_POST[$var_name]) ? $_POST[$var_name] : $_GET[$var_name];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isset($_REQUEST[$var_name]) || (is_array($_REQUEST[$var_name]) && !is_array($default)) || (is_array($default) && !is_array($_REQUEST[$var_name])))
|
|
|
|
|
{
|
|
|
|
|
return (is_array($default)) ? array() : $default;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$var = $_REQUEST[$var_name];
|
|
|
|
|
if (!is_array($default))
|
|
|
|
|
{
|
|
|
|
|
$type = gettype($default);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
list($key_type, $type) = each($default);
|
|
|
|
|
$type = gettype($type);
|
|
|
|
|
$key_type = gettype($key_type);
|
|
|
|
|
if ($type == 'array')
|
|
|
|
|
{
|
|
|
|
|
reset($default);
|
|
|
|
|
$default = current($default);
|
|
|
|
|
list($sub_key_type, $sub_type) = each($default);
|
|
|
|
|
$sub_type = gettype($sub_type);
|
|
|
|
|
$sub_type = ($sub_type == 'array') ? 'NULL' : $sub_type;
|
|
|
|
|
$sub_key_type = gettype($sub_key_type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_array($var))
|
|
|
|
|
{
|
|
|
|
|
$_var = $var;
|
|
|
|
|
$var = array();
|
|
|
|
|
|
|
|
|
|
foreach ($_var as $k => $v)
|
|
|
|
|
{
|
|
|
|
|
set_var($k, $k, $key_type);
|
|
|
|
|
if ($type == 'array' && is_array($v))
|
|
|
|
|
{
|
|
|
|
|
foreach ($v as $_k => $_v)
|
|
|
|
|
{
|
|
|
|
|
if (is_array($_v))
|
|
|
|
|
{
|
|
|
|
|
$_v = null;
|
|
|
|
|
}
|
|
|
|
|
set_var($_k, $_k, $sub_key_type);
|
|
|
|
|
set_var($var[$k][$_k], $_v, $sub_type, $multibyte);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ($type == 'array' || is_array($v))
|
|
|
|
|
{
|
|
|
|
|
$v = null;
|
|
|
|
|
}
|
|
|
|
|
set_var($var[$k], $v, $type, $multibyte);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
set_var($var, $var, $type, $multibyte);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $var;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function get_username ($user_id)
|
|
|
|
|
{
|
|
|
|
|
if (empty($user_id))
|
|
|
|
|
{
|
|
|
|
|
return is_array($user_id) ? array() : false;
|
|
|
|
|
}
|
|
|
|
|
if (is_array($user_id))
|
|
|
|
|
{
|
|
|
|
|
$usernames = array();
|
|
|
|
|
foreach (DB()->fetch_rowset("SELECT user_id, username FROM ". BB_USERS ." WHERE user_id IN(". get_id_csv($user_id) .")") as $row)
|
|
|
|
|
{
|
|
|
|
|
$usernames[$row['user_id']] = $row['username'];
|
|
|
|
|
}
|
|
|
|
|
return $usernames;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$row = DB()->fetch_row("SELECT username FROM ". BB_USERS ." WHERE user_id = $user_id LIMIT 1");
|
|
|
|
|
return $row['username'];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function get_user_id ($username)
|
|
|
|
|
{
|
|
|
|
|
if (empty($username)) return false;
|
|
|
|
|
$row = DB()->fetch_row("SELECT user_id FROM ". BB_USERS ." WHERE username = '". DB()->escape($username) ."' LIMIT 1");
|
|
|
|
|
return $row['user_id'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function str_short ($text, $max_length, $space = ' ')
|
|
|
|
|
{
|
|
|
|
|
if ($max_length && mb_strlen($text, 'UTF-8') > $max_length)
|
|
|
|
|
{
|
|
|
|
|
$text = mb_substr($text, 0, $max_length, 'UTF-8');
|
|
|
|
|
|
|
|
|
|
if ($last_space_pos = $max_length - intval(strpos(strrev($text), $space)))
|
|
|
|
|
{
|
|
|
|
|
if ($last_space_pos > round($max_length * 3/4))
|
|
|
|
|
{
|
|
|
|
|
$last_space_pos--;
|
|
|
|
|
$text = mb_substr($text, 0, $last_space_pos, 'UTF-8');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$text .= '...';
|
|
|
|
|
$text = preg_replace('!&#?(\w+)?;?(\w{1,5})?\.\.\.$!', '...', $text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function wbr ($text, $max_word_length = HTML_WBR_LENGTH)
|
|
|
|
|
{
|
|
|
|
|
return preg_replace("/([\w\->;:.,~!?(){}@#$%^*\/\\\\]{". $max_word_length ."})/ui", '$1<wbr>', $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;
|
|
|
|
|
|
2023-08-10 09:35:32 +03:00
|
|
|
|
if (!$btu = get_bt_userdata($user_id))
|
|
|
|
|
{
|
2023-09-03 07:36:51 +03:00
|
|
|
|
require_once(INC_DIR .'functions_torrent.php');
|
2023-10-26 14:08:57 +03:00
|
|
|
|
if (!generate_passkey($user_id, true))
|
|
|
|
|
{
|
2023-10-26 14:16:48 +03:00
|
|
|
|
bb_die(sprintf($lang['PASSKEY_ERR_EMPTY'], PROFILE_URL . $user_id));
|
2023-10-26 14:08:57 +03:00
|
|
|
|
}
|
2023-08-10 09:35:32 +03:00
|
|
|
|
$btu = get_bt_userdata($user_id);
|
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
|
|
|
|
|
|
$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']) ? $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'];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
2024-01-06 10:26:17 +03:00
|
|
|
|
$sql = null;
|
2023-03-11 12:04:29 +03:00
|
|
|
|
switch ($mode)
|
|
|
|
|
{
|
|
|
|
|
case 'usercount':
|
2024-01-05 22:14:47 +03:00
|
|
|
|
$sql = "SELECT COUNT(user_id) AS total FROM " . BB_USERS . " WHERE user_id NOT IN (" . EXCLUDED_USERS_CSV . ")";
|
2023-03-11 12:04:29 +03:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'newestuser':
|
2024-01-05 22:14:47 +03:00
|
|
|
|
$sql = "SELECT user_id, username FROM " . BB_USERS . " WHERE user_id NOT IN (" . EXCLUDED_USERS_CSV . ") ORDER BY user_id DESC LIMIT 1";
|
2023-03-11 12:04:29 +03:00
|
|
|
|
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':
|
2024-01-05 22:18:54 +03:00
|
|
|
|
return isset($row['total']) ? $row['total'] : 0;
|
2023-03-11 12:04:29 +03:00
|
|
|
|
break;
|
|
|
|
|
case 'newestuser':
|
|
|
|
|
return $row;
|
|
|
|
|
break;
|
|
|
|
|
case 'postcount':
|
2024-01-05 22:18:54 +03:00
|
|
|
|
return isset($row['post_total']) ? $row['post_total'] : 0;
|
2023-03-11 12:04:29 +03:00
|
|
|
|
break;
|
|
|
|
|
case 'topiccount':
|
2024-01-05 22:18:54 +03:00
|
|
|
|
return isset($row['topic_total']) ? $row['topic_total'] : 0;
|
2023-03-11 12:04:29 +03:00
|
|
|
|
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 (intval($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)
|
|
|
|
|
{
|
2023-08-20 10:18:54 +03:00
|
|
|
|
global $datastore, $template, $bb_cfg;
|
|
|
|
|
|
2023-08-20 18:03:27 +03:00
|
|
|
|
if (!$bb_cfg['show_jumpbox'])
|
2023-08-20 10:18:54 +03:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
|
|
|
|
|
|
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 (is_null($max_length))
|
|
|
|
|
{
|
|
|
|
|
$max_length = HTML_SELECT_MAX_LENGTH;
|
|
|
|
|
}
|
|
|
|
|
$select = is_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 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');
|
|
|
|
|
|
|
|
|
|
$theme = array('template_name' => $tpl_dir_name);
|
|
|
|
|
|
|
|
|
|
return $theme;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create date / time with format and friendly date
|
|
|
|
|
function bb_date ($gmepoch, $format = false, $friendly_date = true)
|
|
|
|
|
{
|
|
|
|
|
global $bb_cfg, $lang, $userdata;
|
|
|
|
|
|
2023-10-17 05:15:49 +03:00
|
|
|
|
$gmepoch = (int) $gmepoch;
|
2023-04-06 19:01:38 +03:00
|
|
|
|
|
2023-03-11 12:04:29 +03:00
|
|
|
|
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;
|
2023-04-01 08:22:59 +03:00
|
|
|
|
if (!$date) return '';
|
2023-03-11 12:04:29 +03:00
|
|
|
|
|
|
|
|
|
$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 ) ? '<b>' . $i . '</b>' : '<a href="' . $base_url . "&start=" . ( ( $i - 1 ) * $per_page ) . '">' . $i . '</a>';
|
|
|
|
|
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) ? '<b>' . $i . '</b>' : '<a href="' . $base_url . "&start=" . ( ( $i - 1 ) * $per_page ) . '">' . $i . '</a>';
|
|
|
|
|
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 ) ? '<b>' . $i . '</b>' : '<a href="' . $base_url . "&start=" . ( ( $i - 1 ) * $per_page ) . '">' . $i . '</a>';
|
|
|
|
|
if ($i < $total_pages)
|
|
|
|
|
{
|
|
|
|
|
$page_string .= ", ";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for ($i = 1; $i < $total_pages + 1; $i++)
|
|
|
|
|
{
|
|
|
|
|
$page_string .= ( $i == $on_page ) ? '<b>' . $i . '</b>' : '<a href="' . $base_url . "&start=" . ( ( $i - 1 ) * $per_page ) . '">' . $i . '</a>';
|
|
|
|
|
if ($i < $total_pages)
|
|
|
|
|
{
|
|
|
|
|
$page_string .= ', ';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($add_prevnext_text)
|
|
|
|
|
{
|
|
|
|
|
if ($on_page > 1)
|
|
|
|
|
{
|
|
|
|
|
$page_string = ' <a href="' . $base_url . "&start=" . ( ( $on_page - 2 ) * $per_page ) . '">' . $lang['PREVIOUS_PAGE'] . '</a> ' . $page_string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($on_page < $total_pages)
|
|
|
|
|
{
|
|
|
|
|
$page_string .= ' <a href="' . $base_url . "&start=" . ( $on_page * $per_page ) . '">' . $lang['NEXT_PAGE'] . '</a>';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$pagination = ($page_string) ? '<a class="menu-root" href="#pg-jump">'. $lang['GOTO_PAGE'] .'</a> : '. $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[] = '#(?<!\S)(' . str_replace('\*', '\S*?', preg_quote($row['word'], '#')) . ')(?!\S)#iu';
|
|
|
|
|
$orig_word[] = '#(?<![\p{Nd}\p{L}_])(' . str_replace('\*', '[\p{Nd}\p{L}_]*?', preg_quote($row['word'], '#')) . ')(?![\p{Nd}\p{L}_])#iu';
|
|
|
|
|
$replacement_word[] = $row['replacement'];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function bb_die ($msg_text)
|
|
|
|
|
{
|
|
|
|
|
global $ajax, $bb_cfg, $lang, $template, $theme, $userdata;
|
|
|
|
|
|
|
|
|
|
if (defined('IN_AJAX'))
|
|
|
|
|
{
|
2023-10-26 12:14:20 +03:00
|
|
|
|
$ajax->ajax_die($msg_text);
|
2023-03-11 12:04:29 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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 = session_pagestart();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the header hasn't been output then do it
|
|
|
|
|
if (!defined('PAGE_HEADER_SENT'))
|
|
|
|
|
{
|
|
|
|
|
if (empty($template))
|
|
|
|
|
{
|
|
|
|
|
$template = new 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:<br /><br />$txt");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
header('Content-Type: text/plain; charset='. $bb_cfg['charset']);
|
|
|
|
|
die($txt);
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-14 12:57:22 +03:00
|
|
|
|
// Alias for bb_die()
|
|
|
|
|
function message_die ($msg_code, $msg_text = '')
|
|
|
|
|
{
|
|
|
|
|
if ($msg_code == CRITICAL_MESSAGE || $msg_code == CRITICAL_ERROR)
|
|
|
|
|
{
|
|
|
|
|
bb_simple_die($msg_text);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bb_die($msg_text);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-11 12:04:29 +03:00
|
|
|
|
function bb_realpath ($path)
|
|
|
|
|
{
|
|
|
|
|
return (!@function_exists('realpath') || !@realpath(INC_DIR . 'functions.php')) ? $path : @realpath($path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function login_redirect ($url = '')
|
|
|
|
|
{
|
|
|
|
|
redirect(LOGIN_URL . '?redirect='. (($url) ? $url : (isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/')));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function meta_refresh ($url, $time = 5)
|
|
|
|
|
{
|
|
|
|
|
global $template;
|
|
|
|
|
|
|
|
|
|
$template->assign_var('META', '<meta http-equiv="refresh" content="' . $time . ';url=' . $url . '" />');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function redirect ($url)
|
|
|
|
|
{
|
|
|
|
|
global $bb_cfg;
|
|
|
|
|
|
|
|
|
|
if (headers_sent($filename, $linenum))
|
|
|
|
|
{
|
|
|
|
|
trigger_error("Headers already sent in $filename($linenum)", E_USER_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strstr(urldecode($url), "\n") || strstr(urldecode($url), "\r") || strstr(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')
|
|
|
|
|
{
|
|
|
|
|
for ($i=0; $i < count($listrow['lang_key']); $i++)
|
|
|
|
|
{
|
|
|
|
|
$selected = ($i==$selected_row) ? ' selected="selected"' : '';
|
|
|
|
|
$l_value = (isset($lang[$listrow['lang_key'][$i]])) ? $lang[$listrow['lang_key'][$i]] : $listrow['lang_key'][$i];
|
|
|
|
|
$res .= '<option value="' . $i . '"' . $selected . '>' . $l_value . '</option>';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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 '<img src="styles/images/icon_clip.gif" alt="" border="0" /> ';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* array_combine()
|
|
|
|
|
*
|
|
|
|
|
* @package PHP_Compat
|
|
|
|
|
* @link http://php.net/function.array_combine
|
|
|
|
|
* @author Aidan Lister <aidan@php.net>
|
|
|
|
|
* @version $Revision: 1.21 $
|
|
|
|
|
* @since PHP 5
|
|
|
|
|
*/
|
|
|
|
|
if (!function_exists('array_combine'))
|
|
|
|
|
{
|
|
|
|
|
function array_combine($keys, $values)
|
|
|
|
|
{
|
|
|
|
|
if (!is_array($keys)) {
|
|
|
|
|
user_error('array_combine() expects parameter 1 to be array, ' .
|
|
|
|
|
gettype($keys) . ' given', E_USER_WARNING);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!is_array($values)) {
|
|
|
|
|
user_error('array_combine() expects parameter 2 to be array, ' .
|
|
|
|
|
gettype($values) . ' given', E_USER_WARNING);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$key_count = count($keys);
|
|
|
|
|
$value_count = count($values);
|
|
|
|
|
if ($key_count !== $value_count) {
|
|
|
|
|
user_error('array_combine() both parameters should have equal number of elements', E_USER_WARNING);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($key_count === 0 || $value_count === 0) {
|
|
|
|
|
user_error('array_combine() both parameters should have number of elements at least 0', E_USER_WARNING);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$keys = array_values($keys);
|
|
|
|
|
$values = array_values($values);
|
|
|
|
|
|
|
|
|
|
$combined = array();
|
|
|
|
|
for ($i = 0; $i < $key_count; $i++) {
|
|
|
|
|
$combined[$keys[$i]] = $values[$i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $combined;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* array_intersect_key()
|
|
|
|
|
*
|
|
|
|
|
* @package PHP_Compat
|
|
|
|
|
* @link http://php.net/function.array_intersect_key
|
|
|
|
|
* @author Tom Buskens <ortega@php.net>
|
|
|
|
|
* @version $Revision: 1.4 $
|
|
|
|
|
* @since PHP 5.0.2
|
|
|
|
|
*/
|
|
|
|
|
if (!function_exists('array_intersect_key')) {
|
2023-08-15 11:22:49 +03:00
|
|
|
|
function array_intersect_key()
|
|
|
|
|
{
|
|
|
|
|
$args = func_get_args();
|
|
|
|
|
if (count($args) < 2) {
|
|
|
|
|
user_error('Wrong parameter count for array_intersect_key()', E_USER_WARNING);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check arrays
|
|
|
|
|
$array_count = count($args);
|
|
|
|
|
for ($i = 0; $i !== $array_count; $i++) {
|
|
|
|
|
if (!is_array($args[$i])) {
|
|
|
|
|
user_error('array_intersect_key() Argument #' . ($i + 1) . ' is not an array', E_USER_WARNING);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Compare entries
|
|
|
|
|
$result = array();
|
|
|
|
|
foreach ($args[0] as $key1 => $value1) {
|
|
|
|
|
for ($i = 1; $i !== $array_count; $i++) {
|
|
|
|
|
foreach ($args[$i] as $key2 => $value2) {
|
|
|
|
|
if ((string)$key1 === (string)$key2) {
|
|
|
|
|
$result[$key1] = $value1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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) join(',', $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");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Action Log
|
|
|
|
|
//
|
|
|
|
|
class log_action
|
|
|
|
|
{
|
|
|
|
|
var $log_type = array(
|
|
|
|
|
# LOG_TYPE_NAME LOG_TYPE_ID
|
|
|
|
|
'mod_topic_delete' => 1,
|
|
|
|
|
'mod_topic_move' => 2,
|
|
|
|
|
'mod_topic_lock' => 3,
|
|
|
|
|
'mod_topic_unlock' => 4,
|
|
|
|
|
'mod_post_delete' => 5,
|
2023-08-21 20:23:36 +03:00
|
|
|
|
'mod_topic_split' => 6,
|
|
|
|
|
'adm_user_delete' => 7,
|
|
|
|
|
'adm_user_ban' => 8,
|
|
|
|
|
'adm_user_unban' => 9,
|
|
|
|
|
'mod_post_pin' => 10,
|
|
|
|
|
'mod_post_unpin' => 11,
|
|
|
|
|
'mod_topic_set_downloaded' => 12,
|
|
|
|
|
'mod_topic_unset_downloaded' => 13,
|
2023-08-21 20:57:32 +03:00
|
|
|
|
'mod_topic_renamed' => 14,
|
2023-03-11 12:04:29 +03:00
|
|
|
|
);
|
|
|
|
|
var $log_type_select = array();
|
|
|
|
|
var $log_disabled = false;
|
|
|
|
|
|
|
|
|
|
function init ()
|
|
|
|
|
{
|
|
|
|
|
global $lang, $bb_cfg;
|
|
|
|
|
|
|
|
|
|
foreach ($lang['LOG_ACTION']['LOG_TYPE'] as $log_type => $log_desc)
|
|
|
|
|
{
|
|
|
|
|
$this->log_type_select[strip_tags($log_desc)] = $this->log_type[$log_type];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function mod ($type_name, $args = array())
|
|
|
|
|
{
|
|
|
|
|
global $userdata;
|
|
|
|
|
|
|
|
|
|
if (empty($this->log_type)) $this->init();
|
|
|
|
|
if ($this->log_disabled) return;
|
|
|
|
|
|
|
|
|
|
$forum_id =& $args['forum_id'];
|
|
|
|
|
$forum_id_new =& $args['forum_id_new'];
|
|
|
|
|
$topic_id =& $args['topic_id'];
|
|
|
|
|
$topic_id_new =& $args['topic_id_new'];
|
|
|
|
|
$topic_title =& $args['topic_title'];
|
|
|
|
|
$topic_title_new =& $args['topic_title_new'];
|
|
|
|
|
$log_msg =& $args['log_msg'];
|
|
|
|
|
|
|
|
|
|
if (!empty($userdata))
|
|
|
|
|
{
|
|
|
|
|
$user_id = $userdata['user_id'];
|
|
|
|
|
$username = $userdata['username'];
|
|
|
|
|
$session_ip = $userdata['session_ip'];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$user_id = '';
|
|
|
|
|
$username = defined('IN_CRON') ? 'cron' : CLIENT_IP;
|
|
|
|
|
$session_ip = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$sql_ary = array(
|
|
|
|
|
'log_type_id' => (int) $this->log_type["$type_name"],
|
|
|
|
|
'log_user_id' => (int) $user_id,
|
|
|
|
|
'log_username' => (string) $username,
|
|
|
|
|
'log_user_ip' => (string) $session_ip,
|
|
|
|
|
'log_forum_id' => (int) $forum_id,
|
|
|
|
|
'log_forum_id_new' => (int) $forum_id_new,
|
|
|
|
|
'log_topic_id' => (int) $topic_id,
|
|
|
|
|
'log_topic_id_new' => (int) $topic_id_new,
|
|
|
|
|
'log_topic_title' => (string) $topic_title,
|
|
|
|
|
'log_topic_title_new' => (string) $topic_title_new,
|
|
|
|
|
'log_time' => (int) TIMENOW,
|
|
|
|
|
'log_msg' => (string) $log_msg,
|
|
|
|
|
);
|
|
|
|
|
$sql_args = DB()->build_array('INSERT', $sql_ary);
|
|
|
|
|
|
|
|
|
|
DB()->query("INSERT INTO ". BB_LOG ." $sql_args");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function admin ($type_name, $args = array())
|
|
|
|
|
{
|
|
|
|
|
$this->mod($type_name, $args);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function get_topic_icon ($topic, $is_unread = null)
|
|
|
|
|
{
|
|
|
|
|
global $bb_cfg, $images;
|
|
|
|
|
|
|
|
|
|
$t_hot = ($topic['topic_replies'] >= $bb_cfg['hot_threshold']);
|
|
|
|
|
$is_unread = is_null($is_unread) ? is_unread($topic['topic_last_post_time'], $topic['topic_id'], $topic['forum_id']) : $is_unread;
|
|
|
|
|
|
|
|
|
|
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'];
|
|
|
|
|
}
|
|
|
|
|
else if ($topic['topic_type'] == POST_STICKY)
|
|
|
|
|
{
|
|
|
|
|
$folder = $images['folder_sticky'];
|
|
|
|
|
$folder_new = $images['folder_sticky_new'];
|
|
|
|
|
}
|
|
|
|
|
else if ($topic['topic_status'] == TOPIC_LOCKED)
|
|
|
|
|
{
|
|
|
|
|
$folder = $images['folder_locked'];
|
|
|
|
|
$folder_new = $images['folder_locked_new'];
|
|
|
|
|
}
|
|
|
|
|
else if ($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 .= '<a href="'. $href .'" class="topicPG">'. $page .'</a>';
|
|
|
|
|
|
|
|
|
|
if ($page == 1 && $total_pages > 3)
|
|
|
|
|
{
|
|
|
|
|
$pg .= ' .. ';
|
|
|
|
|
$page = $total_pages - 2;
|
|
|
|
|
$j += ($total_pages - 3) * $per_page;
|
|
|
|
|
}
|
|
|
|
|
else if ($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] = Zend\Json\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',
|
|
|
|
|
));
|
2023-10-31 12:09:19 +03:00
|
|
|
|
|
|
|
|
|
if (empty($tpl_vars['QUESTION']))
|
|
|
|
|
{
|
|
|
|
|
$tpl_vars['QUESTION'] = $lang['QUESTION'];
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-11 12:04:29 +03:00
|
|
|
|
$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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ($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, $remove_stopwords = false, $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 ($remove_stopwords)
|
|
|
|
|
{
|
|
|
|
|
$text = remove_stopwords($text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 = 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))
|
|
|
|
|
{
|
|
|
|
|
require(INC_DIR .'api/sphinx.php');
|
|
|
|
|
$sphinx = new SphinxClient();
|
|
|
|
|
|
|
|
|
|
$sphinx->SetConnectTimeout(5);
|
|
|
|
|
$sphinx->SetRankingMode(SPH_RANK_NONE);
|
|
|
|
|
$sphinx->SetMatchMode(SPH_MATCH_BOOLEAN);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function log_sphinx_error ($err_type, $err_msg, $query = '')
|
|
|
|
|
{
|
2023-04-06 09:38:41 +03:00
|
|
|
|
if (SPHINX_LOG_ERRORS)
|
2023-03-11 12:04:29 +03:00
|
|
|
|
{
|
2023-04-06 09:38:41 +03:00
|
|
|
|
$ignore_err_txt = array(
|
|
|
|
|
'negation on top level',
|
|
|
|
|
'Query word length is less than min prefix length',
|
|
|
|
|
);
|
|
|
|
|
if (!count($ignore_err_txt) || !preg_match('#'. join('|', $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_LOG_NAME);
|
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
|
}
|
2023-04-06 09:38:41 +03:00
|
|
|
|
|
|
|
|
|
return false;
|
2023-03-11 12:04:29 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function get_title_match_topics ($title_match_sql, $forum_ids = array())
|
|
|
|
|
{
|
|
|
|
|
global $bb_cfg, $sphinx, $userdata, $title_match, $lang;
|
|
|
|
|
|
|
|
|
|
$where_ids = array();
|
|
|
|
|
if($forum_ids) $forum_ids = array_diff($forum_ids, array(0 => 0));
|
|
|
|
|
$title_match_sql = encode_text_match($title_match_sql);
|
|
|
|
|
|
|
|
|
|
if ($bb_cfg['search_engine_type'] == '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(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']);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ($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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ($bb_cfg['search_engine_type'] == 'mysql')
|
|
|
|
|
{
|
|
|
|
|
$where_forum = ($forum_ids) ? "AND forum_id IN(". join(',', $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 remove_stopwords ($text)
|
|
|
|
|
{
|
|
|
|
|
static $stopwords = null;
|
|
|
|
|
|
|
|
|
|
if (is_null($stopwords))
|
|
|
|
|
{
|
|
|
|
|
$stopwords = explode(' ', str_compact(@file_get_contents(LANG_DIR .'search_stopwords.txt')));
|
|
|
|
|
array_deep($stopwords, 'pad_with_space');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ($stopwords) ? str_replace($stopwords, ' ', $text) : $text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function pad_with_space ($str)
|
|
|
|
|
{
|
|
|
|
|
return ($str) ? " $str " : $str;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-13 13:14:27 +03:00
|
|
|
|
function create_magnet ($infohash, $auth_key, $name)
|
2023-03-11 12:04:29 +03:00
|
|
|
|
{
|
2023-08-10 11:06:49 +03:00
|
|
|
|
global $bb_cfg, $images, $lang, $userdata;
|
2023-03-11 12:04:29 +03:00
|
|
|
|
|
2023-10-23 20:32:26 +03:00
|
|
|
|
if (!$bb_cfg['magnet_links_enabled'])
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 11:06:49 +03:00
|
|
|
|
if (IS_GUEST && $bb_cfg['bt_tor_browse_only_reg'])
|
|
|
|
|
{
|
|
|
|
|
$passkey = '';
|
|
|
|
|
}
|
|
|
|
|
elseif (empty($auth_key))
|
|
|
|
|
{
|
2023-09-03 07:36:51 +03:00
|
|
|
|
require_once(INC_DIR .'functions_torrent.php');
|
2023-08-10 11:06:49 +03:00
|
|
|
|
if (!$passkey = generate_passkey($userdata['user_id'], true))
|
|
|
|
|
{
|
2023-10-26 14:16:48 +03:00
|
|
|
|
bb_die(sprintf($lang['PASSKEY_ERR_EMPTY'], PROFILE_URL . $userdata['user_id']));
|
2023-08-10 11:06:49 +03:00
|
|
|
|
}
|
|
|
|
|
$auth_key = $passkey;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$passkey = $auth_key;
|
|
|
|
|
}
|
2023-04-02 10:52:32 +03:00
|
|
|
|
|
2023-08-10 11:06:49 +03:00
|
|
|
|
$passkey_url = $passkey ? "?{$bb_cfg['passkey_key']}=$auth_key" : '';
|
2023-10-23 20:23:16 +03:00
|
|
|
|
return '<a title="'.$lang['MAGNET'].'" href="magnet:?xt=urn:btih:'. bin2hex($infohash) .'&tr='. urlencode($bb_cfg['bt_announce_url'] . $passkey_url) .'&dn='. urlencode($name) .'"><img src="'. $images['icon_magnet'] .'" width="12" height="12" border="0" /></a>';
|
2023-03-11 12:04:29 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function set_die_append_msg ($forum_id = null, $topic_id = null, $group_id = null)
|
|
|
|
|
{
|
|
|
|
|
global $lang, $template;
|
|
|
|
|
|
|
|
|
|
$msg = '';
|
|
|
|
|
$msg .= ($topic_id) ? '<p class="mrg_10"><a href="'. TOPIC_URL . $topic_id .'">'. $lang['TOPIC_RETURN'] .'</a></p>' : '';
|
|
|
|
|
$msg .= ($forum_id) ? '<p class="mrg_10"><a href="'. FORUM_URL . $forum_id .'">'. $lang['FORUM_RETURN'] .'</a></p>' : '';
|
|
|
|
|
$msg .= ($group_id) ? '<p class="mrg_10"><a href="'. GROUP_URL . $group_id .'">'. $lang['GROUP_RETURN'] .'</a></p>' : '';
|
|
|
|
|
$msg .= '<p class="mrg_10"><a href="index.php">'. $lang['INDEX_RETURN'] .'</a></p>';
|
|
|
|
|
$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', '
|
|
|
|
|
<a href="'. PROFILE_URL . $pr_uid .'" onclick="return post2url(this.href, {after_edit: 1});">'. $lang['PROFILE_RETURN'] .'</a>
|
|
|
|
|
<br /><br />
|
|
|
|
|
<a href="profile.php?mode=editprofile'. (IS_ADMIN ? "&u=$pr_uid" : '') .'" onclick="return post2url(this.href, {after_edit: 1});">'. $lang['PROFILE_EDIT_RETURN'] .'</a>
|
|
|
|
|
<br /><br />
|
|
|
|
|
<a href="index.php">'. $lang['INDEX_RETURN'] .'</a>
|
|
|
|
|
');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 = '<span title="'. $title .'" class="'. $style .'">'. $username .'</span>';
|
|
|
|
|
|
|
|
|
|
if (!in_array($user_id, array('', GUEST_UID, BOT_UID)) && $username)
|
|
|
|
|
{
|
|
|
|
|
$profile = '<a href="'. make_url(PROFILE_URL . $user_id) .'">'. $profile .'</a>';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $profile;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-09 07:25:41 +03:00
|
|
|
|
function get_avatar ($user_id, $ext_id, $allow_avatar = true, $size = true, $height = '', $width = '')
|
2023-03-11 12:04:29 +03:00
|
|
|
|
{
|
|
|
|
|
global $bb_cfg;
|
|
|
|
|
|
|
|
|
|
if ($size)
|
|
|
|
|
{
|
|
|
|
|
// TODO размеры: s, m, l + кеширование
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$height = ($height != '') ? 'height="'. $height .'"' : '';
|
|
|
|
|
$width = ($width != '') ? 'width="'. $width .'"' : '';
|
|
|
|
|
|
|
|
|
|
$user_avatar = '<img src="'. make_url($bb_cfg['avatars']['upload_path'] . $bb_cfg['avatars']['no_avatar']) .'" alt="'. $user_id .'" '. $height .' '. $width .' />';
|
|
|
|
|
|
|
|
|
|
if ($user_id == BOT_UID && $bb_cfg['avatars']['bot_avatar'])
|
|
|
|
|
{
|
|
|
|
|
$user_avatar = '<img src="'. make_url($bb_cfg['avatars']['upload_path'] . $bb_cfg['avatars']['bot_avatar']) .'" alt="'. $user_id .'" '. $height .' '. $width .' />';
|
|
|
|
|
}
|
|
|
|
|
else if ($allow_avatar && $ext_id)
|
|
|
|
|
{
|
|
|
|
|
if (file_exists(get_avatar_path($user_id, $ext_id)))
|
|
|
|
|
{
|
|
|
|
|
$user_avatar = '<img src="'. make_url(get_avatar_path($user_id, $ext_id)) .'" alt="'. $user_id .'" '. $height .' '. $width .' />';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $user_avatar;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function gender_image ($gender)
|
|
|
|
|
{
|
|
|
|
|
global $bb_cfg, $lang, $images;
|
|
|
|
|
|
|
|
|
|
if (!$bb_cfg['gender'])
|
|
|
|
|
{
|
|
|
|
|
$user_gender = '';
|
|
|
|
|
return $user_gender;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
switch ($gender)
|
|
|
|
|
{
|
|
|
|
|
case MALE:
|
|
|
|
|
$user_gender = '<img src="'. $images['icon_male'] .'" alt="'. $lang['GENDER_SELECT'][MALE] .'" title="'. $lang['GENDER_SELECT'][MALE] .'" border="0" />';
|
|
|
|
|
break;
|
|
|
|
|
case FEMALE:
|
|
|
|
|
$user_gender = '<img src="'. $images['icon_female'] .'" alt="'. $lang['GENDER_SELECT'][FEMALE] .'" title="'. $lang['GENDER_SELECT'][FEMALE] .'" border="0" />';
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
$user_gender = '<img src="'. $images['icon_nogender'] .'" alt="'. $lang['GENDER_SELECT'][NOGENDER] .'" title="'. $lang['GENDER_SELECT'][NOGENDER] .'" border="0" />';
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $user_gender;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function is_gold ($type)
|
|
|
|
|
{
|
|
|
|
|
global $lang, $tr_cfg;
|
|
|
|
|
|
|
|
|
|
if (!$tr_cfg['gold_silver_enabled'])
|
|
|
|
|
{
|
|
|
|
|
$is_gold = '';
|
|
|
|
|
return $is_gold;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
switch ($type)
|
|
|
|
|
{
|
|
|
|
|
case TOR_TYPE_GOLD:
|
2023-08-15 11:05:19 +03:00
|
|
|
|
$is_gold = '<img src="styles/images/tor_gold.gif" width="16" height="15" alt="'. $lang['GOLD'] .'" title="'. $lang['GOLD'] .'" /> ';
|
2023-03-11 12:04:29 +03:00
|
|
|
|
break;
|
|
|
|
|
case TOR_TYPE_SILVER:
|
2023-08-15 11:05:19 +03:00
|
|
|
|
$is_gold = '<img src="styles/images/tor_silver.gif" width="16" height="15" alt="'. $lang['SILVER'] .'" title="'. $lang['SILVER'] .'" /> ';
|
2023-03-11 12:04:29 +03:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
$is_gold = '';
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $is_gold;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function update_atom ($type, $id)
|
|
|
|
|
{
|
|
|
|
|
require_once(INC_DIR .'functions_atom.php');
|
|
|
|
|
|
|
|
|
|
switch ($type)
|
|
|
|
|
{
|
|
|
|
|
case 'user':
|
|
|
|
|
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');
|
|
|
|
|
update_user_feed($topic_poster, get_username($topic_poster));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function hash_search ($hash)
|
|
|
|
|
{
|
|
|
|
|
global $lang;
|
|
|
|
|
|
|
|
|
|
$hash = htmlCHR(trim($hash));
|
|
|
|
|
|
2023-11-14 16:50:10 +03:00
|
|
|
|
if (!isset($hash) || mb_strlen($hash, 'UTF-8') != 40 || !ctype_xdigit($hash))
|
2023-03-11 12:04:29 +03:00
|
|
|
|
{
|
|
|
|
|
bb_die(sprintf($lang['HASH_INVALID'], $hash));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$info_hash = DB()->escape(pack("H*", $hash));
|
|
|
|
|
|
2023-09-03 07:30:17 +03:00
|
|
|
|
if ($row = DB()->fetch_row("SELECT topic_id FROM " . BB_BT_TORRENTS . " WHERE info_hash = '$info_hash'"))
|
2023-03-11 12:04:29 +03:00
|
|
|
|
{
|
|
|
|
|
redirect(TOPIC_URL . $row['topic_id']);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bb_die(sprintf($lang['HASH_NOT_FOUND'], $hash));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function bb_captcha ($mode, $callback = '')
|
|
|
|
|
{
|
2023-08-26 09:34:36 +03:00
|
|
|
|
global $bb_cfg, $lang;
|
2023-03-11 12:04:29 +03:00
|
|
|
|
|
|
|
|
|
$secret = $bb_cfg['captcha']['secret_key'];
|
|
|
|
|
$public = $bb_cfg['captcha']['public_key'];
|
2023-09-16 15:52:36 +03:00
|
|
|
|
$theme = isset($bb_cfg['captcha']['theme']) ? $bb_cfg['captcha']['theme'] : 'light';
|
2023-03-11 12:04:29 +03:00
|
|
|
|
|
2023-12-20 15:13:42 +03:00
|
|
|
|
if (!$bb_cfg['captcha']['disabled'] && (!$public || !$secret))
|
2023-09-16 21:16:52 +03:00
|
|
|
|
{
|
|
|
|
|
bb_die($lang['CAPTCHA_SETTINGS']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
require_once(CLASS_DIR .'recaptcha.php');
|
2023-03-11 12:04:29 +03:00
|
|
|
|
$reCaptcha = new ReCaptcha($secret);
|
|
|
|
|
|
|
|
|
|
switch ($mode)
|
|
|
|
|
{
|
|
|
|
|
case 'get':
|
|
|
|
|
return "
|
|
|
|
|
<script type=\"text/javascript\">
|
|
|
|
|
var onloadCallback = function() {
|
|
|
|
|
grecaptcha.render('tp-captcha', {
|
|
|
|
|
'sitekey' : '" . $public . "',
|
|
|
|
|
'theme' : '" . $theme . "',
|
|
|
|
|
'callback' : '" . $callback . "'
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
<div id=\"tp-captcha\"></div>
|
2023-08-26 09:34:36 +03:00
|
|
|
|
<script src=\"https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit\" async defer></script>";
|
2023-03-11 12:04:29 +03:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'check':
|
|
|
|
|
$resp = null;
|
|
|
|
|
$error = null;
|
|
|
|
|
$g_resp = request_var('g-recaptcha-response', '');
|
|
|
|
|
if ($g_resp) {
|
|
|
|
|
$resp = $reCaptcha->verifyResponse($_SERVER["REMOTE_ADDR"], $g_resp);
|
|
|
|
|
}
|
|
|
|
|
if ($resp != null && $resp->success) {
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
bb_simple_die(__FUNCTION__ .": invalid mode '$mode'");
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2023-06-24 07:08:34 +03:00
|
|
|
|
}
|