diff --git a/ajax.php b/ajax.php
index 8bf17a936..e17753c90 100644
--- a/ajax.php
+++ b/ajax.php
@@ -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
- */
- 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';
- }
-}
+/**
+ * @deprecated ajax_common
+ * Dirty class removed from here since 2.1.6
+ * To add new actions see at src/Legacy/Ajax.php
+ */
diff --git a/common.php b/common.php
index 4d0257045..e801cc30d 100644
--- a/common.php
+++ b/common.php
@@ -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)
diff --git a/group_edit.php b/group_edit.php
index 3d1c6bcf9..960fc3b1c 100644
--- a/group_edit.php
+++ b/group_edit.php
@@ -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;
diff --git a/install/upgrade/r583-convert_avatars.php b/install/upgrade/r583-convert_avatars.php
index 60b938a42..700f17131 100644
--- a/install/upgrade/r583-convert_avatars.php
+++ b/install/upgrade/r583-convert_avatars.php
@@ -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");
diff --git a/library/ajax/sitemap.php b/library/ajax/sitemap.php
index 3403021b3..49e2c8dd5 100644
--- a/library/ajax/sitemap.php
+++ b/library/ajax/sitemap.php
@@ -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) {
diff --git a/library/ajax/view_torrent.php b/library/ajax/view_torrent.php
index 5cc22c5ca..6e41e0b06 100644
--- a/library/ajax/view_torrent.php
+++ b/library/ajax/view_torrent.php
@@ -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 "
{$this->root_dir}
$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 = '
';
- $magnet_ext = '
';
- }
-
- return "$name $length $magnet_name $magnet_ext";
- }
-}
-
-function clean_tor_dirname($dirname)
-{
- return str_replace(array('[', ']', '<', '>', "'"), array('[', ']', '<', '>', '''), $dirname);
-}
diff --git a/library/attach_mod/posting_attachments.php b/library/attach_mod/posting_attachments.php
index 3046d5aa9..59f453323 100644
--- a/library/attach_mod/posting_attachments.php
+++ b/library/attach_mod/posting_attachments.php
@@ -33,1153 +33,6 @@ define('FILENAME_MAX_LENGTH', 180);
define('FILENAME_CRYPTIC', false);
define('FILENAME_CRYPTIC_LENGTH', 64);
-class attach_parent
-{
- public $post_attach = false;
- public $attach_filename = '';
- public $filename = '';
- public $type = '';
- public $extension = '';
- public $file_comment = '';
- public $num_attachments = 0; // number of attachments in message
- public $filesize = 0;
- public $filetime = 0;
- public $thumbnail = 0;
- public $page = 0; // On which page we are on ? This should be filled by child classes.
-
- // Switches
- public $add_attachment_body = 0;
- public $posted_attachments_body = 0;
-
- /**
- * Constructor
- */
- public function __construct()
- {
- $this->add_attachment_body = get_var('add_attachment_body', 0);
- $this->posted_attachments_body = get_var('posted_attachments_body', 0);
-
- $this->file_comment = get_var('filecomment', '');
- $this->attachment_id_list = get_var('attach_id_list', array(0));
- $this->attachment_comment_list = get_var('comment_list', array(''));
- $this->attachment_filesize_list = get_var('filesize_list', array(0));
- $this->attachment_filetime_list = get_var('filetime_list', array(0));
- $this->attachment_filename_list = get_var('filename_list', array(''));
- $this->attachment_extension_list = get_var('extension_list', array(''));
- $this->attachment_mimetype_list = get_var('mimetype_list', array(''));
-
- $this->filename = (isset($_FILES['fileupload']) && isset($_FILES['fileupload']['name']) && $_FILES['fileupload']['name'] !== 'none') ? trim(stripslashes($_FILES['fileupload']['name'])) : '';
-
- $this->attachment_list = get_var('attachment_list', array(''));
- $this->attachment_thumbnail_list = get_var('attach_thumbnail_list', array(0));
- }
-
- /**
- * Get Quota Limits
- * @param array $userdata_quota
- * @param int $user_id
- */
- public function get_quota_limits(array $userdata_quota, $user_id = 0)
- {
- global $attach_config;
-
- $priority = 'user;group';
-
- if (IS_ADMIN) {
- $attach_config['pm_filesize_limit'] = 0; // Unlimited
- $attach_config['upload_filesize_limit'] = 0; // Unlimited
- return;
- }
-
- $quota_type = QUOTA_UPLOAD_LIMIT;
- $limit_type = 'upload_filesize_limit';
- $default = 'attachment_quota';
-
- if (!$user_id) {
- $user_id = (int) $userdata_quota['user_id'];
- }
-
- $priority = explode(';', $priority);
- $found = false;
-
- foreach ($priority as $item) {
- if ($item === 'group' && !$found) {
- // Get Group Quota, if we find one, we have our quota
- $sql = 'SELECT u.group_id
- FROM ' . BB_USER_GROUP . ' u, ' . BB_GROUPS . ' g
- WHERE g.group_single_user = 0
- AND u.user_pending = 0
- AND u.group_id = g.group_id
- AND u.user_id = ' . (int) $user_id;
-
- if (!($result = DB()->sql_query($sql))) {
- bb_die('Could not get user group');
- }
-
- $rows = DB()->sql_fetchrowset($result);
- DB()->sql_freeresult($result);
-
- if ($rows) {
- $group_id = array();
-
- foreach ($rows as $row) {
- $group_id[] = (int) $row['group_id'];
- }
-
- $sql = 'SELECT l.quota_limit
- FROM ' . BB_QUOTA . ' q, ' . BB_QUOTA_LIMITS . ' l
- WHERE q.group_id IN (' . implode(', ', $group_id) . ')
- AND q.group_id <> 0
- AND q.quota_type = ' . (int) $quota_type . '
- AND q.quota_limit_id = l.quota_limit_id
- ORDER BY l.quota_limit DESC
- LIMIT 1';
-
- if (!($result = DB()->sql_query($sql))) {
- bb_die('Could not get group quota');
- }
-
- if (DB()->num_rows($result)) {
- $row = DB()->sql_fetchrow($result);
- $attach_config[$limit_type] = $row['quota_limit'];
- $found = true;
- }
- DB()->sql_freeresult($result);
- }
- }
-
- if ($item === 'user' && !$found) {
- // Get User Quota, if the user is not in a group or the group has no quotas
- $sql = 'SELECT l.quota_limit
- FROM ' . BB_QUOTA . ' q, ' . BB_QUOTA_LIMITS . ' l
- WHERE q.user_id = ' . $user_id . '
- AND q.user_id <> 0
- AND q.quota_type = ' . $quota_type . '
- AND q.quota_limit_id = l.quota_limit_id
- LIMIT 1';
-
- if (!($result = DB()->sql_query($sql))) {
- bb_die('Could not get user quota');
- }
-
- if (DB()->num_rows($result)) {
- $row = DB()->sql_fetchrow($result);
- $attach_config[$limit_type] = $row['quota_limit'];
- $found = true;
- }
- DB()->sql_freeresult($result);
- }
- }
-
- if (!$found) {
- // Set Default Quota Limit
- $quota_id = (int) ((int) $quota_type === QUOTA_UPLOAD_LIMIT) ? $attach_config['default_upload_quota'] : $attach_config['default_pm_quota'];
-
- if (!$quota_id) {
- $attach_config[$limit_type] = $attach_config[$default];
- } else {
- $sql = 'SELECT quota_limit
- FROM ' . BB_QUOTA_LIMITS . '
- WHERE quota_limit_id = ' . (int) $quota_id . '
- LIMIT 1';
-
- if (!($result = DB()->sql_query($sql))) {
- bb_die('Could not get default quota limit');
- }
-
- if (DB()->num_rows($result) > 0) {
- $row = DB()->sql_fetchrow($result);
- $attach_config[$limit_type] = $row['quota_limit'];
- } else {
- $attach_config[$limit_type] = $attach_config[$default];
- }
- DB()->sql_freeresult($result);
- }
- }
-
- // Never exceed the complete Attachment Upload Quota
- if ($quota_type === QUOTA_UPLOAD_LIMIT) {
- if ($attach_config[$limit_type] > $attach_config[$default]) {
- $attach_config[$limit_type] = $attach_config[$default];
- }
- }
- }
-
- /**
- * Handle all modes... (intern)
- * @private
- */
- public function handle_attachments($mode)
- {
- global $is_auth, $attach_config, $refresh, $post_id, $submit, $preview, $error, $error_msg, $lang;
-
- //
- // ok, what shall we do ;)
- //
-
- if (IS_ADMIN) {
- $max_attachments = ADMIN_MAX_ATTACHMENTS;
- } else {
- $max_attachments = (int) $attach_config['max_attachments'];
- }
-
- $sql_id = 'post_id';
-
- // nothing, if the user is not authorized or attachment mod disabled
- if ($attach_config['disable_mod'] || !$is_auth['auth_attachments']) {
- return false;
- }
-
- // Init Vars
- $attachments = array();
-
- if (!$refresh) {
- $add = isset($_POST['add_attachment']);
- $delete = isset($_POST['del_attachment']);
- $edit = isset($_POST['edit_comment']);
- $update_attachment = isset($_POST['update_attachment']);
- $del_thumbnail = isset($_POST['del_thumbnail']);
-
- $add_attachment_box = !empty($_POST['add_attachment_box']);
- $posted_attachments_box = !empty($_POST['posted_attachments_box']);
-
- $refresh = $add || $delete || $edit || $del_thumbnail || $update_attachment || $add_attachment_box || $posted_attachments_box;
- }
-
- // Get Attachments
- $attachments = get_attachments_from_post($post_id);
-
- $auth = $is_auth['auth_edit'] || $is_auth['auth_mod'];
-
- if (!$submit && $mode === 'editpost' && $auth) {
- if (!$refresh && !$preview && !$error) {
- foreach ($attachments as $attachment) {
- $this->attachment_list[] = $attachment['physical_filename'];
- $this->attachment_comment_list[] = $attachment['comment'];
- $this->attachment_filename_list[] = $attachment['real_filename'];
- $this->attachment_extension_list[] = $attachment['extension'];
- $this->attachment_mimetype_list[] = $attachment['mimetype'];
- $this->attachment_filesize_list[] = $attachment['filesize'];
- $this->attachment_filetime_list[] = $attachment['filetime'];
- $this->attachment_id_list[] = $attachment['attach_id'];
- $this->attachment_thumbnail_list[] = $attachment['thumbnail'];
- }
- }
- }
-
- $this->num_attachments = count($this->attachment_list);
-
- if ($submit) {
- if ($mode === 'newtopic' || $mode === 'reply' || $mode === 'editpost') {
- if ($this->filename) {
- if ($this->num_attachments < (int) $max_attachments) {
- $this->upload_attachment();
-
- if (!$error && $this->post_attach) {
- array_unshift($this->attachment_list, $this->attach_filename);
- array_unshift($this->attachment_comment_list, $this->file_comment);
- array_unshift($this->attachment_filename_list, $this->filename);
- array_unshift($this->attachment_extension_list, $this->extension);
- array_unshift($this->attachment_mimetype_list, $this->type);
- array_unshift($this->attachment_filesize_list, $this->filesize);
- array_unshift($this->attachment_filetime_list, $this->filetime);
- array_unshift($this->attachment_id_list, '0');
- array_unshift($this->attachment_thumbnail_list, $this->thumbnail);
-
- $this->file_comment = '';
- $this->post_attach = false;
- }
- } else {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= sprintf($lang['TOO_MANY_ATTACHMENTS'], (int) $max_attachments);
- }
- }
- }
- }
-
- if ($preview || $refresh || $error) {
- $delete_attachment = isset($_POST['del_attachment']);
- $delete_thumbnail = isset($_POST['del_thumbnail']);
-
- $add_attachment = isset($_POST['add_attachment']);
- $edit_attachment = isset($_POST['edit_comment']);
- $update_attachment = isset($_POST['update_attachment']);
-
- // Perform actions on temporary attachments
- if ($delete_attachment || $delete_thumbnail) {
- // store old values
- $actual_id_list = get_var('attach_id_list', array(0));
- $actual_comment_list = get_var('comment_list', array(''));
- $actual_filename_list = get_var('filename_list', array(''));
- $actual_extension_list = get_var('extension_list', array(''));
- $actual_mimetype_list = get_var('mimetype_list', array(''));
- $actual_filesize_list = get_var('filesize_list', array(0));
- $actual_filetime_list = get_var('filetime_list', array(0));
-
- $actual_list = get_var('attachment_list', array(''));
- $actual_thumbnail_list = get_var('attach_thumbnail_list', array(0));
-
- // clean values
- $this->attachment_list = array();
- $this->attachment_comment_list = array();
- $this->attachment_filename_list = array();
- $this->attachment_extension_list = array();
- $this->attachment_mimetype_list = array();
- $this->attachment_filesize_list = array();
- $this->attachment_filetime_list = array();
- $this->attachment_id_list = array();
- $this->attachment_thumbnail_list = array();
-
- // restore values :)
- if (isset($_POST['attachment_list'])) {
- for ($i = 0, $iMax = count($actual_list); $i < $iMax; $i++) {
- $restore = false;
- $del_thumb = false;
-
- if ($delete_thumbnail) {
- if (!isset($_POST['del_thumbnail'][$actual_list[$i]])) {
- $restore = true;
- } else {
- $del_thumb = true;
- }
- }
- if ($delete_attachment) {
- if (!isset($_POST['del_attachment'][$actual_list[$i]])) {
- $restore = true;
- }
- }
-
- if ($restore) {
- $this->attachment_list[] = $actual_list[$i];
- $this->attachment_comment_list[] = $actual_comment_list[$i];
- $this->attachment_filename_list[] = $actual_filename_list[$i];
- $this->attachment_extension_list[] = $actual_extension_list[$i];
- $this->attachment_mimetype_list[] = $actual_mimetype_list[$i];
- $this->attachment_filesize_list[] = $actual_filesize_list[$i];
- $this->attachment_filetime_list[] = $actual_filetime_list[$i];
- $this->attachment_id_list[] = $actual_id_list[$i];
- $this->attachment_thumbnail_list[] = $actual_thumbnail_list[$i];
- } elseif (!$del_thumb) {
- // delete selected attachment
- if ($actual_id_list[$i] == '0') {
- unlink_attach($actual_list[$i]);
-
- if ($actual_thumbnail_list[$i] == 1) {
- unlink_attach($actual_list[$i], MODE_THUMBNAIL);
- }
- } else {
- delete_attachment($post_id, $actual_id_list[$i], $this->page);
- }
- } elseif ($del_thumb) {
- // delete selected thumbnail
- $this->attachment_list[] = $actual_list[$i];
- $this->attachment_comment_list[] = $actual_comment_list[$i];
- $this->attachment_filename_list[] = $actual_filename_list[$i];
- $this->attachment_extension_list[] = $actual_extension_list[$i];
- $this->attachment_mimetype_list[] = $actual_mimetype_list[$i];
- $this->attachment_filesize_list[] = $actual_filesize_list[$i];
- $this->attachment_filetime_list[] = $actual_filetime_list[$i];
- $this->attachment_id_list[] = $actual_id_list[$i];
- $this->attachment_thumbnail_list[] = 0;
-
- if ($actual_id_list[$i] == 0) {
- unlink_attach($actual_list[$i], MODE_THUMBNAIL);
- } else {
- $sql = 'UPDATE ' . BB_ATTACHMENTS_DESC . ' SET thumbnail = 0 WHERE attach_id = ' . (int) $actual_id_list[$i];
-
- if (!(DB()->sql_query($sql))) {
- bb_die('Unable to update ' . BB_ATTACHMENTS_DESC);
- }
- }
- }
- }
- }
- } elseif ($edit_attachment || $update_attachment || $add_attachment || $preview) {
- if ($edit_attachment) {
- $actual_comment_list = get_var('comment_list', array(''));
-
- $this->attachment_comment_list = array();
-
- for ($i = 0, $iMax = count($this->attachment_list); $i < $iMax; $i++) {
- $this->attachment_comment_list[$i] = $actual_comment_list[$i];
- }
- }
-
- if ($update_attachment) {
- if (empty($this->filename)) {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= $lang['ERROR_EMPTY_ADD_ATTACHBOX'];
- }
-
- $this->upload_attachment();
-
- if (!$error) {
- $actual_id_list = get_var('attach_id_list', array(0));
-
- $attachment_id = 0;
- $actual_element = 0;
-
- for ($i = 0, $iMax = count($actual_id_list); $i < $iMax; $i++) {
- if (isset($_POST['update_attachment'][$actual_id_list[$i]])) {
- $attachment_id = (int) $actual_id_list[$i];
- $actual_element = $i;
- }
- }
-
- // Get current informations to delete the Old Attachment
- $sql = 'SELECT physical_filename, comment, thumbnail
- FROM ' . BB_ATTACHMENTS_DESC . '
- WHERE attach_id = ' . (int) $attachment_id;
-
- if (!($result = DB()->sql_query($sql))) {
- bb_die('Unable to select old attachment entry');
- }
-
- if (DB()->num_rows($result) != 1) {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= $lang['ERROR_MISSING_OLD_ENTRY'];
- }
-
- $row = DB()->sql_fetchrow($result);
- DB()->sql_freeresult($result);
-
- $comment = !trim($this->file_comment) ? trim($row['comment']) : trim($this->file_comment);
-
- // Update Entry
- $sql_ary = array(
- 'physical_filename' => (string) basename($this->attach_filename),
- 'real_filename' => (string) basename($this->filename),
- 'comment' => (string) $comment,
- 'extension' => (string) strtolower($this->extension),
- 'mimetype' => (string) strtolower($this->type),
- 'filesize' => (int) $this->filesize,
- 'filetime' => (int) $this->filetime,
- 'thumbnail' => (int) $this->thumbnail
- );
-
- $sql = 'UPDATE ' . BB_ATTACHMENTS_DESC . ' SET ' . attach_mod_sql_build_array('UPDATE', $sql_ary) . '
- WHERE attach_id = ' . (int) $attachment_id;
-
- if (!(DB()->sql_query($sql))) {
- bb_die('Unable to update the attachment');
- }
-
- // Delete the Old Attachment
- unlink_attach($row['physical_filename']);
-
- if ((int) $row['thumbnail'] === 1) {
- unlink_attach($row['physical_filename'], MODE_THUMBNAIL);
- }
-
- //bt
- if ($this->attachment_extension_list[$actual_element] === TORRENT_EXT && $attachments[$actual_element]['tracker_status']) {
- include INC_DIR . '/functions_torrent.php';
- tracker_unregister($attachment_id);
- }
- //bt end
-
- // Make sure it is displayed
- $this->attachment_list[$actual_element] = $this->attach_filename;
- $this->attachment_comment_list[$actual_element] = $comment;
- $this->attachment_filename_list[$actual_element] = $this->filename;
- $this->attachment_extension_list[$actual_element] = $this->extension;
- $this->attachment_mimetype_list[$actual_element] = $this->type;
- $this->attachment_filesize_list[$actual_element] = $this->filesize;
- $this->attachment_filetime_list[$actual_element] = $this->filetime;
- $this->attachment_id_list[$actual_element] = $actual_id_list[$actual_element];
- $this->attachment_thumbnail_list[$actual_element] = $this->thumbnail;
- $this->file_comment = '';
- }
- }
-
- if (($add_attachment || $preview) && !empty($this->filename)) {
- if ($this->num_attachments < (int) $max_attachments) {
- $this->upload_attachment();
-
- if (!$error) {
- array_unshift($this->attachment_list, $this->attach_filename);
- array_unshift($this->attachment_comment_list, $this->file_comment);
- array_unshift($this->attachment_filename_list, $this->filename);
- array_unshift($this->attachment_extension_list, $this->extension);
- array_unshift($this->attachment_mimetype_list, $this->type);
- array_unshift($this->attachment_filesize_list, $this->filesize);
- array_unshift($this->attachment_filetime_list, $this->filetime);
- array_unshift($this->attachment_id_list, '0');
- array_unshift($this->attachment_thumbnail_list, $this->thumbnail);
-
- $this->file_comment = '';
- }
- } else {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= sprintf($lang['TOO_MANY_ATTACHMENTS'], (int) $max_attachments);
- }
- }
- }
- }
-
- return true;
- }
-
- /**
- * Basic Insert Attachment Handling for all Message Types
- */
- public function do_insert_attachment($mode, $message_type, $message_id)
- {
- global $upload_dir;
-
- if ((int) $message_id < 0) {
- return false;
- }
-
- global $post_info, $userdata;
-
- $post_id = (int) $message_id;
- $user_id_1 = (isset($post_info['poster_id'])) ? (int) $post_info['poster_id'] : 0;
-
- if (!$user_id_1) {
- $user_id_1 = (int) $userdata['user_id'];
- }
-
- if ($mode === 'attach_list') {
- for ($i = 0, $iMax = count($this->attachment_list); $i < $iMax; $i++) {
- if ($this->attachment_id_list[$i]) {
- //bt
- if ($this->attachment_extension_list[$i] === TORRENT_EXT && !defined('TORRENT_ATTACH_ID')) {
- define('TORRENT_ATTACH_ID', $this->attachment_id_list[$i]);
- }
- //bt end
-
- // update entry in db if attachment already stored in db and filespace
- $sql = 'UPDATE ' . BB_ATTACHMENTS_DESC . "
- SET comment = '" . @attach_mod_sql_escape($this->attachment_comment_list[$i]) . "'
- WHERE attach_id = " . $this->attachment_id_list[$i];
-
- if (!(DB()->sql_query($sql))) {
- bb_die('Unable to update the file comment');
- }
- } else {
- if (empty($this->attachment_mimetype_list[$i]) && $this->attachment_extension_list[$i] === TORRENT_EXT) {
- $this->attachment_mimetype_list[$i] = 'application/x-bittorrent';
- }
-
- // insert attachment into db
- $sql_ary = array(
- 'physical_filename' => (string) basename($this->attachment_list[$i]),
- 'real_filename' => (string) basename($this->attachment_filename_list[$i]),
- 'comment' => (string) @$this->attachment_comment_list[$i],
- 'extension' => (string) strtolower($this->attachment_extension_list[$i]),
- 'mimetype' => (string) strtolower($this->attachment_mimetype_list[$i]),
- 'filesize' => (int) $this->attachment_filesize_list[$i],
- 'filetime' => (int) $this->attachment_filetime_list[$i],
- 'thumbnail' => (int) $this->attachment_thumbnail_list[$i]
- );
-
- $sql = 'INSERT INTO ' . BB_ATTACHMENTS_DESC . ' ' . attach_mod_sql_build_array('INSERT', $sql_ary);
-
- if (!(DB()->sql_query($sql))) {
- bb_die('Could not store Attachment.
Your ' . $message_type . ' has been stored');
- }
-
- $attach_id = DB()->sql_nextid();
-
- //bt
- if ($this->attachment_extension_list[$i] === TORRENT_EXT && !defined('TORRENT_ATTACH_ID')) {
- define('TORRENT_ATTACH_ID', $attach_id);
- }
- //bt end
-
- $sql_ary = array(
- 'attach_id' => (int) $attach_id,
- 'post_id' => (int) $post_id,
- 'user_id_1' => (int) $user_id_1,
- );
-
- $sql = 'INSERT INTO ' . BB_ATTACHMENTS . ' ' . attach_mod_sql_build_array('INSERT', $sql_ary);
-
- if (!(DB()->sql_query($sql))) {
- bb_die('Could not store Attachment.
Your ' . $message_type . ' has been stored');
- }
- }
- }
-
- return true;
- }
-
- if ($mode === 'last_attachment') {
- if ($this->post_attach && !isset($_POST['update_attachment'])) {
- // insert attachment into db, here the user submited it directly
- $sql_ary = array(
- 'physical_filename' => (string) basename($this->attach_filename),
- 'real_filename' => (string) basename($this->filename),
- 'comment' => (string) $this->file_comment,
- 'extension' => (string) strtolower($this->extension),
- 'mimetype' => (string) strtolower($this->type),
- 'filesize' => (int) $this->filesize,
- 'filetime' => (int) $this->filetime,
- 'thumbnail' => (int) $this->thumbnail
- );
-
- $sql = 'INSERT INTO ' . BB_ATTACHMENTS_DESC . ' ' . attach_mod_sql_build_array('INSERT', $sql_ary);
-
- // Inform the user that his post has been created, but nothing is attached
- if (!(DB()->sql_query($sql))) {
- bb_die('Could not store Attachment.
Your ' . $message_type . ' has been stored');
- }
-
- $attach_id = DB()->sql_nextid();
-
- $sql_ary = array(
- 'attach_id' => (int) $attach_id,
- 'post_id' => (int) $post_id,
- 'user_id_1' => (int) $user_id_1,
- );
-
- $sql = 'INSERT INTO ' . BB_ATTACHMENTS . ' ' . attach_mod_sql_build_array('INSERT', $sql_ary);
-
- if (!(DB()->sql_query($sql))) {
- bb_die('Could not store Attachment.
Your ' . $message_type . ' has been stored');
- }
- }
- }
- }
-
- /**
- * Attachment Mod entry switch/output (intern)
- * @private
- */
- public function display_attachment_bodies()
- {
- global $attach_config, $is_auth, $lang, $template, $upload_dir, $forum_id;
-
- // Choose what to display
- $value_add = $value_posted = 0;
-
- $this->add_attachment_body = 1;
- $this->posted_attachments_body = 1;
-
- $s_hidden = '';
- $s_hidden .= '';
-
- $template->assign_vars(array(
- 'ADD_ATTACH_HIDDEN_FIELDS' => $s_hidden,
- ));
-
- $attachments = array();
-
- if ($this->attachment_list) {
- $hidden = '';
- for ($i = 0, $iMax = count($this->attachment_list); $i < $iMax; $i++) {
- $hidden .= '';
- $hidden .= '';
- $hidden .= '';
- $hidden .= '';
- $hidden .= '';
- $hidden .= '';
- $hidden .= '';
- $hidden .= '';
-
- if (!$this->posted_attachments_body || !$this->attachment_list) {
- $hidden .= '';
- }
- }
- $template->assign_var('POSTED_ATTACHMENTS_HIDDEN_FIELDS', $hidden);
- }
-
- if ($this->add_attachment_body) {
- $template->assign_vars(array(
- 'TPL_ADD_ATTACHMENT' => true,
- 'FILE_COMMENT' => htmlspecialchars($this->file_comment),
- 'FILESIZE' => $attach_config['max_filesize'],
- 'FILENAME' => htmlspecialchars($this->filename),
- 'S_FORM_ENCTYPE' => 'enctype="multipart/form-data"',
- ));
- }
-
- if ($this->posted_attachments_body && $this->attachment_list) {
- $template->assign_vars(array(
- 'TPL_POSTED_ATTACHMENTS' => true,
- ));
-
- for ($i = 0, $iMax = count($this->attachment_list); $i < $iMax; $i++) {
- if (@$this->attachment_id_list[$i] == 0) {
- $download_link = $upload_dir . '/' . basename($this->attachment_list[$i]);
- } else {
- $download_link = BB_ROOT . DOWNLOAD_URL . $this->attachment_id_list[$i];
- }
-
- $template->assign_block_vars('attach_row', array(
- 'FILE_NAME' => @htmlspecialchars($this->attachment_filename_list[$i]),
- 'ATTACH_FILENAME' => @$this->attachment_list[$i],
- 'FILE_COMMENT' => @htmlspecialchars($this->attachment_comment_list[$i]),
- 'ATTACH_ID' => @$this->attachment_id_list[$i],
- 'U_VIEW_ATTACHMENT' => $download_link,
- ));
-
- // Thumbnail there ? And is the User Admin or Mod ? Then present the 'Delete Thumbnail' Button
- if ((int) $this->attachment_thumbnail_list[$i] === 1 && ((isset($is_auth['auth_mod']) && $is_auth['auth_mod']) || IS_ADMIN)) {
- $template->assign_block_vars('attach_row.switch_thumbnail', array());
- }
-
- if (@$this->attachment_id_list[$i]) {
- $template->assign_block_vars('attach_row.switch_update_attachment', array());
- }
- }
- }
-
- $template->assign_var('ATTACHBOX');
- }
-
- /**
- * Upload an Attachment to Filespace (intern)
- */
- public function upload_attachment()
- {
- global $error, $error_msg, $lang, $attach_config, $userdata, $upload_dir, $forum_id;
-
- $this->post_attach = (bool) $this->filename;
-
- if ($this->post_attach) {
- $r_file = trim(basename($this->filename));
- $file = $_FILES['fileupload']['tmp_name'];
- $this->type = $_FILES['fileupload']['type'];
-
- if (isset($_FILES['fileupload']['size']) && $_FILES['fileupload']['size'] == 0) {
- bb_die('Tried to upload empty file');
- }
-
- $this->type = strtolower($this->type);
- $this->extension = strtolower(get_extension($this->filename));
-
- $this->filesize = @filesize($file);
- $this->filesize = (int) $this->filesize;
-
- $sql = 'SELECT g.allow_group, g.max_filesize, g.cat_id, g.forum_permissions
- FROM ' . BB_EXTENSION_GROUPS . ' g, ' . BB_EXTENSIONS . " e
- WHERE g.group_id = e.group_id
- AND e.extension = '" . attach_mod_sql_escape($this->extension) . "'
- LIMIT 1";
-
- if (!($result = DB()->sql_query($sql))) {
- bb_die('Could not query extensions');
- }
-
- $row = DB()->sql_fetchrow($result);
- DB()->sql_freeresult($result);
-
- $allowed_filesize = $row['max_filesize'] ?: $attach_config['max_filesize'];
- $cat_id = (int) $row['cat_id'];
- $auth_cache = trim($row['forum_permissions']);
-
- // check Filename
- if (preg_match("#[\\/:*?\"<>|]#i", $this->filename)) {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= sprintf($lang['INVALID_FILENAME'], htmlspecialchars($this->filename));
- }
-
- // check php upload-size
- if (!$error && $file === 'none') {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $ini_val = 'ini_get';
-
- $max_size = @$ini_val('upload_max_filesize');
-
- if (empty($max_size)) {
- $error_msg .= $lang['ATTACHMENT_PHP_SIZE_NA'];
- } else {
- $error_msg .= sprintf($lang['ATTACHMENT_PHP_SIZE_OVERRUN'], $max_size);
- }
- }
-
- // Check Extension
- if (!$error && (int) $row['allow_group'] == 0) {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= sprintf($lang['DISALLOWED_EXTENSION'], htmlspecialchars($this->extension));
- }
-
- // Check Forum Permissions
- if (!$error && !IS_ADMIN && !is_forum_authed($auth_cache, $forum_id) && trim($auth_cache)) {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= sprintf($lang['DISALLOWED_EXTENSION_WITHIN_FORUM'], htmlspecialchars($this->extension));
- }
-
- //bt
- // Check if user can post torrent
- global $post_data;
-
- if (!$error && $this->extension === TORRENT_EXT && !$post_data['first_post']) {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= $lang['ALLOWED_ONLY_1ST_POST_ATTACH'];
- }
- //bt end
-
- // Upload File
-
- $this->thumbnail = 0;
-
- if (!$error) {
- //
- // Prepare Values
- $this->filetime = TIMENOW;
-
- $this->filename = $r_file;
-
- // physical filename
- //$this->attach_filename = strtolower($this->filename);
- $this->attach_filename = $this->filename;
-
- //bt
- if (FILENAME_CRYPTIC) {
- $this->attach_filename = make_rand_str(FILENAME_CRYPTIC_LENGTH);
- } else { // original
- $this->attach_filename = html_entity_decode(trim(stripslashes($this->attach_filename)));
- $this->attach_filename = delete_extension($this->attach_filename);
- $this->attach_filename = str_replace(array(' ', '-'), '_', $this->attach_filename);
- $this->attach_filename = str_replace('__', '_', $this->attach_filename);
- $this->attach_filename = str_replace(array(',', '.', '!', '?', 'ь', 'Ь', 'ц', 'Ц', 'д', 'Д', ';', ':', '@', "'", '"', '&'), array('', '', '', '', 'ue', 'ue', 'oe', 'oe', 'ae', 'ae', '', '', '', '', '', 'and'), $this->attach_filename);
- $this->attach_filename = str_replace(array('$', 'Я', '>', '<', '§', '%', '=', '/', '(', ')', '#', '*', '+', "\\", '{', '}', '[', ']'), array('dollar', 'ss', 'greater', 'lower', 'paragraph', 'percent', 'equal', '', '', '', '', '', '', '', '', '', '', ''), $this->attach_filename);
- // Remove non-latin characters
- $this->attach_filename = preg_replace('#([\xC2\xC3])([\x80-\xBF])#', 'chr(ord(\'$1\')<<6&0xC0|ord(\'$2\')&0x3F)', $this->attach_filename);
- $this->attach_filename = rawurlencode($this->attach_filename);
- $this->attach_filename = preg_replace("/(%[0-9A-F]{1,2})/i", '', $this->attach_filename);
- $this->attach_filename = trim($this->attach_filename);
- }
- $this->attach_filename = str_replace(array('&', '&', ' '), '_', $this->attach_filename);
- $this->attach_filename = str_replace('php', '_php_', $this->attach_filename);
- $this->attach_filename = substr(trim($this->attach_filename), 0, FILENAME_MAX_LENGTH);
-
- for ($i = 0, $max_try = 5; $i <= $max_try; $i++) {
- $fn_prefix = make_rand_str(FILENAME_PREFIX_LENGTH) . '_';
- $new_physical_filename = clean_filename($fn_prefix . $this->attach_filename);
-
- if (!physical_filename_already_stored($new_physical_filename)) {
- break;
- }
- if ($i === $max_try) {
- bb_die('Could not create filename for attachment');
- }
-
- $this->attach_filename = $new_physical_filename;
- }
-
-
- // Do we have to create a thumbnail ?
- if ($cat_id == IMAGE_CAT && (int) $attach_config['img_create_thumbnail']) {
- $this->thumbnail = 1;
- }
- }
-
- if ($error) {
- $this->post_attach = false;
- return;
- }
-
- // Upload Attachment
- if (!$error) {
- // Descide the Upload method
- $ini_val = 'ini_get';
-
- if (@$ini_val('open_basedir')) {
- $upload_mode = 'move';
- } elseif (@$ini_val('safe_mode')) {
- $upload_mode = 'move';
- } else {
- $upload_mode = 'copy';
- }
-
- // Ok, upload the Attachment
- if (!$error) {
- $this->move_uploaded_attachment($upload_mode, $file);
- }
- }
-
- // Now, check filesize parameters
- if (!$error) {
- if (!$this->filesize) {
- $this->filesize = (int) @filesize($upload_dir . '/' . $this->attach_filename);
- }
- }
-
- // Check Image Size, if it's an image
- if (!$error && !IS_ADMIN && $cat_id === IMAGE_CAT) {
- list($width, $height) = image_getdimension($upload_dir . '/' . $this->attach_filename);
-
- if ($width && $height && (int) $attach_config['img_max_width'] && (int) $attach_config['img_max_height']) {
- if ($width > (int) $attach_config['img_max_width'] || $height > (int) $attach_config['img_max_height']) {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= sprintf($lang['ERROR_IMAGESIZE'], (int) $attach_config['img_max_width'], (int) $attach_config['img_max_height']);
- }
- }
- }
-
- // check Filesize
- if (!$error && $allowed_filesize && $this->filesize > $allowed_filesize && !(IS_ADMIN || IS_MOD || IS_GROUP_MEMBER)) {
- $allowed_filesize = humn_size($allowed_filesize);
-
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= sprintf($lang['ATTACHMENT_TOO_BIG'], $allowed_filesize);
- }
-
- // Check our complete quota
- if ($attach_config['attachment_quota']) {
- $sql = 'SELECT sum(filesize) as total FROM ' . BB_ATTACHMENTS_DESC;
-
- if (!($result = DB()->sql_query($sql))) {
- bb_die('Could not query total filesize #1');
- }
-
- $row = DB()->sql_fetchrow($result);
- DB()->sql_freeresult($result);
-
- $total_filesize = $row['total'];
-
- if (($total_filesize + $this->filesize) > $attach_config['attachment_quota']) {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= $lang['ATTACH_QUOTA_REACHED'];
- }
- }
-
- $this->get_quota_limits($userdata);
-
- // Check our user quota
- if ($attach_config['upload_filesize_limit']) {
- $sql = 'SELECT attach_id
- FROM ' . BB_ATTACHMENTS . '
- WHERE user_id_1 = ' . (int) $userdata['user_id'] . '
- GROUP BY attach_id';
-
- if (!($result = DB()->sql_query($sql))) {
- bb_die('Could not query attachments');
- }
-
- $attach_ids = DB()->sql_fetchrowset($result);
- $num_attach_ids = DB()->num_rows($result);
- DB()->sql_freeresult($result);
-
- $attach_id = array();
-
- for ($i = 0; $i < $num_attach_ids; $i++) {
- $attach_id[] = (int) $attach_ids[$i]['attach_id'];
- }
-
- if ($num_attach_ids > 0) {
- // Now get the total filesize
- $sql = 'SELECT sum(filesize) as total
- FROM ' . BB_ATTACHMENTS_DESC . '
- WHERE attach_id IN (' . implode(', ', $attach_id) . ')';
-
- if (!($result = DB()->sql_query($sql))) {
- bb_die('Could not query total filesize #2');
- }
-
- $row = DB()->sql_fetchrow($result);
- DB()->sql_freeresult($result);
- $total_filesize = $row['total'];
- } else {
- $total_filesize = 0;
- }
-
- if (($total_filesize + $this->filesize) > $attach_config['upload_filesize_limit']) {
- $upload_filesize_limit = $attach_config['upload_filesize_limit'];
- $size_lang = ($upload_filesize_limit >= 1048576) ? $lang['MB'] : (($upload_filesize_limit >= 1024) ? $lang['KB'] : $lang['BYTES']);
-
- if ($upload_filesize_limit >= 1048576) {
- $upload_filesize_limit = round($upload_filesize_limit / 1048576 * 100) / 100;
- } elseif ($upload_filesize_limit >= 1024) {
- $upload_filesize_limit = round($upload_filesize_limit / 1024 * 100) / 100;
- }
-
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= sprintf($lang['USER_UPLOAD_QUOTA_REACHED'], $upload_filesize_limit, $size_lang);
- }
- }
-
- if ($error) {
- unlink_attach($this->attach_filename);
- unlink_attach($this->attach_filename, MODE_THUMBNAIL);
- $this->post_attach = false;
- }
- }
- }
-
- // Copy the temporary attachment to the right location (copy, move_uploaded_file)
- public function move_uploaded_attachment($upload_mode, $file)
- {
- global $error, $error_msg, $lang, $upload_dir;
-
- if (!is_uploaded_file($file)) {
- bb_die('Unable to upload file. The given source has not been uploaded');
- }
-
- switch ($upload_mode) {
- case 'copy':
-
- if (!@copy($file, $upload_dir . '/' . basename($this->attach_filename))) {
- if (!@move_uploaded_file($file, $upload_dir . '/' . basename($this->attach_filename))) {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= sprintf($lang['GENERAL_UPLOAD_ERROR'], './' . $upload_dir . '/' . $this->attach_filename);
- return;
- }
- }
- @chmod($upload_dir . '/' . basename($this->attach_filename), 0666);
-
- break;
-
- case 'move':
-
- if (!@move_uploaded_file($file, $upload_dir . '/' . basename($this->attach_filename))) {
- if (!@copy($file, $upload_dir . '/' . basename($this->attach_filename))) {
- $error = true;
- if (!empty($error_msg)) {
- $error_msg .= '
';
- }
- $error_msg .= sprintf($lang['GENERAL_UPLOAD_ERROR'], './' . $upload_dir . '/' . $this->attach_filename);
- return;
- }
- }
- @chmod($upload_dir . '/' . $this->attach_filename, 0666);
-
- break;
- }
-
- if (!$error && $this->thumbnail === 1) {
- $source = $upload_dir . '/' . basename($this->attach_filename);
- $dest_file = amod_realpath($upload_dir);
- $dest_file .= '/' . THUMB_DIR . '/t_' . basename($this->attach_filename);
-
- if (!create_thumbnail($source, $dest_file, $this->type)) {
- if (!$file || !create_thumbnail($file, $dest_file, $this->type)) {
- $this->thumbnail = 0;
- }
- }
- }
- }
-}
-
-/**
- * @package attachment_mod
- * Attachment posting
- */
-class attach_posting extends attach_parent
-{
- /**
- * Constructor
- */
- public function __construct()
- {
- parent::__construct();
- $this->page = 0;
- }
-
- /**
- * Insert an Attachment into a Post (this is the second function called from posting.php)
- */
- 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();
- }
-}
-
/**
* Entry Point
*/
@@ -1187,6 +40,6 @@ function execute_posting_attachment_handling()
{
global $attachment_mod;
- $attachment_mod['posting'] = new attach_posting();
+ $attachment_mod['posting'] = new TorrentPier\Legacy\AttachPosting();
$attachment_mod['posting']->posting_attachment_mod();
}
diff --git a/library/config.php b/library/config.php
index 20207bb23..d4e3a3870 100644
--- a/library/config.php
+++ b/library/config.php
@@ -285,7 +285,6 @@ 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');
diff --git a/library/includes/bbcode.php b/library/includes/bbcode.php
index 3f3fcafc7..99e62851f 100644
--- a/library/includes/bbcode.php
+++ b/library/includes/bbcode.php
@@ -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
- */
- 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' => '',
- '#\[\*=(\d+)\]#isu' => '- ',
- '#\[pre\](.*?)\[/pre\]#isu' => '
$1
',
- '#\[name=([a-zA-Z0-9_]+?)\]#isu' => '',
- '#\[url=\#([a-zA-Z0-9_]+?)\](.*?)\[/url\]#isu' => '$2',
- '#\[color=([\#0-9a-zA-Z]+)\]#isu' => '',
- '#\[size=([1-2]?[0-9])\]#isu' => '',
- '#\[align=(left|right|center|justify)\]#isu' => '',
- '#\[font="([\w\- \']+)"\]#isu' => '',
- "#\[img\]($img_exp)\[/img\]#isu" => $tpl['img'],
- "#\[img=(left|right|center)\]($img_exp)\[/img\]\s*#isu" => $tpl['img_aligned'],
- "#\[email\]($email_exp)\[/email\]#isu" => '$1',
- "#\[qpost=([0-9]*)\]#isu" => '$1',
- );
-
- $this->str = array(
- '[quote]' => $tpl['quote_open'],
- '[/quote]' => $tpl['quote_close'],
- '[spoiler]' => $tpl['spoiler_open'],
- '[/spoiler]' => $tpl['spoiler_close'],
- '[list]' => '',
- '[*]' => '- ',
- '[/list]' => '
',
- '[/color]' => '',
- '[/size]' => '',
- '[/align]' => '',
- '[/font]' => '',
- '[tab]' => ' ',
- '[br]' => "\n\n",
- '[hr]' => $tpl['hr'],
- '[b]' => '',
- '[/b]' => '',
- '[u]' => '',
- '[/u]' => '',
- '[i]' => '',
- '[/i]' => '',
- '[s]' => '',
- '[/s]' => '',
- '[del]' => '',
- '[/del]' => '',
- '[clear]' => '
',
- );
-
- $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(' ', ' ', $code);
- $code = str_replace(' ', ' ', $code);
- $code = str_replace("\t", ' ', $code);
- $code = str_replace(array('[', ']', ':', ')'), array('[', ']', ':', ')'), $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 = "$url_name";
- } else {
- $link = "$url_name";
- }
-
- 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('[', ']', ':', ')', '"'), $tilte);
- // еще раз htmlspecialchars, т.к. при извлечении из title происходит обратное преобразование
- $tilte = htmlspecialchars($tilte, ENT_QUOTES);
- return $m[1] . $tilte . $m[4];
- }
-
- /**
- * make_clickable
- */
- public function make_clickable($text)
- {
- $url_regexp = "#
- (? $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 = "$name";
- } else {
- $link = "$name";
- }
-
- 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,}#', '
', $text);
- $text = str_replace("\n", '
', $text);
- return $text;
- }
-
- /**
- * tidy
- */
- public function tidy($text)
- {
- $text = tidy_repair_string($text, $this->tidy_cfg, 'utf8');
- return $text;
- }
-}
+/**
+ * @deprecated bb_code
+ * Dirty class removed from here since 2.1.6
+ * To add new bbcodes see at src/Legacy/BBCode.php
+ */
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, '$0', $text);
- $this->del_text_hl = '' . $text_dbg . '
';
- }
- $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);
}
diff --git a/library/includes/cron/jobs/sitemap.php b/library/includes/cron/jobs/sitemap.php
index b45a559bc..72c972331 100644
--- a/library/includes/cron/jobs/sitemap.php
+++ b/library/includes/cron/jobs/sitemap.php
@@ -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")) {
diff --git a/library/includes/functions.php b/library/includes/functions.php
index e4b6bd942..3dca6b3a2 100644
--- a/library/includes/functions.php
+++ b/library/includes/functions.php
@@ -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\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\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\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>$k<$ul>";
- $this->_array2html_rec($v, $ul, $li);
- $this->out .= "$ul>$li>";
- } else {
- $this->out .= "<$li>$v$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) ? '' . $title . '' : $title;
- $id = ($id) ? " id=\"$id\" " : '';
- $checked = ($checked) ? HTML_CHECKED : '';
- $disabled = ($disabled) ? HTML_DISABLED : '';
-
- return '';
- }
-
-# function build_option ($opt_name, $opt_val, $selected = null, $max_length = false)
-# {
-# return "\t\t\n";
-# }
-
-# function build_optgroup ($label, $contents, $max_length = false)
-# {
-# return "\t\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('[', ']', '<', '>', '''), $dirname);
+}
diff --git a/library/includes/init_bb.php b/library/includes/init_bb.php
index 43a086c25..5d4fd9061 100644
--- a/library/includes/init_bb.php
+++ b/library/includes/init_bb.php
@@ -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'));
diff --git a/library/includes/sessions.php b/library/includes/sessions.php
index bc3943b29..7d4f8fe97 100644
--- a/library/includes/sessions.php
+++ b/library/includes/sessions.php
@@ -30,713 +30,18 @@ if (!defined('BB_ROOT')) {
define('ONLY_NEW_POSTS', 1);
define('ONLY_NEW_TOPICS', 2);
-class user_common
-{
- /**
- * 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 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;
- }
- }
-}
+/**
+ * @deprecated user_common
+ * Dirty class removed from here since 2.1.6
+ * To add new opt see at src/Legacy/Common/User.php
+ */
//
// userdata cache
//
function ignore_cached_userdata()
{
- return (defined('IN_PM')) ? true : false;
+ return defined('IN_PM') ? true : false;
}
function cache_get_userdata($id)
diff --git a/library/includes/template.php b/library/includes/template.php
index d7dc15839..4d1540874 100644
--- a/library/includes/template.php
+++ b/library/includes/template.php
@@ -54,1026 +54,3 @@ define('XS_TAG_ELSE', 6);
define('XS_TAG_ELSEIF', 7);
define('XS_TAG_ENDIF', 8);
define('XS_TAG_BEGINELSE', 11);
-
-class template
-{
- public $classname = "Template";
-
- // variable that holds all the data we'll be substituting into
- // the compiled templates.
- // ...
- // This will end up being a multi-dimensional array like this:
- // $this->_tpldata[block.][iteration#][child.][iteration#][child2.][iteration#][variablename] == value
- // if it's a root-level variable, it'll be like this:
- // $this->vars[varname] == value or $this->_tpldata['.'][0][varname] == value
- // array "vars" is added for easier access to data
- public $_tpldata = array('.' => array(0 => array()));
- public $vars;
-
- // Hash of filenames for each template handle.
- public $files = array();
- public $files_cache = array(); // array of cache files that exists
- public $files_cache2 = array(); // array of cache files (exists or not exists)
-
- // Root template directory.
- public $root = '';
-
- // Cache directory
- public $cachedir = CACHE_DIR . '/';
-
- // Template root directory
- public $tpldir = '';
-
- // Default template directory.
- // If file for default template isn't found file from this template is used.
- public $tpldef = 'default';
-
- // this will hash handle names to the compiled code for that handle.
- public $compiled_code = array();
-
- // This will hold the uncompiled code for that handle.
- public $uncompiled_code = array();
-
- // Cache settings
- public $use_cache = 1;
- public $cache_writable = 1;
-
- // Auto-compile setting
- public $auto_compile = 1;
-
- // Current template name
- public $tpl = '';
- public $cur_tpl = '';
-
- // List of replacements. tpl files in this list will be replaced with other tpl files
- // according to configuration in xs.cfg
- public $replace = array();
-
- // counter for include
- public $include_count = 0;
-
- // extension tpl-cache files
- public $cached_tpl_ext = 'php';
-
- // eXtreme Styles variables
- public $xs_started = 0;
- public $xs_version = 8; // number version. internal. do not change.
- public $xs_versiontxt = '2.3.1'; // text version
-
- // These handles will be parsed if pparse() is executed.
- // Can be used to automatically include header/footer if there is any content.
- public $preparse = '';
- public $postparse = '';
-
- // subtemplates mod detection
- public $subtemplates = false;
-
- // style configuration
- public $style_config = array();
-
- public $lang = array();
-
- /**
- * Constructor. Installs XS mod on first run or updates it and sets the root dir.
- */
- public function __construct($root = '.')
- {
- global $bb_cfg, $lang;
-
- // setting pointer "vars"
- $this->vars = &$this->_tpldata['.'][0];
- // load configuration
- $this->tpldir = TEMPLATES_DIR;
- $this->root = $root;
- $this->tpl = basename($root);
- $this->lang =& $lang;
- $this->use_cache = $bb_cfg['xs_use_cache'];
- }
-
- /**
- * Destroys this template object. Should be called when you're done with it, in order
- * to clear out the template data so you can load/parse a new template set.
- */
- public function destroy()
- {
- $this->_tpldata = array('.' => array(0 => array()));
- $this->vars = &$this->_tpldata['.'][0];
- $this->xs_started = 0;
- }
-
- /**
- * Generates a full path+filename for the given filename, which can either
- * be an absolute name, or a name relative to the rootdir for this Template
- * object.
- */
- public function make_filename($filename, $xs_include = false)
- {
- // Check replacements list
- if (!$xs_include && isset($this->replace[$filename])) {
- $filename = $this->replace[$filename];
- }
- // Check if it's an absolute or relative path.
- if (($filename[0] !== '/') && ($filename[1] !== ':')) {
- return $this->root . '/' . $filename;
- } else {
- return $filename;
- }
- }
-
- /**
- * Converts template filename to cache filename.
- * Returns empty string if non-cachable (for tpl files outside of root dir).
- * $filename should be absolute filename
- */
- public function make_filename_cache($filename)
- {
- $filename = clean_filename(str_replace(TEMPLATES_DIR, '', $filename));
-
- return $this->cachedir . XS_TPL_PREFIX . $filename . '.' . $this->cached_tpl_ext;
- }
-
- /**
- * Sets the template filenames for handles. $filename_array
- * should be a hash of handle => filename pairs.
- */
- public function set_filenames($filenames)
- {
- foreach ($filenames as $handle => $filename) {
- $this->set_filename($handle, $filename);
- }
- }
-
- /**
- * Assigns template filename for handle.
- */
- public function set_filename($handle, $filename, $xs_include = false, $quiet = false)
- {
- $can_cache = $this->use_cache;
- $this->files[$handle] = $this->make_filename($filename, $xs_include);
- $this->files_cache[$handle] = '';
- $this->files_cache2[$handle] = '';
- // checking if we have valid filename
- if (!$this->files[$handle]) {
- if ($xs_include || $quiet) {
- return false;
- } else {
- die("Template->make_filename(): Error - invalid template $filename");
- }
- }
- // creating cache filename
- if ($can_cache) {
- $this->files_cache2[$handle] = $this->make_filename_cache($this->files[$handle]);
- if (@file_exists($this->files_cache2[$handle])) {
- $this->files_cache[$handle] = $this->files_cache2[$handle];
- }
- }
- // checking if tpl and/or php file exists
- if (empty($this->files_cache[$handle]) && !@file_exists($this->files[$handle])) {
- if ($quiet) {
- return false;
- }
- die('Template->make_filename(): Error - template file not found:
' . hide_bb_path($this->files[$handle]));
- }
- // checking if we should recompile cache
- if (!empty($this->files_cache[$handle])) {
- $cache_time = @filemtime($this->files_cache[$handle]);
- if (@filemtime($this->files[$handle]) > $cache_time) {
- // file was changed. don't use cache file (will be recompled if configuration allowes it)
- $this->files_cache[$handle] = '';
- }
- }
- return true;
- }
-
- /**
- * includes file or executes code
- */
- public function execute($filename, $code, $handle)
- {
- $this->cur_tpl = $filename;
-
- global $lang, $bb_cfg, $user, $tr_cfg;
-
- $L =& $lang;
- $V =& $this->vars;
-
- if ($filename) {
- include($filename);
- } else {
- eval($code);
- }
- }
-
- /**
- * Load the file for the handle, compile the file,
- * and run the compiled code. This will print out
- * the results of executing the template.
- */
- public function pparse($handle)
- {
- // parsing header if there is one
- if ($this->preparse || $this->postparse) {
- $preparse = $this->preparse;
- $postparse = $this->postparse;
- $this->preparse = '';
- $this->postparse = '';
- if ($preparse) {
- $this->pparse($preparse);
- }
- if ($postparse) {
- $str = $handle;
- $handle = $postparse;
- $this->pparse($str);
- }
- }
- // checking if handle exists
- if (empty($this->files[$handle]) && empty($this->files_cache[$handle])) {
- die("Template->loadfile(): No files found for handle $handle");
- }
- $this->xs_startup();
- $force_recompile = empty($this->uncompiled_code[$handle]) ? false : true;
- // checking if php file exists.
- if (!empty($this->files_cache[$handle]) && !$force_recompile) {
- // php file exists - running it instead of tpl
- $this->execute($this->files_cache[$handle], '', $handle);
- return true;
- }
- if (!$this->loadfile($handle)) {
- die("Template->pparse(): Could not load template file for handle $handle");
- }
- // actually compile the template now.
- if (empty($this->compiled_code[$handle])) {
- // Actually compile the code now.
- if (!empty($this->files_cache2[$handle]) && empty($this->files_cache[$handle]) && !$force_recompile) {
- $this->compiled_code[$handle] = $this->compile2($this->uncompiled_code[$handle], $handle, $this->files_cache2[$handle]);
- } else {
- $this->compiled_code[$handle] = $this->compile2($this->uncompiled_code[$handle], '', '');
- }
- }
- // Run the compiled code.
- if (empty($this->files_cache[$handle]) || $force_recompile) {
- $this->execute('', $this->compiled_code[$handle], $handle);
- } else {
- $this->execute($this->files_cache[$handle], '', $handle);
- }
- return true;
- }
-
- /**
- * Precompile file
- */
- public function precompile($template, $filename)
- {
- global $precompile_num;
- if (empty($precompile_num)) {
- $precompile_num = 0;
- }
- $precompile_num++;
- $handle = 'precompile_' . $precompile_num;
- // save old configuration
- $root = $this->root;
- $tpl_name = $this->tpl;
- $old_config = $this->use_cache;
- $old_autosave = $this->auto_compile;
- // set temporary configuration
- $this->root = $this->tpldir . $template;
- $this->tpl = $template;
- $this->use_cache = 1;
- $this->auto_compile = 1;
- // set filename
- $res = $this->set_filename($handle, $filename, true, true);
- if (!$res || !$this->files_cache2[$handle]) {
- $this->root = $root;
- $this->tpl = $tpl_name;
- $this->use_cache = $old_config;
- $this->auto_compile = $old_autosave;
- return false;
- }
- $this->files_cache[$handle] = '';
- // load template
- $res = $this->loadfile($handle);
- if (!$res || empty($this->uncompiled_code[$handle])) {
- $this->root = $root;
- $this->tpl = $tpl_name;
- $this->use_cache = $old_config;
- $this->auto_compile = $old_autosave;
- return false;
- }
- // compile the code
- $this->compile2($this->uncompiled_code[$handle], $handle, $this->files_cache2[$handle]);
- // restore confirugation
- $this->root = $root;
- $this->tpl = $tpl_name;
- $this->use_cache = $old_config;
- $this->auto_compile = $old_autosave;
- return true;
- }
-
- /**
- * Inserts the uncompiled code for $handle as the
- * value of $varname in the root-level. This can be used
- * to effectively include a template in the middle of another
- * template.
- * Note that all desired assignments to the variables in $handle should be done
- * BEFORE calling this function.
- */
- public function assign_var_from_handle($varname, $handle)
- {
- ob_start();
- $res = $this->pparse($handle);
- $this->vars[$varname] = ob_get_contents();
- ob_end_clean();
- return $res;
- }
-
- /**
- * Block-level variable assignment. Adds a new block iteration with the given
- * variable assignments. Note that this should only be called once per block
- * iteration.
- */
- public function assign_block_vars($blockname, $vararray)
- {
- if (false !== strpos($blockname, '.')) {
- // Nested block.
- $blocks = explode('.', $blockname);
- $blockcount = count($blocks) - 1;
-
- $str = &$this->_tpldata;
- for ($i = 0; $i < $blockcount; $i++) {
- $str = &$str[$blocks[$i] . '.'];
- $str = &$str[count($str) - 1];
- }
- // Now we add the block that we're actually assigning to.
- // We're adding a new iteration to this block with the given
- // variable assignments.
- $str[$blocks[$blockcount] . '.'][] = $vararray;
- } else {
- // Top-level block.
- // Add a new iteration to this block with the variable assignments
- // we were given.
- $this->_tpldata[$blockname . '.'][] = $vararray;
- }
-
- return true;
- }
-
- /**
- * Root-level variable assignment. Adds to current assignments, overriding
- * any existing variable assignment with the same name.
- */
- public function assign_vars($vararray)
- {
- foreach ($vararray as $key => $val) {
- $this->vars[$key] = $val;
- }
- }
-
- /**
- * Root-level variable assignment. Adds to current assignments, overriding
- * any existing variable assignment with the same name.
- */
- public function assign_var($varname, $varval = true)
- {
- $this->vars[$varname] = $varval;
- }
-
- /**
- * TODO: Add type check [??]
- * Root-level. Adds to current assignments, appends
- * to any existing variable assignment with the same name.
- */
- public function append_vars($vararray)
- {
- foreach ($vararray as $key => $val) {
- $this->vars[$key] = !isset($this->vars[$key]) ? $val : $this->vars[$key] . $val;
- }
- }
-
- /**
- * If not already done, load the file for the given handle and populate
- * the uncompiled_code[] hash with its code. Do not compile.
- */
- public function loadfile($handle)
- {
- // If cached file exists do nothing - it will be included via include()
- if (!empty($this->files_cache[$handle])) {
- return true;
- }
-
- // If the file for this handle is already loaded and compiled, do nothing.
- if (!empty($this->uncompiled_code[$handle])) {
- return true;
- }
-
- // If we don't have a file assigned to this handle, die.
- if (empty($this->files[$handle])) {
- die("Template->loadfile(): No file specified for handle $handle");
- }
-
- $filename = $this->files[$handle];
-
- if (($str = @file_get_contents($filename)) === false) {
- die("Template->loadfile(): File $filename for handle $handle is empty");
- }
-
- $this->uncompiled_code[$handle] = $str;
-
- return true;
- }
-
- /**
- * Generates a reference to the given variable inside the given (possibly nested)
- * block namespace. This is a string of the form:
- * ' . $this->_tpldata['parent.'][$_parent_i]['$child1.'][$_child1_i]['$child2.'][$_child2_i]...['varname'] . '
- * It's ready to be inserted into an "echo" line in one of the templates.
- * NOTE: expects a trailing "." on the namespace.
- */
- public function generate_block_varref($namespace, $varname)
- {
- // Strip the trailing period.
- $namespace = substr($namespace, 0, strlen($namespace) - 1);
-
- // Get a reference to the data block for this namespace.
- $varref = $this->generate_block_data_ref($namespace, true);
- // Prepend the necessary code to stick this in an echo line.
-
- // Append the variable reference.
- $varref .= "['$varname']";
-
- $varref = "";
-
- return $varref;
- }
-
- /**
- * Generates a reference to the array of data values for the given
- * (possibly nested) block namespace. This is a string of the form:
- * $this->_tpldata['parent.'][$_parent_i]['$child1.'][$_child1_i]['$child2.'][$_child2_i]...['$childN.']
- *
- * If $include_last_iterator is true, then [$_childN_i] will be appended to the form shown above.
- * NOTE: does not expect a trailing "." on the blockname.
- */
- public function generate_block_data_ref($blockname, $include_last_iterator)
- {
- // Get an array of the blocks involved.
- $blocks = explode('.', $blockname);
- $blockcount = count($blocks) - 1;
- if ($include_last_iterator) {
- return '$' . $blocks[$blockcount] . '_item';
- } else {
- return '$' . $blocks[$blockcount - 1] . '_item[\'' . $blocks[$blockcount] . '.\']';
- }
- }
-
- public function compile_code($filename, $code)
- {
- // $filename - file to load code from. used if $code is empty
- // $code - tpl code
-
- // load code from file
- if (!$code && !empty($filename)) {
- $code = file_get_contents($filename);
- }
-
- // Replace tags
- $search = array('', '');
- $replace = array('<' . '?php ', ' ?' . '>');
- $code = str_replace($search, $replace, $code);
-
- // Break it up into lines and put " -->" back.
- $code_lines = explode(' -->', $code);
- $count = count($code_lines);
- for ($i = 0; $i < ($count - 1); $i++) {
- $code_lines[$i] .= ' -->';
- }
-
- $block_nesting_level = 0;
- $block_names = array();
- $block_names[0] = ".";
- $block_items = array();
- $count_if = 0;
-
- // prepare array for compiled code
- $compiled = array();
-
- // array of switches
- $sw = array();
-
- // replace all short php tags
- $new_code = array();
- $line_count = count($code_lines);
- for ($i = 0; $i < $line_count; $i++) {
- $line = $code_lines[$i];
- $pos = strpos($line, '');
- if ($pos === false) {
- $new_code[] = $line;
- continue;
- }
- if (substr($line, $pos, 5) === '';
- $code_lines[$i] = substr($line, $pos + 2);
- $i--;
- }
- $code_lines = $new_code;
-
- // main loop
- $line_count = count($code_lines);
- for ($i = 0; $i < $line_count; $i++) {
- $line = $code_lines[$i];
- // reset keyword type
- $keyword_type = XS_TAG_NONE;
- // check if we have valid keyword in current line
- $pos1 = strpos($line, '', $pos1);
- if ($pos2 !== false) {
- // find end of keyword in comment
- $pos3 = strpos($line, ' ', $pos1 + 5);
- if ($pos3 !== false && $pos3 <= $pos2) {
- $keyword = substr($line, $pos1 + 5, $pos3 - $pos1 - 5);
- // check keyword against list of supported keywords. case-sensitive
- if ($keyword === 'BEGIN') {
- $keyword_type = XS_TAG_BEGIN;
- } elseif ($keyword === 'END') {
- $keyword_type = XS_TAG_END;
- } elseif ($keyword === 'INCLUDE') {
- $keyword_type = XS_TAG_INCLUDE;
- } elseif ($keyword === 'IF') {
- $keyword_type = XS_TAG_IF;
- } elseif ($keyword === 'ELSE') {
- $keyword_type = XS_TAG_ELSE;
- } elseif ($keyword === 'ELSEIF') {
- $keyword_type = XS_TAG_ELSEIF;
- } elseif ($keyword === 'ENDIF') {
- $keyword_type = XS_TAG_ENDIF;
- } elseif ($keyword === 'BEGINELSE') {
- $keyword_type = XS_TAG_BEGINELSE;
- }
- }
- }
- if (!$keyword_type) {
- // not valid keyword. process the rest of line
- $compiled[] = $this->_compile_text(substr($line, 0, $pos1 + 4));
- $code_lines[$i] = substr($line, $pos1 + 4);
- $i--;
- continue;
- }
- // remove code before keyword
- if ($pos1 > 0) {
- $compiled[] = $this->_compile_text(substr($line, 0, $pos1));
- }
- // remove keyword
- $keyword_str = substr($line, $pos1, $pos2 - $pos1 + 4);
- $params_str = $pos2 == $pos3 ? '' : substr($line, $pos3 + 1, $pos2 - $pos3 - 1);
- $code_lines[$i] = substr($line, $pos2 + 4);
- $i--;
- // Check keywords
-
- /*
- *
- */
- if ($keyword_type == XS_TAG_BEGIN) {
- $params = explode(' ', $params_str);
- $num_params = count($params);
- // get variable name
- if ($num_params == 1) {
- $var = $params[0];
- } elseif ($num_params == 2) {
- if ($params[0] === '') {
- $var = $params[1];
- } elseif ($params[1] === '') {
- $var = $params[0];
- } else {
- // invalid tag
- $compiled[] = $keyword_str;
- continue;
- }
- } else {
- // invalid tag
- $compiled[] = $keyword_str;
- continue;
- }
- // adding code
- $block_nesting_level++;
- $block_names[$block_nesting_level] = $var;
- if (isset($block_items[$var])) {
- $block_items[$var]++;
- } else {
- $block_items[$var] = 1;
- }
- if ($block_nesting_level < 2) {
- // Block is not nested.
- $line = '<' . "?php\n\n";
- $line .= '$' . $var . '_count = ( isset($this->_tpldata[\'' . $var . '.\']) ) ? sizeof($this->_tpldata[\'' . $var . '.\']) : 0;';
- $line .= "\n" . 'for ($' . $var . '_i = 0; $' . $var . '_i < $' . $var . '_count; $' . $var . '_i++)';
- $line .= "\n" . '{' . "\n";
- $line .= ' $' . $var . '_item = &$this->_tpldata[\'' . $var . '.\'][$' . $var . '_i];' . "\n";
- $line .= " \${$var}_item['S_ROW_COUNT'] = \${$var}_i;\n";
- $line .= " \${$var}_item['S_NUM_ROWS'] = \${$var}_count;\n";
- $line .= "\n?" . ">";
- } else {
- // This block is nested.
- // Generate a namespace string for this block.
- $namespace = implode('.', $block_names);
- // strip leading period from root level..
- $namespace = substr($namespace, 2);
- // Get a reference to the data array for this block that depends on the
- // current indices of all parent blocks.
- $varref = $this->generate_block_data_ref($namespace, false);
- // Create the for loop code to iterate over this block.
- $line = '<' . "?php\n\n";
- $line .= '$' . $var . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
- $line .= "\n" . 'for ($' . $var . '_i = 0; $' . $var . '_i < $' . $var . '_count; $' . $var . '_i++)';
- $line .= "\n" . '{' . "\n";
- $line .= ' $' . $var . '_item = &' . $varref . '[$' . $var . '_i];' . "\n";
- $line .= " \${$var}_item['S_ROW_COUNT'] = \${$var}_i;\n";
- $line .= " \${$var}_item['S_NUM_ROWS'] = \${$var}_count;\n";
- $line .= "\n?" . ">";
- }
- $compiled[] = $line;
- continue;
- }
- /*
- *
- */
- if ($keyword_type == XS_TAG_END) {
- $params = explode(' ', $params_str);
- $num_params = count($params);
- if ($num_params == 1) {
- $var = $params[0];
- } elseif ($num_params == 2 && $params[0] === '') {
- $var = $params[1];
- } elseif ($num_params == 2 && $params[1] === '') {
- $var = $params[0];
- } else {
- $compiled[] = $keyword_str;
- continue;
- }
- // We have the end of a block.
- $line = '<' . "?php\n\n";
- $line .= '} // END ' . $var . "\n\n";
- $line .= 'if(isset($' . $var . '_item)) { unset($' . $var . '_item); } ';
- $line .= "\n\n?" . ">";
- if (isset($block_items[$var])) {
- $block_items[$var]--;
- } else {
- $block_items[$var] = -1;
- }
- unset($block_names[$block_nesting_level]);
- $block_nesting_level--;
- $compiled[] = $line;
- continue;
- }
- /*
- *
- */
- if ($keyword_type == XS_TAG_BEGINELSE) {
- if ($block_nesting_level) {
- $var = $block_names[$block_nesting_level];
- $compiled[] = '<' . '?php } if(!$' . $var . '_count) { ?' . '>';
- } else {
- $compiled[] = $keyword_str;
- continue;
- }
- }
- /*
- *
- */
- if ($keyword_type == XS_TAG_INCLUDE) {
- $params = explode(' ', $params_str);
- $num_params = count($params);
- if ($num_params != 1) {
- $compiled[] = $keyword_str;
- continue;
- }
- $line = '<' . '?php ';
- $filehash = md5($params_str . $this->include_count . TIMENOW);
- $line .= ' $this->set_filename(\'xs_include_' . $filehash . '\', \'' . $params_str . '\', true); ';
- $line .= ' $this->pparse(\'xs_include_' . $filehash . '\'); ';
- $line .= ' ?' . '>';
- $this->include_count++;
- $compiled[] = $line;
- continue;
- }
- /*
- *
- */
- if ($keyword_type == XS_TAG_IF || $keyword_type == XS_TAG_ELSEIF) {
- if (!$count_if) {
- $keyword_type = XS_TAG_IF;
- }
- $str = $this->compile_tag_if($params_str, $keyword_type != XS_TAG_IF);
- if ($str) {
- $compiled[] = '';
- if ($keyword_type == XS_TAG_IF) {
- $count_if++;
- }
- } else {
- $compiled[] = $keyword_str;
- }
- continue;
- }
- /*
- *
- */
- if ($keyword_type == XS_TAG_ELSE && $count_if > 0) {
- $compiled[] = '';
- continue;
- }
- /*
- *
- */
- if ($keyword_type == XS_TAG_ENDIF && $count_if > 0) {
- $compiled[] = '';
- $count_if--;
- continue;
- }
- }
-
- // bring it back into a single string.
- $code_header = '';
- $code_footer = '';
-
- return $code_header . implode('', $compiled) . $code_footer;
- }
-
- /*
- * Compile code between tags
- */
- public function _compile_text($code)
- {
- if (strlen($code) < 3) {
- return $code;
- }
- // change template varrefs into PHP varrefs
- // This one will handle varrefs WITH namespaces
- $varrefs = array();
- preg_match_all('#\{(([a-z0-9\-_]+?\.)+)([a-z0-9\-_]+?)\}#is', $code, $varrefs);
- $varcount = count($varrefs[1]);
- $search = array();
- $replace = array();
- for ($i = 0; $i < $varcount; $i++) {
- $namespace = $varrefs[1][$i];
- $varname = $varrefs[3][$i];
- $new = $this->generate_block_varref($namespace, $varname);
- $search[] = $varrefs[0][$i];
- $replace[] = $new;
- }
- if (count($search) > 0) {
- $code = str_replace($search, $replace, $code);
- }
- // This will handle the remaining root-level varrefs
- $code = preg_replace('#\{(L_([a-z0-9\-_]+?))\}#i', '', $code);
- $code = preg_replace('#\{(\$[a-z_][a-z0-9_$\->\'\"\.\[\]]*?)\}#i', '', $code);
- $code = preg_replace('#\{(\#([a-z_][a-z0-9_]*?))\}#i', '', $code);
- $code = preg_replace('#\{([a-z0-9\-_]+?)\}#i', '', $code);
- return $code;
- }
-
- //
- // Compile IF tags - much of this is from Smarty with
- // some adaptions for our block level methods
- //
- public function compile_tag_if($tag_args, $elseif)
- {
- /* Tokenize args for 'if' tag. */
- preg_match_all('/(?:
- "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" |
- \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' |
- [(),] |
- [^\s(),]+)/x', $tag_args, $match);
-
- $tokens = $match[0];
- $tokens_cnt = count($tokens);
- $is_arg_stack = array();
-
- for ($i = 0; $i < $tokens_cnt; $i++) {
- $token = &$tokens[$i];
-
- switch ($token) {
- case 'eq':
- $token = '==';
- break;
-
- case 'ne':
- case 'neq':
- $token = '!=';
- break;
-
- case 'lt':
- $token = '<';
- break;
-
- case 'le':
- case 'lte':
- $token = '<=';
- break;
-
- case 'gt':
- $token = '>';
- break;
-
- case 'ge':
- case 'gte':
- $token = '>=';
- break;
-
- case 'and':
- $token = '&&';
- break;
-
- case 'or':
- $token = '||';
- break;
-
- case 'not':
- $token = '!';
- break;
-
- case 'mod':
- $token = '%';
- break;
-
- case '(':
- $is_arg_stack[] = $i;
- break;
-
- case 'is':
- $is_arg_start = ($tokens[$i - 1] == ')') ? array_pop($is_arg_stack) : $i - 1;
- $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
-
- $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i + 1));
-
- array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
-
- $i = $is_arg_start;
- break;
-
- default:
- $pattern = '@^
- ( # 1
- ([a-z0-9\-_]+?\.)+? # 2 block tpl vars (VAR1.VAR2.) but without last
- )?
- ( # 3
- ([a-z_][a-z0-9\-_]*)? # 4 single tpl var or last block var (last in block)
- (\$[a-z_][a-z0-9_$\->\'\"\.\[\]]*)? # 5 php var
- (\#([a-z_][a-z0-9_]*))? # 7 php const
- )
- $@ix';
- if (preg_match($pattern, $token, $m)) {
- if (!empty($m[1])) {
- $token = $this->generate_block_data_ref(substr($m[1], 0, -1), true) . "['{$m[4]}']";
- } elseif (!empty($m[4])) {
- $token = ($tokens_cnt == 1) ? "!empty(\$V['{$m[4]}'])" : "\$V['{$m[4]}']";
- } elseif (!empty($m[5])) {
- $token = ($tokens_cnt == 1) ? "!empty({$m[5]})" : "{$m[5]}";
- } elseif (!empty($m[7])) {
- $token = ($tokens_cnt == 1) ? "defined('{$m[7]}') && {$m[7]}" : "{$m[7]}";
- }
- }
- break;
- }
- }
-
- if ($elseif) {
- $code = '} elseif (' . implode(' ', $tokens) . ') {';
- } else {
- $code = 'if (' . implode(' ', $tokens) . ') {';
- }
-
- return $code;
- }
-
- // This is from Smarty
- public function _parse_is_expr($is_arg, $tokens)
- {
- $expr_end = 0;
- $negate_expr = false;
-
- if (($first_token = array_shift($tokens)) == 'not') {
- $negate_expr = true;
- $expr_type = array_shift($tokens);
- } else {
- $expr_type = $first_token;
- }
-
- switch ($expr_type) {
- case 'even':
- if (@$tokens[$expr_end] == 'by') {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "!(($is_arg / $expr_arg) % $expr_arg)";
- } else {
- $expr = "!($is_arg % 2)";
- }
- break;
-
- case 'odd':
- if (@$tokens[$expr_end] == 'by') {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "(($is_arg / $expr_arg) % $expr_arg)";
- } else {
- $expr = "($is_arg % 2)";
- }
- break;
-
- case 'div':
- if (@$tokens[$expr_end] == 'by') {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "!($is_arg % $expr_arg)";
- }
- break;
-
- default:
- break;
- }
-
- if ($negate_expr) {
- $expr = "!($expr)";
- }
-
- array_splice($tokens, 0, $expr_end, $expr);
-
- return $tokens;
- }
-
- /**
- * Compiles code and writes to cache if needed
- */
- public function compile2($code, $handle, $cache_file)
- {
- $code = $this->compile_code('', $code, XS_USE_ISSET);
- if ($cache_file && !empty($this->use_cache) && !empty($this->auto_compile)) {
- $res = $this->write_cache($cache_file, $code);
- if ($handle && $res) {
- $this->files_cache[$handle] = $cache_file;
- }
- }
- $code = '?' . '>' . $code . '<' . "?php\n";
- return $code;
- }
-
- /**
- * Compiles the given string of code, and returns
- * the result in a string.
- * If "do_not_echo" is true, the returned code will not be directly
- * executable, but can be used as part of a variable assignment
- * for use in assign_code_from_handle().
- * This function isn't used and kept only for compatibility with original template.php
- */
- public function compile($code, $do_not_echo = false, $retvar = '')
- {
- $code = ' ?' . '>' . $this->compile_code('', $code, true) . '<' . "?php \n";
- if ($do_not_echo) {
- $code = "ob_start();\n" . $code . "\n\${$retvar} = ob_get_contents();\nob_end_clean();\n";
- }
- return $code;
- }
-
- /**
- * Write cache to disk
- */
- public function write_cache($filename, $code)
- {
- file_write($code, $filename, false, true, true);
- }
-
- public function xs_startup()
- {
- global $bb_cfg;
-
- if (empty($this->xs_started)) { // adding predefined variables
- $this->xs_started = 1;
- // adding language variable (eg: "english" or "german")
- // can be used to make truly multi-lingual templates
- $this->vars['LANG'] = isset($this->vars['LANG']) ? $this->vars['LANG'] : $bb_cfg['default_lang'];
- // adding current template
- $tpl = $this->root . '/';
- if (substr($tpl, 0, 2) === './') {
- $tpl = substr($tpl, 2, strlen($tpl));
- }
- $this->vars['TEMPLATE'] = isset($this->vars['TEMPLATE']) ? $this->vars['TEMPLATE'] : $tpl;
- $this->vars['TEMPLATE_NAME'] = isset($this->vars['TEMPLATE_NAME']) ? $this->vars['TEMPLATE_NAME'] : $this->tpl;
- }
- }
-
- public function lang_error($var)
- {
- trigger_error(basename($this->cur_tpl) . " : undefined language variable {L_{$var}}", E_USER_WARNING);
- return "Undefined: {L_{$var}}";
- }
-}
diff --git a/library/includes/ucp/register.php b/library/includes/ucp/register.php
index 65735375d..767cd51aa 100644
--- a/library/includes/ucp/register.php
+++ b/library/includes/ucp/register.php
@@ -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;
diff --git a/poll.php b/poll.php
index 79652d1de..06a396635 100644
--- a/poll.php
+++ b/poll.php
@@ -38,7 +38,7 @@ $return_topic_url .= !empty($_POST['start']) ? "&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");
- }
-}
diff --git a/src/Legacy/Ajax.php b/src/Legacy/Ajax.php
new file mode 100644
index 000000000..61d923202
--- /dev/null
+++ b/src/Legacy/Ajax.php
@@ -0,0 +1,370 @@
+ ['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';
+ }
+}
diff --git a/src/Legacy/Attach.php b/src/Legacy/Attach.php
new file mode 100644
index 000000000..bb0f26e2d
--- /dev/null
+++ b/src/Legacy/Attach.php
@@ -0,0 +1,1094 @@
+add_attachment_body = get_var('add_attachment_body', 0);
+ $this->posted_attachments_body = get_var('posted_attachments_body', 0);
+
+ $this->file_comment = get_var('filecomment', '');
+ $this->attachment_id_list = get_var('attach_id_list', [0]);
+ $this->attachment_comment_list = get_var('comment_list', ['']);
+ $this->attachment_filesize_list = get_var('filesize_list', [0]);
+ $this->attachment_filetime_list = get_var('filetime_list', [0]);
+ $this->attachment_filename_list = get_var('filename_list', ['']);
+ $this->attachment_extension_list = get_var('extension_list', ['']);
+ $this->attachment_mimetype_list = get_var('mimetype_list', ['']);
+
+ $this->filename = (isset($_FILES['fileupload']) && isset($_FILES['fileupload']['name']) && $_FILES['fileupload']['name'] !== 'none') ? trim(stripslashes($_FILES['fileupload']['name'])) : '';
+
+ $this->attachment_list = get_var('attachment_list', ['']);
+ $this->attachment_thumbnail_list = get_var('attach_thumbnail_list', [0]);
+ }
+
+ /**
+ * Get Quota Limits
+ * @param array $userdata_quota
+ * @param int $user_id
+ */
+ public function get_quota_limits(array $userdata_quota, $user_id = 0)
+ {
+ global $attach_config;
+
+ $priority = 'user;group';
+
+ if (IS_ADMIN) {
+ $attach_config['pm_filesize_limit'] = 0; // Unlimited
+ $attach_config['upload_filesize_limit'] = 0; // Unlimited
+ return;
+ }
+
+ $quota_type = QUOTA_UPLOAD_LIMIT;
+ $limit_type = 'upload_filesize_limit';
+ $default = 'attachment_quota';
+
+ if (!$user_id) {
+ $user_id = (int)$userdata_quota['user_id'];
+ }
+
+ $priority = explode(';', $priority);
+ $found = false;
+
+ foreach ($priority as $item) {
+ if ($item === 'group' && !$found) {
+ // Get Group Quota, if we find one, we have our quota
+ $sql = 'SELECT u.group_id
+ FROM ' . BB_USER_GROUP . ' u, ' . BB_GROUPS . ' g
+ WHERE g.group_single_user = 0
+ AND u.user_pending = 0
+ AND u.group_id = g.group_id
+ AND u.user_id = ' . (int)$user_id;
+
+ if (!($result = DB()->sql_query($sql))) {
+ bb_die('Could not get user group');
+ }
+
+ $rows = DB()->sql_fetchrowset($result);
+ DB()->sql_freeresult($result);
+
+ if ($rows) {
+ $group_id = [];
+
+ foreach ($rows as $row) {
+ $group_id[] = (int)$row['group_id'];
+ }
+
+ $sql = 'SELECT l.quota_limit
+ FROM ' . BB_QUOTA . ' q, ' . BB_QUOTA_LIMITS . ' l
+ WHERE q.group_id IN (' . implode(', ', $group_id) . ')
+ AND q.group_id <> 0
+ AND q.quota_type = ' . (int)$quota_type . '
+ AND q.quota_limit_id = l.quota_limit_id
+ ORDER BY l.quota_limit DESC
+ LIMIT 1';
+
+ if (!($result = DB()->sql_query($sql))) {
+ bb_die('Could not get group quota');
+ }
+
+ if (DB()->num_rows($result)) {
+ $row = DB()->sql_fetchrow($result);
+ $attach_config[$limit_type] = $row['quota_limit'];
+ $found = true;
+ }
+ DB()->sql_freeresult($result);
+ }
+ }
+
+ if ($item === 'user' && !$found) {
+ // Get User Quota, if the user is not in a group or the group has no quotas
+ $sql = 'SELECT l.quota_limit
+ FROM ' . BB_QUOTA . ' q, ' . BB_QUOTA_LIMITS . ' l
+ WHERE q.user_id = ' . $user_id . '
+ AND q.user_id <> 0
+ AND q.quota_type = ' . $quota_type . '
+ AND q.quota_limit_id = l.quota_limit_id
+ LIMIT 1';
+
+ if (!($result = DB()->sql_query($sql))) {
+ bb_die('Could not get user quota');
+ }
+
+ if (DB()->num_rows($result)) {
+ $row = DB()->sql_fetchrow($result);
+ $attach_config[$limit_type] = $row['quota_limit'];
+ $found = true;
+ }
+ DB()->sql_freeresult($result);
+ }
+ }
+
+ if (!$found) {
+ // Set Default Quota Limit
+ $quota_id = (int)((int)$quota_type === QUOTA_UPLOAD_LIMIT) ? $attach_config['default_upload_quota'] : $attach_config['default_pm_quota'];
+
+ if (!$quota_id) {
+ $attach_config[$limit_type] = $attach_config[$default];
+ } else {
+ $sql = 'SELECT quota_limit
+ FROM ' . BB_QUOTA_LIMITS . '
+ WHERE quota_limit_id = ' . (int)$quota_id . '
+ LIMIT 1';
+
+ if (!($result = DB()->sql_query($sql))) {
+ bb_die('Could not get default quota limit');
+ }
+
+ if (DB()->num_rows($result) > 0) {
+ $row = DB()->sql_fetchrow($result);
+ $attach_config[$limit_type] = $row['quota_limit'];
+ } else {
+ $attach_config[$limit_type] = $attach_config[$default];
+ }
+ DB()->sql_freeresult($result);
+ }
+ }
+
+ // Never exceed the complete Attachment Upload Quota
+ if ($quota_type === QUOTA_UPLOAD_LIMIT) {
+ if ($attach_config[$limit_type] > $attach_config[$default]) {
+ $attach_config[$limit_type] = $attach_config[$default];
+ }
+ }
+ }
+
+ /**
+ * Handle all modes... (intern)
+ * @private
+ */
+ public function handle_attachments($mode)
+ {
+ global $is_auth, $attach_config, $refresh, $post_id, $submit, $preview, $error, $error_msg, $lang;
+
+ //
+ // ok, what shall we do ;)
+ //
+
+ if (IS_ADMIN) {
+ $max_attachments = ADMIN_MAX_ATTACHMENTS;
+ } else {
+ $max_attachments = (int)$attach_config['max_attachments'];
+ }
+
+ $sql_id = 'post_id';
+
+ // nothing, if the user is not authorized or attachment mod disabled
+ if ($attach_config['disable_mod'] || !$is_auth['auth_attachments']) {
+ return false;
+ }
+
+ // Init Vars
+ $attachments = [];
+
+ if (!$refresh) {
+ $add = isset($_POST['add_attachment']);
+ $delete = isset($_POST['del_attachment']);
+ $edit = isset($_POST['edit_comment']);
+ $update_attachment = isset($_POST['update_attachment']);
+ $del_thumbnail = isset($_POST['del_thumbnail']);
+
+ $add_attachment_box = !empty($_POST['add_attachment_box']);
+ $posted_attachments_box = !empty($_POST['posted_attachments_box']);
+
+ $refresh = $add || $delete || $edit || $del_thumbnail || $update_attachment || $add_attachment_box || $posted_attachments_box;
+ }
+
+ // Get Attachments
+ $attachments = get_attachments_from_post($post_id);
+
+ $auth = $is_auth['auth_edit'] || $is_auth['auth_mod'];
+
+ if (!$submit && $mode === 'editpost' && $auth) {
+ if (!$refresh && !$preview && !$error) {
+ foreach ($attachments as $attachment) {
+ $this->attachment_list[] = $attachment['physical_filename'];
+ $this->attachment_comment_list[] = $attachment['comment'];
+ $this->attachment_filename_list[] = $attachment['real_filename'];
+ $this->attachment_extension_list[] = $attachment['extension'];
+ $this->attachment_mimetype_list[] = $attachment['mimetype'];
+ $this->attachment_filesize_list[] = $attachment['filesize'];
+ $this->attachment_filetime_list[] = $attachment['filetime'];
+ $this->attachment_id_list[] = $attachment['attach_id'];
+ $this->attachment_thumbnail_list[] = $attachment['thumbnail'];
+ }
+ }
+ }
+
+ $this->num_attachments = count($this->attachment_list);
+
+ if ($submit) {
+ if ($mode === 'newtopic' || $mode === 'reply' || $mode === 'editpost') {
+ if ($this->filename) {
+ if ($this->num_attachments < (int)$max_attachments) {
+ $this->upload_attachment();
+
+ if (!$error && $this->post_attach) {
+ array_unshift($this->attachment_list, $this->attach_filename);
+ array_unshift($this->attachment_comment_list, $this->file_comment);
+ array_unshift($this->attachment_filename_list, $this->filename);
+ array_unshift($this->attachment_extension_list, $this->extension);
+ array_unshift($this->attachment_mimetype_list, $this->type);
+ array_unshift($this->attachment_filesize_list, $this->filesize);
+ array_unshift($this->attachment_filetime_list, $this->filetime);
+ array_unshift($this->attachment_id_list, '0');
+ array_unshift($this->attachment_thumbnail_list, $this->thumbnail);
+
+ $this->file_comment = '';
+ $this->post_attach = false;
+ }
+ } else {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= sprintf($lang['TOO_MANY_ATTACHMENTS'], (int)$max_attachments);
+ }
+ }
+ }
+ }
+
+ if ($preview || $refresh || $error) {
+ $delete_attachment = isset($_POST['del_attachment']);
+ $delete_thumbnail = isset($_POST['del_thumbnail']);
+
+ $add_attachment = isset($_POST['add_attachment']);
+ $edit_attachment = isset($_POST['edit_comment']);
+ $update_attachment = isset($_POST['update_attachment']);
+
+ // Perform actions on temporary attachments
+ if ($delete_attachment || $delete_thumbnail) {
+ // store old values
+ $actual_id_list = get_var('attach_id_list', [0]);
+ $actual_comment_list = get_var('comment_list', ['']);
+ $actual_filename_list = get_var('filename_list', ['']);
+ $actual_extension_list = get_var('extension_list', ['']);
+ $actual_mimetype_list = get_var('mimetype_list', ['']);
+ $actual_filesize_list = get_var('filesize_list', [0]);
+ $actual_filetime_list = get_var('filetime_list', [0]);
+
+ $actual_list = get_var('attachment_list', ['']);
+ $actual_thumbnail_list = get_var('attach_thumbnail_list', [0]);
+
+ // clean values
+ $this->attachment_list = [];
+ $this->attachment_comment_list = [];
+ $this->attachment_filename_list = [];
+ $this->attachment_extension_list = [];
+ $this->attachment_mimetype_list = [];
+ $this->attachment_filesize_list = [];
+ $this->attachment_filetime_list = [];
+ $this->attachment_id_list = [];
+ $this->attachment_thumbnail_list = [];
+
+ // restore values :)
+ if (isset($_POST['attachment_list'])) {
+ for ($i = 0, $iMax = count($actual_list); $i < $iMax; $i++) {
+ $restore = false;
+ $del_thumb = false;
+
+ if ($delete_thumbnail) {
+ if (!isset($_POST['del_thumbnail'][$actual_list[$i]])) {
+ $restore = true;
+ } else {
+ $del_thumb = true;
+ }
+ }
+ if ($delete_attachment) {
+ if (!isset($_POST['del_attachment'][$actual_list[$i]])) {
+ $restore = true;
+ }
+ }
+
+ if ($restore) {
+ $this->attachment_list[] = $actual_list[$i];
+ $this->attachment_comment_list[] = $actual_comment_list[$i];
+ $this->attachment_filename_list[] = $actual_filename_list[$i];
+ $this->attachment_extension_list[] = $actual_extension_list[$i];
+ $this->attachment_mimetype_list[] = $actual_mimetype_list[$i];
+ $this->attachment_filesize_list[] = $actual_filesize_list[$i];
+ $this->attachment_filetime_list[] = $actual_filetime_list[$i];
+ $this->attachment_id_list[] = $actual_id_list[$i];
+ $this->attachment_thumbnail_list[] = $actual_thumbnail_list[$i];
+ } elseif (!$del_thumb) {
+ // delete selected attachment
+ if ($actual_id_list[$i] == '0') {
+ unlink_attach($actual_list[$i]);
+
+ if ($actual_thumbnail_list[$i] == 1) {
+ unlink_attach($actual_list[$i], MODE_THUMBNAIL);
+ }
+ } else {
+ delete_attachment($post_id, $actual_id_list[$i], $this->page);
+ }
+ } elseif ($del_thumb) {
+ // delete selected thumbnail
+ $this->attachment_list[] = $actual_list[$i];
+ $this->attachment_comment_list[] = $actual_comment_list[$i];
+ $this->attachment_filename_list[] = $actual_filename_list[$i];
+ $this->attachment_extension_list[] = $actual_extension_list[$i];
+ $this->attachment_mimetype_list[] = $actual_mimetype_list[$i];
+ $this->attachment_filesize_list[] = $actual_filesize_list[$i];
+ $this->attachment_filetime_list[] = $actual_filetime_list[$i];
+ $this->attachment_id_list[] = $actual_id_list[$i];
+ $this->attachment_thumbnail_list[] = 0;
+
+ if ($actual_id_list[$i] == 0) {
+ unlink_attach($actual_list[$i], MODE_THUMBNAIL);
+ } else {
+ $sql = 'UPDATE ' . BB_ATTACHMENTS_DESC . ' SET thumbnail = 0 WHERE attach_id = ' . (int)$actual_id_list[$i];
+
+ if (!(DB()->sql_query($sql))) {
+ bb_die('Unable to update ' . BB_ATTACHMENTS_DESC);
+ }
+ }
+ }
+ }
+ }
+ } elseif ($edit_attachment || $update_attachment || $add_attachment || $preview) {
+ if ($edit_attachment) {
+ $actual_comment_list = get_var('comment_list', ['']);
+
+ $this->attachment_comment_list = [];
+
+ for ($i = 0, $iMax = count($this->attachment_list); $i < $iMax; $i++) {
+ $this->attachment_comment_list[$i] = $actual_comment_list[$i];
+ }
+ }
+
+ if ($update_attachment) {
+ if (empty($this->filename)) {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= $lang['ERROR_EMPTY_ADD_ATTACHBOX'];
+ }
+
+ $this->upload_attachment();
+
+ if (!$error) {
+ $actual_id_list = get_var('attach_id_list', [0]);
+
+ $attachment_id = 0;
+ $actual_element = 0;
+
+ for ($i = 0, $iMax = count($actual_id_list); $i < $iMax; $i++) {
+ if (isset($_POST['update_attachment'][$actual_id_list[$i]])) {
+ $attachment_id = (int)$actual_id_list[$i];
+ $actual_element = $i;
+ }
+ }
+
+ // Get current informations to delete the Old Attachment
+ $sql = 'SELECT physical_filename, comment, thumbnail
+ FROM ' . BB_ATTACHMENTS_DESC . '
+ WHERE attach_id = ' . (int)$attachment_id;
+
+ if (!($result = DB()->sql_query($sql))) {
+ bb_die('Unable to select old attachment entry');
+ }
+
+ if (DB()->num_rows($result) != 1) {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= $lang['ERROR_MISSING_OLD_ENTRY'];
+ }
+
+ $row = DB()->sql_fetchrow($result);
+ DB()->sql_freeresult($result);
+
+ $comment = !trim($this->file_comment) ? trim($row['comment']) : trim($this->file_comment);
+
+ // Update Entry
+ $sql_ary = [
+ 'physical_filename' => (string)basename($this->attach_filename),
+ 'real_filename' => (string)basename($this->filename),
+ 'comment' => (string)$comment,
+ 'extension' => (string)strtolower($this->extension),
+ 'mimetype' => (string)strtolower($this->type),
+ 'filesize' => (int)$this->filesize,
+ 'filetime' => (int)$this->filetime,
+ 'thumbnail' => (int)$this->thumbnail
+ ];
+
+ $sql = 'UPDATE ' . BB_ATTACHMENTS_DESC . ' SET ' . attach_mod_sql_build_array('UPDATE', $sql_ary) . '
+ WHERE attach_id = ' . (int)$attachment_id;
+
+ if (!(DB()->sql_query($sql))) {
+ bb_die('Unable to update the attachment');
+ }
+
+ // Delete the Old Attachment
+ unlink_attach($row['physical_filename']);
+
+ if ((int)$row['thumbnail'] === 1) {
+ unlink_attach($row['physical_filename'], MODE_THUMBNAIL);
+ }
+
+ //bt
+ if ($this->attachment_extension_list[$actual_element] === TORRENT_EXT && $attachments[$actual_element]['tracker_status']) {
+ include INC_DIR . '/functions_torrent.php';
+ tracker_unregister($attachment_id);
+ }
+ //bt end
+
+ // Make sure it is displayed
+ $this->attachment_list[$actual_element] = $this->attach_filename;
+ $this->attachment_comment_list[$actual_element] = $comment;
+ $this->attachment_filename_list[$actual_element] = $this->filename;
+ $this->attachment_extension_list[$actual_element] = $this->extension;
+ $this->attachment_mimetype_list[$actual_element] = $this->type;
+ $this->attachment_filesize_list[$actual_element] = $this->filesize;
+ $this->attachment_filetime_list[$actual_element] = $this->filetime;
+ $this->attachment_id_list[$actual_element] = $actual_id_list[$actual_element];
+ $this->attachment_thumbnail_list[$actual_element] = $this->thumbnail;
+ $this->file_comment = '';
+ }
+ }
+
+ if (($add_attachment || $preview) && !empty($this->filename)) {
+ if ($this->num_attachments < (int)$max_attachments) {
+ $this->upload_attachment();
+
+ if (!$error) {
+ array_unshift($this->attachment_list, $this->attach_filename);
+ array_unshift($this->attachment_comment_list, $this->file_comment);
+ array_unshift($this->attachment_filename_list, $this->filename);
+ array_unshift($this->attachment_extension_list, $this->extension);
+ array_unshift($this->attachment_mimetype_list, $this->type);
+ array_unshift($this->attachment_filesize_list, $this->filesize);
+ array_unshift($this->attachment_filetime_list, $this->filetime);
+ array_unshift($this->attachment_id_list, '0');
+ array_unshift($this->attachment_thumbnail_list, $this->thumbnail);
+
+ $this->file_comment = '';
+ }
+ } else {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= sprintf($lang['TOO_MANY_ATTACHMENTS'], (int)$max_attachments);
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Basic Insert Attachment Handling for all Message Types
+ */
+ public function do_insert_attachment($mode, $message_type, $message_id)
+ {
+ global $upload_dir;
+
+ if ((int)$message_id < 0) {
+ return false;
+ }
+
+ global $post_info, $userdata;
+
+ $post_id = (int)$message_id;
+ $user_id_1 = (isset($post_info['poster_id'])) ? (int)$post_info['poster_id'] : 0;
+
+ if (!$user_id_1) {
+ $user_id_1 = (int)$userdata['user_id'];
+ }
+
+ if ($mode === 'attach_list') {
+ for ($i = 0, $iMax = count($this->attachment_list); $i < $iMax; $i++) {
+ if ($this->attachment_id_list[$i]) {
+ //bt
+ if ($this->attachment_extension_list[$i] === TORRENT_EXT && !defined('TORRENT_ATTACH_ID')) {
+ define('TORRENT_ATTACH_ID', $this->attachment_id_list[$i]);
+ }
+ //bt end
+
+ // update entry in db if attachment already stored in db and filespace
+ $sql = 'UPDATE ' . BB_ATTACHMENTS_DESC . "
+ SET comment = '" . @attach_mod_sql_escape($this->attachment_comment_list[$i]) . "'
+ WHERE attach_id = " . $this->attachment_id_list[$i];
+
+ if (!(DB()->sql_query($sql))) {
+ bb_die('Unable to update the file comment');
+ }
+ } else {
+ if (empty($this->attachment_mimetype_list[$i]) && $this->attachment_extension_list[$i] === TORRENT_EXT) {
+ $this->attachment_mimetype_list[$i] = 'application/x-bittorrent';
+ }
+
+ // insert attachment into db
+ $sql_ary = [
+ 'physical_filename' => (string)basename($this->attachment_list[$i]),
+ 'real_filename' => (string)basename($this->attachment_filename_list[$i]),
+ 'comment' => (string)@$this->attachment_comment_list[$i],
+ 'extension' => (string)strtolower($this->attachment_extension_list[$i]),
+ 'mimetype' => (string)strtolower($this->attachment_mimetype_list[$i]),
+ 'filesize' => (int)$this->attachment_filesize_list[$i],
+ 'filetime' => (int)$this->attachment_filetime_list[$i],
+ 'thumbnail' => (int)$this->attachment_thumbnail_list[$i]
+ ];
+
+ $sql = 'INSERT INTO ' . BB_ATTACHMENTS_DESC . ' ' . attach_mod_sql_build_array('INSERT', $sql_ary);
+
+ if (!(DB()->sql_query($sql))) {
+ bb_die('Could not store Attachment.
Your ' . $message_type . ' has been stored');
+ }
+
+ $attach_id = DB()->sql_nextid();
+
+ //bt
+ if ($this->attachment_extension_list[$i] === TORRENT_EXT && !defined('TORRENT_ATTACH_ID')) {
+ define('TORRENT_ATTACH_ID', $attach_id);
+ }
+ //bt end
+
+ $sql_ary = [
+ 'attach_id' => (int)$attach_id,
+ 'post_id' => (int)$post_id,
+ 'user_id_1' => (int)$user_id_1,
+ ];
+
+ $sql = 'INSERT INTO ' . BB_ATTACHMENTS . ' ' . attach_mod_sql_build_array('INSERT', $sql_ary);
+
+ if (!(DB()->sql_query($sql))) {
+ bb_die('Could not store Attachment.
Your ' . $message_type . ' has been stored');
+ }
+ }
+ }
+
+ return true;
+ }
+
+ if ($mode === 'last_attachment') {
+ if ($this->post_attach && !isset($_POST['update_attachment'])) {
+ // insert attachment into db, here the user submited it directly
+ $sql_ary = [
+ 'physical_filename' => (string)basename($this->attach_filename),
+ 'real_filename' => (string)basename($this->filename),
+ 'comment' => (string)$this->file_comment,
+ 'extension' => (string)strtolower($this->extension),
+ 'mimetype' => (string)strtolower($this->type),
+ 'filesize' => (int)$this->filesize,
+ 'filetime' => (int)$this->filetime,
+ 'thumbnail' => (int)$this->thumbnail
+ ];
+
+ $sql = 'INSERT INTO ' . BB_ATTACHMENTS_DESC . ' ' . attach_mod_sql_build_array('INSERT', $sql_ary);
+
+ // Inform the user that his post has been created, but nothing is attached
+ if (!(DB()->sql_query($sql))) {
+ bb_die('Could not store Attachment.
Your ' . $message_type . ' has been stored');
+ }
+
+ $attach_id = DB()->sql_nextid();
+
+ $sql_ary = [
+ 'attach_id' => (int)$attach_id,
+ 'post_id' => (int)$post_id,
+ 'user_id_1' => (int)$user_id_1,
+ ];
+
+ $sql = 'INSERT INTO ' . BB_ATTACHMENTS . ' ' . attach_mod_sql_build_array('INSERT', $sql_ary);
+
+ if (!(DB()->sql_query($sql))) {
+ bb_die('Could not store Attachment.
Your ' . $message_type . ' has been stored');
+ }
+ }
+ }
+ }
+
+ /**
+ * Attachment Mod entry switch/output (intern)
+ * @private
+ */
+ public function display_attachment_bodies()
+ {
+ global $attach_config, $is_auth, $lang, $template, $upload_dir, $forum_id;
+
+ // Choose what to display
+ $value_add = $value_posted = 0;
+
+ $this->add_attachment_body = 1;
+ $this->posted_attachments_body = 1;
+
+ $s_hidden = '';
+ $s_hidden .= '';
+
+ $template->assign_vars([
+ 'ADD_ATTACH_HIDDEN_FIELDS' => $s_hidden,
+ ]);
+
+ $attachments = [];
+
+ if ($this->attachment_list) {
+ $hidden = '';
+ for ($i = 0, $iMax = count($this->attachment_list); $i < $iMax; $i++) {
+ $hidden .= '';
+ $hidden .= '';
+ $hidden .= '';
+ $hidden .= '';
+ $hidden .= '';
+ $hidden .= '';
+ $hidden .= '';
+ $hidden .= '';
+
+ if (!$this->posted_attachments_body || !$this->attachment_list) {
+ $hidden .= '';
+ }
+ }
+ $template->assign_var('POSTED_ATTACHMENTS_HIDDEN_FIELDS', $hidden);
+ }
+
+ if ($this->add_attachment_body) {
+ $template->assign_vars([
+ 'TPL_ADD_ATTACHMENT' => true,
+ 'FILE_COMMENT' => htmlspecialchars($this->file_comment),
+ 'FILESIZE' => $attach_config['max_filesize'],
+ 'FILENAME' => htmlspecialchars($this->filename),
+ 'S_FORM_ENCTYPE' => 'enctype="multipart/form-data"',
+ ]);
+ }
+
+ if ($this->posted_attachments_body && $this->attachment_list) {
+ $template->assign_vars([
+ 'TPL_POSTED_ATTACHMENTS' => true,
+ ]);
+
+ for ($i = 0, $iMax = count($this->attachment_list); $i < $iMax; $i++) {
+ if (@$this->attachment_id_list[$i] == 0) {
+ $download_link = $upload_dir . '/' . basename($this->attachment_list[$i]);
+ } else {
+ $download_link = BB_ROOT . DOWNLOAD_URL . $this->attachment_id_list[$i];
+ }
+
+ $template->assign_block_vars('attach_row', [
+ 'FILE_NAME' => @htmlspecialchars($this->attachment_filename_list[$i]),
+ 'ATTACH_FILENAME' => @$this->attachment_list[$i],
+ 'FILE_COMMENT' => @htmlspecialchars($this->attachment_comment_list[$i]),
+ 'ATTACH_ID' => @$this->attachment_id_list[$i],
+ 'U_VIEW_ATTACHMENT' => $download_link,
+ ]);
+
+ // Thumbnail there ? And is the User Admin or Mod ? Then present the 'Delete Thumbnail' Button
+ if ((int)$this->attachment_thumbnail_list[$i] === 1 && ((isset($is_auth['auth_mod']) && $is_auth['auth_mod']) || IS_ADMIN)) {
+ $template->assign_block_vars('attach_row.switch_thumbnail', []);
+ }
+
+ if (@$this->attachment_id_list[$i]) {
+ $template->assign_block_vars('attach_row.switch_update_attachment', []);
+ }
+ }
+ }
+
+ $template->assign_var('ATTACHBOX');
+ }
+
+ /**
+ * Upload an Attachment to Filespace (intern)
+ */
+ public function upload_attachment()
+ {
+ global $error, $error_msg, $lang, $attach_config, $userdata, $upload_dir, $forum_id;
+
+ $this->post_attach = (bool)$this->filename;
+
+ if ($this->post_attach) {
+ $r_file = trim(basename($this->filename));
+ $file = $_FILES['fileupload']['tmp_name'];
+ $this->type = $_FILES['fileupload']['type'];
+
+ if (isset($_FILES['fileupload']['size']) && $_FILES['fileupload']['size'] == 0) {
+ bb_die('Tried to upload empty file');
+ }
+
+ $this->type = strtolower($this->type);
+ $this->extension = strtolower(get_extension($this->filename));
+
+ $this->filesize = @filesize($file);
+ $this->filesize = (int)$this->filesize;
+
+ $sql = 'SELECT g.allow_group, g.max_filesize, g.cat_id, g.forum_permissions
+ FROM ' . BB_EXTENSION_GROUPS . ' g, ' . BB_EXTENSIONS . " e
+ WHERE g.group_id = e.group_id
+ AND e.extension = '" . attach_mod_sql_escape($this->extension) . "'
+ LIMIT 1";
+
+ if (!($result = DB()->sql_query($sql))) {
+ bb_die('Could not query extensions');
+ }
+
+ $row = DB()->sql_fetchrow($result);
+ DB()->sql_freeresult($result);
+
+ $allowed_filesize = $row['max_filesize'] ?: $attach_config['max_filesize'];
+ $cat_id = (int)$row['cat_id'];
+ $auth_cache = trim($row['forum_permissions']);
+
+ // check Filename
+ if (preg_match("#[\\/:*?\"<>|]#i", $this->filename)) {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= sprintf($lang['INVALID_FILENAME'], htmlspecialchars($this->filename));
+ }
+
+ // check php upload-size
+ if (!$error && $file === 'none') {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $ini_val = 'ini_get';
+
+ $max_size = @$ini_val('upload_max_filesize');
+
+ if (empty($max_size)) {
+ $error_msg .= $lang['ATTACHMENT_PHP_SIZE_NA'];
+ } else {
+ $error_msg .= sprintf($lang['ATTACHMENT_PHP_SIZE_OVERRUN'], $max_size);
+ }
+ }
+
+ // Check Extension
+ if (!$error && (int)$row['allow_group'] == 0) {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= sprintf($lang['DISALLOWED_EXTENSION'], htmlspecialchars($this->extension));
+ }
+
+ // Check Forum Permissions
+ if (!$error && !IS_ADMIN && !is_forum_authed($auth_cache, $forum_id) && trim($auth_cache)) {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= sprintf($lang['DISALLOWED_EXTENSION_WITHIN_FORUM'], htmlspecialchars($this->extension));
+ }
+
+ //bt
+ // Check if user can post torrent
+ global $post_data;
+
+ if (!$error && $this->extension === TORRENT_EXT && !$post_data['first_post']) {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= $lang['ALLOWED_ONLY_1ST_POST_ATTACH'];
+ }
+ //bt end
+
+ // Upload File
+
+ $this->thumbnail = 0;
+
+ if (!$error) {
+ //
+ // Prepare Values
+ $this->filetime = TIMENOW;
+
+ $this->filename = $r_file;
+
+ // physical filename
+ //$this->attach_filename = strtolower($this->filename);
+ $this->attach_filename = $this->filename;
+
+ //bt
+ if (FILENAME_CRYPTIC) {
+ $this->attach_filename = make_rand_str(FILENAME_CRYPTIC_LENGTH);
+ } else { // original
+ $this->attach_filename = html_entity_decode(trim(stripslashes($this->attach_filename)));
+ $this->attach_filename = delete_extension($this->attach_filename);
+ $this->attach_filename = str_replace([' ', '-'], '_', $this->attach_filename);
+ $this->attach_filename = str_replace('__', '_', $this->attach_filename);
+ $this->attach_filename = str_replace([',', '.', '!', '?', 'ь', 'Ь', 'ц', 'Ц', 'д', 'Д', ';', ':', '@', "'", '"', '&'], ['', '', '', '', 'ue', 'ue', 'oe', 'oe', 'ae', 'ae', '', '', '', '', '', 'and'], $this->attach_filename);
+ $this->attach_filename = str_replace(['$', 'Я', '>', '<', '§', '%', '=', '/', '(', ')', '#', '*', '+', "\\", '{', '}', '[', ']'], ['dollar', 'ss', 'greater', 'lower', 'paragraph', 'percent', 'equal', '', '', '', '', '', '', '', '', '', '', ''], $this->attach_filename);
+ // Remove non-latin characters
+ $this->attach_filename = preg_replace('#([\xC2\xC3])([\x80-\xBF])#', 'chr(ord(\'$1\')<<6&0xC0|ord(\'$2\')&0x3F)', $this->attach_filename);
+ $this->attach_filename = rawurlencode($this->attach_filename);
+ $this->attach_filename = preg_replace("/(%[0-9A-F]{1,2})/i", '', $this->attach_filename);
+ $this->attach_filename = trim($this->attach_filename);
+ }
+ $this->attach_filename = str_replace(['&', '&', ' '], '_', $this->attach_filename);
+ $this->attach_filename = str_replace('php', '_php_', $this->attach_filename);
+ $this->attach_filename = substr(trim($this->attach_filename), 0, FILENAME_MAX_LENGTH);
+
+ for ($i = 0, $max_try = 5; $i <= $max_try; $i++) {
+ $fn_prefix = make_rand_str(FILENAME_PREFIX_LENGTH) . '_';
+ $new_physical_filename = clean_filename($fn_prefix . $this->attach_filename);
+
+ if (!physical_filename_already_stored($new_physical_filename)) {
+ break;
+ }
+ if ($i === $max_try) {
+ bb_die('Could not create filename for attachment');
+ }
+
+ $this->attach_filename = $new_physical_filename;
+ }
+
+
+ // Do we have to create a thumbnail ?
+ if ($cat_id == IMAGE_CAT && (int)$attach_config['img_create_thumbnail']) {
+ $this->thumbnail = 1;
+ }
+ }
+
+ if ($error) {
+ $this->post_attach = false;
+ return;
+ }
+
+ // Upload Attachment
+ if (!$error) {
+ // Descide the Upload method
+ $ini_val = 'ini_get';
+
+ if (@$ini_val('open_basedir')) {
+ $upload_mode = 'move';
+ } elseif (@$ini_val('safe_mode')) {
+ $upload_mode = 'move';
+ } else {
+ $upload_mode = 'copy';
+ }
+
+ // Ok, upload the Attachment
+ if (!$error) {
+ $this->move_uploaded_attachment($upload_mode, $file);
+ }
+ }
+
+ // Now, check filesize parameters
+ if (!$error) {
+ if (!$this->filesize) {
+ $this->filesize = (int)@filesize($upload_dir . '/' . $this->attach_filename);
+ }
+ }
+
+ // Check Image Size, if it's an image
+ if (!$error && !IS_ADMIN && $cat_id === IMAGE_CAT) {
+ list($width, $height) = image_getdimension($upload_dir . '/' . $this->attach_filename);
+
+ if ($width && $height && (int)$attach_config['img_max_width'] && (int)$attach_config['img_max_height']) {
+ if ($width > (int)$attach_config['img_max_width'] || $height > (int)$attach_config['img_max_height']) {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= sprintf($lang['ERROR_IMAGESIZE'], (int)$attach_config['img_max_width'], (int)$attach_config['img_max_height']);
+ }
+ }
+ }
+
+ // check Filesize
+ if (!$error && $allowed_filesize && $this->filesize > $allowed_filesize && !(IS_ADMIN || IS_MOD || IS_GROUP_MEMBER)) {
+ $allowed_filesize = humn_size($allowed_filesize);
+
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= sprintf($lang['ATTACHMENT_TOO_BIG'], $allowed_filesize);
+ }
+
+ // Check our complete quota
+ if ($attach_config['attachment_quota']) {
+ $sql = 'SELECT sum(filesize) as total FROM ' . BB_ATTACHMENTS_DESC;
+
+ if (!($result = DB()->sql_query($sql))) {
+ bb_die('Could not query total filesize #1');
+ }
+
+ $row = DB()->sql_fetchrow($result);
+ DB()->sql_freeresult($result);
+
+ $total_filesize = $row['total'];
+
+ if (($total_filesize + $this->filesize) > $attach_config['attachment_quota']) {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= $lang['ATTACH_QUOTA_REACHED'];
+ }
+ }
+
+ $this->get_quota_limits($userdata);
+
+ // Check our user quota
+ if ($attach_config['upload_filesize_limit']) {
+ $sql = 'SELECT attach_id
+ FROM ' . BB_ATTACHMENTS . '
+ WHERE user_id_1 = ' . (int)$userdata['user_id'] . '
+ GROUP BY attach_id';
+
+ if (!($result = DB()->sql_query($sql))) {
+ bb_die('Could not query attachments');
+ }
+
+ $attach_ids = DB()->sql_fetchrowset($result);
+ $num_attach_ids = DB()->num_rows($result);
+ DB()->sql_freeresult($result);
+
+ $attach_id = [];
+
+ for ($i = 0; $i < $num_attach_ids; $i++) {
+ $attach_id[] = (int)$attach_ids[$i]['attach_id'];
+ }
+
+ if ($num_attach_ids > 0) {
+ // Now get the total filesize
+ $sql = 'SELECT sum(filesize) as total
+ FROM ' . BB_ATTACHMENTS_DESC . '
+ WHERE attach_id IN (' . implode(', ', $attach_id) . ')';
+
+ if (!($result = DB()->sql_query($sql))) {
+ bb_die('Could not query total filesize #2');
+ }
+
+ $row = DB()->sql_fetchrow($result);
+ DB()->sql_freeresult($result);
+ $total_filesize = $row['total'];
+ } else {
+ $total_filesize = 0;
+ }
+
+ if (($total_filesize + $this->filesize) > $attach_config['upload_filesize_limit']) {
+ $upload_filesize_limit = $attach_config['upload_filesize_limit'];
+ $size_lang = ($upload_filesize_limit >= 1048576) ? $lang['MB'] : (($upload_filesize_limit >= 1024) ? $lang['KB'] : $lang['BYTES']);
+
+ if ($upload_filesize_limit >= 1048576) {
+ $upload_filesize_limit = round($upload_filesize_limit / 1048576 * 100) / 100;
+ } elseif ($upload_filesize_limit >= 1024) {
+ $upload_filesize_limit = round($upload_filesize_limit / 1024 * 100) / 100;
+ }
+
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= sprintf($lang['USER_UPLOAD_QUOTA_REACHED'], $upload_filesize_limit, $size_lang);
+ }
+ }
+
+ if ($error) {
+ unlink_attach($this->attach_filename);
+ unlink_attach($this->attach_filename, MODE_THUMBNAIL);
+ $this->post_attach = false;
+ }
+ }
+ }
+
+ // Copy the temporary attachment to the right location (copy, move_uploaded_file)
+ public function move_uploaded_attachment($upload_mode, $file)
+ {
+ global $error, $error_msg, $lang, $upload_dir;
+
+ if (!is_uploaded_file($file)) {
+ bb_die('Unable to upload file. The given source has not been uploaded');
+ }
+
+ switch ($upload_mode) {
+ case 'copy':
+
+ if (!@copy($file, $upload_dir . '/' . basename($this->attach_filename))) {
+ if (!@move_uploaded_file($file, $upload_dir . '/' . basename($this->attach_filename))) {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= sprintf($lang['GENERAL_UPLOAD_ERROR'], './' . $upload_dir . '/' . $this->attach_filename);
+ return;
+ }
+ }
+ @chmod($upload_dir . '/' . basename($this->attach_filename), 0666);
+
+ break;
+
+ case 'move':
+
+ if (!@move_uploaded_file($file, $upload_dir . '/' . basename($this->attach_filename))) {
+ if (!@copy($file, $upload_dir . '/' . basename($this->attach_filename))) {
+ $error = true;
+ if (!empty($error_msg)) {
+ $error_msg .= '
';
+ }
+ $error_msg .= sprintf($lang['GENERAL_UPLOAD_ERROR'], './' . $upload_dir . '/' . $this->attach_filename);
+ return;
+ }
+ }
+ @chmod($upload_dir . '/' . $this->attach_filename, 0666);
+
+ break;
+ }
+
+ if (!$error && $this->thumbnail === 1) {
+ $source = $upload_dir . '/' . basename($this->attach_filename);
+ $dest_file = amod_realpath($upload_dir);
+ $dest_file .= '/' . THUMB_DIR . '/t_' . basename($this->attach_filename);
+
+ if (!create_thumbnail($source, $dest_file, $this->type)) {
+ if (!$file || !create_thumbnail($file, $dest_file, $this->type)) {
+ $this->thumbnail = 0;
+ }
+ }
+ }
+ }
+}
diff --git a/src/Legacy/AttachPosting.php b/src/Legacy/AttachPosting.php
new file mode 100644
index 000000000..4a94a3307
--- /dev/null
+++ b/src/Legacy/AttachPosting.php
@@ -0,0 +1,111 @@
+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();
+ }
+}
diff --git a/src/Legacy/BBCode.php b/src/Legacy/BBCode.php
new file mode 100644
index 000000000..1a6c92c0c
--- /dev/null
+++ b/src/Legacy/BBCode.php
@@ -0,0 +1,427 @@
+ 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' => '',
+ '#\[\*=(\d+)\]#isu' => '- ',
+ '#\[pre\](.*?)\[/pre\]#isu' => '
$1
',
+ '#\[name=([a-zA-Z0-9_]+?)\]#isu' => '',
+ '#\[url=\#([a-zA-Z0-9_]+?)\](.*?)\[/url\]#isu' => '$2',
+ '#\[color=([\#0-9a-zA-Z]+)\]#isu' => '',
+ '#\[size=([1-2]?[0-9])\]#isu' => '',
+ '#\[align=(left|right|center|justify)\]#isu' => '',
+ '#\[font="([\w\- \']+)"\]#isu' => '',
+ "#\[img\]($img_exp)\[/img\]#isu" => $tpl['img'],
+ "#\[img=(left|right|center)\]($img_exp)\[/img\]\s*#isu" => $tpl['img_aligned'],
+ "#\[email\]($email_exp)\[/email\]#isu" => '$1',
+ "#\[qpost=([0-9]*)\]#isu" => '$1',
+ ];
+
+ $this->str = [
+ '[quote]' => $tpl['quote_open'],
+ '[/quote]' => $tpl['quote_close'],
+ '[spoiler]' => $tpl['spoiler_open'],
+ '[/spoiler]' => $tpl['spoiler_close'],
+ '[list]' => '',
+ '[*]' => '- ',
+ '[/list]' => '
',
+ '[/color]' => '',
+ '[/size]' => '',
+ '[/align]' => '',
+ '[/font]' => '',
+ '[tab]' => ' ',
+ '[br]' => "\n\n",
+ '[hr]' => $tpl['hr'],
+ '[b]' => '',
+ '[/b]' => '',
+ '[u]' => '',
+ '[/u]' => '',
+ '[i]' => '',
+ '[/i]' => '',
+ '[s]' => '',
+ '[/s]' => '',
+ '[del]' => '',
+ '[/del]' => '',
+ '[clear]' => '
',
+ ];
+
+ $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(' ', ' ', $code);
+ $code = str_replace(' ', ' ', $code);
+ $code = str_replace("\t", ' ', $code);
+ $code = str_replace(['[', ']', ':', ')'], ['[', ']', ':', ')'], $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 = "$url_name";
+ } else {
+ $link = "$url_name";
+ }
+
+ 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(['[', ']', ':', ')', '"'], ['[', ']', ':', ')', '"'], $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 = "#
+ (? $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 = "$name";
+ } else {
+ $link = "$name";
+ }
+
+ 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,}#', '
', $text);
+ $text = str_replace("\n", '
', $text);
+ return $text;
+ }
+
+ /**
+ * Tidy
+ *
+ * @param string $text
+ * @return string
+ */
+ public function tidy($text)
+ {
+ $text = tidy_repair_string($text, $this->tidy_cfg, 'utf8');
+ return $text;
+ }
+}
diff --git a/library/includes/cache/apc.php b/src/Legacy/Cache/Apc.php
similarity index 95%
rename from library/includes/cache/apc.php
rename to src/Legacy/Cache/Apc.php
index 2fa961be7..5f3272d56 100644
--- a/library/includes/cache/apc.php
+++ b/src/Legacy/Cache/Apc.php
@@ -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';
diff --git a/library/includes/cache/common.php b/src/Legacy/Cache/Common.php
similarity index 96%
rename from library/includes/cache/common.php
rename to src/Legacy/Cache/Common.php
index 3732475a4..e923fc0fb 100644
--- a/library/includes/cache/common.php
+++ b/src/Legacy/Cache/Common.php
@@ -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;
diff --git a/library/includes/cache/file.php b/src/Legacy/Cache/File.php
similarity index 97%
rename from library/includes/cache/file.php
rename to src/Legacy/Cache/File.php
index cccaecfaa..800c6dd3d 100644
--- a/library/includes/cache/file.php
+++ b/src/Legacy/Cache/File.php
@@ -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';
diff --git a/library/includes/cache/memcache.php b/src/Legacy/Cache/Memcache.php
similarity index 95%
rename from library/includes/cache/memcache.php
rename to src/Legacy/Cache/Memcache.php
index 92314cb12..1b10d2c2e 100644
--- a/library/includes/cache/memcache.php
+++ b/src/Legacy/Cache/Memcache.php
@@ -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();
}
diff --git a/library/includes/cache/redis.php b/src/Legacy/Cache/Redis.php
similarity index 95%
rename from library/includes/cache/redis.php
rename to src/Legacy/Cache/Redis.php
index c1506e9aa..94cee9dd9 100644
--- a/library/includes/cache/redis.php
+++ b/src/Legacy/Cache/Redis.php
@@ -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();
}
diff --git a/src/Legacy/Cache/Sqlite.php b/src/Legacy/Cache/Sqlite.php
new file mode 100644
index 000000000..3b9e45631
--- /dev/null
+++ b/src/Legacy/Cache/Sqlite.php
@@ -0,0 +1,129 @@
+ '/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;
+ }
+}
diff --git a/library/includes/cache/sqlite.php b/src/Legacy/Cache/SqliteCommon.php
similarity index 62%
rename from library/includes/cache/sqlite.php
rename to src/Legacy/Cache/SqliteCommon.php
index 8304e4c86..fdc2056ca 100644
--- a/library/includes/cache/sqlite.php
+++ b/src/Legacy/Cache/SqliteCommon.php
@@ -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')
diff --git a/library/includes/cache/xcache.php b/src/Legacy/Cache/Xcache.php
similarity index 95%
rename from library/includes/cache/xcache.php
rename to src/Legacy/Cache/Xcache.php
index 0f201d154..85a4380f0 100644
--- a/library/includes/cache/xcache.php
+++ b/src/Legacy/Cache/Xcache.php
@@ -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';
diff --git a/library/includes/core/caches.php b/src/Legacy/Caches.php
similarity index 80%
rename from library/includes/core/caches.php
rename to src/Legacy/Caches.php
index 46e48fd54..71e6089eb 100644
--- a/library/includes/core/caches.php
+++ b/src/Legacy/Caches.php
@@ -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;
diff --git a/src/Legacy/Common/Ads.php b/src/Legacy/Common/Ads.php
new file mode 100644
index 000000000..d923b23bc
--- /dev/null
+++ b/src/Legacy/Common/Ads.php
@@ -0,0 +1,127 @@
+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;
+ }
+}
diff --git a/src/Legacy/Common/Html.php b/src/Legacy/Common/Html.php
new file mode 100644
index 000000000..4d9368ff7
--- /dev/null
+++ b/src/Legacy/Common/Html.php
@@ -0,0 +1,164 @@
+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\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\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\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>$k<$ul>";
+ $this->_array2html_rec($v, $ul, $li);
+ $this->out .= "$ul>$li>";
+ } else {
+ $this->out .= "<$li>$v$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 ? '' . $title . '' : $title;
+ $id = $id ? " id=\"$id\" " : '';
+ $checked = $checked ? HTML_CHECKED : '';
+ $disabled = $disabled ? HTML_DISABLED : '';
+
+ return '';
+ }
+}
diff --git a/library/includes/functions_upload.php b/src/Legacy/Common/Upload.php
similarity index 89%
rename from library/includes/functions_upload.php
rename to src/Legacy/Common/Upload.php
index 04c645152..96310ad76 100644
--- a/library/includes/functions_upload.php
+++ b/src/Legacy/Common/Upload.php
@@ -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);
diff --git a/src/Legacy/Common/User.php b/src/Legacy/Common/User.php
new file mode 100644
index 000000000..3088ba1b0
--- /dev/null
+++ b/src/Legacy/Common/User.php
@@ -0,0 +1,733 @@
+ 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;
+ }
+ }
+}
diff --git a/library/includes/datastore/apc.php b/src/Legacy/Datastore/Apc.php
similarity index 95%
rename from library/includes/datastore/apc.php
rename to src/Legacy/Datastore/Apc.php
index 4ee1e0171..94d16bdee 100644
--- a/library/includes/datastore/apc.php
+++ b/src/Legacy/Datastore/Apc.php
@@ -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;
diff --git a/library/includes/datastore/common.php b/src/Legacy/Datastore/Common.php
similarity index 93%
rename from library/includes/datastore/common.php
rename to src/Legacy/Datastore/Common.php
index b2a8111b0..282039dc0 100644
--- a/library/includes/datastore/common.php
+++ b/src/Legacy/Datastore/Common.php
@@ -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;
diff --git a/library/includes/datastore/file.php b/src/Legacy/Datastore/File.php
similarity index 96%
rename from library/includes/datastore/file.php
rename to src/Legacy/Datastore/File.php
index b8905b4e2..cf1d0ea95 100644
--- a/library/includes/datastore/file.php
+++ b/src/Legacy/Datastore/File.php
@@ -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;
diff --git a/library/includes/datastore/memcache.php b/src/Legacy/Datastore/Memcache.php
similarity index 95%
rename from library/includes/datastore/memcache.php
rename to src/Legacy/Datastore/Memcache.php
index eba2fd6b9..18c4e536c 100644
--- a/library/includes/datastore/memcache.php
+++ b/src/Legacy/Datastore/Memcache.php
@@ -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();
}
diff --git a/library/includes/datastore/redis.php b/src/Legacy/Datastore/Redis.php
similarity index 95%
rename from library/includes/datastore/redis.php
rename to src/Legacy/Datastore/Redis.php
index b3c5256eb..4b0d361e8 100644
--- a/library/includes/datastore/redis.php
+++ b/src/Legacy/Datastore/Redis.php
@@ -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;
}
diff --git a/library/includes/datastore/sqlite.php b/src/Legacy/Datastore/Sqlite.php
similarity index 93%
rename from library/includes/datastore/sqlite.php
rename to src/Legacy/Datastore/Sqlite.php
index 06fd90d59..bc7f16100 100644
--- a/library/includes/datastore/sqlite.php
+++ b/src/Legacy/Datastore/Sqlite.php
@@ -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;
}
diff --git a/src/Legacy/Datastore/SqliteCommon.php b/src/Legacy/Datastore/SqliteCommon.php
new file mode 100644
index 000000000..029a1d82e
--- /dev/null
+++ b/src/Legacy/Datastore/SqliteCommon.php
@@ -0,0 +1,202 @@
+ '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);
+ }
+ }
+}
diff --git a/library/includes/datastore/xcache.php b/src/Legacy/Datastore/Xcache.php
similarity index 95%
rename from library/includes/datastore/xcache.php
rename to src/Legacy/Datastore/Xcache.php
index fdb688eae..5e8b1d6dd 100644
--- a/library/includes/datastore/xcache.php
+++ b/src/Legacy/Datastore/Xcache.php
@@ -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';
diff --git a/src/Legacy/DateDelta.php b/src/Legacy/DateDelta.php
new file mode 100644
index 000000000..1b51e0467
--- /dev/null
+++ b/src/Legacy/DateDelta.php
@@ -0,0 +1,172 @@
+ '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;
+ }
+}
diff --git a/library/includes/core/dbs.php b/src/Legacy/Dbs.php
similarity index 88%
rename from library/includes/core/dbs.php
rename to src/Legacy/Dbs.php
index e61b84a54..63a4c438d 100644
--- a/library/includes/core/dbs.php
+++ b/src/Legacy/Dbs.php
@@ -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];
diff --git a/src/Legacy/LogAction.php b/src/Legacy/LogAction.php
new file mode 100644
index 000000000..fd75d2029
--- /dev/null
+++ b/src/Legacy/LogAction.php
@@ -0,0 +1,117 @@
+ 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);
+ }
+}
diff --git a/src/Legacy/Poll.php b/src/Legacy/Poll.php
new file mode 100644
index 000000000..a9643b59e
--- /dev/null
+++ b/src/Legacy/Poll.php
@@ -0,0 +1,123 @@
+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");
+ }
+}
diff --git a/library/includes/classes/sitemap.php b/src/Legacy/Sitemap.php
similarity index 98%
rename from library/includes/classes/sitemap.php
rename to src/Legacy/Sitemap.php
index 505e45f33..7f98798f9 100644
--- a/library/includes/classes/sitemap.php
+++ b/src/Legacy/Sitemap.php
@@ -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;
diff --git a/library/includes/core/mysql.php b/src/Legacy/SqlDb.php
similarity index 99%
rename from library/includes/core/mysql.php
rename to src/Legacy/SqlDb.php
index bdf647789..23d8ab430 100644
--- a/library/includes/core/mysql.php
+++ b/src/Legacy/SqlDb.php
@@ -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;
diff --git a/src/Legacy/Template.php b/src/Legacy/Template.php
new file mode 100644
index 000000000..93286a89c
--- /dev/null
+++ b/src/Legacy/Template.php
@@ -0,0 +1,1051 @@
+_tpldata[block.][iteration#][child.][iteration#][child2.][iteration#][variablename] == value
+ // if it's a root-level variable, it'll be like this:
+ // $this->vars[varname] == value or $this->_tpldata['.'][0][varname] == value
+ // array "vars" is added for easier access to data
+ public $_tpldata = array('.' => array(0 => array()));
+ public $vars;
+
+ // Hash of filenames for each template handle.
+ public $files = array();
+ public $files_cache = array(); // array of cache files that exists
+ public $files_cache2 = array(); // array of cache files (exists or not exists)
+
+ // Root template directory.
+ public $root = '';
+
+ // Cache directory
+ public $cachedir = CACHE_DIR . '/';
+
+ // Template root directory
+ public $tpldir = '';
+
+ // Default template directory.
+ // If file for default template isn't found file from this template is used.
+ public $tpldef = 'default';
+
+ // this will hash handle names to the compiled code for that handle.
+ public $compiled_code = array();
+
+ // This will hold the uncompiled code for that handle.
+ public $uncompiled_code = array();
+
+ // Cache settings
+ public $use_cache = 1;
+ public $cache_writable = 1;
+
+ // Auto-compile setting
+ public $auto_compile = 1;
+
+ // Current template name
+ public $tpl = '';
+ public $cur_tpl = '';
+
+ // List of replacements. tpl files in this list will be replaced with other tpl files
+ // according to configuration in xs.cfg
+ public $replace = array();
+
+ // counter for include
+ public $include_count = 0;
+
+ // extension tpl-cache files
+ public $cached_tpl_ext = 'php';
+
+ // eXtreme Styles variables
+ public $xs_started = 0;
+ public $xs_version = 8; // number version. internal. do not change.
+ public $xs_versiontxt = '2.3.1'; // text version
+
+ // These handles will be parsed if pparse() is executed.
+ // Can be used to automatically include header/footer if there is any content.
+ public $preparse = '';
+ public $postparse = '';
+
+ // subtemplates mod detection
+ public $subtemplates = false;
+
+ // style configuration
+ public $style_config = array();
+
+ public $lang = array();
+
+ /**
+ * Constructor. Installs XS mod on first run or updates it and sets the root dir.
+ */
+ public function __construct($root = '.')
+ {
+ global $bb_cfg, $lang;
+
+ // setting pointer "vars"
+ $this->vars = &$this->_tpldata['.'][0];
+ // load configuration
+ $this->tpldir = TEMPLATES_DIR;
+ $this->root = $root;
+ $this->tpl = basename($root);
+ $this->lang =& $lang;
+ $this->use_cache = $bb_cfg['xs_use_cache'];
+ }
+
+ /**
+ * Destroys this template object. Should be called when you're done with it, in order
+ * to clear out the template data so you can load/parse a new template set.
+ */
+ public function destroy()
+ {
+ $this->_tpldata = array('.' => array(0 => array()));
+ $this->vars = &$this->_tpldata['.'][0];
+ $this->xs_started = 0;
+ }
+
+ /**
+ * Generates a full path+filename for the given filename, which can either
+ * be an absolute name, or a name relative to the rootdir for this Template
+ * object.
+ */
+ public function make_filename($filename, $xs_include = false)
+ {
+ // Check replacements list
+ if (!$xs_include && isset($this->replace[$filename])) {
+ $filename = $this->replace[$filename];
+ }
+ // Check if it's an absolute or relative path.
+ if (($filename[0] !== '/') && ($filename[1] !== ':')) {
+ return $this->root . '/' . $filename;
+ } else {
+ return $filename;
+ }
+ }
+
+ /**
+ * Converts template filename to cache filename.
+ * Returns empty string if non-cachable (for tpl files outside of root dir).
+ * $filename should be absolute filename
+ */
+ public function make_filename_cache($filename)
+ {
+ $filename = clean_filename(str_replace(TEMPLATES_DIR, '', $filename));
+
+ return $this->cachedir . XS_TPL_PREFIX . $filename . '.' . $this->cached_tpl_ext;
+ }
+
+ /**
+ * Sets the template filenames for handles. $filename_array
+ * should be a hash of handle => filename pairs.
+ */
+ public function set_filenames($filenames)
+ {
+ foreach ($filenames as $handle => $filename) {
+ $this->set_filename($handle, $filename);
+ }
+ }
+
+ /**
+ * Assigns template filename for handle.
+ */
+ public function set_filename($handle, $filename, $xs_include = false, $quiet = false)
+ {
+ $can_cache = $this->use_cache;
+ $this->files[$handle] = $this->make_filename($filename, $xs_include);
+ $this->files_cache[$handle] = '';
+ $this->files_cache2[$handle] = '';
+ // checking if we have valid filename
+ if (!$this->files[$handle]) {
+ if ($xs_include || $quiet) {
+ return false;
+ } else {
+ die("Template->make_filename(): Error - invalid template $filename");
+ }
+ }
+ // creating cache filename
+ if ($can_cache) {
+ $this->files_cache2[$handle] = $this->make_filename_cache($this->files[$handle]);
+ if (@file_exists($this->files_cache2[$handle])) {
+ $this->files_cache[$handle] = $this->files_cache2[$handle];
+ }
+ }
+ // checking if tpl and/or php file exists
+ if (empty($this->files_cache[$handle]) && !@file_exists($this->files[$handle])) {
+ if ($quiet) {
+ return false;
+ }
+ die('Template->make_filename(): Error - template file not found:
' . hide_bb_path($this->files[$handle]));
+ }
+ // checking if we should recompile cache
+ if (!empty($this->files_cache[$handle])) {
+ $cache_time = @filemtime($this->files_cache[$handle]);
+ if (@filemtime($this->files[$handle]) > $cache_time) {
+ // file was changed. don't use cache file (will be recompled if configuration allowes it)
+ $this->files_cache[$handle] = '';
+ }
+ }
+ return true;
+ }
+
+ /**
+ * includes file or executes code
+ */
+ public function execute($filename, $code, $handle)
+ {
+ $this->cur_tpl = $filename;
+
+ global $lang, $bb_cfg, $user, $tr_cfg;
+
+ $L =& $lang;
+ $V =& $this->vars;
+
+ if ($filename) {
+ include($filename);
+ } else {
+ eval($code);
+ }
+ }
+
+ /**
+ * Load the file for the handle, compile the file,
+ * and run the compiled code. This will print out
+ * the results of executing the template.
+ */
+ public function pparse($handle)
+ {
+ // parsing header if there is one
+ if ($this->preparse || $this->postparse) {
+ $preparse = $this->preparse;
+ $postparse = $this->postparse;
+ $this->preparse = '';
+ $this->postparse = '';
+ if ($preparse) {
+ $this->pparse($preparse);
+ }
+ if ($postparse) {
+ $str = $handle;
+ $handle = $postparse;
+ $this->pparse($str);
+ }
+ }
+ // checking if handle exists
+ if (empty($this->files[$handle]) && empty($this->files_cache[$handle])) {
+ die("Template->loadfile(): No files found for handle $handle");
+ }
+ $this->xs_startup();
+ $force_recompile = empty($this->uncompiled_code[$handle]) ? false : true;
+ // checking if php file exists.
+ if (!empty($this->files_cache[$handle]) && !$force_recompile) {
+ // php file exists - running it instead of tpl
+ $this->execute($this->files_cache[$handle], '', $handle);
+ return true;
+ }
+ if (!$this->loadfile($handle)) {
+ die("Template->pparse(): Could not load template file for handle $handle");
+ }
+ // actually compile the template now.
+ if (empty($this->compiled_code[$handle])) {
+ // Actually compile the code now.
+ if (!empty($this->files_cache2[$handle]) && empty($this->files_cache[$handle]) && !$force_recompile) {
+ $this->compiled_code[$handle] = $this->compile2($this->uncompiled_code[$handle], $handle, $this->files_cache2[$handle]);
+ } else {
+ $this->compiled_code[$handle] = $this->compile2($this->uncompiled_code[$handle], '', '');
+ }
+ }
+ // Run the compiled code.
+ if (empty($this->files_cache[$handle]) || $force_recompile) {
+ $this->execute('', $this->compiled_code[$handle], $handle);
+ } else {
+ $this->execute($this->files_cache[$handle], '', $handle);
+ }
+ return true;
+ }
+
+ /**
+ * Precompile file
+ */
+ public function precompile($template, $filename)
+ {
+ global $precompile_num;
+ if (empty($precompile_num)) {
+ $precompile_num = 0;
+ }
+ $precompile_num++;
+ $handle = 'precompile_' . $precompile_num;
+ // save old configuration
+ $root = $this->root;
+ $tpl_name = $this->tpl;
+ $old_config = $this->use_cache;
+ $old_autosave = $this->auto_compile;
+ // set temporary configuration
+ $this->root = $this->tpldir . $template;
+ $this->tpl = $template;
+ $this->use_cache = 1;
+ $this->auto_compile = 1;
+ // set filename
+ $res = $this->set_filename($handle, $filename, true, true);
+ if (!$res || !$this->files_cache2[$handle]) {
+ $this->root = $root;
+ $this->tpl = $tpl_name;
+ $this->use_cache = $old_config;
+ $this->auto_compile = $old_autosave;
+ return false;
+ }
+ $this->files_cache[$handle] = '';
+ // load template
+ $res = $this->loadfile($handle);
+ if (!$res || empty($this->uncompiled_code[$handle])) {
+ $this->root = $root;
+ $this->tpl = $tpl_name;
+ $this->use_cache = $old_config;
+ $this->auto_compile = $old_autosave;
+ return false;
+ }
+ // compile the code
+ $this->compile2($this->uncompiled_code[$handle], $handle, $this->files_cache2[$handle]);
+ // restore confirugation
+ $this->root = $root;
+ $this->tpl = $tpl_name;
+ $this->use_cache = $old_config;
+ $this->auto_compile = $old_autosave;
+ return true;
+ }
+
+ /**
+ * Inserts the uncompiled code for $handle as the
+ * value of $varname in the root-level. This can be used
+ * to effectively include a template in the middle of another
+ * template.
+ * Note that all desired assignments to the variables in $handle should be done
+ * BEFORE calling this function.
+ */
+ public function assign_var_from_handle($varname, $handle)
+ {
+ ob_start();
+ $res = $this->pparse($handle);
+ $this->vars[$varname] = ob_get_contents();
+ ob_end_clean();
+ return $res;
+ }
+
+ /**
+ * Block-level variable assignment. Adds a new block iteration with the given
+ * variable assignments. Note that this should only be called once per block
+ * iteration.
+ */
+ public function assign_block_vars($blockname, $vararray)
+ {
+ if (false !== strpos($blockname, '.')) {
+ // Nested block.
+ $blocks = explode('.', $blockname);
+ $blockcount = count($blocks) - 1;
+
+ $str = &$this->_tpldata;
+ for ($i = 0; $i < $blockcount; $i++) {
+ $str = &$str[$blocks[$i] . '.'];
+ $str = &$str[count($str) - 1];
+ }
+ // Now we add the block that we're actually assigning to.
+ // We're adding a new iteration to this block with the given
+ // variable assignments.
+ $str[$blocks[$blockcount] . '.'][] = $vararray;
+ } else {
+ // Top-level block.
+ // Add a new iteration to this block with the variable assignments
+ // we were given.
+ $this->_tpldata[$blockname . '.'][] = $vararray;
+ }
+
+ return true;
+ }
+
+ /**
+ * Root-level variable assignment. Adds to current assignments, overriding
+ * any existing variable assignment with the same name.
+ */
+ public function assign_vars($vararray)
+ {
+ foreach ($vararray as $key => $val) {
+ $this->vars[$key] = $val;
+ }
+ }
+
+ /**
+ * Root-level variable assignment. Adds to current assignments, overriding
+ * any existing variable assignment with the same name.
+ */
+ public function assign_var($varname, $varval = true)
+ {
+ $this->vars[$varname] = $varval;
+ }
+
+ /**
+ * TODO: Add type check [??]
+ * Root-level. Adds to current assignments, appends
+ * to any existing variable assignment with the same name.
+ */
+ public function append_vars($vararray)
+ {
+ foreach ($vararray as $key => $val) {
+ $this->vars[$key] = !isset($this->vars[$key]) ? $val : $this->vars[$key] . $val;
+ }
+ }
+
+ /**
+ * If not already done, load the file for the given handle and populate
+ * the uncompiled_code[] hash with its code. Do not compile.
+ */
+ public function loadfile($handle)
+ {
+ // If cached file exists do nothing - it will be included via include()
+ if (!empty($this->files_cache[$handle])) {
+ return true;
+ }
+
+ // If the file for this handle is already loaded and compiled, do nothing.
+ if (!empty($this->uncompiled_code[$handle])) {
+ return true;
+ }
+
+ // If we don't have a file assigned to this handle, die.
+ if (empty($this->files[$handle])) {
+ die("Template->loadfile(): No file specified for handle $handle");
+ }
+
+ $filename = $this->files[$handle];
+
+ if (($str = @file_get_contents($filename)) === false) {
+ die("Template->loadfile(): File $filename for handle $handle is empty");
+ }
+
+ $this->uncompiled_code[$handle] = $str;
+
+ return true;
+ }
+
+ /**
+ * Generates a reference to the given variable inside the given (possibly nested)
+ * block namespace. This is a string of the form:
+ * ' . $this->_tpldata['parent.'][$_parent_i]['$child1.'][$_child1_i]['$child2.'][$_child2_i]...['varname'] . '
+ * It's ready to be inserted into an "echo" line in one of the templates.
+ * NOTE: expects a trailing "." on the namespace.
+ */
+ public function generate_block_varref($namespace, $varname)
+ {
+ // Strip the trailing period.
+ $namespace = substr($namespace, 0, strlen($namespace) - 1);
+
+ // Get a reference to the data block for this namespace.
+ $varref = $this->generate_block_data_ref($namespace, true);
+ // Prepend the necessary code to stick this in an echo line.
+
+ // Append the variable reference.
+ $varref .= "['$varname']";
+
+ $varref = "";
+
+ return $varref;
+ }
+
+ /**
+ * Generates a reference to the array of data values for the given
+ * (possibly nested) block namespace. This is a string of the form:
+ * $this->_tpldata['parent.'][$_parent_i]['$child1.'][$_child1_i]['$child2.'][$_child2_i]...['$childN.']
+ *
+ * If $include_last_iterator is true, then [$_childN_i] will be appended to the form shown above.
+ * NOTE: does not expect a trailing "." on the blockname.
+ */
+ public function generate_block_data_ref($blockname, $include_last_iterator)
+ {
+ // Get an array of the blocks involved.
+ $blocks = explode('.', $blockname);
+ $blockcount = count($blocks) - 1;
+ if ($include_last_iterator) {
+ return '$' . $blocks[$blockcount] . '_item';
+ } else {
+ return '$' . $blocks[$blockcount - 1] . '_item[\'' . $blocks[$blockcount] . '.\']';
+ }
+ }
+
+ public function compile_code($filename, $code)
+ {
+ // $filename - file to load code from. used if $code is empty
+ // $code - tpl code
+
+ // load code from file
+ if (!$code && !empty($filename)) {
+ $code = file_get_contents($filename);
+ }
+
+ // Replace tags
+ $search = array('', '');
+ $replace = array('<' . '?php ', ' ?' . '>');
+ $code = str_replace($search, $replace, $code);
+
+ // Break it up into lines and put " -->" back.
+ $code_lines = explode(' -->', $code);
+ $count = count($code_lines);
+ for ($i = 0; $i < ($count - 1); $i++) {
+ $code_lines[$i] .= ' -->';
+ }
+
+ $block_nesting_level = 0;
+ $block_names = array();
+ $block_names[0] = ".";
+ $block_items = array();
+ $count_if = 0;
+
+ // prepare array for compiled code
+ $compiled = array();
+
+ // array of switches
+ $sw = array();
+
+ // replace all short php tags
+ $new_code = array();
+ $line_count = count($code_lines);
+ for ($i = 0; $i < $line_count; $i++) {
+ $line = $code_lines[$i];
+ $pos = strpos($line, '');
+ if ($pos === false) {
+ $new_code[] = $line;
+ continue;
+ }
+ if (substr($line, $pos, 5) === '';
+ $code_lines[$i] = substr($line, $pos + 2);
+ $i--;
+ }
+ $code_lines = $new_code;
+
+ // main loop
+ $line_count = count($code_lines);
+ for ($i = 0; $i < $line_count; $i++) {
+ $line = $code_lines[$i];
+ // reset keyword type
+ $keyword_type = XS_TAG_NONE;
+ // check if we have valid keyword in current line
+ $pos1 = strpos($line, '', $pos1);
+ if ($pos2 !== false) {
+ // find end of keyword in comment
+ $pos3 = strpos($line, ' ', $pos1 + 5);
+ if ($pos3 !== false && $pos3 <= $pos2) {
+ $keyword = substr($line, $pos1 + 5, $pos3 - $pos1 - 5);
+ // check keyword against list of supported keywords. case-sensitive
+ if ($keyword === 'BEGIN') {
+ $keyword_type = XS_TAG_BEGIN;
+ } elseif ($keyword === 'END') {
+ $keyword_type = XS_TAG_END;
+ } elseif ($keyword === 'INCLUDE') {
+ $keyword_type = XS_TAG_INCLUDE;
+ } elseif ($keyword === 'IF') {
+ $keyword_type = XS_TAG_IF;
+ } elseif ($keyword === 'ELSE') {
+ $keyword_type = XS_TAG_ELSE;
+ } elseif ($keyword === 'ELSEIF') {
+ $keyword_type = XS_TAG_ELSEIF;
+ } elseif ($keyword === 'ENDIF') {
+ $keyword_type = XS_TAG_ENDIF;
+ } elseif ($keyword === 'BEGINELSE') {
+ $keyword_type = XS_TAG_BEGINELSE;
+ }
+ }
+ }
+ if (!$keyword_type) {
+ // not valid keyword. process the rest of line
+ $compiled[] = $this->_compile_text(substr($line, 0, $pos1 + 4));
+ $code_lines[$i] = substr($line, $pos1 + 4);
+ $i--;
+ continue;
+ }
+ // remove code before keyword
+ if ($pos1 > 0) {
+ $compiled[] = $this->_compile_text(substr($line, 0, $pos1));
+ }
+ // remove keyword
+ $keyword_str = substr($line, $pos1, $pos2 - $pos1 + 4);
+ $params_str = $pos2 == $pos3 ? '' : substr($line, $pos3 + 1, $pos2 - $pos3 - 1);
+ $code_lines[$i] = substr($line, $pos2 + 4);
+ $i--;
+ // Check keywords
+
+ /*
+ *
+ */
+ if ($keyword_type == XS_TAG_BEGIN) {
+ $params = explode(' ', $params_str);
+ $num_params = count($params);
+ // get variable name
+ if ($num_params == 1) {
+ $var = $params[0];
+ } elseif ($num_params == 2) {
+ if ($params[0] === '') {
+ $var = $params[1];
+ } elseif ($params[1] === '') {
+ $var = $params[0];
+ } else {
+ // invalid tag
+ $compiled[] = $keyword_str;
+ continue;
+ }
+ } else {
+ // invalid tag
+ $compiled[] = $keyword_str;
+ continue;
+ }
+ // adding code
+ $block_nesting_level++;
+ $block_names[$block_nesting_level] = $var;
+ if (isset($block_items[$var])) {
+ $block_items[$var]++;
+ } else {
+ $block_items[$var] = 1;
+ }
+ if ($block_nesting_level < 2) {
+ // Block is not nested.
+ $line = '<' . "?php\n\n";
+ $line .= '$' . $var . '_count = ( isset($this->_tpldata[\'' . $var . '.\']) ) ? sizeof($this->_tpldata[\'' . $var . '.\']) : 0;';
+ $line .= "\n" . 'for ($' . $var . '_i = 0; $' . $var . '_i < $' . $var . '_count; $' . $var . '_i++)';
+ $line .= "\n" . '{' . "\n";
+ $line .= ' $' . $var . '_item = &$this->_tpldata[\'' . $var . '.\'][$' . $var . '_i];' . "\n";
+ $line .= " \${$var}_item['S_ROW_COUNT'] = \${$var}_i;\n";
+ $line .= " \${$var}_item['S_NUM_ROWS'] = \${$var}_count;\n";
+ $line .= "\n?" . ">";
+ } else {
+ // This block is nested.
+ // Generate a namespace string for this block.
+ $namespace = implode('.', $block_names);
+ // strip leading period from root level..
+ $namespace = substr($namespace, 2);
+ // Get a reference to the data array for this block that depends on the
+ // current indices of all parent blocks.
+ $varref = $this->generate_block_data_ref($namespace, false);
+ // Create the for loop code to iterate over this block.
+ $line = '<' . "?php\n\n";
+ $line .= '$' . $var . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
+ $line .= "\n" . 'for ($' . $var . '_i = 0; $' . $var . '_i < $' . $var . '_count; $' . $var . '_i++)';
+ $line .= "\n" . '{' . "\n";
+ $line .= ' $' . $var . '_item = &' . $varref . '[$' . $var . '_i];' . "\n";
+ $line .= " \${$var}_item['S_ROW_COUNT'] = \${$var}_i;\n";
+ $line .= " \${$var}_item['S_NUM_ROWS'] = \${$var}_count;\n";
+ $line .= "\n?" . ">";
+ }
+ $compiled[] = $line;
+ continue;
+ }
+ /*
+ *
+ */
+ if ($keyword_type == XS_TAG_END) {
+ $params = explode(' ', $params_str);
+ $num_params = count($params);
+ if ($num_params == 1) {
+ $var = $params[0];
+ } elseif ($num_params == 2 && $params[0] === '') {
+ $var = $params[1];
+ } elseif ($num_params == 2 && $params[1] === '') {
+ $var = $params[0];
+ } else {
+ $compiled[] = $keyword_str;
+ continue;
+ }
+ // We have the end of a block.
+ $line = '<' . "?php\n\n";
+ $line .= '} // END ' . $var . "\n\n";
+ $line .= 'if(isset($' . $var . '_item)) { unset($' . $var . '_item); } ';
+ $line .= "\n\n?" . ">";
+ if (isset($block_items[$var])) {
+ $block_items[$var]--;
+ } else {
+ $block_items[$var] = -1;
+ }
+ unset($block_names[$block_nesting_level]);
+ $block_nesting_level--;
+ $compiled[] = $line;
+ continue;
+ }
+ /*
+ *
+ */
+ if ($keyword_type == XS_TAG_BEGINELSE) {
+ if ($block_nesting_level) {
+ $var = $block_names[$block_nesting_level];
+ $compiled[] = '<' . '?php } if(!$' . $var . '_count) { ?' . '>';
+ } else {
+ $compiled[] = $keyword_str;
+ continue;
+ }
+ }
+ /*
+ *
+ */
+ if ($keyword_type == XS_TAG_INCLUDE) {
+ $params = explode(' ', $params_str);
+ $num_params = count($params);
+ if ($num_params != 1) {
+ $compiled[] = $keyword_str;
+ continue;
+ }
+ $line = '<' . '?php ';
+ $filehash = md5($params_str . $this->include_count . TIMENOW);
+ $line .= ' $this->set_filename(\'xs_include_' . $filehash . '\', \'' . $params_str . '\', true); ';
+ $line .= ' $this->pparse(\'xs_include_' . $filehash . '\'); ';
+ $line .= ' ?' . '>';
+ $this->include_count++;
+ $compiled[] = $line;
+ continue;
+ }
+ /*
+ *
+ */
+ if ($keyword_type == XS_TAG_IF || $keyword_type == XS_TAG_ELSEIF) {
+ if (!$count_if) {
+ $keyword_type = XS_TAG_IF;
+ }
+ $str = $this->compile_tag_if($params_str, $keyword_type != XS_TAG_IF);
+ if ($str) {
+ $compiled[] = '';
+ if ($keyword_type == XS_TAG_IF) {
+ $count_if++;
+ }
+ } else {
+ $compiled[] = $keyword_str;
+ }
+ continue;
+ }
+ /*
+ *
+ */
+ if ($keyword_type == XS_TAG_ELSE && $count_if > 0) {
+ $compiled[] = '';
+ continue;
+ }
+ /*
+ *
+ */
+ if ($keyword_type == XS_TAG_ENDIF && $count_if > 0) {
+ $compiled[] = '';
+ $count_if--;
+ continue;
+ }
+ }
+
+ // bring it back into a single string.
+ $code_header = '';
+ $code_footer = '';
+
+ return $code_header . implode('', $compiled) . $code_footer;
+ }
+
+ /*
+ * Compile code between tags
+ */
+ public function _compile_text($code)
+ {
+ if (strlen($code) < 3) {
+ return $code;
+ }
+ // change template varrefs into PHP varrefs
+ // This one will handle varrefs WITH namespaces
+ $varrefs = array();
+ preg_match_all('#\{(([a-z0-9\-_]+?\.)+)([a-z0-9\-_]+?)\}#is', $code, $varrefs);
+ $varcount = count($varrefs[1]);
+ $search = array();
+ $replace = array();
+ for ($i = 0; $i < $varcount; $i++) {
+ $namespace = $varrefs[1][$i];
+ $varname = $varrefs[3][$i];
+ $new = $this->generate_block_varref($namespace, $varname);
+ $search[] = $varrefs[0][$i];
+ $replace[] = $new;
+ }
+ if (count($search) > 0) {
+ $code = str_replace($search, $replace, $code);
+ }
+ // This will handle the remaining root-level varrefs
+ $code = preg_replace('#\{(L_([a-z0-9\-_]+?))\}#i', '', $code);
+ $code = preg_replace('#\{(\$[a-z_][a-z0-9_$\->\'\"\.\[\]]*?)\}#i', '', $code);
+ $code = preg_replace('#\{(\#([a-z_][a-z0-9_]*?))\}#i', '', $code);
+ $code = preg_replace('#\{([a-z0-9\-_]+?)\}#i', '', $code);
+ return $code;
+ }
+
+ //
+ // Compile IF tags - much of this is from Smarty with
+ // some adaptions for our block level methods
+ //
+ public function compile_tag_if($tag_args, $elseif)
+ {
+ /* Tokenize args for 'if' tag. */
+ preg_match_all('/(?:
+ "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" |
+ \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' |
+ [(),] |
+ [^\s(),]+)/x', $tag_args, $match);
+
+ $tokens = $match[0];
+ $tokens_cnt = count($tokens);
+ $is_arg_stack = array();
+
+ for ($i = 0; $i < $tokens_cnt; $i++) {
+ $token = &$tokens[$i];
+
+ switch ($token) {
+ case 'eq':
+ $token = '==';
+ break;
+
+ case 'ne':
+ case 'neq':
+ $token = '!=';
+ break;
+
+ case 'lt':
+ $token = '<';
+ break;
+
+ case 'le':
+ case 'lte':
+ $token = '<=';
+ break;
+
+ case 'gt':
+ $token = '>';
+ break;
+
+ case 'ge':
+ case 'gte':
+ $token = '>=';
+ break;
+
+ case 'and':
+ $token = '&&';
+ break;
+
+ case 'or':
+ $token = '||';
+ break;
+
+ case 'not':
+ $token = '!';
+ break;
+
+ case 'mod':
+ $token = '%';
+ break;
+
+ case '(':
+ $is_arg_stack[] = $i;
+ break;
+
+ case 'is':
+ $is_arg_start = ($tokens[$i - 1] == ')') ? array_pop($is_arg_stack) : $i - 1;
+ $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
+
+ $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i + 1));
+
+ array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
+
+ $i = $is_arg_start;
+ break;
+
+ default:
+ $pattern = '@^
+ ( # 1
+ ([a-z0-9\-_]+?\.)+? # 2 block tpl vars (VAR1.VAR2.) but without last
+ )?
+ ( # 3
+ ([a-z_][a-z0-9\-_]*)? # 4 single tpl var or last block var (last in block)
+ (\$[a-z_][a-z0-9_$\->\'\"\.\[\]]*)? # 5 php var
+ (\#([a-z_][a-z0-9_]*))? # 7 php const
+ )
+ $@ix';
+ if (preg_match($pattern, $token, $m)) {
+ if (!empty($m[1])) {
+ $token = $this->generate_block_data_ref(substr($m[1], 0, -1), true) . "['{$m[4]}']";
+ } elseif (!empty($m[4])) {
+ $token = ($tokens_cnt == 1) ? "!empty(\$V['{$m[4]}'])" : "\$V['{$m[4]}']";
+ } elseif (!empty($m[5])) {
+ $token = ($tokens_cnt == 1) ? "!empty({$m[5]})" : "{$m[5]}";
+ } elseif (!empty($m[7])) {
+ $token = ($tokens_cnt == 1) ? "defined('{$m[7]}') && {$m[7]}" : "{$m[7]}";
+ }
+ }
+ break;
+ }
+ }
+
+ if ($elseif) {
+ $code = '} elseif (' . implode(' ', $tokens) . ') {';
+ } else {
+ $code = 'if (' . implode(' ', $tokens) . ') {';
+ }
+
+ return $code;
+ }
+
+ // This is from Smarty
+ public function _parse_is_expr($is_arg, $tokens)
+ {
+ $expr_end = 0;
+ $negate_expr = false;
+
+ if (($first_token = array_shift($tokens)) == 'not') {
+ $negate_expr = true;
+ $expr_type = array_shift($tokens);
+ } else {
+ $expr_type = $first_token;
+ }
+
+ switch ($expr_type) {
+ case 'even':
+ if (@$tokens[$expr_end] == 'by') {
+ $expr_end++;
+ $expr_arg = $tokens[$expr_end++];
+ $expr = "!(($is_arg / $expr_arg) % $expr_arg)";
+ } else {
+ $expr = "!($is_arg % 2)";
+ }
+ break;
+
+ case 'odd':
+ if (@$tokens[$expr_end] == 'by') {
+ $expr_end++;
+ $expr_arg = $tokens[$expr_end++];
+ $expr = "(($is_arg / $expr_arg) % $expr_arg)";
+ } else {
+ $expr = "($is_arg % 2)";
+ }
+ break;
+
+ case 'div':
+ if (@$tokens[$expr_end] == 'by') {
+ $expr_end++;
+ $expr_arg = $tokens[$expr_end++];
+ $expr = "!($is_arg % $expr_arg)";
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if ($negate_expr) {
+ $expr = "!($expr)";
+ }
+
+ array_splice($tokens, 0, $expr_end, $expr);
+
+ return $tokens;
+ }
+
+ /**
+ * Compiles code and writes to cache if needed
+ */
+ public function compile2($code, $handle, $cache_file)
+ {
+ $code = $this->compile_code('', $code, XS_USE_ISSET);
+ if ($cache_file && !empty($this->use_cache) && !empty($this->auto_compile)) {
+ $res = $this->write_cache($cache_file, $code);
+ if ($handle && $res) {
+ $this->files_cache[$handle] = $cache_file;
+ }
+ }
+ $code = '?' . '>' . $code . '<' . "?php\n";
+ return $code;
+ }
+
+ /**
+ * Compiles the given string of code, and returns
+ * the result in a string.
+ * If "do_not_echo" is true, the returned code will not be directly
+ * executable, but can be used as part of a variable assignment
+ * for use in assign_code_from_handle().
+ * This function isn't used and kept only for compatibility with original template.php
+ */
+ public function compile($code, $do_not_echo = false, $retvar = '')
+ {
+ $code = ' ?' . '>' . $this->compile_code('', $code, true) . '<' . "?php \n";
+ if ($do_not_echo) {
+ $code = "ob_start();\n" . $code . "\n\${$retvar} = ob_get_contents();\nob_end_clean();\n";
+ }
+ return $code;
+ }
+
+ /**
+ * Write cache to disk
+ */
+ public function write_cache($filename, $code)
+ {
+ file_write($code, $filename, false, true, true);
+ }
+
+ public function xs_startup()
+ {
+ global $bb_cfg;
+
+ if (empty($this->xs_started)) { // adding predefined variables
+ $this->xs_started = 1;
+ // adding language variable (eg: "english" or "german")
+ // can be used to make truly multi-lingual templates
+ $this->vars['LANG'] = isset($this->vars['LANG']) ? $this->vars['LANG'] : $bb_cfg['default_lang'];
+ // adding current template
+ $tpl = $this->root . '/';
+ if (substr($tpl, 0, 2) === './') {
+ $tpl = substr($tpl, 2, strlen($tpl));
+ }
+ $this->vars['TEMPLATE'] = isset($this->vars['TEMPLATE']) ? $this->vars['TEMPLATE'] : $tpl;
+ $this->vars['TEMPLATE_NAME'] = isset($this->vars['TEMPLATE_NAME']) ? $this->vars['TEMPLATE_NAME'] : $this->tpl;
+ }
+ }
+
+ public function lang_error($var)
+ {
+ trigger_error(basename($this->cur_tpl) . " : undefined language variable {L_{$var}}", E_USER_WARNING);
+ return "Undefined: {L_{$var}}";
+ }
+}
diff --git a/src/Legacy/TorrentFileList.php b/src/Legacy/TorrentFileList.php
new file mode 100644
index 000000000..5ebf7cb27
--- /dev/null
+++ b/src/Legacy/TorrentFileList.php
@@ -0,0 +1,152 @@
+ []
+ ];
+ 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 "{$this->root_dir}
$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 = '
';
+ $magnet_ext = '
';
+ }
+
+ return "$name $length $magnet_name $magnet_ext";
+ }
+}
diff --git a/src/Legacy/WordsRate.php b/src/Legacy/WordsRate.php
new file mode 100644
index 000000000..4d96ca0bd
--- /dev/null
+++ b/src/Legacy/WordsRate.php
@@ -0,0 +1,103 @@
+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, '$0', $text);
+ $this->del_text_hl = '' . $text_dbg . '
';
+ }
+ $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;
+ }
+}