* @version $Revision: 1.4 $
* @since PHP 5.0.2
*/
if (!function_exists('array_intersect_key')) {
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;
}
}
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,
'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,
'mod_topic_renamed' => 14,
);
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 .= ''. $page .'';
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',
));
$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 = '')
{
if (SPHINX_LOG_ERRORS)
{
$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);
}
}
return false;
}
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;
}
function create_magnet ($infohash, $auth_key, $name)
{
global $bb_cfg, $images, $lang, $userdata;
if (IS_GUEST && $bb_cfg['bt_tor_browse_only_reg'])
{
$passkey = '';
}
elseif (empty($auth_key))
{
require_once(INC_DIR .'functions_torrent.php');
if (!$passkey = generate_passkey($userdata['user_id'], true))
{
bb_die($lang['PASSKEY_ERR_EMPTY']);
}
$auth_key = $passkey;
}
else
{
$passkey = $auth_key;
}
$passkey_url = $passkey ? "?{$bb_cfg['passkey_key']}=$auth_key" : '';
return '
';
}
function set_die_append_msg ($forum_id = null, $topic_id = null, $group_id = null)
{
global $lang, $template;
$msg = '';
$msg .= ($topic_id) ? ''. $lang['TOPIC_RETURN'] .'
' : '';
$msg .= ($forum_id) ? ''. $lang['FORUM_RETURN'] .'
' : '';
$msg .= ($group_id) ? ''. $lang['GROUP_RETURN'] .'
' : '';
$msg .= ''. $lang['INDEX_RETURN'] .'
';
$template->assign_var('BB_DIE_APPEND_MSG', $msg);
}
function set_pr_die_append_msg ($pr_uid)
{
global $lang, $template;
$template->assign_var('BB_DIE_APPEND_MSG', '
'. $lang['PROFILE_RETURN'] .'
'. $lang['PROFILE_EDIT_RETURN'] .'
'. $lang['INDEX_RETURN'] .'
');
}
function send_pm ($user_id, $subject, $message, $poster_id = BOT_UID)
{
global $userdata;
$subject = DB()->escape($subject);
$message = DB()->escape($message);
if ($poster_id == BOT_UID)
{
$poster_ip = '7f000001';
}
elseif ($row = DB()->fetch_row("SELECT user_reg_ip FROM ". BB_USERS ." WHERE user_id = $poster_id"))
{
$poster_ip = $row['user_reg_ip'];
}
else
{
$poster_id = $userdata['user_id'];
$poster_ip = USER_IP;
}
DB()->query("INSERT INTO ". BB_PRIVMSGS ." (privmsgs_type, privmsgs_subject, privmsgs_from_userid, privmsgs_to_userid, privmsgs_date, privmsgs_ip) VALUES (". PRIVMSGS_NEW_MAIL .", '$subject', {$poster_id}, $user_id, ". TIMENOW .", '$poster_ip')");
$pm_id = DB()->sql_nextid();
DB()->query("INSERT INTO " . BB_PRIVMSGS_TEXT . " (privmsgs_text_id, privmsgs_text) VALUES ($pm_id, '$message')");
DB()->query("UPDATE ". BB_USERS ." SET user_new_privmsg = user_new_privmsg + 1, user_last_privmsg = ". TIMENOW .", user_newest_pm_id = $pm_id WHERE user_id = $user_id");
}
function profile_url ($data)
{
global $bb_cfg, $lang, $datastore;
if (!$ranks = $datastore->get('ranks'))
{
$datastore->update('ranks');
$ranks = $datastore->get('ranks');
}
$user_rank = !empty($data['user_rank']) ? $data['user_rank'] : 0;
if (isset($ranks[$user_rank]))
{
$title = $ranks[$user_rank]['rank_title'];
$style = $ranks[$user_rank]['rank_style'];
}
if (empty($title)) $title = $lang['USER'];
if (empty($style)) $style = 'colorUser';
if (!$bb_cfg['color_nick']) $style = '';
$username = !empty($data['username']) ? $data['username'] : $lang['GUEST'];
$user_id = (!empty($data['user_id']) && $username != $lang['GUEST']) ? $data['user_id'] : GUEST_UID;
$profile = ''. $username .'';
if (!in_array($user_id, array('', GUEST_UID, BOT_UID)) && $username)
{
$profile = ''. $profile .'';
}
return $profile;
}
function get_avatar ($user_id, $ext_id, $allow_avatar = true, $size = true, $height = '', $width = '')
{
global $bb_cfg;
if ($size)
{
// TODO размеры: s, m, l + кеширование
}
$height = ($height != '') ? 'height="'. $height .'"' : '';
$width = ($width != '') ? 'width="'. $width .'"' : '';
$user_avatar = '
';
if ($user_id == BOT_UID && $bb_cfg['avatars']['bot_avatar'])
{
$user_avatar = '
';
}
else if ($allow_avatar && $ext_id)
{
if (file_exists(get_avatar_path($user_id, $ext_id)))
{
$user_avatar = '
';
}
}
return $user_avatar;
}
function gender_image ($gender)
{
global $bb_cfg, $lang, $images;
if (!$bb_cfg['gender'])
{
$user_gender = '';
return $user_gender;
}
else
{
switch ($gender)
{
case MALE:
$user_gender = '
';
break;
case FEMALE:
$user_gender = '
';
break;
default:
$user_gender = '
';
break;
}
}
return $user_gender;
}
function is_gold ($type)
{
global $lang, $tr_cfg;
if (!$tr_cfg['gold_silver_enabled'])
{
$is_gold = '';
return $is_gold;
}
else
{
switch ($type)
{
case TOR_TYPE_GOLD:
$is_gold = '
';
break;
case TOR_TYPE_SILVER:
$is_gold = '
';
break;
default:
$is_gold = '';
break;
}
}
return $is_gold;
}
function update_atom ($type, $id)
{
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));
if (!isset($hash) || mb_strlen($hash, 'UTF-8') != 40)
{
bb_die(sprintf($lang['HASH_INVALID'], $hash));
}
$info_hash = DB()->escape(pack("H*", $hash));
if ($row = DB()->fetch_row("SELECT topic_id FROM " . BB_BT_TORRENTS . " WHERE info_hash = '$info_hash'"))
{
redirect(TOPIC_URL . $row['topic_id']);
}
else
{
bb_die(sprintf($lang['HASH_NOT_FOUND'], $hash));
}
}
function bb_captcha ($mode, $callback = '')
{
global $bb_cfg, $lang;
$secret = $bb_cfg['captcha']['secret_key'];
$public = $bb_cfg['captcha']['public_key'];
$theme = isset($bb_cfg['captcha']['theme']) ? $bb_cfg['captcha']['theme'] : 'light';
if (!$bb_cfg['captcha']['disabled'] && (!$public || !$secret))
{
bb_die($lang['CAPTCHA_SETTINGS']);
}
require_once(CLASS_DIR .'recaptcha.php');
$reCaptcha = new ReCaptcha($secret);
switch ($mode)
{
case 'get':
return "
";
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;
}