Перенос файлов движка в корень

This commit is contained in:
Exile 2014-10-28 21:35:42 +03:00
commit f94c0dd2ee
585 changed files with 14 additions and 14 deletions

View file

@ -0,0 +1,2 @@
order allow,deny
deny from all

File diff suppressed because it is too large Load diff

962
library/includes/bbcode.php Normal file
View file

@ -0,0 +1,962 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$datastore->enqueue(array(
'smile_replacements',
));
$page_cfg['include_bbcode_js'] = true;
//
// BBCode templates
//
function get_bbcode_tpl ()
{
$bbcode_tpl = array();
// Quote
$bbcode_tpl['quote_open'] = <<<HTML
<div class="q-wrap">
<div class="q">
HTML;
$bbcode_tpl['quote_username_open'] = <<<HTML
<div class="q-wrap">
<div class="q" head="\\1">
HTML;
$bbcode_tpl['quote_close'] = <<<HTML
</div>
</div>
HTML;
// Code
$bbcode_tpl['code_open'] = <<<HTML
<div class="c-wrap">
<div class="c-body">
HTML;
$bbcode_tpl['code_close'] = <<<HTML
</div>
</div>
HTML;
// Spoiler
$bbcode_tpl['spoiler_open'] = <<<HTML
<div class="sp-wrap">
<div class="sp-body">
HTML;
$bbcode_tpl['spoiler_title_open'] = <<<HTML
<div class="sp-wrap">
<div class="sp-body" title="\\1">
<h3 class="sp-title">\\1</h3>
HTML;
$bbcode_tpl['spoiler_close'] = <<<HTML
</div>
</div>
HTML;
// Image
$bbcode_tpl['img'] = <<<HTML
<var class="postImg" title="$1">&#10;</var>
HTML;
$bbcode_tpl['img_aligned'] = <<<HTML
<var class="postImg postImgAligned img-\\1" title="\\2">&#10;</var>
HTML;
// HR
$bbcode_tpl['hr'] = <<<HTML
<span class="post-hr">-</span>
HTML;
array_deep($bbcode_tpl, 'bbcode_tpl_compact');
return $bbcode_tpl;
}
function bbcode_tpl_compact ($text)
{
$text = str_compact($text);
$text = str_replace('> <', '><', $text);
return $text;
}
// prepare a posted message for entry into the database
function prepare_message ($message)
{
$message = bbcode::clean_up($message);
$message = htmlCHR($message, false, ENT_NOQUOTES);
return $message;
}
// Fill smiley templates (or just the variables) with smileys
// Either in a window or inline
function generate_smilies($mode)
{
global $bb_cfg, $template, $lang, $user, $datastore;
$inline_columns = 4;
$inline_rows = 7;
$window_columns = 8;
if ($mode == 'window')
{
$user->session_start();
}
$data = $datastore->get('smile_replacements');
if ($sql = $data['smile'])
{
$num_smilies = 0;
$rowset = array();
foreach ($sql as $row)
{
if (empty($rowset[$row['smile_url']]))
{
$rowset[$row['smile_url']]['code'] = addslashes($row['code']);
$rowset[$row['smile_url']]['emoticon'] = $row['emoticon'];
$num_smilies++;
}
}
if ($num_smilies)
{
$smilies_count = ($mode == 'inline') ? min(19, $num_smilies) : $num_smilies;
$smilies_split_row = ($mode == 'inline') ? $inline_columns - 1 : $window_columns - 1;
$s_colspan = 0;
$row = 0;
$col = 0;
while (list($smile_url, $data) = @each($rowset))
{
if (!$col)
{
$template->assign_block_vars('smilies_row', array());
}
$template->assign_block_vars('smilies_row.smilies_col', array(
'SMILEY_CODE' => $data['code'],
'SMILEY_IMG' => $bb_cfg['smilies_path'] . '/' . $smile_url,
'SMILEY_DESC' => $data['emoticon'],
));
$s_colspan = max($s_colspan, $col + 1);
if ($col == $smilies_split_row)
{
if ($mode == 'inline' && $row == $inline_rows - 1)
{
break;
}
$col = 0;
$row++;
}
else
{
$col++;
}
}
if ($mode == 'inline' && $num_smilies > $inline_rows * $inline_columns)
{
$template->assign_block_vars('switch_smilies_extra', array());
$template->assign_vars(array(
'U_MORE_SMILIES' => POSTING_URL ."?mode=smilies",
));
}
$template->assign_vars(array(
'PAGE_TITLE' => $lang['EMOTICONS'],
'S_SMILIES_COLSPAN' => $s_colspan,
));
}
}
if ($mode == 'window')
{
print_page('posting_smilies.tpl', 'simple');
}
}
// some functions from vB
// #############################################################################
/**
* Strips away [quote] tags and their contents from the specified string
*
* @param string Text to be stripped of quote tags
*
* @return string
*/
function strip_quotes ($text)
{
$lowertext = strtolower($text);
// find all [quote tags
$start_pos = array();
$curpos = 0;
do
{
$pos = strpos($lowertext, '[quote', $curpos);
if ($pos !== false)
{
$start_pos["$pos"] = 'start';
$curpos = $pos + 6;
}
}
while ($pos !== false);
if (sizeof($start_pos) == 0)
{
return $text;
}
// find all [/quote] tags
$end_pos = array();
$curpos = 0;
do
{
$pos = strpos($lowertext, '[/quote', $curpos);
if ($pos !== false)
{
$end_pos["$pos"] = 'end';
$curpos = $pos + 8;
}
}
while ($pos !== false);
if (sizeof($end_pos) == 0)
{
return $text;
}
// merge them together and sort based on position in string
$pos_list = $start_pos + $end_pos;
ksort($pos_list);
do
{
// build a stack that represents when a quote tag is opened
// and add non-quote text to the new string
$stack = array();
$newtext = '[...] ';
$substr_pos = 0;
foreach ($pos_list AS $pos => $type)
{
$stacksize = sizeof($stack);
if ($type == 'start')
{
// empty stack, so add from the last close tag or the beginning of the string
if ($stacksize == 0)
{
$newtext .= substr($text, $substr_pos, $pos - $substr_pos);
}
array_push($stack, $pos);
}
else
{
// pop off the latest opened tag
if ($stacksize)
{
array_pop($stack);
$substr_pos = $pos + 8;
}
}
}
// add any trailing text
$newtext .= substr($text, $substr_pos);
// check to see if there's a stack remaining, remove those points
// as key points, and repeat. Allows emulation of a non-greedy-type
// recursion.
if ($stack)
{
foreach ($stack AS $pos)
{
unset($pos_list["$pos"]);
}
}
}
while ($stack);
return $newtext;
}
// #############################################################################
/**
* Strips away bbcode from a given string, leaving plain text
*
* @param string Text to be stripped of bbcode tags
* @param boolean If true, strip away quote tags AND their contents
* @param boolean If true, use the fast-and-dirty method rather than the shiny and nice method
*
* @return string
*/
function strip_bbcode ($message, $stripquotes = true, $fast_and_dirty = false, $showlinks = true)
{
$find = array();
$replace = array();
if ($stripquotes)
{
// [quote=username] and [quote]
$message = strip_quotes($message);
}
// a really quick and rather nasty way of removing bbcode
if ($fast_and_dirty)
{
// any old thing in square brackets
$find[] = '#\[.*/?\]#siU';
$replace = '';
$message = preg_replace($find, $replace, $message);
}
// the preferable way to remove bbcode
else
{
// simple links
$find[] = '#\[(email|url)=("??)(.+)\\2\]\\3\[/\\1\]#siU';
$replace[] = '\3';
// named links
$find[] = '#\[(email|url)=("??)(.+)\\2\](.+)\[/\\1\]#siU';
$replace[] = ($showlinks ? '\4 (\3)' : '\4');
// smilies
$find[] = '#(?<=^|\W)(:\w+?:)(?=$|\W)#';
$replace[] = '';
// replace
$message = preg_replace($find, $replace, $message);
// strip out all other instances of [x]...[/x]
while (preg_match('#\[([a-z]+)\s*?(?:[^\]]*?)\](.*?)(\[/\1\])#is', $message, $m))
{
$message = str_replace($m[0], $m[2], $message);
}
$replace = array('[*]', '[hr]', '[br]', '[align=center]', '[align=left]', '[align=right]');
$message = str_replace($replace, ' ', $message);
}
return $message;
}
function extract_search_words ($text)
{
global $bb_cfg;
$max_words_count = $bb_cfg['max_search_words_per_post'];
$min_word_len = max(2, $bb_cfg['search_min_word_len'] - 1);
$max_word_len = $bb_cfg['search_max_word_len'];
$text = ' ' . str_compact(strip_tags(mb_strtolower($text))) . ' ';
$text = str_replace(array('&#91;', '&#93;'), array('[', ']'), $text);
// HTML entities like &nbsp;
$text = preg_replace('/(\w*?)&#?[0-9a-z]+;(\w*?)/iu', '', $text);
// Remove URL's ((www|ftp)\.[\w\#!$%&~/.\-;:=,?@а-яА-Я\[\]+]*?)
$text = preg_replace('#\b[a-z0-9]+://[\w\#!$%&~/.\-;:=,?@а-яА-Я\[\]+]+(/[0-9a-z\?\.%_\-\+=&/]+)?#u', ' ', $text);
$text = str_replace('[url=', ' ', $text);
$text = str_replace('?', ' ', $text);
$text = str_replace('!', ' ', $text);
$text = strip_bbcode($text);
// Filter out characters like ^, $, &, change "it's" to "its"
$text = preg_replace('#[.,:;]#u', ' ', $text);
// short & long words
// $text = preg_replace('#(?<=^|\s)(\S{1,'.$min_word_len.'}|\S{'.$max_word_len.',}|\W*)(?=$|\s)#u', ' ', $text);
$text = remove_stopwords($text);
# $text = replace_synonyms($text);
// Trim 1+ spaces to one space and split this string into unique words
$text = array_unique(explode(' ', str_compact($text)));
// short & long words 2
$text_out = array();
foreach ($text as $word)
{
if (mb_strlen($word) > $min_word_len && mb_strlen($word) <= $max_word_len) $text_out[] = $word;
}
$text = $text_out;
if (sizeof($text) > $max_words_count)
{
# shuffle($text);
$text = array_splice($text, 0, $max_words_count);
}
return $text;
}
function replace_synonyms ($text)
{
static $syn_match = null, $syn_replace = null;
if (is_null($syn_match))
{
preg_match_all("#(\w+) (\w+)(\r?\n|$)#", @file_get_contents(LANG_DIR .'search_synonyms.txt'), $m);
$syn_match = $m[2];
$syn_replace = $m[1];
array_deep($syn_match, 'pad_with_space');
array_deep($syn_replace, 'pad_with_space');
}
return ($syn_match && $syn_replace) ? str_replace($syn_match, $syn_replace, $text) : $text;
}
function add_search_words ($post_id, $post_message, $topic_title = '', $only_return_words = false)
{
global $bb_cfg;
$text = $topic_title .' '. $post_message;
$words = ($text) ? extract_search_words($text) : array();
if ($only_return_words || $bb_cfg['search_engine_type'] == 'sphinx')
{
return join("\n", $words);
}
else
{
DB()->query("DELETE FROM ". BB_POSTS_SEARCH ." WHERE post_id = $post_id");
if ($words_sql = DB()->escape(join("\n", $words)))
{
DB()->query("REPLACE INTO ". BB_POSTS_SEARCH ." (post_id, search_words) VALUES ($post_id, '$words_sql')");
}
}
}
class bbcode
{
var $tpl = array(); // шаблоны для замены тегов
var $smilies = null; // смайлы
var $found_spam = null; // найденные спам "слова"
var $del_words = array(); // см. get_words_rate()
var $tidy_cfg = array(
'drop-empty-paras' => false,
'fix-uri' => false,
'force-output' => true,
'hide-comments' => true,
'join-classes' => false,
'join-styles' => false,
'merge-divs' => false,
'merge-spans' => false,
'newline' => 'LF',
'output-xhtml' => true,
'preserve-entities' => true,
'quiet' => true,
'quote-ampersand' => false,
'show-body-only' => true,
'show-errors' => false,
'show-warnings' => false,
'wrap' => 0,
);
var $block_tags = array(
'align',
'br',
'clear',
'hr',
'list',
'pre',
'quote',
'spoiler',
);
var $preg = array();
var $str = array();
var $preg_search = array();
var $preg_repl = array();
var $str_search = array();
var $str_repl = array();
/**
* Constructor
*/
function bbcode ()
{
$this->tpl = get_bbcode_tpl();
$this->init_replacements();
}
/**
* init_replacements
*/
function init_replacements ()
{
$tpl = $this->tpl;
$img_exp = '(https?:)?//[^\s\?&;=\#\"<>]+?\.(jpg|jpeg|gif|png)([a-z0-9/?&%;][^\[\]]*)?';
$email_exp = '[a-z0-9&\-_.]+?@[\w\-]+\.([\w\-\.]+\.)?[\w]+';
$this->preg = array(
'#\[quote="(.+?)"\]#isu' => $tpl['quote_username_open'],
'#\[spoiler="(.+?)"\]#isu' => $tpl['spoiler_title_open'],
'#\[list=(a|A|i|I|1)\]#isu' => '<ul type="$1">',
'#\[\*=(\d+)\]#isu' => '<li value="$1">',
'#\[pre\](.*?)\[/pre\]#isu' => '<pre class="post-pre">$1</pre>',
'#\[name=([a-zA-Z0-9_]+?)\]#isu' => '<a name="$1"></a>',
'#\[url=\#([a-zA-Z0-9_]+?)\](.*?)\[/url\]#isu' => '<a class="postLink-name" href="#$1">$2</a>',
'#\[color=([\#0-9a-zA-Z]+)\]#isu' => '<span style="color: $1;">',
'#\[size=([1-2]?[0-9])\]#isu' => '<span style="font-size: $1px; line-height: normal;">',
'#\[align=(left|right|center|justify)\]#isu' => '<span class="post-align" style="text-align: $1;">',
'#\[font="([\w\- \']+)"\]#isu' => '<span style="font-family: $1;">',
"#\[img\]($img_exp)\[/img\]#isu" => $tpl['img'],
"#\[img=(left|right|center)\]($img_exp)\[/img\]\s*#isu" => $tpl['img_aligned'],
"#\[email\]($email_exp)\[/email\]#isu" => '<a href="mailto:$1">$1</a>',
"#\[qpost=([0-9]*)\]#isu" => '<u class="q-post">$1</u>',
);
$this->str = array(
'[quote]' => $tpl['quote_open'],
'[/quote]' => $tpl['quote_close'],
'[spoiler]' => $tpl['spoiler_open'],
'[/spoiler]' => $tpl['spoiler_close'],
'[list]' => '<ul>',
'[*]' => '<li>',
'[/list]' => '</ul>',
'[/color]' => '</span>',
'[/size]' => '</span>',
'[/align]' => '</span>',
'[/font]' => '</span>',
'[tab]' => '&nbsp;&nbsp;&nbsp;&nbsp;',
'[br]' => "\n\n",
'[hr]' => $tpl['hr'],
'[b]' => '<span class="post-b">',
'[/b]' => '</span>',
'[u]' => '<span class="post-u">',
'[/u]' => '</span>',
'[i]' => '<span class="post-i">',
'[/i]' => '</span>',
'[s]' => '<span class="post-s">',
'[/s]' => '</span>',
'[del]' => '<span class="post-s">',
'[/del]' => '</span>',
'[clear]' => '<div class="clear">&nbsp;</div>',
);
$this->preg_search = array_keys($this->preg);
$this->preg_repl = array_values($this->preg);
$this->str_search = array_keys($this->str);
$this->str_repl = array_values($this->str);
}
/**
* bbcode2html
* $text должен быть уже обработан htmlCHR($text, false, ENT_NOQUOTES);
*/
function bbcode2html ($text)
{
global $bb_cfg;
$text = " $text ";
$text = $this->clean_up($text);
$text = $this->spam_filter($text);
// Tag parse
if (strpos($text, '[') !== false)
{
// [code]
$text = preg_replace_callback('#(\s*)\[code\](.+?)\[/code\](\s*)#s', array(&$this, 'code_callback'), $text);
// Escape tags inside tiltes in [quote="tilte"]
$text = preg_replace_callback('#(\[(quote|spoiler)=")(.+?)("\])#', array(&$this, 'escape_tiltes_callback'), $text);
// [url]
$url_exp = '[\w\#!$%&~/.\-;:=,?@а-яА-Я()\[\]+]+?';
$text = preg_replace_callback("#\[url\]((?:https?://)?$url_exp)\[/url\]#isu", array(&$this, 'url_callback'), $text);
$text = preg_replace_callback("#\[url\](www\.$url_exp)\[/url\]#isu", array(&$this, 'url_callback'), $text);
$text = preg_replace_callback("#\[url=((?:https?://)?$url_exp)\]([^?\n\t].*?)\[/url\]#isu", array(&$this, 'url_callback'), $text);
$text = preg_replace_callback("#\[url=(www\.$url_exp)\]([^?\n\t].*?)\[/url\]#isu", array(&$this, 'url_callback'), $text);
// Normalize block level tags wrapped with new lines
$block_tags = join('|', $this->block_tags);
$text = str_replace("\n\n[hr]\n\n", '[br][hr][br]', $text);
$text = preg_replace("#(\s*)(\[/?($block_tags)(.*?)\])(\s*)#", '$2', $text);
// Tag replacements
$text = preg_replace($this->preg_search, $this->preg_repl, $text);
$text = str_replace($this->str_search, $this->str_repl, $text);
}
$text = $this->make_clickable($text);
$text = $this->smilies_pass($text);
$text = $this->new_line2html($text);
$text = trim($text);
if ($bb_cfg['tidy_post'])
{
$text = $this->tidy($text);
}
return trim($text);
}
/**
* Clean up
*/
static function clean_up ($text)
{
$text = trim($text);
$text = str_replace("\r", '', $text);
$text = preg_replace('#[ \t]+$#m', '', $text); // trailing spaces
$text = preg_replace('#\n{3,}#', "\n\n", $text);
return $text;
}
/**
* Spam filter
*/
private function spam_filter ($text)
{
global $bb_cfg;
static $spam_words = null;
static $spam_replace = ' СПАМ';
if (isset($this))
{
$found_spam =& $this->found_spam;
}
// set $spam_words and $spam_replace
if (!$bb_cfg['spam_filter_file_path'])
{
return $text;
}
if (is_null($spam_words))
{
$spam_words = file_get_contents($bb_cfg['spam_filter_file_path']);
$spam_words = strtolower($spam_words);
$spam_words = explode("\n", $spam_words);
}
$found_spam = array();
$tm_start = utime();
$msg_decoded = $text;
$msg_decoded = html_entity_decode($msg_decoded);
$msg_decoded = urldecode($msg_decoded);
$msg_decoded = str_replace('&', ' &', $msg_decoded);
$msg_search = strtolower($msg_decoded);
foreach ($spam_words as $spam_str)
{
if (!$spam_str = trim($spam_str))
{
continue;
}
if (strpos($msg_search, $spam_str) !== false)
{
$found_spam[] = $spam_str;
}
}
if ($found_spam)
{
$spam_exp = array();
foreach ($found_spam as $keyword)
{
$spam_exp[] = preg_quote($keyword, '/');
}
$spam_exp = join('|', $spam_exp);
$text = preg_replace("/($spam_exp)(\S*)/i", $spam_replace, $msg_decoded);
$text = htmlCHR($text, false, ENT_NOQUOTES);
# bb_log(date("H:i:s") ." | ". sprintf('%.4f', (utime() - $tm_start)) ." | ". sprintf('%-6s', strlen($text)) ." | ". join(' ** ', $found_spam) ."\n", 'spam_filter');
}
return $text;
}
/**
* [code] callback
*/
function code_callback ($m)
{
$code = trim($m[2]);
$code = str_replace(' ', '&nbsp; ', $code);
$code = str_replace(' ', ' &nbsp;', $code);
$code = str_replace("\t", '&nbsp; ', $code);
$code = str_replace(array('[', ']', ':', ')'), array('&#91;', '&#93;', '&#58;', '&#41;'), $code);
return $this->tpl['code_open'] . $code . $this->tpl['code_close'];
}
/**
* [url] callback
*/
function url_callback ($m)
{
global $bb_cfg;
$url = trim($m[1]);
$url_name = (isset($m[2])) ? trim($m[2]) : $url;
if (!preg_match("#^https?://#isu", $url) && !preg_match("/^#/", $url)) $url = 'http://' . $url;
if (in_array(parse_url($url, PHP_URL_HOST), $bb_cfg['nofollow']['allowed_url']) || $bb_cfg['nofollow']['disabled'])
{
$link = "<a href=\"$url\" class=\"postLink\">$url_name</a>";
}
else
{
$link = "<a href=\"$url\" class=\"postLink\" rel=\"nofollow\">$url_name</a>";
}
return $link;
}
/**
* Escape tags inside tiltes in [quote="tilte"]
*/
function escape_tiltes_callback ($m)
{
$tilte = substr($m[3], 0, 250);
$tilte = str_replace(array('[', ']', ':', ')', '"'), array('&#91;', '&#93;', '&#58;', '&#41;', '&#34;'), $tilte);
// еще раз htmlspecialchars, т.к. при извлечении из title происходит обратное преобразование
$tilte = htmlspecialchars($tilte, ENT_QUOTES);
return $m[1] . $tilte . $m[4];
}
/**
* make_clickable
*/
function make_clickable ($text)
{
$url_regexp = "#
(?<![\"'=])
\b
(
https?://[\w\#!$%&~/.\-;:=?@а-яА-Я()\[\]+]+
)
(?![\"']|\[/url|\[/img|</a)
(?=[,!]?\s|[\)<!])
#xiu";
// pad it with a space so we can match things at the start of the 1st line.
$ret = " $text ";
// hide passkey
$ret = hide_passkey($ret);
// matches an "xxxx://yyyy" URL at the start of a line, or after a space.
$ret = preg_replace_callback($url_regexp, array(&$this, 'make_url_clickable_callback'), $ret);
// Remove our padding..
$ret = substr(substr($ret, 0, -1), 1);
return($ret);
}
/**
* make_url_clickable_callback
*/
function make_url_clickable_callback ($m)
{
global $bb_cfg;
$max_len = 70;
$href = $m[1];
$name = (mb_strlen($href, 'UTF-8') > $max_len) ? mb_substr($href, 0, $max_len - 19) .'...'. mb_substr($href, -16) : $href;
if (in_array(parse_url($href, PHP_URL_HOST), $bb_cfg['nofollow']['allowed_url']) || $bb_cfg['nofollow']['disabled'])
{
$link = "<a href=\"$href\" class=\"postLink\">$name</a>";
}
else
{
$link = "<a href=\"$href\" class=\"postLink\" rel=\"nofollow\">$name</a>";
}
return $link;
}
/**
* smilies_pass
*/
function smilies_pass ($text)
{
global $datastore;
if (is_null($this->smilies))
{
$this->smilies = $datastore->get('smile_replacements');
}
if ($this->smilies)
{
$parsed_text = preg_replace($this->smilies['orig'], $this->smilies['repl'], $text, 101, $smilies_cnt);
$text = ($smilies_cnt <= 100) ? $parsed_text : $text;
}
return $text;
}
/**
* new_line2html
*/
function new_line2html ($text)
{
$text = preg_replace('#\n{2,}#', '<span class="post-br"><br /></span>', $text);
$text = str_replace("\n", '<br />', $text);
return $text;
}
/**
* tidy
*/
function tidy ($text)
{
$text = tidy_repair_string($text, $this->tidy_cfg, 'utf8');
return $text;
}
}
function bbcode2html ($text)
{
global $bbcode;
if (!isset($bbcode))
{
$bbcode = new bbcode();
}
$orig_word = array();
$replacement_word = array();
obtain_word_list($orig_word, $replacement_word);
if ( count($orig_word) )
{
$text = preg_replace($orig_word, $replacement_word, $text);
}
return $bbcode->bbcode2html($text);
}
class words_rate
{
var $dbg_mode = false;
var $words_rate = 0;
var $deleted_words = array();
var $del_text_hl = '';
var $words_del_exp = '';
var $words_cnt_exp = '#[a-zA-Zа-яА-ЯёЁ]{4,}#';
function words_rate ()
{
// слова начинающиеся на..
$del_list = file_get_contents(BB_ROOT .'/library/words_rate_del_list.txt');
$del_list = str_compact($del_list);
$del_list = str_replace(' ', '|', preg_quote($del_list, '/'));
$del_exp = '/\b('.$del_list.')[\w\-]*/i';
$this->words_del_exp = $del_exp;
}
/**
* возвращает "показатель полезности" сообщения используемый для автоудаления коротких сообщений типа "спасибо", "круто" и т.д.
*/
function get_words_rate ($text)
{
$this->words_rate = 127; // максимальное значение по умолчанию
$this->deleted_words = array();
$this->del_text_hl = $text;
// длинное сообщение
if (strlen($text) > 600)
{
return $this->words_rate;
}
// вырезаем цитаты если содержит +1
if (preg_match('#\+\d+#', $text))
{
$text = strip_quotes($text);
}
// содержит ссылку
if (strpos($text, '://'))
{
return $this->words_rate;
}
// вопрос
if ($questions = preg_match_all('#\w\?+#', $text, $m))
{
if ($questions >= 1)
{
return $this->words_rate;
}
}
if ($this->dbg_mode)
{
preg_match_all($this->words_del_exp, $text, $this->deleted_words);
$text_dbg = preg_replace($this->words_del_exp, '<span class="del-word">$0</span>', $text);
$this->del_text_hl = '<div class="prune-post">'. $text_dbg . '</div>';
}
$text = preg_replace($this->words_del_exp, '', $text);
// удаление смайлов
$text = preg_replace('#:\w+:#', '', $text);
// удаление bbcode тегов
$text = preg_replace('#\[\S+\]#', '', $text);
$words_count = preg_match_all($this->words_cnt_exp, $text, $m);
if ($words_count !== false && $words_count < 127)
{
$this->words_rate = ($words_count == 0) ? 1 : $words_count;
}
return $this->words_rate;
}
}
function get_words_rate ($text)
{
static $wr = null;
if (!isset($wr))
{
$wr = new words_rate();
}
return $wr->get_words_rate($text);
}
function hide_passkey ($str)
{
global $bb_cfg;
return preg_replace("#\?{$bb_cfg['passkey_key']}=[a-zA-Z0-9]{". BT_AUTH_KEY_LENGTH ."}#", "?{$bb_cfg['passkey_key']}=passkey", $str);
}
function get_parsed_post ($postrow, $mode = 'full', $return_chars = 600)
{
global $bb_cfg;
if ($bb_cfg['use_posts_cache'] && !empty($postrow['post_html']))
{
return $postrow['post_html'];
}
$message = bbcode2html($postrow['post_text']);
// Posts cache
if ($bb_cfg['use_posts_cache'])
{
DB()->shutdown['post_html'][] = array(
'post_id' => (int) $postrow['post_id'],
'post_html' => (string) $message,
);
}
return $message;
}
function update_post_html ($postrow)
{
DB()->query("DELETE FROM ". BB_POSTS_HTML ." WHERE post_id = ". (int) $postrow['post_id'] ." LIMIT 1");
}

View file

@ -0,0 +1,2 @@
order allow,deny
deny from all

View file

@ -0,0 +1,396 @@
<?php
/**
* Captcha
*/
class captcha_common
{
var $cfg = array(); // конфиг
var $can_bypass = false; // может обойти капчу
var $cap_img_total = 300; // количество текущих картинок
var $new_per_minute = 10; // сколько генерить новых, столько же будет помечаться для удаления
var $key_ttl = 300; // время жизни _code_ ключа
var $cap_sid_len = 20; // длина sid'a
var $cap_min_chars = 3; // минимум символов на картинке
var $cap_max_chars = 5; // максимум
var $img_ext = 'jpg';
var $cap_sid_key = 'cap_sid'; // ключи/значения в $_POST
var $cap_sid_val = '';
var $curr_code_key = '';
var $prev_code_key = '';
var $new_cap_id = 0;
var $new_cap_sid = '';
var $new_code_key = '';
var $new_cap_code = '';
var $new_img_url = '';
var $new_img_path = '';
var $new_img_bin = '';
function captcha_common ($cfg)
{
$this->cfg = $cfg;
$this->can_bypass = !empty($_POST[$this->cfg['secret_key']]);
$this->curr_code_key = $this->get_key_name(TIMENOW);
$this->prev_code_key = $this->get_key_name(TIMENOW - $this->key_ttl);
}
function verify_code ()
{
// обход
if ($this->can_bypass || $this->cfg['disabled'])
{
if (!empty($_POST[$this->cfg['secret_key']])) log_get('cap/off', @$_POST['login_username']);
return true;
}
// cap_sid
if (isset($_POST[$this->cap_sid_key]) && verify_id($_POST[$this->cap_sid_key], $this->cap_sid_len))
{
$this->cap_sid_val = $_POST[$this->cap_sid_key];
}
else
{
return false;
}
// code
$entered_code = '';
if (isset($_POST[$this->curr_code_key]))
{
$entered_code = (string) $_POST[$this->curr_code_key];
}
else if (isset($_POST[$this->prev_code_key]))
{
$entered_code = (string) $_POST[$this->prev_code_key];
}
$entered_code = strtolower(trim($entered_code));
$valid_code = $this->get_code();
if ($entered_code === $valid_code)
{
$this->del_sid();
return true;
}
else
{
$this->del_sid();
return false;
}
}
function get_html ()
{
if ($this->cfg['disabled']) return '';
$this->gen_cap_sid();
$this->new_img_url = $this->get_img_url($this->new_cap_id);
$this->new_code_key = $this->get_key_name(TIMENOW);
return '
<div><img src="'. $this->new_img_url .'?'. mt_rand() .'" width="120" height="72" alt="pic" /></div>
<input type="hidden" name="'. $this->cap_sid_key .'" value="'. $this->new_cap_sid .'" />
<input type="text" name="'. $this->new_code_key .'" value="" size="25" class="bold" />
';
}
function get_code ()
{
if ($this->cap_sid_val AND $code = CACHE('bb_cap_sid')->get('c_sid_'. $this->cap_sid_val))
{
return strtolower(trim($code));
}
else
{
return null;
}
}
function del_sid ()
{
if ($this->cap_sid_val)
{
CACHE('bb_cap_sid')->rm('c_sid_'. $this->cap_sid_val);
}
}
function gen_cap_sid ()
{
$row = DB('cap')->fetch_row("SELECT MIN(cap_id) AS min_id, MAX(cap_id) AS max_id FROM ". BB_CAPTCHA ." WHERE cap_id > 0");
$min_id = intval($row['min_id']) + $this->new_per_minute;
$max_id = intval($row['max_id']);
$this->new_cap_id = ($min_id < $max_id) ? mt_rand($min_id, $max_id) : $max_id;
$this->new_cap_code = (string) DB('cap')->fetch_row("SELECT cap_code FROM ". BB_CAPTCHA ." WHERE cap_id = {$this->new_cap_id}", 'cap_code');
$this->new_cap_sid = make_rand_str($this->cap_sid_len);
CACHE('bb_cap_sid')->set('c_sid_'. $this->new_cap_sid, $this->new_cap_code, $this->key_ttl*2);
}
function get_img_url ($id)
{
return $this->get_path($id, $this->cfg['img_url']);
}
function get_img_path ($id)
{
return $this->get_path($id, $this->cfg['img_path']);
}
function get_path ($id, $base)
{
$path = $base . ($id % 50) .'/'. $id .'.'. $this->img_ext;
return preg_replace("#/($id)(\.{$this->img_ext})\$#", '/'. md5($this->cfg['secret_key'] . md5($id)) .'$2', $path);
}
/**
* Генерит валидное имя ключа для получения введенного кода капчи из $_POST
*/
function get_key_name ($tm)
{
return 'cap_code_'. md5($this->cfg['secret_key'] . md5($tm - ($tm % $this->key_ttl)));
}
}
class captcha_kcaptcha extends captcha_common
{
// generates keystring and image
function gen_img ($cap_id)
{
global $bb_cfg;
// do not change without changing font files!
$alphabet = "0123456789abcdefghijklmnopqrstuvwxyz";
# symbols used to draw CAPTCHA - alphabet without similar symbols (o=0, 1=l, i=j, t=f)
$allowed_symbols = "23456789abcdeghkmnpqsuvxyz";
# folder with fonts
$fontsdir = INC_DIR .'captcha/kcaptcha/fonts/';
$fonts = array(
'antiqua.png',
'baskerville.png',
'batang.png',
'bookman.png',
'calisto.png',
'cambria.png',
'centaur.png',
'century.png',
'chaparral.png',
'constantia.png',
'footlight.png',
'garamond.png',
'georgia.png',
'goudy_old.png',
'kozuka.png',
'lucida.png',
'minion.png',
'palatino.png',
'perpetua.png',
'rockwell.png',
'times.png',
'warnock.png',
);
# CAPTCHA string length
$length = mt_rand($this->cap_min_chars, $this->cap_max_chars);
# CAPTCHA image size (you do not need to change it, whis parameters is optimal)
$width = 120;
$height = 60;
# symbol's vertical fluctuation amplitude divided by 2
$fluctuation_amplitude = 5;
# increase safety by prevention of spaces between symbols
$no_spaces = true;
# show credits
$show_credits = true; # set to false to remove credits line. Credits adds 12 pixels to image height
$credits = $bb_cfg['server_name']; # if empty, HTTP_HOST will be shown
# CAPTCHA image colors (RGB, 0-255)
$foreground_color = array(mt_rand(0,100), mt_rand(0,100), mt_rand(0,100));
$background_color = array(mt_rand(200,255), mt_rand(200,255), mt_rand(200,255));
# JPEG quality of CAPTCHA image (bigger is better quality, but larger file size)
$jpeg_quality = 90;
$alphabet_length=strlen($alphabet);
do{
// generating random keystring
while(true){
$this->keystring='';
for($i=0;$i<$length;$i++){
$this->keystring.=$allowed_symbols[mt_rand(0,strlen($allowed_symbols)-1)];
}
if(!preg_match('/cp|cb|ck|c6|c9|rn|rm|mm|co|do|cl|db|qp|qb|dp|ww/', $this->keystring)) break;
}
$font_file = $fontsdir . $fonts[mt_rand(0, count($fonts)-1)];
$font=imagecreatefrompng($font_file);
imagealphablending($font, true);
$fontfile_width=imagesx($font);
$fontfile_height=imagesy($font)-1;
$font_metrics=array();
$symbol=0;
$reading_symbol=false;
// loading font
for($i=0;$i<$fontfile_width && $symbol<$alphabet_length;$i++){
$transparent = (imagecolorat($font, $i, 0) >> 24) == 127;
if(!$reading_symbol && !$transparent){
$font_metrics[$alphabet[$symbol]]=array('start'=>$i);
$reading_symbol=true;
continue;
}
if($reading_symbol && $transparent){
$font_metrics[$alphabet[$symbol]]['end']=$i;
$reading_symbol=false;
$symbol++;
continue;
}
}
$img=imagecreatetruecolor($width, $height);
imagealphablending($img, true);
$white=imagecolorallocate($img, 255, 255, 255);
$black=imagecolorallocate($img, 0, 0, 0);
imagefilledrectangle($img, 0, 0, $width-1, $height-1, $white);
// draw text
$x=1;
for($i=0;$i<$length;$i++){
$m=$font_metrics[$this->keystring[$i]];
$y=mt_rand(-$fluctuation_amplitude, $fluctuation_amplitude)+($height-$fontfile_height)/2+2;
if($no_spaces){
$shift=0;
if($i>0){
$shift=10000;
for($sy=7;$sy<$fontfile_height-20;$sy+=1){
for($sx=$m['start']-1;$sx<$m['end'];$sx+=1){
$rgb=imagecolorat($font, $sx, $sy);
$opacity=$rgb>>24;
if($opacity<127){
$left=$sx-$m['start']+$x;
$py=$sy+$y;
if($py>$height) break;
for($px=min($left,$width-1);$px>$left-12 && $px>=0;$px-=1){
$color=imagecolorat($img, $px, $py) & 0xff;
if($color+$opacity<190){
if($shift>$left-$px){
$shift=$left-$px;
}
break;
}
}
break;
}
}
}
if($shift==10000){
$shift=mt_rand(4,6);
}
}
}else{
$shift=1;
}
imagecopy($img, $font, $x-$shift, $y, $m['start'], 1, $m['end']-$m['start'], $fontfile_height);
$x+=$m['end']-$m['start']-$shift;
}
}while($x>=$width-10); // while not fit in canvas
$center=$x/2;
// credits
$img2=imagecreatetruecolor($width, $height+($show_credits?12:0));
$foreground=imagecolorallocate($img2, $foreground_color[0], $foreground_color[1], $foreground_color[2]);
$background=imagecolorallocate($img2, $background_color[0], $background_color[1], $background_color[2]);
imagefilledrectangle($img2, 0, 0, $width-1, $height-1, $background);
imagefilledrectangle($img2, 0, $height, $width-1, $height+12, $foreground);
$credits=empty($credits)?$bb_cfg['server_name']:$credits;
imagestring($img2, 2, $width/2-imagefontwidth(2)*strlen($credits)/2, $height-2, $credits, $background);
// periods
$rand1=mt_rand(750000,1200000)/10000000;
$rand2=mt_rand(750000,1200000)/10000000;
$rand3=mt_rand(750000,1200000)/10000000;
$rand4=mt_rand(750000,1200000)/10000000;
// phases
$rand5=mt_rand(0,31415926)/10000000;
$rand6=mt_rand(0,31415926)/10000000;
$rand7=mt_rand(0,31415926)/10000000;
$rand8=mt_rand(0,31415926)/10000000;
// amplitudes
$rand9=mt_rand(330,420)/110;
$rand10=mt_rand(330,450)/110;
//wave distortion
for($x=0;$x<$width;$x++){
for($y=0;$y<$height;$y++){
$sx=$x+(sin($x*$rand1+$rand5)+sin($y*$rand3+$rand6))*$rand9-$width/2+$center+1;
$sy=$y+(sin($x*$rand2+$rand7)+sin($y*$rand4+$rand8))*$rand10;
if($sx<0 || $sy<0 || $sx>=$width-1 || $sy>=$height-1){
continue;
}else{
$color=imagecolorat($img, $sx, $sy) & 0xFF;
$color_x=imagecolorat($img, $sx+1, $sy) & 0xFF;
$color_y=imagecolorat($img, $sx, $sy+1) & 0xFF;
$color_xy=imagecolorat($img, $sx+1, $sy+1) & 0xFF;
}
if($color==255 && $color_x==255 && $color_y==255 && $color_xy==255){
continue;
}else if($color==0 && $color_x==0 && $color_y==0 && $color_xy==0){
$newred=$foreground_color[0];
$newgreen=$foreground_color[1];
$newblue=$foreground_color[2];
}else{
$frsx=$sx-floor($sx);
$frsy=$sy-floor($sy);
$frsx1=1-$frsx;
$frsy1=1-$frsy;
$newcolor=(
$color*$frsx1*$frsy1+
$color_x*$frsx*$frsy1+
$color_y*$frsx1*$frsy+
$color_xy*$frsx*$frsy);
if($newcolor>255) $newcolor=255;
$newcolor=$newcolor/255;
$newcolor0=1-$newcolor;
$newred=$newcolor0*$foreground_color[0]+$newcolor*$background_color[0];
$newgreen=$newcolor0*$foreground_color[1]+$newcolor*$background_color[1];
$newblue=$newcolor0*$foreground_color[2]+$newcolor*$background_color[2];
}
imagesetpixel($img2, $x, $y, imagecolorallocate($img2, $newred, $newgreen, $newblue));
}
}
$img_path = $this->get_img_path($cap_id);
file_write('', $img_path, null, true, true);
imagejpeg($img2, $img_path, $jpeg_quality);
imagedestroy($img2);
return $this->keystring;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View file

@ -0,0 +1,2 @@
order allow,deny
deny from all

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,244 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
class emailer
{
var $msg, $subject, $extra_headers;
var $addresses, $reply_to, $from;
var $use_smtp;
var $tpl_msg = array();
var $vars = array();
function emailer ($use_smtp/*$tpl_name, $sbj, $to_address*/)
{
global $bb_cfg;
$this->reset();
$this->from = $bb_cfg['board_email'];
$this->reply_to = $bb_cfg['board_email'];
$this->use_smtp = $use_smtp; /*!empty($bb_cfg['smtp_host']);
$this->use_template($tpl_name);
$this->set_subject($sbj);
$this->email_address($to_address);*/
}
function set_default_vars ()
{
global $bb_cfg;
$this->vars = array(
'BOARD_EMAIL' => $bb_cfg['board_email'],
'SITENAME' => $bb_cfg['board_email_sitename'],
'EMAIL_SIG' => !empty($bb_cfg['board_email_sig']) ? "-- \n{$bb_cfg['board_email_sig']}" : '',
);
}
// Resets all the data (address, template file, etc etc to default
function reset ()
{
$this->addresses = array();
$this->msg = $this->extra_headers = '';
$this->set_default_vars();
}
// Sets an email address to send to
function email_address ($address)
{
$this->addresses['to'] = trim($address);
}
function cc ($address)
{
$this->addresses['cc'][] = trim($address);
}
function bcc ($address)
{
$this->addresses['bcc'][] = trim($address);
}
function replyto ($address)
{
$this->reply_to = trim($address);
}
function from ($address)
{
$this->from = trim($address);
}
// set up subject for mail
function set_subject ($subject = '')
{
$this->subject = trim(preg_replace('#[\n\r]+#s', '', $subject));
}
// set up extra mail headers
function extra_headers ($headers)
{
$this->extra_headers .= trim($headers) . "\n";
}
function use_template ($template_file, $template_lang = '')
{
global $bb_cfg;
if (trim($template_file) == '')
{
bb_die('No template file set');
}
if (trim($template_lang) == '')
{
$template_lang = $bb_cfg['default_lang'];
}
if (empty($this->tpl_msg[$template_lang . $template_file]))
{
$tpl_file = LANG_ROOT_DIR ."$template_lang/email/$template_file.tpl";
if (!@file_exists(@bb_realpath($tpl_file)))
{
$tpl_file = LANG_ROOT_DIR ."{$bb_cfg['default_lang']}/email/$template_file.tpl";
if (!@file_exists(@bb_realpath($tpl_file)))
{
bb_die('Could not find email template file :: ' . $template_file);
}
}
if (!($fd = @fopen($tpl_file, 'r')))
{
bb_die('Failed opening template file :: ' . $tpl_file);
}
$this->tpl_msg[$template_lang . $template_file] = fread($fd, filesize($tpl_file));
fclose($fd);
}
$this->msg = $this->tpl_msg[$template_lang . $template_file];
return true;
}
// assign variables
function assign_vars ($vars)
{
$this->vars = array_merge($this->vars, $vars);
}
// Send the mail out to the recipients set previously in var $this->address
function send ($email_format = 'text')
{
global $bb_cfg, $lang;
if ($bb_cfg['emailer_disabled'])
{
return;
}
// Escape all quotes
$this->msg = str_replace ("'", "\'", $this->msg);
$this->msg = preg_replace('#\{([a-z0-9\-_]*?)\}#is', "' . $\\1 . '", $this->msg);
// Set vars
reset ($this->vars);
while (list($key, $val) = each($this->vars))
{
$$key = $val;
}
eval("\$this->msg = '$this->msg';");
// Clear vars
reset ($this->vars);
while (list($key, $val) = each($this->vars))
{
unset($$key);
}
// We now try and pull a subject from the email body ... if it exists,
// do this here because the subject may contain a variable
$drop_header = '';
$match = array();
if (preg_match('#^(Subject:(.*?))$#m', $this->msg, $match))
{
$this->subject = (trim($match[2]) != '') ? trim($match[2]) : (($this->subject != '') ? $this->subject : 'No Subject');
$drop_header .= '[\r\n]*?' . preg_quote($match[1], '#');
}
else
{
$this->subject = (($this->subject != '') ? $this->subject : 'No Subject');
}
if (preg_match('#^(Charset:(.*?))$#m', $this->msg, $match))
{
$this->encoding = (trim($match[2]) != '') ? trim($match[2]) : trim($lang['CONTENT_ENCODING']);
$drop_header .= '[\r\n]*?' . preg_quote($match[1], '#');
}
else
{
$this->encoding = trim($lang['CONTENT_ENCODING']);
}
$this->subject = $this->encode($this->subject);
if ($drop_header != '')
{
$this->msg = trim(preg_replace('#' . $drop_header . '#s', '', $this->msg));
}
$to = @$this->addresses['to'];
$cc = (@count($this->addresses['cc'])) ? implode(', ', $this->addresses['cc']) : '';
$bcc = (@count($this->addresses['bcc'])) ? implode(', ', $this->addresses['bcc']) : '';
// Build header
$type = ($email_format == 'html') ? 'html' : 'plain';
$this->extra_headers = (($this->reply_to != '') ? "Reply-to: $this->reply_to\n" : '') . (($this->from != '') ? "From: $this->from\n" : "From: " . $bb_cfg['board_email'] . "\n") . "Return-Path: " . $bb_cfg['board_email'] . "\nMessage-ID: <" . md5(uniqid(TIMENOW)) . "@" . $bb_cfg['server_name'] . ">\nMIME-Version: 1.0\nContent-type: text/$type; charset=" . $this->encoding . "\nContent-transfer-encoding: 8bit\nDate: " . date('r', TIMENOW) . "\nX-Priority: 0\nX-MSMail-Priority: Normal\nX-Mailer: Microsoft Office Outlook, Build 11.0.5510\nX-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1441\nX-Sender: " . $bb_cfg['board_email'] . "\n" . $this->extra_headers . (($cc != '') ? "Cc: $cc\n" : '') . (($bcc != '') ? "Bcc: $bcc\n" : '');
// Send message
if ($this->use_smtp)
{
if (!defined('SMTP_INCLUDED'))
{
include(INC_DIR .'smtp.php');
}
$result = smtpmail($to, $this->subject, $this->msg, $this->extra_headers);
}
else
{
$to = ($to == '') ? ' ' : $to;
$result = @mail($to, $this->subject, preg_replace("#(?<!\r)\n#s", "\n", $this->msg), $this->extra_headers);
}
// Did it work?
if (!$result)
{
bb_die('Failed sending email :: ' . (($this->use_smtp) ? 'SMTP' : 'PHP') . ' :: ' . $result);
}
return true;
}
function encode ($str)
{
if ($this->encoding == '')
{
return $str;
}
// define start delimimter, end delimiter and spacer
$start = "=?$this->encoding?B?";
$end = "?=";
// encode the string and split it into chunks with spacers after each chunk
$str = base64_encode($str);
return $start . $str . $end;
}
}

View file

@ -0,0 +1,183 @@
<?php
/**
* A class for validating method parameters to allowed types via reflection.
*
* Purpose
* Used as a more convenient multiple assert(), standing after the declaration of the methods.
*
* Features and advantage
* * Very easy to use
* * Ability to turn off on the production server
*
* WARNING
* On a production server, it is important to disable assert, that would save server resources.
* For this, use the assert_options(ASSERT_ACTIVE, false) or INI setting "assert.active 0".
* In this case ReflectionTypeHint::isValid() always returns TRUE!
*
* Useful links
* http://www.ilia.ws/archives/205-Type-hinting-for-PHP-5.3.html
* http://php.net/manual/en/language.oop5.typehinting.php
*
* @example ReflectionTypeHint_example.php
* @link http://code.google.com/p/php5-reflection-type-hint/
* @license http://creativecommons.org/licenses/by-sa/3.0/
* @author Nasibullin Rinat
* @version 1.1.0
*/
class ReflectionTypeHint
{
protected static $hints = array(
'int' => 'is_int',
'integer' => 'is_int',
'digit' => 'ctype_digit',
'number' => 'ctype_digit',
'float' => 'is_float',
'double' => 'is_float',
'real' => 'is_float',
'numeric' => 'is_numeric',
'str' => 'is_string',
'string' => 'is_string',
'char' => 'is_string',
'bool' => 'is_bool',
'boolean' => 'is_bool',
'null' => 'is_null',
'array' => 'is_array',
'obj' => 'is_object',
'object' => 'is_object',
'res' => 'is_resource',
'resource' => 'is_resource',
'scalar' => 'is_scalar', #integer, float, string or boolean
'cb' => 'is_callable',
'callback' => 'is_callable',
);
#calling the methods of this class only statically!
private function __construct() {}
public static function isValid()
{
if (! assert_options(ASSERT_ACTIVE)) return true;
$bt = self::debugBacktrace(null, 1);
extract($bt); //to $file, $line, $function, $class, $object, $type, $args
if (! $args) return true; #speed improve
$r = new ReflectionMethod($class, $function);
$doc = $r->getDocComment();
$cache_id = $class. $type. $function;
preg_match_all('~ [\r\n]++ [\x20\t]++ \* [\x20\t]++
@param
[\x20\t]++
\K #memory reduce
( [_a-z]++[_a-z\d]*+
(?>[|/,][_a-z]+[_a-z\d]*)*+
) #1 types
[\x20\t]++
&?+\$([_a-z]++[_a-z\d]*+) #2 name
~sixSX', $doc, $params, PREG_SET_ORDER);
$parameters = $r->getParameters();
//d($args, $params, $parameters);
if (count($parameters) > count($params))
{
$message = 'phpDoc %d piece(s) @param description expected in %s%s%s(), %s given, ' . PHP_EOL
. 'called in %s on line %d ' . PHP_EOL
. 'and defined in %s on line %d';
$message = sprintf($message, count($parameters), $class, $type, $function, count($params), $file, $line, $r->getFileName(), $r->getStartLine());
trigger_error($message, E_USER_NOTICE);
}
foreach ($args as $i => $value)
{
if (! isset($params[$i])) return true;
if ($parameters[$i]->name !== $params[$i][2])
{
$param_num = $i + 1;
$message = 'phpDoc @param %d in %s%s%s() must be named as $%s, $%s given, ' . PHP_EOL
. 'called in %s on line %d ' . PHP_EOL
. 'and defined in %s on line %d';
$message = sprintf($message, $param_num, $class, $type, $function, $parameters[$i]->name, $params[$i][2], $file, $line, $r->getFileName(), $r->getStartLine());
trigger_error($message, E_USER_NOTICE);
}
$hints = preg_split('~[|/,]~sSX', $params[$i][1]);
if (! self::checkValueTypes($hints, $value))
{
$param_num = $i + 1;
$message = 'Argument %d passed to %s%s%s() must be an %s, %s given, ' . PHP_EOL
. 'called in %s on line %d ' . PHP_EOL
. 'and defined in %s on line %d';
$message = sprintf($message, $param_num, $class, $type, $function, implode('|', $hints), (is_object($value) ? get_class($value) . ' ' : '') . gettype($value), $file, $line, $r->getFileName(), $r->getStartLine());
trigger_error($message, E_USER_WARNING);
return false;
}
}
return true;
}
/**
* Return stacktrace. Correctly work with call_user_func*()
* (totally skip them correcting caller references).
* If $return_frame is present, return only $return_frame matched caller, not all stacktrace.
*
* @param string|null $re_ignore example: '~^' . preg_quote(__CLASS__, '~') . '(?![a-zA-Z\d])~sSX'
* @param int|null $return_frame
* @return array
*/
public static function debugBacktrace($re_ignore = null, $return_frame = null)
{
$trace = debug_backtrace();
$a = array();
$frames = 0;
for ($i = 0, $n = count($trace); $i < $n; $i++)
{
$t = $trace[$i];
if (! $t) continue;
// Next frame.
$next = isset($trace[$i+1])? $trace[$i+1] : null;
// Dummy frame before call_user_func*() frames.
if (! isset($t['file']) && $next)
{
$t['over_function'] = $trace[$i+1]['function'];
$t = $t + $trace[$i+1];
$trace[$i+1] = null; // skip call_user_func on next iteration
}
// Skip myself frame.
if (++$frames < 2) continue;
// 'class' and 'function' field of next frame define where this frame function situated.
// Skip frames for functions situated in ignored places.
if ($re_ignore && $next)
{
// Name of function "inside which" frame was generated.
$frame_caller = (isset($next['class']) ? $next['class'] . $next['type'] : '')
. (isset($next['function']) ? $next['function'] : '');
if (preg_match($re_ignore, $frame_caller)) continue;
}
// On each iteration we consider ability to add PREVIOUS frame to $a stack.
if (count($a) === $return_frame) return $t;
$a[] = $t;
}
return $a;
}
/**
* Checks a value to the allowed types
*
* @param array $types
* @param mixed $value
* @return bool
*/
public static function checkValueTypes(array $types, $value)
{
foreach ($types as $type)
{
$type = strtolower($type);
if (array_key_exists($type, self::$hints) && call_user_func(self::$hints[$type], $value)) return true;
if (is_object($value) && @is_a($value, $type)) return true;
if ($type === 'mixed') return true;
}
return false;
}
}

View file

@ -0,0 +1,216 @@
<?php
class sitemap
{
var $home = '';
var $limit = 0;
var $topic_priority = '0.5';
var $stat_priority = '0.5';
var $priority = '0.6';
var $cat_priority = '0.7';
function sitemap () {
global $bb_cfg;
$this->home = 'http://'.$bb_cfg['server_name'].'/';
}
function build_map () {
$map = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n";
$map .= $this->get_static();
$map .= $this->get_forum();
$map .= $this->get_topic();
$map .= "</urlset>";
return $map;
}
function build_index ($count) {
$lm = date('c');
$map = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n";
$map .= "<sitemap>\n<loc>{$this->home}sitemap/sitemap1.xml</loc>\n<lastmod>{$lm}</lastmod>\n</sitemap>\n";
for ($i = 0; $i < $count; $i++) {
$t = $i + 2;
$map .= "<sitemap>\n<loc>{$this->home}sitemap/sitemap{$t}.xml</loc>\n<lastmod>{$lm}</lastmod>\n</sitemap>\n";
}
$map .= "</sitemapindex>";
return $map;
}
function build_stat () {
$map = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n";
$map .= $this->get_static();
$map .= $this->get_forum();
$map .= "</urlset>";
return $map;
}
function build_map_topic ($n) {
$map = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n";
$map .= $this->get_topic($n);
$map .= "</urlset>";
return $map;
}
function get_forum () {
global $datastore;
$this->priority = $this->cat_priority;
$xml = '';
$lm = date('c');
if (!$forums = $datastore->get('cat_forums')) {
$datastore->update('cat_forums');
$forums = $datastore->get('cat_forums');
}
$not_forums_id = $forums['not_auth_forums']['guest_view'];
$ignore_forum_sql = ($not_forums_id) ? "WHERE forum_id NOT IN($not_forums_id)" : '';
$sql = DB()->sql_query("SELECT forum_id, forum_topics, forum_parent, forum_name FROM " . BB_FORUMS . " " . $ignore_forum_sql . " ORDER BY forum_id ASC");
while ($row = DB()->sql_fetchrow($sql)) {
if (function_exists('seo_url')) $loc = $this->home . seo_url(FORUM_URL . $row['forum_id'], $row['forum_name']);
else $loc = $this->home . FORUM_URL . $row['forum_id'];
$xml .= $this->get_xml($loc, $lm);
}
return $xml;
}
function get_topic ($page = false) {
global $datastore;
$xml = '';
$this->priority = $this->topic_priority;
if ($page) {
$page = $page - 1;
$page = $page * 40000;
$this->limit = " LIMIT {$page},40000";
} else {
if ($this->limit < 1) $this->limit = false;
if ($this->limit) {
$this->limit = " LIMIT 0," . $this->limit;
} else {
$this->limit = '';
}
}
if (!$forums = $datastore->get('cat_forums')) {
$datastore->update('cat_forums');
$forums = $datastore->get('cat_forums');
}
$not_forums_id = $forums['not_auth_forums']['guest_view'];
$ignore_forum_sql = ($not_forums_id) ? "WHERE forum_id NOT IN($not_forums_id)" : '';
$sql = DB()->sql_query("SELECT topic_id, topic_title, topic_time FROM " . BB_TOPICS . " " . $ignore_forum_sql . " ORDER BY topic_time ASC" . $this->limit);
while ($row = DB()->sql_fetchrow($sql)) {
if (function_exists('seo_url')) $loc = $this->home . seo_url(TOPIC_URL . $row['topic_id'], $row['topic_title']);
else $loc = $this->home . TOPIC_URL . $row['topic_id'];
$xml .= $this->get_xml($loc, date('c', $row['topic_time']));
}
return $xml;
}
function get_static () {
global $bb_cfg;
$xml = '';
$lm = date('c');
$this->priority = $this->stat_priority;
if (isset($bb_cfg['static_sitemap'])) {
$static_url = preg_replace("/\s/", '', $bb_cfg['static_sitemap']); //вырезаем переносы строк
preg_match_all('#(https?://[\w-]+[\.\w-]+/((?!https?://)[\w- ./?%&=])+)#', $static_url, $out);
$static_url = count($out['0']);
if ($static_url > 0) {
foreach ($out['0'] as $url) {
$loc = $url;
$xml .= $this->get_xml($loc, $lm);
}
}
}
return $xml;
}
function get_xml ($loc, $lm) {
$xml = "\t<url>\n";
$xml .= "\t\t<loc>$loc</loc>\n";
$xml .= "\t\t<lastmod>$lm</lastmod>\n";
$xml .= "\t\t<priority>" . $this->priority . "</priority>\n";
$xml .= "\t</url>\n";
return $xml;
}
function send_url ($url, $map) {
$data = false;
$file = $url.urlencode($map);
if (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $file);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
$data = curl_exec($ch);
curl_close($ch);
return $data;
} else {
return @file_get_contents($file);
}
}
function create () {
$row = DB()->fetch_row("SELECT COUNT(*) AS count FROM " . BB_TOPICS);
if (!$this->limit) $this->limit = $row['count'];
if ($this->limit > 40000) {
$pages_count = @ceil($row['count'] / 40000);
$sitemap = $this->build_index($pages_count);
$handler = fopen(SITEMAP_DIR. "sitemap.xml", "wb+");
fwrite($handler, $sitemap);
fclose($handler);
@chmod(SITEMAP_DIR. "sitemap.xml", 0666);
$sitemap = $this->build_stat();
$handler = fopen(SITEMAP_DIR. "sitemap1.xml", "wb+");
fwrite($handler, $sitemap);
fclose($handler);
@chmod(SITEMAP_DIR. "sitemap.xml", 0666);
for ($i = 0; $i < $pages_count; $i++) {
$t = $i + 2;
$n = $i + 1;
$sitemap = $this->build_map_topic($n);
$handler = fopen(SITEMAP_DIR. "sitemap{$t}.xml", "wb+");
fwrite($handler, $sitemap);
fclose($handler);
@chmod(SITEMAP_DIR. "sitemap{$t}.xml", 0666);
}
} else {
$sitemap = $this->build_map();
$handler = fopen(SITEMAP_DIR. "sitemap.xml", "wb+");
fwrite($handler, $sitemap);
fclose($handler);
@chmod(SITEMAP_DIR. "sitemap.xml", 0666);
}
$params['sitemap_time'] = TIMENOW;
bb_update_config($params);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,984 @@
<?php
if (!defined('SQL_DEBUG')) die(basename(__FILE__));
class sql_db
{
var $cfg = array();
var $cfg_keys = array('dbhost', 'dbname', 'dbuser', 'dbpasswd', 'charset', 'persist');
var $link = null;
var $result = null;
var $db_server = '';
var $selected_db = null;
var $inited = false;
var $locked = false;
var $locks = array();
var $num_queries = 0;
var $sql_starttime = 0;
var $sql_inittime = 0;
var $sql_timetotal = 0;
var $cur_query_time = 0;
var $slow_time = 0;
var $dbg = array();
var $dbg_id = 0;
var $dbg_enabled = false;
var $cur_query = null;
var $do_explain = false;
var $explain_hold = '';
var $explain_out = '';
var $shutdown = array();
var $DBS = array();
/**
* Constructor
*/
function sql_db ($cfg_values)
{
global $DBS;
$this->cfg = array_combine($this->cfg_keys, $cfg_values);
$this->dbg_enabled = (sql_dbg_enabled() || !empty($_COOKIE['explain']));
$this->do_explain = ($this->dbg_enabled && !empty($_COOKIE['explain']));
$this->slow_time = SQL_SLOW_QUERY_TIME;
// ссылки на глобальные переменные (для включения логов сразу на всех серверах, подсчета общего количества запросов и т.д.)
$this->DBS['log_file'] =& $DBS->log_file;
$this->DBS['log_counter'] =& $DBS->log_counter;
$this->DBS['num_queries'] =& $DBS->num_queries;
$this->DBS['sql_inittime'] =& $DBS->sql_inittime;
$this->DBS['sql_timetotal'] =& $DBS->sql_timetotal;
}
/**
* Initialize connection
*/
function init ()
{
// Connect to server
$this->link = $this->connect();
// Select database
$this->selected_db = $this->select_db();
// Set charset
if ($this->cfg['charset'] && !@mysql_set_charset($this->cfg['charset'], $this->link))
{
if (!$this->sql_query("SET NAMES {$this->cfg['charset']}"))
{
die("Could not set charset {$this->cfg['charset']}");
}
}
$this->inited = true;
$this->num_queries = 0;
$this->sql_inittime = $this->sql_timetotal;
$this->DBS['sql_inittime'] += $this->sql_inittime;
}
/**
* Open connection
*/
function connect ()
{
$this->cur_query = ($this->dbg_enabled) ? ($this->cfg['persist'] ? 'p' : '') . "connect to: {$this->cfg['dbhost']}" : 'connect';
$this->debug('start');
$connect_type = ($this->cfg['persist']) ? 'mysql_pconnect' : 'mysql_connect';
if (!$link = @$connect_type($this->cfg['dbhost'], $this->cfg['dbuser'], $this->cfg['dbpasswd']))
{
$server = (DBG_USER) ? $this->cfg['dbhost'] : '';
header("HTTP/1.0 503 Service Unavailable");
bb_log(' ', "db_err/connect_failed_{$this->cfg['dbhost']}");
die("Could not connect to mysql server $server");
}
register_shutdown_function(array(&$this, 'close'));
$this->debug('stop');
$this->cur_query = null;
return $link;
}
/**
* Select database
*/
function select_db ()
{
$this->cur_query = ($this->dbg_enabled) ? "select db: {$this->cfg['dbname']}" : 'select db';
$this->debug('start');
if (!@mysql_select_db($this->cfg['dbname'], $this->link))
{
$database = (DBG_USER) ? $this->cfg['dbhost'] : '';
die("Could not select database $database");
}
$this->debug('stop');
$this->cur_query = null;
return $this->cfg['dbname'];
}
/**
* Base query method
*/
function sql_query ($query)
{
if (!is_resource($this->link))
{
$this->init();
}
if (is_array($query))
{
$query = $this->build_sql($query);
}
if (SQL_PREPEND_SRC_COMM)
{
$query = '/* '. $this->debug_find_source() .' */ '. $query;
}
$this->cur_query = $query;
$this->debug('start');
if (!$this->result = mysql_query($query, $this->link))
{
$this->log_error();
}
$this->debug('stop');
$this->cur_query = null;
if ($this->inited)
{
$this->num_queries++;
$this->DBS['num_queries']++;
}
return $this->result;
}
/**
* Execute query WRAPPER (with error handling)
*/
function query ($query)
{
if (!$result = $this->sql_query($query))
{
$this->trigger_error();
}
return $result;
}
/**
* Return number of rows
*/
function num_rows ($result = false)
{
$num_rows = false;
if ($result OR $result = $this->result)
{
$num_rows = is_resource($result) ? mysql_num_rows($result) : false;
}
return $num_rows;
}
/**
* Return number of affected rows
*/
function affected_rows ()
{
return is_resource($this->link) ? mysql_affected_rows($this->link) : -1;
}
/**
* Fetch current field
*/
function sql_fetchfield($field, $rownum = -1, $query_id = 0)
{
if(!$query_id)
{
$query_id = $this->query_result;
}
if($query_id)
{
if($rownum > -1)
{
$result = @mysql_result($query_id, $rownum, $field);
}
else
{
if(empty($this->row[$query_id]) && empty($this->rowset[$query_id]))
{
if($this->sql_fetchrow())
{
$result = $this->row[$query_id][$field];
}
}
else
{
if($this->rowset[$query_id])
{
$result = $this->rowset[$query_id][0][$field];
}
else if($this->row[$query_id])
{
$result = $this->row[$query_id][$field];
}
}
}
return $result;
}
else
{
return false;
}
}
/**
* Fetch current row
*/
function sql_fetchrow ($result, $field_name = '')
{
$row = mysql_fetch_assoc($result);
if ($field_name)
{
return isset($row[$field_name]) ? $row[$field_name] : false;
}
else
{
return $row;
}
}
/**
* Alias of sql_fetchrow()
*/
function fetch_next ($result)
{
return $this->sql_fetchrow($result);
}
/**
* Fetch row WRAPPER (with error handling)
*/
function fetch_row ($query, $field_name = '')
{
if (!$result = $this->sql_query($query))
{
$this->trigger_error();
}
return $this->sql_fetchrow($result, $field_name);
}
/**
* Fetch all rows
*/
function sql_fetchrowset ($result, $field_name = '')
{
$rowset = array();
while ($row = mysql_fetch_assoc($result))
{
$rowset[] = ($field_name) ? $row[$field_name] : $row;
}
return $rowset;
}
/**
* Fetch all rows WRAPPER (with error handling)
*/
function fetch_rowset ($query, $field_name = '')
{
if (!$result = $this->sql_query($query))
{
$this->trigger_error();
}
return $this->sql_fetchrowset($result, $field_name);
}
/**
* Fetch all rows WRAPPER (with error handling)
*/
function fetch_all ($query, $field_name = '')
{
if (!$result = $this->sql_query($query))
{
$this->trigger_error();
}
return $this->sql_fetchrowset($result, $field_name);
}
/**
* Get last inserted id after insert statement
*/
function sql_nextid ()
{
return mysql_insert_id($this->link);
}
/**
* Free sql result
*/
function sql_freeresult ($result = false)
{
if ($result OR $result = $this->result)
{
$return_value = is_resource($result) ? mysql_free_result($result) : false;
}
$this->result = null;
}
/**
* Escape data used in sql query
*/
function escape ($v, $check_type = false, $dont_escape = false)
{
if ($dont_escape) return $v;
if (!$check_type) return $this->escape_string($v);
switch (true)
{
case is_string ($v): return "'". $this->escape_string($v) ."'";
case is_int ($v): return "$v";
case is_bool ($v): return ($v) ? '1' : '0';
case is_float ($v): return "'$v'";
case is_null ($v): return 'NULL';
}
// if $v has unsuitable type
$this->trigger_error(__FUNCTION__ .' - wrong params');
}
/**
* Escape string
*/
function escape_string ($str)
{
if (!is_resource($this->link))
{
$this->init();
}
return mysql_real_escape_string($str, $this->link);
}
/**
* Build SQL statement from array (based on same method from phpBB3, idea from Ikonboard)
*
* Possible $query_type values: INSERT, INSERT_SELECT, MULTI_INSERT, UPDATE, SELECT
*/
function build_array ($query_type, $input_ary, $data_already_escaped = false, $check_data_type_in_escape = true)
{
$fields = $values = $ary = $query = array();
$dont_escape = $data_already_escaped;
$check_type = $check_data_type_in_escape;
if (empty($input_ary) || !is_array($input_ary))
{
$this->trigger_error(__FUNCTION__ .' - wrong params: $input_ary');
}
if ($query_type == 'INSERT')
{
foreach ($input_ary as $field => $val)
{
$fields[] = $field;
$values[] = $this->escape($val, $check_type, $dont_escape);
}
$fields = join(', ', $fields);
$values = join(', ', $values);
$query = "($fields)\nVALUES\n($values)";
}
else if ($query_type == 'INSERT_SELECT')
{
foreach ($input_ary as $field => $val)
{
$fields[] = $field;
$values[] = $this->escape($val, $check_type, $dont_escape);
}
$fields = join(', ', $fields);
$values = join(', ', $values);
$query = "($fields)\nSELECT\n$values";
}
else if ($query_type == 'MULTI_INSERT')
{
foreach ($input_ary as $id => $sql_ary)
{
foreach ($sql_ary as $field => $val)
{
$values[] = $this->escape($val, $check_type, $dont_escape);
}
$ary[] = '('. join(', ', $values) .')';
$values = array();
}
$fields = join(', ', array_keys($input_ary[0]));
$values = join(",\n", $ary);
$query = "($fields)\nVALUES\n$values";
}
else if ($query_type == 'SELECT' || $query_type == 'UPDATE')
{
foreach ($input_ary as $field => $val)
{
$ary[] = "$field = ". $this->escape($val, $check_type, $dont_escape);
}
$glue = ($query_type == 'SELECT') ? "\nAND " : ",\n";
$query = join($glue, $ary);
}
if (!$query)
{
bb_die('<pre><b>'. __FUNCTION__ ."</b>: Wrong params for <b>$query_type</b> query type\n\n\$input_ary:\n\n". htmlCHR(print_r($input_ary, true)) .'</pre>');
}
return "\n". $query ."\n";
}
function get_empty_sql_array ()
{
return array(
'SELECT' => array(),
'select_options' => array(),
'FROM' => array(),
'INNER JOIN' => array(),
'LEFT JOIN' => array(),
'WHERE' => array(),
'GROUP BY' => array(),
'HAVING' => array(),
'ORDER BY' => array(),
'LIMIT' => array(),
);
}
function build_sql ($sql_ary)
{
$sql = '';
array_deep($sql_ary, 'array_unique', false, true);
foreach ($sql_ary as $clause => $ary)
{
switch ($clause)
{
case 'SELECT':
$sql .= ($ary) ? ' SELECT '. join(' ', $sql_ary['select_options']) .' '. join(', ', $ary) : '';
break;
case 'FROM':
$sql .= ($ary) ? ' FROM '. join(', ', $ary) : '';
break;
case 'INNER JOIN':
$sql .= ($ary) ? ' INNER JOIN '. join(' INNER JOIN ', $ary) : '';
break;
case 'LEFT JOIN':
$sql .= ($ary) ? ' LEFT JOIN '. join(' LEFT JOIN ', $ary) : '';
break;
case 'WHERE':
$sql .= ($ary) ? ' WHERE '. join(' AND ', $ary) : '';
break;
case 'GROUP BY':
$sql .= ($ary) ? ' GROUP BY '. join(', ', $ary) : '';
break;
case 'HAVING':
$sql .= ($ary) ? ' HAVING '. join(' AND ', $ary) : '';
break;
case 'ORDER BY':
$sql .= ($ary) ? ' ORDER BY '. join(', ', $ary) : '';
break;
case 'LIMIT':
$sql .= ($ary) ? ' LIMIT '. join(', ', $ary) : '';
break;
}
}
return trim($sql);
}
/**
* Return sql error array
*/
function sql_error ()
{
if (is_resource($this->link))
{
return array('code' => mysql_errno($this->link), 'message' => mysql_error($this->link));
}
else
{
return array('code' => '', 'message' => 'not connected');
}
}
/**
* Close sql connection
*/
function close ()
{
if (is_resource($this->link))
{
$this->unlock();
if (!empty($this->locks))
{
foreach ($this->locks as $name => $void)
{
$this->release_lock($name);
}
}
$this->exec_shutdown_queries();
mysql_close($this->link);
}
$this->link = $this->selected_db = null;
}
/**
* Add shutdown query
*/
function add_shutdown_query ($sql)
{
$this->shutdown['__sql'][] = $sql;
}
/**
* Exec shutdown queries
*/
function exec_shutdown_queries ()
{
if (empty($this->shutdown)) return;
if (!empty($this->shutdown['post_html']))
{
$post_html_sql = $this->build_array('MULTI_INSERT', $this->shutdown['post_html']);
$this->query("REPLACE INTO ". BB_POSTS_HTML ." $post_html_sql");
}
if (!empty($this->shutdown['__sql']))
{
foreach ($this->shutdown['__sql'] as $sql)
{
$this->query($sql);
}
}
}
/**
* Lock tables
*/
function lock ($tables, $lock_type = 'WRITE')
{
if ($this->cfg['persist'])
{
# return true;
}
$tables_sql = array();
foreach ((array) $tables as $table_name)
{
$tables_sql[] = "$table_name $lock_type";
}
if ($tables_sql = join(', ', $tables_sql))
{
$this->locked = $this->sql_query("LOCK TABLES $tables_sql");
}
return $this->locked;
}
/**
* Unlock tables
*/
function unlock ()
{
if ($this->locked && $this->sql_query("UNLOCK TABLES"))
{
$this->locked = false;
}
return !$this->locked;
}
/**
* Obtain user level lock
*/
function get_lock ($name, $timeout = 0)
{
$lock_name = $this->get_lock_name($name);
$timeout = (int) $timeout;
$row = $this->fetch_row("SELECT GET_LOCK('$lock_name', $timeout) AS lock_result");
if ($row['lock_result'])
{
$this->locks[$name] = true;
}
return $row['lock_result'];
}
/**
* Obtain user level lock status
*/
function release_lock ($name)
{
$lock_name = $this->get_lock_name($name);
$row = $this->fetch_row("SELECT RELEASE_LOCK('$lock_name') AS lock_result");
if ($row['lock_result'])
{
unset($this->locks[$name]);
}
return $row['lock_result'];
}
/**
* Release user level lock
*/
function is_free_lock ($name)
{
$lock_name = $this->get_lock_name($name);
$row = $this->fetch_row("SELECT IS_FREE_LOCK('$lock_name') AS lock_result");
return $row['lock_result'];
}
/**
* Make per db unique lock name
*/
function get_lock_name ($name)
{
if (!$this->selected_db)
{
$this->init();
}
return "{$this->selected_db}_{$name}";
}
/**
* Get info about last query
*/
function query_info ()
{
$info = array();
if ($num = $this->num_rows($this->result))
{
$info[] = "$num rows";
}
if (is_resource($this->link) AND $ext = mysql_info($this->link))
{
$info[] = "$ext";
}
else if (!$num && ($aff = $this->affected_rows($this->result) AND $aff != -1))
{
$info[] = "$aff rows";
}
return str_compact(join(', ', $info));
}
/**
* Get server version
*/
function server_version ()
{
preg_match('#^(\d+\.\d+\.\d+).*#', mysql_get_server_info(), $m);
return $m[1];
}
/**
* Set slow query marker for xx seconds
* This will disable counting other queries as "slow" during this time
*/
function expect_slow_query ($ignoring_time = 60, $new_priority = 10)
{
if ($old_priority = CACHE('bb_cache')->get('dont_log_slow_query'))
{
if ($old_priority > $new_priority)
{
return;
}
}
@define('IN_FIRST_SLOW_QUERY', true);
CACHE('bb_cache')->set('dont_log_slow_query', $new_priority, $ignoring_time);
}
/**
* Store debug info
*/
function debug ($mode)
{
if (!SQL_DEBUG) return;
$id =& $this->dbg_id;
$dbg =& $this->dbg[$id];
if ($mode == 'start')
{
if (SQL_CALC_QUERY_TIME || DBG_LOG || SQL_LOG_SLOW_QUERIES)
{
$this->sql_starttime = utime();
}
if ($this->dbg_enabled)
{
$dbg['sql'] = preg_replace('#^(\s*)(/\*)(.*)(\*/)(\s*)#', '', $this->cur_query);
$dbg['src'] = $this->debug_find_source();
$dbg['file'] = $this->debug_find_source('file');
$dbg['line'] = $this->debug_find_source('line');
$dbg['time'] = '';
$dbg['info'] = '';
$dbg['mem_before'] = sys('mem');
}
if ($this->do_explain)
{
$this->explain('start');
}
}
else if ($mode == 'stop')
{
if (SQL_CALC_QUERY_TIME || DBG_LOG || SQL_LOG_SLOW_QUERIES)
{
$this->cur_query_time = utime() - $this->sql_starttime;
$this->sql_timetotal += $this->cur_query_time;
$this->DBS['sql_timetotal'] += $this->cur_query_time;
if (SQL_LOG_SLOW_QUERIES && $this->cur_query_time > $this->slow_time)
{
$this->log_slow_query();
}
}
if ($this->dbg_enabled)
{
$dbg['time'] = utime() - $this->sql_starttime;
$dbg['info'] = $this->query_info();
$dbg['mem_after'] = sys('mem');
$id++;
}
if ($this->do_explain)
{
$this->explain('stop');
}
// проверка установки $this->inited - для пропуска инициализационных запросов
if ($this->DBS['log_counter'] && $this->inited)
{
$this->log_query($this->DBS['log_file']);
$this->DBS['log_counter']--;
}
}
}
/**
* Trigger error
*/
function trigger_error ($msg = 'DB Error')
{
if (error_reporting())
{
if (DBG_LOG === true)
{
$err = $this->sql_error();
$msg .= "\n". trim(sprintf('#%06d %s', $err['code'], $err['message']));
}
else
{
$msg .= " [". $this->debug_find_source() ."]";
}
trigger_error($msg, E_USER_ERROR);
}
}
/**
* Find caller source
*/
function debug_find_source ($mode = '')
{
foreach (debug_backtrace() as $trace)
{
if (!empty($trace['file']) && $trace['file'] !== __FILE__)
{
switch ($mode)
{
case 'file': return $trace['file'];
case 'line': return $trace['line'];
default: return hide_bb_path($trace['file']) .'('. $trace['line'] .')';
}
}
}
return '';
}
/**
* Prepare for logging
*/
function log_next_query ($queries_count = 1, $log_file = 'sql_queries')
{
$this->DBS['log_file'] = $log_file;
$this->DBS['log_counter'] = $queries_count;
}
/**
* Log query
*/
function log_query ($log_file = 'sql_queries')
{
$q_time = ($this->cur_query_time >= 10) ? round($this->cur_query_time, 0) : sprintf('%.4f', $this->cur_query_time);
$msg = array();
$msg[] = round($this->sql_starttime);
$msg[] = date('m-d H:i:s', $this->sql_starttime);
$msg[] = sprintf('%-6s', $q_time);
$msg[] = sprintf('%-4s', round(sys('la'), 1));
$msg[] = sprintf('%05d', getmypid());
$msg[] = $this->db_server;
$msg[] = short_query($this->cur_query);
$msg = join(LOG_SEPR, $msg);
$msg .= ($info = $this->query_info()) ? ' # '. $info : '';
$msg .= ' # '. $this->debug_find_source() .' ';
$msg .= defined('IN_CRON') ? 'cron' : basename($_SERVER['REQUEST_URI']);
bb_log($msg . LOG_LF, $log_file);
}
/**
* Log slow query
*/
function log_slow_query ($log_file = 'sql_slow_bb')
{
if (!defined('IN_FIRST_SLOW_QUERY') && CACHE('bb_cache')->get('dont_log_slow_query'))
{
return;
}
$this->log_query($log_file);
}
/**
* Log error
*/
function log_error ()
{
if (!SQL_LOG_ERRORS) return;
$msg = array();
$err = $this->sql_error();
$msg[] = str_compact(sprintf('#%06d %s', $err['code'], $err['message']));
$msg[] = '';
$msg[] = str_compact($this->cur_query);
$msg[] = '';
$msg[] = 'Source : '. $this->debug_find_source() ." :: $this->db_server.$this->selected_db";
$msg[] = 'IP : '. @$_SERVER['REMOTE_ADDR'];
$msg[] = 'Date : '. date('Y-m-d H:i:s');
$msg[] = 'Agent : '. @$_SERVER['HTTP_USER_AGENT'];
$msg[] = 'Req_URI : '. @$_SERVER['REQUEST_URI'];
$msg[] = 'Referer : '. @$_SERVER['HTTP_REFERER'];
$msg[] = 'Method : '. @$_SERVER['REQUEST_METHOD'];
$msg[] = 'PID : '. sprintf('%05d', getmypid());
$msg[] = 'Request : '. trim(print_r($_REQUEST, true)) . str_repeat('_', 78) . LOG_LF;
$msg[] = '';
bb_log($msg, 'sql_error_bb');
}
/**
* Explain queries (based on code from phpBB3)
*/
function explain ($mode, $html_table = '', $row = '')
{
$query = str_compact($this->cur_query);
// remove comments
$query = preg_replace('#(\s*)(/\*)(.*)(\*/)(\s*)#', '', $query);
switch ($mode)
{
case 'start':
$this->explain_hold = '';
// TODO: добавить поддержку многотабличных запросов
if (preg_match('#UPDATE ([a-z0-9_]+).*?WHERE(.*)/#', $query, $m))
{
$query = "SELECT * FROM $m[1] WHERE $m[2]";
}
else if (preg_match('#DELETE FROM ([a-z0-9_]+).*?WHERE(.*)#s', $query, $m))
{
$query = "SELECT * FROM $m[1] WHERE $m[2]";
}
if (preg_match('#^SELECT#', $query))
{
$html_table = false;
if ($result = @mysql_query("EXPLAIN $query", $this->link))
{
while ($row = @mysql_fetch_assoc($result))
{
$html_table = $this->explain('add_explain_row', $html_table, $row);
}
}
if ($html_table)
{
$this->explain_hold .= '</table>';
}
}
break;
case 'stop':
if (!$this->explain_hold) break;
$id = $this->dbg_id-1;
$htid = 'expl-'. intval($this->link) .'-'. $id;
$dbg = $this->dbg[$id];
$this->explain_out .= '
<table width="98%" cellpadding="0" cellspacing="0" class="bodyline row2 bCenter" style="border-bottom: 0px;">
<tr>
<th style="height: 22px; cursor: pointer;" align="left">&nbsp;'. $dbg['src'] .'&nbsp; ['. sprintf('%.4f', $dbg['time']) .' s]&nbsp; <i>'. $dbg['info'] .'</i></th>
<th style="height: 22px; cursor: pointer;" align="right" title="Copy to clipboard" onclick="$.copyToClipboard( $(\'#'. $htid .'\').text() );">'. "$this->db_server.$this->selected_db" .' :: Query #'. ($this->num_queries+1) .'&nbsp;</th>
</tr>
<tr><td colspan="2">'. $this->explain_hold .'</td></tr>
</table>
<div class="sqlLog"><div id="'. $htid .'" class="sqlLogRow sqlExplain" style="padding: 0px;">'. short_query($dbg['sql'], true) .'&nbsp;&nbsp;</div></div>
<br />';
break;
case 'add_explain_row':
if (!$html_table && $row)
{
$html_table = true;
$this->explain_hold .= '<table width="100%" cellpadding="3" cellspacing="1" class="bodyline" style="border-width: 0;"><tr>';
foreach (array_keys($row) as $val)
{
$this->explain_hold .= '<td class="row3 gensmall" align="center"><b>'. $val .'</b></td>';
}
$this->explain_hold .= '</tr>';
}
$this->explain_hold .= '<tr>';
foreach (array_values($row) as $i => $val)
{
$class = !($i % 2) ? 'row1' : 'row2';
$this->explain_hold .= '<td class="'. $class .' gen">'. str_replace(array("{$this->selected_db}.", ',', ';'), array('', ', ', ';<br />'), $val) .'</td>';
}
$this->explain_hold .= '</tr>';
return $html_table;
break;
case 'display':
echo '<a name="explain"></a><div class="med">'. $this->explain_out .'</div>';
break;
}
}
}

View file

@ -0,0 +1,2 @@
order allow,deny
deny from all

View file

@ -0,0 +1,38 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
bb_log(date('H:i:s - ') . getmypid() .' --x- SELECT jobs'. LOG_LF, CRON_LOG_DIR .'cron_check');
// Get cron jobs
$cron_jobs = DB()->fetch_rowset("
SELECT * FROM ". BB_CRON ."
WHERE cron_active = 1
AND next_run <= NOW()
ORDER BY run_order
");
// Run cron jobs
if ($cron_jobs)
{
bb_log(date('H:i:s - ') . getmypid() .' --x- RUN jobs'. LOG_LF, CRON_LOG_DIR .'cron_check');
foreach ($cron_jobs as $job)
{
if ($job['disable_board'])
{
cron_disable_board();
sleep(10);
break;
}
}
require(CRON_DIR .'cron_run.php');
// Update cron_last_check
bb_update_config(array('cron_last_check' => (TIMENOW + 10)));
}
else
{
bb_log(date('H:i:s - ') . getmypid() .' --x- no active jobs found ----------------------------------------------'. LOG_LF, CRON_LOG_DIR .'cron_check');
}

View file

@ -0,0 +1,67 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
//
// Functions
//
function cron_get_file_lock ()
{
$lock_obtained = false;
if (file_exists(CRON_ALLOWED))
{
# bb_log(date('H:i:s - ') . getmypid() .' -x-- FILE-LOCK try'. LOG_LF, CRON_LOG_DIR .'cron_check');
$lock_obtained = @rename(CRON_ALLOWED, CRON_RUNNING);
}
elseif (file_exists(CRON_RUNNING))
{
cron_release_deadlock();
}
elseif (!file_exists(CRON_ALLOWED) && !file_exists(CRON_RUNNING))
{
file_write('', CRON_ALLOWED);
$lock_obtained = @rename(CRON_ALLOWED, CRON_RUNNING);
}
return $lock_obtained;
}
function cron_track_running ($mode)
{
@define('CRON_STARTMARK', TRIGGERS_DIR .'cron_started_at_'. date('Y-m-d_H-i-s') .'_by_pid_'. getmypid());
if ($mode == 'start')
{
cron_touch_lock_file(CRON_RUNNING);
file_write('', CRON_STARTMARK);
}
elseif ($mode == 'end')
{
@unlink(CRON_STARTMARK);
}
}
//
// Run cron
//
if (cron_get_file_lock())
{
ignore_user_abort(true);
register_shutdown_function('cron_release_file_lock');
register_shutdown_function('cron_enable_board');
# bb_log(date('H:i:s - ') . getmypid() .' --x- FILE-LOCK OBTAINED ###############'. LOG_LF, CRON_LOG_DIR .'cron_check');
cron_track_running('start');
require(CRON_DIR .'cron_check.php');
cron_track_running('end');
}
if (defined('IN_CRON'))
{
bb_log(date('H:i:s - ') . getmypid() .' --x- ALL jobs FINISHED *************************************************'. LOG_LF, CRON_LOG_DIR .'cron_check');
}

View file

@ -0,0 +1,129 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
define('IN_CRON', true);
// Set SESSION vars
DB()->query("
SET SESSION
myisam_sort_buffer_size = 16*1024*1024
, bulk_insert_buffer_size = 8*1024*1024
, join_buffer_size = 4*1024*1024
, read_buffer_size = 4*1024*1024
, read_rnd_buffer_size = 8*1024*1024
, sort_buffer_size = 4*1024*1024
, tmp_table_size = 80*1024*1024
, group_concat_max_len = 1*1024*1024
");
// Restore vars at shutdown
DB()->add_shutdown_query("
SET SESSION
myisam_sort_buffer_size = DEFAULT
, bulk_insert_buffer_size = DEFAULT
, join_buffer_size = DEFAULT
, read_buffer_size = DEFAULT
, read_rnd_buffer_size = DEFAULT
, sort_buffer_size = DEFAULT
, tmp_table_size = DEFAULT
, group_concat_max_len = DEFAULT
");
// $cron_jobs obtained in cron_check.php
foreach ($cron_jobs as $job)
{
$job_script = CRON_JOB_DIR . basename($job['cron_script']);
if (file_exists($job_script))
{
$cron_start_time = utime();
$cron_runtime_log = '';
$cron_write_log = (CRON_LOG_ENABLED && (CRON_FORCE_LOG || $job['log_enabled'] >= 1));
$cron_sql_log_file = CRON_LOG_DIR .'SQL-'. basename($job['cron_script']);
if ($cron_write_log)
{
$msg = array();
$msg[] = 'start';
$msg[] = date('m-d');
$msg[] = date('H:i:s');
$msg[] = sprintf('%-4s', round(sys('la'), 1));
$msg[] = sprintf('%05d', getmypid());
$msg[] = $job['cron_title'];
$msg = join(LOG_SEPR, $msg);
bb_log($msg . LOG_LF, CRON_LOG_DIR . CRON_LOG_FILE);
}
if ($job['log_sql_queries'])
{
DB()->log_next_query(100000, $cron_sql_log_file);
}
set_time_limit(600);
require($job_script);
if ($job['log_sql_queries'])
{
DB()->log_next_query(0);
bb_log(LOG_LF, $cron_sql_log_file);
}
if ($cron_write_log)
{
$msg = array();
$msg[] = ' end';
$msg[] = date('m-d');
$msg[] = date('H:i:s');
$msg[] = sprintf('%-4s', round(sys('la'), 1));
$msg[] = sprintf('%05d', getmypid());
$msg[] = round(utime() - $cron_start_time) .'/'. round(utime() - TIMESTART) . ' sec';
$msg = join(LOG_SEPR, $msg);
$msg .= LOG_LF .'------=-------=----------=------=-------=----------';
bb_log($msg . LOG_LF, CRON_LOG_DIR . CRON_LOG_FILE);
if ($cron_runtime_log)
{
$runtime_log_file = ($job['log_file']) ? $job['log_file'] : $job['cron_script'];
bb_log($cron_runtime_log . LOG_LF, CRON_LOG_DIR . basename($runtime_log_file));
}
}
DB()->query("
UPDATE ". BB_CRON ." SET
last_run = NOW(),
run_counter = run_counter + 1,
next_run =
CASE
WHEN schedule = 'hourly' THEN
DATE_ADD(NOW(), INTERVAL 1 HOUR)
WHEN schedule = 'daily' THEN
DATE_ADD(DATE_ADD(CURDATE(), INTERVAL 1 DAY), INTERVAL TIME_TO_SEC(run_time) SECOND)
WHEN schedule = 'weekly' THEN
DATE_ADD(
DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(NOW()) DAY), INTERVAL 7 DAY),
INTERVAL CONCAT(ROUND(run_day-1), ' ', run_time) DAY_SECOND)
WHEN schedule = 'monthly' THEN
DATE_ADD(
DATE_ADD(DATE_SUB(CURDATE(), INTERVAL DAYOFMONTH(NOW())-1 DAY), INTERVAL 1 MONTH),
INTERVAL CONCAT(ROUND(run_day-1), ' ', run_time) DAY_SECOND)
ELSE
DATE_ADD(NOW(), INTERVAL TIME_TO_SEC(run_interval) SECOND)
END
WHERE cron_id = {$job['cron_id']}
LIMIT 1
");
sleep(1);
if (utime() - TIMESTART > 600)
{
return; // чтобы daily скрипты не блокировали надолго interval'ные
}
}
else
{
$cron_err_msg = "Can not run \"{$job['cron_title']}\" : file \"$job_script\" not found". LOG_LF;
bb_log($cron_err_msg, 'cron_error');
}
}

View file

@ -0,0 +1,2 @@
order allow,deny
deny from all

View file

@ -0,0 +1,224 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
DB()->expect_slow_query(600);
$fix_errors = true;
$debug_mode = false;
$tmp_attach_tbl = 'tmp_attachments';
$db_max_packet = 800000;
$sql_limit = 3000;
$check_attachments = false;
$orphan_files = $orphan_db_attach = $orphan_tor = array();
$posts_without_attach = $topics_without_attach = array();
DB()->query("
CREATE TEMPORARY TABLE $tmp_attach_tbl (
physical_filename VARCHAR(255) NOT NULL default '',
KEY physical_filename (physical_filename(20))
) ENGINE = MyISAM DEFAULT CHARSET = utf8
");
DB()->add_shutdown_query("DROP TEMPORARY TABLE IF EXISTS $tmp_attach_tbl");
// Get attach_mod config
$attach_dir = get_attachments_dir();
// Get all names of existed attachments and insert them into $tmp_attach_tbl
if ($dir = @opendir($attach_dir))
{
$check_attachments = true;
$files = array();
$f_len = 0;
while (false !== ($f = readdir($dir)))
{
if ($f == 'index.php' || $f == '.htaccess' || is_dir("$attach_dir/$f") || is_link("$attach_dir/$f"))
{
continue;
}
$f = DB()->escape($f);
$files[] = "('$f')";
$f_len += strlen($f) + 5;
if ($f_len > $db_max_packet)
{
$files = join(',', $files);
DB()->query("INSERT INTO $tmp_attach_tbl VALUES $files");
$files = array();
$f_len = 0;
}
}
if ($files = join(',', $files))
{
DB()->query("INSERT INTO $tmp_attach_tbl VALUES $files");
}
closedir($dir);
}
if ($check_attachments)
{
// Delete bad records
DB()->query("
DELETE a, d
FROM ". BB_ATTACHMENTS_DESC ." d
LEFT JOIN ". BB_ATTACHMENTS ." a USING(attach_id)
WHERE (
d.physical_filename = ''
OR d.real_filename = ''
OR d.extension = ''
OR d.mimetype = ''
OR d.filesize = 0
OR d.filetime = 0
OR a.post_id = 0
)
");
// Delete attachments that exist in file system but not exist in DB
$sql = "SELECT f.physical_filename
FROM $tmp_attach_tbl f
LEFT JOIN ". BB_ATTACHMENTS_DESC ." d USING(physical_filename)
WHERE d.physical_filename IS NULL
LIMIT $sql_limit";
foreach (DB()->fetch_rowset($sql) as $row)
{
if ($filename = basename($row['physical_filename']))
{
if ($fix_errors)
{
@unlink("$attach_dir/$filename");
@unlink("$attach_dir/". THUMB_DIR .'/t_'. $filename);
}
if ($debug_mode)
{
$orphan_files[] = "$attach_dir/$filename";
}
}
}
// Find DB records for attachments that exist in DB but not exist in file system
$sql = "SELECT d.attach_id
FROM ". BB_ATTACHMENTS_DESC ." d
LEFT JOIN $tmp_attach_tbl f USING(physical_filename)
WHERE f.physical_filename IS NULL
LIMIT $sql_limit";
foreach (DB()->fetch_rowset($sql) as $row)
{
$orphan_db_attach[] = $row['attach_id'];
}
// Attachment exist in DESC_TABLE but not exist in ATTACH_TABLE
$sql = "SELECT d.attach_id
FROM ". BB_ATTACHMENTS_DESC ." d
LEFT JOIN ". BB_ATTACHMENTS ." a USING(attach_id)
WHERE a.attach_id IS NULL
LIMIT $sql_limit";
foreach (DB()->fetch_rowset($sql) as $row)
{
$orphan_db_attach[] = $row['attach_id'];
}
// Attachment exist in ATTACH_TABLE but not exist in DESC_TABLE
$sql = "SELECT a.attach_id
FROM ". BB_ATTACHMENTS ." a
LEFT JOIN ". BB_ATTACHMENTS_DESC ." d USING(attach_id)
WHERE d.attach_id IS NULL
LIMIT $sql_limit";
foreach (DB()->fetch_rowset($sql) as $row)
{
$orphan_db_attach[] = $row['attach_id'];
}
// Attachments without post
$sql = "SELECT a.attach_id
FROM ". BB_ATTACHMENTS ." a
LEFT JOIN ". BB_POSTS ." p USING(post_id)
WHERE p.post_id IS NULL
LIMIT $sql_limit";
foreach (DB()->fetch_rowset($sql) as $row)
{
$orphan_db_attach[] = $row['attach_id'];
}
// Delete all orphan attachments
if ($orphans_sql = join(',', $orphan_db_attach))
{
if ($fix_errors)
{
DB()->query("DELETE FROM ". BB_ATTACHMENTS_DESC ." WHERE attach_id IN($orphans_sql)");
DB()->query("DELETE FROM ". BB_ATTACHMENTS ." WHERE attach_id IN($orphans_sql)");
}
}
// Torrents without attachments
$sql = "SELECT tor.topic_id
FROM ". BB_BT_TORRENTS ." tor
LEFT JOIN ". BB_ATTACHMENTS_DESC ." d USING(attach_id)
WHERE d.attach_id IS NULL
LIMIT $sql_limit";
foreach (DB()->fetch_rowset($sql) as $row)
{
$orphan_tor[] = $row['topic_id'];
}
// Delete all orphan torrents
if ($orphans_sql = join(',', $orphan_tor))
{
if ($fix_errors)
{
DB()->query("DELETE FROM ". BB_BT_TORRENTS ." WHERE topic_id IN($orphans_sql)");
}
}
// Check post_attachment markers
$sql = "SELECT p.post_id
FROM ". BB_POSTS ." p
LEFT JOIN ". BB_ATTACHMENTS ." a USING(post_id)
WHERE p.post_attachment = 1
AND a.post_id IS NULL";
foreach (DB()->fetch_rowset($sql) as $row)
{
$posts_without_attach[] = $row['post_id'];
}
if ($posts_sql = join(',', $posts_without_attach))
{
if ($fix_errors)
{
DB()->query("UPDATE ". BB_POSTS ." SET post_attachment = 0 WHERE post_id IN($posts_sql)");
}
}
// Check topic_attachment markers
$sql = "SELECT t.topic_id
FROM ". BB_POSTS ." p, ". BB_TOPICS ." t
WHERE t.topic_id = p.topic_id
AND t.topic_attachment = 1
GROUP BY p.topic_id
HAVING SUM(p.post_attachment) = 0";
foreach (DB()->fetch_rowset($sql) as $row)
{
$topics_without_attach[] = $row['topic_id'];
}
if ($topics_sql = join(',', $topics_without_attach))
{
if ($fix_errors)
{
DB()->query("UPDATE ". BB_TOPICS ." SET topic_attachment = 0 WHERE topic_id IN($topics_sql)");
}
}
}
if ($debug_mode)
{
prn_r($orphan_files, '$orphan_files');
prn_r($orphan_db_attach, '$orphan_db_attach');
prn_r($orphan_tor, '$orphan_tor');
prn_r($posts_without_attach, '$posts_without_attach');
prn_r($topics_without_attach, '$topics_without_attach');
}
DB()->query("DROP TEMPORARY TABLE $tmp_attach_tbl");
unset($fix_errors, $debug_mode);

View file

@ -0,0 +1,49 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
require_once(INC_DIR .'functions_admin.php');
// Синхронизация
sync('topic', 'all');
sync('user_posts', 'all');
sync_all_forums();
// Чистка bb_poll_users
if ($poll_max_days = (int) $bb_cfg['poll_max_days'])
{
$per_cycle = 20000;
$row = DB()->fetch_row("SELECT MIN(topic_id) AS start_id, MAX(topic_id) AS finish_id FROM ". BB_POLL_USERS);
$start_id = (int) $row['start_id'];
$finish_id = (int) $row['finish_id'];
while (true)
{
set_time_limit(600);
$end_id = $start_id + $per_cycle - 1;
DB()->query("
DELETE FROM ". BB_POLL_USERS ."
WHERE topic_id BETWEEN $start_id AND $end_id
AND vote_dt < DATE_SUB(NOW(), INTERVAL $poll_max_days DAY)
");
if ($end_id > $finish_id)
{
break;
}
if (!($start_id % ($per_cycle*10)))
{
sleep(1);
}
$start_id += $per_cycle;
}
}
// Чистка user_newpasswd
DB()->query("UPDATE ". BB_USERS ." SET user_newpasswd = '' WHERE user_lastvisit < ". (TIMENOW - 7*86400));
// Чистка кеша постов
if ($posts_days = intval($bb_cfg['posts_cache_days_keep']))
{
DB()->query("DELETE FROM ". BB_POSTS_HTML ." WHERE post_html_time < DATE_SUB(NOW(), INTERVAL $posts_days DAY)");
}

View file

@ -0,0 +1,14 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
global $cron_runtime_log;
foreach ($bb_cfg['cache']['engines'] as $cache_name => $cache_val)
{
if (method_exists(CACHE($cache_name), 'gc'))
{
$changes = CACHE($cache_name)->gc();
$cron_runtime_log = date('Y-m-d H:i:s') ." -- ". str_pad("$cache_name ", 25, '-', STR_PAD_RIGHT) ." del: $changes\n";
}
}

View file

@ -0,0 +1,61 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
//
// Создание новых картинок
//
$cap_img_total = CAPTCHA()->cap_img_total; // сколько должно быть всего активных (cap_id > 0)
$new_per_minute = CAPTCHA()->new_per_minute; // сколько добавлять новых
$cap_expire_time = TIMENOW + CAPTCHA()->key_ttl*2;
$gen_new_img_count = $new_per_minute; // сколько реально нужно сгенерить новых
$expire_img_count = $new_per_minute; // сколько пометить для удаления
$row = DB('cap')->fetch_row("SELECT COUNT(*) AS cnt, MAX(cap_id) AS max_id FROM ". BB_CAPTCHA ." WHERE cap_id > 0");
$cur_total_count = (int) $row['cnt'];
$cur_max_id = (int) $row['max_id'];
if ($cur_total_count < $cap_img_total)
{
$gen_new_img_count += ($cap_img_total - $cur_total_count);
}
$start_id = $cur_max_id + 1;
$cur_id = $start_id;
$finish_id = $start_id + $gen_new_img_count - 1;
while ($cur_id <= $finish_id)
{
$code = CAPTCHA()->gen_img($cur_id);
DB('cap')->query("INSERT INTO ". BB_CAPTCHA ." (cap_id, cap_code) VALUES ($cur_id, '$code')");
$cur_id++;
}
//
// Метка о неактивности и об истечении срока
//
DB('cap')->query("
UPDATE ". BB_CAPTCHA ." SET
cap_id = -cap_id,
cap_expire = $cap_expire_time
WHERE cap_id > 0
ORDER BY cap_id
LIMIT $expire_img_count
");
//
// Удаление старых
//
$del_ids = DB('cap')->fetch_rowset("SELECT cap_id FROM ". BB_CAPTCHA ." WHERE cap_id < 0 AND cap_expire < ". TIMENOW, 'cap_id');
foreach ($del_ids as $del_id)
{
$cap_img_path = CAPTCHA()->get_img_path(abs($del_id));
if (@fopen($cap_img_path, 'r'))
{
unlink($cap_img_path);
}
DB('cap')->query("DELETE FROM ". BB_CAPTCHA ." WHERE cap_id = $del_id LIMIT 1");
}

View file

@ -0,0 +1,80 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
// Delete staled dl-status records
$keeping_dlstat = array(
DL_STATUS_WILL => (int) $bb_cfg['dl_will_days_keep'],
DL_STATUS_DOWN => (int) $bb_cfg['dl_down_days_keep'],
DL_STATUS_COMPLETE => (int) $bb_cfg['dl_complete_days_keep'],
DL_STATUS_CANCEL => (int) $bb_cfg['dl_cancel_days_keep'],
);
$delete_dlstat_sql = array();
foreach ($keeping_dlstat as $dl_status => $days_to_keep)
{
if ($days_to_keep)
{
$delete_dlstat_sql[] = "
user_status = $dl_status
AND
last_modified_dlstatus < DATE_SUB(NOW(), INTERVAL $days_to_keep DAY)
";
}
}
if ($delete_dlstat_sql = join(') OR (', $delete_dlstat_sql))
{
DB()->query("DELETE QUICK FROM ". BB_BT_DLSTATUS ." WHERE ($delete_dlstat_sql)");
}
// Delete orphans
DB()->query("
DELETE QUICK dl
FROM ". BB_BT_DLSTATUS ." dl
LEFT JOIN ". BB_USERS ." u USING(user_id)
WHERE u.user_id IS NULL
");
DB()->query("
DELETE QUICK dl
FROM ". BB_BT_DLSTATUS ." dl
LEFT JOIN ". BB_TOPICS ." t USING(topic_id)
WHERE t.topic_id IS NULL
");
// Tor-Stats cleanup
if ($torstat_days_keep = intval($bb_cfg['torstat_days_keep']))
{
DB()->query("DELETE QUICK FROM ". BB_BT_TORSTAT ." WHERE last_modified_torstat < DATE_SUB(NOW(), INTERVAL $torstat_days_keep DAY)");
}
DB()->query("
DELETE QUICK tst
FROM ". BB_BT_TORSTAT ." tst
LEFT JOIN ". BB_BT_TORRENTS ." tor USING(topic_id)
WHERE tor.topic_id IS NULL
");
DB()->query("
UPDATE
". BB_BT_USERS ."
SET
up_yesterday = up_today,
down_yesterday = down_today,
up_release_yesterday = up_release_today,
up_bonus_yesterday = up_bonus_today,
points_yesterday = points_today
");
DB()->query("
UPDATE
". BB_BT_USERS ."
SET
up_today = 0,
down_today = 0,
up_release_today = 0,
up_bonus_today = 0,
points_today = 0
");

View file

@ -0,0 +1,10 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$log_days_keep = (int) $bb_cfg['log_days_keep'];
DB()->query("
DELETE FROM ". BB_LOG ."
WHERE log_time < ". (TIMENOW - 86400*$log_days_keep) ."
");

View file

@ -0,0 +1,10 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$search_results_expire = TIMENOW - 3*3600;
DB()->query("
DELETE FROM ". BB_SEARCH ."
WHERE search_time < $search_results_expire
");

View file

@ -0,0 +1,5 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$datastore->update('cat_forums');

View file

@ -0,0 +1,5 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$datastore->update('stats');

View file

@ -0,0 +1,26 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
// Lock tables
DB()->lock(array(
BB_TOPICS .' t',
BUF_TOPIC_VIEW .' buf',
));
// Flash buffered records
DB()->query("
UPDATE
". BB_TOPICS ." t,
". BUF_TOPIC_VIEW ." buf
SET
t.topic_views = t.topic_views + buf.topic_views
WHERE
t.topic_id = buf.topic_id
");
// Delete buffered records
DB()->query("DELETE buf FROM ". BUF_TOPIC_VIEW ." buf");
// Unlock tables
DB()->unlock();

View file

@ -0,0 +1,15 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
require_once(INC_DIR .'functions_admin.php');
if ($bb_cfg['prune_enable'])
{
$sql = "SELECT forum_id, prune_days FROM ". BB_FORUMS ." WHERE prune_days != 0";
foreach (DB()->fetch_rowset($sql) as $row)
{
topic_delete('prune', $row['forum_id'], (TIMENOW - 86400*$row['prune_days']));
}
}

View file

@ -0,0 +1,57 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
require_once(INC_DIR .'functions_admin.php');
$users_per_cycle = 1000;
while (true)
{
@set_time_limit(600);
$prune_users = $not_activated_users = $not_active_users = array();
if ($not_activated_days = intval($bb_cfg['user_not_activated_days_keep']))
{
$sql = DB()->fetch_rowset("SELECT user_id FROM ". BB_USERS ."
WHERE user_level = 0
AND user_lastvisit = 0
AND user_session_time = 0
AND user_regdate <= ". (TIMENOW - 86400 * $not_activated_days) ."
AND user_id NOT IN(". EXCLUDED_USERS_CSV .")
LIMIT $users_per_cycle");
foreach ($sql as $row)
{
$not_activated_users[] = $row['user_id'];
}
}
if ($not_active_days = intval($bb_cfg['user_not_active_days_keep']))
{
$sql = DB()->fetch_rowset("SELECT user_id FROM ". BB_USERS ."
WHERE user_level = 0
AND user_posts = 0
AND user_lastvisit <= ". (TIMENOW - 86400 * $not_active_days) ."
AND user_id NOT IN(". EXCLUDED_USERS_CSV .")
LIMIT $users_per_cycle");
foreach ($sql as $row)
{
$not_active_users[] = $row['user_id'];
}
}
if ($prune_users = $not_activated_users + $not_active_users)
{
user_delete($prune_users);
}
if (count($prune_users) < $users_per_cycle)
{
break;
}
sleep(3);
}

View file

@ -0,0 +1,14 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
if ($bb_cfg['topic_moved_days_keep'])
{
$prune_time = TIMENOW - 86400*$bb_cfg['topic_moved_days_keep'];
DB()->query("
DELETE FROM ". BB_TOPICS ."
WHERE topic_status = ". TOPIC_MOVED ."
AND topic_time < $prune_time
");
}

View file

@ -0,0 +1,47 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$user_session_expire_time = TIMENOW - intval($bb_cfg['user_session_duration']);
$admin_session_expire_time = TIMENOW - intval($bb_cfg['admin_session_duration']);
$user_session_gc_time = $user_session_expire_time - intval($bb_cfg['user_session_gc_ttl']);
$admin_session_gc_time = $admin_session_expire_time;
// ############################ Tables LOCKED ################################
DB()->lock(array(
BB_USERS .' u',
BB_SESSIONS .' s',
));
// Update user's session time
DB()->query("
UPDATE
". BB_USERS ." u,
". BB_SESSIONS ." s
SET
u.user_session_time = IF(u.user_session_time < s.session_time, s.session_time, u.user_session_time)
WHERE
u.user_id = s.session_user_id
AND s.session_user_id != ". GUEST_UID ."
AND (
(s.session_time < $user_session_expire_time AND s.session_admin = 0)
OR
(s.session_time < $admin_session_expire_time AND s.session_admin != 0)
)
");
DB()->unlock();
// ############################ Tables UNLOCKED ##############################
sleep(5);
// Delete staled sessions
DB()->query("
DELETE s
FROM ". BB_SESSIONS ." s
WHERE
(s.session_time < $user_session_gc_time AND s.session_admin = 0)
OR
(s.session_time < $admin_session_gc_time AND s.session_admin != 0)
");

View file

@ -0,0 +1,18 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
require(CLASS_DIR .'sitemap.php');
$map = new sitemap();
$map->create();
if (@file_exists(BB_ROOT. "/sitemap/sitemap.xml"))
{
$map_link = make_url('/sitemap/sitemap.xml');
$map->send_url("http://google.com/webmasters/sitemaps/ping?sitemap=", $map_link);
$map->send_url("http://ping.blogs.yandex.ru/ping?sitemap=", $map_link);
$map->send_url("http://www.bing.com/ping?sitemap=", $map_link);
$map->send_url("http://rpc.weblogs.com/pingSiteForm?name=InfraBlog&url=", $map_link);
}

View file

@ -0,0 +1,205 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$releaser = DL_STATUS_RELEASER;
define('NEW_BB_BT_LAST_TORSTAT', 'new_bt_last_torstat');
define('OLD_BB_BT_LAST_TORSTAT', 'old_bt_last_torstat');
define('NEW_BB_BT_LAST_USERSTAT', 'new_bt_last_userstat');
define('OLD_BB_BT_LAST_USERSTAT', 'old_bt_last_userstat');
DB()->query("DROP TABLE IF EXISTS ". NEW_BB_BT_LAST_TORSTAT .", ". NEW_BB_BT_LAST_USERSTAT);
DB()->query("DROP TABLE IF EXISTS ". OLD_BB_BT_LAST_TORSTAT .", ". OLD_BB_BT_LAST_USERSTAT);
DB()->query("CREATE TABLE ". NEW_BB_BT_LAST_TORSTAT ." LIKE ". BB_BT_LAST_TORSTAT);
DB()->query("CREATE TABLE ". NEW_BB_BT_LAST_USERSTAT ." LIKE ". BB_BT_LAST_USERSTAT);
DB()->expect_slow_query(600);
// Update dlstat (part 1)
if ($tr_cfg['update_dlstat'])
{
// ############################ Tables LOCKED ################################
DB()->lock(array(
BB_BT_TRACKER,
NEW_BB_BT_LAST_TORSTAT,
));
// Get PER TORRENT user's dlstat from tracker
DB()->query("
INSERT INTO ". NEW_BB_BT_LAST_TORSTAT ."
(topic_id, user_id, dl_status, up_add, down_add, release_add, speed_up, speed_down)
SELECT
topic_id, user_id, IF(releaser, $releaser, seeder), SUM(up_add), SUM(down_add), IF(releaser, SUM(up_add), 0), SUM(speed_up), SUM(speed_down)
FROM ". BB_BT_TRACKER ."
WHERE (up_add != 0 OR down_add != 0)
GROUP BY topic_id, user_id
");
// Reset up/down additions in tracker
DB()->query("UPDATE ". BB_BT_TRACKER ." SET up_add = 0, down_add = 0");
DB()->unlock();
// ############################ Tables UNLOCKED ##############################
}
// Update last seeder info in BUF
DB()->query("
REPLACE INTO ". BUF_LAST_SEEDER ."
(topic_id, seeder_last_seen)
SELECT
topic_id, ". TIMENOW ."
FROM ". BB_BT_TRACKER ."
WHERE seeder = 1
GROUP BY topic_id
");
// Clean peers table
if ($tr_cfg['autoclean'])
{
$announce_interval = max(intval($bb_cfg['announce_interval']), 60);
$expire_factor = max(floatval($tr_cfg['expire_factor']), 1);
$peer_expire_time = TIMENOW - floor($announce_interval * $expire_factor);
DB()->query("DELETE FROM ". BB_BT_TRACKER ." WHERE update_time < $peer_expire_time");
}
// Update dlstat (part 2)
if ($tr_cfg['update_dlstat'])
{
// Set "only 1 seeder" bonus
DB()->query("
UPDATE
". NEW_BB_BT_LAST_TORSTAT ." tb,
". BB_BT_TRACKER_SNAP ." sn
SET
tb.bonus_add = tb.up_add
WHERE
tb.topic_id = sn.topic_id
AND sn.seeders = 1
AND tb.up_add != 0
AND tb.dl_status = ". DL_STATUS_COMPLETE ."
");
// Get SUMMARIZED user's dlstat
DB()->query("
INSERT INTO ". NEW_BB_BT_LAST_USERSTAT ."
(user_id, up_add, down_add, release_add, bonus_add, speed_up, speed_down)
SELECT
user_id, SUM(up_add), SUM(down_add), SUM(release_add), SUM(bonus_add), SUM(speed_up), SUM(speed_down)
FROM ". NEW_BB_BT_LAST_TORSTAT ."
GROUP BY user_id
");
// Update TOTAL user's dlstat
DB()->query("
UPDATE
". BB_BT_USERS ." u,
". NEW_BB_BT_LAST_USERSTAT ." ub
SET
u.u_up_total = u.u_up_total + ub.up_add,
u.u_down_total = u.u_down_total + ub.down_add,
u.u_up_release = u.u_up_release + ub.release_add,
u.u_up_bonus = u.u_up_bonus + ub.bonus_add,
u.up_today = u.up_today + ub.up_add,
u.down_today = u.down_today + ub.down_add,
u.up_release_today = u.up_release_today + ub.release_add,
u.up_bonus_today = u.up_bonus_today + ub.bonus_add
WHERE u.user_id = ub.user_id
");
// Delete from dl_list what exists in BUF but not exsits in NEW
DB()->query("
DELETE dl
FROM ". BB_BT_DLSTATUS ." dl
INNER JOIN ". NEW_BB_BT_LAST_TORSTAT ." buf USING(user_id, topic_id)
WHERE buf.user_id IS NULL
AND buf.topic_id IS NULL
");
// Update DL-Status
DB()->query("
REPLACE INTO ". BB_BT_DLSTATUS ."
(user_id, topic_id, user_status)
SELECT
user_id, topic_id, dl_status
FROM ". NEW_BB_BT_LAST_TORSTAT ."
");
// Update PER TORRENT DL-Status (for "completed" counter)
DB()->query("
INSERT IGNORE INTO ". BB_BT_TORSTAT ."
(topic_id, user_id)
SELECT
topic_id, user_id
FROM ". NEW_BB_BT_LAST_TORSTAT ."
WHERE dl_status = ". DL_STATUS_COMPLETE ."
");
}
DB()->query("
RENAME TABLE
". BB_BT_LAST_TORSTAT ." TO ". OLD_BB_BT_LAST_TORSTAT .",
". NEW_BB_BT_LAST_TORSTAT ." TO ". BB_BT_LAST_TORSTAT ."
");
DB()->query("DROP TABLE IF EXISTS ". NEW_BB_BT_LAST_TORSTAT .", ". OLD_BB_BT_LAST_TORSTAT);
DB()->query("
RENAME TABLE
". BB_BT_LAST_USERSTAT ." TO ". OLD_BB_BT_LAST_USERSTAT .",
". NEW_BB_BT_LAST_USERSTAT ." TO ". BB_BT_LAST_USERSTAT ."
");
DB()->query("DROP TABLE IF EXISTS ". NEW_BB_BT_LAST_USERSTAT .", ". OLD_BB_BT_LAST_USERSTAT);
DB()->expect_slow_query(10);
if($bb_cfg['seed_bonus_enabled'] && $bb_cfg['seed_bonus_points'] && $bb_cfg['seed_bonus_release'])
{
DB()->query("
CREATE TEMPORARY TABLE tmp_bonus (
user_id INT UNSIGNED NOT NULL DEFAULT '0',
release_count INT UNSIGNED NOT NULL DEFAULT '0'
) ENGINE = MEMORY
");
$tor_size = ($bb_cfg['seed_bonus_tor_size'] * 1073741824);
DB()->query("INSERT INTO tmp_bonus
SELECT bt.user_id, count(bt.seeder) AS release_count
FROM ". BB_BT_TRACKER ." bt, ". BB_BT_TORRENTS ." tor
WHERE tor.topic_id = bt.topic_id
AND tor.size > $tor_size
AND bt.seeder > 0
GROUP BY user_id
");
$seed_bonus = unserialize($bb_cfg['seed_bonus_points']);
$seed_release = unserialize($bb_cfg['seed_bonus_release']);
foreach($seed_bonus as $i => $points)
{
if(!$points || !$seed_release[$i]) continue;
$user_points = ($points / 4);
$release = $seed_release[$i];
$user_regdate = (TIMENOW - $bb_cfg['seed_bonus_user_regdate'] * 86400);
DB()->query("
UPDATE ". BB_USERS ." u, ". BB_BT_USERS ." bu, tmp_bonus b
SET
u.user_points = u.user_points + $user_points,
bu.points_today = bu.points_today + $user_points,
b.user_id = 0
WHERE
b.user_id = u.user_id
AND bu.user_id = u.user_id
AND b.release_count <= $release
AND u.user_regdate < $user_regdate
AND u.user_active = 1
AND u.user_id not IN(". EXCLUDED_USERS_CSV .")
");
}
DB()->query("DROP TEMPORARY TABLE IF EXISTS tmp_bonus");
}

View file

@ -0,0 +1,48 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
global $bb_cfg;
if ($bb_cfg['ocelot']['enabled'])
{
// Update TORRENT "completed" counters
DB()->query("
UPDATE
". BB_BT_TORRENTS ." tor,
". BB_BT_TRACKER_SNAP. " snap
SET
tor.complete_count = snap.complete
WHERE
tor.topic_id = snap.topic_id
");
}
else
{
// Get complete counts
DB()->query("
CREATE TEMPORARY TABLE tmp_complete_count
SELECT
topic_id, COUNT(*) AS compl_cnt
FROM ". BB_BT_TORSTAT ."
WHERE completed = 0
GROUP BY topic_id
");
// Update USER "completed" counters
DB()->query("UPDATE ". BB_BT_TORSTAT ." SET completed = 1");
// Update TORRENT "completed" counters
DB()->query("
UPDATE
". BB_BT_TORRENTS ." tor,
tmp_complete_count tmp
SET
tor.complete_count = tor.complete_count + tmp.compl_cnt
WHERE
tor.topic_id = tmp.topic_id
");
// Drop tmp table
DB()->query("DROP TEMPORARY TABLE tmp_complete_count");
}

View file

@ -0,0 +1,56 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
if (empty($bb_cfg['seeder_last_seen_days_keep']) || empty($bb_cfg['seeder_never_seen_days_keep']))
{
return;
}
$last_seen_time = TIMENOW - 86400*$bb_cfg['seeder_last_seen_days_keep'];
$never_seen_time = TIMENOW - 86400*$bb_cfg['seeder_never_seen_days_keep'];
$limit_sql = 3000;
$topics_sql = $attach_sql = array();
$sql = "SELECT topic_id, attach_id
FROM ". BB_BT_TORRENTS ."
WHERE reg_time < $never_seen_time
AND seeder_last_seen < $last_seen_time
LIMIT $limit_sql";
foreach (DB()->fetch_rowset($sql) as $row)
{
$topics_sql[] = $row['topic_id'];
$attach_sql[] = $row['attach_id'];
}
$dead_tor_sql = join(',', $topics_sql);
$attach_sql = join(',', $attach_sql);
if ($dead_tor_sql && $attach_sql)
{
// Delete torstat
DB()->query("
DELETE FROM ". BB_BT_TORSTAT ."
WHERE topic_id IN($dead_tor_sql)
");
// Update attach
DB()->query("
UPDATE
". BB_ATTACHMENTS_DESC ." a,
". BB_BT_TORRENTS ." tor
SET
a.tracker_status = 0,
a.download_count = tor.complete_count
WHERE
a.attach_id = tor.attach_id
AND tor.attach_id IN($attach_sql)
");
// Remove torrents
DB()->query("
DELETE FROM ". BB_BT_TORRENTS ."
WHERE topic_id IN($dead_tor_sql)
");
}

View file

@ -0,0 +1,205 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
global $bb_cfg;
DB()->expect_slow_query(600);
//
// Make tracker snapshot
//
if (!$bb_cfg['ocelot']['enabled'])
{
define('NEW_BB_BT_TRACKER_SNAP', 'new_tracker_snap');
define('OLD_BB_BT_TRACKER_SNAP', 'old_tracker_snap');
DB()->query("DROP TABLE IF EXISTS " . NEW_BB_BT_TRACKER_SNAP . ", " . OLD_BB_BT_TRACKER_SNAP);
DB()->query("CREATE TABLE " . NEW_BB_BT_TRACKER_SNAP . " LIKE " . BB_BT_TRACKER_SNAP);
}
$per_cycle = 50000;
$row = DB()->fetch_row("SELECT MIN(topic_id) AS start_id, MAX(topic_id) AS finish_id FROM ". BB_BT_TRACKER);
$start_id = (int) $row['start_id'];
$finish_id = (int) $row['finish_id'];
while (true)
{
set_time_limit(600);
$end_id = $start_id + $per_cycle - 1;
$val = array();
if (!$bb_cfg['ocelot']['enabled'])
{
$sql = "
SELECT
topic_id, SUM(seeder) AS seeders, (COUNT(*) - SUM(seeder)) AS leechers,
SUM(speed_up) AS speed_up, SUM(speed_down) AS speed_down
FROM " . BB_BT_TRACKER . "
WHERE topic_id BETWEEN $start_id AND $end_id
GROUP BY topic_id
";
}
else
{
$sql = "
SELECT
topic_id, SUM(speed_up) AS speed_up, SUM(speed_down) AS speed_down
FROM " . BB_BT_TRACKER . "
WHERE topic_id BETWEEN $start_id AND $end_id
GROUP BY topic_id
";
}
foreach (DB()->fetch_rowset($sql) as $row)
{
$val[] = join(',', $row);
}
if ($val)
{
if (!$bb_cfg['ocelot']['enabled'])
{
DB()->query("
REPLACE INTO " . NEW_BB_BT_TRACKER_SNAP . "
(topic_id, seeders, leechers, speed_up, speed_down)
VALUES(" . join('),(', $val) . ")
");
}
else
{
DB()->query("
INSERT INTO " . BB_BT_TRACKER_SNAP . "
(topic_id, speed_up, speed_down)
VALUES(". join('),(', $val) .")
ON DUPLICATE KEY UPDATE speed_up = VALUES(speed_up), speed_down = VALUES(speed_down)
");
}
}
if ($end_id > $finish_id)
{
break;
}
if (!($start_id % ($per_cycle*10)))
{
sleep(1);
}
$start_id += $per_cycle;
}
if (!$bb_cfg['ocelot']['enabled'])
{
DB()->query("
RENAME TABLE
". BB_BT_TRACKER_SNAP ." TO ". OLD_BB_BT_TRACKER_SNAP .",
". NEW_BB_BT_TRACKER_SNAP ." TO ". BB_BT_TRACKER_SNAP ."
");
DB()->query("DROP TABLE IF EXISTS ". NEW_BB_BT_TRACKER_SNAP .", ". OLD_BB_BT_TRACKER_SNAP);
}
//
// Make dl-list snapshot
//
define('NEW_BB_BT_DLSTATUS_SNAP', 'new_dlstatus_snap');
define('OLD_BB_BT_DLSTATUS_SNAP', 'old_dlstatus_snap');
DB()->query("DROP TABLE IF EXISTS ". NEW_BB_BT_DLSTATUS_SNAP .", ". OLD_BB_BT_DLSTATUS_SNAP);
DB()->query("CREATE TABLE ". NEW_BB_BT_DLSTATUS_SNAP ." LIKE ". BB_BT_DLSTATUS_SNAP);
if ($bb_cfg['bt_show_dl_list'] && $bb_cfg['bt_dl_list_only_count'])
{
DB()->query("
INSERT INTO ". NEW_BB_BT_DLSTATUS_SNAP ."
(topic_id, dl_status, users_count)
SELECT
topic_id, user_status, COUNT(*)
FROM ". BB_BT_DLSTATUS ."
WHERE user_status != ". DL_STATUS_RELEASER ."
GROUP BY topic_id, user_status
");
}
DB()->query("
RENAME TABLE
". BB_BT_DLSTATUS_SNAP ." TO ". OLD_BB_BT_DLSTATUS_SNAP .",
". NEW_BB_BT_DLSTATUS_SNAP ." TO ". BB_BT_DLSTATUS_SNAP ."
");
DB()->query("DROP TABLE IF EXISTS ". NEW_BB_BT_DLSTATUS_SNAP .", ". OLD_BB_BT_DLSTATUS_SNAP);
//
// TORHELP
//
if ($bb_cfg['torhelp_enabled'])
{
$tor_min_seeders = 0; // "<="
$tor_min_leechers = 2; // ">="
$tor_min_completed = 10; // ">="
$tor_seed_last_seen_days = 3; // "<="
$tor_downloaded_days_ago = 60; // ">="
$user_last_seen_online = 15; // minutes
$users_limit = 3000;
$dl_status_ary = array(DL_STATUS_COMPLETE);
define('NEW_BB_BT_TORHELP', 'new_torhelp');
define('OLD_BB_BT_TORHELP', 'old_torhelp');
DB()->query("DROP TABLE IF EXISTS ". NEW_BB_BT_TORHELP .", ". OLD_BB_BT_TORHELP);
DB()->query("CREATE TABLE ". NEW_BB_BT_TORHELP ." LIKE ". BB_BT_TORHELP);
// Select users
$sql = "
SELECT DISTINCT session_user_id AS uid
FROM ". BB_SESSIONS ."
WHERE session_time > (UNIX_TIMESTAMP() - $user_last_seen_online*60)
AND session_user_id != ". GUEST_UID ."
ORDER BY session_time DESC
LIMIT $users_limit
";
$online_users_ary = array();
foreach (DB()->fetch_rowset($sql) as $row)
{
$online_users_ary[] = $row['uid'];
}
if ($online_users_csv = join(',', $online_users_ary))
{
DB()->query("
INSERT INTO ". NEW_BB_BT_TORHELP ." (user_id, topic_id_csv)
SELECT
dl.user_id, GROUP_CONCAT(dl.topic_id)
FROM ". BB_BT_TRACKER_SNAP ." trsn
INNER JOIN ". BB_BT_TORRENTS ." tor ON (tor.topic_id = trsn.topic_id)
INNER JOIN ". BB_BT_DLSTATUS ." dl ON (dl.topic_id = tor.topic_id)
WHERE
trsn.seeders <= $tor_min_seeders
AND trsn.leechers >= $tor_min_leechers
AND tor.forum_id != ". (int) $bb_cfg['trash_forum_id'] ."
AND tor.complete_count >= $tor_min_completed
AND tor.seeder_last_seen <= (UNIX_TIMESTAMP() - $tor_seed_last_seen_days*86400)
AND dl.user_id IN($online_users_csv)
AND dl.user_status IN(". get_id_csv($dl_status_ary) .")
AND dl.last_modified_dlstatus > DATE_SUB(NOW(), INTERVAL $tor_downloaded_days_ago DAY)
GROUP BY dl.user_id
LIMIT 10000
");
}
DB()->query("
RENAME TABLE
". BB_BT_TORHELP ." TO ". OLD_BB_BT_TORHELP .",
". NEW_BB_BT_TORHELP ." TO ". BB_BT_TORHELP ."
");
DB()->query("DROP TABLE IF EXISTS ". NEW_BB_BT_TORHELP .", ". OLD_BB_BT_TORHELP);
}
DB()->expect_slow_query(10);

View file

@ -0,0 +1,15 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
DB()->query("
UPDATE
". BUF_LAST_SEEDER ." b,
". BB_BT_TORRENTS ." tor
SET
tor.seeder_last_seen = b.seeder_last_seen
WHERE
tor.topic_id = b.topic_id
");
DB()->query("TRUNCATE TABLE ". BUF_LAST_SEEDER);

View file

@ -0,0 +1,31 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
global $bb_cfg;
require_once(INC_DIR .'functions_atom.php');
$timecheck = TIMENOW - 600;
$forums_data = DB()->fetch_rowset("SELECT forum_id, allow_reg_tracker, forum_name FROM ". BB_FORUMS);
if (file_exists($bb_cfg['atom']['path'] .'/f/0.atom'))
{
if (filemtime($bb_cfg['atom']['path'] .'/f/0.atom') <= $timecheck) update_forum_feed(0, $forums_data);
}
else
{
update_forum_feed(0, $forums_data);
}
foreach ($forums_data as $forum_data)
{
if (file_exists($bb_cfg['atom']['path'] .'/f/'. $forum_data['forum_id'] .'.atom'))
{
if (filemtime($bb_cfg['atom']['path'] .'/f/'. $forum_data['forum_id'] .'.atom') <= $timecheck) update_forum_feed($forum_data['forum_id'], $forum_data);
}
else
{
update_forum_feed($forum_data['forum_id'], $forum_data);
}
}

View file

@ -0,0 +1,2 @@
order allow,deny
deny from all

View file

@ -0,0 +1,17 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
// Don't count on forbidden extensions table, because it is not allowed to allow forbidden extensions at all
$extensions = DB()->fetch_rowset("
SELECT
e.extension, g.cat_id, g.download_mode, g.upload_icon
FROM
". BB_EXTENSIONS ." e,
". BB_EXTENSION_GROUPS ." g
WHERE
e.group_id = g.group_id
AND g.allow_group = 1
");
$this->store('attach_extensions', $extensions);

View file

@ -0,0 +1,195 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
global $bf, $bb_cfg;
//
// cat_forums
//
$data = array(
'not_auth_forums' => array(
'guest_view' => array(),
'guest_read' => array(),
'user_view' => array(),
'user_read' => array(),
),
'tracker_forums' => array(),
'cat_title_html' => array(),
'forum_name_html' => array(),
'c' => array(), // also has $data['c']['cat_id']['forums'] key
'f' => array(), // also has $data['f']['forum_id']['subforums'] key
);
// Store only these fields from BB_FORUMS in $data['f']
$forum_store_fields = array_flip(array_keys($bf['forum_perm']));
$forum_store_fields += array_flip(array(
'forum_id',
'cat_id',
'forum_name',
'forum_desc',
'forum_status',
'forum_posts',
'forum_topics',
'forum_parent',
));
// Categories
$sql = "SELECT * FROM ". BB_CATEGORIES ." ORDER BY cat_order";
foreach(DB()->fetch_rowset($sql) as $row)
{
$data['c'][$row['cat_id']] = $row;
$data['cat_title_html'][$row['cat_id']] = htmlCHR($row['cat_title']);
}
$sql = "
SELECT f.*
FROM ". BB_FORUMS ." f, ". BB_CATEGORIES ." c
WHERE f.cat_id = c.cat_id
ORDER BY c.cat_order, f.forum_order
";
foreach (DB()->fetch_rowset($sql) as $row)
{
$fid = $row['forum_id'];
$not_auth =& $data['not_auth_forums'];
// Find not auth forums
if ($row['auth_view'] != AUTH_ALL)
{
$not_auth['guest_view'][] = $fid;
}
if ($row['auth_view'] != AUTH_ALL && $row['auth_view'] != AUTH_REG)
{
$not_auth['user_view'][] = $fid;
}
if ($row['auth_read'] != AUTH_ALL)
{
$not_auth['guest_read'][] = $fid;
}
if ($row['auth_read'] != AUTH_ALL && $row['auth_read'] != AUTH_REG)
{
$not_auth['user_read'][] = $fid;
}
$data['forum'][$fid] = $row;
// Store forums data
if ($parent_id = $row['forum_parent'])
{
$parent =& $data['f'][$parent_id];
$parent['subforums'][] = $fid;
$parent['forum_posts'] += $row['forum_posts'];
$parent['forum_topics'] += $row['forum_topics'];
}
if ($row['allow_reg_tracker'])
{
$data['tracker_forums'][] = $fid;
}
$data['f'][$fid] = array_intersect_key($row, $forum_store_fields);
$data['forum_name_html'][$fid] = htmlCHR($row['forum_name']);
// Forum ids in cat
$data['c'][$row['cat_id']]['forums'][] = $fid;
}
foreach ($data['not_auth_forums'] as $key => $val)
{
$data['not_auth_forums'][$key] = join(',', $val);
}
$data['tracker_forums'] = join(',', $data['tracker_forums']);
$this->store('cat_forums', $data);
//
// jumpbox
//
$data = array(
'guest' => get_forum_select('guest', 'f', null, null, null, 'id="jumpbox" onchange="window.location.href=\'viewforum.php?f=\'+this.value;"'),
'user' => get_forum_select('user', 'f', null, null, null, 'id="jumpbox" onchange="window.location.href=\'viewforum.php?f=\'+this.value;"'),
);
$this->store('jumpbox', $data);
file_write($data['guest'], AJAX_HTML_DIR .'jumpbox_guest.html', false, true, true);
file_write($data['user'], AJAX_HTML_DIR .'jumpbox_user.html', false, true, true);
//
// viewtopic_forum_select
//
$data = array(
'viewtopic_forum_select' => get_forum_select('admin', 'new_forum_id'),
);
$this->store('viewtopic_forum_select', $data);
//
// latest_news
//
if ($bb_cfg['show_latest_news'] AND $news_forum_ids = $bb_cfg['latest_news_forum_id'])
{
$news_count = max($bb_cfg['latest_news_count'], 1);
$data = DB()->fetch_rowset("
SELECT topic_id, topic_time, topic_title, forum_id
FROM ". BB_TOPICS ."
WHERE forum_id IN ($news_forum_ids)
AND topic_moved_id = 0
ORDER BY topic_time DESC
LIMIT $news_count
");
$this->store('latest_news', $data);
}
//
// Network_news
//
if ($bb_cfg['show_network_news'] AND $net_forum_ids = $bb_cfg['network_news_forum_id'])
{
$net_count = max($bb_cfg['network_news_count'], 1);
$data = DB()->fetch_rowset("
SELECT topic_id, topic_time, topic_title, forum_id
FROM ". BB_TOPICS ."
WHERE forum_id IN ($net_forum_ids)
AND topic_moved_id = 0
ORDER BY topic_time DESC
LIMIT $net_count
");
$this->store('network_news', $data);
}
//
// Ads
//
if ($bb_cfg['show_ads'])
{
$ad_html = $ad_block_assignment = array();
$active_ads = DB()->fetch_rowset("
SELECT *
FROM ". BB_ADS ."
WHERE ad_status = 1
AND ad_start_time < NOW()
AND DATE_ADD(ad_start_time, INTERVAL ad_active_days DAY) > NOW()
");
foreach ($active_ads as $ad)
{
if ($ad['ad_block_ids'])
{
foreach(explode(',', $ad['ad_block_ids']) as $block_id)
{
$ad_block_assignment[$block_id][] = $ad['ad_id'];
}
}
$ad_html[$ad['ad_id']] = $ad['ad_html'];
}
$this->store('ads', $ad_html);
bb_update_config(array('active_ads' => serialize($ad_block_assignment)));
}

View file

@ -0,0 +1,107 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$data = array(
'name_users' => array(), // only by personal permissions
'name_groups' => array(), // only visible to all users
'mod_users' => array(), // only by personal permissions
'mod_groups' => array(), // only visible to all users
'moderators' => array(), // all moderators
'admins' => array(), // all admins
);
// name_users
// mod_users
$sql = "
SELECT
aa.forum_id, u.user_id, u.username
FROM
". BB_AUTH_ACCESS ." aa,
". BB_USER_GROUP ." ug,
". BB_GROUPS ." g,
". BB_USERS ." u
WHERE
aa.forum_perm & ". BF_AUTH_MOD ."
AND ug.group_id = aa.group_id
AND ug.user_pending = 0
AND g.group_id = ug.group_id
AND g.group_single_user = 1
AND u.user_id = ug.user_id
GROUP BY
aa.forum_id, u.user_id
ORDER BY
u.username
";
foreach (DB()->fetch_rowset($sql) as $row)
{
$data['name_users'][$row['user_id']] = $row['username'];
$data['mod_users'][$row['forum_id']][] = $row['user_id'];
}
// name_groups
// mod_groups
$sql = "
SELECT
aa.forum_id, g.group_id, g.group_name
FROM
". BB_AUTH_ACCESS ." aa,
". BB_GROUPS ." g
WHERE
aa.forum_perm & ". BF_AUTH_MOD ."
AND g.group_id = aa.group_id
AND g.group_single_user = 0
AND g.group_type != ". GROUP_HIDDEN ."
GROUP BY
aa.forum_id, g.group_id
ORDER BY
g.group_name
";
foreach (DB()->fetch_rowset($sql) as $row)
{
$data['name_groups'][$row['group_id']] = $row['group_name'];
$data['mod_groups'][$row['forum_id']][] = $row['group_id'];
}
// moderators
$sql = "
SELECT
u.user_id, u.username
FROM
". BB_AUTH_ACCESS ." aa,
". BB_USER_GROUP ." ug,
". BB_GROUPS ." g,
". BB_USERS ." u
WHERE
aa.forum_perm & ". BF_AUTH_MOD ."
AND ug.group_id = aa.group_id
AND ug.user_pending = 0
AND g.group_id = ug.group_id
AND u.user_id = ug.user_id
GROUP BY
u.user_id
ORDER BY
u.username
";
foreach (DB()->fetch_rowset($sql) as $row)
{
$data['moderators'][$row['user_id']] = $row['username'];
}
// admins
$sql = "
SELECT user_id, username
FROM ". BB_USERS ."
WHERE user_level = ". ADMIN ."
ORDER BY username
";
foreach (DB()->fetch_rowset($sql) as $row)
{
$data['admins'][$row['user_id']] = $row['username'];
}
$this->store('moderators', $data);

View file

@ -0,0 +1,14 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$ranks = array();
$sql = "SELECT rank_id, rank_title, rank_image, rank_style FROM ". BB_RANKS;
foreach (DB()->fetch_rowset($sql) as $row)
{
$ranks[$row['rank_id']] = $row;
}
$this->store('ranks', $ranks);

View file

@ -0,0 +1,19 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
global $bb_cfg;
$smilies = array();
$rowset = DB()->fetch_rowset("SELECT * FROM ". BB_SMILIES);
sort($rowset);
foreach ($rowset as $smile)
{
$smilies['orig'][] = '#(?<=^|\W)'. preg_quote($smile['code'], '#') .'(?=$|\W)#';
$smilies['repl'][] = ' <img class="smile" src="'. $bb_cfg['smilies_path'] .'/'. $smile['smile_url'] .'" alt="'. $smile['emoticon'] .'" align="absmiddle" border="0" />';
$smilies['smile'][] = $smile;
}
$this->store('smile_replacements', $smilies);

View file

@ -0,0 +1,96 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
global $bb_cfg;
$data = array();
// usercount
$row = DB()->fetch_row("SELECT COUNT(*) AS usercount FROM ". BB_USERS ." WHERE user_id NOT IN(". EXCLUDED_USERS_CSV .")");
$data['usercount'] = number_format($row['usercount']);
// newestuser
$row = DB()->fetch_row("SELECT user_id, username, user_rank FROM ". BB_USERS ." WHERE user_active = 1 ORDER BY user_id DESC LIMIT 1");
$data['newestuser'] = $row;
// post/topic count
$row = DB()->fetch_row("SELECT SUM(forum_topics) AS topiccount, SUM(forum_posts) AS postcount FROM ". BB_FORUMS);
$data['postcount'] = number_format($row['postcount']);
$data['topiccount'] = number_format($row['topiccount']);
// Tracker stats
if ($bb_cfg['tor_stats'])
{
// torrents stat
$row = DB()->fetch_row("SELECT COUNT(topic_id) AS torrentcount, SUM(size) AS size FROM ". BB_BT_TORRENTS);
$data['torrentcount'] = number_format($row['torrentcount']);
$data['size'] = $row['size'];
// peers stat
$row = DB()->fetch_row("SELECT SUM(seeders) AS seeders, SUM(leechers) AS leechers, ((SUM(speed_up) + SUM(speed_down))/2) AS speed FROM ". BB_BT_TRACKER_SNAP);
$data['seeders'] = number_format($row['seeders']);
$data['leechers'] = number_format($row['leechers']);
$data['peers'] = number_format($row['seeders'] + $row['leechers']);
$data['speed'] = $row['speed'];
}
// gender stat
if ($bb_cfg['gender'])
{
$male = DB()->fetch_row("SELECT COUNT(user_id) AS male FROM ". BB_USERS ." WHERE user_gender = ". MALE ." AND user_id NOT IN(". EXCLUDED_USERS_CSV .")");
$female = DB()->fetch_row("SELECT COUNT(user_id) AS female FROM ". BB_USERS ." WHERE user_gender = ". FEMALE ." AND user_id NOT IN(". EXCLUDED_USERS_CSV .")");
$unselect = DB()->fetch_row("SELECT COUNT(user_id) AS unselect FROM ". BB_USERS ." WHERE user_gender = 0 AND user_id NOT IN(". EXCLUDED_USERS_CSV .")");
$data['male'] = $male['male'];
$data['female'] = $female['female'];
$data['unselect'] = $unselect['unselect'];
}
// birthday stat
if ($bb_cfg['birthday_check_day'] && $bb_cfg['birthday_enabled'])
{
$sql = DB()->fetch_rowset("SELECT user_id, username, user_rank , user_birthday
FROM ". BB_USERS ."
WHERE user_id NOT IN(". EXCLUDED_USERS_CSV .")
AND user_birthday != '0000-00-00'
AND user_active = 1
ORDER BY user_level DESC, username
");
$date_today = bb_date(TIMENOW, 'md', false);
$date_forward = bb_date(TIMENOW + ($bb_cfg['birthday_check_day']*86400), 'md', false);
$birthday_today_list = $birthday_week_list = array();
foreach ($sql as $row)
{
$user_birthday = date('md', strtotime($row['user_birthday']));
if ($user_birthday > $date_today && $user_birthday <= $date_forward)
{
// user are having birthday within the next days
$birthday_week_list[] = array(
'user_id' => $row['user_id'],
'username' => $row['username'],
'user_rank' => $row['user_rank'],
'user_birthday' => $row['user_birthday'],
);
}
elseif ($user_birthday == $date_today)
{
//user have birthday today
$birthday_today_list[] = array(
'user_id' => $row['user_id'],
'username' => $row['username'],
'user_rank' => $row['user_rank'],
'user_birthday' => $row['user_birthday'],
);
}
}
$data['birthday_today_list'] = $birthday_today_list;
$data['birthday_week_list'] = $birthday_week_list;
}
$this->store('stats', $data);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,805 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
function sync_all_forums ()
{
foreach (DB()->fetch_rowset("SELECT forum_id FROM ". BB_FORUMS) as $row)
{
sync('forum', $row['forum_id']);
}
}
function sync ($type, $id)
{
switch ($type)
{
case 'forum':
if (!$forum_csv = get_id_csv($id))
{
break;
}
// sync posts
$tmp_sync_forums = 'tmp_sync_forums';
DB()->query("
CREATE TEMPORARY TABLE $tmp_sync_forums (
forum_id SMALLINT UNSIGNED NOT NULL DEFAULT '0',
forum_last_post_id INT UNSIGNED NOT NULL DEFAULT '0',
forum_posts MEDIUMINT UNSIGNED NOT NULL DEFAULT '0',
forum_topics MEDIUMINT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (forum_id)
) ENGINE = MEMORY
");
DB()->add_shutdown_query("DROP TEMPORARY TABLE IF EXISTS $tmp_sync_forums");
// начальное обнуление значений
$forum_ary = explode(',', $forum_csv);
DB()->query("REPLACE INTO $tmp_sync_forums (forum_id) VALUES(". join('),(', $forum_ary) .")");
DB()->query("
REPLACE INTO $tmp_sync_forums
(forum_id, forum_last_post_id, forum_posts, forum_topics)
SELECT
forum_id,
MAX(topic_last_post_id),
SUM(topic_replies) + COUNT(topic_id),
COUNT(topic_id)
FROM ". BB_TOPICS ."
WHERE forum_id IN($forum_csv)
GROUP BY forum_id
");
DB()->query("
UPDATE
$tmp_sync_forums tmp, ". BB_FORUMS ." f
SET
f.forum_last_post_id = tmp.forum_last_post_id,
f.forum_posts = tmp.forum_posts,
f.forum_topics = tmp.forum_topics
WHERE
f.forum_id = tmp.forum_id
");
DB()->query("DROP TEMPORARY TABLE $tmp_sync_forums");
break;
case 'topic':
$all_topics = ($id === 'all');
if (!$all_topics AND !$topic_csv = get_id_csv($id))
{
break;
}
// Проверка на остаточные записи об уже удаленных топиках
DB()->query("DELETE FROM ". BB_TOPICS ." WHERE topic_first_post_id NOT IN (SELECT post_id FROM ". BB_POSTS .")");
$tmp_sync_topics = 'tmp_sync_topics';
DB()->query("
CREATE TEMPORARY TABLE $tmp_sync_topics (
topic_id INT UNSIGNED NOT NULL DEFAULT '0',
total_posts INT UNSIGNED NOT NULL DEFAULT '0',
topic_first_post_id INT UNSIGNED NOT NULL DEFAULT '0',
topic_last_post_id INT UNSIGNED NOT NULL DEFAULT '0',
topic_last_post_time INT UNSIGNED NOT NULL DEFAULT '0',
topic_attachment INT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (topic_id)
) ENGINE = MEMORY
");
DB()->add_shutdown_query("DROP TEMPORARY TABLE IF EXISTS $tmp_sync_topics");
$where_sql = (!$all_topics) ? "AND t.topic_id IN($topic_csv)" : '';
DB()->query("
INSERT INTO $tmp_sync_topics
SELECT
t.topic_id,
COUNT(p.post_id) AS total_posts,
MIN(p.post_id) AS topic_first_post_id,
MAX(p.post_id) AS topic_last_post_id,
MAX(p.post_time) AS topic_last_post_time,
IF(MAX(a.attach_id), 1, 0) AS topic_attachment
FROM ". BB_TOPICS ." t
LEFT JOIN ". BB_POSTS ." p ON(p.topic_id = t.topic_id)
LEFT JOIN ". BB_ATTACHMENTS ." a ON(a.post_id = p.post_id)
WHERE t.topic_status != ". TOPIC_MOVED ."
$where_sql
GROUP BY t.topic_id
");
DB()->query("
UPDATE
$tmp_sync_topics tmp, ". BB_TOPICS ." t
SET
t.topic_replies = tmp.total_posts - 1,
t.topic_first_post_id = tmp.topic_first_post_id,
t.topic_last_post_id = tmp.topic_last_post_id,
t.topic_last_post_time = tmp.topic_last_post_time,
t.topic_attachment = tmp.topic_attachment
WHERE
t.topic_id = tmp.topic_id
");
if ($topics = DB()->fetch_rowset("SELECT topic_id FROM ". $tmp_sync_topics ." WHERE total_posts = 0", 'topic_id'))
{
topic_delete($topics);
}
DB()->query("DROP TEMPORARY TABLE $tmp_sync_topics");
break;
case 'user_posts':
$all_users = ($id === 'all');
if (!$all_users AND !$user_csv = get_id_csv($id))
{
break;
}
$tmp_user_posts = 'tmp_sync_user_posts';
DB()->query("
CREATE TEMPORARY TABLE $tmp_user_posts (
user_id INT NOT NULL DEFAULT '0',
user_posts MEDIUMINT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (user_id)
) ENGINE = MEMORY
");
DB()->add_shutdown_query("DROP TEMPORARY TABLE IF EXISTS $tmp_user_posts");
// Set posts count = 0 and then update to real count
$where_user_sql = (!$all_users) ? "AND user_id IN($user_csv)" : "AND user_posts != 0";
$where_post_sql = (!$all_users) ? "AND poster_id IN($user_csv)" : '';
DB()->query("
REPLACE INTO $tmp_user_posts
SELECT user_id, 0
FROM ". BB_USERS ."
WHERE user_id != ". GUEST_UID ."
$where_user_sql
UNION
SELECT poster_id, COUNT(*)
FROM ". BB_POSTS ."
WHERE poster_id != ". GUEST_UID ."
$where_post_sql
GROUP BY poster_id
");
DB()->query("
UPDATE
$tmp_user_posts tmp, ". BB_USERS ." u
SET
u.user_posts = tmp.user_posts
WHERE
u.user_id = tmp.user_id
");
DB()->query("DROP TEMPORARY TABLE $tmp_user_posts");
break;
}
}
function topic_delete ($mode_or_topic_id, $forum_id = null, $prune_time = 0, $prune_all = false)
{
global $lang, $log_action;
$prune = ($mode_or_topic_id === 'prune');
if (!$prune AND !$topic_csv = get_id_csv($mode_or_topic_id))
{
return false;
}
$log_topics = $sync_forums = array();
if ($prune)
{
$sync_forums[$forum_id] = true;
}
else
{
$where_sql = ($forum_csv = get_id_csv($forum_id)) ? "AND forum_id IN($forum_csv)" : '';
$sql = "
SELECT topic_id, forum_id, topic_title, topic_status
FROM ". BB_TOPICS ."
WHERE topic_id IN($topic_csv)
$where_sql
";
$topic_csv = array();
foreach (DB()->fetch_rowset($sql) as $row)
{
$topic_csv[] = $row['topic_id'];
$log_topics[] = $row;
$sync_forums[$row['forum_id']] = true;
}
if (!$topic_csv = get_id_csv($topic_csv))
{
return false;
}
}
// Get topics to delete
$tmp_delete_topics = 'tmp_delete_topics';
DB()->query("
CREATE TEMPORARY TABLE $tmp_delete_topics (
topic_id INT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (topic_id)
) ENGINE = MEMORY
");
DB()->add_shutdown_query("DROP TEMPORARY TABLE IF EXISTS $tmp_delete_topics");
$where_sql = ($prune) ? "forum_id = $forum_id" : "topic_id IN($topic_csv)";
$where_sql .= ($prune && $prune_time) ? " AND topic_last_post_time < $prune_time" : '';
$where_sql .= ($prune && !$prune_all) ? " AND topic_type NOT IN(". POST_ANNOUNCE .",". POST_STICKY .")": '';
DB()->query("INSERT INTO $tmp_delete_topics SELECT topic_id FROM ". BB_TOPICS ." WHERE $where_sql");
// Get topics count
$row = DB()->fetch_row("SELECT COUNT(*) AS topics_count FROM $tmp_delete_topics");
if (!$deleted_topics_count = $row['topics_count'])
{
DB()->query("DROP TEMPORARY TABLE $tmp_delete_topics");
return 0;
}
// Update user posts count
$tmp_user_posts = 'tmp_user_posts';
DB()->query("
CREATE TEMPORARY TABLE $tmp_user_posts (
user_id INT NOT NULL DEFAULT '0',
user_posts MEDIUMINT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (user_id)
) ENGINE = MEMORY
");
DB()->add_shutdown_query("DROP TEMPORARY TABLE IF EXISTS $tmp_user_posts");
DB()->query("
INSERT INTO $tmp_user_posts
SELECT p.poster_id, COUNT(p.post_id)
FROM ". $tmp_delete_topics ." del, ". BB_POSTS ." p
WHERE p.topic_id = del.topic_id
AND p.poster_id != ". GUEST_UID ."
GROUP BY p.poster_id
");
// Get array for atom update
$atom_csv = array();
foreach (DB()->fetch_rowset('SELECT user_id FROM '.$tmp_user_posts) as $at)
{
$atom_csv[] = $at['user_id'];
}
DB()->query("
UPDATE
$tmp_user_posts tmp, ". BB_USERS ." u
SET
u.user_posts = u.user_posts - tmp.user_posts
WHERE
u.user_id = tmp.user_id
");
DB()->query("DROP TEMPORARY TABLE $tmp_user_posts");
// Delete votes
DB()->query("
DELETE pv, pu
FROM ". $tmp_delete_topics ." del
LEFT JOIN ". BB_POLL_VOTES ." pv USING(topic_id)
LEFT JOIN ". BB_POLL_USERS ." pu USING(topic_id)
");
// Delete attachments (from disk)
$attach_dir = get_attachments_dir();
$result = DB()->query("
SELECT
d.physical_filename
FROM
". $tmp_delete_topics ." del,
". BB_POSTS ." p,
". BB_ATTACHMENTS ." a,
". BB_ATTACHMENTS_DESC ." d
WHERE
p.topic_id = del.topic_id
AND a.post_id = p.post_id
AND d.attach_id = a.attach_id
");
while ($row = DB()->fetch_next($result))
{
if ($filename = basename($row['physical_filename']))
{
@unlink("$attach_dir/". $filename);
@unlink("$attach_dir/". THUMB_DIR .'/t_'. $filename);
}
}
unset($row, $result);
// Delete posts, posts_text, attachments (from DB)
DB()->query("
DELETE p, pt, ps, a, d, ph
FROM ". $tmp_delete_topics ." del
LEFT JOIN ". BB_POSTS ." p ON(p.topic_id = del.topic_id)
LEFT JOIN ". BB_POSTS_TEXT ." pt ON(pt.post_id = p.post_id)
LEFT JOIN ". BB_POSTS_HTML ." ph ON(ph.post_id = p.post_id)
LEFT JOIN ". BB_POSTS_SEARCH ." ps ON(ps.post_id = p.post_id)
LEFT JOIN ". BB_ATTACHMENTS ." a ON(a.post_id = p.post_id)
LEFT JOIN ". BB_ATTACHMENTS_DESC ." d ON(d.attach_id = a.attach_id)
");
// Delete topics, topics watch
DB()->query("
DELETE t, tw
FROM ". $tmp_delete_topics ." del
LEFT JOIN ". BB_TOPICS ." t USING(topic_id)
LEFT JOIN ". BB_TOPICS_WATCH ." tw USING(topic_id)
");
// Delete topic moved stubs
DB()->query("
DELETE t
FROM ". $tmp_delete_topics ." del, ". BB_TOPICS ." t
WHERE t.topic_moved_id = del.topic_id
");
// Delete torrents
DB()->query("
DELETE tor, tr, dl
FROM ". $tmp_delete_topics ." del
LEFT JOIN ". BB_BT_TORRENTS ." tor USING(topic_id)
LEFT JOIN ". BB_BT_TRACKER ." tr USING(topic_id)
LEFT JOIN ". BB_BT_DLSTATUS ." dl USING(topic_id)
");
// Log action
if ($prune)
{
// TODO
}
else
{
foreach ($log_topics as $row)
{
if ($row['topic_status'] == TOPIC_MOVED)
{
$row['topic_title'] = '<i>'. $lang['TOPIC_MOVED'] .'</i> '. $row['topic_title'];
}
$log_action->mod('mod_topic_delete', array(
'forum_id' => $row['forum_id'],
'topic_id' => $row['topic_id'],
'topic_title' => $row['topic_title'],
));
}
}
// Sync
sync('forum', array_keys($sync_forums));
// Update atom feed
foreach ($atom_csv as $atom)
{
update_atom('user', $atom);
}
DB()->query("DROP TEMPORARY TABLE $tmp_delete_topics");
return $deleted_topics_count;
}
function topic_move ($topic_id, $to_forum_id, $from_forum_id = null, $leave_shadow = false, $insert_bot_msg = false)
{
global $log_action;
$to_forum_id = (int) $to_forum_id;
// Verify input params
if (!$topic_csv = get_id_csv($topic_id))
{
return false;
}
if (!forum_exists($to_forum_id))
{
return false;
}
if ($from_forum_id && (!forum_exists($from_forum_id) || $to_forum_id == $from_forum_id))
{
return false;
}
// Get topics info
$where_sql = ($forum_csv = get_id_csv($from_forum_id)) ? "AND forum_id IN($forum_csv)" : '';
$sql = "SELECT * FROM ". BB_TOPICS ." WHERE topic_id IN($topic_csv) AND topic_status != ". TOPIC_MOVED ." $where_sql";
$topics = array();
$sync_forums = array($to_forum_id => true);
foreach (DB()->fetch_rowset($sql) as $row)
{
if ($row['forum_id'] != $to_forum_id)
{
$topics[$row['topic_id']] = $row;
$sync_forums[$row['forum_id']] = true;
}
}
if (!$topics OR !$topic_csv = get_id_csv(array_keys($topics)))
{
return false;
}
// Insert topic in the old forum that indicates that the topic has moved
if ($leave_shadow)
{
$shadows = array();
foreach ($topics as $topic_id => $row)
{
$shadows[] = array(
'forum_id' => $row['forum_id'],
'topic_title' => $row['topic_title'],
'topic_poster' => $row['topic_poster'],
'topic_time' => TIMENOW,
'topic_status' => TOPIC_MOVED,
'topic_type' => POST_NORMAL,
'topic_vote' => $row['topic_vote'],
'topic_views' => $row['topic_views'],
'topic_replies' => $row['topic_replies'],
'topic_first_post_id' => $row['topic_first_post_id'],
'topic_last_post_id' => $row['topic_last_post_id'],
'topic_moved_id' => $topic_id,
'topic_last_post_time' => $row['topic_last_post_time'],
);
}
if ($sql_args = DB()->build_array('MULTI_INSERT', $shadows))
{
DB()->query("INSERT INTO ". BB_TOPICS . $sql_args);
}
}
DB()->query("UPDATE ". BB_TOPICS ." SET forum_id = $to_forum_id WHERE topic_id IN($topic_csv)");
DB()->query("UPDATE ". BB_POSTS ." SET forum_id = $to_forum_id WHERE topic_id IN($topic_csv)");
DB()->query("UPDATE ". BB_BT_TORRENTS ." SET forum_id = $to_forum_id WHERE topic_id IN($topic_csv)");
// Bot
if ($insert_bot_msg)
{
foreach ($topics as $topic_id => $row)
{
insert_post('after_move', $topic_id, $to_forum_id, $row['forum_id']);
}
sync('topic', array_keys($topics));
}
// Sync
sync('forum', array_keys($sync_forums));
// Log action
foreach ($topics as $topic_id => $row)
{
$log_action->mod('mod_topic_move', array(
'forum_id' => $row['forum_id'],
'forum_id_new' => $to_forum_id,
'topic_id' => $topic_id,
'topic_title' => $row['topic_title'],
));
}
return true;
}
// $exclude_first - в режиме удаления сообщений по списку исключать первое сообщение в теме
function post_delete ($mode_or_post_id, $user_id = null, $exclude_first = true)
{
global $log_action;
$del_user_posts = ($mode_or_post_id === 'user'); // Delete all user posts
// Get required params
if ($del_user_posts)
{
if (!$user_csv = get_id_csv($user_id)) return false;
}
else
{
if (!$post_csv = get_id_csv($mode_or_post_id)) return false;
// фильтр заглавных сообщений в теме
if ($exclude_first)
{
$sql = "SELECT topic_first_post_id FROM ". BB_TOPICS ." WHERE topic_first_post_id IN($post_csv)";
if ($first_posts = DB()->fetch_rowset($sql, 'topic_first_post_id'))
{
$posts_without_first = array_diff(explode(',', $post_csv), $first_posts);
if (!$post_csv = get_id_csv($posts_without_first))
{
return false;
}
}
}
}
// Collect data for logs, sync..
$log_topics = $sync_forums = $sync_topics = $sync_users = array();
if ($del_user_posts)
{
$sync_topics = DB()->fetch_rowset("SELECT DISTINCT topic_id FROM ". BB_POSTS ." WHERE poster_id IN($user_csv)", 'topic_id');
if ($topic_csv = get_id_csv($sync_topics))
{
foreach (DB()->fetch_rowset("SELECT DISTINCT forum_id FROM ". BB_TOPICS ." WHERE topic_id IN($topic_csv)") as $row)
{
$sync_forums[$row['forum_id']] = true;
}
}
$sync_users = explode(',', $user_csv);
}
else
{
$sql = "
SELECT p.topic_id, p.forum_id, t.topic_title
FROM ". BB_POSTS ." p, ". BB_TOPICS ." t
WHERE p.post_id IN($post_csv)
AND t.topic_id = p.topic_id
GROUP BY t.topic_id
";
foreach (DB()->fetch_rowset($sql) as $row)
{
$log_topics[] = $row;
$sync_topics[] = $row['topic_id'];
$sync_forums[$row['forum_id']] = true;
}
$sync_users = DB()->fetch_rowset("SELECT DISTINCT poster_id FROM ". BB_POSTS ." WHERE post_id IN($post_csv)", 'poster_id');
}
// Get all post_id for deleting
$tmp_delete_posts = 'tmp_delete_posts';
DB()->query("
CREATE TEMPORARY TABLE $tmp_delete_posts (
post_id INT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (post_id)
) ENGINE = MEMORY
");
DB()->add_shutdown_query("DROP TEMPORARY TABLE IF EXISTS $tmp_delete_posts");
if ($del_user_posts)
{
$where_sql = "poster_id IN($user_csv)";
$exclude_posts_ary = array();
foreach (DB()->fetch_rowset("SELECT topic_first_post_id FROM ". BB_TOPICS ." WHERE topic_poster IN($user_csv)") as $row)
{
$exclude_posts_ary[] = $row['topic_first_post_id'];
}
if ($exclude_posts_csv = get_id_csv($exclude_posts_ary))
{
$where_sql .= " AND post_id NOT IN($exclude_posts_csv)";
}
}
else
{
$where_sql = "post_id IN($post_csv)";
}
DB()->query("INSERT INTO $tmp_delete_posts SELECT post_id FROM ". BB_POSTS ." WHERE $where_sql");
// Deleted posts count
$row = DB()->fetch_row("SELECT COUNT(*) AS posts_count FROM $tmp_delete_posts");
if (!$deleted_posts_count = $row['posts_count'])
{
DB()->query("DROP TEMPORARY TABLE $tmp_delete_posts");
return 0;
}
// Delete attachments (from disk)
$attach_dir = get_attachments_dir();
$result = DB()->query("
SELECT
d.physical_filename
FROM
". $tmp_delete_posts ." del,
". BB_ATTACHMENTS ." a,
". BB_ATTACHMENTS_DESC ." d
WHERE
a.post_id = del.post_id
AND d.attach_id = a.attach_id
");
while ($row = DB()->fetch_next($result))
{
if ($filename = basename($row['physical_filename']))
{
@unlink("$attach_dir/". $filename);
@unlink("$attach_dir/". THUMB_DIR .'/t_'. $filename);
}
}
unset($row, $result);
// Delete posts, posts_text, attachments (from DB)
DB()->query("
DELETE p, pt, ps, tor, a, d, ph
FROM ". $tmp_delete_posts ." del
LEFT JOIN ". BB_POSTS ." p ON(p.post_id = del.post_id)
LEFT JOIN ". BB_POSTS_TEXT ." pt ON(pt.post_id = del.post_id)
LEFT JOIN ". BB_POSTS_HTML ." ph ON(ph.post_id = del.post_id)
LEFT JOIN ". BB_POSTS_SEARCH ." ps ON(ps.post_id = del.post_id)
LEFT JOIN ". BB_BT_TORRENTS ." tor ON(tor.post_id = del.post_id)
LEFT JOIN ". BB_ATTACHMENTS ." a ON(a.post_id = del.post_id)
LEFT JOIN ". BB_ATTACHMENTS_DESC ." d ON(d.attach_id = a.attach_id)
");
// Log action
if ($del_user_posts)
{
$log_action->admin('mod_post_delete', array(
'log_msg' => 'user: '. get_usernames_for_log($user_id) ."<br />posts: $deleted_posts_count",
));
}
else if (!defined('IN_CRON'))
{
foreach ($log_topics as $row)
{
$log_action->mod('mod_post_delete', array(
'forum_id' => $row['forum_id'],
'topic_id' => $row['topic_id'],
'topic_title' => $row['topic_title'],
));
}
}
// Sync
sync('topic', $sync_topics);
sync('forum', array_keys($sync_forums));
sync('user_posts', $sync_users);
// Update atom feed
foreach ($sync_topics as $atom_topic)
{
update_atom('topic', $atom_topic);
}
foreach ($sync_users as $atom_user)
{
update_atom('user', $atom_user);
}
DB()->query("DROP TEMPORARY TABLE $tmp_delete_posts");
return $deleted_posts_count;
}
function user_delete ($user_id, $delete_posts = false)
{
global $bb_cfg, $log_action;
if (!$user_csv = get_id_csv($user_id))
{
return false;
}
if (!$user_id = DB()->fetch_rowset("SELECT user_id FROM ". BB_USERS ." WHERE user_id IN($user_csv)", 'user_id'))
{
return false;
}
$user_csv = get_id_csv($user_id);
// LOG
$log_action->admin('adm_user_delete', array(
'log_msg' => get_usernames_for_log($user_id),
));
// Avatar
$result = DB()->query("SELECT user_id, avatar_ext_id FROM ". BB_USERS ." WHERE avatar_ext_id > 0 AND user_id IN($user_csv)");
while ($row = DB()->fetch_next($result))
{
delete_avatar($row['user_id'], $row['avatar_ext_id']);
}
if ($delete_posts)
{
post_delete('user', $user_id);
}
else
{
DB()->query("UPDATE ". BB_POSTS ." SET poster_id = ". DELETED ." WHERE poster_id IN($user_csv)");
}
DB()->query("UPDATE ". BB_GROUPS ." SET group_moderator = 2 WHERE group_single_user = 0 AND group_moderator IN($user_csv)");
DB()->query("UPDATE ". BB_TOPICS ." SET topic_poster = ". DELETED ." WHERE topic_poster IN($user_csv)");
DB()->query("UPDATE ". BB_BT_TORRENTS ." SET poster_id = ". DELETED ." WHERE poster_id IN($user_csv)");
DB()->query("
DELETE ug, g, a, qt1, qt2
FROM ". BB_USER_GROUP ." ug
LEFT JOIN ". BB_GROUPS ." g ON(g.group_id = ug.group_id AND g.group_single_user = 1)
LEFT JOIN ". BB_AUTH_ACCESS ." a ON(a.group_id = g.group_id)
LEFT JOIN ". BB_QUOTA ." qt1 ON(qt1.user_id = ug.user_id)
LEFT JOIN ". BB_QUOTA ." qt2 ON(qt2.group_id = g.group_id)
WHERE ug.user_id IN($user_csv)
");
DB()->query("
DELETE u, ban, pu, s, tw, asn
FROM ". BB_USERS ." u
LEFT JOIN ". BB_BANLIST ." ban ON(ban.ban_userid = u.user_id)
LEFT JOIN ". BB_POLL_USERS ." pu ON(pu.user_id = u.user_id)
LEFT JOIN ". BB_SESSIONS ." s ON(s.session_user_id = u.user_id)
LEFT JOIN ". BB_TOPICS_WATCH ." tw ON(tw.user_id = u.user_id)
LEFT JOIN ". BB_AUTH_ACCESS_SNAP ." asn ON(asn.user_id = u.user_id)
WHERE u.user_id IN($user_csv)
");
DB()->query("
DELETE btu, tr
FROM ". BB_BT_USERS ." btu
LEFT JOIN ". BB_BT_TRACKER ." tr ON(tr.user_id = btu.user_id)
WHERE btu.user_id IN($user_csv)
");
// PM
DB()->query("
DELETE pm, pmt
FROM ". BB_PRIVMSGS ." pm
LEFT JOIN ". BB_PRIVMSGS_TEXT ." pmt ON(pmt.privmsgs_text_id = pm.privmsgs_id)
WHERE pm.privmsgs_from_userid IN($user_csv)
AND pm.privmsgs_type IN(". PRIVMSGS_SENT_MAIL .','. PRIVMSGS_SAVED_OUT_MAIL .")
");
DB()->query("
DELETE pm, pmt
FROM ". BB_PRIVMSGS ." pm
LEFT JOIN ". BB_PRIVMSGS_TEXT ." pmt ON(pmt.privmsgs_text_id = pm.privmsgs_id)
WHERE pm.privmsgs_to_userid IN($user_csv)
AND pm.privmsgs_type IN(". PRIVMSGS_READ_MAIL .','. PRIVMSGS_SAVED_IN_MAIL .")
");
DB()->query("UPDATE ". BB_PRIVMSGS ." SET privmsgs_from_userid = ". DELETED ." WHERE privmsgs_from_userid IN($user_csv)");
DB()->query("UPDATE ". BB_PRIVMSGS ." SET privmsgs_to_userid = ". DELETED ." WHERE privmsgs_to_userid IN($user_csv)");
// Delete user feed
foreach (explode(',', $user_csv) as $user_id)
{
$file_path = $bb_cfg['atom']['path'] .'/u/'. floor($user_id/5000) .'/'. ($user_id % 100) .'/'. $user_id .'.atom';
@unlink($file_path);
}
}
function get_usernames_for_log ($user_id)
{
$users_log_msg = array();
if ($user_csv = get_id_csv($user_id))
{
$sql = "SELECT user_id, username FROM ". BB_USERS ." WHERE user_id IN($user_csv)";
foreach (DB()->fetch_rowset($sql) as $row)
{
$users_log_msg[] = "<b>$row[username]</b> [$row[user_id]]";
}
}
return join(', ', $users_log_msg);
}

View file

@ -0,0 +1,157 @@
<?php
function run_jobs($jobs)
{
global $bb_cfg, $tr_cfg, $datastore;
define('IN_CRON', true);
$sql = "SELECT cron_script FROM " . BB_CRON ." WHERE cron_id IN ($jobs)";
if (!$result = DB()->sql_query($sql))
{
bb_die('Could not obtain cron script');
}
while ($row = DB()->sql_fetchrow($result))
{
$job = $row['cron_script'];
$job_script = INC_DIR . 'cron/jobs/' . $job;
require($job_script);
}
DB()->query("
UPDATE ". BB_CRON ." SET
last_run = NOW(),
run_counter = run_counter + 1,
next_run =
CASE
WHEN schedule = 'hourly' THEN
DATE_ADD(NOW(), INTERVAL 1 HOUR)
WHEN schedule = 'daily' THEN
DATE_ADD(DATE_ADD(CURDATE(), INTERVAL 1 DAY), INTERVAL TIME_TO_SEC(run_time) SECOND)
WHEN schedule = 'weekly' THEN
DATE_ADD(
DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(NOW()) DAY), INTERVAL 7 DAY),
INTERVAL CONCAT(ROUND(run_day-1), ' ', run_time) DAY_SECOND)
WHEN schedule = 'monthly' THEN
DATE_ADD(
DATE_ADD(DATE_SUB(CURDATE(), INTERVAL DAYOFMONTH(NOW())-1 DAY), INTERVAL 1 MONTH),
INTERVAL CONCAT(ROUND(run_day-1), ' ', run_time) DAY_SECOND)
ELSE
DATE_ADD(NOW(), INTERVAL TIME_TO_SEC(run_interval) SECOND)
END
WHERE cron_id IN ($jobs)
");
sleep(3);
return;
}
function delete_jobs($jobs)
{
DB()->query("DELETE FROM " . BB_CRON . " WHERE cron_id IN ($jobs)");
return;
}
function toggle_active($jobs, $cron_action)
{
$active = ($cron_action == 'disable') ? 0 : 1;
DB()->query("UPDATE " . BB_CRON . " SET cron_active = $active WHERE cron_id IN ($jobs)");
return;
}
function validate_cron_post($cron_arr) {
$errors = 'Errors in: ';
$errnum = 0;
if (!$cron_arr['cron_title']){
$errors .= 'cron title (empty value), ';
$errnum++;
}
if (!$cron_arr['cron_script']){
$errors .= 'cron script (empty value), ';
$errnum++;
}
if ($errnum > 0){
$result = $errors . ' total ' . $errnum . ' errors <br/> <a href="javascript:history.back(-1)">Back</a>';
}
else {
$result = 1;
}
return $result;
}
function insert_cron_job($cron_arr)
{
$row = DB()->fetch_row("SELECT cron_title, cron_script FROM ". BB_CRON ." WHERE cron_title = '". $_POST['cron_title'] ."' or cron_script = '". $_POST['cron_script'] ."' ");
if ($row)
{
global $lang;
if ($_POST['cron_script'] == $row['cron_script'])
{
$langmode = $lang['SCRIPT_DUPLICATE'];
}
else $langmode = $lang['TITLE_DUPLICATE'];
$message = $langmode . "<br /><br />" . sprintf($lang['CLICK_RETURN_JOBS_ADDED'], "<a href=\"javascript:history.back(-1)\">", "</a>") . "<br /><br />" . sprintf($lang['CLICK_RETURN_JOBS'], "<a href=\"admin_cron.php?mode=list\">", "</a>") . "<br /><br />" . sprintf($lang['CLICK_RETURN_ADMIN_INDEX'], "<a href=\"index.php?pane=right\">", "</a>");
bb_die($message);
}
$cron_active = $cron_arr['cron_active'];
$cron_title = $cron_arr['cron_title'];
$cron_script = $cron_arr['cron_script'];
$schedule = $cron_arr['schedule'];
$run_day = $cron_arr['run_day'];
$run_time = $cron_arr['run_time'];
$run_order = $cron_arr['run_order'];
$last_run = $cron_arr['last_run'];
$next_run = $cron_arr['next_run'];
$run_interval = $cron_arr['run_interval'];
$log_enabled = $cron_arr['log_enabled'];
$log_file = $cron_arr['log_file'];
$log_sql_queries = $cron_arr['log_sql_queries'];
$disable_board = $cron_arr['disable_board'];
$run_counter = $cron_arr['run_counter'];
DB()->query("INSERT INTO ". BB_CRON ." (cron_active, cron_title, cron_script, schedule, run_day, run_time, run_order, last_run, next_run, run_interval, log_enabled, log_file, log_sql_queries, disable_board, run_counter) VALUES (
$cron_active, '$cron_title', '$cron_script', '$schedule', '$run_day', '$run_time', '$run_order', '$last_run', '$next_run', '$run_interval', $log_enabled, '$log_file', $log_sql_queries, $disable_board, '$run_counter')");
}
function update_cron_job($cron_arr)
{
$cron_id = $cron_arr['cron_id'];
$cron_active = $cron_arr['cron_active'];
$cron_title = DB()->escape($cron_arr['cron_title']);
$cron_script = DB()->escape($cron_arr['cron_script']);
$schedule = $cron_arr['schedule'];
$run_day = $cron_arr['run_day'];
$run_time = $cron_arr['run_time'];
$run_order = $cron_arr['run_order'];
$last_run = $cron_arr['last_run'];
$next_run = $cron_arr['next_run'];
$run_interval = $cron_arr['run_interval'];
$log_enabled = $cron_arr['log_enabled'];
$log_file = DB()->escape($cron_arr['log_file']);
$log_sql_queries = $cron_arr['log_sql_queries'];
$disable_board = $cron_arr['disable_board'];
$run_counter = $cron_arr['run_counter'];
DB()->query("UPDATE " . BB_CRON . " SET
cron_active = '$cron_active',
cron_title = '$cron_title',
cron_script = '$cron_script',
schedule = '$schedule',
run_day = '$run_day',
run_time = '$run_time',
run_order = '$run_order',
last_run = '$last_run',
next_run = '$next_run',
run_interval = '$run_interval',
log_enabled = '$log_enabled',
log_file = '$log_file',
log_sql_queries = '$log_sql_queries',
disable_board = '$disable_board',
run_counter = '$run_counter'
WHERE cron_id = $cron_id
");
}

View file

@ -0,0 +1,113 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
function update_table_bool ($table_name, $key, $field_name, $field_def_val)
{
// Clear current status
$sql = "UPDATE $table_name
SET $field_name = $field_def_val
WHERE 1";
if (!$result = DB()->sql_query($sql))
{
bb_die('Could not update '. $table_name);
}
if (isset($_POST[$field_name]))
{
// Get new status
$in_sql = array();
foreach ($_POST[$field_name] as $i => $val)
{
$in_sql[] = intval($val);
}
// Update status
if ($in_sql = join(',', $in_sql))
{
$sql = "UPDATE $table_name
SET $field_name = 1
WHERE $key IN($in_sql)";
if (!$result = DB()->sql_query($sql))
{
bb_die('Could not update '. $table_name);
}
}
}
return;
}
function set_tpl_vars ($default_cfg, $cfg)
{
global $template;
foreach ($default_cfg as $config_name => $config_value)
{
$template->assign_vars(array(strtoupper($config_name) => htmlspecialchars($cfg[$config_name])));
}
}
function set_tpl_vars_bool ($default_cfg, $cfg)
{
global $template, $lang;
foreach ($default_cfg as $config_name => $config_value)
{
// YES/NO 'checked="checked"'
$template->assign_vars(array(
strtoupper($config_name) .'_YES' => ($cfg[$config_name]) ? HTML_CHECKED : '',
strtoupper($config_name) .'_NO' => (!$cfg[$config_name]) ? HTML_CHECKED : '',
));
// YES/NO lang vars
$template->assign_vars(array(
'L_'. strtoupper($config_name) .'_YES' => ($cfg[$config_name]) ? "<u>$lang[YES]</u>" : $lang['YES'],
'L_'. strtoupper($config_name) .'_NO' => (!$cfg[$config_name]) ? "<u>$lang[NO]</u>" : $lang['NO'],
));
}
}
function set_tpl_vars_lang ($default_cfg)
{
global $template, $lang;
foreach ($default_cfg as $config_name => $config_value)
{
$template->assign_vars(array(
'L_'. strtoupper($config_name) => isset($lang[$config_name]) ? $lang[$config_name] : '',
'L_'. strtoupper($config_name) .'_EXPL' => isset($lang[$config_name .'_expl']) ? $lang[$config_name .'_expl'] : '',
'L_'. strtoupper($config_name) .'_HEAD' => isset($lang[$config_name .'_head']) ? $lang[$config_name .'_head'] : '',
));
}
}
function update_config_table ($table_name, $default_cfg, $cfg, $type)
{
foreach ($default_cfg as $config_name => $config_value)
{
if (isset($_POST[$config_name]) && $_POST[$config_name] != $cfg[$config_name])
{
if ($type == 'str')
{
$config_value = $_POST[$config_name];
}
else if ($type == 'bool')
{
$config_value = ($_POST[$config_name]) ? 1 : 0;
}
else if ($type == 'num')
{
$config_value = abs(intval($_POST[$config_name]));
}
else
{
return;
}
bb_update_config(array($config_name => $config_value), $table_name);
}
}
}

View file

@ -0,0 +1,186 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
// Максимум записей = 50
// [Обновлено] - если дата изменения первого поста топика не старее недели (?) или в топике новые сообщения не старее недели (?)
function update_forum_feed ($forum_id, $forum_data)
{
global $bb_cfg;
$file_path = $bb_cfg['atom']['path'] .'/f/'. $forum_id .'.atom';
$select_tor_sql = $join_tor_sql = '';
if ($forum_id == 0) $forum_data['forum_name'] = 'Общая по всем разделам';
if ($forum_id > 0 && $forum_data['allow_reg_tracker'])
{
$select_tor_sql = ', tor.size AS tor_size, tor.tor_status';
$join_tor_sql = "LEFT JOIN ". BB_BT_TORRENTS ." tor ON(t.topic_id = tor.topic_id)";
}
if ($forum_id == 0)
{
$sql = "
SELECT
t.topic_id, t.topic_title, t.topic_status,
u1.username AS first_username,
p1.post_time AS topic_first_post_time, p1.post_edit_time AS topic_first_post_edit_time,
p2.post_time AS topic_last_post_time, p2.post_edit_time AS topic_last_post_edit_time,
tor.size AS tor_size, tor.tor_status
FROM ". BB_BT_TORRENTS ." tor
LEFT JOIN ". BB_TOPICS ." t ON(tor.topic_id = t.topic_id)
LEFT JOIN ". BB_USERS ." u1 ON(t.topic_poster = u1.user_id)
LEFT JOIN ". BB_POSTS ." p1 ON(t.topic_first_post_id = p1.post_id)
LEFT JOIN ". BB_POSTS ." p2 ON(t.topic_last_post_id = p2.post_id)
ORDER BY t.topic_last_post_time DESC
LIMIT 100
";
}
else if ($forum_id > 0)
{
$sql = "
SELECT
t.topic_id, t.topic_title, t.topic_status,
u1.username AS first_username,
p1.post_time AS topic_first_post_time, p1.post_edit_time AS topic_first_post_edit_time,
p2.post_time AS topic_last_post_time, p2.post_edit_time AS topic_last_post_edit_time
$select_tor_sql
FROM ". BB_TOPICS ." t
LEFT JOIN ". BB_USERS ." u1 ON(t.topic_poster = u1.user_id)
LEFT JOIN ". BB_POSTS ." p1 ON(t.topic_first_post_id = p1.post_id)
LEFT JOIN ". BB_POSTS ." p2 ON(t.topic_last_post_id = p2.post_id)
$join_tor_sql
WHERE t.forum_id = $forum_id
ORDER BY t.topic_last_post_time DESC
LIMIT 50
";
}
$topics_tmp = DB()->fetch_rowset($sql);
$topics = array();
foreach ($topics_tmp as $topic)
{
if (isset($topic['topic_status']))
{
if ($topic['topic_status'] == TOPIC_MOVED) continue;
}
if (isset($topic['tor_status']))
{
if (isset($bb_cfg['tor_frozen'][$topic['tor_status']])) continue;
}
$topics[] = $topic;
}
if (!count($topics))
{
@unlink($file_path);
return false;
}
if (create_atom($file_path, 'f', $forum_id, htmlCHR($forum_data['forum_name']), $topics)) return true;
else return false;
}
function update_user_feed ($user_id, $username)
{
global $bb_cfg;
$file_path = $bb_cfg['atom']['path'] .'/u/'. floor($user_id/5000) .'/'. ($user_id % 100) .'/'. $user_id .'.atom';
$sql = "
SELECT
t.topic_id, t.topic_title, t.topic_status,
u1.username AS first_username,
p1.post_time AS topic_first_post_time, p1.post_edit_time AS topic_first_post_edit_time,
p2.post_time AS topic_last_post_time, p2.post_edit_time AS topic_last_post_edit_time,
tor.size AS tor_size, tor.tor_status
FROM ". BB_TOPICS ." t
LEFT JOIN ". BB_USERS ." u1 ON(t.topic_poster = u1.user_id)
LEFT JOIN ". BB_POSTS ." p1 ON(t.topic_first_post_id = p1.post_id)
LEFT JOIN ". BB_POSTS ." p2 ON(t.topic_last_post_id = p2.post_id)
LEFT JOIN ". BB_BT_TORRENTS ." tor ON(t.topic_id = tor.topic_id)
WHERE t.topic_poster = $user_id
ORDER BY t.topic_last_post_time DESC
LIMIT 50
";
$topics_tmp = DB()->fetch_rowset($sql);
$topics = array();
foreach ($topics_tmp as $topic)
{
if (isset($topic['topic_status']))
{
if ($topic['topic_status'] == TOPIC_MOVED) continue;
}
if (isset($topic['tor_status']))
{
if (isset($bb_cfg['tor_frozen'][$topic['tor_status']])) continue;
}
$topics[] = $topic;
}
if (!count($topics))
{
@unlink($file_path);
return false;
}
if (create_atom($file_path, 'u', $user_id, wbr($username), $topics)) return true;
else return false;
}
function create_atom ($file_path, $mode, $id, $title, $topics)
{
global $bb_cfg;
$dir = dirname($file_path);
if (!file_exists($dir))
{
if (!bb_mkdir($dir)) return false;
}
foreach ($topics as $topic)
{
$last_time = $topic['topic_last_post_time'];
if ($topic['topic_last_post_edit_time']) $last_time = $topic['topic_last_post_edit_time'];
$date = bb_date($last_time, 'Y-m-d', 0);
$time = bb_date($last_time, 'H:i:s', 0);
break;
}
$atom = "";
$atom .= "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
$atom .= "<feed xmlns=\"http://www.w3.org/2005/Atom\" xml:base=\"http://". $bb_cfg['server_name'] . $bb_cfg['script_path'] ."\">\n";
$atom .= "<title>$title</title>\n";
$atom .= "<updated>". $date ."T$time+00:00</updated>\n";
$atom .= "<id>tag:rto.feed,2000:/$mode/$id</id>\n";
$atom .= "<link href=\"http://". $bb_cfg['server_name'] . $bb_cfg['script_path'] ."\" />\n";
foreach ($topics as $topic)
{
$topic_id = $topic['topic_id'];
$tor_size = '';
if (isset($topic['tor_size']))
{
$tor_size = str_replace('&nbsp;', ' ', ' ['. humn_size($topic['tor_size']) .']');
}
$topic_title = $topic['topic_title'];
$orig_word = array();
$replacement_word = array();
obtain_word_list($orig_word, $replacement_word);
if (count($orig_word))
{
$topic_title = preg_replace($orig_word, $replacement_word, $topic_title);
}
$topic_title = wbr($topic_title);
$author_name = ($topic['first_username']) ? wbr($topic['first_username']) : 'Гость';
$last_time = $topic['topic_last_post_time'];
if ($topic['topic_last_post_edit_time']) $last_time = $topic['topic_last_post_edit_time'];
$date = bb_date($last_time, 'Y-m-d', 0);
$time = bb_date($last_time, 'H:i:s', 0);
$updated = '';
$checktime = TIMENOW - 604800; // неделя (week)
if ($topic['topic_first_post_edit_time'] && $topic['topic_first_post_edit_time'] > $checktime) $updated = '[Обновлено] ';
$atom .= "<entry>\n";
$atom .= " <title type=\"html\"><![CDATA[$updated$topic_title$tor_size]]></title>\n";
$atom .= " <author>\n";
$atom .= " <name>$author_name</name>\n";
$atom .= " </author>\n";
$atom .= " <updated>". $date ."T$time+00:00</updated>\n";
$atom .= " <id>tag:rto.feed,". $date .":/t/$topic_id</id>\n";
$atom .= " <link href=\"viewtopic.php?t=$topic_id\" />\n";
$atom .= "</entry>\n";
}
$atom .= "</feed>";
@unlink($file_path);
$fp = fopen($file_path, "w");
fwrite($fp, $atom);
fclose ($fp);
return true;
}

View file

@ -0,0 +1,68 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
function get_sql_log ()
{
global $DBS, $CACHES, $sphinx, $datastore;
$log = '';
foreach ($DBS->srv as $srv_name => $db_obj)
{
$log .= !empty($db_obj) ? get_sql_log_html($db_obj, "$srv_name [MySQL]") : '';
}
foreach ($CACHES->obj as $cache_name => $cache_obj)
{
if (!empty($cache_obj->db))
{
$log .= get_sql_log_html($cache_obj->db, "cache: $cache_name [{$cache_obj->db->engine}]");
}
elseif (!empty($cache_obj->engine))
{
$log .= get_sql_log_html($cache_obj, "cache: $cache_name [{$cache_obj->engine}]");
}
}
$log .= !empty($sphinx) ? get_sql_log_html($sphinx, '$sphinx') : '';
if (!empty($datastore->db->dbg))
{
$log .= get_sql_log_html($datastore->db, 'cache: datastore ['.$datastore->engine.']');
}
else if(!empty($datastore->dbg))
{
$log .= get_sql_log_html($datastore, 'cache: datastore ['.$datastore->engine.']');
}
return $log;
}
function get_sql_log_html ($db_obj, $log_name)
{
$log = '';
foreach ($db_obj->dbg as $i => $dbg)
{
$id = "sql_{$i}_". mt_rand();
$sql = short_query($dbg['sql'], true);
$time = sprintf('%.4f', $dbg['time']);
$perc = @sprintf('[%2d]', $dbg['time']*100/$db_obj->sql_timetotal);
$info = !empty($dbg['info']) ? $dbg['info'] .' ['. $dbg['src'] .']' : $dbg['src'];
$log .= ''
. '<div class="sqlLogRow" title="'. $info .'">'
. '<span style="letter-spacing: -1px;">'. $time .' </span>'
. '<span title="Copy to clipboard" onclick="$.copyToClipboard( $(\'#'. $id .'\').text() );" style="color: gray; letter-spacing: -1px;">'. $perc .'</span>'
. ' '
. '<span style="letter-spacing: 0px;" id="'. $id .'">'. $sql .'</span>'
. '<span style="color: gray"> # '. $info .' </span>'
. '</div>'
. "\n";
}
return '
<div class="sqlLogTitle">'. $log_name .'</div>
'. $log .'
';
}

View file

@ -0,0 +1,232 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
function update_user_level ($user_id)
{
global $datastore;
if (is_array($user_id))
{
$user_id = join(',', $user_id);
}
$user_groups_in = ($user_id !== 'all') ? "AND ug.user_id IN($user_id)" : '';
$users_in = ($user_id !== 'all') ? "AND u.user_id IN($user_id)" : '';
$tmp_table = 'tmp_levels';
DB()->query("
CREATE TEMPORARY TABLE $tmp_table (
user_id MEDIUMINT NOT NULL DEFAULT '0',
user_level TINYINT NOT NULL DEFAULT '0',
PRIMARY KEY (user_id)
) ENGINE = MEMORY
");
DB()->query("
REPLACE INTO $tmp_table (user_id, user_level)
SELECT u.user_id, ". USER ."
FROM ". BB_USERS ." u
WHERE user_level NOT IN(". USER .",". ADMIN .")
$users_in
UNION
SELECT DISTINCT ug.user_id, ". GROUP_MEMBER ."
FROM ". BB_GROUPS ." g, ". BB_USER_GROUP ." ug
WHERE g.group_single_user = 0
AND ug.group_id = g.group_id
AND ug.user_pending = 0
$user_groups_in
UNION
SELECT DISTINCT ug.user_id, ". MOD ."
FROM ". BB_AUTH_ACCESS ." aa, ". BB_USER_GROUP ." ug
WHERE aa.forum_perm & ". BF_AUTH_MOD ."
AND ug.group_id = aa.group_id
AND ug.user_pending = 0
$user_groups_in
");
DB()->query("
UPDATE ". BB_USERS ." u, $tmp_table lev SET
u.user_level = lev.user_level
WHERE lev.user_id = u.user_id
AND u.user_level NOT IN(". ADMIN .")
$users_in
");
DB()->query("DROP TEMPORARY TABLE $tmp_table");
update_user_permissions($user_id);
delete_orphan_usergroups();
$datastore->update('moderators');
}
function delete_group ($group_id)
{
$group_id = (int) $group_id;
DB()->query("
DELETE ug, g, aa
FROM ". BB_USER_GROUP ." ug
LEFT JOIN ". BB_GROUPS ." g ON(g.group_id = $group_id)
LEFT JOIN ". BB_AUTH_ACCESS ." aa ON(aa.group_id = $group_id)
WHERE ug.group_id = $group_id
");
DB()->query("UPDATE " . BB_POSTS . " SET attach_rg_sig = 0, poster_rg_id = 0 WHERE poster_rg_id = ". $group_id);
update_user_level('all');
}
function add_user_into_group ($group_id, $user_id, $user_pending = 0, $user_time = TIMENOW)
{
$args = DB()->build_array('INSERT', array(
'group_id' => (int) $group_id,
'user_id' => (int) $user_id,
'user_pending' => (int) $user_pending,
'user_time' => (int) $user_time,
));
DB()->query("REPLACE INTO ". BB_USER_GROUP . $args);
if (!$user_pending)
{
update_user_level($user_id);
}
}
function delete_user_group ($group_id, $user_id)
{
DB()->query("
DELETE FROM ". BB_USER_GROUP ."
WHERE user_id = ". (int) $user_id ."
AND group_id = ". (int) $group_id ."
");
update_user_level($user_id);
}
function create_user_group ($user_id)
{
DB()->query("INSERT INTO ". BB_GROUPS ." (group_single_user) VALUES (1)");
$group_id = (int) DB()->sql_nextid();
$user_id = (int) $user_id;
DB()->query("INSERT INTO ". BB_USER_GROUP ." (user_id, group_id, user_time) VALUES ($user_id, $group_id, ". TIMENOW .")");
return $group_id;
}
function get_group_data ($group_id)
{
if ($group_id === 'all')
{
$sql = "SELECT g.*, u.username AS moderator_name, aa.group_id AS auth_mod
FROM ". BB_GROUPS ." g
LEFT JOIN ". BB_USERS ." u ON(g.group_moderator = u.user_id)
LEFT JOIN ". BB_AUTH_ACCESS ." aa ON(aa.group_id = g.group_id AND aa.forum_perm & ". BF_AUTH_MOD .")
WHERE g.group_single_user = 0
GROUP BY g.group_id
ORDER BY g.group_name";
}
else
{
$sql = "SELECT g.*, u.username AS moderator_name, aa.group_id AS auth_mod
FROM ". BB_GROUPS ." g
LEFT JOIN ". BB_USERS ." u ON(g.group_moderator = u.user_id)
LEFT JOIN ". BB_AUTH_ACCESS ." aa ON(aa.group_id = g.group_id AND aa.forum_perm & ". BF_AUTH_MOD .")
WHERE g.group_id = ". (int) $group_id ."
AND g.group_single_user = 0
LIMIT 1";
}
$method = ($group_id === 'all') ? 'fetch_rowset' : 'fetch_row';
return DB()->$method($sql);
}
function delete_permissions ($group_id = null, $user_id = null, $cat_id = null)
{
$group_id = get_id_csv($group_id);
$user_id = get_id_csv($user_id);
$cat_id = get_id_csv($cat_id);
$forums_join_sql = ($cat_id) ? "
INNER JOIN ". BB_FORUMS ." f ON(a.forum_id = f.forum_id AND f.cat_id IN($cat_id))
" : '';
if ($group_id)
{
DB()->query("DELETE a FROM ". BB_AUTH_ACCESS ." a $forums_join_sql WHERE a.group_id IN($group_id)");
}
if ($user_id)
{
DB()->query("DELETE a FROM ". BB_AUTH_ACCESS_SNAP ." a $forums_join_sql WHERE a.user_id IN($user_id)");
}
}
function store_permissions ($group_id, $auth_ary)
{
if (empty($auth_ary) || !is_array($auth_ary)) return;
$values = array();
foreach ($auth_ary as $forum_id => $permission)
{
$values[] = array(
'group_id' => (int) $group_id,
'forum_id' => (int) $forum_id,
'forum_perm' => (int) $permission,
);
}
$values = DB()->build_array('MULTI_INSERT', $values);
DB()->query("INSERT INTO ". BB_AUTH_ACCESS . $values);
}
function update_user_permissions ($user_id = 'all')
{
if (is_array($user_id))
{
$user_id = join(',', $user_id);
}
$delete_in = ($user_id !== 'all') ? " WHERE user_id IN($user_id)" : '';
$users_in = ($user_id !== 'all') ? "AND ug.user_id IN($user_id)" : '';
DB()->query("DELETE FROM ". BB_AUTH_ACCESS_SNAP . $delete_in);
DB()->query("
INSERT INTO ". BB_AUTH_ACCESS_SNAP ."
(user_id, forum_id, forum_perm)
SELECT
ug.user_id, aa.forum_id, BIT_OR(aa.forum_perm)
FROM
". BB_USER_GROUP ." ug,
". BB_GROUPS ." g,
". BB_AUTH_ACCESS ." aa
WHERE
ug.user_pending = 0
$users_in
AND g.group_id = ug.group_id
AND aa.group_id = g.group_id
GROUP BY
ug.user_id, aa.forum_id
");
}
function delete_orphan_usergroups ()
{
// GROUP_SINGLE_USER without AUTH_ACCESS
DB()->query("
DELETE g
FROM ". BB_GROUPS ." g
LEFT JOIN ". BB_AUTH_ACCESS ." aa USING(group_id)
WHERE g.group_single_user = 1
AND aa.group_id IS NULL
");
// orphan USER_GROUP (against GROUP table)
DB()->query("
DELETE ug
FROM ". BB_USER_GROUP ." ug
LEFT JOIN ". BB_GROUPS ." g USING(group_id)
WHERE g.group_id IS NULL
");
}

View file

@ -0,0 +1,542 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
//
// Prepare a message for posting
//
function prepare_post(&$mode, &$post_data, &$error_msg, &$username, &$subject, &$message)
{
global $bb_cfg, $user, $userdata, $lang;
// Check username
if (!empty($username))
{
$username = clean_username($username);
if (!$userdata['session_logged_in'] || ($userdata['session_logged_in'] && $username != $user->name))
{
require(INC_DIR .'functions_validate.php');
if ($err = validate_username($username))
{
$error_msg .= $err;
}
}
else
{
$username = '';
}
}
// Check subject
if (!empty($subject))
{
$subject = str_replace('&amp;', '&', $subject);
}
else if ($mode == 'newtopic' || ($mode == 'editpost' && $post_data['first_post']))
{
$error_msg .= (!empty($error_msg)) ? '<br />' . $lang['EMPTY_SUBJECT'] : $lang['EMPTY_SUBJECT'];
}
// Check message
if (!empty($message))
{
}
else if ($mode != 'delete')
{
$error_msg .= (!empty($error_msg)) ? '<br />' . $lang['EMPTY_MESSAGE'] : $lang['EMPTY_MESSAGE'];
}
// Check smilies limit
if ($bb_cfg['max_smilies'])
{
$count_smilies = substr_count(bbcode2html($message), '<img class="smile" src="'. $bb_cfg['smilies_path']);
if ($count_smilies > $bb_cfg['max_smilies'])
{
$to_many_smilies = sprintf($lang['MAX_SMILIES_PER_POST'], $bb_cfg['max_smilies']);
$error_msg .= (!empty($error_msg)) ? '<br />'. $to_many_smilies : $to_many_smilies;
}
}
if (IS_GUEST && !CAPTCHA()->verify_code())
{
$error_msg .= (!empty($error_msg)) ? '<br />' . $lang['CONFIRM_CODE_WRONG'] : $lang['CONFIRM_CODE_WRONG'];
}
}
//
// Post a new topic/reply or edit existing post/poll
//
function submit_post($mode, &$post_data, &$message, &$meta, &$forum_id, &$topic_id, &$post_id, &$topic_type, $post_username, $post_subject, $post_message, $update_post_time, $poster_rg_id, $attach_rg_sig)
{
global $userdata, $post_info, $is_auth, $bb_cfg, $lang, $datastore;
$current_time = TIMENOW;
// Flood control
$row = null;
$where_sql = (IS_GUEST) ? "p.poster_ip = '". USER_IP ."'" : "p.poster_id = {$userdata['user_id']}";
if ($mode == 'newtopic' || $mode == 'reply')
{
$sql = "SELECT MAX(p.post_time) AS last_post_time FROM ". BB_POSTS ." p WHERE $where_sql";
if ($row = DB()->fetch_row($sql) AND $row['last_post_time'])
{
if ($userdata['user_level'] == USER)
{
if (TIMENOW - $row['last_post_time'] < $bb_cfg['flood_interval'])
{
bb_die($lang['FLOOD_ERROR']);
}
}
}
}
// Double Post Control
if ($mode != 'editpost' && !empty($row['last_post_time']) && !IS_AM)
{
$sql = "
SELECT pt.post_text
FROM ". BB_POSTS ." p, ". BB_POSTS_TEXT ." pt
WHERE
$where_sql
AND p.post_time = ". (int) $row['last_post_time'] ."
AND pt.post_id = p.post_id
LIMIT 1
";
if ($row = DB()->fetch_row($sql))
{
$last_msg = DB()->escape($row['post_text']);
if ($last_msg == $post_message)
{
bb_die($lang['DOUBLE_POST_ERROR']);
}
}
}
if ($mode == 'newtopic' || ($mode == 'editpost' && $post_data['first_post']))
{
$topic_dl_type = (isset($_POST['topic_dl_type']) && ($post_info['allow_reg_tracker'] || $is_auth['auth_mod'])) ? TOPIC_DL_TYPE_DL : TOPIC_DL_TYPE_NORMAL;
$sql_insert = "
INSERT INTO
" . BB_TOPICS . " (topic_title, topic_poster, topic_time, forum_id, topic_status, topic_type, topic_dl_type)
VALUES
('$post_subject', " . $userdata['user_id'] . ", $current_time, $forum_id, " . TOPIC_UNLOCKED . ", $topic_type, $topic_dl_type)
";
$sql_update = "
UPDATE
" . BB_TOPICS . "
SET
topic_title = '$post_subject',
topic_type = $topic_type,
topic_dl_type = $topic_dl_type
WHERE
topic_id = $topic_id
";
$sql = ($mode != "editpost") ? $sql_insert : $sql_update;
if (!DB()->sql_query($sql))
{
bb_die('Error in posting #1');
}
if ($mode == 'newtopic')
{
$topic_id = DB()->sql_nextid();
}
}
$edited_sql = ($mode == 'editpost' && !$post_data['last_post'] && $post_data['poster_post']) ? ", post_edit_time = $current_time, post_edit_count = post_edit_count + 1" : "";
if ($update_post_time && $mode == 'editpost' && $post_data['last_post'] && !$post_data['first_post'])
{
$edited_sql .= ", post_time = $current_time ";
//lpt
DB()->sql_query("UPDATE ". BB_TOPICS ." SET topic_last_post_time = $current_time WHERE topic_id = $topic_id LIMIT 1");
}
$sql = ($mode != "editpost") ? "INSERT INTO " . BB_POSTS . " (topic_id, forum_id, poster_id, post_username, post_time, poster_ip, poster_rg_id, attach_rg_sig) VALUES ($topic_id, $forum_id, " . $userdata['user_id'] . ", '$post_username', $current_time, '". USER_IP ."', $poster_rg_id, $attach_rg_sig)" : "UPDATE " . BB_POSTS . " SET post_username = '$post_username'" . $edited_sql . ", poster_rg_id = $poster_rg_id, attach_rg_sig = $attach_rg_sig WHERE post_id = $post_id";
if (!DB()->sql_query($sql))
{
bb_die('Error in posting #2');
}
if ($mode != 'editpost')
{
$post_id = DB()->sql_nextid();
}
$sql = ($mode != 'editpost') ? "INSERT INTO " . BB_POSTS_TEXT . " (post_id, post_text) VALUES ($post_id, '$post_message')" : "UPDATE " . BB_POSTS_TEXT . " SET post_text = '$post_message' WHERE post_id = $post_id";
if (!DB()->sql_query($sql))
{
bb_die('Error in posting #3');
}
if ($userdata['user_id'] != BOT_UID)
{
$s_post_message = str_replace('\n', "\n", $post_message);
$s_post_subject = str_replace('\n', "\n", $post_subject);
add_search_words($post_id, stripslashes($s_post_message), stripslashes($s_post_subject));
}
update_post_html(array(
'post_id' => $post_id,
'post_text' => $post_message,
));
//Обновление кеша новостей на главной
if($bb_cfg['show_latest_news'])
{
$news_forums = array_flip(explode(',', $bb_cfg['latest_news_forum_id']));
if(isset($news_forums[$forum_id]) && $bb_cfg['show_latest_news'] && $mode == 'newtopic')
{
$datastore->enqueue('latest_news');
$datastore->update('latest_news');
}
}
if($bb_cfg['show_network_news'])
{
$net_forums = array_flip(explode(',', $bb_cfg['network_news_forum_id']));
if(isset($net_forums[$forum_id]) && $bb_cfg['show_network_news'] && $mode == 'newtopic')
{
$datastore->enqueue('network_news');
$datastore->update('network_news');
}
}
meta_refresh(POST_URL ."$post_id#$post_id");
set_die_append_msg($forum_id, $topic_id);
return $mode;
}
//
// Update post stats and details
//
function update_post_stats($mode, $post_data, $forum_id, $topic_id, $post_id, $user_id)
{
$sign = ($mode == 'delete') ? '- 1' : '+ 1';
$forum_update_sql = "forum_posts = forum_posts $sign";
$topic_update_sql = '';
if ($mode == 'delete')
{
if ($post_data['last_post'])
{
if ($post_data['first_post'])
{
$forum_update_sql .= ', forum_topics = forum_topics - 1';
}
else
{
$topic_update_sql .= 'topic_replies = topic_replies - 1';
$sql = "SELECT MAX(post_id) AS last_post_id, MAX(post_time) AS topic_last_post_time
FROM " . BB_POSTS . "
WHERE topic_id = $topic_id";
if (!($result = DB()->sql_query($sql)))
{
bb_die('Error in deleting post #1');
}
if ($row = DB()->sql_fetchrow($result))
{
$topic_update_sql .= ", topic_last_post_id = {$row['last_post_id']}, topic_last_post_time = {$row['topic_last_post_time']}";
}
}
if ($post_data['last_topic'])
{
$sql = "SELECT MAX(post_id) AS last_post_id
FROM " . BB_POSTS . "
WHERE forum_id = $forum_id";
if (!($result = DB()->sql_query($sql)))
{
bb_die('Error in deleting post #2');
}
if ($row = DB()->sql_fetchrow($result))
{
$forum_update_sql .= ($row['last_post_id']) ? ', forum_last_post_id = ' . $row['last_post_id'] : ', forum_last_post_id = 0';
}
}
}
else if ($post_data['first_post'])
{
$sql = "SELECT MIN(post_id) AS first_post_id FROM " . BB_POSTS . " WHERE topic_id = $topic_id";
if (!($result = DB()->sql_query($sql)))
{
bb_die('Error in deleting post #3');
}
if ($row = DB()->sql_fetchrow($result))
{
$topic_update_sql .= 'topic_replies = topic_replies - 1, topic_first_post_id = ' . $row['first_post_id'];
}
}
else
{
$topic_update_sql .= 'topic_replies = topic_replies - 1';
}
}
else
{
$forum_update_sql .= ", forum_last_post_id = $post_id" . (($mode == 'newtopic') ? ", forum_topics = forum_topics $sign" : "");
$topic_update_sql = "topic_last_post_id = $post_id, topic_last_post_time = ". TIMENOW . (($mode == 'reply') ? ", topic_replies = topic_replies $sign" : ", topic_first_post_id = $post_id");
}
$sql = "UPDATE " . BB_FORUMS . " SET $forum_update_sql WHERE forum_id = $forum_id";
if (!DB()->sql_query($sql))
{
bb_die('Error in posting #4');
}
if ($topic_update_sql != '')
{
$sql = "UPDATE " . BB_TOPICS . " SET $topic_update_sql WHERE topic_id = $topic_id";
if (!DB()->sql_query($sql))
{
bb_die('Error in posting #5');
}
}
$sql = "UPDATE " . BB_USERS . " SET user_posts = user_posts $sign WHERE user_id = $user_id";
if (!DB()->sql_query($sql))
{
bb_die('Error in posting #6');
}
}
//
// Delete a post
//
function delete_post($mode, $post_data, &$message, &$meta, $forum_id, $topic_id, $post_id)
{
global $lang;
$message = $lang['DELETED'];
post_delete($post_id);
set_die_append_msg($forum_id, $topic_id);
}
//
// Handle user notification on new post
//
function user_notification($mode, &$post_data, &$topic_title, &$forum_id, &$topic_id, &$notify_user)
{
global $bb_cfg, $lang, $userdata;
if (!$bb_cfg['topic_notify_enabled'])
{
return;
}
if ($mode != 'delete')
{
if ($mode == 'reply')
{
$update_watched_sql = $user_id_sql = array();
$sql = DB()->fetch_rowset("SELECT ban_userid FROM ". BB_BANLIST ." WHERE ban_userid != 0");
foreach ($sql as $row)
{
$user_id_sql[] = ','. $row['ban_userid'];
}
$user_id_sql = join('', $user_id_sql);
$watch_list = DB()->fetch_rowset("SELECT u.username, u.user_id, u.user_email, u.user_lang
FROM " . BB_TOPICS_WATCH . " tw, " . BB_USERS . " u
WHERE tw.topic_id = $topic_id
AND tw.user_id NOT IN (". $userdata['user_id'] .", ". EXCLUDED_USERS_CSV . $user_id_sql .")
AND tw.notify_status = ". TOPIC_WATCH_NOTIFIED ."
AND u.user_id = tw.user_id
AND u.user_active = 1
ORDER BY u.user_id
");
if ($watch_list)
{
require(CLASS_DIR .'emailer.php');
$emailer = new emailer($bb_cfg['smtp_delivery']);
$orig_word = $replacement_word = array();
obtain_word_list($orig_word, $replacement_word);
if (count($orig_word))
{
$topic_title = preg_replace($orig_word, $replacement_word, $topic_title);
}
$u_topic = make_url(TOPIC_URL . $topic_id .'&view=newest#newest');
$unwatch_topic = make_url(TOPIC_URL ."$topic_id&unwatch=topic");
foreach ($watch_list as $row)
{
$emailer->from($bb_cfg['sitename'] ." <{$bb_cfg['board_email']}>");
$emailer->email_address($row['username'] ." <{$row['user_email']}>");
$emailer->use_template('topic_notify', $row['user_lang']);
$emailer->assign_vars(array(
'TOPIC_TITLE' => html_entity_decode($topic_title),
'SITENAME' => $bb_cfg['sitename'],
'USERNAME' => $row['username'],
'U_TOPIC' => $u_topic,
'U_STOP_WATCHING_TOPIC' => $unwatch_topic,
));
$emailer->send();
$emailer->reset();
$update_watched_sql[] = $row['user_id'];
}
$update_watched_sql = join(',', $update_watched_sql);
}
if ($update_watched_sql)
{
DB()->query("UPDATE ". BB_TOPICS_WATCH ."
SET notify_status = ". TOPIC_WATCH_UNNOTIFIED ."
WHERE topic_id = $topic_id
AND user_id IN ($update_watched_sql)
");
}
}
$topic_watch = DB()->fetch_row("SELECT topic_id FROM ". BB_TOPICS_WATCH ." WHERE topic_id = $topic_id AND user_id = {$userdata['user_id']}", 'topic_id');
if (!$notify_user && !empty($topic_watch))
{
DB()->query("DELETE FROM ". BB_TOPICS_WATCH ." WHERE topic_id = $topic_id AND user_id = {$userdata['user_id']}");
}
else if ($notify_user && empty($topic_watch))
{
DB()->query("
INSERT INTO " . BB_TOPICS_WATCH . " (user_id, topic_id, notify_status)
VALUES (". $userdata['user_id'] .", $topic_id, ". TOPIC_WATCH_NOTIFIED .")
");
}
}
}
function insert_post ($mode, $topic_id, $forum_id = '', $old_forum_id = '', $new_topic_id = '', $new_topic_title = '', $old_topic_id = '', $message = '', $poster_id = '')
{
global $userdata, $lang;
if (!$topic_id) return;
$post_username = $post_subject = $post_text = $poster_ip = '';
$post_time = $current_time = TIMENOW;
if ($mode == 'after_move')
{
if (!$forum_id || !$old_forum_id) return;
$sql = "SELECT forum_id, forum_name
FROM ". BB_FORUMS ."
WHERE forum_id IN($forum_id, $old_forum_id)";
$forum_names = array();
foreach (DB()->fetch_rowset($sql) as $row)
{
$forum_names[$row['forum_id']] = htmlCHR($row['forum_name']);
}
if (!$forum_names) return;
$post_text = sprintf($lang['BOT_TOPIC_MOVED_FROM_TO'], '[url='. make_url(FORUM_URL . $old_forum_id) .']'. $forum_names[$old_forum_id] .'[/url]', '[url='. make_url(FORUM_URL . $forum_id) .']'. $forum_names[$forum_id] .'[/url]', profile_url($userdata));
$poster_id = BOT_UID;
$poster_ip = '7f000001';
}
else if ($mode == 'after_split_to_old')
{
$post_text = sprintf($lang['BOT_MESS_SPLITS'], '[url='. make_url(TOPIC_URL . $new_topic_id) .']'. htmlCHR($new_topic_title) .'[/url]', profile_url($userdata));
$poster_id = BOT_UID;
$poster_ip = '7f000001';
}
else if ($mode == 'after_split_to_new')
{
$sql = "SELECT t.topic_title, p.post_time
FROM ". BB_TOPICS ." t, ". BB_POSTS ." p
WHERE t.topic_id = $old_topic_id
AND p.post_id = t.topic_first_post_id";
if ($row = DB()->fetch_row($sql))
{
$post_time = $row['post_time'] - 1;
$post_text = sprintf($lang['BOT_TOPIC_SPLITS'], '[url='. make_url(TOPIC_URL . $old_topic_id) .']'. $row['topic_title'] .'[/url]', profile_url($userdata));
$poster_id = BOT_UID;
$poster_ip = '7f000001';
}
else
{
return;
}
}
else
{
return;
}
$post_columns = 'topic_id, forum_id, poster_id, post_username, post_time, poster_ip';
$post_values = "$topic_id, $forum_id, $poster_id, '$post_username', $post_time, '$poster_ip'";
DB()->query("INSERT INTO ". BB_POSTS ." ($post_columns) VALUES ($post_values)");
$post_id = DB()->sql_nextid();
$post_text = DB()->escape($post_text);
$post_text_columns = 'post_id, post_text';
$post_text_values = "$post_id, '$post_text'";
DB()->query("INSERT INTO ". BB_POSTS_TEXT ." ($post_text_columns) VALUES ($post_text_values)");
}
function topic_review ($topic_id)
{
global $bb_cfg, $template;
// Fetch posts data
$review_posts = DB()->fetch_rowset("
SELECT
p.*, h.post_html, IF(h.post_html IS NULL, pt.post_text, NULL) AS post_text,
IF(p.poster_id = ". GUEST_UID .", p.post_username, u.username) AS username, u.user_rank
FROM ". BB_POSTS ." p
LEFT JOIN ". BB_USERS ." u ON(u.user_id = p.poster_id)
LEFT JOIN ". BB_POSTS_TEXT ." pt ON(pt.post_id = p.post_id)
LEFT JOIN ". BB_POSTS_HTML ." h ON(h.post_id = p.post_id)
WHERE p.topic_id = ". (int) $topic_id ."
ORDER BY p.post_time DESC
LIMIT ". $bb_cfg['posts_per_page'] ."
");
// Topic posts block
foreach ($review_posts as $i => $post)
{
$template->assign_block_vars('review', array(
'ROW_CLASS' => !($i % 2) ? 'row1' : 'row2',
'POSTER' => profile_url($post),
'POSTER_NAME_JS' => addslashes($post['username']),
'POST_DATE' => bb_date($post['post_time'], $bb_cfg['post_date_format']),
'MESSAGE' => get_parsed_post($post),
));
}
$template->assign_vars(array(
'TPL_TOPIC_REVIEW' => (bool) $review_posts,
));
}

View file

@ -0,0 +1,66 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
//
// Languages
//
function language_select ($default_lang, $select_name = 'language')
{
global $bb_cfg;
$lang_select = '<select name="'. $select_name .'">';
$x = 0;
foreach ($bb_cfg['languages'] as $folder => $name)
{
$selected = '';
if ($folder == $default_lang) $selected = ' selected="selected"';
$lang_select .= '<option value="'. $folder .'"'. $selected .'>'. $name .'</option>';
$x++;
}
$lang_select .= '</select>';
return ($x > 1) ? $lang_select : reset($bb_cfg['languages']);
}
//
// Pick a timezone
//
function tz_select ($default, $select_name = 'timezone')
{
global $sys_timezone, $lang;
if (!isset($default))
{
$default == $sys_timezone;
}
$tz_select = '<select name="' . $select_name . '">';
while( list($offset, $zone) = @each($lang['TZ']) )
{
$selected = ( $offset == $default ) ? ' selected="selected"' : '';
$tz_select .= '<option value="' . $offset . '"' . $selected . '>' . $zone . '</option>';
}
$tz_select .= '</select>';
return $tz_select;
}
//
// Templates
//
function templates_select ($default_style, $select_name = 'tpl_name')
{
global $bb_cfg;
$templates_select = '<select name="'. $select_name .'">';
$x = 0;
foreach ($bb_cfg['templates'] as $folder => $name)
{
$selected = '';
if ($folder == $default_style) $selected = ' selected="selected"';
$templates_select .= '<option value="'. $folder .'"'. $selected .'>'. $name .'</option>';
$x++;
}
$templates_select .= '</select>';
return ($x > 1) ? $templates_select : reset($bb_cfg['templates']);
}

View file

@ -0,0 +1,863 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
function get_torrent_info ($attach_id)
{
global $lang;
$attach_id = intval($attach_id);
$sql = "
SELECT
a.post_id, d.physical_filename, d.extension, d.tracker_status,
t.topic_first_post_id,
p.poster_id, p.topic_id, p.forum_id,
f.allow_reg_tracker
FROM
". BB_ATTACHMENTS ." a,
". BB_ATTACHMENTS_DESC ." d,
". BB_POSTS ." p,
". BB_TOPICS ." t,
". BB_FORUMS ." f
WHERE
a.attach_id = $attach_id
AND d.attach_id = $attach_id
AND p.post_id = a.post_id
AND t.topic_id = p.topic_id
AND f.forum_id = p.forum_id
LIMIT 1
";
if (!$torrent = DB()->fetch_row($sql))
{
bb_die($lang['INVALID_ATTACH_ID']);
}
return $torrent;
}
function torrent_auth_check ($forum_id, $poster_id)
{
global $userdata, $lang, $attach_config;
if (IS_ADMIN) return true;
$is_auth = auth(AUTH_ALL, $forum_id, $userdata);
if ($poster_id != $userdata['user_id'] && !$is_auth['auth_mod'])
{
bb_die($lang['NOT_MODERATOR']);
}
else if (!$is_auth['auth_view'] || !$is_auth['auth_attachments'] || $attach_config['disable_mod'])
{
bb_die(sprintf($lang['SORRY_AUTH_READ'], $is_auth['auth_read_type']));
}
return $is_auth;
}
function tracker_unregister ($attach_id, $mode = '')
{
global $lang, $bb_cfg;
$attach_id = (int) $attach_id;
$post_id = $topic_id = $forum_id = $info_hash = null;
// Get torrent info
if ($torrent = get_torrent_info($attach_id))
{
$post_id = $torrent['post_id'];
$topic_id = $torrent['topic_id'];
$forum_id = $torrent['forum_id'];
}
if ($mode == 'request')
{
if (!$torrent)
{
bb_die($lang['TOR_NOT_FOUND']);
}
if (!$torrent['tracker_status'])
{
bb_die('Torrent already unregistered');
}
torrent_auth_check($forum_id, $torrent['poster_id']);
}
if (!$topic_id)
{
$sql = "SELECT topic_id FROM ". BB_BT_TORRENTS ." WHERE attach_id = $attach_id";
if (!$result = DB()->sql_query($sql))
{
bb_die('Could not query torrent information');
}
if ($row = DB()->sql_fetchrow($result))
{
$topic_id = $row['topic_id'];
}
}
// Unset DL-Type for topic
if ($bb_cfg['bt_unset_dltype_on_tor_unreg'] && $topic_id)
{
$sql = "UPDATE ". BB_TOPICS ." SET topic_dl_type = ". TOPIC_DL_TYPE_NORMAL ." WHERE topic_id = $topic_id LIMIT 1";
if (!$result = DB()->sql_query($sql))
{
bb_die('Could not update topics table #1');
}
}
// Remove peers from tracker
$sql = "DELETE FROM ". BB_BT_TRACKER ." WHERE topic_id = $topic_id";
if (!DB()->sql_query($sql))
{
bb_die('Could not delete peers');
}
// Ocelot
if ($bb_cfg['ocelot']['enabled'])
{
if ($row = DB()->fetch_row("SELECT info_hash FROM ". BB_BT_TORRENTS ." WHERE attach_id = $attach_id LIMIT 1"))
{
$info_hash = $row['info_hash'];
}
ocelot_update_tracker('delete_torrent', array('info_hash' => rawurlencode($info_hash), 'id' => $topic_id));
}
// Delete torrent
$sql = "DELETE FROM ". BB_BT_TORRENTS ." WHERE attach_id = $attach_id";
if (!DB()->sql_query($sql))
{
bb_die('Could not delete torrent from torrents table');
}
// Update tracker_status
$sql = "UPDATE ". BB_ATTACHMENTS_DESC ." SET tracker_status = 0 WHERE attach_id = $attach_id LIMIT 1";
if (!DB()->sql_query($sql))
{
bb_die('Could not update torrent status #1');
}
if ($mode == 'request')
{
set_die_append_msg($forum_id, $topic_id);
bb_die($lang['BT_UNREGISTERED']);
}
}
function delete_torrent ($attach_id, $mode = '')
{
global $lang, $reg_mode, $topic_id;
$attach_id = intval($attach_id);
$reg_mode = $mode;
if (!$torrent = get_torrent_info($attach_id))
{
bb_die($lang['TOR_NOT_FOUND']);
}
$topic_id = $torrent['topic_id'];
$forum_id = $torrent['forum_id'];
$poster_id = $torrent['poster_id'];
if ($torrent['extension'] !== TORRENT_EXT)
{
bb_die($lang['NOT_TORRENT']);
}
torrent_auth_check($forum_id, $poster_id);
tracker_unregister($attach_id);
delete_attachment(0, $attach_id);
return;
}
function change_tor_status ($attach_id, $new_tor_status)
{
global $topic_id, $userdata;
$attach_id = (int) $attach_id;
$new_tor_status = (int) $new_tor_status;
if (!$torrent = get_torrent_info($attach_id))
{
bb_die($lang['TOR_NOT_FOUND']);
}
$topic_id = $torrent['topic_id'];
torrent_auth_check($torrent['forum_id'], $torrent['poster_id']);
DB()->query("
UPDATE ". BB_BT_TORRENTS ." SET
tor_status = $new_tor_status,
checked_user_id = {$userdata['user_id']},
checked_time = '". TIMENOW ."'
WHERE attach_id = $attach_id
LIMIT 1
");
}
// Set gold/silver type for torrent
function change_tor_type ($attach_id, $tor_status_gold)
{
global $topic_id, $lang, $bb_cfg;
if (!$torrent = get_torrent_info($attach_id))
{
bb_die($lang['TOR_NOT_FOUND']);
}
if (!IS_AM) bb_die($lang['ONLY_FOR_MOD']);
$topic_id = $torrent['topic_id'];
$tor_status_gold = intval($tor_status_gold);
$info_hash = null;
DB()->query("UPDATE ". BB_BT_TORRENTS ." SET tor_type = $tor_status_gold WHERE topic_id = $topic_id LIMIT 1");
// Ocelot
if ($bb_cfg['ocelot']['enabled'])
{
if ($row = DB()->fetch_row("SELECT info_hash FROM ". BB_BT_TORRENTS ." WHERE topic_id = $topic_id LIMIT 1"))
{
$info_hash = $row['info_hash'];
}
ocelot_update_tracker('update_torrent', array('info_hash' => rawurlencode($info_hash), 'freetorrent' => $tor_status_gold));
}
}
function tracker_register ($attach_id, $mode = '', $tor_status = TOR_NOT_APPROVED, $reg_time = TIMENOW)
{
global $bb_cfg, $lang, $reg_mode, $tr_cfg;
$attach_id = intval($attach_id);
$reg_mode = $mode;
if (!$torrent = get_torrent_info($attach_id))
{
bb_die($lang['TOR_NOT_FOUND']);
}
$post_id = $torrent['post_id'];
$topic_id = $torrent['topic_id'];
$forum_id = $torrent['forum_id'];
$poster_id = $torrent['poster_id'];
$info_hash = null;
if ($torrent['extension'] !== TORRENT_EXT) return torrent_error_exit($lang['NOT_TORRENT']);
if (!$torrent['allow_reg_tracker']) return torrent_error_exit($lang['REG_NOT_ALLOWED_IN_THIS_FORUM']);
if ($post_id != $torrent['topic_first_post_id']) return torrent_error_exit($lang['ALLOWED_ONLY_1ST_POST_REG']);
if ($torrent['tracker_status']) return torrent_error_exit($lang['ALREADY_REG']);
if ($this_topic_torrents = get_registered_torrents($topic_id, 'topic')) return torrent_error_exit($lang['ONLY_1_TOR_PER_TOPIC']);
torrent_auth_check($forum_id, $torrent['poster_id']);
$filename = get_attachments_dir() .'/'. $torrent['physical_filename'];
if (!is_file($filename)) return torrent_error_exit('File name error');
if (!file_exists($filename)) return torrent_error_exit('File not exists');
if (!$tor = bdecode_file($filename)) return torrent_error_exit('This is not a bencoded file');
if ($bb_cfg['bt_disable_dht'])
{
$tor['info']['private'] = (int) 1;
$fp = fopen($filename, 'w+');
fwrite ($fp, bencode($tor));
fclose ($fp);
}
if ($bb_cfg['bt_check_announce_url'])
{
include(INC_DIR .'torrent_announce_urls.php');
$ann = (@$tor['announce']) ? $tor['announce'] : '';
$announce_urls['main_url'] = $bb_cfg['bt_announce_url'];
if (!$ann || !in_array($ann, $announce_urls))
{
$msg = sprintf($lang['INVALID_ANN_URL'], htmlspecialchars($ann), $announce_urls['main_url']);
return torrent_error_exit($msg);
}
}
$info = (@$tor['info']) ? $tor['info'] : array();
if (!isset($info['name']) || !isset($info['piece length']) || !isset($info['pieces']) || strlen($info['pieces']) % 20 != 0)
{
return torrent_error_exit($lang['TORFILE_INVALID']);
}
$info_hash = pack('H*', sha1(bencode($info)));
$info_hash_sql = rtrim(DB()->escape($info_hash), ' ');
$info_hash_md5 = md5($info_hash);
// Ocelot
if ($bb_cfg['ocelot']['enabled'])
{
ocelot_update_tracker('add_torrent', array('info_hash' => rawurlencode($info_hash), 'id' => $topic_id, 'freetorrent' => 0));
}
if ($row = DB()->fetch_row("SELECT topic_id FROM ". BB_BT_TORRENTS ." WHERE info_hash = '$info_hash_sql' LIMIT 1"))
{
$msg = sprintf($lang['BT_REG_FAIL_SAME_HASH'], TOPIC_URL . $row['topic_id']);
bb_die($msg);
set_die_append_msg($forum_id, $topic_id);
}
$totallen = 0;
if (isset($info['length']))
{
$totallen = (float) $info['length'];
}
else if (isset($info['files']) && is_array($info['files']))
{
foreach ($info['files'] as $fn => $f)
{
$totallen += (float) $f['length'];
}
}
else
{
return torrent_error_exit($lang['TORFILE_INVALID']);
}
$size = sprintf('%.0f', (float) $totallen);
$columns = ' info_hash, post_id, poster_id, topic_id, forum_id, attach_id, size, reg_time, tor_status';
$values = "'$info_hash_sql', $post_id, $poster_id, $topic_id, $forum_id, $attach_id, '$size', $reg_time, $tor_status";
$sql = "INSERT INTO ". BB_BT_TORRENTS ." ($columns) VALUES ($values)";
if (!DB()->sql_query($sql))
{
$sql_error = DB()->sql_error();
if ($sql_error['code'] == 1062) // Duplicate entry
{
return torrent_error_exit($lang['BT_REG_FAIL_SAME_HASH']);
}
bb_die('Could not register torrent on tracker');
}
// update tracker status for this attachment
$sql = 'UPDATE '. BB_ATTACHMENTS_DESC ." SET tracker_status = 1 WHERE attach_id = $attach_id LIMIT 1";
if (!DB()->sql_query($sql))
{
bb_die('Could not update torrent status #2');
}
// set DL-Type for topic
if ($bb_cfg['bt_set_dltype_on_tor_reg'])
{
$sql = 'UPDATE '. BB_TOPICS .' SET topic_dl_type = '. TOPIC_DL_TYPE_DL ." WHERE topic_id = $topic_id LIMIT 1";
if (!$result = DB()->sql_query($sql))
{
bb_die('Could not update topics table #2');
}
}
if ($tr_cfg['tor_topic_up'])
{
DB()->query("UPDATE ". BB_TOPICS ." SET topic_last_post_time = GREATEST(topic_last_post_time, ". (TIMENOW - 3*86400) .") WHERE topic_id = $topic_id LIMIT 1");
}
if ($reg_mode == 'request' || $reg_mode == 'newtopic')
{
set_die_append_msg($forum_id, $topic_id);
$mess = sprintf($lang['BT_REGISTERED'], DOWNLOAD_URL . $attach_id);
bb_die($mess);
}
return;
}
function send_torrent_with_passkey ($filename)
{
global $attachment, $auth_pages, $userdata, $bb_cfg, $tr_cfg, $lang;
if (!$bb_cfg['bt_add_auth_key'] || $attachment['extension'] !== TORRENT_EXT || !$size = @filesize($filename))
{
return;
}
$post_id = $poster_id = $passkey_val = '';
$user_id = $userdata['user_id'];
$attach_id = $attachment['attach_id'];
if (!$passkey_key = $bb_cfg['passkey_key'])
{
bb_die('Could not add passkey (wrong config $bb_cfg[\'passkey_key\'])');
}
// Get $post_id & $poster_id
foreach ($auth_pages as $rid => $row)
{
if ($row['attach_id'] == $attach_id)
{
$post_id = $row['post_id'];
$poster_id = $row['user_id_1'];
break;
}
}
// Get $topic_id
$topic_id_sql = 'SELECT topic_id FROM ' . BB_POSTS . ' WHERE post_id = ' . (int) $post_id;
if (!($topic_id_result = DB()->sql_query($topic_id_sql)))
{
bb_die('Could not query post information');
}
$topic_id_row = DB()->sql_fetchrow($topic_id_result);
$topic_id = $topic_id_row['topic_id'];
if (!$attachment['tracker_status'])
{
bb_die($lang['PASSKEY_ERR_TOR_NOT_REG']);
}
if (bf($userdata['user_opt'], 'user_opt', 'dis_passkey') && !IS_GUEST)
{
bb_die('Could not add passkey');
}
if ($bt_userdata = get_bt_userdata($user_id))
{
$passkey_val = $bt_userdata['auth_key'];
}
if (!$passkey_val)
{
if (!$passkey_val = generate_passkey($user_id))
{
bb_simple_die('Could not generate passkey');
}
elseif ($bb_cfg['ocelot']['enabled'])
{
ocelot_update_tracker('add_user', array('id' => $user_id ,'passkey' => $passkey_val));
}
}
// Ratio limits
$min_ratio = $bb_cfg['bt_min_ratio_allow_dl_tor'];
if ($min_ratio && $user_id != $poster_id && ($user_ratio = get_bt_ratio($bt_userdata)) !== null)
{
if ($user_ratio < $min_ratio && $post_id)
{
$dl = DB()->fetch_row("
SELECT dl.user_status
FROM ". BB_POSTS ." p
LEFT JOIN ". BB_BT_DLSTATUS ." dl ON dl.topic_id = p.topic_id AND dl.user_id = $user_id
WHERE p.post_id = $post_id
LIMIT 1
");
if (!isset($dl['user_status']) || $dl['user_status'] != DL_STATUS_COMPLETE)
{
bb_die(sprintf($lang['BT_LOW_RATIO_FOR_DL'], round($user_ratio, 2), "search.php?dlu=$user_id&amp;dlc=1"));
}
}
}
// Announce URL
$ann_url = $bb_cfg['bt_announce_url'];
if (!$tor = bdecode_file($filename))
{
bb_die('This is not a bencoded file');
}
$announce = $bb_cfg['ocelot']['enabled'] ? strval($bb_cfg['ocelot']['url'] .$passkey_val. "/announce") : strval($ann_url . "?$passkey_key=$passkey_val");
// Replace original announce url with tracker default
if ($bb_cfg['bt_replace_ann_url'] || !isset($tor['announce']))
{
$tor['announce'] = $announce;
}
// Delete all additional urls
if ($bb_cfg['bt_del_addit_ann_urls'] || $bb_cfg['bt_disable_dht'])
{
unset($tor['announce-list']);
}
elseif (isset($tor['announce-list']))
{
$tor['announce-list'] = array_merge($tor['announce-list'], array(array($announce)));
}
// Add retracker
if (isset($tr_cfg['retracker']) && $tr_cfg['retracker'])
{
if (bf($userdata['user_opt'], 'user_opt', 'user_retracker') || IS_GUEST)
{
if (!isset($tor['announce-list']))
{
$tor['announce-list'] = array(
array($announce),
array($tr_cfg['retracker_host'])
);
}
else
{
$tor['announce-list'] = array_merge($tor['announce-list'], array(array($tr_cfg['retracker_host'])));
}
}
}
// Add publisher & topic url
$publisher_name = $bb_cfg['server_name'];
$publisher_url = make_url(TOPIC_URL . $topic_id);
$tor['publisher'] = strval($publisher_name);
unset($tor['publisher.utf-8']);
$tor['publisher-url'] = strval($publisher_url);
unset($tor['publisher-url.utf-8']);
$tor['comment'] = strval($publisher_url);
unset($tor['comment.utf-8']);
// Send torrent
$output = bencode($tor);
$dl_fname = ($bb_cfg['torrent_name_style'] ? '['.$bb_cfg['server_name'].'].t' . $topic_id . '.torrent' : clean_filename(basename($attachment['real_filename'])));
if (!empty($_COOKIE['explain']))
{
$out = "attach path: $filename<br /><br />";
$tor['info']['pieces'] = '[...] '. strlen($tor['info']['pieces']) .' bytes';
$out .= print_r($tor, true);
bb_die("<pre>$out</pre>");
}
header("Content-Type: application/x-bittorrent; name=\"$dl_fname\"");
header("Content-Disposition: attachment; filename=\"$dl_fname\"");
bb_exit($output);
}
function generate_passkey ($user_id, $force_generate = false)
{
global $bb_cfg, $lang, $sql;
$user_id = (int) $user_id;
// Check if user can change passkey
if (!$force_generate)
{
$sql = "SELECT user_opt FROM ". BB_USERS ." WHERE user_id = $user_id LIMIT 1";
if (!$result = DB()->sql_query($sql))
{
bb_die('Could not query userdata for passkey');
}
if ($row = DB()->sql_fetchrow($result))
{
if (bf($row['user_opt'], 'user_opt', 'dis_passkey'))
{
bb_die($lang['NOT_AUTHORISED']);
}
}
}
for ($i=0; $i < 20; $i++)
{
$passkey_val = make_rand_str(BT_AUTH_KEY_LENGTH);
$old_passkey = null;
if ($row = DB()->fetch_row("SELECT auth_key FROM ". BB_BT_USERS ." WHERE user_id = $user_id LIMIT 1"))
{
$old_passkey = $row['auth_key'];
}
// Insert new row
DB()->query("INSERT IGNORE INTO ". BB_BT_USERS ." (user_id, auth_key) VALUES ($user_id, '$passkey_val')");
if (DB()->affected_rows() == 1)
{
return $passkey_val;
}
// Update
DB()->query("UPDATE IGNORE ". BB_BT_USERS ." SET auth_key = '$passkey_val' WHERE user_id = $user_id LIMIT 1");
if (DB()->affected_rows() == 1)
{
// Ocelot
if ($bb_cfg['ocelot']['enabled'])
{
ocelot_update_tracker('change_passkey', array('oldpasskey' => $old_passkey,'newpasskey' => $passkey_val));
}
return $passkey_val;
}
}
return false;
}
function tracker_rm_torrent ($topic_id)
{
return DB()->sql_query("DELETE FROM ". BB_BT_TRACKER ." WHERE topic_id = ". (int) $topic_id);
}
function tracker_rm_user ($user_id)
{
return DB()->sql_query("DELETE FROM ". BB_BT_TRACKER ." WHERE user_id = ". (int) $user_id);
}
function get_registered_torrents ($id, $mode)
{
$field = ($mode == 'topic') ? 'topic_id' : 'post_id';
$sql = "SELECT topic_id FROM ". BB_BT_TORRENTS ." WHERE $field = $id LIMIT 1";
if (!$result = DB()->sql_query($sql))
{
bb_die('Could not query torrent id');
}
if ($rowset = @DB()->sql_fetchrowset($result))
{
return $rowset;
}
else
{
return false;
}
}
function torrent_error_exit ($message)
{
global $reg_mode, $return_message, $lang;
$msg = '';
if (isset($reg_mode) && ($reg_mode == 'request' || $reg_mode == 'newtopic'))
{
if (isset($return_message))
{
$msg .= $return_message .'<br /><br /><hr /><br />';
}
$msg .= '<b>'. $lang['BT_REG_FAIL'] .'</b><br /><br />';
}
bb_die($msg . $message);
}
function ocelot_update_tracker ($action, $updates)
{
global $bb_cfg;
$get = $bb_cfg['ocelot']['secret'] . "/update?action=$action";
foreach ($updates as $key => $value)
{
$get .= "&$key=$value";
}
$max_attempts = 3;
$err = false;
if (ocelot_send_request($get, $max_attempts, $err) === false)
{
return false;
}
return true;
}
function ocelot_send_request ($get, $max_attempts = 1, &$err = false)
{
global $bb_cfg;
$header = "GET /$get HTTP/1.1\r\nConnection: Close\r\n\r\n";
$attempts = $sleep = $success = $response = 0;
$start_time = microtime(true);
while (!$success && $attempts++ < $max_attempts)
{
if ($sleep)
{
sleep($sleep);
}
// Send request
$file = fsockopen($bb_cfg['ocelot']['host'], $bb_cfg['ocelot']['port'], $error_num, $error_string);
if ($file)
{
if (fwrite($file, $header) === false)
{
$err = "Failed to fwrite()";
$sleep = 3;
continue;
}
}
else
{
$err = "Failed to fsockopen() - $error_num - $error_string";
$sleep = 6;
continue;
}
// Check for response
while (!feof($file))
{
$response .= fread($file, 1024);
}
$data_start = strpos($response, "\r\n\r\n") + 4;
$data_end = strrpos($response, "\n");
if ($data_end > $data_start)
{
$data = substr($response, $data_start, $data_end - $data_start);
}
else
{
$data = "";
}
$status = substr($response, $data_end + 1);
if ($status == "success")
{
$success = true;
}
}
return $success;
}
// bdecode: based on OpenTracker
function bdecode_file ($filename)
{
$file_contents = file_get_contents($filename);
return bdecode($file_contents);
}
function bdecode ($str)
{
$pos = 0;
return bdecode_r($str, $pos);
}
function bdecode_r ($str, &$pos)
{
$strlen = strlen($str);
if (($pos < 0) || ($pos >= $strlen))
{
return null;
}
else if ($str[$pos] == 'i')
{
$pos++;
$numlen = strspn($str, '-0123456789', $pos);
$spos = $pos;
$pos += $numlen;
if (($pos >= $strlen) || ($str[$pos] != 'e'))
{
return null;
}
else
{
$pos++;
return floatval(substr($str, $spos, $numlen));
}
}
else if ($str[$pos] == 'd')
{
$pos++;
$ret = array();
while ($pos < $strlen)
{
if ($str[$pos] == 'e')
{
$pos++;
return $ret;
}
else
{
$key = bdecode_r($str, $pos);
if ($key === null)
{
return null;
}
else
{
$val = bdecode_r($str, $pos);
if ($val === null)
{
return null;
}
else if (!is_array($key))
{
$ret[$key] = $val;
}
}
}
}
return null;
}
else if ($str[$pos] == 'l')
{
$pos++;
$ret = array();
while ($pos < $strlen)
{
if ($str[$pos] == 'e')
{
$pos++;
return $ret;
}
else
{
$val = bdecode_r($str, $pos);
if ($val === null)
{
return null;
}
else
{
$ret[] = $val;
}
}
}
return null;
}
else
{
$numlen = strspn($str, '0123456789', $pos);
$spos = $pos;
$pos += $numlen;
if (($pos >= $strlen) || ($str[$pos] != ':'))
{
return null;
}
else
{
$vallen = intval(substr($str, $spos, $numlen));
$pos++;
$val = substr($str, $pos, $vallen);
if (strlen($val) != $vallen)
{
return null;
}
else
{
$pos += $vallen;
return $val;
}
}
}
}

View file

@ -0,0 +1,162 @@
<?php
class upload_common
{
var $cfg = array(
'max_size' => 0,
'max_width' => 0,
'max_height' => 0,
'allowed_ext' => array(),
'upload_path' => '',
);
var $file = array(
'name' => '',
'type' => '',
'size' => 0,
'tmp_name' => '',
'error' => UPLOAD_ERR_NO_FILE,
);
var $orig_name = '';
var $file_path = ''; // Stored file path
var $file_ext = '';
var $file_ext_id = '';
var $file_size = '';
var $ext_ids = array(); // array_flip($bb_cfg['file_id_ext'])
var $errors = array();
var $img_types = array(
1 => 'gif',
2 => 'jpg',
3 => 'png',
6 => 'bmp',
7 => 'tiff',
8 => 'tiff',
);
function init ($cfg = array(), $post_params = array(), $uploaded_only = true)
{
global $bb_cfg, $lang;
$this->cfg = array_merge($this->cfg, $cfg);
$this->file = $post_params;
// upload errors from $_FILES
if ($this->file['error'])
{
$msg = $lang['UPLOAD_ERROR_COMMON'];
$msg .= ($err_desc =& $lang['UPLOAD_ERRORS'][$this->file['error']]) ? " ($err_desc)" : '';
$this->errors[] = $msg;
return false;
}
// file_exists
if (!file_exists($this->file['tmp_name']))
{
$this->errors[] = "Uploaded file not exists: {$this->file['tmp_name']}";
return false;
}
// size
if (!$this->file_size = filesize($this->file['tmp_name']))
{
$this->errors[] = "Uploaded file is empty: {$this->file['tmp_name']}";
return false;
}
if ($this->cfg['max_size'] && $this->file_size > $this->cfg['max_size'])
{
$this->errors[] = sprintf($lang['UPLOAD_ERROR_SIZE'], humn_size($this->cfg['max_size']));
return false;
}
// is_uploaded_file
if ($uploaded_only && !is_uploaded_file($this->file['tmp_name']))
{
$this->errors[] = "Not uploaded file: {$this->file['tmp_name']}";
return false;
}
// get ext
$this->ext_ids = array_flip($bb_cfg['file_id_ext']);
$file_name_ary = explode('.', $this->file['name']);
$this->file_ext = strtolower(end($file_name_ary));
// img
if ($this->cfg['max_width'] || $this->cfg['max_height'])
{
if ($img_info = getimagesize($this->file['tmp_name']))
{
list($width, $height, $type, $attr) = $img_info;
// redefine ext
if (!$width || !$height || !$type || !isset($this->img_types[$type]))
{
$this->errors[] = $lang['UPLOAD_ERROR_FORMAT'];
return false;
}
$this->file_ext = $this->img_types[$type];
// width & height
if (($this->cfg['max_width'] && $width > $this->cfg['max_width']) || ($this->cfg['max_height'] && $height > $this->cfg['max_height']))
{
$this->errors[] = sprintf($lang['UPLOAD_ERROR_DIMENSIONS'], $this->cfg['max_width'], $this->cfg['max_height']);
return false;
}
}
else
{
$this->errors[] = $lang['UPLOAD_ERROR_NOT_IMAGE'];
return false;
}
}
// check ext
if ($uploaded_only && (!isset($this->ext_ids[$this->file_ext]) || !in_array($this->file_ext, $this->cfg['allowed_ext'], true)))
{
$this->errors[] = sprintf($lang['UPLOAD_ERROR_NOT_ALLOWED'], htmlCHR($this->file_ext));
return false;
}
$this->file_ext_id = $this->ext_ids[$this->file_ext];
return true;
}
function store ($mode = '', $params = array())
{
global $bb_cfg;
if ($mode == 'avatar')
{
delete_avatar($params['user_id'], $params['avatar_ext_id']);
$file_path = get_avatar_path($params['user_id'], $this->file_ext_id, $bb_cfg['avatars']['upload_path']);
return $this->_move($file_path);
}
else if ($mode == 'attach')
{
$file_path = get_attach_path($params['topic_id']);
return $this->_move($file_path);
}
else
{
trigger_error("Invalid upload mode: $mode", E_USER_ERROR);
}
}
function _move ($file_path)
{
$dir = dirname($file_path);
if (!file_exists($dir))
{
if (!bb_mkdir($dir))
{
$this->errors[] = "Cannot create dir: $dir";
return false;
}
}
if (!@rename($this->file['tmp_name'], $file_path))
{
if (!@copy($this->file['tmp_name'], $file_path))
{
$this->errors[] = 'Cannot copy tmp file';
return false;
}
@unlink($this->file['tmp_name']);
}
@chmod($file_path, 0664);
return file_exists($file_path);
}
}

View file

@ -0,0 +1,114 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
// !!! $username должен быть предварительно обработан clean_username() !!!
function validate_username ($username, $check_ban_and_taken = true)
{
global $user, $lang;
static $name_chars = 'a-z0-9а-яё_@$%^&;(){}\#\-\'.:+ ';
$username = str_compact($username);
$username = clean_username($username);
// Length
if (mb_strlen($username, 'UTF-8') > USERNAME_MAX_LENGTH)
{
return $lang['USERNAME_TOO_LONG'];
}
else if (mb_strlen($username, 'UTF-8') < USERNAME_MIN_LENGTH)
{
return $lang['USERNAME_TOO_SMALL'];
}
// Allowed symbols
if (!preg_match('#^['.$name_chars.']+$#iu', $username, $m))
{
$invalid_chars = preg_replace('#['.$name_chars.']#iu', '', $username);
return "{$lang['USERNAME_INVALID']}: <b>". htmlCHR($invalid_chars) ."</b>";
}
// HTML Entities
if (preg_match_all('/&(#[0-9]+|[a-z]+);/iu', $username, $m))
{
foreach ($m[0] as $ent)
{
if (!preg_match('/^(&amp;|&lt;|&gt;)$/iu', $ent))
{
return $lang['USERNAME_INVALID'];
}
}
}
if ($check_ban_and_taken)
{
// Занято
$username_sql = DB()->escape($username);
if ($row = DB()->fetch_row("SELECT username FROM ". BB_USERS ." WHERE username = '$username_sql' LIMIT 1"))
{
if ((!IS_GUEST && $row['username'] != $user->name) || IS_GUEST)
{
return $lang['USERNAME_TAKEN'];
}
}
// Запрещено
$banned_names = array();
foreach (DB()->fetch_rowset("SELECT disallow_username FROM ". BB_DISALLOW ." ORDER BY NULL") as $row)
{
$banned_names[] = str_replace('\*', '.*?', preg_quote($row['disallow_username'], '#u'));
}
if ($banned_names_exp = join('|', $banned_names))
{
if (preg_match("#^($banned_names_exp)$#iu", $username))
{
return $lang['USERNAME_DISALLOWED'];
}
}
}
return false;
}
// Check to see if email address is banned or already present in the DB
function validate_email ($email, $check_ban_and_taken = true)
{
global $lang, $userdata;
if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL))
{
return $lang['EMAIL_INVALID'];
}
if (strlen($email) > USEREMAIL_MAX_LENGTH)
{
return $lang['EMAIL_TOO_LONG'];
}
if ($check_ban_and_taken)
{
$banned_emails = array();
foreach (DB()->fetch_rowset("SELECT ban_email FROM ". BB_BANLIST ." ORDER BY NULL") as $row)
{
$banned_emails[] = str_replace('\*', '.*?', preg_quote($row['ban_email'], '#'));
}
if ($banned_emails_exp = join('|', $banned_emails))
{
if (preg_match("#^($banned_emails_exp)$#i", $email))
{
return sprintf($lang['EMAIL_BANNED'], $email);
}
}
$email_sql = DB()->escape($email);
if ($row = DB()->fetch_row("SELECT `user_email` FROM ". BB_USERS ." WHERE user_email = '$email_sql' LIMIT 1"))
{
if($row['user_email'] == $userdata['user_email'])
return false;
else
return $lang['EMAIL_TAKEN'];
}
}
return false;
}

View file

@ -0,0 +1,554 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
if (PHP_VERSION < '5.3') die('TorrentPier II requires PHP version 5.3+. Your PHP version '. PHP_VERSION);
if (!defined('BB_SCRIPT')) define('BB_SCRIPT', 'undefined');
if (!defined('BB_CFG_LOADED')) trigger_error('File config.php not loaded', E_USER_ERROR);
// Define some basic configuration arrays
unset($stopwords, $synonyms_match, $synonyms_replace);
$userdata = $theme = $images = $lang = $nav_links = $bf = $attach_config = array();
$gen_simple_header = false;
$user = null;
// Obtain and encode user IP
$client_ip = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1';
$user_ip = encode_ip($client_ip);
define('CLIENT_IP', $client_ip);
define('USER_IP', $user_ip);
function send_page ($contents)
{
return compress_output($contents);
}
define('UA_GZIP_SUPPORTED', (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false));
function compress_output ($contents)
{
global $bb_cfg;
if ($bb_cfg['gzip_compress'] && GZIP_OUTPUT_ALLOWED && !defined('NO_GZIP'))
{
if (UA_GZIP_SUPPORTED && strlen($contents) > 2000)
{
header('Content-Encoding: gzip');
$contents = gzencode($contents, 1);
}
}
return $contents;
}
// Start output buffering
if (!defined('IN_AJAX'))
{
ob_start('send_page');
}
// Cookie params
$c = $bb_cfg['cookie_prefix'];
define('COOKIE_DATA', $c .'data');
define('COOKIE_FORUM', $c .'f');
define('COOKIE_MARK', $c .'mark_read');
define('COOKIE_TOPIC', $c .'t');
define('COOKIE_PM', $c .'pm');
unset($c);
define('COOKIE_SESSION', 0);
define('COOKIE_EXPIRED', TIMENOW - 31536000);
define('COOKIE_PERSIST', TIMENOW + 31536000);
define('COOKIE_MAX_TRACKS', 90);
function bb_setcookie ($name, $val, $lifetime = COOKIE_PERSIST, $httponly = false)
{
global $bb_cfg;
return setcookie($name, $val, $lifetime, $bb_cfg['script_path'], $bb_cfg['cookie_domain'], $bb_cfg['cookie_secure'], $httponly);
}
// Debug options
if (DBG_USER)
{
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 1);
}
else
{
unset($_COOKIE['explain']);
}
define('DELETED', -1);
// User Levels
define('USER', 0);
define('ADMIN', 1);
define('MOD', 2);
define('GROUP_MEMBER', 20);
define('CP_HOLDER', 25);
$excluded_users = array(
GUEST_UID,
BOT_UID,
);
define('EXCLUDED_USERS_CSV', implode(',', $excluded_users));
// User related
define('USER_ACTIVATION_NONE', 0);
define('USER_ACTIVATION_SELF', 1);
// Group settings
define('GROUP_OPEN', 0);
define('GROUP_CLOSED', 1);
define('GROUP_HIDDEN', 2);
// Forum state
define('FORUM_UNLOCKED', 0);
define('FORUM_LOCKED', 1);
// Topic status
define('TOPIC_UNLOCKED', 0);
define('TOPIC_LOCKED', 1);
define('TOPIC_MOVED', 2);
define('TOPIC_WATCH_NOTIFIED', 1);
define('TOPIC_WATCH_UNNOTIFIED', 0);
// Topic types
define('POST_NORMAL', 0);
define('POST_STICKY', 1);
define('POST_ANNOUNCE', 2);
// Search types
define('SEARCH_TYPE_POST', 0);
define('SEARCH_TYPE_TRACKER', 1);
// Ajax error codes
define('E_AJAX_GENERAL_ERROR', 1000);
define('E_AJAX_NEED_LOGIN', 1001);
// Private messaging
define('PRIVMSGS_READ_MAIL', 0);
define('PRIVMSGS_NEW_MAIL', 1);
define('PRIVMSGS_SENT_MAIL', 2);
define('PRIVMSGS_SAVED_IN_MAIL', 3);
define('PRIVMSGS_SAVED_OUT_MAIL', 4);
define('PRIVMSGS_UNREAD_MAIL', 5);
define('HAVE_UNREAD_PM', 1);
define('HAVE_NEW_PM', 2);
define('USERNAME_MIN_LENGTH', 3);
// URL PARAMETERS (hardcoding allowed)
define('POST_CAT_URL', 'c');
define('POST_FORUM_URL', 'f');
define('POST_GROUPS_URL', 'g');
define('POST_POST_URL', 'p');
define('POST_TOPIC_URL', 't');
define('POST_USERS_URL', 'u');
// Download Modes
define('INLINE_LINK', 1);
define('PHYSICAL_LINK', 2);
// Categories
define('NONE_CAT', 0);
define('IMAGE_CAT', 1);
// Misc
define('ADMIN_MAX_ATTACHMENTS', 50);
define('THUMB_DIR', 'thumbs');
define('MODE_THUMBNAIL', 1);
// Quota Types
define('QUOTA_UPLOAD_LIMIT', 1);
define('QUOTA_PM_LIMIT', 2);
// Torrents
define('TOR_STATUS_NORMAL', 0);
define('TOR_STATUS_FROZEN', 1);
// Gender
define('MALE', 1);
define('FEMALE', 2);
define('NOGENDER', 0);
// Poll
# 1 - обычный опрос
define('POLL_FINISHED', 2);
// Group avatars
define('GROUP_AVATAR_MASK', 999000);
// Torrents (reserved: -1)
define('TOR_NOT_APPROVED', 0); // не проверено
define('TOR_CLOSED', 1); // закрыто
define('TOR_APPROVED', 2); // проверено
define('TOR_NEED_EDIT', 3); // недооформлено
define('TOR_NO_DESC', 4); // неоформлено
define('TOR_DUP', 5); // повтор
define('TOR_CLOSED_CPHOLD', 6); // закрыто правообладателем
define('TOR_CONSUMED', 7); // поглощено
define('TOR_DOUBTFUL', 8); // сомнительно
define('TOR_CHECKING', 9); // проверяется
define('TOR_TMP', 10); // временная
define('TOR_PREMOD', 11); // премодерация
$bb_cfg['tor_icons'] = array(
TOR_NOT_APPROVED => '<span class="tor-icon tor-not-approved">*</span>',
TOR_CLOSED => '<span class="tor-icon tor-closed">x</span>',
TOR_APPROVED => '<span class="tor-icon tor-approved">&radic;</span>',
TOR_NEED_EDIT => '<span class="tor-icon tor-need-edit">?</span>',
TOR_NO_DESC => '<span class="tor-icon tor-no-desc">!</span>',
TOR_DUP => '<span class="tor-icon tor-dup">D</span>',
TOR_CLOSED_CPHOLD => '<span class="tor-icon tor-closed-cp">&copy;</span>',
TOR_CONSUMED => '<span class="tor-icon tor-consumed">&sum;</span>',
TOR_DOUBTFUL => '<span class="tor-icon tor-approved">#</span>',
TOR_CHECKING => '<span class="tor-icon tor-checking">%</span>',
TOR_TMP => '<span class="tor-icon tor-dup">T</span>',
TOR_PREMOD => '<span class="tor-icon tor-dup">&#8719;</span>',
);
// Запрет на скачивание
$bb_cfg['tor_frozen'] = array(
TOR_CHECKING => true,
TOR_CLOSED => true,
TOR_CLOSED_CPHOLD => true,
TOR_CONSUMED => true,
TOR_DUP => true,
TOR_NO_DESC => true,
TOR_PREMOD => true,
);
// Разрешение на скачку автором, если закрыто на скачивание.
$bb_cfg['tor_frozen_author_download'] = array(
TOR_CHECKING => true,
TOR_NO_DESC => true,
TOR_PREMOD => true,
);
// Запрет на редактирование головного сообщения
$bb_cfg['tor_cannot_edit'] = array(
TOR_CHECKING => true,
TOR_CLOSED => true,
TOR_CONSUMED => true,
TOR_DUP => true,
);
// Запрет на создание новых раздач если стоит статус недооформлено/неоформлено/сомнительно
$bb_cfg['tor_cannot_new'] = array(TOR_NEED_EDIT, TOR_NO_DESC, TOR_DOUBTFUL);
// Разрешение на ответ релизера, если раздача исправлена.
$bb_cfg['tor_reply'] = array(TOR_NEED_EDIT, TOR_NO_DESC, TOR_DOUBTFUL);
// Если такой статус у релиза, то статистика раздачи будет скрыта
$bb_cfg['tor_no_tor_act'] = array(
TOR_CLOSED => true,
TOR_DUP => true,
TOR_CLOSED_CPHOLD => true,
TOR_CONSUMED => true,
);
// Table names
define('BUF_TOPIC_VIEW', 'buf_topic_view');
define('BUF_LAST_SEEDER', 'buf_last_seeder');
define('BB_ADS', 'bb_ads');
define('BB_ATTACH_CONFIG', 'bb_attachments_config');
define('BB_ATTACHMENTS_DESC', 'bb_attachments_desc');
define('BB_ATTACHMENTS', 'bb_attachments');
define('BB_AUTH_ACCESS_SNAP', 'bb_auth_access_snap');
define('BB_AUTH_ACCESS', 'bb_auth_access');
define('BB_BANLIST', 'bb_banlist');
define('BB_BT_DLSTATUS', 'bb_bt_dlstatus');
define('BB_BT_DLSTATUS_SNAP', 'bb_bt_dlstatus_snap');
define('BB_BT_LAST_TORSTAT', 'bb_bt_last_torstat');
define('BB_BT_LAST_USERSTAT', 'bb_bt_last_userstat');
define('BB_BT_TORHELP', 'bb_bt_torhelp');
define('BB_BT_TORSTAT', 'bb_bt_torstat');
define('BB_CATEGORIES', 'bb_categories');
define('BB_CAPTCHA', 'bb_captcha');
define('BB_CONFIG', 'bb_config');
define('BB_CRON', 'bb_cron');
define('BB_DISALLOW', 'bb_disallow');
define('BB_EXTENSION_GROUPS', 'bb_extension_groups');
define('BB_EXTENSIONS', 'bb_extensions');
define('BB_FORUMS', 'bb_forums');
define('BB_GROUPS', 'bb_groups');
define('BB_LOG', 'bb_log');
define('BB_POLL_USERS', 'bb_poll_users');
define('BB_POLL_VOTES', 'bb_poll_votes');
define('BB_POSTS_SEARCH', 'bb_posts_search');
define('BB_POSTS', 'bb_posts');
define('BB_POSTS_TEXT', 'bb_posts_text');
define('BB_POSTS_HTML', 'bb_posts_html');
define('BB_PRIVMSGS', 'bb_privmsgs');
define('BB_PRIVMSGS_TEXT', 'bb_privmsgs_text');
define('BB_QUOTA_LIMITS', 'bb_quota_limits');
define('BB_QUOTA', 'bb_attach_quota');
define('BB_RANKS', 'bb_ranks');
define('BB_SEARCH_REBUILD', 'bb_search_rebuild');
define('BB_SEARCH', 'bb_search_results');
define('BB_SESSIONS', 'bb_sessions');
define('BB_SMILIES', 'bb_smilies');
define('BB_TOPIC_TPL', 'bb_topic_tpl');
define('BB_TOPICS', 'bb_topics');
define('BB_TOPICS_WATCH', 'bb_topics_watch');
define('BB_USER_GROUP', 'bb_user_group');
define('BB_USERS', 'bb_users');
define('BB_WORDS', 'bb_words');
define('TORRENT_EXT', 'torrent');
define('TOPIC_DL_TYPE_NORMAL', 0);
define('TOPIC_DL_TYPE_DL', 1);
define('SHOW_PEERS_COUNT', 1);
define('SHOW_PEERS_NAMES', 2);
define('SHOW_PEERS_FULL', 3);
define('SEARCH_ID_LENGTH', 12);
define('SID_LENGTH', 20);
define('LOGIN_KEY_LENGTH', 12);
define('USERNAME_MAX_LENGTH', 25);
define('USEREMAIL_MAX_LENGTH', 40);
define('PAGE_HEADER', INC_DIR .'page_header.php');
define('PAGE_FOOTER', INC_DIR .'page_footer.php');
define('CAT_URL', 'index.php?c=');
define('DOWNLOAD_URL', 'dl.php?id=');
define('FORUM_URL', 'viewforum.php?f=');
define('GROUP_URL', 'group.php?g=');
define('LOGIN_URL', $bb_cfg['login_url']);
define('MODCP_URL', 'modcp.php?f=');
define('PM_URL', $bb_cfg['pm_url']);
define('POST_URL', 'viewtopic.php?p=');
define('POSTING_URL', $bb_cfg['posting_url']);
define('PROFILE_URL', 'profile.php?mode=viewprofile&amp;u=');
define('BONUS_URL', 'profile.php?mode=bonus');
define('TOPIC_URL', 'viewtopic.php?t=');
define('USER_AGENT', strtolower($_SERVER['HTTP_USER_AGENT']));
define('HTML_SELECT_MAX_LENGTH', 60);
define('HTML_WBR_LENGTH', 12);
define('HTML_CHECKED', ' checked="checked" ');
define('HTML_DISABLED', ' disabled="disabled" ');
define('HTML_READONLY', ' readonly="readonly" ');
define('HTML_SELECTED', ' selected="selected" ');
define('HTML_SF_SPACER', '&nbsp;|-&nbsp;');
// $GPC
define('KEY_NAME', 0); // position in $GPC['xxx']
define('DEF_VAL', 1);
define('GPC_TYPE', 2);
define('GET', 1);
define('POST', 2);
define('COOKIE', 3);
define('REQUEST', 4);
define('CHBOX', 5);
define('SELECT', 6);
if (!empty($banned_user_agents))
{
foreach ($banned_user_agents as $agent)
{
if (strstr(USER_AGENT, $agent))
{
$filename = 'Download files by using browser';
$output = '@';
header('Content-Type: text/plain');
header('Content-Disposition: attachment; filename="'. $filename .'"');
die($output);
}
}
}
// Functions
function send_no_cache_headers ()
{
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '. gmdate('D, d M Y H:i:s'). ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
}
function bb_exit ($output = '')
{
if ($output)
{
echo $output;
}
exit;
}
function prn_r ($var, $title = '', $print = true)
{
$r = '<pre>'. (($title) ? "<b>$title</b>\n\n" : '') . htmlspecialchars(print_r($var, true)) .'</pre>';
if ($print) echo $r;
return $r;
}
function pre ($var, $title = '', $print = true)
{
prn_r($var, $title, $print);
}
function prn ()
{
if (!DBG_USER) return;
foreach (func_get_args() as $var) prn_r($var);
}
function vdump ($var, $title = '')
{
echo '<pre>'. (($title) ? "<b>$title</b>\n\n" : '');
var_dump($var);
echo '</pre>';
}
function htmlCHR ($txt, $double_encode = false, $quote_style = ENT_QUOTES, $charset = 'UTF-8')
{
return (string) htmlspecialchars($txt, $quote_style, $charset, $double_encode);
}
function html_ent_decode ($txt, $quote_style = ENT_QUOTES, $charset = 'UTF-8')
{
return (string) html_entity_decode($txt, $quote_style, $charset);
}
function make_url ($path)
{
return FULL_URL . preg_replace('#^\/?(.*?)\/?$#', '\1', $path);
}
require(INC_DIR .'functions.php');
require(INC_DIR .'sessions.php');
require(INC_DIR .'template.php');
require(INC_DIR .'core/mysql.php');
define('SQL_LAYER', 'mysql');
$bb_cfg = array_merge(bb_get_config(BB_CONFIG), $bb_cfg);
$user = new user_common();
$userdata =& $user->data;
if (DBG_USER) require(INC_DIR .'functions_dev.php');
$html = new html_common();
$log_action = new log_action();
$ads = new ads_common();
// TODO temporarily 'cat_forums' always enqueued
$datastore->enqueue(array('cat_forums'));
// Дата старта вашего проекта
if (!$bb_cfg['board_startdate'])
{
bb_update_config(array('board_startdate' => TIMENOW));
DB()->query("UPDATE ". BB_USERS ." SET user_regdate = ". TIMENOW ." WHERE user_id IN(2, ". EXCLUDED_USERS_CSV .")");
}
// Cron
if ((empty($_POST) && !defined('IN_ADMIN') && !defined('IN_AJAX') && !file_exists(CRON_RUNNING) && ($bb_cfg['cron_enabled'] || defined('START_CRON'))) || defined('FORCE_CRON'))
{
if (TIMENOW - $bb_cfg['cron_last_check'] > $bb_cfg['cron_check_interval'])
{
// Update cron_last_check
bb_update_config(array('cron_last_check' => (TIMENOW + 10)));
define('CRON_LOG_ENABLED', true); // global ON/OFF
define('CRON_FORCE_LOG', false); // always log regardless of job settings
define('CRON_DIR', INC_DIR .'cron/');
define('CRON_JOB_DIR', CRON_DIR .'jobs/');
define('CRON_LOG_DIR', 'cron/'); // inside LOG_DIR
define('CRON_LOG_FILE', 'cron'); // without ext
bb_log(date('H:i:s - ') . getmypid() .' -x-- DB-LOCK try'. LOG_LF, CRON_LOG_DIR .'cron_check');
if (DB()->get_lock('cron', 1))
{
bb_log(date('H:i:s - ') . getmypid() .' --x- DB-LOCK OBTAINED !!!!!!!!!!!!!!!!!'. LOG_LF, CRON_LOG_DIR .'cron_check');
sleep(2);
require(CRON_DIR .'cron_init.php');
DB()->release_lock('cron');
}
}
}
$dl_link_css = array(
DL_STATUS_RELEASER => 'genmed',
DL_STATUS_WILL => 'dlWill',
DL_STATUS_DOWN => 'leechmed',
DL_STATUS_COMPLETE => 'seedmed',
DL_STATUS_CANCEL => 'dlCancel',
);
$dl_status_css = array(
DL_STATUS_RELEASER => 'genmed',
DL_STATUS_WILL => 'dlWill',
DL_STATUS_DOWN => 'dlDown',
DL_STATUS_COMPLETE => 'dlComplete',
DL_STATUS_CANCEL => 'dlCancel',
);
// Exit if board is disabled via ON/OFF trigger or by admin
if (($bb_cfg['board_disable'] || file_exists(BB_DISABLED)) && !defined('IN_ADMIN') && !defined('IN_AJAX') && !defined('IN_LOGIN'))
{
header('HTTP/1.0 503 Service Unavailable');
if ($bb_cfg['board_disable'])
{
// admin lock
send_no_cache_headers();
bb_die('BOARD_DISABLE');
}
else if (file_exists(BB_DISABLED))
{
// trigger lock
cron_release_deadlock();
send_no_cache_headers();
bb_die('BOARD_DISABLE_CRON');
}
}
// Cron functions
function cron_release_deadlock ()
{
if (file_exists(CRON_RUNNING))
{
if (TIMENOW - filemtime(CRON_RUNNING) > 2400)
{
cron_enable_board();
cron_release_file_lock();
}
}
}
function cron_release_file_lock ()
{
$lock_released = @rename(CRON_RUNNING, CRON_ALLOWED);
cron_touch_lock_file(CRON_ALLOWED);
}
function cron_touch_lock_file ($lock_file)
{
file_write(make_rand_str(20), $lock_file, 0, true, true);
}
function cron_enable_board ()
{
@rename(BB_DISABLED, BB_ENABLED);
}
function cron_disable_board ()
{
@rename(BB_ENABLED, BB_DISABLED);
}

View file

@ -0,0 +1,153 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
global $lang;
// Obtain user/online information
$logged_online = $guests_online = 0;
$time_online = TIMENOW - 300;
# $time_online = 0;
$ulist = array(
ADMIN => array(),
MOD => array(),
GROUP_MEMBER => array(),
USER => array(),
);
$users_cnt = array(
'admin' => 0,
'mod' => 0,
'group_member' => 0,
'ignore_load' => 0,
'user' => 0,
'guest' => 0,
);
$online = $online_short = array('userlist' => '');
$sql = "
SELECT
u.username, u.user_id, u.user_opt, u.user_rank, u.user_level,
s.session_logged_in, s.session_ip, (s.session_time - s.session_start) AS ses_len, COUNT(s.session_id) AS sessions, COUNT(DISTINCT s.session_ip) AS ips
FROM ". BB_SESSIONS ." s, ". BB_USERS ." u
WHERE s.session_time > $time_online
AND u.user_id = s.session_user_id
GROUP BY s.session_user_id
ORDER BY u.username
";
foreach (DB()->fetch_rowset($sql) as $u)
{
if ($u['session_logged_in'])
{
$stat = array();
$name = profile_url($u);
$level = $u['user_level'];
if ($level == ADMIN)
{
$name = "<b>$name</b>";
$users_cnt['admin']++;
}
else if ($level == MOD)
{
$name = "<b>$name</b>";
$users_cnt['mod']++;
}
else if ($level == GROUP_MEMBER)
{
$name = "<b>$name</b>";
$users_cnt['group_member']++;
}
else
{
$users_cnt['user']++;
}
if ($u['sessions'] > 3)
{
$color = ($u['sessions'] > 2) ? '#FF0000' : '#B22222';
$s = $u['sessions'];
$stat[] = "s:<span style=\"color: $color\">$s</span>";
}
if ($u['ips'] > 2)
{
$ip = $u['ips'];
$stat[] = "ip:<span style=\"color: #0000FF\">$ip</span>";
}
if ($u['ses_len'] > 6*3600 && $level == USER)
{
$t = round($u['ses_len'] / 3600, 1);
$stat[] = "t:<span style=\"color: #1E90FF\">$t</span>";
}
$ulist[$level][] = ($stat) ? "$name<span class=\"ou_stat\" style=\"color: #707070\" title=\"{$u['session_ip']}\"> [<b>". join(', ', $stat) .'</b>]</span>' : $name;
}
else
{
$guests_online = $u['ips'];
$users_cnt['guest'] = $guests_online;
}
}
if ($ulist)
{
$inline = $block = $short = array();
foreach ($ulist as $level => $users)
{
if (empty($users)) continue;
if (count($users) > 200)
{
$style = 'margin: 3px 0; padding: 2px 4px; border: 1px inset; height: 200px; overflow: auto;';
$block[] = "<div style=\"$style\">\n". join(",\n", $users) ."</div>\n";
$short[] = '<a href="index.php?online_full=1#online">'. $lang['USERS'] .': '. count($users) .'</a>';
}
else
{
$inline[] = join(",\n", $users);
$short[] = join(",\n", $users);
}
$logged_online += count($users);
}
$online['userlist'] = join(",\n", $inline) . join("\n", $block);
$online_short['userlist'] = join(",\n", $short);
}
if (!$online['userlist'])
{
$online['userlist'] = $online_short['userlist'] = $lang['NONE'];
}
else if (isset($_REQUEST['f']))
{
$online['userlist'] = $online_short['userlist'] = $lang['BROWSING_FORUM'] .' '. $online['userlist'];
}
$total_online = $logged_online + $guests_online;
if ($total_online > $bb_cfg['record_online_users'])
{
bb_update_config(array(
'record_online_users' => $total_online,
'record_online_date' => TIMENOW,
));
}
$online['stat'] = $online_short['stat'] = sprintf($lang['ONLINE_USERS'], $total_online, $logged_online, $guests_online);
$online['cnt'] = $online_short['cnt'] = <<<HTML
[
<span class="colorAdmin bold">{$users_cnt['admin']}</span> <span class="small">&middot;</span>
<span class="colorMod bold">{$users_cnt['mod']}</span> <span class="small">&middot;</span>
<span class="colorGroup bold">{$users_cnt['group_member']}</span> <span class="small">&middot;</span>
<span class="colorISL">{$users_cnt['ignore_load']}</span> <span class="small">&middot;</span>
<span>{$users_cnt['user']}</span> <span class="small">&middot;</span>
<span>{$users_cnt['guest']}</span>
]
HTML;
CACHE('bb_cache')->set('online_'.$userdata['user_lang'], $online, 60);
CACHE('bb_cache')->set('online_short_'.$userdata['user_lang'], $online_short, 60);

View file

@ -0,0 +1,105 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
global $bb_cfg, $userdata, $template, $DBS, $lang;
if (!empty($template))
{
$template->assign_vars(array(
'SIMPLE_FOOTER' => !empty($gen_simple_header),
'POWERED' => base64_decode($lang['POWERED']),
'SHOW_ADMIN_LINK' => (IS_ADMIN && !defined('IN_ADMIN')),
'ADMIN_LINK_HREF' => "admin/index.php",
));
$template->set_filenames(array('page_footer' => 'page_footer.tpl'));
$template->pparse('page_footer');
}
$show_dbg_info = (DBG_USER && IS_ADMIN && !(isset($_GET['pane']) && $_GET['pane'] == 'left'));
if(!$bb_cfg['gzip_compress'])
{
flush();
}
if ($show_dbg_info)
{
$gen_time = utime() - TIMESTART;
$gen_time_txt = sprintf('%.3f', $gen_time);
$gzip_text = (UA_GZIP_SUPPORTED) ? 'GZIP ' : '<s>GZIP</s> ';
$gzip_text .= ($bb_cfg['gzip_compress']) ? $lang['ON'] : $lang['OFF'];
$stat = '[&nbsp; '. $lang['EXECUTION_TIME'] ." $gen_time_txt ". $lang['SEC'];
if (!empty($DBS))
{
$sql_t = $DBS->sql_timetotal;
$sql_time_txt = ($sql_t) ? sprintf('%.3f '.$lang['SEC'].' (%d%%) &middot; ', $sql_t, round($sql_t*100/$gen_time)) : '';
$num_q = $DBS->num_queries;
$stat .= " &nbsp;|&nbsp; MySQL: {$sql_time_txt}{$num_q} " . $lang['QUERIES'];
}
$stat .= " &nbsp;|&nbsp; $gzip_text";
$stat .= ' &nbsp;|&nbsp; '.$lang['MEMORY'];
$stat .= humn_size($bb_cfg['mem_on_start'], 2) .' / ';
$stat .= humn_size(sys('mem_peak'), 2) .' / ';
$stat .= humn_size(sys('mem'), 2);
if ($l = sys('la'))
{
$l = explode(' ', $l);
for ($i=0; $i < 3; $i++)
{
$l[$i] = round($l[$i], 1);
}
$stat .= " &nbsp;|&nbsp; ". $lang['LIMIT'] ." $l[0] $l[1] $l[2]";
}
$stat .= ' &nbsp;]';
$stat .= '
<label><input type="checkbox" onclick="setCookie(\'sql_log\', this.checked ? 1 : 0); window.location.reload();" '. (!empty($_COOKIE['sql_log']) ? HTML_CHECKED : '') .' />show log </label>
<label title="cut long queries"><input type="checkbox" onclick="setCookie(\'sql_log_full\', this.checked ? 1 : 0); window.location.reload();" '. (!empty($_COOKIE['sql_log_full']) ? HTML_CHECKED : '') .' />cut </label>
<label><input type="checkbox" onclick="setCookie(\'explain\', this.checked ? 1 : 0); window.location.reload();" '. (!empty($_COOKIE['explain']) ? HTML_CHECKED : '') .' />explain </label>
';
$stat .= !empty($_COOKIE['sql_log']) ? '[ <a href="#" class="med" onclick="$p(\'sqlLog\').className=\'sqlLog sqlLogWrapped\'; return false;">wrap</a> &middot; <a href="#sqlLog" class="med" onclick="$(\'#sqlLog\').css({ height: $(window).height()-50 }); return false;">max</a> ]' : '';
echo '<div style="margin: 6px; font-size:10px; color: #444444; letter-spacing: -1px; text-align: center;">'. $stat .'</div>';
}
echo '
</div><!--/body_container-->
';
if (DBG_USER && SQL_DEBUG && !(isset($_GET['pane']) && $_GET['pane'] == 'left'))
{
require(INC_DIR . 'page_footer_dev.php');
}
##### LOG #####
global $log_ip_resp;
if (isset($log_ip_resp[USER_IP]) || isset($log_ip_resp[CLIENT_IP]))
{
$str = date('H:i:s') . LOG_SEPR . preg_replace("#\s+#", ' ', $contents) . LOG_LF;
$file = 'sessions/'. date('m-d') .'_{'. USER_IP .'}_'. CLIENT_IP .'_resp';
bb_log($str, $file);
}
### LOG END ###
echo '
</body>
</html>
';
if (defined('REQUESTED_PAGE') && !defined('DISABLE_CACHING_OUTPUT'))
{
if (IS_GUEST === true)
{
caching_output(true, 'store', REQUESTED_PAGE .'_guest_'. $bb_cfg['default_lang']);
}
}
bb_exit();

View file

@ -0,0 +1,102 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
?>
<style type="text/css">
.sqlLog {
clear: both;
font-family: Courier, monospace;
font-size: 12px;
white-space: nowrap;
background: #F5F5F5;
border: 1px solid #BBC0C8;
overflow: auto;
width: 98%;
margin: 0 auto;
padding: 2px 4px;
}
.sqlLogTitle {
font-weight: bold;
color: #444444;
font-size: 11px;
font-family: Verdana, Arial, Helvetica, sans-serif;
padding-bottom: 2px;
}
.sqlLogRow {
background-color: #F5F5F5;
padding-bottom: 1px;
border: solid #F5F5F5;
border-width: 0 0 1px 0;
cursor: pointer;
}
.sqlLogHead {
text-align: right;
float: right;
width: 100%;
}
.sqlLogHead fieldset {
float: right;
margin-right: 4px;
}
.sqlLogWrapped {
white-space: normal;
overflow: visible;
}
.sqlExplain {
color: #B50000;
font-size: 13px;
cursor: default;
}
.sqlHover {
border-color: #8B0000;
}
.sqlHighlight {
background: #FFE4E1;
}
</style>
<?php
if (!empty($_COOKIE['explain']))
{
foreach ($DBS->srv as $srv_name => $db_obj)
{
if (!empty($db_obj->do_explain))
{
$db_obj->explain('display');
}
}
}
$sql_log = !empty($_COOKIE['sql_log']) ? get_sql_log() : '';
echo '
<script type="text/javascript">
function fixSqlLog() {
if ($("#sqlLog").height() > 400) {
$("#sqlLog").height(400);
}
$("#sqlLog div.sqlLogRow")
.hover(
function(){ $(this).addClass("sqlHover"); },
function(){ $(this).removeClass("sqlHover"); }
)
.click(
function(){ $(this).toggleClass("sqlHighlight"); }
)
;
}
</script>
<div class="sqlLogHead">
';
echo '</div><!-- / sqlLogHead -->';
if ($sql_log)
{
echo '<div class="sqlLog" id="sqlLog">'. ($sql_log ? $sql_log : '') .'</div><!-- / sqlLog --><br clear="all" />';
}
?>
<script type="text/javascript">
$(document).ready(fixSqlLog);
</script>

View file

@ -0,0 +1,276 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
if (defined('PAGE_HEADER_SENT')) return;
// Parse and show the overall page header
global $page_cfg, $userdata, $user, $ads, $bb_cfg, $template, $lang, $images;
$logged_in = (int) !empty($userdata['session_logged_in']);
// Generate logged in/logged out status
if ($logged_in)
{
$u_login_logout = BB_ROOT . LOGIN_URL . "?logout=1";
}
else
{
$u_login_logout = BB_ROOT . LOGIN_URL;
}
// Online userlist
if (defined('SHOW_ONLINE') && SHOW_ONLINE)
{
$online_full = !empty($_REQUEST['online_full']);
$online_list = ($online_full) ? 'online_'.$userdata['user_lang'] : 'online_short_'.$userdata['user_lang'];
${$online_list} = array(
'stat' => '',
'userlist' => '',
'cnt' => '',
);
if (defined('IS_GUEST') && !(IS_GUEST || IS_USER))
{
$template->assign_var('SHOW_ONLINE_LIST');
if (!${$online_list} = CACHE('bb_cache')->get($online_list))
{
require(INC_DIR .'online_userlist.php');
}
}
$template->assign_vars(array(
'TOTAL_USERS_ONLINE' => ${$online_list}['stat'],
'LOGGED_IN_USER_LIST' => ${$online_list}['userlist'],
'USERS_ONLINE_COUNTS' => ${$online_list}['cnt'],
'RECORD_USERS' => sprintf($lang['RECORD_ONLINE_USERS'], $bb_cfg['record_online_users'], bb_date($bb_cfg['record_online_date'])),
));
}
// Info about new private messages
$icon_pm = $images['pm_no_new_msg'];
$pm_info = $lang['NO_NEW_PM'];
$have_new_pm = $have_unread_pm = 0;
if ($logged_in && empty($gen_simple_header) && !defined('IN_ADMIN'))
{
if ($userdata['user_new_privmsg'])
{
$have_new_pm = $userdata['user_new_privmsg'];
$icon_pm = $images['pm_new_msg'];
$pm_info = declension($userdata['user_new_privmsg'], $lang['NEW_PMS_DECLENSION'], $lang['NEW_PMS_FORMAT']);
if ($userdata['user_last_privmsg'] > $userdata['user_lastvisit'] && defined('IN_PM'))
{
$userdata['user_last_privmsg'] = $userdata['user_lastvisit'];
db_update_userdata($userdata, array(
'user_last_privmsg' => $userdata['user_lastvisit'],
));
$have_new_pm = ($userdata['user_new_privmsg'] > 1);
}
}
if (!$have_new_pm && $userdata['user_unread_privmsg'])
{
// synch unread pm count
if (defined('IN_PM'))
{
$row = DB()->fetch_row("
SELECT COUNT(*) AS pm_count
FROM ". BB_PRIVMSGS ."
WHERE privmsgs_to_userid = ". $userdata['user_id'] ."
AND privmsgs_type = ". PRIVMSGS_UNREAD_MAIL ."
GROUP BY privmsgs_to_userid
");
$real_unread_pm_count = (int) $row['pm_count'];
if ($userdata['user_unread_privmsg'] != $real_unread_pm_count)
{
$userdata['user_unread_privmsg'] = $real_unread_pm_count;
db_update_userdata($userdata, array(
'user_unread_privmsg' => $real_unread_pm_count,
));
}
}
$pm_info = declension($userdata['user_unread_privmsg'], $lang['UNREAD_PMS_DECLENSION'], $lang['UNREAD_PMS_FORMAT']);
$have_unread_pm = true;
}
}
$template->assign_vars(array(
'HAVE_NEW_PM' => $have_new_pm,
'HAVE_UNREAD_PM' => $have_unread_pm,
));
// The following assigns all _common_ variables that may be used at any point in a template
$template->assign_vars(array(
'SIMPLE_HEADER' => !empty($gen_simple_header),
'IN_ADMIN' => defined('IN_ADMIN'),
'SHOW_ADS' => (!$logged_in || isset($bb_cfg['show_ads_users'][$user->id]) || (!IS_AM && $user->show_ads)),
'USER_HIDE_CAT' => (BB_SCRIPT == 'index'),
'USER_LANG' => $userdata['user_lang'],
'INCLUDE_BBCODE_JS' => !empty($page_cfg['include_bbcode_js']),
'USER_OPTIONS_JS' => (IS_GUEST) ? '{}' : bb_json_encode($user->opt_js),
'USE_TABLESORTER' => !empty($page_cfg['use_tablesorter']),
'SITENAME' => $bb_cfg['sitename'],
'U_INDEX' => BB_ROOT ."index.php",
'T_INDEX' => sprintf($lang['FORUM_INDEX'], $bb_cfg['sitename']),
'IS_GUEST' => IS_GUEST,
'IS_USER' => IS_USER,
'IS_ADMIN' => IS_ADMIN,
'IS_MOD' => IS_MOD,
'IS_AM' => IS_AM,
'FORUM_PATH' => FORUM_PATH,
'FULL_URL' => FULL_URL,
'CURRENT_TIME' => sprintf($lang['CURRENT_TIME'], bb_date(TIMENOW, $bb_cfg['last_visit_date_format'], false)),
'S_TIMEZONE' => preg_replace('/\(.*?\)/', '', sprintf($lang['ALL_TIMES'], $lang['TZ'][str_replace(',', '.', floatval($bb_cfg['board_timezone']))])),
'BOARD_TIMEZONE' => $bb_cfg['board_timezone'],
'PM_INFO' => $pm_info,
'PRIVMSG_IMG' => $icon_pm,
'LOGGED_IN' => $logged_in,
'SESSION_USER_ID' => $userdata['user_id'],
'POINTS' => $userdata['user_points'],
'THIS_USER' => profile_url($userdata),
'THIS_AVATAR' => get_avatar($userdata['user_id'], $userdata['avatar_ext_id'], !bf($userdata['user_opt'], 'user_opt', 'dis_avatar')),
'SHOW_LOGIN_LINK' => !defined('IN_LOGIN'),
'AUTOLOGIN_DISABLED' => !$bb_cfg['allow_autologin'],
'S_LOGIN_ACTION' => LOGIN_URL,
'U_CUR_DOWNLOADS' => PROFILE_URL . $userdata['user_id'],
'U_FORUM' => "viewforum.php",
'U_GROUPS' => "group.php",
'U_LOGIN_LOGOUT' => $u_login_logout,
'U_MEMBERLIST' => "memberlist.php",
'U_MODCP' => "modcp.php",
'U_OPTIONS' => "profile.php?mode=editprofile",
'U_PRIVATEMSGS' => PM_URL . "?folder=inbox",
'U_PROFILE' => PROFILE_URL . $userdata['user_id'],
'U_READ_PM' => PM_URL . "?folder=inbox". (($userdata['user_newest_pm_id'] && $userdata['user_new_privmsg'] == 1) ? "&mode=read&p={$userdata['user_newest_pm_id']}" : ''),
'U_REGISTER' => "profile.php?mode=register",
'U_SEARCH' => "search.php",
'U_SEND_PASSWORD' => "profile.php?mode=sendpassword",
'U_TERMS' => $bb_cfg['terms_and_conditions_url'],
'U_TRACKER' => "tracker.php",
'SHOW_SIDEBAR1' => (!empty($page_cfg['show_sidebar1'][BB_SCRIPT]) || $bb_cfg['show_sidebar1_on_every_page']),
'SHOW_SIDEBAR2' => (!empty($page_cfg['show_sidebar2'][BB_SCRIPT]) || $bb_cfg['show_sidebar2_on_every_page']),
'HTML_AGREEMENT' => LANG_DIR . 'html/user_agreement.html',
'HTML_COPYRIGHT' => LANG_DIR . 'html/copyright_holders.html',
'HTML_ADVERT' => LANG_DIR . 'html/advert.html',
'HTML_SIDEBAR_1' => LANG_DIR . 'html/sidebar1.html',
'HTML_SIDEBAR_2' => LANG_DIR . 'html/sidebar2.html',
// Common urls
'AVATARS_URL' => 'data/avatars',
'CAT_URL' => BB_ROOT . CAT_URL,
'DOWNLOAD_URL' => BB_ROOT . DOWNLOAD_URL,
'FORUM_URL' => BB_ROOT . FORUM_URL,
'GROUP_URL' => BB_ROOT . GROUP_URL,
'LOGIN_URL' => $bb_cfg['login_url'],
'NEWEST_URL' => '&amp;view=newest#newest',
'PM_URL' => $bb_cfg['pm_url'],
'POST_URL' => BB_ROOT . POST_URL,
'POSTING_URL' => $bb_cfg['posting_url'],
'PROFILE_URL' => BB_ROOT . PROFILE_URL,
'TOPIC_URL' => BB_ROOT . TOPIC_URL,
'AJAX_HTML_DIR' => AJAX_HTML_DIR,
'ONLY_NEW_POSTS' => ONLY_NEW_POSTS,
'ONLY_NEW_TOPICS' => ONLY_NEW_TOPICS,
// Misc
'BOT_UID' => BOT_UID,
'COOKIE_MARK' => COOKIE_MARK,
'SID' => $userdata['session_id'],
'SID_HIDDEN' => '<input type="hidden" name="sid" value="'. $userdata['session_id'] .'" />',
'CHECKED' => HTML_CHECKED,
'DISABLED' => HTML_DISABLED,
'READONLY' => HTML_READONLY,
'SELECTED' => HTML_SELECTED,
'U_SEARCH_SELF_BY_LAST' => "search.php?uid={$userdata['user_id']}&amp;o=5",
'U_WATCHED_TOPICS' => "profile.php?mode=watch",
));
if (!empty($page_cfg['show_torhelp'][BB_SCRIPT]) && !empty($userdata['torhelp']))
{
$ignore_time = !empty($_COOKIE['torhelp']) ? (int) $_COOKIE['torhelp'] : 0;
if (TIMENOW > $ignore_time)
{
if ($ignore_time)
{
bb_setcookie('torhelp', '', COOKIE_EXPIRED);
}
$sql = "
SELECT topic_id, topic_title
FROM ". BB_TOPICS ."
WHERE topic_id IN(". $userdata['torhelp'] .")
LIMIT 8
";
$torhelp_topics = array();
foreach (DB()->fetch_rowset($sql) as $row)
{
$torhelp_topics[] = '<a href="viewtopic.php?t='. $row['topic_id'] .'">'. $row['topic_title'] .'</a>';
}
$template->assign_vars(array(
'TORHELP_TOPICS' => join("</li>\n<li>", $torhelp_topics),
));
}
}
// Ads
if ($user->show_ads)
{
$load_ads = array('trans');
if (defined('BB_SCRIPT'))
{
$load_ads[] = BB_SCRIPT;
}
foreach ($ads->get($load_ads) as $block_id => $ad_html)
{
$template->assign_var("AD_BLOCK_{$block_id}", $ad_html);
}
}
// Login box
$in_out = ($logged_in) ? 'in' : 'out';
$template->assign_block_vars("switch_user_logged_{$in_out}", array());
if (!IS_GUEST)
{
header('Cache-Control: private, pre-check=0, post-check=0, max-age=0');
header('Expires: 0');
header('Pragma: no-cache');
}
$template->set_filenames(array('page_header' => 'page_header.tpl'));
$template->pparse('page_header');
define('PAGE_HEADER_SENT', true);
if (!$bb_cfg['gzip_compress'])
{
flush();
}

View file

@ -0,0 +1,82 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$can_edit_tpl = IS_SUPER_ADMIN;
$edit_tpl_mode = ($can_edit_tpl && !empty($_REQUEST['edit_tpl']));
// forum_data
$sql = "SELECT forum_name, allow_reg_tracker, forum_tpl_id FROM ". BB_FORUMS ." WHERE forum_id = $forum_id LIMIT 1";
if (!$forum_id OR !$f_data = DB()->fetch_row($sql))
{
bb_die($lang['FORUM_NOT_EXIST']);
}
// tpl_data
$tpl_data = array();
$sql = "SELECT * FROM ". BB_TOPIC_TPL ." WHERE tpl_id = {$f_data['forum_tpl_id']} LIMIT 1";
if (!$f_data['forum_tpl_id'] OR !$tpl_data = DB()->fetch_row($sql))
{
if (!$edit_tpl_mode)
{
redirect(POSTING_URL . "?mode=newtopic&f=$forum_id");
}
}
$template->assign_vars(array(
'PAGE_TITLE' => $lang['NEW_RELEASE'],
'FORUM_NAME' => $f_data['forum_name'],
'FORUM_ID' => $forum_id,
'TPL_FORM_ACTION' => POSTING_URL . "?mode=newtopic&amp;f=$forum_id",
'REGULAR_TOPIC_HREF' => POSTING_URL . "?mode=newtopic&amp;f=$forum_id",
'TOR_REQUIRED' => $f_data['allow_reg_tracker'],
'EDIT_TPL' => $edit_tpl_mode,
'CAN_EDIT_TPL' => $can_edit_tpl,
'EDIT_TPL_URL' => POSTING_URL . "?mode=new_rel&amp;f=$forum_id&amp;edit_tpl=1",
));
if ($tpl_data)
{
// tpl_rules_html
$tpl_rules_html = '';
if ($tpl_data['tpl_rules_post_id'])
{
if (!$tpl_rules_html = bbcode2html(DB()->fetch_row("SELECT post_text FROM ". BB_POSTS_TEXT ." WHERE post_id = ". $tpl_data['tpl_rules_post_id'], 'post_text')))
{
$tpl_data['tpl_rules_post_id'] = 0;
DB()->query("UPDATE ". BB_TOPIC_TPL ." SET tpl_rules_post_id = 0 WHERE tpl_id = {$f_data['forum_tpl_id']} LIMIT 1");
}
}
$template->assign_vars(array(
'TPL_ID' => $tpl_data['tpl_id'],
'TPL_NAME' => $tpl_data['tpl_name'],
'TPL_SRC_FORM_VAL' => $tpl_data['tpl_src_form'],
'TPL_SRC_TITLE_VAL' => $tpl_data['tpl_src_title'],
'TPL_SRC_MSG_VAL' => $tpl_data['tpl_src_msg'],
'TPL_RULES_HTML' => $tpl_rules_html,
));
}
if ($edit_tpl_mode)
{
$template->assign_vars(array(
'NO_TPL_ASSIGNED' => !($f_data['forum_tpl_id']),
'TPL_SELECT' => get_select('forum_tpl', $f_data['forum_tpl_id']),
));
if ($tpl_data)
{
$template->assign_vars(array(
'TPL_COMMENT' => $tpl_data['tpl_comment'],
'TPL_RULES_POST_ID' => $tpl_data['tpl_rules_post_id'],
'TPL_LAST_EDIT_TIME' => bb_date($tpl_data['tpl_last_edit_tm'], 'd-M-y H:i'),
'TPL_LAST_EDIT_USER' => get_username(intval($tpl_data['tpl_last_edit_by'])),
'TPL_LAST_EDIT_TIMESTAMP' => $tpl_data['tpl_last_edit_tm'],
));
}
}
print_page(TEMPLATES_DIR . 'posting_tpl.tpl');

View file

@ -0,0 +1,890 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
define('ONLY_NEW_POSTS', 1);
define('ONLY_NEW_TOPICS', 2);
class user_common
{
/**
* Config
*/
var $cfg = array(
'req_login' => false, // requires user to be logged in
'req_session_admin' => false, // requires active admin session (for moderation or admin actions)
);
/**
* PHP-JS exchangeable options (JSON'ized as {USER_OPTIONS_JS} in TPL)
*/
var $opt_js = array(
'only_new' => 0, // show ony new posts or topics
'h_av' => 0, // hide avatar
'h_rnk_i' => 0, // hide rank images
'h_post_i' => 0, // hide post images
'h_smile' => 0, // hide smilies
'h_sig' => 0, // hide signatures
'sp_op' => 0, // show spoiler opened
'tr_t_ax' => 0, // ajax open topics
'tr_t_t' => 0, // show time of the creation topics
'hl_tr' => 1, // show cursor in tracker.php
'i_aft_l' => 0, // show images only after full loading
'h_tsp' => 0, // show released title {...}
);
/**
* Defaults options for guests
*/
var $opt_js_guest = array(
'h_av' => 1, // hide avatar
'h_rnk_i' => 1, // hide rank images
'h_smile' => 1, // hide smilies
'h_sig' => 1, // hide signatures
);
/**
* Sessiondata
*/
var $sessiondata = array(
'uk' => null,
'uid' => null,
'sid' => '',
);
/**
* Old $userdata
*/
var $data = array();
/**
* Shortcuts
*/
var $id = null;
/**
* Misc
*/
var $show_ads = false;
/**
* Constructor
*/
function user_common ()
{
$this->get_sessiondata();
}
/**
* Start session (restore existent session or create new)
*/
function session_start ($cfg = array())
{
global $bb_cfg;
$update_sessions_table = false;
$this->cfg = array_merge($this->cfg, $cfg);
$session_id = $this->sessiondata['sid'];
// Does a session exist?
if ($session_id || !$this->sessiondata['uk'])
{
$SQL = DB()->get_empty_sql_array();
$SQL['SELECT'][] = "u.*, s.*";
$SQL['FROM'][] = BB_SESSIONS ." s";
$SQL['INNER JOIN'][] = BB_USERS ." u ON(u.user_id = s.session_user_id)";
if ($session_id)
{
$SQL['WHERE'][] = "s.session_id = '$session_id'";
if ($bb_cfg['torhelp_enabled'])
{
$SQL['SELECT'][] = "th.topic_id_csv AS torhelp";
$SQL['LEFT JOIN'][] = BB_BT_TORHELP ." th ON(u.user_id = th.user_id)";
}
$userdata_cache_id = $session_id;
}
else
{
$SQL['WHERE'][] = "s.session_ip = '". USER_IP ."'";
$SQL['WHERE'][] = "s.session_user_id = ". GUEST_UID;
$userdata_cache_id = USER_IP;
}
if (!$this->data = cache_get_userdata($userdata_cache_id))
{
$this->data = DB()->fetch_row($SQL);
if ($this->data && (TIMENOW - $this->data['session_time']) > $bb_cfg['session_update_intrv'])
{
$this->data['session_time'] = TIMENOW;
$update_sessions_table = true;
}
cache_set_userdata($this->data);
}
}
##### LOG #####
global $log_ip_req;
if (isset($log_ip_req[USER_IP]) || isset($log_ip_req[CLIENT_IP]))
{
$file = 'sessions/'. date('m-d') .'_{'. USER_IP .'}_'. CLIENT_IP;
$str = array();
$str[] = date('H:i:s');
$str[] = (@$this->sessiondata['uid']) ? sprintf('%06d', strval($this->sessiondata['uid'])) : 'guest ';
$str[] = (@$this->data['session_start']) ? gmdate('H:i:s', $this->data['session_start']) : 'guest ';
$str[] = (@$this->sessiondata['sid']) ? sprintf('%-12s', strval($this->sessiondata['sid'])) : 'none ';
$str[] = $_SERVER['REQUEST_URI'];
# $str[] = 'REFERER: '. $_SERVER['HTTP_REFERER'];
$str[] = @$_SERVER['HTTP_USER_AGENT'];
$str = join(LOG_SEPR, $str) . LOG_LF;
bb_log($str, $file);
}
### LOG END ###
// Did the session exist in the DB?
if ($this->data)
{
// Do not check IP assuming equivalence, if IPv4 we'll check only first 24
// bits ... I've been told (by vHiker) this should alleviate problems with
// load balanced et al proxies while retaining some reliance on IP security.
$ip_check_s = substr($this->data['session_ip'], 0, 6);
$ip_check_u = substr(USER_IP, 0, 6);
if ($ip_check_s == $ip_check_u)
{
if ($this->data['user_id'] != GUEST_UID && defined('IN_ADMIN'))
{
define('SID_GET', "sid={$this->data['session_id']}");
}
$session_id = $this->sessiondata['sid'] = $this->data['session_id'];
// Only update session a minute or so after last update
if ($update_sessions_table)
{
DB()->query("
UPDATE ". BB_SESSIONS ." SET
session_time = ". TIMENOW ."
WHERE session_id = '$session_id'
LIMIT 1
");
}
$this->set_session_cookies($this->data['user_id']);
}
else
{
$this->data = array();
}
}
// If we reach here then no (valid) session exists. So we'll create a new one,
// using the cookie user_id if available to pull basic user prefs.
if (!$this->data)
{
$login = false;
$user_id = ($bb_cfg['allow_autologin'] && $this->sessiondata['uk'] && $this->sessiondata['uid']) ? $this->sessiondata['uid'] : GUEST_UID;
if ($userdata = get_userdata(intval($user_id), false, true))
{
if ($userdata['user_id'] != GUEST_UID && $userdata['user_active'])
{
if (verify_id($this->sessiondata['uk'], LOGIN_KEY_LENGTH) && $this->verify_autologin_id($userdata, true, false))
{
$login = ($userdata['autologin_id'] && $this->sessiondata['uk'] === $userdata['autologin_id']);
}
}
}
if (!$userdata || ($userdata['user_id'] != GUEST_UID && !$login))
{
$userdata = get_userdata(GUEST_UID, false, true);
}
$this->session_create($userdata, true);
}
define('IS_GUEST', (!$this->data['session_logged_in']));
define('IS_ADMIN', (!IS_GUEST && $this->data['user_level'] == ADMIN));
define('IS_MOD', (!IS_GUEST && $this->data['user_level'] == MOD));
define('IS_GROUP_MEMBER', (!IS_GUEST && $this->data['user_level'] == GROUP_MEMBER));
define('IS_USER', (!IS_GUEST && $this->data['user_level'] == USER));
define('IS_SUPER_ADMIN', (IS_ADMIN && isset($bb_cfg['super_admins'][$this->data['user_id']])));
define('IS_AM', (IS_ADMIN || IS_MOD));
$this->set_shortcuts();
// Redirect guests to login page
if (IS_GUEST && $this->cfg['req_login'])
{
login_redirect();
}
$this->init_userprefs();
return $this->data;
}
/**
* Create new session for the given user
*/
function session_create ($userdata, $auto_created = false)
{
global $bb_cfg;
$this->data = $userdata;
$session_id = $this->sessiondata['sid'];
$login = (int) ($this->data['user_id'] != GUEST_UID);
$is_user = ($this->data['user_level'] != ADMIN);
$user_id = (int) $this->data['user_id'];
$mod_admin_session = ($this->data['user_level'] == ADMIN || $this->data['user_level'] == MOD);
// Initial ban check against user_id or IP address
if ($is_user)
{
preg_match('#(..)(..)(..)(..)#', USER_IP, $ip);
$where_sql = "ban_ip IN('". USER_IP ."', '$ip[1]$ip[2]$ip[3]ff', '$ip[1]$ip[2]ffff', '$ip[1]ffffff')";
$where_sql .= ($login) ? " OR ban_userid = $user_id" : '';
$sql = "SELECT ban_id FROM ". BB_BANLIST ." WHERE $where_sql LIMIT 1";
if (DB()->fetch_row($sql))
{
header('Location: http://torrentpier.me/pages/banned/');
}
}
// Create new session
for ($i=0, $max_try=5; $i <= $max_try; $i++)
{
$session_id = make_rand_str(SID_LENGTH);
$args = DB()->build_array('INSERT', array(
'session_id' => (string) $session_id,
'session_user_id' => (int) $user_id,
'session_start' => (int) TIMENOW,
'session_time' => (int) TIMENOW,
'session_ip' => (string) USER_IP,
'session_logged_in' => (int) $login,
'session_admin' => (int) $mod_admin_session,
));
$sql = "INSERT INTO ". BB_SESSIONS . $args;
if (@DB()->query($sql))
{
break;
}
if ($i == $max_try)
{
trigger_error('Error creating new session', E_USER_ERROR);
}
}
// Update last visit for logged in users
if ($login)
{
$last_visit = $this->data['user_lastvisit'];
if (!$session_time = $this->data['user_session_time'])
{
$last_visit = TIMENOW;
define('FIRST_LOGON', true);
}
else if ($session_time < (TIMENOW - $bb_cfg['last_visit_update_intrv']))
{
$last_visit = max($session_time, (TIMENOW - 86400*$bb_cfg['max_last_visit_days']));
}
if ($last_visit != $this->data['user_lastvisit'])
{
DB()->query("
UPDATE ". BB_USERS ." SET
user_session_time = ". TIMENOW .",
user_lastvisit = $last_visit,
user_last_ip = '". USER_IP ."',
user_reg_ip = IF(user_reg_ip = '', '". USER_IP ."', user_reg_ip)
WHERE user_id = $user_id
LIMIT 1
");
bb_setcookie(COOKIE_TOPIC, '');
bb_setcookie(COOKIE_FORUM, '');
$this->data['user_lastvisit'] = $last_visit;
}
if (!empty($_POST['autologin']) && $bb_cfg['allow_autologin'])
{
if (!$auto_created)
{
$this->verify_autologin_id($this->data, true, true);
}
$this->sessiondata['uk'] = $this->data['autologin_id'];
}
$this->sessiondata['uid'] = $user_id;
$this->sessiondata['sid'] = $session_id;
}
$this->data['session_id'] = $session_id;
$this->data['session_ip'] = USER_IP;
$this->data['session_user_id'] = $user_id;
$this->data['session_logged_in'] = $login;
$this->data['session_start'] = TIMENOW;
$this->data['session_time'] = TIMENOW;
$this->data['session_admin'] = $mod_admin_session;
$this->set_session_cookies($user_id);
if ($login && (defined('IN_ADMIN') || $mod_admin_session))
{
define('SID_GET', "sid=$session_id");
}
cache_set_userdata($this->data);
return $this->data;
}
/**
* Initialize sessiondata stored in cookies
*/
function session_end ($update_lastvisit = false, $set_cookie = true)
{
DB()->query("
DELETE FROM ". BB_SESSIONS ."
WHERE session_id = '{$this->data['session_id']}'
");
if (!IS_GUEST)
{
if ($update_lastvisit)
{
DB()->query("
UPDATE ". BB_USERS ." SET
user_session_time = ". TIMENOW .",
user_lastvisit = ". TIMENOW .",
user_last_ip = '". USER_IP ."',
user_reg_ip = IF(user_reg_ip = '', '". USER_IP ."', user_reg_ip)
WHERE user_id = {$this->data['user_id']}
LIMIT 1
");
}
if (isset($_REQUEST['reset_autologin']))
{
$this->create_autologin_id($this->data, false);
DB()->query("
DELETE FROM ". BB_SESSIONS ."
WHERE session_user_id = '{$this->data['user_id']}'
");
}
}
if ($set_cookie)
{
$this->set_session_cookies(GUEST_UID);
}
}
/**
* Login
*/
function login ($args, $mod_admin_login = false)
{
$username = !empty($args['login_username']) ? clean_username($args['login_username']) : '';
$password = !empty($args['login_password']) ? $args['login_password'] : '';
if ($username && $password)
{
$username_sql = str_replace("\\'", "''", $username);
$password_sql = md5(md5($password));
$sql = "
SELECT *
FROM ". BB_USERS ."
WHERE username = '$username_sql'
AND user_password = '$password_sql'
AND user_active = 1
AND user_id != ". GUEST_UID ."
LIMIT 1
";
if ($userdata = DB()->fetch_row($sql))
{
if (!$userdata['username'] || !$userdata['user_password'] || $userdata['user_id'] == GUEST_UID || md5(md5($password)) !== $userdata['user_password'] || !$userdata['user_active'])
{
trigger_error('invalid userdata', E_USER_ERROR);
}
// Start mod/admin session
if ($mod_admin_login)
{
DB()->query("
UPDATE ". BB_SESSIONS ." SET
session_admin = ". $this->data['user_level'] ."
WHERE session_user_id = ". $this->data['user_id'] ."
AND session_id = '". $this->data['session_id'] ."'
");
$this->data['session_admin'] = $this->data['user_level'];
cache_update_userdata($this->data);
return $this->data;
}
else if ($new_session_userdata = $this->session_create($userdata, false))
{
// Removing guest sessions from this IP
DB()->query("
DELETE FROM ". BB_SESSIONS ."
WHERE session_ip = '". USER_IP ."'
AND session_user_id = ". GUEST_UID ."
");
return $new_session_userdata;
}
else
{
trigger_error("Could not start session : login", E_USER_ERROR);
}
}
}
return array();
}
/**
* Initialize sessiondata stored in cookies
*/
function get_sessiondata ()
{
$sd_resv = !empty($_COOKIE[COOKIE_DATA]) ? @unserialize($_COOKIE[COOKIE_DATA]) : array();
// autologin_id
if (!empty($sd_resv['uk']) && verify_id($sd_resv['uk'], LOGIN_KEY_LENGTH))
{
$this->sessiondata['uk'] = $sd_resv['uk'];
}
// user_id
if (!empty($sd_resv['uid']))
{
$this->sessiondata['uid'] = intval($sd_resv['uid']);
}
// sid
if (!empty($sd_resv['sid']) && verify_id($sd_resv['sid'], SID_LENGTH))
{
$this->sessiondata['sid'] = $sd_resv['sid'];
}
}
/**
* Store sessiondata in cookies
*/
function set_session_cookies ($user_id)
{
global $bb_cfg;
if ($user_id == GUEST_UID)
{
$delete_cookies = array(
COOKIE_DATA,
COOKIE_DBG,
'torhelp',
'explain',
'sql_log',
'sql_log_full',
);
foreach ($delete_cookies as $cookie)
{
if (isset($_COOKIE[$cookie]))
{
bb_setcookie($cookie, '', COOKIE_EXPIRED);
}
}
}
else
{
$c_sdata_resv = !empty($_COOKIE[COOKIE_DATA]) ? $_COOKIE[COOKIE_DATA] : null;
$c_sdata_curr = ($this->sessiondata) ? serialize($this->sessiondata) : '';
if ($c_sdata_curr !== $c_sdata_resv)
{
bb_setcookie(COOKIE_DATA, $c_sdata_curr, COOKIE_PERSIST, true);
}
if (isset($bb_cfg['dbg_users'][$this->data['user_id']]) && !isset($_COOKIE[COOKIE_DBG]))
{
bb_setcookie(COOKIE_DBG, 1, COOKIE_SESSION);
}
}
}
/**
* Verify autologin_id
*/
function verify_autologin_id ($userdata, $expire_check = false, $create_new = true)
{
global $bb_cfg;
$autologin_id = $userdata['autologin_id'];
if ($expire_check)
{
if ($create_new && !$autologin_id)
{
return $this->create_autologin_id($userdata);
}
else if ($autologin_id && $userdata['user_session_time'] && $bb_cfg['max_autologin_time'])
{
if (TIMENOW - $userdata['user_session_time'] > $bb_cfg['max_autologin_time']*86400)
{
return $this->create_autologin_id($userdata, $create_new);
}
}
}
return verify_id($autologin_id, LOGIN_KEY_LENGTH);
}
/**
* Create autologin_id
*/
function create_autologin_id ($userdata, $create_new = true)
{
$autologin_id = ($create_new) ? make_rand_str(LOGIN_KEY_LENGTH) : '';
DB()->query("
UPDATE ". BB_USERS ." SET
autologin_id = '$autologin_id'
WHERE user_id = ". (int) $userdata['user_id'] ."
LIMIT 1
");
return $autologin_id;
}
/**
* Set shortcuts
*/
function set_shortcuts ()
{
$this->id =& $this->data['user_id'];
$this->active =& $this->data['user_active'];
$this->name =& $this->data['username'];
$this->lastvisit =& $this->data['user_lastvisit'];
$this->regdate =& $this->data['user_regdate'];
$this->level =& $this->data['user_level'];
$this->opt =& $this->data['user_opt'];
$this->ip = CLIENT_IP;
}
/**
* Initialise user settings
*/
function init_userprefs ()
{
global $bb_cfg, $theme, $lang, $DeltaTime;
if (defined('LANG_DIR')) return; // prevent multiple calling
define('DEFAULT_LANG_DIR', LANG_ROOT_DIR . $bb_cfg['default_lang'] .'/');
define('ENGLISH_LANG_DIR', LANG_ROOT_DIR .'en/');
if ($this->data['user_id'] != GUEST_UID)
{
if ($this->data['user_lang'] && $this->data['user_lang'] != $bb_cfg['default_lang'])
{
$bb_cfg['default_lang'] = basename($this->data['user_lang']);
define('LANG_DIR', LANG_ROOT_DIR . $bb_cfg['default_lang'] .'/');
}
if (isset($this->data['user_timezone']))
{
$bb_cfg['board_timezone'] = $this->data['user_timezone'];
}
}
$this->data['user_lang'] = $bb_cfg['default_lang'];
$this->data['user_timezone'] = $bb_cfg['board_timezone'];
if (!defined('LANG_DIR')) define('LANG_DIR', DEFAULT_LANG_DIR);
require(LANG_DIR .'main.php');
$theme = setup_style();
$DeltaTime = new Date_Delta();
// Handle marking posts read
if (!IS_GUEST && !empty($_COOKIE[COOKIE_MARK]))
{
$this->mark_read($_COOKIE[COOKIE_MARK]);
}
$this->load_opt_js();
$this->enqueue_ads();
}
/**
* Mark read
*/
function mark_read ($type)
{
if ($type === 'all_forums')
{
// Update session time
DB()->query("
UPDATE ". BB_SESSIONS ." SET
session_time = ". TIMENOW ."
WHERE session_id = '{$this->data['session_id']}'
LIMIT 1
");
// Update userdata
$this->data['session_time'] = TIMENOW;
$this->data['user_lastvisit'] = TIMENOW;
// Update lastvisit
db_update_userdata($this->data, array(
'user_session_time' => $this->data['session_time'],
'user_lastvisit' => $this->data['user_lastvisit'],
));
// Delete cookies
bb_setcookie(COOKIE_TOPIC, '');
bb_setcookie(COOKIE_FORUM, '');
bb_setcookie(COOKIE_MARK, '');
}
}
/**
* Load misc options
*/
function load_opt_js ()
{
if (IS_GUEST)
{
$this->opt_js = array_merge($this->opt_js, $this->opt_js_guest);
}
else if (!empty($_COOKIE['opt_js']))
{
$opt_js = bb_json_decode($_COOKIE['opt_js']);
if (is_array($opt_js))
{
$this->opt_js = array_merge($this->opt_js, $opt_js);
}
}
}
/**
* Get not auth forums
*/
function get_not_auth_forums ($auth_type)
{
global $datastore;
if (IS_ADMIN) return '';
if (!$forums = $datastore->get('cat_forums'))
{
$datastore->update('cat_forums');
$forums = $datastore->get('cat_forums');
}
if ($auth_type == AUTH_VIEW)
{
if (IS_GUEST)
{
return $forums['not_auth_forums']['guest_view'];
}
}
if ($auth_type == AUTH_READ)
{
if (IS_GUEST)
{
return $forums['not_auth_forums']['guest_read'];
}
}
$auth_field_match = array(
AUTH_VIEW => 'auth_view',
AUTH_READ => 'auth_read',
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_ATTACH => 'auth_attachments',
AUTH_DOWNLOAD => 'auth_download',
);
$not_auth_forums = array();
$auth_field = $auth_field_match[$auth_type];
$is_auth_ary = auth($auth_type, AUTH_LIST_ALL, $this->data);
foreach ($is_auth_ary as $forum_id => $is_auth)
{
if (!$is_auth[$auth_field])
{
$not_auth_forums[] = $forum_id;
}
}
return join(',', $not_auth_forums);
}
/**
* Get excluded forums
*/
function get_excluded_forums ($auth_type, $return_as = 'csv')
{
$excluded = array();
if ($not_auth = $this->get_not_auth_forums($auth_type))
{
$excluded[] = $not_auth;
}
if (bf($this->opt, 'user_opt', 'user_porn_forums'))
{
global $datastore;
if (!$forums = $datastore->get('cat_forums'))
{
$datastore->update('cat_forums');
$forums = $datastore->get('cat_forums');
}
if (isset($forums['forum']))
{
foreach ($forums['forum'] as $key => $row)
{
if ($row['allow_porno_topic']) $excluded[] = $row['forum_id'];
}
}
}
switch ($return_as)
{
case 'csv': return join(',', $excluded);
case 'array': return $excluded;
case 'flip': return array_flip(explode(',', $excluded));
}
}
/**
* Enqueue ads
*/
function enqueue_ads ()
{
global $datastore, $bb_cfg;
if ($bb_cfg['show_ads'] && !bf($this->opt, 'user_opt', 'user_hide_ads') && !defined('IN_ADMIN') && !defined('IN_AJAX'))
{
$datastore->enqueue('ads');
$this->show_ads = true;
}
}
}
//
// userdata cache
//
function ignore_cached_userdata ()
{
return (defined('IN_PM')) ? true : false;
}
function cache_get_userdata ($id)
{
if (ignore_cached_userdata()) return false;
return CACHE('session_cache')->get($id);
}
function cache_set_userdata ($userdata, $force = false)
{
global $bb_cfg;
if (!$userdata || (ignore_cached_userdata() && !$force)) return false;
$id = ($userdata['user_id'] == GUEST_UID) ? $userdata['session_ip'] : $userdata['session_id'];
return CACHE('session_cache')->set($id, $userdata, $bb_cfg['session_update_intrv']);
}
function cache_rm_userdata ($userdata)
{
if (!$userdata) return false;
$id = ($userdata['user_id'] == GUEST_UID) ? $userdata['session_ip'] : $userdata['session_id'];
return CACHE('session_cache')->rm($id);
}
// $user_id - array(id1,id2,..) or (string) id
function cache_rm_user_sessions ($user_id)
{
$user_id = get_id_csv($user_id);
$rowset = DB()->fetch_rowset("
SELECT session_id FROM ". BB_SESSIONS ." WHERE session_user_id IN($user_id)
");
foreach ($rowset as $row)
{
CACHE('session_cache')->rm($row['session_id']);
}
}
function cache_update_userdata ($userdata)
{
return cache_set_userdata($userdata, true);
}
function db_update_userdata ($userdata, $sql_ary, $data_already_escaped = true)
{
if (!$userdata) return false;
$sql_args = DB()->build_array('UPDATE', $sql_ary, $data_already_escaped);
DB()->query("UPDATE ". BB_USERS ." SET $sql_args WHERE user_id = {$userdata['user_id']}");
if (DB()->affected_rows())
{
cache_rm_userdata($userdata);
}
}
// $user_id - array(id1,id2,..) or (string) id
function delete_user_sessions ($user_id)
{
cache_rm_user_sessions($user_id);
$user_id = get_id_csv($user_id);
DB()->query("DELETE FROM ". BB_SESSIONS ." WHERE session_user_id IN($user_id)");
}
// deprecated
function session_begin ($userdata, $page_id = 0, $enable_autologin = false, $auto_created = false)
{
global $user;
$user->session_create($userdata, $auto_created);
return $user->data;
}
// deprecated
function session_pagestart ($user_ip = USER_IP, $page_id = 0, $req_login = false)
{
global $user;
$user->session_start(array('req_login' => $req_login));
return $user->data;
}

183
library/includes/smtp.php Normal file
View file

@ -0,0 +1,183 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
define('SMTP_INCLUDED', 1);
function server_parse($socket, $response, $line = __LINE__)
{
$server_response = '';
while (substr($server_response, 3, 1) != ' ')
{
if (!($server_response = fgets($socket, 256)))
{
bb_die('Could not get mail server response codes');
}
}
if (!(substr($server_response, 0, 3) == $response))
{
bb_die('Ran into problems sending mail. Response: '. $server_response);
}
}
// Replacement or substitute for PHP's mail command
function smtpmail($mail_to, $subject, $message, $headers = '')
{
global $bb_cfg;
// Fix any bare linefeeds in the message to make it RFC821 Compliant.
$message = preg_replace("#(?<!\r)\n#si", "\r\n", $message);
if ($headers != '')
{
if (is_array($headers))
{
if (sizeof($headers) > 1)
{
$headers = join("\n", $headers);
}
else
{
$headers = $headers[0];
}
}
$headers = chop($headers);
// Make sure there are no bare linefeeds in the headers
$headers = preg_replace('#(?<!\r)\n#si', "\r\n", $headers);
// Ok this is rather confusing all things considered,
// but we have to grab bcc and cc headers and treat them differently
// Something we really didn't take into consideration originally
$header_array = explode("\r\n", $headers);
@reset($header_array);
$headers = $cc = $bcc = '';
while(list(, $header) = each($header_array))
{
if (preg_match('#^cc:#si', $header))
{
$cc = preg_replace('#^cc:(.*)#si', '\1', $header);
}
else if (preg_match('#^bcc:#si', $header))
{
$bcc = preg_replace('#^bcc:(.*)#si', '\1', $header);
$header = '';
}
$headers .= ($header != '') ? $header . "\r\n" : '';
}
$headers = chop($headers);
$cc = explode(', ', $cc);
$bcc = explode(', ', $bcc);
}
if (trim($subject) == '')
{
bb_die('No email subject specified');
}
if (trim($message) == '')
{
bb_die('Email message was blank');
}
// Ok we have error checked as much as we can to this point let's get on it already
$ssl = ($bb_cfg['smtp_ssl']) ? 'ssl://' : '';
if( !$socket = @fsockopen($ssl . $bb_cfg['smtp_host'], $bb_cfg['smtp_port'], $errno, $errstr, 20) )
{
bb_die('Could not connect to smtp host : '. $errno .' : '. $errstr);
}
// Wait for reply
server_parse($socket, "220", __LINE__);
// Do we want to use AUTH?, send RFC2554 EHLO, else send RFC821 HELO
// This improved as provided by SirSir to accomodate
if( !empty($bb_cfg['smtp_username']) && !empty($bb_cfg['smtp_password']) )
{
fputs($socket, "EHLO " . $bb_cfg['smtp_host'] . "\r\n");
server_parse($socket, "250", __LINE__);
fputs($socket, "AUTH LOGIN\r\n");
server_parse($socket, "334", __LINE__);
fputs($socket, base64_encode($bb_cfg['smtp_username']) . "\r\n");
server_parse($socket, "334", __LINE__);
fputs($socket, base64_encode($bb_cfg['smtp_password']) . "\r\n");
server_parse($socket, "235", __LINE__);
}
else
{
fputs($socket, "HELO " . $bb_cfg['smtp_host'] . "\r\n");
server_parse($socket, "250", __LINE__);
}
// From this point onward most server response codes should be 250
// Specify who the mail is from....
fputs($socket, "MAIL FROM: <" . $bb_cfg['board_email'] . ">\r\n");
server_parse($socket, "250", __LINE__);
// Add an additional bit of error checking to the To field.
$mail_to = (trim($mail_to) == '') ? 'Undisclosed-recipients:;' : trim($mail_to);
if (preg_match('#[^ ]+\@[^ ]+#', $mail_to))
{
fputs($socket, "RCPT TO: <$mail_to>\r\n");
server_parse($socket, "250", __LINE__);
}
// Ok now do the CC and BCC fields...
@reset($bcc);
while(list(, $bcc_address) = each($bcc))
{
// Add an additional bit of error checking to bcc header...
$bcc_address = trim($bcc_address);
if (preg_match('#[^ ]+\@[^ ]+#', $bcc_address))
{
fputs($socket, "RCPT TO: <$bcc_address>\r\n");
server_parse($socket, "250", __LINE__);
}
}
@reset($cc);
while(list(, $cc_address) = each($cc))
{
// Add an additional bit of error checking to cc header
$cc_address = trim($cc_address);
if (preg_match('#[^ ]+\@[^ ]+#', $cc_address))
{
fputs($socket, "RCPT TO: <$cc_address>\r\n");
server_parse($socket, "250", __LINE__);
}
}
// Ok now we tell the server we are ready to start sending data
fputs($socket, "DATA\r\n");
// This is the last response code we look for until the end of the message.
server_parse($socket, "354", __LINE__);
// Send the Subject Line...
fputs($socket, "Subject: $subject\r\n");
// Now the To Header.
fputs($socket, "To: $mail_to\r\n");
// Now any custom headers....
fputs($socket, "$headers\r\n\r\n");
// Ok now we are ready for the message...
fputs($socket, "$message\r\n");
// Ok the all the ingredients are mixed in let's cook this puppy...
fputs($socket, ".\r\n");
server_parse($socket, "250", __LINE__);
// Now tell the server we are done and close the socket...
fputs($socket, "QUIT\r\n");
fclose($socket);
return TRUE;
}

View file

@ -0,0 +1,164 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
//
// remove_comments will strip the sql comment lines out of an uploaded sql file
// specifically for mssql and postgres type files in the install....
//
function remove_comments(&$output)
{
$lines = explode("\n", $output);
$output = "";
// try to keep mem. use down
$linecount = count($lines);
$in_comment = false;
for($i = 0; $i < $linecount; $i++)
{
if( preg_match("/^\/\*/", preg_quote($lines[$i])) )
{
$in_comment = true;
}
if( !$in_comment )
{
$output .= $lines[$i] . "\n";
}
if( preg_match("/\*\/$/", preg_quote($lines[$i])) )
{
$in_comment = false;
}
}
unset($lines);
return $output;
}
//
// remove_remarks will strip the sql comment lines out of an uploaded sql file
//
function remove_remarks($sql)
{
$lines = explode("\n", $sql);
// try to keep mem. use down
$sql = "";
$linecount = count($lines);
$output = "";
for ($i = 0; $i < $linecount; $i++)
{
if (($i != ($linecount - 1)) || (strlen($lines[$i]) > 0))
{
if ($lines[$i][0] != "#")
{
$output .= $lines[$i] . "\n";
}
else
{
$output .= "\n";
}
// Trading a bit of speed for lower mem. use here.
$lines[$i] = "";
}
}
return $output;
}
//
// split_sql_file will split an uploaded sql file into single sql statements.
// Note: expects trim() to have already been run on $sql.
//
function split_sql_file($sql, $delimiter)
{
// Split up our string into "possible" SQL statements.
$tokens = explode($delimiter, $sql);
// try to save mem.
$sql = "";
$output = array();
// we don't actually care about the matches preg gives us.
$matches = array();
// this is faster than calling count($oktens) every time thru the loop.
$token_count = count($tokens);
for ($i = 0; $i < $token_count; $i++)
{
// Don't wanna add an empty string as the last thing in the array.
if (($i != ($token_count - 1)) || (strlen($tokens[$i] > 0)))
{
// This is the total number of single quotes in the token.
$total_quotes = preg_match_all("/'/", $tokens[$i], $matches);
// Counts single quotes that are preceded by an odd number of backslashes,
// which means they're escaped quotes.
$escaped_quotes = preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $tokens[$i], $matches);
$unescaped_quotes = $total_quotes - $escaped_quotes;
// If the number of unescaped quotes is even, then the delimiter did NOT occur inside a string literal.
if (($unescaped_quotes % 2) == 0)
{
// It's a complete sql statement.
$output[] = $tokens[$i];
// save memory.
$tokens[$i] = "";
}
else
{
// incomplete sql statement. keep adding tokens until we have a complete one.
// $temp will hold what we have so far.
$temp = $tokens[$i] . $delimiter;
// save memory..
$tokens[$i] = "";
// Do we have a complete statement yet?
$complete_stmt = false;
for ($j = $i + 1; (!$complete_stmt && ($j < $token_count)); $j++)
{
// This is the total number of single quotes in the token.
$total_quotes = preg_match_all("/'/", $tokens[$j], $matches);
// Counts single quotes that are preceded by an odd number of backslashes,
// which means they're escaped quotes.
$escaped_quotes = preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $tokens[$j], $matches);
$unescaped_quotes = $total_quotes - $escaped_quotes;
if (($unescaped_quotes % 2) == 1)
{
// odd number of unescaped quotes. In combination with the previous incomplete
// statement(s), we now have a complete statement. (2 odds always make an even)
$output[] = $temp . $tokens[$j];
// save memory.
$tokens[$j] = "";
$temp = "";
// exit the loop.
$complete_stmt = true;
// make sure the outer loop continues at the right point.
$i = $j;
}
else
{
// even number of unescaped quotes. We still don't have a complete statement.
// (1 odd and 1 even always make an odd)
$temp .= $tokens[$j] . $delimiter;
// save memory.
$tokens[$j] = "";
}
} // for..
} // else
}
}
return $output;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,11 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$announce_urls = array();
// Here you can define additional allowed announce urls
// For example, if you want to add http://demo.torrentpier.me
// add this line: $announce_urls[] = 'http://demo.torrentpier.me/bt/announce.php';
// $announce_urls[] = 'http://demo.torrentpier.me/bt/announce.php';

View file

@ -0,0 +1,142 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$show_canceled_in_count_mode = false;
$title_date_format = 'Y-m-d';
$dl_list_sql_limit = 300; // DL-List overall limit
$max_dl_users_before_overflow = 100; // for each dl-status
$dl_users_overflow_div_height = '120px';
$dl_users_div_style_normal = 'padding: 0px;';
$dl_users_div_style_overflow = "padding: 6px; height: $dl_users_overflow_div_height; overflow: auto; border: 1px inset;";
$template->assign_vars(array('DL_BUTTONS' => false));
$count_mode = ($bb_cfg['bt_dl_list_only_count'] && !(@$_GET['dl'] === 'names'));
$dl_topic = ($t_data['topic_dl_type'] == TOPIC_DL_TYPE_DL && !($bb_cfg['bt_dl_list_only_1st_page'] && $start));
$show_dl_list = ($dl_topic && ($bb_cfg['bt_show_dl_list'] || ($bb_cfg['allow_dl_list_names_mode'] && @$_GET['dl'] === 'names')));
$show_dl_buttons = ($dl_topic && $bb_cfg['bt_show_dl_list_buttons']);
// link to clear DL-List
$template->assign_vars(array('S_DL_DELETE' => false));
if (($is_auth['auth_mod']) && ($t_data['topic_dl_type'] == TOPIC_DL_TYPE_DL))
{
$s_dl_delete = "<br /><a href=\"dl_list.php?mode=dl_delete&amp;". POST_TOPIC_URL ."=$topic_id&amp;sid=". $userdata['session_id'] .'">'. $lang['DL_LIST_DEL'] .'</a>';
$template->assign_vars(array('S_DL_DELETE' => $s_dl_delete));
}
$dl_cat = $dl_count = array();
if ($show_dl_list)
{
foreach ($dl_status_css as $i => $desc)
{
$dl_cat[$i] = '';
$dl_count[$i] = 0;
}
if ($count_mode)
{
$sql = "SELECT dl_status AS user_status, users_count AS username
FROM ". BB_BT_DLSTATUS_SNAP ."
WHERE topic_id = $topic_id";
}
else
{
$sql = "SELECT d.user_status, d.user_id, DATE_FORMAT(d.last_modified_dlstatus, '%Y-%m-%d') AS last_modified_dlstatus, u.username, u.user_rank
FROM ". BB_BT_DLSTATUS ." d, ". BB_USERS ." u
WHERE d.topic_id = $topic_id
AND d.user_id = u.user_id
AND d.user_status != ". DL_STATUS_RELEASER ."
ORDER BY d.user_status /* ASC, d.last_modified_dlstatus DESC */
LIMIT $dl_list_sql_limit";
}
if ($dl_info = DB()->fetch_rowset($sql))
{
if ($count_mode)
{
$template->assign_block_vars('dl_counts', array());
}
else
{
$template->assign_block_vars('dl_users', array());
}
foreach ($dl_info as $rid => $u)
{
$u_link_class = $dl_status_css[$u['user_status']];
if ($count_mode)
{
$dl_cat[$u['user_status']] = $u['username'];
$dl_count[$u['user_status']] = $u['username'];
}
else
{
$u_prof_href = ($u['user_id'] == GUEST_UID) ? '#' : "profile.php?mode=viewprofile&amp;u=". $u['user_id'] ."#torrent";
$dl_cat[$u['user_status']] .= '<nobr><a class="'. $u_link_class .'" href="'. $u_prof_href .'" title="'. $u['last_modified_dlstatus'] .'">'. profile_url(array('username' => $u['username'], 'user_rank' => $u['user_rank'])) .'</a></nobr>, ';
$dl_count[$u['user_status']]++;
}
}
foreach ($dl_status_css as $i => $desc)
{
if ($dl_cat[$i] && !$count_mode)
{
$dl_users_div_style = ($dl_count[$i] > $max_dl_users_before_overflow) ? $dl_users_div_style_overflow : $dl_users_div_style_normal;
$dl_cat[$i][strlen($dl_cat[$i])-2] = ' ';
$dl_cat[$i] = "<span class=$desc>". $dl_cat[$i] .'</span>';
$template->assign_block_vars('dl_users.users_row', array(
'DL_OPTION_NAME' => $lang[strtoupper($desc)],
'DL_OPTION_USERS' => $dl_cat[$i],
'DL_COUNT' => $dl_count[$i],
'DL_USERS_DIV_STYLE' => $dl_users_div_style,
));
}
else if ($dl_count[$i] && $count_mode)
{
if ($i == DL_STATUS_CANCEL && !$show_canceled_in_count_mode)
{
continue;
}
$template->assign_block_vars('dl_counts.count_row', array(
'DL_OPTION_NAME' => $lang[strtoupper($desc)],
'DL_OPTION_USERS' => $dl_count[$i],
));
}
}
}
else
{
$template->assign_block_vars('dl_list_none', array());
}
}
if ($show_dl_buttons)
{
$template->assign_vars(array(
'DL_BUTTONS' => true,
'DL_BUT_WILL' => $bb_cfg['bt_show_dl_but_will'],
'DL_BUT_DOWN' => $bb_cfg['bt_show_dl_but_down'],
'DL_BUT_COMPL' => $bb_cfg['bt_show_dl_but_compl'],
'DL_BUT_CANCEL' => $bb_cfg['bt_show_dl_but_cancel'],
));
$dl_hidden_fields = '
<input type="hidden" name="sid" value="'. $userdata['session_id'] .'" />
<input type="hidden" name="'. POST_FORUM_URL .'" value="'. $forum_id .'" />
<input type="hidden" name="'. POST_TOPIC_URL .'" value="'. $topic_id .'" />
<input type="hidden" name="mode" value="set_dl_status" />
';
$template->assign_vars(array(
'DL_HIDDEN_FIELDS' => $dl_hidden_fields,
'S_DL_ACTION' => "dl_list.php?". POST_TOPIC_URL ."=$topic_id",
));
}
$template->assign_vars(array('SHOW_DL_LIST' => $show_dl_list));
unset($dl_info);

View file

@ -0,0 +1,2 @@
order allow,deny
deny from all

View file

@ -0,0 +1,47 @@
<?php
if (!defined('IN_FORUM')) die('Hacking attempt');
if (empty($_GET['u']) || empty($_GET['act_key']))
{
bb_die('Bad request');
}
$sql = "SELECT user_active, user_id, username, user_email, user_newpasswd, user_lang, user_actkey
FROM " . BB_USERS . "
WHERE user_id = " . intval($_GET[POST_USERS_URL]);
if (!($result = DB()->sql_query($sql)))
{
bb_die('Could not obtain user information');
}
if ($row = DB()->sql_fetchrow($result))
{
if ($row['user_active'] && trim($row['user_actkey']) == '')
{
bb_die($lang['ALREADY_ACTIVATED']);
}
else if ((trim($row['user_actkey']) == trim($_GET['act_key'])) && (trim($row['user_actkey']) != ''))
{
$sql_update_pass = ( $row['user_newpasswd'] != '' ) ? ", user_password = '" . md5(md5($row['user_newpasswd'])) . "', user_newpasswd = ''" : '';
$sql = "UPDATE " . BB_USERS . "
SET user_active = 1, user_actkey = ''" . $sql_update_pass . "
WHERE user_id = " . $row['user_id'];
if (!($result = DB()->sql_query($sql)))
{
bb_die('Could not update users table');
}
$message = ( $sql_update_pass == '' ) ? $lang['ACCOUNT_ACTIVE'] : $lang['PASSWORD_ACTIVATED'];
bb_die($message);
}
else
{
bb_die($lang['WRONG_ACTIVATION']);
}
}
else
{
bb_die($lang['NO_SUCH_USER']);
}

View file

@ -0,0 +1,80 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
$user_id = $userdata['user_id'];
$user_points = $userdata['user_points'];
if($bb_cfg['seed_bonus_enabled'] && $bb_cfg['bonus_upload'] && $bb_cfg['bonus_upload_price'])
{
$upload_row = unserialize($bb_cfg['bonus_upload']);
$price_row = unserialize($bb_cfg['bonus_upload_price']);
}
else bb_die($lang['EXCHANGE_NOT']);
if (isset($_POST['bonus_id']))
{
$id = (int) $_POST['bonus_id'];
$btu = get_bt_userdata($user_id);
if (empty($btu))
{
require(INC_DIR .'functions_torrent.php');
generate_passkey($user_id, true);
$btu = get_bt_userdata($user_id);
}
$upload = $upload_row[$id]*1024*1024*1024;
$points = $price_row[$id];
if ($userdata['user_points'] < $points)
{
meta_refresh('index.php', 5);
$message = $lang['BONUS_NOT_SUCCES'] .'<br /><br /><a href="'. BONUS_URL .'">'. $lang['BONUS_RETURN'] .'</a><br /><br /><a href="'. PROFILE_URL . $userdata['user_id'] .'">'. $lang['RETURN_PROFILE'] .'</a><br /><br />'. sprintf($lang['CLICK_RETURN_INDEX'], '<a href="index.php">', '</a>');
bb_die($message);
}
DB()->query("UPDATE ". BB_BT_USERS ." bu, ". BB_USERS ." u
SET
bu.u_up_total = u_up_total + $upload,
u.user_points = u.user_points - $points
WHERE
bu.user_id = $user_id
AND u.user_id = bu.user_id
");
cache_rm_user_sessions($user_id);
meta_refresh(BONUS_URL, 5);
$message = sprintf($lang['BONUS_SUCCES'], humn_size($upload_row[$id]*1024*1024*1024));
$message .= '<br /><br /><a href="'. BONUS_URL .'">'. $lang['BONUS_RETURN'] .'</a><br /><br /><a href="'. PROFILE_URL . $userdata['user_id'] .'">'. $lang['RETURN_PROFILE'] .'</a><br /><br />'. sprintf($lang['CLICK_RETURN_INDEX'], '<a href="index.php">', '</a>');
bb_die($message);
}
else
{
$template->assign_vars(array(
'U_USER_PROFILE' => PROFILE_URL . $user_id,
'S_MODE_ACTION' => 'profile.php?mode=bonus',
'PAGE_TITLE' => $lang['EXCHANGE_BONUS'],
'MY_BONUS' => sprintf($lang['MY_BONUS'], $user_points),
));
foreach($price_row as $i => $price)
{
if(!$price || !$upload_row[$i]) continue;
$class = ($user_points >= $price) ? 'seed' : 'leech';
$template->assign_block_vars('bonus_upload', array(
'ROW_CLASS' => !($i % 2) ? 'row2' : 'row1',
'ID' => $i,
'DESC' => sprintf($lang['BONUS_UPLOAD_DESC'], humn_size($upload_row[$i]*1024*1024*1024)),
'PRICE' => sprintf($lang['BONUS_UPLOAD_PRICE'], $class, sprintf('%.2f', $price)),
));
}
print_page('usercp_bonus.tpl');
}

View file

@ -0,0 +1,91 @@
<?php
if (!defined('IN_FORUM')) die("Hacking attempt");
// Is send through board enabled? No, return to index
if (!$bb_cfg['board_email_form'])
{
redirect("index.php");
}
set_die_append_msg();
if ( !empty($_GET[POST_USERS_URL]) || !empty($_POST[POST_USERS_URL]) )
{
$user_id = ( !empty($_GET[POST_USERS_URL]) ) ? intval($_GET[POST_USERS_URL]) : intval($_POST[POST_USERS_URL]);
}
else
{
bb_die($lang['NO_USER_SPECIFIED']);
}
if ( !$userdata['session_logged_in'] )
{
redirect(LOGIN_URL . "?redirect=profile.php&mode=email&" . POST_USERS_URL . "=$user_id");
}
$errors = array();
$sql = "SELECT username, user_id, user_rank, user_email, user_lang
FROM " . BB_USERS . "
WHERE user_id = $user_id
";
if ($row = DB()->fetch_row($sql))
{
$username = $row['username'];
$user_email = $row['user_email'];
$user_lang = $row['user_lang'];
if ( true || IS_ADMIN ) // TRUE instead of missing user_opt "prevent_email"
{
if (isset($_POST['submit']))
{
$subject = trim(html_entity_decode($_POST['subject']));
$message = trim(html_entity_decode($_POST['message']));
if (!$subject) $errors[] = $lang['EMPTY_SUBJECT_EMAIL'];
if (!$message) $errors[] = $lang['EMPTY_MESSAGE_EMAIL'];
if (!$errors)
{
require(CLASS_DIR .'emailer.php');
$emailer = new emailer($bb_cfg['smtp_delivery']);
$emailer->from($userdata['username'] ." <{$userdata['user_email']}>");
$emailer->email_address($username ." <$user_email>");
$emailer->use_template('profile_send_email', $user_lang);
$emailer->set_subject($subject);
$emailer->assign_vars(array(
'SITENAME' => $bb_cfg['sitename'],
'FROM_USERNAME' => $userdata['username'],
'TO_USERNAME' => $username,
'MESSAGE' => $message,
));
$emailer->send();
$emailer->reset();
bb_die($lang['EMAIL_SENT']);
}
}
$template->assign_vars(array(
'USERNAME' => profile_url($row),
'S_HIDDEN_FIELDS' => '',
'S_POST_ACTION' => "profile.php?mode=email&amp;" . POST_USERS_URL . "=$user_id",
'ERROR_MESSAGE' => ($errors) ? join('<br />', array_unique($errors)) : '',
));
print_page('usercp_email.tpl');
}
else
{
bb_die($lang['USER_PREVENT_EMAIL']);
}
}
else
{
bb_die($lang['USER_NOT_EXIST']);
}

View file

@ -0,0 +1,779 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
array_deep($_POST, 'trim');
set_die_append_msg();
if (IS_ADMIN)
{
$bb_cfg['reg_email_activation'] = false;
$new_user = (int) request_var('admin', '');
if ($new_user) $gen_simple_header = true;
$template->assign_vars(array(
'NEW_USER' => $new_user,
));
}
$can_register = (IS_GUEST || IS_ADMIN);
$submit = !empty($_POST['submit']);
$errors = array();
$adm_edit = false; // редактирование админом чужого профиля
require(INC_DIR .'bbcode.php');
require(INC_DIR .'functions_validate.php');
require(INC_DIR .'functions_selects.php');
$pr_data = array(); // данные редактируемого либо регистрационного профиля
$db_data = array(); // данные для базы: регистрационные либо измененные данные юзера
$tp_data = array(); // данные для tpl
// Данные профиля
switch ($mode)
{
/**
* Регистрация
*/
case 'register':
if (!$can_register) redirect('index.php');
if (!IS_ADMIN)
{
// Ограничение по ip
if($bb_cfg['unique_ip'])
{
if($users = DB()->fetch_row("SELECT user_id, username FROM ". BB_USERS ." WHERE user_reg_ip = '". USER_IP ."' LIMIT 1"))
{
bb_die(sprintf($lang['ALREADY_REG_IP'], '<a href="'. PROFILE_URL . $users['user_id'] .'"><b>'. $users['username'] .'</b></a>', $bb_cfg['tech_admin_email']));
}
}
// Отключение регистрации
if ($bb_cfg['new_user_reg_disabled'] || ($bb_cfg['reg_email_activation'] && $bb_cfg['emailer_disabled']))
{
bb_die($lang['NEW_USER_REG_DISABLED']);
}
// Ограничение по времени
else if ($bb_cfg['new_user_reg_restricted'])
{
if (in_array(date('G'), array(0,/*1,2,3,4,5,6,7,8,11,12,13,14,15,16,*/17,18,19,20,21,22,23)))
{
bb_die($lang['REGISTERED_IN_TIME']);
}
}
}
// field => can_edit
$profile_fields = array(
'username' => true,
'user_password' => true,
'user_email' => true,
'user_timezone' => true,
'user_lang' => true,
'user_opt' => true,
);
$pr_data = array(
'user_id' => GUEST_UID,
'username' => '',
'user_password' => '',
'user_email' => '',
'user_timezone' => $bb_cfg['board_timezone'],
'user_lang' => $bb_cfg['default_lang'],
'user_opt' => 0,
'avatar_ext_id' => 0,
);
break;
/**
* Редактирование профиля
*/
case 'editprofile':
if (IS_GUEST) login_redirect();
// field => can_edit
$profile_fields = array(
'user_active' => IS_ADMIN,
'username' => (IS_ADMIN || $bb_cfg['allow_namechange']),
'user_password' => true,
'user_email' => true, // должен быть после user_password
'user_lang' => true,
'user_gender' => true,
'user_birthday' => true,
'user_timezone' => true,
'user_opt' => true,
'avatar_ext_id' => true,
'user_icq' => true,
'user_skype' => true,
'user_twitter' => true,
'user_website' => true,
'user_from' => true,
'user_sig' => true,
'user_occ' => true,
'user_interests' => true,
'tpl_name' => true,
);
// Выбор профиля: для юзера свой, для админа любой
if (IS_ADMIN && !empty($_REQUEST['u']))
{
$pr_user_id = (int) $_REQUEST['u'];
$adm_edit = ($pr_user_id != $userdata['user_id']);
}
else
{
$pr_user_id = $userdata['user_id'];
}
$profile_fields_sql = join(', ', array_keys($profile_fields));
$sql = "
SELECT
user_id,
user_rank,
user_level,
$profile_fields_sql
FROM ". BB_USERS ."
WHERE user_id = $pr_user_id
LIMIT 1
";
if (!$pr_data = DB()->fetch_row($sql))
{
bb_die($lang['PROFILE_NOT_FOUND']);
}
break;
default:
trigger_error("invalid mode: $mode", E_USER_ERROR);
}
// CAPTCHA
$need_captcha = ($mode == 'register' && !IS_ADMIN);
if ($submit)
{
if ($need_captcha && !CAPTCHA()->verify_code())
{
$errors[] = $lang['CONFIRM_CODE_WRONG'];
}
}
// Валидация данных
$cur_pass_valid = $adm_edit;
foreach ($profile_fields as $field => $can_edit)
{
switch ($field)
{
/**
* Активация (edit, reg)
*/
case 'user_active':
$active = isset($_POST['user_active']) ? (int) $_POST['user_active'] : $pr_data['user_active'];
if ($submit && $adm_edit)
{
$pr_data['user_active'] = $active;
$db_data['user_active'] = $active;
}
break;
/**
* Имя (edit, reg)
*/
case 'username':
$username = !empty($_POST['username']) ? clean_username($_POST['username']) : $pr_data['username'];
if ($submit)
{
$err = validate_username($username);
if (!$errors AND $err && $mode == 'register')
{
$errors[] = $err;
}
if ($can_edit && $username != $pr_data['username'] || $mode == 'register')
{
$pr_data['username'] = $username;
$db_data['username'] = $username;
}
}
$tp_data['CAN_EDIT_USERNAME'] = $can_edit;
$tp_data['USERNAME'] = $pr_data['username'];
break;
/**
* Пароль (edit, reg)
*/
case 'user_password':
if ($submit)
{
$cur_pass = (string) @$_POST['cur_pass'];
$new_pass = (string) @$_POST['new_pass'];
$cfm_pass = (string) @$_POST['cfm_pass'];
// пароль для гостя и при смене пароля юзером
if (!empty($new_pass))
{
if (mb_strlen($new_pass, 'UTF-8') > 20)
{
$errors[] = sprintf($lang['CHOOSE_PASS_ERR_MAX'], 20);
}
elseif (mb_strlen($new_pass, 'UTF-8') < 4)
{
$errors[] = sprintf($lang['CHOOSE_PASS_ERR_MIN'], 4);
}
elseif ($new_pass != $cfm_pass)
{
$errors[] = $lang['CHOOSE_PASS_ERR'];
}
$db_data['user_password'] = md5(md5($new_pass));
}
if ($mode == 'register')
{
if (empty($new_pass))
{
$errors[] = $lang['CHOOSE_PASS'];
}
}
else
{
if (!empty($cur_pass))
{
$cur_pass_valid = ($pr_data['user_password'] === md5(md5($cur_pass)));
}
if (!empty($new_pass) && !$cur_pass_valid)
{
$errors[] = $lang['CHOOSE_PASS_FAILED'];
}
}
}
break;
/**
* E-mail (edit, reg)
*/
case 'user_email':
$email = !empty($_POST['user_email']) ? (string) $_POST['user_email'] : $pr_data['user_email'];
if ($submit)
{
if ($mode == 'register')
{
if (empty($email))
{
$errors[] = $lang['CHOOSE_E_MAIL'];
}
if (!$errors AND $err = validate_email($email))
{
$errors[] = $err;
}
$db_data['user_email'] = $email;
}
else if ($email != $pr_data['user_email']) // если смена мейла юзером
{
if (!$cur_pass_valid)
{
$errors[] = $lang['CONFIRM_PASSWORD_EXPLAIN'];
}
if (!$errors AND $err = validate_email($email))
{
$errors[] = $err;
}
if ($bb_cfg['reg_email_activation'])
{
$pr_data['user_active'] = 0;
$db_data['user_active'] = 0;
}
$db_data['user_email'] = $email;
}
}
$tp_data['USER_EMAIL'] = htmlCHR($email);
break;
/**
* Язык (edit, reg)
*/
case 'user_lang':
$user_lang = isset($_POST['user_lang']) ? (string) $_POST['user_lang'] : $pr_data['user_lang'];
if ($submit && ($user_lang != $pr_data['user_lang'] || $mode == 'register'))
{
$pr_data['user_lang'] = $user_lang;
$db_data['user_lang'] = $user_lang;
}
break;
/**
* Часовой пояс (edit, reg)
*/
case 'user_timezone':
$user_timezone = isset($_POST['user_timezone']) ? (int) $_POST['user_timezone'] : $pr_data['user_timezone'];
if ($submit && ($user_timezone != $pr_data['user_timezone'] || $mode == 'register'))
{
if (isset($lang['TZ'][$user_timezone]))
{
$pr_data['user_timezone'] = $user_timezone;
$db_data['user_timezone'] = $user_timezone;
}
}
break;
/**
* Пол (edit, reg)
*/
case 'user_gender':
$user_gender = isset($_POST['user_gender']) ? (int) $_POST['user_gender'] : $pr_data['user_gender'];
if ($submit && $user_gender != $pr_data['user_gender'])
{
$pr_data['user_gender'] = $user_gender;
$db_data['user_gender'] = $user_gender;
}
$tp_data['USER_GENDER'] = build_select('user_gender', array_flip($lang['GENDER_SELECT']), $pr_data['user_gender']);
break;
/**
* Возраст (edit)
*/
case 'user_birthday':
$user_birthday = isset($_POST['user_birthday']) ? (string) $_POST['user_birthday'] : $pr_data['user_birthday'];
if ($submit && $user_birthday != $pr_data['user_birthday'])
{
$birthday_date = date_parse($user_birthday);
if (!empty($birthday_date['year']))
{
if (strtotime($user_birthday) >= TIMENOW)
{
$errors[] = $lang['WRONG_BIRTHDAY_FORMAT'];
}
elseif (bb_date(TIMENOW, 'Y', false) - $birthday_date['year'] > $bb_cfg['birthday_max_age'])
{
$errors[] = sprintf($lang['BIRTHDAY_TO_HIGH'], $bb_cfg['birthday_max_age']);
}
elseif (bb_date(TIMENOW, 'Y', false) - $birthday_date['year'] < $bb_cfg['birthday_min_age'])
{
$errors[] = sprintf($lang['BIRTHDAY_TO_LOW'], $bb_cfg['birthday_min_age']);
}
}
$pr_data['user_birthday'] = $user_birthday;
$db_data['user_birthday'] = $user_birthday;
}
$tp_data['USER_BIRTHDAY'] = $pr_data['user_birthday'];
break;
/**
* opt (edit)
*/
case 'user_opt':
$user_opt = $pr_data['user_opt'];
$reg_mode = ($mode == 'register');
$update_user_opt = array(
# 'user_opt_name' => ($reg_mode) ? #reg_value : #in_login_change
'user_viewemail' => ($reg_mode) ? false : true,
'user_viewonline' => ($reg_mode) ? false : true,
'user_notify' => ($reg_mode) ? true : true,
'user_notify_pm' => ($reg_mode) ? true : true,
'user_porn_forums' => ($reg_mode) ? false : true,
'user_dls' => ($reg_mode) ? false : true,
'user_callseed' => ($reg_mode) ? true : true,
'user_retracker' => ($reg_mode) ? true : true,
);
foreach ($update_user_opt as $opt => $can_change_opt)
{
if ($submit && (isset($_POST[$opt]) && $can_change_opt || $reg_mode))
{
$change_opt = ($reg_mode) ? $can_change_opt : !empty($_POST[$opt]);
setbit($user_opt, $bf['user_opt'][$opt], $change_opt);
}
$tp_data[strtoupper($opt)] = bf($user_opt, 'user_opt', $opt);
}
if ($submit && ($user_opt != $pr_data['user_opt'] || $reg_mode))
{
$pr_data['user_opt'] = $user_opt;
$db_data['user_opt'] = (int) $user_opt;
}
break;
/**
* Avatar (edit)
*/
case 'avatar_ext_id':
if ($submit && !bf($pr_data['user_opt'], 'user_opt', 'dis_avatar'))
{
if (isset($_POST['delete_avatar']))
{
delete_avatar($pr_data['user_id'], $pr_data['avatar_ext_id']);
$pr_data['avatar_ext_id'] = 0;
$db_data['avatar_ext_id'] = 0;
}
else if (!empty($_FILES['avatar']['name']) && $bb_cfg['avatars']['up_allowed'])
{
require(INC_DIR .'functions_upload.php');
$upload = new upload_common();
if ($upload->init($bb_cfg['avatars'], $_FILES['avatar']) AND $upload->store('avatar', $pr_data))
{
$pr_data['avatar_ext_id'] = $upload->file_ext_id;
$db_data['avatar_ext_id'] = (int) $upload->file_ext_id;
}
else
{
$errors = array_merge($errors, $upload->errors);
}
}
}
$tp_data['AVATARS_MAX_SIZE'] = humn_size($bb_cfg['avatars']['max_size']);
break;
/**
* ICQ (edit)
*/
case 'user_icq':
$icq = isset($_POST['user_icq']) ? (string) $_POST['user_icq'] : $pr_data['user_icq'];
if ($submit && $icq != $pr_data['user_icq'])
{
if ($icq == '' || preg_match('#^\d{6,15}$#', $icq))
{
$pr_data['user_icq'] = $icq;
$db_data['user_icq'] = (string) $icq;
}
else
{
$pr_data['user_icq'] = '';
$errors[] = htmlCHR($lang['ICQ_ERROR']);
}
}
$tp_data['USER_ICQ'] = $pr_data['user_icq'];
break;
/**
* Сайт (edit)
*/
case 'user_website':
$website = isset($_POST['user_website']) ? (string) $_POST['user_website'] : $pr_data['user_website'];
$website = htmlCHR($website);
if ($submit && $website != $pr_data['user_website'])
{
if ($website == '' || preg_match('#^https?://[\w\#!$%&~/.\-;:=,?@а-яА-Я\[\]+]+$#iu', $website))
{
$pr_data['user_website'] = $website;
$db_data['user_website'] = (string) $website;
}
else
{
$pr_data['user_website'] = '';
$errors[] = htmlCHR($lang['WEBSITE_ERROR']);
}
}
$tp_data['USER_WEBSITE'] = $pr_data['user_website'];
break;
/**
* Откуда (edit)
*/
case 'user_from':
$from = isset($_POST['user_from']) ? (string) $_POST['user_from'] : $pr_data['user_from'];
$from = htmlCHR($from);
if ($submit && $from != $pr_data['user_from'])
{
$pr_data['user_from'] = $from;
$db_data['user_from'] = (string) $from;
}
$tp_data['USER_FROM'] = $pr_data['user_from'];
break;
/**
* Подпись (edit)
*/
case 'user_sig':
$sig = isset($_POST['user_sig']) ? (string) $_POST['user_sig'] : $pr_data['user_sig'];
if ($submit && $sig != $pr_data['user_sig'])
{
$sig = prepare_message($sig);
if (mb_strlen($sig, 'UTF-8') > $bb_cfg['max_sig_chars'])
{
$errors[] = $lang['SIGNATURE_TOO_LONG'];
}
else if (preg_match('#<(a|b|i|u|table|tr|td|img) #i', $sig) || preg_match('#(href|src|target|title)=#i', $sig))
{
$errors[] = $lang['SIGNATURE_ERROR_HTML'];
}
$pr_data['user_sig'] = $sig;
$db_data['user_sig'] = (string) $sig;
}
$tp_data['USER_SIG'] = $pr_data['user_sig'];
break;
/**
* Род занятий (edit)
*/
case 'user_occ':
$occ = isset($_POST['user_occ']) ? (string) $_POST['user_occ'] : $pr_data['user_occ'];
$occ = htmlCHR($occ);
if ($submit && $occ != $pr_data['user_occ'])
{
$pr_data['user_occ'] = $occ;
$db_data['user_occ'] = (string) $occ;
}
$tp_data['USER_OCC'] = $pr_data['user_occ'];
break;
/**
* Интересы
*/
case 'user_interests':
$interests = isset($_POST['user_interests']) ? (string) $_POST['user_interests'] : $pr_data['user_interests'];
$interests = htmlCHR($interests);
if ($submit && $interests != $pr_data['user_interests'])
{
$pr_data['user_interests'] = $interests;
$db_data['user_interests'] = (string) $interests;
}
$tp_data['USER_INTERESTS'] = $pr_data['user_interests'];
break;
/**
* Skype
*/
case 'user_skype':
$skype = isset($_POST['user_skype']) ? (string) $_POST['user_skype'] : $pr_data['user_skype'];
if ($submit && $skype != $pr_data['user_skype'])
{
if ($skype != '' && !preg_match("#^[a-zA-Z0-9_.\-@,]{6,32}$#", $skype))
{
$errors[] = $lang['SKYPE_ERROR'];
}
$pr_data['user_skype'] = $skype;
$db_data['user_skype'] = (string) $skype;
}
$tp_data['USER_SKYPE'] = $pr_data['user_skype'];
break;
/**
* Twitter
*/
case 'user_twitter':
$twitter = isset($_POST['user_twitter']) ? (string) $_POST['user_twitter'] : $pr_data['user_twitter'];
if ($submit && $twitter != $pr_data['user_twitter'])
{
if ($twitter != '' && !preg_match("#^[a-zA-Z0-9_]{1,15}$#", $twitter))
{
$errors[] = $lang['TWITTER_ERROR'];
}
$pr_data['user_twitter'] = $twitter;
$db_data['user_twitter'] = (string) $twitter;
}
$tp_data['USER_TWITTER'] = $pr_data['user_twitter'];
break;
/**
* Выбор шаблона (edit)
*/
case 'tpl_name':
$templates = isset($_POST['tpl_name']) ? (string) $_POST['tpl_name'] : $pr_data['tpl_name'];
$templates = htmlCHR($templates);
if ($submit && $templates != $pr_data['tpl_name'])
{
$pr_data['tpl_name'] = $bb_cfg['tpl_name'];
$db_data['tpl_name'] = (string) $bb_cfg['tpl_name'];
foreach ($bb_cfg['templates'] as $folder => $name)
{
if ($templates == $folder)
{
$pr_data['tpl_name'] = $templates;
$db_data['tpl_name'] = (string) $templates;
}
}
}
$tp_data['TEMPLATES_SELECT'] = templates_select($pr_data['tpl_name'], 'tpl_name');
break;
/**
* default
*/
default:
trigger_error("invalid profile field: $field", E_USER_ERROR);
}
}
// submit
if ($submit && !$errors)
{
/**
* Создание нового профиля
*/
if ($mode == 'register')
{
if ($bb_cfg['reg_email_activation'])
{
$user_actkey = make_rand_str(12);
$db_data['user_active'] = 0;
$db_data['user_actkey'] = $user_actkey;
}
else
{
$db_data['user_active'] = 1;
$db_data['user_actkey'] = '';
}
$db_data['user_regdate'] = TIMENOW;
if (!IS_ADMIN) $db_data['user_reg_ip'] = USER_IP;
if (!isset($db_data['tpl_name'])) $db_data['tpl_name'] = (string) $bb_cfg['tpl_name'];
$sql_args = DB()->build_array('INSERT', $db_data);
DB()->query("INSERT INTO ". BB_USERS . $sql_args);
$new_user_id = DB()->sql_nextid();
if (IS_ADMIN)
{
set_pr_die_append_msg($new_user_id);
$message = $lang['ACCOUNT_ADDED'];
}
else
{
if ($bb_cfg['reg_email_activation'])
{
$message = $lang['ACCOUNT_INACTIVE'];
$email_template = 'user_welcome_inactive';
}
else
{
$message = $lang['ACCOUNT_ADDED'];
$email_template = 'user_welcome';
}
require(CLASS_DIR .'emailer.php');
$emailer = new emailer($bb_cfg['smtp_delivery']);
$emailer->from($bb_cfg['sitename'] ." <{$bb_cfg['board_email']}>");
$emailer->email_address("$username <$email>");
$emailer->use_template($email_template, $user_lang);
$emailer->assign_vars(array(
'SITENAME' => $bb_cfg['sitename'],
'WELCOME_MSG' => sprintf($lang['WELCOME_SUBJECT'], $bb_cfg['sitename']),
'USERNAME' => html_entity_decode($username),
'PASSWORD' => $new_pass,
'U_ACTIVATE' => make_url('profile.php?mode=activate&' . POST_USERS_URL . '=' . $new_user_id . '&act_key=' . $db_data['user_actkey'])
));
$emailer->send();
$emailer->reset();
}
bb_die($message);
}
/**
* Редактирование
*/
else
{
set_pr_die_append_msg($pr_data['user_id']);
// если что-то было изменено
if ($db_data)
{
if (!$pr_data['user_active'])
{
$user_actkey = make_rand_str(12);
$pr_data['user_actkey'] = $user_actkey;
$db_data['user_actkey'] = $user_actkey;
require(CLASS_DIR .'emailer.php');
$emailer = new emailer($bb_cfg['smtp_delivery']);
$emailer->from($bb_cfg['sitename'] ." <{$bb_cfg['board_email']}>");
$emailer->use_template('user_activate', $pr_data['user_lang']);
$emailer->email_address("$username <$email>");
$emailer->assign_vars(array(
'SITENAME' => $bb_cfg['sitename'],
'USERNAME' => html_entity_decode($username),
'U_ACTIVATE' => make_url("profile.php?mode=activate&u={$pr_data['user_id']}&act_key=$user_actkey"),
));
$emailer->send();
$emailer->reset();
$message = $lang['PROFILE_UPDATED_INACTIVE'];
$user->session_end();
}
else
{
meta_refresh('index.php' , 10);
$message = $lang['PROFILE_UPDATED'];
}
$sql_args = DB()->build_array('UPDATE', $db_data);
DB()->query("UPDATE ". BB_USERS ." SET $sql_args WHERE user_id = {$pr_data['user_id']} LIMIT 1");
if ($pr_data['user_id'] != $userdata['user_id'])
{
if ($pr_data['user_level'] == MOD && !empty($db_data['username']))
{
$datastore->update('moderators');
}
}
cache_rm_user_sessions ($pr_data['user_id']);
if($adm_edit)
{
bb_die($lang['PROFILE_USER'] . ' <b>'. profile_url($pr_data) .'</b> '. $lang['GOOD_UPDATE']);
}
elseif(!$pr_data['user_active'])
{
bb_die($lang['PROFILE_UPDATED_INACTIVE']);
}
else
{
meta_refresh('index.php' , 10);
bb_die($lang['PROFILE_UPDATED']);
}
}
else
{
bb_die($lang['NOTHING_HAS_CHANGED']);
}
}
}
$template->assign_vars($tp_data);
$template->assign_vars(array(
'PAGE_TITLE' => ($mode == 'editprofile') ? $lang['EDIT_PROFILE'] . ($adm_edit ? " :: {$pr_data['username']}" : '') : $lang['REGISTER'],
'SHOW_REG_AGREEMENT' => ($mode == 'register' && !IS_ADMIN),
'ERROR_MESSAGE' => ($errors) ? join('<br />', array_unique($errors)) : '',
'MODE' => $mode,
'EDIT_PROFILE' => ($mode == 'editprofile'),
'ADM_EDIT' => $adm_edit,
'SHOW_PASS' => ($adm_edit || ($mode == 'register' && IS_ADMIN)),
'CAPTCHA_HTML' => ($need_captcha) ? CAPTCHA()->get_html() : '',
'LANGUAGE_SELECT' => language_select($pr_data['user_lang'], 'user_lang'),
'TIMEZONE_SELECT' => tz_select($pr_data['user_timezone'], 'user_timezone'),
'USER_TIMEZONE' => $pr_data['user_timezone'],
'AVATAR_EXPLAIN' => sprintf($lang['AVATAR_EXPLAIN'], $bb_cfg['avatars']['max_width'], $bb_cfg['avatars']['max_height'], (round($bb_cfg['avatars']['max_size'] / 1024))),
'AVATAR_DISALLOWED' => bf($pr_data['user_opt'], 'user_opt', 'dis_avatar'),
'AVATAR_DIS_EXPLAIN' => sprintf($lang['AVATAR_DISABLE'], $bb_cfg['terms_and_conditions_url']),
'SIGNATURE_EXPLAIN' => sprintf($lang['SIGNATURE_EXPLAIN'], $bb_cfg['max_sig_chars']),
'SIG_DISALLOWED' => bf($pr_data['user_opt'], 'user_opt', 'dis_sig'),
'PR_USER_ID' => $pr_data['user_id'],
'U_RESET_AUTOLOGIN' => LOGIN_URL . "?logout=1&amp;reset_autologin=1&amp;sid={$userdata['session_id']}",
'AVATAR_URL_PATH' => ($pr_data['avatar_ext_id']) ? get_avatar_path($pr_data['user_id'], $pr_data['avatar_ext_id']) : '',
));
print_page('usercp_register.tpl');

View file

@ -0,0 +1,87 @@
<?php
if (!defined('IN_FORUM')) die("Hacking attempt");
set_die_append_msg();
if ($bb_cfg['emailer_disabled']) bb_die($lang['EMAILER_DISABLED']);
$need_captcha = ($_GET['mode'] == 'sendpassword' && !IS_ADMIN);
if ( isset($_POST['submit']) )
{
if ($need_captcha && !CAPTCHA()->verify_code()) bb_die($lang['CONFIRM_CODE_WRONG']);
$email = ( !empty($_POST['email']) ) ? trim(strip_tags(htmlspecialchars($_POST['email']))) : '';
$sql = "SELECT *
FROM " . BB_USERS . "
WHERE user_email = '" . DB()->escape($email)."'";
if ( $result = DB()->sql_query($sql) )
{
if ( $row = DB()->sql_fetchrow($result) )
{
if (!$row['user_active'])
{
bb_die($lang['NO_SEND_ACCOUNT_INACTIVE']);
}
if (in_array($row['user_level'], array(MOD, ADMIN)))
{
bb_die($lang['NO_SEND_ACCOUNT']);
}
$username = $row['username'];
$user_id = $row['user_id'];
$user_actkey = make_rand_str(12);
$user_password = make_rand_str(8);
$sql = "UPDATE " . BB_USERS . "
SET user_newpasswd = '$user_password', user_actkey = '$user_actkey'
WHERE user_id = " . $row['user_id'];
if (!DB()->sql_query($sql))
{
bb_die('Could not update new password information');
}
require(CLASS_DIR .'emailer.php');
$emailer = new emailer($bb_cfg['smtp_delivery']);
$emailer->from($bb_cfg['sitename'] ." <{$bb_cfg['board_email']}>");
$emailer->email_address("$username <{$row['user_email']}>");
$emailer->use_template('user_activate_passwd', $row['user_lang']);
$emailer->assign_vars(array(
'SITENAME' => $bb_cfg['sitename'],
'USERNAME' => $username,
'PASSWORD' => $user_password,
'U_ACTIVATE' => make_url('profile.php?mode=activate&' . POST_USERS_URL . '=' . $user_id . '&act_key=' . $user_actkey)
));
$emailer->send();
$emailer->reset();
bb_die($lang['PASSWORD_UPDATED']);
}
else
{
bb_die($lang['NO_EMAIL_MATCH']);
}
}
else
{
bb_die('Could not obtain user information for sendpassword');
}
}
else
{
$email = $username = '';
}
$template->assign_vars(array(
'USERNAME' => $username,
'EMAIL' => $email,
'CAPTCHA_HTML' => ($need_captcha) ? CAPTCHA()->get_html() : '',
'S_HIDDEN_FIELDS' => '',
'S_PROFILE_ACTION' => "profile.php?mode=sendpassword",
));
print_page('usercp_sendpasswd.tpl');

View file

@ -0,0 +1,100 @@
<?php
if (empty($bb_cfg['topic_notify_enabled']))
{
bb_die($lang['DISABLED']);
}
$page_cfg['use_tablesorter'] = true;
$page_cfg['include_bbcode_js'] = true;
$tracking_topics = get_tracks('topic');
$user_id = $userdata['user_id'];
$start = isset($_GET['start']) ? abs(intval($_GET['start'])) : 0;
$per_page = $bb_cfg['topics_per_page'];
if (isset($_POST['topic_id_list']))
{
$topic_ids = implode(",", $_POST['topic_id_list']);
$sql = "DELETE FROM ". BB_TOPICS_WATCH ." WHERE topic_id IN(". $topic_ids .") AND user_id = $user_id";
if (!($result = DB() ->sql_query($sql)))
{
bb_die('Could not delete topic watch information #1');
}
}
$template->assign_vars(array(
'PAGE_TITLE' => $lang['WATCHED_TOPICS'],
'S_FORM_ACTION' => BB_ROOT .'profile.php?mode=watch',
));
$sql = "SELECT COUNT(topic_id) as watch_count FROM ". BB_TOPICS_WATCH ." WHERE user_id = $user_id";
if ( !($result = DB() ->sql_query($sql)) )
{
bb_die('Could not obtain watch topic information #2');
}
$row = DB() ->sql_fetchrow($result);
$watch_count = ( $row['watch_count'] ) ? $row['watch_count'] : 0;
DB() ->sql_freeresult($result);
if ($watch_count > 0)
{
$sql = "SELECT w.*, t.*, f.*, u.*, u2.username as last_username, u2.user_id as last_user_id,
u2.user_level as last_user_level, u2.user_rank as last_user_rank
FROM ". BB_TOPICS_WATCH ." w, ". BB_TOPICS ." t, ". BB_USERS ." u, ". BB_FORUMS ." f, ". BB_POSTS ." p, " . BB_USERS . " u2
WHERE w.topic_id = t.topic_id
AND t.forum_id = f.forum_id
AND p.post_id = t.topic_last_post_id
AND p.poster_id = u2.user_id
AND t.topic_poster = u.user_id
AND w.user_id = $user_id
GROUP BY t.topic_last_post_time DESC
LIMIT $start, $per_page";
if (!($result = DB() ->sql_query($sql)))
{
bb_die('Could not obtain watch topic information #3');
}
$watch = DB() ->sql_fetchrowset($result);
if ($watch)
{
for ( $i = 0; $i < count($watch); $i++ )
{
$is_unread = is_unread($watch[$i]['topic_last_post_time'], $watch[$i]['topic_id'], $watch[$i]['forum_id']);
$template->assign_block_vars('watch', array(
'ROW_CLASS' => ( !($i % 2) ) ? 'row1' : 'row2',
'POST_ID' => $watch[$i]['topic_first_post_id'],
'TOPIC_ID' => $watch[$i]['topic_id'],
'TOPIC_TITLE' => wbr(str_short($watch[$i]['topic_title'], 70)),
'FULL_TOPIC_TITLE' => wbr($watch[$i]['topic_title']),
'U_TOPIC' => TOPIC_URL . $watch[$i]['topic_id'],
'FORUM_TITLE' => wbr($watch[$i]['forum_name']),
'U_FORUM' => FORUM_URL . $watch[$i]['forum_id'],
'REPLIES' => $watch[$i]['topic_replies'],
'AUTHOR' => profile_url($watch[$i]),
'LAST_POST' => bb_date($watch[$i]['topic_last_post_time']) .'<br />'. profile_url(array('user_id' => $watch[$i]['last_user_id'], 'username' => $watch[$i]['last_username'], 'user_rank' => $watch[$i]['last_user_rank'])),
'LAST_POST_ID' => $watch[$i]['topic_last_post_id'],
'IS_UNREAD' => $is_unread,
'TOPIC_ICON' => get_topic_icon($watch[$i], $is_unread),
'PAGINATION' => ($watch[$i]['topic_status'] == TOPIC_MOVED) ? '' : build_topic_pagination(TOPIC_URL . $watch[$i]['topic_id'], $watch[$i]['topic_replies'], $bb_cfg['posts_per_page']),
));
}
$template->assign_vars(array(
'MATCHES' => (count($watch) == 1) ? sprintf($lang['FOUND_SEARCH_MATCH'], count($watch)) : sprintf($lang['FOUND_SEARCH_MATCHES'], count($watch)),
'PAGINATION' => generate_pagination(BB_ROOT .'profile.php?mode=watch', $watch_count, $per_page, $start),
'PAGE_NUMBER' => sprintf($lang['PAGE_OF'], ( floor( $start / $per_page ) + 1 ), ceil( $watch_count / $per_page )),
'U_PER_PAGE' => BB_ROOT .'profile.php?mode=watch',
'PER_PAGE' => $per_page,
));
}
DB() ->sql_freeresult($result);
}
else
{
meta_refresh(BB_ROOT, '3');
bb_die($lang['NO_WATCHED_TOPICS']);
}
print_page('usercp_topic_watch.tpl');

View file

@ -0,0 +1,223 @@
<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
require(INC_DIR .'bbcode.php');
$datastore->enqueue(array(
'ranks',
));
if (empty($_GET[POST_USERS_URL]) || $_GET[POST_USERS_URL] == GUEST_UID)
{
bb_die($lang['NO_USER_ID_SPECIFIED']);
}
if (!$profiledata = get_userdata($_GET[POST_USERS_URL]))
{
bb_die($lang['NO_USER_ID_SPECIFIED']);
}
if (!$userdata['session_logged_in'])
{
redirect(LOGIN_URL . "?redirect={$_SERVER['REQUEST_URI']}");
}
if (!$ranks = $datastore->get('ranks'))
{
$datastore->update('ranks');
$ranks = $datastore->get('ranks');
}
$poster_rank = $rank_image= $rank_style = $rank_select = '';
if ($user_rank = $profiledata['user_rank'] AND isset($ranks[$user_rank]))
{
$rank_image = ($ranks[$user_rank]['rank_image']) ? '<img src="'. $ranks[$user_rank]['rank_image'] .'" alt="" title="" border="0" />' : '';
$poster_rank = $ranks[$user_rank]['rank_title'];
$rank_style = $ranks[$user_rank]['rank_style'];
}
if (IS_ADMIN)
{
$rank_select = array($lang['NONE'] => 0);
foreach ($ranks as $row)
{
$rank_select[$row['rank_title']] = $row['rank_id'];
}
$rank_select = build_select('rank-sel', $rank_select, $user_rank);
}
if (bf($profiledata['user_opt'], 'user_opt', 'user_viewemail') || $profiledata['user_id'] == $userdata['user_id'] || IS_AM)
{
$email_uri = ($bb_cfg['board_email_form']) ? 'profile.php?mode=email&amp;'. POST_USERS_URL .'='. $profiledata['user_id'] : 'mailto:'. $profiledata['user_email'];
$email = '<a class="editable" href="'. $email_uri .'">'. $profiledata['user_email'] .'</a>';
}
else
{
$email = '';
}
//
// Generate page
//
$profile_user_id = ($profiledata['user_id'] == $userdata['user_id']);
$signature = ($bb_cfg['allow_sig'] && $profiledata['user_sig']) ? $profiledata['user_sig'] : '';
if(bf($profiledata['user_opt'], 'user_opt', 'dis_sig'))
{
if($profile_user_id)
{
$signature = $lang['SIGNATURE_DISABLE'];
}
else
{
$signature = '';
}
}
else if ($signature)
{
$signature = bbcode2html($signature);
}
$template->assign_vars(array(
'PAGE_TITLE' => sprintf($lang['VIEWING_USER_PROFILE'], $profiledata['username']),
'USERNAME' => $profiledata['username'],
'PROFILE_USER_ID' => $profiledata['user_id'],
'PROFILE_USER' => $profile_user_id,
'USER_REGDATE' => bb_date($profiledata['user_regdate'], 'Y-m-d H:i', false),
'POSTER_RANK' => ($poster_rank) ? "<span class=\"$rank_style\">". $poster_rank ."</span>" : $lang['USER'],
'RANK_IMAGE' => $rank_image,
'RANK_SELECT' => $rank_select,
'POSTS' => $profiledata['user_posts'],
'PM' => '<a href="' . PM_URL . '?mode=post&amp;'. POST_USERS_URL .'='. $profiledata['user_id'] .'">'. $lang['SEND_PRIVATE_MESSAGE'] .'</a>',
'EMAIL' => $email,
'WWW' => $profiledata['user_website'],
'ICQ' => $profiledata['user_icq'],
'LAST_VISIT_TIME' => ($profiledata['user_lastvisit']) ? (bf($profiledata['user_opt'], 'user_opt', 'user_viewonline') && !IS_ADMIN) ? $lang['HIDDEN_USER'] : bb_date($profiledata['user_lastvisit'], 'Y-m-d H:i', false) : $lang['NEVER'],
'LAST_ACTIVITY_TIME' => ($profiledata['user_session_time']) ? (bf($profiledata['user_opt'], 'user_opt', 'user_viewonline') && !IS_ADMIN) ? $lang['HIDDEN_USER'] : bb_date($profiledata['user_session_time'], 'Y-m-d H:i', false) : $lang['NEVER'],
'USER_ACTIVE' => $profiledata['user_active'],
'LOCATION' => $profiledata['user_from'],
'OCCUPATION' => $profiledata['user_occ'],
'INTERESTS' => $profiledata['user_interests'],
'SKYPE' => $profiledata['user_skype'],
'TWITTER' => $profiledata['user_twitter'],
'USER_POINTS' => $profiledata['user_points'],
'GENDER' => ($bb_cfg['gender']) ? $lang['GENDER_SELECT'][$profiledata['user_gender']] : '',
'BIRTHDAY' => ($bb_cfg['birthday_enabled'] && $profiledata['user_birthday'] != '0000-00-00') ? $profiledata['user_birthday'] : '',
'AGE' => ($bb_cfg['birthday_enabled'] && $profiledata['user_birthday'] != '0000-00-00') ? birthday_age($profiledata['user_birthday']) : '',
'L_VIEWING_PROFILE' => sprintf($lang['VIEWING_USER_PROFILE'], $profiledata['username']),
'L_MY_PROFILE' => sprintf($lang['VIEWING_MY_PROFILE'], 'profile.php?mode=editprofile'),
'U_SEARCH_USER' => "search.php?search_author=1&amp;uid={$profiledata['user_id']}",
'U_SEARCH_TOPICS' => "search.php?uid={$profiledata['user_id']}&amp;myt=1",
'U_SEARCH_RELEASES' => "tracker.php?rid={$profiledata['user_id']}#results",
'AVATAR_IMG' => get_avatar($profiledata['user_id'], $profiledata['avatar_ext_id'], !bf($profiledata['user_opt'], 'user_opt', 'dis_avatar')),
'SIGNATURE' => $signature,
'SHOW_PASSKEY' => (IS_ADMIN || $profile_user_id),
'SHOW_ROLE' => (IS_AM || $profile_user_id || $profiledata['user_active']),
'GROUP_MEMBERSHIP' => false,
'TRAF_STATS' => !(IS_AM || $profile_user_id),
));
if (IS_ADMIN)
{
$group_membership = array();
$sql = "
SELECT COUNT(g.group_id) AS groups_cnt, g.group_single_user, ug.user_pending
FROM ". BB_USER_GROUP ." ug
LEFT JOIN ". BB_GROUPS ." g USING(group_id)
WHERE ug.user_id = {$profiledata['user_id']}
GROUP BY ug.user_id, g.group_single_user, ug.user_pending
ORDER BY NULL
";
if ($rowset = DB()->fetch_rowset($sql))
{
$member = $pending = $single = 0;
foreach ($rowset as $row)
{
if (!$row['group_single_user'] && !$row['user_pending'])
{
$member = $row['groups_cnt'];
}
else if (!$row['group_single_user'] && $row['user_pending'])
{
$pending = $row['groups_cnt'];
}
else if ($row['group_single_user'])
{
$single = $row['groups_cnt'];
}
}
if ($member) $group_membership[] = $lang['PARTY'] ." <b>$member</b>";
if ($pending) $group_membership[] = $lang['CANDIDATE'] ." <b>$pending</b>";
if ($single) $group_membership[] = $lang['INDIVIDUAL'];
$group_membership = join(', ', $group_membership);
}
$template->assign_vars(array(
'GROUP_MEMBERSHIP' => (bool) $group_membership,
'GROUP_MEMBERSHIP_TXT' => $group_membership,
));
}
else if (IS_MOD)
{
$template->assign_vars(array(
'SHOW_GROUP_MEMBERSHIP' => ($profiledata['user_level'] != USER),
));
}
// Show users torrent-profile
if (IS_AM || $profile_user_id || !bf($profiledata['user_opt'], 'user_opt', 'user_dls'))
{
require(UCP_DIR .'viewtorrent.php');
}
// Ajax bt_userdata
if (IS_AM || $profile_user_id)
{
show_bt_userdata($profiledata['user_id']);
}
else
{
$template->assign_vars(array(
'DOWN_TOTAL_BYTES' => false,
'MIN_DL_BYTES' => false,
));
}
if (IS_ADMIN)
{
$ajax_user_opt = bb_json_encode(array(
'dis_avatar' => bf($profiledata['user_opt'], 'user_opt', 'dis_avatar'),
'dis_sig' => bf($profiledata['user_opt'], 'user_opt', 'dis_sig'),
'dis_passkey' => bf($profiledata['user_opt'], 'user_opt', 'dis_passkey'),
'dis_pm' => bf($profiledata['user_opt'], 'user_opt', 'dis_pm'),
'dis_post' => bf($profiledata['user_opt'], 'user_opt', 'dis_post'),
'dis_post_edit' => bf($profiledata['user_opt'], 'user_opt', 'dis_post_edit'),
'dis_topic' => bf($profiledata['user_opt'], 'user_opt', 'dis_topic'),
));
$template->assign_vars(array(
'EDITABLE_TPLS' => true,
'AJAX_USER_OPT' => $ajax_user_opt,
'U_MANAGE' => "profile.php?mode=editprofile&amp;u={$profiledata['user_id']}",
'U_PERMISSIONS' => "admin/admin_ug_auth.php?mode=user&amp;u={$profiledata['user_id']}",
));
}
$user_restrictions = array();
if (bf($profiledata['user_opt'], 'user_opt', 'dis_avatar')) $user_restrictions[] = $lang['HIDE_AVATARS'];
if (bf($profiledata['user_opt'], 'user_opt', 'dis_sig')) $user_restrictions[] = $lang['SHOW_CAPTION'];
if (bf($profiledata['user_opt'], 'user_opt', 'dis_passkey')) $user_restrictions[] = $lang['DOWNLOAD_TORRENT'];
if (bf($profiledata['user_opt'], 'user_opt', 'dis_pm')) $user_restrictions[] = $lang['SEND_PM'];
if (bf($profiledata['user_opt'], 'user_opt', 'dis_post')) $user_restrictions[] = $lang['SEND_MESSAGE'];
if (bf($profiledata['user_opt'], 'user_opt', 'dis_post_edit')) $user_restrictions[] = $lang['EDIT_POST'];
if (bf($profiledata['user_opt'], 'user_opt', 'dis_topic')) $user_restrictions[] = $lang['NEW_THREADS'];
$template->assign_var('USER_RESTRICTIONS', join('</li><li>', $user_restrictions));
print_page('usercp_viewprofile.tpl');

View file

@ -0,0 +1,123 @@
<?php
if (!defined('IN_PROFILE')) die(basename(__FILE__));
$releasing = $seeding = $leeching = array();
$releasing_count = $seeding_count = $leeching_count = 0;
// Auth
$excluded_forums_csv = $user->get_excluded_forums(AUTH_VIEW);
$not_auth_forums_sql = ($excluded_forums_csv) ? "
AND f.forum_id NOT IN($excluded_forums_csv)
AND f.forum_parent NOT IN($excluded_forums_csv)
" : '';
$sql = DB()->fetch_rowset("
SELECT
f.forum_id, f.forum_name, t.topic_title,
tor.tor_type, tor.size,
sn.seeders, sn.leechers, tr.*
FROM ". BB_FORUMS ." f, ". BB_TOPICS ." t, ". BB_BT_TRACKER ." tr, ". BB_BT_TORRENTS ." tor, ". BB_BT_TRACKER_SNAP ." sn
WHERE tr.user_id = {$profiledata['user_id']}
AND tr.topic_id = tor.topic_id
AND sn.topic_id = tor.topic_id
AND tor.topic_id = t.topic_id
AND t.forum_id = f.forum_id
$not_auth_forums_sql
GROUP BY tr.topic_id
ORDER BY f.forum_name, t.topic_title
");
foreach ($sql as $rowset)
{
if ($rowset['releaser'])
{
$releasing[] = $rowset;
}
elseif ($rowset['seeder'])
{
$seeding[] = $rowset;
}
else
{
$leeching[] = $rowset;
}
}
if ($releasing)
{
foreach ($releasing as $i => $row)
{
$topic_title = wbr($row['topic_title']);
$template->assign_block_vars('released', array(
'ROW_CLASS' => !($i % 2) ? 'row1' : 'row2',
'FORUM_NAME' => htmlCHR($row['forum_name']),
'TOPIC_TITLE' => ($row['update_time']) ? $topic_title : "<s>$topic_title</s>",
'U_VIEW_FORUM' => FORUM_URL . $row['forum_id'],
'U_VIEW_TOPIC' => TOPIC_URL . $row['topic_id'],
'TOR_TYPE' => is_gold($row['tor_type']),
'TOPIC_SEEDERS' => ($row['seeders']) ? $row['seeders'] : 0,
'TOPIC_LEECHERS' => ($row['leechers']) ? $row['leechers'] : 0,
'SPEED_UP' => ($row['speed_up']) ? humn_size($row['speed_up'], 0, 'KB') .'/s' : '-',
));
$releasing_count++;
}
}
if ($seeding)
{
foreach ($seeding as $i => $row)
{
$topic_title = wbr($row['topic_title']);
$template->assign_block_vars('seed', array(
'ROW_CLASS' => !($i % 2) ? 'row1' : 'row2',
'FORUM_NAME' => htmlCHR($row['forum_name']),
'TOPIC_TITLE' => ($row['update_time']) ? $topic_title : "<s>$topic_title</s>",
'U_VIEW_FORUM' => FORUM_URL . $row['forum_id'],
'U_VIEW_TOPIC' => TOPIC_URL . $row['topic_id'],
'TOR_TYPE' => is_gold($row['tor_type']),
'TOPIC_SEEDERS' => ($row['seeders']) ? $row['seeders'] : 0,
'TOPIC_LEECHERS' => ($row['leechers']) ? $row['leechers'] : 0,
'SPEED_UP' => ($row['speed_up']) ? humn_size($row['speed_up'], 0, 'KB') .'/s' : '-',
));
$seeding_count++;
}
}
if ($leeching)
{
foreach ($leeching as $i => $row)
{
$compl_size = ($row['remain'] && $row['size'] && $row['size'] > $row['remain']) ? ($row['size'] - $row['remain']) : 0;
$compl_perc = ($compl_size) ? floor($compl_size * 100 / $row['size']) : 0;
$topic_title = wbr($row['topic_title']);
$template->assign_block_vars('leech', array(
'ROW_CLASS' => !($i % 2) ? 'row1' : 'row2',
'FORUM_NAME' => htmlCHR($row['forum_name']),
'TOPIC_TITLE' => ($row['update_time']) ? $topic_title : "<s>$topic_title</s>",
'U_VIEW_FORUM' => FORUM_URL . $row['forum_id'],
'U_VIEW_TOPIC' => TOPIC_URL . $row['topic_id'],
'COMPL_PERC' => $compl_perc,
'TOR_TYPE' => is_gold($row['tor_type']),
'TOPIC_SEEDERS' => ($row['seeders']) ? $row['seeders'] : 0,
'TOPIC_LEECHERS' => ($row['leechers']) ? $row['leechers'] : 0,
'SPEED_DOWN' => ($row['speed_down']) ? humn_size($row['speed_down'], 0, 'KB') .'/s' : '-',
));
$leeching_count++;
}
}
$template->assign_vars(array(
'SHOW_SEARCH_DL' => IS_AM || $profile_user_id,
'USERNAME' => $profiledata['username'],
'L_RELEASINGS' => "{$lang['RELEASING']}: ". (($releasing_count) ? "<b>$releasing_count</b>" : '0'),
'L_SEEDINGS' => "{$lang['SEEDING']}: ". (($seeding_count) ? "<b>$seeding_count</b>" : '0'),
'L_LEECHINGS' => "{$lang['LEECHING']}: ". (($leeching_count) ? "<b>$leeching_count</b>" : '0'),
'USER_DLS' => $releasing_count || $seeding_count || $leeching_count,
));