Augmentation vers version 3.3.0
This commit is contained in:
1730
install/update/new/includes/acp/acp_attachments.php
Normal file
1730
install/update/new/includes/acp/acp_attachments.php
Normal file
File diff suppressed because it is too large
Load Diff
480
install/update/new/includes/acp/acp_bbcodes.php
Normal file
480
install/update/new/includes/acp/acp_bbcodes.php
Normal file
@@ -0,0 +1,480 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
class acp_bbcodes
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $db, $user, $template, $cache, $request, $phpbb_dispatcher, $phpbb_container;
|
||||
global $phpbb_log;
|
||||
|
||||
$user->add_lang('acp/posting');
|
||||
|
||||
// Set up general vars
|
||||
$action = $request->variable('action', '');
|
||||
$bbcode_id = $request->variable('bbcode', 0);
|
||||
|
||||
$this->tpl_name = 'acp_bbcodes';
|
||||
$this->page_title = 'ACP_BBCODES';
|
||||
$form_key = 'acp_bbcodes';
|
||||
|
||||
add_form_key($form_key);
|
||||
|
||||
// Set up mode-specific vars
|
||||
switch ($action)
|
||||
{
|
||||
case 'add':
|
||||
$bbcode_match = $bbcode_tpl = $bbcode_helpline = '';
|
||||
$display_on_posting = 0;
|
||||
break;
|
||||
|
||||
case 'edit':
|
||||
$sql = 'SELECT bbcode_match, bbcode_tpl, display_on_posting, bbcode_helpline
|
||||
FROM ' . BBCODES_TABLE . '
|
||||
WHERE bbcode_id = ' . $bbcode_id;
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$row)
|
||||
{
|
||||
trigger_error($user->lang['BBCODE_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$bbcode_match = $row['bbcode_match'];
|
||||
$bbcode_tpl = htmlspecialchars($row['bbcode_tpl']);
|
||||
$display_on_posting = $row['display_on_posting'];
|
||||
$bbcode_helpline = $row['bbcode_helpline'];
|
||||
break;
|
||||
|
||||
case 'modify':
|
||||
$sql = 'SELECT bbcode_id, bbcode_tag
|
||||
FROM ' . BBCODES_TABLE . '
|
||||
WHERE bbcode_id = ' . $bbcode_id;
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$row)
|
||||
{
|
||||
trigger_error($user->lang['BBCODE_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
// No break here
|
||||
|
||||
case 'create':
|
||||
$display_on_posting = $request->variable('display_on_posting', 0);
|
||||
|
||||
$bbcode_match = $request->variable('bbcode_match', '');
|
||||
$bbcode_tpl = htmlspecialchars_decode($request->variable('bbcode_tpl', '', true));
|
||||
$bbcode_helpline = $request->variable('bbcode_helpline', '', true);
|
||||
break;
|
||||
}
|
||||
|
||||
// Do major work
|
||||
switch ($action)
|
||||
{
|
||||
case 'edit':
|
||||
case 'add':
|
||||
|
||||
$tpl_ary = array(
|
||||
'S_EDIT_BBCODE' => true,
|
||||
'U_BACK' => $this->u_action,
|
||||
'U_ACTION' => $this->u_action . '&action=' . (($action == 'add') ? 'create' : 'modify') . (($bbcode_id) ? "&bbcode=$bbcode_id" : ''),
|
||||
|
||||
'L_BBCODE_USAGE_EXPLAIN'=> sprintf($user->lang['BBCODE_USAGE_EXPLAIN'], '<a href="#down">', '</a>'),
|
||||
'BBCODE_MATCH' => $bbcode_match,
|
||||
'BBCODE_TPL' => $bbcode_tpl,
|
||||
'BBCODE_HELPLINE' => $bbcode_helpline,
|
||||
'DISPLAY_ON_POSTING' => $display_on_posting,
|
||||
);
|
||||
|
||||
$bbcode_tokens = array('TEXT', 'SIMPLETEXT', 'INTTEXT', 'IDENTIFIER', 'NUMBER', 'EMAIL', 'URL', 'LOCAL_URL', 'RELATIVE_URL', 'COLOR');
|
||||
|
||||
/**
|
||||
* Modify custom bbcode template data before we display the add/edit form
|
||||
*
|
||||
* @event core.acp_bbcodes_edit_add
|
||||
* @var string action Type of the action: add|edit
|
||||
* @var array tpl_ary Array with custom bbcode add/edit data
|
||||
* @var int bbcode_id When editing: the bbcode id,
|
||||
* when creating: 0
|
||||
* @var array bbcode_tokens Array of bbcode tokens
|
||||
* @since 3.1.0-a3
|
||||
*/
|
||||
$vars = array('action', 'tpl_ary', 'bbcode_id', 'bbcode_tokens');
|
||||
extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_edit_add', compact($vars)));
|
||||
|
||||
$template->assign_vars($tpl_ary);
|
||||
|
||||
foreach ($bbcode_tokens as $token)
|
||||
{
|
||||
$template->assign_block_vars('token', array(
|
||||
'TOKEN' => '{' . $token . '}',
|
||||
'EXPLAIN' => ($token === 'LOCAL_URL') ? $user->lang(array('tokens', $token), generate_board_url() . '/') : $user->lang(array('tokens', $token)),
|
||||
));
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
break;
|
||||
|
||||
case 'modify':
|
||||
case 'create':
|
||||
|
||||
$sql_ary = $hidden_fields = array();
|
||||
|
||||
/**
|
||||
* Modify custom bbcode data before the modify/create action
|
||||
*
|
||||
* @event core.acp_bbcodes_modify_create
|
||||
* @var string action Type of the action: modify|create
|
||||
* @var array sql_ary Array with new bbcode data
|
||||
* @var int bbcode_id When editing: the bbcode id,
|
||||
* when creating: 0
|
||||
* @var bool display_on_posting Display bbcode on posting form
|
||||
* @var string bbcode_match The bbcode usage string to match
|
||||
* @var string bbcode_tpl The bbcode HTML replacement string
|
||||
* @var string bbcode_helpline The bbcode help line string
|
||||
* @var array hidden_fields Array of hidden fields for use when
|
||||
* submitting form when $warn_unsafe is true
|
||||
* @since 3.1.0-a3
|
||||
*/
|
||||
$vars = array(
|
||||
'action',
|
||||
'sql_ary',
|
||||
'bbcode_id',
|
||||
'display_on_posting',
|
||||
'bbcode_match',
|
||||
'bbcode_tpl',
|
||||
'bbcode_helpline',
|
||||
'hidden_fields',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_modify_create', compact($vars)));
|
||||
|
||||
$acp_utils = $phpbb_container->get('text_formatter.acp_utils');
|
||||
$bbcode_info = $acp_utils->analyse_bbcode($bbcode_match, $bbcode_tpl);
|
||||
$warn_unsafe = ($bbcode_info['status'] === $acp_utils::BBCODE_STATUS_UNSAFE);
|
||||
|
||||
if ($bbcode_info['status'] === $acp_utils::BBCODE_STATUS_INVALID_TEMPLATE)
|
||||
{
|
||||
trigger_error($user->lang['BBCODE_INVALID_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
if ($bbcode_info['status'] === $acp_utils::BBCODE_STATUS_INVALID_DEFINITION)
|
||||
{
|
||||
trigger_error($user->lang['BBCODE_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
if (!$warn_unsafe && !check_form_key($form_key))
|
||||
{
|
||||
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
if (!$warn_unsafe || confirm_box(true))
|
||||
{
|
||||
$data = $this->build_regexp($bbcode_match, $bbcode_tpl);
|
||||
|
||||
// Make sure the user didn't pick a "bad" name for the BBCode tag.
|
||||
$hard_coded = array('code', 'quote', 'quote=', 'attachment', 'attachment=', 'b', 'i', 'url', 'url=', 'img', 'size', 'size=', 'color', 'color=', 'u', 'list', 'list=', 'email', 'email=', 'flash', 'flash=');
|
||||
|
||||
if (($action == 'modify' && strtolower($data['bbcode_tag']) !== strtolower($row['bbcode_tag'])) || ($action == 'create'))
|
||||
{
|
||||
$sql = 'SELECT 1 as test
|
||||
FROM ' . BBCODES_TABLE . "
|
||||
WHERE LOWER(bbcode_tag) = '" . $db->sql_escape(strtolower($data['bbcode_tag'])) . "'";
|
||||
$result = $db->sql_query($sql);
|
||||
$info = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// Grab the end, interrogate the last closing tag
|
||||
if (isset($info['test']) && $info['test'] === '1'
|
||||
|| in_array(strtolower($data['bbcode_tag']), $hard_coded)
|
||||
|| (preg_match('#\[/([^[]*)]$#', $bbcode_match, $regs) && in_array(strtolower($regs[1]), $hard_coded))
|
||||
)
|
||||
{
|
||||
trigger_error($user->lang['BBCODE_INVALID_TAG_NAME'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if (substr($data['bbcode_tag'], -1) === '=')
|
||||
{
|
||||
$test = substr($data['bbcode_tag'], 0, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$test = $data['bbcode_tag'];
|
||||
}
|
||||
|
||||
if (strlen($data['bbcode_tag']) > 16)
|
||||
{
|
||||
trigger_error($user->lang['BBCODE_TAG_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
if (strlen($bbcode_match) > 4000)
|
||||
{
|
||||
trigger_error($user->lang['BBCODE_TAG_DEF_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
if (strlen($bbcode_helpline) > 255)
|
||||
{
|
||||
trigger_error($user->lang['BBCODE_HELPLINE_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$sql_ary = array_merge($sql_ary, array(
|
||||
'bbcode_tag' => $data['bbcode_tag'],
|
||||
'bbcode_match' => $bbcode_match,
|
||||
'bbcode_tpl' => $bbcode_tpl,
|
||||
'display_on_posting' => $display_on_posting,
|
||||
'bbcode_helpline' => $bbcode_helpline,
|
||||
'first_pass_match' => $data['first_pass_match'],
|
||||
'first_pass_replace' => $data['first_pass_replace'],
|
||||
'second_pass_match' => $data['second_pass_match'],
|
||||
'second_pass_replace' => $data['second_pass_replace']
|
||||
));
|
||||
|
||||
if ($action == 'create')
|
||||
{
|
||||
$sql = 'SELECT MAX(bbcode_id) as max_bbcode_id
|
||||
FROM ' . BBCODES_TABLE;
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($row)
|
||||
{
|
||||
$bbcode_id = (int) $row['max_bbcode_id'] + 1;
|
||||
|
||||
// Make sure it is greater than the core bbcode ids...
|
||||
if ($bbcode_id <= NUM_CORE_BBCODES)
|
||||
{
|
||||
$bbcode_id = NUM_CORE_BBCODES + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$bbcode_id = NUM_CORE_BBCODES + 1;
|
||||
}
|
||||
|
||||
if ($bbcode_id > BBCODE_LIMIT)
|
||||
{
|
||||
trigger_error($user->lang['TOO_MANY_BBCODES'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$sql_ary['bbcode_id'] = (int) $bbcode_id;
|
||||
|
||||
$db->sql_query('INSERT INTO ' . BBCODES_TABLE . $db->sql_build_array('INSERT', $sql_ary));
|
||||
$cache->destroy('sql', BBCODES_TABLE);
|
||||
$phpbb_container->get('text_formatter.cache')->invalidate();
|
||||
|
||||
$lang = 'BBCODE_ADDED';
|
||||
$log_action = 'LOG_BBCODE_ADD';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql = 'UPDATE ' . BBCODES_TABLE . '
|
||||
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
|
||||
WHERE bbcode_id = ' . $bbcode_id;
|
||||
$db->sql_query($sql);
|
||||
$cache->destroy('sql', BBCODES_TABLE);
|
||||
$phpbb_container->get('text_formatter.cache')->invalidate();
|
||||
|
||||
$lang = 'BBCODE_EDITED';
|
||||
$log_action = 'LOG_BBCODE_EDIT';
|
||||
}
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, $log_action, false, array($data['bbcode_tag']));
|
||||
|
||||
/**
|
||||
* Event after a BBCode has been added or updated
|
||||
*
|
||||
* @event core.acp_bbcodes_modify_create_after
|
||||
* @var string action Type of the action: modify|create
|
||||
* @var int bbcode_id The id of the added or updated bbcode
|
||||
* @var array sql_ary Array with bbcode data (read only)
|
||||
* @since 3.2.4-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'action',
|
||||
'bbcode_id',
|
||||
'sql_ary',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_modify_create_after', compact($vars)));
|
||||
|
||||
trigger_error($user->lang[$lang] . adm_back_link($this->u_action));
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, $user->lang['BBCODE_DANGER'], build_hidden_fields(array_merge($hidden_fields, array(
|
||||
'action' => $action,
|
||||
'bbcode' => $bbcode_id,
|
||||
'bbcode_match' => $bbcode_match,
|
||||
'bbcode_tpl' => htmlspecialchars($bbcode_tpl),
|
||||
'bbcode_helpline' => $bbcode_helpline,
|
||||
'display_on_posting' => $display_on_posting,
|
||||
)))
|
||||
, 'confirm_bbcode.html');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
|
||||
$sql = 'SELECT bbcode_tag
|
||||
FROM ' . BBCODES_TABLE . "
|
||||
WHERE bbcode_id = $bbcode_id";
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($row)
|
||||
{
|
||||
if (confirm_box(true))
|
||||
{
|
||||
$bbcode_tag = $row['bbcode_tag'];
|
||||
|
||||
$db->sql_query('DELETE FROM ' . BBCODES_TABLE . " WHERE bbcode_id = $bbcode_id");
|
||||
$cache->destroy('sql', BBCODES_TABLE);
|
||||
$phpbb_container->get('text_formatter.cache')->invalidate();
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_BBCODE_DELETE', false, array($bbcode_tag));
|
||||
|
||||
/**
|
||||
* Event after a BBCode has been deleted
|
||||
*
|
||||
* @event core.acp_bbcodes_delete_after
|
||||
* @var string action Type of the action: delete
|
||||
* @var int bbcode_id The id of the deleted bbcode
|
||||
* @var string bbcode_tag The tag of the deleted bbcode
|
||||
* @since 3.2.4-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'action',
|
||||
'bbcode_id',
|
||||
'bbcode_tag',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_delete_after', compact($vars)));
|
||||
|
||||
if ($request->is_ajax())
|
||||
{
|
||||
$json_response = new \phpbb\json_response;
|
||||
$json_response->send(array(
|
||||
'MESSAGE_TITLE' => $user->lang['INFORMATION'],
|
||||
'MESSAGE_TEXT' => $user->lang['BBCODE_DELETED'],
|
||||
'REFRESH_DATA' => array(
|
||||
'time' => 3
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
|
||||
'bbcode' => $bbcode_id,
|
||||
'i' => $id,
|
||||
'mode' => $mode,
|
||||
'action' => $action))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$u_action = $this->u_action;
|
||||
|
||||
$template_data = array(
|
||||
'U_ACTION' => $this->u_action . '&action=add',
|
||||
);
|
||||
|
||||
$sql_ary = array(
|
||||
'SELECT' => 'b.*',
|
||||
'FROM' => array(BBCODES_TABLE => 'b'),
|
||||
'ORDER_BY' => 'b.bbcode_tag',
|
||||
);
|
||||
|
||||
/**
|
||||
* Modify custom bbcode template data before we display the form
|
||||
*
|
||||
* @event core.acp_bbcodes_display_form
|
||||
* @var string action Type of the action: modify|create
|
||||
* @var array sql_ary The SQL array to get custom bbcode data
|
||||
* @var array template_data Array with form template data
|
||||
* @var string u_action The u_action link
|
||||
* @since 3.1.0-a3
|
||||
*/
|
||||
$vars = array('action', 'sql_ary', 'template_data', 'u_action');
|
||||
extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_display_form', compact($vars)));
|
||||
|
||||
$result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary));
|
||||
|
||||
$template->assign_vars($template_data);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$bbcodes_array = array(
|
||||
'BBCODE_TAG' => $row['bbcode_tag'],
|
||||
'U_EDIT' => $u_action . '&action=edit&bbcode=' . $row['bbcode_id'],
|
||||
'U_DELETE' => $u_action . '&action=delete&bbcode=' . $row['bbcode_id'],
|
||||
);
|
||||
|
||||
/**
|
||||
* Modify display of custom bbcodes in the form
|
||||
*
|
||||
* @event core.acp_bbcodes_display_bbcodes
|
||||
* @var array row Array with current bbcode data
|
||||
* @var array bbcodes_array Array of bbcodes template data
|
||||
* @var string u_action The u_action link
|
||||
* @since 3.1.0-a3
|
||||
*/
|
||||
$vars = array('bbcodes_array', 'row', 'u_action');
|
||||
extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_display_bbcodes', compact($vars)));
|
||||
|
||||
$template->assign_block_vars('bbcodes', $bbcodes_array);
|
||||
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build regular expression for custom bbcode
|
||||
*/
|
||||
function build_regexp(&$bbcode_match, &$bbcode_tpl)
|
||||
{
|
||||
$bbcode_match = trim($bbcode_match);
|
||||
$bbcode_tag = preg_replace('/.*?\[([a-z0-9_-]+).*/i', '$1', $bbcode_match);
|
||||
|
||||
if (!preg_match('/^[a-zA-Z0-9_-]+$/', $bbcode_tag))
|
||||
{
|
||||
global $user;
|
||||
trigger_error($user->lang['BBCODE_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
return array(
|
||||
'bbcode_tag' => $bbcode_tag,
|
||||
'first_pass_match' => '/(?!)/',
|
||||
'first_pass_replace' => '',
|
||||
// Use a non-matching, valid regexp to effectively disable this BBCode
|
||||
'second_pass_match' => '/(?!)/',
|
||||
'second_pass_replace' => ''
|
||||
);
|
||||
}
|
||||
}
|
||||
1172
install/update/new/includes/acp/acp_board.php
Normal file
1172
install/update/new/includes/acp/acp_board.php
Normal file
File diff suppressed because it is too large
Load Diff
616
install/update/new/includes/acp/acp_database.php
Normal file
616
install/update/new/includes/acp/acp_database.php
Normal file
@@ -0,0 +1,616 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
class acp_database
|
||||
{
|
||||
var $db_tools;
|
||||
var $u_action;
|
||||
public $page_title;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $cache, $db, $user, $template, $table_prefix, $request;
|
||||
global $phpbb_root_path, $phpbb_container, $phpbb_log;
|
||||
|
||||
$this->db_tools = $phpbb_container->get('dbal.tools');
|
||||
|
||||
$user->add_lang('acp/database');
|
||||
|
||||
$this->tpl_name = 'acp_database';
|
||||
$this->page_title = 'ACP_DATABASE';
|
||||
|
||||
$action = $request->variable('action', '');
|
||||
|
||||
$form_key = 'acp_database';
|
||||
add_form_key($form_key);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'MODE' => $mode
|
||||
));
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case 'backup':
|
||||
|
||||
$this->page_title = 'ACP_BACKUP';
|
||||
|
||||
switch ($action)
|
||||
{
|
||||
case 'download':
|
||||
$type = $request->variable('type', '');
|
||||
$table = array_intersect($this->db_tools->sql_list_tables(), $request->variable('table', array('')));
|
||||
$format = $request->variable('method', '');
|
||||
|
||||
if (!count($table))
|
||||
{
|
||||
trigger_error($user->lang['TABLE_SELECT_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
if (!check_form_key($form_key))
|
||||
{
|
||||
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$store = true;
|
||||
$structure = false;
|
||||
$schema_data = false;
|
||||
|
||||
if ($type == 'full' || $type == 'structure')
|
||||
{
|
||||
$structure = true;
|
||||
}
|
||||
|
||||
if ($type == 'full' || $type == 'data')
|
||||
{
|
||||
$schema_data = true;
|
||||
}
|
||||
|
||||
@set_time_limit(1200);
|
||||
@set_time_limit(0);
|
||||
|
||||
$time = time();
|
||||
|
||||
$filename = 'backup_' . $time . '_' . unique_id();
|
||||
|
||||
/** @var phpbb\db\extractor\extractor_interface $extractor Database extractor */
|
||||
$extractor = $phpbb_container->get('dbal.extractor');
|
||||
$extractor->init_extractor($format, $filename, $time, false, $store);
|
||||
|
||||
$extractor->write_start($table_prefix);
|
||||
|
||||
foreach ($table as $table_name)
|
||||
{
|
||||
// Get the table structure
|
||||
if ($structure)
|
||||
{
|
||||
$extractor->write_table($table_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We might wanna empty out all that junk :D
|
||||
switch ($db->get_sql_layer())
|
||||
{
|
||||
case 'sqlite3':
|
||||
$extractor->flush('DELETE FROM ' . $table_name . ";\n");
|
||||
break;
|
||||
|
||||
case 'mssql_odbc':
|
||||
case 'mssqlnative':
|
||||
$extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n");
|
||||
break;
|
||||
|
||||
case 'oracle':
|
||||
$extractor->flush('TRUNCATE TABLE ' . $table_name . "/\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
$extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Data
|
||||
if ($schema_data)
|
||||
{
|
||||
$extractor->write_data($table_name);
|
||||
}
|
||||
}
|
||||
|
||||
$extractor->write_end();
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_BACKUP');
|
||||
|
||||
trigger_error($user->lang['BACKUP_SUCCESS'] . adm_back_link($this->u_action));
|
||||
break;
|
||||
|
||||
default:
|
||||
$tables = $this->db_tools->sql_list_tables();
|
||||
asort($tables);
|
||||
foreach ($tables as $table_name)
|
||||
{
|
||||
if (strlen($table_prefix) === 0 || stripos($table_name, $table_prefix) === 0)
|
||||
{
|
||||
$template->assign_block_vars('tables', array(
|
||||
'TABLE' => $table_name
|
||||
));
|
||||
}
|
||||
}
|
||||
unset($tables);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_ACTION' => $this->u_action . '&action=download'
|
||||
));
|
||||
|
||||
$available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2');
|
||||
|
||||
foreach ($available_methods as $type => $module)
|
||||
{
|
||||
if (!@extension_loaded($module))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$template->assign_block_vars('methods', array(
|
||||
'TYPE' => $type
|
||||
));
|
||||
}
|
||||
|
||||
$template->assign_block_vars('methods', array(
|
||||
'TYPE' => 'text'
|
||||
));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'restore':
|
||||
|
||||
$this->page_title = 'ACP_RESTORE';
|
||||
|
||||
switch ($action)
|
||||
{
|
||||
case 'submit':
|
||||
$delete = $request->variable('delete', '');
|
||||
$file = $request->variable('file', '');
|
||||
|
||||
$backup_info = $this->get_backup_file($phpbb_root_path . 'store/', $file);
|
||||
|
||||
if (empty($backup_info) || !is_readable($backup_info['file_name']))
|
||||
{
|
||||
trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
if ($delete)
|
||||
{
|
||||
if (confirm_box(true))
|
||||
{
|
||||
unlink($backup_info['file_name']);
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_DELETE');
|
||||
trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action));
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file)));
|
||||
}
|
||||
}
|
||||
else if (confirm_box(true))
|
||||
{
|
||||
switch ($backup_info['extension'])
|
||||
{
|
||||
case 'sql':
|
||||
$fp = fopen($backup_info['file_name'], 'rb');
|
||||
$read = 'fread';
|
||||
$seek = 'fseek';
|
||||
$eof = 'feof';
|
||||
$close = 'fclose';
|
||||
$fgetd = 'fgetd';
|
||||
break;
|
||||
|
||||
case 'sql.bz2':
|
||||
$fp = bzopen($backup_info['file_name'], 'r');
|
||||
$read = 'bzread';
|
||||
$seek = '';
|
||||
$eof = 'feof';
|
||||
$close = 'bzclose';
|
||||
$fgetd = 'fgetd_seekless';
|
||||
break;
|
||||
|
||||
case 'sql.gz':
|
||||
$fp = gzopen($backup_info['file_name'], 'rb');
|
||||
$read = 'gzread';
|
||||
$seek = 'gzseek';
|
||||
$eof = 'gzeof';
|
||||
$close = 'gzclose';
|
||||
$fgetd = 'fgetd';
|
||||
break;
|
||||
|
||||
default:
|
||||
trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($db->get_sql_layer())
|
||||
{
|
||||
case 'mysqli':
|
||||
case 'sqlite3':
|
||||
while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
|
||||
{
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'postgres':
|
||||
$delim = ";\n";
|
||||
while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
|
||||
{
|
||||
$query = trim($sql);
|
||||
|
||||
if (substr($query, 0, 13) == 'CREATE DOMAIN')
|
||||
{
|
||||
list(, , $domain) = explode(' ', $query);
|
||||
$sql = "SELECT domain_name
|
||||
FROM information_schema.domains
|
||||
WHERE domain_name = '$domain';";
|
||||
$result = $db->sql_query($sql);
|
||||
if (!$db->sql_fetchrow($result))
|
||||
{
|
||||
$db->sql_query($query);
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
else
|
||||
{
|
||||
$db->sql_query($query);
|
||||
}
|
||||
|
||||
if (substr($query, 0, 4) == 'COPY')
|
||||
{
|
||||
while (($sub = $fgetd($fp, "\n", $read, $seek, $eof)) !== '\.')
|
||||
{
|
||||
if ($sub === false)
|
||||
{
|
||||
trigger_error($user->lang['RESTORE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
pg_put_line($db->get_db_connect_id(), $sub . "\n");
|
||||
}
|
||||
pg_put_line($db->get_db_connect_id(), "\\.\n");
|
||||
pg_end_copy($db->get_db_connect_id());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'oracle':
|
||||
while (($sql = $fgetd($fp, "/\n", $read, $seek, $eof)) !== false)
|
||||
{
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'mssql_odbc':
|
||||
case 'mssqlnative':
|
||||
while (($sql = $fgetd($fp, "GO\n", $read, $seek, $eof)) !== false)
|
||||
{
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$close($fp);
|
||||
|
||||
// Purge the cache due to updated data
|
||||
$cache->purge();
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_RESTORE');
|
||||
trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action));
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, $user->lang['RESTORE_SELECTED_BACKUP'], build_hidden_fields(array('file' => $file)));
|
||||
}
|
||||
|
||||
default:
|
||||
$backup_files = $this->get_file_list($phpbb_root_path . 'store/');
|
||||
|
||||
if (!empty($backup_files))
|
||||
{
|
||||
krsort($backup_files);
|
||||
|
||||
foreach ($backup_files as $name => $file)
|
||||
{
|
||||
$template->assign_block_vars('files', array(
|
||||
'FILE' => sha1($file),
|
||||
'NAME' => $user->format_date($name, 'd-m-Y H:i', true),
|
||||
'SUPPORTED' => true,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_ACTION' => $this->u_action . '&action=submit'
|
||||
));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get backup file from file hash
|
||||
*
|
||||
* @param string $directory Relative path to directory
|
||||
* @param string $file_hash Hash of selected file
|
||||
*
|
||||
* @return array Backup file data or empty array if unable to find file
|
||||
*/
|
||||
protected function get_backup_file($directory, $file_hash)
|
||||
{
|
||||
$backup_data = [];
|
||||
|
||||
$file_list = $this->get_file_list($directory);
|
||||
$supported_extensions = $this->get_supported_extensions();
|
||||
|
||||
foreach ($file_list as $file)
|
||||
{
|
||||
preg_match('#^backup_(\d{10,})_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $file, $matches);
|
||||
if (sha1($file) === $file_hash && in_array($matches[2], $supported_extensions))
|
||||
{
|
||||
$backup_data = [
|
||||
'file_name' => $directory . $file,
|
||||
'extension' => $matches[2],
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $backup_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get backup file list for directory
|
||||
*
|
||||
* @param string $directory Relative path to backup directory
|
||||
*
|
||||
* @return array List of backup files in specified directory
|
||||
*/
|
||||
protected function get_file_list($directory)
|
||||
{
|
||||
$supported_extensions = $this->get_supported_extensions();
|
||||
|
||||
$dh = @opendir($directory);
|
||||
|
||||
$backup_files = [];
|
||||
|
||||
if ($dh)
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
if (preg_match('#^backup_(\d{10,})_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $file, $matches))
|
||||
{
|
||||
if (in_array($matches[2], $supported_extensions))
|
||||
{
|
||||
$backup_files[(int) $matches[1]] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
|
||||
return $backup_files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get supported extensions for backup
|
||||
*
|
||||
* @return array List of supported extensions
|
||||
*/
|
||||
protected function get_supported_extensions()
|
||||
{
|
||||
$extensions = ['sql'];
|
||||
$available_methods = ['sql.gz' => 'zlib', 'sql.bz2' => 'bz2'];
|
||||
|
||||
foreach ($available_methods as $type => $module)
|
||||
{
|
||||
if (!@extension_loaded($module))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$extensions[] = $type;
|
||||
}
|
||||
|
||||
return $extensions;
|
||||
}
|
||||
}
|
||||
|
||||
// get how much space we allow for a chunk of data, very similar to phpMyAdmin's way of doing things ;-) (hey, we only do this for MySQL anyway :P)
|
||||
function get_usable_memory()
|
||||
{
|
||||
$val = trim(@ini_get('memory_limit'));
|
||||
|
||||
if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs))
|
||||
{
|
||||
$memory_limit = (int) $regs[1];
|
||||
switch ($regs[2])
|
||||
{
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
$memory_limit *= 1024;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
$memory_limit *= 1048576;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
case 'G':
|
||||
$memory_limit *= 1073741824;
|
||||
break;
|
||||
}
|
||||
|
||||
// how much memory PHP requires at the start of export (it is really a little less)
|
||||
if ($memory_limit > 6100000)
|
||||
{
|
||||
$memory_limit -= 6100000;
|
||||
}
|
||||
|
||||
// allow us to consume half of the total memory available
|
||||
$memory_limit /= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the buffer to 1M if we have no clue how much memory PHP will give us :P
|
||||
$memory_limit = 1048576;
|
||||
}
|
||||
|
||||
return $memory_limit;
|
||||
}
|
||||
|
||||
function sanitize_data_mssql($text)
|
||||
{
|
||||
$data = preg_split('/[\n\t\r\b\f]/', $text);
|
||||
preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
|
||||
|
||||
$val = array();
|
||||
|
||||
foreach ($data as $value)
|
||||
{
|
||||
if (strlen($value))
|
||||
{
|
||||
$val[] = "'" . $value . "'";
|
||||
}
|
||||
if (count($matches[0]))
|
||||
{
|
||||
$val[] = 'char(' . ord(array_shift($matches[0])) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
return implode('+', $val);
|
||||
}
|
||||
|
||||
function sanitize_data_oracle($text)
|
||||
{
|
||||
// $data = preg_split('/[\0\n\t\r\b\f\'"\/\\\]/', $text);
|
||||
// preg_match_all('/[\0\n\t\r\b\f\'"\/\\\]/', $text, $matches);
|
||||
$data = preg_split('/[\0\b\f\'\/]/', $text);
|
||||
preg_match_all('/[\0\r\b\f\'\/]/', $text, $matches);
|
||||
|
||||
$val = array();
|
||||
|
||||
foreach ($data as $value)
|
||||
{
|
||||
if (strlen($value))
|
||||
{
|
||||
$val[] = "'" . $value . "'";
|
||||
}
|
||||
if (count($matches[0]))
|
||||
{
|
||||
$val[] = 'chr(' . ord(array_shift($matches[0])) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
return implode('||', $val);
|
||||
}
|
||||
|
||||
function sanitize_data_generic($text)
|
||||
{
|
||||
$data = preg_split('/[\n\t\r\b\f]/', $text);
|
||||
preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
|
||||
|
||||
$val = array();
|
||||
|
||||
foreach ($data as $value)
|
||||
{
|
||||
if (strlen($value))
|
||||
{
|
||||
$val[] = "'" . $value . "'";
|
||||
}
|
||||
if (count($matches[0]))
|
||||
{
|
||||
$val[] = "'" . array_shift($matches[0]) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
return implode('||', $val);
|
||||
}
|
||||
|
||||
// modified from PHP.net
|
||||
function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
|
||||
{
|
||||
$record = '';
|
||||
$delim_len = strlen($delim);
|
||||
|
||||
while (!$eof($fp))
|
||||
{
|
||||
$pos = strpos($record, $delim);
|
||||
if ($pos === false)
|
||||
{
|
||||
$record .= $read($fp, $buffer);
|
||||
if ($eof($fp) && ($pos = strpos($record, $delim)) !== false)
|
||||
{
|
||||
$seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
|
||||
return substr($record, 0, $pos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
|
||||
return substr($record, 0, $pos);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function fgetd_seekless(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
|
||||
{
|
||||
static $array = array();
|
||||
static $record = '';
|
||||
|
||||
if (!count($array))
|
||||
{
|
||||
while (!$eof($fp))
|
||||
{
|
||||
if (strpos($record, $delim) !== false)
|
||||
{
|
||||
$array = explode($delim, $record);
|
||||
$record = array_pop($array);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
$record .= $read($fp, $buffer);
|
||||
}
|
||||
}
|
||||
if ($eof($fp) && strpos($record, $delim) !== false)
|
||||
{
|
||||
$array = explode($delim, $record);
|
||||
$record = array_pop($array);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($array))
|
||||
{
|
||||
return array_shift($array);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
771
install/update/new/includes/acp/acp_extensions.php
Normal file
771
install/update/new/includes/acp/acp_extensions.php
Normal file
@@ -0,0 +1,771 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
use phpbb\exception\exception_interface;
|
||||
use phpbb\exception\version_check_exception;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
class acp_extensions
|
||||
{
|
||||
var $u_action;
|
||||
var $tpl_name;
|
||||
var $page_title;
|
||||
|
||||
private $config;
|
||||
private $template;
|
||||
private $user;
|
||||
private $log;
|
||||
private $request;
|
||||
private $phpbb_dispatcher;
|
||||
private $ext_manager;
|
||||
private $phpbb_container;
|
||||
private $php_ini;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
// Start the page
|
||||
global $config, $user, $template, $request, $phpbb_extension_manager, $phpbb_root_path, $phpbb_log, $phpbb_dispatcher, $phpbb_container;
|
||||
|
||||
$this->config = $config;
|
||||
$this->template = $template;
|
||||
$this->user = $user;
|
||||
$this->request = $request;
|
||||
$this->log = $phpbb_log;
|
||||
$this->phpbb_dispatcher = $phpbb_dispatcher;
|
||||
$this->ext_manager = $phpbb_extension_manager;
|
||||
$this->phpbb_container = $phpbb_container;
|
||||
$this->php_ini = $this->phpbb_container->get('php_ini');
|
||||
|
||||
$this->user->add_lang(array('install', 'acp/extensions', 'migrator'));
|
||||
|
||||
$this->page_title = 'ACP_EXTENSIONS';
|
||||
|
||||
$action = $this->request->variable('action', 'list');
|
||||
$ext_name = $this->request->variable('ext_name', '');
|
||||
|
||||
// What is a safe limit of execution time? Half the max execution time should be safe.
|
||||
$safe_time_limit = ($this->php_ini->getNumeric('max_execution_time') / 2);
|
||||
$start_time = time();
|
||||
|
||||
// Cancel action
|
||||
if ($this->request->is_set_post('cancel'))
|
||||
{
|
||||
$action = 'list';
|
||||
$ext_name = '';
|
||||
}
|
||||
|
||||
if (in_array($action, array('enable', 'disable', 'delete_data')) && !check_link_hash($this->request->variable('hash', ''), $action . '.' . $ext_name))
|
||||
{
|
||||
trigger_error('FORM_INVALID', E_USER_WARNING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Event to run a specific action on extension
|
||||
*
|
||||
* @event core.acp_extensions_run_action_before
|
||||
* @var string action Action to run; if the event completes execution of the action, should be set to 'none'
|
||||
* @var string u_action Url we are at
|
||||
* @var string ext_name Extension name from request
|
||||
* @var int safe_time_limit Safe limit of execution time
|
||||
* @var int start_time Start time
|
||||
* @var string tpl_name Template file to load
|
||||
* @since 3.1.11-RC1
|
||||
* @changed 3.2.1-RC1 Renamed to core.acp_extensions_run_action_before, added tpl_name, added action 'none'
|
||||
*/
|
||||
$u_action = $this->u_action;
|
||||
$tpl_name = '';
|
||||
$vars = array('action', 'u_action', 'ext_name', 'safe_time_limit', 'start_time', 'tpl_name');
|
||||
extract($this->phpbb_dispatcher->trigger_event('core.acp_extensions_run_action_before', compact($vars)));
|
||||
|
||||
// In case they have been updated by the event
|
||||
$this->u_action = $u_action;
|
||||
$this->tpl_name = $tpl_name;
|
||||
|
||||
// If they've specified an extension, let's load the metadata manager and validate it.
|
||||
if ($ext_name)
|
||||
{
|
||||
$md_manager = $this->ext_manager->create_extension_metadata_manager($ext_name);
|
||||
|
||||
try
|
||||
{
|
||||
$md_manager->get_metadata('all');
|
||||
}
|
||||
catch (exception_interface $e)
|
||||
{
|
||||
$message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
|
||||
trigger_error($message . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
// What are we doing?
|
||||
switch ($action)
|
||||
{
|
||||
case 'none':
|
||||
// Intentionally empty, used by extensions that execute additional actions in the prior event
|
||||
break;
|
||||
|
||||
case 'set_config_version_check_force_unstable':
|
||||
$force_unstable = $this->request->variable('force_unstable', false);
|
||||
|
||||
if ($force_unstable)
|
||||
{
|
||||
$s_hidden_fields = build_hidden_fields(array(
|
||||
'force_unstable' => $force_unstable,
|
||||
));
|
||||
|
||||
confirm_box(false, $this->user->lang('EXTENSION_FORCE_UNSTABLE_CONFIRM'), $s_hidden_fields);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->config->set('extension_force_unstable', false);
|
||||
trigger_error($this->user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'list':
|
||||
default:
|
||||
if (confirm_box(true))
|
||||
{
|
||||
$this->config->set('extension_force_unstable', true);
|
||||
trigger_error($this->user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
|
||||
}
|
||||
|
||||
$this->list_enabled_exts();
|
||||
$this->list_disabled_exts();
|
||||
$this->list_available_exts();
|
||||
|
||||
$this->template->assign_vars(array(
|
||||
'U_VERSIONCHECK_FORCE' => $this->u_action . '&action=list&versioncheck_force=1',
|
||||
'FORCE_UNSTABLE' => $this->config['extension_force_unstable'],
|
||||
'U_ACTION' => $this->u_action,
|
||||
));
|
||||
|
||||
$this->tpl_name = 'acp_ext_list';
|
||||
break;
|
||||
|
||||
case 'enable_pre':
|
||||
try
|
||||
{
|
||||
$md_manager->validate_enable();
|
||||
}
|
||||
catch (exception_interface $e)
|
||||
{
|
||||
$message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
|
||||
trigger_error($message . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$extension = $this->ext_manager->get_extension($ext_name);
|
||||
|
||||
$this->check_is_enableable($extension);
|
||||
|
||||
if ($this->ext_manager->is_enabled($ext_name))
|
||||
{
|
||||
redirect($this->u_action);
|
||||
}
|
||||
|
||||
if (confirm_box(true))
|
||||
{
|
||||
redirect($this->u_action . '&action=enable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('enable.' . $ext_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, $this->user->lang('EXTENSION_ENABLE_CONFIRM', $md_manager->get_metadata('display-name')), build_hidden_fields(array(
|
||||
'i' => $id,
|
||||
'mode' => $mode,
|
||||
'action' => 'enable_pre',
|
||||
'ext_name' => $ext_name,
|
||||
)));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'enable':
|
||||
try
|
||||
{
|
||||
$md_manager->validate_enable();
|
||||
}
|
||||
catch (exception_interface $e)
|
||||
{
|
||||
$message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
|
||||
trigger_error($message . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$extension = $this->ext_manager->get_extension($ext_name);
|
||||
|
||||
$this->check_is_enableable($extension);
|
||||
|
||||
try
|
||||
{
|
||||
while ($this->ext_manager->enable_step($ext_name))
|
||||
{
|
||||
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
|
||||
if ((time() - $start_time) >= $safe_time_limit)
|
||||
{
|
||||
meta_refresh(0, $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('enable.' . $ext_name));
|
||||
trigger_error('EXTENSION_ENABLE_IN_PROGRESS', E_USER_NOTICE);
|
||||
}
|
||||
}
|
||||
|
||||
// Update custom style for admin area
|
||||
$this->template->set_custom_style(array(
|
||||
array(
|
||||
'name' => 'adm',
|
||||
'ext_path' => 'adm/style/',
|
||||
),
|
||||
), array($phpbb_root_path . 'adm/style'));
|
||||
|
||||
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_EXT_ENABLE', time(), array($ext_name));
|
||||
}
|
||||
catch (\phpbb\db\migration\exception $e)
|
||||
{
|
||||
trigger_error($this->user->lang('MIGRATION_EXCEPTION_ERROR', $e->getLocalisedMessage($this->user)), E_USER_WARNING);
|
||||
}
|
||||
|
||||
if ($this->request->is_ajax())
|
||||
{
|
||||
$actions = $this->output_actions('enabled', [
|
||||
'DISABLE' => $this->u_action . '&action=disable_pre&ext_name=' . urlencode($ext_name),
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'EXT_ENABLE_SUCCESS' => true,
|
||||
'ACTIONS' => $actions,
|
||||
'REFRESH_DATA' => [
|
||||
'url' => '',
|
||||
'time' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
$json_response = new \phpbb\json_response;
|
||||
$json_response->send($data);
|
||||
}
|
||||
|
||||
trigger_error($this->user->lang('EXTENSION_ENABLE_SUCCESS') . adm_back_link($this->u_action), E_USER_NOTICE);
|
||||
break;
|
||||
|
||||
case 'disable_pre':
|
||||
if (!$this->ext_manager->is_enabled($ext_name))
|
||||
{
|
||||
redirect($this->u_action);
|
||||
}
|
||||
|
||||
if (confirm_box(true))
|
||||
{
|
||||
redirect($this->u_action . '&action=disable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('disable.' . $ext_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, $this->user->lang('EXTENSION_DISABLE_CONFIRM', $md_manager->get_metadata('display-name')), build_hidden_fields(array(
|
||||
'i' => $id,
|
||||
'mode' => $mode,
|
||||
'action' => 'disable_pre',
|
||||
'ext_name' => $ext_name,
|
||||
)));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'disable':
|
||||
if (!$this->ext_manager->is_enabled($ext_name))
|
||||
{
|
||||
redirect($this->u_action);
|
||||
}
|
||||
|
||||
while ($this->ext_manager->disable_step($ext_name))
|
||||
{
|
||||
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
|
||||
if ((time() - $start_time) >= $safe_time_limit)
|
||||
{
|
||||
$this->template->assign_var('S_NEXT_STEP', true);
|
||||
|
||||
meta_refresh(0, $this->u_action . '&action=disable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('disable.' . $ext_name));
|
||||
trigger_error('EXTENSION_DISABLE_IN_PROGRESS', E_USER_NOTICE);
|
||||
}
|
||||
}
|
||||
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_EXT_DISABLE', time(), array($ext_name));
|
||||
|
||||
if ($this->request->is_ajax())
|
||||
{
|
||||
$actions = $this->output_actions('disabled', [
|
||||
'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($ext_name),
|
||||
'DELETE_DATA' => $this->u_action . '&action=delete_data_pre&ext_name=' . urlencode($ext_name),
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'EXT_DISABLE_SUCCESS' => true,
|
||||
'ACTIONS' => $actions,
|
||||
'REFRESH_DATA' => [
|
||||
'url' => '',
|
||||
'time' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
$json_response = new \phpbb\json_response;
|
||||
$json_response->send($data);
|
||||
}
|
||||
|
||||
trigger_error($this->user->lang('EXTENSION_DISABLE_SUCCESS') . adm_back_link($this->u_action), E_USER_NOTICE);
|
||||
break;
|
||||
|
||||
case 'delete_data_pre':
|
||||
if ($this->ext_manager->is_enabled($ext_name))
|
||||
{
|
||||
redirect($this->u_action);
|
||||
}
|
||||
|
||||
if (confirm_box(true))
|
||||
{
|
||||
redirect($this->u_action . '&action=delete_data&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('delete_data.' . $ext_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, $this->user->lang('EXTENSION_DELETE_DATA_CONFIRM', $md_manager->get_metadata('display-name')), build_hidden_fields(array(
|
||||
'i' => $id,
|
||||
'mode' => $mode,
|
||||
'action' => 'delete_data_pre',
|
||||
'ext_name' => $ext_name,
|
||||
)));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'delete_data':
|
||||
if ($this->ext_manager->is_enabled($ext_name))
|
||||
{
|
||||
redirect($this->u_action);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
while ($this->ext_manager->purge_step($ext_name))
|
||||
{
|
||||
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
|
||||
if ((time() - $start_time) >= $safe_time_limit)
|
||||
{
|
||||
$this->template->assign_var('S_NEXT_STEP', true);
|
||||
|
||||
meta_refresh(0, $this->u_action . '&action=delete_data&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('delete_data.' . $ext_name));
|
||||
trigger_error('EXTENSION_DELETE_DATA_IN_PROGRESS', E_USER_NOTICE);
|
||||
}
|
||||
}
|
||||
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_EXT_PURGE', time(), array($ext_name));
|
||||
}
|
||||
catch (\phpbb\db\migration\exception $e)
|
||||
{
|
||||
trigger_error($this->user->lang('MIGRATION_EXCEPTION_ERROR', $e->getLocalisedMessage($this->user)), E_USER_WARNING);
|
||||
}
|
||||
|
||||
if ($this->request->is_ajax())
|
||||
{
|
||||
$actions = $this->output_actions('disabled', [
|
||||
'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($ext_name),
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'EXT_DELETE_DATA_SUCCESS' => true,
|
||||
'ACTIONS' => $actions,
|
||||
'REFRESH_DATA' => [
|
||||
'url' => '',
|
||||
'time' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
$json_response = new \phpbb\json_response;
|
||||
$json_response->send($data);
|
||||
}
|
||||
|
||||
trigger_error($this->user->lang('EXTENSION_DELETE_DATA_SUCCESS') . adm_back_link($this->u_action), E_USER_NOTICE);
|
||||
break;
|
||||
|
||||
case 'details':
|
||||
// Output it to the template
|
||||
$meta = $md_manager->get_metadata('all');
|
||||
$this->output_metadata_to_template($meta);
|
||||
|
||||
if (isset($meta['extra']['version-check']))
|
||||
{
|
||||
try
|
||||
{
|
||||
$updates_available = $this->ext_manager->version_check($md_manager, $this->request->variable('versioncheck_force', false), false, $this->config['extension_force_unstable'] ? 'unstable' : null);
|
||||
|
||||
$this->template->assign_vars(array(
|
||||
'S_UP_TO_DATE' => empty($updates_available),
|
||||
'UP_TO_DATE_MSG' => $this->user->lang(empty($updates_available) ? 'UP_TO_DATE' : 'NOT_UP_TO_DATE', $md_manager->get_metadata('display-name')),
|
||||
));
|
||||
|
||||
$this->template->assign_block_vars('updates_available', $updates_available);
|
||||
}
|
||||
catch (exception_interface $e)
|
||||
{
|
||||
$message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
|
||||
|
||||
$this->template->assign_vars(array(
|
||||
'S_VERSIONCHECK_FAIL' => true,
|
||||
'VERSIONCHECK_FAIL_REASON' => ($e->getMessage() !== 'VERSIONCHECK_FAIL') ? $message : '',
|
||||
));
|
||||
}
|
||||
$this->template->assign_var('S_VERSIONCHECK', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->template->assign_var('S_VERSIONCHECK', false);
|
||||
}
|
||||
|
||||
$this->template->assign_vars(array(
|
||||
'U_BACK' => $this->u_action . '&action=list',
|
||||
'U_VERSIONCHECK_FORCE' => $this->u_action . '&action=details&versioncheck_force=1&ext_name=' . urlencode($md_manager->get_metadata('name')),
|
||||
));
|
||||
|
||||
$this->tpl_name = 'acp_ext_details';
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event to run after a specific action on extension has completed
|
||||
*
|
||||
* @event core.acp_extensions_run_action_after
|
||||
* @var string action Action that has run
|
||||
* @var string u_action Url we are at
|
||||
* @var string ext_name Extension name from request
|
||||
* @var int safe_time_limit Safe limit of execution time
|
||||
* @var int start_time Start time
|
||||
* @var string tpl_name Template file to load
|
||||
* @since 3.1.11-RC1
|
||||
*/
|
||||
$u_action = $this->u_action;
|
||||
$tpl_name = $this->tpl_name;
|
||||
$vars = array('action', 'u_action', 'ext_name', 'safe_time_limit', 'start_time', 'tpl_name');
|
||||
extract($this->phpbb_dispatcher->trigger_event('core.acp_extensions_run_action_after', compact($vars)));
|
||||
|
||||
// In case they have been updated by the event
|
||||
$this->u_action = $u_action;
|
||||
$this->tpl_name = $tpl_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all the enabled extensions and dumps to the template
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function list_enabled_exts()
|
||||
{
|
||||
$enabled_extension_meta_data = array();
|
||||
|
||||
foreach ($this->ext_manager->all_enabled() as $name => $location)
|
||||
{
|
||||
$md_manager = $this->ext_manager->create_extension_metadata_manager($name);
|
||||
|
||||
try
|
||||
{
|
||||
$meta = $md_manager->get_metadata('all');
|
||||
$enabled_extension_meta_data[$name] = array(
|
||||
'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'),
|
||||
'META_VERSION' => $meta['version'],
|
||||
);
|
||||
|
||||
if (isset($meta['extra']['version-check']))
|
||||
{
|
||||
try
|
||||
{
|
||||
$force_update = $this->request->variable('versioncheck_force', false);
|
||||
$updates = $this->ext_manager->version_check($md_manager, $force_update, !$force_update);
|
||||
|
||||
$enabled_extension_meta_data[$name]['S_UP_TO_DATE'] = empty($updates);
|
||||
$enabled_extension_meta_data[$name]['S_VERSIONCHECK'] = true;
|
||||
$enabled_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&action=details&versioncheck_force=1&ext_name=' . urlencode($md_manager->get_metadata('name'));
|
||||
}
|
||||
catch (exception_interface $e)
|
||||
{
|
||||
// Ignore exceptions due to the version check
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$enabled_extension_meta_data[$name]['S_VERSIONCHECK'] = false;
|
||||
}
|
||||
}
|
||||
catch (exception_interface $e)
|
||||
{
|
||||
$message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
|
||||
$this->template->assign_block_vars('disabled', array(
|
||||
'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $message),
|
||||
'S_VERSIONCHECK' => false,
|
||||
));
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
$enabled_extension_meta_data[$name]['S_VERSIONCHECK'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
uasort($enabled_extension_meta_data, array($this, 'sort_extension_meta_data_table'));
|
||||
|
||||
foreach ($enabled_extension_meta_data as $name => $block_vars)
|
||||
{
|
||||
$block_vars['NAME'] = $name;
|
||||
$block_vars['U_DETAILS'] = $this->u_action . '&action=details&ext_name=' . urlencode($name);
|
||||
|
||||
$this->template->assign_block_vars('enabled', $block_vars);
|
||||
|
||||
$this->output_actions('enabled', array(
|
||||
'DISABLE' => $this->u_action . '&action=disable_pre&ext_name=' . urlencode($name),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all the disabled extensions and dumps to the template
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function list_disabled_exts()
|
||||
{
|
||||
$disabled_extension_meta_data = array();
|
||||
|
||||
foreach ($this->ext_manager->all_disabled() as $name => $location)
|
||||
{
|
||||
$md_manager = $this->ext_manager->create_extension_metadata_manager($name);
|
||||
|
||||
try
|
||||
{
|
||||
$meta = $md_manager->get_metadata('all');
|
||||
$disabled_extension_meta_data[$name] = array(
|
||||
'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'),
|
||||
'META_VERSION' => $meta['version'],
|
||||
);
|
||||
|
||||
if (isset($meta['extra']['version-check']))
|
||||
{
|
||||
$force_update = $this->request->variable('versioncheck_force', false);
|
||||
$updates = $this->ext_manager->version_check($md_manager, $force_update, !$force_update);
|
||||
|
||||
$disabled_extension_meta_data[$name]['S_UP_TO_DATE'] = empty($updates);
|
||||
$disabled_extension_meta_data[$name]['S_VERSIONCHECK'] = true;
|
||||
$disabled_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&action=details&versioncheck_force=1&ext_name=' . urlencode($md_manager->get_metadata('name'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$disabled_extension_meta_data[$name]['S_VERSIONCHECK'] = false;
|
||||
}
|
||||
}
|
||||
catch (version_check_exception $e)
|
||||
{
|
||||
$disabled_extension_meta_data[$name]['S_VERSIONCHECK'] = false;
|
||||
}
|
||||
catch (exception_interface $e)
|
||||
{
|
||||
$message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
|
||||
$this->template->assign_block_vars('disabled', array(
|
||||
'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $message),
|
||||
'S_VERSIONCHECK' => false,
|
||||
));
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
$disabled_extension_meta_data[$name]['S_VERSIONCHECK'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
uasort($disabled_extension_meta_data, array($this, 'sort_extension_meta_data_table'));
|
||||
|
||||
foreach ($disabled_extension_meta_data as $name => $block_vars)
|
||||
{
|
||||
$block_vars['NAME'] = $name;
|
||||
$block_vars['U_DETAILS'] = $this->u_action . '&action=details&ext_name=' . urlencode($name);
|
||||
|
||||
$this->template->assign_block_vars('disabled', $block_vars);
|
||||
|
||||
$this->output_actions('disabled', array(
|
||||
'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name),
|
||||
'DELETE_DATA' => $this->u_action . '&action=delete_data_pre&ext_name=' . urlencode($name),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all the available extensions and dumps to the template
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function list_available_exts()
|
||||
{
|
||||
$uninstalled = array_diff_key($this->ext_manager->all_available(), $this->ext_manager->all_configured());
|
||||
|
||||
$available_extension_meta_data = array();
|
||||
|
||||
foreach ($uninstalled as $name => $location)
|
||||
{
|
||||
$md_manager = $this->ext_manager->create_extension_metadata_manager($name);
|
||||
|
||||
try
|
||||
{
|
||||
$meta = $md_manager->get_metadata('all');
|
||||
$available_extension_meta_data[$name] = array(
|
||||
'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'),
|
||||
'META_VERSION' => $meta['version'],
|
||||
);
|
||||
|
||||
if (isset($meta['extra']['version-check']))
|
||||
{
|
||||
$force_update = $this->request->variable('versioncheck_force', false);
|
||||
$updates = $this->ext_manager->version_check($md_manager, $force_update, !$force_update);
|
||||
|
||||
$available_extension_meta_data[$name]['S_UP_TO_DATE'] = empty($updates);
|
||||
$available_extension_meta_data[$name]['S_VERSIONCHECK'] = true;
|
||||
$available_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&action=details&versioncheck_force=1&ext_name=' . urlencode($md_manager->get_metadata('name'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$available_extension_meta_data[$name]['S_VERSIONCHECK'] = false;
|
||||
}
|
||||
}
|
||||
catch (version_check_exception $e)
|
||||
{
|
||||
$available_extension_meta_data[$name]['S_VERSIONCHECK'] = false;
|
||||
}
|
||||
catch (exception_interface $e)
|
||||
{
|
||||
$message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
|
||||
$this->template->assign_block_vars('disabled', array(
|
||||
'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $message),
|
||||
'S_VERSIONCHECK' => false,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
uasort($available_extension_meta_data, array($this, 'sort_extension_meta_data_table'));
|
||||
|
||||
foreach ($available_extension_meta_data as $name => $block_vars)
|
||||
{
|
||||
$block_vars['NAME'] = $name;
|
||||
$block_vars['U_DETAILS'] = $this->u_action . '&action=details&ext_name=' . urlencode($name);
|
||||
|
||||
$this->template->assign_block_vars('disabled', $block_vars);
|
||||
|
||||
$this->output_actions('disabled', array(
|
||||
'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output actions to a block
|
||||
*
|
||||
* @param string $block
|
||||
* @param array $actions
|
||||
* @return array List of actions to be performed on the extension
|
||||
*/
|
||||
private function output_actions($block, $actions)
|
||||
{
|
||||
$vars_ary = array();
|
||||
foreach ($actions as $lang => $options)
|
||||
{
|
||||
$url = $options;
|
||||
if (is_array($options))
|
||||
{
|
||||
$url = $options['url'];
|
||||
}
|
||||
|
||||
$vars = array(
|
||||
'L_ACTION' => $this->user->lang('EXTENSION_' . $lang),
|
||||
'L_ACTION_EXPLAIN' => (isset($this->user->lang['EXTENSION_' . $lang . '_EXPLAIN'])) ? $this->user->lang('EXTENSION_' . $lang . '_EXPLAIN') : '',
|
||||
'U_ACTION' => $url,
|
||||
'ACTION_AJAX' => 'ext_' . strtolower($lang),
|
||||
);
|
||||
|
||||
if (isset($options['color']))
|
||||
{
|
||||
$vars['COLOR'] = $options['color'];
|
||||
}
|
||||
|
||||
$this->template->assign_block_vars($block . '.actions', $vars);
|
||||
|
||||
$vars_ary[] = $vars;
|
||||
}
|
||||
|
||||
return $vars_ary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort helper for the table containing the metadata about the extensions.
|
||||
*/
|
||||
protected function sort_extension_meta_data_table($val1, $val2)
|
||||
{
|
||||
return strnatcasecmp($val1['META_DISPLAY_NAME'], $val2['META_DISPLAY_NAME']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs extension metadata into the template
|
||||
*
|
||||
* @param array $metadata Array with all metadata for the extension
|
||||
* @return null
|
||||
*/
|
||||
public function output_metadata_to_template($metadata)
|
||||
{
|
||||
$this->template->assign_vars(array(
|
||||
'META_NAME' => $metadata['name'],
|
||||
'META_TYPE' => $metadata['type'],
|
||||
'META_DESCRIPTION' => (isset($metadata['description'])) ? $metadata['description'] : '',
|
||||
'META_HOMEPAGE' => (isset($metadata['homepage'])) ? $metadata['homepage'] : '',
|
||||
'META_VERSION' => $metadata['version'],
|
||||
'META_TIME' => (isset($metadata['time'])) ? $metadata['time'] : '',
|
||||
'META_LICENSE' => $metadata['license'],
|
||||
|
||||
'META_REQUIRE_PHP' => (isset($metadata['require']['php'])) ? $metadata['require']['php'] : '',
|
||||
'META_REQUIRE_PHP_FAIL' => (isset($metadata['require']['php'])) ? false : true,
|
||||
|
||||
'META_REQUIRE_PHPBB' => (isset($metadata['extra']['soft-require']['phpbb/phpbb'])) ? $metadata['extra']['soft-require']['phpbb/phpbb'] : '',
|
||||
'META_REQUIRE_PHPBB_FAIL' => (isset($metadata['extra']['soft-require']['phpbb/phpbb'])) ? false : true,
|
||||
|
||||
'META_DISPLAY_NAME' => (isset($metadata['extra']['display-name'])) ? $metadata['extra']['display-name'] : '',
|
||||
));
|
||||
|
||||
foreach ($metadata['authors'] as $author)
|
||||
{
|
||||
$this->template->assign_block_vars('meta_authors', array(
|
||||
'AUTHOR_NAME' => $author['name'],
|
||||
'AUTHOR_EMAIL' => (isset($author['email'])) ? $author['email'] : '',
|
||||
'AUTHOR_HOMEPAGE' => (isset($author['homepage'])) ? $author['homepage'] : '',
|
||||
'AUTHOR_ROLE' => (isset($author['role'])) ? $author['role'] : '',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the extension can be enabled. Triggers error if not.
|
||||
* Error message can be set by the extension.
|
||||
*
|
||||
* @param \phpbb\extension\extension_interface $extension Extension to check
|
||||
*/
|
||||
protected function check_is_enableable(\phpbb\extension\extension_interface $extension)
|
||||
{
|
||||
$message = $extension->is_enableable();
|
||||
if ($message !== true)
|
||||
{
|
||||
if (empty($message))
|
||||
{
|
||||
$message = $this->user->lang('EXTENSION_NOT_ENABLEABLE');
|
||||
}
|
||||
else if (is_array($message))
|
||||
{
|
||||
$message = implode('<br>', $message);
|
||||
}
|
||||
|
||||
trigger_error($message . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
2211
install/update/new/includes/acp/acp_forums.php
Normal file
2211
install/update/new/includes/acp/acp_forums.php
Normal file
File diff suppressed because it is too large
Load Diff
146
install/update/new/includes/acp/acp_help_phpbb.php
Normal file
146
install/update/new/includes/acp/acp_help_phpbb.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
class acp_help_phpbb
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $config, $request, $template, $user, $phpbb_dispatcher, $phpbb_admin_path, $phpbb_root_path, $phpEx;
|
||||
|
||||
if (!class_exists('phpbb_questionnaire_data_collector'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/questionnaire/questionnaire.' . $phpEx);
|
||||
}
|
||||
|
||||
$collect_url = "https://www.phpbb.com/statistics/send";
|
||||
|
||||
$this->tpl_name = 'acp_help_phpbb';
|
||||
$this->page_title = 'ACP_HELP_PHPBB';
|
||||
|
||||
$submit = ($request->is_set_post('submit')) ? true : false;
|
||||
|
||||
$form_key = 'acp_help_phpbb';
|
||||
add_form_key($form_key);
|
||||
$error = array();
|
||||
|
||||
if ($submit && !check_form_key($form_key))
|
||||
{
|
||||
$error[] = $user->lang['FORM_INVALID'];
|
||||
}
|
||||
// Do not write values if there is an error
|
||||
if (count($error))
|
||||
{
|
||||
$submit = false;
|
||||
}
|
||||
|
||||
// generate a unique id if necessary
|
||||
if (!isset($config['questionnaire_unique_id']))
|
||||
{
|
||||
$install_id = unique_id();
|
||||
$config->set('questionnaire_unique_id', $install_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
$install_id = $config['questionnaire_unique_id'];
|
||||
}
|
||||
|
||||
$collector = new phpbb_questionnaire_data_collector($install_id);
|
||||
|
||||
// Add data provider
|
||||
$collector->add_data_provider(new phpbb_questionnaire_php_data_provider());
|
||||
$collector->add_data_provider(new phpbb_questionnaire_system_data_provider());
|
||||
$collector->add_data_provider(new phpbb_questionnaire_phpbb_data_provider($config));
|
||||
|
||||
/**
|
||||
* Event to modify ACP help phpBB page and/or listen to submit
|
||||
*
|
||||
* @event core.acp_help_phpbb_submit_before
|
||||
* @var boolean submit Do we display the form or process the submission
|
||||
* @since 3.2.0-RC2
|
||||
*/
|
||||
$vars = array('submit');
|
||||
extract($phpbb_dispatcher->trigger_event('core.acp_help_phpbb_submit_before', compact($vars)));
|
||||
|
||||
if ($submit)
|
||||
{
|
||||
$config->set('help_send_statistics', $request->variable('help_send_statistics', false));
|
||||
$response = $request->variable('send_statistics_response', '');
|
||||
|
||||
$config->set('help_send_statistics_time', time());
|
||||
|
||||
if (!empty($response))
|
||||
{
|
||||
$decoded_response = json_decode(htmlspecialchars_decode($response), true);
|
||||
|
||||
if ($decoded_response && isset($decoded_response['status']) && $decoded_response['status'] == 'ok')
|
||||
{
|
||||
trigger_error($user->lang('THANKS_SEND_STATISTICS') . adm_back_link($this->u_action));
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error($user->lang('FAIL_SEND_STATISTICS') . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
trigger_error($user->lang('CONFIG_UPDATED') . adm_back_link($this->u_action));
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_COLLECT_STATS' => $collect_url,
|
||||
'S_COLLECT_STATS' => (!empty($config['help_send_statistics'])) ? true : false,
|
||||
'S_STATS' => $collector->get_data_raw(),
|
||||
'S_STATS_DATA' => json_encode($collector->get_data_raw()),
|
||||
'U_ACP_MAIN' => append_sid("{$phpbb_admin_path}index.$phpEx"),
|
||||
'U_ACTION' => $this->u_action,
|
||||
// Pass earliest time we should try to send stats again
|
||||
'COLLECT_STATS_TIME' => intval($config['help_send_statistics_time']) + 86400,
|
||||
));
|
||||
|
||||
$raw = $collector->get_data_raw();
|
||||
|
||||
foreach ($raw as $provider => $data)
|
||||
{
|
||||
if ($provider == 'install_id')
|
||||
{
|
||||
$data = array($provider => $data);
|
||||
}
|
||||
|
||||
$template->assign_block_vars('providers', array(
|
||||
'NAME' => htmlspecialchars($provider),
|
||||
));
|
||||
|
||||
foreach ($data as $key => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
$value = utf8_wordwrap(serialize($value), 75, "\n", true);
|
||||
}
|
||||
|
||||
$template->assign_block_vars('providers.values', array(
|
||||
'KEY' => utf8_htmlspecialchars($key),
|
||||
'VALUE' => utf8_htmlspecialchars($value),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
707
install/update/new/includes/acp/acp_main.php
Normal file
707
install/update/new/includes/acp/acp_main.php
Normal file
@@ -0,0 +1,707 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
class acp_main
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $config, $db, $cache, $user, $auth, $template, $request, $phpbb_log;
|
||||
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_container, $phpbb_dispatcher, $phpbb_filesystem;
|
||||
|
||||
// Show restore permissions notice
|
||||
if ($user->data['user_perm_from'] && $auth->acl_get('a_switchperm'))
|
||||
{
|
||||
$this->tpl_name = 'acp_main';
|
||||
$this->page_title = 'ACP_MAIN';
|
||||
|
||||
$sql = 'SELECT user_id, username, user_colour
|
||||
FROM ' . USERS_TABLE . '
|
||||
WHERE user_id = ' . $user->data['user_perm_from'];
|
||||
$result = $db->sql_query($sql);
|
||||
$user_row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$perm_from = get_username_string('full', $user_row['user_id'], $user_row['username'], $user_row['user_colour']);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'S_RESTORE_PERMISSIONS' => true,
|
||||
'U_RESTORE_PERMISSIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=restore_perm'),
|
||||
'PERM_FROM' => $perm_from,
|
||||
'L_PERMISSIONS_TRANSFERRED_EXPLAIN' => sprintf($user->lang['PERMISSIONS_TRANSFERRED_EXPLAIN'], $perm_from, append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=restore_perm')),
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$action = $request->variable('action', '');
|
||||
|
||||
if ($action)
|
||||
{
|
||||
if ($action === 'admlogout')
|
||||
{
|
||||
$user->unset_admin();
|
||||
redirect(append_sid("{$phpbb_root_path}index.$phpEx"));
|
||||
}
|
||||
|
||||
if (!confirm_box(true))
|
||||
{
|
||||
switch ($action)
|
||||
{
|
||||
case 'online':
|
||||
$confirm = true;
|
||||
$confirm_lang = 'RESET_ONLINE_CONFIRM';
|
||||
break;
|
||||
case 'stats':
|
||||
$confirm = true;
|
||||
$confirm_lang = 'RESYNC_STATS_CONFIRM';
|
||||
break;
|
||||
case 'user':
|
||||
$confirm = true;
|
||||
$confirm_lang = 'RESYNC_POSTCOUNTS_CONFIRM';
|
||||
break;
|
||||
case 'date':
|
||||
$confirm = true;
|
||||
$confirm_lang = 'RESET_DATE_CONFIRM';
|
||||
break;
|
||||
case 'db_track':
|
||||
$confirm = true;
|
||||
$confirm_lang = 'RESYNC_POST_MARKING_CONFIRM';
|
||||
break;
|
||||
case 'purge_cache':
|
||||
$confirm = true;
|
||||
$confirm_lang = 'PURGE_CACHE_CONFIRM';
|
||||
break;
|
||||
case 'purge_sessions':
|
||||
$confirm = true;
|
||||
$confirm_lang = 'PURGE_SESSIONS_CONFIRM';
|
||||
break;
|
||||
|
||||
default:
|
||||
$confirm = true;
|
||||
$confirm_lang = 'CONFIRM_OPERATION';
|
||||
}
|
||||
|
||||
if ($confirm)
|
||||
{
|
||||
confirm_box(false, $user->lang[$confirm_lang], build_hidden_fields(array(
|
||||
'i' => $id,
|
||||
'mode' => $mode,
|
||||
'action' => $action,
|
||||
)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ($action)
|
||||
{
|
||||
|
||||
case 'online':
|
||||
if (!$auth->acl_get('a_board'))
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$config->set('record_online_users', 1, false);
|
||||
$config->set('record_online_date', time(), false);
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_RESET_ONLINE');
|
||||
|
||||
if ($request->is_ajax())
|
||||
{
|
||||
trigger_error('RESET_ONLINE_SUCCESS');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'stats':
|
||||
if (!$auth->acl_get('a_board'))
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$sql = 'SELECT COUNT(post_id) AS stat
|
||||
FROM ' . POSTS_TABLE . '
|
||||
WHERE post_visibility = ' . ITEM_APPROVED;
|
||||
$result = $db->sql_query($sql);
|
||||
$config->set('num_posts', (int) $db->sql_fetchfield('stat'), false);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$sql = 'SELECT COUNT(topic_id) AS stat
|
||||
FROM ' . TOPICS_TABLE . '
|
||||
WHERE topic_visibility = ' . ITEM_APPROVED;
|
||||
$result = $db->sql_query($sql);
|
||||
$config->set('num_topics', (int) $db->sql_fetchfield('stat'), false);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$sql = 'SELECT COUNT(user_id) AS stat
|
||||
FROM ' . USERS_TABLE . '
|
||||
WHERE user_type IN (' . USER_NORMAL . ',' . USER_FOUNDER . ')';
|
||||
$result = $db->sql_query($sql);
|
||||
$config->set('num_users', (int) $db->sql_fetchfield('stat'), false);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$sql = 'SELECT COUNT(attach_id) as stat
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE is_orphan = 0';
|
||||
$result = $db->sql_query($sql);
|
||||
$config->set('num_files', (int) $db->sql_fetchfield('stat'), false);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$sql = 'SELECT SUM(filesize) as stat
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE is_orphan = 0';
|
||||
$result = $db->sql_query($sql);
|
||||
$config->set('upload_dir_size', (float) $db->sql_fetchfield('stat'), false);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!function_exists('update_last_username'))
|
||||
{
|
||||
include($phpbb_root_path . "includes/functions_user.$phpEx");
|
||||
}
|
||||
update_last_username();
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_RESYNC_STATS');
|
||||
|
||||
if ($request->is_ajax())
|
||||
{
|
||||
trigger_error('RESYNC_STATS_SUCCESS');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'user':
|
||||
if (!$auth->acl_get('a_board'))
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
// Resync post counts
|
||||
$start = $max_post_id = 0;
|
||||
|
||||
// Find the maximum post ID, we can only stop the cycle when we've reached it
|
||||
$sql = 'SELECT MAX(forum_last_post_id) as max_post_id
|
||||
FROM ' . FORUMS_TABLE;
|
||||
$result = $db->sql_query($sql);
|
||||
$max_post_id = (int) $db->sql_fetchfield('max_post_id');
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// No maximum post id? :o
|
||||
if (!$max_post_id)
|
||||
{
|
||||
$sql = 'SELECT MAX(post_id) as max_post_id
|
||||
FROM ' . POSTS_TABLE;
|
||||
$result = $db->sql_query($sql);
|
||||
$max_post_id = (int) $db->sql_fetchfield('max_post_id');
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
// Still no maximum post id? Then we are finished
|
||||
if (!$max_post_id)
|
||||
{
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_RESYNC_POSTCOUNTS');
|
||||
break;
|
||||
}
|
||||
|
||||
$step = ($config['num_posts']) ? (max((int) ($config['num_posts'] / 5), 20000)) : 20000;
|
||||
$db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_posts = 0');
|
||||
|
||||
while ($start < $max_post_id)
|
||||
{
|
||||
$sql = 'SELECT COUNT(post_id) AS num_posts, poster_id
|
||||
FROM ' . POSTS_TABLE . '
|
||||
WHERE post_id BETWEEN ' . ($start + 1) . ' AND ' . ($start + $step) . '
|
||||
AND post_postcount = 1 AND post_visibility = ' . ITEM_APPROVED . '
|
||||
GROUP BY poster_id';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
if ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
do
|
||||
{
|
||||
$sql = 'UPDATE ' . USERS_TABLE . " SET user_posts = user_posts + {$row['num_posts']} WHERE user_id = {$row['poster_id']}";
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
while ($row = $db->sql_fetchrow($result));
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$start += $step;
|
||||
}
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_RESYNC_POSTCOUNTS');
|
||||
|
||||
if ($request->is_ajax())
|
||||
{
|
||||
trigger_error('RESYNC_POSTCOUNTS_SUCCESS');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'date':
|
||||
if (!$auth->acl_get('a_board'))
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$config->set('board_startdate', time() - 1);
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_RESET_DATE');
|
||||
|
||||
if ($request->is_ajax())
|
||||
{
|
||||
trigger_error('RESET_DATE_SUCCESS');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'db_track':
|
||||
switch ($db->get_sql_layer())
|
||||
{
|
||||
case 'sqlite3':
|
||||
$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
|
||||
break;
|
||||
|
||||
default:
|
||||
$db->sql_query('TRUNCATE TABLE ' . TOPICS_POSTED_TABLE);
|
||||
break;
|
||||
}
|
||||
|
||||
// This can get really nasty... therefore we only do the last six months
|
||||
$get_from_time = time() - (6 * 4 * 7 * 24 * 60 * 60);
|
||||
|
||||
// Select forum ids, do not include categories
|
||||
$sql = 'SELECT forum_id
|
||||
FROM ' . FORUMS_TABLE . '
|
||||
WHERE forum_type <> ' . FORUM_CAT;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$forum_ids = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$forum_ids[] = $row['forum_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// Any global announcements? ;)
|
||||
$forum_ids[] = 0;
|
||||
|
||||
// Now go through the forums and get us some topics...
|
||||
foreach ($forum_ids as $forum_id)
|
||||
{
|
||||
$sql = 'SELECT p.poster_id, p.topic_id
|
||||
FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t
|
||||
WHERE t.forum_id = ' . $forum_id . '
|
||||
AND t.topic_moved_id = 0
|
||||
AND t.topic_last_post_time > ' . $get_from_time . '
|
||||
AND t.topic_id = p.topic_id
|
||||
AND p.poster_id <> ' . ANONYMOUS . '
|
||||
GROUP BY p.poster_id, p.topic_id';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$posted = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$posted[$row['poster_id']][] = $row['topic_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$sql_ary = array();
|
||||
foreach ($posted as $user_id => $topic_row)
|
||||
{
|
||||
foreach ($topic_row as $topic_id)
|
||||
{
|
||||
$sql_ary[] = array(
|
||||
'user_id' => (int) $user_id,
|
||||
'topic_id' => (int) $topic_id,
|
||||
'topic_posted' => 1,
|
||||
);
|
||||
}
|
||||
}
|
||||
unset($posted);
|
||||
|
||||
if (count($sql_ary))
|
||||
{
|
||||
$db->sql_multi_insert(TOPICS_POSTED_TABLE, $sql_ary);
|
||||
}
|
||||
}
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_RESYNC_POST_MARKING');
|
||||
|
||||
if ($request->is_ajax())
|
||||
{
|
||||
trigger_error('RESYNC_POST_MARKING_SUCCESS');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'purge_cache':
|
||||
$config->increment('assets_version', 1);
|
||||
$cache->purge();
|
||||
|
||||
// Remove old renderers from the text_formatter service. Since this
|
||||
// operation is performed after the cache is purged, there is not "current"
|
||||
// renderer and in effect all renderers will be purged
|
||||
$phpbb_container->get('text_formatter.cache')->tidy();
|
||||
|
||||
// Clear permissions
|
||||
$auth->acl_clear_prefetch();
|
||||
phpbb_cache_moderators($db, $cache, $auth);
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_PURGE_CACHE');
|
||||
|
||||
if ($request->is_ajax())
|
||||
{
|
||||
trigger_error('PURGE_CACHE_SUCCESS');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'purge_sessions':
|
||||
if ((int) $user->data['user_type'] !== USER_FOUNDER)
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$tables = array(CONFIRM_TABLE, SESSIONS_TABLE);
|
||||
|
||||
foreach ($tables as $table)
|
||||
{
|
||||
switch ($db->get_sql_layer())
|
||||
{
|
||||
case 'sqlite3':
|
||||
$db->sql_query("DELETE FROM $table");
|
||||
break;
|
||||
|
||||
default:
|
||||
$db->sql_query("TRUNCATE TABLE $table");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// let's restore the admin session
|
||||
$reinsert_ary = array(
|
||||
'session_id' => (string) $user->session_id,
|
||||
'session_page' => (string) substr($user->page['page'], 0, 199),
|
||||
'session_forum_id' => $user->page['forum'],
|
||||
'session_user_id' => (int) $user->data['user_id'],
|
||||
'session_start' => (int) $user->data['session_start'],
|
||||
'session_last_visit' => (int) $user->data['session_last_visit'],
|
||||
'session_time' => (int) $user->time_now,
|
||||
'session_browser' => (string) trim(substr($user->browser, 0, 149)),
|
||||
'session_forwarded_for' => (string) $user->forwarded_for,
|
||||
'session_ip' => (string) $user->ip,
|
||||
'session_autologin' => (int) $user->data['session_autologin'],
|
||||
'session_admin' => 1,
|
||||
'session_viewonline' => (int) $user->data['session_viewonline'],
|
||||
);
|
||||
|
||||
$sql = 'INSERT INTO ' . SESSIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $reinsert_ary);
|
||||
$db->sql_query($sql);
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_PURGE_SESSIONS');
|
||||
|
||||
if ($request->is_ajax())
|
||||
{
|
||||
trigger_error('PURGE_SESSIONS_SUCCESS');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Version check
|
||||
$user->add_lang('install');
|
||||
|
||||
if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.4.0', '<'))
|
||||
{
|
||||
$template->assign_vars(array(
|
||||
'S_PHP_VERSION_OLD' => true,
|
||||
'L_PHP_VERSION_OLD' => sprintf($user->lang['PHP_VERSION_OLD'], PHP_VERSION, '5.4.0', '<a href="https://www.phpbb.com/support/docs/en/3.2/ug/quickstart/requirements">', '</a>'),
|
||||
));
|
||||
}
|
||||
|
||||
if ($auth->acl_get('a_board'))
|
||||
{
|
||||
$version_helper = $phpbb_container->get('version_helper');
|
||||
try
|
||||
{
|
||||
$recheck = $request->variable('versioncheck_force', false);
|
||||
$updates_available = $version_helper->get_update_on_branch($recheck);
|
||||
$upgrades_available = $version_helper->get_suggested_updates();
|
||||
if (!empty($upgrades_available))
|
||||
{
|
||||
$upgrades_available = array_pop($upgrades_available);
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'S_VERSION_UP_TO_DATE' => empty($updates_available),
|
||||
'S_VERSION_UPGRADEABLE' => !empty($upgrades_available),
|
||||
'UPGRADE_INSTRUCTIONS' => !empty($upgrades_available) ? $user->lang('UPGRADE_INSTRUCTIONS', $upgrades_available['current'], $upgrades_available['announcement']) : false,
|
||||
));
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
$message = call_user_func_array(array($user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
|
||||
$template->assign_vars(array(
|
||||
'S_VERSIONCHECK_FAIL' => true,
|
||||
'VERSIONCHECK_FAIL_REASON' => ($e->getMessage() !== 'VERSIONCHECK_FAIL') ? $message : '',
|
||||
));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We set this template var to true, to not display an outdated version notice.
|
||||
$template->assign_var('S_VERSION_UP_TO_DATE', true);
|
||||
}
|
||||
|
||||
// Incomplete update?
|
||||
if (phpbb_version_compare($config['version'], PHPBB_VERSION, '<'))
|
||||
{
|
||||
$template->assign_var('S_UPDATE_INCOMPLETE', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notice admin
|
||||
*
|
||||
* @event core.acp_main_notice
|
||||
* @since 3.1.0-RC3
|
||||
*/
|
||||
$phpbb_dispatcher->dispatch('core.acp_main_notice');
|
||||
|
||||
// Get forum statistics
|
||||
$total_posts = $config['num_posts'];
|
||||
$total_topics = $config['num_topics'];
|
||||
$total_users = $config['num_users'];
|
||||
$total_files = $config['num_files'];
|
||||
|
||||
$start_date = $user->format_date($config['board_startdate']);
|
||||
|
||||
$boarddays = (time() - $config['board_startdate']) / 86400;
|
||||
|
||||
$posts_per_day = sprintf('%.2f', $total_posts / $boarddays);
|
||||
$topics_per_day = sprintf('%.2f', $total_topics / $boarddays);
|
||||
$users_per_day = sprintf('%.2f', $total_users / $boarddays);
|
||||
$files_per_day = sprintf('%.2f', $total_files / $boarddays);
|
||||
|
||||
$upload_dir_size = get_formatted_filesize($config['upload_dir_size']);
|
||||
|
||||
$avatar_dir_size = 0;
|
||||
|
||||
if ($avatar_dir = @opendir($phpbb_root_path . $config['avatar_path']))
|
||||
{
|
||||
while (($file = readdir($avatar_dir)) !== false)
|
||||
{
|
||||
if ($file[0] != '.' && $file != 'CVS' && strpos($file, 'index.') === false)
|
||||
{
|
||||
$avatar_dir_size += filesize($phpbb_root_path . $config['avatar_path'] . '/' . $file);
|
||||
}
|
||||
}
|
||||
closedir($avatar_dir);
|
||||
|
||||
$avatar_dir_size = get_formatted_filesize($avatar_dir_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Couldn't open Avatar dir.
|
||||
$avatar_dir_size = $user->lang['NOT_AVAILABLE'];
|
||||
}
|
||||
|
||||
if ($posts_per_day > $total_posts)
|
||||
{
|
||||
$posts_per_day = $total_posts;
|
||||
}
|
||||
|
||||
if ($topics_per_day > $total_topics)
|
||||
{
|
||||
$topics_per_day = $total_topics;
|
||||
}
|
||||
|
||||
if ($users_per_day > $total_users)
|
||||
{
|
||||
$users_per_day = $total_users;
|
||||
}
|
||||
|
||||
if ($files_per_day > $total_files)
|
||||
{
|
||||
$files_per_day = $total_files;
|
||||
}
|
||||
|
||||
if ($config['allow_attachments'] || $config['allow_pm_attach'])
|
||||
{
|
||||
$sql = 'SELECT COUNT(attach_id) AS total_orphan
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE is_orphan = 1
|
||||
AND filetime < ' . (time() - 3*60*60);
|
||||
$result = $db->sql_query($sql);
|
||||
$total_orphan = (int) $db->sql_fetchfield('total_orphan');
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
else
|
||||
{
|
||||
$total_orphan = false;
|
||||
}
|
||||
|
||||
$dbsize = get_database_size();
|
||||
|
||||
$template->assign_vars(array(
|
||||
'TOTAL_POSTS' => $total_posts,
|
||||
'POSTS_PER_DAY' => $posts_per_day,
|
||||
'TOTAL_TOPICS' => $total_topics,
|
||||
'TOPICS_PER_DAY' => $topics_per_day,
|
||||
'TOTAL_USERS' => $total_users,
|
||||
'USERS_PER_DAY' => $users_per_day,
|
||||
'TOTAL_FILES' => $total_files,
|
||||
'FILES_PER_DAY' => $files_per_day,
|
||||
'START_DATE' => $start_date,
|
||||
'AVATAR_DIR_SIZE' => $avatar_dir_size,
|
||||
'DBSIZE' => $dbsize,
|
||||
'UPLOAD_DIR_SIZE' => $upload_dir_size,
|
||||
'TOTAL_ORPHAN' => $total_orphan,
|
||||
'S_TOTAL_ORPHAN' => ($total_orphan === false) ? false : true,
|
||||
'GZIP_COMPRESSION' => ($config['gzip_compress'] && @extension_loaded('zlib')) ? $user->lang['ON'] : $user->lang['OFF'],
|
||||
'DATABASE_INFO' => $db->sql_server_info(),
|
||||
'PHP_VERSION_INFO' => PHP_VERSION,
|
||||
'BOARD_VERSION' => $config['version'],
|
||||
|
||||
'U_ACTION' => $this->u_action,
|
||||
'U_ADMIN_LOG' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=logs&mode=admin'),
|
||||
'U_INACTIVE_USERS' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=inactive&mode=list'),
|
||||
'U_VERSIONCHECK' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=update&mode=version_check'),
|
||||
'U_VERSIONCHECK_FORCE' => append_sid("{$phpbb_admin_path}index.$phpEx", 'versioncheck_force=1'),
|
||||
'U_ATTACH_ORPHAN' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=acp_attachments&mode=orphan'),
|
||||
|
||||
'S_VERSIONCHECK' => ($auth->acl_get('a_board')) ? true : false,
|
||||
'S_ACTION_OPTIONS' => ($auth->acl_get('a_board')) ? true : false,
|
||||
'S_FOUNDER' => ($user->data['user_type'] == USER_FOUNDER) ? true : false,
|
||||
)
|
||||
);
|
||||
|
||||
$log_data = array();
|
||||
$log_count = false;
|
||||
|
||||
if ($auth->acl_get('a_viewlogs'))
|
||||
{
|
||||
view_log('admin', $log_data, $log_count, 5);
|
||||
|
||||
foreach ($log_data as $row)
|
||||
{
|
||||
$template->assign_block_vars('log', array(
|
||||
'USERNAME' => $row['username_full'],
|
||||
'IP' => $row['ip'],
|
||||
'DATE' => $user->format_date($row['time']),
|
||||
'ACTION' => $row['action'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($auth->acl_get('a_user'))
|
||||
{
|
||||
$user->add_lang('memberlist');
|
||||
|
||||
$inactive = array();
|
||||
$inactive_count = 0;
|
||||
|
||||
view_inactive_users($inactive, $inactive_count, 10);
|
||||
|
||||
foreach ($inactive as $row)
|
||||
{
|
||||
$template->assign_block_vars('inactive', array(
|
||||
'INACTIVE_DATE' => $user->format_date($row['user_inactive_time']),
|
||||
'REMINDED_DATE' => $user->format_date($row['user_reminded_time']),
|
||||
'JOINED' => $user->format_date($row['user_regdate']),
|
||||
'LAST_VISIT' => (!$row['user_lastvisit']) ? ' - ' : $user->format_date($row['user_lastvisit']),
|
||||
|
||||
'REASON' => $row['inactive_reason'],
|
||||
'USER_ID' => $row['user_id'],
|
||||
'POSTS' => ($row['user_posts']) ? $row['user_posts'] : 0,
|
||||
'REMINDED' => $row['user_reminded'],
|
||||
|
||||
'REMINDED_EXPLAIN' => $user->lang('USER_LAST_REMINDED', (int) $row['user_reminded'], $user->format_date($row['user_reminded_time'])),
|
||||
|
||||
'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&mode=overview')),
|
||||
'USERNAME' => get_username_string('username', $row['user_id'], $row['username'], $row['user_colour']),
|
||||
'USER_COLOR' => get_username_string('colour', $row['user_id'], $row['username'], $row['user_colour']),
|
||||
|
||||
'U_USER_ADMIN' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=users&mode=overview&u={$row['user_id']}"),
|
||||
'U_SEARCH_USER' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id={$row['user_id']}&sr=posts") : '',
|
||||
));
|
||||
}
|
||||
|
||||
$option_ary = array('activate' => 'ACTIVATE', 'delete' => 'DELETE');
|
||||
if ($config['email_enable'])
|
||||
{
|
||||
$option_ary += array('remind' => 'REMIND');
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'S_INACTIVE_USERS' => true,
|
||||
'S_INACTIVE_OPTIONS' => build_select($option_ary))
|
||||
);
|
||||
}
|
||||
|
||||
// Warn if install is still present
|
||||
if (!defined('IN_INSTALL') && !$phpbb_container->getParameter('allow_install_dir') && file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install'))
|
||||
{
|
||||
$template->assign_var('S_REMOVE_INSTALL', true);
|
||||
}
|
||||
|
||||
// Warn if no search index is created
|
||||
if ($config['num_posts'] && class_exists($config['search_type']))
|
||||
{
|
||||
$error = false;
|
||||
$search_type = $config['search_type'];
|
||||
$search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
|
||||
|
||||
if (!$search->index_created())
|
||||
{
|
||||
$template->assign_vars(array(
|
||||
'S_SEARCH_INDEX_MISSING' => true,
|
||||
'L_NO_SEARCH_INDEX' => $user->lang('NO_SEARCH_INDEX', $search->get_name(), '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=acp_search&mode=index') . '">', '</a>'),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (!defined('PHPBB_DISABLE_CONFIG_CHECK') && file_exists($phpbb_root_path . 'config.' . $phpEx) && $phpbb_filesystem->is_writable($phpbb_root_path . 'config.' . $phpEx))
|
||||
{
|
||||
// World-Writable? (000x)
|
||||
$template->assign_var('S_WRITABLE_CONFIG', (bool) (@fileperms($phpbb_root_path . 'config.' . $phpEx) & 0x0002));
|
||||
}
|
||||
|
||||
if (extension_loaded('mbstring'))
|
||||
{
|
||||
$template->assign_vars(array(
|
||||
'S_MBSTRING_LOADED' => true,
|
||||
'S_MBSTRING_FUNC_OVERLOAD_FAIL' => (intval(@ini_get('mbstring.func_overload')) & (MB_OVERLOAD_MAIL | MB_OVERLOAD_STRING)),
|
||||
'S_MBSTRING_ENCODING_TRANSLATION_FAIL' => (@ini_get('mbstring.encoding_translation') != 0),
|
||||
'S_MBSTRING_HTTP_INPUT_FAIL' => !in_array(@ini_get('mbstring.http_input'), array('pass', '')),
|
||||
'S_MBSTRING_HTTP_OUTPUT_FAIL' => !in_array(@ini_get('mbstring.http_output'), array('pass', '')),
|
||||
));
|
||||
}
|
||||
|
||||
// Fill dbms version if not yet filled
|
||||
if (empty($config['dbms_version']))
|
||||
{
|
||||
$config->set('dbms_version', $db->sql_server_info(true));
|
||||
}
|
||||
|
||||
$this->tpl_name = 'acp_main';
|
||||
$this->page_title = 'ACP_MAIN';
|
||||
}
|
||||
}
|
||||
1346
install/update/new/includes/acp/acp_permissions.php
Normal file
1346
install/update/new/includes/acp/acp_permissions.php
Normal file
File diff suppressed because it is too large
Load Diff
588
install/update/new/includes/acp/acp_prune.php
Normal file
588
install/update/new/includes/acp/acp_prune.php
Normal file
@@ -0,0 +1,588 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
class acp_prune
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $user, $phpEx, $phpbb_root_path;
|
||||
|
||||
$user->add_lang('acp/prune');
|
||||
|
||||
if (!function_exists('user_active_flip'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
|
||||
}
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case 'forums':
|
||||
$this->tpl_name = 'acp_prune_forums';
|
||||
$this->page_title = 'ACP_PRUNE_FORUMS';
|
||||
$this->prune_forums($id, $mode);
|
||||
break;
|
||||
|
||||
case 'users':
|
||||
$this->tpl_name = 'acp_prune_users';
|
||||
$this->page_title = 'ACP_PRUNE_USERS';
|
||||
$this->prune_users($id, $mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prune forums
|
||||
*/
|
||||
function prune_forums($id, $mode)
|
||||
{
|
||||
global $db, $user, $auth, $template, $phpbb_log, $request, $phpbb_dispatcher;
|
||||
|
||||
$all_forums = $request->variable('all_forums', 0);
|
||||
$forum_id = $request->variable('f', array(0));
|
||||
$submit = (isset($_POST['submit'])) ? true : false;
|
||||
|
||||
if ($all_forums)
|
||||
{
|
||||
$sql = 'SELECT forum_id
|
||||
FROM ' . FORUMS_TABLE . '
|
||||
ORDER BY left_id';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$forum_id = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$forum_id[] = $row['forum_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
if ($submit)
|
||||
{
|
||||
if (confirm_box(true))
|
||||
{
|
||||
$prune_posted = $request->variable('prune_days', 0);
|
||||
$prune_viewed = $request->variable('prune_vieweddays', 0);
|
||||
$prune_all = (!$prune_posted && !$prune_viewed) ? true : false;
|
||||
|
||||
$prune_flags = 0;
|
||||
$prune_flags += ($request->variable('prune_old_polls', 0)) ? 2 : 0;
|
||||
$prune_flags += ($request->variable('prune_announce', 0)) ? 4 : 0;
|
||||
$prune_flags += ($request->variable('prune_sticky', 0)) ? 8 : 0;
|
||||
|
||||
// Convert days to seconds for timestamp functions...
|
||||
$prunedate_posted = time() - ($prune_posted * 86400);
|
||||
$prunedate_viewed = time() - ($prune_viewed * 86400);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'S_PRUNED' => true)
|
||||
);
|
||||
|
||||
$sql_forum = (count($forum_id)) ? ' AND ' . $db->sql_in_set('forum_id', $forum_id) : '';
|
||||
|
||||
// Get a list of forum's or the data for the forum that we are pruning.
|
||||
$sql = 'SELECT forum_id, forum_name
|
||||
FROM ' . FORUMS_TABLE . '
|
||||
WHERE forum_type = ' . FORUM_POST . "
|
||||
$sql_forum
|
||||
ORDER BY left_id ASC";
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
if ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$prune_ids = array();
|
||||
$p_result['topics'] = 0;
|
||||
$p_result['posts'] = 0;
|
||||
$log_data = '';
|
||||
|
||||
do
|
||||
{
|
||||
if (!$auth->acl_get('f_list', $row['forum_id']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($prune_all)
|
||||
{
|
||||
$p_result = prune($row['forum_id'], 'posted', time(), $prune_flags, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($prune_posted)
|
||||
{
|
||||
$return = prune($row['forum_id'], 'posted', $prunedate_posted, $prune_flags, false);
|
||||
$p_result['topics'] += $return['topics'];
|
||||
$p_result['posts'] += $return['posts'];
|
||||
}
|
||||
|
||||
if ($prune_viewed)
|
||||
{
|
||||
$return = prune($row['forum_id'], 'viewed', $prunedate_viewed, $prune_flags, false);
|
||||
$p_result['topics'] += $return['topics'];
|
||||
$p_result['posts'] += $return['posts'];
|
||||
}
|
||||
}
|
||||
|
||||
$prune_ids[] = $row['forum_id'];
|
||||
|
||||
$template->assign_block_vars('pruned', array(
|
||||
'FORUM_NAME' => $row['forum_name'],
|
||||
'NUM_TOPICS' => $p_result['topics'],
|
||||
'NUM_POSTS' => $p_result['posts'])
|
||||
);
|
||||
|
||||
$log_data .= (($log_data != '') ? ', ' : '') . $row['forum_name'];
|
||||
}
|
||||
while ($row = $db->sql_fetchrow($result));
|
||||
|
||||
// Sync all pruned forums at once
|
||||
sync('forum', 'forum_id', $prune_ids, true, true);
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_PRUNE', false, array($log_data));
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$hidden_fields = array(
|
||||
'i' => $id,
|
||||
'mode' => $mode,
|
||||
'submit' => 1,
|
||||
'all_forums' => $all_forums,
|
||||
'f' => $forum_id,
|
||||
|
||||
'prune_days' => $request->variable('prune_days', 0),
|
||||
'prune_vieweddays' => $request->variable('prune_vieweddays', 0),
|
||||
'prune_old_polls' => $request->variable('prune_old_polls', 0),
|
||||
'prune_announce' => $request->variable('prune_announce', 0),
|
||||
'prune_sticky' => $request->variable('prune_sticky', 0),
|
||||
);
|
||||
|
||||
/**
|
||||
* Use this event to pass data from the prune form to the confirmation screen
|
||||
*
|
||||
* @event core.prune_forums_settings_confirm
|
||||
* @var array hidden_fields Hidden fields that are passed through the confirm screen
|
||||
* @since 3.2.2-RC1
|
||||
*/
|
||||
$vars = array('hidden_fields');
|
||||
extract($phpbb_dispatcher->trigger_event('core.prune_forums_settings_confirm', compact($vars)));
|
||||
|
||||
confirm_box(false, $user->lang['PRUNE_FORUM_CONFIRM'], build_hidden_fields($hidden_fields));
|
||||
}
|
||||
}
|
||||
|
||||
// If they haven't selected a forum for pruning yet then
|
||||
// display a select box to use for pruning.
|
||||
if (!count($forum_id))
|
||||
{
|
||||
$template->assign_vars(array(
|
||||
'U_ACTION' => $this->u_action,
|
||||
'S_SELECT_FORUM' => true,
|
||||
'S_FORUM_OPTIONS' => make_forum_select(false, false, false))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql = 'SELECT forum_id, forum_name
|
||||
FROM ' . FORUMS_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('forum_id', $forum_id);
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
|
||||
if (!$row)
|
||||
{
|
||||
$db->sql_freeresult($result);
|
||||
trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$forum_list = $s_hidden_fields = '';
|
||||
do
|
||||
{
|
||||
$forum_list .= (($forum_list != '') ? ', ' : '') . '<b>' . $row['forum_name'] . '</b>';
|
||||
$s_hidden_fields .= '<input type="hidden" name="f[]" value="' . $row['forum_id'] . '" />';
|
||||
}
|
||||
while ($row = $db->sql_fetchrow($result));
|
||||
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$l_selected_forums = (count($forum_id) == 1) ? 'SELECTED_FORUM' : 'SELECTED_FORUMS';
|
||||
|
||||
$template_data = array(
|
||||
'L_SELECTED_FORUMS' => $user->lang[$l_selected_forums],
|
||||
'U_ACTION' => $this->u_action,
|
||||
'U_BACK' => $this->u_action,
|
||||
'FORUM_LIST' => $forum_list,
|
||||
'S_HIDDEN_FIELDS' => $s_hidden_fields,
|
||||
);
|
||||
|
||||
/**
|
||||
* Event to add/modify prune forums settings template data
|
||||
*
|
||||
* @event core.prune_forums_settings_template_data
|
||||
* @var array template_data Array with form template data
|
||||
* @since 3.2.2-RC1
|
||||
*/
|
||||
$vars = array('template_data');
|
||||
extract($phpbb_dispatcher->trigger_event('core.prune_forums_settings_template_data', compact($vars)));
|
||||
|
||||
$template->assign_vars($template_data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prune users
|
||||
*/
|
||||
function prune_users($id, $mode)
|
||||
{
|
||||
global $db, $user, $auth, $template, $phpbb_log, $request;
|
||||
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_container;
|
||||
|
||||
/** @var \phpbb\group\helper $group_helper */
|
||||
$group_helper = $phpbb_container->get('group_helper');
|
||||
|
||||
$user->add_lang('memberlist');
|
||||
|
||||
$prune = (isset($_POST['prune'])) ? true : false;
|
||||
|
||||
if ($prune)
|
||||
{
|
||||
$action = $request->variable('action', 'deactivate');
|
||||
$deleteposts = $request->variable('deleteposts', 0);
|
||||
|
||||
if (confirm_box(true))
|
||||
{
|
||||
$user_ids = $usernames = array();
|
||||
|
||||
$this->get_prune_users($user_ids, $usernames);
|
||||
if (count($user_ids))
|
||||
{
|
||||
if ($action == 'deactivate')
|
||||
{
|
||||
user_active_flip('deactivate', $user_ids);
|
||||
$l_log = 'LOG_PRUNE_USER_DEAC';
|
||||
}
|
||||
else if ($action == 'delete')
|
||||
{
|
||||
if ($deleteposts)
|
||||
{
|
||||
user_delete('remove', $user_ids);
|
||||
|
||||
$l_log = 'LOG_PRUNE_USER_DEL_DEL';
|
||||
}
|
||||
else
|
||||
{
|
||||
user_delete('retain', $user_ids, true);
|
||||
|
||||
$l_log = 'LOG_PRUNE_USER_DEL_ANON';
|
||||
}
|
||||
}
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, $l_log, false, array(implode(', ', $usernames)));
|
||||
$msg = $user->lang['USER_' . strtoupper($action) . '_SUCCESS'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg = $user->lang['USER_PRUNE_FAILURE'];
|
||||
}
|
||||
|
||||
trigger_error($msg . adm_back_link($this->u_action));
|
||||
}
|
||||
else
|
||||
{
|
||||
// We list the users which will be pruned...
|
||||
$user_ids = $usernames = array();
|
||||
$this->get_prune_users($user_ids, $usernames);
|
||||
|
||||
if (!count($user_ids))
|
||||
{
|
||||
trigger_error($user->lang['USER_PRUNE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
// Assign to template
|
||||
foreach ($user_ids as $user_id)
|
||||
{
|
||||
$template->assign_block_vars('users', array(
|
||||
'USERNAME' => $usernames[$user_id],
|
||||
'USER_ID' => $user_id,
|
||||
'U_PROFILE' => get_username_string('profile', $user_id, $usernames[$user_id]),
|
||||
'U_USER_ADMIN' => ($auth->acl_get('a_user')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&mode=overview&u=' . $user_id, true, $user->session_id) : '',
|
||||
));
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'S_DEACTIVATE' => ($action == 'deactivate') ? true : false,
|
||||
'S_DELETE' => ($action == 'delete') ? true : false,
|
||||
));
|
||||
|
||||
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
|
||||
'i' => $id,
|
||||
'mode' => $mode,
|
||||
'prune' => 1,
|
||||
|
||||
'deleteposts' => $request->variable('deleteposts', 0),
|
||||
'action' => $request->variable('action', ''),
|
||||
)), 'confirm_body_prune.html');
|
||||
}
|
||||
}
|
||||
|
||||
$find_count = array('lt' => $user->lang['LESS_THAN'], 'eq' => $user->lang['EQUAL_TO'], 'gt' => $user->lang['MORE_THAN']);
|
||||
$s_find_count = '';
|
||||
|
||||
foreach ($find_count as $key => $value)
|
||||
{
|
||||
$selected = ($key == 'eq') ? ' selected="selected"' : '';
|
||||
$s_find_count .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
|
||||
}
|
||||
|
||||
$find_time = array('lt' => $user->lang['BEFORE'], 'gt' => $user->lang['AFTER']);
|
||||
$s_find_active_time = '';
|
||||
foreach ($find_time as $key => $value)
|
||||
{
|
||||
$s_find_active_time .= '<option value="' . $key . '">' . $value . '</option>';
|
||||
}
|
||||
|
||||
$sql = 'SELECT group_id, group_name
|
||||
FROM ' . GROUPS_TABLE . '
|
||||
WHERE group_type <> ' . GROUP_SPECIAL . '
|
||||
ORDER BY group_name ASC';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$s_group_list = '';
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$s_group_list .= '<option value="' . $row['group_id'] . '">' . $group_helper->get_name($row['group_name']) . '</option>';
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($s_group_list)
|
||||
{
|
||||
// Only prepend the "All groups" option if there are groups,
|
||||
// otherwise we don't want to display this option at all.
|
||||
$s_group_list = '<option value="0">' . $user->lang['PRUNE_USERS_GROUP_NONE'] . '</option>' . $s_group_list;
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_ACTION' => $this->u_action,
|
||||
'S_ACTIVE_OPTIONS' => $s_find_active_time,
|
||||
'S_GROUP_LIST' => $s_group_list,
|
||||
'S_COUNT_OPTIONS' => $s_find_count,
|
||||
'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_prune&field=users'),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user_ids/usernames from those being pruned
|
||||
*/
|
||||
function get_prune_users(&$user_ids, &$usernames)
|
||||
{
|
||||
global $user, $db, $request;
|
||||
|
||||
$users_by_name = $request->variable('users', '', true);
|
||||
$users_by_id = $request->variable('user_ids', array(0));
|
||||
$group_id = $request->variable('group_id', 0);
|
||||
$posts_on_queue = (trim($request->variable('posts_on_queue', '')) === '') ? false : $request->variable('posts_on_queue', 0);
|
||||
|
||||
if ($users_by_name)
|
||||
{
|
||||
$users = explode("\n", $users_by_name);
|
||||
$where_sql = ' AND ' . $db->sql_in_set('username_clean', array_map('utf8_clean_string', $users));
|
||||
}
|
||||
else if (!empty($users_by_id))
|
||||
{
|
||||
$user_ids = $users_by_id;
|
||||
user_get_id_name($user_ids, $usernames);
|
||||
|
||||
$where_sql = ' AND ' . $db->sql_in_set('user_id', $user_ids);
|
||||
}
|
||||
else
|
||||
{
|
||||
$username = $request->variable('username', '', true);
|
||||
$email = $request->variable('email', '');
|
||||
|
||||
$active_select = $request->variable('active_select', 'lt');
|
||||
$count_select = $request->variable('count_select', 'eq');
|
||||
$queue_select = $request->variable('queue_select', 'gt');
|
||||
$joined_before = $request->variable('joined_before', '');
|
||||
$joined_after = $request->variable('joined_after', '');
|
||||
$active = $request->variable('active', '');
|
||||
|
||||
$count = ($request->variable('count', '') === '') ? false : $request->variable('count', 0);
|
||||
|
||||
$active = ($active) ? explode('-', $active) : array();
|
||||
$joined_before = ($joined_before) ? explode('-', $joined_before) : array();
|
||||
$joined_after = ($joined_after) ? explode('-', $joined_after) : array();
|
||||
|
||||
// calculate the conditions required by the join time criteria
|
||||
$joined_sql = '';
|
||||
if (!empty($joined_before) && !empty($joined_after))
|
||||
{
|
||||
// if the two entered dates are equal, we need to adjust
|
||||
// so that our time range is a full day instead of 1 second
|
||||
if ($joined_after == $joined_before)
|
||||
{
|
||||
$joined_after[2] += 1;
|
||||
}
|
||||
|
||||
$joined_sql = ' AND user_regdate BETWEEN ' . gmmktime(0, 0, 0, (int) $joined_after[1], (int) $joined_after[2], (int) $joined_after[0]) .
|
||||
' AND ' . gmmktime(0, 0, 0, (int) $joined_before[1], (int) $joined_before[2], (int) $joined_before[0]);
|
||||
}
|
||||
else if (empty($joined_before) && !empty($joined_after))
|
||||
{
|
||||
$joined_sql = ' AND user_regdate > ' . gmmktime(0, 0, 0, (int) $joined_after[1], (int) $joined_after[2], (int) $joined_after[0]);
|
||||
}
|
||||
else if (empty($joined_after) && !empty($joined_before))
|
||||
{
|
||||
$joined_sql = ' AND user_regdate < ' . gmmktime(0, 0, 0, (int) $joined_before[1], (int) $joined_before[2], (int) $joined_before[0]);
|
||||
}
|
||||
// implicit else when both arrays are empty do nothing
|
||||
|
||||
if ((count($active) && count($active) != 3) || (count($joined_before) && count($joined_before) != 3) || (count($joined_after) && count($joined_after) != 3))
|
||||
{
|
||||
trigger_error($user->lang['WRONG_ACTIVE_JOINED_DATE'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$key_match = array('lt' => '<', 'gt' => '>', 'eq' => '=');
|
||||
|
||||
$where_sql = '';
|
||||
$where_sql .= ($username) ? ' AND username_clean ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), utf8_clean_string($username))) : '';
|
||||
$where_sql .= ($email) ? ' AND user_email ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), $email)) . ' ' : '';
|
||||
$where_sql .= $joined_sql;
|
||||
$where_sql .= ($count !== false) ? " AND user_posts " . $key_match[$count_select] . ' ' . (int) $count . ' ' : '';
|
||||
|
||||
// First handle pruning of users who never logged in, last active date is 0000-00-00
|
||||
if (count($active) && (int) $active[0] == 0 && (int) $active[1] == 0 && (int) $active[2] == 0)
|
||||
{
|
||||
$where_sql .= ' AND user_lastvisit = 0';
|
||||
}
|
||||
else if (count($active) && $active_select != 'lt')
|
||||
{
|
||||
$where_sql .= ' AND user_lastvisit ' . $key_match[$active_select] . ' ' . gmmktime(0, 0, 0, (int) $active[1], (int) $active[2], (int) $active[0]);
|
||||
}
|
||||
else if (count($active))
|
||||
{
|
||||
$where_sql .= ' AND (user_lastvisit > 0 AND user_lastvisit < ' . gmmktime(0, 0, 0, (int) $active[1], (int) $active[2], (int) $active[0]) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
// If no search criteria were provided, go no further.
|
||||
if (!$where_sql && !$group_id && $posts_on_queue === false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get bot ids
|
||||
$sql = 'SELECT user_id
|
||||
FROM ' . BOTS_TABLE;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$bot_ids = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$bot_ids[] = $row['user_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// Protect the admin, do not prune if no options are given...
|
||||
if ($where_sql)
|
||||
{
|
||||
// Do not prune founder members
|
||||
$sql = 'SELECT user_id, username
|
||||
FROM ' . USERS_TABLE . '
|
||||
WHERE user_id <> ' . ANONYMOUS . '
|
||||
AND user_type <> ' . USER_FOUNDER . "
|
||||
$where_sql";
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$user_ids = $usernames = array();
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
// Do not prune bots and the user currently pruning.
|
||||
if ($row['user_id'] != $user->data['user_id'] && !in_array($row['user_id'], $bot_ids))
|
||||
{
|
||||
$user_ids[] = $row['user_id'];
|
||||
$usernames[$row['user_id']] = $row['username'];
|
||||
}
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
if ($group_id)
|
||||
{
|
||||
$sql = 'SELECT u.user_id, u.username
|
||||
FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . ' u
|
||||
WHERE ug.group_id = ' . (int) $group_id . '
|
||||
AND ug.user_id <> ' . ANONYMOUS . '
|
||||
AND u.user_type <> ' . USER_FOUNDER . '
|
||||
AND ug.user_pending = 0
|
||||
AND ug.group_leader = 0
|
||||
AND u.user_id = ug.user_id
|
||||
' . (!empty($user_ids) ? ' AND ' . $db->sql_in_set('ug.user_id', $user_ids) : '');
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
// we're performing an intersection operation, so all the relevant users
|
||||
// come from this most recent query (which was limited to the results of the
|
||||
// previous query)
|
||||
$user_ids = $usernames = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
// Do not prune bots and the user currently pruning.
|
||||
if ($row['user_id'] != $user->data['user_id'] && !in_array($row['user_id'], $bot_ids))
|
||||
{
|
||||
$user_ids[] = $row['user_id'];
|
||||
$usernames[$row['user_id']] = $row['username'];
|
||||
}
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
if ($posts_on_queue !== false)
|
||||
{
|
||||
$sql = 'SELECT u.user_id, u.username, COUNT(p.post_id) AS queue_posts
|
||||
FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
|
||||
WHERE u.user_id <> ' . ANONYMOUS . '
|
||||
AND u.user_type <> ' . USER_FOUNDER . '
|
||||
AND ' . $db->sql_in_set('p.post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)) . '
|
||||
AND u.user_id = p.poster_id
|
||||
' . (!empty($user_ids) ? ' AND ' . $db->sql_in_set('p.poster_id', $user_ids) : '') . '
|
||||
GROUP BY p.poster_id
|
||||
HAVING queue_posts ' . $key_match[$queue_select] . ' ' . $posts_on_queue;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
// same intersection logic as the above group ID portion
|
||||
$user_ids = $usernames = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
// Do not prune bots and the user currently pruning.
|
||||
if ($row['user_id'] != $user->data['user_id'] && !in_array($row['user_id'], $bot_ids))
|
||||
{
|
||||
$user_ids[] = $row['user_id'];
|
||||
$usernames[$row['user_id']] = $row['username'];
|
||||
}
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
392
install/update/new/includes/acp/acp_reasons.php
Normal file
392
install/update/new/includes/acp/acp_reasons.php
Normal file
@@ -0,0 +1,392 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
class acp_reasons
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $db, $user, $template;
|
||||
global $request, $phpbb_log;
|
||||
|
||||
$user->add_lang(array('mcp', 'acp/posting'));
|
||||
|
||||
// Set up general vars
|
||||
$action = $request->variable('action', '');
|
||||
$submit = (isset($_POST['submit'])) ? true : false;
|
||||
$reason_id = $request->variable('id', 0);
|
||||
|
||||
$this->tpl_name = 'acp_reasons';
|
||||
$this->page_title = 'ACP_REASONS';
|
||||
|
||||
$form_name = 'acp_reason';
|
||||
add_form_key('acp_reason');
|
||||
|
||||
$error = array();
|
||||
|
||||
switch ($action)
|
||||
{
|
||||
case 'add':
|
||||
case 'edit':
|
||||
|
||||
$reason_row = array(
|
||||
'reason_title' => $request->variable('reason_title', '', true),
|
||||
'reason_description' => $request->variable('reason_description', '', true),
|
||||
);
|
||||
|
||||
if ($submit)
|
||||
{
|
||||
if (!check_form_key($form_name))
|
||||
{
|
||||
$error[] = $user->lang['FORM_INVALID'];
|
||||
}
|
||||
// Reason specified?
|
||||
if (!$reason_row['reason_title'] || !$reason_row['reason_description'])
|
||||
{
|
||||
$error[] = $user->lang['NO_REASON_INFO'];
|
||||
}
|
||||
|
||||
$check_double = ($action == 'add') ? true : false;
|
||||
|
||||
if ($action == 'edit')
|
||||
{
|
||||
$sql = 'SELECT reason_title
|
||||
FROM ' . REPORTS_REASONS_TABLE . "
|
||||
WHERE reason_id = $reason_id";
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (strtolower($row['reason_title']) == 'other' || strtolower($reason_row['reason_title']) == 'other')
|
||||
{
|
||||
$reason_row['reason_title'] = 'other';
|
||||
}
|
||||
|
||||
if ($row['reason_title'] != $reason_row['reason_title'])
|
||||
{
|
||||
$check_double = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for same reason if adding it...
|
||||
if ($check_double)
|
||||
{
|
||||
$sql = 'SELECT reason_id
|
||||
FROM ' . REPORTS_REASONS_TABLE . "
|
||||
WHERE reason_title = '" . $db->sql_escape($reason_row['reason_title']) . "'";
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($row || ($action == 'add' && strtolower($reason_row['reason_title']) == 'other'))
|
||||
{
|
||||
$error[] = $user->lang['REASON_ALREADY_EXIST'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!count($error))
|
||||
{
|
||||
// New reason?
|
||||
if ($action == 'add')
|
||||
{
|
||||
// Get new order...
|
||||
$sql = 'SELECT MAX(reason_order) as max_reason_order
|
||||
FROM ' . REPORTS_REASONS_TABLE;
|
||||
$result = $db->sql_query($sql);
|
||||
$max_order = (int) $db->sql_fetchfield('max_reason_order');
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$sql_ary = array(
|
||||
'reason_title' => (string) $reason_row['reason_title'],
|
||||
'reason_description' => (string) $reason_row['reason_description'],
|
||||
'reason_order' => $max_order + 1
|
||||
);
|
||||
|
||||
$db->sql_query('INSERT INTO ' . REPORTS_REASONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
|
||||
|
||||
$log = 'ADDED';
|
||||
}
|
||||
else if ($reason_id)
|
||||
{
|
||||
$sql_ary = array(
|
||||
'reason_title' => (string) $reason_row['reason_title'],
|
||||
'reason_description' => (string) $reason_row['reason_description'],
|
||||
);
|
||||
|
||||
$db->sql_query('UPDATE ' . REPORTS_REASONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
|
||||
WHERE reason_id = ' . $reason_id);
|
||||
|
||||
$log = 'UPDATED';
|
||||
}
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_REASON_' . $log, false, array($reason_row['reason_title']));
|
||||
trigger_error($user->lang['REASON_' . $log] . adm_back_link($this->u_action));
|
||||
}
|
||||
}
|
||||
else if ($reason_id)
|
||||
{
|
||||
$sql = 'SELECT *
|
||||
FROM ' . REPORTS_REASONS_TABLE . '
|
||||
WHERE reason_id = ' . $reason_id;
|
||||
$result = $db->sql_query($sql);
|
||||
$reason_row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$reason_row)
|
||||
{
|
||||
trigger_error($user->lang['NO_REASON'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
$l_title = ($action == 'edit') ? 'EDIT' : 'ADD';
|
||||
|
||||
$translated = false;
|
||||
|
||||
// If the reason is defined within the language file, we will use the localized version, else just use the database entry...
|
||||
if (isset($user->lang['report_reasons']['TITLE'][strtoupper($reason_row['reason_title'])]) && isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($reason_row['reason_title'])]))
|
||||
{
|
||||
$translated = true;
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'L_TITLE' => $user->lang['REASON_' . $l_title],
|
||||
'U_ACTION' => $this->u_action . "&id=$reason_id&action=$action",
|
||||
'U_BACK' => $this->u_action,
|
||||
'ERROR_MSG' => (count($error)) ? implode('<br />', $error) : '',
|
||||
|
||||
'REASON_TITLE' => $reason_row['reason_title'],
|
||||
'REASON_DESCRIPTION' => $reason_row['reason_description'],
|
||||
|
||||
'TRANSLATED_TITLE' => ($translated) ? $user->lang['report_reasons']['TITLE'][strtoupper($reason_row['reason_title'])] : '',
|
||||
'TRANSLATED_DESCRIPTION'=> ($translated) ? $user->lang['report_reasons']['DESCRIPTION'][strtoupper($reason_row['reason_title'])] : '',
|
||||
|
||||
'S_AVAILABLE_TITLES' => implode($user->lang['COMMA_SEPARATOR'], array_map('htmlspecialchars', array_keys($user->lang['report_reasons']['TITLE']))),
|
||||
'S_EDIT_REASON' => true,
|
||||
'S_TRANSLATED' => $translated,
|
||||
'S_ERROR' => (count($error)) ? true : false,
|
||||
)
|
||||
);
|
||||
|
||||
return;
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
|
||||
$sql = 'SELECT *
|
||||
FROM ' . REPORTS_REASONS_TABLE . '
|
||||
WHERE reason_id = ' . $reason_id;
|
||||
$result = $db->sql_query($sql);
|
||||
$reason_row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$reason_row)
|
||||
{
|
||||
trigger_error($user->lang['NO_REASON'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
if (strtolower($reason_row['reason_title']) == 'other')
|
||||
{
|
||||
trigger_error($user->lang['NO_REMOVE_DEFAULT_REASON'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
// Let the deletion be confirmed...
|
||||
if (confirm_box(true))
|
||||
{
|
||||
$sql = 'SELECT reason_id
|
||||
FROM ' . REPORTS_REASONS_TABLE . "
|
||||
WHERE LOWER(reason_title) = 'other'";
|
||||
$result = $db->sql_query($sql);
|
||||
$other_reason_id = (int) $db->sql_fetchfield('reason_id');
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
switch ($db->get_sql_layer())
|
||||
{
|
||||
// The ugly one!
|
||||
case 'mysqli':
|
||||
// Change the reports using this reason to 'other'
|
||||
$sql = 'UPDATE ' . REPORTS_TABLE . '
|
||||
SET reason_id = ' . $other_reason_id . ", report_text = CONCAT('" . $db->sql_escape($reason_row['reason_description']) . "\n\n', report_text)
|
||||
WHERE reason_id = $reason_id";
|
||||
break;
|
||||
|
||||
// Standard? What's that?
|
||||
case 'mssql_odbc':
|
||||
case 'mssqlnative':
|
||||
// Change the reports using this reason to 'other'
|
||||
$sql = "DECLARE @ptrval binary(16)
|
||||
|
||||
SELECT @ptrval = TEXTPTR(report_text)
|
||||
FROM " . REPORTS_TABLE . "
|
||||
WHERE reason_id = " . $reason_id . "
|
||||
|
||||
UPDATETEXT " . REPORTS_TABLE . ".report_text @ptrval 0 0 '" . $db->sql_escape($reason_row['reason_description']) . "\n\n'
|
||||
|
||||
UPDATE " . REPORTS_TABLE . '
|
||||
SET reason_id = ' . $other_reason_id . "
|
||||
WHERE reason_id = $reason_id";
|
||||
break;
|
||||
|
||||
// Teh standard
|
||||
case 'postgres':
|
||||
case 'oracle':
|
||||
case 'sqlite3':
|
||||
// Change the reports using this reason to 'other'
|
||||
$sql = 'UPDATE ' . REPORTS_TABLE . '
|
||||
SET reason_id = ' . $other_reason_id . ", report_text = '" . $db->sql_escape($reason_row['reason_description']) . "\n\n' || report_text
|
||||
WHERE reason_id = $reason_id";
|
||||
break;
|
||||
}
|
||||
$db->sql_query($sql);
|
||||
|
||||
$db->sql_query('DELETE FROM ' . REPORTS_REASONS_TABLE . ' WHERE reason_id = ' . $reason_id);
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_REASON_REMOVED', false, array($reason_row['reason_title']));
|
||||
trigger_error($user->lang['REASON_REMOVED'] . adm_back_link($this->u_action));
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
|
||||
'i' => $id,
|
||||
'mode' => $mode,
|
||||
'action' => $action,
|
||||
'id' => $reason_id))
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'move_up':
|
||||
case 'move_down':
|
||||
|
||||
if (!check_link_hash($request->variable('hash', ''), 'acp_reasons'))
|
||||
{
|
||||
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$sql = 'SELECT reason_order
|
||||
FROM ' . REPORTS_REASONS_TABLE . "
|
||||
WHERE reason_id = $reason_id";
|
||||
$result = $db->sql_query($sql);
|
||||
$order = $db->sql_fetchfield('reason_order');
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($order === false || ($order == 0 && $action == 'move_up'))
|
||||
{
|
||||
break;
|
||||
}
|
||||
$order = (int) $order;
|
||||
$order_total = $order * 2 + (($action == 'move_up') ? -1 : 1);
|
||||
|
||||
$sql = 'UPDATE ' . REPORTS_REASONS_TABLE . '
|
||||
SET reason_order = ' . $order_total . ' - reason_order
|
||||
WHERE reason_order IN (' . $order . ', ' . (($action == 'move_up') ? $order - 1 : $order + 1) . ')';
|
||||
$db->sql_query($sql);
|
||||
|
||||
if ($request->is_ajax())
|
||||
{
|
||||
$json_response = new \phpbb\json_response;
|
||||
$json_response->send(array(
|
||||
'success' => (bool) $db->sql_affectedrows(),
|
||||
));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// By default, check that order is valid and fix it if necessary
|
||||
$sql = 'SELECT reason_id, reason_order
|
||||
FROM ' . REPORTS_REASONS_TABLE . '
|
||||
ORDER BY reason_order';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
if ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$order = 0;
|
||||
do
|
||||
{
|
||||
++$order;
|
||||
|
||||
if ($row['reason_order'] != $order)
|
||||
{
|
||||
$sql = 'UPDATE ' . REPORTS_REASONS_TABLE . "
|
||||
SET reason_order = $order
|
||||
WHERE reason_id = {$row['reason_id']}";
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
}
|
||||
while ($row = $db->sql_fetchrow($result));
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_ACTION' => $this->u_action,
|
||||
)
|
||||
);
|
||||
|
||||
// Reason count
|
||||
$sql = 'SELECT reason_id, COUNT(reason_id) AS reason_count
|
||||
FROM ' . REPORTS_TABLE . '
|
||||
GROUP BY reason_id';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$reason_count = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$reason_count[$row['reason_id']] = $row['reason_count'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$sql = 'SELECT *
|
||||
FROM ' . REPORTS_REASONS_TABLE . '
|
||||
ORDER BY reason_order ASC';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$translated = false;
|
||||
$other_reason = ($row['reason_title'] == 'other') ? true : false;
|
||||
|
||||
// If the reason is defined within the language file, we will use the localized version, else just use the database entry...
|
||||
if (isset($user->lang['report_reasons']['TITLE'][strtoupper($row['reason_title'])]) && isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])]))
|
||||
{
|
||||
$row['reason_description'] = $user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])];
|
||||
$row['reason_title'] = $user->lang['report_reasons']['TITLE'][strtoupper($row['reason_title'])];
|
||||
|
||||
$translated = true;
|
||||
}
|
||||
|
||||
$template->assign_block_vars('reasons', array(
|
||||
'REASON_TITLE' => $row['reason_title'],
|
||||
'REASON_DESCRIPTION' => $row['reason_description'],
|
||||
'REASON_COUNT' => (isset($reason_count[$row['reason_id']])) ? $reason_count[$row['reason_id']] : 0,
|
||||
|
||||
'S_TRANSLATED' => $translated,
|
||||
'S_OTHER_REASON' => $other_reason,
|
||||
|
||||
'U_EDIT' => $this->u_action . '&action=edit&id=' . $row['reason_id'],
|
||||
'U_DELETE' => (!$other_reason) ? $this->u_action . '&action=delete&id=' . $row['reason_id'] : '',
|
||||
'U_MOVE_UP' => $this->u_action . '&action=move_up&id=' . $row['reason_id'] . '&hash=' . generate_link_hash('acp_reasons'),
|
||||
'U_MOVE_DOWN' => $this->u_action . '&action=move_down&id=' . $row['reason_id'] . '&hash=' . generate_link_hash('acp_reasons'))
|
||||
);
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
}
|
||||
1396
install/update/new/includes/acp/acp_styles.php
Normal file
1396
install/update/new/includes/acp/acp_styles.php
Normal file
File diff suppressed because it is too large
Load Diff
88
install/update/new/includes/acp/acp_update.php
Normal file
88
install/update/new/includes/acp/acp_update.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
class acp_update
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $config, $user, $template, $request;
|
||||
global $phpbb_root_path, $phpEx, $phpbb_container;
|
||||
|
||||
$user->add_lang('install');
|
||||
|
||||
$this->tpl_name = 'acp_update';
|
||||
$this->page_title = 'ACP_VERSION_CHECK';
|
||||
|
||||
/* @var $version_helper \phpbb\version_helper */
|
||||
$version_helper = $phpbb_container->get('version_helper');
|
||||
try
|
||||
{
|
||||
$recheck = $request->variable('versioncheck_force', false);
|
||||
$updates_available = $version_helper->get_update_on_branch($recheck);
|
||||
$upgrades_available = $version_helper->get_suggested_updates();
|
||||
if (!empty($upgrades_available))
|
||||
{
|
||||
$upgrades_available = array_pop($upgrades_available);
|
||||
}
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
$template->assign_var('S_VERSIONCHECK_FAIL', true);
|
||||
|
||||
$updates_available = array();
|
||||
}
|
||||
|
||||
if (!empty($updates_available))
|
||||
{
|
||||
$template->assign_block_vars('updates_available', $updates_available);
|
||||
}
|
||||
|
||||
$update_link = $phpbb_root_path . 'install/app.' . $phpEx;
|
||||
|
||||
$template_ary = [
|
||||
'S_UP_TO_DATE' => empty($updates_available),
|
||||
'U_ACTION' => $this->u_action,
|
||||
'U_VERSIONCHECK_FORCE' => append_sid($this->u_action . '&versioncheck_force=1'),
|
||||
|
||||
'CURRENT_VERSION' => $config['version'],
|
||||
|
||||
'UPDATE_INSTRUCTIONS' => $user->lang('UPDATE_INSTRUCTIONS', $update_link),
|
||||
'S_VERSION_UPGRADEABLE' => !empty($upgrades_available),
|
||||
'UPGRADE_INSTRUCTIONS' => !empty($upgrades_available) ? $user->lang('UPGRADE_INSTRUCTIONS', $upgrades_available['current'], $upgrades_available['announcement']) : false,
|
||||
];
|
||||
|
||||
$template->assign_vars($template_ary);
|
||||
|
||||
// Incomplete update?
|
||||
if (phpbb_version_compare($config['version'], PHPBB_VERSION, '<'))
|
||||
{
|
||||
$database_update_link = $phpbb_root_path . 'install/app.php/update';
|
||||
|
||||
$template->assign_vars(array(
|
||||
'S_UPDATE_INCOMPLETE' => true,
|
||||
'FILES_VERSION' => PHPBB_VERSION,
|
||||
'INCOMPLETE_INSTRUCTIONS' => $user->lang('UPDATE_INCOMPLETE_EXPLAIN', $database_update_link),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
2689
install/update/new/includes/acp/acp_users.php
Normal file
2689
install/update/new/includes/acp/acp_users.php
Normal file
File diff suppressed because it is too large
Load Diff
1316
install/update/new/includes/acp/auth.php
Normal file
1316
install/update/new/includes/acp/auth.php
Normal file
File diff suppressed because it is too large
Load Diff
707
install/update/new/includes/bbcode.php
Normal file
707
install/update/new/includes/bbcode.php
Normal file
@@ -0,0 +1,707 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* BBCode class
|
||||
*/
|
||||
class bbcode
|
||||
{
|
||||
var $bbcode_uid = '';
|
||||
var $bbcode_bitfield = '';
|
||||
var $bbcode_cache = array();
|
||||
var $bbcode_template = array();
|
||||
|
||||
var $bbcodes = array();
|
||||
|
||||
var $template_bitfield;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct($bitfield = '')
|
||||
{
|
||||
$this->bbcode_set_bitfield($bitfield);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init bbcode cache entries if bitfield is specified
|
||||
*
|
||||
* @param string $bitfield The bbcode bitfield
|
||||
*/
|
||||
function bbcode_set_bitfield($bitfield = '')
|
||||
{
|
||||
if ($bitfield)
|
||||
{
|
||||
$this->bbcode_bitfield = $bitfield;
|
||||
$this->bbcode_cache_init();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Second pass bbcodes
|
||||
*/
|
||||
function bbcode_second_pass(&$message, $bbcode_uid = '', $bbcode_bitfield = false)
|
||||
{
|
||||
if ($bbcode_uid)
|
||||
{
|
||||
$this->bbcode_uid = $bbcode_uid;
|
||||
}
|
||||
|
||||
if ($bbcode_bitfield !== false)
|
||||
{
|
||||
$this->bbcode_bitfield = $bbcode_bitfield;
|
||||
|
||||
// Init those added with a new bbcode_bitfield (already stored codes will not get parsed again)
|
||||
$this->bbcode_cache_init();
|
||||
}
|
||||
|
||||
if (!$this->bbcode_bitfield)
|
||||
{
|
||||
// Remove the uid from tags that have not been transformed into HTML
|
||||
if ($this->bbcode_uid)
|
||||
{
|
||||
$message = str_replace(':' . $this->bbcode_uid, '', $message);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$str = array('search' => array(), 'replace' => array());
|
||||
$preg = array('search' => array(), 'replace' => array());
|
||||
|
||||
$bitfield = new bitfield($this->bbcode_bitfield);
|
||||
$bbcodes_set = $bitfield->get_all_set();
|
||||
|
||||
$undid_bbcode_specialchars = false;
|
||||
foreach ($bbcodes_set as $bbcode_id)
|
||||
{
|
||||
if (!empty($this->bbcode_cache[$bbcode_id]))
|
||||
{
|
||||
foreach ($this->bbcode_cache[$bbcode_id] as $type => $array)
|
||||
{
|
||||
foreach ($array as $search => $replace)
|
||||
{
|
||||
${$type}['search'][] = str_replace('$uid', $this->bbcode_uid, $search);
|
||||
${$type}['replace'][] = $replace;
|
||||
}
|
||||
|
||||
if (count($str['search']))
|
||||
{
|
||||
$message = str_replace($str['search'], $str['replace'], $message);
|
||||
$str = array('search' => array(), 'replace' => array());
|
||||
}
|
||||
|
||||
if (count($preg['search']))
|
||||
{
|
||||
// we need to turn the entities back into their original form to allow the
|
||||
// search patterns to work properly
|
||||
if (!$undid_bbcode_specialchars)
|
||||
{
|
||||
$message = str_replace(array(':', '.'), array(':', '.'), $message);
|
||||
$undid_bbcode_specialchars = true;
|
||||
}
|
||||
|
||||
foreach ($preg['search'] as $key => $search)
|
||||
{
|
||||
if (is_callable($preg['replace'][$key]))
|
||||
{
|
||||
$message = preg_replace_callback($search, $preg['replace'][$key], $message);
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = preg_replace($search, $preg['replace'][$key], $message);
|
||||
}
|
||||
}
|
||||
|
||||
$preg = array('search' => array(), 'replace' => array());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the uid from tags that have not been transformed into HTML
|
||||
$message = str_replace(':' . $this->bbcode_uid, '', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init bbcode cache
|
||||
*
|
||||
* requires: $this->bbcode_bitfield
|
||||
* sets: $this->bbcode_cache with bbcode templates needed for bbcode_bitfield
|
||||
*/
|
||||
function bbcode_cache_init()
|
||||
{
|
||||
global $user, $phpbb_dispatcher, $phpbb_extension_manager, $phpbb_container, $phpbb_filesystem;
|
||||
|
||||
if (empty($this->template_filename))
|
||||
{
|
||||
$this->template_bitfield = new bitfield($user->style['bbcode_bitfield']);
|
||||
|
||||
$template = new \phpbb\template\twig\twig(
|
||||
$phpbb_container->get('path_helper'),
|
||||
$phpbb_container->get('config'),
|
||||
new \phpbb\template\context(),
|
||||
new \phpbb\template\twig\environment(
|
||||
$phpbb_container->get('config'),
|
||||
$phpbb_container->get('filesystem'),
|
||||
$phpbb_container->get('path_helper'),
|
||||
$phpbb_container->getParameter('core.cache_dir'),
|
||||
$phpbb_container->get('ext.manager'),
|
||||
new \phpbb\template\twig\loader(
|
||||
$phpbb_filesystem
|
||||
)
|
||||
),
|
||||
$phpbb_container->getParameter('core.cache_dir'),
|
||||
$phpbb_container->get('user'),
|
||||
$phpbb_container->get('template.twig.extensions.collection'),
|
||||
$phpbb_extension_manager
|
||||
);
|
||||
|
||||
$template->set_style();
|
||||
$template->set_filenames(array('bbcode.html' => 'bbcode.html'));
|
||||
$this->template_filename = $template->get_source_file_for_handle('bbcode.html');
|
||||
}
|
||||
|
||||
$bbcode_ids = $rowset = $sql = array();
|
||||
|
||||
$bitfield = new bitfield($this->bbcode_bitfield);
|
||||
$bbcodes_set = $bitfield->get_all_set();
|
||||
|
||||
foreach ($bbcodes_set as $bbcode_id)
|
||||
{
|
||||
if (isset($this->bbcode_cache[$bbcode_id]))
|
||||
{
|
||||
// do not try to re-cache it if it's already in
|
||||
continue;
|
||||
}
|
||||
$bbcode_ids[] = $bbcode_id;
|
||||
|
||||
if ($bbcode_id > NUM_CORE_BBCODES)
|
||||
{
|
||||
$sql[] = $bbcode_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($sql))
|
||||
{
|
||||
global $db;
|
||||
|
||||
$sql = 'SELECT *
|
||||
FROM ' . BBCODES_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('bbcode_id', $sql);
|
||||
$result = $db->sql_query($sql, 3600);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
// To circumvent replacing newlines with <br /> for the generated html,
|
||||
// we use carriage returns here. They are later changed back to newlines
|
||||
$row['bbcode_tpl'] = str_replace("\n", "\r", $row['bbcode_tpl']);
|
||||
$row['second_pass_replace'] = str_replace("\n", "\r", $row['second_pass_replace']);
|
||||
|
||||
$rowset[$row['bbcode_id']] = $row;
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
// To perform custom second pass in extension, use $this->bbcode_second_pass_by_extension()
|
||||
// method which accepts variable number of parameters
|
||||
foreach ($bbcode_ids as $bbcode_id)
|
||||
{
|
||||
switch ($bbcode_id)
|
||||
{
|
||||
case BBCODE_ID_QUOTE:
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'str' => array(
|
||||
'[/quote:$uid]' => $this->bbcode_tpl('quote_close', $bbcode_id)
|
||||
),
|
||||
'preg' => array(
|
||||
'#\[quote(?:="(.*?)")?:$uid\]((?!\[quote(?:=".*?")?:$uid\]).)?#is' => function ($match) {
|
||||
if (!isset($match[2]))
|
||||
{
|
||||
$match[2] = '';
|
||||
}
|
||||
|
||||
return $this->bbcode_second_pass_quote($match[1], $match[2]);
|
||||
},
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case BBCODE_ID_B:
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'str' => array(
|
||||
'[b:$uid]' => $this->bbcode_tpl('b_open', $bbcode_id),
|
||||
'[/b:$uid]' => $this->bbcode_tpl('b_close', $bbcode_id),
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case BBCODE_ID_I:
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'str' => array(
|
||||
'[i:$uid]' => $this->bbcode_tpl('i_open', $bbcode_id),
|
||||
'[/i:$uid]' => $this->bbcode_tpl('i_close', $bbcode_id),
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case BBCODE_ID_URL:
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'preg' => array(
|
||||
'#\[url:$uid\]((.*?))\[/url:$uid\]#s' => $this->bbcode_tpl('url', $bbcode_id),
|
||||
'#\[url=([^\[]+?):$uid\](.*?)\[/url:$uid\]#s' => $this->bbcode_tpl('url', $bbcode_id),
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case BBCODE_ID_IMG:
|
||||
if ($user->optionget('viewimg'))
|
||||
{
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'preg' => array(
|
||||
'#\[img:$uid\](.*?)\[/img:$uid\]#s' => $this->bbcode_tpl('img', $bbcode_id),
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'preg' => array(
|
||||
'#\[img:$uid\](.*?)\[/img:$uid\]#s' => str_replace('$2', '[ img ]', $this->bbcode_tpl('url', $bbcode_id, true)),
|
||||
)
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case BBCODE_ID_SIZE:
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'preg' => array(
|
||||
'#\[size=([\-\+]?\d+):$uid\](.*?)\[/size:$uid\]#s' => $this->bbcode_tpl('size', $bbcode_id),
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case BBCODE_ID_COLOR:
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'preg' => array(
|
||||
'!\[color=(#[0-9a-f]{3}|#[0-9a-f]{6}|[a-z\-]+):$uid\](.*?)\[/color:$uid\]!is' => $this->bbcode_tpl('color', $bbcode_id),
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case BBCODE_ID_U:
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'str' => array(
|
||||
'[u:$uid]' => $this->bbcode_tpl('u_open', $bbcode_id),
|
||||
'[/u:$uid]' => $this->bbcode_tpl('u_close', $bbcode_id),
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case BBCODE_ID_CODE:
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'preg' => array(
|
||||
'#\[code(?:=([a-z]+))?:$uid\](.*?)\[/code:$uid\]#is' => function ($match) {
|
||||
return $this->bbcode_second_pass_code($match[1], $match[2]);
|
||||
},
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case BBCODE_ID_LIST:
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'preg' => array(
|
||||
'#(\[\/?(list|\*):[mou]?:?$uid\])[\n]{1}#' => "\$1",
|
||||
'#(\[list=([^\[]+):$uid\])[\n]{1}#' => "\$1",
|
||||
'#\[list=([^\[]+):$uid\]#' => function ($match) {
|
||||
return $this->bbcode_list($match[1]);
|
||||
},
|
||||
),
|
||||
'str' => array(
|
||||
'[list:$uid]' => $this->bbcode_tpl('ulist_open_default', $bbcode_id),
|
||||
'[/list:u:$uid]' => $this->bbcode_tpl('ulist_close', $bbcode_id),
|
||||
'[/list:o:$uid]' => $this->bbcode_tpl('olist_close', $bbcode_id),
|
||||
'[*:$uid]' => $this->bbcode_tpl('listitem', $bbcode_id),
|
||||
'[/*:$uid]' => $this->bbcode_tpl('listitem_close', $bbcode_id),
|
||||
'[/*:m:$uid]' => $this->bbcode_tpl('listitem_close', $bbcode_id)
|
||||
),
|
||||
);
|
||||
break;
|
||||
|
||||
case BBCODE_ID_EMAIL:
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'preg' => array(
|
||||
'#\[email:$uid\]((.*?))\[/email:$uid\]#is' => $this->bbcode_tpl('email', $bbcode_id),
|
||||
'#\[email=([^\[]+):$uid\](.*?)\[/email:$uid\]#is' => $this->bbcode_tpl('email', $bbcode_id)
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case BBCODE_ID_FLASH:
|
||||
if ($user->optionget('viewflash'))
|
||||
{
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'preg' => array(
|
||||
'#\[flash=([0-9]+),([0-9]+):$uid\](.*?)\[/flash:$uid\]#' => $this->bbcode_tpl('flash', $bbcode_id),
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'preg' => array(
|
||||
'#\[flash=([0-9]+),([0-9]+):$uid\](.*?)\[/flash:$uid\]#' => str_replace('$1', '$3', str_replace('$2', '[ flash ]', $this->bbcode_tpl('url', $bbcode_id, true)))
|
||||
)
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case BBCODE_ID_ATTACH:
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'str' => array(
|
||||
'[/attachment:$uid]' => $this->bbcode_tpl('inline_attachment_close', $bbcode_id)
|
||||
),
|
||||
'preg' => array(
|
||||
'#\[attachment=([0-9]+):$uid\]#' => $this->bbcode_tpl('inline_attachment_open', $bbcode_id)
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isset($rowset[$bbcode_id]))
|
||||
{
|
||||
if ($this->template_bitfield->get($bbcode_id))
|
||||
{
|
||||
// The bbcode requires a custom template to be loaded
|
||||
if (!$bbcode_tpl = $this->bbcode_tpl($rowset[$bbcode_id]['bbcode_tag'], $bbcode_id))
|
||||
{
|
||||
// For some reason, the required template seems not to be available, use the default template
|
||||
$bbcode_tpl = (!empty($rowset[$bbcode_id]['second_pass_replace'])) ? $rowset[$bbcode_id]['second_pass_replace'] : $rowset[$bbcode_id]['bbcode_tpl'];
|
||||
}
|
||||
else
|
||||
{
|
||||
// In order to use templates with custom bbcodes we need
|
||||
// to replace all {VARS} to corresponding backreferences
|
||||
// Note that backreferences are numbered from bbcode_match
|
||||
if (preg_match_all('/\{(URL|LOCAL_URL|EMAIL|TEXT|SIMPLETEXT|INTTEXT|IDENTIFIER|COLOR|NUMBER)[0-9]*\}/', $rowset[$bbcode_id]['bbcode_match'], $m))
|
||||
{
|
||||
foreach ($m[0] as $i => $tok)
|
||||
{
|
||||
$bbcode_tpl = str_replace($tok, '$' . ($i + 1), $bbcode_tpl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default template
|
||||
$bbcode_tpl = (!empty($rowset[$bbcode_id]['second_pass_replace'])) ? $rowset[$bbcode_id]['second_pass_replace'] : $rowset[$bbcode_id]['bbcode_tpl'];
|
||||
}
|
||||
|
||||
// Replace {L_*} lang strings
|
||||
$bbcode_tpl = preg_replace_callback('/{L_([A-Z0-9_]+)}/', function ($match) use ($user) {
|
||||
return (!empty($user->lang[$match[1]])) ? $user->lang($match[1]) : ucwords(strtolower(str_replace('_', ' ', $match[1])));
|
||||
}, $bbcode_tpl);
|
||||
|
||||
if (!empty($rowset[$bbcode_id]['second_pass_replace']))
|
||||
{
|
||||
// The custom BBCode requires second-pass pattern replacements
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'preg' => array($rowset[$bbcode_id]['second_pass_match'] => $bbcode_tpl)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->bbcode_cache[$bbcode_id] = array(
|
||||
'str' => array($rowset[$bbcode_id]['second_pass_match'] => $bbcode_tpl)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->bbcode_cache[$bbcode_id] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$bbcode_cache = $this->bbcode_cache;
|
||||
$bbcode_bitfield = $this->bbcode_bitfield;
|
||||
$bbcode_uid = $this->bbcode_uid;
|
||||
|
||||
/**
|
||||
* Use this event to modify the bbcode_cache
|
||||
*
|
||||
* @event core.bbcode_cache_init_end
|
||||
* @var array bbcode_cache The array of cached search and replace patterns of bbcodes
|
||||
* @var string bbcode_bitfield The bbcode bitfield
|
||||
* @var string bbcode_uid The bbcode uid
|
||||
* @since 3.1.3-RC1
|
||||
*/
|
||||
$vars = array('bbcode_cache', 'bbcode_bitfield', 'bbcode_uid');
|
||||
extract($phpbb_dispatcher->trigger_event('core.bbcode_cache_init_end', compact($vars)));
|
||||
|
||||
$this->bbcode_cache = $bbcode_cache;
|
||||
$this->bbcode_bitfield = $bbcode_bitfield;
|
||||
$this->bbcode_uid = $bbcode_uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return bbcode template
|
||||
*/
|
||||
function bbcode_tpl($tpl_name, $bbcode_id = -1, $skip_bitfield_check = false)
|
||||
{
|
||||
static $bbcode_hardtpl = array();
|
||||
if (empty($bbcode_hardtpl))
|
||||
{
|
||||
global $user;
|
||||
|
||||
$bbcode_hardtpl = array(
|
||||
'b_open' => '<span style="font-weight: bold">',
|
||||
'b_close' => '</span>',
|
||||
'i_open' => '<span style="font-style: italic">',
|
||||
'i_close' => '</span>',
|
||||
'u_open' => '<span style="text-decoration: underline">',
|
||||
'u_close' => '</span>',
|
||||
'img' => '<img src="$1" class="postimage" alt="' . $user->lang['IMAGE'] . '" />',
|
||||
'size' => '<span style="font-size: $1%; line-height: normal">$2</span>',
|
||||
'color' => '<span style="color: $1">$2</span>',
|
||||
'email' => '<a href="mailto:$1">$2</a>'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bbcode_id != -1 && !$skip_bitfield_check && !$this->template_bitfield->get($bbcode_id))
|
||||
{
|
||||
return (isset($bbcode_hardtpl[$tpl_name])) ? $bbcode_hardtpl[$tpl_name] : false;
|
||||
}
|
||||
|
||||
if (empty($this->bbcode_template))
|
||||
{
|
||||
if (($tpl = file_get_contents($this->template_filename)) === false)
|
||||
{
|
||||
trigger_error('Could not load bbcode template', E_USER_ERROR);
|
||||
}
|
||||
|
||||
// replace \ with \\ and then ' with \'.
|
||||
$tpl = str_replace('\\', '\\\\', $tpl);
|
||||
$tpl = str_replace("'", "\'", $tpl);
|
||||
|
||||
// strip newlines and indent
|
||||
$tpl = preg_replace("/\n[\n\r\s\t]*/", '', $tpl);
|
||||
|
||||
// Turn template blocks into PHP assignment statements for the values of $bbcode_tpl..
|
||||
$this->bbcode_template = array();
|
||||
|
||||
// Capture the BBCode template matches
|
||||
// Allow phpBB template or the Twig syntax
|
||||
$matches = (preg_match_all('#<!-- BEGIN (.*?) -->(.*?)<!-- END (?:.*?) -->#', $tpl, $match)) ?:
|
||||
preg_match_all('#{% for (.*?) in .*? %}(.*?){% endfor %}#s', $tpl, $match);
|
||||
|
||||
for ($i = 0; $i < $matches; $i++)
|
||||
{
|
||||
if (empty($match[1][$i]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->bbcode_template[$match[1][$i]] = $this->bbcode_tpl_replace($match[1][$i], $match[2][$i]);
|
||||
}
|
||||
}
|
||||
|
||||
return (isset($this->bbcode_template[$tpl_name])) ? $this->bbcode_template[$tpl_name] : ((isset($bbcode_hardtpl[$tpl_name])) ? $bbcode_hardtpl[$tpl_name] : false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return bbcode template replacement
|
||||
*/
|
||||
function bbcode_tpl_replace($tpl_name, $tpl)
|
||||
{
|
||||
global $user;
|
||||
|
||||
static $replacements = array(
|
||||
'quote_username_open' => array('{USERNAME}' => '$1'),
|
||||
'color' => array('{COLOR}' => '$1', '{TEXT}' => '$2'),
|
||||
'size' => array('{SIZE}' => '$1', '{TEXT}' => '$2'),
|
||||
'img' => array('{URL}' => '$1'),
|
||||
'flash' => array('{WIDTH}' => '$1', '{HEIGHT}' => '$2', '{URL}' => '$3'),
|
||||
'url' => array('{URL}' => '$1', '{DESCRIPTION}' => '$2'),
|
||||
'email' => array('{EMAIL}' => '$1', '{DESCRIPTION}' => '$2')
|
||||
);
|
||||
|
||||
$tpl = preg_replace_callback('/{L_([A-Z0-9_]+)}/', function ($match) use ($user) {
|
||||
return (!empty($user->lang[$match[1]])) ? $user->lang($match[1]) : ucwords(strtolower(str_replace('_', ' ', $match[1])));
|
||||
}, $tpl);
|
||||
|
||||
if (!empty($replacements[$tpl_name]))
|
||||
{
|
||||
$tpl = strtr($tpl, $replacements[$tpl_name]);
|
||||
}
|
||||
|
||||
return trim($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Second parse list bbcode
|
||||
*/
|
||||
function bbcode_list($type)
|
||||
{
|
||||
if ($type == '')
|
||||
{
|
||||
$tpl = 'ulist_open_default';
|
||||
$type = 'default';
|
||||
}
|
||||
else if ($type == 'i')
|
||||
{
|
||||
$tpl = 'olist_open';
|
||||
$type = 'lower-roman';
|
||||
}
|
||||
else if ($type == 'I')
|
||||
{
|
||||
$tpl = 'olist_open';
|
||||
$type = 'upper-roman';
|
||||
}
|
||||
else if (preg_match('#^(disc|circle|square)$#i', $type))
|
||||
{
|
||||
$tpl = 'ulist_open';
|
||||
$type = strtolower($type);
|
||||
}
|
||||
else if (preg_match('#^[a-z]$#', $type))
|
||||
{
|
||||
$tpl = 'olist_open';
|
||||
$type = 'lower-alpha';
|
||||
}
|
||||
else if (preg_match('#[A-Z]#', $type))
|
||||
{
|
||||
$tpl = 'olist_open';
|
||||
$type = 'upper-alpha';
|
||||
}
|
||||
else if (is_numeric($type))
|
||||
{
|
||||
$tpl = 'olist_open';
|
||||
$type = 'decimal';
|
||||
}
|
||||
else
|
||||
{
|
||||
$tpl = 'olist_open';
|
||||
$type = 'decimal';
|
||||
}
|
||||
|
||||
return str_replace('{LIST_TYPE}', $type, $this->bbcode_tpl($tpl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Second parse quote tag
|
||||
*/
|
||||
function bbcode_second_pass_quote($username, $quote)
|
||||
{
|
||||
// when using the /e modifier, preg_replace slashes double-quotes but does not
|
||||
// seem to slash anything else
|
||||
$quote = str_replace('\"', '"', $quote);
|
||||
$username = str_replace('\"', '"', $username);
|
||||
|
||||
// remove newline at the beginning
|
||||
if ($quote == "\n")
|
||||
{
|
||||
$quote = '';
|
||||
}
|
||||
|
||||
$quote = (($username) ? str_replace('$1', $username, $this->bbcode_tpl('quote_username_open')) : $this->bbcode_tpl('quote_open')) . $quote;
|
||||
|
||||
return $quote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Second parse code tag
|
||||
*/
|
||||
function bbcode_second_pass_code($type, $code)
|
||||
{
|
||||
// when using the /e modifier, preg_replace slashes double-quotes but does not
|
||||
// seem to slash anything else
|
||||
$code = str_replace('\"', '"', $code);
|
||||
|
||||
switch ($type)
|
||||
{
|
||||
case 'php':
|
||||
// Not the english way, but valid because of hardcoded syntax highlighting
|
||||
if (strpos($code, '<span class="syntaxdefault"><br /></span>') === 0)
|
||||
{
|
||||
$code = substr($code, 41);
|
||||
}
|
||||
|
||||
// no break;
|
||||
|
||||
default:
|
||||
$code = str_replace("\t", ' ', $code);
|
||||
$code = str_replace(' ', ' ', $code);
|
||||
$code = str_replace(' ', ' ', $code);
|
||||
$code = str_replace("\n ", "\n ", $code);
|
||||
|
||||
// keep space at the beginning
|
||||
if (!empty($code) && $code[0] == ' ')
|
||||
{
|
||||
$code = ' ' . substr($code, 1);
|
||||
}
|
||||
|
||||
// remove newline at the beginning
|
||||
if (!empty($code) && $code[0] == "\n")
|
||||
{
|
||||
$code = substr($code, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$code = $this->bbcode_tpl('code_open') . $code . $this->bbcode_tpl('code_close');
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to perform custom bbcode second pass by extensions
|
||||
* can be used to assign bbcode pattern replacement
|
||||
* Example: '#\[list=([^\[]+):$uid\]#e' => "\$this->bbcode_second_pass_by_extension('\$1')"
|
||||
*
|
||||
* Accepts variable number of parameters
|
||||
*
|
||||
* @return mixed Second pass result
|
||||
*/
|
||||
function bbcode_second_pass_by_extension()
|
||||
{
|
||||
global $phpbb_dispatcher;
|
||||
|
||||
$return = false;
|
||||
$params_array = func_get_args();
|
||||
|
||||
/**
|
||||
* Event to perform bbcode second pass with
|
||||
* the custom validating methods provided by extensions
|
||||
*
|
||||
* @event core.bbcode_second_pass_by_extension
|
||||
* @var array params_array Array with the function parameters
|
||||
* @var mixed return Second pass result to return
|
||||
*
|
||||
* @since 3.1.5-RC1
|
||||
*/
|
||||
$vars = array('params_array', 'return');
|
||||
extract($phpbb_dispatcher->trigger_event('core.bbcode_second_pass_by_extension', compact($vars)));
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
92
install/update/new/includes/compatibility_globals.php
Normal file
92
install/update/new/includes/compatibility_globals.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Deprecated globals
|
||||
//
|
||||
define('ATTACHMENT_CATEGORY_WM', 2); // Windows Media Files - Streaming - @deprecated 3.2
|
||||
define('ATTACHMENT_CATEGORY_RM', 3); // Real Media Files - Streaming - @deprecated 3.2
|
||||
define('ATTACHMENT_CATEGORY_QUICKTIME', 6); // Quicktime/Mov files - @deprecated 3.2
|
||||
define('ATTACHMENT_CATEGORY_FLASH', 5); // Flash/SWF files - @deprecated 3.3
|
||||
|
||||
/**
|
||||
* Sets compatibility globals in the global scope
|
||||
*
|
||||
* This function registers compatibility variables to the global
|
||||
* variable scope. This is required to make it possible to include this file
|
||||
* in a service.
|
||||
*/
|
||||
function register_compatibility_globals()
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
global $cache, $phpbb_dispatcher, $request, $user, $auth, $db, $config, $language, $phpbb_log;
|
||||
global $symfony_request, $phpbb_filesystem, $phpbb_path_helper, $phpbb_extension_manager, $template;
|
||||
|
||||
// set up caching
|
||||
/* @var $cache \phpbb\cache\service */
|
||||
$cache = $phpbb_container->get('cache');
|
||||
|
||||
// Instantiate some basic classes
|
||||
/* @var $phpbb_dispatcher \phpbb\event\dispatcher */
|
||||
$phpbb_dispatcher = $phpbb_container->get('dispatcher');
|
||||
|
||||
/* @var $request \phpbb\request\request_interface */
|
||||
$request = $phpbb_container->get('request');
|
||||
// Inject request instance, so only this instance is used with request_var
|
||||
request_var('', 0, false, false, $request);
|
||||
|
||||
/* @var $user \phpbb\user */
|
||||
$user = $phpbb_container->get('user');
|
||||
|
||||
/* @var \phpbb\language\language $language */
|
||||
$language = $phpbb_container->get('language');
|
||||
|
||||
/* @var $auth \phpbb\auth\auth */
|
||||
$auth = $phpbb_container->get('auth');
|
||||
|
||||
/* @var $db \phpbb\db\driver\driver_interface */
|
||||
$db = $phpbb_container->get('dbal.conn');
|
||||
|
||||
// Grab global variables, re-cache if necessary
|
||||
/* @var $config phpbb\config\db */
|
||||
$config = $phpbb_container->get('config');
|
||||
set_config('', '', false, $config);
|
||||
set_config_count('', 0, false, $config);
|
||||
|
||||
/* @var $phpbb_log \phpbb\log\log_interface */
|
||||
$phpbb_log = $phpbb_container->get('log');
|
||||
|
||||
/* @var $symfony_request \phpbb\symfony_request */
|
||||
$symfony_request = $phpbb_container->get('symfony_request');
|
||||
|
||||
/* @var $phpbb_filesystem \phpbb\filesystem\filesystem_interface */
|
||||
$phpbb_filesystem = $phpbb_container->get('filesystem');
|
||||
|
||||
/* @var $phpbb_path_helper \phpbb\path_helper */
|
||||
$phpbb_path_helper = $phpbb_container->get('path_helper');
|
||||
|
||||
// load extensions
|
||||
/* @var $phpbb_extension_manager \phpbb\extension\manager */
|
||||
$phpbb_extension_manager = $phpbb_container->get('ext.manager');
|
||||
|
||||
/* @var $template \phpbb\template\template */
|
||||
$template = $phpbb_container->get('template');
|
||||
}
|
||||
312
install/update/new/includes/constants.php
Normal file
312
install/update/new/includes/constants.php
Normal file
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* valid external constants:
|
||||
* PHPBB_MSG_HANDLER
|
||||
* PHPBB_DB_NEW_LINK
|
||||
* PHPBB_ROOT_PATH
|
||||
* PHPBB_ADMIN_PATH
|
||||
*/
|
||||
|
||||
// phpBB Version
|
||||
@define('PHPBB_VERSION', '3.3.0');
|
||||
|
||||
// QA-related
|
||||
// define('PHPBB_QA', 1);
|
||||
|
||||
// User related
|
||||
define('ANONYMOUS', 1);
|
||||
|
||||
define('USER_ACTIVATION_NONE', 0);
|
||||
define('USER_ACTIVATION_SELF', 1);
|
||||
define('USER_ACTIVATION_ADMIN', 2);
|
||||
define('USER_ACTIVATION_DISABLE', 3);
|
||||
|
||||
define('AVATAR_UPLOAD', 1);
|
||||
define('AVATAR_REMOTE', 2);
|
||||
define('AVATAR_GALLERY', 3);
|
||||
|
||||
define('USER_NORMAL', 0);
|
||||
define('USER_INACTIVE', 1);
|
||||
define('USER_IGNORE', 2);
|
||||
define('USER_FOUNDER', 3);
|
||||
|
||||
define('INACTIVE_REGISTER', 1); // Newly registered account
|
||||
define('INACTIVE_PROFILE', 2); // Profile details changed
|
||||
define('INACTIVE_MANUAL', 3); // Account deactivated by administrator
|
||||
define('INACTIVE_REMIND', 4); // Forced user account reactivation
|
||||
|
||||
// ACL
|
||||
define('ACL_NEVER', 0);
|
||||
define('ACL_YES', 1);
|
||||
define('ACL_NO', -1);
|
||||
|
||||
// Login error codes
|
||||
define('LOGIN_CONTINUE', 1);
|
||||
define('LOGIN_BREAK', 2);
|
||||
define('LOGIN_SUCCESS', 3);
|
||||
define('LOGIN_SUCCESS_CREATE_PROFILE', 20);
|
||||
define('LOGIN_SUCCESS_LINK_PROFILE', 21);
|
||||
define('LOGIN_ERROR_USERNAME', 10);
|
||||
define('LOGIN_ERROR_PASSWORD', 11);
|
||||
define('LOGIN_ERROR_ACTIVE', 12);
|
||||
define('LOGIN_ERROR_ATTEMPTS', 13);
|
||||
define('LOGIN_ERROR_EXTERNAL_AUTH', 14);
|
||||
define('LOGIN_ERROR_PASSWORD_CONVERT', 15);
|
||||
|
||||
// Maximum login attempts
|
||||
// The value is arbitrary, but it has to fit into the user_login_attempts field.
|
||||
define('LOGIN_ATTEMPTS_MAX', 100);
|
||||
|
||||
// Group settings
|
||||
define('GROUP_OPEN', 0);
|
||||
define('GROUP_CLOSED', 1);
|
||||
define('GROUP_HIDDEN', 2);
|
||||
define('GROUP_SPECIAL', 3);
|
||||
define('GROUP_FREE', 4);
|
||||
|
||||
// Forum/Topic states
|
||||
define('FORUM_CAT', 0);
|
||||
define('FORUM_POST', 1);
|
||||
define('FORUM_LINK', 2);
|
||||
define('ITEM_UNLOCKED', 0);
|
||||
define('ITEM_LOCKED', 1);
|
||||
define('ITEM_MOVED', 2);
|
||||
|
||||
define('ITEM_UNAPPROVED', 0); // => has not yet been approved
|
||||
define('ITEM_APPROVED', 1); // => has been approved, and has not been soft deleted
|
||||
define('ITEM_DELETED', 2); // => has been soft deleted
|
||||
define('ITEM_REAPPROVE', 3); // => has been edited and needs to be re-approved
|
||||
|
||||
// Forum Flags
|
||||
define('FORUM_FLAG_LINK_TRACK', 1);
|
||||
define('FORUM_FLAG_PRUNE_POLL', 2);
|
||||
define('FORUM_FLAG_PRUNE_ANNOUNCE', 4);
|
||||
define('FORUM_FLAG_PRUNE_STICKY', 8);
|
||||
define('FORUM_FLAG_ACTIVE_TOPICS', 16);
|
||||
define('FORUM_FLAG_POST_REVIEW', 32);
|
||||
define('FORUM_FLAG_QUICK_REPLY', 64);
|
||||
|
||||
// Forum Options... sequential order. Modifications should begin at number 10 (number 29 is maximum)
|
||||
define('FORUM_OPTION_FEED_NEWS', 1);
|
||||
define('FORUM_OPTION_FEED_EXCLUDE', 2);
|
||||
|
||||
// Optional text flags
|
||||
define('OPTION_FLAG_BBCODE', 1);
|
||||
define('OPTION_FLAG_SMILIES', 2);
|
||||
define('OPTION_FLAG_LINKS', 4);
|
||||
|
||||
// Topic types
|
||||
define('POST_NORMAL', 0);
|
||||
define('POST_STICKY', 1);
|
||||
define('POST_ANNOUNCE', 2);
|
||||
define('POST_GLOBAL', 3);
|
||||
|
||||
// Lastread types
|
||||
define('TRACK_NORMAL', 0);
|
||||
define('TRACK_POSTED', 1);
|
||||
|
||||
// Notify methods
|
||||
define('NOTIFY_EMAIL', 0);
|
||||
define('NOTIFY_IM', 1);
|
||||
define('NOTIFY_BOTH', 2);
|
||||
|
||||
// Notify status
|
||||
define('NOTIFY_YES', 0);
|
||||
define('NOTIFY_NO', 1);
|
||||
|
||||
// Email Priority Settings
|
||||
define('MAIL_LOW_PRIORITY', 4);
|
||||
define('MAIL_NORMAL_PRIORITY', 3);
|
||||
define('MAIL_HIGH_PRIORITY', 2);
|
||||
|
||||
// Log types
|
||||
define('LOG_ADMIN', 0);
|
||||
define('LOG_MOD', 1);
|
||||
define('LOG_CRITICAL', 2);
|
||||
define('LOG_USERS', 3);
|
||||
|
||||
// Private messaging - Do NOT change these values
|
||||
define('PRIVMSGS_HOLD_BOX', -4);
|
||||
define('PRIVMSGS_NO_BOX', -3);
|
||||
define('PRIVMSGS_OUTBOX', -2);
|
||||
define('PRIVMSGS_SENTBOX', -1);
|
||||
define('PRIVMSGS_INBOX', 0);
|
||||
|
||||
// Full Folder Actions
|
||||
define('FULL_FOLDER_NONE', -3);
|
||||
define('FULL_FOLDER_DELETE', -2);
|
||||
define('FULL_FOLDER_HOLD', -1);
|
||||
|
||||
// Download Modes - Attachments
|
||||
define('INLINE_LINK', 1);
|
||||
// This mode is only used internally to allow modders extending the attachment functionality
|
||||
define('PHYSICAL_LINK', 2);
|
||||
|
||||
// Confirm types
|
||||
define('CONFIRM_REG', 1);
|
||||
define('CONFIRM_LOGIN', 2);
|
||||
define('CONFIRM_POST', 3);
|
||||
define('CONFIRM_REPORT', 4);
|
||||
|
||||
// Categories - Attachments
|
||||
define('ATTACHMENT_CATEGORY_NONE', 0);
|
||||
define('ATTACHMENT_CATEGORY_IMAGE', 1); // Inline Images
|
||||
define('ATTACHMENT_CATEGORY_THUMB', 4); // Not used within the database, only while displaying posts
|
||||
|
||||
// BBCode UID length
|
||||
define('BBCODE_UID_LEN', 8);
|
||||
|
||||
// Number of core BBCodes
|
||||
define('NUM_CORE_BBCODES', 12);
|
||||
define('NUM_PREDEFINED_BBCODES', 22);
|
||||
|
||||
// BBCode IDs
|
||||
define('BBCODE_ID_QUOTE', 0);
|
||||
define('BBCODE_ID_B', 1);
|
||||
define('BBCODE_ID_I', 2);
|
||||
define('BBCODE_ID_URL', 3);
|
||||
define('BBCODE_ID_IMG', 4);
|
||||
define('BBCODE_ID_SIZE', 5);
|
||||
define('BBCODE_ID_COLOR', 6);
|
||||
define('BBCODE_ID_U', 7);
|
||||
define('BBCODE_ID_CODE', 8);
|
||||
define('BBCODE_ID_LIST', 9);
|
||||
define('BBCODE_ID_EMAIL', 10);
|
||||
define('BBCODE_ID_FLASH', 11);
|
||||
define('BBCODE_ID_ATTACH', 12);
|
||||
|
||||
// BBCode hard limit
|
||||
define('BBCODE_LIMIT', 1511);
|
||||
|
||||
// Smiley hard limit
|
||||
define('SMILEY_LIMIT', 1000);
|
||||
|
||||
// Magic url types
|
||||
define('MAGIC_URL_EMAIL', 1);
|
||||
define('MAGIC_URL_FULL', 2);
|
||||
define('MAGIC_URL_LOCAL', 3);
|
||||
define('MAGIC_URL_WWW', 4);
|
||||
|
||||
// Profile Field Types
|
||||
define('FIELD_INT', 1);
|
||||
define('FIELD_STRING', 2);
|
||||
define('FIELD_TEXT', 3);
|
||||
define('FIELD_BOOL', 4);
|
||||
define('FIELD_DROPDOWN', 5);
|
||||
define('FIELD_DATE', 6);
|
||||
|
||||
// referer validation
|
||||
define('REFERER_VALIDATE_NONE', 0);
|
||||
define('REFERER_VALIDATE_HOST', 1);
|
||||
define('REFERER_VALIDATE_PATH', 2);
|
||||
|
||||
// phpbb_chmod() permissions
|
||||
@define('CHMOD_ALL', 7);
|
||||
@define('CHMOD_READ', 4);
|
||||
@define('CHMOD_WRITE', 2);
|
||||
@define('CHMOD_EXECUTE', 1);
|
||||
|
||||
// Captcha code length
|
||||
define('CAPTCHA_MIN_CHARS', 4);
|
||||
define('CAPTCHA_MAX_CHARS', 7);
|
||||
|
||||
// Additional constants
|
||||
define('VOTE_CONVERTED', 127);
|
||||
|
||||
// BC global FTW
|
||||
global $table_prefix;
|
||||
|
||||
// Table names
|
||||
define('ACL_GROUPS_TABLE', $table_prefix . 'acl_groups');
|
||||
define('ACL_OPTIONS_TABLE', $table_prefix . 'acl_options');
|
||||
define('ACL_ROLES_DATA_TABLE', $table_prefix . 'acl_roles_data');
|
||||
define('ACL_ROLES_TABLE', $table_prefix . 'acl_roles');
|
||||
define('ACL_USERS_TABLE', $table_prefix . 'acl_users');
|
||||
define('ATTACHMENTS_TABLE', $table_prefix . 'attachments');
|
||||
define('BANLIST_TABLE', $table_prefix . 'banlist');
|
||||
define('BBCODES_TABLE', $table_prefix . 'bbcodes');
|
||||
define('BOOKMARKS_TABLE', $table_prefix . 'bookmarks');
|
||||
define('BOTS_TABLE', $table_prefix . 'bots');
|
||||
@define('CONFIG_TABLE', $table_prefix . 'config');
|
||||
define('CONFIG_TEXT_TABLE', $table_prefix . 'config_text');
|
||||
define('CONFIRM_TABLE', $table_prefix . 'confirm');
|
||||
define('DISALLOW_TABLE', $table_prefix . 'disallow');
|
||||
define('DRAFTS_TABLE', $table_prefix . 'drafts');
|
||||
define('EXT_TABLE', $table_prefix . 'ext');
|
||||
define('EXTENSIONS_TABLE', $table_prefix . 'extensions');
|
||||
define('EXTENSION_GROUPS_TABLE', $table_prefix . 'extension_groups');
|
||||
define('FORUMS_TABLE', $table_prefix . 'forums');
|
||||
define('FORUMS_ACCESS_TABLE', $table_prefix . 'forums_access');
|
||||
define('FORUMS_TRACK_TABLE', $table_prefix . 'forums_track');
|
||||
define('FORUMS_WATCH_TABLE', $table_prefix . 'forums_watch');
|
||||
define('GROUPS_TABLE', $table_prefix . 'groups');
|
||||
define('ICONS_TABLE', $table_prefix . 'icons');
|
||||
define('LANG_TABLE', $table_prefix . 'lang');
|
||||
define('LOG_TABLE', $table_prefix . 'log');
|
||||
define('LOGIN_ATTEMPT_TABLE', $table_prefix . 'login_attempts');
|
||||
define('MIGRATIONS_TABLE', $table_prefix . 'migrations');
|
||||
define('MODERATOR_CACHE_TABLE', $table_prefix . 'moderator_cache');
|
||||
define('MODULES_TABLE', $table_prefix . 'modules');
|
||||
define('NOTIFICATION_TYPES_TABLE', $table_prefix . 'notification_types');
|
||||
define('NOTIFICATIONS_TABLE', $table_prefix . 'notifications');
|
||||
define('POLL_OPTIONS_TABLE', $table_prefix . 'poll_options');
|
||||
define('POLL_VOTES_TABLE', $table_prefix . 'poll_votes');
|
||||
define('POSTS_TABLE', $table_prefix . 'posts');
|
||||
define('PRIVMSGS_TABLE', $table_prefix . 'privmsgs');
|
||||
define('PRIVMSGS_FOLDER_TABLE', $table_prefix . 'privmsgs_folder');
|
||||
define('PRIVMSGS_RULES_TABLE', $table_prefix . 'privmsgs_rules');
|
||||
define('PRIVMSGS_TO_TABLE', $table_prefix . 'privmsgs_to');
|
||||
define('PROFILE_FIELDS_TABLE', $table_prefix . 'profile_fields');
|
||||
define('PROFILE_FIELDS_DATA_TABLE', $table_prefix . 'profile_fields_data');
|
||||
define('PROFILE_FIELDS_LANG_TABLE', $table_prefix . 'profile_fields_lang');
|
||||
define('PROFILE_LANG_TABLE', $table_prefix . 'profile_lang');
|
||||
define('RANKS_TABLE', $table_prefix . 'ranks');
|
||||
define('REPORTS_TABLE', $table_prefix . 'reports');
|
||||
define('REPORTS_REASONS_TABLE', $table_prefix . 'reports_reasons');
|
||||
define('SEARCH_RESULTS_TABLE', $table_prefix . 'search_results');
|
||||
define('SEARCH_WORDLIST_TABLE', $table_prefix . 'search_wordlist');
|
||||
define('SEARCH_WORDMATCH_TABLE', $table_prefix . 'search_wordmatch');
|
||||
define('SESSIONS_TABLE', $table_prefix . 'sessions');
|
||||
define('SESSIONS_KEYS_TABLE', $table_prefix . 'sessions_keys');
|
||||
define('SITELIST_TABLE', $table_prefix . 'sitelist');
|
||||
define('SMILIES_TABLE', $table_prefix . 'smilies');
|
||||
define('SPHINX_TABLE', $table_prefix . 'sphinx');
|
||||
define('STYLES_TABLE', $table_prefix . 'styles');
|
||||
define('STYLES_TEMPLATE_TABLE', $table_prefix . 'styles_template');
|
||||
define('STYLES_TEMPLATE_DATA_TABLE',$table_prefix . 'styles_template_data');
|
||||
define('STYLES_THEME_TABLE', $table_prefix . 'styles_theme');
|
||||
define('STYLES_IMAGESET_TABLE', $table_prefix . 'styles_imageset');
|
||||
define('STYLES_IMAGESET_DATA_TABLE',$table_prefix . 'styles_imageset_data');
|
||||
define('TEAMPAGE_TABLE', $table_prefix . 'teampage');
|
||||
define('TOPICS_TABLE', $table_prefix . 'topics');
|
||||
define('TOPICS_POSTED_TABLE', $table_prefix . 'topics_posted');
|
||||
define('TOPICS_TRACK_TABLE', $table_prefix . 'topics_track');
|
||||
define('TOPICS_WATCH_TABLE', $table_prefix . 'topics_watch');
|
||||
define('USER_GROUP_TABLE', $table_prefix . 'user_group');
|
||||
define('USER_NOTIFICATIONS_TABLE', $table_prefix . 'user_notifications');
|
||||
define('USERS_TABLE', $table_prefix . 'users');
|
||||
define('WARNINGS_TABLE', $table_prefix . 'warnings');
|
||||
define('WORDS_TABLE', $table_prefix . 'words');
|
||||
define('ZEBRA_TABLE', $table_prefix . 'zebra');
|
||||
|
||||
// Additional tables
|
||||
557
install/update/new/includes/diff/engine.php
Normal file
557
install/update/new/includes/diff/engine.php
Normal file
@@ -0,0 +1,557 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Code from pear.php.net, Text_Diff-1.1.0 package
|
||||
* http://pear.php.net/package/Text_Diff/ (native engine)
|
||||
*
|
||||
* Modified by phpBB Limited to meet our coding standards
|
||||
* and being able to integrate into phpBB
|
||||
*
|
||||
* Class used internally by Text_Diff to actually compute the diffs. This
|
||||
* class is implemented using native PHP code.
|
||||
*
|
||||
* The algorithm used here is mostly lifted from the perl module
|
||||
* Algorithm::Diff (version 1.06) by Ned Konz, which is available at:
|
||||
* http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip
|
||||
*
|
||||
* More ideas are taken from: http://www.ics.uci.edu/~eppstein/161/960229.html
|
||||
*
|
||||
* Some ideas (and a bit of code) are taken from analyze.c, of GNU
|
||||
* diffutils-2.7, which can be found at:
|
||||
* ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz
|
||||
*
|
||||
* Some ideas (subdivision by NCHUNKS > 2, and some optimizations) are from
|
||||
* Geoffrey T. Dairiki <dairiki@dairiki.org>. The original PHP version of this
|
||||
* code was written by him, and is used/adapted with his permission.
|
||||
*
|
||||
* Copyright 2004-2008 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @package diff
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class diff_engine
|
||||
{
|
||||
/**
|
||||
* If set to true we trim all lines before we compare them. This ensures that sole space/tab changes do not trigger diffs.
|
||||
*/
|
||||
var $skip_whitespace_changes = true;
|
||||
|
||||
function diff(&$from_lines, &$to_lines, $preserve_cr = true)
|
||||
{
|
||||
// Remove empty lines...
|
||||
// If preserve_cr is true, we basically only change \r\n and bare \r to \n to get the same carriage returns for both files
|
||||
// If it is false, we try to only use \n once per line and ommit all empty lines to be able to get a proper data diff
|
||||
|
||||
if (is_array($from_lines))
|
||||
{
|
||||
$from_lines = implode("\n", $from_lines);
|
||||
}
|
||||
|
||||
if (is_array($to_lines))
|
||||
{
|
||||
$to_lines = implode("\n", $to_lines);
|
||||
}
|
||||
|
||||
if ($preserve_cr)
|
||||
{
|
||||
$from_lines = explode("\n", str_replace("\r", "\n", str_replace("\r\n", "\n", $from_lines)));
|
||||
$to_lines = explode("\n", str_replace("\r", "\n", str_replace("\r\n", "\n", $to_lines)));
|
||||
}
|
||||
else
|
||||
{
|
||||
$from_lines = explode("\n", preg_replace('#[\n\r]+#', "\n", $from_lines));
|
||||
$to_lines = explode("\n", preg_replace('#[\n\r]+#', "\n", $to_lines));
|
||||
}
|
||||
|
||||
$n_from = count($from_lines);
|
||||
$n_to = count($to_lines);
|
||||
|
||||
$this->xchanged = $this->ychanged = $this->xv = $this->yv = $this->xind = $this->yind = array();
|
||||
unset($this->seq, $this->in_seq, $this->lcs);
|
||||
|
||||
// Skip leading common lines.
|
||||
for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++)
|
||||
{
|
||||
if (trim($from_lines[$skip]) !== trim($to_lines[$skip]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
$this->xchanged[$skip] = $this->ychanged[$skip] = false;
|
||||
}
|
||||
|
||||
// Skip trailing common lines.
|
||||
$xi = $n_from;
|
||||
$yi = $n_to;
|
||||
|
||||
for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++)
|
||||
{
|
||||
if (trim($from_lines[$xi]) !== trim($to_lines[$yi]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
$this->xchanged[$xi] = $this->ychanged[$yi] = false;
|
||||
}
|
||||
|
||||
// Ignore lines which do not exist in both files.
|
||||
for ($xi = $skip; $xi < $n_from - $endskip; $xi++)
|
||||
{
|
||||
if ($this->skip_whitespace_changes) $xhash[trim($from_lines[$xi])] = 1; else $xhash[$from_lines[$xi]] = 1;
|
||||
}
|
||||
|
||||
for ($yi = $skip; $yi < $n_to - $endskip; $yi++)
|
||||
{
|
||||
$line = ($this->skip_whitespace_changes) ? trim($to_lines[$yi]) : $to_lines[$yi];
|
||||
|
||||
if (($this->ychanged[$yi] = empty($xhash[$line])))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$yhash[$line] = 1;
|
||||
$this->yv[] = $line;
|
||||
$this->yind[] = $yi;
|
||||
}
|
||||
|
||||
for ($xi = $skip; $xi < $n_from - $endskip; $xi++)
|
||||
{
|
||||
$line = ($this->skip_whitespace_changes) ? trim($from_lines[$xi]) : $from_lines[$xi];
|
||||
|
||||
if (($this->xchanged[$xi] = empty($yhash[$line])))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$this->xv[] = $line;
|
||||
$this->xind[] = $xi;
|
||||
}
|
||||
|
||||
// Find the LCS.
|
||||
$this->_compareseq(0, count($this->xv), 0, count($this->yv));
|
||||
|
||||
// Merge edits when possible.
|
||||
if ($this->skip_whitespace_changes)
|
||||
{
|
||||
$from_lines_clean = array_map('trim', $from_lines);
|
||||
$to_lines_clean = array_map('trim', $to_lines);
|
||||
|
||||
$this->_shift_boundaries($from_lines_clean, $this->xchanged, $this->ychanged);
|
||||
$this->_shift_boundaries($to_lines_clean, $this->ychanged, $this->xchanged);
|
||||
|
||||
unset($from_lines_clean, $to_lines_clean);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_shift_boundaries($from_lines, $this->xchanged, $this->ychanged);
|
||||
$this->_shift_boundaries($to_lines, $this->ychanged, $this->xchanged);
|
||||
}
|
||||
|
||||
// Compute the edit operations.
|
||||
$edits = array();
|
||||
$xi = $yi = 0;
|
||||
|
||||
while ($xi < $n_from || $yi < $n_to)
|
||||
{
|
||||
// Skip matching "snake".
|
||||
$copy = array();
|
||||
|
||||
while ($xi < $n_from && $yi < $n_to && !$this->xchanged[$xi] && !$this->ychanged[$yi])
|
||||
{
|
||||
$copy[] = $from_lines[$xi++];
|
||||
$yi++;
|
||||
}
|
||||
|
||||
if ($copy)
|
||||
{
|
||||
$edits[] = new diff_op_copy($copy);
|
||||
}
|
||||
|
||||
// Find deletes & adds.
|
||||
$delete = array();
|
||||
while ($xi < $n_from && $this->xchanged[$xi])
|
||||
{
|
||||
$delete[] = $from_lines[$xi++];
|
||||
}
|
||||
|
||||
$add = array();
|
||||
while ($yi < $n_to && $this->ychanged[$yi])
|
||||
{
|
||||
$add[] = $to_lines[$yi++];
|
||||
}
|
||||
|
||||
if ($delete && $add)
|
||||
{
|
||||
$edits[] = new diff_op_change($delete, $add);
|
||||
}
|
||||
else if ($delete)
|
||||
{
|
||||
$edits[] = new diff_op_delete($delete);
|
||||
}
|
||||
else if ($add)
|
||||
{
|
||||
$edits[] = new diff_op_add($add);
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the Largest Common Subsequence (LCS) of the sequences (XOFF,
|
||||
* XLIM) and (YOFF, YLIM) into NCHUNKS approximately equally sized segments.
|
||||
*
|
||||
* Returns (LCS, PTS). LCS is the length of the LCS. PTS is an array of
|
||||
* NCHUNKS+1 (X, Y) indexes giving the diving points between sub
|
||||
* sequences. The first sub-sequence is contained in (X0, X1), (Y0, Y1),
|
||||
* the second in (X1, X2), (Y1, Y2) and so on. Note that (X0, Y0) ==
|
||||
* (XOFF, YOFF) and (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM).
|
||||
*
|
||||
* This function assumes that the first lines of the specified portions of
|
||||
* the two files do not match, and likewise that the last lines do not
|
||||
* match. The caller must trim matching lines from the beginning and end
|
||||
* of the portions it is going to specify.
|
||||
*/
|
||||
function _diag($xoff, $xlim, $yoff, $ylim, $nchunks)
|
||||
{
|
||||
$flip = false;
|
||||
|
||||
if ($xlim - $xoff > $ylim - $yoff)
|
||||
{
|
||||
// Things seems faster (I'm not sure I understand why) when the shortest sequence is in X.
|
||||
$flip = true;
|
||||
list($xoff, $xlim, $yoff, $ylim) = array($yoff, $ylim, $xoff, $xlim);
|
||||
}
|
||||
|
||||
if ($flip)
|
||||
{
|
||||
for ($i = $ylim - 1; $i >= $yoff; $i--)
|
||||
{
|
||||
$ymatches[$this->xv[$i]][] = $i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ($i = $ylim - 1; $i >= $yoff; $i--)
|
||||
{
|
||||
$ymatches[$this->yv[$i]][] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
$this->lcs = 0;
|
||||
$this->seq[0]= $yoff - 1;
|
||||
$this->in_seq = array();
|
||||
$ymids[0] = array();
|
||||
|
||||
$numer = $xlim - $xoff + $nchunks - 1;
|
||||
$x = $xoff;
|
||||
|
||||
for ($chunk = 0; $chunk < $nchunks; $chunk++)
|
||||
{
|
||||
if ($chunk > 0)
|
||||
{
|
||||
for ($i = 0; $i <= $this->lcs; $i++)
|
||||
{
|
||||
$ymids[$i][$chunk - 1] = $this->seq[$i];
|
||||
}
|
||||
}
|
||||
|
||||
$x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $chunk) / $nchunks);
|
||||
|
||||
for (; $x < $x1; $x++)
|
||||
{
|
||||
$line = $flip ? $this->yv[$x] : $this->xv[$x];
|
||||
if (empty($ymatches[$line]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$matches = $ymatches[$line];
|
||||
|
||||
reset($matches);
|
||||
while ($y = current($matches))
|
||||
{
|
||||
next($matches);
|
||||
if (empty($this->in_seq[$y]))
|
||||
{
|
||||
$k = $this->_lcs_pos($y);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// no reset() here
|
||||
while ($y = current($matches))
|
||||
{
|
||||
next($matches);
|
||||
if ($y > $this->seq[$k - 1])
|
||||
{
|
||||
// Optimization: this is a common case: next match is just replacing previous match.
|
||||
$this->in_seq[$this->seq[$k]] = false;
|
||||
$this->seq[$k] = $y;
|
||||
$this->in_seq[$y] = 1;
|
||||
}
|
||||
else if (empty($this->in_seq[$y]))
|
||||
{
|
||||
$k = $this->_lcs_pos($y);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$seps[] = $flip ? array($yoff, $xoff) : array($xoff, $yoff);
|
||||
$ymid = $ymids[$this->lcs];
|
||||
|
||||
for ($n = 0; $n < $nchunks - 1; $n++)
|
||||
{
|
||||
$x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $n) / $nchunks);
|
||||
$y1 = $ymid[$n] + 1;
|
||||
$seps[] = $flip ? array($y1, $x1) : array($x1, $y1);
|
||||
}
|
||||
$seps[] = $flip ? array($ylim, $xlim) : array($xlim, $ylim);
|
||||
|
||||
return array($this->lcs, $seps);
|
||||
}
|
||||
|
||||
function _lcs_pos($ypos)
|
||||
{
|
||||
$end = $this->lcs;
|
||||
|
||||
if ($end == 0 || $ypos > $this->seq[$end])
|
||||
{
|
||||
$this->seq[++$this->lcs] = $ypos;
|
||||
$this->in_seq[$ypos] = 1;
|
||||
return $this->lcs;
|
||||
}
|
||||
|
||||
$beg = 1;
|
||||
while ($beg < $end)
|
||||
{
|
||||
$mid = (int)(($beg + $end) / 2);
|
||||
if ($ypos > $this->seq[$mid])
|
||||
{
|
||||
$beg = $mid + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$end = $mid;
|
||||
}
|
||||
}
|
||||
|
||||
$this->in_seq[$this->seq[$end]] = false;
|
||||
$this->seq[$end] = $ypos;
|
||||
$this->in_seq[$ypos] = 1;
|
||||
|
||||
return $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds LCS of two sequences.
|
||||
*
|
||||
* The results are recorded in the vectors $this->{x,y}changed[], by
|
||||
* storing a 1 in the element for each line that is an insertion or
|
||||
* deletion (ie. is not in the LCS).
|
||||
*
|
||||
* The subsequence of file 0 is (XOFF, XLIM) and likewise for file 1.
|
||||
*
|
||||
* Note that XLIM, YLIM are exclusive bounds. All line numbers are
|
||||
* origin-0 and discarded lines are not counted.
|
||||
*/
|
||||
function _compareseq($xoff, $xlim, $yoff, $ylim)
|
||||
{
|
||||
// Slide down the bottom initial diagonal.
|
||||
while ($xoff < $xlim && $yoff < $ylim && $this->xv[$xoff] == $this->yv[$yoff])
|
||||
{
|
||||
++$xoff;
|
||||
++$yoff;
|
||||
}
|
||||
|
||||
// Slide up the top initial diagonal.
|
||||
while ($xlim > $xoff && $ylim > $yoff && $this->xv[$xlim - 1] == $this->yv[$ylim - 1])
|
||||
{
|
||||
--$xlim;
|
||||
--$ylim;
|
||||
}
|
||||
|
||||
if ($xoff == $xlim || $yoff == $ylim)
|
||||
{
|
||||
$lcs = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is ad hoc but seems to work well.
|
||||
// $nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5);
|
||||
// $nchunks = max(2,min(8,(int)$nchunks));
|
||||
$nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1;
|
||||
list($lcs, $seps) = $this->_diag($xoff, $xlim, $yoff, $ylim, $nchunks);
|
||||
}
|
||||
|
||||
if ($lcs == 0)
|
||||
{
|
||||
// X and Y sequences have no common subsequence: mark all changed.
|
||||
while ($yoff < $ylim)
|
||||
{
|
||||
$this->ychanged[$this->yind[$yoff++]] = 1;
|
||||
}
|
||||
|
||||
while ($xoff < $xlim)
|
||||
{
|
||||
$this->xchanged[$this->xind[$xoff++]] = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the partitions to split this problem into subproblems.
|
||||
reset($seps);
|
||||
$pt1 = $seps[0];
|
||||
|
||||
while ($pt2 = next($seps))
|
||||
{
|
||||
$this->_compareseq($pt1[0], $pt2[0], $pt1[1], $pt2[1]);
|
||||
$pt1 = $pt2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts inserts/deletes of identical lines to join changes as much as possible.
|
||||
*
|
||||
* We do something when a run of changed lines include a line at one end
|
||||
* and has an excluded, identical line at the other. We are free to
|
||||
* choose which identical line is included. 'compareseq' usually chooses
|
||||
* the one at the beginning, but usually it is cleaner to consider the
|
||||
* following identical line to be the "change".
|
||||
*
|
||||
* This is extracted verbatim from analyze.c (GNU diffutils-2.7).
|
||||
*/
|
||||
function _shift_boundaries($lines, &$changed, $other_changed)
|
||||
{
|
||||
$i = 0;
|
||||
$j = 0;
|
||||
|
||||
$len = count($lines);
|
||||
$other_len = count($other_changed);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Scan forward to find the beginning of another run of
|
||||
// changes. Also keep track of the corresponding point in the other file.
|
||||
//
|
||||
// Throughout this code, $i and $j are adjusted together so that
|
||||
// the first $i elements of $changed and the first $j elements of
|
||||
// $other_changed both contain the same number of zeros (unchanged lines).
|
||||
//
|
||||
// Furthermore, $j is always kept so that $j == $other_len or $other_changed[$j] == false.
|
||||
while ($j < $other_len && $other_changed[$j])
|
||||
{
|
||||
$j++;
|
||||
}
|
||||
|
||||
while ($i < $len && ! $changed[$i])
|
||||
{
|
||||
$i++;
|
||||
$j++;
|
||||
|
||||
while ($j < $other_len && $other_changed[$j])
|
||||
{
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($i == $len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$start = $i;
|
||||
|
||||
// Find the end of this run of changes.
|
||||
while (++$i < $len && $changed[$i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
// Record the length of this run of changes, so that we can later determine whether the run has grown.
|
||||
$runlength = $i - $start;
|
||||
|
||||
// Move the changed region back, so long as the previous unchanged line matches the last changed one.
|
||||
// This merges with previous changed regions.
|
||||
while ($start > 0 && $lines[$start - 1] == $lines[$i - 1])
|
||||
{
|
||||
$changed[--$start] = 1;
|
||||
$changed[--$i] = false;
|
||||
|
||||
while ($start > 0 && $changed[$start - 1])
|
||||
{
|
||||
$start--;
|
||||
}
|
||||
|
||||
while ($other_changed[--$j])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Set CORRESPONDING to the end of the changed run, at the last point where it corresponds to a changed run in the
|
||||
// other file. CORRESPONDING == LEN means no such point has been found.
|
||||
$corresponding = $j < $other_len ? $i : $len;
|
||||
|
||||
// Move the changed region forward, so long as the first changed line matches the following unchanged one.
|
||||
// This merges with following changed regions.
|
||||
// Do this second, so that if there are no merges, the changed region is moved forward as far as possible.
|
||||
while ($i < $len && $lines[$start] == $lines[$i])
|
||||
{
|
||||
$changed[$start++] = false;
|
||||
$changed[$i++] = 1;
|
||||
|
||||
while ($i < $len && $changed[$i])
|
||||
{
|
||||
$i++;
|
||||
}
|
||||
|
||||
$j++;
|
||||
if ($j < $other_len && $other_changed[$j])
|
||||
{
|
||||
$corresponding = $i;
|
||||
while ($j < $other_len && $other_changed[$j])
|
||||
{
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while ($runlength != $i - $start);
|
||||
|
||||
// If possible, move the fully-merged run of changes back to a corresponding run in the other file.
|
||||
while ($corresponding < $i)
|
||||
{
|
||||
$changed[--$start] = 1;
|
||||
$changed[--$i] = 0;
|
||||
|
||||
while ($other_changed[--$j])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
4630
install/update/new/includes/functions.php
Normal file
4630
install/update/new/includes/functions.php
Normal file
File diff suppressed because it is too large
Load Diff
727
install/update/new/includes/functions_acp.php
Normal file
727
install/update/new/includes/functions_acp.php
Normal file
@@ -0,0 +1,727 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Header for acp pages
|
||||
*/
|
||||
function adm_page_header($page_title)
|
||||
{
|
||||
global $config, $user, $template;
|
||||
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $SID, $_SID;
|
||||
global $phpbb_dispatcher, $phpbb_container;
|
||||
|
||||
if (defined('HEADER_INC'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
define('HEADER_INC', true);
|
||||
|
||||
// A listener can set this variable to `true` when it overrides this function
|
||||
$adm_page_header_override = false;
|
||||
|
||||
/**
|
||||
* Execute code and/or overwrite adm_page_header()
|
||||
*
|
||||
* @event core.adm_page_header
|
||||
* @var string page_title Page title
|
||||
* @var bool adm_page_header_override Shall we return instead of
|
||||
* running the rest of adm_page_header()
|
||||
* @since 3.1.0-a1
|
||||
*/
|
||||
$vars = array('page_title', 'adm_page_header_override');
|
||||
extract($phpbb_dispatcher->trigger_event('core.adm_page_header', compact($vars)));
|
||||
|
||||
if ($adm_page_header_override)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$user->update_session_infos();
|
||||
|
||||
// gzip_compression
|
||||
if ($config['gzip_compress'])
|
||||
{
|
||||
if (@extension_loaded('zlib') && !headers_sent())
|
||||
{
|
||||
ob_start('ob_gzhandler');
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'PAGE_TITLE' => $page_title,
|
||||
'USERNAME' => $user->data['username'],
|
||||
|
||||
'SID' => $SID,
|
||||
'_SID' => $_SID,
|
||||
'SESSION_ID' => $user->session_id,
|
||||
'ROOT_PATH' => $phpbb_root_path,
|
||||
'ADMIN_ROOT_PATH' => $phpbb_admin_path,
|
||||
|
||||
'U_LOGOUT' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=logout'),
|
||||
'U_ADM_LOGOUT' => append_sid("{$phpbb_admin_path}index.$phpEx", 'action=admlogout'),
|
||||
'U_ADM_INDEX' => append_sid("{$phpbb_admin_path}index.$phpEx"),
|
||||
'U_INDEX' => append_sid("{$phpbb_root_path}index.$phpEx"),
|
||||
|
||||
'T_IMAGES_PATH' => "{$phpbb_root_path}images/",
|
||||
'T_SMILIES_PATH' => "{$phpbb_root_path}{$config['smilies_path']}/",
|
||||
'T_AVATAR_PATH' => "{$phpbb_root_path}{$config['avatar_path']}/",
|
||||
'T_AVATAR_GALLERY_PATH' => "{$phpbb_root_path}{$config['avatar_gallery_path']}/",
|
||||
'T_ICONS_PATH' => "{$phpbb_root_path}{$config['icons_path']}/",
|
||||
'T_RANKS_PATH' => "{$phpbb_root_path}{$config['ranks_path']}/",
|
||||
'T_UPLOAD_PATH' => "{$phpbb_root_path}{$config['upload_path']}/",
|
||||
'T_FONT_AWESOME_LINK' => !empty($config['allow_cdn']) && !empty($config['load_font_awesome_url']) ? $config['load_font_awesome_url'] : "{$phpbb_root_path}assets/css/font-awesome.min.css?assets_version=" . $config['assets_version'],
|
||||
|
||||
'T_ASSETS_VERSION' => $config['assets_version'],
|
||||
|
||||
'ICON_MOVE_UP' => '<img src="' . htmlspecialchars($phpbb_admin_path) . 'images/icon_up.gif" alt="' . $user->lang['MOVE_UP'] . '" title="' . $user->lang['MOVE_UP'] . '" />',
|
||||
'ICON_MOVE_UP_DISABLED' => '<img src="' . htmlspecialchars($phpbb_admin_path) . 'images/icon_up_disabled.gif" alt="' . $user->lang['MOVE_UP'] . '" title="' . $user->lang['MOVE_UP'] . '" />',
|
||||
'ICON_MOVE_DOWN' => '<img src="' . htmlspecialchars($phpbb_admin_path) . 'images/icon_down.gif" alt="' . $user->lang['MOVE_DOWN'] . '" title="' . $user->lang['MOVE_DOWN'] . '" />',
|
||||
'ICON_MOVE_DOWN_DISABLED' => '<img src="' . htmlspecialchars($phpbb_admin_path) . 'images/icon_down_disabled.gif" alt="' . $user->lang['MOVE_DOWN'] . '" title="' . $user->lang['MOVE_DOWN'] . '" />',
|
||||
'ICON_EDIT' => '<img src="' . htmlspecialchars($phpbb_admin_path) . 'images/icon_edit.gif" alt="' . $user->lang['EDIT'] . '" title="' . $user->lang['EDIT'] . '" />',
|
||||
'ICON_EDIT_DISABLED' => '<img src="' . htmlspecialchars($phpbb_admin_path) . 'images/icon_edit_disabled.gif" alt="' . $user->lang['EDIT'] . '" title="' . $user->lang['EDIT'] . '" />',
|
||||
'ICON_DELETE' => '<img src="' . htmlspecialchars($phpbb_admin_path) . 'images/icon_delete.gif" alt="' . $user->lang['DELETE'] . '" title="' . $user->lang['DELETE'] . '" />',
|
||||
'ICON_DELETE_DISABLED' => '<img src="' . htmlspecialchars($phpbb_admin_path) . 'images/icon_delete_disabled.gif" alt="' . $user->lang['DELETE'] . '" title="' . $user->lang['DELETE'] . '" />',
|
||||
'ICON_SYNC' => '<img src="' . htmlspecialchars($phpbb_admin_path) . 'images/icon_sync.gif" alt="' . $user->lang['RESYNC'] . '" title="' . $user->lang['RESYNC'] . '" />',
|
||||
'ICON_SYNC_DISABLED' => '<img src="' . htmlspecialchars($phpbb_admin_path) . 'images/icon_sync_disabled.gif" alt="' . $user->lang['RESYNC'] . '" title="' . $user->lang['RESYNC'] . '" />',
|
||||
|
||||
'S_USER_LANG' => $user->lang['USER_LANG'],
|
||||
'S_CONTENT_DIRECTION' => $user->lang['DIRECTION'],
|
||||
'S_CONTENT_ENCODING' => 'UTF-8',
|
||||
'S_CONTENT_FLOW_BEGIN' => ($user->lang['DIRECTION'] == 'ltr') ? 'left' : 'right',
|
||||
'S_CONTENT_FLOW_END' => ($user->lang['DIRECTION'] == 'ltr') ? 'right' : 'left',
|
||||
|
||||
'CONTAINER_EXCEPTION' => $phpbb_container->hasParameter('container_exception') ? $phpbb_container->getParameter('container_exception') : false,
|
||||
));
|
||||
|
||||
// An array of http headers that phpBB will set. The following event may override these.
|
||||
$http_headers = array(
|
||||
// application/xhtml+xml not used because of IE
|
||||
'Content-type' => 'text/html; charset=UTF-8',
|
||||
'Cache-Control' => 'private, no-cache="set-cookie"',
|
||||
'Expires' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
|
||||
'Referrer-Policy' => 'strict-origin-when-cross-origin',
|
||||
);
|
||||
|
||||
/**
|
||||
* Execute code and/or overwrite _common_ template variables after they have been assigned.
|
||||
*
|
||||
* @event core.adm_page_header_after
|
||||
* @var string page_title Page title
|
||||
* @var array http_headers HTTP headers that should be set by phpbb
|
||||
*
|
||||
* @since 3.1.0-RC3
|
||||
*/
|
||||
$vars = array('page_title', 'http_headers');
|
||||
extract($phpbb_dispatcher->trigger_event('core.adm_page_header_after', compact($vars)));
|
||||
|
||||
foreach ($http_headers as $hname => $hval)
|
||||
{
|
||||
header((string) $hname . ': ' . (string) $hval);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Page footer for acp pages
|
||||
*/
|
||||
function adm_page_footer($copyright_html = true)
|
||||
{
|
||||
global $db, $config, $template, $user, $auth;
|
||||
global $phpbb_root_path;
|
||||
global $request, $phpbb_dispatcher;
|
||||
|
||||
// A listener can set this variable to `true` when it overrides this function
|
||||
$adm_page_footer_override = false;
|
||||
|
||||
/**
|
||||
* Execute code and/or overwrite adm_page_footer()
|
||||
*
|
||||
* @event core.adm_page_footer
|
||||
* @var bool copyright_html Shall we display the copyright?
|
||||
* @var bool adm_page_footer_override Shall we return instead of
|
||||
* running the rest of adm_page_footer()
|
||||
* @since 3.1.0-a1
|
||||
*/
|
||||
$vars = array('copyright_html', 'adm_page_footer_override');
|
||||
extract($phpbb_dispatcher->trigger_event('core.adm_page_footer', compact($vars)));
|
||||
|
||||
if ($adm_page_footer_override)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
phpbb_check_and_display_sql_report($request, $auth, $db);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'DEBUG_OUTPUT' => phpbb_generate_debug_output($db, $config, $auth, $user, $phpbb_dispatcher),
|
||||
'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '',
|
||||
'S_COPYRIGHT_HTML' => $copyright_html,
|
||||
'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Limited'),
|
||||
'T_JQUERY_LINK' => !empty($config['allow_cdn']) && !empty($config['load_jquery_url']) ? $config['load_jquery_url'] : "{$phpbb_root_path}assets/javascript/jquery-3.4.1.min.js",
|
||||
'S_ALLOW_CDN' => !empty($config['allow_cdn']),
|
||||
'VERSION' => $config['version'])
|
||||
);
|
||||
|
||||
$template->display('body');
|
||||
|
||||
garbage_collection();
|
||||
exit_handler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate back link for acp pages
|
||||
*/
|
||||
function adm_back_link($u_action)
|
||||
{
|
||||
global $user;
|
||||
return '<br /><br /><a href="' . $u_action . '">« ' . $user->lang['BACK_TO_PREV'] . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build select field options in acp pages
|
||||
*/
|
||||
function build_select($option_ary, $option_default = false)
|
||||
{
|
||||
global $user;
|
||||
|
||||
$html = '';
|
||||
foreach ($option_ary as $value => $title)
|
||||
{
|
||||
$selected = ($option_default !== false && $value == $option_default) ? ' selected="selected"' : '';
|
||||
$html .= '<option value="' . $value . '"' . $selected . '>' . $user->lang[$title] . '</option>';
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build radio fields in acp pages
|
||||
*/
|
||||
function h_radio($name, $input_ary, $input_default = false, $id = false, $key = false, $separator = '')
|
||||
{
|
||||
global $user;
|
||||
|
||||
$html = '';
|
||||
$id_assigned = false;
|
||||
foreach ($input_ary as $value => $title)
|
||||
{
|
||||
$selected = ($input_default !== false && $value == $input_default) ? ' checked="checked"' : '';
|
||||
$html .= '<label><input type="radio" name="' . $name . '"' . (($id && !$id_assigned) ? ' id="' . $id . '"' : '') . ' value="' . $value . '"' . $selected . (($key) ? ' accesskey="' . $key . '"' : '') . ' class="radio" /> ' . $user->lang[$title] . '</label>' . $separator;
|
||||
$id_assigned = true;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build configuration template for acp configuration pages
|
||||
*/
|
||||
function build_cfg_template($tpl_type, $key, &$new_ary, $config_key, $vars)
|
||||
{
|
||||
global $user, $module, $phpbb_dispatcher;
|
||||
|
||||
$tpl = '';
|
||||
$name = 'config[' . $config_key . ']';
|
||||
|
||||
// Make sure there is no notice printed out for non-existent config options (we simply set them)
|
||||
if (!isset($new_ary[$config_key]))
|
||||
{
|
||||
$new_ary[$config_key] = '';
|
||||
}
|
||||
|
||||
switch ($tpl_type[0])
|
||||
{
|
||||
case 'password':
|
||||
if ($new_ary[$config_key] !== '')
|
||||
{
|
||||
// replace passwords with asterixes
|
||||
$new_ary[$config_key] = '********';
|
||||
}
|
||||
case 'text':
|
||||
case 'url':
|
||||
case 'email':
|
||||
case 'tel':
|
||||
case 'search':
|
||||
// maxlength and size are only valid for these types and will be
|
||||
// ignored for other input types.
|
||||
$size = (int) $tpl_type[1];
|
||||
$maxlength = (int) $tpl_type[2];
|
||||
|
||||
$tpl = '<input id="' . $key . '" type="' . $tpl_type[0] . '"' . (($size) ? ' size="' . $size . '"' : '') . ' maxlength="' . (($maxlength) ? $maxlength : 255) . '" name="' . $name . '" value="' . $new_ary[$config_key] . '"' . (($tpl_type[0] === 'password') ? ' autocomplete="off"' : '') . ' />';
|
||||
break;
|
||||
|
||||
case 'color':
|
||||
case 'datetime':
|
||||
case 'datetime-local':
|
||||
case 'month':
|
||||
case 'week':
|
||||
$tpl = '<input id="' . $key . '" type="' . $tpl_type[0] . '" name="' . $name . '" value="' . $new_ary[$config_key] . '" />';
|
||||
break;
|
||||
|
||||
case 'date':
|
||||
case 'time':
|
||||
case 'number':
|
||||
case 'range':
|
||||
$max = '';
|
||||
$min = ( isset($tpl_type[1]) ) ? (int) $tpl_type[1] : false;
|
||||
if ( isset($tpl_type[2]) )
|
||||
{
|
||||
$max = (int) $tpl_type[2];
|
||||
}
|
||||
|
||||
$tpl = '<input id="' . $key . '" type="' . $tpl_type[0] . '"' . (( $min != '' ) ? ' min="' . $min . '"' : '') . (( $max != '' ) ? ' max="' . $max . '"' : '') . ' name="' . $name . '" value="' . $new_ary[$config_key] . '" />';
|
||||
break;
|
||||
|
||||
case 'dimension':
|
||||
$max = '';
|
||||
|
||||
$min = (int) $tpl_type[1];
|
||||
|
||||
if ( isset($tpl_type[2]) )
|
||||
{
|
||||
$max = (int) $tpl_type[2];
|
||||
}
|
||||
|
||||
$tpl = '<input id="' . $key . '" type="number"' . (( $min !== '' ) ? ' min="' . $min . '"' : '') . (( $max != '' ) ? ' max="' . $max . '"' : '') . ' name="config[' . $config_key . '_width]" value="' . $new_ary[$config_key . '_width'] . '" /> x <input type="number"' . (( $min !== '' ) ? ' min="' . $min . '"' : '') . (( $max != '' ) ? ' max="' . $max . '"' : '') . ' name="config[' . $config_key . '_height]" value="' . $new_ary[$config_key . '_height'] . '" />';
|
||||
break;
|
||||
|
||||
case 'textarea':
|
||||
$rows = (int) $tpl_type[1];
|
||||
$cols = (int) $tpl_type[2];
|
||||
|
||||
$tpl = '<textarea id="' . $key . '" name="' . $name . '" rows="' . $rows . '" cols="' . $cols . '">' . $new_ary[$config_key] . '</textarea>';
|
||||
break;
|
||||
|
||||
case 'radio':
|
||||
$key_yes = ($new_ary[$config_key]) ? ' checked="checked"' : '';
|
||||
$key_no = (!$new_ary[$config_key]) ? ' checked="checked"' : '';
|
||||
|
||||
$tpl_type_cond = explode('_', $tpl_type[1]);
|
||||
$type_no = ($tpl_type_cond[0] == 'disabled' || $tpl_type_cond[0] == 'enabled') ? false : true;
|
||||
|
||||
$tpl_no = '<label><input type="radio" name="' . $name . '" value="0"' . $key_no . ' class="radio" /> ' . (($type_no) ? $user->lang['NO'] : $user->lang['DISABLED']) . '</label>';
|
||||
$tpl_yes = '<label><input type="radio" id="' . $key . '" name="' . $name . '" value="1"' . $key_yes . ' class="radio" /> ' . (($type_no) ? $user->lang['YES'] : $user->lang['ENABLED']) . '</label>';
|
||||
|
||||
$tpl = ($tpl_type_cond[0] == 'yes' || $tpl_type_cond[0] == 'enabled') ? $tpl_yes . $tpl_no : $tpl_no . $tpl_yes;
|
||||
break;
|
||||
|
||||
case 'select':
|
||||
case 'custom':
|
||||
|
||||
if (isset($vars['method']))
|
||||
{
|
||||
$call = array($module->module, $vars['method']);
|
||||
}
|
||||
else if (isset($vars['function']))
|
||||
{
|
||||
$call = $vars['function'];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($vars['params']))
|
||||
{
|
||||
$args = array();
|
||||
foreach ($vars['params'] as $value)
|
||||
{
|
||||
switch ($value)
|
||||
{
|
||||
case '{CONFIG_VALUE}':
|
||||
$value = $new_ary[$config_key];
|
||||
break;
|
||||
|
||||
case '{KEY}':
|
||||
$value = $key;
|
||||
break;
|
||||
}
|
||||
|
||||
$args[] = $value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$args = array($new_ary[$config_key], $key);
|
||||
}
|
||||
|
||||
$return = call_user_func_array($call, $args);
|
||||
|
||||
if ($tpl_type[0] == 'select')
|
||||
{
|
||||
$size = (isset($tpl_type[1])) ? (int) $tpl_type[1] : 1;
|
||||
$data_toggle = (!empty($tpl_type[2])) ? ' data-togglable-settings="true"' : '';
|
||||
|
||||
$tpl = '<select id="' . $key . '" name="' . $name . '"' . (($size > 1) ? ' size="' . $size . '"' : '') . $data_toggle . '>' . $return . '</select>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$tpl = $return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($vars['append']))
|
||||
{
|
||||
$tpl .= $vars['append'];
|
||||
}
|
||||
|
||||
$new = $new_ary;
|
||||
/**
|
||||
* Overwrite the html code we display for the config value
|
||||
*
|
||||
* @event core.build_config_template
|
||||
* @var array tpl_type Config type array:
|
||||
* 0 => data type
|
||||
* 1 [optional] => string: size, int: minimum
|
||||
* 2 [optional] => string: max. length, int: maximum
|
||||
* @var string key Should be used for the id attribute in html
|
||||
* @var array new Array with the config values we display
|
||||
* @var string name Should be used for the name attribute
|
||||
* @var array vars Array with the options for the config
|
||||
* @var string tpl The resulting html code we display
|
||||
* @since 3.1.0-a1
|
||||
*/
|
||||
$vars = array('tpl_type', 'key', 'new', 'name', 'vars', 'tpl');
|
||||
extract($phpbb_dispatcher->trigger_event('core.build_config_template', compact($vars)));
|
||||
$new_ary = $new;
|
||||
unset($new);
|
||||
|
||||
return $tpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Going through a config array and validate values, writing errors to $error. The validation method accepts parameters separated by ':' for string and int.
|
||||
* The first parameter defines the type to be used, the second the lower bound and the third the upper bound. Only the type is required.
|
||||
*/
|
||||
function validate_config_vars($config_vars, &$cfg_array, &$error)
|
||||
{
|
||||
global $phpbb_root_path, $user, $phpbb_dispatcher, $phpbb_filesystem, $language;
|
||||
|
||||
$type = 0;
|
||||
$min = 1;
|
||||
$max = 2;
|
||||
|
||||
foreach ($config_vars as $config_name => $config_definition)
|
||||
{
|
||||
if (!isset($cfg_array[$config_name]) || strpos($config_name, 'legend') !== false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($config_definition['validate']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$validator = explode(':', $config_definition['validate']);
|
||||
|
||||
// Validate a bit. ;) (0 = type, 1 = min, 2= max)
|
||||
switch ($validator[$type])
|
||||
{
|
||||
case 'url':
|
||||
$cfg_array[$config_name] = trim($cfg_array[$config_name]);
|
||||
|
||||
if (!empty($cfg_array[$config_name]) && !preg_match('#^' . get_preg_expression('url') . '$#iu', $cfg_array[$config_name]))
|
||||
{
|
||||
$error[] = $language->lang('URL_INVALID', $language->lang($config_definition['lang']));
|
||||
}
|
||||
|
||||
// no break here
|
||||
|
||||
case 'string':
|
||||
$length = utf8_strlen($cfg_array[$config_name]);
|
||||
|
||||
// the column is a VARCHAR
|
||||
$validator[$max] = (isset($validator[$max])) ? min(255, $validator[$max]) : 255;
|
||||
|
||||
if (isset($validator[$min]) && $length < $validator[$min])
|
||||
{
|
||||
$error[] = sprintf($user->lang['SETTING_TOO_SHORT'], $user->lang[$config_definition['lang']], $validator[$min]);
|
||||
}
|
||||
else if (isset($validator[$max]) && $length > $validator[2])
|
||||
{
|
||||
$error[] = sprintf($user->lang['SETTING_TOO_LONG'], $user->lang[$config_definition['lang']], $validator[$max]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'bool':
|
||||
$cfg_array[$config_name] = ($cfg_array[$config_name]) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case 'int':
|
||||
$cfg_array[$config_name] = (int) $cfg_array[$config_name];
|
||||
|
||||
if (isset($validator[$min]) && $cfg_array[$config_name] < $validator[$min])
|
||||
{
|
||||
$error[] = sprintf($user->lang['SETTING_TOO_LOW'], $user->lang[$config_definition['lang']], $validator[$min]);
|
||||
}
|
||||
else if (isset($validator[$max]) && $cfg_array[$config_name] > $validator[$max])
|
||||
{
|
||||
$error[] = sprintf($user->lang['SETTING_TOO_BIG'], $user->lang[$config_definition['lang']], $validator[$max]);
|
||||
}
|
||||
|
||||
if (strpos($config_name, '_max') !== false)
|
||||
{
|
||||
// Min/max pairs of settings should ensure that min <= max
|
||||
// Replace _max with _min to find the name of the minimum
|
||||
// corresponding configuration variable
|
||||
$min_name = str_replace('_max', '_min', $config_name);
|
||||
|
||||
if (isset($cfg_array[$min_name]) && is_numeric($cfg_array[$min_name]) && $cfg_array[$config_name] < $cfg_array[$min_name])
|
||||
{
|
||||
// A minimum value exists and the maximum value is less than it
|
||||
$error[] = sprintf($user->lang['SETTING_TOO_LOW'], $user->lang[$config_definition['lang']], (int) $cfg_array[$min_name]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'email':
|
||||
if (!preg_match('/^' . get_preg_expression('email') . '$/i', $cfg_array[$config_name]))
|
||||
{
|
||||
$error[] = $user->lang['EMAIL_INVALID_EMAIL'];
|
||||
}
|
||||
break;
|
||||
|
||||
// Absolute path
|
||||
case 'script_path':
|
||||
if (!$cfg_array[$config_name])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$destination = str_replace('\\', '/', $cfg_array[$config_name]);
|
||||
|
||||
if ($destination !== '/')
|
||||
{
|
||||
// Adjust destination path (no trailing slash)
|
||||
if (substr($destination, -1, 1) == '/')
|
||||
{
|
||||
$destination = substr($destination, 0, -1);
|
||||
}
|
||||
|
||||
$destination = str_replace(array('../', './'), '', $destination);
|
||||
|
||||
if ($destination[0] != '/')
|
||||
{
|
||||
$destination = '/' . $destination;
|
||||
}
|
||||
}
|
||||
|
||||
$cfg_array[$config_name] = trim($destination);
|
||||
|
||||
break;
|
||||
|
||||
// Absolute path
|
||||
case 'lang':
|
||||
if (!$cfg_array[$config_name])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$cfg_array[$config_name] = basename($cfg_array[$config_name]);
|
||||
|
||||
if (!file_exists($phpbb_root_path . 'language/' . $cfg_array[$config_name] . '/'))
|
||||
{
|
||||
$error[] = $user->lang['WRONG_DATA_LANG'];
|
||||
}
|
||||
break;
|
||||
|
||||
// Relative path (appended $phpbb_root_path)
|
||||
case 'rpath':
|
||||
case 'rwpath':
|
||||
if (!$cfg_array[$config_name])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$destination = $cfg_array[$config_name];
|
||||
|
||||
// Adjust destination path (no trailing slash)
|
||||
if (substr($destination, -1, 1) == '/' || substr($destination, -1, 1) == '\\')
|
||||
{
|
||||
$destination = substr($destination, 0, -1);
|
||||
}
|
||||
|
||||
$destination = str_replace(array('../', '..\\', './', '.\\'), '', $destination);
|
||||
if ($destination && ($destination[0] == '/' || $destination[0] == "\\"))
|
||||
{
|
||||
$destination = '';
|
||||
}
|
||||
|
||||
$cfg_array[$config_name] = trim($destination);
|
||||
|
||||
// Path being relative (still prefixed by phpbb_root_path), but with the ability to escape the root dir...
|
||||
case 'path':
|
||||
case 'wpath':
|
||||
|
||||
if (!$cfg_array[$config_name])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$cfg_array[$config_name] = trim($cfg_array[$config_name]);
|
||||
|
||||
// Make sure no NUL byte is present...
|
||||
if (strpos($cfg_array[$config_name], "\0") !== false || strpos($cfg_array[$config_name], '%00') !== false)
|
||||
{
|
||||
$cfg_array[$config_name] = '';
|
||||
break;
|
||||
}
|
||||
|
||||
$path = $phpbb_root_path . $cfg_array[$config_name];
|
||||
|
||||
if (!file_exists($path))
|
||||
{
|
||||
$error[] = sprintf($user->lang['DIRECTORY_DOES_NOT_EXIST'], $cfg_array[$config_name]);
|
||||
}
|
||||
|
||||
if (file_exists($path) && !is_dir($path))
|
||||
{
|
||||
$error[] = sprintf($user->lang['DIRECTORY_NOT_DIR'], $cfg_array[$config_name]);
|
||||
}
|
||||
|
||||
// Check if the path is writable
|
||||
if ($config_definition['validate'] == 'wpath' || $config_definition['validate'] == 'rwpath')
|
||||
{
|
||||
if (file_exists($path) && !$phpbb_filesystem->is_writable($path))
|
||||
{
|
||||
$error[] = sprintf($user->lang['DIRECTORY_NOT_WRITABLE'], $cfg_array[$config_name]);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
/**
|
||||
* Validate a config value
|
||||
*
|
||||
* @event core.validate_config_variable
|
||||
* @var array cfg_array Array with config values
|
||||
* @var string config_name Name of the config we validate
|
||||
* @var array config_definition Array with the options for
|
||||
* this config
|
||||
* @var array error Array of errors, the errors should
|
||||
* be strings only, language keys are
|
||||
* not replaced afterwards
|
||||
* @since 3.1.0-a1
|
||||
*/
|
||||
$vars = array('cfg_array', 'config_name', 'config_definition', 'error');
|
||||
extract($phpbb_dispatcher->trigger_event('core.validate_config_variable', compact($vars)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whatever or not a variable is OK for use in the Database
|
||||
* param mixed $value_ary An array of the form array(array('lang' => ..., 'value' => ..., 'column_type' =>))'
|
||||
* param mixed $error The error array
|
||||
*/
|
||||
function validate_range($value_ary, &$error)
|
||||
{
|
||||
global $user;
|
||||
|
||||
$column_types = array(
|
||||
'BOOL' => array('php_type' => 'int', 'min' => 0, 'max' => 1),
|
||||
'USINT' => array('php_type' => 'int', 'min' => 0, 'max' => 65535),
|
||||
'UINT' => array('php_type' => 'int', 'min' => 0, 'max' => (int) 0x7fffffff),
|
||||
// Do not use (int) 0x80000000 - it evaluates to different
|
||||
// values on 32-bit and 64-bit systems.
|
||||
// Apparently -2147483648 is a float on 32-bit systems,
|
||||
// despite fitting in an int, thus explicit cast is needed.
|
||||
'INT' => array('php_type' => 'int', 'min' => (int) -2147483648, 'max' => (int) 0x7fffffff),
|
||||
'TINT' => array('php_type' => 'int', 'min' => -128, 'max' => 127),
|
||||
|
||||
'VCHAR' => array('php_type' => 'string', 'min' => 0, 'max' => 255),
|
||||
);
|
||||
foreach ($value_ary as $value)
|
||||
{
|
||||
$column = explode(':', $value['column_type']);
|
||||
if (!isset($column_types[$column[0]]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = $column_types[$column[0]];
|
||||
}
|
||||
|
||||
switch ($type['php_type'])
|
||||
{
|
||||
case 'string' :
|
||||
$max = (isset($column[1])) ? min($column[1],$type['max']) : $type['max'];
|
||||
if (utf8_strlen($value['value']) > $max)
|
||||
{
|
||||
$error[] = sprintf($user->lang['SETTING_TOO_LONG'], $user->lang[$value['lang']], $max);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'int':
|
||||
$min = (isset($column[1])) ? max($column[1],$type['min']) : $type['min'];
|
||||
$max = (isset($column[2])) ? min($column[2],$type['max']) : $type['max'];
|
||||
if ($value['value'] < $min)
|
||||
{
|
||||
$error[] = sprintf($user->lang['SETTING_TOO_LOW'], $user->lang[$value['lang']], $min);
|
||||
}
|
||||
else if ($value['value'] > $max)
|
||||
{
|
||||
$error[] = sprintf($user->lang['SETTING_TOO_BIG'], $user->lang[$value['lang']], $max);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts new config display_vars into an exisiting display_vars array
|
||||
* at the given position.
|
||||
*
|
||||
* @param array $display_vars An array of existing config display vars
|
||||
* @param array $add_config_vars An array of new config display vars
|
||||
* @param array $where Where to place the new config vars,
|
||||
* before or after an exisiting config, as an array
|
||||
* of the form: array('after' => 'config_name') or
|
||||
* array('before' => 'config_name').
|
||||
* @return array The array of config display vars
|
||||
*/
|
||||
function phpbb_insert_config_array($display_vars, $add_config_vars, $where)
|
||||
{
|
||||
if (is_array($where) && array_key_exists(current($where), $display_vars))
|
||||
{
|
||||
$position = array_search(current($where), array_keys($display_vars)) + ((key($where) == 'before') ? 0 : 1);
|
||||
$display_vars = array_merge(
|
||||
array_slice($display_vars, 0, $position),
|
||||
$add_config_vars,
|
||||
array_slice($display_vars, $position)
|
||||
);
|
||||
}
|
||||
|
||||
return $display_vars;
|
||||
}
|
||||
3096
install/update/new/includes/functions_admin.php
Normal file
3096
install/update/new/includes/functions_admin.php
Normal file
File diff suppressed because it is too large
Load Diff
675
install/update/new/includes/functions_compatibility.php
Normal file
675
install/update/new/includes/functions_compatibility.php
Normal file
@@ -0,0 +1,675 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user avatar
|
||||
*
|
||||
* @deprecated 3.1.0-a1 (To be removed: 4.0.0)
|
||||
*
|
||||
* @param string $avatar Users assigned avatar name
|
||||
* @param int $avatar_type Type of avatar
|
||||
* @param string $avatar_width Width of users avatar
|
||||
* @param string $avatar_height Height of users avatar
|
||||
* @param string $alt Optional language string for alt tag within image, can be a language key or text
|
||||
* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
|
||||
* @param bool $lazy If true, will be lazy loaded (requires JS)
|
||||
*
|
||||
* @return string Avatar image
|
||||
*/
|
||||
function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $alt = 'USER_AVATAR', $ignore_config = false, $lazy = false)
|
||||
{
|
||||
// map arguments to new function phpbb_get_avatar()
|
||||
$row = array(
|
||||
'avatar' => $avatar,
|
||||
'avatar_type' => $avatar_type,
|
||||
'avatar_width' => $avatar_width,
|
||||
'avatar_height' => $avatar_height,
|
||||
);
|
||||
|
||||
return phpbb_get_avatar($row, $alt, $ignore_config, $lazy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash the password
|
||||
*
|
||||
* @deprecated 3.1.0-a2 (To be removed: 4.0.0)
|
||||
*
|
||||
* @param string $password Password to be hashed
|
||||
*
|
||||
* @return string|bool Password hash or false if something went wrong during hashing
|
||||
*/
|
||||
function phpbb_hash($password)
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
/* @var $passwords_manager \phpbb\passwords\manager */
|
||||
$passwords_manager = $phpbb_container->get('passwords.manager');
|
||||
return $passwords_manager->hash($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for correct password
|
||||
*
|
||||
* @deprecated 3.1.0-a2 (To be removed: 4.0.0)
|
||||
*
|
||||
* @param string $password The password in plain text
|
||||
* @param string $hash The stored password hash
|
||||
*
|
||||
* @return bool Returns true if the password is correct, false if not.
|
||||
*/
|
||||
function phpbb_check_hash($password, $hash)
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
/* @var $passwords_manager \phpbb\passwords\manager */
|
||||
$passwords_manager = $phpbb_container->get('passwords.manager');
|
||||
return $passwords_manager->check($password, $hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Eliminates useless . and .. components from specified path.
|
||||
*
|
||||
* Deprecated, use filesystem class instead
|
||||
*
|
||||
* @param string $path Path to clean
|
||||
* @return string Cleaned path
|
||||
*
|
||||
* @deprecated 3.1.0 (To be removed: 4.0.0)
|
||||
*/
|
||||
function phpbb_clean_path($path)
|
||||
{
|
||||
global $phpbb_path_helper, $phpbb_container;
|
||||
|
||||
if (!$phpbb_path_helper && $phpbb_container)
|
||||
{
|
||||
/* @var $phpbb_path_helper \phpbb\path_helper */
|
||||
$phpbb_path_helper = $phpbb_container->get('path_helper');
|
||||
}
|
||||
else if (!$phpbb_path_helper)
|
||||
{
|
||||
global $phpbb_root_path, $phpEx;
|
||||
|
||||
// The container is not yet loaded, use a new instance
|
||||
if (!class_exists('\phpbb\path_helper'))
|
||||
{
|
||||
require($phpbb_root_path . 'phpbb/path_helper.' . $phpEx);
|
||||
}
|
||||
|
||||
$request = new phpbb\request\request();
|
||||
$phpbb_path_helper = new phpbb\path_helper(
|
||||
new phpbb\symfony_request(
|
||||
$request
|
||||
),
|
||||
new phpbb\filesystem\filesystem(),
|
||||
$request,
|
||||
$phpbb_root_path,
|
||||
$phpEx
|
||||
);
|
||||
}
|
||||
|
||||
return $phpbb_path_helper->clean_path($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a timezone
|
||||
*
|
||||
* @param string $default A timezone to select
|
||||
* @param boolean $truncate Shall we truncate the options text
|
||||
*
|
||||
* @return string Returns the options for timezone selector only
|
||||
*
|
||||
* @deprecated 3.1.0 (To be removed: 4.0.0)
|
||||
*/
|
||||
function tz_select($default = '', $truncate = false)
|
||||
{
|
||||
global $template, $user;
|
||||
|
||||
return phpbb_timezone_select($template, $user, $default, $truncate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache moderators. Called whenever permissions are changed
|
||||
* via admin_permissions. Changes of usernames and group names
|
||||
* must be carried through for the moderators table.
|
||||
*
|
||||
* @deprecated 3.1.0 (To be removed: 4.0.0)
|
||||
* @return null
|
||||
*/
|
||||
function cache_moderators()
|
||||
{
|
||||
global $db, $cache, $auth;
|
||||
return phpbb_cache_moderators($db, $cache, $auth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes moderators and administrators from foe lists.
|
||||
*
|
||||
* @deprecated 3.1.0 (To be removed: 4.0.0)
|
||||
* @param array|bool $group_id If an array, remove all members of this group from foe lists, or false to ignore
|
||||
* @param array|bool $user_id If an array, remove this user from foe lists, or false to ignore
|
||||
* @return null
|
||||
*/
|
||||
function update_foes($group_id = false, $user_id = false)
|
||||
{
|
||||
global $db, $auth;
|
||||
return phpbb_update_foes($db, $auth, $group_id, $user_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user rank title and image
|
||||
*
|
||||
* @param int $user_rank the current stored users rank id
|
||||
* @param int $user_posts the users number of posts
|
||||
* @param string &$rank_title the rank title will be stored here after execution
|
||||
* @param string &$rank_img the rank image as full img tag is stored here after execution
|
||||
* @param string &$rank_img_src the rank image source is stored here after execution
|
||||
*
|
||||
* @deprecated 3.1.0-RC5 (To be removed: 4.0.0)
|
||||
*
|
||||
* Note: since we do not want to break backwards-compatibility, this function will only properly assign ranks to guests if you call it for them with user_posts == false
|
||||
*/
|
||||
function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank_img_src)
|
||||
{
|
||||
global $phpbb_root_path, $phpEx;
|
||||
if (!function_exists('phpbb_get_user_rank'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
|
||||
}
|
||||
|
||||
$rank_data = phpbb_get_user_rank(array('user_rank' => $user_rank), $user_posts);
|
||||
$rank_title = $rank_data['title'];
|
||||
$rank_img = $rank_data['img'];
|
||||
$rank_img_src = $rank_data['img_src'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve contents from remotely stored file
|
||||
*
|
||||
* @deprecated 3.1.2 Use file_downloader instead
|
||||
*/
|
||||
function get_remote_file($host, $directory, $filename, &$errstr, &$errno, $port = 80, $timeout = 6)
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
// Get file downloader and assign $errstr and $errno
|
||||
/* @var $file_downloader \phpbb\file_downloader */
|
||||
$file_downloader = $phpbb_container->get('file_downloader');
|
||||
|
||||
$file_data = $file_downloader->get($host, $directory, $filename, $port, $timeout);
|
||||
$errstr = $file_downloader->get_error_string();
|
||||
$errno = $file_downloader->get_error_number();
|
||||
|
||||
return $file_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add log entry
|
||||
*
|
||||
* @param string $mode The mode defines which log_type is used and from which log the entry is retrieved
|
||||
* @param int $forum_id Mode 'mod' ONLY: forum id of the related item, NOT INCLUDED otherwise
|
||||
* @param int $topic_id Mode 'mod' ONLY: topic id of the related item, NOT INCLUDED otherwise
|
||||
* @param int $reportee_id Mode 'user' ONLY: user id of the reportee, NOT INCLUDED otherwise
|
||||
* @param string $log_operation Name of the operation
|
||||
* @param array $additional_data More arguments can be added, depending on the log_type
|
||||
*
|
||||
* @return int|bool Returns the log_id, if the entry was added to the database, false otherwise.
|
||||
*
|
||||
* @deprecated 3.1.0 (To be removed: 4.0.0)
|
||||
*/
|
||||
function add_log()
|
||||
{
|
||||
global $phpbb_log, $user;
|
||||
|
||||
$args = func_get_args();
|
||||
$mode = array_shift($args);
|
||||
|
||||
// This looks kind of dirty, but add_log has some additional data before the log_operation
|
||||
$additional_data = array();
|
||||
switch ($mode)
|
||||
{
|
||||
case 'admin':
|
||||
case 'critical':
|
||||
break;
|
||||
case 'mod':
|
||||
$additional_data['forum_id'] = array_shift($args);
|
||||
$additional_data['topic_id'] = array_shift($args);
|
||||
break;
|
||||
case 'user':
|
||||
$additional_data['reportee_id'] = array_shift($args);
|
||||
break;
|
||||
}
|
||||
|
||||
$log_operation = array_shift($args);
|
||||
$additional_data = array_merge($additional_data, $args);
|
||||
|
||||
$user_id = (empty($user->data)) ? ANONYMOUS : $user->data['user_id'];
|
||||
$user_ip = (empty($user->ip)) ? '' : $user->ip;
|
||||
|
||||
return $phpbb_log->add($mode, $user_id, $user_ip, $log_operation, time(), $additional_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a configuration option's value.
|
||||
*
|
||||
* Please note that this function does not update the is_dynamic value for
|
||||
* an already existing config option.
|
||||
*
|
||||
* @param string $config_name The configuration option's name
|
||||
* @param string $config_value New configuration value
|
||||
* @param bool $is_dynamic Whether this variable should be cached (false) or
|
||||
* if it changes too frequently (true) to be
|
||||
* efficiently cached.
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* @deprecated 3.1.0 (To be removed: 4.0.0)
|
||||
*/
|
||||
function set_config($config_name, $config_value, $is_dynamic = false, \phpbb\config\config $set_config = null)
|
||||
{
|
||||
static $config = null;
|
||||
|
||||
if ($set_config !== null)
|
||||
{
|
||||
$config = $set_config;
|
||||
|
||||
if (empty($config_name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$config->set($config_name, $config_value, !$is_dynamic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments an integer config value directly in the database.
|
||||
*
|
||||
* @param string $config_name The configuration option's name
|
||||
* @param int $increment Amount to increment by
|
||||
* @param bool $is_dynamic Whether this variable should be cached (false) or
|
||||
* if it changes too frequently (true) to be
|
||||
* efficiently cached.
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* @deprecated 3.1.0 (To be removed: 4.0.0)
|
||||
*/
|
||||
function set_config_count($config_name, $increment, $is_dynamic = false, \phpbb\config\config $set_config = null)
|
||||
{
|
||||
static $config = null;
|
||||
if ($set_config !== null)
|
||||
{
|
||||
$config = $set_config;
|
||||
if (empty($config_name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
$config->increment($config_name, $increment, !$is_dynamic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function of \phpbb\request\request::variable which exists for backwards compatability.
|
||||
* See {@link \phpbb\request\request_interface::variable \phpbb\request\request_interface::variable} for
|
||||
* documentation of this function's use.
|
||||
*
|
||||
* @deprecated 3.1.0 (To be removed: 4.0.0)
|
||||
* @param mixed $var_name The form variable's name from which data shall be retrieved.
|
||||
* If the value is an array this may be an array of indizes which will give
|
||||
* direct access to a value at any depth. E.g. if the value of "var" is array(1 => "a")
|
||||
* then specifying array("var", 1) as the name will return "a".
|
||||
* If you pass an instance of {@link \phpbb\request\request_interface phpbb_request_interface}
|
||||
* as this parameter it will overwrite the current request class instance. If you do
|
||||
* not do so, it will create its own instance (but leave superglobals enabled).
|
||||
* @param mixed $default A default value that is returned if the variable was not set.
|
||||
* This function will always return a value of the same type as the default.
|
||||
* @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters
|
||||
* Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks
|
||||
* @param bool $cookie This param is mapped to \phpbb\request\request_interface::COOKIE as the last param for
|
||||
* \phpbb\request\request_interface::variable for backwards compatability reasons.
|
||||
* @param \phpbb\request\request_interface|null|false If an instance of \phpbb\request\request_interface is given the instance is stored in
|
||||
* a static variable and used for all further calls where this parameters is null. Until
|
||||
* the function is called with an instance it automatically creates a new \phpbb\request\request
|
||||
* instance on every call. By passing false this per-call instantiation can be restored
|
||||
* after having passed in a \phpbb\request\request_interface instance.
|
||||
*
|
||||
* @return mixed The value of $_REQUEST[$var_name] run through {@link set_var set_var} to ensure that the type is the
|
||||
* the same as that of $default. If the variable is not set $default is returned.
|
||||
*/
|
||||
function request_var($var_name, $default, $multibyte = false, $cookie = false, $request = null)
|
||||
{
|
||||
// This is all just an ugly hack to add "Dependency Injection" to a function
|
||||
// the only real code is the function call which maps this function to a method.
|
||||
static $static_request = null;
|
||||
if ($request instanceof \phpbb\request\request_interface)
|
||||
{
|
||||
$static_request = $request;
|
||||
if (empty($var_name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ($request === false)
|
||||
{
|
||||
$static_request = null;
|
||||
if (empty($var_name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
$tmp_request = $static_request;
|
||||
// no request class set, create a temporary one ourselves to keep backwards compatibility
|
||||
if ($tmp_request === null)
|
||||
{
|
||||
// false param: enable super globals, so the created request class does not
|
||||
// make super globals inaccessible everywhere outside this function.
|
||||
$tmp_request = new \phpbb\request\request(new \phpbb\request\type_cast_helper(), false);
|
||||
}
|
||||
return $tmp_request->variable($var_name, $default, $multibyte, ($cookie) ? \phpbb\request\request_interface::COOKIE : \phpbb\request\request_interface::REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tables of a database
|
||||
*
|
||||
* @deprecated 3.1.0 (To be removed: 4.0.0)
|
||||
*/
|
||||
function get_tables($db)
|
||||
{
|
||||
$db_tools_factory = new \phpbb\db\tools\factory();
|
||||
$db_tools = $db_tools_factory->get($db);
|
||||
|
||||
return $db_tools->sql_list_tables();
|
||||
}
|
||||
|
||||
/**
|
||||
* Global function for chmodding directories and files for internal use
|
||||
*
|
||||
* This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions.
|
||||
* The function determines owner and group from common.php file and sets the same to the provided file.
|
||||
* The function uses bit fields to build the permissions.
|
||||
* The function sets the appropiate execute bit on directories.
|
||||
*
|
||||
* Supported constants representing bit fields are:
|
||||
*
|
||||
* CHMOD_ALL - all permissions (7)
|
||||
* CHMOD_READ - read permission (4)
|
||||
* CHMOD_WRITE - write permission (2)
|
||||
* CHMOD_EXECUTE - execute permission (1)
|
||||
*
|
||||
* NOTE: The function uses POSIX extension and fileowner()/filegroup() functions. If any of them is disabled, this function tries to build proper permissions, by calling is_readable() and is_writable() functions.
|
||||
*
|
||||
* @param string $filename The file/directory to be chmodded
|
||||
* @param int $perms Permissions to set
|
||||
*
|
||||
* @return bool true on success, otherwise false
|
||||
*
|
||||
* @deprecated 3.2.0-dev use \phpbb\filesystem\filesystem::phpbb_chmod() instead
|
||||
*/
|
||||
function phpbb_chmod($filename, $perms = CHMOD_READ)
|
||||
{
|
||||
global $phpbb_filesystem;
|
||||
|
||||
try
|
||||
{
|
||||
$phpbb_filesystem->phpbb_chmod($filename, $perms);
|
||||
}
|
||||
catch (\phpbb\filesystem\exception\filesystem_exception $e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a file/directory is writable
|
||||
*
|
||||
* This function calls the native is_writable() when not running under
|
||||
* Windows and it is not disabled.
|
||||
*
|
||||
* @param string $file Path to perform write test on
|
||||
* @return bool True when the path is writable, otherwise false.
|
||||
*
|
||||
* @deprecated 3.2.0-dev use \phpbb\filesystem\filesystem::is_writable() instead
|
||||
*/
|
||||
function phpbb_is_writable($file)
|
||||
{
|
||||
global $phpbb_filesystem;
|
||||
|
||||
return $phpbb_filesystem->is_writable($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a path ($path) is absolute or relative
|
||||
*
|
||||
* @param string $path Path to check absoluteness of
|
||||
* @return boolean
|
||||
*
|
||||
* @deprecated 3.2.0-dev use \phpbb\filesystem\filesystem::is_absolute_path() instead
|
||||
*/
|
||||
function phpbb_is_absolute($path)
|
||||
{
|
||||
global $phpbb_filesystem;
|
||||
|
||||
return $phpbb_filesystem->is_absolute_path($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper for realpath
|
||||
*
|
||||
* @deprecated 3.2.0-dev use \phpbb\filesystem\filesystem::realpath() instead
|
||||
*/
|
||||
function phpbb_realpath($path)
|
||||
{
|
||||
global $phpbb_filesystem;
|
||||
|
||||
return $phpbb_filesystem->realpath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine which plural form we should use.
|
||||
* For some languages this is not as simple as for English.
|
||||
*
|
||||
* @param $rule int ID of the plural rule we want to use, see https://area51.phpbb.com/docs/dev/32x/language/plurals.html
|
||||
* @param $number int|float The number we want to get the plural case for. Float numbers are floored.
|
||||
* @return int The plural-case we need to use for the number plural-rule combination
|
||||
*
|
||||
* @deprecated 3.2.0-dev (To be removed: 4.0.0)
|
||||
*/
|
||||
function phpbb_get_plural_form($rule, $number)
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
/** @var \phpbb\language\language $language */
|
||||
$language = $phpbb_container->get('language');
|
||||
return $language->get_plural_form($number, $rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool Always true
|
||||
* @deprecated 3.2.0-dev
|
||||
*/
|
||||
function phpbb_pcre_utf8_support()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts a variable to the given type.
|
||||
*
|
||||
* @deprecated 3.1 (To be removed 4.0.0)
|
||||
*/
|
||||
function set_var(&$result, $var, $type, $multibyte = false)
|
||||
{
|
||||
// no need for dependency injection here, if you have the object, call the method yourself!
|
||||
$type_cast_helper = new \phpbb\request\type_cast_helper();
|
||||
$type_cast_helper->set_var($result, $var, $type, $multibyte);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Attachments
|
||||
*
|
||||
* @deprecated 3.2.0-a1 (To be removed: 4.0.0)
|
||||
*
|
||||
* @param string $mode can be: post|message|topic|attach|user
|
||||
* @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids
|
||||
* @param bool $resync set this to false if you are deleting posts or topics
|
||||
*/
|
||||
function delete_attachments($mode, $ids, $resync = true)
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$num_deleted = $attachment_manager->delete($mode, $ids, $resync);
|
||||
|
||||
unset($attachment_manager);
|
||||
|
||||
return $num_deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete attached file
|
||||
*
|
||||
* @deprecated 3.2.0-a1 (To be removed: 4.0.0)
|
||||
*/
|
||||
function phpbb_unlink($filename, $mode = 'file', $entry_removed = false)
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$unlink = $attachment_manager->unlink($filename, $mode, $entry_removed);
|
||||
unset($attachment_manager);
|
||||
|
||||
return $unlink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display reasons
|
||||
*
|
||||
* @deprecated 3.2.0-dev (To be removed: 4.0.0)
|
||||
*/
|
||||
function display_reasons($reason_id = 0)
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
$phpbb_container->get('phpbb.report.report_reason_list_provider')->display_reasons($reason_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload Attachment - filedata is generated here
|
||||
* Uses upload class
|
||||
*
|
||||
* @deprecated 3.2.0-a1 (To be removed: 4.0.0)
|
||||
*
|
||||
* @param string $form_name The form name of the file upload input
|
||||
* @param int $forum_id The id of the forum
|
||||
* @param bool $local Whether the file is local or not
|
||||
* @param string $local_storage The path to the local file
|
||||
* @param bool $is_message Whether it is a PM or not
|
||||
* @param array $local_filedata A filespec object created for the local file
|
||||
*
|
||||
* @return array File data array
|
||||
*/
|
||||
function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false)
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$file = $attachment_manager->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata);
|
||||
unset($attachment_manager);
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for php's checkdnsrr function.
|
||||
*
|
||||
* @param string $host Fully-Qualified Domain Name
|
||||
* @param string $type Resource record type to lookup
|
||||
* Supported types are: MX (default), A, AAAA, NS, TXT, CNAME
|
||||
* Other types may work or may not work
|
||||
*
|
||||
* @return mixed true if entry found,
|
||||
* false if entry not found,
|
||||
* null if this function is not supported by this environment
|
||||
*
|
||||
* Since null can also be returned, you probably want to compare the result
|
||||
* with === true or === false,
|
||||
*
|
||||
* @deprecated 3.3.0-b2 (To be removed: 4.0.0)
|
||||
*/
|
||||
function phpbb_checkdnsrr($host, $type = 'MX')
|
||||
{
|
||||
return checkdnsrr($host, $type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for inet_ntop()
|
||||
*
|
||||
* Converts a packed internet address to a human readable representation
|
||||
* inet_ntop() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
|
||||
*
|
||||
* @param string $in_addr A 32bit IPv4, or 128bit IPv6 address.
|
||||
*
|
||||
* @return mixed false on failure,
|
||||
* string otherwise
|
||||
*
|
||||
* @deprecated 3.3.0-b2 (To be removed: 4.0.0)
|
||||
*/
|
||||
function phpbb_inet_ntop($in_addr)
|
||||
{
|
||||
return inet_ntop($in_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for inet_pton()
|
||||
*
|
||||
* Converts a human readable IP address to its packed in_addr representation
|
||||
* inet_pton() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
|
||||
*
|
||||
* @param string $address A human readable IPv4 or IPv6 address.
|
||||
*
|
||||
* @return mixed false if address is invalid,
|
||||
* in_addr representation of the given address otherwise (string)
|
||||
*
|
||||
* @deprecated 3.3.0-b2 (To be removed: 4.0.0)
|
||||
*/
|
||||
function phpbb_inet_pton($address)
|
||||
{
|
||||
return inet_pton($address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashes an email address to a big integer
|
||||
*
|
||||
* @param string $email Email address
|
||||
*
|
||||
* @return string Unsigned Big Integer
|
||||
*
|
||||
* @deprecated 3.3.0-b2 (To be removed: 4.0.0)
|
||||
*/
|
||||
function phpbb_email_hash($email)
|
||||
{
|
||||
return sprintf('%u', crc32(strtolower($email))) . strlen($email);
|
||||
}
|
||||
830
install/update/new/includes/functions_compress.php
Normal file
830
install/update/new/includes/functions_compress.php
Normal file
@@ -0,0 +1,830 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for handling archives (compression/decompression)
|
||||
*/
|
||||
class compress
|
||||
{
|
||||
var $fp = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $filelist = array();
|
||||
|
||||
/**
|
||||
* Add file to archive
|
||||
*/
|
||||
function add_file($src, $src_rm_prefix = '', $src_add_prefix = '', $skip_files = '')
|
||||
{
|
||||
global $phpbb_root_path;
|
||||
|
||||
$skip_files = explode(',', $skip_files);
|
||||
|
||||
// Remove rm prefix from src path
|
||||
$src_path = ($src_rm_prefix) ? preg_replace('#^(' . preg_quote($src_rm_prefix, '#') . ')#', '', $src) : $src;
|
||||
// Add src prefix
|
||||
$src_path = ($src_add_prefix) ? ($src_add_prefix . ((substr($src_add_prefix, -1) != '/') ? '/' : '') . $src_path) : $src_path;
|
||||
// Remove initial "/" if present
|
||||
$src_path = (substr($src_path, 0, 1) == '/') ? substr($src_path, 1) : $src_path;
|
||||
|
||||
if (is_file($phpbb_root_path . $src))
|
||||
{
|
||||
$this->data($src_path, file_get_contents("$phpbb_root_path$src"), stat("$phpbb_root_path$src"), false);
|
||||
}
|
||||
else if (is_dir($phpbb_root_path . $src))
|
||||
{
|
||||
// Clean up path, add closing / if not present
|
||||
$src_path = ($src_path && substr($src_path, -1) != '/') ? $src_path . '/' : $src_path;
|
||||
|
||||
$filelist = filelist("$phpbb_root_path$src", '', '*');
|
||||
krsort($filelist);
|
||||
|
||||
/**
|
||||
* Commented out, as adding the folders produces corrupted archives
|
||||
if ($src_path)
|
||||
{
|
||||
$this->data($src_path, '', true, stat("$phpbb_root_path$src"));
|
||||
}
|
||||
*/
|
||||
|
||||
foreach ($filelist as $path => $file_ary)
|
||||
{
|
||||
/**
|
||||
* Commented out, as adding the folders produces corrupted archives
|
||||
if ($path)
|
||||
{
|
||||
// Same as for src_path
|
||||
$path = (substr($path, 0, 1) == '/') ? substr($path, 1) : $path;
|
||||
$path = ($path && substr($path, -1) != '/') ? $path . '/' : $path;
|
||||
|
||||
$this->data("$src_path$path", '', true, stat("$phpbb_root_path$src$path"));
|
||||
}
|
||||
*/
|
||||
|
||||
foreach ($file_ary as $file)
|
||||
{
|
||||
if (in_array($path . $file, $skip_files))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->data("$src_path$path$file", file_get_contents("$phpbb_root_path$src$path$file"), stat("$phpbb_root_path$src$path$file"), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// $src does not exist
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom file (the filepath will not be adjusted)
|
||||
*/
|
||||
function add_custom_file($src, $filename)
|
||||
{
|
||||
if (!file_exists($src))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->data($filename, file_get_contents($src), stat($src), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add file data
|
||||
*/
|
||||
function add_data($src, $name)
|
||||
{
|
||||
$stat = array();
|
||||
$stat[2] = 436; //384
|
||||
$stat[4] = $stat[5] = 0;
|
||||
$stat[7] = strlen($src);
|
||||
$stat[9] = time();
|
||||
$this->data($name, $src, $stat, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a file by that name as already been added and, if it has,
|
||||
* returns a new, unique name.
|
||||
*
|
||||
* @param string $name The filename
|
||||
* @return string A unique filename
|
||||
*/
|
||||
protected function unique_filename($name)
|
||||
{
|
||||
if (isset($this->filelist[$name]))
|
||||
{
|
||||
$start = $name;
|
||||
$ext = '';
|
||||
$this->filelist[$name]++;
|
||||
|
||||
// Separate the extension off the end of the filename to preserve it
|
||||
$pos = strrpos($name, '.');
|
||||
if ($pos !== false)
|
||||
{
|
||||
$start = substr($name, 0, $pos);
|
||||
$ext = substr($name, $pos);
|
||||
}
|
||||
|
||||
return $start . '_' . $this->filelist[$name] . $ext;
|
||||
}
|
||||
|
||||
$this->filelist[$name] = 0;
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return available methods
|
||||
*
|
||||
* @return array Array of strings of available compression methods (.tar, .tar.gz, .zip, etc.)
|
||||
*/
|
||||
static public function methods()
|
||||
{
|
||||
$methods = array('.tar');
|
||||
$available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib');
|
||||
|
||||
foreach ($available_methods as $type => $module)
|
||||
{
|
||||
if (!@extension_loaded($module))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$methods[] = $type;
|
||||
}
|
||||
|
||||
return $methods;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zip creation class from phpMyAdmin 2.3.0 (c) Tobias Ratschiller, Olivier Müller, Loïc Chapeaux,
|
||||
* Marc Delisle, http://www.phpmyadmin.net/
|
||||
*
|
||||
* Zip extraction function by Alexandre Tedeschi, alexandrebr at gmail dot com
|
||||
*
|
||||
* Modified extensively by psoTFX and DavidMJ, (c) phpBB Limited, 2003
|
||||
*
|
||||
* Based on work by Eric Mueller and Denis125
|
||||
* Official ZIP file format: http://www.pkware.com/appnote.txt
|
||||
*/
|
||||
class compress_zip extends compress
|
||||
{
|
||||
var $datasec = array();
|
||||
var $ctrl_dir = array();
|
||||
var $eof_cdh = "\x50\x4b\x05\x06\x00\x00\x00\x00";
|
||||
|
||||
var $old_offset = 0;
|
||||
var $datasec_len = 0;
|
||||
|
||||
/**
|
||||
* @var \phpbb\filesystem\filesystem_interface
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct($mode, $file)
|
||||
{
|
||||
global $phpbb_filesystem;
|
||||
|
||||
$this->fp = @fopen($file, $mode . 'b');
|
||||
$this->filesystem = ($phpbb_filesystem instanceof \phpbb\filesystem\filesystem_interface) ? $phpbb_filesystem : new \phpbb\filesystem\filesystem();
|
||||
|
||||
if (!$this->fp)
|
||||
{
|
||||
trigger_error('Unable to open file ' . $file . ' [' . $mode . 'b]');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert unix to dos time
|
||||
*/
|
||||
function unix_to_dos_time($time)
|
||||
{
|
||||
$timearray = (!$time) ? getdate() : getdate($time);
|
||||
|
||||
if ($timearray['year'] < 1980)
|
||||
{
|
||||
$timearray['year'] = 1980;
|
||||
$timearray['mon'] = $timearray['mday'] = 1;
|
||||
$timearray['hours'] = $timearray['minutes'] = $timearray['seconds'] = 0;
|
||||
}
|
||||
|
||||
return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract archive
|
||||
*/
|
||||
function extract($dst)
|
||||
{
|
||||
// Loop the file, looking for files and folders
|
||||
$dd_try = false;
|
||||
rewind($this->fp);
|
||||
|
||||
while (!feof($this->fp))
|
||||
{
|
||||
// Check if the signature is valid...
|
||||
$signature = fread($this->fp, 4);
|
||||
|
||||
switch ($signature)
|
||||
{
|
||||
// 'Local File Header'
|
||||
case "\x50\x4b\x03\x04":
|
||||
// Lets get everything we need.
|
||||
// We don't store the version needed to extract, the general purpose bit flag or the date and time fields
|
||||
$data = unpack("@4/vc_method/@10/Vcrc/Vc_size/Vuc_size/vname_len/vextra_field", fread($this->fp, 26));
|
||||
$file_name = fread($this->fp, $data['name_len']); // filename
|
||||
|
||||
if ($data['extra_field'])
|
||||
{
|
||||
fread($this->fp, $data['extra_field']); // extra field
|
||||
}
|
||||
|
||||
$target_filename = "$dst$file_name";
|
||||
|
||||
if (!$data['uc_size'] && !$data['crc'] && substr($file_name, -1, 1) == '/')
|
||||
{
|
||||
if (!is_dir($target_filename))
|
||||
{
|
||||
$str = '';
|
||||
$folders = explode('/', $target_filename);
|
||||
|
||||
// Create and folders and subfolders if they do not exist
|
||||
foreach ($folders as $folder)
|
||||
{
|
||||
$folder = trim($folder);
|
||||
if (!$folder)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$str = (!empty($str)) ? $str . '/' . $folder : $folder;
|
||||
if (!is_dir($str))
|
||||
{
|
||||
if (!@mkdir($str, 0777))
|
||||
{
|
||||
trigger_error("Could not create directory $folder");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
|
||||
}
|
||||
catch (\phpbb\filesystem\exception\filesystem_exception $e)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// This is a directory, we are not writing files
|
||||
continue 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some archivers are punks, they don't include folders in their archives!
|
||||
$str = '';
|
||||
$folders = explode('/', pathinfo($target_filename, PATHINFO_DIRNAME));
|
||||
|
||||
// Create and folders and subfolders if they do not exist
|
||||
foreach ($folders as $folder)
|
||||
{
|
||||
$folder = trim($folder);
|
||||
if (!$folder)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$str = (!empty($str)) ? $str . '/' . $folder : $folder;
|
||||
if (!is_dir($str))
|
||||
{
|
||||
if (!@mkdir($str, 0777))
|
||||
{
|
||||
trigger_error("Could not create directory $folder");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
|
||||
}
|
||||
catch (\phpbb\filesystem\exception\filesystem_exception $e)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$data['uc_size'])
|
||||
{
|
||||
$content = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$content = fread($this->fp, $data['c_size']);
|
||||
}
|
||||
|
||||
$fp = fopen($target_filename, "w");
|
||||
|
||||
switch ($data['c_method'])
|
||||
{
|
||||
case 0:
|
||||
// Not compressed
|
||||
fwrite($fp, $content);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
// Deflate
|
||||
fwrite($fp, gzinflate($content, $data['uc_size']));
|
||||
break;
|
||||
|
||||
case 12:
|
||||
// Bzip2
|
||||
fwrite($fp, bzdecompress($content));
|
||||
break;
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
break;
|
||||
|
||||
// We hit the 'Central Directory Header', we can stop because nothing else in here requires our attention
|
||||
// or we hit the end of the central directory record, we can safely end the loop as we are totally finished with looking for files and folders
|
||||
case "\x50\x4b\x01\x02":
|
||||
// This case should simply never happen.. but it does exist..
|
||||
case "\x50\x4b\x05\x06":
|
||||
break 2;
|
||||
|
||||
// 'Packed to Removable Disk', ignore it and look for the next signature...
|
||||
case 'PK00':
|
||||
continue 2;
|
||||
|
||||
// We have encountered a header that is weird. Lets look for better data...
|
||||
default:
|
||||
if (!$dd_try)
|
||||
{
|
||||
// Unexpected header. Trying to detect wrong placed 'Data Descriptor';
|
||||
$dd_try = true;
|
||||
fseek($this->fp, 8, SEEK_CUR); // Jump over 'crc-32'(4) 'compressed-size'(4), 'uncompressed-size'(4)
|
||||
continue 2;
|
||||
}
|
||||
trigger_error("Unexpected header, ending loop");
|
||||
break 2;
|
||||
}
|
||||
|
||||
$dd_try = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close archive
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
// Write out central file directory and footer ... if it exists
|
||||
if (count($this->ctrl_dir))
|
||||
{
|
||||
fwrite($this->fp, $this->file());
|
||||
}
|
||||
fclose($this->fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the structures ... note we assume version made by is MSDOS
|
||||
*/
|
||||
function data($name, $data, $stat, $is_dir = false)
|
||||
{
|
||||
$name = str_replace('\\', '/', $name);
|
||||
$name = $this->unique_filename($name);
|
||||
|
||||
$hexdtime = pack('V', $this->unix_to_dos_time($stat[9]));
|
||||
|
||||
if ($is_dir)
|
||||
{
|
||||
$unc_len = $c_len = $crc = 0;
|
||||
$zdata = '';
|
||||
$var_ext = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
$unc_len = strlen($data);
|
||||
$crc = crc32($data);
|
||||
$zdata = gzdeflate($data);
|
||||
$c_len = strlen($zdata);
|
||||
$var_ext = 20;
|
||||
|
||||
// Did we compress? No, then use data as is
|
||||
if ($c_len >= $unc_len)
|
||||
{
|
||||
$zdata = $data;
|
||||
$c_len = $unc_len;
|
||||
$var_ext = 10;
|
||||
}
|
||||
}
|
||||
unset($data);
|
||||
|
||||
// If we didn't compress set method to store, else deflate
|
||||
$c_method = ($c_len == $unc_len) ? "\x00\x00" : "\x08\x00";
|
||||
|
||||
// Are we a file or a directory? Set archive for file
|
||||
$attrib = ($is_dir) ? 16 : 32;
|
||||
|
||||
// File Record Header
|
||||
$fr = "\x50\x4b\x03\x04"; // Local file header 4bytes
|
||||
$fr .= pack('v', $var_ext); // ver needed to extract 2bytes
|
||||
$fr .= "\x00\x00"; // gen purpose bit flag 2bytes
|
||||
$fr .= $c_method; // compression method 2bytes
|
||||
$fr .= $hexdtime; // last mod time and date 2+2bytes
|
||||
$fr .= pack('V', $crc); // crc32 4bytes
|
||||
$fr .= pack('V', $c_len); // compressed filesize 4bytes
|
||||
$fr .= pack('V', $unc_len); // uncompressed filesize 4bytes
|
||||
$fr .= pack('v', strlen($name));// length of filename 2bytes
|
||||
|
||||
$fr .= pack('v', 0); // extra field length 2bytes
|
||||
$fr .= $name;
|
||||
$fr .= $zdata;
|
||||
unset($zdata);
|
||||
|
||||
$this->datasec_len += strlen($fr);
|
||||
|
||||
// Add data to file ... by writing data out incrementally we save some memory
|
||||
fwrite($this->fp, $fr);
|
||||
unset($fr);
|
||||
|
||||
// Central Directory Header
|
||||
$cdrec = "\x50\x4b\x01\x02"; // header 4bytes
|
||||
$cdrec .= "\x00\x00"; // version made by
|
||||
$cdrec .= pack('v', $var_ext); // version needed to extract
|
||||
$cdrec .= "\x00\x00"; // gen purpose bit flag
|
||||
$cdrec .= $c_method; // compression method
|
||||
$cdrec .= $hexdtime; // last mod time & date
|
||||
$cdrec .= pack('V', $crc); // crc32
|
||||
$cdrec .= pack('V', $c_len); // compressed filesize
|
||||
$cdrec .= pack('V', $unc_len); // uncompressed filesize
|
||||
$cdrec .= pack('v', strlen($name)); // length of filename
|
||||
$cdrec .= pack('v', 0); // extra field length
|
||||
$cdrec .= pack('v', 0); // file comment length
|
||||
$cdrec .= pack('v', 0); // disk number start
|
||||
$cdrec .= pack('v', 0); // internal file attributes
|
||||
$cdrec .= pack('V', $attrib); // external file attributes
|
||||
$cdrec .= pack('V', $this->old_offset); // relative offset of local header
|
||||
$cdrec .= $name;
|
||||
|
||||
// Save to central directory
|
||||
$this->ctrl_dir[] = $cdrec;
|
||||
|
||||
$this->old_offset = $this->datasec_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* file
|
||||
*/
|
||||
function file()
|
||||
{
|
||||
$ctrldir = implode('', $this->ctrl_dir);
|
||||
|
||||
return $ctrldir . $this->eof_cdh .
|
||||
pack('v', count($this->ctrl_dir)) . // total # of entries "on this disk"
|
||||
pack('v', count($this->ctrl_dir)) . // total # of entries overall
|
||||
pack('V', strlen($ctrldir)) . // size of central dir
|
||||
pack('V', $this->datasec_len) . // offset to start of central dir
|
||||
"\x00\x00"; // .zip file comment length
|
||||
}
|
||||
|
||||
/**
|
||||
* Download archive
|
||||
*/
|
||||
function download($filename, $download_name = false)
|
||||
{
|
||||
global $phpbb_root_path;
|
||||
|
||||
if ($download_name === false)
|
||||
{
|
||||
$download_name = $filename;
|
||||
}
|
||||
|
||||
$mimetype = 'application/zip';
|
||||
|
||||
header('Cache-Control: private, no-cache');
|
||||
header("Content-Type: $mimetype; name=\"$download_name.zip\"");
|
||||
header("Content-disposition: attachment; filename=$download_name.zip");
|
||||
|
||||
$fp = @fopen("{$phpbb_root_path}store/$filename.zip", 'rb');
|
||||
if ($fp)
|
||||
{
|
||||
while ($buffer = fread($fp, 1024))
|
||||
{
|
||||
echo $buffer;
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tar/tar.gz compression routine
|
||||
* Header/checksum creation derived from tarfile.pl, (c) Tom Horsley, 1994
|
||||
*/
|
||||
class compress_tar extends compress
|
||||
{
|
||||
var $isgz = false;
|
||||
var $isbz = false;
|
||||
var $filename = '';
|
||||
var $mode = '';
|
||||
var $type = '';
|
||||
var $wrote = false;
|
||||
|
||||
/**
|
||||
* @var \phpbb\filesystem\filesystem_interface
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct($mode, $file, $type = '')
|
||||
{
|
||||
global $phpbb_filesystem;
|
||||
|
||||
$type = (!$type) ? $file : $type;
|
||||
$this->isgz = preg_match('#(\.tar\.gz|\.tgz)$#', $type);
|
||||
$this->isbz = preg_match('#\.tar\.bz2$#', $type);
|
||||
|
||||
$this->mode = &$mode;
|
||||
$this->file = &$file;
|
||||
$this->type = &$type;
|
||||
$this->open();
|
||||
|
||||
$this->filesystem = ($phpbb_filesystem instanceof \phpbb\filesystem\filesystem_interface) ? $phpbb_filesystem : new \phpbb\filesystem\filesystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract archive
|
||||
*/
|
||||
function extract($dst)
|
||||
{
|
||||
$fzread = ($this->isbz && function_exists('bzread')) ? 'bzread' : (($this->isgz && @extension_loaded('zlib')) ? 'gzread' : 'fread');
|
||||
|
||||
// Run through the file and grab directory entries
|
||||
while ($buffer = $fzread($this->fp, 512))
|
||||
{
|
||||
$tmp = unpack('A6magic', substr($buffer, 257, 6));
|
||||
|
||||
if (trim($tmp['magic']) == 'ustar')
|
||||
{
|
||||
$tmp = unpack('A100name', $buffer);
|
||||
$filename = trim($tmp['name']);
|
||||
|
||||
$tmp = unpack('Atype', substr($buffer, 156, 1));
|
||||
$filetype = (int) trim($tmp['type']);
|
||||
|
||||
$tmp = unpack('A12size', substr($buffer, 124, 12));
|
||||
$filesize = octdec((int) trim($tmp['size']));
|
||||
|
||||
$target_filename = "$dst$filename";
|
||||
|
||||
if ($filetype == 5)
|
||||
{
|
||||
if (!is_dir($target_filename))
|
||||
{
|
||||
$str = '';
|
||||
$folders = explode('/', $target_filename);
|
||||
|
||||
// Create and folders and subfolders if they do not exist
|
||||
foreach ($folders as $folder)
|
||||
{
|
||||
$folder = trim($folder);
|
||||
if (!$folder)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$str = (!empty($str)) ? $str . '/' . $folder : $folder;
|
||||
if (!is_dir($str))
|
||||
{
|
||||
if (!@mkdir($str, 0777))
|
||||
{
|
||||
trigger_error("Could not create directory $folder");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
|
||||
}
|
||||
catch (\phpbb\filesystem\exception\filesystem_exception $e)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($filesize >= 0 && ($filetype == 0 || $filetype == "\0"))
|
||||
{
|
||||
// Some archivers are punks, they don't properly order the folders in their archives!
|
||||
$str = '';
|
||||
$folders = explode('/', pathinfo($target_filename, PATHINFO_DIRNAME));
|
||||
|
||||
// Create and folders and subfolders if they do not exist
|
||||
foreach ($folders as $folder)
|
||||
{
|
||||
$folder = trim($folder);
|
||||
if (!$folder)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$str = (!empty($str)) ? $str . '/' . $folder : $folder;
|
||||
if (!is_dir($str))
|
||||
{
|
||||
if (!@mkdir($str, 0777))
|
||||
{
|
||||
trigger_error("Could not create directory $folder");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
|
||||
}
|
||||
catch (\phpbb\filesystem\exception\filesystem_exception $e)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the files
|
||||
if (!($fp = fopen($target_filename, 'wb')))
|
||||
{
|
||||
trigger_error("Couldn't create file $filename");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->filesystem->phpbb_chmod($target_filename, CHMOD_READ);
|
||||
}
|
||||
catch (\phpbb\filesystem\exception\filesystem_exception $e)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
// Grab the file contents
|
||||
fwrite($fp, ($filesize) ? $fzread($this->fp, ($filesize + 511) &~ 511) : '', $filesize);
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close archive
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$fzclose = ($this->isbz && function_exists('bzclose')) ? 'bzclose' : (($this->isgz && @extension_loaded('zlib')) ? 'gzclose' : 'fclose');
|
||||
|
||||
if ($this->wrote)
|
||||
{
|
||||
$fzwrite = ($this->isbz && function_exists('bzwrite')) ? 'bzwrite' : (($this->isgz && @extension_loaded('zlib')) ? 'gzwrite' : 'fwrite');
|
||||
|
||||
// The end of a tar archive ends in two records of all NULLs (1024 bytes of \0)
|
||||
$fzwrite($this->fp, str_repeat("\0", 1024));
|
||||
}
|
||||
|
||||
$fzclose($this->fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the structures
|
||||
*/
|
||||
function data($name, $data, $stat, $is_dir = false)
|
||||
{
|
||||
$name = $this->unique_filename($name);
|
||||
$this->wrote = true;
|
||||
$fzwrite = ($this->isbz && function_exists('bzwrite')) ? 'bzwrite' : (($this->isgz && @extension_loaded('zlib')) ? 'gzwrite' : 'fwrite');
|
||||
|
||||
$typeflag = ($is_dir) ? '5' : '';
|
||||
|
||||
// This is the header data, it contains all the info we know about the file or folder that we are about to archive
|
||||
$header = '';
|
||||
$header .= pack('a100', $name); // file name
|
||||
$header .= pack('a8', sprintf("%07o", $stat[2])); // file mode
|
||||
$header .= pack('a8', sprintf("%07o", $stat[4])); // owner id
|
||||
$header .= pack('a8', sprintf("%07o", $stat[5])); // group id
|
||||
$header .= pack('a12', sprintf("%011o", $stat[7])); // file size
|
||||
$header .= pack('a12', sprintf("%011o", $stat[9])); // last mod time
|
||||
|
||||
// Checksum
|
||||
$checksum = 0;
|
||||
for ($i = 0; $i < 148; $i++)
|
||||
{
|
||||
$checksum += ord($header[$i]);
|
||||
}
|
||||
|
||||
// We precompute the rest of the hash, this saves us time in the loop and allows us to insert our hash without resorting to string functions
|
||||
$checksum += 2415 + (($is_dir) ? 53 : 0);
|
||||
|
||||
$header .= pack('a8', sprintf("%07o", $checksum)); // checksum
|
||||
$header .= pack('a1', $typeflag); // link indicator
|
||||
$header .= pack('a100', ''); // name of linked file
|
||||
$header .= pack('a6', 'ustar'); // ustar indicator
|
||||
$header .= pack('a2', '00'); // ustar version
|
||||
$header .= pack('a32', 'Unknown'); // owner name
|
||||
$header .= pack('a32', 'Unknown'); // group name
|
||||
$header .= pack('a8', ''); // device major number
|
||||
$header .= pack('a8', ''); // device minor number
|
||||
$header .= pack('a155', ''); // filename prefix
|
||||
$header .= pack('a12', ''); // end
|
||||
|
||||
// This writes the entire file in one shot. Header, followed by data and then null padded to a multiple of 512
|
||||
$fzwrite($this->fp, $header . (($stat[7] !== 0 && !$is_dir) ? $data . str_repeat("\0", (($stat[7] + 511) &~ 511) - $stat[7]) : ''));
|
||||
unset($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open archive
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
$fzopen = ($this->isbz && function_exists('bzopen')) ? 'bzopen' : (($this->isgz && @extension_loaded('zlib')) ? 'gzopen' : 'fopen');
|
||||
$this->fp = @$fzopen($this->file, $this->mode . (($fzopen == 'bzopen') ? '' : 'b') . (($fzopen == 'gzopen') ? '9' : ''));
|
||||
|
||||
if (!$this->fp)
|
||||
{
|
||||
trigger_error('Unable to open file ' . $this->file . ' [' . $fzopen . ' - ' . $this->mode . 'b]');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download archive
|
||||
*/
|
||||
function download($filename, $download_name = false)
|
||||
{
|
||||
global $phpbb_root_path;
|
||||
|
||||
if ($download_name === false)
|
||||
{
|
||||
$download_name = $filename;
|
||||
}
|
||||
|
||||
switch ($this->type)
|
||||
{
|
||||
case '.tar':
|
||||
$mimetype = 'application/x-tar';
|
||||
break;
|
||||
|
||||
case '.tar.gz':
|
||||
$mimetype = 'application/x-gzip';
|
||||
break;
|
||||
|
||||
case '.tar.bz2':
|
||||
$mimetype = 'application/x-bzip2';
|
||||
break;
|
||||
|
||||
default:
|
||||
$mimetype = 'application/octet-stream';
|
||||
break;
|
||||
}
|
||||
|
||||
header('Cache-Control: private, no-cache');
|
||||
header("Content-Type: $mimetype; name=\"$download_name$this->type\"");
|
||||
header("Content-disposition: attachment; filename=$download_name$this->type");
|
||||
|
||||
$fp = @fopen("{$phpbb_root_path}store/$filename$this->type", 'rb');
|
||||
if ($fp)
|
||||
{
|
||||
while ($buffer = fread($fp, 1024))
|
||||
{
|
||||
echo $buffer;
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
1788
install/update/new/includes/functions_content.php
Normal file
1788
install/update/new/includes/functions_content.php
Normal file
File diff suppressed because it is too large
Load Diff
2500
install/update/new/includes/functions_convert.php
Normal file
2500
install/update/new/includes/functions_convert.php
Normal file
File diff suppressed because it is too large
Load Diff
1725
install/update/new/includes/functions_display.php
Normal file
1725
install/update/new/includes/functions_display.php
Normal file
File diff suppressed because it is too large
Load Diff
782
install/update/new/includes/functions_download.php
Normal file
782
install/update/new/includes/functions_download.php
Normal file
@@ -0,0 +1,782 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* A simplified function to deliver avatars
|
||||
* The argument needs to be checked before calling this function.
|
||||
*/
|
||||
function send_avatar_to_browser($file, $browser)
|
||||
{
|
||||
global $config, $phpbb_root_path;
|
||||
|
||||
$prefix = $config['avatar_salt'] . '_';
|
||||
$image_dir = $config['avatar_path'];
|
||||
|
||||
// Adjust image_dir path (no trailing slash)
|
||||
if (substr($image_dir, -1, 1) == '/' || substr($image_dir, -1, 1) == '\\')
|
||||
{
|
||||
$image_dir = substr($image_dir, 0, -1) . '/';
|
||||
}
|
||||
$image_dir = str_replace(array('../', '..\\', './', '.\\'), '', $image_dir);
|
||||
|
||||
if ($image_dir && ($image_dir[0] == '/' || $image_dir[0] == '\\'))
|
||||
{
|
||||
$image_dir = '';
|
||||
}
|
||||
$file_path = $phpbb_root_path . $image_dir . '/' . $prefix . $file;
|
||||
|
||||
if ((@file_exists($file_path) && @is_readable($file_path)) && !headers_sent())
|
||||
{
|
||||
header('Cache-Control: public');
|
||||
|
||||
$image_data = @getimagesize($file_path);
|
||||
header('Content-Type: ' . image_type_to_mime_type($image_data[2]));
|
||||
|
||||
if ((strpos(strtolower($browser), 'msie') !== false) && !phpbb_is_greater_ie_version($browser, 7))
|
||||
{
|
||||
header('Content-Disposition: attachment; ' . header_filename($file));
|
||||
|
||||
if (strpos(strtolower($browser), 'msie 6.0') !== false)
|
||||
{
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
|
||||
}
|
||||
else
|
||||
{
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
header('Content-Disposition: inline; ' . header_filename($file));
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');
|
||||
}
|
||||
|
||||
$size = @filesize($file_path);
|
||||
if ($size)
|
||||
{
|
||||
header("Content-Length: $size");
|
||||
}
|
||||
|
||||
if (@readfile($file_path) == false)
|
||||
{
|
||||
$fp = @fopen($file_path, 'rb');
|
||||
|
||||
if ($fp !== false)
|
||||
{
|
||||
while (!feof($fp))
|
||||
{
|
||||
echo fread($fp, 8192);
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
|
||||
flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an url into a simple html page. Used to display attachments in IE.
|
||||
* this is a workaround for now; might be moved to template system later
|
||||
* direct any complaints to 1 Microsoft Way, Redmond
|
||||
*/
|
||||
function wrap_img_in_html($src, $title)
|
||||
{
|
||||
echo '<!DOCTYPE html>';
|
||||
echo '<html>';
|
||||
echo '<head>';
|
||||
echo '<meta charset="utf-8">';
|
||||
echo '<meta http-equiv="X-UA-Compatible" content="IE=edge">';
|
||||
echo '<title>' . $title . '</title>';
|
||||
echo '</head>';
|
||||
echo '<body>';
|
||||
echo '<div>';
|
||||
echo '<img src="' . $src . '" alt="' . $title . '" />';
|
||||
echo '</div>';
|
||||
echo '</body>';
|
||||
echo '</html>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Send file to browser
|
||||
*/
|
||||
function send_file_to_browser($attachment, $upload_dir, $category)
|
||||
{
|
||||
global $user, $db, $phpbb_dispatcher, $phpbb_root_path, $request;
|
||||
|
||||
$filename = $phpbb_root_path . $upload_dir . '/' . $attachment['physical_filename'];
|
||||
|
||||
if (!@file_exists($filename))
|
||||
{
|
||||
send_status_line(404, 'Not Found');
|
||||
trigger_error('ERROR_NO_ATTACHMENT');
|
||||
}
|
||||
|
||||
// Correct the mime type - we force application/octetstream for all files, except images
|
||||
// Please do not change this, it is a security precaution
|
||||
if ($category != ATTACHMENT_CATEGORY_IMAGE || strpos($attachment['mimetype'], 'image') !== 0)
|
||||
{
|
||||
$attachment['mimetype'] = (strpos(strtolower($user->browser), 'msie') !== false || strpos(strtolower($user->browser), 'opera') !== false) ? 'application/octetstream' : 'application/octet-stream';
|
||||
}
|
||||
|
||||
if (@ob_get_length())
|
||||
{
|
||||
@ob_end_clean();
|
||||
}
|
||||
|
||||
// Now send the File Contents to the Browser
|
||||
$size = @filesize($filename);
|
||||
|
||||
/**
|
||||
* Event to alter attachment before it is sent to browser.
|
||||
*
|
||||
* @event core.send_file_to_browser_before
|
||||
* @var array attachment Attachment data
|
||||
* @var string upload_dir Relative path of upload directory
|
||||
* @var int category Attachment category
|
||||
* @var string filename Path to file, including filename
|
||||
* @var int size File size
|
||||
* @since 3.1.11-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'attachment',
|
||||
'upload_dir',
|
||||
'category',
|
||||
'filename',
|
||||
'size',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.send_file_to_browser_before', compact($vars)));
|
||||
|
||||
// To correctly display further errors we need to make sure we are using the correct headers for both (unsetting content-length may not work)
|
||||
|
||||
// Check if headers already sent or not able to get the file contents.
|
||||
if (headers_sent() || !@file_exists($filename) || !@is_readable($filename))
|
||||
{
|
||||
// PHP track_errors setting On?
|
||||
if (!empty($php_errormsg))
|
||||
{
|
||||
send_status_line(500, 'Internal Server Error');
|
||||
trigger_error($user->lang['UNABLE_TO_DELIVER_FILE'] . '<br />' . sprintf($user->lang['TRACKED_PHP_ERROR'], $php_errormsg));
|
||||
}
|
||||
|
||||
send_status_line(500, 'Internal Server Error');
|
||||
trigger_error('UNABLE_TO_DELIVER_FILE');
|
||||
}
|
||||
|
||||
// Make sure the database record for the filesize is correct
|
||||
if ($size > 0 && $size != $attachment['filesize'] && strpos($attachment['physical_filename'], 'thumb_') === false)
|
||||
{
|
||||
// Update database record
|
||||
$sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
|
||||
SET filesize = ' . (int) $size . '
|
||||
WHERE attach_id = ' . (int) $attachment['attach_id'];
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
|
||||
// Now the tricky part... let's dance
|
||||
header('Cache-Control: private');
|
||||
|
||||
// Send out the Headers. Do not set Content-Disposition to inline please, it is a security measure for users using the Internet Explorer.
|
||||
header('Content-Type: ' . $attachment['mimetype']);
|
||||
|
||||
if (phpbb_is_greater_ie_version($user->browser, 7))
|
||||
{
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
}
|
||||
|
||||
if (empty($user->browser) || ((strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($user->browser, 7)))
|
||||
{
|
||||
header('Content-Disposition: attachment; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
|
||||
if (empty($user->browser) || (strpos(strtolower($user->browser), 'msie 6.0') !== false))
|
||||
{
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
header('Content-Disposition: ' . ((strpos($attachment['mimetype'], 'image') === 0) ? 'inline' : 'attachment') . '; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
|
||||
if (phpbb_is_greater_ie_version($user->browser, 7) && (strpos($attachment['mimetype'], 'image') !== 0))
|
||||
{
|
||||
header('X-Download-Options: noopen');
|
||||
}
|
||||
}
|
||||
|
||||
// Close the db connection before sending the file etc.
|
||||
file_gc(false);
|
||||
|
||||
if (!set_modified_headers($attachment['filetime'], $user->browser))
|
||||
{
|
||||
// We make sure those have to be enabled manually by defining a constant
|
||||
// because of the potential disclosure of full attachment path
|
||||
// in case support for features is absent in the webserver software.
|
||||
if (defined('PHPBB_ENABLE_X_ACCEL_REDIRECT') && PHPBB_ENABLE_X_ACCEL_REDIRECT)
|
||||
{
|
||||
// X-Accel-Redirect - http://wiki.nginx.org/XSendfile
|
||||
header('X-Accel-Redirect: ' . $user->page['root_script_path'] . $upload_dir . '/' . $attachment['physical_filename']);
|
||||
exit;
|
||||
}
|
||||
else if (defined('PHPBB_ENABLE_X_SENDFILE') && PHPBB_ENABLE_X_SENDFILE && !phpbb_http_byte_range($size))
|
||||
{
|
||||
// X-Sendfile - http://blog.lighttpd.net/articles/2006/07/02/x-sendfile
|
||||
// Lighttpd's X-Sendfile does not support range requests as of 1.4.26
|
||||
// and always requires an absolute path.
|
||||
header('X-Sendfile: ' . dirname(__FILE__) . "/../$upload_dir/{$attachment['physical_filename']}");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($size)
|
||||
{
|
||||
header("Content-Length: $size");
|
||||
}
|
||||
|
||||
// Try to deliver in chunks
|
||||
@set_time_limit(0);
|
||||
|
||||
$fp = @fopen($filename, 'rb');
|
||||
|
||||
if ($fp !== false)
|
||||
{
|
||||
// Deliver file partially if requested
|
||||
if ($range = phpbb_http_byte_range($size))
|
||||
{
|
||||
fseek($fp, $range['byte_pos_start']);
|
||||
|
||||
send_status_line(206, 'Partial Content');
|
||||
header('Content-Range: bytes ' . $range['byte_pos_start'] . '-' . $range['byte_pos_end'] . '/' . $range['bytes_total']);
|
||||
header('Content-Length: ' . $range['bytes_requested']);
|
||||
|
||||
// First read chunks
|
||||
while (!feof($fp) && ftell($fp) < $range['byte_pos_end'] - 8192)
|
||||
{
|
||||
echo fread($fp, 8192);
|
||||
}
|
||||
// Then, read the remainder
|
||||
echo fread($fp, $range['bytes_requested'] % 8192);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!feof($fp))
|
||||
{
|
||||
echo fread($fp, 8192);
|
||||
}
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
@readfile($filename);
|
||||
}
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a browser friendly UTF-8 encoded filename
|
||||
*/
|
||||
function header_filename($file)
|
||||
{
|
||||
global $request;
|
||||
|
||||
$user_agent = $request->header('User-Agent');
|
||||
|
||||
// There be dragons here.
|
||||
// Not many follows the RFC...
|
||||
if (strpos($user_agent, 'MSIE') !== false || strpos($user_agent, 'Konqueror') !== false)
|
||||
{
|
||||
return "filename=" . rawurlencode($file);
|
||||
}
|
||||
|
||||
// follow the RFC for extended filename for the rest
|
||||
return "filename*=UTF-8''" . rawurlencode($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if downloading item is allowed
|
||||
*/
|
||||
function download_allowed()
|
||||
{
|
||||
global $config, $user, $db, $request;
|
||||
|
||||
if (!$config['secure_downloads'])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
$url = htmlspecialchars_decode($request->header('Referer'));
|
||||
|
||||
if (!$url)
|
||||
{
|
||||
return ($config['secure_allow_empty_referer']) ? true : false;
|
||||
}
|
||||
|
||||
// Split URL into domain and script part
|
||||
$url = @parse_url($url);
|
||||
|
||||
if ($url === false)
|
||||
{
|
||||
return ($config['secure_allow_empty_referer']) ? true : false;
|
||||
}
|
||||
|
||||
$hostname = $url['host'];
|
||||
unset($url);
|
||||
|
||||
$allowed = ($config['secure_allow_deny']) ? false : true;
|
||||
$iplist = array();
|
||||
|
||||
if (($ip_ary = @gethostbynamel($hostname)) !== false)
|
||||
{
|
||||
foreach ($ip_ary as $ip)
|
||||
{
|
||||
if ($ip)
|
||||
{
|
||||
$iplist[] = $ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for own server...
|
||||
$server_name = $user->host;
|
||||
|
||||
// Forcing server vars is the only way to specify/override the protocol
|
||||
if ($config['force_server_vars'] || !$server_name)
|
||||
{
|
||||
$server_name = $config['server_name'];
|
||||
}
|
||||
|
||||
if (preg_match('#^.*?' . preg_quote($server_name, '#') . '.*?$#i', $hostname))
|
||||
{
|
||||
$allowed = true;
|
||||
}
|
||||
|
||||
// Get IP's and Hostnames
|
||||
if (!$allowed)
|
||||
{
|
||||
$sql = 'SELECT site_ip, site_hostname, ip_exclude
|
||||
FROM ' . SITELIST_TABLE;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$site_ip = trim($row['site_ip']);
|
||||
$site_hostname = trim($row['site_hostname']);
|
||||
|
||||
if ($site_ip)
|
||||
{
|
||||
foreach ($iplist as $ip)
|
||||
{
|
||||
if (preg_match('#^' . str_replace('\*', '.*?', preg_quote($site_ip, '#')) . '$#i', $ip))
|
||||
{
|
||||
if ($row['ip_exclude'])
|
||||
{
|
||||
$allowed = ($config['secure_allow_deny']) ? false : true;
|
||||
break 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
$allowed = ($config['secure_allow_deny']) ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($site_hostname)
|
||||
{
|
||||
if (preg_match('#^' . str_replace('\*', '.*?', preg_quote($site_hostname, '#')) . '$#i', $hostname))
|
||||
{
|
||||
if ($row['ip_exclude'])
|
||||
{
|
||||
$allowed = ($config['secure_allow_deny']) ? false : true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
$allowed = ($config['secure_allow_deny']) ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
return $allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the browser has the file already and set the appropriate headers-
|
||||
* @returns false if a resend is in order.
|
||||
*/
|
||||
function set_modified_headers($stamp, $browser)
|
||||
{
|
||||
global $request;
|
||||
|
||||
// let's see if we have to send the file at all
|
||||
$last_load = $request->header('If-Modified-Since') ? strtotime(trim($request->header('If-Modified-Since'))) : false;
|
||||
|
||||
if (strpos(strtolower($browser), 'msie 6.0') === false && !phpbb_is_greater_ie_version($browser, 7))
|
||||
{
|
||||
if ($last_load !== false && $last_load >= $stamp)
|
||||
{
|
||||
send_status_line(304, 'Not Modified');
|
||||
// seems that we need those too ... browsers
|
||||
header('Cache-Control: private');
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $stamp) . ' GMT');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Garbage Collection
|
||||
*
|
||||
* @param bool $exit Whether to die or not.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
function file_gc($exit = true)
|
||||
{
|
||||
global $cache, $db;
|
||||
|
||||
if (!empty($cache))
|
||||
{
|
||||
$cache->unload();
|
||||
}
|
||||
|
||||
$db->sql_close();
|
||||
|
||||
if ($exit)
|
||||
{
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP range support (RFC 2616 Section 14.35)
|
||||
*
|
||||
* Allows browsers to request partial file content
|
||||
* in case a download has been interrupted.
|
||||
*
|
||||
* @param int $filesize the size of the file in bytes we are about to deliver
|
||||
*
|
||||
* @return mixed false if the whole file has to be delivered
|
||||
* associative array on success
|
||||
*/
|
||||
function phpbb_http_byte_range($filesize)
|
||||
{
|
||||
// Only call find_range_request() once.
|
||||
static $request_array;
|
||||
|
||||
if (!$filesize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($request_array))
|
||||
{
|
||||
$request_array = phpbb_find_range_request();
|
||||
}
|
||||
|
||||
return (empty($request_array)) ? false : phpbb_parse_range_request($request_array, $filesize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for HTTP range request in request headers.
|
||||
*
|
||||
* @return mixed false if no request found
|
||||
* array of strings containing the requested ranges otherwise
|
||||
* e.g. array(0 => '0-0', 1 => '123-125')
|
||||
*/
|
||||
function phpbb_find_range_request()
|
||||
{
|
||||
global $request;
|
||||
|
||||
$value = $request->header('Range');
|
||||
|
||||
// Make sure range request starts with "bytes="
|
||||
if (strpos($value, 'bytes=') === 0)
|
||||
{
|
||||
// Strip leading 'bytes='
|
||||
// Multiple ranges can be separated by a comma
|
||||
return explode(',', substr($value, 6));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyses a range request array.
|
||||
*
|
||||
* A range request can contain multiple ranges,
|
||||
* we however only handle the first request and
|
||||
* only support requests from a given byte to the end of the file.
|
||||
*
|
||||
* @param array $request_array array of strings containing the requested ranges
|
||||
* @param int $filesize the full size of the file in bytes that has been requested
|
||||
*
|
||||
* @return mixed false if the whole file has to be delivered
|
||||
* associative array on success
|
||||
* byte_pos_start the first byte position, can be passed to fseek()
|
||||
* byte_pos_end the last byte position
|
||||
* bytes_requested the number of bytes requested
|
||||
* bytes_total the full size of the file
|
||||
*/
|
||||
function phpbb_parse_range_request($request_array, $filesize)
|
||||
{
|
||||
$first_byte_pos = -1;
|
||||
$last_byte_pos = -1;
|
||||
|
||||
// Go through all ranges
|
||||
foreach ($request_array as $range_string)
|
||||
{
|
||||
$range = explode('-', trim($range_string));
|
||||
|
||||
// "-" is invalid, "0-0" however is valid and means the very first byte.
|
||||
if (count($range) != 2 || $range[0] === '' && $range[1] === '')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Substitute defaults
|
||||
if ($range[0] === '')
|
||||
{
|
||||
$range[0] = 0;
|
||||
}
|
||||
|
||||
if ($range[1] === '')
|
||||
{
|
||||
$range[1] = $filesize - 1;
|
||||
}
|
||||
|
||||
if ($last_byte_pos >= 0 && $last_byte_pos + 1 != $range[0])
|
||||
{
|
||||
// We only support contiguous ranges, no multipart stuff :(
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($range[1] && $range[1] < $range[0])
|
||||
{
|
||||
// The requested range contains 0 bytes.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Return bytes from $range[0] to $range[1]
|
||||
if ($first_byte_pos < 0)
|
||||
{
|
||||
$first_byte_pos = (int) $range[0];
|
||||
}
|
||||
|
||||
$last_byte_pos = (int) $range[1];
|
||||
|
||||
if ($first_byte_pos >= $filesize)
|
||||
{
|
||||
// Requested range not satisfiable
|
||||
return false;
|
||||
}
|
||||
|
||||
// Adjust last-byte-pos if it is absent or greater than the content.
|
||||
if ($range[1] === '' || $last_byte_pos >= $filesize)
|
||||
{
|
||||
$last_byte_pos = $filesize - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($first_byte_pos < 0 || $last_byte_pos < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return array(
|
||||
'byte_pos_start' => $first_byte_pos,
|
||||
'byte_pos_end' => $last_byte_pos,
|
||||
'bytes_requested' => $last_byte_pos - $first_byte_pos + 1,
|
||||
'bytes_total' => $filesize,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the download count of all provided attachments
|
||||
*
|
||||
* @param \phpbb\db\driver\driver_interface $db The database object
|
||||
* @param array|int $ids The attach_id of each attachment
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
function phpbb_increment_downloads($db, $ids)
|
||||
{
|
||||
if (!is_array($ids))
|
||||
{
|
||||
$ids = array($ids);
|
||||
}
|
||||
|
||||
$sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
|
||||
SET download_count = download_count + 1
|
||||
WHERE ' . $db->sql_in_set('attach_id', $ids);
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles authentication when downloading attachments from a post or topic
|
||||
*
|
||||
* @param \phpbb\db\driver\driver_interface $db The database object
|
||||
* @param \phpbb\auth\auth $auth The authentication object
|
||||
* @param int $topic_id The id of the topic that we are downloading from
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
function phpbb_download_handle_forum_auth($db, $auth, $topic_id)
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
$sql_array = array(
|
||||
'SELECT' => 't.topic_visibility, t.forum_id, f.forum_name, f.forum_password, f.parent_id',
|
||||
'FROM' => array(
|
||||
TOPICS_TABLE => 't',
|
||||
FORUMS_TABLE => 'f',
|
||||
),
|
||||
'WHERE' => 't.topic_id = ' . (int) $topic_id . '
|
||||
AND t.forum_id = f.forum_id',
|
||||
);
|
||||
|
||||
$sql = $db->sql_build_query('SELECT', $sql_array);
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$phpbb_content_visibility = $phpbb_container->get('content.visibility');
|
||||
|
||||
if ($row && !$phpbb_content_visibility->is_visible('topic', $row['forum_id'], $row))
|
||||
{
|
||||
send_status_line(404, 'Not Found');
|
||||
trigger_error('ERROR_NO_ATTACHMENT');
|
||||
}
|
||||
else if ($row && $auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id']))
|
||||
{
|
||||
if ($row['forum_password'])
|
||||
{
|
||||
// Do something else ... ?
|
||||
login_forum_box($row);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error('SORRY_AUTH_VIEW_ATTACH');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles authentication when downloading attachments from PMs
|
||||
*
|
||||
* @param \phpbb\db\driver\driver_interface $db The database object
|
||||
* @param \phpbb\auth\auth $auth The authentication object
|
||||
* @param int $user_id The user id
|
||||
* @param int $msg_id The id of the PM that we are downloading from
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
function phpbb_download_handle_pm_auth($db, $auth, $user_id, $msg_id)
|
||||
{
|
||||
global $phpbb_dispatcher;
|
||||
|
||||
if (!$auth->acl_get('u_pm_download'))
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error('SORRY_AUTH_VIEW_ATTACH');
|
||||
}
|
||||
|
||||
$allowed = phpbb_download_check_pm_auth($db, $user_id, $msg_id);
|
||||
|
||||
/**
|
||||
* Event to modify PM attachments download auth
|
||||
*
|
||||
* @event core.modify_pm_attach_download_auth
|
||||
* @var bool allowed Whether the user is allowed to download from that PM or not
|
||||
* @var int msg_id The id of the PM to download from
|
||||
* @var int user_id The user id for auth check
|
||||
* @since 3.1.11-RC1
|
||||
*/
|
||||
$vars = array('allowed', 'msg_id', 'user_id');
|
||||
extract($phpbb_dispatcher->trigger_event('core.modify_pm_attach_download_auth', compact($vars)));
|
||||
|
||||
if (!$allowed)
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error('ERROR_NO_ATTACHMENT');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user can download from a particular PM
|
||||
*
|
||||
* @param \phpbb\db\driver\driver_interface $db The database object
|
||||
* @param int $user_id The user id
|
||||
* @param int $msg_id The id of the PM that we are downloading from
|
||||
*
|
||||
* @return bool Whether the user is allowed to download from that PM or not
|
||||
*/
|
||||
function phpbb_download_check_pm_auth($db, $user_id, $msg_id)
|
||||
{
|
||||
// Check if the attachment is within the users scope...
|
||||
$sql = 'SELECT msg_id
|
||||
FROM ' . PRIVMSGS_TO_TABLE . '
|
||||
WHERE msg_id = ' . (int) $msg_id . '
|
||||
AND (
|
||||
user_id = ' . (int) $user_id . '
|
||||
OR author_id = ' . (int) $user_id . '
|
||||
)';
|
||||
$result = $db->sql_query_limit($sql, 1);
|
||||
$allowed = (bool) $db->sql_fetchfield('msg_id');
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
return $allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the browser is internet explorer version 7+
|
||||
*
|
||||
* @param string $user_agent User agent HTTP header
|
||||
* @param int $version IE version to check against
|
||||
*
|
||||
* @return bool true if internet explorer version is greater than $version
|
||||
*/
|
||||
function phpbb_is_greater_ie_version($user_agent, $version)
|
||||
{
|
||||
if (preg_match('/msie (\d+)/', strtolower($user_agent), $matches))
|
||||
{
|
||||
$ie_version = (int) $matches[1];
|
||||
return ($ie_version > $version);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
1935
install/update/new/includes/functions_messenger.php
Normal file
1935
install/update/new/includes/functions_messenger.php
Normal file
File diff suppressed because it is too large
Load Diff
1153
install/update/new/includes/functions_module.php
Normal file
1153
install/update/new/includes/functions_module.php
Normal file
File diff suppressed because it is too large
Load Diff
2804
install/update/new/includes/functions_posting.php
Normal file
2804
install/update/new/includes/functions_posting.php
Normal file
File diff suppressed because it is too large
Load Diff
2303
install/update/new/includes/functions_privmsgs.php
Normal file
2303
install/update/new/includes/functions_privmsgs.php
Normal file
File diff suppressed because it is too large
Load Diff
899
install/update/new/includes/functions_transfer.php
Normal file
899
install/update/new/includes/functions_transfer.php
Normal file
@@ -0,0 +1,899 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer class, wrapper for ftp/sftp/ssh
|
||||
*/
|
||||
class transfer
|
||||
{
|
||||
var $connection;
|
||||
var $host;
|
||||
var $port;
|
||||
var $username;
|
||||
var $password;
|
||||
var $timeout;
|
||||
var $root_path;
|
||||
var $tmp_path;
|
||||
var $file_perms;
|
||||
var $dir_perms;
|
||||
|
||||
/**
|
||||
* Constructor - init some basic values
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
global $phpbb_root_path;
|
||||
|
||||
$this->file_perms = 0644;
|
||||
$this->dir_perms = 0777;
|
||||
|
||||
// We use the store directory as temporary path to circumvent open basedir restrictions
|
||||
$this->tmp_path = $phpbb_root_path . 'store/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Write file to location
|
||||
*/
|
||||
function write_file($destination_file = '', $contents = '')
|
||||
{
|
||||
global $phpbb_root_path;
|
||||
|
||||
$destination_file = $this->root_path . str_replace($phpbb_root_path, '', $destination_file);
|
||||
|
||||
// need to create a temp file and then move that temp file.
|
||||
// ftp functions can only move files around and can't create.
|
||||
// This means that the users will need to have access to write
|
||||
// temporary files or have write access on a folder within phpBB
|
||||
// like the cache folder. If the user can't do either, then
|
||||
// he/she needs to use the fsock ftp method
|
||||
$temp_name = tempnam($this->tmp_path, 'transfer_');
|
||||
@unlink($temp_name);
|
||||
|
||||
$fp = @fopen($temp_name, 'w');
|
||||
|
||||
if (!$fp)
|
||||
{
|
||||
trigger_error('Unable to create temporary file ' . $temp_name, E_USER_ERROR);
|
||||
}
|
||||
|
||||
@fwrite($fp, $contents);
|
||||
@fclose($fp);
|
||||
|
||||
$result = $this->overwrite_file($temp_name, $destination_file);
|
||||
|
||||
// remove temporary file now
|
||||
@unlink($temp_name);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moving file into location. If the destination file already exists it gets overwritten
|
||||
*/
|
||||
function overwrite_file($source_file, $destination_file)
|
||||
{
|
||||
/**
|
||||
* @todo generally think about overwriting files in another way, by creating a temporary file and then renaming it
|
||||
* @todo check for the destination file existance too
|
||||
*/
|
||||
$this->_delete($destination_file);
|
||||
$result = $this->_put($source_file, $destination_file);
|
||||
$this->_chmod($destination_file, $this->file_perms);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create directory structure
|
||||
*/
|
||||
function make_dir($dir)
|
||||
{
|
||||
global $phpbb_root_path;
|
||||
|
||||
$dir = str_replace($phpbb_root_path, '', $dir);
|
||||
$dir = explode('/', $dir);
|
||||
$dirs = '';
|
||||
|
||||
for ($i = 0, $total = count($dir); $i < $total; $i++)
|
||||
{
|
||||
$result = true;
|
||||
|
||||
if (strpos($dir[$i], '.') === 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$cur_dir = $dir[$i] . '/';
|
||||
|
||||
if (!file_exists($phpbb_root_path . $dirs . $cur_dir))
|
||||
{
|
||||
// create the directory
|
||||
$result = $this->_mkdir($dir[$i]);
|
||||
$this->_chmod($dir[$i], $this->dir_perms);
|
||||
}
|
||||
|
||||
$this->_chdir($this->root_path . $dirs . $dir[$i]);
|
||||
$dirs .= $cur_dir;
|
||||
}
|
||||
|
||||
$this->_chdir($this->root_path);
|
||||
|
||||
/**
|
||||
* @todo stack result into array to make sure every path creation has been taken care of
|
||||
*/
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy file from source location to destination location
|
||||
*/
|
||||
function copy_file($from_loc, $to_loc)
|
||||
{
|
||||
global $phpbb_root_path;
|
||||
|
||||
$from_loc = ((strpos($from_loc, $phpbb_root_path) !== 0) ? $phpbb_root_path : '') . $from_loc;
|
||||
$to_loc = $this->root_path . str_replace($phpbb_root_path, '', $to_loc);
|
||||
|
||||
if (!file_exists($from_loc))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $this->overwrite_file($from_loc, $to_loc);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove file
|
||||
*/
|
||||
function delete_file($file)
|
||||
{
|
||||
global $phpbb_root_path;
|
||||
|
||||
$file = $this->root_path . str_replace($phpbb_root_path, '', $file);
|
||||
|
||||
return $this->_delete($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove directory
|
||||
* @todo remove child directories?
|
||||
*/
|
||||
function remove_dir($dir)
|
||||
{
|
||||
global $phpbb_root_path;
|
||||
|
||||
$dir = $this->root_path . str_replace($phpbb_root_path, '', $dir);
|
||||
|
||||
return $this->_rmdir($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a file or folder
|
||||
*/
|
||||
function rename($old_handle, $new_handle)
|
||||
{
|
||||
global $phpbb_root_path;
|
||||
|
||||
$old_handle = $this->root_path . str_replace($phpbb_root_path, '', $old_handle);
|
||||
|
||||
return $this->_rename($old_handle, $new_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a specified file exist...
|
||||
*/
|
||||
function file_exists($directory, $filename)
|
||||
{
|
||||
global $phpbb_root_path;
|
||||
|
||||
$directory = $this->root_path . str_replace($phpbb_root_path, '', $directory);
|
||||
|
||||
$this->_chdir($directory);
|
||||
$result = $this->_ls();
|
||||
|
||||
if ($result !== false && is_array($result))
|
||||
{
|
||||
return (in_array($filename, $result)) ? true : false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open session
|
||||
*/
|
||||
function open_session()
|
||||
{
|
||||
return $this->_init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close current session
|
||||
*/
|
||||
function close_session()
|
||||
{
|
||||
return $this->_close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine methods able to be used
|
||||
*/
|
||||
static public function methods()
|
||||
{
|
||||
$methods = array();
|
||||
$disabled_functions = explode(',', @ini_get('disable_functions'));
|
||||
|
||||
if (@extension_loaded('ftp'))
|
||||
{
|
||||
$methods[] = 'ftp';
|
||||
}
|
||||
|
||||
if (!in_array('fsockopen', $disabled_functions))
|
||||
{
|
||||
$methods[] = 'ftp_fsock';
|
||||
}
|
||||
|
||||
return $methods;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FTP transfer class
|
||||
*/
|
||||
class ftp extends transfer
|
||||
{
|
||||
/**
|
||||
* Standard parameters for FTP session
|
||||
*/
|
||||
function __construct($host, $username, $password, $root_path, $port = 21, $timeout = 10)
|
||||
{
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->timeout = $timeout;
|
||||
|
||||
// Make sure $this->root_path is layed out the same way as the $user->page['root_script_path'] value (/ at the end)
|
||||
$this->root_path = str_replace('\\', '/', $this->root_path);
|
||||
|
||||
if (!empty($root_path))
|
||||
{
|
||||
$this->root_path = (($root_path[0] != '/' ) ? '/' : '') . $root_path . ((substr($root_path, -1, 1) == '/') ? '' : '/');
|
||||
}
|
||||
|
||||
// Init some needed values
|
||||
$this->transfer();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests data
|
||||
*/
|
||||
static public function data()
|
||||
{
|
||||
global $user;
|
||||
|
||||
return array(
|
||||
'host' => 'localhost',
|
||||
'username' => 'anonymous',
|
||||
'password' => '',
|
||||
'root_path' => $user->page['root_script_path'],
|
||||
'port' => 21,
|
||||
'timeout' => 10
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init FTP Session
|
||||
* @access private
|
||||
*/
|
||||
function _init()
|
||||
{
|
||||
// connect to the server
|
||||
$this->connection = @ftp_connect($this->host, $this->port, $this->timeout);
|
||||
|
||||
if (!$this->connection)
|
||||
{
|
||||
return 'ERR_CONNECTING_SERVER';
|
||||
}
|
||||
|
||||
// login to the server
|
||||
if (!@ftp_login($this->connection, $this->username, $this->password))
|
||||
{
|
||||
return 'ERR_UNABLE_TO_LOGIN';
|
||||
}
|
||||
|
||||
// attempt to turn pasv mode on
|
||||
@ftp_pasv($this->connection, true);
|
||||
|
||||
// change to the root directory
|
||||
if (!$this->_chdir($this->root_path))
|
||||
{
|
||||
return 'ERR_CHANGING_DIRECTORY';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Directory (MKDIR)
|
||||
* @access private
|
||||
*/
|
||||
function _mkdir($dir)
|
||||
{
|
||||
return @ftp_mkdir($this->connection, $dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove directory (RMDIR)
|
||||
* @access private
|
||||
*/
|
||||
function _rmdir($dir)
|
||||
{
|
||||
return @ftp_rmdir($this->connection, $dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename file
|
||||
* @access private
|
||||
*/
|
||||
function _rename($old_handle, $new_handle)
|
||||
{
|
||||
return @ftp_rename($this->connection, $old_handle, $new_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change current working directory (CHDIR)
|
||||
* @access private
|
||||
*/
|
||||
function _chdir($dir = '')
|
||||
{
|
||||
if ($dir && $dir !== '/')
|
||||
{
|
||||
if (substr($dir, -1, 1) == '/')
|
||||
{
|
||||
$dir = substr($dir, 0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return @ftp_chdir($this->connection, $dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* change file permissions (CHMOD)
|
||||
* @access private
|
||||
*/
|
||||
function _chmod($file, $perms)
|
||||
{
|
||||
if (function_exists('ftp_chmod'))
|
||||
{
|
||||
$err = @ftp_chmod($this->connection, $perms, $file);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unfortunatly CHMOD is not expecting an octal value...
|
||||
// We need to transform the integer (which was an octal) to an octal representation (to get the int) and then pass as is. ;)
|
||||
$chmod_cmd = 'CHMOD ' . base_convert($perms, 10, 8) . ' ' . $file;
|
||||
$err = $this->_site($chmod_cmd);
|
||||
}
|
||||
|
||||
return $err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload file to location (PUT)
|
||||
* @access private
|
||||
*/
|
||||
function _put($from_file, $to_file)
|
||||
{
|
||||
// We only use the BINARY file mode to cicumvent rewrite actions from ftp server (mostly linefeeds being replaced)
|
||||
$mode = FTP_BINARY;
|
||||
|
||||
$to_dir = dirname($to_file);
|
||||
$to_file = basename($to_file);
|
||||
$this->_chdir($to_dir);
|
||||
|
||||
$result = @ftp_put($this->connection, $to_file, $from_file, $mode);
|
||||
$this->_chdir($this->root_path);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete file (DELETE)
|
||||
* @access private
|
||||
*/
|
||||
function _delete($file)
|
||||
{
|
||||
return @ftp_delete($this->connection, $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close ftp session (CLOSE)
|
||||
* @access private
|
||||
*/
|
||||
function _close()
|
||||
{
|
||||
if (!$this->connection)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return @ftp_quit($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current working directory (CWD)
|
||||
* At the moment not used by parent class
|
||||
* @access private
|
||||
*/
|
||||
function _cwd()
|
||||
{
|
||||
return @ftp_pwd($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of files in a given directory (LS)
|
||||
* @access private
|
||||
*/
|
||||
function _ls($dir = './')
|
||||
{
|
||||
$list = @ftp_nlist($this->connection, $dir);
|
||||
|
||||
// See bug #46295 - Some FTP daemons don't like './'
|
||||
if ($dir === './')
|
||||
{
|
||||
// Let's try some alternatives
|
||||
$list = (empty($list)) ? @ftp_nlist($this->connection, '.') : $list;
|
||||
$list = (empty($list)) ? @ftp_nlist($this->connection, '') : $list;
|
||||
}
|
||||
|
||||
// Return on error
|
||||
if ($list === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove path if prepended
|
||||
foreach ($list as $key => $item)
|
||||
{
|
||||
// Use same separator for item and dir
|
||||
$item = str_replace('\\', '/', $item);
|
||||
$dir = str_replace('\\', '/', $dir);
|
||||
|
||||
if (!empty($dir) && strpos($item, $dir) === 0)
|
||||
{
|
||||
$item = substr($item, strlen($dir));
|
||||
}
|
||||
|
||||
$list[$key] = $item;
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* FTP SITE command (ftp-only function)
|
||||
* @access private
|
||||
*/
|
||||
function _site($command)
|
||||
{
|
||||
return @ftp_site($this->connection, $command);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FTP fsock transfer class
|
||||
*/
|
||||
class ftp_fsock extends transfer
|
||||
{
|
||||
var $data_connection;
|
||||
|
||||
/**
|
||||
* Standard parameters for FTP session
|
||||
*/
|
||||
function __construct($host, $username, $password, $root_path, $port = 21, $timeout = 10)
|
||||
{
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->timeout = $timeout;
|
||||
|
||||
// Make sure $this->root_path is layed out the same way as the $user->page['root_script_path'] value (/ at the end)
|
||||
$this->root_path = str_replace('\\', '/', $this->root_path);
|
||||
|
||||
if (!empty($root_path))
|
||||
{
|
||||
$this->root_path = (($root_path[0] != '/' ) ? '/' : '') . $root_path . ((substr($root_path, -1, 1) == '/') ? '' : '/');
|
||||
}
|
||||
|
||||
// Init some needed values
|
||||
parent::__construct();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests data
|
||||
*/
|
||||
static public function data()
|
||||
{
|
||||
global $user;
|
||||
|
||||
return array(
|
||||
'host' => 'localhost',
|
||||
'username' => 'anonymous',
|
||||
'password' => '',
|
||||
'root_path' => $user->page['root_script_path'],
|
||||
'port' => 21,
|
||||
'timeout' => 10
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init FTP Session
|
||||
* @access private
|
||||
*/
|
||||
function _init()
|
||||
{
|
||||
$errno = 0;
|
||||
$errstr = '';
|
||||
|
||||
// connect to the server
|
||||
$this->connection = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);
|
||||
|
||||
if (!$this->connection || !$this->_check_command())
|
||||
{
|
||||
return 'ERR_CONNECTING_SERVER';
|
||||
}
|
||||
|
||||
@stream_set_timeout($this->connection, $this->timeout);
|
||||
|
||||
// login
|
||||
if (!$this->_send_command('USER', $this->username))
|
||||
{
|
||||
return 'ERR_UNABLE_TO_LOGIN';
|
||||
}
|
||||
|
||||
if (!$this->_send_command('PASS', $this->password))
|
||||
{
|
||||
return 'ERR_UNABLE_TO_LOGIN';
|
||||
}
|
||||
|
||||
// change to the root directory
|
||||
if (!$this->_chdir($this->root_path))
|
||||
{
|
||||
return 'ERR_CHANGING_DIRECTORY';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Directory (MKDIR)
|
||||
* @access private
|
||||
*/
|
||||
function _mkdir($dir)
|
||||
{
|
||||
return $this->_send_command('MKD', $dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove directory (RMDIR)
|
||||
* @access private
|
||||
*/
|
||||
function _rmdir($dir)
|
||||
{
|
||||
return $this->_send_command('RMD', $dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename File
|
||||
* @access private
|
||||
*/
|
||||
function _rename($old_handle, $new_handle)
|
||||
{
|
||||
$this->_send_command('RNFR', $old_handle);
|
||||
return $this->_send_command('RNTO', $new_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change current working directory (CHDIR)
|
||||
* @access private
|
||||
*/
|
||||
function _chdir($dir = '')
|
||||
{
|
||||
if ($dir && $dir !== '/')
|
||||
{
|
||||
if (substr($dir, -1, 1) == '/')
|
||||
{
|
||||
$dir = substr($dir, 0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_send_command('CWD', $dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* change file permissions (CHMOD)
|
||||
* @access private
|
||||
*/
|
||||
function _chmod($file, $perms)
|
||||
{
|
||||
// Unfortunatly CHMOD is not expecting an octal value...
|
||||
// We need to transform the integer (which was an octal) to an octal representation (to get the int) and then pass as is. ;)
|
||||
return $this->_send_command('SITE CHMOD', base_convert($perms, 10, 8) . ' ' . $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload file to location (PUT)
|
||||
* @access private
|
||||
*/
|
||||
function _put($from_file, $to_file)
|
||||
{
|
||||
// We only use the BINARY file mode to cicumvent rewrite actions from ftp server (mostly linefeeds being replaced)
|
||||
// 'I' == BINARY
|
||||
// 'A' == ASCII
|
||||
if (!$this->_send_command('TYPE', 'I'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// open the connection to send file over
|
||||
if (!$this->_open_data_connection())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_send_command('STOR', $to_file, false);
|
||||
|
||||
// send the file
|
||||
$fp = @fopen($from_file, 'rb');
|
||||
while (!@feof($fp))
|
||||
{
|
||||
@fwrite($this->data_connection, @fread($fp, 4096));
|
||||
}
|
||||
@fclose($fp);
|
||||
|
||||
// close connection
|
||||
$this->_close_data_connection();
|
||||
|
||||
return $this->_check_command();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete file (DELETE)
|
||||
* @access private
|
||||
*/
|
||||
function _delete($file)
|
||||
{
|
||||
return $this->_send_command('DELE', $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close ftp session (CLOSE)
|
||||
* @access private
|
||||
*/
|
||||
function _close()
|
||||
{
|
||||
if (!$this->connection)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->_send_command('QUIT');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current working directory (CWD)
|
||||
* At the moment not used by parent class
|
||||
* @access private
|
||||
*/
|
||||
function _cwd()
|
||||
{
|
||||
$this->_send_command('PWD', '', false);
|
||||
return preg_replace('#^[0-9]{3} "(.+)" .+\r\n#', '\\1', $this->_check_command(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of files in a given directory (LS)
|
||||
* @access private
|
||||
*/
|
||||
function _ls($dir = './')
|
||||
{
|
||||
if (!$this->_open_data_connection())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_send_command('NLST', $dir);
|
||||
|
||||
$list = array();
|
||||
while (!@feof($this->data_connection))
|
||||
{
|
||||
$filename = preg_replace('#[\r\n]#', '', @fgets($this->data_connection, 512));
|
||||
|
||||
if ($filename !== '')
|
||||
{
|
||||
$list[] = $filename;
|
||||
}
|
||||
}
|
||||
$this->_close_data_connection();
|
||||
|
||||
// Clear buffer
|
||||
$this->_check_command();
|
||||
|
||||
// See bug #46295 - Some FTP daemons don't like './'
|
||||
if ($dir === './' && empty($list))
|
||||
{
|
||||
// Let's try some alternatives
|
||||
$list = $this->_ls('.');
|
||||
|
||||
if (empty($list))
|
||||
{
|
||||
$list = $this->_ls('');
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
// Remove path if prepended
|
||||
foreach ($list as $key => $item)
|
||||
{
|
||||
// Use same separator for item and dir
|
||||
$item = str_replace('\\', '/', $item);
|
||||
$dir = str_replace('\\', '/', $dir);
|
||||
|
||||
if (!empty($dir) && strpos($item, $dir) === 0)
|
||||
{
|
||||
$item = substr($item, strlen($dir));
|
||||
}
|
||||
|
||||
$list[$key] = $item;
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a command to server (FTP fsock only function)
|
||||
* @access private
|
||||
*/
|
||||
function _send_command($command, $args = '', $check = true)
|
||||
{
|
||||
if (!empty($args))
|
||||
{
|
||||
$command = "$command $args";
|
||||
}
|
||||
|
||||
fwrite($this->connection, $command . "\r\n");
|
||||
|
||||
if ($check === true && !$this->_check_command())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a connection to send data (FTP fosck only function)
|
||||
* @access private
|
||||
*/
|
||||
function _open_data_connection()
|
||||
{
|
||||
// Try to find out whether we have a IPv4 or IPv6 (control) connection
|
||||
if (function_exists('stream_socket_get_name'))
|
||||
{
|
||||
$socket_name = stream_socket_get_name($this->connection, true);
|
||||
$server_ip = substr($socket_name, 0, strrpos($socket_name, ':'));
|
||||
}
|
||||
|
||||
if (isset($server_ip) && filter_var($server_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) // ipv4
|
||||
{
|
||||
// Passive mode
|
||||
$this->_send_command('PASV', '', false);
|
||||
|
||||
if (!$ip_port = $this->_check_command(true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// open the connection to start sending the file
|
||||
if (!preg_match('#[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+#', $ip_port, $temp))
|
||||
{
|
||||
// bad ip and port
|
||||
return false;
|
||||
}
|
||||
|
||||
$temp = explode(',', $temp[0]);
|
||||
$server_ip = $temp[0] . '.' . $temp[1] . '.' . $temp[2] . '.' . $temp[3];
|
||||
$server_port = $temp[4] * 256 + $temp[5];
|
||||
}
|
||||
else // ipv6
|
||||
{
|
||||
// Extended Passive Mode - RFC2428
|
||||
$this->_send_command('EPSV', '', false);
|
||||
|
||||
if (!$epsv_response = $this->_check_command(true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Response looks like "229 Entering Extended Passive Mode (|||12345|)"
|
||||
// where 12345 is the tcp port for the data connection
|
||||
if (!preg_match('#\(\|\|\|([0-9]+)\|\)#', $epsv_response, $match))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$server_port = (int) $match[1];
|
||||
|
||||
// fsockopen expects IPv6 address in square brackets
|
||||
$server_ip = "[$server_ip]";
|
||||
}
|
||||
|
||||
$errno = 0;
|
||||
$errstr = '';
|
||||
|
||||
if (!$this->data_connection = @fsockopen($server_ip, $server_port, $errno, $errstr, $this->timeout))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@stream_set_timeout($this->data_connection, $this->timeout);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a connection used to send data
|
||||
* @access private
|
||||
*/
|
||||
function _close_data_connection()
|
||||
{
|
||||
return @fclose($this->data_connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to make sure command was successful (FTP fsock only function)
|
||||
* @access private
|
||||
*/
|
||||
function _check_command($return = false)
|
||||
{
|
||||
$response = '';
|
||||
|
||||
do
|
||||
{
|
||||
$result = @fgets($this->connection, 512);
|
||||
$response .= $result;
|
||||
}
|
||||
while (substr($result, 3, 1) !== ' ');
|
||||
|
||||
if (!preg_match('#^[123]#', $response))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ($return) ? $response : true;
|
||||
}
|
||||
}
|
||||
3757
install/update/new/includes/functions_user.php
Normal file
3757
install/update/new/includes/functions_user.php
Normal file
File diff suppressed because it is too large
Load Diff
301
install/update/new/includes/mcp/mcp_ban.php
Normal file
301
install/update/new/includes/mcp/mcp_ban.php
Normal file
@@ -0,0 +1,301 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
class mcp_ban
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $db, $user, $auth, $template, $request, $phpbb_dispatcher;
|
||||
global $phpbb_root_path, $phpEx;
|
||||
|
||||
if (!function_exists('user_ban'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
|
||||
}
|
||||
|
||||
// Include the admin banning interface...
|
||||
if (!class_exists('acp_ban'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/acp/acp_ban.' . $phpEx);
|
||||
}
|
||||
|
||||
$bansubmit = $request->is_set_post('bansubmit');
|
||||
$unbansubmit = $request->is_set_post('unbansubmit');
|
||||
|
||||
$user->add_lang(array('acp/ban', 'acp/users'));
|
||||
$this->tpl_name = 'mcp_ban';
|
||||
|
||||
/**
|
||||
* Use this event to pass perform actions when a ban is issued or revoked
|
||||
*
|
||||
* @event core.mcp_ban_main
|
||||
* @var bool bansubmit True if a ban is issued
|
||||
* @var bool unbansubmit True if a ban is removed
|
||||
* @var string mode Mode of the ban that is being worked on
|
||||
* @since 3.1.0-RC5
|
||||
*/
|
||||
$vars = array(
|
||||
'bansubmit',
|
||||
'unbansubmit',
|
||||
'mode',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_ban_main', compact($vars)));
|
||||
|
||||
// Ban submitted?
|
||||
if ($bansubmit)
|
||||
{
|
||||
// Grab the list of entries
|
||||
$ban = $request->variable('ban', '', $mode === 'user');
|
||||
$ban_length = $request->variable('banlength', 0);
|
||||
$ban_length_other = $request->variable('banlengthother', '');
|
||||
$ban_exclude = $request->variable('banexclude', 0);
|
||||
$ban_reason = $request->variable('banreason', '', true);
|
||||
$ban_give_reason = $request->variable('bangivereason', '', true);
|
||||
|
||||
if ($ban)
|
||||
{
|
||||
if (confirm_box(true))
|
||||
{
|
||||
$abort_ban = false;
|
||||
/**
|
||||
* Use this event to modify the ban details before the ban is performed
|
||||
*
|
||||
* @event core.mcp_ban_before
|
||||
* @var string mode One of the following: user, ip, email
|
||||
* @var string ban Either string or array with usernames, ips or email addresses
|
||||
* @var int ban_length Ban length in minutes
|
||||
* @var string ban_length_other Ban length as a date (YYYY-MM-DD)
|
||||
* @var bool ban_exclude Are we banning or excluding from another ban
|
||||
* @var string ban_reason Ban reason displayed to moderators
|
||||
* @var string ban_give_reason Ban reason displayed to the banned user
|
||||
* @var mixed abort_ban Either false, or an error message that is displayed to the user.
|
||||
* If a string is given the bans are not issued.
|
||||
* @since 3.1.0-RC5
|
||||
*/
|
||||
$vars = array(
|
||||
'mode',
|
||||
'ban',
|
||||
'ban_length',
|
||||
'ban_length_other',
|
||||
'ban_exclude',
|
||||
'ban_reason',
|
||||
'ban_give_reason',
|
||||
'abort_ban',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_ban_before', compact($vars)));
|
||||
|
||||
if ($abort_ban)
|
||||
{
|
||||
trigger_error($abort_ban);
|
||||
}
|
||||
user_ban($mode, $ban, $ban_length, $ban_length_other, $ban_exclude, $ban_reason, $ban_give_reason);
|
||||
|
||||
/**
|
||||
* Use this event to perform actions after the ban has been performed
|
||||
*
|
||||
* @event core.mcp_ban_after
|
||||
* @var string mode One of the following: user, ip, email
|
||||
* @var string ban Either string or array with usernames, ips or email addresses
|
||||
* @var int ban_length Ban length in minutes
|
||||
* @var string ban_length_other Ban length as a date (YYYY-MM-DD)
|
||||
* @var bool ban_exclude Are we banning or excluding from another ban
|
||||
* @var string ban_reason Ban reason displayed to moderators
|
||||
* @var string ban_give_reason Ban reason displayed to the banned user
|
||||
* @since 3.1.0-RC5
|
||||
*/
|
||||
$vars = array(
|
||||
'mode',
|
||||
'ban',
|
||||
'ban_length',
|
||||
'ban_length_other',
|
||||
'ban_exclude',
|
||||
'ban_reason',
|
||||
'ban_give_reason',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_ban_after', compact($vars)));
|
||||
|
||||
trigger_error($user->lang['BAN_UPDATE_SUCCESSFUL'] . '<br /><br /><a href="' . $this->u_action . '">« ' . $user->lang['BACK_TO_PREV'] . '</a>');
|
||||
}
|
||||
else
|
||||
{
|
||||
$hidden_fields = array(
|
||||
'mode' => $mode,
|
||||
'ban' => $ban,
|
||||
'bansubmit' => true,
|
||||
'banlength' => $ban_length,
|
||||
'banlengthother' => $ban_length_other,
|
||||
'banexclude' => $ban_exclude,
|
||||
'banreason' => $ban_reason,
|
||||
'bangivereason' => $ban_give_reason,
|
||||
);
|
||||
|
||||
/**
|
||||
* Use this event to pass data from the ban form to the confirmation screen
|
||||
*
|
||||
* @event core.mcp_ban_confirm
|
||||
* @var array hidden_fields Hidden fields that are passed through the confirm screen
|
||||
* @since 3.1.0-RC5
|
||||
*/
|
||||
$vars = array('hidden_fields');
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_ban_confirm', compact($vars)));
|
||||
|
||||
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($hidden_fields));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($unbansubmit)
|
||||
{
|
||||
$ban = $request->variable('unban', array(''));
|
||||
|
||||
if ($ban)
|
||||
{
|
||||
if (confirm_box(true))
|
||||
{
|
||||
user_unban($mode, $ban);
|
||||
|
||||
trigger_error($user->lang['BAN_UPDATE_SUCCESSFUL'] . '<br /><br /><a href="' . $this->u_action . '">« ' . $user->lang['BACK_TO_PREV'] . '</a>');
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
|
||||
'mode' => $mode,
|
||||
'unbansubmit' => true,
|
||||
'unban' => $ban)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ban length options
|
||||
$ban_end_text = array(0 => $user->lang['PERMANENT'], 30 => $user->lang['30_MINS'], 60 => $user->lang['1_HOUR'], 360 => $user->lang['6_HOURS'], 1440 => $user->lang['1_DAY'], 10080 => $user->lang['7_DAYS'], 20160 => $user->lang['2_WEEKS'], 40320 => $user->lang['1_MONTH'], -1 => $user->lang['UNTIL'] . ' -> ');
|
||||
|
||||
$ban_end_options = '';
|
||||
foreach ($ban_end_text as $length => $text)
|
||||
{
|
||||
$ban_end_options .= '<option value="' . $length . '">' . $text . '</option>';
|
||||
}
|
||||
|
||||
// Define language vars
|
||||
$this->page_title = $user->lang[strtoupper($mode) . '_BAN'];
|
||||
|
||||
$l_ban_explain = $user->lang[strtoupper($mode) . '_BAN_EXPLAIN'];
|
||||
$l_ban_exclude_explain = $user->lang[strtoupper($mode) . '_BAN_EXCLUDE_EXPLAIN'];
|
||||
$l_unban_title = $user->lang[strtoupper($mode) . '_UNBAN'];
|
||||
$l_unban_explain = $user->lang[strtoupper($mode) . '_UNBAN_EXPLAIN'];
|
||||
$l_no_ban_cell = $user->lang[strtoupper($mode) . '_NO_BANNED'];
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case 'user':
|
||||
$l_ban_cell = $user->lang['USERNAME'];
|
||||
break;
|
||||
|
||||
case 'ip':
|
||||
$l_ban_cell = $user->lang['IP_HOSTNAME'];
|
||||
break;
|
||||
|
||||
case 'email':
|
||||
$l_ban_cell = $user->lang['EMAIL_ADDRESS'];
|
||||
break;
|
||||
}
|
||||
|
||||
acp_ban::display_ban_options($mode);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'L_TITLE' => $this->page_title,
|
||||
'L_EXPLAIN' => $l_ban_explain,
|
||||
'L_UNBAN_TITLE' => $l_unban_title,
|
||||
'L_UNBAN_EXPLAIN' => $l_unban_explain,
|
||||
'L_BAN_CELL' => $l_ban_cell,
|
||||
'L_BAN_EXCLUDE_EXPLAIN' => $l_ban_exclude_explain,
|
||||
'L_NO_BAN_CELL' => $l_no_ban_cell,
|
||||
|
||||
'S_USERNAME_BAN' => ($mode == 'user') ? true : false,
|
||||
|
||||
'U_ACTION' => $this->u_action,
|
||||
'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp_ban&field=ban'),
|
||||
));
|
||||
|
||||
if ($mode === 'email' && !$auth->acl_get('a_user'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// As a "service" we will check if any post id is specified and populate the username of the poster id if given
|
||||
$post_id = $request->variable('p', 0);
|
||||
$user_id = $request->variable('u', 0);
|
||||
$pre_fill = false;
|
||||
|
||||
if ($user_id && $user_id <> ANONYMOUS)
|
||||
{
|
||||
$sql = 'SELECT username, user_email, user_ip
|
||||
FROM ' . USERS_TABLE . '
|
||||
WHERE user_id = ' . $user_id;
|
||||
$result = $db->sql_query($sql);
|
||||
switch ($mode)
|
||||
{
|
||||
case 'user':
|
||||
$pre_fill = (string) $db->sql_fetchfield('username');
|
||||
break;
|
||||
|
||||
case 'ip':
|
||||
$pre_fill = (string) $db->sql_fetchfield('user_ip');
|
||||
break;
|
||||
|
||||
case 'email':
|
||||
$pre_fill = (string) $db->sql_fetchfield('user_email');
|
||||
break;
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
else if ($post_id)
|
||||
{
|
||||
$post_info = phpbb_get_post_data(array($post_id), 'm_ban');
|
||||
|
||||
if (count($post_info) && !empty($post_info[$post_id]))
|
||||
{
|
||||
switch ($mode)
|
||||
{
|
||||
case 'user':
|
||||
$pre_fill = $post_info[$post_id]['username'];
|
||||
break;
|
||||
|
||||
case 'ip':
|
||||
$pre_fill = $post_info[$post_id]['poster_ip'];
|
||||
break;
|
||||
|
||||
case 'email':
|
||||
$pre_fill = $post_info[$post_id]['user_email'];
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ($pre_fill)
|
||||
{
|
||||
// left for legacy template compatibility
|
||||
$template->assign_var('USERNAMES', $pre_fill);
|
||||
$template->assign_var('BAN_QUANTIFIER', $pre_fill);
|
||||
}
|
||||
}
|
||||
}
|
||||
230
install/update/new/includes/mcp/mcp_logs.php
Normal file
230
install/update/new/includes/mcp/mcp_logs.php
Normal file
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* mcp_logs
|
||||
* Handling warning the users
|
||||
*/
|
||||
class mcp_logs
|
||||
{
|
||||
var $u_action;
|
||||
var $p_master;
|
||||
|
||||
function __construct($p_master)
|
||||
{
|
||||
$this->p_master = $p_master;
|
||||
}
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $auth, $db, $user, $template, $request;
|
||||
global $config, $phpbb_container, $phpbb_log;
|
||||
|
||||
$user->add_lang('acp/common');
|
||||
|
||||
$action = $request->variable('action', array('' => ''));
|
||||
|
||||
if (is_array($action))
|
||||
{
|
||||
$action = key($action);
|
||||
}
|
||||
else
|
||||
{
|
||||
$action = $request->variable('action', '');
|
||||
}
|
||||
|
||||
// Set up general vars
|
||||
$start = $request->variable('start', 0);
|
||||
$deletemark = ($action == 'del_marked') ? true : false;
|
||||
$deleteall = ($action == 'del_all') ? true : false;
|
||||
$marked = $request->variable('mark', array(0));
|
||||
|
||||
// Sort keys
|
||||
$sort_days = $request->variable('st', 0);
|
||||
$sort_key = $request->variable('sk', 't');
|
||||
$sort_dir = $request->variable('sd', 'd');
|
||||
|
||||
$this->tpl_name = 'mcp_logs';
|
||||
$this->page_title = 'MCP_LOGS';
|
||||
|
||||
/* @var $pagination \phpbb\pagination */
|
||||
$pagination = $phpbb_container->get('pagination');
|
||||
|
||||
$forum_list = array_values(array_intersect(get_forum_list('f_read'), get_forum_list('m_')));
|
||||
$forum_list[] = 0;
|
||||
|
||||
$forum_id = $topic_id = 0;
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case 'front':
|
||||
break;
|
||||
|
||||
case 'forum_logs':
|
||||
$forum_id = $request->variable('f', 0);
|
||||
|
||||
if (!in_array($forum_id, $forum_list))
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error('NOT_AUTHORISED');
|
||||
}
|
||||
|
||||
$forum_list = array($forum_id);
|
||||
break;
|
||||
|
||||
case 'topic_logs':
|
||||
$topic_id = $request->variable('t', 0);
|
||||
|
||||
$sql = 'SELECT forum_id
|
||||
FROM ' . TOPICS_TABLE . '
|
||||
WHERE topic_id = ' . $topic_id;
|
||||
$result = $db->sql_query($sql);
|
||||
$forum_id = (int) $db->sql_fetchfield('forum_id');
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!in_array($forum_id, $forum_list))
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error('NOT_AUTHORISED');
|
||||
}
|
||||
|
||||
$forum_list = array($forum_id);
|
||||
break;
|
||||
}
|
||||
|
||||
// Delete entries if requested and able
|
||||
if (($deletemark || $deleteall) && $auth->acl_get('a_clearlogs'))
|
||||
{
|
||||
if (confirm_box(true))
|
||||
{
|
||||
if ($deletemark && count($marked))
|
||||
{
|
||||
$conditions = array(
|
||||
'forum_id' => array('IN' => $forum_list),
|
||||
'log_id' => array('IN' => $marked),
|
||||
);
|
||||
|
||||
$phpbb_log->delete('mod', $conditions);
|
||||
}
|
||||
else if ($deleteall)
|
||||
{
|
||||
$keywords = $request->variable('keywords', '', true);
|
||||
|
||||
$conditions = array(
|
||||
'forum_id' => array('IN' => $forum_list),
|
||||
'keywords' => $keywords,
|
||||
);
|
||||
|
||||
if ($sort_days)
|
||||
{
|
||||
$conditions['log_time'] = array('>=', time() - ($sort_days * 86400));
|
||||
}
|
||||
|
||||
if ($mode == 'topic_logs')
|
||||
{
|
||||
$conditions['topic_id'] = $topic_id;
|
||||
}
|
||||
|
||||
$phpbb_log->delete('mod', $conditions);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
|
||||
'f' => $forum_id,
|
||||
't' => $topic_id,
|
||||
'start' => $start,
|
||||
'delmarked' => $deletemark,
|
||||
'delall' => $deleteall,
|
||||
'mark' => $marked,
|
||||
'st' => $sort_days,
|
||||
'sk' => $sort_key,
|
||||
'sd' => $sort_dir,
|
||||
'i' => $id,
|
||||
'mode' => $mode,
|
||||
'action' => $request->variable('action', array('' => ''))))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Sorting
|
||||
$limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
|
||||
$sort_by_text = array('u' => $user->lang['SORT_USERNAME'], 't' => $user->lang['SORT_DATE'], 'i' => $user->lang['SORT_IP'], 'o' => $user->lang['SORT_ACTION']);
|
||||
$sort_by_sql = array('u' => 'u.username_clean', 't' => 'l.log_time', 'i' => 'l.log_ip', 'o' => 'l.log_operation');
|
||||
|
||||
$s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
|
||||
gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param);
|
||||
|
||||
// Define where and sort sql for use in displaying logs
|
||||
$sql_where = ($sort_days) ? (time() - ($sort_days * 86400)) : 0;
|
||||
$sql_sort = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
|
||||
|
||||
$keywords = $request->variable('keywords', '', true);
|
||||
$keywords_param = !empty($keywords) ? '&keywords=' . urlencode(htmlspecialchars_decode($keywords)) : '';
|
||||
|
||||
// Grab log data
|
||||
$log_data = array();
|
||||
$log_count = 0;
|
||||
$start = view_log('mod', $log_data, $log_count, $config['topics_per_page'], $start, $forum_list, $topic_id, 0, $sql_where, $sql_sort, $keywords);
|
||||
|
||||
$base_url = $this->u_action . "&$u_sort_param$keywords_param";
|
||||
$pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'TOTAL' => $user->lang('TOTAL_LOGS', (int) $log_count),
|
||||
|
||||
'L_TITLE' => $user->lang['MCP_LOGS'],
|
||||
|
||||
'U_POST_ACTION' => $this->u_action . "&$u_sort_param$keywords_param&start=$start",
|
||||
'S_CLEAR_ALLOWED' => ($auth->acl_get('a_clearlogs')) ? true : false,
|
||||
'S_SELECT_SORT_DIR' => $s_sort_dir,
|
||||
'S_SELECT_SORT_KEY' => $s_sort_key,
|
||||
'S_SELECT_SORT_DAYS' => $s_limit_days,
|
||||
'S_LOGS' => ($log_count > 0),
|
||||
'S_KEYWORDS' => $keywords,
|
||||
)
|
||||
);
|
||||
|
||||
foreach ($log_data as $row)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$checks = array('viewpost', 'viewtopic', 'viewforum');
|
||||
foreach ($checks as $check)
|
||||
{
|
||||
if (isset($row[$check]) && $row[$check])
|
||||
{
|
||||
$data[] = '<a href="' . $row[$check] . '">' . $user->lang['LOGVIEW_' . strtoupper($check)] . '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign_block_vars('log', array(
|
||||
'USERNAME' => $row['username_full'],
|
||||
'IP' => $row['ip'],
|
||||
'DATE' => $user->format_date($row['time']),
|
||||
'ACTION' => $row['action'],
|
||||
'DATA' => (count($data)) ? implode(' | ', $data) : '',
|
||||
'ID' => $row['id'],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
1717
install/update/new/includes/mcp/mcp_main.php
Normal file
1717
install/update/new/includes/mcp/mcp_main.php
Normal file
File diff suppressed because it is too large
Load Diff
258
install/update/new/includes/mcp/mcp_notes.php
Normal file
258
install/update/new/includes/mcp/mcp_notes.php
Normal file
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* mcp_notes
|
||||
* Displays notes about a user
|
||||
*/
|
||||
class mcp_notes
|
||||
{
|
||||
var $p_master;
|
||||
var $u_action;
|
||||
|
||||
function __construct($p_master)
|
||||
{
|
||||
$this->p_master = $p_master;
|
||||
}
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $user, $template, $request;
|
||||
global $phpbb_root_path, $phpEx;
|
||||
|
||||
$action = $request->variable('action', array('' => ''));
|
||||
|
||||
if (is_array($action))
|
||||
{
|
||||
$action = key($action);
|
||||
}
|
||||
|
||||
$this->page_title = 'MCP_NOTES';
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case 'front':
|
||||
$template->assign_vars(array(
|
||||
'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp&field=username&select_single=true'),
|
||||
'U_POST_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes'),
|
||||
|
||||
'L_TITLE' => $user->lang['MCP_NOTES'],
|
||||
));
|
||||
|
||||
$this->tpl_name = 'mcp_notes_front';
|
||||
break;
|
||||
|
||||
case 'user_notes':
|
||||
$user->add_lang('acp/common');
|
||||
|
||||
$this->mcp_notes_user_view($action);
|
||||
$this->tpl_name = 'mcp_notes_user';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display user notes
|
||||
*/
|
||||
function mcp_notes_user_view($action)
|
||||
{
|
||||
global $config, $phpbb_log, $request;
|
||||
global $template, $db, $user, $auth, $phpbb_container;
|
||||
|
||||
$user_id = $request->variable('u', 0);
|
||||
$username = $request->variable('username', '', true);
|
||||
$start = $request->variable('start', 0);
|
||||
$st = $request->variable('st', 0);
|
||||
$sk = $request->variable('sk', 'b');
|
||||
$sd = $request->variable('sd', 'd');
|
||||
|
||||
/* @var $pagination \phpbb\pagination */
|
||||
$pagination = $phpbb_container->get('pagination');
|
||||
|
||||
add_form_key('mcp_notes');
|
||||
|
||||
$sql_where = ($user_id) ? "user_id = $user_id" : "username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
|
||||
|
||||
$sql = 'SELECT *
|
||||
FROM ' . USERS_TABLE . "
|
||||
WHERE $sql_where";
|
||||
$result = $db->sql_query($sql);
|
||||
$userrow = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$userrow)
|
||||
{
|
||||
trigger_error('NO_USER');
|
||||
}
|
||||
|
||||
$user_id = $userrow['user_id'];
|
||||
|
||||
// Populate user id to the currently active module (this module)
|
||||
// The following method is another way of adjusting module urls. It is the easy variant if we want
|
||||
// to directly adjust the current module url based on data retrieved within the same module.
|
||||
if (strpos($this->u_action, "&u=$user_id") === false)
|
||||
{
|
||||
$this->p_master->adjust_url('&u=' . $user_id);
|
||||
$this->u_action .= "&u=$user_id";
|
||||
}
|
||||
|
||||
$deletemark = ($action == 'del_marked') ? true : false;
|
||||
$deleteall = ($action == 'del_all') ? true : false;
|
||||
$marked = $request->variable('marknote', array(0));
|
||||
$usernote = $request->variable('usernote', '', true);
|
||||
|
||||
// Handle any actions
|
||||
if (($deletemark || $deleteall) && $auth->acl_get('a_clearlogs'))
|
||||
{
|
||||
$where_sql = '';
|
||||
if ($deletemark && $marked)
|
||||
{
|
||||
$sql_in = array();
|
||||
foreach ($marked as $mark)
|
||||
{
|
||||
$sql_in[] = $mark;
|
||||
}
|
||||
$where_sql = ' AND ' . $db->sql_in_set('log_id', $sql_in);
|
||||
unset($sql_in);
|
||||
}
|
||||
|
||||
if ($where_sql || $deleteall)
|
||||
{
|
||||
if (check_form_key('mcp_notes'))
|
||||
{
|
||||
$sql = 'DELETE FROM ' . LOG_TABLE . '
|
||||
WHERE log_type = ' . LOG_USERS . "
|
||||
AND reportee_id = $user_id
|
||||
$where_sql";
|
||||
$db->sql_query($sql);
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CLEAR_USER', false, array($userrow['username']));
|
||||
|
||||
$msg = ($deletemark) ? 'MARKED_NOTES_DELETED' : 'ALL_NOTES_DELETED';
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg = 'FORM_INVALID';
|
||||
}
|
||||
$redirect = $this->u_action . '&u=' . $user_id;
|
||||
meta_refresh(3, $redirect);
|
||||
trigger_error($user->lang[$msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($usernote && $action == 'add_feedback')
|
||||
{
|
||||
if (check_form_key('mcp_notes'))
|
||||
{
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_USER_FEEDBACK', false, array($userrow['username']));
|
||||
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_USER_FEEDBACK', false, array(
|
||||
'forum_id' => 0,
|
||||
'topic_id' => 0,
|
||||
$userrow['username']
|
||||
));
|
||||
$phpbb_log->add('user', $user->data['user_id'], $user->ip, 'LOG_USER_GENERAL', false, array(
|
||||
'reportee_id' => $user_id,
|
||||
$usernote
|
||||
));
|
||||
|
||||
$msg = $user->lang['USER_FEEDBACK_ADDED'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg = $user->lang['FORM_INVALID'];
|
||||
}
|
||||
$redirect = $this->u_action;
|
||||
meta_refresh(3, $redirect);
|
||||
|
||||
trigger_error($msg . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>'));
|
||||
}
|
||||
|
||||
// Generate the appropriate user information for the user we are looking at
|
||||
|
||||
$rank_title = $rank_img = '';
|
||||
$avatar_img = phpbb_get_user_avatar($userrow);
|
||||
|
||||
$limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
|
||||
$sort_by_text = array('a' => $user->lang['SORT_USERNAME'], 'b' => $user->lang['SORT_DATE'], 'c' => $user->lang['SORT_IP'], 'd' => $user->lang['SORT_ACTION']);
|
||||
$sort_by_sql = array('a' => 'u.username_clean', 'b' => 'l.log_time', 'c' => 'l.log_ip', 'd' => 'l.log_operation');
|
||||
|
||||
$s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
|
||||
gen_sort_selects($limit_days, $sort_by_text, $st, $sk, $sd, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param);
|
||||
|
||||
// Define where and sort sql for use in displaying logs
|
||||
$sql_where = ($st) ? (time() - ($st * 86400)) : 0;
|
||||
$sql_sort = $sort_by_sql[$sk] . ' ' . (($sd == 'd') ? 'DESC' : 'ASC');
|
||||
|
||||
$keywords = $request->variable('keywords', '', true);
|
||||
$keywords_param = !empty($keywords) ? '&keywords=' . urlencode(htmlspecialchars_decode($keywords)) : '';
|
||||
|
||||
$log_data = array();
|
||||
$log_count = 0;
|
||||
$start = view_log('user', $log_data, $log_count, $config['topics_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort, $keywords);
|
||||
|
||||
if ($log_count)
|
||||
{
|
||||
$template->assign_var('S_USER_NOTES', true);
|
||||
|
||||
foreach ($log_data as $row)
|
||||
{
|
||||
$template->assign_block_vars('usernotes', array(
|
||||
'REPORT_BY' => $row['username_full'],
|
||||
'REPORT_AT' => $user->format_date($row['time']),
|
||||
'ACTION' => $row['action'],
|
||||
'IP' => $row['ip'],
|
||||
'ID' => $row['id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$base_url = $this->u_action . "&$u_sort_param$keywords_param";
|
||||
$pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_POST_ACTION' => $this->u_action,
|
||||
'S_CLEAR_ALLOWED' => ($auth->acl_get('a_clearlogs')) ? true : false,
|
||||
'S_SELECT_SORT_DIR' => $s_sort_dir,
|
||||
'S_SELECT_SORT_KEY' => $s_sort_key,
|
||||
'S_SELECT_SORT_DAYS' => $s_limit_days,
|
||||
'S_KEYWORDS' => $keywords,
|
||||
|
||||
'L_TITLE' => $user->lang['MCP_NOTES_USER'],
|
||||
|
||||
'TOTAL_REPORTS' => $user->lang('LIST_REPORTS', (int) $log_count),
|
||||
|
||||
'RANK_TITLE' => $rank_title,
|
||||
'JOINED' => $user->format_date($userrow['user_regdate']),
|
||||
'POSTS' => ($userrow['user_posts']) ? $userrow['user_posts'] : 0,
|
||||
'WARNINGS' => ($userrow['user_warnings']) ? $userrow['user_warnings'] : 0,
|
||||
|
||||
'USERNAME_FULL' => get_username_string('full', $userrow['user_id'], $userrow['username'], $userrow['user_colour']),
|
||||
'USERNAME_COLOUR' => get_username_string('colour', $userrow['user_id'], $userrow['username'], $userrow['user_colour']),
|
||||
'USERNAME' => get_username_string('username', $userrow['user_id'], $userrow['username'], $userrow['user_colour']),
|
||||
'U_PROFILE' => get_username_string('profile', $userrow['user_id'], $userrow['username'], $userrow['user_colour']),
|
||||
|
||||
'AVATAR_IMG' => $avatar_img,
|
||||
'RANK_IMG' => $rank_img,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
834
install/update/new/includes/mcp/mcp_topic.php
Normal file
834
install/update/new/includes/mcp/mcp_topic.php
Normal file
@@ -0,0 +1,834 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* View topic in MCP
|
||||
*/
|
||||
function mcp_topic_view($id, $mode, $action)
|
||||
{
|
||||
global $phpEx, $phpbb_root_path, $config, $request;
|
||||
global $template, $db, $user, $auth, $phpbb_container, $phpbb_dispatcher;
|
||||
|
||||
$url = append_sid("{$phpbb_root_path}mcp.$phpEx?" . phpbb_extra_url());
|
||||
|
||||
/* @var $pagination \phpbb\pagination */
|
||||
$pagination = $phpbb_container->get('pagination');
|
||||
$user->add_lang('viewtopic');
|
||||
|
||||
$topic_id = $request->variable('t', 0);
|
||||
$topic_info = phpbb_get_topic_data(array($topic_id), false, true);
|
||||
|
||||
if (!count($topic_info))
|
||||
{
|
||||
trigger_error('TOPIC_NOT_EXIST');
|
||||
}
|
||||
|
||||
$topic_info = $topic_info[$topic_id];
|
||||
|
||||
// Set up some vars
|
||||
$icon_id = $request->variable('icon', 0);
|
||||
$subject = $request->variable('subject', '', true);
|
||||
$start = $request->variable('start', 0);
|
||||
$sort_days_old = $request->variable('st_old', 0);
|
||||
$forum_id = $request->variable('f', 0);
|
||||
$to_topic_id = $request->variable('to_topic_id', 0);
|
||||
$to_forum_id = $request->variable('to_forum_id', 0);
|
||||
$sort = isset($_POST['sort']) ? true : false;
|
||||
$submitted_id_list = $request->variable('post_ids', array(0));
|
||||
$checked_ids = $post_id_list = $request->variable('post_id_list', array(0));
|
||||
|
||||
// Resync Topic?
|
||||
if ($action == 'resync')
|
||||
{
|
||||
if (!function_exists('mcp_resync_topics'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/mcp/mcp_forum.' . $phpEx);
|
||||
}
|
||||
mcp_resync_topics(array($topic_id));
|
||||
}
|
||||
|
||||
// Split Topic?
|
||||
if ($action == 'split_all' || $action == 'split_beyond')
|
||||
{
|
||||
if (!$sort)
|
||||
{
|
||||
split_topic($action, $topic_id, $to_forum_id, $subject);
|
||||
}
|
||||
$action = 'split';
|
||||
}
|
||||
|
||||
// Merge Posts?
|
||||
if ($action == 'merge_posts')
|
||||
{
|
||||
if (!$sort)
|
||||
{
|
||||
merge_posts($topic_id, $to_topic_id);
|
||||
}
|
||||
$action = 'merge';
|
||||
}
|
||||
|
||||
if ($action == 'split' && !$subject)
|
||||
{
|
||||
$subject = $topic_info['topic_title'];
|
||||
}
|
||||
|
||||
// Restore or pprove posts?
|
||||
if (($action == 'restore' || $action == 'approve') && $auth->acl_get('m_approve', $topic_info['forum_id']))
|
||||
{
|
||||
if (!class_exists('mcp_queue'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/mcp/mcp_queue.' . $phpEx);
|
||||
}
|
||||
|
||||
include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
|
||||
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
|
||||
|
||||
if (!count($post_id_list))
|
||||
{
|
||||
trigger_error('NO_POST_SELECTED');
|
||||
}
|
||||
|
||||
if (!$sort)
|
||||
{
|
||||
mcp_queue::approve_posts($action, $post_id_list, $id, $mode);
|
||||
}
|
||||
}
|
||||
|
||||
// Jumpbox, sort selects and that kind of things
|
||||
make_jumpbox($url . "&i=$id&mode=forum_view", $topic_info['forum_id'], false, 'm_', true);
|
||||
$where_sql = ($action == 'reports') ? 'WHERE post_reported = 1 AND ' : 'WHERE';
|
||||
|
||||
$sort_days = $total = 0;
|
||||
$sort_key = $sort_dir = '';
|
||||
$sort_by_sql = $sort_order_sql = array();
|
||||
phpbb_mcp_sorting('viewtopic', $sort_days, $sort_key, $sort_dir, $sort_by_sql, $sort_order_sql, $total, $topic_info['forum_id'], $topic_id, $where_sql);
|
||||
|
||||
/* @var $phpbb_content_visibility \phpbb\content_visibility */
|
||||
$phpbb_content_visibility = $phpbb_container->get('content.visibility');
|
||||
$limit_time_sql = ($sort_days) ? 'AND p.post_time >= ' . (time() - ($sort_days * 86400)) : '';
|
||||
|
||||
if ($total == -1)
|
||||
{
|
||||
$total = $phpbb_content_visibility->get_count('topic_posts', $topic_info, $topic_info['forum_id']);
|
||||
}
|
||||
|
||||
$posts_per_page = max(0, $request->variable('posts_per_page', intval($config['posts_per_page'])));
|
||||
if ($posts_per_page == 0)
|
||||
{
|
||||
$posts_per_page = $total;
|
||||
}
|
||||
|
||||
if ((!empty($sort_days_old) && $sort_days_old != $sort_days) || $total <= $posts_per_page)
|
||||
{
|
||||
$start = 0;
|
||||
}
|
||||
$start = $pagination->validate_start($start, $posts_per_page, $total);
|
||||
|
||||
$sql_where = (($action == 'reports') ? 'p.post_reported = 1 AND ' : '') . '
|
||||
p.topic_id = ' . $topic_id . '
|
||||
AND ' . $phpbb_content_visibility->get_visibility_sql('post', $topic_info['forum_id'], 'p.') . '
|
||||
AND p.poster_id = u.user_id ' .
|
||||
$limit_time_sql;
|
||||
|
||||
$sql_ary = array(
|
||||
'SELECT' => 'u.username, u.username_clean, u.user_colour, p.*',
|
||||
'FROM' => array(
|
||||
POSTS_TABLE => 'p',
|
||||
USERS_TABLE => 'u'
|
||||
),
|
||||
'LEFT_JOIN' => array(),
|
||||
'WHERE' => $sql_where,
|
||||
'ORDER_BY' => $sort_order_sql,
|
||||
);
|
||||
|
||||
/**
|
||||
* Event to modify the SQL query before the MCP topic review posts is queried
|
||||
*
|
||||
* @event core.mcp_topic_modify_sql_ary
|
||||
* @var array sql_ary The SQL array to get the data of the MCP topic review posts
|
||||
* @since 3.2.8-RC1
|
||||
*/
|
||||
$vars = array('sql_ary');
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_topic_modify_sql_ary', compact($vars)));
|
||||
|
||||
$sql = $db->sql_build_query('SELECT', $sql_ary);
|
||||
unset($sql_ary);
|
||||
|
||||
$result = $db->sql_query_limit($sql, $posts_per_page, $start);
|
||||
|
||||
$rowset = $post_id_list = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$rowset[] = $row;
|
||||
$post_id_list[] = $row['post_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// Get topic tracking info
|
||||
if ($config['load_db_lastread'])
|
||||
{
|
||||
$tmp_topic_data = array($topic_id => $topic_info);
|
||||
$topic_tracking_info = get_topic_tracking($topic_info['forum_id'], $topic_id, $tmp_topic_data, array($topic_info['forum_id'] => $topic_info['forum_mark_time']));
|
||||
unset($tmp_topic_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
$topic_tracking_info = get_complete_topic_tracking($topic_info['forum_id'], $topic_id);
|
||||
}
|
||||
|
||||
$has_unapproved_posts = $has_deleted_posts = false;
|
||||
|
||||
// Grab extensions
|
||||
$attachments = array();
|
||||
if ($topic_info['topic_attachment'] && count($post_id_list))
|
||||
{
|
||||
// Get attachments...
|
||||
if ($auth->acl_get('u_download') && $auth->acl_get('f_download', $topic_info['forum_id']))
|
||||
{
|
||||
$sql = 'SELECT *
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('post_msg_id', $post_id_list) . '
|
||||
AND in_message = 0
|
||||
ORDER BY filetime DESC, post_msg_id ASC';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$attachments[$row['post_msg_id']][] = $row;
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event to modify the post data for the MCP topic review before assigning the posts
|
||||
*
|
||||
* @event core.mcp_topic_modify_post_data
|
||||
* @var array attachments List of attachments post_id => array of attachments
|
||||
* @var int forum_id The forum ID we are currently in
|
||||
* @var int id ID of the tab we are displaying
|
||||
* @var string mode Mode of the MCP page we are displaying
|
||||
* @var array post_id_list Array with post ids we are going to display
|
||||
* @var array rowset Array with the posts data
|
||||
* @var int topic_id The topic ID we are currently reviewing
|
||||
* @since 3.1.7-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'attachments',
|
||||
'forum_id',
|
||||
'id',
|
||||
'mode',
|
||||
'post_id_list',
|
||||
'rowset',
|
||||
'topic_id',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_topic_modify_post_data', compact($vars)));
|
||||
|
||||
foreach ($rowset as $current_row_number => $row)
|
||||
{
|
||||
$message = $row['post_text'];
|
||||
$post_subject = ($row['post_subject'] != '') ? $row['post_subject'] : $topic_info['topic_title'];
|
||||
|
||||
$parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES;
|
||||
$message = generate_text_for_display($message, $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, false);
|
||||
|
||||
if (!empty($attachments[$row['post_id']]))
|
||||
{
|
||||
$update_count = array();
|
||||
parse_attachments($topic_info['forum_id'], $message, $attachments[$row['post_id']], $update_count);
|
||||
}
|
||||
|
||||
if ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE)
|
||||
{
|
||||
$has_unapproved_posts = true;
|
||||
}
|
||||
|
||||
if ($row['post_visibility'] == ITEM_DELETED)
|
||||
{
|
||||
$has_deleted_posts = true;
|
||||
}
|
||||
|
||||
$post_unread = (isset($topic_tracking_info[$topic_id]) && $row['post_time'] > $topic_tracking_info[$topic_id]) ? true : false;
|
||||
|
||||
$post_row = array(
|
||||
'POST_AUTHOR_FULL' => get_username_string('full', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
|
||||
'POST_AUTHOR_COLOUR' => get_username_string('colour', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
|
||||
'POST_AUTHOR' => get_username_string('username', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
|
||||
'U_POST_AUTHOR' => get_username_string('profile', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
|
||||
|
||||
'POST_DATE' => $user->format_date($row['post_time']),
|
||||
'POST_SUBJECT' => $post_subject,
|
||||
'MESSAGE' => $message,
|
||||
'POST_ID' => $row['post_id'],
|
||||
'RETURN_TOPIC' => sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $topic_id) . '">', '</a>'),
|
||||
|
||||
'MINI_POST_IMG' => ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'),
|
||||
|
||||
'S_POST_REPORTED' => ($row['post_reported'] && $auth->acl_get('m_report', $topic_info['forum_id'])),
|
||||
'S_POST_UNAPPROVED' => (($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $topic_info['forum_id'])),
|
||||
'S_POST_DELETED' => ($row['post_visibility'] == ITEM_DELETED && $auth->acl_get('m_approve', $topic_info['forum_id'])),
|
||||
'S_CHECKED' => (($submitted_id_list && !in_array(intval($row['post_id']), $submitted_id_list)) || in_array(intval($row['post_id']), $checked_ids)) ? true : false,
|
||||
'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false,
|
||||
|
||||
'U_POST_DETAILS' => "$url&i=$id&p={$row['post_id']}&mode=post_details" . (($forum_id) ? "&f=$forum_id" : ''),
|
||||
'U_MCP_APPROVE' => ($auth->acl_get('m_approve', $topic_info['forum_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=approve_details&f=' . $topic_info['forum_id'] . '&p=' . $row['post_id']) : '',
|
||||
'U_MCP_REPORT' => ($auth->acl_get('m_report', $topic_info['forum_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&mode=report_details&f=' . $topic_info['forum_id'] . '&p=' . $row['post_id']) : '',
|
||||
);
|
||||
|
||||
/**
|
||||
* Event to modify the template data block for topic reviews in the MCP
|
||||
*
|
||||
* @event core.mcp_topic_review_modify_row
|
||||
* @var int id ID of the tab we are displaying
|
||||
* @var string mode Mode of the MCP page we are displaying
|
||||
* @var int topic_id The topic ID we are currently reviewing
|
||||
* @var int forum_id The forum ID we are currently in
|
||||
* @var int start Start item of this page
|
||||
* @var int current_row_number Number of the post on this page
|
||||
* @var array post_row Template block array of the current post
|
||||
* @var array row Array with original post and user data
|
||||
* @var array topic_info Array with topic data
|
||||
* @var int total Total posts count
|
||||
* @since 3.1.4-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'id',
|
||||
'mode',
|
||||
'topic_id',
|
||||
'forum_id',
|
||||
'start',
|
||||
'current_row_number',
|
||||
'post_row',
|
||||
'row',
|
||||
'topic_info',
|
||||
'total',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_topic_review_modify_row', compact($vars)));
|
||||
|
||||
$template->assign_block_vars('postrow', $post_row);
|
||||
|
||||
// Display not already displayed Attachments for this post, we already parsed them. ;)
|
||||
if (!empty($attachments[$row['post_id']]))
|
||||
{
|
||||
foreach ($attachments[$row['post_id']] as $attachment)
|
||||
{
|
||||
$template->assign_block_vars('postrow.attachment', array(
|
||||
'DISPLAY_ATTACHMENT' => $attachment)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
unset($rowset[$current_row_number]);
|
||||
}
|
||||
|
||||
// Display topic icons for split topic
|
||||
$s_topic_icons = false;
|
||||
|
||||
if ($auth->acl_gets('m_split', 'm_merge', (int) $topic_info['forum_id']))
|
||||
{
|
||||
include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
|
||||
$s_topic_icons = posting_gen_topic_icons('', $icon_id);
|
||||
|
||||
// Has the user selected a topic for merge?
|
||||
if ($to_topic_id)
|
||||
{
|
||||
$to_topic_info = phpbb_get_topic_data(array($to_topic_id), 'm_merge');
|
||||
|
||||
if (!count($to_topic_info))
|
||||
{
|
||||
$to_topic_id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$to_topic_info = $to_topic_info[$to_topic_id];
|
||||
|
||||
if (!$to_topic_info['enable_icons'] || $auth->acl_get('!f_icons', $topic_info['forum_id']))
|
||||
{
|
||||
$s_topic_icons = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$s_hidden_fields = build_hidden_fields(array(
|
||||
'st_old' => $sort_days,
|
||||
'post_ids' => $post_id_list,
|
||||
));
|
||||
|
||||
$base_url = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&t={$topic_info['topic_id']}&mode=$mode&action=$action&to_topic_id=$to_topic_id&posts_per_page=$posts_per_page&st=$sort_days&sk=$sort_key&sd=$sort_dir");
|
||||
if ($posts_per_page)
|
||||
{
|
||||
$pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $posts_per_page, $start);
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'TOPIC_TITLE' => $topic_info['topic_title'],
|
||||
'U_VIEW_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topic_info['forum_id'] . '&t=' . $topic_info['topic_id']),
|
||||
|
||||
'TO_TOPIC_ID' => $to_topic_id,
|
||||
'TO_TOPIC_INFO' => ($to_topic_id) ? sprintf($user->lang['YOU_SELECTED_TOPIC'], $to_topic_id, '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $to_topic_info['forum_id'] . '&t=' . $to_topic_id) . '">' . $to_topic_info['topic_title'] . '</a>') : '',
|
||||
|
||||
'SPLIT_SUBJECT' => $subject,
|
||||
'POSTS_PER_PAGE' => $posts_per_page,
|
||||
'ACTION' => $action,
|
||||
|
||||
'REPORTED_IMG' => $user->img('icon_topic_reported', 'POST_REPORTED'),
|
||||
'UNAPPROVED_IMG' => $user->img('icon_topic_unapproved', 'POST_UNAPPROVED'),
|
||||
'DELETED_IMG' => $user->img('icon_topic_deleted', 'POST_DELETED_RESTORE'),
|
||||
'INFO_IMG' => $user->img('icon_post_info', 'VIEW_INFO'),
|
||||
|
||||
'S_MCP_ACTION' => "$url&i=$id&mode=$mode&action=$action&start=$start",
|
||||
'S_FORUM_SELECT' => ($to_forum_id) ? make_forum_select($to_forum_id, false, false, true, true, true) : make_forum_select($topic_info['forum_id'], false, false, true, true, true),
|
||||
'S_CAN_SPLIT' => ($auth->acl_get('m_split', $topic_info['forum_id'])) ? true : false,
|
||||
'S_CAN_MERGE' => ($auth->acl_get('m_merge', $topic_info['forum_id'])) ? true : false,
|
||||
'S_CAN_DELETE' => ($auth->acl_get('m_delete', $topic_info['forum_id'])) ? true : false,
|
||||
'S_CAN_APPROVE' => ($has_unapproved_posts && $auth->acl_get('m_approve', $topic_info['forum_id'])) ? true : false,
|
||||
'S_CAN_RESTORE' => ($has_deleted_posts && $auth->acl_get('m_approve', $topic_info['forum_id'])) ? true : false,
|
||||
'S_CAN_LOCK' => ($auth->acl_get('m_lock', $topic_info['forum_id'])) ? true : false,
|
||||
'S_CAN_REPORT' => ($auth->acl_get('m_report', $topic_info['forum_id'])) ? true : false,
|
||||
'S_CAN_SYNC' => $auth->acl_get('m_', $topic_info['forum_id']),
|
||||
'S_REPORT_VIEW' => ($action == 'reports') ? true : false,
|
||||
'S_MERGE_VIEW' => ($action == 'merge') ? true : false,
|
||||
'S_SPLIT_VIEW' => ($action == 'split') ? true : false,
|
||||
|
||||
'S_HIDDEN_FIELDS' => $s_hidden_fields,
|
||||
|
||||
'S_SHOW_TOPIC_ICONS' => $s_topic_icons,
|
||||
'S_TOPIC_ICON' => $icon_id,
|
||||
|
||||
'U_SELECT_TOPIC' => "$url&i=$id&mode=forum_view&action=merge_select" . (($forum_id) ? "&f=$forum_id" : ''),
|
||||
|
||||
'RETURN_TOPIC' => sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$topic_info['forum_id']}&t={$topic_info['topic_id']}&start=$start") . '">', '</a>'),
|
||||
'RETURN_FORUM' => sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", "f={$topic_info['forum_id']}&start=$start") . '">', '</a>'),
|
||||
|
||||
'TOTAL_POSTS' => $user->lang('VIEW_TOPIC_POSTS', (int) $total),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Split topic
|
||||
*/
|
||||
function split_topic($action, $topic_id, $to_forum_id, $subject)
|
||||
{
|
||||
global $db, $template, $user, $phpEx, $phpbb_root_path, $auth, $config, $phpbb_log, $request, $phpbb_dispatcher;
|
||||
|
||||
$post_id_list = $request->variable('post_id_list', array(0));
|
||||
$forum_id = $request->variable('forum_id', 0);
|
||||
$start = $request->variable('start', 0);
|
||||
|
||||
if (!count($post_id_list))
|
||||
{
|
||||
$template->assign_var('MESSAGE', $user->lang['NO_POST_SELECTED']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!phpbb_check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_split')))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$post_id = $post_id_list[0];
|
||||
$post_info = phpbb_get_post_data(array($post_id));
|
||||
|
||||
if (!count($post_info))
|
||||
{
|
||||
$template->assign_var('MESSAGE', $user->lang['NO_POST_SELECTED']);
|
||||
return;
|
||||
}
|
||||
|
||||
$post_info = $post_info[$post_id];
|
||||
$subject = trim($subject);
|
||||
|
||||
// Make some tests
|
||||
if (!$subject)
|
||||
{
|
||||
$template->assign_var('MESSAGE', $user->lang['EMPTY_SUBJECT']);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($to_forum_id <= 0)
|
||||
{
|
||||
$template->assign_var('MESSAGE', $user->lang['NO_DESTINATION_FORUM']);
|
||||
return;
|
||||
}
|
||||
|
||||
$forum_info = phpbb_get_forum_data(array($to_forum_id), 'f_post');
|
||||
|
||||
if (!count($forum_info))
|
||||
{
|
||||
$template->assign_var('MESSAGE', $user->lang['USER_CANNOT_POST']);
|
||||
return;
|
||||
}
|
||||
|
||||
$forum_info = $forum_info[$to_forum_id];
|
||||
|
||||
if ($forum_info['forum_type'] != FORUM_POST)
|
||||
{
|
||||
$template->assign_var('MESSAGE', $user->lang['FORUM_NOT_POSTABLE']);
|
||||
return;
|
||||
}
|
||||
|
||||
$redirect = $request->variable('redirect', build_url(array('quickmod')));
|
||||
|
||||
$s_hidden_fields = build_hidden_fields(array(
|
||||
'i' => 'main',
|
||||
'post_id_list' => $post_id_list,
|
||||
'f' => $forum_id,
|
||||
'mode' => 'topic_view',
|
||||
'start' => $start,
|
||||
'action' => $action,
|
||||
't' => $topic_id,
|
||||
'redirect' => $redirect,
|
||||
'subject' => $subject,
|
||||
'to_forum_id' => $to_forum_id,
|
||||
'icon' => $request->variable('icon', 0))
|
||||
);
|
||||
|
||||
if (confirm_box(true))
|
||||
{
|
||||
if ($action == 'split_beyond')
|
||||
{
|
||||
$sort_days = $total = 0;
|
||||
$sort_key = $sort_dir = '';
|
||||
$sort_by_sql = $sort_order_sql = array();
|
||||
phpbb_mcp_sorting('viewtopic', $sort_days, $sort_key, $sort_dir, $sort_by_sql, $sort_order_sql, $total, $forum_id, $topic_id);
|
||||
|
||||
$limit_time_sql = ($sort_days) ? 'AND t.topic_last_post_time >= ' . (time() - ($sort_days * 86400)) : '';
|
||||
|
||||
if ($sort_order_sql[0] == 'u')
|
||||
{
|
||||
$sql = 'SELECT p.post_id, p.forum_id, p.post_visibility
|
||||
FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u
|
||||
WHERE p.topic_id = $topic_id
|
||||
AND p.poster_id = u.user_id
|
||||
$limit_time_sql
|
||||
ORDER BY $sort_order_sql";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql = 'SELECT p.post_id, p.forum_id, p.post_visibility
|
||||
FROM ' . POSTS_TABLE . " p
|
||||
WHERE p.topic_id = $topic_id
|
||||
$limit_time_sql
|
||||
ORDER BY $sort_order_sql";
|
||||
}
|
||||
$result = $db->sql_query_limit($sql, 0, $start);
|
||||
|
||||
$store = false;
|
||||
$post_id_list = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
// If split from selected post (split_beyond), we split the unapproved items too.
|
||||
if (($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) && !$auth->acl_get('m_approve', $row['forum_id']))
|
||||
{
|
||||
// continue;
|
||||
}
|
||||
|
||||
// Start to store post_ids as soon as we see the first post that was selected
|
||||
if ($row['post_id'] == $post_id)
|
||||
{
|
||||
$store = true;
|
||||
}
|
||||
|
||||
if ($store)
|
||||
{
|
||||
$post_id_list[] = $row['post_id'];
|
||||
}
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
if (!count($post_id_list))
|
||||
{
|
||||
trigger_error('NO_POST_SELECTED');
|
||||
}
|
||||
|
||||
$icon_id = $request->variable('icon', 0);
|
||||
|
||||
$sql_ary = array(
|
||||
'forum_id' => $to_forum_id,
|
||||
'topic_title' => $subject,
|
||||
'icon_id' => $icon_id,
|
||||
'topic_visibility' => 1
|
||||
);
|
||||
|
||||
$sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
|
||||
$db->sql_query($sql);
|
||||
|
||||
$to_topic_id = $db->sql_nextid();
|
||||
move_posts($post_id_list, $to_topic_id);
|
||||
|
||||
$topic_info = phpbb_get_topic_data(array($topic_id));
|
||||
$topic_info = $topic_info[$topic_id];
|
||||
|
||||
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_SPLIT_DESTINATION', false, array(
|
||||
'forum_id' => $to_forum_id,
|
||||
'topic_id' => $to_topic_id,
|
||||
$subject
|
||||
));
|
||||
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_SPLIT_SOURCE', false, array(
|
||||
'forum_id' => $forum_id,
|
||||
'topic_id' => $topic_id,
|
||||
$topic_info['topic_title']
|
||||
));
|
||||
|
||||
// Change topic title of first post
|
||||
$sql = 'UPDATE ' . POSTS_TABLE . "
|
||||
SET post_subject = '" . $db->sql_escape($subject) . "'
|
||||
WHERE post_id = {$post_id_list[0]}";
|
||||
$db->sql_query($sql);
|
||||
|
||||
// Grab data for first post in split topic
|
||||
$sql_array = array(
|
||||
'SELECT' => 'p.post_id, p.forum_id, p.poster_id, p.post_text, f.enable_indexing',
|
||||
'FROM' => array(
|
||||
POSTS_TABLE => 'p',
|
||||
),
|
||||
'LEFT_JOIN' => array(
|
||||
array(
|
||||
'FROM' => array(FORUMS_TABLE => 'f'),
|
||||
'ON' => 'p.forum_id = f.forum_id',
|
||||
)
|
||||
),
|
||||
'WHERE' => "post_id = {$post_id_list[0]}",
|
||||
);
|
||||
$sql = $db->sql_build_query('SELECT', $sql_array);
|
||||
$result = $db->sql_query($sql);
|
||||
$first_post_data = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// Index first post as if it were edited
|
||||
if ($first_post_data['enable_indexing'])
|
||||
{
|
||||
// Select the search method and do some additional checks to ensure it can actually be utilised
|
||||
$search_type = $config['search_type'];
|
||||
|
||||
if (!class_exists($search_type))
|
||||
{
|
||||
trigger_error('NO_SUCH_SEARCH_MODULE');
|
||||
}
|
||||
|
||||
$error = false;
|
||||
$search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
|
||||
|
||||
if ($error)
|
||||
{
|
||||
trigger_error($error);
|
||||
}
|
||||
|
||||
$search->index('edit', $first_post_data['post_id'], $first_post_data['post_text'], $subject, $first_post_data['poster_id'], $first_post_data['forum_id']);
|
||||
}
|
||||
|
||||
// Copy topic subscriptions to new topic
|
||||
$sql = 'SELECT user_id, notify_status
|
||||
FROM ' . TOPICS_WATCH_TABLE . '
|
||||
WHERE topic_id = ' . $topic_id;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$sql_ary = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$sql_ary[] = array(
|
||||
'topic_id' => (int) $to_topic_id,
|
||||
'user_id' => (int) $row['user_id'],
|
||||
'notify_status' => (int) $row['notify_status'],
|
||||
);
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (count($sql_ary))
|
||||
{
|
||||
$db->sql_multi_insert(TOPICS_WATCH_TABLE, $sql_ary);
|
||||
}
|
||||
|
||||
// Copy bookmarks to new topic
|
||||
$sql = 'SELECT user_id
|
||||
FROM ' . BOOKMARKS_TABLE . '
|
||||
WHERE topic_id = ' . $topic_id;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$sql_ary = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$sql_ary[] = array(
|
||||
'topic_id' => (int) $to_topic_id,
|
||||
'user_id' => (int) $row['user_id'],
|
||||
);
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (count($sql_ary))
|
||||
{
|
||||
$db->sql_multi_insert(BOOKMARKS_TABLE, $sql_ary);
|
||||
}
|
||||
|
||||
$success_msg = 'TOPIC_SPLIT_SUCCESS';
|
||||
|
||||
// Update forum statistics
|
||||
$config->increment('num_topics', 1, false);
|
||||
|
||||
// Link back to both topics
|
||||
$return_link = sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $post_info['forum_id'] . '&t=' . $post_info['topic_id']) . '">', '</a>') . '<br /><br />' . sprintf($user->lang['RETURN_NEW_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $to_forum_id . '&t=' . $to_topic_id) . '">', '</a>');
|
||||
$redirect = $request->variable('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id");
|
||||
$redirect = reapply_sid($redirect);
|
||||
|
||||
meta_refresh(3, $redirect);
|
||||
trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link);
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, ($action == 'split_all') ? 'SPLIT_TOPIC_ALL' : 'SPLIT_TOPIC_BEYOND', $s_hidden_fields);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge selected posts into selected topic
|
||||
*/
|
||||
function merge_posts($topic_id, $to_topic_id)
|
||||
{
|
||||
global $db, $template, $user, $phpEx, $phpbb_root_path, $phpbb_log, $request, $phpbb_dispatcher;
|
||||
|
||||
if (!$to_topic_id)
|
||||
{
|
||||
$template->assign_var('MESSAGE', $user->lang['NO_FINAL_TOPIC_SELECTED']);
|
||||
return;
|
||||
}
|
||||
|
||||
$sync_topics = array($topic_id, $to_topic_id);
|
||||
|
||||
$topic_data = phpbb_get_topic_data($sync_topics, 'm_merge');
|
||||
|
||||
if (!count($topic_data) || empty($topic_data[$to_topic_id]))
|
||||
{
|
||||
$template->assign_var('MESSAGE', $user->lang['NO_FINAL_TOPIC_SELECTED']);
|
||||
return;
|
||||
}
|
||||
|
||||
$sync_forums = array();
|
||||
foreach ($topic_data as $data)
|
||||
{
|
||||
$sync_forums[$data['forum_id']] = $data['forum_id'];
|
||||
}
|
||||
|
||||
$topic_data = $topic_data[$to_topic_id];
|
||||
|
||||
$post_id_list = $request->variable('post_id_list', array(0));
|
||||
$start = $request->variable('start', 0);
|
||||
|
||||
if (!count($post_id_list))
|
||||
{
|
||||
$template->assign_var('MESSAGE', $user->lang['NO_POST_SELECTED']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!phpbb_check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_merge')))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$redirect = $request->variable('redirect', build_url(array('quickmod')));
|
||||
|
||||
$s_hidden_fields = build_hidden_fields(array(
|
||||
'i' => 'main',
|
||||
'post_id_list' => $post_id_list,
|
||||
'to_topic_id' => $to_topic_id,
|
||||
'mode' => 'topic_view',
|
||||
'action' => 'merge_posts',
|
||||
'start' => $start,
|
||||
'redirect' => $redirect,
|
||||
't' => $topic_id)
|
||||
);
|
||||
$return_link = '';
|
||||
|
||||
if (confirm_box(true))
|
||||
{
|
||||
$to_forum_id = $topic_data['forum_id'];
|
||||
|
||||
move_posts($post_id_list, $to_topic_id, false);
|
||||
|
||||
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_MERGE', false, array(
|
||||
'forum_id' => $to_forum_id,
|
||||
'topic_id' => $to_topic_id,
|
||||
$topic_data['topic_title']
|
||||
));
|
||||
|
||||
// Message and return links
|
||||
$success_msg = 'POSTS_MERGED_SUCCESS';
|
||||
|
||||
// Does the original topic still exist? If yes, link back to it
|
||||
$sql = 'SELECT forum_id
|
||||
FROM ' . POSTS_TABLE . '
|
||||
WHERE topic_id = ' . $topic_id;
|
||||
$result = $db->sql_query_limit($sql, 1);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($row)
|
||||
{
|
||||
$return_link .= sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id'] . '&t=' . $topic_id) . '">', '</a>');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!function_exists('phpbb_update_rows_avoiding_duplicates_notify_status'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_database_helper.' . $phpEx);
|
||||
}
|
||||
|
||||
// If the topic no longer exist, we will update the topic watch table.
|
||||
phpbb_update_rows_avoiding_duplicates_notify_status($db, TOPICS_WATCH_TABLE, 'topic_id', array($topic_id), $to_topic_id);
|
||||
|
||||
// If the topic no longer exist, we will update the bookmarks table.
|
||||
phpbb_update_rows_avoiding_duplicates($db, BOOKMARKS_TABLE, 'topic_id', array($topic_id), $to_topic_id);
|
||||
}
|
||||
|
||||
// Re-sync the topics and forums because the auto-sync was deactivated in the call of move_posts()
|
||||
sync('topic_reported', 'topic_id', $sync_topics);
|
||||
sync('topic_attachment', 'topic_id', $sync_topics);
|
||||
sync('topic', 'topic_id', $sync_topics, true);
|
||||
sync('forum', 'forum_id', $sync_forums, true, true);
|
||||
|
||||
// Link to the new topic
|
||||
$return_link .= (($return_link) ? '<br /><br />' : '') . sprintf($user->lang['RETURN_NEW_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $to_forum_id . '&t=' . $to_topic_id) . '">', '</a>');
|
||||
$redirect = $request->variable('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id");
|
||||
$redirect = reapply_sid($redirect);
|
||||
|
||||
/**
|
||||
* Perform additional actions after merging posts.
|
||||
*
|
||||
* @event core.mcp_topics_merge_posts_after
|
||||
* @var int topic_id The topic ID from which posts are being moved
|
||||
* @var int to_topic_id The topic ID to which posts are being moved
|
||||
* @since 3.1.11-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'topic_id',
|
||||
'to_topic_id',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_topics_merge_posts_after', compact($vars)));
|
||||
|
||||
meta_refresh(3, $redirect);
|
||||
trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link);
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, 'MERGE_POSTS', $s_hidden_fields);
|
||||
}
|
||||
}
|
||||
610
install/update/new/includes/mcp/mcp_warn.php
Normal file
610
install/update/new/includes/mcp/mcp_warn.php
Normal file
@@ -0,0 +1,610 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* mcp_warn
|
||||
* Handling warning the users
|
||||
*/
|
||||
class mcp_warn
|
||||
{
|
||||
var $p_master;
|
||||
var $u_action;
|
||||
|
||||
function __construct($p_master)
|
||||
{
|
||||
$this->p_master = $p_master;
|
||||
}
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $request;
|
||||
|
||||
$action = $request->variable('action', array('' => ''));
|
||||
|
||||
if (is_array($action))
|
||||
{
|
||||
$action = key($action);
|
||||
}
|
||||
|
||||
$this->page_title = 'MCP_WARN';
|
||||
|
||||
add_form_key('mcp_warn');
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case 'front':
|
||||
$this->mcp_warn_front_view();
|
||||
$this->tpl_name = 'mcp_warn_front';
|
||||
break;
|
||||
|
||||
case 'list':
|
||||
$this->mcp_warn_list_view($action);
|
||||
$this->tpl_name = 'mcp_warn_list';
|
||||
break;
|
||||
|
||||
case 'warn_post':
|
||||
$this->mcp_warn_post_view($action);
|
||||
$this->tpl_name = 'mcp_warn_post';
|
||||
break;
|
||||
|
||||
case 'warn_user':
|
||||
$this->mcp_warn_user_view($action);
|
||||
$this->tpl_name = 'mcp_warn_user';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the summary on the main page of the warning module
|
||||
*/
|
||||
function mcp_warn_front_view()
|
||||
{
|
||||
global $phpEx, $phpbb_root_path;
|
||||
global $template, $db, $user;
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp&field=username&select_single=true'),
|
||||
'U_POST_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&mode=warn_user'),
|
||||
));
|
||||
|
||||
// Obtain a list of the 5 naughtiest users....
|
||||
// These are the 5 users with the highest warning count
|
||||
$highest = array();
|
||||
$count = 0;
|
||||
|
||||
view_warned_users($highest, $count, 5);
|
||||
|
||||
foreach ($highest as $row)
|
||||
{
|
||||
$template->assign_block_vars('highest', array(
|
||||
'U_NOTES' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes&u=' . $row['user_id']),
|
||||
|
||||
'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
|
||||
|
||||
'WARNING_TIME' => $user->format_date($row['user_last_warning']),
|
||||
'WARNINGS' => $row['user_warnings'],
|
||||
));
|
||||
}
|
||||
|
||||
// And now the 5 most recent users to get in trouble
|
||||
$sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_colour, u.user_warnings, w.warning_time
|
||||
FROM ' . USERS_TABLE . ' u, ' . WARNINGS_TABLE . ' w
|
||||
WHERE u.user_id = w.user_id
|
||||
ORDER BY w.warning_time DESC';
|
||||
$result = $db->sql_query_limit($sql, 5);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$template->assign_block_vars('latest', array(
|
||||
'U_NOTES' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes&u=' . $row['user_id']),
|
||||
|
||||
'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
|
||||
|
||||
'WARNING_TIME' => $user->format_date($row['warning_time']),
|
||||
'WARNINGS' => $row['user_warnings'],
|
||||
));
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all users with warnings
|
||||
*/
|
||||
function mcp_warn_list_view($action)
|
||||
{
|
||||
global $phpEx, $phpbb_root_path, $config, $phpbb_container;
|
||||
global $template, $user, $auth, $request;
|
||||
|
||||
/* @var $pagination \phpbb\pagination */
|
||||
$pagination = $phpbb_container->get('pagination');
|
||||
$user->add_lang('memberlist');
|
||||
|
||||
$start = $request->variable('start', 0);
|
||||
$st = $request->variable('st', 0);
|
||||
$sk = $request->variable('sk', 'b');
|
||||
$sd = $request->variable('sd', 'd');
|
||||
|
||||
$limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
|
||||
$sort_by_text = array('a' => $user->lang['SORT_USERNAME'], 'b' => $user->lang['SORT_DATE'], 'c' => $user->lang['SORT_WARNINGS']);
|
||||
$sort_by_sql = array('a' => 'username_clean', 'b' => 'user_last_warning', 'c' => 'user_warnings');
|
||||
|
||||
$s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
|
||||
gen_sort_selects($limit_days, $sort_by_text, $st, $sk, $sd, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param);
|
||||
|
||||
// Define where and sort sql for use in displaying logs
|
||||
$sql_where = ($st) ? (time() - ($st * 86400)) : 0;
|
||||
$sql_sort = $sort_by_sql[$sk] . ' ' . (($sd == 'd') ? 'DESC' : 'ASC');
|
||||
|
||||
$users = array();
|
||||
$user_count = 0;
|
||||
|
||||
view_warned_users($users, $user_count, $config['topics_per_page'], $start, $sql_where, $sql_sort);
|
||||
|
||||
foreach ($users as $row)
|
||||
{
|
||||
$template->assign_block_vars('user', array(
|
||||
'U_NOTES' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes&u=' . $row['user_id']),
|
||||
|
||||
'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
|
||||
|
||||
'WARNING_TIME' => $user->format_date($row['user_last_warning']),
|
||||
'WARNINGS' => $row['user_warnings'],
|
||||
));
|
||||
}
|
||||
|
||||
$base_url = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=warn&mode=list&st=$st&sk=$sk&sd=$sd");
|
||||
$pagination->generate_template_pagination($base_url, 'pagination', 'start', $user_count, $config['topics_per_page'], $start);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_POST_ACTION' => $this->u_action,
|
||||
'S_CLEAR_ALLOWED' => ($auth->acl_get('a_clearlogs')) ? true : false,
|
||||
'S_SELECT_SORT_DIR' => $s_sort_dir,
|
||||
'S_SELECT_SORT_KEY' => $s_sort_key,
|
||||
'S_SELECT_SORT_DAYS' => $s_limit_days,
|
||||
|
||||
'TOTAL_USERS' => $user->lang('LIST_USERS', (int) $user_count),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles warning the user when the warning is for a specific post
|
||||
*/
|
||||
function mcp_warn_post_view($action)
|
||||
{
|
||||
global $phpEx, $phpbb_root_path, $config, $request;
|
||||
global $template, $db, $user, $phpbb_dispatcher;
|
||||
|
||||
$post_id = $request->variable('p', 0);
|
||||
$forum_id = $request->variable('f', 0);
|
||||
$notify = (isset($_REQUEST['notify_user'])) ? true : false;
|
||||
$warning = $request->variable('warning', '', true);
|
||||
|
||||
$sql = 'SELECT u.*, p.*
|
||||
FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u
|
||||
WHERE p.post_id = $post_id
|
||||
AND u.user_id = p.poster_id";
|
||||
$result = $db->sql_query($sql);
|
||||
$user_row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$user_row)
|
||||
{
|
||||
trigger_error('NO_POST');
|
||||
}
|
||||
|
||||
// There is no point issuing a warning to ignored users (ie anonymous and bots)
|
||||
if ($user_row['user_type'] == USER_IGNORE)
|
||||
{
|
||||
trigger_error('CANNOT_WARN_ANONYMOUS');
|
||||
}
|
||||
|
||||
// Prevent someone from warning themselves
|
||||
if ($user_row['user_id'] == $user->data['user_id'])
|
||||
{
|
||||
trigger_error('CANNOT_WARN_SELF');
|
||||
}
|
||||
|
||||
// Check if there is already a warning for this post to prevent multiple
|
||||
// warnings for the same offence
|
||||
$sql = 'SELECT post_id
|
||||
FROM ' . WARNINGS_TABLE . "
|
||||
WHERE post_id = $post_id";
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($row)
|
||||
{
|
||||
trigger_error('ALREADY_WARNED');
|
||||
}
|
||||
|
||||
$user_id = $user_row['user_id'];
|
||||
|
||||
if (strpos($this->u_action, "&f=$forum_id&p=$post_id") === false)
|
||||
{
|
||||
$this->p_master->adjust_url("&f=$forum_id&p=$post_id");
|
||||
$this->u_action .= "&f=$forum_id&p=$post_id";
|
||||
}
|
||||
|
||||
// Check if can send a notification
|
||||
if ($config['allow_privmsg'])
|
||||
{
|
||||
$auth2 = new \phpbb\auth\auth();
|
||||
$auth2->acl($user_row);
|
||||
$s_can_notify = ($auth2->acl_get('u_readpm')) ? true : false;
|
||||
unset($auth2);
|
||||
}
|
||||
else
|
||||
{
|
||||
$s_can_notify = false;
|
||||
}
|
||||
|
||||
// Prevent against clever people
|
||||
if ($notify && !$s_can_notify)
|
||||
{
|
||||
$notify = false;
|
||||
}
|
||||
|
||||
if ($warning && $action == 'add_warning')
|
||||
{
|
||||
if (check_form_key('mcp_warn'))
|
||||
{
|
||||
$s_mcp_warn_post = true;
|
||||
|
||||
/**
|
||||
* Event for before warning a user for a post.
|
||||
*
|
||||
* @event core.mcp_warn_post_before
|
||||
* @var array user_row The entire user row
|
||||
* @var string warning The warning message
|
||||
* @var bool notify If true, we notify the user for the warning
|
||||
* @var int post_id The post id for which the warning is added
|
||||
* @var bool s_mcp_warn_post If true, we add the warning else we omit it
|
||||
* @since 3.1.0-b4
|
||||
*/
|
||||
$vars = array(
|
||||
'user_row',
|
||||
'warning',
|
||||
'notify',
|
||||
'post_id',
|
||||
's_mcp_warn_post',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_warn_post_before', compact($vars)));
|
||||
|
||||
if ($s_mcp_warn_post)
|
||||
{
|
||||
add_warning($user_row, $warning, $notify, $post_id);
|
||||
$message = $user->lang['USER_WARNING_ADDED'];
|
||||
|
||||
/**
|
||||
* Event for after warning a user for a post.
|
||||
*
|
||||
* @event core.mcp_warn_post_after
|
||||
* @var array user_row The entire user row
|
||||
* @var string warning The warning message
|
||||
* @var bool notify If true, the user was notified for the warning
|
||||
* @var int post_id The post id for which the warning is added
|
||||
* @var string message Message displayed to the moderator
|
||||
* @since 3.1.0-b4
|
||||
*/
|
||||
$vars = array(
|
||||
'user_row',
|
||||
'warning',
|
||||
'notify',
|
||||
'post_id',
|
||||
'message',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_warn_post_after', compact($vars)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = $user->lang['FORM_INVALID'];
|
||||
}
|
||||
|
||||
if (!empty($message))
|
||||
{
|
||||
$redirect = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=notes&mode=user_notes&u=$user_id");
|
||||
meta_refresh(2, $redirect);
|
||||
trigger_error($message . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>'));
|
||||
}
|
||||
}
|
||||
|
||||
// OK, they didn't submit a warning so lets build the page for them to do so
|
||||
|
||||
// We want to make the message available here as a reminder
|
||||
// Parse the message and subject
|
||||
$parse_flags = OPTION_FLAG_SMILIES | ($user_row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0);
|
||||
$message = generate_text_for_display($user_row['post_text'], $user_row['bbcode_uid'], $user_row['bbcode_bitfield'], $parse_flags, true);
|
||||
|
||||
// Generate the appropriate user information for the user we are looking at
|
||||
if (!function_exists('phpbb_get_user_rank'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
|
||||
}
|
||||
|
||||
$user_rank_data = phpbb_get_user_rank($user_row, $user_row['user_posts']);
|
||||
$avatar_img = phpbb_get_user_avatar($user_row);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_POST_ACTION' => $this->u_action,
|
||||
|
||||
'POST' => $message,
|
||||
'USERNAME' => $user_row['username'],
|
||||
'USER_COLOR' => (!empty($user_row['user_colour'])) ? $user_row['user_colour'] : '',
|
||||
'RANK_TITLE' => $user_rank_data['title'],
|
||||
'JOINED' => $user->format_date($user_row['user_regdate']),
|
||||
'POSTS' => ($user_row['user_posts']) ? $user_row['user_posts'] : 0,
|
||||
'WARNINGS' => ($user_row['user_warnings']) ? $user_row['user_warnings'] : 0,
|
||||
|
||||
'AVATAR_IMG' => $avatar_img,
|
||||
'RANK_IMG' => $user_rank_data['img'],
|
||||
|
||||
'L_WARNING_POST_DEFAULT' => sprintf($user->lang['WARNING_POST_DEFAULT'], generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&p=$post_id#p$post_id"),
|
||||
|
||||
'S_CAN_NOTIFY' => $s_can_notify,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles warning the user
|
||||
*/
|
||||
function mcp_warn_user_view($action)
|
||||
{
|
||||
global $phpEx, $phpbb_root_path, $config, $request;
|
||||
global $template, $db, $user, $phpbb_dispatcher;
|
||||
|
||||
$user_id = $request->variable('u', 0);
|
||||
$username = $request->variable('username', '', true);
|
||||
$notify = (isset($_REQUEST['notify_user'])) ? true : false;
|
||||
$warning = $request->variable('warning', '', true);
|
||||
|
||||
$sql_where = ($user_id) ? "user_id = $user_id" : "username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
|
||||
|
||||
$sql = 'SELECT *
|
||||
FROM ' . USERS_TABLE . '
|
||||
WHERE ' . $sql_where;
|
||||
$result = $db->sql_query($sql);
|
||||
$user_row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$user_row)
|
||||
{
|
||||
trigger_error('NO_USER');
|
||||
}
|
||||
|
||||
// Prevent someone from warning themselves
|
||||
if ($user_row['user_id'] == $user->data['user_id'])
|
||||
{
|
||||
trigger_error('CANNOT_WARN_SELF');
|
||||
}
|
||||
|
||||
$user_id = $user_row['user_id'];
|
||||
|
||||
if (strpos($this->u_action, "&u=$user_id") === false)
|
||||
{
|
||||
$this->p_master->adjust_url('&u=' . $user_id);
|
||||
$this->u_action .= "&u=$user_id";
|
||||
}
|
||||
|
||||
// Check if can send a notification
|
||||
if ($config['allow_privmsg'])
|
||||
{
|
||||
$auth2 = new \phpbb\auth\auth();
|
||||
$auth2->acl($user_row);
|
||||
$s_can_notify = ($auth2->acl_get('u_readpm')) ? true : false;
|
||||
unset($auth2);
|
||||
}
|
||||
else
|
||||
{
|
||||
$s_can_notify = false;
|
||||
}
|
||||
|
||||
// Prevent against clever people
|
||||
if ($notify && !$s_can_notify)
|
||||
{
|
||||
$notify = false;
|
||||
}
|
||||
|
||||
if ($warning && $action == 'add_warning')
|
||||
{
|
||||
if (check_form_key('mcp_warn'))
|
||||
{
|
||||
$s_mcp_warn_user = true;
|
||||
|
||||
/**
|
||||
* Event for before warning a user from MCP.
|
||||
*
|
||||
* @event core.mcp_warn_user_before
|
||||
* @var array user_row The entire user row
|
||||
* @var string warning The warning message
|
||||
* @var bool notify If true, we notify the user for the warning
|
||||
* @var bool s_mcp_warn_user If true, we add the warning else we omit it
|
||||
* @since 3.1.0-b4
|
||||
*/
|
||||
$vars = array(
|
||||
'user_row',
|
||||
'warning',
|
||||
'notify',
|
||||
's_mcp_warn_user',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_warn_user_before', compact($vars)));
|
||||
|
||||
if ($s_mcp_warn_user)
|
||||
{
|
||||
add_warning($user_row, $warning, $notify);
|
||||
$message = $user->lang['USER_WARNING_ADDED'];
|
||||
|
||||
/**
|
||||
* Event for after warning a user from MCP.
|
||||
*
|
||||
* @event core.mcp_warn_user_after
|
||||
* @var array user_row The entire user row
|
||||
* @var string warning The warning message
|
||||
* @var bool notify If true, the user was notified for the warning
|
||||
* @var string message Message displayed to the moderator
|
||||
* @since 3.1.0-b4
|
||||
*/
|
||||
$vars = array(
|
||||
'user_row',
|
||||
'warning',
|
||||
'notify',
|
||||
'message',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.mcp_warn_user_after', compact($vars)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = $user->lang['FORM_INVALID'];
|
||||
}
|
||||
|
||||
if (!empty($message))
|
||||
{
|
||||
$redirect = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=notes&mode=user_notes&u=$user_id");
|
||||
meta_refresh(2, $redirect);
|
||||
trigger_error($message . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>'));
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the appropriate user information for the user we are looking at
|
||||
if (!function_exists('phpbb_get_user_rank'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
|
||||
}
|
||||
$user_rank_data = phpbb_get_user_rank($user_row, $user_row['user_posts']);
|
||||
$avatar_img = phpbb_get_user_avatar($user_row);
|
||||
|
||||
// OK, they didn't submit a warning so lets build the page for them to do so
|
||||
$template->assign_vars(array(
|
||||
'U_POST_ACTION' => $this->u_action,
|
||||
|
||||
'RANK_TITLE' => $user_rank_data['title'],
|
||||
'JOINED' => $user->format_date($user_row['user_regdate']),
|
||||
'POSTS' => ($user_row['user_posts']) ? $user_row['user_posts'] : 0,
|
||||
'WARNINGS' => ($user_row['user_warnings']) ? $user_row['user_warnings'] : 0,
|
||||
|
||||
'USERNAME_FULL' => get_username_string('full', $user_row['user_id'], $user_row['username'], $user_row['user_colour']),
|
||||
'USERNAME_COLOUR' => get_username_string('colour', $user_row['user_id'], $user_row['username'], $user_row['user_colour']),
|
||||
'USERNAME' => get_username_string('username', $user_row['user_id'], $user_row['username'], $user_row['user_colour']),
|
||||
'U_PROFILE' => get_username_string('profile', $user_row['user_id'], $user_row['username'], $user_row['user_colour']),
|
||||
|
||||
'AVATAR_IMG' => $avatar_img,
|
||||
'RANK_IMG' => $user_rank_data['img'],
|
||||
|
||||
'S_CAN_NOTIFY' => $s_can_notify,
|
||||
));
|
||||
|
||||
return $user_id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the warning into the database
|
||||
*/
|
||||
function add_warning($user_row, $warning, $send_pm = true, $post_id = 0)
|
||||
{
|
||||
global $phpEx, $phpbb_root_path, $config, $phpbb_log;
|
||||
global $db, $user;
|
||||
|
||||
if ($send_pm)
|
||||
{
|
||||
include_once($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
|
||||
include_once($phpbb_root_path . 'includes/message_parser.' . $phpEx);
|
||||
|
||||
// Attempt to translate warning to language of user being warned if user's language differs from issuer's language
|
||||
if ($user_row['user_lang'] != $user->lang_name)
|
||||
{
|
||||
$lang = array();
|
||||
|
||||
$user_row['user_lang'] = (file_exists($phpbb_root_path . 'language/' . basename($user_row['user_lang']) . "/mcp." . $phpEx)) ? $user_row['user_lang'] : $config['default_lang'];
|
||||
include($phpbb_root_path . 'language/' . basename($user_row['user_lang']) . "/mcp." . $phpEx);
|
||||
|
||||
$warn_pm_subject = $lang['WARNING_PM_SUBJECT'];
|
||||
$warn_pm_body = sprintf($lang['WARNING_PM_BODY'], $warning);
|
||||
|
||||
unset($lang);
|
||||
}
|
||||
else
|
||||
{
|
||||
$warn_pm_subject = $user->lang('WARNING_PM_SUBJECT');
|
||||
$warn_pm_body = $user->lang('WARNING_PM_BODY', $warning);
|
||||
}
|
||||
|
||||
$message_parser = new parse_message();
|
||||
|
||||
$message_parser->message = $warn_pm_body;
|
||||
$message_parser->parse(true, true, true, false, false, true, true);
|
||||
|
||||
$pm_data = array(
|
||||
'from_user_id' => $user->data['user_id'],
|
||||
'from_user_ip' => $user->ip,
|
||||
'from_username' => $user->data['username'],
|
||||
'enable_sig' => false,
|
||||
'enable_bbcode' => true,
|
||||
'enable_smilies' => true,
|
||||
'enable_urls' => false,
|
||||
'icon_id' => 0,
|
||||
'bbcode_bitfield' => $message_parser->bbcode_bitfield,
|
||||
'bbcode_uid' => $message_parser->bbcode_uid,
|
||||
'message' => $message_parser->message,
|
||||
'address_list' => array('u' => array($user_row['user_id'] => 'to')),
|
||||
);
|
||||
|
||||
submit_pm('post', $warn_pm_subject, $pm_data, false);
|
||||
}
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_USER_WARNING', false, array($user_row['username']));
|
||||
$log_id = $phpbb_log->add('user', $user->data['user_id'], $user->ip, 'LOG_USER_WARNING_BODY', false, array(
|
||||
'reportee_id' => $user_row['user_id'],
|
||||
$warning
|
||||
));
|
||||
|
||||
$sql_ary = array(
|
||||
'user_id' => $user_row['user_id'],
|
||||
'post_id' => $post_id,
|
||||
'log_id' => $log_id,
|
||||
'warning_time' => time(),
|
||||
);
|
||||
|
||||
$db->sql_query('INSERT INTO ' . WARNINGS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
|
||||
|
||||
$sql = 'UPDATE ' . USERS_TABLE . '
|
||||
SET user_warnings = user_warnings + 1,
|
||||
user_last_warning = ' . time() . '
|
||||
WHERE user_id = ' . $user_row['user_id'];
|
||||
$db->sql_query($sql);
|
||||
|
||||
// We add this to the mod log too for moderators to see that a specific user got warned.
|
||||
$sql = 'SELECT forum_id, topic_id
|
||||
FROM ' . POSTS_TABLE . '
|
||||
WHERE post_id = ' . $post_id;
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_USER_WARNING', false, array(
|
||||
'forum_id' => $row['forum_id'],
|
||||
'topic_id' => $row['topic_id'],
|
||||
'post_id' => $post_id,
|
||||
$user_row['username']
|
||||
));
|
||||
}
|
||||
2087
install/update/new/includes/message_parser.php
Normal file
2087
install/update/new/includes/message_parser.php
Normal file
File diff suppressed because it is too large
Load Diff
497
install/update/new/includes/questionnaire/questionnaire.php
Normal file
497
install/update/new/includes/questionnaire/questionnaire.php
Normal file
@@ -0,0 +1,497 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class collects data which is used to create some usage statistics.
|
||||
*
|
||||
* The collected data is - after authorization of the administrator - submitted
|
||||
* to a central server. For privacy reasons we try to collect only data which aren't private
|
||||
* or don't give any information which might help to identify the user.
|
||||
*
|
||||
* @author Johannes Schlueter <johannes@php.net>
|
||||
* @copyright (c) 2007-2008 Johannes Schlueter
|
||||
*/
|
||||
class phpbb_questionnaire_data_collector
|
||||
{
|
||||
var $providers;
|
||||
var $data = null;
|
||||
var $install_id = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string
|
||||
*/
|
||||
function __construct($install_id)
|
||||
{
|
||||
$this->install_id = $install_id;
|
||||
$this->providers = array();
|
||||
}
|
||||
|
||||
function add_data_provider($provider)
|
||||
{
|
||||
$this->providers[] = $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data as an array.
|
||||
*
|
||||
* @return array All Data
|
||||
*/
|
||||
function get_data_raw()
|
||||
{
|
||||
if (!$this->data)
|
||||
{
|
||||
$this->collect();
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
function get_data_for_form()
|
||||
{
|
||||
return base64_encode(json_encode($this->get_data_raw()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect info into the data property.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
function collect()
|
||||
{
|
||||
foreach (array_keys($this->providers) as $key)
|
||||
{
|
||||
$provider = $this->providers[$key];
|
||||
$this->data[$provider->get_identifier()] = $provider->get_data();
|
||||
}
|
||||
$this->data['install_id'] = $this->install_id;
|
||||
}
|
||||
}
|
||||
|
||||
/** interface: get_indentifier(), get_data() */
|
||||
|
||||
/**
|
||||
* Questionnaire PHP data provider
|
||||
*/
|
||||
class phpbb_questionnaire_php_data_provider
|
||||
{
|
||||
function get_identifier()
|
||||
{
|
||||
return 'PHP';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data about the PHP runtime setup.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_data()
|
||||
{
|
||||
return array(
|
||||
'version' => PHP_VERSION,
|
||||
'sapi' => PHP_SAPI,
|
||||
'int_size' => defined('PHP_INT_SIZE') ? PHP_INT_SIZE : '',
|
||||
'open_basedir' => (int) @ini_get('open_basedir'),
|
||||
'memory_limit' => @ini_get('memory_limit'),
|
||||
'allow_url_fopen' => (int) @ini_get('allow_url_fopen'),
|
||||
'allow_url_include' => (int) @ini_get('allow_url_include'),
|
||||
'file_uploads' => (int) @ini_get('file_uploads'),
|
||||
'upload_max_filesize' => @ini_get('upload_max_filesize'),
|
||||
'post_max_size' => @ini_get('post_max_size'),
|
||||
'disable_functions' => @ini_get('disable_functions'),
|
||||
'disable_classes' => @ini_get('disable_classes'),
|
||||
'enable_dl' => (int) @ini_get('enable_dl'),
|
||||
'filter.default' => @ini_get('filter.default'),
|
||||
'zend.ze1_compatibility_mode' => (int) @ini_get('zend.ze1_compatibility_mode'),
|
||||
'unicode.semantics' => (int) @ini_get('unicode.semantics'),
|
||||
'zend_thread_safty' => (int) function_exists('zend_thread_id'),
|
||||
'extensions' => implode(',', get_loaded_extensions()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Questionnaire System data provider
|
||||
*/
|
||||
class phpbb_questionnaire_system_data_provider
|
||||
{
|
||||
function get_identifier()
|
||||
{
|
||||
return 'System';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data about the general system information, like OS or IP (shortened).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_data()
|
||||
{
|
||||
global $request;
|
||||
|
||||
// Start discovering the IPV4 server address, if available
|
||||
// Try apache, IIS, fall back to 0.0.0.0
|
||||
$server_address = htmlspecialchars_decode($request->server('SERVER_ADDR', $request->server('LOCAL_ADDR', '0.0.0.0')));
|
||||
|
||||
return array(
|
||||
'os' => PHP_OS,
|
||||
'httpd' => htmlspecialchars_decode($request->server('SERVER_SOFTWARE')),
|
||||
// we don't want the real IP address (for privacy policy reasons) but only
|
||||
// a network address to see whether your installation is running on a private or public network.
|
||||
'private_ip' => $this->is_private_ip($server_address),
|
||||
'ipv6' => strpos($server_address, ':') !== false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given IP is in a private network.
|
||||
*
|
||||
* @param string $ip IP in v4 dot-decimal or v6 hex format
|
||||
* @return bool true if the IP is from a private network, else false
|
||||
*/
|
||||
function is_private_ip($ip)
|
||||
{
|
||||
// IPv4
|
||||
if (strpos($ip, ':') === false)
|
||||
{
|
||||
$ip_address_ary = explode('.', $ip);
|
||||
|
||||
// build ip
|
||||
if (!isset($ip_address_ary[0]) || !isset($ip_address_ary[1]))
|
||||
{
|
||||
$ip_address_ary = explode('.', '0.0.0.0');
|
||||
}
|
||||
|
||||
// IANA reserved addresses for private networks (RFC 1918) are:
|
||||
// - 10.0.0.0/8
|
||||
// - 172.16.0.0/12
|
||||
// - 192.168.0.0/16
|
||||
if ($ip_address_ary[0] == '10' ||
|
||||
($ip_address_ary[0] == '172' && intval($ip_address_ary[1]) > 15 && intval($ip_address_ary[1]) < 32) ||
|
||||
($ip_address_ary[0] == '192' && $ip_address_ary[1] == '168'))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// IPv6
|
||||
else
|
||||
{
|
||||
// unique local unicast
|
||||
$prefix = substr($ip, 0, 2);
|
||||
if ($prefix == 'fc' || $prefix == 'fd')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Questionnaire phpBB data provider
|
||||
*/
|
||||
class phpbb_questionnaire_phpbb_data_provider
|
||||
{
|
||||
var $config;
|
||||
var $unique_id;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config
|
||||
*/
|
||||
function __construct($config)
|
||||
{
|
||||
// generate a unique id if necessary
|
||||
if (empty($config['questionnaire_unique_id']))
|
||||
{
|
||||
$this->unique_id = unique_id();
|
||||
$config->set('questionnaire_unique_id', $this->unique_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->unique_id = $config['questionnaire_unique_id'];
|
||||
}
|
||||
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string identifier for this data provider
|
||||
*
|
||||
* @return string "phpBB"
|
||||
*/
|
||||
function get_identifier()
|
||||
{
|
||||
return 'phpBB';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data about this phpBB installation.
|
||||
*
|
||||
* @return array Relevant anonymous config options
|
||||
*/
|
||||
function get_data()
|
||||
{
|
||||
global $phpbb_config_php_file;
|
||||
|
||||
extract($phpbb_config_php_file->get_all());
|
||||
unset($dbhost, $dbport, $dbname, $dbuser, $dbpasswd); // Just a precaution
|
||||
|
||||
$dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);
|
||||
|
||||
// Only send certain config vars
|
||||
$config_vars = array(
|
||||
'active_sessions' => true,
|
||||
'allow_attachments' => true,
|
||||
'allow_autologin' => true,
|
||||
'allow_avatar' => true,
|
||||
'allow_avatar_local' => true,
|
||||
'allow_avatar_remote' => true,
|
||||
'allow_avatar_upload' => true,
|
||||
'allow_bbcode' => true,
|
||||
'allow_birthdays' => true,
|
||||
'allow_bookmarks' => true,
|
||||
'allow_emailreuse' => true,
|
||||
'allow_forum_notify' => true,
|
||||
'allow_mass_pm' => true,
|
||||
'allow_name_chars' => true,
|
||||
'allow_namechange' => true,
|
||||
'allow_nocensors' => true,
|
||||
'allow_pm_attach' => true,
|
||||
'allow_pm_report' => true,
|
||||
'allow_post_flash' => true,
|
||||
'allow_post_links' => true,
|
||||
'allow_privmsg' => true,
|
||||
'allow_quick_reply' => true,
|
||||
'allow_sig' => true,
|
||||
'allow_sig_bbcode' => true,
|
||||
'allow_sig_flash' => true,
|
||||
'allow_sig_img' => true,
|
||||
'allow_sig_links' => true,
|
||||
'allow_sig_pm' => true,
|
||||
'allow_sig_smilies' => true,
|
||||
'allow_smilies' => true,
|
||||
'allow_topic_notify' => true,
|
||||
'attachment_quota' => true,
|
||||
'auth_bbcode_pm' => true,
|
||||
'auth_flash_pm' => true,
|
||||
'auth_img_pm' => true,
|
||||
'auth_method' => true,
|
||||
'auth_smilies_pm' => true,
|
||||
'avatar_filesize' => true,
|
||||
'avatar_max_height' => true,
|
||||
'avatar_max_width' => true,
|
||||
'avatar_min_height' => true,
|
||||
'avatar_min_width' => true,
|
||||
'board_email_form' => true,
|
||||
'board_hide_emails' => true,
|
||||
'board_timezone' => true,
|
||||
'browser_check' => true,
|
||||
'bump_interval' => true,
|
||||
'bump_type' => true,
|
||||
'cache_gc' => true,
|
||||
'captcha_plugin' => true,
|
||||
'captcha_gd' => true,
|
||||
'captcha_gd_foreground_noise' => true,
|
||||
'captcha_gd_x_grid' => true,
|
||||
'captcha_gd_y_grid' => true,
|
||||
'captcha_gd_wave' => true,
|
||||
'captcha_gd_3d_noise' => true,
|
||||
'captcha_gd_fonts' => true,
|
||||
'confirm_refresh' => true,
|
||||
'check_attachment_content' => true,
|
||||
'check_dnsbl' => true,
|
||||
'chg_passforce' => true,
|
||||
'cookie_secure' => true,
|
||||
'coppa_enable' => true,
|
||||
'database_gc' => true,
|
||||
'dbms_version' => true,
|
||||
'default_dateformat' => true,
|
||||
'default_lang' => true,
|
||||
'display_last_edited' => true,
|
||||
'display_order' => true,
|
||||
'edit_time' => true,
|
||||
'email_check_mx' => true,
|
||||
'email_enable' => true,
|
||||
'email_force_sender' => true,
|
||||
'email_package_size' => true,
|
||||
'enable_confirm' => true,
|
||||
'enable_pm_icons' => true,
|
||||
'enable_post_confirm' => true,
|
||||
'feed_enable' => true,
|
||||
'feed_http_auth' => true,
|
||||
'feed_limit_post' => true,
|
||||
'feed_limit_topic' => true,
|
||||
'feed_overall' => true,
|
||||
'feed_overall_forums' => true,
|
||||
'feed_forum' => true,
|
||||
'feed_topic' => true,
|
||||
'feed_topics_new' => true,
|
||||
'feed_topics_active' => true,
|
||||
'feed_item_statistics' => true,
|
||||
'flood_interval' => true,
|
||||
'force_server_vars' => true,
|
||||
'form_token_lifetime' => true,
|
||||
'form_token_mintime' => true,
|
||||
'form_token_sid_guests' => true,
|
||||
'forward_pm' => true,
|
||||
'forwarded_for_check' => true,
|
||||
'full_folder_action' => true,
|
||||
'fulltext_native_common_thres' => true,
|
||||
'fulltext_native_load_upd' => true,
|
||||
'fulltext_native_max_chars' => true,
|
||||
'fulltext_native_min_chars' => true,
|
||||
'gzip_compress' => true,
|
||||
'hot_threshold' => true,
|
||||
'img_create_thumbnail' => true,
|
||||
'img_display_inlined' => true,
|
||||
'img_link_height' => true,
|
||||
'img_link_width' => true,
|
||||
'img_max_height' => true,
|
||||
'img_max_thumb_width' => true,
|
||||
'img_max_width' => true,
|
||||
'img_min_thumb_filesize' => true,
|
||||
'ip_check' => true,
|
||||
'jab_enable' => true,
|
||||
'jab_package_size' => true,
|
||||
'jab_use_ssl' => true,
|
||||
'limit_load' => true,
|
||||
'limit_search_load' => true,
|
||||
'load_anon_lastread' => true,
|
||||
'load_birthdays' => true,
|
||||
'load_cpf_memberlist' => true,
|
||||
'load_cpf_viewprofile' => true,
|
||||
'load_cpf_viewtopic' => true,
|
||||
'load_db_lastread' => true,
|
||||
'load_db_track' => true,
|
||||
'load_jumpbox' => true,
|
||||
'load_moderators' => true,
|
||||
'load_online' => true,
|
||||
'load_online_guests' => true,
|
||||
'load_online_time' => true,
|
||||
'load_onlinetrack' => true,
|
||||
'load_search' => true,
|
||||
'load_tplcompile' => true,
|
||||
'load_user_activity' => true,
|
||||
'max_attachments' => true,
|
||||
'max_attachments_pm' => true,
|
||||
'max_autologin_time' => true,
|
||||
'max_filesize' => true,
|
||||
'max_filesize_pm' => true,
|
||||
'max_login_attempts' => true,
|
||||
'max_name_chars' => true,
|
||||
'max_num_search_keywords' => true,
|
||||
'max_poll_options' => true,
|
||||
'max_post_chars' => true,
|
||||
'max_post_font_size' => true,
|
||||
'max_post_img_height' => true,
|
||||
'max_post_img_width' => true,
|
||||
'max_post_smilies' => true,
|
||||
'max_post_urls' => true,
|
||||
'max_quote_depth' => true,
|
||||
'max_reg_attempts' => true,
|
||||
'max_sig_chars' => true,
|
||||
'max_sig_font_size' => true,
|
||||
'max_sig_img_height' => true,
|
||||
'max_sig_img_width' => true,
|
||||
'max_sig_smilies' => true,
|
||||
'max_sig_urls' => true,
|
||||
'min_name_chars' => true,
|
||||
'min_pass_chars' => true,
|
||||
'min_post_chars' => true,
|
||||
'min_search_author_chars' => true,
|
||||
'mime_triggers' => true,
|
||||
'new_member_post_limit' => true,
|
||||
'new_member_group_default' => true,
|
||||
'override_user_style' => true,
|
||||
'pass_complex' => true,
|
||||
'pm_edit_time' => true,
|
||||
'pm_max_boxes' => true,
|
||||
'pm_max_msgs' => true,
|
||||
'pm_max_recipients' => true,
|
||||
'posts_per_page' => true,
|
||||
'print_pm' => true,
|
||||
'queue_interval' => true,
|
||||
'require_activation' => true,
|
||||
'referer_validation' => true,
|
||||
'search_block_size' => true,
|
||||
'search_gc' => true,
|
||||
'search_interval' => true,
|
||||
'search_anonymous_interval' => true,
|
||||
'search_type' => true,
|
||||
'search_store_results' => true,
|
||||
'secure_allow_deny' => true,
|
||||
'secure_allow_empty_referer' => true,
|
||||
'secure_downloads' => true,
|
||||
'session_gc' => true,
|
||||
'session_length' => true,
|
||||
'smtp_auth_method' => true,
|
||||
'smtp_delivery' => true,
|
||||
'topics_per_page' => true,
|
||||
'tpl_allow_php' => true,
|
||||
'version' => true,
|
||||
'warnings_expire_days' => true,
|
||||
'warnings_gc' => true,
|
||||
|
||||
'num_files' => true,
|
||||
'num_posts' => true,
|
||||
'num_topics' => true,
|
||||
'num_users' => true,
|
||||
'record_online_users' => true,
|
||||
);
|
||||
|
||||
$result = array();
|
||||
foreach ($config_vars as $name => $void)
|
||||
{
|
||||
if (isset($this->config[$name]))
|
||||
{
|
||||
$result['config_' . $name] = $this->config[$name];
|
||||
}
|
||||
}
|
||||
|
||||
global $db, $request;
|
||||
|
||||
$result['dbms'] = $dbms;
|
||||
$result['acm_type'] = $acm_type;
|
||||
$result['user_agent'] = 'Unknown';
|
||||
$result['dbms_version'] = $db->sql_server_info(true);
|
||||
|
||||
// Try to get user agent vendor and version
|
||||
$match = array();
|
||||
$user_agent = $request->header('User-Agent');
|
||||
$agents = array('firefox', 'msie', 'opera', 'chrome', 'safari', 'mozilla', 'seamonkey', 'konqueror', 'netscape', 'gecko', 'navigator', 'mosaic', 'lynx', 'amaya', 'omniweb', 'avant', 'camino', 'flock', 'aol');
|
||||
|
||||
// We check here 1 by 1 because some strings occur after others (for example Mozilla [...] Firefox/)
|
||||
foreach ($agents as $agent)
|
||||
{
|
||||
if (preg_match('#(' . $agent . ')[/ ]?([0-9.]*)#i', $user_agent, $match))
|
||||
{
|
||||
$result['user_agent'] = $match[1] . ' ' . $match[2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
86
install/update/new/includes/startup.php
Normal file
86
install/update/new/includes/startup.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
// Report all errors, except notices and deprecation messages
|
||||
$level = E_ALL & ~E_NOTICE & ~E_DEPRECATED;
|
||||
error_reporting($level);
|
||||
|
||||
/**
|
||||
* Minimum Requirement: PHP 7.1.3
|
||||
*/
|
||||
if (version_compare(PHP_VERSION, '7.1.3', '<'))
|
||||
{
|
||||
die('You are running an unsupported PHP version. Please upgrade to PHP 7.1.3 or higher before trying to install or update to phpBB 3.3');
|
||||
}
|
||||
// Register globals and magic quotes have been dropped in PHP 5.4 so no need for extra checks
|
||||
|
||||
|
||||
// In PHP 5.3.0 the error level has been raised to E_WARNING which causes problems
|
||||
// because we show E_WARNING errors and do not set a default timezone.
|
||||
// This is because we have our own timezone handling and work in UTC only anyway.
|
||||
|
||||
// So what we basically want to do is set our timezone to UTC,
|
||||
// but we don't know what other scripts (such as bridges) are involved,
|
||||
// so we check whether a timezone is already set by calling date_default_timezone_get().
|
||||
|
||||
// Unfortunately, date_default_timezone_get() itself might throw E_WARNING
|
||||
// if no timezone has been set, so we have to keep it quiet with @.
|
||||
|
||||
// date_default_timezone_get() tries to guess the correct timezone first
|
||||
// and then falls back to UTC when everything fails.
|
||||
// We just set the timezone to whatever date_default_timezone_get() returns.
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
// Autoloading of dependencies.
|
||||
// Three options are supported:
|
||||
// 1. If dependencies are installed with Composer, Composer will create a
|
||||
// vendor/autoload.php. If this file exists it will be
|
||||
// automatically used by phpBB. This is the default mode that phpBB
|
||||
// will use when shipped.
|
||||
// 2. To disable composer autoloading, PHPBB_NO_COMPOSER_AUTOLOAD can be specified.
|
||||
// Additionally specify PHPBB_AUTOLOAD=/path/to/autoload.php in the
|
||||
// environment. This is useful for running CLI scripts and tests.
|
||||
// /path/to/autoload.php should define and register class loaders
|
||||
// for all of phpBB's dependencies.
|
||||
// 3. You can also set PHPBB_NO_COMPOSER_AUTOLOAD without setting PHPBB_AUTOLOAD.
|
||||
// In this case autoloading needs to be defined before running any phpBB
|
||||
// script. This might be useful in cases when phpBB is integrated into a
|
||||
// larger program.
|
||||
if (getenv('PHPBB_NO_COMPOSER_AUTOLOAD'))
|
||||
{
|
||||
if (getenv('PHPBB_AUTOLOAD'))
|
||||
{
|
||||
require(getenv('PHPBB_AUTOLOAD'));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!file_exists($phpbb_root_path . 'vendor/autoload.php'))
|
||||
{
|
||||
trigger_error(
|
||||
'Composer dependencies have not been set up yet, run ' .
|
||||
"'php ../composer.phar install' from the phpBB directory to do so.",
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
require($phpbb_root_path . 'vendor/autoload.php');
|
||||
}
|
||||
|
||||
$starttime = microtime(true);
|
||||
219
install/update/new/includes/ucp/ucp_attachments.php
Normal file
219
install/update/new/includes/ucp/ucp_attachments.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* ucp_attachments
|
||||
* User attachments
|
||||
*/
|
||||
class ucp_attachments
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $template, $user, $db, $config, $phpEx, $phpbb_root_path, $phpbb_container, $request, $auth;
|
||||
|
||||
$start = $request->variable('start', 0);
|
||||
$sort_key = $request->variable('sk', 'a');
|
||||
$sort_dir = $request->variable('sd', 'a');
|
||||
|
||||
$delete = (isset($_POST['delete'])) ? true : false;
|
||||
$delete_ids = array_keys($request->variable('attachment', array(0)));
|
||||
|
||||
if ($delete && count($delete_ids))
|
||||
{
|
||||
// Validate $delete_ids...
|
||||
$sql = 'SELECT a.attach_id, p.post_edit_locked, t.topic_status, f.forum_id, f.forum_status
|
||||
FROM ' . ATTACHMENTS_TABLE . ' a
|
||||
LEFT JOIN ' . POSTS_TABLE . ' p
|
||||
ON (a.post_msg_id = p.post_id AND a.in_message = 0)
|
||||
LEFT JOIN ' . TOPICS_TABLE . ' t
|
||||
ON (t.topic_id = p.topic_id AND a.in_message = 0)
|
||||
LEFT JOIN ' . FORUMS_TABLE . ' f
|
||||
ON (f.forum_id = t.forum_id AND a.in_message = 0)
|
||||
WHERE a.poster_id = ' . $user->data['user_id'] . '
|
||||
AND a.is_orphan = 0
|
||||
AND ' . $db->sql_in_set('a.attach_id', $delete_ids);
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$delete_ids = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
if (!$auth->acl_get('m_edit', $row['forum_id']) && ($row['forum_status'] == ITEM_LOCKED || $row['topic_status'] == ITEM_LOCKED || $row['post_edit_locked']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$delete_ids[] = $row['attach_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
if ($delete && count($delete_ids))
|
||||
{
|
||||
$s_hidden_fields = array(
|
||||
'delete' => 1
|
||||
);
|
||||
|
||||
foreach ($delete_ids as $attachment_id)
|
||||
{
|
||||
$s_hidden_fields['attachment'][$attachment_id] = 1;
|
||||
}
|
||||
|
||||
if (confirm_box(true))
|
||||
{
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$attachment_manager->delete('attach', $delete_ids);
|
||||
unset($attachment_manager);
|
||||
|
||||
meta_refresh(3, $this->u_action);
|
||||
$message = ((count($delete_ids) == 1) ? $user->lang['ATTACHMENT_DELETED'] : $user->lang['ATTACHMENTS_DELETED']) . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
|
||||
trigger_error($message);
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, (count($delete_ids) == 1) ? 'DELETE_ATTACHMENT' : 'DELETE_ATTACHMENTS', build_hidden_fields($s_hidden_fields));
|
||||
}
|
||||
}
|
||||
|
||||
// Select box eventually
|
||||
$sort_key_text = array('a' => $user->lang['SORT_FILENAME'], 'b' => $user->lang['SORT_COMMENT'], 'c' => $user->lang['SORT_EXTENSION'], 'd' => $user->lang['SORT_SIZE'], 'e' => $user->lang['SORT_DOWNLOADS'], 'f' => $user->lang['SORT_POST_TIME'], 'g' => $user->lang['SORT_TOPIC_TITLE']);
|
||||
$sort_key_sql = array('a' => 'a.real_filename', 'b' => 'a.attach_comment', 'c' => 'a.extension', 'd' => 'a.filesize', 'e' => 'a.download_count', 'f' => 'a.filetime', 'g' => 't.topic_title');
|
||||
|
||||
$sort_dir_text = array('a' => $user->lang['ASCENDING'], 'd' => $user->lang['DESCENDING']);
|
||||
|
||||
$s_sort_key = '';
|
||||
foreach ($sort_key_text as $key => $value)
|
||||
{
|
||||
$selected = ($sort_key == $key) ? ' selected="selected"' : '';
|
||||
$s_sort_key .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
|
||||
}
|
||||
|
||||
$s_sort_dir = '';
|
||||
foreach ($sort_dir_text as $key => $value)
|
||||
{
|
||||
$selected = ($sort_dir == $key) ? ' selected="selected"' : '';
|
||||
$s_sort_dir .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
|
||||
}
|
||||
|
||||
if (!isset($sort_key_sql[$sort_key]))
|
||||
{
|
||||
$sort_key = 'a';
|
||||
}
|
||||
|
||||
$order_by = $sort_key_sql[$sort_key] . ' ' . (($sort_dir == 'a') ? 'ASC' : 'DESC');
|
||||
|
||||
$sql = 'SELECT COUNT(attach_id) as num_attachments
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE poster_id = ' . $user->data['user_id'] . '
|
||||
AND is_orphan = 0';
|
||||
$result = $db->sql_query($sql);
|
||||
$num_attachments = $db->sql_fetchfield('num_attachments');
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// Ensure start is a valid value
|
||||
/* @var $pagination \phpbb\pagination */
|
||||
$pagination = $phpbb_container->get('pagination');
|
||||
$start = $pagination->validate_start($start, $config['topics_per_page'], $num_attachments);
|
||||
|
||||
$sql = 'SELECT a.*, t.topic_title, pr.message_subject as message_title, p.post_edit_locked, t.topic_status, f.forum_id, f.forum_status
|
||||
FROM ' . ATTACHMENTS_TABLE . ' a
|
||||
LEFT JOIN ' . POSTS_TABLE . ' p ON (a.post_msg_id = p.post_id AND a.in_message = 0)
|
||||
LEFT JOIN ' . TOPICS_TABLE . ' t ON (a.topic_id = t.topic_id AND a.in_message = 0)
|
||||
LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = t.forum_id AND a.in_message = 0)
|
||||
LEFT JOIN ' . PRIVMSGS_TABLE . ' pr ON (a.post_msg_id = pr.msg_id AND a.in_message = 1)
|
||||
WHERE a.poster_id = ' . $user->data['user_id'] . "
|
||||
AND a.is_orphan = 0
|
||||
ORDER BY $order_by";
|
||||
$result = $db->sql_query_limit($sql, $config['topics_per_page'], $start);
|
||||
|
||||
$row_count = 0;
|
||||
if ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$template->assign_var('S_ATTACHMENT_ROWS', true);
|
||||
|
||||
do
|
||||
{
|
||||
if ($row['in_message'])
|
||||
{
|
||||
$view_topic = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&p={$row['post_msg_id']}");
|
||||
}
|
||||
else
|
||||
{
|
||||
$view_topic = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t={$row['topic_id']}&p={$row['post_msg_id']}") . "#p{$row['post_msg_id']}";
|
||||
}
|
||||
|
||||
$template->assign_block_vars('attachrow', array(
|
||||
'ROW_NUMBER' => $row_count + ($start + 1),
|
||||
'FILENAME' => $row['real_filename'],
|
||||
'COMMENT' => bbcode_nl2br($row['attach_comment']),
|
||||
'EXTENSION' => $row['extension'],
|
||||
'SIZE' => get_formatted_filesize($row['filesize']),
|
||||
'DOWNLOAD_COUNT' => $row['download_count'],
|
||||
'POST_TIME' => $user->format_date($row['filetime']),
|
||||
'TOPIC_TITLE' => ($row['in_message']) ? $row['message_title'] : $row['topic_title'],
|
||||
|
||||
'ATTACH_ID' => $row['attach_id'],
|
||||
'POST_ID' => $row['post_msg_id'],
|
||||
'TOPIC_ID' => $row['topic_id'],
|
||||
|
||||
'S_IN_MESSAGE' => $row['in_message'],
|
||||
'S_LOCKED' => !$row['in_message'] && !$auth->acl_get('m_edit', $row['forum_id']) && ($row['forum_status'] == ITEM_LOCKED || $row['topic_status'] == ITEM_LOCKED || $row['post_edit_locked']),
|
||||
|
||||
'U_VIEW_ATTACHMENT' => append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $row['attach_id']),
|
||||
'U_VIEW_TOPIC' => $view_topic)
|
||||
);
|
||||
|
||||
$row_count++;
|
||||
}
|
||||
while ($row = $db->sql_fetchrow($result));
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$base_url = $this->u_action . "&sk=$sort_key&sd=$sort_dir";
|
||||
$pagination->generate_template_pagination($base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'TOTAL_ATTACHMENTS' => $num_attachments,
|
||||
'NUM_ATTACHMENTS' => $user->lang('NUM_ATTACHMENTS', $num_attachments),
|
||||
|
||||
'L_TITLE' => $user->lang['UCP_ATTACHMENTS'],
|
||||
|
||||
'U_SORT_FILENAME' => $this->u_action . "&sk=a&sd=" . (($sort_key == 'a' && $sort_dir == 'a') ? 'd' : 'a'),
|
||||
'U_SORT_FILE_COMMENT' => $this->u_action . "&sk=b&sd=" . (($sort_key == 'b' && $sort_dir == 'a') ? 'd' : 'a'),
|
||||
'U_SORT_EXTENSION' => $this->u_action . "&sk=c&sd=" . (($sort_key == 'c' && $sort_dir == 'a') ? 'd' : 'a'),
|
||||
'U_SORT_FILESIZE' => $this->u_action . "&sk=d&sd=" . (($sort_key == 'd' && $sort_dir == 'a') ? 'd' : 'a'),
|
||||
'U_SORT_DOWNLOADS' => $this->u_action . "&sk=e&sd=" . (($sort_key == 'e' && $sort_dir == 'a') ? 'd' : 'a'),
|
||||
'U_SORT_POST_TIME' => $this->u_action . "&sk=f&sd=" . (($sort_key == 'f' && $sort_dir == 'a') ? 'd' : 'a'),
|
||||
'U_SORT_TOPIC_TITLE' => $this->u_action . "&sk=g&sd=" . (($sort_key == 'g' && $sort_dir == 'a') ? 'd' : 'a'),
|
||||
|
||||
'S_DISPLAY_MARK_ALL' => ($num_attachments) ? true : false,
|
||||
'S_DISPLAY_PAGINATION' => ($num_attachments) ? true : false,
|
||||
'S_UCP_ACTION' => $this->u_action,
|
||||
'S_SORT_OPTIONS' => $s_sort_key,
|
||||
'S_ORDER_SELECT' => $s_sort_dir)
|
||||
);
|
||||
|
||||
$this->tpl_name = 'ucp_attachments';
|
||||
$this->page_title = 'UCP_ATTACHMENTS';
|
||||
}
|
||||
}
|
||||
1142
install/update/new/includes/ucp/ucp_groups.php
Normal file
1142
install/update/new/includes/ucp/ucp_groups.php
Normal file
File diff suppressed because it is too large
Load Diff
442
install/update/new/includes/ucp/ucp_pm.php
Normal file
442
install/update/new/includes/ucp/ucp_pm.php
Normal file
@@ -0,0 +1,442 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private Message Class
|
||||
*
|
||||
* $_REQUEST['folder'] display folder with the id used
|
||||
* $_REQUEST['folder'] inbox|outbox|sentbox display folder with the associated name
|
||||
*
|
||||
* Display Messages (default to inbox) - mode=view
|
||||
* Display single message - mode=view&p=[msg_id] or &p=[msg_id] (short linkage)
|
||||
*
|
||||
* if the folder id with (&f=[folder_id]) is used when displaying messages, one query will be saved. If it is not used, phpBB needs to grab
|
||||
* the folder id first in order to display the input boxes and folder names and such things. ;) phpBB always checks this against the database to make
|
||||
* sure the user is able to view the message.
|
||||
*
|
||||
* Composing Messages (mode=compose):
|
||||
* To specific user (u=[user_id])
|
||||
* To specific group (g=[group_id])
|
||||
* Quoting a post (action=quotepost&p=[post_id])
|
||||
* Quoting a PM (action=quote&p=[msg_id])
|
||||
* Forwarding a PM (action=forward&p=[msg_id])
|
||||
*/
|
||||
class ucp_pm
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $user, $template, $phpbb_root_path, $auth, $phpEx, $db, $config, $request;
|
||||
|
||||
if (!$user->data['is_registered'])
|
||||
{
|
||||
trigger_error('NO_MESSAGE');
|
||||
}
|
||||
|
||||
// Is PM disabled?
|
||||
if (!$config['allow_privmsg'])
|
||||
{
|
||||
trigger_error('PM_DISABLED');
|
||||
}
|
||||
|
||||
$user->add_lang('posting');
|
||||
$template->assign_var('S_PRIVMSGS', true);
|
||||
|
||||
// Folder directly specified?
|
||||
$folder_specified = $request->variable('folder', '');
|
||||
|
||||
if (!in_array($folder_specified, array('inbox', 'outbox', 'sentbox')))
|
||||
{
|
||||
$folder_specified = (int) $folder_specified;
|
||||
}
|
||||
else
|
||||
{
|
||||
$folder_specified = ($folder_specified == 'inbox') ? PRIVMSGS_INBOX : (($folder_specified == 'outbox') ? PRIVMSGS_OUTBOX : PRIVMSGS_SENTBOX);
|
||||
}
|
||||
|
||||
if (!$folder_specified)
|
||||
{
|
||||
$mode = (!$mode) ? $request->variable('mode', 'view') : $mode;
|
||||
}
|
||||
else
|
||||
{
|
||||
$mode = 'view';
|
||||
}
|
||||
|
||||
if (!function_exists('get_folder'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
|
||||
}
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
// Compose message
|
||||
case 'compose':
|
||||
$action = $request->variable('action', 'post');
|
||||
|
||||
$user_folders = get_folder($user->data['user_id']);
|
||||
|
||||
if ($action != 'delete' && !$auth->acl_get('u_sendpm'))
|
||||
{
|
||||
// trigger_error('NO_AUTH_SEND_MESSAGE');
|
||||
$template->assign_vars(array(
|
||||
'S_NO_AUTH_SEND_MESSAGE' => true,
|
||||
'S_COMPOSE_PM_VIEW' => true,
|
||||
));
|
||||
|
||||
$tpl_file = 'ucp_pm_viewfolder';
|
||||
break;
|
||||
}
|
||||
|
||||
if (!function_exists('compose_pm'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/ucp/ucp_pm_compose.' . $phpEx);
|
||||
}
|
||||
compose_pm($id, $mode, $action, $user_folders);
|
||||
|
||||
$tpl_file = 'posting_body';
|
||||
break;
|
||||
|
||||
case 'options':
|
||||
set_user_message_limit();
|
||||
get_folder($user->data['user_id']);
|
||||
|
||||
if (!function_exists('message_options'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/ucp/ucp_pm_options.' . $phpEx);
|
||||
}
|
||||
message_options($id, $mode, $global_privmsgs_rules, $global_rule_conditions);
|
||||
|
||||
$tpl_file = 'ucp_pm_options';
|
||||
break;
|
||||
|
||||
case 'drafts':
|
||||
|
||||
get_folder($user->data['user_id']);
|
||||
$this->p_name = 'pm';
|
||||
|
||||
if (!class_exists('ucp_main'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/ucp/ucp_main.' . $phpEx);
|
||||
}
|
||||
|
||||
$module = new ucp_main($this);
|
||||
$module->u_action = $this->u_action;
|
||||
$module->main($id, $mode);
|
||||
|
||||
$this->tpl_name = $module->tpl_name;
|
||||
$this->page_title = 'UCP_PM_DRAFTS';
|
||||
|
||||
unset($module);
|
||||
return;
|
||||
|
||||
break;
|
||||
|
||||
case 'view':
|
||||
|
||||
set_user_message_limit();
|
||||
|
||||
if ($folder_specified)
|
||||
{
|
||||
$folder_id = $folder_specified;
|
||||
$action = 'view_folder';
|
||||
}
|
||||
else
|
||||
{
|
||||
$folder_id = $request->variable('f', PRIVMSGS_NO_BOX);
|
||||
$action = $request->variable('action', 'view_folder');
|
||||
}
|
||||
|
||||
$msg_id = $request->variable('p', 0);
|
||||
$view = $request->variable('view', '');
|
||||
|
||||
// View message if specified
|
||||
if ($msg_id)
|
||||
{
|
||||
$action = 'view_message';
|
||||
}
|
||||
|
||||
if (!$auth->acl_get('u_readpm'))
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error('NO_AUTH_READ_MESSAGE');
|
||||
}
|
||||
|
||||
if ($view == 'print' && (!$config['print_pm'] || !$auth->acl_get('u_pm_printpm')))
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error('NO_AUTH_PRINT_MESSAGE');
|
||||
}
|
||||
|
||||
// Do not allow hold messages to be seen
|
||||
if ($folder_id == PRIVMSGS_HOLD_BOX)
|
||||
{
|
||||
trigger_error('NO_AUTH_READ_HOLD_MESSAGE');
|
||||
}
|
||||
|
||||
add_form_key('ucp_pm_view');
|
||||
|
||||
// First Handle Mark actions and moving messages
|
||||
$submit_mark = (isset($_POST['submit_mark'])) ? true : false;
|
||||
$move_pm = (isset($_POST['move_pm'])) ? true : false;
|
||||
$mark_option = $request->variable('mark_option', '');
|
||||
$dest_folder = $request->variable('dest_folder', PRIVMSGS_NO_BOX);
|
||||
|
||||
// Is moving PM triggered through mark options?
|
||||
if (!in_array($mark_option, array('mark_important', 'delete_marked')) && $submit_mark)
|
||||
{
|
||||
$move_pm = true;
|
||||
$dest_folder = (int) $mark_option;
|
||||
$submit_mark = false;
|
||||
}
|
||||
|
||||
if (($move_pm || $submit_mark) && !check_form_key('ucp_pm_view'))
|
||||
{
|
||||
trigger_error('FORM_INVALID');
|
||||
}
|
||||
|
||||
// Move PM
|
||||
if ($move_pm)
|
||||
{
|
||||
$move_msg_ids = (isset($_POST['marked_msg_id'])) ? $request->variable('marked_msg_id', array(0)) : array();
|
||||
$cur_folder_id = $request->variable('cur_folder_id', PRIVMSGS_NO_BOX);
|
||||
|
||||
if (move_pm($user->data['user_id'], $user->data['message_limit'], $move_msg_ids, $dest_folder, $cur_folder_id))
|
||||
{
|
||||
// Return to folder view if single message moved
|
||||
if ($action == 'view_message')
|
||||
{
|
||||
$msg_id = 0;
|
||||
$folder_id = $request->variable('cur_folder_id', PRIVMSGS_NO_BOX);
|
||||
$action = 'view_folder';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Message Mark Options
|
||||
if ($submit_mark)
|
||||
{
|
||||
handle_mark_actions($user->data['user_id'], $mark_option);
|
||||
}
|
||||
|
||||
// If new messages arrived, place them into the appropriate folder
|
||||
$num_not_moved = $num_removed = 0;
|
||||
$release = $request->variable('release', 0);
|
||||
|
||||
if ($user->data['user_new_privmsg'] && ($action == 'view_folder' || $action == 'view_message'))
|
||||
{
|
||||
$return = place_pm_into_folder($global_privmsgs_rules, $release);
|
||||
$num_not_moved = $return['not_moved'];
|
||||
$num_removed = $return['removed'];
|
||||
}
|
||||
|
||||
if (!$msg_id && $folder_id == PRIVMSGS_NO_BOX)
|
||||
{
|
||||
$folder_id = PRIVMSGS_INBOX;
|
||||
}
|
||||
else if ($msg_id && $folder_id == PRIVMSGS_NO_BOX)
|
||||
{
|
||||
$sql = 'SELECT folder_id
|
||||
FROM ' . PRIVMSGS_TO_TABLE . "
|
||||
WHERE msg_id = $msg_id
|
||||
AND folder_id <> " . PRIVMSGS_NO_BOX . '
|
||||
AND user_id = ' . $user->data['user_id'];
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$row)
|
||||
{
|
||||
trigger_error('NO_MESSAGE');
|
||||
}
|
||||
$folder_id = (int) $row['folder_id'];
|
||||
}
|
||||
|
||||
if ($request->variable('mark', '') == 'all' && check_link_hash($request->variable('token', ''), 'mark_all_pms_read'))
|
||||
{
|
||||
mark_folder_read($user->data['user_id'], $folder_id);
|
||||
|
||||
meta_refresh(3, $this->u_action);
|
||||
$message = $user->lang['PM_MARK_ALL_READ_SUCCESS'];
|
||||
|
||||
if ($request->is_ajax())
|
||||
{
|
||||
$json_response = new \phpbb\json_response();
|
||||
$json_response->send(array(
|
||||
'MESSAGE_TITLE' => $user->lang['INFORMATION'],
|
||||
'MESSAGE_TEXT' => $message,
|
||||
'success' => true,
|
||||
));
|
||||
}
|
||||
$message .= '<br /><br />' . $user->lang('RETURN_UCP', '<a href="' . $this->u_action . '">', '</a>');
|
||||
|
||||
trigger_error($message);
|
||||
}
|
||||
|
||||
$message_row = array();
|
||||
if ($action == 'view_message' && $msg_id)
|
||||
{
|
||||
// Get Message user want to see
|
||||
if ($view == 'next' || $view == 'previous')
|
||||
{
|
||||
$sql_condition = ($view == 'next') ? '>' : '<';
|
||||
$sql_ordering = ($view == 'next') ? 'ASC' : 'DESC';
|
||||
|
||||
$sql = 'SELECT t.msg_id
|
||||
FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p, ' . PRIVMSGS_TABLE . " p2
|
||||
WHERE p2.msg_id = $msg_id
|
||||
AND t.folder_id = $folder_id
|
||||
AND t.user_id = " . $user->data['user_id'] . "
|
||||
AND t.msg_id = p.msg_id
|
||||
AND p.message_time $sql_condition p2.message_time
|
||||
ORDER BY p.message_time $sql_ordering";
|
||||
$result = $db->sql_query_limit($sql, 1);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$row)
|
||||
{
|
||||
$message = ($view == 'next') ? 'NO_NEWER_PM' : 'NO_OLDER_PM';
|
||||
trigger_error($message);
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg_id = $row['msg_id'];
|
||||
}
|
||||
}
|
||||
|
||||
$sql = 'SELECT t.*, p.*, u.*
|
||||
FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p, ' . USERS_TABLE . ' u
|
||||
WHERE t.user_id = ' . $user->data['user_id'] . "
|
||||
AND p.author_id = u.user_id
|
||||
AND t.folder_id = $folder_id
|
||||
AND t.msg_id = p.msg_id
|
||||
AND p.msg_id = $msg_id";
|
||||
$result = $db->sql_query($sql);
|
||||
$message_row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$message_row)
|
||||
{
|
||||
trigger_error('NO_MESSAGE');
|
||||
}
|
||||
|
||||
// Update unread status
|
||||
update_unread_status($message_row['pm_unread'], $message_row['msg_id'], $user->data['user_id'], $folder_id);
|
||||
}
|
||||
|
||||
$folder = get_folder($user->data['user_id'], $folder_id);
|
||||
|
||||
$s_folder_options = $s_to_folder_options = '';
|
||||
foreach ($folder as $f_id => $folder_ary)
|
||||
{
|
||||
$option = '<option' . ((!in_array($f_id, array(PRIVMSGS_INBOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX))) ? ' class="sep"' : '') . ' value="' . $f_id . '"' . (($f_id == $folder_id) ? ' selected="selected"' : '') . '>' . $folder_ary['folder_name'] . (($folder_ary['unread_messages']) ? ' [' . $folder_ary['unread_messages'] . '] ' : '') . '</option>';
|
||||
|
||||
$s_to_folder_options .= ($f_id != PRIVMSGS_OUTBOX && $f_id != PRIVMSGS_SENTBOX) ? $option : '';
|
||||
$s_folder_options .= $option;
|
||||
}
|
||||
clean_sentbox($folder[PRIVMSGS_SENTBOX]['num_messages']);
|
||||
|
||||
// Header for message view - folder and so on
|
||||
$folder_status = get_folder_status($folder_id, $folder);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'CUR_FOLDER_ID' => $folder_id,
|
||||
'CUR_FOLDER_NAME' => $folder_status['folder_name'],
|
||||
'NUM_NOT_MOVED' => $num_not_moved,
|
||||
'NUM_REMOVED' => $num_removed,
|
||||
'RELEASE_MESSAGE_INFO' => sprintf($user->lang['RELEASE_MESSAGES'], '<a href="' . $this->u_action . '&folder=' . $folder_id . '&release=1">', '</a>'),
|
||||
'NOT_MOVED_MESSAGES' => $user->lang('NOT_MOVED_MESSAGES', (int) $num_not_moved),
|
||||
'RULE_REMOVED_MESSAGES' => $user->lang('RULE_REMOVED_MESSAGES', (int) $num_removed),
|
||||
|
||||
'S_FOLDER_OPTIONS' => $s_folder_options,
|
||||
'S_TO_FOLDER_OPTIONS' => $s_to_folder_options,
|
||||
'S_FOLDER_ACTION' => $this->u_action . '&action=view_folder',
|
||||
'S_PM_ACTION' => $this->u_action . '&action=' . $action,
|
||||
|
||||
'U_INBOX' => $this->u_action . '&folder=inbox',
|
||||
'U_OUTBOX' => $this->u_action . '&folder=outbox',
|
||||
'U_SENTBOX' => $this->u_action . '&folder=sentbox',
|
||||
'U_CREATE_FOLDER' => $this->u_action . '&mode=options',
|
||||
'U_CURRENT_FOLDER' => $this->u_action . '&folder=' . $folder_id,
|
||||
'U_MARK_ALL' => $this->u_action . '&folder=' . $folder_id . '&mark=all&token=' . generate_link_hash('mark_all_pms_read'),
|
||||
|
||||
'S_IN_INBOX' => ($folder_id == PRIVMSGS_INBOX) ? true : false,
|
||||
'S_IN_OUTBOX' => ($folder_id == PRIVMSGS_OUTBOX) ? true : false,
|
||||
'S_IN_SENTBOX' => ($folder_id == PRIVMSGS_SENTBOX) ? true : false,
|
||||
|
||||
'FOLDER_STATUS' => $folder_status['message'],
|
||||
'FOLDER_MAX_MESSAGES' => $folder_status['max'],
|
||||
'FOLDER_CUR_MESSAGES' => $folder_status['cur'],
|
||||
'FOLDER_REMAINING_MESSAGES' => $folder_status['remaining'],
|
||||
'FOLDER_PERCENT' => $folder_status['percent'])
|
||||
);
|
||||
|
||||
if ($action == 'view_folder')
|
||||
{
|
||||
if (!function_exists('view_folder'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/ucp/ucp_pm_viewfolder.' . $phpEx);
|
||||
}
|
||||
view_folder($id, $mode, $folder_id, $folder);
|
||||
|
||||
$tpl_file = 'ucp_pm_viewfolder';
|
||||
}
|
||||
else if ($action == 'view_message')
|
||||
{
|
||||
$template->assign_vars(array(
|
||||
'S_VIEW_MESSAGE' => true,
|
||||
'L_RETURN_TO_FOLDER' => $user->lang('RETURN_TO', $folder_status['folder_name']),
|
||||
'MSG_ID' => $msg_id,
|
||||
));
|
||||
|
||||
if (!$msg_id)
|
||||
{
|
||||
trigger_error('NO_MESSAGE');
|
||||
}
|
||||
|
||||
if (!function_exists('view_message'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/ucp/ucp_pm_viewmessage.' . $phpEx);
|
||||
}
|
||||
view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row);
|
||||
|
||||
$tpl_file = ($view == 'print') ? 'ucp_pm_viewmessage_print' : 'ucp_pm_viewmessage';
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
trigger_error('NO_ACTION_MODE', E_USER_ERROR);
|
||||
break;
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'L_TITLE' => $user->lang['UCP_PM_' . strtoupper($mode)],
|
||||
'S_UCP_ACTION' => $this->u_action . ((isset($action)) ? "&action=$action" : ''))
|
||||
);
|
||||
|
||||
// Set desired template
|
||||
$this->tpl_name = $tpl_file;
|
||||
$this->page_title = 'UCP_PM_' . strtoupper($mode);
|
||||
}
|
||||
}
|
||||
1562
install/update/new/includes/ucp/ucp_pm_compose.php
Normal file
1562
install/update/new/includes/ucp/ucp_pm_compose.php
Normal file
File diff suppressed because it is too large
Load Diff
611
install/update/new/includes/ucp/ucp_pm_viewfolder.php
Normal file
611
install/update/new/includes/ucp/ucp_pm_viewfolder.php
Normal file
@@ -0,0 +1,611 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* View message folder
|
||||
* Called from ucp_pm with mode == 'view' && action == 'view_folder'
|
||||
*/
|
||||
function view_folder($id, $mode, $folder_id, $folder)
|
||||
{
|
||||
global $user, $template, $auth, $db, $cache, $request;
|
||||
global $phpbb_root_path, $config, $phpEx;
|
||||
|
||||
$submit_export = (isset($_POST['submit_export'])) ? true : false;
|
||||
|
||||
$folder_info = get_pm_from($folder_id, $folder, $user->data['user_id']);
|
||||
|
||||
add_form_key('ucp_pm_view_folder');
|
||||
|
||||
if (!$submit_export)
|
||||
{
|
||||
$user->add_lang('viewforum');
|
||||
|
||||
// Grab icons
|
||||
$icons = $cache->obtain_icons();
|
||||
|
||||
$color_rows = array('message_reported', 'marked', 'replied');
|
||||
|
||||
$_module = new p_master();
|
||||
$_module->list_modules('ucp');
|
||||
$_module->set_active('zebra');
|
||||
|
||||
$zebra_enabled = ($_module->active_module === false) ? false : true;
|
||||
|
||||
unset($_module);
|
||||
|
||||
if ($zebra_enabled)
|
||||
{
|
||||
$color_rows = array_merge($color_rows, array('friend', 'foe'));
|
||||
}
|
||||
|
||||
foreach ($color_rows as $var)
|
||||
{
|
||||
$template->assign_block_vars('pm_colour_info', array(
|
||||
'IMG' => $user->img("pm_{$var}", ''),
|
||||
'CLASS' => "pm_{$var}_colour",
|
||||
'LANG' => $user->lang[strtoupper($var) . '_MESSAGE'])
|
||||
);
|
||||
}
|
||||
|
||||
$mark_options = array('mark_important', 'delete_marked');
|
||||
|
||||
// Minimise edits
|
||||
if (!$auth->acl_get('u_pm_delete') && $key = array_search('delete_marked', $mark_options))
|
||||
{
|
||||
unset($mark_options[$key]);
|
||||
}
|
||||
|
||||
$s_mark_options = '';
|
||||
foreach ($mark_options as $mark_option)
|
||||
{
|
||||
$s_mark_options .= '<option value="' . $mark_option . '">' . $user->lang[strtoupper($mark_option)] . '</option>';
|
||||
}
|
||||
|
||||
// We do the folder moving options here too, for template authors to use...
|
||||
$s_folder_move_options = '';
|
||||
if ($folder_id != PRIVMSGS_NO_BOX && $folder_id != PRIVMSGS_OUTBOX)
|
||||
{
|
||||
foreach ($folder as $f_id => $folder_ary)
|
||||
{
|
||||
if ($f_id == PRIVMSGS_OUTBOX || $f_id == PRIVMSGS_SENTBOX || $f_id == $folder_id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$s_folder_move_options .= '<option' . (($f_id != PRIVMSGS_INBOX) ? ' class="sep"' : '') . ' value="' . $f_id . '">';
|
||||
$s_folder_move_options .= sprintf($user->lang['MOVE_MARKED_TO_FOLDER'], $folder_ary['folder_name']);
|
||||
$s_folder_move_options .= (($folder_ary['unread_messages']) ? ' [' . $folder_ary['unread_messages'] . '] ' : '') . '</option>';
|
||||
}
|
||||
}
|
||||
$friend = $foe = array();
|
||||
|
||||
// Get friends and foes
|
||||
$sql = 'SELECT *
|
||||
FROM ' . ZEBRA_TABLE . '
|
||||
WHERE user_id = ' . $user->data['user_id'];
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$friend[$row['zebra_id']] = $row['friend'];
|
||||
$foe[$row['zebra_id']] = $row['foe'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'S_MARK_OPTIONS' => $s_mark_options,
|
||||
'S_MOVE_MARKED_OPTIONS' => $s_folder_move_options)
|
||||
);
|
||||
|
||||
// Okay, lets dump out the page ...
|
||||
if (count($folder_info['pm_list']))
|
||||
{
|
||||
$address_list = array();
|
||||
|
||||
// Build Recipient List if in outbox/sentbox - max two additional queries
|
||||
if ($folder_id == PRIVMSGS_OUTBOX || $folder_id == PRIVMSGS_SENTBOX)
|
||||
{
|
||||
$address_list = get_recipient_strings($folder_info['rowset']);
|
||||
}
|
||||
|
||||
foreach ($folder_info['pm_list'] as $message_id)
|
||||
{
|
||||
$row = &$folder_info['rowset'][$message_id];
|
||||
|
||||
$folder_img = ($row['pm_unread']) ? 'pm_unread' : 'pm_read';
|
||||
$folder_alt = ($row['pm_unread']) ? 'NEW_MESSAGES' : 'NO_NEW_MESSAGES';
|
||||
|
||||
// Generate all URIs ...
|
||||
$view_message_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&mode=view&f=$folder_id&p=$message_id");
|
||||
$remove_message_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&mode=compose&action=delete&p=$message_id");
|
||||
|
||||
$row_indicator = '';
|
||||
foreach ($color_rows as $var)
|
||||
{
|
||||
if (($var !== 'friend' && $var !== 'foe' && $row[($var === 'message_reported') ? $var : "pm_{$var}"])
|
||||
||
|
||||
(($var === 'friend' || $var === 'foe') && isset(${$var}[$row['author_id']]) && ${$var}[$row['author_id']]))
|
||||
{
|
||||
$row_indicator = $var;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Send vars to template
|
||||
$template->assign_block_vars('messagerow', array(
|
||||
'PM_CLASS' => ($row_indicator) ? 'pm_' . $row_indicator . '_colour' : '',
|
||||
|
||||
'MESSAGE_AUTHOR_FULL' => get_username_string('full', $row['author_id'], $row['username'], $row['user_colour'], $row['username']),
|
||||
'MESSAGE_AUTHOR_COLOUR' => get_username_string('colour', $row['author_id'], $row['username'], $row['user_colour'], $row['username']),
|
||||
'MESSAGE_AUTHOR' => get_username_string('username', $row['author_id'], $row['username'], $row['user_colour'], $row['username']),
|
||||
'U_MESSAGE_AUTHOR' => get_username_string('profile', $row['author_id'], $row['username'], $row['user_colour'], $row['username']),
|
||||
|
||||
'FOLDER_ID' => $folder_id,
|
||||
'MESSAGE_ID' => $message_id,
|
||||
'SENT_TIME' => $user->format_date($row['message_time']),
|
||||
'SUBJECT' => censor_text($row['message_subject']),
|
||||
'FOLDER' => (isset($folder[$row['folder_id']])) ? $folder[$row['folder_id']]['folder_name'] : '',
|
||||
'U_FOLDER' => (isset($folder[$row['folder_id']])) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'folder=' . $row['folder_id']) : '',
|
||||
'PM_ICON_IMG' => (!empty($icons[$row['icon_id']])) ? '<img src="' . $config['icons_path'] . '/' . $icons[$row['icon_id']]['img'] . '" width="' . $icons[$row['icon_id']]['width'] . '" height="' . $icons[$row['icon_id']]['height'] . '" alt="" title="" />' : '',
|
||||
'PM_ICON_URL' => (!empty($icons[$row['icon_id']])) ? $config['icons_path'] . '/' . $icons[$row['icon_id']]['img'] : '',
|
||||
'FOLDER_IMG' => $user->img($folder_img, $folder_alt),
|
||||
'FOLDER_IMG_STYLE' => $folder_img,
|
||||
'PM_IMG' => ($row_indicator) ? $user->img('pm_' . $row_indicator, '') : '',
|
||||
'ATTACH_ICON_IMG' => ($auth->acl_get('u_pm_download') && $row['message_attachment'] && $config['allow_pm_attach']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '',
|
||||
|
||||
'S_PM_UNREAD' => ($row['pm_unread']) ? true : false,
|
||||
'S_PM_DELETED' => ($row['pm_deleted']) ? true : false,
|
||||
'S_PM_REPORTED' => (isset($row['report_id'])) ? true : false,
|
||||
'S_AUTHOR_DELETED' => ($row['author_id'] == ANONYMOUS) ? true : false,
|
||||
|
||||
'U_VIEW_PM' => ($row['pm_deleted']) ? '' : $view_message_url,
|
||||
'U_REMOVE_PM' => ($row['pm_deleted']) ? $remove_message_url : '',
|
||||
'U_MCP_REPORT' => (isset($row['report_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=pm_reports&mode=pm_report_details&r=' . $row['report_id']) : '',
|
||||
'RECIPIENTS' => ($folder_id == PRIVMSGS_OUTBOX || $folder_id == PRIVMSGS_SENTBOX) ? implode($user->lang['COMMA_SEPARATOR'], $address_list[$message_id]) : '')
|
||||
);
|
||||
}
|
||||
unset($folder_info['rowset']);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'S_SHOW_RECIPIENTS' => ($folder_id == PRIVMSGS_OUTBOX || $folder_id == PRIVMSGS_SENTBOX) ? true : false,
|
||||
'S_SHOW_COLOUR_LEGEND' => true,
|
||||
|
||||
'REPORTED_IMG' => $user->img('icon_topic_reported', 'PM_REPORTED'),
|
||||
'S_PM_ICONS' => ($config['enable_pm_icons']) ? true : false)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$export_type = $request->variable('export_option', '');
|
||||
$enclosure = $request->variable('enclosure', '');
|
||||
$delimiter = $request->variable('delimiter', '');
|
||||
|
||||
if (!check_form_key('ucp_pm_view_folder'))
|
||||
{
|
||||
trigger_error('FORM_INVALID');
|
||||
}
|
||||
|
||||
if ($export_type == 'CSV' && ($delimiter === '' || $enclosure === ''))
|
||||
{
|
||||
$template->assign_var('PROMPT', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Build Recipient List if in outbox/sentbox
|
||||
|
||||
$address_temp = $address = $data = array();
|
||||
|
||||
if ($folder_id == PRIVMSGS_OUTBOX || $folder_id == PRIVMSGS_SENTBOX)
|
||||
{
|
||||
foreach ($folder_info['rowset'] as $message_id => $row)
|
||||
{
|
||||
$address_temp[$message_id] = rebuild_header(array('to' => $row['to_address'], 'bcc' => $row['bcc_address']));
|
||||
$address[$message_id] = array();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($folder_info['pm_list'] as $message_id)
|
||||
{
|
||||
$row = &$folder_info['rowset'][$message_id];
|
||||
|
||||
include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
|
||||
|
||||
$sql = 'SELECT p.message_text, p.bbcode_uid
|
||||
FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p, ' . USERS_TABLE . ' u
|
||||
WHERE t.user_id = ' . $user->data['user_id'] . "
|
||||
AND p.author_id = u.user_id
|
||||
AND t.folder_id = $folder_id
|
||||
AND t.msg_id = p.msg_id
|
||||
AND p.msg_id = $message_id";
|
||||
$result = $db->sql_query_limit($sql, 1);
|
||||
$message_row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$_types = array('u', 'g');
|
||||
foreach ($_types as $ug_type)
|
||||
{
|
||||
if (isset($address_temp[$message_id][$ug_type]) && count($address_temp[$message_id][$ug_type]))
|
||||
{
|
||||
if (!isset($address[$message_id][$ug_type]))
|
||||
{
|
||||
$address[$message_id][$ug_type] = array();
|
||||
}
|
||||
if ($ug_type == 'u')
|
||||
{
|
||||
$sql = 'SELECT user_id as id, username as name
|
||||
FROM ' . USERS_TABLE . '
|
||||
WHERE ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql = 'SELECT group_id as id, group_name as name
|
||||
FROM ' . GROUPS_TABLE . '
|
||||
WHERE ';
|
||||
}
|
||||
$sql .= $db->sql_in_set(($ug_type == 'u') ? 'user_id' : 'group_id', array_map('intval', array_keys($address_temp[$message_id][$ug_type])));
|
||||
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($info_row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$address[$message_id][$ug_type][$address_temp[$message_id][$ug_type][$info_row['id']]][] = $info_row['name'];
|
||||
unset($address_temp[$message_id][$ug_type][$info_row['id']]);
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
}
|
||||
|
||||
// There is the chance that all recipients of the message got deleted. To avoid creating
|
||||
// exports without recipients, we add a bogus "undisclosed recipient".
|
||||
if (!(isset($address[$message_id]['g']) && count($address[$message_id]['g'])) &&
|
||||
!(isset($address[$message_id]['u']) && count($address[$message_id]['u'])))
|
||||
{
|
||||
$address[$message_id]['u'] = array();
|
||||
$address[$message_id]['u']['to'] = array();
|
||||
$address[$message_id]['u']['to'][] = $user->lang['UNDISCLOSED_RECIPIENT'];
|
||||
}
|
||||
|
||||
decode_message($message_row['message_text'], $message_row['bbcode_uid']);
|
||||
|
||||
$data[] = array(
|
||||
'subject' => censor_text($row['message_subject']),
|
||||
'sender' => $row['username'],
|
||||
// ISO 8601 date. For PHP4 we are able to hardcode the timezone because $user->format_date() does not set it.
|
||||
'date' => $user->format_date($row['message_time'], 'c', true),
|
||||
'to' => ($folder_id == PRIVMSGS_OUTBOX || $folder_id == PRIVMSGS_SENTBOX) ? $address[$message_id] : '',
|
||||
'message' => $message_row['message_text']
|
||||
);
|
||||
}
|
||||
|
||||
switch ($export_type)
|
||||
{
|
||||
case 'CSV':
|
||||
case 'CSV_EXCEL':
|
||||
$mimetype = 'text/csv';
|
||||
$filetype = 'csv';
|
||||
|
||||
if ($export_type == 'CSV_EXCEL')
|
||||
{
|
||||
$enclosure = '"';
|
||||
$delimiter = ',';
|
||||
$newline = "\r\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$newline = "\n";
|
||||
}
|
||||
|
||||
$string = '';
|
||||
foreach ($data as $value)
|
||||
{
|
||||
$recipients = $value['to'];
|
||||
$value['to'] = $value['bcc'] = '';
|
||||
|
||||
if (is_array($recipients))
|
||||
{
|
||||
foreach ($recipients as $values)
|
||||
{
|
||||
$value['bcc'] .= (isset($values['bcc']) && is_array($values['bcc'])) ? ',' . implode(',', $values['bcc']) : '';
|
||||
$value['to'] .= (isset($values['to']) && is_array($values['to'])) ? ',' . implode(',', $values['to']) : '';
|
||||
}
|
||||
|
||||
// Remove the commas which will appear before the first entry.
|
||||
$value['to'] = substr($value['to'], 1);
|
||||
$value['bcc'] = substr($value['bcc'], 1);
|
||||
}
|
||||
|
||||
foreach ($value as $tag => $text)
|
||||
{
|
||||
$cell = str_replace($enclosure, $enclosure . $enclosure, $text);
|
||||
|
||||
if (strpos($cell, $enclosure) !== false || strpos($cell, $delimiter) !== false || strpos($cell, $newline) !== false)
|
||||
{
|
||||
$string .= $enclosure . $text . $enclosure . $delimiter;
|
||||
}
|
||||
else
|
||||
{
|
||||
$string .= $cell . $delimiter;
|
||||
}
|
||||
}
|
||||
$string = substr($string, 0, -1) . $newline;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'XML':
|
||||
$mimetype = 'application/xml';
|
||||
$filetype = 'xml';
|
||||
$string = '<?xml version="1.0"?>' . "\n";
|
||||
$string .= "<phpbb>\n";
|
||||
|
||||
foreach ($data as $value)
|
||||
{
|
||||
$string .= "\t<privmsg>\n";
|
||||
|
||||
if (is_array($value['to']))
|
||||
{
|
||||
foreach ($value['to'] as $key => $values)
|
||||
{
|
||||
foreach ($values as $type => $types)
|
||||
{
|
||||
foreach ($types as $name)
|
||||
{
|
||||
$string .= "\t\t<recipient type=\"$type\" status=\"$key\">$name</recipient>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($value['to']);
|
||||
|
||||
foreach ($value as $tag => $text)
|
||||
{
|
||||
$string .= "\t\t<$tag>$text</$tag>\n";
|
||||
}
|
||||
|
||||
$string .= "\t</privmsg>\n";
|
||||
}
|
||||
$string .= '</phpbb>';
|
||||
break;
|
||||
}
|
||||
|
||||
header('Cache-Control: private, no-cache');
|
||||
header("Content-Type: $mimetype; name=\"data.$filetype\"");
|
||||
header("Content-disposition: attachment; filename=data.$filetype");
|
||||
echo $string;
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Messages from folder/user
|
||||
*/
|
||||
function get_pm_from($folder_id, $folder, $user_id)
|
||||
{
|
||||
global $user, $db, $template, $config, $auth, $phpbb_container, $phpbb_root_path, $phpEx, $request, $phpbb_dispatcher;
|
||||
|
||||
$start = $request->variable('start', 0);
|
||||
|
||||
// Additional vars later, pm ordering is mostly different from post ordering. :/
|
||||
$sort_days = $request->variable('st', 0);
|
||||
$sort_key = $request->variable('sk', 't');
|
||||
$sort_dir = $request->variable('sd', 'd');
|
||||
|
||||
/* @var $pagination \phpbb\pagination */
|
||||
$pagination = $phpbb_container->get('pagination');
|
||||
|
||||
// PM ordering options
|
||||
$limit_days = array(0 => $user->lang['ALL_MESSAGES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
|
||||
|
||||
// No sort by Author for sentbox/outbox (already only author available)
|
||||
// Also, sort by msg_id for the time - private messages are not as prone to errors as posts are.
|
||||
if ($folder_id == PRIVMSGS_OUTBOX || $folder_id == PRIVMSGS_SENTBOX)
|
||||
{
|
||||
$sort_by_text = array('t' => $user->lang['POST_TIME'], 's' => $user->lang['SUBJECT']);
|
||||
$sort_by_sql = array('t' => 'p.message_time', 's' => array('p.message_subject', 'p.message_time'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 's' => $user->lang['SUBJECT']);
|
||||
$sort_by_sql = array('a' => array('u.username_clean', 'p.message_time'), 't' => 'p.message_time', 's' => array('p.message_subject', 'p.message_time'));
|
||||
}
|
||||
|
||||
$s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
|
||||
gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param);
|
||||
|
||||
$folder_sql = 't.folder_id = ' . (int) $folder_id;
|
||||
|
||||
// Limit pms to certain time frame, obtain correct pm count
|
||||
if ($sort_days)
|
||||
{
|
||||
$min_post_time = time() - ($sort_days * 86400);
|
||||
|
||||
if (isset($_POST['sort']))
|
||||
{
|
||||
$start = 0;
|
||||
}
|
||||
|
||||
$sql = 'SELECT COUNT(t.msg_id) AS pm_count
|
||||
FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . " p
|
||||
WHERE $folder_sql
|
||||
AND t.user_id = $user_id
|
||||
AND t.msg_id = p.msg_id
|
||||
AND p.message_time >= $min_post_time";
|
||||
$result = $db->sql_query_limit($sql, 1);
|
||||
$pm_count = (int) $db->sql_fetchfield('pm_count');
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$sql_limit_time = "AND p.message_time >= $min_post_time";
|
||||
}
|
||||
else
|
||||
{
|
||||
$pm_count = (!empty($folder[$folder_id]['num_messages'])) ? $folder[$folder_id]['num_messages'] : 0;
|
||||
$sql_limit_time = '';
|
||||
}
|
||||
|
||||
$base_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&mode=view&action=view_folder&f=$folder_id&$u_sort_param");
|
||||
$start = $pagination->validate_start($start, $config['topics_per_page'], $pm_count);
|
||||
$pagination->generate_template_pagination($base_url, 'pagination', 'start', $pm_count, $config['topics_per_page'], $start);
|
||||
|
||||
$template_vars = array(
|
||||
'TOTAL_MESSAGES' => $user->lang('VIEW_PM_MESSAGES', (int) $pm_count),
|
||||
|
||||
'POST_IMG' => (!$auth->acl_get('u_sendpm')) ? $user->img('button_topic_locked', 'POST_PM_LOCKED') : $user->img('button_pm_new', 'POST_NEW_PM'),
|
||||
|
||||
'S_NO_AUTH_SEND_MESSAGE' => !$auth->acl_get('u_sendpm'),
|
||||
|
||||
'S_SELECT_SORT_DIR' => $s_sort_dir,
|
||||
'S_SELECT_SORT_KEY' => $s_sort_key,
|
||||
'S_SELECT_SORT_DAYS' => $s_limit_days,
|
||||
'S_TOPIC_ICONS' => ($config['enable_pm_icons']) ? true : false,
|
||||
|
||||
'U_POST_NEW_TOPIC' => ($auth->acl_get('u_sendpm')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose') : '',
|
||||
'S_PM_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&mode=view&action=view_folder&f=$folder_id" . (($start !== 0) ? "&start=$start" : '')),
|
||||
);
|
||||
|
||||
/**
|
||||
* Modify template variables before they are assigned
|
||||
*
|
||||
* @event core.ucp_pm_view_folder_get_pm_from_template
|
||||
* @var int folder_id Folder ID
|
||||
* @var array folder Folder data
|
||||
* @var int user_id User ID
|
||||
* @var string base_url Pagination base URL
|
||||
* @var int start Pagination start
|
||||
* @var int pm_count Count of PMs
|
||||
* @var array template_vars Template variables to be assigned
|
||||
* @since 3.1.11-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'folder_id',
|
||||
'folder',
|
||||
'user_id',
|
||||
'base_url',
|
||||
'start',
|
||||
'pm_count',
|
||||
'template_vars',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_pm_view_folder_get_pm_from_template', compact($vars)));
|
||||
|
||||
$template->assign_vars($template_vars);
|
||||
|
||||
// Grab all pm data
|
||||
$rowset = $pm_list = array();
|
||||
|
||||
// If the user is trying to reach late pages, start searching from the end
|
||||
$store_reverse = false;
|
||||
$sql_limit = $config['topics_per_page'];
|
||||
if ($start > $pm_count / 2)
|
||||
{
|
||||
$store_reverse = true;
|
||||
|
||||
// Select the sort order
|
||||
$direction = ($sort_dir == 'd') ? 'ASC' : 'DESC';
|
||||
$sql_limit = $pagination->reverse_limit($start, $sql_limit, $pm_count);
|
||||
$sql_start = $pagination->reverse_start($start, $sql_limit, $pm_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select the sort order
|
||||
$direction = ($sort_dir == 'd') ? 'DESC' : 'ASC';
|
||||
$sql_start = $start;
|
||||
}
|
||||
|
||||
// Sql sort order
|
||||
if (is_array($sort_by_sql[$sort_key]))
|
||||
{
|
||||
$sql_sort_order = implode(' ' . $direction . ', ', $sort_by_sql[$sort_key]) . ' ' . $direction;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql_sort_order = $sort_by_sql[$sort_key] . ' ' . $direction;
|
||||
}
|
||||
|
||||
$sql_ary = array(
|
||||
'SELECT' => 't.*, p.root_level, p.message_time, p.message_subject, p.icon_id, p.to_address, p.message_attachment, p.bcc_address, u.username, u.username_clean, u.user_colour, p.message_reported',
|
||||
'FROM' => array(
|
||||
PRIVMSGS_TO_TABLE => 't',
|
||||
PRIVMSGS_TABLE => 'p',
|
||||
USERS_TABLE => 'u',
|
||||
),
|
||||
'WHERE' => "t.user_id = $user_id
|
||||
AND p.author_id = u.user_id
|
||||
AND $folder_sql
|
||||
AND t.msg_id = p.msg_id
|
||||
$sql_limit_time",
|
||||
'ORDER_BY' => $sql_sort_order,
|
||||
);
|
||||
|
||||
/**
|
||||
* Modify SQL before it is executed
|
||||
*
|
||||
* @event core.ucp_pm_view_folder_get_pm_from_sql
|
||||
* @var array sql_ary SQL array
|
||||
* @var int sql_limit SQL limit
|
||||
* @var int sql_start SQL start
|
||||
* @since 3.1.11-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'sql_ary',
|
||||
'sql_limit',
|
||||
'sql_start',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_pm_view_folder_get_pm_from_sql', compact($vars)));
|
||||
|
||||
$result = $db->sql_query_limit($db->sql_build_query('SELECT', $sql_ary), $sql_limit, $sql_start);
|
||||
|
||||
$pm_reported = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$rowset[$row['msg_id']] = $row;
|
||||
$pm_list[] = $row['msg_id'];
|
||||
if ($row['message_reported'])
|
||||
{
|
||||
$pm_reported[] = $row['msg_id'];
|
||||
}
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// Fetch the report_ids, if there are any reported pms.
|
||||
if (!empty($pm_reported) && $auth->acl_getf_global('m_report'))
|
||||
{
|
||||
$sql = 'SELECT pm_id, report_id
|
||||
FROM ' . REPORTS_TABLE . '
|
||||
WHERE report_closed = 0
|
||||
AND ' . $db->sql_in_set('pm_id', $pm_reported);
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$rowset[$row['pm_id']]['report_id'] = $row['report_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
$pm_list = ($store_reverse) ? array_reverse($pm_list) : $pm_list;
|
||||
|
||||
return array(
|
||||
'pm_count' => $pm_count,
|
||||
'pm_list' => $pm_list,
|
||||
'rowset' => $rowset
|
||||
);
|
||||
}
|
||||
847
install/update/new/includes/ucp/ucp_profile.php
Normal file
847
install/update/new/includes/ucp/ucp_profile.php
Normal file
@@ -0,0 +1,847 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* ucp_profile
|
||||
* Changing profile settings
|
||||
*
|
||||
* @todo what about pertaining user_sig_options?
|
||||
*/
|
||||
class ucp_profile
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $config, $db, $user, $auth, $template, $phpbb_root_path, $phpEx;
|
||||
global $request, $phpbb_container, $phpbb_log, $phpbb_dispatcher;
|
||||
|
||||
$user->add_lang('posting');
|
||||
|
||||
$submit = $request->variable('submit', false, false, \phpbb\request\request_interface::POST);
|
||||
$error = $data = array();
|
||||
$s_hidden_fields = '';
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case 'reg_details':
|
||||
|
||||
$data = array(
|
||||
'username' => $request->variable('username', $user->data['username'], true),
|
||||
'email' => strtolower($request->variable('email', $user->data['user_email'])),
|
||||
'new_password' => $request->variable('new_password', '', true),
|
||||
'cur_password' => $request->variable('cur_password', '', true),
|
||||
'password_confirm' => $request->variable('password_confirm', '', true),
|
||||
);
|
||||
|
||||
/**
|
||||
* Modify user registration data on editing account settings in UCP
|
||||
*
|
||||
* @event core.ucp_profile_reg_details_data
|
||||
* @var array data Array with current or updated user registration data
|
||||
* @var bool submit Flag indicating if submit button has been pressed
|
||||
* @since 3.1.4-RC1
|
||||
*/
|
||||
$vars = array('data', 'submit');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_profile_reg_details_data', compact($vars)));
|
||||
|
||||
add_form_key('ucp_reg_details');
|
||||
|
||||
if ($submit)
|
||||
{
|
||||
// Do not check cur_password, it is the old one.
|
||||
$check_ary = array(
|
||||
'new_password' => array(
|
||||
array('string', true, $config['min_pass_chars'], 0),
|
||||
array('password')),
|
||||
'password_confirm' => array('string', true, $config['min_pass_chars'], 0),
|
||||
'email' => array(
|
||||
array('string', false, 6, 60),
|
||||
array('user_email')),
|
||||
);
|
||||
|
||||
if ($auth->acl_get('u_chgname') && $config['allow_namechange'])
|
||||
{
|
||||
$check_ary['username'] = array(
|
||||
array('string', false, $config['min_name_chars'], $config['max_name_chars']),
|
||||
array('username'),
|
||||
);
|
||||
}
|
||||
|
||||
$error = validate_data($data, $check_ary);
|
||||
|
||||
if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && $data['password_confirm'] != $data['new_password'])
|
||||
{
|
||||
$error[] = ($data['password_confirm']) ? 'NEW_PASSWORD_ERROR' : 'NEW_PASSWORD_CONFIRM_EMPTY';
|
||||
}
|
||||
|
||||
// Instantiate passwords manager
|
||||
/* @var $passwords_manager \phpbb\passwords\manager */
|
||||
$passwords_manager = $phpbb_container->get('passwords.manager');
|
||||
|
||||
// Only check the new password against the previous password if there have been no errors
|
||||
if (!count($error) && $auth->acl_get('u_chgpasswd') && $data['new_password'] && $passwords_manager->check($data['new_password'], $user->data['user_password']))
|
||||
{
|
||||
$error[] = 'SAME_PASSWORD_ERROR';
|
||||
}
|
||||
|
||||
if (!$passwords_manager->check($data['cur_password'], $user->data['user_password']))
|
||||
{
|
||||
$error[] = ($data['cur_password']) ? 'CUR_PASSWORD_ERROR' : 'CUR_PASSWORD_EMPTY';
|
||||
}
|
||||
|
||||
if (!check_form_key('ucp_reg_details'))
|
||||
{
|
||||
$error[] = 'FORM_INVALID';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate user data on editing registration data in UCP
|
||||
*
|
||||
* @event core.ucp_profile_reg_details_validate
|
||||
* @var array data Array with user profile data
|
||||
* @var bool submit Flag indicating if submit button has been pressed
|
||||
* @var array error Array of any generated errors
|
||||
* @since 3.1.4-RC1
|
||||
*/
|
||||
$vars = array('data', 'submit', 'error');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_profile_reg_details_validate', compact($vars)));
|
||||
|
||||
if (!count($error))
|
||||
{
|
||||
$sql_ary = array(
|
||||
'username' => ($auth->acl_get('u_chgname') && $config['allow_namechange']) ? $data['username'] : $user->data['username'],
|
||||
'username_clean' => ($auth->acl_get('u_chgname') && $config['allow_namechange']) ? utf8_clean_string($data['username']) : $user->data['username_clean'],
|
||||
'user_email' => ($auth->acl_get('u_chgemail')) ? $data['email'] : $user->data['user_email'],
|
||||
'user_password' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? $passwords_manager->hash($data['new_password']) : $user->data['user_password'],
|
||||
);
|
||||
|
||||
if ($auth->acl_get('u_chgname') && $config['allow_namechange'] && $data['username'] != $user->data['username'])
|
||||
{
|
||||
$phpbb_log->add('user', $user->data['user_id'], $user->ip, 'LOG_USER_UPDATE_NAME', false, array(
|
||||
'reportee_id' => $user->data['user_id'],
|
||||
$user->data['username'],
|
||||
$data['username']
|
||||
));
|
||||
}
|
||||
|
||||
if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && !$passwords_manager->check($data['new_password'], $user->data['user_password']))
|
||||
{
|
||||
$sql_ary['user_passchg'] = time();
|
||||
|
||||
$user->reset_login_keys();
|
||||
$phpbb_log->add('user', $user->data['user_id'], $user->ip, 'LOG_USER_NEW_PASSWORD', false, array(
|
||||
'reportee_id' => $user->data['user_id'],
|
||||
$user->data['username']
|
||||
));
|
||||
}
|
||||
|
||||
if ($auth->acl_get('u_chgemail') && $data['email'] != $user->data['user_email'])
|
||||
{
|
||||
$phpbb_log->add('user', $user->data['user_id'], $user->ip, 'LOG_USER_UPDATE_EMAIL', false, array(
|
||||
'reportee_id' => $user->data['user_id'],
|
||||
$user->data['username'],
|
||||
$user->data['user_email'],
|
||||
$data['email']
|
||||
));
|
||||
}
|
||||
|
||||
$message = 'PROFILE_UPDATED';
|
||||
|
||||
if ($auth->acl_get('u_chgemail') && $config['email_enable'] && $data['email'] != $user->data['user_email'] && $user->data['user_type'] != USER_FOUNDER && ($config['require_activation'] == USER_ACTIVATION_SELF || $config['require_activation'] == USER_ACTIVATION_ADMIN))
|
||||
{
|
||||
$message = ($config['require_activation'] == USER_ACTIVATION_SELF) ? 'ACCOUNT_EMAIL_CHANGED' : 'ACCOUNT_EMAIL_CHANGED_ADMIN';
|
||||
|
||||
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
|
||||
|
||||
$server_url = generate_board_url();
|
||||
|
||||
$user_actkey = gen_rand_string(mt_rand(6, 10));
|
||||
|
||||
$messenger = new messenger(false);
|
||||
|
||||
$template_file = ($config['require_activation'] == USER_ACTIVATION_ADMIN) ? 'user_activate_inactive' : 'user_activate';
|
||||
$messenger->template($template_file, $user->data['user_lang']);
|
||||
|
||||
$messenger->to($data['email'], $data['username']);
|
||||
|
||||
$messenger->anti_abuse_headers($config, $user);
|
||||
|
||||
$messenger->assign_vars(array(
|
||||
'USERNAME' => htmlspecialchars_decode($data['username']),
|
||||
'U_ACTIVATE' => "$server_url/ucp.$phpEx?mode=activate&u={$user->data['user_id']}&k=$user_actkey")
|
||||
);
|
||||
|
||||
$messenger->send(NOTIFY_EMAIL);
|
||||
|
||||
if ($config['require_activation'] == USER_ACTIVATION_ADMIN)
|
||||
{
|
||||
$notifications_manager = $phpbb_container->get('notification_manager');
|
||||
$notifications_manager->add_notifications('notification.type.admin_activate_user', array(
|
||||
'user_id' => $user->data['user_id'],
|
||||
'user_actkey' => $user_actkey,
|
||||
'user_regdate' => time(), // Notification time
|
||||
));
|
||||
}
|
||||
|
||||
user_active_flip('deactivate', $user->data['user_id'], INACTIVE_PROFILE);
|
||||
|
||||
// Because we want the profile to be reactivated we set user_newpasswd to empty (else the reactivation will fail)
|
||||
$sql_ary['user_actkey'] = $user_actkey;
|
||||
$sql_ary['user_newpasswd'] = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify user registration data before submitting it to the database
|
||||
*
|
||||
* @event core.ucp_profile_reg_details_sql_ary
|
||||
* @var array data Array with current or updated user registration data
|
||||
* @var array sql_ary Array with user registration data to submit to the database
|
||||
* @since 3.1.4-RC1
|
||||
*/
|
||||
$vars = array('data', 'sql_ary');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_profile_reg_details_sql_ary', compact($vars)));
|
||||
|
||||
if (count($sql_ary))
|
||||
{
|
||||
$sql = 'UPDATE ' . USERS_TABLE . '
|
||||
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
|
||||
WHERE user_id = ' . $user->data['user_id'];
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
|
||||
// Need to update config, forum, topic, posting, messages, etc.
|
||||
if ($data['username'] != $user->data['username'] && $auth->acl_get('u_chgname') && $config['allow_namechange'])
|
||||
{
|
||||
user_update_name($user->data['username'], $data['username']);
|
||||
}
|
||||
|
||||
// Now, we can remove the user completely (kill the session) - NOT BEFORE!!!
|
||||
if (!empty($sql_ary['user_actkey']))
|
||||
{
|
||||
meta_refresh(5, append_sid($phpbb_root_path . 'index.' . $phpEx));
|
||||
$message = $user->lang[$message] . '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid($phpbb_root_path . 'index.' . $phpEx) . '">', '</a>');
|
||||
|
||||
// Because the user gets deactivated we log him out too, killing his session
|
||||
$user->session_kill();
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_refresh(3, $this->u_action);
|
||||
$message = $user->lang[$message] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
|
||||
}
|
||||
|
||||
trigger_error($message);
|
||||
}
|
||||
|
||||
// Replace "error" strings with their real, localised form
|
||||
$error = array_map(array($user, 'lang'), $error);
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'ERROR' => (count($error)) ? implode('<br />', $error) : '',
|
||||
|
||||
'USERNAME' => $data['username'],
|
||||
'EMAIL' => $data['email'],
|
||||
'PASSWORD_CONFIRM' => $data['password_confirm'],
|
||||
'NEW_PASSWORD' => $data['new_password'],
|
||||
'CUR_PASSWORD' => '',
|
||||
|
||||
'L_USERNAME_EXPLAIN' => $user->lang($config['allow_name_chars'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_name_chars']), $user->lang('CHARACTERS', (int) $config['max_name_chars'])),
|
||||
'L_CHANGE_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars'])),
|
||||
|
||||
'S_FORCE_PASSWORD' => ($auth->acl_get('u_chgpasswd') && $config['chg_passforce'] && $user->data['user_passchg'] < time() - ($config['chg_passforce'] * 86400)) ? true : false,
|
||||
'S_CHANGE_USERNAME' => ($config['allow_namechange'] && $auth->acl_get('u_chgname')) ? true : false,
|
||||
'S_CHANGE_EMAIL' => ($auth->acl_get('u_chgemail')) ? true : false,
|
||||
'S_CHANGE_PASSWORD' => ($auth->acl_get('u_chgpasswd')) ? true : false)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'profile_info':
|
||||
// Do not display profile information panel if not authed to do so
|
||||
if (!$auth->acl_get('u_chgprofileinfo'))
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error('NO_AUTH_PROFILEINFO');
|
||||
}
|
||||
|
||||
/* @var $cp \phpbb\profilefields\manager */
|
||||
$cp = $phpbb_container->get('profilefields.manager');
|
||||
|
||||
$cp_data = $cp_error = array();
|
||||
|
||||
$data = array(
|
||||
'jabber' => $request->variable('jabber', $user->data['user_jabber'], true),
|
||||
);
|
||||
|
||||
if ($config['allow_birthdays'])
|
||||
{
|
||||
$data['bday_day'] = $data['bday_month'] = $data['bday_year'] = 0;
|
||||
|
||||
if ($user->data['user_birthday'])
|
||||
{
|
||||
list($data['bday_day'], $data['bday_month'], $data['bday_year']) = explode('-', $user->data['user_birthday']);
|
||||
}
|
||||
|
||||
$data['bday_day'] = $request->variable('bday_day', $data['bday_day']);
|
||||
$data['bday_month'] = $request->variable('bday_month', $data['bday_month']);
|
||||
$data['bday_year'] = $request->variable('bday_year', $data['bday_year']);
|
||||
$data['user_birthday'] = sprintf('%2d-%2d-%4d', $data['bday_day'], $data['bday_month'], $data['bday_year']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify user data on editing profile in UCP
|
||||
*
|
||||
* @event core.ucp_profile_modify_profile_info
|
||||
* @var array data Array with user profile data
|
||||
* @var bool submit Flag indicating if submit button has been pressed
|
||||
* @since 3.1.4-RC1
|
||||
*/
|
||||
$vars = array('data', 'submit');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_profile_modify_profile_info', compact($vars)));
|
||||
|
||||
add_form_key('ucp_profile_info');
|
||||
|
||||
if ($submit)
|
||||
{
|
||||
$validate_array = array(
|
||||
'jabber' => array(
|
||||
array('string', true, 5, 255),
|
||||
array('jabber')),
|
||||
);
|
||||
|
||||
if ($config['allow_birthdays'])
|
||||
{
|
||||
$validate_array = array_merge($validate_array, array(
|
||||
'bday_day' => array('num', true, 1, 31),
|
||||
'bday_month' => array('num', true, 1, 12),
|
||||
'bday_year' => array('num', true, 1901, gmdate('Y', time()) + 50),
|
||||
'user_birthday' => array('date', true),
|
||||
));
|
||||
}
|
||||
|
||||
$error = validate_data($data, $validate_array);
|
||||
|
||||
// validate custom profile fields
|
||||
$cp->submit_cp_field('profile', $user->get_iso_lang_id(), $cp_data, $cp_error);
|
||||
|
||||
if (count($cp_error))
|
||||
{
|
||||
$error = array_merge($error, $cp_error);
|
||||
}
|
||||
|
||||
if (!check_form_key('ucp_profile_info'))
|
||||
{
|
||||
$error[] = 'FORM_INVALID';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate user data on editing profile in UCP
|
||||
*
|
||||
* @event core.ucp_profile_validate_profile_info
|
||||
* @var array data Array with user profile data
|
||||
* @var bool submit Flag indicating if submit button has been pressed
|
||||
* @var array error Array of any generated errors
|
||||
* @since 3.1.4-RC1
|
||||
*/
|
||||
$vars = array('data', 'submit', 'error');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_profile_validate_profile_info', compact($vars)));
|
||||
|
||||
if (!count($error))
|
||||
{
|
||||
$data['notify'] = $user->data['user_notify_type'];
|
||||
|
||||
if ($data['notify'] == NOTIFY_IM && (!$config['jab_enable'] || !$data['jabber'] || !@extension_loaded('xml')))
|
||||
{
|
||||
// User has not filled in a jabber address (Or one of the modules is disabled or jabber is disabled)
|
||||
// Disable notify by Jabber now for this user.
|
||||
$data['notify'] = NOTIFY_EMAIL;
|
||||
}
|
||||
|
||||
$sql_ary = array(
|
||||
'user_jabber' => $data['jabber'],
|
||||
'user_notify_type' => $data['notify'],
|
||||
);
|
||||
|
||||
if ($config['allow_birthdays'])
|
||||
{
|
||||
$sql_ary['user_birthday'] = $data['user_birthday'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify profile data in UCP before submitting to the database
|
||||
*
|
||||
* @event core.ucp_profile_info_modify_sql_ary
|
||||
* @var array cp_data Array with the user custom profile fields data
|
||||
* @var array data Array with user profile data
|
||||
* @var array sql_ary user options data we update
|
||||
* @since 3.1.4-RC1
|
||||
*/
|
||||
$vars = array('cp_data', 'data', 'sql_ary');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_profile_info_modify_sql_ary', compact($vars)));
|
||||
|
||||
$sql = 'UPDATE ' . USERS_TABLE . '
|
||||
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
|
||||
WHERE user_id = ' . $user->data['user_id'];
|
||||
$db->sql_query($sql);
|
||||
|
||||
// Update Custom Fields
|
||||
$cp->update_profile_field_data($user->data['user_id'], $cp_data);
|
||||
|
||||
meta_refresh(3, $this->u_action);
|
||||
$message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
|
||||
trigger_error($message);
|
||||
}
|
||||
|
||||
// Replace "error" strings with their real, localised form
|
||||
$error = array_map(array($user, 'lang'), $error);
|
||||
}
|
||||
|
||||
if ($config['allow_birthdays'])
|
||||
{
|
||||
$s_birthday_day_options = '<option value="0"' . ((!$data['bday_day']) ? ' selected="selected"' : '') . '>--</option>';
|
||||
for ($i = 1; $i < 32; $i++)
|
||||
{
|
||||
$selected = ($i == $data['bday_day']) ? ' selected="selected"' : '';
|
||||
$s_birthday_day_options .= "<option value=\"$i\"$selected>$i</option>";
|
||||
}
|
||||
|
||||
$s_birthday_month_options = '<option value="0"' . ((!$data['bday_month']) ? ' selected="selected"' : '') . '>--</option>';
|
||||
for ($i = 1; $i < 13; $i++)
|
||||
{
|
||||
$selected = ($i == $data['bday_month']) ? ' selected="selected"' : '';
|
||||
$s_birthday_month_options .= "<option value=\"$i\"$selected>$i</option>";
|
||||
}
|
||||
|
||||
$now = getdate();
|
||||
$s_birthday_year_options = '<option value="0"' . ((!$data['bday_year']) ? ' selected="selected"' : '') . '>--</option>';
|
||||
for ($i = $now['year'] - 100; $i <= $now['year']; $i++)
|
||||
{
|
||||
$selected = ($i == $data['bday_year']) ? ' selected="selected"' : '';
|
||||
$s_birthday_year_options .= "<option value=\"$i\"$selected>$i</option>";
|
||||
}
|
||||
unset($now);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'S_BIRTHDAY_DAY_OPTIONS' => $s_birthday_day_options,
|
||||
'S_BIRTHDAY_MONTH_OPTIONS' => $s_birthday_month_options,
|
||||
'S_BIRTHDAY_YEAR_OPTIONS' => $s_birthday_year_options,
|
||||
'S_BIRTHDAYS_ENABLED' => true,
|
||||
));
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'ERROR' => (count($error)) ? implode('<br />', $error) : '',
|
||||
'S_JABBER_ENABLED' => $config['jab_enable'],
|
||||
'JABBER' => $data['jabber'],
|
||||
));
|
||||
|
||||
// Get additional profile fields and assign them to the template block var 'profile_fields'
|
||||
$user->get_profile_fields($user->data['user_id']);
|
||||
|
||||
$cp->generate_profile_fields('profile', $user->get_iso_lang_id());
|
||||
|
||||
break;
|
||||
|
||||
case 'signature':
|
||||
|
||||
if (!$auth->acl_get('u_sig'))
|
||||
{
|
||||
send_status_line(403, 'Forbidden');
|
||||
trigger_error('NO_AUTH_SIGNATURE');
|
||||
}
|
||||
|
||||
if (!function_exists('generate_smilies'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
|
||||
}
|
||||
|
||||
if (!function_exists('display_custom_bbcodes'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
|
||||
}
|
||||
|
||||
$preview = $request->is_set_post('preview');
|
||||
|
||||
$enable_bbcode = ($config['allow_sig_bbcode']) ? $user->optionget('sig_bbcode') : false;
|
||||
$enable_smilies = ($config['allow_sig_smilies']) ? $user->optionget('sig_smilies') : false;
|
||||
$enable_urls = ($config['allow_sig_links']) ? $user->optionget('sig_links') : false;
|
||||
|
||||
$bbcode_flags = ($enable_bbcode ? OPTION_FLAG_BBCODE : 0) + ($enable_smilies ? OPTION_FLAG_SMILIES : 0) + ($enable_urls ? OPTION_FLAG_LINKS : 0);
|
||||
|
||||
$decoded_message = generate_text_for_edit($user->data['user_sig'], $user->data['user_sig_bbcode_uid'], $bbcode_flags);
|
||||
$signature = $request->variable('signature', $decoded_message['text'], true);
|
||||
$signature_preview = '';
|
||||
|
||||
if ($submit || $preview)
|
||||
{
|
||||
$enable_bbcode = ($config['allow_sig_bbcode']) ? !$request->variable('disable_bbcode', false) : false;
|
||||
$enable_smilies = ($config['allow_sig_smilies']) ? !$request->variable('disable_smilies', false) : false;
|
||||
$enable_urls = ($config['allow_sig_links']) ? !$request->variable('disable_magic_url', false) : false;
|
||||
|
||||
if (!check_form_key('ucp_sig'))
|
||||
{
|
||||
$error[] = 'FORM_INVALID';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify user signature on editing profile in UCP
|
||||
*
|
||||
* @event core.ucp_profile_modify_signature
|
||||
* @var bool enable_bbcode Whether or not bbcode is enabled
|
||||
* @var bool enable_smilies Whether or not smilies are enabled
|
||||
* @var bool enable_urls Whether or not urls are enabled
|
||||
* @var string signature Users signature text
|
||||
* @var array error Any error strings
|
||||
* @var bool submit Whether or not the form has been sumitted
|
||||
* @var bool preview Whether or not the signature is being previewed
|
||||
* @since 3.1.10-RC1
|
||||
* @changed 3.2.0-RC2 Removed message parser
|
||||
*/
|
||||
$vars = array(
|
||||
'enable_bbcode',
|
||||
'enable_smilies',
|
||||
'enable_urls',
|
||||
'signature',
|
||||
'error',
|
||||
'submit',
|
||||
'preview',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_profile_modify_signature', compact($vars)));
|
||||
|
||||
$bbcode_uid = $bbcode_bitfield = $bbcode_flags = '';
|
||||
$warn_msg = generate_text_for_storage(
|
||||
$signature,
|
||||
$bbcode_uid,
|
||||
$bbcode_bitfield,
|
||||
$bbcode_flags,
|
||||
$enable_bbcode,
|
||||
$enable_urls,
|
||||
$enable_smilies,
|
||||
$config['allow_sig_img'],
|
||||
$config['allow_sig_flash'],
|
||||
true,
|
||||
$config['allow_sig_links'],
|
||||
'sig'
|
||||
);
|
||||
|
||||
if (count($warn_msg))
|
||||
{
|
||||
$error += $warn_msg;
|
||||
}
|
||||
|
||||
if (!$submit)
|
||||
{
|
||||
// Parse it for displaying
|
||||
$signature_preview = generate_text_for_display($signature, $bbcode_uid, $bbcode_bitfield, $bbcode_flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!count($error))
|
||||
{
|
||||
$user->optionset('sig_bbcode', $enable_bbcode);
|
||||
$user->optionset('sig_smilies', $enable_smilies);
|
||||
$user->optionset('sig_links', $enable_urls);
|
||||
|
||||
$sql_ary = array(
|
||||
'user_sig' => $signature,
|
||||
'user_options' => $user->data['user_options'],
|
||||
'user_sig_bbcode_uid' => $bbcode_uid,
|
||||
'user_sig_bbcode_bitfield' => $bbcode_bitfield
|
||||
);
|
||||
|
||||
/**
|
||||
* Modify user registration data before submitting it to the database
|
||||
*
|
||||
* @event core.ucp_profile_modify_signature_sql_ary
|
||||
* @var array sql_ary Array with user signature data to submit to the database
|
||||
* @since 3.1.10-RC1
|
||||
*/
|
||||
$vars = array('sql_ary');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_profile_modify_signature_sql_ary', compact($vars)));
|
||||
|
||||
$sql = 'UPDATE ' . USERS_TABLE . '
|
||||
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
|
||||
WHERE user_id = ' . $user->data['user_id'];
|
||||
$db->sql_query($sql);
|
||||
|
||||
$message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
|
||||
trigger_error($message);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace "error" strings with their real, localised form
|
||||
$error = array_map(array($user, 'lang'), $error);
|
||||
|
||||
if ($request->is_set_post('preview'))
|
||||
{
|
||||
$decoded_message = generate_text_for_edit($signature, $bbcode_uid, $bbcode_flags);
|
||||
}
|
||||
|
||||
/** @var \phpbb\controller\helper $controller_helper */
|
||||
$controller_helper = $phpbb_container->get('controller.helper');
|
||||
|
||||
$template->assign_vars(array(
|
||||
'ERROR' => (count($error)) ? implode('<br />', $error) : '',
|
||||
'SIGNATURE' => $decoded_message['text'],
|
||||
'SIGNATURE_PREVIEW' => $signature_preview,
|
||||
|
||||
'S_BBCODE_CHECKED' => (!$enable_bbcode) ? ' checked="checked"' : '',
|
||||
'S_SMILIES_CHECKED' => (!$enable_smilies) ? ' checked="checked"' : '',
|
||||
'S_MAGIC_URL_CHECKED' => (!$enable_urls) ? ' checked="checked"' : '',
|
||||
|
||||
'BBCODE_STATUS' => $user->lang(($config['allow_sig_bbcode'] ? 'BBCODE_IS_ON' : 'BBCODE_IS_OFF'), '<a href="' . $controller_helper->route('phpbb_help_bbcode_controller') . '">', '</a>'),
|
||||
'SMILIES_STATUS' => ($config['allow_sig_smilies']) ? $user->lang['SMILIES_ARE_ON'] : $user->lang['SMILIES_ARE_OFF'],
|
||||
'IMG_STATUS' => ($config['allow_sig_img']) ? $user->lang['IMAGES_ARE_ON'] : $user->lang['IMAGES_ARE_OFF'],
|
||||
'FLASH_STATUS' => ($config['allow_sig_flash']) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'],
|
||||
'URL_STATUS' => ($config['allow_sig_links']) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'],
|
||||
'MAX_FONT_SIZE' => (int) $config['max_sig_font_size'],
|
||||
|
||||
'L_SIGNATURE_EXPLAIN' => $user->lang('SIGNATURE_EXPLAIN', (int) $config['max_sig_chars']),
|
||||
|
||||
'S_BBCODE_ALLOWED' => $config['allow_sig_bbcode'],
|
||||
'S_SMILIES_ALLOWED' => $config['allow_sig_smilies'],
|
||||
'S_BBCODE_IMG' => ($config['allow_sig_img']) ? true : false,
|
||||
'S_BBCODE_FLASH' => ($config['allow_sig_flash']) ? true : false,
|
||||
'S_LINKS_ALLOWED' => ($config['allow_sig_links']) ? true : false)
|
||||
);
|
||||
|
||||
add_form_key('ucp_sig');
|
||||
|
||||
// Build custom bbcodes array
|
||||
display_custom_bbcodes();
|
||||
|
||||
// Generate smiley listing
|
||||
generate_smilies('inline', 0);
|
||||
|
||||
break;
|
||||
|
||||
case 'avatar':
|
||||
|
||||
add_form_key('ucp_avatar');
|
||||
|
||||
$avatars_enabled = false;
|
||||
|
||||
if ($config['allow_avatar'] && $auth->acl_get('u_chgavatar'))
|
||||
{
|
||||
/* @var $phpbb_avatar_manager \phpbb\avatar\manager */
|
||||
$phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
|
||||
$avatar_drivers = $phpbb_avatar_manager->get_enabled_drivers();
|
||||
|
||||
// This is normalised data, without the user_ prefix
|
||||
$avatar_data = \phpbb\avatar\manager::clean_row($user->data, 'user');
|
||||
|
||||
if ($submit)
|
||||
{
|
||||
if (check_form_key('ucp_avatar'))
|
||||
{
|
||||
$driver_name = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', ''));
|
||||
|
||||
if (in_array($driver_name, $avatar_drivers) && !$request->is_set_post('avatar_delete'))
|
||||
{
|
||||
$driver = $phpbb_avatar_manager->get_driver($driver_name);
|
||||
$result = $driver->process_form($request, $template, $user, $avatar_data, $error);
|
||||
|
||||
if ($result && empty($error))
|
||||
{
|
||||
// Success! Lets save the result in the database
|
||||
$result = array(
|
||||
'user_avatar_type' => $driver_name,
|
||||
'user_avatar' => $result['avatar'],
|
||||
'user_avatar_width' => $result['avatar_width'],
|
||||
'user_avatar_height' => $result['avatar_height'],
|
||||
);
|
||||
|
||||
/**
|
||||
* Trigger events on successfull avatar change
|
||||
*
|
||||
* @event core.ucp_profile_avatar_sql
|
||||
* @var array result Array with data to be stored in DB
|
||||
* @since 3.1.11-RC1
|
||||
*/
|
||||
$vars = array('result');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_profile_avatar_sql', compact($vars)));
|
||||
|
||||
$sql = 'UPDATE ' . USERS_TABLE . '
|
||||
SET ' . $db->sql_build_array('UPDATE', $result) . '
|
||||
WHERE user_id = ' . (int) $user->data['user_id'];
|
||||
$db->sql_query($sql);
|
||||
|
||||
meta_refresh(3, $this->u_action);
|
||||
$message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
|
||||
trigger_error($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$error[] = 'FORM_INVALID';
|
||||
}
|
||||
}
|
||||
|
||||
// Handle deletion of avatars
|
||||
if ($request->is_set_post('avatar_delete'))
|
||||
{
|
||||
if (!confirm_box(true))
|
||||
{
|
||||
confirm_box(false, $user->lang('CONFIRM_AVATAR_DELETE'), build_hidden_fields(array(
|
||||
'avatar_delete' => true,
|
||||
'i' => $id,
|
||||
'mode' => $mode))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$phpbb_avatar_manager->handle_avatar_delete($db, $user, $avatar_data, USERS_TABLE, 'user_');
|
||||
|
||||
meta_refresh(3, $this->u_action);
|
||||
$message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
|
||||
trigger_error($message);
|
||||
}
|
||||
}
|
||||
|
||||
$selected_driver = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', $user->data['user_avatar_type']));
|
||||
|
||||
$template->assign_vars(array(
|
||||
'AVATAR_MIN_WIDTH' => $config['avatar_min_width'],
|
||||
'AVATAR_MAX_WIDTH' => $config['avatar_max_width'],
|
||||
'AVATAR_MIN_HEIGHT' => $config['avatar_min_height'],
|
||||
'AVATAR_MAX_HEIGHT' => $config['avatar_max_height'],
|
||||
));
|
||||
|
||||
foreach ($avatar_drivers as $current_driver)
|
||||
{
|
||||
$driver = $phpbb_avatar_manager->get_driver($current_driver);
|
||||
|
||||
$avatars_enabled = true;
|
||||
$template->set_filenames(array(
|
||||
'avatar' => $driver->get_template_name(),
|
||||
));
|
||||
|
||||
if ($driver->prepare_form($request, $template, $user, $avatar_data, $error))
|
||||
{
|
||||
$driver_name = $phpbb_avatar_manager->prepare_driver_name($current_driver);
|
||||
$driver_upper = strtoupper($driver_name);
|
||||
|
||||
$template->assign_block_vars('avatar_drivers', array(
|
||||
'L_TITLE' => $user->lang($driver_upper . '_TITLE'),
|
||||
'L_EXPLAIN' => $user->lang($driver_upper . '_EXPLAIN'),
|
||||
|
||||
'DRIVER' => $driver_name,
|
||||
'SELECTED' => $current_driver == $selected_driver,
|
||||
'OUTPUT' => $template->assign_display('avatar'),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Replace "error" strings with their real, localised form
|
||||
$error = $phpbb_avatar_manager->localize_errors($user, $error);
|
||||
}
|
||||
|
||||
$avatar = phpbb_get_user_avatar($user->data, 'USER_AVATAR', true);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'ERROR' => (count($error)) ? implode('<br />', $error) : '',
|
||||
'AVATAR' => $avatar,
|
||||
|
||||
'S_FORM_ENCTYPE' => ' enctype="multipart/form-data"',
|
||||
|
||||
'L_AVATAR_EXPLAIN' => phpbb_avatar_explanation_string(),
|
||||
|
||||
'S_AVATARS_ENABLED' => ($config['allow_avatar'] && $avatars_enabled),
|
||||
));
|
||||
|
||||
break;
|
||||
|
||||
case 'autologin_keys':
|
||||
|
||||
add_form_key('ucp_autologin_keys');
|
||||
|
||||
if ($submit)
|
||||
{
|
||||
$keys = $request->variable('keys', array(''));
|
||||
|
||||
if (!check_form_key('ucp_autologin_keys'))
|
||||
{
|
||||
$error[] = 'FORM_INVALID';
|
||||
}
|
||||
|
||||
if (!count($error))
|
||||
{
|
||||
if (!empty($keys))
|
||||
{
|
||||
foreach ($keys as $key => $id)
|
||||
{
|
||||
$keys[$key] = $db->sql_like_expression($id . $db->get_any_char());
|
||||
}
|
||||
$sql_where = '(key_id ' . implode(' OR key_id ', $keys) . ')';
|
||||
$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
|
||||
WHERE user_id = ' . (int) $user->data['user_id'] . '
|
||||
AND ' . $sql_where ;
|
||||
|
||||
$db->sql_query($sql);
|
||||
|
||||
meta_refresh(3, $this->u_action);
|
||||
$message = $user->lang['AUTOLOGIN_SESSION_KEYS_DELETED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
|
||||
trigger_error($message);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace "error" strings with their real, localised form
|
||||
$error = array_map(array($user, 'lang'), $error);
|
||||
}
|
||||
|
||||
$sql = 'SELECT key_id, last_ip, last_login
|
||||
FROM ' . SESSIONS_KEYS_TABLE . '
|
||||
WHERE user_id = ' . (int) $user->data['user_id'] . '
|
||||
ORDER BY last_login ASC';
|
||||
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$template->assign_block_vars('sessions', array(
|
||||
'KEY' => substr($row['key_id'], 0, 8),
|
||||
'IP' => $row['last_ip'],
|
||||
'LOGIN_TIME' => $user->format_date($row['last_login']),
|
||||
));
|
||||
}
|
||||
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'ERROR' => (count($error)) ? implode('<br />', $error) : '',
|
||||
|
||||
'L_TITLE' => $user->lang['UCP_PROFILE_' . strtoupper($mode)],
|
||||
|
||||
'S_HIDDEN_FIELDS' => $s_hidden_fields,
|
||||
'S_UCP_ACTION' => $this->u_action)
|
||||
);
|
||||
|
||||
// Set desired template
|
||||
$this->tpl_name = 'ucp_profile_' . $mode;
|
||||
$this->page_title = 'UCP_PROFILE_' . strtoupper($mode);
|
||||
}
|
||||
}
|
||||
738
install/update/new/includes/ucp/ucp_register.php
Normal file
738
install/update/new/includes/ucp/ucp_register.php
Normal file
@@ -0,0 +1,738 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* ucp_register
|
||||
* Board registration
|
||||
*/
|
||||
class ucp_register
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $config, $db, $user, $template, $phpbb_root_path, $phpEx;
|
||||
global $request, $phpbb_container, $phpbb_dispatcher;
|
||||
|
||||
//
|
||||
if ($config['require_activation'] == USER_ACTIVATION_DISABLE ||
|
||||
(in_array($config['require_activation'], array(USER_ACTIVATION_SELF, USER_ACTIVATION_ADMIN)) && !$config['email_enable']))
|
||||
{
|
||||
trigger_error('UCP_REGISTER_DISABLE');
|
||||
}
|
||||
|
||||
$coppa = $request->is_set('coppa_yes') ? 1 : ($request->is_set('coppa_no') ? 0 : false);
|
||||
$coppa = $request->is_set('coppa') ? $request->variable('coppa', 0) : $coppa;
|
||||
$agreed = $request->variable('agreed', false);
|
||||
$submit = $request->is_set_post('submit');
|
||||
$change_lang = $request->variable('change_lang', '');
|
||||
$user_lang = $request->variable('lang', $user->lang_name);
|
||||
|
||||
if ($agreed && !check_form_key('ucp_register'))
|
||||
{
|
||||
$agreed = false;
|
||||
}
|
||||
|
||||
if ($coppa !== false && !check_form_key('ucp_register'))
|
||||
{
|
||||
$coppa = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add UCP register data before they are assigned to the template or submitted
|
||||
*
|
||||
* To assign data to the template, use $template->assign_vars()
|
||||
*
|
||||
* @event core.ucp_register_requests_after
|
||||
* @var bool coppa Is set coppa
|
||||
* @var bool agreed Did user agree to coppa?
|
||||
* @var bool submit Is set post submit?
|
||||
* @var string change_lang Change language request
|
||||
* @var string user_lang User language request
|
||||
* @since 3.1.11-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'coppa',
|
||||
'agreed',
|
||||
'submit',
|
||||
'change_lang',
|
||||
'user_lang',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_register_requests_after', compact($vars)));
|
||||
|
||||
add_form_key('ucp_register');
|
||||
|
||||
if ($change_lang || $user_lang != $config['default_lang'])
|
||||
{
|
||||
$use_lang = ($change_lang) ? basename($change_lang) : basename($user_lang);
|
||||
|
||||
if (!validate_language_iso_name($use_lang))
|
||||
{
|
||||
if ($change_lang)
|
||||
{
|
||||
$submit = false;
|
||||
|
||||
// Setting back agreed to let the user view the agreement in his/her language
|
||||
$agreed = false;
|
||||
}
|
||||
|
||||
$user_lang = $use_lang;
|
||||
}
|
||||
else
|
||||
{
|
||||
$change_lang = '';
|
||||
$user_lang = $user->lang_name;
|
||||
}
|
||||
}
|
||||
|
||||
/* @var $cp \phpbb\profilefields\manager */
|
||||
$cp = $phpbb_container->get('profilefields.manager');
|
||||
|
||||
$error = $cp_data = $cp_error = array();
|
||||
$s_hidden_fields = array();
|
||||
|
||||
// Handle login_link data added to $_hidden_fields
|
||||
$login_link_data = $this->get_login_link_data_array();
|
||||
|
||||
if (!empty($login_link_data))
|
||||
{
|
||||
// Confirm that we have all necessary data
|
||||
/* @var $provider_collection \phpbb\auth\provider_collection */
|
||||
$provider_collection = $phpbb_container->get('auth.provider_collection');
|
||||
$auth_provider = $provider_collection->get_provider($request->variable('auth_provider', ''));
|
||||
|
||||
$result = $auth_provider->login_link_has_necessary_data($login_link_data);
|
||||
if ($result !== null)
|
||||
{
|
||||
$error[] = $user->lang[$result];
|
||||
}
|
||||
|
||||
$s_hidden_fields = array_merge($s_hidden_fields, $this->get_login_link_data_for_hidden_fields($login_link_data));
|
||||
}
|
||||
|
||||
if (!$agreed || ($coppa === false && $config['coppa_enable']) || ($coppa && !$config['coppa_enable']))
|
||||
{
|
||||
$add_coppa = ($coppa !== false) ? '&coppa=' . $coppa : '';
|
||||
|
||||
$s_hidden_fields = array_merge($s_hidden_fields, array(
|
||||
'change_lang' => '',
|
||||
));
|
||||
|
||||
// If we change the language, we want to pass on some more possible parameter.
|
||||
if ($change_lang)
|
||||
{
|
||||
// We do not include the password
|
||||
$s_hidden_fields = array_merge($s_hidden_fields, array(
|
||||
'username' => $request->variable('username', '', true),
|
||||
'email' => strtolower($request->variable('email', '')),
|
||||
'lang' => $user->lang_name,
|
||||
'tz' => $request->variable('tz', $config['board_timezone']),
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
// Checking amount of available languages
|
||||
$sql = 'SELECT lang_id
|
||||
FROM ' . LANG_TABLE;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$lang_row = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$lang_row[] = $row;
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($coppa === false && $config['coppa_enable'])
|
||||
{
|
||||
$now = getdate();
|
||||
$coppa_birthday = $user->create_datetime()
|
||||
->setDate($now['year'] - 13, $now['mon'], $now['mday'] - 1)
|
||||
->setTime(0, 0, 0)
|
||||
->format($user->lang['DATE_FORMAT'], true);
|
||||
unset($now);
|
||||
|
||||
$template_vars = array(
|
||||
'S_LANG_OPTIONS' => (count($lang_row) > 1) ? language_select($user_lang) : '',
|
||||
'L_COPPA_NO' => $user->lang('UCP_COPPA_BEFORE', $coppa_birthday),
|
||||
'L_COPPA_YES' => $user->lang('UCP_COPPA_ON_AFTER', $coppa_birthday),
|
||||
|
||||
'S_SHOW_COPPA' => true,
|
||||
'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields),
|
||||
'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register'),
|
||||
|
||||
'COOKIE_NAME' => $config['cookie_name'],
|
||||
'COOKIE_PATH' => $config['cookie_path'],
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$template_vars = array(
|
||||
'S_LANG_OPTIONS' => (count($lang_row) > 1) ? language_select($user_lang) : '',
|
||||
'L_TERMS_OF_USE' => sprintf($user->lang['TERMS_OF_USE_CONTENT'], $config['sitename'], generate_board_url()),
|
||||
|
||||
'S_SHOW_COPPA' => false,
|
||||
'S_REGISTRATION' => true,
|
||||
'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields),
|
||||
'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register' . $add_coppa),
|
||||
|
||||
'COOKIE_NAME' => $config['cookie_name'],
|
||||
'COOKIE_PATH' => $config['cookie_path'],
|
||||
);
|
||||
}
|
||||
|
||||
$tpl_name = 'ucp_agreement';
|
||||
|
||||
/**
|
||||
* Allows to modify the agreements.
|
||||
*
|
||||
* @event core.ucp_register_agreement_modify_template_data
|
||||
* @var string tpl_name Template file
|
||||
* @var array template_vars Array with data about to be assigned to the template
|
||||
* @var array s_hidden_fields Array with hidden form elements
|
||||
* @var array lang_row Array with available languages, read only
|
||||
* @since 3.2.2-RC1
|
||||
*/
|
||||
$vars = array('tpl_name', 'template_vars', 's_hidden_fields', 'lang_row');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_register_agreement_modify_template_data', compact($vars)));
|
||||
|
||||
unset($lang_row);
|
||||
|
||||
$template_vars = array_merge($template_vars, array(
|
||||
'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields),
|
||||
));
|
||||
|
||||
$template->assign_vars($template_vars);
|
||||
|
||||
/**
|
||||
* Allows to modify the agreements.
|
||||
*
|
||||
* To assign data to the template, use $template->assign_vars()
|
||||
*
|
||||
* @event core.ucp_register_agreement
|
||||
* @since 3.1.6-RC1
|
||||
* @deprecated 3.2.2-RC1 Replaced by core.ucp_register_agreement_modify_template_data and to be removed in 3.3.0-RC1
|
||||
*/
|
||||
$phpbb_dispatcher->dispatch('core.ucp_register_agreement');
|
||||
|
||||
$this->tpl_name = $tpl_name;
|
||||
return;
|
||||
}
|
||||
|
||||
// The CAPTCHA kicks in here. We can't help that the information gets lost on language change.
|
||||
if ($config['enable_confirm'])
|
||||
{
|
||||
$captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
|
||||
$captcha->init(CONFIRM_REG);
|
||||
}
|
||||
|
||||
$timezone = $config['board_timezone'];
|
||||
|
||||
$data = array(
|
||||
'username' => $request->variable('username', '', true),
|
||||
'new_password' => $request->variable('new_password', '', true),
|
||||
'password_confirm' => $request->variable('password_confirm', '', true),
|
||||
'email' => strtolower($request->variable('email', '')),
|
||||
'lang' => basename($request->variable('lang', $user->lang_name)),
|
||||
'tz' => $request->variable('tz', $timezone),
|
||||
);
|
||||
/**
|
||||
* Add UCP register data before they are assigned to the template or submitted
|
||||
*
|
||||
* To assign data to the template, use $template->assign_vars()
|
||||
*
|
||||
* @event core.ucp_register_data_before
|
||||
* @var bool submit Do we display the form only
|
||||
* or did the user press submit
|
||||
* @var array data Array with current ucp registration data
|
||||
* @since 3.1.4-RC1
|
||||
*/
|
||||
$vars = array('submit', 'data');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_register_data_before', compact($vars)));
|
||||
|
||||
// Check and initialize some variables if needed
|
||||
if ($submit)
|
||||
{
|
||||
$error = validate_data($data, array(
|
||||
'username' => array(
|
||||
array('string', false, $config['min_name_chars'], $config['max_name_chars']),
|
||||
array('username', '')),
|
||||
'new_password' => array(
|
||||
array('string', false, $config['min_pass_chars'], 0),
|
||||
array('password')),
|
||||
'password_confirm' => array('string', false, $config['min_pass_chars'], 0),
|
||||
'email' => array(
|
||||
array('string', false, 6, 60),
|
||||
array('user_email')),
|
||||
'tz' => array('timezone'),
|
||||
'lang' => array('language_iso_name'),
|
||||
));
|
||||
|
||||
if (!check_form_key('ucp_register'))
|
||||
{
|
||||
$error[] = $user->lang['FORM_INVALID'];
|
||||
}
|
||||
|
||||
// Replace "error" strings with their real, localised form
|
||||
$error = array_map(array($user, 'lang'), $error);
|
||||
|
||||
if ($config['enable_confirm'])
|
||||
{
|
||||
$vc_response = $captcha->validate($data);
|
||||
if ($vc_response !== false)
|
||||
{
|
||||
$error[] = $vc_response;
|
||||
}
|
||||
|
||||
if ($config['max_reg_attempts'] && $captcha->get_attempt_count() > $config['max_reg_attempts'])
|
||||
{
|
||||
$error[] = $user->lang['TOO_MANY_REGISTERS'];
|
||||
}
|
||||
}
|
||||
|
||||
// DNSBL check
|
||||
if ($config['check_dnsbl'])
|
||||
{
|
||||
if (($dnsbl = $user->check_dnsbl('register')) !== false)
|
||||
{
|
||||
$error[] = sprintf($user->lang['IP_BLACKLISTED'], $user->ip, $dnsbl[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// validate custom profile fields
|
||||
$cp->submit_cp_field('register', $user->get_iso_lang_id(), $cp_data, $error);
|
||||
|
||||
if (!count($error))
|
||||
{
|
||||
if ($data['new_password'] != $data['password_confirm'])
|
||||
{
|
||||
$error[] = $user->lang['NEW_PASSWORD_ERROR'];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check UCP registration data after they are submitted
|
||||
*
|
||||
* @event core.ucp_register_data_after
|
||||
* @var bool submit Do we display the form only
|
||||
* or did the user press submit
|
||||
* @var array data Array with current ucp registration data
|
||||
* @var array cp_data Array with custom profile fields data
|
||||
* @var array error Array with list of errors
|
||||
* @since 3.1.4-RC1
|
||||
*/
|
||||
$vars = array('submit', 'data', 'cp_data', 'error');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_register_data_after', compact($vars)));
|
||||
|
||||
if (!count($error))
|
||||
{
|
||||
$server_url = generate_board_url();
|
||||
|
||||
// Which group by default?
|
||||
$group_name = ($coppa) ? 'REGISTERED_COPPA' : 'REGISTERED';
|
||||
|
||||
$sql = 'SELECT group_id
|
||||
FROM ' . GROUPS_TABLE . "
|
||||
WHERE group_name = '" . $db->sql_escape($group_name) . "'
|
||||
AND group_type = " . GROUP_SPECIAL;
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$row)
|
||||
{
|
||||
trigger_error('NO_GROUP');
|
||||
}
|
||||
|
||||
$group_id = $row['group_id'];
|
||||
|
||||
if (($coppa ||
|
||||
$config['require_activation'] == USER_ACTIVATION_SELF ||
|
||||
$config['require_activation'] == USER_ACTIVATION_ADMIN) && $config['email_enable'])
|
||||
{
|
||||
$user_actkey = gen_rand_string(mt_rand(6, 10));
|
||||
$user_type = USER_INACTIVE;
|
||||
$user_inactive_reason = INACTIVE_REGISTER;
|
||||
$user_inactive_time = time();
|
||||
}
|
||||
else
|
||||
{
|
||||
$user_type = USER_NORMAL;
|
||||
$user_actkey = '';
|
||||
$user_inactive_reason = 0;
|
||||
$user_inactive_time = 0;
|
||||
}
|
||||
|
||||
// Instantiate passwords manager
|
||||
/* @var $passwords_manager \phpbb\passwords\manager */
|
||||
$passwords_manager = $phpbb_container->get('passwords.manager');
|
||||
|
||||
$user_row = array(
|
||||
'username' => $data['username'],
|
||||
'user_password' => $passwords_manager->hash($data['new_password']),
|
||||
'user_email' => $data['email'],
|
||||
'group_id' => (int) $group_id,
|
||||
'user_timezone' => $data['tz'],
|
||||
'user_lang' => $data['lang'],
|
||||
'user_type' => $user_type,
|
||||
'user_actkey' => $user_actkey,
|
||||
'user_ip' => $user->ip,
|
||||
'user_regdate' => time(),
|
||||
'user_inactive_reason' => $user_inactive_reason,
|
||||
'user_inactive_time' => $user_inactive_time,
|
||||
);
|
||||
|
||||
if ($config['new_member_post_limit'])
|
||||
{
|
||||
$user_row['user_new'] = 1;
|
||||
}
|
||||
/**
|
||||
* Add into $user_row before user_add
|
||||
*
|
||||
* user_add allows adding more data into the users table
|
||||
*
|
||||
* @event core.ucp_register_user_row_after
|
||||
* @var bool submit Do we display the form only
|
||||
* or did the user press submit
|
||||
* @var array cp_data Array with custom profile fields data
|
||||
* @var array user_row Array with current ucp registration data
|
||||
* @since 3.1.4-RC1
|
||||
*/
|
||||
$vars = array('submit', 'cp_data', 'user_row');
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_register_user_row_after', compact($vars)));
|
||||
|
||||
// Register user...
|
||||
$user_id = user_add($user_row, $cp_data);
|
||||
|
||||
// This should not happen, because the required variables are listed above...
|
||||
if ($user_id === false)
|
||||
{
|
||||
trigger_error('NO_USER', E_USER_ERROR);
|
||||
}
|
||||
|
||||
// Okay, captcha, your job is done.
|
||||
if ($config['enable_confirm'] && isset($captcha))
|
||||
{
|
||||
$captcha->reset();
|
||||
}
|
||||
|
||||
if ($coppa && $config['email_enable'])
|
||||
{
|
||||
$message = $user->lang['ACCOUNT_COPPA'];
|
||||
$email_template = 'coppa_welcome_inactive';
|
||||
}
|
||||
else if ($config['require_activation'] == USER_ACTIVATION_SELF && $config['email_enable'])
|
||||
{
|
||||
$message = $user->lang['ACCOUNT_INACTIVE'];
|
||||
$email_template = 'user_welcome_inactive';
|
||||
}
|
||||
else if ($config['require_activation'] == USER_ACTIVATION_ADMIN && $config['email_enable'])
|
||||
{
|
||||
$message = $user->lang['ACCOUNT_INACTIVE_ADMIN'];
|
||||
$email_template = 'admin_welcome_inactive';
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = $user->lang['ACCOUNT_ADDED'];
|
||||
$email_template = 'user_welcome';
|
||||
|
||||
// Autologin after registration
|
||||
$user->session_create($user_id, 0, false, 1);
|
||||
}
|
||||
|
||||
if ($config['email_enable'])
|
||||
{
|
||||
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
|
||||
|
||||
$messenger = new messenger(false);
|
||||
|
||||
$messenger->template($email_template, $data['lang']);
|
||||
|
||||
$messenger->to($data['email'], $data['username']);
|
||||
|
||||
$messenger->anti_abuse_headers($config, $user);
|
||||
|
||||
$messenger->assign_vars(array(
|
||||
'WELCOME_MSG' => htmlspecialchars_decode(sprintf($user->lang['WELCOME_SUBJECT'], $config['sitename'])),
|
||||
'USERNAME' => htmlspecialchars_decode($data['username']),
|
||||
'PASSWORD' => htmlspecialchars_decode($data['new_password']),
|
||||
'U_ACTIVATE' => "$server_url/ucp.$phpEx?mode=activate&u=$user_id&k=$user_actkey")
|
||||
);
|
||||
|
||||
if ($coppa)
|
||||
{
|
||||
$messenger->assign_vars(array(
|
||||
'FAX_INFO' => $config['coppa_fax'],
|
||||
'MAIL_INFO' => $config['coppa_mail'],
|
||||
'EMAIL_ADDRESS' => $data['email'])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify messenger data before welcome mail is sent
|
||||
*
|
||||
* @event core.ucp_register_welcome_email_before
|
||||
* @var array user_row Array with user registration data
|
||||
* @var array cp_data Array with custom profile fields data
|
||||
* @var array data Array with current ucp registration data
|
||||
* @var string message Message to be displayed to the user after registration
|
||||
* @var string server_url Server URL
|
||||
* @var int user_id New user ID
|
||||
* @var string user_actkey User activation key
|
||||
* @var messenger messenger phpBB Messenger
|
||||
* @since 3.2.4-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'user_row',
|
||||
'cp_data',
|
||||
'data',
|
||||
'message',
|
||||
'server_url',
|
||||
'user_id',
|
||||
'user_actkey',
|
||||
'messenger',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_register_welcome_email_before', compact($vars)));
|
||||
|
||||
$messenger->send(NOTIFY_EMAIL);
|
||||
}
|
||||
|
||||
if ($config['require_activation'] == USER_ACTIVATION_ADMIN)
|
||||
{
|
||||
/* @var $phpbb_notifications \phpbb\notification\manager */
|
||||
$phpbb_notifications = $phpbb_container->get('notification_manager');
|
||||
$phpbb_notifications->add_notifications('notification.type.admin_activate_user', array(
|
||||
'user_id' => $user_id,
|
||||
'user_actkey' => $user_row['user_actkey'],
|
||||
'user_regdate' => $user_row['user_regdate'],
|
||||
));
|
||||
}
|
||||
|
||||
// Perform account linking if necessary
|
||||
if (!empty($login_link_data))
|
||||
{
|
||||
$login_link_data['user_id'] = $user_id;
|
||||
|
||||
$result = $auth_provider->link_account($login_link_data);
|
||||
|
||||
if ($result)
|
||||
{
|
||||
$message = $message . '<br /><br />' . $user->lang[$result];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform additional actions after user registration
|
||||
*
|
||||
* @event core.ucp_register_register_after
|
||||
* @var array user_row Array with user registration data
|
||||
* @var array cp_data Array with custom profile fields data
|
||||
* @var array data Array with current ucp registration data
|
||||
* @var string message Message to be displayed to the user after registration
|
||||
* @var string server_url Server URL
|
||||
* @var int user_id New user ID
|
||||
* @var string user_actkey User activation key
|
||||
* @since 3.2.4-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'user_row',
|
||||
'cp_data',
|
||||
'data',
|
||||
'message',
|
||||
'server_url',
|
||||
'user_id',
|
||||
'user_actkey',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_register_register_after', compact($vars)));
|
||||
|
||||
$message = $message . '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a>');
|
||||
trigger_error($message);
|
||||
}
|
||||
}
|
||||
|
||||
$s_hidden_fields = array_merge($s_hidden_fields, array(
|
||||
'agreed' => 'true',
|
||||
'change_lang' => 0,
|
||||
));
|
||||
|
||||
if ($config['coppa_enable'])
|
||||
{
|
||||
$s_hidden_fields['coppa'] = $coppa;
|
||||
}
|
||||
|
||||
if ($config['enable_confirm'])
|
||||
{
|
||||
$s_hidden_fields = array_merge($s_hidden_fields, $captcha->get_hidden_fields());
|
||||
}
|
||||
|
||||
// Visual Confirmation - Show images
|
||||
if ($config['enable_confirm'])
|
||||
{
|
||||
$template->assign_vars(array(
|
||||
'CAPTCHA_TEMPLATE' => $captcha->get_template(),
|
||||
));
|
||||
}
|
||||
|
||||
//
|
||||
$l_reg_cond = '';
|
||||
switch ($config['require_activation'])
|
||||
{
|
||||
case USER_ACTIVATION_SELF:
|
||||
$l_reg_cond = $user->lang['UCP_EMAIL_ACTIVATE'];
|
||||
break;
|
||||
|
||||
case USER_ACTIVATION_ADMIN:
|
||||
$l_reg_cond = $user->lang['UCP_ADMIN_ACTIVATE'];
|
||||
break;
|
||||
}
|
||||
|
||||
/* @var $provider_collection \phpbb\auth\provider_collection */
|
||||
$provider_collection = $phpbb_container->get('auth.provider_collection');
|
||||
$auth_provider = $provider_collection->get_provider();
|
||||
|
||||
$auth_provider_data = $auth_provider->get_login_data();
|
||||
if ($auth_provider_data)
|
||||
{
|
||||
if (isset($auth_provider_data['VARS']))
|
||||
{
|
||||
$template->assign_vars($auth_provider_data['VARS']);
|
||||
}
|
||||
|
||||
if (isset($auth_provider_data['BLOCK_VAR_NAME']))
|
||||
{
|
||||
foreach ($auth_provider_data['BLOCK_VARS'] as $block_vars)
|
||||
{
|
||||
$template->assign_block_vars($auth_provider_data['BLOCK_VAR_NAME'], $block_vars);
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'PROVIDER_TEMPLATE_FILE' => $auth_provider_data['TEMPLATE_FILE'],
|
||||
));
|
||||
}
|
||||
|
||||
// Assign template vars for timezone select
|
||||
phpbb_timezone_select($template, $user, $data['tz'], true);
|
||||
|
||||
$template_vars = array(
|
||||
'USERNAME' => $data['username'],
|
||||
'PASSWORD' => $data['new_password'],
|
||||
'PASSWORD_CONFIRM' => $data['password_confirm'],
|
||||
'EMAIL' => $data['email'],
|
||||
|
||||
'L_REG_COND' => $l_reg_cond,
|
||||
'L_USERNAME_EXPLAIN' => $user->lang($config['allow_name_chars'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_name_chars']), $user->lang('CHARACTERS', (int) $config['max_name_chars'])),
|
||||
'L_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars'])),
|
||||
|
||||
'S_LANG_OPTIONS' => language_select($data['lang']),
|
||||
'S_TZ_PRESELECT' => !$submit,
|
||||
'S_CONFIRM_REFRESH' => ($config['enable_confirm'] && $config['confirm_refresh']) ? true : false,
|
||||
'S_REGISTRATION' => true,
|
||||
'S_COPPA' => $coppa,
|
||||
'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register'),
|
||||
|
||||
'COOKIE_NAME' => $config['cookie_name'],
|
||||
'COOKIE_PATH' => $config['cookie_path'],
|
||||
);
|
||||
|
||||
$tpl_name = 'ucp_register';
|
||||
|
||||
/**
|
||||
* Modify template data on the registration page
|
||||
*
|
||||
* @event core.ucp_register_modify_template_data
|
||||
* @var array template_vars Array with template data
|
||||
* @var array data Array with user data, read only
|
||||
* @var array error Array with errors
|
||||
* @var array s_hidden_fields Array with hidden field elements
|
||||
* @var string tpl_name Template name
|
||||
* @since 3.2.2-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'template_vars',
|
||||
'data',
|
||||
'error',
|
||||
's_hidden_fields',
|
||||
'tpl_name',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.ucp_register_modify_template_data', compact($vars)));
|
||||
|
||||
$template_vars = array_merge($template_vars, array(
|
||||
'ERROR' => (count($error)) ? implode('<br />', $error) : '',
|
||||
'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields),
|
||||
));
|
||||
|
||||
$template->assign_vars($template_vars);
|
||||
|
||||
//
|
||||
$user->profile_fields = array();
|
||||
|
||||
// Generate profile fields -> Template Block Variable profile_fields
|
||||
$cp->generate_profile_fields('register', $user->get_iso_lang_id());
|
||||
|
||||
//
|
||||
$this->tpl_name = $tpl_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the login_link data array
|
||||
*
|
||||
* @return array Returns an array of all POST paramaters whose names
|
||||
* begin with 'login_link_'
|
||||
*/
|
||||
protected function get_login_link_data_array()
|
||||
{
|
||||
global $request;
|
||||
|
||||
$var_names = $request->variable_names(\phpbb\request\request_interface::POST);
|
||||
$login_link_data = array();
|
||||
$string_start_length = strlen('login_link_');
|
||||
|
||||
foreach ($var_names as $var_name)
|
||||
{
|
||||
if (strpos($var_name, 'login_link_') === 0)
|
||||
{
|
||||
$key_name = substr($var_name, $string_start_length);
|
||||
$login_link_data[$key_name] = $request->variable($var_name, '', false, \phpbb\request\request_interface::POST);
|
||||
}
|
||||
}
|
||||
|
||||
return $login_link_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends they key names of an associative array with 'login_link_' for
|
||||
* inclusion on the page as hidden fields.
|
||||
*
|
||||
* @param array $data The array to be modified
|
||||
* @return array The modified array
|
||||
*/
|
||||
protected function get_login_link_data_for_hidden_fields($data)
|
||||
{
|
||||
$new_data = array();
|
||||
|
||||
foreach ($data as $key => $value)
|
||||
{
|
||||
$new_data['login_link_' . $key] = $value;
|
||||
}
|
||||
|
||||
return $new_data;
|
||||
}
|
||||
}
|
||||
163
install/update/new/includes/ucp/ucp_resend.php
Normal file
163
install/update/new/includes/ucp/ucp_resend.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* ucp_resend
|
||||
* Resending activation emails
|
||||
*/
|
||||
class ucp_resend
|
||||
{
|
||||
var $u_action;
|
||||
|
||||
function main($id, $mode)
|
||||
{
|
||||
global $config, $phpbb_root_path, $phpEx;
|
||||
global $db, $user, $auth, $template, $request;
|
||||
|
||||
$username = $request->variable('username', '', true);
|
||||
$email = strtolower($request->variable('email', ''));
|
||||
$submit = (isset($_POST['submit'])) ? true : false;
|
||||
|
||||
add_form_key('ucp_resend');
|
||||
|
||||
if ($submit)
|
||||
{
|
||||
if (!check_form_key('ucp_resend'))
|
||||
{
|
||||
trigger_error('FORM_INVALID');
|
||||
}
|
||||
|
||||
$sql = 'SELECT user_id, group_id, username, user_email, user_type, user_lang, user_actkey, user_inactive_reason
|
||||
FROM ' . USERS_TABLE . "
|
||||
WHERE user_email = '" . $db->sql_escape($email) . "'
|
||||
AND username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
|
||||
$result = $db->sql_query($sql);
|
||||
$user_row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$user_row)
|
||||
{
|
||||
trigger_error('NO_EMAIL_USER');
|
||||
}
|
||||
|
||||
if ($user_row['user_type'] == USER_IGNORE)
|
||||
{
|
||||
trigger_error('NO_USER');
|
||||
}
|
||||
|
||||
if (!$user_row['user_actkey'] && $user_row['user_type'] != USER_INACTIVE)
|
||||
{
|
||||
trigger_error('ACCOUNT_ALREADY_ACTIVATED');
|
||||
}
|
||||
|
||||
if (!$user_row['user_actkey'] || ($user_row['user_type'] == USER_INACTIVE && $user_row['user_inactive_reason'] == INACTIVE_MANUAL))
|
||||
{
|
||||
trigger_error('ACCOUNT_DEACTIVATED');
|
||||
}
|
||||
|
||||
// Determine coppa status on group (REGISTERED(_COPPA))
|
||||
$sql = 'SELECT group_name, group_type
|
||||
FROM ' . GROUPS_TABLE . '
|
||||
WHERE group_id = ' . $user_row['group_id'];
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$row)
|
||||
{
|
||||
trigger_error('NO_GROUP');
|
||||
}
|
||||
|
||||
$coppa = ($row['group_name'] == 'REGISTERED_COPPA' && $row['group_type'] == GROUP_SPECIAL) ? true : false;
|
||||
|
||||
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
|
||||
$messenger = new messenger(false);
|
||||
|
||||
if ($config['require_activation'] == USER_ACTIVATION_SELF || $coppa)
|
||||
{
|
||||
$messenger->template(($coppa) ? 'coppa_resend_inactive' : 'user_resend_inactive', $user_row['user_lang']);
|
||||
$messenger->set_addresses($user_row);
|
||||
|
||||
$messenger->anti_abuse_headers($config, $user);
|
||||
|
||||
$messenger->assign_vars(array(
|
||||
'WELCOME_MSG' => htmlspecialchars_decode(sprintf($user->lang['WELCOME_SUBJECT'], $config['sitename'])),
|
||||
'USERNAME' => htmlspecialchars_decode($user_row['username']),
|
||||
'U_ACTIVATE' => generate_board_url() . "/ucp.$phpEx?mode=activate&u={$user_row['user_id']}&k={$user_row['user_actkey']}")
|
||||
);
|
||||
|
||||
if ($coppa)
|
||||
{
|
||||
$messenger->assign_vars(array(
|
||||
'FAX_INFO' => $config['coppa_fax'],
|
||||
'MAIL_INFO' => $config['coppa_mail'],
|
||||
'EMAIL_ADDRESS' => $user_row['user_email'])
|
||||
);
|
||||
}
|
||||
|
||||
$messenger->send(NOTIFY_EMAIL);
|
||||
}
|
||||
|
||||
if ($config['require_activation'] == USER_ACTIVATION_ADMIN)
|
||||
{
|
||||
// Grab an array of user_id's with a_user permissions ... these users can activate a user
|
||||
$admin_ary = $auth->acl_get_list(false, 'a_user', false);
|
||||
|
||||
$sql = 'SELECT user_id, username, user_email, user_lang, user_jabber, user_notify_type
|
||||
FROM ' . USERS_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('user_id', $admin_ary[0]['a_user']);
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$messenger->template('admin_activate', $row['user_lang']);
|
||||
$messenger->set_addresses($row);
|
||||
|
||||
$messenger->anti_abuse_headers($config, $user);
|
||||
|
||||
$messenger->assign_vars(array(
|
||||
'USERNAME' => htmlspecialchars_decode($user_row['username']),
|
||||
'U_USER_DETAILS' => generate_board_url() . "/memberlist.$phpEx?mode=viewprofile&u={$user_row['user_id']}",
|
||||
'U_ACTIVATE' => generate_board_url() . "/ucp.$phpEx?mode=activate&u={$user_row['user_id']}&k={$user_row['user_actkey']}")
|
||||
);
|
||||
|
||||
$messenger->send($row['user_notify_type']);
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
meta_refresh(3, append_sid("{$phpbb_root_path}index.$phpEx"));
|
||||
|
||||
$message = ($config['require_activation'] == USER_ACTIVATION_ADMIN) ? $user->lang['ACTIVATION_EMAIL_SENT_ADMIN'] : $user->lang['ACTIVATION_EMAIL_SENT'];
|
||||
$message .= '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a>');
|
||||
trigger_error($message);
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'USERNAME' => $username,
|
||||
'EMAIL' => $email,
|
||||
'S_PROFILE_ACTION' => append_sid($phpbb_root_path . 'ucp.' . $phpEx, 'mode=resend_act'))
|
||||
);
|
||||
|
||||
$this->tpl_name = 'ucp_resend';
|
||||
$this->page_title = 'UCP_RESEND';
|
||||
}
|
||||
}
|
||||
1469
install/update/new/includes/utf/utf_tools.php
Normal file
1469
install/update/new/includes/utf/utf_tools.php
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user