Merge pull request #237 from Exile37/feature/legacy_autoloading

PSR-4 compatible legacy code autoloading
This commit is contained in:
Yuriy Pikhtarev 2017-05-23 23:27:00 +03:00 committed by GitHub
commit 8104657016
51 changed files with 5296 additions and 4525 deletions

341
ajax.php
View file

@ -26,7 +26,7 @@
define('BB_SCRIPT', 'ajax');
define('IN_AJAX', true);
$ajax = new ajax_common();
$ajax = new TorrentPier\Legacy\Ajax();
require __DIR__ . '/common.php';
@ -83,10 +83,6 @@ switch ($ajax->action) {
case 'manage_group':
require INC_DIR . '/functions_group.php';
break;
case 'sitemap':
require CLASS_DIR . '/sitemap.php';
break;
}
// Position in $ajax->valid_actions['xxx']
@ -94,335 +90,8 @@ define('AJAX_AUTH', 0); // 'guest', 'user', 'mod', 'admin', 'super_admin'
$ajax->exec();
//
// Ajax
//
class ajax_common
{
public $request = array();
public $response = array();
public $valid_actions = array(
// ACTION NAME AJAX_AUTH
'edit_user_profile' => array('admin'),
'change_user_rank' => array('admin'),
'change_user_opt' => array('admin'),
'manage_user' => array('admin'),
'manage_admin' => array('admin'),
'sitemap' => array('admin'),
'mod_action' => array('mod'),
'topic_tpl' => array('mod'),
'group_membership' => array('mod'),
'post_mod_comment' => array('mod'),
'avatar' => array('user'),
'gen_passkey' => array('user'),
'change_torrent' => array('user'),
'change_tor_status' => array('user'),
'manage_group' => array('user'),
'view_post' => array('guest'),
'view_torrent' => array('guest'),
'user_register' => array('guest'),
'posts' => array('guest'),
'index_data' => array('guest'),
);
public $action;
/**
* Constructor
/**
* @deprecated ajax_common
* Dirty class removed from here since 2.1.6
* To add new actions see at src/Legacy/Ajax.php
*/
public function __construct()
{
ob_start(array(&$this, 'ob_handler'));
header('Content-Type: text/plain');
}
/**
* Perform action
*/
public function exec()
{
global $lang;
// Exit if we already have errors
if (!empty($this->response['error_code'])) {
$this->send();
}
// Check that requested action is valid
$action = $this->action;
if (!$action || !is_string($action)) {
$this->ajax_die('no action specified');
} elseif (!$action_params =& $this->valid_actions[$action]) {
$this->ajax_die('invalid action: ' . $action);
}
// Auth check
switch ($action_params[AJAX_AUTH]) {
// GUEST
case 'guest':
break;
// USER
case 'user':
if (IS_GUEST) {
$this->ajax_die($lang['NEED_TO_LOGIN_FIRST']);
}
break;
// MOD
case 'mod':
if (!IS_AM) {
$this->ajax_die($lang['ONLY_FOR_MOD']);
}
$this->check_admin_session();
break;
// ADMIN
case 'admin':
if (!IS_ADMIN) {
$this->ajax_die($lang['ONLY_FOR_ADMIN']);
}
$this->check_admin_session();
break;
// SUPER_ADMIN
case 'super_admin':
if (!IS_SUPER_ADMIN) {
$this->ajax_die($lang['ONLY_FOR_SUPER_ADMIN']);
}
$this->check_admin_session();
break;
default:
trigger_error("invalid auth type for $action", E_USER_ERROR);
}
// Run action
$this->$action();
// Send output
$this->send();
}
/**
* Exit on error
*/
public function ajax_die($error_msg, $error_code = E_AJAX_GENERAL_ERROR)
{
$this->response['error_code'] = $error_code;
$this->response['error_msg'] = $error_msg;
$this->send();
}
/**
* Initialization
*/
public function init()
{
$this->request = $_POST;
$this->action =& $this->request['action'];
}
/**
* Send data
*/
public function send()
{
$this->response['action'] = $this->action;
if (DBG_USER && SQL_DEBUG && !empty($_COOKIE['sql_log'])) {
$this->response['sql_log'] = get_sql_log();
}
// sending output will be handled by $this->ob_handler()
exit();
}
/**
* OB Handler
*/
public function ob_handler($contents)
{
if (DBG_USER) {
if ($contents) {
$this->response['raw_output'] = $contents;
}
}
$response_js = json_encode($this->response);
if (GZIP_OUTPUT_ALLOWED && !defined('NO_GZIP')) {
if (UA_GZIP_SUPPORTED && strlen($response_js) > 2000) {
header('Content-Encoding: gzip');
$response_js = gzencode($response_js, 1);
}
}
return $response_js;
}
/**
* Admin session
*/
public function check_admin_session()
{
global $user;
if (!$user->data['session_admin']) {
if (empty($this->request['user_password'])) {
$this->prompt_for_password();
} else {
$login_args = array(
'login_username' => $user->data['username'],
'login_password' => $_POST['user_password'],
);
if (!$user->login($login_args, true)) {
$this->ajax_die('Wrong password');
}
}
}
}
/**
* Prompt for password
*/
public function prompt_for_password()
{
$this->response['prompt_password'] = 1;
$this->send();
}
/**
* Prompt for confirmation
*/
public function prompt_for_confirm($confirm_msg)
{
if (empty($confirm_msg)) {
$this->ajax_die('false');
}
$this->response['prompt_confirm'] = 1;
$this->response['confirm_msg'] = $confirm_msg;
$this->send();
}
/**
* Verify mod rights
*/
public function verify_mod_rights($forum_id)
{
global $userdata, $lang;
$is_auth = auth(AUTH_MOD, $forum_id, $userdata);
if (!$is_auth['auth_mod']) {
$this->ajax_die($lang['ONLY_FOR_MOD']);
}
}
public function edit_user_profile()
{
require AJAX_DIR . '/edit_user_profile.php';
}
public function change_user_rank()
{
require AJAX_DIR . '/change_user_rank.php';
}
public function change_user_opt()
{
require AJAX_DIR . '/change_user_opt.php';
}
public function gen_passkey()
{
require AJAX_DIR . '/gen_passkey.php';
}
public function group_membership()
{
require AJAX_DIR . '/group_membership.php';
}
public function manage_group()
{
require AJAX_DIR . '/edit_group_profile.php';
}
public function post_mod_comment()
{
require AJAX_DIR . '/post_mod_comment.php';
}
public function view_post()
{
require AJAX_DIR . '/view_post.php';
}
public function change_tor_status()
{
require AJAX_DIR . '/change_tor_status.php';
}
public function change_torrent()
{
require AJAX_DIR . '/change_torrent.php';
}
public function view_torrent()
{
require AJAX_DIR . '/view_torrent.php';
}
public function user_register()
{
require AJAX_DIR . '/user_register.php';
}
public function mod_action()
{
require AJAX_DIR . '/mod_action.php';
}
public function posts()
{
require AJAX_DIR . '/posts.php';
}
public function manage_user()
{
require AJAX_DIR . '/manage_user.php';
}
public function manage_admin()
{
require AJAX_DIR . '/manage_admin.php';
}
public function topic_tpl()
{
require AJAX_DIR . '/topic_tpl.php';
}
public function index_data()
{
require AJAX_DIR . '/index_data.php';
}
public function avatar()
{
require AJAX_DIR . '/avatar.php';
}
public function sitemap()
{
require AJAX_DIR . '/sitemap.php';
}
}

View file

@ -100,16 +100,8 @@ define('BOT_UID', -746);
/**
* Database
*/
// Core DB class
require CORE_DIR . '/dbs.php';
require CORE_DIR . '/mysql.php';
$DBS = new DBS($bb_cfg);
$DBS = new TorrentPier\Legacy\Dbs($bb_cfg);
/**
* @param string $db_alias
* @return \sql_db
* @deprecated
*/
function DB($db_alias = 'db1')
{
global $DBS;
@ -119,14 +111,7 @@ function DB($db_alias = 'db1')
/**
* Cache
*/
// Main cache class
require INC_DIR . '/cache/common.php';
// Main datastore class
require INC_DIR . '/datastore/common.php';
// Core CACHE class
require CORE_DIR . '/caches.php';
$CACHES = new CACHES($bb_cfg);
$CACHES = new TorrentPier\Legacy\Caches($bb_cfg);
function CACHE($cache_name)
{
@ -134,29 +119,12 @@ function CACHE($cache_name)
return $CACHES->get_cache_obj($cache_name);
}
// Common cache classes
require INC_DIR . '/cache/memcache.php';
require INC_DIR . '/cache/sqlite.php';
require INC_DIR . '/cache/redis.php';
require INC_DIR . '/cache/apc.php';
require INC_DIR . '/cache/xcache.php';
require INC_DIR . '/cache/file.php';
/**
* Datastore
*/
// Common datastore classes
require INC_DIR . '/datastore/memcache.php';
require INC_DIR . '/datastore/sqlite.php';
require INC_DIR . '/datastore/redis.php';
require INC_DIR . '/datastore/apc.php';
require INC_DIR . '/datastore/xcache.php';
require INC_DIR . '/datastore/file.php';
// Initialize datastore
switch ($bb_cfg['datastore_type']) {
case 'memcache':
$datastore = new datastore_memcache($bb_cfg['cache']['memcache'], $bb_cfg['cache']['prefix']);
$datastore = new TorrentPier\Legacy\Datastore\Memcache($bb_cfg['cache']['memcache'], $bb_cfg['cache']['prefix']);
break;
case 'sqlite':
@ -165,24 +133,24 @@ switch ($bb_cfg['datastore_type']) {
'pconnect' => true,
'con_required' => true,
);
$datastore = new datastore_sqlite($default_cfg, $bb_cfg['cache']['prefix']);
$datastore = new TorrentPier\Legacy\Datastore\Sqlite($default_cfg, $bb_cfg['cache']['prefix']);
break;
case 'redis':
$datastore = new datastore_redis($bb_cfg['cache']['redis'], $bb_cfg['cache']['prefix']);
$datastore = new TorrentPier\Legacy\Datastore\Redis($bb_cfg['cache']['redis'], $bb_cfg['cache']['prefix']);
break;
case 'apc':
$datastore = new datastore_apc($bb_cfg['cache']['prefix']);
$datastore = new TorrentPier\Legacy\Datastore\Apc($bb_cfg['cache']['prefix']);
break;
case 'xcache':
$datastore = new datastore_xcache($bb_cfg['cache']['prefix']);
$datastore = new TorrentPier\Legacy\Datastore\Xcache($bb_cfg['cache']['prefix']);
break;
case 'filecache':
default:
$datastore = new datastore_file($bb_cfg['cache']['db_dir'] . 'datastore/', $bb_cfg['cache']['prefix']);
$datastore = new TorrentPier\Legacy\Datastore\File($bb_cfg['cache']['db_dir'] . 'datastore/', $bb_cfg['cache']['prefix']);
}
function sql_dbg_enabled()
@ -201,7 +169,7 @@ function short_query($sql, $esc_html = false)
}
}
return ($esc_html) ? htmlCHR($sql, true) : $sql;
return $esc_html ? htmlCHR($sql, true) : $sql;
}
// Functions
@ -270,7 +238,7 @@ function mkdir_rec($path, $mode)
return ($path !== '.' && $path !== '..') ? is_writable($path) : false;
}
return (mkdir_rec(dirname($path), $mode)) ? @mkdir($path, $mode) : false;
return mkdir_rec(dirname($path), $mode) ? @mkdir($path, $mode) : false;
}
function verify_id($id, $length)

View file

@ -56,8 +56,7 @@ if ($is_moderator) {
// Avatar
if ($submit) {
if (!empty($_FILES['avatar']['name']) && $bb_cfg['group_avatars']['up_allowed']) {
require INC_DIR . '/functions_upload.php';
$upload = new upload_common();
$upload = new TorrentPier\Legacy\Common\Upload();
if ($upload->init($bb_cfg['group_avatars'], $_FILES['avatar']) and $upload->store('avatar', array("user_id" => GROUP_AVATAR_MASK . $group_id, "avatar_ext_id" => $group_info['avatar_ext_id']))) {
$avatar_ext_id = (int)$upload->file_ext_id;

View file

@ -26,7 +26,6 @@
define('IN_FORUM', true);
define('BB_ROOT', './');
require(BB_ROOT . 'common.php');
require(INC_DIR . 'functions_upload.php');
while (@ob_end_flush()) ;
ob_implicit_flush();
@ -74,7 +73,7 @@ if ($confirm) {
'tmp_name' => BB_ROOT . $bb_cfg['avatar_path'] . '/' . basename($row['user_avatar']),
'error' => 0,
);
$upload = new upload_common();
$upload = new TorrentPier\Legacy\Common\Upload();
if ($upload->init($bb_cfg['avatars'], $FILE, false) and $upload->store('avatar', $row)) {
DB()->query("UPDATE " . BB_USERS . " SET avatar_ext_id = {$upload->file_ext_id} WHERE user_id = {$row['user_id']} LIMIT 1");

View file

@ -30,7 +30,7 @@ if (!defined('IN_AJAX')) {
global $bb_cfg, $lang;
$mode = (string)$this->request['mode'];
$map = new sitemap();
$map = new TorrentPier\Legacy\Sitemap();
$html = '';
switch ($mode) {

View file

@ -52,122 +52,7 @@ if (!$tor = bdecode($file_contents)) {
return $lang['TORFILE_INVALID'];
}
$torrent = new TorrentFileList($tor);
$torrent = new TorrentPier\Legacy\TorrentFileList($tor);
$tor_filelist = $torrent->get_filelist();
$this->response['html'] = $tor_filelist;
/**
* Class TorrentFileList
*/
class TorrentFileList
{
public $tor_decoded = [];
public $files_ary = [
'/' => []
];
public $multiple = false;
public $root_dir = '';
public $files_html = '';
public function __construct($decoded_file_contents)
{
$this->tor_decoded = $decoded_file_contents;
}
public function get_filelist()
{
global $html;
$this->build_filelist_array();
if ($this->multiple) {
if ($this->files_ary['/'] !== '') {
$this->files_ary = array_merge($this->files_ary, $this->files_ary['/']);
unset($this->files_ary['/']);
}
$filelist = $html->array2html($this->files_ary);
return "<div class=\"tor-root-dir\">{$this->root_dir}</div>$filelist";
} else {
return implode('', $this->files_ary['/']);
}
}
private function build_filelist_array()
{
$info = $this->tor_decoded['info'];
if (isset($info['name.utf-8'])) {
$info['name'] =& $info['name.utf-8'];
}
if (isset($info['files']) && is_array($info['files'])) {
$this->root_dir = isset($info['name']) ? '../' . clean_tor_dirname($info['name']) : '...';
$this->multiple = true;
foreach ($info['files'] as $f) {
if (isset($f['path.utf-8'])) {
$f['path'] =& $f['path.utf-8'];
}
if (!isset($f['path']) || !is_array($f['path'])) {
continue;
}
array_deep($f['path'], 'clean_tor_dirname');
$length = isset($f['length']) ? (float)$f['length'] : 0;
$subdir_count = count($f['path']) - 1;
if ($subdir_count > 0) {
$name = array_pop($f['path']);
$cur_files_ary =& $this->files_ary;
for ($i = 0, $j = 1; $i < $subdir_count; $i++, $j++) {
$subdir = $f['path'][$i];
if (!isset($cur_files_ary[$subdir])) {
$cur_files_ary[$subdir] = array();
}
$cur_files_ary =& $cur_files_ary[$subdir];
if ($j == $subdir_count) {
if (is_string($cur_files_ary)) {
$GLOBALS['bnc_error'] = 1;
break(1);
}
$cur_files_ary[] = $this->build_file_item($name, $length);
}
}
natsort($cur_files_ary);
} else {
$name = $f['path'][0];
$this->files_ary['/'][] = $this->build_file_item($name, $length);
natsort($this->files_ary['/']);
}
}
} else {
$name = clean_tor_dirname($info['name']);
$length = (float)$info['length'];
$this->files_ary['/'][] = $this->build_file_item($name, $length);
natsort($this->files_ary['/']);
}
}
private function build_file_item($name, $length)
{
global $bb_cfg, $images, $lang;
$magnet_name = $magnet_ext = '';
if ($bb_cfg['magnet_links_enabled']) {
$magnet_name = '<a title="' . $lang['DC_MAGNET'] . '" href="dchub:magnet:?kt=' . $name . '&xl=' . $length . '"><img src="' . $images['icon_dc_magnet'] . '" width="10" height="10" border="0" /></a>';
$magnet_ext = '<a title="' . $lang['DC_MAGNET_EXT'] . '" href="dchub:magnet:?kt=.' . substr(strrchr($name, '.'), 1) . '&xl=' . $length . '"><img src="' . $images['icon_dc_magnet_ext'] . '" width="10" height="10" border="0" /></a>';
}
return "$name <i>$length</i> $magnet_name $magnet_ext";
}
}
function clean_tor_dirname($dirname)
{
return str_replace(array('[', ']', '<', '>', "'"), array('&#91;', '&#93;', '&lt;', '&gt;', '&#039;'), $dirname);
}

File diff suppressed because it is too large Load diff

View file

@ -284,8 +284,6 @@ define('AJAX_DIR', BB_PATH . '/library/ajax');
define('ATTACH_DIR', BB_PATH . '/library/attach_mod');
define('CFG_DIR', BB_PATH . '/library/config');
define('INC_DIR', BB_PATH . '/library/includes');
define('CLASS_DIR', BB_PATH . '/library/includes/classes');
define('CORE_DIR', BB_PATH . '/library/includes/core');
define('UCP_DIR', BB_PATH . '/library/includes/ucp');
define('LANG_ROOT_DIR', BB_PATH . '/library/language');
define('IMAGES_DIR', BB_PATH . '/styles/images');

View file

@ -403,378 +403,18 @@ function add_search_words($post_id, $post_message, $topic_title = '', $only_retu
}
}
class bbcode
{
public $tpl = array(); // шаблоны для замены тегов
public $smilies; // смайлы
public $found_spam; // найденные спам "слова"
public $del_words = array(); // см. get_words_rate()
public $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,
'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,
);
public $block_tags = array(
'align',
'br',
'clear',
'hr',
'list',
'pre',
'quote',
'spoiler',
);
public $preg = array();
public $str = array();
public $preg_search = array();
public $preg_repl = array();
public $str_search = array();
public $str_repl = array();
/**
* Constructor
/**
* @deprecated bb_code
* Dirty class removed from here since 2.1.6
* To add new bbcodes see at src/Legacy/BBCode.php
*/
public function __construct()
{
$this->tpl = get_bbcode_tpl();
$this->init_replacements();
}
/**
* init_replacements
*/
public 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);
*/
public function bbcode2html($text)
{
global $bb_cfg;
$text = " $text ";
$text = static::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 = implode('|', $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
*/
public 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 (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 = implode('|', $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
*/
public 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
*/
public 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"]
*/
public 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
*/
public 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
*/
public 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
*/
public function smilies_pass($text)
{
global $datastore;
if (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
*/
public 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
*/
public 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();
$bbcode = new TorrentPier\Legacy\BBCode();
}
$orig_word = array();
$replacement_word = array();
@ -785,81 +425,11 @@ function bbcode2html($text)
return $bbcode->bbcode2html($text);
}
class words_rate
{
public $dbg_mode = false;
public $words_rate = 0;
public $deleted_words = array();
public $del_text_hl = '';
public $words_del_exp = '';
public $words_cnt_exp = '#[a-zA-Zа-яА-ЯёЁ]{4,}#';
public function __construct()
{
// слова начинающиеся на..
$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;
}
/**
* возвращает "показатель полезности" сообщения используемый для автоудаления коротких сообщений типа "спасибо", "круто" и т.д.
*/
public 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();
$wr = new TorrentPier\Legacy\WordsRate();
}
return $wr->get_words_rate($text);
}

View file

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

View file

@ -27,9 +27,7 @@ if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
require CLASS_DIR . '/sitemap.php';
$map = new sitemap();
$map = new TorrentPier\Legacy\Sitemap();
$map->create();
if (@file_exists(BB_ROOT . "/sitemap/sitemap.xml")) {

View file

@ -130,95 +130,6 @@ function is_unread($ref, $topic_id = 0, $forum_id = 0)
return (!IS_GUEST && $ref > get_last_read($topic_id, $forum_id));
}
//
// Ads
//
class ads_common
{
public $ad_blocks = array();
public $active_ads = array();
/**
* Constructor
*/
public function __construct()
{
global $bb_cfg;
$this->ad_blocks =& $bb_cfg['ad_blocks'];
$this->active_ads = !empty($bb_cfg['active_ads']) ? @unserialize($bb_cfg['active_ads']) : array();
}
/**
* Get ads to show for each block
*/
public function get($block_types)
{
$ads = array();
if ($this->active_ads) {
$block_ids = $this->get_block_ids($block_types);
if ($ad_ids = $this->get_ad_ids($block_ids)) {
$ad_html = $this->get_ads_html();
foreach ($ad_ids as $block_id => $ad_id) {
$ads[$block_id] =& $ad_html[$ad_id];
}
}
}
return $ads;
}
/**
* Get ads html
*/
public function get_ads_html()
{
global $datastore;
if (!$ads_html = $datastore->get('ads')) {
$datastore->update('ads');
$ads_html = $datastore->get('ads');
}
return $ads_html;
}
/**
* Get block_ids for specified block_types
*/
public function get_block_ids($block_types)
{
$block_ids = array();
foreach ($block_types as $block_type) {
if ($blocks =& $this->ad_blocks[$block_type]) {
$block_ids = array_merge($block_ids, array_keys($blocks));
}
}
return $block_ids;
}
/**
* Get ad_ids for specified blocks
*/
public function get_ad_ids($block_ids)
{
$ad_ids = array();
foreach ($block_ids as $block_id) {
if ($ads =& $this->active_ads[$block_id]) {
shuffle($ads);
$ad_ids[$block_id] = $ads[0];
}
}
return $ad_ids;
}
}
//
// Auth
//
@ -517,130 +428,6 @@ function auth_check($bf_ary, $bf_key, $perm_ary, $perm_key, $is_admin = false)
return bf($perm_ary[$perm_key], $bf_ary, $bf_key);
}
class Date_Delta
{
public $auto_granularity = array(
60 => 'seconds', // set granularity to "seconds" if delta less then 1 minute
10800 => 'minutes', // 3 hours
259200 => 'hours', // 3 days
31363200 => 'mday', // 12 months
311040000 => 'mon', // 10 years
);
public $intervals = array();
public $format = '';
// Creates new object.
public function __construct()
{
global $lang;
$this->intervals = $lang['DELTA_TIME']['INTERVALS'];
$this->format = $lang['DELTA_TIME']['FORMAT'];
}
// Makes the spellable phrase.
public function spellDelta($first, $last, $from = 'auto')
{
if ($last < $first) {
$old_first = $first;
$first = $last;
$last = $old_first;
}
if ($from == 'auto') {
$from = 'year';
$diff = $last - $first;
foreach ($this->auto_granularity as $seconds_count => $granule) {
if ($diff < $seconds_count) {
$from = $granule;
break;
}
}
}
// Solve data delta.
$delta = $this->getDelta($first, $last);
if (!$delta) {
return false;
}
// Make spellable phrase.
$parts = array();
$intervals = $GLOBALS['lang']['DELTA_TIME']['INTERVALS'];
foreach (array_reverse($delta) as $k => $n) {
if (!$n) {
if ($k == $from) {
if (!$parts) {
$parts[] = declension($n, $this->intervals[$k], $this->format);
}
break;
}
continue;
}
$parts[] = declension($n, $this->intervals[$k], $this->format);
if ($k == $from) {
break;
}
}
return implode(' ', $parts);
}
// returns the associative array with date deltas.
public function getDelta($first, $last)
{
if ($last < $first) {
return false;
}
// Solve H:M:S part.
$hms = ($last - $first) % (3600 * 24);
$delta['seconds'] = $hms % 60;
$delta['minutes'] = floor($hms / 60) % 60;
$delta['hours'] = floor($hms / 3600) % 60;
// Now work only with date, delta time = 0.
$last -= $hms;
$f = getdate($first);
$l = getdate($last); // the same daytime as $first!
$dYear = $dMon = $dDay = 0;
// Delta day. Is negative, month overlapping.
$dDay += $l['mday'] - $f['mday'];
if ($dDay < 0) {
$monlen = $this->monthLength(date('Y', $first), date('m', $first));
$dDay += $monlen;
$dMon--;
}
$delta['mday'] = $dDay;
// Delta month. If negative, year overlapping.
$dMon += $l['mon'] - $f['mon'];
if ($dMon < 0) {
$dMon += 12;
$dYear--;
}
$delta['mon'] = $dMon;
// Delta year.
$dYear += $l['year'] - $f['year'];
$delta['year'] = $dYear;
return $delta;
}
// Returns the length (in days) of the specified month.
public function monthLength($year, $mon)
{
$l = 28;
while (checkdate($mon, $l + 1, $year)) {
$l++;
}
return $l;
}
}
function delta_time($timestamp_1, $timestamp_2 = TIMENOW, $granularity = 'auto')
{
return $GLOBALS['DeltaTime']->spellDelta($timestamp_1, $timestamp_2, $granularity);
@ -672,116 +459,6 @@ function get_select($select, $selected = null, $return_as = 'html', $first_opt =
return ($return_as == 'html') ? build_select($select_name, $select_ary, $selected) : $select_ary;
}
class html_common
{
public $options = '';
public $attr = array();
public $cur_attr;
public $max_length = HTML_SELECT_MAX_LENGTH;
public $selected = array();
public function build_select($name, $params, $selected = null, $max_length = HTML_SELECT_MAX_LENGTH, $multiple_size = null, $js = '')
{
if (empty($params)) {
return '';
}
$this->options = '';
$this->selected = array_flip((array)$selected);
$this->max_length = $max_length;
$this->attr = array();
$this->cur_attr =& $this->attr;
if (isset($params['__attributes'])) {
$this->attr = $params['__attributes'];
unset($params['__attributes']);
}
$this->_build_select_rec($params);
$select_params = ($js) ? " $js" : '';
$select_params .= ($multiple_size) ? ' multiple="multiple" size="' . $multiple_size . '"' : '';
$select_params .= ' name="' . htmlCHR($name) . '"';
$select_params .= ' id="' . htmlCHR($name) . '"';
return "\n<select $select_params>\n" . $this->options . "</select>\n";
}
public function _build_select_rec($params)
{
foreach ($params as $opt_name => $opt_val) {
$opt_name = rtrim($opt_name);
if (is_array($opt_val)) {
$this->cur_attr =& $this->cur_attr[$opt_name];
$label = htmlCHR(str_short($opt_name, $this->max_length));
$this->options .= "\t<optgroup label=\"&nbsp;" . $label . "\">\n";
$this->_build_select_rec($opt_val);
$this->options .= "\t</optgroup>\n";
$this->cur_attr =& $this->attr;
} else {
$text = htmlCHR(str_short($opt_name, $this->max_length));
$value = ' value="' . htmlCHR($opt_val) . '"';
$class = isset($this->cur_attr[$opt_name]['class']) ? ' class="' . $this->cur_attr[$opt_name]['class'] . '"' : '';
$style = isset($this->cur_attr[$opt_name]['style']) ? ' style="' . $this->cur_attr[$opt_name]['style'] . '"' : '';
$selected = isset($this->selected[$opt_val]) ? HTML_SELECTED : '';
$disabled = isset($this->cur_attr[$opt_name]['disabled']) ? HTML_DISABLED : '';
$this->options .= "\t\t<option" . $class . $style . $selected . $disabled . $value . '>&nbsp;' . $text . "&nbsp;</option>\n";
}
}
}
public function array2html($array, $ul = 'ul', $li = 'li')
{
$this->out = '';
$this->_array2html_rec($array, $ul, $li);
return "<$ul class=\"tree-root\">{$this->out}</$ul>";
}
public function _array2html_rec($array, $ul, $li)
{
foreach ($array as $k => $v) {
if (is_array($v)) {
$this->out .= "<$li><span class=\"b\">$k</span><$ul>";
$this->_array2html_rec($v, $ul, $li);
$this->out .= "</$ul></$li>";
} else {
$this->out .= "<$li><span>$v</span></$li>";
}
}
}
// all arguments should be already htmlspecialchar()d (if needed)
public function build_checkbox($name, $title, $checked = false, $disabled = false, $class = null, $id = null, $value = 1)
{
$name = ' name="' . $name . '" ';
$value = ' value="' . $value . '" ';
$title = ($class) ? '<span class="' . $class . '">' . $title . '</span>' : $title;
$id = ($id) ? " id=\"$id\" " : '';
$checked = ($checked) ? HTML_CHECKED : '';
$disabled = ($disabled) ? HTML_DISABLED : '';
return '<label><input type="checkbox" ' . $id . $name . $value . $checked . $disabled . ' />&nbsp;' . $title . '&nbsp;</label>';
}
# function build_option ($opt_name, $opt_val, $selected = null, $max_length = false)
# {
# return "\t\t<option value=\"". htmlCHR($opt_val) .'"'. (($selected) ? ' selected="selected"' : '') .'>'. htmlCHR(str_short($opt_name, $max_length)) ."</option>\n";
# }
# function build_optgroup ($label, $contents, $max_length = false)
# {
# return "\t<optgroup label=\"&nbsp;". htmlCHR(str_short($label, $max_length)) ."\">\n". $contents ."\t</optgroup>\n";
# }
}
function build_select($name, $params, $selected = null, $max_length = HTML_SELECT_MAX_LENGTH, $multiple_size = null, $js = '')
{
global $html;
@ -1428,7 +1105,7 @@ function setup_style()
}
}
$template = new Template(TEMPLATES_DIR . '/' . $tpl_dir_name);
$template = new TorrentPier\Legacy\Template(TEMPLATES_DIR . '/' . $tpl_dir_name);
$css_dir = 'styles/' . basename(TEMPLATES_DIR) . '/' . $tpl_dir_name . '/css/';
$template->assign_vars(array(
@ -1678,7 +1355,7 @@ function bb_die($msg_text)
// If the header hasn't been output then do it
if (!defined('PAGE_HEADER_SENT')) {
if (empty($template)) {
$template = new Template(BB_ROOT . "templates/{$bb_cfg['tpl_name']}");
$template = new TorrentPier\Legacy\Template(BB_ROOT . "templates/{$bb_cfg['tpl_name']}");
}
if (empty($theme)) {
$theme = setup_style();
@ -1944,89 +1621,6 @@ function cat_exists($cat_id)
return DB()->fetch_row("SELECT cat_id FROM " . BB_CATEGORIES . " WHERE cat_id = $cat_id LIMIT 1");
}
//
// Action Log
//
class log_action
{
public $log_type = array(
# LOG_TYPE_NAME LOG_TYPE_ID
'mod_topic_delete' => 1,
'mod_topic_move' => 2,
'mod_topic_lock' => 3,
'mod_topic_unlock' => 4,
'mod_post_delete' => 5,
'mod_topic_split' => 6,
'adm_user_delete' => 7,
'adm_user_ban' => 8,
'adm_user_unban' => 9,
);
public $log_type_select = array();
public $log_disabled = false;
public function init()
{
global $lang, $bb_cfg;
foreach ($lang['LOG_ACTION']['LOG_TYPE'] as $log_type => $log_desc) {
$this->log_type_select[strip_tags($log_desc)] = $this->log_type[$log_type];
}
}
public function mod($type_name, array $args = array())
{
global $userdata;
if (empty($this->log_type)) {
$this->init();
}
if ($this->log_disabled) {
return;
}
$forum_id =& $args['forum_id'];
$forum_id_new =& $args['forum_id_new'];
$topic_id =& $args['topic_id'];
$topic_id_new =& $args['topic_id_new'];
$topic_title =& $args['topic_title'];
$topic_title_new =& $args['topic_title_new'];
$log_msg =& $args['log_msg'];
if (!empty($userdata)) {
$user_id = $userdata['user_id'];
$username = $userdata['username'];
$session_ip = $userdata['session_ip'];
} else {
$user_id = '';
$username = defined('IN_CRON') ? 'cron' : CLIENT_IP;
$session_ip = '';
}
$sql_ary = array(
'log_type_id' => (int)$this->log_type["$type_name"],
'log_user_id' => (int)$user_id,
'log_username' => (string)$username,
'log_user_ip' => (string)$session_ip,
'log_forum_id' => (int)$forum_id,
'log_forum_id_new' => (int)$forum_id_new,
'log_topic_id' => (int)$topic_id,
'log_topic_id_new' => (int)$topic_id_new,
'log_topic_title' => (string)$topic_title,
'log_topic_title_new' => (string)$topic_title_new,
'log_time' => (int)TIMENOW,
'log_msg' => (string)$log_msg,
);
$sql_args = DB()->build_array('INSERT', $sql_ary);
DB()->query("INSERT INTO " . BB_LOG . " $sql_args");
}
public function admin($type_name, array $args = array())
{
$this->mod($type_name, $args);
}
}
function get_topic_icon($topic, $is_unread = null)
{
global $bb_cfg, $images;
@ -2587,3 +2181,8 @@ function bb_captcha($mode, $callback = '')
}
return false;
}
function clean_tor_dirname($dirname)
{
return str_replace(array('[', ']', '<', '>', "'"), array('&#91;', '&#93;', '&lt;', '&gt;', '&#039;'), $dirname);
}

View file

@ -460,16 +460,16 @@ define('SQL_LAYER', 'mysql');
$bb_cfg = array_merge(bb_get_config(BB_CONFIG), $bb_cfg);
$user = new user_common();
$user = new TorrentPier\Legacy\Common\User();
$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();
$ads = new TorrentPier\Legacy\Common\Ads();
$html = new TorrentPier\Legacy\Common\Html();
$log_action = new TorrentPier\Legacy\LogAction();
// TODO temporarily 'cat_forums' always enqueued
$datastore->enqueue(array('cat_forums'));

View file

@ -30,713 +30,18 @@ if (!defined('BB_ROOT')) {
define('ONLY_NEW_POSTS', 1);
define('ONLY_NEW_TOPICS', 2);
class user_common
{
/**
* Config
/**
* @deprecated user_common
* Dirty class removed from here since 2.1.6
* To add new opt see at src/Legacy/Common/User.php
*/
public $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)
*/
public $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
*/
public $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
*/
public $sessiondata = array(
'uk' => null,
'uid' => null,
'sid' => '',
);
/**
* Old $userdata
*/
public $data = array();
/**
* Shortcuts
*/
public $id;
/**
* Misc
*/
public $show_ads = false;
/**
* Constructor
*/
public function __construct()
{
$this->get_sessiondata();
}
/**
* Start session (restore existent session or create new)
*/
public function session_start(array $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);
}
}
// 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((int)$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
*/
public 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: https://torrentpier.me/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);
} elseif ($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
*/
public 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
*/
public 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;
} elseif ($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
*/
public 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'] = (int)$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
*/
public 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
*/
public 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);
} elseif ($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
*/
public 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
*/
public 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
*/
public 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');
setlocale(LC_ALL, isset($bb_cfg['lang'][$this->data['user_lang']]['locale']) ?
$bb_cfg['lang'][$this->data['user_lang']]['locale'] : 'en_US.UTF-8');
$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
*/
public 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
*/
public function load_opt_js()
{
if (IS_GUEST) {
$this->opt_js = array_merge($this->opt_js, $this->opt_js_guest);
} elseif (!empty($_COOKIE['opt_js'])) {
$opt_js = json_decode($_COOKIE['opt_js'], true);
if (is_array($opt_js)) {
$this->opt_js = array_merge($this->opt_js, $opt_js);
}
}
}
/**
* Get not auth forums
*/
public 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 implode(',', $not_auth_forums);
}
/**
* Get excluded forums
*/
public 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 implode(',', $excluded);
case 'array':
return $excluded;
case 'flip':
return array_flip(explode(',', $excluded));
}
}
/**
* Enqueue ads
*/
public 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;
return defined('IN_PM') ? true : false;
}
function cache_get_userdata($id)

File diff suppressed because it is too large Load diff

View file

@ -384,8 +384,7 @@ foreach ($profile_fields as $field => $can_edit) {
$pr_data['avatar_ext_id'] = 0;
$db_data['avatar_ext_id'] = 0;
} elseif (!empty($_FILES['avatar']['name']) && $bb_cfg['avatars']['up_allowed']) {
require INC_DIR . '/functions_upload.php';
$upload = new upload_common();
$upload = new TorrentPier\Legacy\Common\Upload();
if ($upload->init($bb_cfg['avatars'], $_FILES['avatar']) and $upload->store('avatar', $pr_data)) {
$pr_data['avatar_ext_id'] = $upload->file_ext_id;

View file

@ -38,7 +38,7 @@ $return_topic_url .= !empty($_POST['start']) ? "&amp;start=" . (int)$_POST['star
set_die_append_msg($forum_id, $topic_id);
$poll = new bb_poll();
$poll = new TorrentPier\Legacy\Poll();
// проверка валидности $topic_id
if (!$topic_id) {
@ -161,76 +161,3 @@ switch ($mode) {
default:
bb_die('Invalid mode: ' . htmlCHR($mode));
}
// Functions
class bb_poll
{
public $err_msg = '';
public $poll_votes = array();
public $max_votes = 0;
public function __construct()
{
global $bb_cfg;
$this->max_votes = $bb_cfg['max_poll_options'];
}
public function build_poll_data($posted_data)
{
$poll_caption = (string)@$posted_data['poll_caption'];
$poll_votes = (string)@$posted_data['poll_votes'];
$this->poll_votes = array();
if (!$poll_caption = str_compact($poll_caption)) {
global $lang;
return $this->err_msg = $lang['EMPTY_POLL_TITLE'];
}
$this->poll_votes[] = $poll_caption; // заголовок имеет vote_id = 0
foreach (explode("\n", $poll_votes) as $vote) {
if (!$vote = str_compact($vote)) {
continue;
}
$this->poll_votes[] = $vote;
}
// проверять на "< 3" -- 2 варианта ответа + заголовок
if (count($this->poll_votes) < 3 || count($this->poll_votes) > $this->max_votes + 1) {
global $lang;
return $this->err_msg = sprintf($lang['NEW_POLL_VOTES'], $this->max_votes);
}
}
public function insert_votes_into_db($topic_id)
{
$this->delete_votes_data($topic_id);
$sql_ary = array();
foreach ($this->poll_votes as $vote_id => $vote_text) {
$sql_ary[] = array(
'topic_id' => (int)$topic_id,
'vote_id' => (int)$vote_id,
'vote_text' => (string)$vote_text,
'vote_result' => (int)0,
);
}
$sql_args = DB()->build_array('MULTI_INSERT', $sql_ary);
DB()->query("REPLACE INTO " . BB_POLL_VOTES . $sql_args);
DB()->query("UPDATE " . BB_TOPICS . " SET topic_vote = 1 WHERE topic_id = $topic_id LIMIT 1");
}
public function delete_poll($topic_id)
{
DB()->query("UPDATE " . BB_TOPICS . " SET topic_vote = 0 WHERE topic_id = $topic_id LIMIT 1");
$this->delete_votes_data($topic_id);
}
public function delete_votes_data($topic_id)
{
DB()->query("DELETE FROM " . BB_POLL_VOTES . " WHERE topic_id = $topic_id");
DB()->query("DELETE FROM " . BB_POLL_USERS . " WHERE topic_id = $topic_id");
CACHE('bb_poll_data')->rm("poll_$topic_id");
}
}

370
src/Legacy/Ajax.php Normal file
View file

@ -0,0 +1,370 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy;
/**
* Class Ajax
* @package TorrentPier\Legacy
*/
class Ajax
{
public $request = [];
public $response = [];
public $valid_actions = [
// ACTION NAME AJAX_AUTH
'edit_user_profile' => ['admin'],
'change_user_rank' => ['admin'],
'change_user_opt' => ['admin'],
'manage_user' => ['admin'],
'manage_admin' => ['admin'],
'sitemap' => ['admin'],
'mod_action' => ['mod'],
'topic_tpl' => ['mod'],
'group_membership' => ['mod'],
'post_mod_comment' => ['mod'],
'avatar' => ['user'],
'gen_passkey' => ['user'],
'change_torrent' => ['user'],
'change_tor_status' => ['user'],
'manage_group' => ['user'],
'view_post' => ['guest'],
'view_torrent' => ['guest'],
'user_register' => ['guest'],
'posts' => ['guest'],
'index_data' => ['guest'],
];
public $action;
/**
* Constructor
*/
public function __construct()
{
ob_start([&$this, 'ob_handler']);
header('Content-Type: text/plain');
}
/**
* Perform action
*/
public function exec()
{
global $lang;
// Exit if we already have errors
if (!empty($this->response['error_code'])) {
$this->send();
}
// Check that requested action is valid
$action = $this->action;
if (!$action || !is_string($action)) {
$this->ajax_die('no action specified');
} elseif (!$action_params =& $this->valid_actions[$action]) {
$this->ajax_die('invalid action: ' . $action);
}
// Auth check
switch ($action_params[AJAX_AUTH]) {
// GUEST
case 'guest':
break;
// USER
case 'user':
if (IS_GUEST) {
$this->ajax_die($lang['NEED_TO_LOGIN_FIRST']);
}
break;
// MOD
case 'mod':
if (!IS_AM) {
$this->ajax_die($lang['ONLY_FOR_MOD']);
}
$this->check_admin_session();
break;
// ADMIN
case 'admin':
if (!IS_ADMIN) {
$this->ajax_die($lang['ONLY_FOR_ADMIN']);
}
$this->check_admin_session();
break;
// SUPER_ADMIN
case 'super_admin':
if (!IS_SUPER_ADMIN) {
$this->ajax_die($lang['ONLY_FOR_SUPER_ADMIN']);
}
$this->check_admin_session();
break;
default:
trigger_error("invalid auth type for $action", E_USER_ERROR);
}
// Run action
$this->$action();
// Send output
$this->send();
}
/**
* Exit on error
*
* @param $error_msg
* @param int $error_code
*/
public function ajax_die($error_msg, $error_code = E_AJAX_GENERAL_ERROR)
{
$this->response['error_code'] = $error_code;
$this->response['error_msg'] = $error_msg;
$this->send();
}
/**
* Initialization
*/
public function init()
{
$this->request = $_POST;
$this->action =& $this->request['action'];
}
/**
* Send data
*/
public function send()
{
$this->response['action'] = $this->action;
if (DBG_USER && SQL_DEBUG && !empty($_COOKIE['sql_log'])) {
$this->response['sql_log'] = get_sql_log();
}
// sending output will be handled by $this->ob_handler()
exit();
}
/**
* OB Handler
*
* @param $contents
* @return string
*/
public function ob_handler($contents)
{
if (DBG_USER) {
if ($contents) {
$this->response['raw_output'] = $contents;
}
}
$response_js = json_encode($this->response);
if (GZIP_OUTPUT_ALLOWED && !defined('NO_GZIP')) {
if (UA_GZIP_SUPPORTED && strlen($response_js) > 2000) {
header('Content-Encoding: gzip');
$response_js = gzencode($response_js, 1);
}
}
return $response_js;
}
/**
* Admin session
*/
public function check_admin_session()
{
global $user;
if (!$user->data['session_admin']) {
if (empty($this->request['user_password'])) {
$this->prompt_for_password();
} else {
$login_args = [
'login_username' => $user->data['username'],
'login_password' => $_POST['user_password'],
];
if (!$user->login($login_args, true)) {
$this->ajax_die('Wrong password');
}
}
}
}
/**
* Prompt for password
*/
public function prompt_for_password()
{
$this->response['prompt_password'] = 1;
$this->send();
}
/**
* Prompt for confirmation
*
* @param string $confirm_msg
*/
public function prompt_for_confirm($confirm_msg)
{
if (empty($confirm_msg)) {
$this->ajax_die('false');
}
$this->response['prompt_confirm'] = 1;
$this->response['confirm_msg'] = $confirm_msg;
$this->send();
}
/**
* Verify mod rights
*
* @param integer $forum_id
*/
public function verify_mod_rights($forum_id)
{
global $userdata, $lang;
$is_auth = auth(AUTH_MOD, $forum_id, $userdata);
if (!$is_auth['auth_mod']) {
$this->ajax_die($lang['ONLY_FOR_MOD']);
}
}
public function edit_user_profile()
{
require AJAX_DIR . '/edit_user_profile.php';
}
public function change_user_rank()
{
require AJAX_DIR . '/change_user_rank.php';
}
public function change_user_opt()
{
require AJAX_DIR . '/change_user_opt.php';
}
public function gen_passkey()
{
require AJAX_DIR . '/gen_passkey.php';
}
public function group_membership()
{
require AJAX_DIR . '/group_membership.php';
}
public function manage_group()
{
require AJAX_DIR . '/edit_group_profile.php';
}
public function post_mod_comment()
{
require AJAX_DIR . '/post_mod_comment.php';
}
public function view_post()
{
require AJAX_DIR . '/view_post.php';
}
public function change_tor_status()
{
require AJAX_DIR . '/change_tor_status.php';
}
public function change_torrent()
{
require AJAX_DIR . '/change_torrent.php';
}
public function view_torrent()
{
require AJAX_DIR . '/view_torrent.php';
}
public function user_register()
{
require AJAX_DIR . '/user_register.php';
}
public function mod_action()
{
require AJAX_DIR . '/mod_action.php';
}
public function posts()
{
require AJAX_DIR . '/posts.php';
}
public function manage_user()
{
require AJAX_DIR . '/manage_user.php';
}
public function manage_admin()
{
require AJAX_DIR . '/manage_admin.php';
}
public function topic_tpl()
{
require AJAX_DIR . '/topic_tpl.php';
}
public function index_data()
{
require AJAX_DIR . '/index_data.php';
}
public function avatar()
{
require AJAX_DIR . '/avatar.php';
}
public function sitemap()
{
require AJAX_DIR . '/sitemap.php';
}
}

1094
src/Legacy/Attach.php Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,111 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy;
/**
* Class AttachPosting
* @package TorrentPier\Legacy
*/
class AttachPosting extends Attach
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->page = 0;
}
/**
* Insert an Attachment into a Post (this is the second function called from posting.php)
*
* @param $post_id
*/
public function insert_attachment($post_id)
{
global $is_auth, $mode;
// Insert Attachment ?
if ($post_id && ($mode === 'newtopic' || $mode === 'reply' || $mode === 'editpost') && $is_auth['auth_attachments']) {
$this->do_insert_attachment('attach_list', 'post', $post_id);
$this->do_insert_attachment('last_attachment', 'post', $post_id);
if ((count($this->attachment_list) > 0 || $this->post_attach) && !isset($_POST['update_attachment'])) {
$sql = 'UPDATE ' . BB_POSTS . ' SET post_attachment = 1 WHERE post_id = ' . (int)$post_id;
if (!DB()->sql_query($sql)) {
bb_die('Unable to update posts table');
}
$sql = 'SELECT topic_id FROM ' . BB_POSTS . ' WHERE post_id = ' . (int)$post_id;
if (!($result = DB()->sql_query($sql))) {
bb_die('Unable to select posts table');
}
$row = DB()->sql_fetchrow($result);
DB()->sql_freeresult($result);
$sql = 'UPDATE ' . BB_TOPICS . ' SET topic_attachment = 1 WHERE topic_id = ' . (int)$row['topic_id'];
if (!DB()->sql_query($sql)) {
bb_die('Unable to update topics table');
}
}
}
}
/**
* Handle Attachments (Add/Delete/Edit/Show) - This is the first function called from every message handler
*/
public function posting_attachment_mod()
{
global $mode, $confirm, $is_auth, $post_id, $delete, $refresh;
if (!$refresh) {
$add_attachment_box = (!empty($_POST['add_attachment_box'])) ? true : false;
$posted_attachments_box = (!empty($_POST['posted_attachments_box'])) ? true : false;
$refresh = $add_attachment_box || $posted_attachments_box;
}
// Choose what to display
$result = $this->handle_attachments($mode);
if ($result === false) {
return;
}
if ($confirm && ($delete || $mode === 'delete' || $mode === 'editpost') && ($is_auth['auth_delete'] || $is_auth['auth_mod'])) {
if ($post_id) {
delete_attachment($post_id);
}
}
$this->display_attachment_bodies();
}
}

427
src/Legacy/BBCode.php Normal file
View file

@ -0,0 +1,427 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy;
/**
* Class BBCode
* @package TorrentPier\Legacy
*/
class BBCode
{
public $tpl = []; // шаблоны для замены тегов
public $smilies; // смайлы
public $found_spam; // найденные спам "слова"
public $del_words = []; // см. get_words_rate()
public $tidy_cfg = [
'drop-empty-paras' => false,
'fix-uri' => false,
'force-output' => true,
'hide-comments' => true,
'join-classes' => false,
'join-styles' => false,
'merge-divs' => 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,
];
public $block_tags = [
'align',
'br',
'clear',
'hr',
'list',
'pre',
'quote',
'spoiler',
];
public $preg = [];
public $str = [];
public $preg_search = [];
public $preg_repl = [];
public $str_search = [];
public $str_repl = [];
/**
* Constructor
*/
public function __construct()
{
$this->tpl = get_bbcode_tpl();
$this->init_replacements();
}
/**
* init_replacements
*/
public 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 = [
'#\[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 = [
'[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
*
* @param string $text должен быть уже обработан htmlCHR($text, false, ENT_NOQUOTES)
* @return string
*/
public function bbcode2html($text)
{
global $bb_cfg;
$text = " $text ";
$text = static::clean_up($text);
$text = $this->spam_filter($text);
// Tag parse
if (strpos($text, '[') !== false) {
// [code]
$text = preg_replace_callback('#(\s*)\[code\](.+?)\[/code\](\s*)#s', [&$this, 'code_callback'], $text);
// Escape tags inside tiltes in [quote="tilte"]
$text = preg_replace_callback('#(\[(quote|spoiler)=")(.+?)("\])#', [&$this, 'escape_tiltes_callback'], $text);
// [url]
$url_exp = '[\w\#!$%&~/.\-;:=,?@а-яА-Я()\[\]+]+?';
$text = preg_replace_callback("#\[url\]((?:https?://)?$url_exp)\[/url\]#isu", [&$this, 'url_callback'], $text);
$text = preg_replace_callback("#\[url\](www\.$url_exp)\[/url\]#isu", [&$this, 'url_callback'], $text);
$text = preg_replace_callback("#\[url=((?:https?://)?$url_exp)\]([^?\n\t].*?)\[/url\]#isu", [&$this, 'url_callback'], $text);
$text = preg_replace_callback("#\[url=(www\.$url_exp)\]([^?\n\t].*?)\[/url\]#isu", [&$this, 'url_callback'], $text);
// Normalize block level tags wrapped with new lines
$block_tags = implode('|', $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
*
* @param string $text
* @return string
*/
public 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
*
* @param string $text
* @return string
*/
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 (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 = [];
$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 = [];
foreach ($found_spam as $keyword) {
$spam_exp[] = preg_quote($keyword, '/');
}
$spam_exp = implode('|', $spam_exp);
$text = preg_replace("/($spam_exp)(\S*)/i", $spam_replace, $msg_decoded);
$text = htmlCHR($text, false, ENT_NOQUOTES);
}
return $text;
}
/**
* [code] callback
*
* @param string $m
* @return string
*/
public 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(['[', ']', ':', ')'], ['&#91;', '&#93;', '&#58;', '&#41;'], $code);
return $this->tpl['code_open'] . $code . $this->tpl['code_close'];
}
/**
* [url] callback
*
* @param string $m
* @return string
*/
public 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 titles in [quote="title"]
*
* @param string $m
* @return string
*/
public function escape_tiltes_callback($m)
{
$tilte = substr($m[3], 0, 250);
$tilte = str_replace(['[', ']', ':', ')', '"'], ['&#91;', '&#93;', '&#58;', '&#41;', '&#34;'], $tilte);
// еще раз htmlspecialchars, т.к. при извлечении из title происходит обратное преобразование
$tilte = htmlspecialchars($tilte, ENT_QUOTES);
return $m[1] . $tilte . $m[4];
}
/**
* Make clickable
*
* @param $text
* @return string
*/
public 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, [&$this, 'make_url_clickable_callback'], $ret);
// Remove our padding..
$ret = substr(substr($ret, 0, -1), 1);
return ($ret);
}
/**
* Make url clickable
*
* @param string $m
* @return string
*/
public 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;
}
/**
* Add smilies
*
* @param string $text
* @return string
*/
public function smilies_pass($text)
{
global $datastore;
if (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;
}
/**
* Replace new line code to html
*
* @param string $text
* @return string
*/
public 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
*
* @param string $text
* @return string
*/
public function tidy($text)
{
$text = tidy_repair_string($text, $this->tidy_cfg, 'utf8');
return $text;
}
}

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Cache;
class cache_apc extends cache_common
/**
* Class Apc
* @package TorrentPier\Legacy\Cache
*/
class Apc extends Common
{
public $used = true;
public $engine = 'APC';

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Cache;
class cache_common
/**
* Class Common
* @package TorrentPier\Legacy\Cache
*/
class Common
{
public $used = false;

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Cache;
class cache_file extends cache_common
/**
* Class File
* @package TorrentPier\Legacy\Cache
*/
class File extends Common
{
public $used = true;
public $engine = 'Filecache';

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Cache;
class cache_memcache extends cache_common
/**
* Class Memcache
* @package TorrentPier\Legacy\Cache
*/
class Memcache extends Common
{
public $used = true;
public $engine = 'Memcache';
@ -44,7 +46,7 @@ class cache_memcache extends cache_common
$this->cfg = $cfg;
$this->prefix = $prefix;
$this->memcache = new Memcache;
$this->memcache = new \Memcache();
$this->dbg_enabled = sql_dbg_enabled();
}

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Cache;
class cache_redis extends cache_common
/**
* Class Redis
* @package TorrentPier\Legacy\Cache
*/
class Redis extends Common
{
public $used = true;
public $engine = 'Redis';
@ -44,7 +46,7 @@ class cache_redis extends cache_common
$this->cfg = $cfg;
$this->prefix = $prefix;
$this->redis = new Redis();
$this->redis = new \Redis();
$this->dbg_enabled = sql_dbg_enabled();
}

129
src/Legacy/Cache/Sqlite.php Normal file
View file

@ -0,0 +1,129 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy\Cache;
use SQLite3;
/**
* Class Sqlite
* @package TorrentPier\Legacy\Cache
*/
class Sqlite extends Common
{
public $used = true;
public $db;
public $prefix;
public $cfg = array(
'db_file_path' => '/path/to/cache.db.sqlite',
'table_name' => 'cache',
'table_schema' => 'CREATE TABLE cache (
cache_name VARCHAR(255),
cache_expire_time INT,
cache_value TEXT,
PRIMARY KEY (cache_name)
)',
'pconnect' => true,
'con_required' => true,
'log_name' => 'CACHE',
);
public function __construct($cfg, $prefix = null)
{
$this->cfg = array_merge($this->cfg, $cfg);
$this->db = new SqliteCommon($this->cfg);
$this->prefix = $prefix;
}
public function get($name, $get_miss_key_callback = '', $ttl = 604800)
{
if (empty($name)) {
return is_array($name) ? array() : false;
}
$this->db->shard($name);
$cached_items = array();
$this->prefix_len = strlen($this->prefix);
$this->prefix_sql = SQLite3::escapeString($this->prefix);
$name_ary = $name_sql = (array)$name;
array_deep($name_sql, 'SQLite3::escapeString');
// get available items
$rowset = $this->db->fetch_rowset("
SELECT cache_name, cache_value
FROM " . $this->cfg['table_name'] . "
WHERE cache_name IN('$this->prefix_sql" . implode("','$this->prefix_sql", $name_sql) . "') AND cache_expire_time > " . TIMENOW . "
LIMIT " . count($name) . "
");
$this->db->debug('start', 'unserialize()');
foreach ($rowset as $row) {
$cached_items[substr($row['cache_name'], $this->prefix_len)] = unserialize($row['cache_value']);
}
$this->db->debug('stop');
// get miss items
if ($get_miss_key_callback and $miss_key = array_diff($name_ary, array_keys($cached_items))) {
foreach ($get_miss_key_callback($miss_key) as $k => $v) {
$this->set($this->prefix . $k, $v, $ttl);
$cached_items[$k] = $v;
}
}
// return
if (is_array($this->prefix . $name)) {
return $cached_items;
} else {
return isset($cached_items[$name]) ? $cached_items[$name] : false;
}
}
public function set($name, $value, $ttl = 604800)
{
$this->db->shard($this->prefix . $name);
$name_sql = SQLite3::escapeString($this->prefix . $name);
$expire = TIMENOW + $ttl;
$value_sql = SQLite3::escapeString(serialize($value));
$result = $this->db->query("REPLACE INTO " . $this->cfg['table_name'] . " (cache_name, cache_expire_time, cache_value) VALUES ('$name_sql', $expire, '$value_sql')");
return (bool)$result;
}
public function rm($name = '')
{
if ($name) {
$this->db->shard($this->prefix . $name);
$result = $this->db->query("DELETE FROM " . $this->cfg['table_name'] . " WHERE cache_name = '" . SQLite3::escapeString($this->prefix . $name) . "'");
} else {
$result = $this->db->query("DELETE FROM " . $this->cfg['table_name']);
}
return (bool)$result;
}
public function gc($expire_time = TIMENOW)
{
$result = $this->db->query("DELETE FROM " . $this->cfg['table_name'] . " WHERE cache_expire_time < $expire_time");
return $result ? $this->db->changes() : 0;
}
}

View file

@ -23,108 +23,15 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Cache;
class cache_sqlite extends cache_common
{
public $used = true;
public $db;
public $prefix;
public $cfg = array(
'db_file_path' => '/path/to/cache.db.sqlite',
'table_name' => 'cache',
'table_schema' => 'CREATE TABLE cache (
cache_name VARCHAR(255),
cache_expire_time INT,
cache_value TEXT,
PRIMARY KEY (cache_name)
)',
'pconnect' => true,
'con_required' => true,
'log_name' => 'CACHE',
);
use SQLite3;
public function __construct($cfg, $prefix = null)
{
$this->cfg = array_merge($this->cfg, $cfg);
$this->db = new sqlite_common($this->cfg);
$this->prefix = $prefix;
}
public function get($name, $get_miss_key_callback = '', $ttl = 604800)
{
if (empty($name)) {
return is_array($name) ? array() : false;
}
$this->db->shard($name);
$cached_items = array();
$this->prefix_len = strlen($this->prefix);
$this->prefix_sql = SQLite3::escapeString($this->prefix);
$name_ary = $name_sql = (array)$name;
array_deep($name_sql, 'SQLite3::escapeString');
// get available items
$rowset = $this->db->fetch_rowset("
SELECT cache_name, cache_value
FROM " . $this->cfg['table_name'] . "
WHERE cache_name IN('$this->prefix_sql" . implode("','$this->prefix_sql", $name_sql) . "') AND cache_expire_time > " . TIMENOW . "
LIMIT " . count($name) . "
");
$this->db->debug('start', 'unserialize()');
foreach ($rowset as $row) {
$cached_items[substr($row['cache_name'], $this->prefix_len)] = unserialize($row['cache_value']);
}
$this->db->debug('stop');
// get miss items
if ($get_miss_key_callback and $miss_key = array_diff($name_ary, array_keys($cached_items))) {
foreach ($get_miss_key_callback($miss_key) as $k => $v) {
$this->set($this->prefix . $k, $v, $ttl);
$cached_items[$k] = $v;
}
}
// return
if (is_array($this->prefix . $name)) {
return $cached_items;
} else {
return isset($cached_items[$name]) ? $cached_items[$name] : false;
}
}
public function set($name, $value, $ttl = 604800)
{
$this->db->shard($this->prefix . $name);
$name_sql = SQLite3::escapeString($this->prefix . $name);
$expire = TIMENOW + $ttl;
$value_sql = SQLite3::escapeString(serialize($value));
$result = $this->db->query("REPLACE INTO " . $this->cfg['table_name'] . " (cache_name, cache_expire_time, cache_value) VALUES ('$name_sql', $expire, '$value_sql')");
return (bool)$result;
}
public function rm($name = '')
{
if ($name) {
$this->db->shard($this->prefix . $name);
$result = $this->db->query("DELETE FROM " . $this->cfg['table_name'] . " WHERE cache_name = '" . SQLite3::escapeString($this->prefix . $name) . "'");
} else {
$result = $this->db->query("DELETE FROM " . $this->cfg['table_name']);
}
return (bool)$result;
}
public function gc($expire_time = TIMENOW)
{
$result = $this->db->query("DELETE FROM " . $this->cfg['table_name'] . " WHERE cache_expire_time < $expire_time");
return ($result) ? $this->db->changes() : 0;
}
}
class sqlite_common extends cache_common
/**
* Class SqliteCommon
* @package TorrentPier\Legacy\Cache
*/
class SqliteCommon extends Common
{
public $cfg = array(
'db_file_path' => 'sqlite.db',
@ -151,7 +58,7 @@ class sqlite_common extends cache_common
public function connect()
{
$this->cur_query = ($this->dbg_enabled) ? 'connect to: ' . $this->cfg['db_file_path'] : 'connect';
$this->cur_query = $this->dbg_enabled ? 'connect to: ' . $this->cfg['db_file_path'] : 'connect';
$this->debug('start');
if (@$this->dbh = new SQLite3($this->cfg['db_file_path'])) {
@ -283,7 +190,7 @@ class sqlite_common extends cache_common
public function gc($expire_time = TIMENOW)
{
$result = $this->db->query("DELETE FROM " . $this->cfg['table_name'] . " WHERE cache_expire_time < $expire_time");
return ($result) ? sqlite_changes($this->db->dbh) : 0;
return $result ? sqlite_changes($this->db->dbh) : 0;
}
public function trigger_error($msg = 'DB Error')

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Cache;
class cache_xcache extends cache_common
/**
* Class Xcache
* @package TorrentPier\Legacy\Cache
*/
class Xcache extends Common
{
public $used = true;
public $engine = 'XCache';

View file

@ -23,20 +23,22 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy;
class caches
/**
* Class Caches
* @package TorrentPier\Legacy
*/
class Caches
{
public $cfg = array(); // конфиг
public $obj = array(); // кеш-объекты
public $ref = array(); // ссылки на $obj (имя_кеша => кеш_объект)
public $cfg = []; // конфиг
public $obj = []; // кеш-объекты
public $ref = []; // ссылки на $obj (имя_кеша => кеш_объект)
public function __construct($cfg)
{
$this->cfg = $cfg['cache'];
$this->obj['__stub'] = new cache_common();
$this->obj['__stub'] = new Cache\Common();
}
public function get_cache_obj($cache_name)
@ -51,7 +53,7 @@ class caches
switch ($cache_type) {
case 'memcache':
if (!isset($this->obj[$cache_name])) {
$this->obj[$cache_name] = new cache_memcache($this->cfg['memcache'], $this->cfg['prefix']);
$this->obj[$cache_name] = new Cache\Memcache($this->cfg['memcache'], $this->cfg['prefix']);
}
$this->ref[$cache_name] =& $this->obj[$cache_name];
break;
@ -61,7 +63,7 @@ class caches
$cache_cfg['pconnect'] = $this->cfg['pconnect'];
$cache_cfg['db_file_path'] = $this->get_db_path($cache_name, $cache_cfg, '.sqlite.db');
$this->obj[$cache_name] = new cache_sqlite($cache_cfg, $this->cfg['prefix']);
$this->obj[$cache_name] = new Cache\Sqlite($cache_cfg, $this->cfg['prefix']);
}
$this->ref[$cache_name] =& $this->obj[$cache_name];
break;
@ -73,35 +75,35 @@ class caches
$cache_cfg['table_name'] = $cache_name;
$cache_cfg['table_schema'] = $this->get_table_schema($cache_cfg);
$this->obj[$cache_name] = new sqlite_common($cache_cfg);
$this->obj[$cache_name] = new Cache\SqliteCommon($cache_cfg);
}
$this->ref[$cache_name] =& $this->obj[$cache_name];
break;
case 'redis':
if (!isset($this->obj[$cache_name])) {
$this->obj[$cache_name] = new cache_redis($this->cfg['redis'], $this->cfg['prefix']);
$this->obj[$cache_name] = new Cache\Redis($this->cfg['redis'], $this->cfg['prefix']);
}
$this->ref[$cache_name] =& $this->obj[$cache_name];
break;
case 'apc':
if (!isset($this->obj[$cache_name])) {
$this->obj[$cache_name] = new cache_apc($this->cfg['prefix']);
$this->obj[$cache_name] = new Cache\Apc($this->cfg['prefix']);
}
$this->ref[$cache_name] =& $this->obj[$cache_name];
break;
case 'xcache':
if (!isset($this->obj[$cache_name])) {
$this->obj[$cache_name] = new cache_xcache($this->cfg['prefix']);
$this->obj[$cache_name] = new Cache\Xcache($this->cfg['prefix']);
}
$this->ref[$cache_name] =& $this->obj[$cache_name];
break;
default: //filecache
if (!isset($this->obj[$cache_name])) {
$this->obj[$cache_name] = new cache_file($this->cfg['db_dir'] . $cache_name . '/', $this->cfg['prefix']);
$this->obj[$cache_name] = new Cache\File($this->cfg['db_dir'] . $cache_name . '/', $this->cfg['prefix']);
}
$this->ref[$cache_name] =& $this->obj[$cache_name];
break;

127
src/Legacy/Common/Ads.php Normal file
View file

@ -0,0 +1,127 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy\Common;
/**
* Class Ads
* @package TorrentPier\Legacy\Common
*/
class Ads
{
public $ad_blocks = [];
public $active_ads = [];
/**
* Constructor
*/
public function __construct()
{
global $bb_cfg;
$this->ad_blocks =& $bb_cfg['ad_blocks'];
$this->active_ads = !empty($bb_cfg['active_ads']) ? @unserialize($bb_cfg['active_ads']) : [];
}
/**
* Get ads to show for each block
*
* @param $block_types
* @return array
*/
public function get($block_types)
{
$ads = [];
if ($this->active_ads) {
$block_ids = $this->get_block_ids($block_types);
if ($ad_ids = $this->get_ad_ids($block_ids)) {
$ad_html = $this->get_ads_html();
foreach ($ad_ids as $block_id => $ad_id) {
$ads[$block_id] =& $ad_html[$ad_id];
}
}
}
return $ads;
}
/**
* Get ads html
*
* @return string
*/
public function get_ads_html()
{
global $datastore;
if (!$ads_html = $datastore->get('ads')) {
$datastore->update('ads');
$ads_html = $datastore->get('ads');
}
return $ads_html;
}
/**
* Get block_ids for specified block_types
*
* @param $block_types
* @return array
*/
public function get_block_ids($block_types)
{
$block_ids = [];
foreach ($block_types as $block_type) {
if ($blocks =& $this->ad_blocks[$block_type]) {
$block_ids = array_merge($block_ids, array_keys($blocks));
}
}
return $block_ids;
}
/**
* Get ad_ids for specified blocks
*
* @param $block_ids
* @return array
*/
public function get_ad_ids($block_ids)
{
$ad_ids = [];
foreach ($block_ids as $block_id) {
if ($ads =& $this->active_ads[$block_id]) {
shuffle($ads);
$ad_ids[$block_id] = $ads[0];
}
}
return $ad_ids;
}
}

164
src/Legacy/Common/Html.php Normal file
View file

@ -0,0 +1,164 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy\Common;
/**
* Class Html
* @package TorrentPier\Legacy\Common
*/
class Html
{
public $options = '';
public $attr = [];
public $cur_attr;
public $max_length = HTML_SELECT_MAX_LENGTH;
public $selected = [];
/**
* @param $name
* @param $params
* @param null $selected
* @param int $max_length
* @param null $multiple_size
* @param string $js
* @return string
*/
public function build_select($name, $params, $selected = null, $max_length = HTML_SELECT_MAX_LENGTH, $multiple_size = null, $js = '')
{
if (empty($params)) {
return '';
}
$this->options = '';
$this->selected = array_flip((array)$selected);
$this->max_length = $max_length;
$this->attr = [];
$this->cur_attr =& $this->attr;
if (isset($params['__attributes'])) {
$this->attr = $params['__attributes'];
unset($params['__attributes']);
}
$this->_build_select_rec($params);
$select_params = ($js) ? " $js" : '';
$select_params .= ($multiple_size) ? ' multiple="multiple" size="' . $multiple_size . '"' : '';
$select_params .= ' name="' . htmlCHR($name) . '"';
$select_params .= ' id="' . htmlCHR($name) . '"';
return "\n<select $select_params>\n" . $this->options . "</select>\n";
}
/**
* @param $params
*/
public function _build_select_rec($params)
{
foreach ($params as $opt_name => $opt_val) {
$opt_name = rtrim($opt_name);
if (is_array($opt_val)) {
$this->cur_attr =& $this->cur_attr[$opt_name];
$label = htmlCHR(str_short($opt_name, $this->max_length));
$this->options .= "\t<optgroup label=\"&nbsp;" . $label . "\">\n";
$this->_build_select_rec($opt_val);
$this->options .= "\t</optgroup>\n";
$this->cur_attr =& $this->attr;
} else {
$text = htmlCHR(str_short($opt_name, $this->max_length));
$value = ' value="' . htmlCHR($opt_val) . '"';
$class = isset($this->cur_attr[$opt_name]['class']) ? ' class="' . $this->cur_attr[$opt_name]['class'] . '"' : '';
$style = isset($this->cur_attr[$opt_name]['style']) ? ' style="' . $this->cur_attr[$opt_name]['style'] . '"' : '';
$selected = isset($this->selected[$opt_val]) ? HTML_SELECTED : '';
$disabled = isset($this->cur_attr[$opt_name]['disabled']) ? HTML_DISABLED : '';
$this->options .= "\t\t<option" . $class . $style . $selected . $disabled . $value . '>&nbsp;' . $text . "&nbsp;</option>\n";
}
}
}
/**
* @param $array
* @param string $ul
* @param string $li
* @return string
*/
public function array2html($array, $ul = 'ul', $li = 'li')
{
$this->out = '';
$this->_array2html_rec($array, $ul, $li);
return "<$ul class=\"tree-root\">{$this->out}</$ul>";
}
/**
* @param $array
* @param $ul
* @param $li
*/
public function _array2html_rec($array, $ul, $li)
{
foreach ($array as $k => $v) {
if (is_array($v)) {
$this->out .= "<$li><span class=\"b\">$k</span><$ul>";
$this->_array2html_rec($v, $ul, $li);
$this->out .= "</$ul></$li>";
} else {
$this->out .= "<$li><span>$v</span></$li>";
}
}
}
/**
* All arguments should be already htmlspecialchar (if needed)
*
* @param $name
* @param $title
* @param bool $checked
* @param bool $disabled
* @param null $class
* @param null $id
* @param int $value
* @return string
*/
public function build_checkbox($name, $title, $checked = false, $disabled = false, $class = null, $id = null, $value = 1)
{
$name = ' name="' . $name . '" ';
$value = ' value="' . $value . '" ';
$title = $class ? '<span class="' . $class . '">' . $title . '</span>' : $title;
$id = $id ? " id=\"$id\" " : '';
$checked = $checked ? HTML_CHECKED : '';
$disabled = $disabled ? HTML_DISABLED : '';
return '<label><input type="checkbox" ' . $id . $name . $value . $checked . $disabled . ' />&nbsp;' . $title . '&nbsp;</label>';
}
}

View file

@ -23,42 +23,50 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Common;
class upload_common
/**
* Class Upload
* @package TorrentPier\Legacy\Common
*/
class Upload
{
public $cfg = array(
public $cfg = [
'max_size' => 0,
'max_width' => 0,
'max_height' => 0,
'allowed_ext' => array(),
'allowed_ext' => [],
'upload_path' => '',
);
public $file = array(
];
public $file = [
'name' => '',
'type' => '',
'size' => 0,
'tmp_name' => '',
'error' => UPLOAD_ERR_NO_FILE,
);
];
public $orig_name = '';
public $file_path = ''; // Stored file path
public $file_ext = '';
public $file_ext_id = '';
public $file_size = '';
public $ext_ids = array(); // array_flip($bb_cfg['file_id_ext'])
public $errors = array();
public $img_types = array(
public $ext_ids = []; // array_flip($bb_cfg['file_id_ext'])
public $errors = [];
public $img_types = [
1 => 'gif',
2 => 'jpg',
3 => 'png',
6 => 'bmp',
7 => 'tiff',
8 => 'tiff',
);
];
/**
* @param array $cfg
* @param array $post_params
* @param bool $uploaded_only
* @return bool
*/
public function init(array $cfg = [], array $post_params = [], $uploaded_only = true)
{
global $bb_cfg, $lang;
@ -129,7 +137,12 @@ class upload_common
return true;
}
public function store($mode = '', array $params = array())
/**
* @param string $mode
* @param array $params
* @return bool
*/
public function store($mode = '', array $params = [])
{
if ($mode == 'avatar') {
delete_avatar($params['user_id'], $params['avatar_ext_id']);
@ -145,6 +158,10 @@ class upload_common
}
}
/**
* @param $file_path
* @return bool
*/
public function _move($file_path)
{
$dir = dirname($file_path);

733
src/Legacy/Common/User.php Normal file
View file

@ -0,0 +1,733 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy\Common;
use TorrentPier\Legacy\DateDelta;
/**
* Class User
* @package TorrentPier\Legacy\Common
*/
class User
{
/**
* Config
*/
public $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)
*/
public $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
*/
public $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
*/
public $sessiondata = array(
'uk' => null,
'uid' => null,
'sid' => '',
);
/**
* Old $userdata
*/
public $data = array();
/**
* Shortcuts
*/
public $id;
/**
* Misc
*/
public $show_ads = false;
/**
* Constructor
*/
public function __construct()
{
$this->get_sessiondata();
}
/**
* Start session (restore existent session or create new)
*/
public function session_start(array $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);
}
}
// 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((int)$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
*/
public 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: https://torrentpier.me/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);
} elseif ($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
*/
public 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
*/
public 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;
} elseif ($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
*/
public 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'] = (int)$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
*/
public 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
*/
public 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);
} elseif ($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
*/
public 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
*/
public 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
*/
public 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');
setlocale(LC_ALL, isset($bb_cfg['lang'][$this->data['user_lang']]['locale']) ?
$bb_cfg['lang'][$this->data['user_lang']]['locale'] : 'en_US.UTF-8');
$theme = setup_style();
$DeltaTime = new DateDelta();
// 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
*/
public 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
*/
public function load_opt_js()
{
if (IS_GUEST) {
$this->opt_js = array_merge($this->opt_js, $this->opt_js_guest);
} elseif (!empty($_COOKIE['opt_js'])) {
$opt_js = json_decode($_COOKIE['opt_js'], true);
if (is_array($opt_js)) {
$this->opt_js = array_merge($this->opt_js, $opt_js);
}
}
}
/**
* Get not auth forums
*/
public 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 implode(',', $not_auth_forums);
}
/**
* Get excluded forums
*/
public 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 implode(',', $excluded);
case 'array':
return $excluded;
case 'flip':
return array_flip(explode(',', $excluded));
}
}
/**
* Enqueue ads
*/
public 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;
}
}
}

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Datastore;
class datastore_apc extends datastore_common
/**
* Class Apc
* @package TorrentPier\Legacy\Datastore
*/
class Apc extends Common
{
public $engine = 'APC';
public $prefix;

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Datastore;
class datastore_common
/**
* Class Common
* @package TorrentPier\Legacy\Datastore
*/
class Common
{
/**
* Директория с builder-скриптами (внутри INC_DIR)
@ -37,19 +39,19 @@ class datastore_common
* Готовая к употреблению data
* array('title' => data)
*/
public $data = array();
public $data = [];
/**
* Список элементов, которые будут извлечены из хранилища при первом же запросе get()
* до этого момента они ставятся в очередь $queued_items для дальнейшего извлечения _fetch()'ем
* всех элементов одним запросом
* array('title1', 'title2'...)
*/
public $queued_items = array();
public $queued_items = [];
/**
* 'title' => 'builder script name' inside "includes/datastore" dir
*/
public $known_items = array(
public $known_items = [
'cat_forums' => 'build_cat_forums.php',
'jumpbox' => 'build_cat_forums.php',
'viewtopic_forum_select' => 'build_cat_forums.php',
@ -61,17 +63,10 @@ class datastore_common
'ranks' => 'build_ranks.php',
'attach_extensions' => 'build_attach_extensions.php',
'smile_replacements' => 'build_smilies.php',
);
];
/**
* Constructor
*/
public function __construct()
{
}
/**
* @param array(item1_title, item2_title...) or single item's title
* @param array (item1_title, item2_title...) or single item's title
*/
public function enqueue($items)
{
@ -123,7 +118,7 @@ class datastore_common
}
}
$this->queued_items = array();
$this->queued_items = [];
}
public function _fetch_from_store()
@ -146,7 +141,7 @@ class datastore_common
public $sql_timetotal = 0;
public $cur_query_time = 0;
public $dbg = array();
public $dbg = [];
public $dbg_id = 0;
public $dbg_enabled = false;
public $cur_query;

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Datastore;
class datastore_file extends datastore_common
/**
* Class File
* @package TorrentPier\Legacy\Datastore
*/
class File extends Common
{
public $dir;
public $prefix;

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Datastore;
class datastore_memcache extends datastore_common
/**
* Class Memcache
* @package TorrentPier\Legacy\Datastore
*/
class Memcache extends Common
{
public $cfg;
public $memcache;
@ -43,7 +45,7 @@ class datastore_memcache extends datastore_common
$this->cfg = $cfg;
$this->prefix = $prefix;
$this->memcache = new Memcache;
$this->memcache = new \Memcache();
$this->dbg_enabled = sql_dbg_enabled();
}

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Datastore;
class datastore_redis extends datastore_common
/**
* Class Redis
* @package TorrentPier\Legacy\Datastore
*/
class Redis extends Common
{
public $cfg;
public $redis;
@ -42,7 +44,7 @@ class datastore_redis extends datastore_common
}
$this->cfg = $cfg;
$this->redis = new Redis();
$this->redis = new \Redis();
$this->dbg_enabled = sql_dbg_enabled();
$this->prefix = $prefix;
}

View file

@ -23,11 +23,15 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Datastore;
class datastore_sqlite extends datastore_common
use SQLite3;
/**
* Class Sqlite
* @package TorrentPier\Legacy\Datastore
*/
class Sqlite extends Common
{
public $engine = 'SQLite';
public $db;
@ -48,7 +52,7 @@ class datastore_sqlite extends datastore_common
public function __construct($cfg, $prefix = null)
{
$this->cfg = array_merge($this->cfg, $cfg);
$this->db = new sqlite_common($this->cfg);
$this->db = new SqliteCommon($this->cfg);
$this->prefix = $prefix;
}

View file

@ -0,0 +1,202 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy\Datastore;
use SQLite3;
/**
* Class SqliteCommon
* @package TorrentPier\Legacy\Datastore
*/
class SqliteCommon extends Common
{
public $cfg = array(
'db_file_path' => 'sqlite.db',
'table_name' => 'table_name',
'table_schema' => 'CREATE TABLE table_name (...)',
'pconnect' => true,
'con_required' => true,
'log_name' => 'SQLite',
'shard_type' => 'none', # none, string, int (тип перевичного ключа для шардинга)
'shard_val' => 0, # для string - кол. начальных символов, для int - делитель (будет использован остаток от деления)
);
public $engine = 'SQLite';
public $dbh;
public $connected = false;
public $shard_val = false;
public $table_create_attempts = 0;
public function __construct($cfg)
{
$this->cfg = array_merge($this->cfg, $cfg);
$this->dbg_enabled = sql_dbg_enabled();
}
public function connect()
{
$this->cur_query = $this->dbg_enabled ? 'connect to: ' . $this->cfg['db_file_path'] : 'connect';
$this->debug('start');
if (@$this->dbh = new SQLite3($this->cfg['db_file_path'])) {
$this->connected = true;
}
if (DBG_LOG) {
dbg_log(' ', $this->cfg['log_name'] . '-connect' . ($this->connected ? '' : '-FAIL'));
}
if (!$this->connected && $this->cfg['con_required']) {
trigger_error('SQLite not connected', E_USER_ERROR);
}
$this->debug('stop');
$this->cur_query = null;
}
public function create_table()
{
$this->table_create_attempts++;
return $this->dbh->query($this->cfg['table_schema']);
}
public function shard($name)
{
$type = $this->cfg['shard_type'];
if ($type == 'none') {
return;
}
if (is_array($name)) {
trigger_error('cannot shard: $name is array', E_USER_ERROR);
}
// define shard_val
if ($type == 'string') {
$shard_val = substr($name, 0, $this->cfg['shard_val']);
} else {
$shard_val = $name % $this->cfg['shard_val'];
}
// все запросы должны быть к одному и тому же шарду
if ($this->shard_val !== false) {
if ($shard_val != $this->shard_val) {
trigger_error("shard cannot be reassigned. [{$this->shard_val}, $shard_val, $name]", E_USER_ERROR);
} else {
return;
}
}
$this->shard_val = $shard_val;
$this->cfg['db_file_path'] = str_replace('*', $shard_val, $this->cfg['db_file_path']);
}
public function query($query)
{
if (!$this->connected) {
$this->connect();
}
$this->cur_query = $query;
$this->debug('start');
if (!$result = @$this->dbh->query($query)) {
$rowsresult = $this->dbh->query("PRAGMA table_info({$this->cfg['table_name']})");
$rowscount = 0;
while ($row = $rowsresult->fetchArray(SQLITE3_ASSOC)) {
$rowscount++;
}
if (!$this->table_create_attempts && !$rowscount) {
if ($this->create_table()) {
$result = $this->dbh->query($query);
}
}
if (!$result) {
$this->trigger_error($this->get_error_msg());
}
}
$this->debug('stop');
$this->cur_query = null;
$this->num_queries++;
return $result;
}
public function fetch_row($query)
{
$result = $this->query($query);
return is_resource($result) ? $result->fetchArray(SQLITE3_ASSOC) : false;
}
public function fetch_rowset($query)
{
$result = $this->query($query);
$rowset = array();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$rowset[] = $row;
}
return $rowset;
}
public function changes()
{
return is_resource($this->dbh) ? $this->dbh->changes() : 0;
}
public function escape($str)
{
return SQLite3::escapeString($str);
}
public function get_error_msg()
{
return 'SQLite error #' . ($err_code = $this->dbh->lastErrorCode()) . ': ' . $this->dbh->lastErrorMsg();
}
public function rm($name = '')
{
if ($name) {
$this->db->shard($this->prefix . $name);
$result = $this->db->query("DELETE FROM " . $this->cfg['table_name'] . " WHERE cache_name = '" . SQLite3::escapeString($this->prefix . $name) . "'");
} else {
$result = $this->db->query("DELETE FROM " . $this->cfg['table_name']);
}
return (bool)$result;
}
public function gc($expire_time = TIMENOW)
{
$result = $this->db->query("DELETE FROM " . $this->cfg['table_name'] . " WHERE cache_expire_time < $expire_time");
return $result ? sqlite_changes($this->db->dbh) : 0;
}
public function trigger_error($msg = 'DB Error')
{
if (error_reporting()) {
trigger_error($msg, E_USER_ERROR);
}
}
}

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy\Datastore;
class datastore_xcache extends datastore_common
/**
* Class Xcache
* @package TorrentPier\Legacy\Datastore
*/
class Xcache extends Common
{
public $prefix;
public $engine = 'XCache';

172
src/Legacy/DateDelta.php Normal file
View file

@ -0,0 +1,172 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy;
/**
* Class DateDelta
* @package TorrentPier\Legacy
*/
class DateDelta
{
public $auto_granularity = [
60 => 'seconds', // set granularity to "seconds" if delta less then 1 minute
10800 => 'minutes', // 3 hours
259200 => 'hours', // 3 days
31363200 => 'mday', // 12 months
311040000 => 'mon', // 10 years
];
public $intervals = [];
public $format = '';
public function __construct()
{
global $lang;
$this->intervals = $lang['DELTA_TIME']['INTERVALS'];
$this->format = $lang['DELTA_TIME']['FORMAT'];
}
/**
* Makes the spellable phrase
*
* @param $first
* @param $last
* @param string $from
* @return bool|string
*/
public function spellDelta($first, $last, $from = 'auto')
{
if ($last < $first) {
$old_first = $first;
$first = $last;
$last = $old_first;
}
if ($from == 'auto') {
$from = 'year';
$diff = $last - $first;
foreach ($this->auto_granularity as $seconds_count => $granule) {
if ($diff < $seconds_count) {
$from = $granule;
break;
}
}
}
// Solve data delta.
$delta = $this->getDelta($first, $last);
if (!$delta) {
return false;
}
// Make spellable phrase.
$parts = [];
$intervals = $GLOBALS['lang']['DELTA_TIME']['INTERVALS'];
foreach (array_reverse($delta) as $k => $n) {
if (!$n) {
if ($k == $from) {
if (!$parts) {
$parts[] = declension($n, $this->intervals[$k], $this->format);
}
break;
}
continue;
}
$parts[] = declension($n, $this->intervals[$k], $this->format);
if ($k == $from) {
break;
}
}
return implode(' ', $parts);
}
/**
* Returns the associative array with date deltas
*
* @param $first
* @param $last
* @return bool
*/
public function getDelta($first, $last)
{
if ($last < $first) {
return false;
}
// Solve H:M:S part.
$hms = ($last - $first) % (3600 * 24);
$delta['seconds'] = $hms % 60;
$delta['minutes'] = floor($hms / 60) % 60;
$delta['hours'] = floor($hms / 3600) % 60;
// Now work only with date, delta time = 0.
$last -= $hms;
$f = getdate($first);
$l = getdate($last); // the same daytime as $first!
$dYear = $dMon = $dDay = 0;
// Delta day. Is negative, month overlapping.
$dDay += $l['mday'] - $f['mday'];
if ($dDay < 0) {
$monlen = $this->monthLength(date('Y', $first), date('m', $first));
$dDay += $monlen;
$dMon--;
}
$delta['mday'] = $dDay;
// Delta month. If negative, year overlapping.
$dMon += $l['mon'] - $f['mon'];
if ($dMon < 0) {
$dMon += 12;
$dYear--;
}
$delta['mon'] = $dMon;
// Delta year.
$dYear += $l['year'] - $f['year'];
$delta['year'] = $dYear;
return $delta;
}
/**
* Returns the length (in days) of the specified month
*
* @param $year
* @param $mon
* @return int
*/
public function monthLength($year, $mon)
{
$l = 28;
while (checkdate($mon, $l + 1, $year)) {
$l++;
}
return $l;
}
}

View file

@ -23,15 +23,17 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy;
class dbs
/**
* Class Dbs
* @package TorrentPier\Legacy
*/
class Dbs
{
public $cfg = array(); // $srv_name => $srv_cfg
public $srv = array(); // $srv_name => $db_obj
public $alias = array(); // $srv_alias => $srv_name
public $cfg = []; // $srv_name => $srv_cfg
public $srv = []; // $srv_name => $db_obj
public $alias = []; // $srv_alias => $srv_name
public $log_file = 'sql_queries';
public $log_counter = 0;
@ -55,7 +57,7 @@ class dbs
$srv_name = $this->get_srv_name($srv_name_or_alias);
if (!is_object($this->srv[$srv_name])) {
$this->srv[$srv_name] = new sql_db($this->cfg[$srv_name]);
$this->srv[$srv_name] = new SqlDb($this->cfg[$srv_name]);
$this->srv[$srv_name]->db_server = $srv_name;
}
return $this->srv[$srv_name];

117
src/Legacy/LogAction.php Normal file
View file

@ -0,0 +1,117 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy;
/**
* Class LogAction
* @package TorrentPier\Legacy
*/
class LogAction
{
public $log_type = [
'mod_topic_delete' => 1,
'mod_topic_move' => 2,
'mod_topic_lock' => 3,
'mod_topic_unlock' => 4,
'mod_post_delete' => 5,
'mod_topic_split' => 6,
'adm_user_delete' => 7,
'adm_user_ban' => 8,
'adm_user_unban' => 9,
];
public $log_type_select = [];
public $log_disabled = false;
public function init()
{
global $lang, $bb_cfg;
foreach ($lang['LOG_ACTION']['LOG_TYPE'] as $log_type => $log_desc) {
$this->log_type_select[strip_tags($log_desc)] = $this->log_type[$log_type];
}
}
/**
* @param $type_name
* @param array $args
*/
public function mod($type_name, array $args = [])
{
global $userdata;
if (empty($this->log_type)) {
$this->init();
}
if ($this->log_disabled) {
return;
}
$forum_id =& $args['forum_id'];
$forum_id_new =& $args['forum_id_new'];
$topic_id =& $args['topic_id'];
$topic_id_new =& $args['topic_id_new'];
$topic_title =& $args['topic_title'];
$topic_title_new =& $args['topic_title_new'];
$log_msg =& $args['log_msg'];
if (!empty($userdata)) {
$user_id = $userdata['user_id'];
$username = $userdata['username'];
$session_ip = $userdata['session_ip'];
} else {
$user_id = '';
$username = defined('IN_CRON') ? 'cron' : CLIENT_IP;
$session_ip = '';
}
$sql_ary = [
'log_type_id' => (int)$this->log_type["$type_name"],
'log_user_id' => (int)$user_id,
'log_username' => (string)$username,
'log_user_ip' => (string)$session_ip,
'log_forum_id' => (int)$forum_id,
'log_forum_id_new' => (int)$forum_id_new,
'log_topic_id' => (int)$topic_id,
'log_topic_id_new' => (int)$topic_id_new,
'log_topic_title' => (string)$topic_title,
'log_topic_title_new' => (string)$topic_title_new,
'log_time' => (int)TIMENOW,
'log_msg' => (string)$log_msg,
];
$sql_args = DB()->build_array('INSERT', $sql_ary);
DB()->query("INSERT INTO " . BB_LOG . " $sql_args");
}
/**
* @param $type_name
* @param array $args
*/
public function admin($type_name, array $args = [])
{
$this->mod($type_name, $args);
}
}

123
src/Legacy/Poll.php Normal file
View file

@ -0,0 +1,123 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy;
/**
* Class Poll
* @package TorrentPier\Legacy
*/
class Poll
{
public $err_msg = '';
public $poll_votes = [];
public $max_votes = 0;
public function __construct()
{
global $bb_cfg;
$this->max_votes = $bb_cfg['max_poll_options'];
}
/**
* Формирование результатов голосования
*
* @param $posted_data
* @return string
*/
public function build_poll_data($posted_data)
{
$poll_caption = (string)@$posted_data['poll_caption'];
$poll_votes = (string)@$posted_data['poll_votes'];
$this->poll_votes = [];
if (!$poll_caption = str_compact($poll_caption)) {
global $lang;
return $this->err_msg = $lang['EMPTY_POLL_TITLE'];
}
$this->poll_votes[] = $poll_caption; // заголовок имеет vote_id = 0
foreach (explode("\n", $poll_votes) as $vote) {
if (!$vote = str_compact($vote)) {
continue;
}
$this->poll_votes[] = $vote;
}
// проверять на "< 3" -- 2 варианта ответа + заголовок
if (count($this->poll_votes) < 3 || count($this->poll_votes) > $this->max_votes + 1) {
global $lang;
return $this->err_msg = sprintf($lang['NEW_POLL_VOTES'], $this->max_votes);
}
}
/**
* Добавление голосов в базу данных
*
* @param integer $topic_id
*/
public function insert_votes_into_db($topic_id)
{
$this->delete_votes_data($topic_id);
$sql_ary = [];
foreach ($this->poll_votes as $vote_id => $vote_text) {
$sql_ary[] = [
'topic_id' => (int)$topic_id,
'vote_id' => (int)$vote_id,
'vote_text' => (string)$vote_text,
'vote_result' => (int)0,
];
}
$sql_args = DB()->build_array('MULTI_INSERT', $sql_ary);
DB()->query("REPLACE INTO " . BB_POLL_VOTES . $sql_args);
DB()->query("UPDATE " . BB_TOPICS . " SET topic_vote = 1 WHERE topic_id = $topic_id LIMIT 1");
}
/**
* Удаление голосования
*
* @param integer $topic_id
*/
public function delete_poll($topic_id)
{
DB()->query("UPDATE " . BB_TOPICS . " SET topic_vote = 0 WHERE topic_id = $topic_id LIMIT 1");
$this->delete_votes_data($topic_id);
}
/**
* Удаление информации о проголосовавших и голосов
*
* @param integer $topic_id
*/
public function delete_votes_data($topic_id)
{
DB()->query("DELETE FROM " . BB_POLL_VOTES . " WHERE topic_id = $topic_id");
DB()->query("DELETE FROM " . BB_POLL_USERS . " WHERE topic_id = $topic_id");
CACHE('bb_poll_data')->rm("poll_$topic_id");
}
}

View file

@ -23,11 +23,13 @@
* SOFTWARE.
*/
if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy;
class sitemap
/**
* Class Sitemap
* @package TorrentPier\Legacy
*/
class Sitemap
{
public $home = '';
public $limit = 0;

View file

@ -23,14 +23,15 @@
* SOFTWARE.
*/
if (!defined('SQL_DEBUG')) {
die(basename(__FILE__));
}
namespace TorrentPier\Legacy;
use mysqli_result;
/**
* Class sql_db
* Class SqlDb
* @package TorrentPier\Legacy
*/
class sql_db
class SqlDb
{
public $cfg = [];
public $cfg_keys = ['dbhost', 'dbname', 'dbuser', 'dbpasswd', 'charset', 'persist'];
@ -119,7 +120,7 @@ class sql_db
if (mysqli_connect_error()) {
$server = (DBG_USER) ? $this->cfg['dbhost'] : '';
header("HTTP/1.0 503 Service Unavailable");
header('HTTP/1.0 503 Service Unavailable');
bb_log(' ', "db_err/connect_failed_{$this->cfg['dbhost']}");
die("Could not connect to mysql server $server");
}
@ -319,7 +320,7 @@ class sql_db
$rowset = [];
while ($row = mysqli_fetch_assoc($result)) {
$rowset[] = ($field_name) ? $row[$field_name] : $row;
$rowset[] = $field_name ? $row[$field_name] : $row;
}
return $rowset;

1051
src/Legacy/Template.php Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,152 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy;
/**
* Class TorrentFileList
* @package TorrentPier\Legacy
*/
class TorrentFileList
{
public $tor_decoded = [];
public $files_ary = [
'/' => []
];
public $multiple = false;
public $root_dir = '';
public $files_html = '';
public function __construct($decoded_file_contents)
{
$this->tor_decoded = $decoded_file_contents;
}
/**
* Получение списка файлов
*
* @return string
*/
public function get_filelist()
{
global $html;
$this->build_filelist_array();
if ($this->multiple) {
if ($this->files_ary['/'] !== '') {
$this->files_ary = array_merge($this->files_ary, $this->files_ary['/']);
unset($this->files_ary['/']);
}
$filelist = $html->array2html($this->files_ary);
return "<div class=\"tor-root-dir\">{$this->root_dir}</div>$filelist";
}
return implode('', $this->files_ary['/']);
}
/**
* Формирование списка файлов
*/
private function build_filelist_array()
{
$info = $this->tor_decoded['info'];
if (isset($info['name.utf-8'])) {
$info['name'] =& $info['name.utf-8'];
}
if (isset($info['files']) && is_array($info['files'])) {
$this->root_dir = isset($info['name']) ? '../' . clean_tor_dirname($info['name']) : '...';
$this->multiple = true;
foreach ($info['files'] as $f) {
if (isset($f['path.utf-8'])) {
$f['path'] =& $f['path.utf-8'];
}
if (!isset($f['path']) || !is_array($f['path'])) {
continue;
}
array_deep($f['path'], 'clean_tor_dirname');
$length = isset($f['length']) ? (float)$f['length'] : 0;
$subdir_count = count($f['path']) - 1;
if ($subdir_count > 0) {
$name = array_pop($f['path']);
$cur_files_ary =& $this->files_ary;
for ($i = 0, $j = 1; $i < $subdir_count; $i++, $j++) {
$subdir = $f['path'][$i];
if (!isset($cur_files_ary[$subdir])) {
$cur_files_ary[$subdir] = array();
}
$cur_files_ary =& $cur_files_ary[$subdir];
if ($j === $subdir_count) {
if (is_string($cur_files_ary)) {
$GLOBALS['bnc_error'] = 1;
break;
}
$cur_files_ary[] = $this->build_file_item($name, $length);
}
}
natsort($cur_files_ary);
} else {
$name = $f['path'][0];
$this->files_ary['/'][] = $this->build_file_item($name, $length);
natsort($this->files_ary['/']);
}
}
} else {
$name = clean_tor_dirname($info['name']);
$length = (float)$info['length'];
$this->files_ary['/'][] = $this->build_file_item($name, $length);
natsort($this->files_ary['/']);
}
}
/**
* Формирование файла
*
* @param $name
* @param $length
* @return string
*/
private function build_file_item($name, $length)
{
global $bb_cfg, $images, $lang;
$magnet_name = $magnet_ext = '';
if ($bb_cfg['magnet_links_enabled']) {
$magnet_name = '<a title="' . $lang['DC_MAGNET'] . '" href="dchub:magnet:?kt=' . $name . '&xl=' . $length . '"><img src="' . $images['icon_dc_magnet'] . '" width="10" height="10" border="0" /></a>';
$magnet_ext = '<a title="' . $lang['DC_MAGNET_EXT'] . '" href="dchub:magnet:?kt=.' . substr(strrchr($name, '.'), 1) . '&xl=' . $length . '"><img src="' . $images['icon_dc_magnet_ext'] . '" width="10" height="10" border="0" /></a>';
}
return "$name <i>$length</i> $magnet_name $magnet_ext";
}
}

103
src/Legacy/WordsRate.php Normal file
View file

@ -0,0 +1,103 @@
<?php
/**
* MIT License
*
* Copyright (c) 2005-2017 TorrentPier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace TorrentPier\Legacy;
/**
* Class WordsRate
* @package TorrentPier\Legacy
*/
class WordsRate
{
public $dbg_mode = false;
public $words_rate = 0;
public $deleted_words = [];
public $del_text_hl = '';
public $words_del_exp = '';
public $words_cnt_exp = '#[a-zA-Zа-яА-ЯёЁ]{4,}#';
public function __construct()
{
// слова начинающиеся на..
$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;
}
/**
* Возвращает "показатель полезности" сообщения используемый для автоудаления коротких сообщений типа "спасибо", "круто" и т.д.
*
* @param string $text
* @return int
*/
public function get_words_rate($text)
{
$this->words_rate = 127; // максимальное значение по умолчанию
$this->deleted_words = [];
$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;
}
}