aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/acp/acp_attachments.php41
-rw-r--r--phpBB/includes/acp/acp_ban.php5
-rw-r--r--phpBB/includes/acp/acp_bbcodes.php33
-rw-r--r--phpBB/includes/acp/acp_board.php51
-rw-r--r--phpBB/includes/acp/acp_bots.php6
-rw-r--r--phpBB/includes/acp/acp_contact.php2
-rw-r--r--phpBB/includes/acp/acp_database.php1662
-rw-r--r--phpBB/includes/acp/acp_disallow.php4
-rw-r--r--phpBB/includes/acp/acp_email.php11
-rw-r--r--phpBB/includes/acp/acp_extensions.php30
-rw-r--r--phpBB/includes/acp/acp_forums.php49
-rw-r--r--phpBB/includes/acp/acp_groups.php36
-rw-r--r--phpBB/includes/acp/acp_icons.php20
-rw-r--r--phpBB/includes/acp/acp_inactive.php18
-rw-r--r--phpBB/includes/acp/acp_jabber.php12
-rw-r--r--phpBB/includes/acp/acp_language.php43
-rw-r--r--phpBB/includes/acp/acp_main.php13
-rw-r--r--phpBB/includes/acp/acp_modules.php617
-rw-r--r--phpBB/includes/acp/acp_permission_roles.php11
-rw-r--r--phpBB/includes/acp/acp_permissions.php33
-rw-r--r--phpBB/includes/acp/acp_profile.php102
-rw-r--r--phpBB/includes/acp/acp_prune.php23
-rw-r--r--phpBB/includes/acp/acp_search.php5
-rw-r--r--phpBB/includes/acp/acp_send_statistics.php5
-rw-r--r--phpBB/includes/acp/acp_styles.php30
-rw-r--r--phpBB/includes/acp/acp_users.php105
-rw-r--r--phpBB/includes/acp/acp_words.php4
-rw-r--r--phpBB/includes/acp/auth.php64
-rw-r--r--phpBB/includes/bbcode.php76
-rw-r--r--phpBB/includes/compatibility_globals.php77
-rw-r--r--phpBB/includes/constants.php6
-rw-r--r--phpBB/includes/functions.php824
-rw-r--r--phpBB/includes/functions_acp.php30
-rw-r--r--phpBB/includes/functions_admin.php351
-rw-r--r--phpBB/includes/functions_compatibility.php120
-rw-r--r--phpBB/includes/functions_compress.php69
-rw-r--r--phpBB/includes/functions_content.php181
-rw-r--r--phpBB/includes/functions_convert.php18
-rw-r--r--phpBB/includes/functions_display.php123
-rw-r--r--phpBB/includes/functions_install.php4
-rw-r--r--phpBB/includes/functions_mcp.php40
-rw-r--r--phpBB/includes/functions_messenger.php37
-rw-r--r--phpBB/includes/functions_module.php4
-rw-r--r--phpBB/includes/functions_posting.php264
-rw-r--r--phpBB/includes/functions_privmsgs.php91
-rw-r--r--phpBB/includes/functions_upload.php1107
-rw-r--r--phpBB/includes/functions_user.php176
-rw-r--r--phpBB/includes/mcp/info/mcp_pm_reports.php6
-rw-r--r--phpBB/includes/mcp/mcp_forum.php44
-rw-r--r--phpBB/includes/mcp/mcp_front.php39
-rw-r--r--phpBB/includes/mcp/mcp_logs.php2
-rw-r--r--phpBB/includes/mcp/mcp_main.php34
-rw-r--r--phpBB/includes/mcp/mcp_pm_reports.php2
-rw-r--r--phpBB/includes/mcp/mcp_post.php61
-rw-r--r--phpBB/includes/mcp/mcp_queue.php24
-rw-r--r--phpBB/includes/mcp/mcp_reports.php63
-rw-r--r--phpBB/includes/mcp/mcp_topic.php24
-rw-r--r--phpBB/includes/mcp/mcp_warn.php1
-rw-r--r--phpBB/includes/message_parser.php437
-rw-r--r--phpBB/includes/startup.php6
-rw-r--r--phpBB/includes/ucp/info/ucp_notifications.php2
-rw-r--r--phpBB/includes/ucp/ucp_activate.php13
-rw-r--r--phpBB/includes/ucp/ucp_attachments.php10
-rw-r--r--phpBB/includes/ucp/ucp_groups.php19
-rw-r--r--phpBB/includes/ucp/ucp_notifications.php31
-rw-r--r--phpBB/includes/ucp/ucp_pm_compose.php56
-rw-r--r--phpBB/includes/ucp/ucp_pm_options.php13
-rw-r--r--phpBB/includes/ucp/ucp_pm_viewmessage.php5
-rw-r--r--phpBB/includes/ucp/ucp_prefs.php2
-rw-r--r--phpBB/includes/ucp/ucp_profile.php17
-rw-r--r--phpBB/includes/ucp/ucp_register.php10
71 files changed, 2331 insertions, 5223 deletions
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php
index 6bef42c472..00dd209c6f 100644
--- a/phpBB/includes/acp/acp_attachments.php
+++ b/phpBB/includes/acp/acp_attachments.php
@@ -36,13 +36,19 @@ class acp_attachments
/** @var \phpbb\user */
protected $user;
+ /** @var \phpbb\filesystem\filesystem_interface */
+ protected $filesystem;
+
+ /** @var \phpbb\attachment\manager */
+ protected $attachment_manager;
+
public $id;
public $u_action;
protected $new_config;
function main($id, $mode)
{
- global $db, $user, $auth, $template, $cache, $phpbb_container;
+ global $db, $user, $auth, $template, $cache, $phpbb_container, $phpbb_filesystem;
global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx, $phpbb_log, $request;
$this->id = $id;
@@ -51,6 +57,8 @@ class acp_attachments
$this->template = $template;
$this->user = $user;
$this->phpbb_container = $phpbb_container;
+ $this->filesystem = $phpbb_filesystem;
+ $this->attachment_manager = $phpbb_container->get('attachment.manager');
$user->add_lang(array('posting', 'viewtopic', 'acp/attachments'));
@@ -106,7 +114,10 @@ class acp_attachments
{
case 'attach':
- include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
+ if (!function_exists('get_supported_image_types'))
+ {
+ include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
+ }
$sql = 'SELECT group_name, cat_id
FROM ' . EXTENSION_GROUPS_TABLE . '
@@ -153,7 +164,7 @@ class acp_attachments
'img_create_thumbnail' => array('lang' => 'CREATE_THUMBNAIL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'img_max_thumb_width' => array('lang' => 'MAX_THUMB_WIDTH', 'validate' => 'int:0:999999999999999', 'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'img_min_thumb_filesize' => array('lang' => 'MIN_THUMB_FILESIZE', 'validate' => 'int:0:999999999999999', 'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),
- 'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'path', 'type' => 'text:20:200', 'explain' => true, 'append' => '&nbsp;&nbsp;<span>[ <a href="' . $this->u_action . '&amp;action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'),
+ 'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'absolute_path', 'type' => 'text:20:200', 'explain' => true, 'append' => '&nbsp;&nbsp;<span>[ <a href="' . $this->u_action . '&amp;action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'),
'img_max' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int:0:9999', 'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'img_link' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int:0:9999', 'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
)
@@ -616,10 +627,7 @@ class acp_attachments
$cat_lang = array(
ATTACHMENT_CATEGORY_NONE => $user->lang['NO_FILE_CAT'],
ATTACHMENT_CATEGORY_IMAGE => $user->lang['CAT_IMAGES'],
- ATTACHMENT_CATEGORY_WM => $user->lang['CAT_WM_FILES'],
- ATTACHMENT_CATEGORY_RM => $user->lang['CAT_RM_FILES'],
ATTACHMENT_CATEGORY_FLASH => $user->lang['CAT_FLASH_FILES'],
- ATTACHMENT_CATEGORY_QUICKTIME => $user->lang['CAT_QUICKTIME_FILES'],
);
$group_id = $request->variable('g', 0);
@@ -921,11 +929,11 @@ class acp_attachments
$delete_files = array();
while ($row = $db->sql_fetchrow($result))
{
- phpbb_unlink($row['physical_filename'], 'file');
+ $this->attachment_manager->unlink($row['physical_filename'], 'file');
if ($row['thumbnail'])
{
- phpbb_unlink($row['physical_filename'], 'thumbnail');
+ $this->attachment_manager->unlink($row['physical_filename'], 'thumbnail');
}
$delete_files[$row['attach_id']] = $row['real_filename'];
@@ -1090,7 +1098,7 @@ class acp_attachments
}
$db->sql_freeresult($result);
- if ($num_deleted = delete_attachments('attach', $delete_files))
+ if ($num_deleted = $this->attachment_manager->delete('attach', $delete_files))
{
if (sizeof($delete_files) != $num_deleted)
{
@@ -1367,10 +1375,7 @@ class acp_attachments
$types = array(
ATTACHMENT_CATEGORY_NONE => $user->lang['NO_FILE_CAT'],
ATTACHMENT_CATEGORY_IMAGE => $user->lang['CAT_IMAGES'],
- ATTACHMENT_CATEGORY_WM => $user->lang['CAT_WM_FILES'],
- ATTACHMENT_CATEGORY_RM => $user->lang['CAT_RM_FILES'],
ATTACHMENT_CATEGORY_FLASH => $user->lang['CAT_FLASH_FILES'],
- ATTACHMENT_CATEGORY_QUICKTIME => $user->lang['CAT_QUICKTIME_FILES'],
);
if ($group_id)
@@ -1501,7 +1506,15 @@ class acp_attachments
if (!file_exists($phpbb_root_path . $upload_dir))
{
@mkdir($phpbb_root_path . $upload_dir, 0777);
- phpbb_chmod($phpbb_root_path . $upload_dir, CHMOD_READ | CHMOD_WRITE);
+
+ try
+ {
+ $this->filesystem->phpbb_chmod($phpbb_root_path . $upload_dir, CHMOD_READ | CHMOD_WRITE);
+ }
+ catch (\phpbb\filesystem\exception\filesystem_exception $e)
+ {
+ // Do nothing
+ }
}
}
@@ -1517,7 +1530,7 @@ class acp_attachments
return;
}
- if (!phpbb_is_writable($phpbb_root_path . $upload_dir))
+ if (!$this->filesystem->is_writable($phpbb_root_path . $upload_dir))
{
$error[] = sprintf($user->lang['NO_WRITE_UPLOAD'], $upload_dir);
return;
diff --git a/phpBB/includes/acp/acp_ban.php b/phpBB/includes/acp/acp_ban.php
index b555f46a94..286bc92813 100644
--- a/phpBB/includes/acp/acp_ban.php
+++ b/phpBB/includes/acp/acp_ban.php
@@ -28,7 +28,10 @@ class acp_ban
global $user, $template, $request, $phpbb_dispatcher;
global $phpbb_root_path, $phpEx;
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_ban'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$bansubmit = $request->is_set_post('bansubmit');
$unbansubmit = $request->is_set_post('unbansubmit');
diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php
index a5cd48c444..c9225a7eae 100644
--- a/phpBB/includes/acp/acp_bbcodes.php
+++ b/phpBB/includes/acp/acp_bbcodes.php
@@ -25,7 +25,7 @@ class acp_bbcodes
function main($id, $mode)
{
- global $db, $user, $auth, $template, $cache, $request, $phpbb_dispatcher;
+ global $db, $user, $auth, $template, $cache, $request, $phpbb_dispatcher, $phpbb_container;
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_log;
$user->add_lang('acp/posting');
@@ -269,6 +269,7 @@ class acp_bbcodes
$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';
@@ -280,6 +281,7 @@ class acp_bbcodes
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';
@@ -319,6 +321,7 @@ class acp_bbcodes
{
$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($row['bbcode_tag']));
if ($request->is_ajax())
@@ -413,8 +416,6 @@ class acp_bbcodes
// Allow unicode characters for URL|LOCAL_URL|RELATIVE_URL|INTTEXT tokens
$utf8 = preg_match('/(URL|LOCAL_URL|RELATIVE_URL|INTTEXT)/', $bbcode_match);
- $utf8_pcre_properties = phpbb_pcre_utf8_support();
-
$fp_match = preg_quote($bbcode_match, '!');
$fp_replace = preg_replace('#^\[(.*?)\]#', '[$1:$uid]', $bbcode_match);
$fp_replace = preg_replace('#\[/(.*?)\]$#', '[/$1:$uid]', $fp_replace);
@@ -445,7 +446,7 @@ class acp_bbcodes
'!([a-zA-Z0-9-+.,_ ]+)!' => "$1"
),
'INTTEXT' => array(
- ($utf8_pcre_properties) ? '!([\p{L}\p{N}\-+,_. ]+)!u' : '!([a-zA-Z0-9\-+,_. ]+)!u' => "$1"
+ '!([\p{L}\p{N}\-+,_. ]+)!u' => "$1"
),
'IDENTIFIER' => array(
'!([a-zA-Z0-9-_]+)!' => "$1"
@@ -465,7 +466,7 @@ class acp_bbcodes
'EMAIL' => '(' . get_preg_expression('email') . ')',
'TEXT' => '(.*?)',
'SIMPLETEXT' => '([a-zA-Z0-9-+.,_ ]+)',
- 'INTTEXT' => ($utf8_pcre_properties) ? '([\p{L}\p{N}\-+,_. ]+)' : '([a-zA-Z0-9\-+,_. ]+)',
+ 'INTTEXT' => '([\p{L}\p{N}\-+,_. ]+)',
'IDENTIFIER' => '([a-zA-Z0-9-_]+)',
'COLOR' => '([a-zA-Z]+|#[0-9abcdefABCDEF]+)',
'NUMBER' => '([0-9]+)',
@@ -473,7 +474,7 @@ class acp_bbcodes
$pad = 0;
$modifiers = 'i';
- $modifiers .= ($utf8 && $utf8_pcre_properties) ? 'u' : '';
+ $modifiers .= ($utf8) ? 'u' : '';
if (preg_match_all('/\{(' . implode('|', array_keys($tokens)) . ')[0-9]*\}/i', $bbcode_match, $m))
{
@@ -488,7 +489,9 @@ class acp_bbcodes
if (preg_match_all('/(?<!\\\\)\$([0-9]+)/', $replace, $repad))
{
$repad = $pad + sizeof(array_unique($repad[0]));
- $replace = preg_replace('/(?<!\\\\)\$([0-9]+)/e', "'\${' . (\$1 + \$pad) . '}'", $replace);
+ $replace = preg_replace_callback('/(?<!\\\\)\$([0-9]+)/', function ($match) use ($pad) {
+ return '${' . ($match[1] + $pad) . '}';
+ }, $replace);
$pad = $repad;
}
@@ -553,10 +556,18 @@ class acp_bbcodes
trigger_error($user->lang['BBCODE_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
- $fp_match = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $fp_match);
- $fp_replace = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $fp_replace);
- $sp_match = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $sp_match);
- $sp_replace = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $sp_replace);
+ $fp_match = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
+ return strtolower($match[0]);
+ }, $fp_match);
+ $fp_replace = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
+ return strtolower($match[0]);
+ }, $fp_replace);
+ $sp_match = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
+ return strtolower($match[0]);
+ }, $sp_match);
+ $sp_replace = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
+ return strtolower($match[0]);
+ }, $sp_replace);
return array(
'bbcode_tag' => $bbcode_tag,
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index 965f1a6f70..5a0ede1de3 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -94,6 +94,7 @@ class acp_board
'allow_bbcode' => array('lang' => 'ALLOW_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'allow_smilies' => array('lang' => 'ALLOW_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'allow_sig' => array('lang' => 'ALLOW_SIG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ 'allow_board_notifications' => array('lang' => 'ALLOW_BOARD_NOTIFICATIONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'allow_nocensors' => array('lang' => 'ALLOW_NO_CENSORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'allow_bookmarks' => array('lang' => 'ALLOW_BOOKMARKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'allow_birthdays' => array('lang' => 'ALLOW_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
@@ -447,6 +448,7 @@ class acp_board
'board_email' => array('lang' => 'ADMIN_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true),
'board_email_sig' => array('lang' => 'EMAIL_SIG', 'validate' => 'string', 'type' => 'textarea:5:30', 'explain' => true),
'board_hide_emails' => array('lang' => 'BOARD_HIDE_EMAILS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'send_test_email' => array('lang' => 'SEND_TEST_EMAIL', 'validate' => 'bool', 'type' => 'custom', 'method' => 'send_test_email', 'explain' => true),
'legend2' => 'SMTP_SETTINGS',
'smtp_delivery' => array('lang' => 'USE_SMTP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
@@ -501,7 +503,7 @@ class acp_board
}
// We go through the display_vars to make sure no one is trying to set variables he/she is not allowed to...
- foreach ($display_vars['vars'] as $config_name => $null)
+ foreach ($display_vars['vars'] as $config_name => $data)
{
if (!isset($cfg_array[$config_name]) || strpos($config_name, 'legend') !== false)
{
@@ -515,7 +517,8 @@ class acp_board
if ($config_name == 'guest_style')
{
- if (isset($cfg_array[$config_name])) {
+ if (isset($cfg_array[$config_name]))
+ {
$this->guest_style_set($cfg_array[$config_name]);
}
continue;
@@ -532,6 +535,13 @@ class acp_board
if ($submit)
{
+ if (strpos($data['type'], 'password') === 0 && $config_value === '********')
+ {
+ // Do not update password fields if the content is ********,
+ // because that is the password replacement we use to not
+ // send the password to the output
+ continue;
+ }
$config->set($config_name, $config_value);
if ($config_name == 'allow_quick_reply' && isset($_POST['allow_quick_reply_enable']))
@@ -561,6 +571,7 @@ class acp_board
$old_auth_config = array();
foreach ($auth_providers as $provider)
{
+ /** @var \phpbb\auth\provider\provider_interface $provider */
if ($fields = $provider->acp())
{
// Check if we need to create config fields for this plugin and save config when submit was pressed
@@ -576,6 +587,14 @@ class acp_board
continue;
}
+ if (substr($field, -9) === '_password' && $cfg_array[$field] === '********')
+ {
+ // Do not update password fields if the content is ********,
+ // because that is the password replacement we use to not
+ // send the password to the output
+ continue;
+ }
+
$old_auth_config[$field] = $this->new_config[$field];
$config_value = $cfg_array[$field];
$this->new_config[$field] = $config_value;
@@ -613,6 +632,27 @@ class acp_board
}
}
+ if ($mode == 'email' && $request->is_set_post('send_test_email'))
+ {
+ if ($config['email_enable'])
+ {
+ include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+
+ $messenger = new messenger(false);
+ $messenger->template('test');
+ $messenger->set_addresses($user->data);
+ $messenger->anti_abuse_headers($config, $user);
+ $messenger->send(NOTIFY_EMAIL);
+
+ trigger_error($user->lang('TEST_EMAIL_SENT') . adm_back_link($this->u_action));
+ }
+ else
+ {
+ $user->add_lang('memberlist');
+ trigger_error($user->lang('EMAIL_DISABLED') . adm_back_link($this->u_action), E_USER_WARNING);
+ }
+ }
+
if ($submit)
{
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_' . strtoupper($mode));
@@ -1121,4 +1161,11 @@ class acp_board
return h_radio($field_name, array(1 => 'YES', 0 => 'NO'), $value) .
($message !== false ? '<br /><span>' . $user->lang($message) . '</span>' : '');
}
+
+ function send_test_email($value, $key)
+ {
+ global $user;
+
+ return '<input class="button2" type="submit" id="' . $key . '" name="' . $key . '" value="' . $user->lang['SEND_TEST_EMAIL'] . '" />';
+ }
}
diff --git a/phpBB/includes/acp/acp_bots.php b/phpBB/includes/acp/acp_bots.php
index e0220ad0c3..422e1e34d7 100644
--- a/phpBB/includes/acp/acp_bots.php
+++ b/phpBB/includes/acp/acp_bots.php
@@ -141,7 +141,11 @@ class acp_bots
case 'edit':
case 'add':
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+
+ if (!function_exists('user_update_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$bot_row = array(
'bot_name' => $request->variable('bot_name', '', true),
diff --git a/phpBB/includes/acp/acp_contact.php b/phpBB/includes/acp/acp_contact.php
index 945add66a4..1a4d5b95a3 100644
--- a/phpBB/includes/acp/acp_contact.php
+++ b/phpBB/includes/acp/acp_contact.php
@@ -119,7 +119,7 @@ class acp_contact
'S_SMILIES_DISABLE_CHECKED' => !$contact_admin_edit['allow_smilies'],
'S_MAGIC_URL_DISABLE_CHECKED' => !$contact_admin_edit['allow_urls'],
- 'BBCODE_STATUS' => $user->lang('BBCODE_IS_ON', '<a href="' . $controller_helper->route('phpbb_help_controller', array('mode' => 'bbcode')) . '">', '</a>'),
+ 'BBCODE_STATUS' => $user->lang('BBCODE_IS_ON', '<a href="' . $controller_helper->route('phpbb_help_bbcode_controller') . '">', '</a>'),
'SMILIES_STATUS' => $user->lang['SMILIES_ARE_ON'],
'IMG_STATUS' => $user->lang['IMAGES_ARE_ON'],
'FLASH_STATUS' => $user->lang['FLASH_IS_ON'],
diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php
index 25cddaa5d4..984301a38f 100644
--- a/phpBB/includes/acp/acp_database.php
+++ b/phpBB/includes/acp/acp_database.php
@@ -90,36 +90,9 @@ class acp_database
$time = time();
$filename = 'backup_' . $time . '_' . unique_id();
- switch ($db->get_sql_layer())
- {
- case 'mysqli':
- case 'mysql4':
- case 'mysql':
- $extractor = new mysql_extractor($format, $filename, $time, $download, $store);
- break;
-
- case 'sqlite':
- $extractor = new sqlite_extractor($format, $filename, $time, $download, $store);
- break;
- case 'sqlite3':
- $extractor = new sqlite3_extractor($format, $filename, $time, $download, $store);
- break;
-
- case 'postgres':
- $extractor = new postgres_extractor($format, $filename, $time, $download, $store);
- break;
-
- case 'oracle':
- $extractor = new oracle_extractor($format, $filename, $time, $download, $store);
- break;
-
- case 'mssql':
- case 'mssql_odbc':
- case 'mssqlnative':
- $extractor = new mssql_extractor($format, $filename, $time, $download, $store);
- break;
- }
+ $extractor = $phpbb_container->get('dbal.extractor');
+ $extractor->init_extractor($format, $filename, $time, $download, $store);
$extractor->write_start($table_prefix);
@@ -461,1637 +434,6 @@ class acp_database
}
}
-class base_extractor
-{
- var $fh;
- var $fp;
- var $write;
- var $close;
- var $store;
- var $download;
- var $time;
- var $format;
- var $run_comp = false;
-
- function base_extractor($format, $filename, $time, $download = false, $store = false)
- {
- global $request;
-
- $this->download = $download;
- $this->store = $store;
- $this->time = $time;
- $this->format = $format;
-
- switch ($format)
- {
- case 'text':
- $ext = '.sql';
- $open = 'fopen';
- $this->write = 'fwrite';
- $this->close = 'fclose';
- $mimetype = 'text/x-sql';
- break;
- case 'bzip2':
- $ext = '.sql.bz2';
- $open = 'bzopen';
- $this->write = 'bzwrite';
- $this->close = 'bzclose';
- $mimetype = 'application/x-bzip2';
- break;
- case 'gzip':
- $ext = '.sql.gz';
- $open = 'gzopen';
- $this->write = 'gzwrite';
- $this->close = 'gzclose';
- $mimetype = 'application/x-gzip';
- break;
- }
-
- if ($download == true)
- {
- $name = $filename . $ext;
- header('Cache-Control: private, no-cache');
- header("Content-Type: $mimetype; name=\"$name\"");
- header("Content-disposition: attachment; filename=$name");
-
- switch ($format)
- {
- case 'bzip2':
- ob_start();
- break;
-
- case 'gzip':
- if (strpos($request->header('Accept-Encoding'), 'gzip') !== false && strpos(strtolower($request->header('User-Agent')), 'msie') === false)
- {
- ob_start('ob_gzhandler');
- }
- else
- {
- $this->run_comp = true;
- }
- break;
- }
- }
-
- if ($store == true)
- {
- global $phpbb_root_path;
- $file = $phpbb_root_path . 'store/' . $filename . $ext;
-
- $this->fp = $open($file, 'w');
-
- if (!$this->fp)
- {
- trigger_error('FILE_WRITE_FAIL', E_USER_ERROR);
- }
- }
- }
-
- function write_end()
- {
- static $close;
-
- if ($this->store)
- {
- if ($close === null)
- {
- $close = $this->close;
- }
- $close($this->fp);
- }
-
- // bzip2 must be written all the way at the end
- if ($this->download && $this->format === 'bzip2')
- {
- $c = ob_get_clean();
- echo bzcompress($c);
- }
- }
-
- function flush($data)
- {
- static $write;
- if ($this->store === true)
- {
- if ($write === null)
- {
- $write = $this->write;
- }
- $write($this->fp, $data);
- }
-
- if ($this->download === true)
- {
- if ($this->format === 'bzip2' || $this->format === 'text' || ($this->format === 'gzip' && !$this->run_comp))
- {
- echo $data;
- }
-
- // we can write the gzip data as soon as we get it
- if ($this->format === 'gzip')
- {
- if ($this->run_comp)
- {
- echo gzencode($data);
- }
- else
- {
- ob_flush();
- flush();
- }
- }
- }
- }
-}
-
-class mysql_extractor extends base_extractor
-{
- function write_start($table_prefix)
- {
- $sql_data = "#\n";
- $sql_data .= "# phpBB Backup Script\n";
- $sql_data .= "# Dump of tables for $table_prefix\n";
- $sql_data .= "# DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
- $sql_data .= "#\n";
- $this->flush($sql_data);
- }
-
- function write_table($table_name)
- {
- global $db;
- static $new_extract;
-
- if ($new_extract === null)
- {
- if ($db->get_sql_layer() === 'mysqli' || version_compare($db->sql_server_info(true), '3.23.20', '>='))
- {
- $new_extract = true;
- }
- else
- {
- $new_extract = false;
- }
- }
-
- if ($new_extract)
- {
- $this->new_write_table($table_name);
- }
- else
- {
- $this->old_write_table($table_name);
- }
- }
-
- function write_data($table_name)
- {
- global $db;
- if ($db->get_sql_layer() === 'mysqli')
- {
- $this->write_data_mysqli($table_name);
- }
- else
- {
- $this->write_data_mysql($table_name);
- }
- }
-
- function write_data_mysqli($table_name)
- {
- global $db;
- $sql = "SELECT *
- FROM $table_name";
- $result = mysqli_query($db->get_db_connect_id(), $sql, MYSQLI_USE_RESULT);
- if ($result != false)
- {
- $fields_cnt = mysqli_num_fields($result);
-
- // Get field information
- $field = mysqli_fetch_fields($result);
- $field_set = array();
-
- for ($j = 0; $j < $fields_cnt; $j++)
- {
- $field_set[] = $field[$j]->name;
- }
-
- $search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
- $replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
- $fields = implode(', ', $field_set);
- $sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
- $first_set = true;
- $query_len = 0;
- $max_len = get_usable_memory();
-
- while ($row = mysqli_fetch_row($result))
- {
- $values = array();
- if ($first_set)
- {
- $query = $sql_data . '(';
- }
- else
- {
- $query .= ',(';
- }
-
- for ($j = 0; $j < $fields_cnt; $j++)
- {
- if (!isset($row[$j]) || is_null($row[$j]))
- {
- $values[$j] = 'NULL';
- }
- else if (($field[$j]->flags & 32768) && !($field[$j]->flags & 1024))
- {
- $values[$j] = $row[$j];
- }
- else
- {
- $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
- }
- }
- $query .= implode(', ', $values) . ')';
-
- $query_len += strlen($query);
- if ($query_len > $max_len)
- {
- $this->flush($query . ";\n\n");
- $query = '';
- $query_len = 0;
- $first_set = true;
- }
- else
- {
- $first_set = false;
- }
- }
- mysqli_free_result($result);
-
- // check to make sure we have nothing left to flush
- if (!$first_set && $query)
- {
- $this->flush($query . ";\n\n");
- }
- }
- }
-
- function write_data_mysql($table_name)
- {
- global $db;
- $sql = "SELECT *
- FROM $table_name";
- $result = mysql_unbuffered_query($sql, $db->get_db_connect_id());
-
- if ($result != false)
- {
- $fields_cnt = mysql_num_fields($result);
-
- // Get field information
- $field = array();
- for ($i = 0; $i < $fields_cnt; $i++)
- {
- $field[] = mysql_fetch_field($result, $i);
- }
- $field_set = array();
-
- for ($j = 0; $j < $fields_cnt; $j++)
- {
- $field_set[] = $field[$j]->name;
- }
-
- $search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
- $replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
- $fields = implode(', ', $field_set);
- $sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
- $first_set = true;
- $query_len = 0;
- $max_len = get_usable_memory();
-
- while ($row = mysql_fetch_row($result))
- {
- $values = array();
- if ($first_set)
- {
- $query = $sql_data . '(';
- }
- else
- {
- $query .= ',(';
- }
-
- for ($j = 0; $j < $fields_cnt; $j++)
- {
- if (!isset($row[$j]) || is_null($row[$j]))
- {
- $values[$j] = 'NULL';
- }
- else if ($field[$j]->numeric && ($field[$j]->type !== 'timestamp'))
- {
- $values[$j] = $row[$j];
- }
- else
- {
- $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
- }
- }
- $query .= implode(', ', $values) . ')';
-
- $query_len += strlen($query);
- if ($query_len > $max_len)
- {
- $this->flush($query . ";\n\n");
- $query = '';
- $query_len = 0;
- $first_set = true;
- }
- else
- {
- $first_set = false;
- }
- }
- mysql_free_result($result);
-
- // check to make sure we have nothing left to flush
- if (!$first_set && $query)
- {
- $this->flush($query . ";\n\n");
- }
- }
- }
-
- function new_write_table($table_name)
- {
- global $db;
-
- $sql = 'SHOW CREATE TABLE ' . $table_name;
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
-
- $sql_data = '# Table: ' . $table_name . "\n";
- $sql_data .= "DROP TABLE IF EXISTS $table_name;\n";
- $this->flush($sql_data . $row['Create Table'] . ";\n\n");
-
- $db->sql_freeresult($result);
- }
-
- function old_write_table($table_name)
- {
- global $db;
-
- $sql_data = '# Table: ' . $table_name . "\n";
- $sql_data .= "DROP TABLE IF EXISTS $table_name;\n";
- $sql_data .= "CREATE TABLE $table_name(\n";
- $rows = array();
-
- $sql = "SHOW FIELDS
- FROM $table_name";
- $result = $db->sql_query($sql);
-
- while ($row = $db->sql_fetchrow($result))
- {
- $line = ' ' . $row['Field'] . ' ' . $row['Type'];
-
- if (!is_null($row['Default']))
- {
- $line .= " DEFAULT '{$row['Default']}'";
- }
-
- if ($row['Null'] != 'YES')
- {
- $line .= ' NOT NULL';
- }
-
- if ($row['Extra'] != '')
- {
- $line .= ' ' . $row['Extra'];
- }
-
- $rows[] = $line;
- }
- $db->sql_freeresult($result);
-
- $sql = "SHOW KEYS
- FROM $table_name";
-
- $result = $db->sql_query($sql);
-
- $index = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $kname = $row['Key_name'];
-
- if ($kname != 'PRIMARY')
- {
- if ($row['Non_unique'] == 0)
- {
- $kname = "UNIQUE|$kname";
- }
- }
-
- if ($row['Sub_part'])
- {
- $row['Column_name'] .= '(' . $row['Sub_part'] . ')';
- }
- $index[$kname][] = $row['Column_name'];
- }
- $db->sql_freeresult($result);
-
- foreach ($index as $key => $columns)
- {
- $line = ' ';
-
- if ($key == 'PRIMARY')
- {
- $line .= 'PRIMARY KEY (' . implode(', ', $columns) . ')';
- }
- else if (strpos($key, 'UNIQUE') === 0)
- {
- $line .= 'UNIQUE ' . substr($key, 7) . ' (' . implode(', ', $columns) . ')';
- }
- else if (strpos($key, 'FULLTEXT') === 0)
- {
- $line .= 'FULLTEXT ' . substr($key, 9) . ' (' . implode(', ', $columns) . ')';
- }
- else
- {
- $line .= "KEY $key (" . implode(', ', $columns) . ')';
- }
-
- $rows[] = $line;
- }
-
- $sql_data .= implode(",\n", $rows);
- $sql_data .= "\n);\n\n";
-
- $this->flush($sql_data);
- }
-}
-
-class sqlite_extractor extends base_extractor
-{
- function write_start($prefix)
- {
- $sql_data = "--\n";
- $sql_data .= "-- phpBB Backup Script\n";
- $sql_data .= "-- Dump of tables for $prefix\n";
- $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
- $sql_data .= "--\n";
- $sql_data .= "BEGIN TRANSACTION;\n";
- $this->flush($sql_data);
- }
-
- function write_table($table_name)
- {
- global $db;
- $sql_data = '-- Table: ' . $table_name . "\n";
- $sql_data .= "DROP TABLE $table_name;\n";
-
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '" . $db->sql_escape($table_name) . "'
- ORDER BY type DESC, name;";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- // Create Table
- $sql_data .= $row['sql'] . ";\n";
-
- $result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');");
-
- $ar = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $ar[] = $row;
- }
- $db->sql_freeresult($result);
-
- foreach ($ar as $value)
- {
- if (strpos($value['name'], 'autoindex') !== false)
- {
- continue;
- }
-
- $result = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($value['name']) . "');");
-
- $fields = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $fields[] = $row['name'];
- }
- $db->sql_freeresult($result);
-
- $sql_data .= 'CREATE ' . ($value['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $value['name'] . ' on ' . $table_name . ' (' . implode(', ', $fields) . ");\n";
- }
-
- $this->flush($sql_data . "\n");
- }
-
- function write_data($table_name)
- {
- global $db;
-
- $col_types = sqlite_fetch_column_types($db->get_db_connect_id(), $table_name);
-
- $sql = "SELECT *
- FROM $table_name";
- $result = sqlite_unbuffered_query($db->get_db_connect_id(), $sql);
- $rows = sqlite_fetch_all($result, SQLITE_ASSOC);
- $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES (';
- foreach ($rows as $row)
- {
- foreach ($row as $column_name => $column_data)
- {
- if (is_null($column_data))
- {
- $row[$column_name] = 'NULL';
- }
- else if ($column_data == '')
- {
- $row[$column_name] = "''";
- }
- else if (strpos($col_types[$column_name], 'text') !== false || strpos($col_types[$column_name], 'char') !== false || strpos($col_types[$column_name], 'blob') !== false)
- {
- $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data));
- }
- }
- $this->flush($sql_insert . implode(', ', $row) . ");\n");
- }
- }
-
- function write_end()
- {
- $this->flush("COMMIT;\n");
- parent::write_end();
- }
-}
-
-class sqlite3_extractor extends base_extractor
-{
- function write_start($prefix)
- {
- $sql_data = "--\n";
- $sql_data .= "-- phpBB Backup Script\n";
- $sql_data .= "-- Dump of tables for $prefix\n";
- $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
- $sql_data .= "--\n";
- $sql_data .= "BEGIN TRANSACTION;\n";
- $this->flush($sql_data);
- }
-
- function write_table($table_name)
- {
- global $db;
- $sql_data = '-- Table: ' . $table_name . "\n";
- $sql_data .= "DROP TABLE $table_name;\n";
-
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '" . $db->sql_escape($table_name) . "'
- ORDER BY name ASC;";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- // Create Table
- $sql_data .= $row['sql'] . ";\n";
-
- $result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');");
-
- while ($row = $db->sql_fetchrow($result))
- {
- if (strpos($row['name'], 'autoindex') !== false)
- {
- continue;
- }
-
- $result2 = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($row['name']) . "');");
-
- $fields = array();
- while ($row2 = $db->sql_fetchrow($result2))
- {
- $fields[] = $row2['name'];
- }
- $db->sql_freeresult($result2);
-
- $sql_data .= 'CREATE ' . ($row['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $row['name'] . ' ON ' . $table_name . ' (' . implode(', ', $fields) . ");\n";
- }
- $db->sql_freeresult($result);
-
- $this->flush($sql_data . "\n");
- }
-
- function write_data($table_name)
- {
- global $db;
-
- $result = $db->sql_query("PRAGMA table_info('" . $db->sql_escape($table_name) . "');");
-
- $col_types = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $col_types[$row['name']] = $row['type'];
- }
- $db->sql_freeresult($result);
-
- $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES (';
-
- $sql = "SELECT *
- FROM $table_name";
- $result = $db->sql_query($sql);
-
- while ($row = $db->sql_fetchrow($result))
- {
- foreach ($row as $column_name => $column_data)
- {
- if (is_null($column_data))
- {
- $row[$column_name] = 'NULL';
- }
- else if ($column_data === '')
- {
- $row[$column_name] = "''";
- }
- else if (stripos($col_types[$column_name], 'text') !== false || stripos($col_types[$column_name], 'char') !== false || stripos($col_types[$column_name], 'blob') !== false)
- {
- $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data));
- }
- }
- $this->flush($sql_insert . implode(', ', $row) . ");\n");
- }
- }
-
- function write_end()
- {
- $this->flush("COMMIT;\n");
- parent::write_end();
- }
-}
-
-class postgres_extractor extends base_extractor
-{
- function write_start($prefix)
- {
- $sql_data = "--\n";
- $sql_data .= "-- phpBB Backup Script\n";
- $sql_data .= "-- Dump of tables for $prefix\n";
- $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
- $sql_data .= "--\n";
- $sql_data .= "BEGIN TRANSACTION;\n";
- $this->flush($sql_data);
- }
-
- function write_table($table_name)
- {
- global $db;
- static $domains_created = array();
-
- $sql = "SELECT a.domain_name, a.data_type, a.character_maximum_length, a.domain_default
- FROM INFORMATION_SCHEMA.domains a, INFORMATION_SCHEMA.column_domain_usage b
- WHERE a.domain_name = b.domain_name
- AND b.table_name = '{$table_name}'";
- $result = $db->sql_query($sql);
- while ($row = $db->sql_fetchrow($result))
- {
- if (empty($domains_created[$row['domain_name']]))
- {
- $domains_created[$row['domain_name']] = true;
- //$sql_data = "DROP DOMAIN {$row['domain_name']};\n";
- $sql_data = "CREATE DOMAIN {$row['domain_name']} as {$row['data_type']}";
- if (!empty($row['character_maximum_length']))
- {
- $sql_data .= '(' . $row['character_maximum_length'] . ')';
- }
- $sql_data .= ' NOT NULL';
- if (!empty($row['domain_default']))
- {
- $sql_data .= ' DEFAULT ' . $row['domain_default'];
- }
- $this->flush($sql_data . ";\n");
- }
- }
-
- $sql_data = '-- Table: ' . $table_name . "\n";
- $sql_data .= "DROP TABLE $table_name;\n";
- // PGSQL does not "tightly" bind sequences and tables, we must guess...
- $sql = "SELECT relname
- FROM pg_class
- WHERE relkind = 'S'
- AND relname = '{$table_name}_seq'";
- $result = $db->sql_query($sql);
- // We don't even care about storing the results. We already know the answer if we get rows back.
- if ($db->sql_fetchrow($result))
- {
- $sql_data .= "DROP SEQUENCE {$table_name}_seq;\n";
- $sql_data .= "CREATE SEQUENCE {$table_name}_seq;\n";
- }
- $db->sql_freeresult($result);
-
- $field_query = "SELECT a.attnum, a.attname as field, t.typname as type, a.attlen as length, a.atttypmod as lengthvar, a.attnotnull as notnull
- FROM pg_class c, pg_attribute a, pg_type t
- WHERE c.relname = '" . $db->sql_escape($table_name) . "'
- AND a.attnum > 0
- AND a.attrelid = c.oid
- AND a.atttypid = t.oid
- ORDER BY a.attnum";
- $result = $db->sql_query($field_query);
-
- $sql_data .= "CREATE TABLE $table_name(\n";
- $lines = array();
- while ($row = $db->sql_fetchrow($result))
- {
- // Get the data from the table
- $sql_get_default = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
- FROM pg_attrdef d, pg_class c
- WHERE (c.relname = '" . $db->sql_escape($table_name) . "')
- AND (c.oid = d.adrelid)
- AND d.adnum = " . $row['attnum'];
- $def_res = $db->sql_query($sql_get_default);
- $def_row = $db->sql_fetchrow($def_res);
- $db->sql_freeresult($def_res);
-
- if (empty($def_row))
- {
- unset($row['rowdefault']);
- }
- else
- {
- $row['rowdefault'] = $def_row['rowdefault'];
- }
-
- if ($row['type'] == 'bpchar')
- {
- // Internally stored as bpchar, but isn't accepted in a CREATE TABLE statement.
- $row['type'] = 'char';
- }
-
- $line = ' ' . $row['field'] . ' ' . $row['type'];
-
- if (strpos($row['type'], 'char') !== false)
- {
- if ($row['lengthvar'] > 0)
- {
- $line .= '(' . ($row['lengthvar'] - 4) . ')';
- }
- }
-
- if (strpos($row['type'], 'numeric') !== false)
- {
- $line .= '(';
- $line .= sprintf("%s,%s", (($row['lengthvar'] >> 16) & 0xffff), (($row['lengthvar'] - 4) & 0xffff));
- $line .= ')';
- }
-
- if (isset($row['rowdefault']))
- {
- $line .= ' DEFAULT ' . $row['rowdefault'];
- }
-
- if ($row['notnull'] == 't')
- {
- $line .= ' NOT NULL';
- }
-
- $lines[] = $line;
- }
- $db->sql_freeresult($result);
-
- // Get the listing of primary keys.
- $sql_pri_keys = "SELECT ic.relname as index_name, bc.relname as tab_name, ta.attname as column_name, i.indisunique as unique_key, i.indisprimary as primary_key
- FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia
- WHERE (bc.oid = i.indrelid)
- AND (ic.oid = i.indexrelid)
- AND (ia.attrelid = i.indexrelid)
- AND (ta.attrelid = bc.oid)
- AND (bc.relname = '" . $db->sql_escape($table_name) . "')
- AND (ta.attrelid = i.indrelid)
- AND (ta.attnum = i.indkey[ia.attnum-1])
- ORDER BY index_name, tab_name, column_name";
-
- $result = $db->sql_query($sql_pri_keys);
-
- $index_create = $index_rows = $primary_key = array();
-
- // We do this in two steps. It makes placing the comma easier
- while ($row = $db->sql_fetchrow($result))
- {
- if ($row['primary_key'] == 't')
- {
- $primary_key[] = $row['column_name'];
- $primary_key_name = $row['index_name'];
- }
- else
- {
- // We have to store this all this info because it is possible to have a multi-column key...
- // we can loop through it again and build the statement
- $index_rows[$row['index_name']]['table'] = $table_name;
- $index_rows[$row['index_name']]['unique'] = ($row['unique_key'] == 't') ? true : false;
- $index_rows[$row['index_name']]['column_names'][] = $row['column_name'];
- }
- }
- $db->sql_freeresult($result);
-
- if (!empty($index_rows))
- {
- foreach ($index_rows as $idx_name => $props)
- {
- $index_create[] = 'CREATE ' . ($props['unique'] ? 'UNIQUE ' : '') . "INDEX $idx_name ON $table_name (" . implode(', ', $props['column_names']) . ");";
- }
- }
-
- if (!empty($primary_key))
- {
- $lines[] = " CONSTRAINT $primary_key_name PRIMARY KEY (" . implode(', ', $primary_key) . ")";
- }
-
- // Generate constraint clauses for CHECK constraints
- $sql_checks = "SELECT conname as index_name, consrc
- FROM pg_constraint, pg_class bc
- WHERE conrelid = bc.oid
- AND bc.relname = '" . $db->sql_escape($table_name) . "'
- AND NOT EXISTS (
- SELECT *
- FROM pg_constraint as c, pg_inherits as i
- WHERE i.inhrelid = pg_constraint.conrelid
- AND c.conname = pg_constraint.conname
- AND c.consrc = pg_constraint.consrc
- AND c.conrelid = i.inhparent
- )";
- $result = $db->sql_query($sql_checks);
-
- // Add the constraints to the sql file.
- while ($row = $db->sql_fetchrow($result))
- {
- if (!is_null($row['consrc']))
- {
- $lines[] = ' CONSTRAINT ' . $row['index_name'] . ' CHECK ' . $row['consrc'];
- }
- }
- $db->sql_freeresult($result);
-
- $sql_data .= implode(", \n", $lines);
- $sql_data .= "\n);\n";
-
- if (!empty($index_create))
- {
- $sql_data .= implode("\n", $index_create) . "\n\n";
- }
- $this->flush($sql_data);
- }
-
- function write_data($table_name)
- {
- global $db;
- // Grab all of the data from current table.
- $sql = "SELECT *
- FROM $table_name";
- $result = $db->sql_query($sql);
-
- $i_num_fields = pg_num_fields($result);
- $seq = '';
-
- for ($i = 0; $i < $i_num_fields; $i++)
- {
- $ary_type[] = pg_field_type($result, $i);
- $ary_name[] = pg_field_name($result, $i);
-
- $sql = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
- FROM pg_attrdef d, pg_class c
- WHERE (c.relname = '{$table_name}')
- AND (c.oid = d.adrelid)
- AND d.adnum = " . strval($i + 1);
- $result2 = $db->sql_query($sql);
- if ($row = $db->sql_fetchrow($result2))
- {
- // Determine if we must reset the sequences
- if (strpos($row['rowdefault'], "nextval('") === 0)
- {
- $seq .= "SELECT SETVAL('{$table_name}_seq',(select case when max({$ary_name[$i]})>0 then max({$ary_name[$i]})+1 else 1 end FROM {$table_name}));\n";
- }
- }
- }
-
- $this->flush("COPY $table_name (" . implode(', ', $ary_name) . ') FROM stdin;' . "\n");
- while ($row = $db->sql_fetchrow($result))
- {
- $schema_vals = array();
-
- // Build the SQL statement to recreate the data.
- for ($i = 0; $i < $i_num_fields; $i++)
- {
- $str_val = $row[$ary_name[$i]];
-
- if (preg_match('#char|text|bool|bytea#i', $ary_type[$i]))
- {
- $str_val = str_replace(array("\n", "\t", "\r", "\b", "\f", "\v"), array('\n', '\t', '\r', '\b', '\f', '\v'), addslashes($str_val));
- $str_empty = '';
- }
- else
- {
- $str_empty = '\N';
- }
-
- if (empty($str_val) && $str_val !== '0')
- {
- $str_val = $str_empty;
- }
-
- $schema_vals[] = $str_val;
- }
-
- // Take the ordered fields and their associated data and build it
- // into a valid sql statement to recreate that field in the data.
- $this->flush(implode("\t", $schema_vals) . "\n");
- }
- $db->sql_freeresult($result);
- $this->flush("\\.\n");
-
- // Write out the sequence statements
- $this->flush($seq);
- }
-
- function write_end()
- {
- $this->flush("COMMIT;\n");
- parent::write_end();
- }
-}
-
-class mssql_extractor extends base_extractor
-{
- function write_end()
- {
- $this->flush("COMMIT\nGO\n");
- parent::write_end();
- }
-
- function write_start($prefix)
- {
- $sql_data = "--\n";
- $sql_data .= "-- phpBB Backup Script\n";
- $sql_data .= "-- Dump of tables for $prefix\n";
- $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
- $sql_data .= "--\n";
- $sql_data .= "BEGIN TRANSACTION\n";
- $sql_data .= "GO\n";
- $this->flush($sql_data);
- }
-
- function write_table($table_name)
- {
- global $db;
- $sql_data = '-- Table: ' . $table_name . "\n";
- $sql_data .= "IF OBJECT_ID(N'$table_name', N'U') IS NOT NULL\n";
- $sql_data .= "DROP TABLE $table_name;\n";
- $sql_data .= "GO\n";
- $sql_data .= "\nCREATE TABLE [$table_name] (\n";
- $rows = array();
-
- $text_flag = false;
-
- $sql = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') as IS_IDENTITY
- FROM INFORMATION_SCHEMA.COLUMNS
- WHERE TABLE_NAME = '$table_name'";
- $result = $db->sql_query($sql);
-
- while ($row = $db->sql_fetchrow($result))
- {
- $line = "\t[{$row['COLUMN_NAME']}] [{$row['DATA_TYPE']}]";
-
- if ($row['DATA_TYPE'] == 'text')
- {
- $text_flag = true;
- }
-
- if ($row['IS_IDENTITY'])
- {
- $line .= ' IDENTITY (1 , 1)';
- }
-
- if ($row['CHARACTER_MAXIMUM_LENGTH'] && $row['DATA_TYPE'] !== 'text')
- {
- $line .= ' (' . $row['CHARACTER_MAXIMUM_LENGTH'] . ')';
- }
-
- if ($row['IS_NULLABLE'] == 'YES')
- {
- $line .= ' NULL';
- }
- else
- {
- $line .= ' NOT NULL';
- }
-
- if ($row['COLUMN_DEFAULT'])
- {
- $line .= ' DEFAULT ' . $row['COLUMN_DEFAULT'];
- }
-
- $rows[] = $line;
- }
- $db->sql_freeresult($result);
-
- $sql_data .= implode(",\n", $rows);
- $sql_data .= "\n) ON [PRIMARY]";
-
- if ($text_flag)
- {
- $sql_data .= " TEXTIMAGE_ON [PRIMARY]";
- }
-
- $sql_data .= "\nGO\n\n";
- $rows = array();
-
- $sql = "SELECT CONSTRAINT_NAME, COLUMN_NAME
- FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
- WHERE TABLE_NAME = '$table_name'";
- $result = $db->sql_query($sql);
- while ($row = $db->sql_fetchrow($result))
- {
- if (!sizeof($rows))
- {
- $sql_data .= "ALTER TABLE [$table_name] WITH NOCHECK ADD\n";
- $sql_data .= "\tCONSTRAINT [{$row['CONSTRAINT_NAME']}] PRIMARY KEY CLUSTERED \n\t(\n";
- }
- $rows[] = "\t\t[{$row['COLUMN_NAME']}]";
- }
- if (sizeof($rows))
- {
- $sql_data .= implode(",\n", $rows);
- $sql_data .= "\n\t) ON [PRIMARY] \nGO\n";
- }
- $db->sql_freeresult($result);
-
- $index = array();
- $sql = "EXEC sp_statistics '$table_name'";
- $result = $db->sql_query($sql);
- while ($row = $db->sql_fetchrow($result))
- {
- if ($row['TYPE'] == 3)
- {
- $index[$row['INDEX_NAME']][] = '[' . $row['COLUMN_NAME'] . ']';
- }
- }
- $db->sql_freeresult($result);
-
- foreach ($index as $index_name => $column_name)
- {
- $index[$index_name] = implode(', ', $column_name);
- }
-
- foreach ($index as $index_name => $columns)
- {
- $sql_data .= "\nCREATE INDEX [$index_name] ON [$table_name]($columns) ON [PRIMARY]\nGO\n";
- }
- $this->flush($sql_data);
- }
-
- function write_data($table_name)
- {
- global $db;
-
- if ($db->get_sql_layer() === 'mssql')
- {
- $this->write_data_mssql($table_name);
- }
- else if($db->get_sql_layer() === 'mssqlnative')
- {
- $this->write_data_mssqlnative($table_name);
- }
- else
- {
- $this->write_data_odbc($table_name);
- }
- }
-
- function write_data_mssql($table_name)
- {
- global $db;
- $ary_type = $ary_name = array();
- $ident_set = false;
- $sql_data = '';
-
- // Grab all of the data from current table.
- $sql = "SELECT *
- FROM $table_name";
- $result = $db->sql_query($sql);
-
- $retrieved_data = mssql_num_rows($result);
-
- $i_num_fields = mssql_num_fields($result);
-
- for ($i = 0; $i < $i_num_fields; $i++)
- {
- $ary_type[$i] = mssql_field_type($result, $i);
- $ary_name[$i] = mssql_field_name($result, $i);
- }
-
- if ($retrieved_data)
- {
- $sql = "SELECT 1 as has_identity
- FROM INFORMATION_SCHEMA.COLUMNS
- WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
- $result2 = $db->sql_query($sql);
- $row2 = $db->sql_fetchrow($result2);
- if (!empty($row2['has_identity']))
- {
- $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
- $ident_set = true;
- }
- $db->sql_freeresult($result2);
- }
-
- while ($row = $db->sql_fetchrow($result))
- {
- $schema_vals = $schema_fields = array();
-
- // Build the SQL statement to recreate the data.
- for ($i = 0; $i < $i_num_fields; $i++)
- {
- $str_val = $row[$ary_name[$i]];
-
- if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
- {
- $str_quote = '';
- $str_empty = "''";
- $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
- }
- else if (preg_match('#date|timestamp#i', $ary_type[$i]))
- {
- if (empty($str_val))
- {
- $str_quote = '';
- }
- else
- {
- $str_quote = "'";
- }
- }
- else
- {
- $str_quote = '';
- $str_empty = 'NULL';
- }
-
- if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
- {
- $str_val = $str_empty;
- }
-
- $schema_vals[$i] = $str_quote . $str_val . $str_quote;
- $schema_fields[$i] = $ary_name[$i];
- }
-
- // Take the ordered fields and their associated data and build it
- // into a valid sql statement to recreate that field in the data.
- $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
-
- $this->flush($sql_data);
- $sql_data = '';
- }
- $db->sql_freeresult($result);
-
- if ($retrieved_data && $ident_set)
- {
- $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
- }
- $this->flush($sql_data);
- }
-
- function write_data_mssqlnative($table_name)
- {
- global $db;
- $ary_type = $ary_name = array();
- $ident_set = false;
- $sql_data = '';
-
- // Grab all of the data from current table.
- $sql = "SELECT * FROM $table_name";
- $db->mssqlnative_set_query_options(array('Scrollable' => SQLSRV_CURSOR_STATIC));
- $result = $db->sql_query($sql);
-
- $retrieved_data = $db->mssqlnative_num_rows($result);
-
- if (!$retrieved_data)
- {
- $db->sql_freeresult($result);
- return;
- }
-
- $sql = "SELECT COLUMN_NAME, DATA_TYPE
- FROM INFORMATION_SCHEMA.COLUMNS
- WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = '" . $db->sql_escape($table_name) . "'";
- $result_fields = $db->sql_query($sql);
-
- $i_num_fields = 0;
- while ($row = $db->sql_fetchrow($result_fields))
- {
- $ary_type[$i_num_fields] = $row['DATA_TYPE'];
- $ary_name[$i_num_fields] = $row['COLUMN_NAME'];
- $i_num_fields++;
- }
- $db->sql_freeresult($result_fields);
-
- $sql = "SELECT 1 as has_identity
- FROM INFORMATION_SCHEMA.COLUMNS
- WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
- $result2 = $db->sql_query($sql);
- $row2 = $db->sql_fetchrow($result2);
-
- if (!empty($row2['has_identity']))
- {
- $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
- $ident_set = true;
- }
- $db->sql_freeresult($result2);
-
- while ($row = $db->sql_fetchrow($result))
- {
- $schema_vals = $schema_fields = array();
-
- // Build the SQL statement to recreate the data.
- for ($i = 0; $i < $i_num_fields; $i++)
- {
- $str_val = $row[$ary_name[$i]];
-
- // defaults to type number - better quote just to be safe, so check for is_int too
- if (is_int($ary_type[$i]) || preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
- {
- $str_quote = '';
- $str_empty = "''";
- $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
- }
- else if (preg_match('#date|timestamp#i', $ary_type[$i]))
- {
- if (empty($str_val))
- {
- $str_quote = '';
- }
- else
- {
- $str_quote = "'";
- }
- }
- else
- {
- $str_quote = '';
- $str_empty = 'NULL';
- }
-
- if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
- {
- $str_val = $str_empty;
- }
-
- $schema_vals[$i] = $str_quote . $str_val . $str_quote;
- $schema_fields[$i] = $ary_name[$i];
- }
-
- // Take the ordered fields and their associated data and build it
- // into a valid sql statement to recreate that field in the data.
- $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
-
- $this->flush($sql_data);
- $sql_data = '';
- }
- $db->sql_freeresult($result);
-
- if ($ident_set)
- {
- $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
- }
- $this->flush($sql_data);
- }
-
- function write_data_odbc($table_name)
- {
- global $db;
- $ary_type = $ary_name = array();
- $ident_set = false;
- $sql_data = '';
-
- // Grab all of the data from current table.
- $sql = "SELECT *
- FROM $table_name";
- $result = $db->sql_query($sql);
-
- $retrieved_data = odbc_num_rows($result);
-
- if ($retrieved_data)
- {
- $sql = "SELECT 1 as has_identity
- FROM INFORMATION_SCHEMA.COLUMNS
- WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
- $result2 = $db->sql_query($sql);
- $row2 = $db->sql_fetchrow($result2);
- if (!empty($row2['has_identity']))
- {
- $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
- $ident_set = true;
- }
- $db->sql_freeresult($result2);
- }
-
- $i_num_fields = odbc_num_fields($result);
-
- for ($i = 0; $i < $i_num_fields; $i++)
- {
- $ary_type[$i] = odbc_field_type($result, $i + 1);
- $ary_name[$i] = odbc_field_name($result, $i + 1);
- }
-
- while ($row = $db->sql_fetchrow($result))
- {
- $schema_vals = $schema_fields = array();
-
- // Build the SQL statement to recreate the data.
- for ($i = 0; $i < $i_num_fields; $i++)
- {
- $str_val = $row[$ary_name[$i]];
-
- if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
- {
- $str_quote = '';
- $str_empty = "''";
- $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
- }
- else if (preg_match('#date|timestamp#i', $ary_type[$i]))
- {
- if (empty($str_val))
- {
- $str_quote = '';
- }
- else
- {
- $str_quote = "'";
- }
- }
- else
- {
- $str_quote = '';
- $str_empty = 'NULL';
- }
-
- if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
- {
- $str_val = $str_empty;
- }
-
- $schema_vals[$i] = $str_quote . $str_val . $str_quote;
- $schema_fields[$i] = $ary_name[$i];
- }
-
- // Take the ordered fields and their associated data and build it
- // into a valid sql statement to recreate that field in the data.
- $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
-
- $this->flush($sql_data);
-
- $sql_data = '';
-
- }
- $db->sql_freeresult($result);
-
- if ($retrieved_data && $ident_set)
- {
- $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
- }
- $this->flush($sql_data);
- }
-
-}
-
-class oracle_extractor extends base_extractor
-{
- function write_table($table_name)
- {
- global $db, $request;
-
- $sql_data = '-- Table: ' . $table_name . "\n";
- $sql_data .= "DROP TABLE $table_name\n/\n";
- $sql_data .= "\nCREATE TABLE $table_name (\n";
-
- $sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_LENGTH, NULLABLE, DATA_DEFAULT
- FROM ALL_TAB_COLS
- WHERE table_name = '{$table_name}'";
- $result = $db->sql_query($sql);
-
- $rows = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $line = ' "' . $row['column_name'] . '" ' . $row['data_type'];
-
- if ($row['data_type'] !== 'CLOB')
- {
- if ($row['data_type'] !== 'VARCHAR2' && $row['data_type'] !== 'CHAR')
- {
- $line .= '(' . $row['data_precision'] . ')';
- }
- else
- {
- $line .= '(' . $row['data_length'] . ')';
- }
- }
-
- if (!empty($row['data_default']))
- {
- $line .= ' DEFAULT ' . $row['data_default'];
- }
-
- if ($row['nullable'] == 'N')
- {
- $line .= ' NOT NULL';
- }
- $rows[] = $line;
- }
- $db->sql_freeresult($result);
-
- $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
- FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
- WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
- AND B.CONSTRAINT_TYPE = 'P'
- AND A.TABLE_NAME = '{$table_name}'";
- $result = $db->sql_query($sql);
-
- $primary_key = array();
- $contraint_name = '';
- while ($row = $db->sql_fetchrow($result))
- {
- $constraint_name = '"' . $row['constraint_name'] . '"';
- $primary_key[] = '"' . $row['column_name'] . '"';
- }
- $db->sql_freeresult($result);
-
- if (sizeof($primary_key))
- {
- $rows[] = " CONSTRAINT {$constraint_name} PRIMARY KEY (" . implode(', ', $primary_key) . ')';
- }
-
- $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
- FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
- WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
- AND B.CONSTRAINT_TYPE = 'U'
- AND A.TABLE_NAME = '{$table_name}'";
- $result = $db->sql_query($sql);
-
- $unique = array();
- $contraint_name = '';
- while ($row = $db->sql_fetchrow($result))
- {
- $constraint_name = '"' . $row['constraint_name'] . '"';
- $unique[] = '"' . $row['column_name'] . '"';
- }
- $db->sql_freeresult($result);
-
- if (sizeof($unique))
- {
- $rows[] = " CONSTRAINT {$constraint_name} UNIQUE (" . implode(', ', $unique) . ')';
- }
-
- $sql_data .= implode(",\n", $rows);
- $sql_data .= "\n)\n/\n";
-
- $sql = "SELECT A.REFERENCED_NAME, C.*
- FROM USER_DEPENDENCIES A, USER_TRIGGERS B, USER_SEQUENCES C
- WHERE A.REFERENCED_TYPE = 'SEQUENCE'
- AND A.NAME = B.TRIGGER_NAME
- AND B.TABLE_NAME = '{$table_name}'
- AND C.SEQUENCE_NAME = A.REFERENCED_NAME";
- $result = $db->sql_query($sql);
-
- $type = $request->variable('type', '');
-
- while ($row = $db->sql_fetchrow($result))
- {
- $sql_data .= "\nDROP SEQUENCE \"{$row['referenced_name']}\"\n/\n";
- $sql_data .= "\nCREATE SEQUENCE \"{$row['referenced_name']}\"";
-
- if ($type == 'full')
- {
- $sql_data .= ' START WITH ' . $row['last_number'];
- }
-
- $sql_data .= "\n/\n";
- }
- $db->sql_freeresult($result);
-
- $sql = "SELECT DESCRIPTION, WHEN_CLAUSE, TRIGGER_BODY
- FROM USER_TRIGGERS
- WHERE TABLE_NAME = '{$table_name}'";
- $result = $db->sql_query($sql);
- while ($row = $db->sql_fetchrow($result))
- {
- $sql_data .= "\nCREATE OR REPLACE TRIGGER {$row['description']}WHEN ({$row['when_clause']})\n{$row['trigger_body']}\n/\n";
- }
- $db->sql_freeresult($result);
-
- $sql = "SELECT A.INDEX_NAME, B.COLUMN_NAME
- FROM USER_INDEXES A, USER_IND_COLUMNS B
- WHERE A.UNIQUENESS = 'NONUNIQUE'
- AND A.INDEX_NAME = B.INDEX_NAME
- AND B.TABLE_NAME = '{$table_name}'";
- $result = $db->sql_query($sql);
-
- $index = array();
-
- while ($row = $db->sql_fetchrow($result))
- {
- $index[$row['index_name']][] = $row['column_name'];
- }
-
- foreach ($index as $index_name => $column_names)
- {
- $sql_data .= "\nCREATE INDEX $index_name ON $table_name(" . implode(', ', $column_names) . ")\n/\n";
- }
- $db->sql_freeresult($result);
- $this->flush($sql_data);
- }
-
- function write_data($table_name)
- {
- global $db;
- $ary_type = $ary_name = array();
-
- // Grab all of the data from current table.
- $sql = "SELECT *
- FROM $table_name";
- $result = $db->sql_query($sql);
-
- $i_num_fields = ocinumcols($result);
-
- for ($i = 0; $i < $i_num_fields; $i++)
- {
- $ary_type[$i] = ocicolumntype($result, $i + 1);
- $ary_name[$i] = ocicolumnname($result, $i + 1);
- }
-
- $sql_data = '';
-
- while ($row = $db->sql_fetchrow($result))
- {
- $schema_vals = $schema_fields = array();
-
- // Build the SQL statement to recreate the data.
- for ($i = 0; $i < $i_num_fields; $i++)
- {
- // Oracle uses uppercase - we use lowercase
- $str_val = $row[strtolower($ary_name[$i])];
-
- if (preg_match('#char|text|bool|raw|clob#i', $ary_type[$i]))
- {
- $str_quote = '';
- $str_empty = "''";
- $str_val = sanitize_data_oracle($str_val);
- }
- else if (preg_match('#date|timestamp#i', $ary_type[$i]))
- {
- if (empty($str_val))
- {
- $str_quote = '';
- }
- else
- {
- $str_quote = "'";
- }
- }
- else
- {
- $str_quote = '';
- $str_empty = 'NULL';
- }
-
- if (empty($str_val) && $str_val !== '0')
- {
- $str_val = $str_empty;
- }
-
- $schema_vals[$i] = $str_quote . $str_val . $str_quote;
- $schema_fields[$i] = '"' . $ary_name[$i] . '"';
- }
-
- // Take the ordered fields and their associated data and build it
- // into a valid sql statement to recreate that field in the data.
- $sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ")\n/\n";
-
- $this->flush($sql_data);
- }
- $db->sql_freeresult($result);
- }
-
- function write_start($prefix)
- {
- $sql_data = "--\n";
- $sql_data .= "-- phpBB Backup Script\n";
- $sql_data .= "-- Dump of tables for $prefix\n";
- $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
- $sql_data .= "--\n";
- $this->flush($sql_data);
- }
-}
-
// 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()
{
diff --git a/phpBB/includes/acp/acp_disallow.php b/phpBB/includes/acp/acp_disallow.php
index 2c27616748..b2a7128209 100644
--- a/phpBB/includes/acp/acp_disallow.php
+++ b/phpBB/includes/acp/acp_disallow.php
@@ -26,9 +26,7 @@ class acp_disallow
function main($id, $mode)
{
global $db, $user, $auth, $template, $cache, $phpbb_log, $request;
- global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
-
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ global $config, $phpbb_admin_path;
$user->add_lang('acp/posting');
diff --git a/phpBB/includes/acp/acp_email.php b/phpBB/includes/acp/acp_email.php
index ebc4a86de3..98c74ff8b3 100644
--- a/phpBB/includes/acp/acp_email.php
+++ b/phpBB/includes/acp/acp_email.php
@@ -189,8 +189,15 @@ class acp_email
$db->sql_freeresult($result);
// Send the messages
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!class_exists('messenger'))
+ {
+ include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ }
+
+ if (!function_exists('get_group_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$messenger = new messenger($use_queue);
$errored = false;
diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php
index 89fdc8b863..7bcf6e1957 100644
--- a/phpBB/includes/acp/acp_extensions.php
+++ b/phpBB/includes/acp/acp_extensions.php
@@ -70,15 +70,16 @@ class acp_extensions
// If they've specified an extension, let's load the metadata manager and validate it.
if ($ext_name)
{
- $md_manager = new \phpbb\extension\metadata_manager($ext_name, $config, $phpbb_extension_manager, $template, $user, $phpbb_root_path);
+ $md_manager = new \phpbb\extension\metadata_manager($ext_name, $config, $phpbb_extension_manager, $template, $phpbb_root_path);
try
{
$md_manager->get_metadata('all');
}
- catch(\phpbb\extension\exception $e)
+ catch (\phpbb\extension\exception $e)
{
- trigger_error($e, E_USER_WARNING);
+ $message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
+ trigger_error($message, E_USER_WARNING);
}
}
@@ -174,11 +175,6 @@ class acp_extensions
trigger_error($user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
- if ($phpbb_extension_manager->is_enabled($ext_name))
- {
- redirect($this->u_action);
- }
-
try
{
while ($phpbb_extension_manager->enable_step($ext_name))
@@ -357,10 +353,11 @@ class acp_extensions
$enabled_extension_meta_data[$name]['S_VERSIONCHECK'] = true;
$enabled_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&amp;action=details&amp;versioncheck_force=1&amp;ext_name=' . urlencode($md_manager->get_metadata('name'));
}
- catch(\phpbb\extension\exception $e)
+ catch (\phpbb\extension\exception $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, $e),
+ 'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $message),
'S_VERSIONCHECK' => false,
));
}
@@ -374,6 +371,7 @@ class acp_extensions
foreach ($enabled_extension_meta_data as $name => $block_vars)
{
+ $block_vars['NAME'] = $name;
$block_vars['U_DETAILS'] = $this->u_action . '&amp;action=details&amp;ext_name=' . urlencode($name);
$this->template->assign_block_vars('enabled', $block_vars);
@@ -413,10 +411,11 @@ class acp_extensions
$disabled_extension_meta_data[$name]['S_VERSIONCHECK'] = true;
$disabled_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&amp;action=details&amp;versioncheck_force=1&amp;ext_name=' . urlencode($md_manager->get_metadata('name'));
}
- catch(\phpbb\extension\exception $e)
+ catch (\phpbb\extension\exception $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, $e),
+ 'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $message),
'S_VERSIONCHECK' => false,
));
}
@@ -430,6 +429,7 @@ class acp_extensions
foreach ($disabled_extension_meta_data as $name => $block_vars)
{
+ $block_vars['NAME'] = $name;
$block_vars['U_DETAILS'] = $this->u_action . '&amp;action=details&amp;ext_name=' . urlencode($name);
$this->template->assign_block_vars('disabled', $block_vars);
@@ -472,10 +472,11 @@ class acp_extensions
$available_extension_meta_data[$name]['S_VERSIONCHECK'] = true;
$available_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&amp;action=details&amp;versioncheck_force=1&amp;ext_name=' . urlencode($md_manager->get_metadata('name'));
}
- catch(\phpbb\extension\exception $e)
+ catch (\phpbb\extension\exception $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, $e),
+ 'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $message),
'S_VERSIONCHECK' => false,
));
}
@@ -489,6 +490,7 @@ class acp_extensions
foreach ($available_extension_meta_data as $name => $block_vars)
{
+ $block_vars['NAME'] = $name;
$block_vars['U_DETAILS'] = $this->u_action . '&amp;action=details&amp;ext_name=' . urlencode($name);
$this->template->assign_block_vars('disabled', $block_vars);
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index 0ba1c0c9fd..dd9ff37773 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -950,17 +950,21 @@ class acp_forums
$errors = array();
+ $forum_data_ary = $forum_data;
/**
* Validate the forum data before we create/update the forum
*
* @event core.acp_manage_forums_validate_data
- * @var array forum_data Array with new forum data
+ * @var array forum_data_ary Array with new forum data
* @var array errors Array of errors, should be strings and not
* language key.
* @since 3.1.0-a1
+ * @change 3.2.0-a1 Replaced forum_data with forum_data_ary
*/
- $vars = array('forum_data', 'errors');
+ $vars = array('forum_data_ary', 'errors');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_validate_data', compact($vars)));
+ $forum_data = $forum_data_ary;
+ unset($forum_data_ary);
if ($forum_data['forum_name'] == '')
{
@@ -1058,18 +1062,22 @@ class acp_forums
}
unset($forum_data_sql['forum_password_unset']);
+ $forum_data_ary = $forum_data;
/**
* Remove invalid values from forum_data_sql that should not be updated
*
* @event core.acp_manage_forums_update_data_before
- * @var array forum_data Array with forum data
+ * @var array forum_data_ary Array with forum data
* @var array forum_data_sql Array with data we are going to update
* If forum_data_sql[forum_id] is set, we update
* that forum, otherwise a new one is created.
* @since 3.1.0-a1
+ * @change 3.2.0-a1 Replaced forum_data by forum_data_ary
*/
- $vars = array('forum_data', 'forum_data_sql');
+ $vars = array('forum_data_ary', 'forum_data_sql');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_before', compact($vars)));
+ $forum_data = $forum_data_ary;
+ unset($forum_data_ary);
$is_new_forum = !isset($forum_data_sql['forum_id']);
@@ -1348,11 +1356,12 @@ class acp_forums
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_EDIT', false, array($forum_data['forum_name']));
}
+ $forum_data_ary = $forum_data;
/**
* Event after a forum was updated or created
*
* @event core.acp_manage_forums_update_data_after
- * @var array forum_data Array with forum data
+ * @var array forum_data_ary Array with forum data
* @var array forum_data_sql Array with data we updated
* @var bool is_new_forum Did we create a forum or update one
* If you want to overwrite this value,
@@ -1360,9 +1369,12 @@ class acp_forums
* @var array errors Array of errors, should be strings and not
* language key.
* @since 3.1.0-a1
+ * @change 3.2.0-a1 Replaced forum_data with forum_data_ary
*/
- $vars = array('forum_data', 'forum_data_sql', 'is_new_forum', 'errors');
+ $vars = array('forum_data_ary', 'forum_data_sql', 'is_new_forum', 'errors');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_after', compact($vars)));
+ $forum_data = $forum_data_ary;
+ unset($forum_data_ary);
return $errors;
}
@@ -1788,7 +1800,7 @@ class acp_forums
*/
function delete_forum_content($forum_id)
{
- global $db, $config, $phpbb_root_path, $phpEx;
+ global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
@@ -1809,7 +1821,10 @@ class acp_forums
}
$db->sql_freeresult($result);
- delete_attachments('topic', $topic_ids, false);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('topic', $topic_ids, false);
+ unset($attachment_manager);
// Delete shadow topics pointing to topics in this forum
delete_topic_shadows($forum_id);
@@ -1920,6 +1935,24 @@ class acp_forums
$table_ary = array(FORUMS_ACCESS_TABLE, FORUMS_TRACK_TABLE, FORUMS_WATCH_TABLE, LOG_TABLE, MODERATOR_CACHE_TABLE, POSTS_TABLE, TOPICS_TABLE, TOPICS_TRACK_TABLE);
+ /**
+ * Perform additional actions before forum content deletion
+ *
+ * @event core.delete_forum_content_before_query
+ * @var array table_ary Array of tables from which all rows will be deleted that hold the forum_id
+ * @var int forum_id the forum id
+ * @var array topic_ids Array of the topic ids from the forum to be deleted
+ * @var array post_counts Array of counts of posts in the forum, by poster_id
+ * @since 3.1.6-RC1
+ */
+ $vars = array(
+ 'table_ary',
+ 'forum_id',
+ 'topic_ids',
+ 'post_counts',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.delete_forum_content_before_query', compact($vars)));
+
foreach ($table_ary as $table)
{
$db->sql_query("DELETE FROM $table WHERE forum_id = $forum_id");
diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php
index 57fa52fba3..41366982d2 100644
--- a/phpBB/includes/acp/acp_groups.php
+++ b/phpBB/includes/acp/acp_groups.php
@@ -42,7 +42,10 @@ class acp_groups
return;
}
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('group_user_attributes'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
// Check and set some common vars
$action = (isset($_POST['add'])) ? 'add' : ((isset($_POST['addusers'])) ? 'addusers' : $request->variable('action', ''));
@@ -54,6 +57,9 @@ class acp_groups
$start = $request->variable('start', 0);
$update = (isset($_POST['update'])) ? true : false;
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
// Clear some vars
$group_row = array();
@@ -98,7 +104,7 @@ class acp_groups
}
// Approve, demote or promote
- $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'];
+ $group_name = $group_helper->get_name($group_row['group_name']);
$error = group_user_attributes($action, $group_id, $mark_ary, false, $group_name);
if (!$error)
@@ -139,7 +145,7 @@ class acp_groups
if (confirm_box(true))
{
- $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'];
+ $group_name = $group_helper->get_name($group_row['group_name']);
group_user_attributes('default', $group_id, $mark_ary, false, $group_name, $group_row);
trigger_error($user->lang['GROUP_DEFS_UPDATED'] . adm_back_link($this->u_action . '&amp;action=list&amp;g=' . $group_id));
}
@@ -158,7 +164,7 @@ class acp_groups
case 'set_default_on_all':
if (confirm_box(true))
{
- $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'];
+ $group_name = $group_helper->get_name($group_row['group_name']);
$start = 0;
@@ -236,7 +242,7 @@ class acp_groups
break;
case 'deleteusers':
- $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'];
+ $group_name = $group_helper->get_name($group_row['group_name']);
$error = group_user_del($group_id, $mark_ary, false, $group_name);
break;
}
@@ -280,7 +286,7 @@ class acp_groups
}
$name_ary = array_unique(explode("\n", $name_ary));
- $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'];
+ $group_name = $group_helper->get_name($group_row['group_name']);
// Add user/s to group
if ($error = group_user_add($group_id, false, $name_ary, $group_name, $default, $leader, 0, $group_row))
@@ -295,7 +301,10 @@ class acp_groups
case 'edit':
case 'add':
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ if (!function_exists('display_forums'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
$data = $submit_ary = array();
@@ -720,7 +729,7 @@ class acp_groups
'S_AVATARS_ENABLED' => ($config['allow_avatar'] && $avatars_enabled),
'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '',
- 'GROUP_NAME' => ($group_type == GROUP_SPECIAL) ? $user->lang['G_' . $group_name] : $group_name,
+ 'GROUP_NAME' => $group_helper->get_name($group_name),
'GROUP_INTERNAL_NAME' => $group_name,
'GROUP_DESC' => $group_desc_data['text'],
'GROUP_RECEIVE_PM' => (isset($group_row['group_receive_pm']) && $group_row['group_receive_pm']) ? ' checked="checked"' : '',
@@ -855,7 +864,7 @@ class acp_groups
'S_GROUP_SPECIAL' => ($group_row['group_type'] == GROUP_SPECIAL) ? true : false,
'S_ACTION_OPTIONS' => $s_action_options,
- 'GROUP_NAME' => ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'],
+ 'GROUP_NAME' => $group_helper->get_name($group_row['group_name']),
'U_ACTION' => $this->u_action . "&amp;g=$group_id",
'U_BACK' => $this->u_action,
@@ -984,6 +993,9 @@ class acp_groups
$teampage_id = $request->variable('t', 0);
$category_id = $request->variable('c', 0);
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
if ($field && !in_array($field, array('legend', 'teampage')))
{
// Invalid mode
@@ -1086,7 +1098,7 @@ class acp_groups
$s_group_select_legend = '';
while ($row = $db->sql_fetchrow($result))
{
- $group_name = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
+ $group_name = $group_helper->get_name($row['group_name']);
if ($row['group_legend'])
{
$template->assign_block_vars('legend', array(
@@ -1134,7 +1146,7 @@ class acp_groups
if ($row['group_id'])
{
- $group_name = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
+ $group_name = $group_helper->get_name($row['group_name']);
$group_type = $user->lang[\phpbb\groupposition\teampage::group_type_language($row['group_type'])];
}
else
@@ -1167,7 +1179,7 @@ class acp_groups
$s_group_select_teampage = '';
while ($row = $db->sql_fetchrow($result))
{
- $group_name = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
+ $group_name = $group_helper->get_name($row['group_name']);
$template->assign_block_vars('add_teampage', array(
'GROUP_ID' => (int) $row['group_id'],
'GROUP_NAME' => $group_name,
diff --git a/phpBB/includes/acp/acp_icons.php b/phpBB/includes/acp/acp_icons.php
index fdf366097a..57a36bb9f3 100644
--- a/phpBB/includes/acp/acp_icons.php
+++ b/phpBB/includes/acp/acp_icons.php
@@ -28,7 +28,7 @@ class acp_icons
function main($id, $mode)
{
- global $db, $user, $auth, $template, $cache;
+ global $db, $user, $auth, $template, $cache, $phpbb_container;
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
global $request, $phpbb_container;
@@ -248,7 +248,7 @@ class acp_icons
$data = $_images;
}
- $colspan = (($mode == 'smilies') ? 7 : 5);
+ $colspan = (($mode == 'smilies') ? 7 : 6);
$colspan += ($icon_id) ? 1 : 0;
$colspan += ($action == 'add') ? 2 : 0;
@@ -292,6 +292,8 @@ class acp_icons
'ID' => (isset($img_row[$fields . '_id'])) ? $img_row[$fields . '_id'] : 0,
'WIDTH' => (!empty($img_row[$fields .'_width'])) ? $img_row[$fields .'_width'] : $img_row['width'],
'HEIGHT' => (!empty($img_row[$fields .'_height'])) ? $img_row[$fields .'_height'] : $img_row['height'],
+ 'TEXT_ALT' => ($mode == 'icons' && !empty($img_row['icons_alt'])) ? $img_row['icons_alt'] : $img,
+ 'ALT' => ($mode == 'icons' && !empty($img_row['icons_alt'])) ? $img_row['icons_alt'] : '',
'POSTING_CHECKED' => (!empty($img_row['display_on_posting']) || $action == 'add') ? ' checked="checked"' : '',
));
}
@@ -336,6 +338,7 @@ class acp_icons
$image_add = (isset($_POST['add_img'])) ? $request->variable('add_img', array('' => 0)) : array();
$image_emotion = $request->variable('emotion', array('' => ''), true);
$image_code = $request->variable('code', array('' => ''), true);
+ $image_alt = ($request->is_set_post('alt')) ? $request->variable('alt', array('' => ''), true) : array();
$image_display_on_posting = (isset($_POST['display_on_posting'])) ? $request->variable('display_on_posting', array('' => 0)) : array();
// Ok, add the relevant bits if we are adding new codes to existing emoticons...
@@ -438,6 +441,13 @@ class acp_icons
);
}
+ if ($mode == 'icons')
+ {
+ $img_sql = array_merge($img_sql, array(
+ 'icons_alt' => $image_alt[$image])
+ );
+ }
+
// Image_order holds the 'new' order value
if (!empty($image_order[$image]))
{
@@ -486,6 +496,7 @@ class acp_icons
$cache->destroy('_icons');
$cache->destroy('sql', $table);
+ $phpbb_container->get('text_formatter.cache')->invalidate();
$level = ($icons_updated) ? E_USER_NOTICE : E_USER_WARNING;
$errormsgs = '';
@@ -661,6 +672,7 @@ class acp_icons
$cache->destroy('_icons');
$cache->destroy('sql', $table);
+ $phpbb_container->get('text_formatter.cache')->invalidate();
trigger_error($user->lang[$lang . '_IMPORT_SUCCESS'] . adm_back_link($this->u_action));
}
@@ -783,6 +795,7 @@ class acp_icons
$cache->destroy('_icons');
$cache->destroy('sql', $table);
+ $phpbb_container->get('text_formatter.cache')->invalidate();
if ($request->is_ajax())
{
@@ -848,6 +861,7 @@ class acp_icons
$cache->destroy('_icons');
$cache->destroy('sql', $table);
+ $phpbb_container->get('text_formatter.cache')->invalidate();
if ($request->is_ajax())
{
@@ -917,7 +931,7 @@ class acp_icons
while ($row = $db->sql_fetchrow($result))
{
- $alt_text = ($mode == 'smilies') ? $row['code'] : '';
+ $alt_text = ($mode == 'smilies') ? $row['code'] : (($mode == 'icons' && !empty($row['icons_alt'])) ? $row['icons_alt'] : $row['icons_url']);
$template->assign_block_vars('items', array(
'S_SPACER' => (!$spacer && !$row['display_on_posting']) ? true : false,
diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php
index 3a72cf1fe6..8c021560a0 100644
--- a/phpBB/includes/acp/acp_inactive.php
+++ b/phpBB/includes/acp/acp_inactive.php
@@ -34,7 +34,10 @@ class acp_inactive
global $config, $db, $user, $auth, $template, $phpbb_container, $phpbb_log, $request;
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix;
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_active_flip'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$user->add_lang('memberlist');
@@ -111,7 +114,10 @@ class acp_inactive
if ($config['require_activation'] == USER_ACTIVATION_ADMIN && !empty($inactive_users))
{
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ if (!class_exists('messenger'))
+ {
+ include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ }
$messenger = new messenger(false);
@@ -200,7 +206,10 @@ class acp_inactive
if ($row = $db->sql_fetchrow($result))
{
// Send the messages
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ if (!class_exists('messenger'))
+ {
+ include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ }
$messenger = new messenger();
$usernames = $user_ids = array();
@@ -275,9 +284,10 @@ class acp_inactive
'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&amp;mode=overview')),
+ 'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&amp;mode=overview&amp;redirect=acp_inactive')),
'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']),
+ 'USER_EMAIL' => $row['user_email'],
'U_USER_ADMIN' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=users&amp;mode=overview&amp;u={$row['user_id']}"),
'U_SEARCH_USER' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id={$row['user_id']}&amp;sr=posts") : '',
diff --git a/phpBB/includes/acp/acp_jabber.php b/phpBB/includes/acp/acp_jabber.php
index d860ae27f4..1726728086 100644
--- a/phpBB/includes/acp/acp_jabber.php
+++ b/phpBB/includes/acp/acp_jabber.php
@@ -34,7 +34,10 @@ class acp_jabber
$user->add_lang('acp/board');
- include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx);
+ if (!class_exists('jabber'))
+ {
+ include($phpbb_root_path . 'includes/functions_jabber.' . $phpEx);
+ }
$action = $request->variable('action', '');
$submit = (isset($_POST['submit'])) ? true : false;
@@ -107,7 +110,10 @@ class acp_jabber
$config->set('jab_host', $jab_host);
$config->set('jab_port', $jab_port);
$config->set('jab_username', $jab_username);
- $config->set('jab_password', $jab_password);
+ if ($jab_password !== '********')
+ {
+ $config->set('jab_password', $jab_password);
+ }
$config->set('jab_package_size', $jab_package_size);
$config->set('jab_use_ssl', $jab_use_ssl);
@@ -122,7 +128,7 @@ class acp_jabber
'JAB_HOST' => $jab_host,
'JAB_PORT' => ($jab_port) ? $jab_port : '',
'JAB_USERNAME' => $jab_username,
- 'JAB_PASSWORD' => $jab_password,
+ 'JAB_PASSWORD' => $jab_password !== '' ? '********' : '',
'JAB_PACKAGE_SIZE' => $jab_package_size,
'JAB_USE_SSL' => $jab_use_ssl,
'S_CAN_USE_SSL' => jabber::can_use_ssl(),
diff --git a/phpBB/includes/acp/acp_language.php b/phpBB/includes/acp/acp_language.php
index 3fd118b0dd..03172e475a 100644
--- a/phpBB/includes/acp/acp_language.php
+++ b/phpBB/includes/acp/acp_language.php
@@ -31,10 +31,13 @@ class acp_language
function main($id, $mode)
{
- global $config, $db, $user, $template, $phpbb_log;
+ global $config, $db, $user, $template, $phpbb_log, $phpbb_container;
global $phpbb_root_path, $phpEx, $request;
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('validate_language_iso_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
// Check and set some common vars
$action = (isset($_POST['update_details'])) ? 'update_details' : '';
@@ -377,37 +380,19 @@ class acp_language
$db->sql_freeresult($result);
$new_ary = $iso = array();
- $dp = @opendir("{$phpbb_root_path}language");
- if ($dp)
+ /** @var \phpbb\language\language_file_helper $language_helper */
+ $language_helper = $phpbb_container->get('language.helper.language_file');
+ $iso = $language_helper->get_available_languages();
+
+ foreach ($iso as $lang_array)
{
- while (($file = readdir($dp)) !== false)
- {
- if ($file[0] == '.' || !is_dir($phpbb_root_path . 'language/' . $file))
- {
- continue;
- }
+ $lang_iso = $lang_array['iso'];
- if (file_exists("{$phpbb_root_path}language/$file/iso.txt"))
- {
- if (!in_array($file, $installed))
- {
- if ($iso = file("{$phpbb_root_path}language/$file/iso.txt"))
- {
- if (sizeof($iso) == 3)
- {
- $new_ary[$file] = array(
- 'iso' => $file,
- 'name' => trim($iso[0]),
- 'local_name'=> trim($iso[1]),
- 'author' => trim($iso[2])
- );
- }
- }
- }
- }
+ if (!in_array($lang_iso, $installed))
+ {
+ $new_ary[$lang_iso] = $lang_array;
}
- closedir($dp);
}
unset($installed);
diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php
index c49ccdf479..47e2660770 100644
--- a/phpBB/includes/acp/acp_main.php
+++ b/phpBB/includes/acp/acp_main.php
@@ -26,7 +26,7 @@ class acp_main
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;
+ 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'))
@@ -352,6 +352,11 @@ class acp_main
$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);
@@ -421,7 +426,7 @@ class acp_main
// Version check
$user->add_lang('install');
- if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.3.3', '<'))
+ if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.4', '<'))
{
$template->assign_vars(array(
'S_PHP_VERSION_OLD' => true,
@@ -633,7 +638,7 @@ class acp_main
{
$error = false;
$search_type = $config['search_type'];
- $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
if (!$search->index_created())
{
@@ -644,7 +649,7 @@ class acp_main
}
}
- if (!defined('PHPBB_DISABLE_CONFIG_CHECK') && file_exists($phpbb_root_path . 'config.' . $phpEx) && phpbb_is_writable($phpbb_root_path . 'config.' . $phpEx))
+ 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));
diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php
index 4fca366868..c2407f15b4 100644
--- a/phpBB/includes/acp/acp_modules.php
+++ b/phpBB/includes/acp/acp_modules.php
@@ -19,6 +19,8 @@ if (!defined('IN_PHPBB'))
exit;
}
+use phpbb\module\exception\module_exception;
+
/**
* - Able to check for new module versions (modes changed/adjusted/added/removed)
* Icons for:
@@ -37,8 +39,10 @@ class acp_modules
function main($id, $mode)
{
- global $db, $user, $auth, $template, $module, $request, $phpbb_log;
- global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx;
+ global $db, $user, $template, $module, $request, $phpbb_log, $phpbb_container;
+
+ /** @var \phpbb\module\module_manager $module_manager */
+ $module_manager = $phpbb_container->get('module.manager');
// Set a global define for modules we might include (the author is able to prevent execution of code by checking this constant)
define('MODULE_INCLUDE', true);
@@ -91,13 +95,20 @@ class acp_modules
$db->sql_freeresult($result);
}
- $errors = $this->delete_module($module_id);
-
- if (!sizeof($errors))
+ try
{
- $this->remove_cache_file();
- trigger_error($user->lang['MODULE_DELETED'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
+ $row = $module_manager->get_module_row($module_id, $this->module_class);
+ $module_manager->delete_module($module_id, $this->module_class);
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_REMOVED', false, array($user->lang($row['module_langname'])));
}
+ catch (module_exception $e)
+ {
+ $msg = $user->lang($e->getMessage());
+ trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
+ }
+
+ $module_manager->remove_cache_file($this->module_class);
+ trigger_error($user->lang['MODULE_DELETED'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
}
else
{
@@ -138,8 +149,8 @@ class acp_modules
AND module_id = $module_id";
$db->sql_query($sql);
- $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_' . strtoupper($action), false, array($this->lang_name($row['module_langname'])));
- $this->remove_cache_file();
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_' . strtoupper($action), false, array($user->lang($row['module_langname'])));
+ $module_manager->remove_cache_file($this->module_class);
break;
@@ -163,12 +174,16 @@ class acp_modules
trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
}
- $move_module_name = $this->move_module_by($row, $action, 1);
+ try
+ {
+ $move_module_name = $module_manager->move_module_by($row, $this->module_class, $action, 1);
- if ($move_module_name !== false)
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_' . strtoupper($action), false, array($user->lang($row['module_langname']), $move_module_name));
+ $module_manager->remove_cache_file($this->module_class);
+ }
+ catch (module_exception $e)
{
- $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_' . strtoupper($action), false, array($this->lang_name($row['module_langname']), $move_module_name));
- $this->remove_cache_file();
+ // Do nothing
}
if ($request->is_ajax())
@@ -194,7 +209,7 @@ class acp_modules
list($module_basename, $module_mode) = explode('::', $quick_install);
// Check if module name and mode exist...
- $fileinfo = $this->get_module_infos($module_basename);
+ $fileinfo = $module_manager->get_module_infos($this->module_class, $module_basename);
$fileinfo = $fileinfo[$module_basename];
if (isset($fileinfo['modes'][$module_mode]))
@@ -210,11 +225,20 @@ class acp_modules
'module_auth' => $fileinfo['modes'][$module_mode]['auth'],
);
- $errors = $this->update_module_data($module_data);
+ try
+ {
+ $module_manager->update_module_data($module_data);
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_ADD', false, array($user->lang($module_data['module_langname'])));
+ }
+ catch (\phpbb\module\exception\module_exception $e)
+ {
+ $msg = $user->lang($e->getMessage());
+ trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
+ }
if (!sizeof($errors))
{
- $this->remove_cache_file();
+ $module_manager->remove_cache_file($this->module_class);
trigger_error($user->lang['MODULE_ADDED'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
}
@@ -240,7 +264,15 @@ class acp_modules
trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
}
- $module_row = $this->get_module_row($module_id);
+ try
+ {
+ $module_row = $module_manager->get_module_row($module_id, $this->module_class);
+ }
+ catch (\phpbb\module\exception\module_not_found_exception $e)
+ {
+ $msg = $user->lang($e->getMessage());
+ trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
+ }
// no break
@@ -294,15 +326,29 @@ class acp_modules
// Adjust auth row
if ($module_data['module_basename'] && $module_data['module_mode'])
{
- $fileinfo = $this->get_module_infos($module_data['module_basename']);
+ $fileinfo = $module_manager->get_module_infos($this->module_class, $module_data['module_basename']);
$module_data['module_auth'] = $fileinfo[$module_data['module_basename']]['modes'][$module_data['module_mode']]['auth'];
}
- $errors = $this->update_module_data($module_data);
+ try
+ {
+ $module_manager->update_module_data($module_data);
+ $phpbb_log->add('admin',
+ $user->data['user_id'],
+ $user->ip,
+ ($action === 'edit') ? 'LOG_MODULE_EDIT' : 'LOG_MODULE_ADD',
+ false,
+ array($user->lang($module_data['module_langname']))
+ ); }
+ catch (\phpbb\module\exception\module_exception $e)
+ {
+ $msg = $user->lang($e->getMessage());
+ trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
+ }
if (!sizeof($errors))
{
- $this->remove_cache_file();
+ $module_manager->remove_cache_file($this->module_class);
trigger_error((($action == 'add') ? $user->lang['MODULE_ADDED'] : $user->lang['MODULE_EDITED']) . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
}
@@ -312,7 +358,7 @@ class acp_modules
$is_cat = (!$module_data['module_basename']) ? true : false;
// Get module information
- $module_infos = $this->get_module_infos();
+ $module_infos = $module_manager->get_module_infos($this->module_class);
// Build name options
$s_name_options = $s_mode_options = '';
@@ -324,7 +370,7 @@ class acp_modules
}
// Name options
- $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $this->lang_name($values['title']) . ' [' . $option . ']</option>';
+ $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $user->lang($values['title']) . ' [' . $option . ']</option>';
$template->assign_block_vars('m_names', array('NAME' => $option, 'A_NAME' => addslashes($option)));
@@ -333,14 +379,14 @@ class acp_modules
{
if ($option == $module_data['module_basename'])
{
- $s_mode_options .= '<option value="' . $m_mode . '"' . (($m_mode == $module_data['module_mode']) ? ' selected="selected"' : '') . '>' . $this->lang_name($m_values['title']) . '</option>';
+ $s_mode_options .= '<option value="' . $m_mode . '"' . (($m_mode == $module_data['module_mode']) ? ' selected="selected"' : '') . '>' . $user->lang($m_values['title']) . '</option>';
}
$template->assign_block_vars('m_names.modes', array(
'OPTION' => $m_mode,
- 'VALUE' => $this->lang_name($m_values['title']),
+ 'VALUE' => $user->lang($m_values['title']),
'A_OPTION' => addslashes($m_mode),
- 'A_VALUE' => addslashes($this->lang_name($m_values['title'])))
+ 'A_VALUE' => addslashes($user->lang($m_values['title'])))
);
}
}
@@ -358,7 +404,7 @@ class acp_modules
'L_TITLE' => $user->lang[strtoupper($action) . '_MODULE'],
- 'MODULENAME' => $this->lang_name($module_data['module_langname']),
+ 'MODULENAME' => $user->lang($module_data['module_langname']),
'ACTION' => $action,
'MODULE_ID' => $module_id,
@@ -406,11 +452,11 @@ class acp_modules
{
$navigation = '<a href="' . $this->u_action . '">' . strtoupper($this->module_class) . '</a>';
- $modules_nav = $this->get_module_branch($this->parent_id, 'parents', 'descending');
+ $modules_nav = $module_manager->get_module_branch($this->parent_id, $this->module_class, 'parents');
foreach ($modules_nav as $row)
{
- $langname = $this->lang_name($row['module_langname']);
+ $langname = $user->lang($row['module_langname']);
if ($row['module_id'] == $this->parent_id)
{
@@ -437,7 +483,7 @@ class acp_modules
{
do
{
- $langname = $this->lang_name($row['module_langname']);
+ $langname = $user->lang($row['module_langname']);
if (!$row['module_enabled'])
{
@@ -472,7 +518,15 @@ class acp_modules
}
else if ($this->parent_id)
{
- $row = $this->get_module_row($this->parent_id);
+ try
+ {
+ $row = $module_manager->get_module_row($this->parent_id, $this->module_class);
+ }
+ catch (\phpbb\module\exception\module_not_found_exception $e)
+ {
+ $msg = $user->lang($e->getMessage());
+ trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
+ }
$url = $this->u_action . '&amp;parent_id=' . $this->parent_id . '&amp;m=' . $row['module_id'];
@@ -491,19 +545,19 @@ class acp_modules
$db->sql_freeresult($result);
// Quick adding module
- $module_infos = $this->get_module_infos();
+ $module_infos = $module_manager->get_module_infos($this->module_class);
// Build quick options
$s_install_options = '';
foreach ($module_infos as $option => $values)
{
// Name options
- $s_install_options .= '<optgroup label="' . $this->lang_name($values['title']) . ' [' . $option . ']">';
+ $s_install_options .= '<optgroup label="' . $user->lang($values['title']) . ' [' . $option . ']">';
// Build module modes
foreach ($values['modes'] as $m_mode => $m_values)
{
- $s_install_options .= '<option value="' . $option . '::' . $m_mode . '">&nbsp; &nbsp;' . $this->lang_name($m_values['title']) . '</option>';
+ $s_install_options .= '<option value="' . $option . '::' . $m_mode . '">&nbsp; &nbsp;' . $user->lang($m_values['title']) . '</option>';
}
$s_install_options .= '</optgroup>';
@@ -521,104 +575,6 @@ class acp_modules
}
/**
- * Get row for specified module
- */
- function get_module_row($module_id)
- {
- global $db, $user;
-
- $sql = 'SELECT *
- FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND module_id = $module_id";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if (!$row)
- {
- trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
- }
-
- return $row;
- }
-
- /**
- * Get available module information from module files
- *
- * @param string $module
- * @param bool|string $module_class
- * @param bool $use_all_available Use all available instead of just all
- * enabled extensions
- * @return array
- */
- function get_module_infos($module = '', $module_class = false, $use_all_available = false)
- {
- global $phpbb_extension_manager, $phpbb_root_path, $phpEx;
-
- $module_class = ($module_class === false) ? $this->module_class : $module_class;
-
- $directory = $phpbb_root_path . 'includes/' . $module_class . '/info/';
- $fileinfo = array();
-
- $finder = $phpbb_extension_manager->get_finder($use_all_available);
-
- $modules = $finder
- ->extension_suffix('_module')
- ->extension_directory("/$module_class")
- ->core_path("includes/$module_class/info/")
- ->core_prefix($module_class . '_')
- ->get_classes(true);
-
- foreach ($modules as $cur_module)
- {
- // Skip entries we do not need if we know the module we are
- // looking for
- if ($module && strpos(str_replace('\\', '_', $cur_module), $module) === false && $module !== $cur_module)
- {
- continue;
- }
-
- $info_class = preg_replace('/_module$/', '_info', $cur_module);
-
- // If the class does not exist it might be following the old
- // format. phpbb_acp_info_acp_foo needs to be turned into
- // acp_foo_info and the respective file has to be included
- // manually because it does not support auto loading
- $old_info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module);
- $old_info_class = $old_info_class_file . '_info';
-
- if (class_exists($old_info_class))
- {
- $info_class = $old_info_class;
- }
- else if (!class_exists($info_class))
- {
- $info_class = $old_info_class;
- // need to check class exists again because previous checks triggered autoloading
- if (!class_exists($info_class) && file_exists($directory . $old_info_class_file . '.' . $phpEx))
- {
- include($directory . $old_info_class_file . '.' . $phpEx);
- }
- }
-
- if (class_exists($info_class))
- {
- $info = new $info_class();
- $module_info = $info->module();
-
- $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $cur_module;
-
- $fileinfo[$main_class] = $module_info;
- }
- }
-
- ksort($fileinfo);
-
- return $fileinfo;
- }
-
- /**
* Simple version of jumpbox, just lists modules
*/
function make_module_select($select_id = false, $ignore_id = false, $ignore_acl = false, $ignore_nonpost = false, $ignore_emptycat = true, $ignore_noncat = false)
@@ -678,7 +634,7 @@ class acp_modules
$selected = (is_array($select_id)) ? ((in_array($row['module_id'], $select_id)) ? ' selected="selected"' : '') : (($row['module_id'] == $select_id) ? ' selected="selected"' : '');
- $langname = $this->lang_name($row['module_langname']);
+ $langname = $user->lang($row['module_langname']);
$module_list .= '<option value="' . $row['module_id'] . '"' . $selected . ((!$row['module_enabled']) ? ' class="disabled"' : '') . '>' . $padding . $langname . '</option>';
$iteration++;
@@ -689,401 +645,4 @@ class acp_modules
return $module_list;
}
-
- /**
- * Get module branch
- */
- function get_module_branch($module_id, $type = 'all', $order = 'descending', $include_module = true)
- {
- global $db;
-
- switch ($type)
- {
- case 'parents':
- $condition = 'm1.left_id BETWEEN m2.left_id AND m2.right_id';
- break;
-
- case 'children':
- $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id';
- break;
-
- default:
- $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id OR m1.left_id BETWEEN m2.left_id AND m2.right_id';
- break;
- }
-
- $rows = array();
-
- $sql = 'SELECT m2.*
- FROM ' . MODULES_TABLE . ' m1
- LEFT JOIN ' . MODULES_TABLE . " m2 ON ($condition)
- WHERE m1.module_class = '" . $db->sql_escape($this->module_class) . "'
- AND m2.module_class = '" . $db->sql_escape($this->module_class) . "'
- AND m1.module_id = $module_id
- ORDER BY m2.left_id " . (($order == 'descending') ? 'ASC' : 'DESC');
- $result = $db->sql_query($sql);
-
- while ($row = $db->sql_fetchrow($result))
- {
- if (!$include_module && $row['module_id'] == $module_id)
- {
- continue;
- }
-
- $rows[] = $row;
- }
- $db->sql_freeresult($result);
-
- return $rows;
- }
-
- /**
- * Remove modules cache file
- */
- function remove_cache_file()
- {
- global $phpbb_container;
-
- // Sanitise for future path use, it's escaped as appropriate for queries
- $p_class = str_replace(array('.', '/', '\\'), '', basename($this->module_class));
-
- $phpbb_container->get('cache.driver')->destroy('_modules_' . $p_class);
-
- // Additionally remove sql cache
- $phpbb_container->get('cache.driver')->destroy('sql', MODULES_TABLE);
- }
-
- /**
- * Return correct language name
- */
- function lang_name($module_langname)
- {
- global $user;
-
- return (!empty($user->lang[$module_langname])) ? $user->lang[$module_langname] : $module_langname;
- }
-
- /**
- * Update/Add module
- *
- * @param array &$module_data The module data
- * @param bool $run_inline if set to true errors will be returned and no logs being written
- */
- function update_module_data(&$module_data, $run_inline = false)
- {
- global $db, $user, $phpbb_log;
-
- if (!isset($module_data['module_id']))
- {
- // no module_id means we're creating a new category/module
- if ($module_data['parent_id'])
- {
- $sql = 'SELECT left_id, right_id
- FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
- AND module_id = " . (int) $module_data['parent_id'];
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if (!$row)
- {
- if ($run_inline)
- {
- return 'PARENT_NO_EXIST';
- }
-
- trigger_error($user->lang['PARENT_NO_EXIST'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
- }
-
- // Workaround
- $row['left_id'] = (int) $row['left_id'];
- $row['right_id'] = (int) $row['right_id'];
-
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id + 2, right_id = right_id + 2
- WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
- AND left_id > {$row['right_id']}";
- $db->sql_query($sql);
-
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET right_id = right_id + 2
- WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
- AND {$row['left_id']} BETWEEN left_id AND right_id";
- $db->sql_query($sql);
-
- $module_data['left_id'] = (int) $row['right_id'];
- $module_data['right_id'] = (int) $row['right_id'] + 1;
- }
- else
- {
- $sql = 'SELECT MAX(right_id) AS right_id
- FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- $module_data['left_id'] = (int) $row['right_id'] + 1;
- $module_data['right_id'] = (int) $row['right_id'] + 2;
- }
-
- $sql = 'INSERT INTO ' . MODULES_TABLE . ' ' . $db->sql_build_array('INSERT', $module_data);
- $db->sql_query($sql);
-
- $module_data['module_id'] = $db->sql_nextid();
-
- if (!$run_inline)
- {
- $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_ADD', false, array($this->lang_name($module_data['module_langname'])));
- }
- }
- else
- {
- $row = $this->get_module_row($module_data['module_id']);
-
- if ($module_data['module_basename'] && !$row['module_basename'])
- {
- // we're turning a category into a module
- $branch = $this->get_module_branch($module_data['module_id'], 'children', 'descending', false);
-
- if (sizeof($branch))
- {
- return array($user->lang['NO_CATEGORY_TO_MODULE']);
- }
- }
-
- if ($row['parent_id'] != $module_data['parent_id'])
- {
- $this->move_module($module_data['module_id'], $module_data['parent_id']);
- }
-
- $update_ary = $module_data;
- unset($update_ary['module_id']);
-
- $sql = 'UPDATE ' . MODULES_TABLE . '
- SET ' . $db->sql_build_array('UPDATE', $update_ary) . "
- WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
- AND module_id = " . (int) $module_data['module_id'];
- $db->sql_query($sql);
-
- if (!$run_inline)
- {
- $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_EDIT', false, array($this->lang_name($module_data['module_langname'])));
- }
- }
-
- return array();
- }
-
- /**
- * Move module around the tree
- */
- function move_module($from_module_id, $to_parent_id)
- {
- global $db;
-
- $moved_modules = $this->get_module_branch($from_module_id, 'children', 'descending');
- $from_data = $moved_modules[0];
- $diff = sizeof($moved_modules) * 2;
-
- $moved_ids = array();
- for ($i = 0; $i < sizeof($moved_modules); ++$i)
- {
- $moved_ids[] = $moved_modules[$i]['module_id'];
- }
-
- // Resync parents
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET right_id = right_id - $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id < " . (int) $from_data['right_id'] . '
- AND right_id > ' . (int) $from_data['right_id'];
- $db->sql_query($sql);
-
- // Resync righthand side of tree
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id - $diff, right_id = right_id - $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id > " . (int) $from_data['right_id'];
- $db->sql_query($sql);
-
- if ($to_parent_id > 0)
- {
- $to_data = $this->get_module_row($to_parent_id);
-
- // Resync new parents
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET right_id = right_id + $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND " . (int) $to_data['right_id'] . ' BETWEEN left_id AND right_id
- AND ' . $db->sql_in_set('module_id', $moved_ids, true);
- $db->sql_query($sql);
-
- // Resync the righthand side of the tree
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id + $diff, right_id = right_id + $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id > " . (int) $to_data['right_id'] . '
- AND ' . $db->sql_in_set('module_id', $moved_ids, true);
- $db->sql_query($sql);
-
- // Resync moved branch
- $to_data['right_id'] += $diff;
- if ($to_data['right_id'] > $from_data['right_id'])
- {
- $diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1);
- }
- else
- {
- $diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1);
- }
- }
- else
- {
- $sql = 'SELECT MAX(right_id) AS right_id
- FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND " . $db->sql_in_set('module_id', $moved_ids, true);
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- $diff = '+ ' . (int) ($row['right_id'] - $from_data['left_id'] + 1);
- }
-
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id $diff, right_id = right_id $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND " . $db->sql_in_set('module_id', $moved_ids);
- $db->sql_query($sql);
- }
-
- /**
- * Remove module from tree
- */
- function delete_module($module_id)
- {
- global $db, $user, $phpbb_log;
-
- $row = $this->get_module_row($module_id);
-
- $branch = $this->get_module_branch($module_id, 'children', 'descending', false);
-
- if (sizeof($branch))
- {
- return array($user->lang['CANNOT_REMOVE_MODULE']);
- }
-
- // If not move
- $diff = 2;
- $sql = 'DELETE FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND module_id = $module_id";
- $db->sql_query($sql);
-
- $row['right_id'] = (int) $row['right_id'];
- $row['left_id'] = (int) $row['left_id'];
-
- // Resync tree
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET right_id = right_id - $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id < {$row['right_id']} AND right_id > {$row['right_id']}";
- $db->sql_query($sql);
-
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id - $diff, right_id = right_id - $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id > {$row['right_id']}";
- $db->sql_query($sql);
-
- $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_REMOVED', false, array($this->lang_name($row['module_langname'])));
-
- return array();
-
- }
-
- /**
- * Move module position by $steps up/down
- */
- function move_module_by($module_row, $action = 'move_up', $steps = 1)
- {
- global $db;
-
- /**
- * Fetch all the siblings between the module's current spot
- * and where we want to move it to. If there are less than $steps
- * siblings between the current spot and the target then the
- * module will move as far as possible
- */
- $sql = 'SELECT module_id, left_id, right_id, module_langname
- FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND parent_id = " . (int) $module_row['parent_id'] . '
- AND ' . (($action == 'move_up') ? 'right_id < ' . (int) $module_row['right_id'] . ' ORDER BY right_id DESC' : 'left_id > ' . (int) $module_row['left_id'] . ' ORDER BY left_id ASC');
- $result = $db->sql_query_limit($sql, $steps);
-
- $target = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $target = $row;
- }
- $db->sql_freeresult($result);
-
- if (!sizeof($target))
- {
- // The module is already on top or bottom
- return false;
- }
-
- /**
- * $left_id and $right_id define the scope of the nodes that are affected by the move.
- * $diff_up and $diff_down are the values to substract or add to each node's left_id
- * and right_id in order to move them up or down.
- * $move_up_left and $move_up_right define the scope of the nodes that are moving
- * up. Other nodes in the scope of ($left_id, $right_id) are considered to move down.
- */
- if ($action == 'move_up')
- {
- $left_id = (int) $target['left_id'];
- $right_id = (int) $module_row['right_id'];
-
- $diff_up = (int) ($module_row['left_id'] - $target['left_id']);
- $diff_down = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
-
- $move_up_left = (int) $module_row['left_id'];
- $move_up_right = (int) $module_row['right_id'];
- }
- else
- {
- $left_id = (int) $module_row['left_id'];
- $right_id = (int) $target['right_id'];
-
- $diff_up = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
- $diff_down = (int) ($target['right_id'] - $module_row['right_id']);
-
- $move_up_left = (int) ($module_row['right_id'] + 1);
- $move_up_right = (int) $target['right_id'];
- }
-
- // Now do the dirty job
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id + CASE
- WHEN left_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
- ELSE {$diff_down}
- END,
- right_id = right_id + CASE
- WHEN right_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
- ELSE {$diff_down}
- END
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id BETWEEN {$left_id} AND {$right_id}
- AND right_id BETWEEN {$left_id} AND {$right_id}";
- $db->sql_query($sql);
-
- $this->remove_cache_file();
-
- return $this->lang_name($target['module_langname']);
- }
}
diff --git a/phpBB/includes/acp/acp_permission_roles.php b/phpBB/includes/acp/acp_permission_roles.php
index 21c751b61a..2d71ab4c71 100644
--- a/phpBB/includes/acp/acp_permission_roles.php
+++ b/phpBB/includes/acp/acp_permission_roles.php
@@ -30,8 +30,15 @@ class acp_permission_roles
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
global $request, $phpbb_log;
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
- include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
+
+ if (!class_exists('auth_admin'))
+ {
+ include($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ }
$this->auth_admin = new auth_admin();
diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php
index b36eae0f93..26e7266409 100644
--- a/phpBB/includes/acp/acp_permissions.php
+++ b/phpBB/includes/acp/acp_permissions.php
@@ -34,8 +34,15 @@ class acp_permissions
global $db, $user, $auth, $template, $cache, $phpbb_container, $request;
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
- include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
+
+ if (!class_exists('auth_admin'))
+ {
+ include($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ }
$this->permissions = $phpbb_container->get('acl.permissions');
@@ -909,7 +916,7 @@ class acp_permissions
*/
function log_action($mode, $action, $permission_type, $ug_type, $ug_id, $forum_id)
{
- global $db, $user, $phpbb_log;
+ global $db, $user, $phpbb_log, $phpbb_container;
if (!is_array($ug_id))
{
@@ -926,10 +933,14 @@ class acp_permissions
$sql .= $db->sql_in_set(($ug_type == 'group') ? 'group_id' : 'user_id', array_map('intval', $ug_id));
$result = $db->sql_query($sql);
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
$l_ug_list = '';
while ($row = $db->sql_fetchrow($result))
{
- $l_ug_list .= (($l_ug_list != '') ? ', ' : '') . ((isset($row['group_type']) && $row['group_type'] == GROUP_SPECIAL) ? '<span class="sep">' . $user->lang['G_' . $row['name']] . '</span>' : $row['name']);
+ $group_name = $group_helper->get_name($row['name']);
+ $l_ug_list .= (($l_ug_list != '') ? ', ' : '') . ((isset($row['group_type']) && $row['group_type'] == GROUP_SPECIAL) ? '<span class="sep">' . $group_name . '</span>' : $group_name);
}
$db->sql_freeresult($result);
@@ -963,7 +974,7 @@ class acp_permissions
*/
function permission_trace($user_id, $forum_id, $permission)
{
- global $db, $template, $user, $auth, $request;
+ global $db, $template, $user, $auth, $request, $phpbb_container;
if ($user_id != $user->data['user_id'])
{
@@ -979,6 +990,9 @@ class acp_permissions
trigger_error('NO_USERS', E_USER_ERROR);
}
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
$forum_name = false;
if ($forum_id)
@@ -1025,7 +1039,7 @@ class acp_permissions
{
$groups[$row['group_id']] = array(
'auth_setting' => ACL_NO,
- 'group_name' => ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']
+ 'group_name' => $group_helper->get_name($row['group_name']),
);
}
$db->sql_freeresult($result);
@@ -1233,7 +1247,10 @@ class acp_permissions
*/
function retrieve_defined_user_groups($permission_scope, $forum_id, $permission_type)
{
- global $db, $user;
+ global $db, $phpbb_container;
+
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
$sql_forum_id = ($permission_scope == 'global') ? 'AND a.forum_id = 0' : ((sizeof($forum_id)) ? 'AND ' . $db->sql_in_set('a.forum_id', $forum_id) : 'AND a.forum_id <> 0');
@@ -1308,7 +1325,7 @@ class acp_permissions
$defined_group_ids = array();
while ($row = $db->sql_fetchrow($result))
{
- $s_defined_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '">' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>';
+ $s_defined_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '">' . $group_helper->get_name($row['group_name']) . '</option>';
$defined_group_ids[] = $row['group_id'];
}
$db->sql_freeresult($result);
diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php
index 146e116cfd..07620d0dcd 100644
--- a/phpBB/includes/acp/acp_profile.php
+++ b/phpBB/includes/acp/acp_profile.php
@@ -35,10 +35,17 @@ class acp_profile
{
global $config, $db, $user, $auth, $template, $cache;
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix;
- global $request, $phpbb_container, $phpbb_log;
+ global $request, $phpbb_container, $phpbb_log, $phpbb_dispatcher;
- include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('generate_smilies'))
+ {
+ include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
+ }
+
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$user->add_lang(array('ucp', 'acp/profile'));
$this->tpl_name = 'acp_profile';
@@ -375,6 +382,32 @@ class acp_profile
'field_is_contact',
);
+ /**
+ * Event to add initialization for new profile field table fields
+ *
+ * @event core.acp_profile_create_edit_init
+ * @var string action create|edit
+ * @var int step Configuration step (1|2|3)
+ * @var bool submit Form has been submitted
+ * @var bool save Configuration should be saved
+ * @var string field_type Type of the field we are dealing with
+ * @var array field_row Array of data about the field
+ * @var array exclude Array of excluded fields by step
+ * @var array visibility_ary Array of fields that are visibility related
+ * @since 3.1.6-RC1
+ */
+ $vars = array(
+ 'action',
+ 'step',
+ 'submit',
+ 'save',
+ 'field_type',
+ 'field_row',
+ 'exclude',
+ 'visibility_ary',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.acp_profile_create_edit_init', compact($vars)));
+
$options = $profile_field->prepare_options_form($exclude, $visibility_ary);
$cp->vars['field_ident'] = ($action == 'create' && $step == 1) ? utf8_clean_string($request->variable('field_ident', $field_row['field_ident'], true)) : $request->variable('field_ident', $field_row['field_ident']);
@@ -517,13 +550,14 @@ class acp_profile
}
}
- $step = (isset($_REQUEST['next'])) ? $step + 1 : ((isset($_REQUEST['prev'])) ? $step - 1 : $step);
-
if (sizeof($error))
{
- $step--;
$submit = false;
}
+ else
+ {
+ $step = (isset($_REQUEST['next'])) ? $step + 1 : ((isset($_REQUEST['prev'])) ? $step - 1 : $step);
+ }
// Build up the specific hidden fields
foreach ($exclude as $num => $key_ary)
@@ -541,7 +575,7 @@ class acp_profile
$var = $profile_field->prepare_hidden_fields($step, $key, $action, $field_data);
if ($var !== null)
{
- $_new_key_ary[$key] = $profile_field->prepare_hidden_fields($step, $key, $action, $field_data);
+ $_new_key_ary[$key] = $var;
}
}
$cp->vars = $field_data;
@@ -551,11 +585,7 @@ class acp_profile
if (!sizeof($error))
{
- if ($step == 3 && (sizeof($this->lang_defs['iso']) == 1 || $save))
- {
- $this->save_profile_field($cp, $field_type, $action);
- }
- else if ($action == 'edit' && $save)
+ if (($step == 3 && (sizeof($this->lang_defs['iso']) == 1 || $save)) || ($action == 'edit' && $save))
{
$this->save_profile_field($cp, $field_type, $action);
}
@@ -650,6 +680,33 @@ class acp_profile
break;
}
+ $field_data = $cp->vars;
+ /**
+ * Event to add template variables for new profile field table fields
+ *
+ * @event core.acp_profile_create_edit_after
+ * @var string action create|edit
+ * @var int step Configuration step (1|2|3)
+ * @var bool submit Form has been submitted
+ * @var bool save Configuration should be saved
+ * @var string field_type Type of the field we are dealing with
+ * @var array field_data Array of data about the field
+ * @var array s_hidden_fields Array of hidden fields in case this needs modification
+ * @var array options Array of options specific to this step
+ * @since 3.1.6-RC1
+ */
+ $vars = array(
+ 'action',
+ 'step',
+ 'submit',
+ 'save',
+ 'field_type',
+ 'field_data',
+ 's_hidden_fields',
+ 'options',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.acp_profile_create_edit_after', compact($vars)));
+
$template->assign_vars(array(
'S_HIDDEN_FIELDS' => $s_hidden_fields)
);
@@ -816,7 +873,7 @@ class acp_profile
*/
function save_profile_field(&$cp, $field_type, $action = 'create')
{
- global $db, $config, $user, $phpbb_container, $phpbb_log, $request;
+ global $db, $config, $user, $phpbb_container, $phpbb_log, $request, $phpbb_dispatcher;
$field_id = $request->variable('field_id', 0);
@@ -858,6 +915,25 @@ class acp_profile
'field_contact_url' => $cp->vars['field_contact_url'],
);
+ $field_data = $cp->vars;
+ /**
+ * Event to modify profile field configuration data before saving to database
+ *
+ * @event core.acp_profile_create_edit_save_before
+ * @var string action create|edit
+ * @var string field_type Type of the field we are dealing with
+ * @var array field_data Array of data about the field
+ * @var array profile_fields Array of fields to be sent to the database
+ * @since 3.1.6-RC1
+ */
+ $vars = array(
+ 'action',
+ 'field_type',
+ 'field_data',
+ 'profile_fields',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.acp_profile_create_edit_save_before', compact($vars)));
+
if ($action == 'create')
{
$profile_fields += array(
diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php
index 63a103aa0c..2ea1e89df6 100644
--- a/phpBB/includes/acp/acp_prune.php
+++ b/phpBB/includes/acp/acp_prune.php
@@ -28,7 +28,11 @@ class acp_prune
global $user, $phpEx, $phpbb_admin_path, $phpbb_root_path;
$user->add_lang('acp/prune');
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+
+ if (!function_exists('user_active_flip'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
switch ($mode)
{
@@ -230,7 +234,10 @@ class acp_prune
function prune_users($id, $mode)
{
global $db, $user, $auth, $template, $cache, $phpbb_log, $request;
- global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
+ global $config, $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');
@@ -342,7 +349,7 @@ class acp_prune
$s_group_list = '';
while ($row = $db->sql_fetchrow($result))
{
- $s_group_list .= '<option value="' . $row['group_id'] . '">' . $row['group_name'] . '</option>';
+ $s_group_list .= '<option value="' . $row['group_id'] . '">' . $group_helper->get_name($row['group_name']) . '</option>';
}
$db->sql_freeresult($result);
@@ -507,9 +514,9 @@ class acp_prune
WHERE ug.group_id = ' . (int) $group_id . '
AND ug.user_id <> ' . ANONYMOUS . '
AND u.user_type <> ' . USER_FOUNDER . '
- AND ug.user_pending = 0 ' .
- ((!empty($user_ids)) ? ' AND ' . $db->sql_in_set('ug.user_id', $user_ids) : '') . '
- AND u.user_id = ug.user_id';
+ AND ug.user_pending = 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
@@ -533,10 +540,10 @@ class acp_prune
$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 .
- ((!empty($user_ids)) ? ' AND ' . $db->sql_in_set('p.poster_id', $user_ids) : '') . '
+ 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);
diff --git a/phpBB/includes/acp/acp_search.php b/phpBB/includes/acp/acp_search.php
index f7382f826d..25fc1ed8dc 100644
--- a/phpBB/includes/acp/acp_search.php
+++ b/phpBB/includes/acp/acp_search.php
@@ -445,7 +445,6 @@ class acp_search
$search = null;
$error = false;
- $search_options = '';
foreach ($search_types as $type)
{
if ($this->init_search($type, $search, $error) || !method_exists($search, 'index_created'))
@@ -597,7 +596,7 @@ class acp_search
*/
function init_search($type, &$search, &$error)
{
- global $phpbb_root_path, $phpEx, $user, $auth, $config, $db;
+ global $phpbb_root_path, $phpEx, $user, $auth, $config, $db, $phpbb_dispatcher;
if (!class_exists($type) || !method_exists($type, 'keyword_search'))
{
@@ -606,7 +605,7 @@ class acp_search
}
$error = false;
- $search = new $type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
return $error;
}
diff --git a/phpBB/includes/acp/acp_send_statistics.php b/phpBB/includes/acp/acp_send_statistics.php
index 4c5786dbe9..74da5996f1 100644
--- a/phpBB/includes/acp/acp_send_statistics.php
+++ b/phpBB/includes/acp/acp_send_statistics.php
@@ -27,7 +27,10 @@ class acp_send_statistics
{
global $config, $template, $phpbb_admin_path, $phpbb_root_path, $phpEx;
- include($phpbb_root_path . 'includes/questionnaire/questionnaire.' . $phpEx);
+ if (!class_exists('phpbb_questionnaire_data_collector'))
+ {
+ include($phpbb_root_path . 'includes/questionnaire/questionnaire.' . $phpEx);
+ }
$collect_url = "https://www.phpbb.com/stats/receive_stats.php";
diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php
index 45f224f8b1..0cd6633710 100644
--- a/phpBB/includes/acp/acp_styles.php
+++ b/phpBB/includes/acp/acp_styles.php
@@ -53,15 +53,21 @@ class acp_styles
/** @var \phpbb\auth\auth */
protected $auth;
+ /** @var \phpbb\textformatter\cache_interface */
+ protected $text_formatter_cache;
+
/** @var string */
protected $phpbb_root_path;
/** @var string */
protected $php_ext;
+ /** @var \phpbb\event\dispatcher_interface */
+ protected $dispatcher;
+
public function main($id, $mode)
{
- global $db, $user, $phpbb_admin_path, $phpbb_root_path, $phpEx, $template, $request, $cache, $auth, $config;
+ global $db, $user, $phpbb_admin_path, $phpbb_root_path, $phpEx, $template, $request, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_container;
$this->db = $db;
$this->user = $user;
@@ -69,9 +75,11 @@ class acp_styles
$this->request = $request;
$this->cache = $cache;
$this->auth = $auth;
+ $this->text_formatter_cache = $phpbb_container->get('text_formatter.cache');
$this->config = $config;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $phpEx;
+ $this->dispatcher = $phpbb_dispatcher;
$this->default_style = $config['default_style'];
$this->styles_path = $this->phpbb_root_path . $this->styles_path_absolute . '/';
@@ -121,6 +129,18 @@ class acp_styles
)
);
+ /**
+ * Run code before ACP styles action execution
+ *
+ * @event core.acp_styles_action_before
+ * @var int id Module ID
+ * @var string mode Active module
+ * @var string action Module that should be run
+ * @since 3.1.7-RC1
+ */
+ $vars = array('id', 'mode', 'action');
+ extract($this->dispatcher->trigger_event('core.acp_styles_action_before', compact($vars)));
+
// Execute actions
switch ($action)
{
@@ -216,6 +236,12 @@ class acp_styles
}
}
+ // Invalidate the text formatter's cache for the new styles to take effect
+ if (!empty($installed_names))
+ {
+ $this->text_formatter_cache->invalidate();
+ }
+
// Show message
if (!count($messages))
{
@@ -1003,7 +1029,7 @@ class acp_styles
// Assign template variables
$this->template->assign_block_vars('styles_list', $row);
- foreach($actions as $action)
+ foreach ($actions as $action)
{
$this->template->assign_block_vars('styles_list.actions', $action);
}
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index fec32146c1..b0b8fb1e60 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -44,6 +44,11 @@ class acp_users
$user_id = $request->variable('u', 0);
$action = $request->variable('action', '');
+ // Get referer to redirect user to the appropriate page after delete action
+ $redirect = $request->variable('redirect', '');
+ $redirect_tag = "redirect=$redirect";
+ $redirect_url = append_sid("{$phpbb_admin_path}index.$phpEx", "i=$redirect");
+
$submit = (isset($_POST['update']) && !isset($_POST['cancel'])) ? true : false;
$form_name = 'acp_users';
@@ -52,7 +57,10 @@ class acp_users
// Whois (special case)
if ($action == 'whois')
{
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$this->page_title = 'WHOIS';
$this->tpl_name = 'simple_body';
@@ -146,9 +154,9 @@ class acp_users
}
$template->assign_vars(array(
- 'U_BACK' => $this->u_action,
+ 'U_BACK' => (empty($redirect)) ? $this->u_action : $redirect_url,
'U_MODE_SELECT' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&amp;u=$user_id"),
- 'U_ACTION' => $this->u_action . '&amp;u=' . $user_id,
+ 'U_ACTION' => $this->u_action . '&amp;u=' . $user_id . ((empty($redirect)) ? '' : '&amp;' . $redirect_tag),
'S_FORM_OPTIONS' => $s_form_options,
'MANAGED_USERNAME' => $user_row['username'])
);
@@ -165,7 +173,10 @@ class acp_users
{
case 'overview':
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$user->add_lang('acp/ban');
@@ -221,19 +232,30 @@ class acp_users
user_delete($delete_type, $user_id, $user_row['username']);
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_USER_DELETED', false, array($user_row['username']));
- trigger_error($user->lang['USER_DELETED'] . adm_back_link($this->u_action));
+ trigger_error($user->lang['USER_DELETED'] . adm_back_link(
+ (empty($redirect)) ? $this->u_action : $redirect_url
+ )
+ );
}
else
{
- confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
+ $delete_confirm_hidden_fields = array(
'u' => $user_id,
'i' => $id,
'mode' => $mode,
'action' => $action,
'update' => true,
'delete' => 1,
- 'delete_type' => $delete_type))
+ 'delete_type' => $delete_type,
);
+
+ // Checks if the redirection page is specified
+ if (!empty($redirect))
+ {
+ $delete_confirm_hidden_fields['redirect'] = $redirect;
+ }
+
+ confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($delete_confirm_hidden_fields));
}
}
else
@@ -338,7 +360,10 @@ class acp_users
if ($config['email_enable'])
{
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ if (!class_exists('messenger'))
+ {
+ include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ }
$server_url = generate_board_url();
@@ -424,7 +449,10 @@ class acp_users
$phpbb_notifications = $phpbb_container->get('notification_manager');
$phpbb_notifications->delete_notifications('notification.type.admin_activate_user', $user_row['user_id']);
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ if (!class_exists('messenger'))
+ {
+ include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ }
$messenger = new messenger(false);
@@ -527,7 +555,10 @@ class acp_users
if (confirm_box(true))
{
- delete_attachments('user', $user_id);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('user', $user_id);
+ unset($attachment_manager);
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_USER_DEL_ATTACH', false, array($user_row['username']));
trigger_error($user->lang['USER_ATTACHMENTS_REMOVED'] . adm_back_link($this->u_action . '&amp;u=' . $user_id));
@@ -1381,7 +1412,10 @@ class acp_users
case 'profile':
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
/* @var $cp \phpbb\profilefields\manager */
$cp = $phpbb_container->get('profilefields.manager');
@@ -1541,7 +1575,10 @@ class acp_users
case 'prefs':
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$data = array(
'dateformat' => $request->variable('dateformat', $user_row['user_dateformat'], true),
@@ -1811,8 +1848,6 @@ class acp_users
case 'avatar':
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
-
$avatars_enabled = false;
if ($config['allow_avatar'])
@@ -1968,7 +2003,10 @@ class acp_users
case 'sig':
- include_once($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ if (!function_exists('display_custom_bbcodes'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
$enable_bbcode = ($config['allow_sig_bbcode']) ? $this->optionget($user_row, 'sig_bbcode') : false;
$enable_smilies = ($config['allow_sig_smilies']) ? $this->optionget($user_row, 'sig_smilies') : false;
@@ -1991,7 +2029,20 @@ class acp_users
}
$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);
+ $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 (sizeof($warn_msg))
{
@@ -2045,7 +2096,7 @@ class acp_users
'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_controller', array('mode' => 'bbcode')) . '">', '</a>'),
+ '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'],
@@ -2110,7 +2161,10 @@ class acp_users
}
$db->sql_freeresult($result);
- delete_attachments('attach', $marked);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('attach', $marked);
+ unset($attachment_manager);
$message = (sizeof($log_attachments) == 1) ? $user->lang['ATTACHMENT_DELETED'] : $user->lang['ATTACHMENTS_DELETED'];
@@ -2220,7 +2274,10 @@ class acp_users
case 'groups':
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('group_user_attributes'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$user->add_lang(array('groups', 'acp/groups'));
$group_id = $request->variable('g', 0);
@@ -2348,6 +2405,9 @@ class acp_users
$error = array();
}
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
$sql = 'SELECT ug.*, g.*
FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . " ug
WHERE ug.user_id = $user_id
@@ -2392,7 +2452,7 @@ class acp_users
continue;
}
- $s_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '">' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>';
+ $s_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '">' . $group_helper->get_name($row['group_name']) . '</option>';
}
$db->sql_freeresult($result);
@@ -2436,7 +2496,10 @@ class acp_users
case 'perm':
- include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ if (!class_exists('auth_admin'))
+ {
+ include($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ }
$auth_admin = new auth_admin();
diff --git a/phpBB/includes/acp/acp_words.php b/phpBB/includes/acp/acp_words.php
index d28aa8e60b..ea8d47a109 100644
--- a/phpBB/includes/acp/acp_words.php
+++ b/phpBB/includes/acp/acp_words.php
@@ -28,7 +28,7 @@ class acp_words
function main($id, $mode)
{
- global $db, $user, $auth, $template, $cache, $phpbb_log, $request;
+ global $db, $user, $auth, $template, $cache, $phpbb_log, $request, $phpbb_container;
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
$user->add_lang('acp/posting');
@@ -115,6 +115,7 @@ class acp_words
}
$cache->destroy('_word_censors');
+ $phpbb_container->get('text_formatter.cache')->invalidate();
$log_action = ($word_id) ? 'LOG_WORD_EDIT' : 'LOG_WORD_ADD';
@@ -148,6 +149,7 @@ class acp_words
$db->sql_query($sql);
$cache->destroy('_word_censors');
+ $phpbb_container->get('text_formatter.cache')->invalidate();
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_WORD_DELETE', false, array($deleted_word));
diff --git a/phpBB/includes/acp/auth.php b/phpBB/includes/acp/auth.php
index 644b1ac7a5..027be03a00 100644
--- a/phpBB/includes/acp/auth.php
+++ b/phpBB/includes/acp/auth.php
@@ -271,6 +271,9 @@ class auth_admin extends \phpbb\auth\auth
/* @var $phpbb_permissions \phpbb\permissions */
$phpbb_permissions = $phpbb_container->get('acl.permissions');
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
// Define names for template loops, might be able to be set
$tpl_pmask = 'p_mask';
$tpl_fmask = 'f_mask';
@@ -302,7 +305,7 @@ class auth_admin extends \phpbb\auth\auth
$ug_names_ary = array();
while ($row = $db->sql_fetchrow($result))
{
- $ug_names_ary[$row['ug_id']] = ($user_mode == 'user') ? $row['ug_name'] : (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['ug_name']] : $row['ug_name']);
+ $ug_names_ary[$row['ug_id']] = ($user_mode == 'user') ? $row['ug_name'] : $group_helper->get_name($row['ug_name']);
}
$db->sql_freeresult($result);
@@ -410,14 +413,7 @@ class auth_admin extends \phpbb\auth\auth
{
foreach ($memberships as $row)
{
- if ($groups[$row['group_id']]['group_type'] == GROUP_SPECIAL)
- {
- $user_groups_default[$row['user_id']][] = $user->lang['G_' . $groups[$row['group_id']]['group_name']];
- }
- else
- {
- $user_groups_custom[$row['user_id']][] = $groups[$row['group_id']]['group_name'];
- }
+ $user_groups_default[$row['user_id']][] = $group_helper->get_name($groups[$row['group_id']]['group_name']);
}
}
unset($memberships, $groups);
@@ -470,7 +466,8 @@ class auth_admin extends \phpbb\auth\auth
// Build role dropdown options
$current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0;
- $s_role_options = '';
+ // Output current role id to template
+ $template->assign_var('S_ROLE_ID', $current_role_id);
@reset($roles);
while (list($role_id, $role_row) = each($roles))
@@ -478,13 +475,12 @@ class auth_admin extends \phpbb\auth\auth
$role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']);
$role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name'];
- $title = ($role_description) ? ' title="' . $role_description . '"' : '';
- $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>';
- }
-
- if ($s_role_options)
- {
- $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN']) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options;
+ $template->assign_block_vars('role_options', array(
+ 'ID' => $role_id,
+ 'ROLE_NAME' => $role_name,
+ 'TITLE' => $role_description,
+ 'SELECTED' => $role_id == $current_role_id,
+ ));
}
if (!$current_role_id && $mode != 'view')
@@ -507,7 +503,6 @@ class auth_admin extends \phpbb\auth\auth
$template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array(
'NAME' => $ug_names_ary[$ug_id],
- 'S_ROLE_OPTIONS' => $s_role_options,
'UG_ID' => $ug_id,
'S_CUSTOM' => $s_custom_permissions,
'FORUM_ID' => $forum_id)
@@ -556,7 +551,8 @@ class auth_admin extends \phpbb\auth\auth
// Build role dropdown options
$current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0;
- $s_role_options = '';
+ // Output current role id to template
+ $template->assign_var('S_ROLE_ID', $current_role_id);
@reset($roles);
while (list($role_id, $role_row) = each($roles))
@@ -564,13 +560,12 @@ class auth_admin extends \phpbb\auth\auth
$role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']);
$role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name'];
- $title = ($role_description) ? ' title="' . $role_description . '"' : '';
- $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>';
- }
-
- if ($s_role_options)
- {
- $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN']) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options;
+ $template->assign_block_vars('role_options', array(
+ 'ID' => $role_id,
+ 'ROLE_NAME' => $role_name,
+ 'TITLE' => $role_description,
+ 'SELECTED' => $role_id == $current_role_id,
+ ));
}
if (!$current_role_id && $mode != 'view')
@@ -594,7 +589,6 @@ class auth_admin extends \phpbb\auth\auth
$template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array(
'NAME' => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'],
'PADDING' => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'],
- 'S_ROLE_OPTIONS' => $s_role_options,
'S_CUSTOM' => $s_custom_permissions,
'UG_ID' => $ug_id,
'FORUM_ID' => $forum_id)
@@ -614,12 +608,16 @@ class auth_admin extends \phpbb\auth\auth
function display_role_mask(&$hold_ary)
{
global $db, $template, $user, $phpbb_root_path, $phpbb_admin_path, $phpEx;
+ global $phpbb_container;
if (!sizeof($hold_ary))
{
return;
}
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
// Get forum names
$sql = 'SELECT forum_id, forum_name
FROM ' . FORUMS_TABLE . '
@@ -675,7 +673,7 @@ class auth_admin extends \phpbb\auth\auth
{
$template->assign_block_vars('role_mask.groups', array(
'GROUP_ID' => $row['group_id'],
- 'GROUP_NAME' => ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'],
+ 'GROUP_NAME' => $group_helper->get_name($row['group_name']),
'U_PROFILE' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=group&amp;g={$row['group_id']}"))
);
}
@@ -1116,6 +1114,11 @@ class auth_admin extends \phpbb\auth\auth
@reset($category_array);
while (list($cat, $cat_array) = each($category_array))
{
+ if (!$phpbb_permissions->category_defined($cat))
+ {
+ continue;
+ }
+
$template->assign_block_vars($tpl_cat, array(
'S_YES' => ($cat_array['S_YES'] && !$cat_array['S_NEVER'] && !$cat_array['S_NO']) ? true : false,
'S_NEVER' => ($cat_array['S_NEVER'] && !$cat_array['S_YES'] && !$cat_array['S_NO']) ? true : false,
@@ -1142,6 +1145,11 @@ class auth_admin extends \phpbb\auth\auth
@reset($cat_array['permissions']);
while (list($permission, $allowed) = each($cat_array['permissions']))
{
+ if (!$phpbb_permissions->permission_defined($permission))
+ {
+ continue;
+ }
+
if ($s_view)
{
$template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array(
diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php
index ee911b5ec5..41d4ec40fe 100644
--- a/phpBB/includes/bbcode.php
+++ b/phpBB/includes/bbcode.php
@@ -110,7 +110,18 @@ class bbcode
$undid_bbcode_specialchars = true;
}
- $message = preg_replace($preg['search'], $preg['replace'], $message);
+ 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());
}
}
@@ -129,7 +140,7 @@ class bbcode
*/
function bbcode_cache_init()
{
- global $phpbb_root_path, $phpEx, $config, $user, $phpbb_dispatcher, $phpbb_extension_manager, $phpbb_path_helper, $phpbb_container;
+ global $phpbb_root_path, $phpEx, $config, $user, $phpbb_dispatcher, $phpbb_extension_manager, $phpbb_path_helper, $phpbb_container, $phpbb_filesystem;
if (empty($this->template_filename))
{
@@ -138,17 +149,20 @@ class bbcode
$template = new \phpbb\template\twig\twig(
$phpbb_container->get('path_helper'),
$phpbb_container->get('config'),
- $phpbb_container->get('user'),
new \phpbb\template\context(),
new \phpbb\template\twig\environment(
$phpbb_container->get('config'),
+ $phpbb_container->get('filesystem'),
$phpbb_container->get('path_helper'),
$phpbb_container,
$phpbb_container->getParameter('core.root_path') . 'cache/',
$phpbb_container->get('ext.manager'),
- new \phpbb\template\twig\loader()
+ new \phpbb\template\twig\loader(
+ $phpbb_filesystem
+ )
),
$phpbb_container->getParameter('core.root_path') . 'cache/',
+ $phpbb_container->get('user'),
$phpbb_container->get('template.twig.extensions.collection'),
$phpbb_extension_manager
);
@@ -199,6 +213,8 @@ class bbcode
$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)
@@ -209,7 +225,9 @@ class bbcode
'[/quote:$uid]' => $this->bbcode_tpl('quote_close', $bbcode_id)
),
'preg' => array(
- '#\[quote(?:=&quot;(.*?)&quot;)?:$uid\]((?!\[quote(?:=&quot;.*?&quot;)?:$uid\]).)?#ise' => "\$this->bbcode_second_pass_quote('\$1', '\$2')"
+ '#\[quote(?:=&quot;(.*?)&quot;)?:$uid\]((?!\[quote(?:=&quot;.*?&quot;)?:$uid\]).)?#is' => function ($match) {
+ return $this->bbcode_second_pass_quote($match[1], $match[2]);
+ },
)
);
break;
@@ -288,7 +306,9 @@ class bbcode
case 8:
$this->bbcode_cache[$bbcode_id] = array(
'preg' => array(
- '#\[code(?:=([a-z]+))?:$uid\](.*?)\[/code:$uid\]#ise' => "\$this->bbcode_second_pass_code('\$1', '\$2')",
+ '#\[code(?:=([a-z]+))?:$uid\](.*?)\[/code:$uid\]#is' => function ($match) {
+ return $this->bbcode_second_pass_code($match[1], $match[2]);
+ },
)
);
break;
@@ -298,7 +318,9 @@ class bbcode
'preg' => array(
'#(\[\/?(list|\*):[mou]?:?$uid\])[\n]{1}#' => "\$1",
'#(\[list=([^\[]+):$uid\])[\n]{1}#' => "\$1",
- '#\[list=([^\[]+):$uid\]#e' => "\$this->bbcode_list('\$1')",
+ '#\[list=([^\[]+):$uid\]#' => function ($match) {
+ return $this->bbcode_list($match[1]);
+ },
),
'str' => array(
'[list:$uid]' => $this->bbcode_tpl('ulist_open_default', $bbcode_id),
@@ -382,7 +404,9 @@ class bbcode
}
// Replace {L_*} lang strings
- $bbcode_tpl = preg_replace('/{L_([A-Z0-9_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $bbcode_tpl);
+ $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']))
{
@@ -506,7 +530,9 @@ class bbcode
'email' => array('{EMAIL}' => '$1', '{DESCRIPTION}' => '$2')
);
- $tpl = preg_replace('/{L_([A-Z0-9_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $tpl);
+ $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]))
{
@@ -630,4 +656,36 @@ class bbcode
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;
+ }
}
diff --git a/phpBB/includes/compatibility_globals.php b/phpBB/includes/compatibility_globals.php
index b0919aefb3..ae532c0f13 100644
--- a/phpBB/includes/compatibility_globals.php
+++ b/phpBB/includes/compatibility_globals.php
@@ -18,45 +18,62 @@ if (!defined('IN_PHPBB'))
exit;
}
-// set up caching
-/* @var $cache \phpbb\cache\service */
-$cache = $phpbb_container->get('cache');
+/**
+ * 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, $phpbb_log;
+ global $symfony_request, $phpbb_filesystem, $phpbb_path_helper, $phpbb_extension_manager, $template;
-// Instantiate some basic classes
-/* @var $phpbb_dispatcher \phpbb\event\dispatcher */
-$phpbb_dispatcher = $phpbb_container->get('dispatcher');
+ // set up caching
+ /* @var $cache \phpbb\cache\service */
+ $cache = $phpbb_container->get('cache');
-/* @var $request \phpbb\request\request_interface */
-$request = $phpbb_container->get('request');
+ // Instantiate some basic classes
+ /* @var $phpbb_dispatcher \phpbb\event\dispatcher */
+ $phpbb_dispatcher = $phpbb_container->get('dispatcher');
-/* @var $user \phpbb\user */
-$user = $phpbb_container->get('user');
+ /* @var $request \phpbb\request\request_interface */
+ $request = $phpbb_container->get('request');
-/* @var $auth \phpbb\auth\auth */
-$auth = $phpbb_container->get('auth');
+ /* @var $user \phpbb\user */
+ $user = $phpbb_container->get('user');
-/* @var $db \phpbb\db\driver\driver_interface */
-$db = $phpbb_container->get('dbal.conn');
+ /* @var $auth \phpbb\auth\auth */
+ $auth = $phpbb_container->get('auth');
-// Grab global variables, re-cache if necessary
-/* @var $config phpbb\config\db */
-$config = $phpbb_container->get('config');
+ /* @var $db \phpbb\db\driver\driver_interface */
+ $db = $phpbb_container->get('dbal.conn');
-/* @var $phpbb_log \phpbb\log\log_interface */
-$phpbb_log = $phpbb_container->get('log');
+ // Grab global variables, re-cache if necessary
+ /* @var $config phpbb\config\db */
+ $config = $phpbb_container->get('config');
-/* @var $symfony_request \phpbb\symfony_request */
-$symfony_request = $phpbb_container->get('symfony_request');
+ /* @var $phpbb_log \phpbb\log\log_interface */
+ $phpbb_log = $phpbb_container->get('log');
-/* @var $phpbb_filesystem \phpbb\filesystem */
-$phpbb_filesystem = $phpbb_container->get('filesystem');
+ /* @var $symfony_request \phpbb\symfony_request */
+ $symfony_request = $phpbb_container->get('symfony_request');
-/* @var $phpbb_path_helper \phpbb\path_helper */
-$phpbb_path_helper = $phpbb_container->get('path_helper');
+ /* @var $phpbb_filesystem \phpbb\filesystem\filesystem_interface */
+ $phpbb_filesystem = $phpbb_container->get('filesystem');
-// load extensions
-/* @var $phpbb_extension_manager \phpbb\extension\manager */
-$phpbb_extension_manager = $phpbb_container->get('ext.manager');
+ /* @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');
+}
-/* @var $template \phpbb\template\template */
-$template = $phpbb_container->get('template');
+register_compatibility_globals();
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index 126cf44842..bd73201290 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -171,11 +171,11 @@ define('CONFIRM_REPORT', 4);
// Categories - Attachments
define('ATTACHMENT_CATEGORY_NONE', 0);
define('ATTACHMENT_CATEGORY_IMAGE', 1); // Inline Images
-define('ATTACHMENT_CATEGORY_WM', 2); // Windows Media Files - Streaming
-define('ATTACHMENT_CATEGORY_RM', 3); // Real Media Files - Streaming
+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_THUMB', 4); // Not used within the database, only while displaying posts
define('ATTACHMENT_CATEGORY_FLASH', 5); // Flash/SWF files
-define('ATTACHMENT_CATEGORY_QUICKTIME', 6); // Quicktime/Mov files
+define('ATTACHMENT_CATEGORY_QUICKTIME', 6); // Quicktime/Mov files - @deprecated 3.2
// BBCode UID length
define('BBCODE_UID_LEN', 8);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 2514dd48d5..b7a5bee3c4 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -311,448 +311,6 @@ function phpbb_version_compare($version1, $version2, $operator = null)
}
}
-/**
-* 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
-*/
-function phpbb_chmod($filename, $perms = CHMOD_READ)
-{
- static $_chmod_info;
-
- // Return if the file no longer exists.
- if (!file_exists($filename))
- {
- return false;
- }
-
- // Determine some common vars
- if (empty($_chmod_info))
- {
- if (!function_exists('fileowner') || !function_exists('filegroup'))
- {
- // No need to further determine owner/group - it is unknown
- $_chmod_info['process'] = false;
- }
- else
- {
- global $phpbb_root_path, $phpEx;
-
- // Determine owner/group of common.php file and the filename we want to change here
- $common_php_owner = @fileowner($phpbb_root_path . 'common.' . $phpEx);
- $common_php_group = @filegroup($phpbb_root_path . 'common.' . $phpEx);
-
- // And the owner and the groups PHP is running under.
- $php_uid = (function_exists('posix_getuid')) ? @posix_getuid() : false;
- $php_gids = (function_exists('posix_getgroups')) ? @posix_getgroups() : false;
-
- // If we are unable to get owner/group, then do not try to set them by guessing
- if (!$php_uid || empty($php_gids) || !$common_php_owner || !$common_php_group)
- {
- $_chmod_info['process'] = false;
- }
- else
- {
- $_chmod_info = array(
- 'process' => true,
- 'common_owner' => $common_php_owner,
- 'common_group' => $common_php_group,
- 'php_uid' => $php_uid,
- 'php_gids' => $php_gids,
- );
- }
- }
- }
-
- if ($_chmod_info['process'])
- {
- $file_uid = @fileowner($filename);
- $file_gid = @filegroup($filename);
-
- // Change owner
- if (@chown($filename, $_chmod_info['common_owner']))
- {
- clearstatcache();
- $file_uid = @fileowner($filename);
- }
-
- // Change group
- if (@chgrp($filename, $_chmod_info['common_group']))
- {
- clearstatcache();
- $file_gid = @filegroup($filename);
- }
-
- // If the file_uid/gid now match the one from common.php we can process further, else we are not able to change something
- if ($file_uid != $_chmod_info['common_owner'] || $file_gid != $_chmod_info['common_group'])
- {
- $_chmod_info['process'] = false;
- }
- }
-
- // Still able to process?
- if ($_chmod_info['process'])
- {
- if ($file_uid == $_chmod_info['php_uid'])
- {
- $php = 'owner';
- }
- else if (in_array($file_gid, $_chmod_info['php_gids']))
- {
- $php = 'group';
- }
- else
- {
- // Since we are setting the everyone bit anyway, no need to do expensive operations
- $_chmod_info['process'] = false;
- }
- }
-
- // We are not able to determine or change something
- if (!$_chmod_info['process'])
- {
- $php = 'other';
- }
-
- // Owner always has read/write permission
- $owner = CHMOD_READ | CHMOD_WRITE;
- if (is_dir($filename))
- {
- $owner |= CHMOD_EXECUTE;
-
- // Only add execute bit to the permission if the dir needs to be readable
- if ($perms & CHMOD_READ)
- {
- $perms |= CHMOD_EXECUTE;
- }
- }
-
- switch ($php)
- {
- case 'owner':
- $result = @chmod($filename, ($owner << 6) + (0 << 3) + (0 << 0));
-
- clearstatcache();
-
- if (is_readable($filename) && phpbb_is_writable($filename))
- {
- break;
- }
-
- case 'group':
- $result = @chmod($filename, ($owner << 6) + ($perms << 3) + (0 << 0));
-
- clearstatcache();
-
- if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || phpbb_is_writable($filename)))
- {
- break;
- }
-
- case 'other':
- $result = @chmod($filename, ($owner << 6) + ($perms << 3) + ($perms << 0));
-
- clearstatcache();
-
- if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || phpbb_is_writable($filename)))
- {
- break;
- }
-
- default:
- return false;
- break;
- }
-
- return $result;
-}
-
-/**
-* 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.
-*/
-function phpbb_is_writable($file)
-{
- if (strtolower(substr(PHP_OS, 0, 3)) === 'win' || !function_exists('is_writable'))
- {
- if (file_exists($file))
- {
- // Canonicalise path to absolute path
- $file = phpbb_realpath($file);
-
- if (is_dir($file))
- {
- // Test directory by creating a file inside the directory
- $result = @tempnam($file, 'i_w');
-
- if (is_string($result) && file_exists($result))
- {
- unlink($result);
-
- // Ensure the file is actually in the directory (returned realpathed)
- return (strpos($result, $file) === 0) ? true : false;
- }
- }
- else
- {
- $handle = @fopen($file, 'r+');
-
- if (is_resource($handle))
- {
- fclose($handle);
- return true;
- }
- }
- }
- else
- {
- // file does not exist test if we can write to the directory
- $dir = dirname($file);
-
- if (file_exists($dir) && is_dir($dir) && phpbb_is_writable($dir))
- {
- return true;
- }
- }
-
- return false;
- }
- else
- {
- return is_writable($file);
- }
-}
-
-/**
-* Checks if a path ($path) is absolute or relative
-*
-* @param string $path Path to check absoluteness of
-* @return boolean
-*/
-function phpbb_is_absolute($path)
-{
- return (isset($path[0]) && $path[0] == '/' || preg_match('#^[a-z]:[/\\\]#i', $path)) ? true : false;
-}
-
-/**
-* @author Chris Smith <chris@project-minerva.org>
-* @copyright 2006 Project Minerva Team
-* @param string $path The path which we should attempt to resolve.
-* @return mixed
-*/
-function phpbb_own_realpath($path)
-{
- global $request;
-
- // Now to perform funky shizzle
-
- // Switch to use UNIX slashes
- $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
- $path_prefix = '';
-
- // Determine what sort of path we have
- if (phpbb_is_absolute($path))
- {
- $absolute = true;
-
- if ($path[0] == '/')
- {
- // Absolute path, *NIX style
- $path_prefix = '';
- }
- else
- {
- // Absolute path, Windows style
- // Remove the drive letter and colon
- $path_prefix = $path[0] . ':';
- $path = substr($path, 2);
- }
- }
- else
- {
- // Relative Path
- // Prepend the current working directory
- if (function_exists('getcwd'))
- {
- // This is the best method, hopefully it is enabled!
- $path = str_replace(DIRECTORY_SEPARATOR, '/', getcwd()) . '/' . $path;
- $absolute = true;
- if (preg_match('#^[a-z]:#i', $path))
- {
- $path_prefix = $path[0] . ':';
- $path = substr($path, 2);
- }
- else
- {
- $path_prefix = '';
- }
- }
- else if ($request->server('SCRIPT_FILENAME'))
- {
- // Warning: If chdir() has been used this will lie!
- // Warning: This has some problems sometime (CLI can create them easily)
- $filename = htmlspecialchars_decode($request->server('SCRIPT_FILENAME'));
- $path = str_replace(DIRECTORY_SEPARATOR, '/', dirname($filename)) . '/' . $path;
- $absolute = true;
- $path_prefix = '';
- }
- else
- {
- // We have no way of getting the absolute path, just run on using relative ones.
- $absolute = false;
- $path_prefix = '.';
- }
- }
-
- // Remove any repeated slashes
- $path = preg_replace('#/{2,}#', '/', $path);
-
- // Remove the slashes from the start and end of the path
- $path = trim($path, '/');
-
- // Break the string into little bits for us to nibble on
- $bits = explode('/', $path);
-
- // Remove any . in the path, renumber array for the loop below
- $bits = array_values(array_diff($bits, array('.')));
-
- // Lets get looping, run over and resolve any .. (up directory)
- for ($i = 0, $max = sizeof($bits); $i < $max; $i++)
- {
- // @todo Optimise
- if ($bits[$i] == '..' )
- {
- if (isset($bits[$i - 1]))
- {
- if ($bits[$i - 1] != '..')
- {
- // We found a .. and we are able to traverse upwards, lets do it!
- unset($bits[$i]);
- unset($bits[$i - 1]);
- $i -= 2;
- $max -= 2;
- $bits = array_values($bits);
- }
- }
- else if ($absolute) // ie. !isset($bits[$i - 1]) && $absolute
- {
- // We have an absolute path trying to descend above the root of the filesystem
- // ... Error!
- return false;
- }
- }
- }
-
- // Prepend the path prefix
- array_unshift($bits, $path_prefix);
-
- $resolved = '';
-
- $max = sizeof($bits) - 1;
-
- // Check if we are able to resolve symlinks, Windows (prior to Vista and Server 2008) cannot.
- $symlink_resolve = (function_exists('readlink')) ? true : false;
-
- foreach ($bits as $i => $bit)
- {
- if (@is_dir("$resolved/$bit") || ($i == $max && @is_file("$resolved/$bit")))
- {
- // Path Exists
- if ($symlink_resolve && is_link("$resolved/$bit") && ($link = readlink("$resolved/$bit")))
- {
- // Resolved a symlink.
- $resolved = $link . (($i == $max) ? '' : '/');
- continue;
- }
- }
- else
- {
- // Something doesn't exist here!
- // This is correct realpath() behaviour but sadly open_basedir and safe_mode make this problematic
- // return false;
- }
- $resolved .= $bit . (($i == $max) ? '' : '/');
- }
-
- // @todo If the file exists fine and open_basedir only has one path we should be able to prepend it
- // because we must be inside that basedir, the question is where...
- // @internal The slash in is_dir() gets around an open_basedir restriction
- if (!@file_exists($resolved) || (!@is_dir($resolved . '/') && !is_file($resolved)))
- {
- return false;
- }
-
- // Put the slashes back to the native operating systems slashes
- $resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved);
-
- // Check for DIRECTORY_SEPARATOR at the end (and remove it!)
- if (substr($resolved, -1) == DIRECTORY_SEPARATOR)
- {
- return substr($resolved, 0, -1);
- }
-
- return $resolved; // We got here, in the end!
-}
-
-if (!function_exists('realpath'))
-{
- /**
- * A wrapper for realpath
- * @ignore
- */
- function phpbb_realpath($path)
- {
- return phpbb_own_realpath($path);
- }
-}
-else
-{
- /**
- * A wrapper for realpath
- */
- function phpbb_realpath($path)
- {
- $realpath = realpath($path);
-
- // Strangely there are provider not disabling realpath but returning strange values. :o
- // We at least try to cope with them.
- if ($realpath === $path || $realpath === false)
- {
- return phpbb_own_realpath($path);
- }
-
- // Check for DIRECTORY_SEPARATOR at the end (and remove it!)
- if (substr($realpath, -1) == DIRECTORY_SEPARATOR)
- {
- $realpath = substr($realpath, 0, -1);
- }
-
- return $realpath;
- }
-}
-
// functions used for building option fields
/**
@@ -1029,7 +587,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
/**
* This event is used for performing actions directly before marking forums,
* topics or posts as read.
- *
+ *
* It is also possible to prevent the marking. For that, the $should_markread parameter
* should be set to FALSE.
*
@@ -1066,7 +624,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
$phpbb_notifications = $phpbb_container->get('notification_manager');
// Mark all topic notifications read for this user
- $phpbb_notifications->mark_notifications_read(array(
+ $phpbb_notifications->mark_notifications(array(
'notification.type.topic',
'notification.type.quote',
'notification.type.bookmark',
@@ -1128,11 +686,15 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
{
$forum_id = array($forum_id);
}
+ else
+ {
+ $forum_id = array_unique($forum_id);
+ }
/* @var $phpbb_notifications \phpbb\notification\manager */
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->mark_notifications_read_by_parent(array(
+ $phpbb_notifications->mark_notifications_by_parent(array(
'notification.type.topic',
'notification.type.approve_topic',
), $forum_id, $user->data['user_id'], $post_time);
@@ -1149,7 +711,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
}
$db->sql_freeresult($result);
- $phpbb_notifications->mark_notifications_read_by_parent(array(
+ $phpbb_notifications->mark_notifications_by_parent(array(
'notification.type.quote',
'notification.type.bookmark',
'notification.type.post',
@@ -1256,12 +818,12 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
$phpbb_notifications = $phpbb_container->get('notification_manager');
// Mark post notifications read for this user in this topic
- $phpbb_notifications->mark_notifications_read(array(
+ $phpbb_notifications->mark_notifications(array(
'notification.type.topic',
'notification.type.approve_topic',
), $topic_id, $user->data['user_id'], $post_time);
- $phpbb_notifications->mark_notifications_read_by_parent(array(
+ $phpbb_notifications->mark_notifications_by_parent(array(
'notification.type.quote',
'notification.type.bookmark',
'notification.type.post',
@@ -2161,7 +1723,7 @@ function redirect($url, $return = false, $disable_cd_check = false)
$failover_flag = false;
- if (empty($user->lang))
+ if (!$user->is_setup())
{
$user->add_lang('common');
}
@@ -2182,7 +1744,7 @@ function redirect($url, $return = false, $disable_cd_check = false)
// Attention: only able to redirect within the same domain if $disable_cd_check is false (yourdomain.com -> www.yourdomain.com will not work)
if (!$disable_cd_check && $url_parts['host'] !== $user->host)
{
- $url = generate_board_url();
+ trigger_error('INSECURE_REDIRECT', E_USER_ERROR);
}
}
else if ($url[0] == '/')
@@ -2220,7 +1782,7 @@ function redirect($url, $return = false, $disable_cd_check = false)
// Clean URL and check if we go outside the forum directory
$url = $phpbb_path_helper->clean_url($url);
- if (!$disable_cd_check && strpos($url, generate_board_url(true)) === false)
+ if (!$disable_cd_check && strpos($url, generate_board_url(true) . '/') !== 0)
{
trigger_error('INSECURE_REDIRECT', E_USER_ERROR);
}
@@ -2262,7 +1824,7 @@ function redirect($url, $return = false, $disable_cd_check = false)
}
// Redirect via an HTML form for PITA webservers
- if (@preg_match('#Microsoft|WebSTAR|Xitami#', getenv('SERVER_SOFTWARE')))
+ if (@preg_match('#WebSTAR|Xitami#', getenv('SERVER_SOFTWARE')))
{
header('Refresh: 0; URL=' . $url);
@@ -2417,13 +1979,19 @@ function phpbb_request_http_version()
{
global $request;
+ $version = '';
if ($request && $request->server('SERVER_PROTOCOL'))
{
- return $request->server('SERVER_PROTOCOL');
+ $version = $request->server('SERVER_PROTOCOL');
}
else if (isset($_SERVER['SERVER_PROTOCOL']))
{
- return $_SERVER['SERVER_PROTOCOL'];
+ $version = $_SERVER['SERVER_PROTOCOL'];
+ }
+
+ if (!empty($version) && is_string($version) && preg_match('#^HTTP/[0-9]\.[0-9]$#', $version))
+ {
+ return $version;
}
return 'HTTP/1.0';
@@ -2679,7 +2247,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
$err = '';
// Make sure user->setup() has been called
- if (empty($user->lang))
+ if (!$user->is_setup())
{
$user->setup();
}
@@ -2793,19 +2361,6 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
// Special cases... determine
switch ($result['status'])
{
- case LOGIN_ERROR_ATTEMPTS:
-
- $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
- $captcha->init(CONFIRM_LOGIN);
- // $captcha->reset();
-
- $template->assign_vars(array(
- 'CAPTCHA_TEMPLATE' => $captcha->get_template(),
- ));
-
- $err = $user->lang[$result['error_msg']];
- break;
-
case LOGIN_ERROR_PASSWORD_CONVERT:
$err = sprintf(
$user->lang[$result['error_msg']],
@@ -2816,6 +2371,17 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
);
break;
+ case LOGIN_ERROR_ATTEMPTS:
+
+ $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
+ $captcha->init(CONFIRM_LOGIN);
+ // $captcha->reset();
+
+ $template->assign_vars(array(
+ 'CAPTCHA_TEMPLATE' => $captcha->get_template(),
+ ));
+ // no break;
+
// Username, password, etc...
default:
$err = $user->lang[$result['error_msg']];
@@ -3183,7 +2749,7 @@ function get_preg_expression($mode)
return array(
'#<!\-\- e \-\-><a href="mailto:(.*?)">.*?</a><!\-\- e \-\->#',
'#<!\-\- l \-\-><a (?:class="[\w-]+" )?href="(.*?)(?:(&amp;|\?)sid=[0-9a-f]{32})?">.*?</a><!\-\- l \-\->#',
- '#<!\-\- ([mw]) \-\-><a (?:class="[\w-]+" )?href="(.*?)">.*?</a><!\-\- \1 \-\->#',
+ '#<!\-\- ([mw]) \-\-><a (?:class="[\w-]+" )?href="(.*?)">(.*?)</a><!\-\- \1 \-\->#',
'#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/.*? \/><!\-\- s\1 \-\->#',
'#<!\-\- .*? \-\->#s',
'#<.*?>#s',
@@ -3249,31 +2815,19 @@ function get_preg_expression($mode)
* Depends on whether installed PHP version supports unicode properties
*
* @param string $word word template to be replaced
-* @param bool $use_unicode whether or not to take advantage of PCRE supporting unicode
*
* @return string $preg_expr regex to use with word censor
*/
-function get_censor_preg_expression($word, $use_unicode = true)
+function get_censor_preg_expression($word)
{
// Unescape the asterisk to simplify further conversions
$word = str_replace('\*', '*', preg_quote($word, '#'));
- if ($use_unicode && phpbb_pcre_utf8_support())
- {
- // Replace asterisk(s) inside the pattern, at the start and at the end of it with regexes
- $word = preg_replace(array('#(?<=[\p{Nd}\p{L}_])\*+(?=[\p{Nd}\p{L}_])#iu', '#^\*+#', '#\*+$#'), array('([\x20]*?|[\p{Nd}\p{L}_-]*?)', '[\p{Nd}\p{L}_-]*?', '[\p{Nd}\p{L}_-]*?'), $word);
-
- // Generate the final substitution
- $preg_expr = '#(?<![\p{Nd}\p{L}_-])(' . $word . ')(?![\p{Nd}\p{L}_-])#iu';
- }
- else
- {
- // Replace the asterisk inside the pattern, at the start and at the end of it with regexes
- $word = preg_replace(array('#(?<=\S)\*+(?=\S)#iu', '#^\*+#', '#\*+$#'), array('(\x20*?\S*?)', '\S*?', '\S*?'), $word);
+ // Replace asterisk(s) inside the pattern, at the start and at the end of it with regexes
+ $word = preg_replace(array('#(?<=[\p{Nd}\p{L}_])\*+(?=[\p{Nd}\p{L}_])#iu', '#^\*+#', '#\*+$#'), array('([\x20]*?|[\p{Nd}\p{L}_-]*?)', '[\p{Nd}\p{L}_-]*?', '[\p{Nd}\p{L}_-]*?'), $word);
- // Generate the final substitution
- $preg_expr = '#(?<!\S)(' . $word . ')(?!\S)#iu';
- }
+ // Generate the final substitution
+ $preg_expr = '#(?<![\p{Nd}\p{L}_-])(' . $word . ')(?![\p{Nd}\p{L}_-])#iu';
return $preg_expr;
}
@@ -3706,7 +3260,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
case E_USER_ERROR:
- if (!empty($user) && !empty($user->lang))
+ if (!empty($user) && $user->is_setup())
{
$msg_text = (!empty($user->lang[$msg_text])) ? $user->lang[$msg_text] : $msg_text;
$msg_title = (!isset($msg_title)) ? $user->lang['GENERAL_ERROR'] : ((!empty($user->lang[$msg_title])) ? $user->lang[$msg_title] : $msg_title);
@@ -3826,7 +3380,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
// We re-init the auth array to get correct results on login/logout
$auth->acl($user->data);
- if (empty($user->lang))
+ if (!$user->is_setup())
{
$user->setup();
}
@@ -3915,11 +3469,21 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
*/
function phpbb_filter_root_path($errfile)
{
+ global $phpbb_filesystem;
+
static $root_path;
if (empty($root_path))
{
- $root_path = phpbb_realpath(dirname(__FILE__) . '/../');
+ if ($phpbb_filesystem)
+ {
+ $root_path = $phpbb_filesystem->realpath(dirname(__FILE__) . '/../');
+ }
+ else
+ {
+ $filesystem = new \phpbb\filesystem\filesystem();
+ $root_path = $filesystem->realpath(dirname(__FILE__) . '/../');
+ }
}
return str_replace(array($root_path, '\\'), array('[ROOT]', '/'), $errfile);
@@ -4054,10 +3618,14 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum'
if (sizeof($online_users['online_users']))
{
- $sql = 'SELECT username, username_clean, user_id, user_type, user_allow_viewonline, user_colour
- FROM ' . USERS_TABLE . '
- WHERE ' . $db->sql_in_set('user_id', $online_users['online_users']) . '
- ORDER BY username_clean ASC';
+ $sql_ary = array(
+ 'SELECT' => 'u.username, u.username_clean, u.user_id, u.user_type, u.user_allow_viewonline, u.user_colour',
+ 'FROM' => array(
+ USERS_TABLE => 'u',
+ ),
+ 'WHERE' => $db->sql_in_set('u.user_id', $online_users['online_users']),
+ 'ORDER BY' => 'u.username_clean ASC',
+ );
/**
* Modify SQL query to obtain online users data
@@ -4069,13 +3637,14 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum'
* @var string item Restrict online users to a certain
* session item, e.g. forum for
* session_forum_id
- * @var string sql SQL query to obtain users online data
+ * @var string sql_ary SQL query to obtain users online data
* @since 3.1.4-RC1
+ * @changed 3.1.7-RC1 Change sql query into array and adjust var accordingly. Allows extension authors the ability to adjust the sql_ary.
*/
- $vars = array('online_users', 'item_id', 'item', 'sql');
+ $vars = array('online_users', 'item_id', 'item', 'sql_ary');
extract($phpbb_dispatcher->trigger_event('core.obtain_users_online_string_sql', compact($vars)));
- $result = $db->sql_query($sql);
+ $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary));
$rowset = $db->sql_fetchrowset($result);
$db->sql_freeresult($result);
@@ -4089,7 +3658,7 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum'
$row['username'] = '<em>' . $row['username'] . '</em>';
}
- if (!isset($online_users['hidden_users'][$row['user_id']]) || $auth->acl_get('u_viewonline'))
+ if (!isset($online_users['hidden_users'][$row['user_id']]) || $auth->acl_get('u_viewonline') || $row['user_id'] === $user->data['user_id'])
{
$user_online_link[$row['user_id']] = get_username_string(($row['user_type'] <> USER_IGNORE) ? 'full' : 'no_profile', $row['user_id'], $row['username'], $row['user_colour']);
}
@@ -4198,178 +3767,6 @@ function phpbb_optionset($bit, $set, $data)
}
/**
-* 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 http://wiki.phpbb.com/Plural_Rules#Plural_Rules
-* @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
-*/
-function phpbb_get_plural_form($rule, $number)
-{
- $number = (int) $number;
-
- if ($rule > 15 || $rule < 0)
- {
- trigger_error('INVALID_PLURAL_RULE');
- }
-
- /**
- * The following plural rules are based on a list published by the Mozilla Developer Network
- * https://developer.mozilla.org/en/Localization_and_Plurals
- */
- switch ($rule)
- {
- case 0:
- /**
- * Families: Asian (Chinese, Japanese, Korean, Vietnamese), Persian, Turkic/Altaic (Turkish), Thai, Lao
- * 1 - everything: 0, 1, 2, ...
- */
- return 1;
-
- case 1:
- /**
- * Families: Germanic (Danish, Dutch, English, Faroese, Frisian, German, Norwegian, Swedish), Finno-Ugric (Estonian, Finnish, Hungarian), Language isolate (Basque), Latin/Greek (Greek), Semitic (Hebrew), Romanic (Italian, Portuguese, Spanish, Catalan)
- * 1 - 1
- * 2 - everything else: 0, 2, 3, ...
- */
- return ($number == 1) ? 1 : 2;
-
- case 2:
- /**
- * Families: Romanic (French, Brazilian Portuguese)
- * 1 - 0, 1
- * 2 - everything else: 2, 3, ...
- */
- return (($number == 0) || ($number == 1)) ? 1 : 2;
-
- case 3:
- /**
- * Families: Baltic (Latvian)
- * 1 - 0
- * 2 - ends in 1, not 11: 1, 21, ... 101, 121, ...
- * 3 - everything else: 2, 3, ... 10, 11, 12, ... 20, 22, ...
- */
- return ($number == 0) ? 1 : ((($number % 10 == 1) && ($number % 100 != 11)) ? 2 : 3);
-
- case 4:
- /**
- * Families: Celtic (Scottish Gaelic)
- * 1 - is 1 or 11: 1, 11
- * 2 - is 2 or 12: 2, 12
- * 3 - others between 3 and 19: 3, 4, ... 10, 13, ... 18, 19
- * 4 - everything else: 0, 20, 21, ...
- */
- return ($number == 1 || $number == 11) ? 1 : (($number == 2 || $number == 12) ? 2 : (($number >= 3 && $number <= 19) ? 3 : 4));
-
- case 5:
- /**
- * Families: Romanic (Romanian)
- * 1 - 1
- * 2 - is 0 or ends in 01-19: 0, 2, 3, ... 19, 101, 102, ... 119, 201, ...
- * 3 - everything else: 20, 21, ...
- */
- return ($number == 1) ? 1 : ((($number == 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 2 : 3);
-
- case 6:
- /**
- * Families: Baltic (Lithuanian)
- * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, ...
- * 2 - ends in 0 or ends in 10-20: 0, 10, 11, 12, ... 19, 20, 30, 40, ...
- * 3 - everything else: 2, 3, ... 8, 9, 22, 23, ... 29, 32, 33, ...
- */
- return (($number % 10 == 1) && ($number % 100 != 11)) ? 1 : ((($number % 10 < 2) || (($number % 100 >= 10) && ($number % 100 < 20))) ? 2 : 3);
-
- case 7:
- /**
- * Families: Slavic (Croatian, Serbian, Russian, Ukrainian)
- * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, ...
- * 2 - ends in 2-4, not 12-14: 2, 3, 4, 22, 23, 24, 32, ...
- * 3 - everything else: 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 26, ...
- */
- return (($number % 10 == 1) && ($number % 100 != 11)) ? 1 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 2 : 3);
-
- case 8:
- /**
- * Families: Slavic (Slovak, Czech)
- * 1 - 1
- * 2 - 2, 3, 4
- * 3 - everything else: 0, 5, 6, 7, ...
- */
- return ($number == 1) ? 1 : ((($number >= 2) && ($number <= 4)) ? 2 : 3);
-
- case 9:
- /**
- * Families: Slavic (Polish)
- * 1 - 1
- * 2 - ends in 2-4, not 12-14: 2, 3, 4, 22, 23, 24, 32, ... 104, 122, ...
- * 3 - everything else: 0, 5, 6, ... 11, 12, 13, 14, 15, ... 20, 21, 25, ...
- */
- return ($number == 1) ? 1 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 2 : 3);
-
- case 10:
- /**
- * Families: Slavic (Slovenian, Sorbian)
- * 1 - ends in 01: 1, 101, 201, ...
- * 2 - ends in 02: 2, 102, 202, ...
- * 3 - ends in 03-04: 3, 4, 103, 104, 203, 204, ...
- * 4 - everything else: 0, 5, 6, 7, 8, 9, 10, 11, ...
- */
- return ($number % 100 == 1) ? 1 : (($number % 100 == 2) ? 2 : ((($number % 100 == 3) || ($number % 100 == 4)) ? 3 : 4));
-
- case 11:
- /**
- * Families: Celtic (Irish Gaeilge)
- * 1 - 1
- * 2 - 2
- * 3 - is 3-6: 3, 4, 5, 6
- * 4 - is 7-10: 7, 8, 9, 10
- * 5 - everything else: 0, 11, 12, ...
- */
- return ($number == 1) ? 1 : (($number == 2) ? 2 : (($number >= 3 && $number <= 6) ? 3 : (($number >= 7 && $number <= 10) ? 4 : 5)));
-
- case 12:
- /**
- * Families: Semitic (Arabic)
- * 1 - 1
- * 2 - 2
- * 3 - ends in 03-10: 3, 4, ... 10, 103, 104, ... 110, 203, 204, ...
- * 4 - ends in 11-99: 11, ... 99, 111, 112, ...
- * 5 - everything else: 100, 101, 102, 200, 201, 202, ...
- * 6 - 0
- */
- return ($number == 1) ? 1 : (($number == 2) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : (($number != 0) ? 5 : 6))));
-
- case 13:
- /**
- * Families: Semitic (Maltese)
- * 1 - 1
- * 2 - is 0 or ends in 01-10: 0, 2, 3, ... 9, 10, 101, 102, ...
- * 3 - ends in 11-19: 11, 12, ... 18, 19, 111, 112, ...
- * 4 - everything else: 20, 21, ...
- */
- return ($number == 1) ? 1 : ((($number == 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 2 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 3 : 4));
-
- case 14:
- /**
- * Families: Slavic (Macedonian)
- * 1 - ends in 1: 1, 11, 21, ...
- * 2 - ends in 2: 2, 12, 22, ...
- * 3 - everything else: 0, 3, 4, ... 10, 13, 14, ... 20, 23, ...
- */
- return ($number % 10 == 1) ? 1 : (($number % 10 == 2) ? 2 : 3);
-
- case 15:
- /**
- * Families: Icelandic
- * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, 131, ...
- * 2 - everything else: 0, 2, 3, ... 10, 11, 12, ... 20, 22, ...
- */
- return (($number % 10 == 1) && ($number % 100 != 11)) ? 1 : 2;
- }
-}
-
-/**
* Login using http authenticate.
*
* @param array $param Parameter array, see $param_defaults array.
@@ -4573,13 +3970,14 @@ function phpbb_build_hidden_fields_for_query_params($request, $exclude = null)
* @param array $user_row Row from the users table
* @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 html
*/
-function phpbb_get_user_avatar($user_row, $alt = 'USER_AVATAR', $ignore_config = false)
+function phpbb_get_user_avatar($user_row, $alt = 'USER_AVATAR', $ignore_config = false, $lazy = false)
{
$row = \phpbb\avatar\manager::clean_row($user_row, 'user');
- return phpbb_get_avatar($row, $alt, $ignore_config);
+ return phpbb_get_avatar($row, $alt, $ignore_config, $lazy);
}
/**
@@ -4588,13 +3986,14 @@ function phpbb_get_user_avatar($user_row, $alt = 'USER_AVATAR', $ignore_config =
* @param array $group_row Row from the groups table
* @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 html
*/
-function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config = false)
+function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config = false, $lazy = false)
{
$row = \phpbb\avatar\manager::clean_row($user_row, 'group');
- return phpbb_get_avatar($row, $alt, $ignore_config);
+ return phpbb_get_avatar($row, $alt, $ignore_config, $lazy);
}
/**
@@ -4603,14 +4002,15 @@ function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config
* @param array $row Row cleaned by \phpbb\avatar\manager::clean_row
* @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 html
*/
-function phpbb_get_avatar($row, $alt, $ignore_config = false)
+function phpbb_get_avatar($row, $alt, $ignore_config = false, $lazy = false)
{
global $user, $config, $cache, $phpbb_root_path, $phpEx;
global $request;
- global $phpbb_container;
+ global $phpbb_container, $phpbb_dispatcher;
if (!$config['allow_avatar'] && !$ignore_config)
{
@@ -4625,7 +4025,7 @@ function phpbb_get_avatar($row, $alt, $ignore_config = false)
/* @var $phpbb_avatar_manager \phpbb\avatar\manager */
$phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
- $driver = $phpbb_avatar_manager->get_driver($row['avatar_type'], $ignore_config);
+ $driver = $phpbb_avatar_manager->get_driver($row['avatar_type'], !$ignore_config);
$html = '';
if ($driver)
@@ -4636,7 +4036,7 @@ function phpbb_get_avatar($row, $alt, $ignore_config = false)
return $html;
}
- $avatar_data = $driver->get_data($row, $ignore_config);
+ $avatar_data = $driver->get_data($row);
}
else
{
@@ -4645,12 +4045,47 @@ function phpbb_get_avatar($row, $alt, $ignore_config = false)
if (!empty($avatar_data['src']))
{
- $html = '<img src="' . $avatar_data['src'] . '" ' .
+ if ($lazy)
+ {
+ // Determine board url - we may need it later
+ $board_url = generate_board_url() . '/';
+ // This path is sent with the base template paths in the assign_vars()
+ // call below. We need to correct it in case we are accessing from a
+ // controller because the web paths will be incorrect otherwise.
+ $phpbb_path_helper = $phpbb_container->get('path_helper');
+ $corrected_path = $phpbb_path_helper->get_web_root_path();
+
+ $web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $corrected_path;
+
+ $theme = "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme';
+
+ $src = 'src="' . $theme . '/images/no_avatar.gif" data-src="' . $avatar_data['src'] . '"';
+ }
+ else
+ {
+ $src = 'src="' . $avatar_data['src'] . '"';
+ }
+
+ $html = '<img class="avatar" ' . $src . ' ' .
($avatar_data['width'] ? ('width="' . $avatar_data['width'] . '" ') : '') .
($avatar_data['height'] ? ('height="' . $avatar_data['height'] . '" ') : '') .
'alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />';
}
+ /**
+ * Event to modify HTML <img> tag of avatar
+ *
+ * @event core.get_avatar_after
+ * @var array row Row cleaned by \phpbb\avatar\manager::clean_row
+ * @var string alt Optional language string for alt tag within image, can be a language key or text
+ * @var bool ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+ * @var array avatar_data The HTML attributes for avatar <img> tag
+ * @var string html The HTML <img> tag of generated avatar
+ * @since 3.1.6-RC1
+ */
+ $vars = array('row', 'alt', 'ignore_config', 'avatar_data', 'html');
+ extract($phpbb_dispatcher->trigger_event('core.get_avatar_after', compact($vars)));
+
return $html;
}
@@ -4846,12 +4281,12 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
// Output the notifications
$notifications = false;
- if ($config['load_notifications'] && $user->data['user_id'] != ANONYMOUS && $user->data['user_type'] != USER_IGNORE)
+ if ($config['load_notifications'] && $config['allow_board_notifications'] && $user->data['user_id'] != ANONYMOUS && $user->data['user_type'] != USER_IGNORE)
{
/* @var $phpbb_notifications \phpbb\notification\manager */
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $notifications = $phpbb_notifications->load_notifications(array(
+ $notifications = $phpbb_notifications->load_notifications('notification.method.board', array(
'all_unread' => true,
'limit' => 5,
));
@@ -4888,7 +4323,7 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'U_VIEW_ALL_NOTIFICATIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications'),
'U_MARK_ALL_NOTIFICATIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications&amp;mode=notification_list&amp;mark=all&amp;token=' . $notification_mark_hash),
'U_NOTIFICATION_SETTINGS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications&amp;mode=notification_options'),
- 'S_NOTIFICATIONS_DISPLAY' => $config['load_notifications'],
+ 'S_NOTIFICATIONS_DISPLAY' => $config['load_notifications'] && $config['allow_board_notifications'],
'S_USER_NEW_PRIVMSG' => $user->data['user_new_privmsg'],
'S_USER_UNREAD_PRIVMSG' => $user->data['user_unread_privmsg'],
@@ -4917,7 +4352,7 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'U_PROFILE' => append_sid("{$phpbb_root_path}ucp.$phpEx"),
'U_USER_PROFILE' => get_username_string('profile', $user->data['user_id'], $user->data['username'], $user->data['user_colour']),
'U_MODCP' => append_sid("{$phpbb_root_path}mcp.$phpEx", false, true, $user->session_id),
- 'U_FAQ' => $controller_helper->route('phpbb_help_controller', array('mode' => 'faq')),
+ 'U_FAQ' => $controller_helper->route('phpbb_help_faq_controller'),
'U_SEARCH_SELF' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=egosearch'),
'U_SEARCH_NEW' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=newposts'),
'U_SEARCH_UNANSWERED' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=unanswered'),
@@ -4929,7 +4364,7 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'U_TERMS_USE' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=terms'),
'U_PRIVACY' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=privacy'),
'U_RESTORE_PERMISSIONS' => ($user->data['user_perm_from'] && $auth->acl_get('a_switchperm')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=restore_perm') : '',
- 'U_FEED' => generate_board_url() . "/feed.$phpEx",
+ 'U_FEED' => $controller_helper->route('phpbb_feed_index'),
'S_USER_LOGGED_IN' => ($user->data['user_id'] != ANONYMOUS) ? true : false,
'S_AUTOLOGIN_ENABLED' => ($config['allow_autologin']) ? true : false,
@@ -4980,7 +4415,8 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'T_RANKS_PATH' => "{$web_path}{$config['ranks_path']}/",
'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/",
'T_STYLESHEET_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/stylesheet.css?assets_version=' . $config['assets_version'],
- 'T_STYLESHEET_LANG_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'],
+ 'T_STYLESHEET_LANG_LINK'=> "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'],
+ 'T_FONT_AWESOME_LINK' => !empty($config['allow_cdn']) && !empty($config['load_font_awesome_url']) ? $config['load_font_awesome_url'] : "{$web_path}assets/css/font-awesome.min.css?assets_version=" . $config['assets_version'],
'T_JQUERY_LINK' => !empty($config['allow_cdn']) && !empty($config['load_jquery_url']) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.min.js?assets_version=" . $config['assets_version'],
'S_ALLOW_CDN' => !empty($config['allow_cdn']),
@@ -5072,10 +4508,10 @@ function phpbb_generate_debug_output(\phpbb\db\driver\driver_interface $db, \php
if (isset($GLOBALS['starttime']))
{
$totaltime = microtime(true) - $GLOBALS['starttime'];
- $debug_info[] = sprintf('<abbr title="SQL time: %.3fs / PHP time: %.3fs">Time: %.3fs</abbr>', $db->get_sql_time(), ($totaltime - $db->get_sql_time()), $totaltime);
+ $debug_info[] = sprintf('<span title="SQL time: %.3fs / PHP time: %.3fs">Time: %.3fs</span>', $db->get_sql_time(), ($totaltime - $db->get_sql_time()), $totaltime);
}
- $debug_info[] = sprintf('<abbr title="Cached: %d">Queries: %d</abbr>', $db->sql_num_queries(true), $db->sql_num_queries());
+ $debug_info[] = sprintf('<span title="Cached: %d">Queries: %d</span>', $db->sql_num_queries(true), $db->sql_num_queries());
$memory_usage = memory_get_peak_usage();
if ($memory_usage)
@@ -5299,22 +4735,6 @@ function phpbb_user_session_handler()
}
/**
-* Check if PCRE has UTF-8 support
-* PHP may not be linked with the bundled PCRE lib and instead with an older version
-*
-* @return bool Returns true if PCRE (the regular expressions library) supports UTF-8 encoding
-*/
-function phpbb_pcre_utf8_support()
-{
- static $utf8_pcre_properties = null;
- if (is_null($utf8_pcre_properties))
- {
- $utf8_pcre_properties = (@preg_match('/\p{L}/u', 'a') !== false);
- }
- return $utf8_pcre_properties;
-}
-
-/**
* Casts a numeric string $input to an appropriate numeric type (i.e. integer or float)
*
* @param string $input A numeric string.
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php
index e30c6da505..390b59b9e9 100644
--- a/phpBB/includes/functions_acp.php
+++ b/phpBB/includes/functions_acp.php
@@ -245,8 +245,13 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars)
switch ($tpl_type[0])
{
- case 'text':
case 'password':
+ if ($new[$config_key] !== '')
+ {
+ // replace passwords with asterixes
+ $new[$config_key] = '********';
+ }
+ case 'text':
case 'url':
case 'email':
case 'color':
@@ -378,6 +383,7 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars)
$tpl .= $vars['append'];
}
+ $new_ary = $new;
/**
* Overwrite the html code we display for the config value
*
@@ -387,14 +393,17 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars)
* 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 array new_ary 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
+ * @change 3.2.0-a1 Replaced new with new_ary
*/
- $vars = array('tpl_type', 'key', 'new', 'name', 'vars', 'tpl');
+ $vars = array('tpl_type', 'key', 'new_ary', 'name', 'vars', 'tpl');
extract($phpbb_dispatcher->trigger_event('core.build_config_template', compact($vars)));
+ $new = $new_ary;
+ unset($new_ary);
return $tpl;
}
@@ -405,7 +414,7 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars)
*/
function validate_config_vars($config_vars, &$cfg_array, &$error)
{
- global $phpbb_root_path, $user, $phpbb_dispatcher;
+ global $phpbb_root_path, $user, $phpbb_dispatcher, $phpbb_filesystem;
$type = 0;
$min = 1;
@@ -550,6 +559,9 @@ function validate_config_vars($config_vars, &$cfg_array, &$error)
$cfg_array[$config_name] = trim($destination);
+ // Absolute file path
+ case 'absolute_path':
+ case 'absolute_path_writable':
// Path being relative (still prefixed by phpbb_root_path), but with the ability to escape the root dir...
case 'path':
case 'wpath':
@@ -568,20 +580,22 @@ function validate_config_vars($config_vars, &$cfg_array, &$error)
break;
}
- if (!file_exists($phpbb_root_path . $cfg_array[$config_name]))
+ $path = in_array($config_definition['validate'], array('wpath', 'path', 'rpath', 'rwpath')) ? $phpbb_root_path . $cfg_array[$config_name] : $cfg_array[$config_name];
+
+ if (!file_exists($path))
{
$error[] = sprintf($user->lang['DIRECTORY_DOES_NOT_EXIST'], $cfg_array[$config_name]);
}
- if (file_exists($phpbb_root_path . $cfg_array[$config_name]) && !is_dir($phpbb_root_path . $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 ($config_definition['validate'] == 'wpath' || $config_definition['validate'] == 'rwpath' || $config_definition['validate'] === 'absolute_path_writable')
{
- if (file_exists($phpbb_root_path . $cfg_array[$config_name]) && !phpbb_is_writable($phpbb_root_path . $cfg_array[$config_name]))
+ if (file_exists($path) && !$phpbb_filesystem->is_writable($path))
{
$error[] = sprintf($user->lang['DIRECTORY_NOT_WRITABLE'], $cfg_array[$config_name]);
}
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index fce4bf841b..bca451deb6 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -171,7 +171,10 @@ function size_select_options($size_compare)
*/
function group_select_options($group_id, $exclude_ids = false, $manage_founder = false)
{
- global $db, $user, $config;
+ global $db, $config, $phpbb_container;
+
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
$exclude_sql = ($exclude_ids !== false && sizeof($exclude_ids)) ? 'WHERE ' . $db->sql_in_set('group_id', array_map('intval', $exclude_ids), true) : '';
$sql_and = (!$config['coppa_enable']) ? (($exclude_sql) ? ' AND ' : ' WHERE ') . "group_name <> 'REGISTERED_COPPA'" : '';
@@ -189,7 +192,7 @@ function group_select_options($group_id, $exclude_ids = false, $manage_founder =
while ($row = $db->sql_fetchrow($result))
{
$selected = ($row['group_id'] == $group_id) ? ' selected="selected"' : '';
- $s_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '"' . $selected . '>' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>';
+ $s_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '"' . $selected . '>' . $group_helper->get_name($row['group_name']) . '</option>';
}
$db->sql_freeresult($result);
@@ -500,7 +503,7 @@ function filelist($rootdir, $dir = '', $type = 'gif|jpg|jpeg|png')
*/
function move_topics($topic_ids, $forum_id, $auto_sync = true)
{
- global $db;
+ global $db, $phpbb_dispatcher;
if (empty($topic_ids))
{
@@ -534,6 +537,27 @@ function move_topics($topic_ids, $forum_id, $auto_sync = true)
}
$table_ary = array(TOPICS_TABLE, POSTS_TABLE, LOG_TABLE, DRAFTS_TABLE, TOPICS_TRACK_TABLE);
+
+ /**
+ * Perform additional actions before topics move
+ *
+ * @event core.move_topics_before_query
+ * @var array table_ary Array of tables from which forum_id will be updated for all rows that hold the moved topics
+ * @var array topic_ids Array of the moved topic ids
+ * @var string forum_id The forum id from where the topics are moved
+ * @var array forum_ids Array of the forums where the topics are moving (includes also forum_id)
+ * @var bool auto_sync Whether or not to perform auto sync
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'table_ary',
+ 'topic_ids',
+ 'forum_id',
+ 'forum_ids',
+ 'auto_sync',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.move_topics_before_query', compact($vars)));
+
foreach ($table_ary as $table)
{
$sql = "UPDATE $table
@@ -555,7 +579,7 @@ function move_topics($topic_ids, $forum_id, $auto_sync = true)
*/
function move_posts($post_ids, $topic_id, $auto_sync = true)
{
- global $db;
+ global $db, $phpbb_dispatcher;
if (!is_array($post_ids))
{
@@ -589,6 +613,28 @@ function move_posts($post_ids, $topic_id, $auto_sync = true)
trigger_error('NO_TOPIC');
}
+ /**
+ * Perform additional actions before moving posts
+ *
+ * @event core.move_posts_before
+ * @var array post_ids Array of post ids to move
+ * @var string topic_id The topic id the posts are moved to
+ * @var bool auto_sync Whether or not to perform auto sync
+ * @var array forum_ids Array of the forum ids the posts are moved from
+ * @var array topic_ids Array of the topic ids the posts are moved from
+ * @var array forum_row Array with the forum id of the topic the posts are moved to
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'post_ids',
+ 'topic_id',
+ 'auto_sync',
+ 'forum_ids',
+ 'topic_ids',
+ 'forum_row',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.move_posts_before', compact($vars)));
+
$sql = 'UPDATE ' . POSTS_TABLE . '
SET forum_id = ' . (int) $forum_row['forum_id'] . ", topic_id = $topic_id
WHERE " . $db->sql_in_set('post_id', $post_ids);
@@ -599,6 +645,28 @@ function move_posts($post_ids, $topic_id, $auto_sync = true)
WHERE " . $db->sql_in_set('post_msg_id', $post_ids);
$db->sql_query($sql);
+ /**
+ * Perform additional actions after moving posts
+ *
+ * @event core.move_posts_after
+ * @var array post_ids Array of the moved post ids
+ * @var string topic_id The topic id the posts are moved to
+ * @var bool auto_sync Whether or not to perform auto sync
+ * @var array forum_ids Array of the forum ids the posts are moved from
+ * @var array topic_ids Array of the topic ids the posts are moved from
+ * @var array forum_row Array with the forum id of the topic the posts are moved to
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'post_ids',
+ 'topic_id',
+ 'auto_sync',
+ 'forum_ids',
+ 'topic_ids',
+ 'forum_row',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.move_posts_after', compact($vars)));
+
if ($auto_sync)
{
$forum_ids[] = (int) $forum_row['forum_id'];
@@ -866,6 +934,32 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
$table_ary = array(POSTS_TABLE, REPORTS_TABLE);
+ /**
+ * Perform additional actions during post(s) deletion before running the queries
+ *
+ * @event core.delete_posts_in_transaction_before
+ * @var array post_ids Array with deleted posts' ids
+ * @var array poster_ids Array with deleted posts' author ids
+ * @var array topic_ids Array with deleted posts' topic ids
+ * @var array forum_ids Array with deleted posts' forum ids
+ * @var string where_type Variable containing posts deletion mode
+ * @var mixed where_ids Array or comma separated list of post ids to delete
+ * @var array delete_notifications_types Array with notifications types to delete
+ * @var array table_ary Array with table names to delete data from
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'post_ids',
+ 'poster_ids',
+ 'topic_ids',
+ 'forum_ids',
+ 'where_type',
+ 'where_ids',
+ 'delete_notifications_types',
+ 'table_ary',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.delete_posts_in_transaction_before', compact($vars)));
+
foreach ($table_ary as $table)
{
$sql = "DELETE FROM $table
@@ -921,7 +1015,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
}
$error = false;
- $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
if ($error)
{
@@ -930,7 +1024,10 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
$search->index_remove($post_ids, $poster_ids, $forum_ids);
- delete_attachments('post', $post_ids, false);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('post', $post_ids, false);
+ unset($attachment_manager);
/**
* Perform additional actions during post(s) deletion
@@ -1017,225 +1114,21 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
/**
* Delete Attachments
*
+* @deprecated 3.2.0-a1 (To be removed: 3.4.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 $db, $config;
-
- // 0 is as bad as an empty array
- if (empty($ids))
- {
- return false;
- }
-
- if (is_array($ids))
- {
- $ids = array_unique($ids);
- $ids = array_map('intval', $ids);
- }
- else
- {
- $ids = array((int) $ids);
- }
-
- $sql_where = '';
-
- switch ($mode)
- {
- case 'post':
- case 'message':
- $sql_id = 'post_msg_id';
- $sql_where = ' AND in_message = ' . ($mode == 'message' ? 1 : 0);
- break;
-
- case 'topic':
- $sql_id = 'topic_id';
- break;
-
- case 'user':
- $sql_id = 'poster_id';
- break;
-
- case 'attach':
- default:
- $sql_id = 'attach_id';
- $mode = 'attach';
- break;
- }
-
- $post_ids = $message_ids = $topic_ids = $physical = array();
-
- // Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled)
- $sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan
- FROM ' . ATTACHMENTS_TABLE . '
- WHERE ' . $db->sql_in_set($sql_id, $ids);
-
- $sql .= $sql_where;
-
- $result = $db->sql_query($sql);
-
- while ($row = $db->sql_fetchrow($result))
- {
- // We only need to store post/message/topic ids if resync is enabled and the file is not orphaned
- if ($resync && !$row['is_orphan'])
- {
- if (!$row['in_message'])
- {
- $post_ids[] = $row['post_msg_id'];
- $topic_ids[] = $row['topic_id'];
- }
- else
- {
- $message_ids[] = $row['post_msg_id'];
- }
- }
-
- $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize'], 'is_orphan' => $row['is_orphan']);
- }
- $db->sql_freeresult($result);
-
- // Delete attachments
- $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . '
- WHERE ' . $db->sql_in_set($sql_id, $ids);
-
- $sql .= $sql_where;
-
- $db->sql_query($sql);
- $num_deleted = $db->sql_affectedrows();
-
- if (!$num_deleted)
- {
- return 0;
- }
-
- // Delete attachments from filesystem
- $space_removed = $files_removed = 0;
- foreach ($physical as $file_ary)
- {
- if (phpbb_unlink($file_ary['filename'], 'file', true) && !$file_ary['is_orphan'])
- {
- // Only non-orphaned files count to the file size
- $space_removed += $file_ary['filesize'];
- $files_removed++;
- }
-
- if ($file_ary['thumbnail'])
- {
- phpbb_unlink($file_ary['filename'], 'thumbnail', true);
- }
- }
+ global $phpbb_container;
- if ($space_removed || $files_removed)
- {
- $config->increment('upload_dir_size', $space_removed * (-1), false);
- $config->increment('num_files', $files_removed * (-1), false);
- }
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $num_deleted = $attachment_manager->delete($mode, $ids, $resync);
- // If we do not resync, we do not need to adjust any message, post, topic or user entries
- if (!$resync)
- {
- return $num_deleted;
- }
-
- // No more use for the original ids
- unset($ids);
-
- // Now, we need to resync posts, messages, topics. We go through every one of them
- $post_ids = array_unique($post_ids);
- $message_ids = array_unique($message_ids);
- $topic_ids = array_unique($topic_ids);
-
- // Update post indicators for posts now no longer having attachments
- if (sizeof($post_ids))
- {
- // Just check which posts are still having an assigned attachment not orphaned by querying the attachments table
- $sql = 'SELECT post_msg_id
- FROM ' . ATTACHMENTS_TABLE . '
- WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . '
- AND in_message = 0
- AND is_orphan = 0';
- $result = $db->sql_query($sql);
-
- $remaining_ids = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $remaining_ids[] = $row['post_msg_id'];
- }
- $db->sql_freeresult($result);
-
- // Now only unset those ids remaining
- $post_ids = array_diff($post_ids, $remaining_ids);
-
- if (sizeof($post_ids))
- {
- $sql = 'UPDATE ' . POSTS_TABLE . '
- SET post_attachment = 0
- WHERE ' . $db->sql_in_set('post_id', $post_ids);
- $db->sql_query($sql);
- }
- }
-
- // Update message table if messages are affected
- if (sizeof($message_ids))
- {
- // Just check which messages are still having an assigned attachment not orphaned by querying the attachments table
- $sql = 'SELECT post_msg_id
- FROM ' . ATTACHMENTS_TABLE . '
- WHERE ' . $db->sql_in_set('post_msg_id', $message_ids) . '
- AND in_message = 1
- AND is_orphan = 0';
- $result = $db->sql_query($sql);
-
- $remaining_ids = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $remaining_ids[] = $row['post_msg_id'];
- }
- $db->sql_freeresult($result);
-
- // Now only unset those ids remaining
- $message_ids = array_diff($message_ids, $remaining_ids);
-
- if (sizeof($message_ids))
- {
- $sql = 'UPDATE ' . PRIVMSGS_TABLE . '
- SET message_attachment = 0
- WHERE ' . $db->sql_in_set('msg_id', $message_ids);
- $db->sql_query($sql);
- }
- }
-
- // Now update the topics. This is a bit trickier, because there could be posts still having attachments within the topic
- if (sizeof($topic_ids))
- {
- // Just check which topics are still having an assigned attachment not orphaned by querying the attachments table (much less entries expected)
- $sql = 'SELECT topic_id
- FROM ' . ATTACHMENTS_TABLE . '
- WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . '
- AND is_orphan = 0';
- $result = $db->sql_query($sql);
-
- $remaining_ids = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $remaining_ids[] = $row['topic_id'];
- }
- $db->sql_freeresult($result);
-
- // Now only unset those ids remaining
- $topic_ids = array_diff($topic_ids, $remaining_ids);
-
- if (sizeof($topic_ids))
- {
- $sql = 'UPDATE ' . TOPICS_TABLE . '
- SET topic_attachment = 0
- WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
- $db->sql_query($sql);
- }
- }
+ unset($attachment_manager);
return $num_deleted;
}
@@ -1353,27 +1246,19 @@ function update_posted_info(&$topic_ids)
/**
* Delete attached file
+*
+* @deprecated 3.2.0-a1 (To be removed: 3.4.0)
*/
function phpbb_unlink($filename, $mode = 'file', $entry_removed = false)
{
- global $db, $phpbb_root_path, $config;
-
- // Because of copying topics or modifications a physical filename could be assigned more than once. If so, do not remove the file itself.
- $sql = 'SELECT COUNT(attach_id) AS num_entries
- FROM ' . ATTACHMENTS_TABLE . "
- WHERE physical_filename = '" . $db->sql_escape(utf8_basename($filename)) . "'";
- $result = $db->sql_query($sql);
- $num_entries = (int) $db->sql_fetchfield('num_entries');
- $db->sql_freeresult($result);
+ global $phpbb_container;
- // Do not remove file if at least one additional entry with the same name exist.
- if (($entry_removed && $num_entries > 0) || (!$entry_removed && $num_entries > 1))
- {
- return false;
- }
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $unlink = $attachment_manager->unlink($filename, $mode, $entry_removed);
+ unset($attachment_manager);
- $filename = ($mode == 'thumbnail') ? 'thumb_' . utf8_basename($filename) : utf8_basename($filename);
- return @unlink($phpbb_root_path . $config['upload_path'] . '/' . $filename);
+ return $unlink;
}
/**
diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php
index 4707238951..4b085a6050 100644
--- a/phpBB/includes/functions_compatibility.php
+++ b/phpBB/includes/functions_compatibility.php
@@ -30,10 +30,11 @@ if (!defined('IN_PHPBB'))
* @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)
+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(
@@ -43,7 +44,7 @@ function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $
'avatar_height' => $avatar_height,
);
- return phpbb_get_avatar($row, $alt, $ignore_config);
+ return phpbb_get_avatar($row, $alt, $ignore_config, $lazy);
}
/**
@@ -117,7 +118,7 @@ function phpbb_clean_path($path)
new phpbb\symfony_request(
$request
),
- new phpbb\filesystem(),
+ new phpbb\filesystem\filesystem(),
$request,
$phpbb_root_path,
$phpEx
@@ -397,3 +398,116 @@ function get_tables(&$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 http://wiki.phpbb.com/Plural_Rules#Plural_Rules
+ * @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: 3.3.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;
+}
diff --git a/phpBB/includes/functions_compress.php b/phpBB/includes/functions_compress.php
index a7ee29dd91..e768a0f47b 100644
--- a/phpBB/includes/functions_compress.php
+++ b/phpBB/includes/functions_compress.php
@@ -184,7 +184,7 @@ class compress
}
/**
-* Zip creation class from phpMyAdmin 2.3.0 (c) Tobias Ratschiller, Olivier Müller, Loïc Chapeaux,
+* 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
@@ -204,11 +204,19 @@ class compress_zip extends compress
var $datasec_len = 0;
/**
+ * @var \phpbb\filesystem\filesystem_interface
+ */
+ protected $filesystem;
+
+ /**
* Constructor
*/
function compress_zip($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)
{
@@ -286,7 +294,15 @@ class compress_zip extends compress
{
trigger_error("Could not create directory $folder");
}
- phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
+
+ try
+ {
+ $this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
+ }
+ catch (\phpbb\filesystem\exception\filesystem_exception $e)
+ {
+ // Do nothing
+ }
}
}
}
@@ -315,7 +331,15 @@ class compress_zip extends compress
{
trigger_error("Could not create directory $folder");
}
- phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
+
+ try
+ {
+ $this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
+ }
+ catch (\phpbb\filesystem\exception\filesystem_exception $e)
+ {
+ // Do nothing
+ }
}
}
}
@@ -539,10 +563,17 @@ class compress_tar extends compress
var $wrote = false;
/**
+ * @var \phpbb\filesystem\filesystem_interface
+ */
+ protected $filesystem;
+
+ /**
* Constructor
*/
function compress_tar($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);
@@ -551,6 +582,8 @@ class compress_tar extends compress
$this->file = &$file;
$this->type = &$type;
$this->open();
+
+ $this->filesystem = ($phpbb_filesystem instanceof \phpbb\filesystem\filesystem_interface) ? $phpbb_filesystem : new \phpbb\filesystem\filesystem();
}
/**
@@ -601,7 +634,15 @@ class compress_tar extends compress
{
trigger_error("Could not create directory $folder");
}
- phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
+
+ try
+ {
+ $this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
+ }
+ catch (\phpbb\filesystem\exception\filesystem_exception $e)
+ {
+ // Do nothing
+ }
}
}
}
@@ -628,7 +669,15 @@ class compress_tar extends compress
{
trigger_error("Could not create directory $folder");
}
- phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
+
+ try
+ {
+ $this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
+ }
+ catch (\phpbb\filesystem\exception\filesystem_exception $e)
+ {
+ // Do nothing
+ }
}
}
@@ -637,7 +686,15 @@ class compress_tar extends compress
{
trigger_error("Couldn't create file $filename");
}
- phpbb_chmod($target_filename, CHMOD_READ);
+
+ 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);
diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php
index bdbc8a92fa..b87220caa5 100644
--- a/phpBB/includes/functions_content.php
+++ b/phpBB/includes/functions_content.php
@@ -389,46 +389,68 @@ function phpbb_clean_search_string($search_string)
/**
* Decode text whereby text is coming from the db and expected to be pre-parsed content
* We are placing this outside of the message parser because we are often in need of it...
+*
+* NOTE: special chars are kept encoded
+*
+* @param string &$message Original message, passed by reference
+* @param string $bbcode_uid BBCode UID
+* @return null
*/
function decode_message(&$message, $bbcode_uid = '')
{
- global $config;
+ global $phpbb_container;
- if ($bbcode_uid)
+ if (preg_match('#^<[rt][ >]#', $message))
{
- $match = array('<br />', "[/*:m:$bbcode_uid]", ":u:$bbcode_uid", ":o:$bbcode_uid", ":$bbcode_uid");
- $replace = array("\n", '', '', '', '');
+ $message = htmlspecialchars($phpbb_container->get('text_formatter.utils')->unparse($message), ENT_COMPAT);
}
else
{
- $match = array('<br />');
- $replace = array("\n");
- }
+ if ($bbcode_uid)
+ {
+ $match = array('<br />', "[/*:m:$bbcode_uid]", ":u:$bbcode_uid", ":o:$bbcode_uid", ":$bbcode_uid");
+ $replace = array("\n", '', '', '', '');
+ }
+ else
+ {
+ $match = array('<br />');
+ $replace = array("\n");
+ }
- $message = str_replace($match, $replace, $message);
+ $message = str_replace($match, $replace, $message);
- $match = get_preg_expression('bbcode_htm');
- $replace = array('\1', '\1', '\2', '\1', '', '');
+ $match = get_preg_expression('bbcode_htm');
+ $replace = array('\1', '\1', '\3', '\1', '', '');
- $message = preg_replace($match, $replace, $message);
+ $message = preg_replace($match, $replace, $message);
+ }
}
/**
-* Strips all bbcode from a text and returns the plain content
+* Strips all bbcode from a text in place
*/
function strip_bbcode(&$text, $uid = '')
{
- if (!$uid)
+ global $phpbb_container;
+
+ if (preg_match('#^<[rt][ >]#', $text))
{
- $uid = '[0-9a-z]{5,}';
+ $text = $phpbb_container->get('text_formatter.utils')->clean_formatting($text);
}
+ else
+ {
+ if (!$uid)
+ {
+ $uid = '[0-9a-z]{5,}';
+ }
- $text = preg_replace("#\[\/?[a-z0-9\*\+\-]+(?:=(?:&quot;.*&quot;|[^\]]*))?(?::[a-z])?(\:$uid)\]#", ' ', $text);
+ $text = preg_replace("#\[\/?[a-z0-9\*\+\-]+(?:=(?:&quot;.*&quot;|[^\]]*))?(?::[a-z])?(\:$uid)\]#", ' ', $text);
- $match = get_preg_expression('bbcode_htm');
- $replace = array('\1', '\1', '\2', '\1', '', '');
+ $match = get_preg_expression('bbcode_htm');
+ $replace = array('\1', '\1', '\2', '\1', '', '');
- $text = preg_replace($match, $replace, $text);
+ $text = preg_replace($match, $replace, $text);
+ }
}
/**
@@ -438,7 +460,7 @@ function strip_bbcode(&$text, $uid = '')
function generate_text_for_display($text, $uid, $bitfield, $flags, $censor_text = true)
{
static $bbcode;
- global $phpbb_dispatcher;
+ global $phpbb_dispatcher, $phpbb_container;
if ($text === '')
{
@@ -459,34 +481,56 @@ function generate_text_for_display($text, $uid, $bitfield, $flags, $censor_text
$vars = array('text', 'uid', 'bitfield', 'flags', 'censor_text');
extract($phpbb_dispatcher->trigger_event('core.modify_text_for_display_before', compact($vars)));
- if ($censor_text)
+ if (preg_match('#^<[rt][ >]#', $text))
{
- $text = censor_text($text);
- }
+ $renderer = $phpbb_container->get('text_formatter.renderer');
- // Parse bbcode if bbcode uid stored and bbcode enabled
- if ($uid && ($flags & OPTION_FLAG_BBCODE))
- {
- if (!class_exists('bbcode'))
+ // Temporarily switch off viewcensors if applicable
+ $old_censor = $renderer->get_viewcensors();
+ if ($old_censor !== $censor_text)
{
- global $phpbb_root_path, $phpEx;
- include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
+ $renderer->set_viewcensors($censor_text);
}
- if (empty($bbcode))
+ $text = $renderer->render($text);
+
+ // Restore the previous value
+ if ($old_censor !== $censor_text)
{
- $bbcode = new bbcode($bitfield);
+ $renderer->set_viewcensors($old_censor);
}
- else
+ }
+ else
+ {
+ if ($censor_text)
{
- $bbcode->bbcode($bitfield);
+ $text = censor_text($text);
}
- $bbcode->bbcode_second_pass($text, $uid);
- }
+ // Parse bbcode if bbcode uid stored and bbcode enabled
+ if ($uid && ($flags & OPTION_FLAG_BBCODE))
+ {
+ if (!class_exists('bbcode'))
+ {
+ global $phpbb_root_path, $phpEx;
+ include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
+ }
- $text = bbcode_nl2br($text);
- $text = smiley_text($text, !($flags & OPTION_FLAG_SMILIES));
+ if (empty($bbcode))
+ {
+ $bbcode = new bbcode($bitfield);
+ }
+ else
+ {
+ $bbcode->bbcode($bitfield);
+ }
+
+ $bbcode->bbcode_second_pass($text, $uid);
+ }
+
+ $text = bbcode_nl2br($text);
+ $text = smiley_text($text, !($flags & OPTION_FLAG_SMILIES));
+ }
/**
* Use this event to modify the text after it is parsed
@@ -516,10 +560,15 @@ function generate_text_for_display($text, $uid, $bitfield, $flags, $censor_text
* @param bool $allow_bbcode If BBCode is allowed (i.e. if BBCode is parsed)
* @param bool $allow_urls If urls is allowed
* @param bool $allow_smilies If smilies are allowed
+* @param bool $allow_img_bbcode
+* @param bool $allow_flash_bbcode
+* @param bool $allow_quote_bbcode
+* @param bool $allow_url_bbcode
+* @param string $mode Mode to parse text as, e.g. post or sig
*
* @return array An array of string with the errors that occurred while parsing
*/
-function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bbcode = false, $allow_urls = false, $allow_smilies = false)
+function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bbcode = false, $allow_urls = false, $allow_smilies = false, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $mode = 'post')
{
global $phpbb_root_path, $phpEx, $phpbb_dispatcher;
@@ -534,7 +583,13 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb
* @var bool allow_bbcode Whether or not to parse BBCode
* @var bool allow_urls Whether or not to parse URLs
* @var bool allow_smilies Whether or not to parse Smilies
+ * @var bool allow_img_bbcode Whether or not to parse the [img] BBCode
+ * @var bool allow_flash_bbcode Whether or not to parse the [flash] BBCode
+ * @var bool allow_quote_bbcode Whether or not to parse the [quote] BBCode
+ * @var bool allow_url_bbcode Whether or not to parse the [url] BBCode
+ * @var string mode Mode to parse text as, e.g. post or sig
* @since 3.1.0-a1
+ * @changed 3.2.0-a1
*/
$vars = array(
'text',
@@ -544,24 +599,24 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb
'allow_bbcode',
'allow_urls',
'allow_smilies',
+ 'allow_img_bbcode',
+ 'allow_flash_bbcode',
+ 'allow_quote_bbcode',
+ 'allow_url_bbcode',
+ 'mode',
);
extract($phpbb_dispatcher->trigger_event('core.modify_text_for_storage_before', compact($vars)));
$uid = $bitfield = '';
$flags = (($allow_bbcode) ? OPTION_FLAG_BBCODE : 0) + (($allow_smilies) ? OPTION_FLAG_SMILIES : 0) + (($allow_urls) ? OPTION_FLAG_LINKS : 0);
- if ($text === '')
- {
- return;
- }
-
if (!class_exists('parse_message'))
{
include($phpbb_root_path . 'includes/message_parser.' . $phpEx);
}
$message_parser = new parse_message($text);
- $message_parser->parse($allow_bbcode, $allow_urls, $allow_smilies);
+ $message_parser->parse($allow_bbcode, $allow_urls, $allow_smilies, $allow_img_bbcode, $allow_flash_bbcode, $allow_quote_bbcode, $allow_url_bbcode, true, $mode);
$text = $message_parser->message;
$uid = $message_parser->bbcode_uid;
@@ -1120,38 +1175,6 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
$update_count[] = $attachment['attach_id'];
break;
- // Windows Media Streams
- case ATTACHMENT_CATEGORY_WM:
-
- // Giving the filename directly because within the wm object all variables are in local context making it impossible
- // to validate against a valid session (all params can differ)
- // $download_link = $filename;
-
- $block_array += array(
- 'U_FORUM' => generate_board_url(),
- 'ATTACH_ID' => $attachment['attach_id'],
- 'S_WM_FILE' => true,
- );
-
- // Viewed/Heared File ... update the download count
- $update_count[] = $attachment['attach_id'];
- break;
-
- // Real Media Streams
- case ATTACHMENT_CATEGORY_RM:
- case ATTACHMENT_CATEGORY_QUICKTIME:
-
- $block_array += array(
- 'S_RM_FILE' => ($display_cat == ATTACHMENT_CATEGORY_RM) ? true : false,
- 'S_QUICKTIME_FILE' => ($display_cat == ATTACHMENT_CATEGORY_QUICKTIME) ? true : false,
- 'U_FORUM' => generate_board_url(),
- 'ATTACH_ID' => $attachment['attach_id'],
- );
-
- // Viewed/Heared File ... update the download count
- $update_count[] = $attachment['attach_id'];
- break;
-
// Macromedia Flash Files
case ATTACHMENT_CATEGORY_FLASH:
list($width, $height) = @getimagesize($filename);
@@ -1187,6 +1210,7 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
);
}
+ $update_count_ary = $update_count;
/**
* Use this event to modify the attachment template data.
*
@@ -1200,8 +1224,9 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
* @var array extensions Array with attachment extensions data
* @var mixed forum_id The forum id the attachments are displayed in (false if in private message)
* @var bool preview Flag indicating if we are in post preview mode
- * @var array update_count Array with attachment ids to update download count
+ * @var array update_count_ary Array with attachment ids to update download count
* @since 3.1.0-RC5
+ * @change 3.2.0-a1 Replaced update_count with update_count_ary
*/
$vars = array(
'attachment',
@@ -1211,9 +1236,11 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
'extensions',
'forum_id',
'preview',
- 'update_count',
+ 'update_count_ary',
);
extract($phpbb_dispatcher->trigger_event('core.parse_attachments_modify_template_data', compact($vars)));
+ $update_count = $update_count_ary;
+ unset($update_count_ary);
$template->assign_block_vars('_file', $block_array);
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index ea7816077d..0a25ae8c36 100644
--- a/phpBB/includes/functions_convert.php
+++ b/phpBB/includes/functions_convert.php
@@ -966,7 +966,7 @@ function get_remote_avatar_dim($src, $axis)
$protocol = (isset($url_info['scheme'])) ? $url_info['scheme'] : 'http';
if (empty($port))
{
- switch(strtolower($protocol))
+ switch (strtolower($protocol))
{
case 'ftp':
$port = 21;
@@ -2316,7 +2316,10 @@ function convert_bbcode($message, $convert_size = true, $extended_bbcodes = fals
function copy_file($src, $trg, $overwrite = false, $die_on_failure = true, $source_relative_path = true)
{
- global $convert, $phpbb_root_path, $config, $user, $db;
+ global $convert, $phpbb_root_path, $config, $user, $db, $phpbb_filesystem;
+
+ /** @var \phpbb\filesystem\filesystem_interface $filesystem */
+ $filesystem = $phpbb_filesystem;
if (substr($trg, -1) == '/')
{
@@ -2349,7 +2352,7 @@ function copy_file($src, $trg, $overwrite = false, $die_on_failure = true, $sour
}
}
- if (!phpbb_is_writable($path))
+ if (!$filesystem->is_writable($path))
{
@chmod($path, 0777);
}
@@ -2370,7 +2373,10 @@ function copy_file($src, $trg, $overwrite = false, $die_on_failure = true, $sour
function copy_dir($src, $trg, $copy_subdirs = true, $overwrite = false, $die_on_failure = true, $source_relative_path = true)
{
- global $convert, $phpbb_root_path, $config, $user, $db;
+ global $convert, $phpbb_root_path, $config, $user, $db, $phpbb_filesystem;
+
+ /** @var \phpbb\filesystem\filesystem_interface $filesystem */
+ $filesystem = $phpbb_filesystem;
$dirlist = $filelist = $bad_dirs = array();
$src = path($src, $source_relative_path);
@@ -2384,7 +2390,7 @@ function copy_dir($src, $trg, $copy_subdirs = true, $overwrite = false, $die_on_
@chmod($trg_path, 0777);
}
- if (!phpbb_is_writable($trg_path))
+ if (!$filesystem->is_writable($trg_path))
{
$bad_dirs[] = path($config['script_path']) . $trg;
}
@@ -2451,7 +2457,7 @@ function copy_dir($src, $trg, $copy_subdirs = true, $overwrite = false, $die_on_
@chmod($trg_path . $dir, 0777);
}
- if (!phpbb_is_writable($trg_path . $dir))
+ if (!$filesystem->is_writable($trg_path . $dir))
{
$bad_dirs[] = $trg . $dir;
$bad_dirs[] = $trg_path . $dir;
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index a6c9c529d6..9e45f32689 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -150,7 +150,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query($sql);
- $forum_tracking_info = array();
+ $forum_tracking_info = $valid_categories = array();
$branch_root_id = $root_data['forum_id'];
/* @var $phpbb_content_visibility \phpbb\content_visibility */
@@ -251,6 +251,12 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
}
}
+ // Fill list of categories with forums
+ if (isset($forum_rows[$row['parent_id']]))
+ {
+ $valid_categories[$row['parent_id']] = true;
+ }
+
//
if ($row['parent_id'] == $root_data['forum_id'] || $row['parent_id'] == $branch_root_id)
{
@@ -268,6 +274,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$branch_root_id = $forum_id;
}
$forum_rows[$parent_id]['forum_id_last_post'] = $row['forum_id'];
+ $forum_rows[$parent_id]['forum_password_last_post'] = $row['forum_password'];
$forum_rows[$parent_id]['orig_forum_last_post_time'] = $row['forum_last_post_time'];
}
else if ($row['forum_type'] != FORUM_CAT)
@@ -309,6 +316,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$forum_rows[$parent_id]['forum_last_poster_name'] = $row['forum_last_poster_name'];
$forum_rows[$parent_id]['forum_last_poster_colour'] = $row['forum_last_poster_colour'];
$forum_rows[$parent_id]['forum_id_last_post'] = $forum_id;
+ $forum_rows[$parent_id]['forum_password_last_post'] = $row['forum_password'];
}
}
@@ -405,6 +413,12 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
// Category
if ($row['parent_id'] == $root_data['forum_id'] && $row['forum_type'] == FORUM_CAT)
{
+ // Do not display categories without any forums to display
+ if (!isset($valid_categories[$row['forum_id']]))
+ {
+ continue;
+ }
+
$cat_row = array(
'S_IS_CAT' => true,
'FORUM_ID' => $row['forum_id'],
@@ -424,15 +438,14 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
*
* @event core.display_forums_modify_category_template_vars
* @var array cat_row Template data of the 'category'
- * @var bool catless The flag indicating whether the 'category' has a parent category
* @var bool last_catless The flag indicating whether the last forum had a parent category
* @var array root_data Array with the root forum data
* @var array row The data of the 'category'
* @since 3.1.0-RC4
+ * @change 3.1.7-RC1 Removed undefined catless variable
*/
$vars = array(
'cat_row',
- 'catless',
'last_catless',
'root_data',
'row',
@@ -523,8 +536,15 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
// Create last post link information, if appropriate
if ($row['forum_last_post_id'])
{
- $last_post_subject = $row['forum_last_post_subject'];
- $last_post_subject_truncated = truncate_string(censor_text($last_post_subject), 30, 255, false, $user->lang['ELLIPSIS']);
+ if ($row['forum_password_last_post'] === '' && $auth->acl_get('f_read', $row['forum_id_last_post']))
+ {
+ $last_post_subject = censor_text($row['forum_last_post_subject']);
+ $last_post_subject_truncated = truncate_string($last_post_subject, 30, 255, false, $user->lang['ELLIPSIS']);
+ }
+ else
+ {
+ $last_post_subject = $last_post_subject_truncated = '';
+ }
$last_post_time = $user->format_date($row['forum_last_post_time']);
$last_post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id_last_post'] . '&amp;p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id'];
}
@@ -584,7 +604,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
'S_LOCKED_FORUM' => ($row['forum_status'] == ITEM_LOCKED) ? true : false,
'S_LIST_SUBFORUMS' => ($row['display_subforum_list']) ? true : false,
'S_SUBFORUMS' => (sizeof($subforums_list)) ? true : false,
- 'S_DISPLAY_SUBJECT' => ($last_post_subject && $config['display_last_subject'] && !$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? true : false,
+ 'S_DISPLAY_SUBJECT' => ($last_post_subject !== '' && $config['display_last_subject']) ? true : false,
'S_FEED_ENABLED' => ($config['feed_forum'] && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $row['forum_options']) && $row['forum_type'] == FORUM_POST) ? true : false,
'FORUM_ID' => $row['forum_id'],
@@ -597,8 +617,8 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
'FORUM_FOLDER_IMG_ALT' => isset($user->lang[$folder_alt]) ? $user->lang[$folder_alt] : '',
'FORUM_IMAGE' => ($row['forum_image']) ? '<img src="' . $phpbb_root_path . $row['forum_image'] . '" alt="' . $user->lang[$folder_alt] . '" />' : '',
'FORUM_IMAGE_SRC' => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '',
- 'LAST_POST_SUBJECT' => (!$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? censor_text($last_post_subject) : "",
- 'LAST_POST_SUBJECT_TRUNCATED' => (!$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? $last_post_subject_truncated : "",
+ 'LAST_POST_SUBJECT' => $last_post_subject,
+ 'LAST_POST_SUBJECT_TRUNCATED' => $last_post_subject_truncated,
'LAST_POST_TIME' => $last_post_time,
'LAST_POSTER' => get_username_string('username', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
'LAST_POSTER_COLOUR' => get_username_string('colour', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
@@ -733,13 +753,15 @@ function generate_forum_rules(&$forum_data)
function generate_forum_nav(&$forum_data)
{
global $db, $user, $template, $auth, $config;
- global $phpEx, $phpbb_root_path;
+ global $phpEx, $phpbb_root_path, $phpbb_dispatcher;
if (!$auth->acl_get('f_list', $forum_data['forum_id']))
{
return;
}
+ $navlinks = $navlinks_parents = $forum_template_data = array();
+
// Get forum parents
$forum_parents = get_forum_parents($forum_data);
@@ -758,35 +780,63 @@ function generate_forum_nav(&$forum_data)
continue;
}
- $template->assign_block_vars('navlinks', array(
+ $navlinks_parents[] = array(
'S_IS_CAT' => ($parent_type == FORUM_CAT) ? true : false,
'S_IS_LINK' => ($parent_type == FORUM_LINK) ? true : false,
'S_IS_POST' => ($parent_type == FORUM_POST) ? true : false,
'FORUM_NAME' => $parent_name,
'FORUM_ID' => $parent_forum_id,
'MICRODATA' => $microdata_attr . '="' . $parent_forum_id . '"',
- 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $parent_forum_id))
+ 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $parent_forum_id),
);
}
}
- $template->assign_block_vars('navlinks', array(
+ $navlinks = array(
'S_IS_CAT' => ($forum_data['forum_type'] == FORUM_CAT) ? true : false,
'S_IS_LINK' => ($forum_data['forum_type'] == FORUM_LINK) ? true : false,
'S_IS_POST' => ($forum_data['forum_type'] == FORUM_POST) ? true : false,
'FORUM_NAME' => $forum_data['forum_name'],
'FORUM_ID' => $forum_data['forum_id'],
'MICRODATA' => $microdata_attr . '="' . $forum_data['forum_id'] . '"',
- 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_data['forum_id']))
+ 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_data['forum_id']),
);
- $template->assign_vars(array(
+ $forum_template_data = array(
'FORUM_ID' => $forum_data['forum_id'],
'FORUM_NAME' => $forum_data['forum_name'],
'FORUM_DESC' => generate_text_for_display($forum_data['forum_desc'], $forum_data['forum_desc_uid'], $forum_data['forum_desc_bitfield'], $forum_data['forum_desc_options']),
'S_ENABLE_FEEDS_FORUM' => ($config['feed_forum'] && $forum_data['forum_type'] == FORUM_POST && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $forum_data['forum_options'])) ? true : false,
- ));
+ );
+
+ $forum_data_ary = $forum_data;
+ /**
+ * Event to modify the navlinks text
+ *
+ * @event core.generate_forum_nav
+ * @var array forum_data_ary Array with the forum data
+ * @var array forum_template_data Array with generic forum template data
+ * @var string microdata_attr The microdata attribute
+ * @var array navlinks_parents Array with the forum parents navlinks data
+ * @var array navlinks Array with the forum navlinks data
+ * @since 3.1.5-RC1
+ * @change 3.2.0-a1 Replaced forum_data with forum_data_ary
+ */
+ $vars = array(
+ 'forum_data_ary',
+ 'forum_template_data',
+ 'microdata_attr',
+ 'navlinks_parents',
+ 'navlinks',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.generate_forum_nav', compact($vars)));
+ $forum_data = $forum_data_ary;
+ unset($forum_data_ary);
+
+ $template->assign_block_vars_array('navlinks', $navlinks_parents);
+ $template->assign_block_vars('navlinks', $navlinks);
+ $template->assign_vars($forum_template_data);
return;
}
@@ -839,6 +889,7 @@ function get_forum_parents(&$forum_data)
function get_moderators(&$forum_moderators, $forum_id = false)
{
global $config, $template, $db, $phpbb_root_path, $phpEx, $user, $auth;
+ global $phpbb_container;
$forum_id_ary = array();
@@ -874,6 +925,9 @@ function get_moderators(&$forum_moderators, $forum_id = false)
'WHERE' => 'm.display_on_index = 1',
);
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
// We query every forum here because for caching we should not have any parameter.
$sql = $db->sql_build_query('SELECT', $sql_array);
$result = $db->sql_query($sql, 3600);
@@ -893,7 +947,7 @@ function get_moderators(&$forum_moderators, $forum_id = false)
}
else
{
- $group_name = (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']);
+ $group_name = $group_helper->get_name($row['group_name']);
if ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile'))
{
@@ -1097,33 +1151,14 @@ function display_custom_bbcodes()
/**
* Display reasons
+*
+* @deprecated 3.2.0-dev
*/
function display_reasons($reason_id = 0)
{
- global $db, $user, $template;
-
- $sql = 'SELECT *
- FROM ' . REPORTS_REASONS_TABLE . '
- ORDER BY reason_order ASC';
- $result = $db->sql_query($sql);
+ global $phpbb_container;
- while ($row = $db->sql_fetchrow($result))
- {
- // 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'])];
- }
-
- $template->assign_block_vars('reason', array(
- 'ID' => $row['reason_id'],
- 'TITLE' => $row['reason_title'],
- 'DESCRIPTION' => $row['reason_description'],
- 'S_SELECTED' => ($row['reason_id'] == $reason_id) ? true : false)
- );
- }
- $db->sql_freeresult($result);
+ $phpbb_container->get('phpbb.report.report_reason_list_provider')->display_reasons($reason_id);
}
/**
@@ -1205,17 +1240,21 @@ function display_user_activity(&$userdata)
}
}
+ $userdata_ary = $userdata;
/**
* Alter list of forums and topics to display as active
*
* @event core.display_user_activity_modify_actives
- * @var array userdata User's data
+ * @var array userdata_ary User's data
* @var array active_f_row List of active forums
* @var array active_t_row List of active posts
* @since 3.1.0-RC3
+ * @change 3.2.0-a1 Replaced userdata with userdata_ary
*/
- $vars = array('userdata', 'active_f_row', 'active_t_row');
+ $vars = array('userdata_ary', 'active_f_row', 'active_t_row');
extract($phpbb_dispatcher->trigger_event('core.display_user_activity_modify_actives', compact($vars)));
+ $userdata = $userdata_ary;
+ unset($userdata_ary);
$userdata['active_t_row'] = $active_t_row;
$userdata['active_f_row'] = $active_f_row;
@@ -1451,7 +1490,7 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id,
* @param array $user_data the current stored users data
* @param int $user_posts the users number of posts
*
-* @return array An associative array containing the rank title (title), the rank image source (img) and the rank image as full img tag (img)
+* @return array An associative array containing the rank title (title), the rank image as full img tag (img) and the rank image source (img_src)
*
* 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
*/
diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php
index 8dacd25230..d9d073e984 100644
--- a/phpBB/includes/functions_install.php
+++ b/phpBB/includes/functions_install.php
@@ -189,7 +189,7 @@ function dbms_select($default = '', $only_20x_options = false)
*/
function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix, $dbhost, $dbuser, $dbpasswd, $dbname, $dbport, $prefix_may_exist = false, $load_dbal = true, $unicode_check = true)
{
- global $phpbb_root_path, $phpEx, $config, $lang;
+ global $phpbb_root_path, $phpEx, $config, $lang, $phpbb_filesystem;
$dbms = $dbms_details['DRIVER'];
@@ -205,7 +205,7 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
}
// Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea
- if (($dbms_details['DRIVER'] == 'phpbb\db\driver\sqlite' || $dbms_details['DRIVER'] == 'phpbb\db\driver\sqlite3') && stripos(phpbb_realpath($dbhost), phpbb_realpath('../')) === 0)
+ if (($dbms_details['DRIVER'] == 'phpbb\db\driver\sqlite' || $dbms_details['DRIVER'] == 'phpbb\db\driver\sqlite3') && stripos($phpbb_filesystem->realpath($dbhost), $phpbb_filesystem->realpath('../')) === 0)
{
$error[] = $lang['INST_ERR_DB_FORUM_PATH'];
return false;
diff --git a/phpBB/includes/functions_mcp.php b/phpBB/includes/functions_mcp.php
index 46e85c5674..f9e38e8aa0 100644
--- a/phpBB/includes/functions_mcp.php
+++ b/phpBB/includes/functions_mcp.php
@@ -389,7 +389,7 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
if (!$auth->acl_get('m_approve', $forum_id))
{
- $sql .= 'AND topic_visibility = ' . ITEM_APPROVED;
+ $sql .= ' AND topic_visibility = ' . ITEM_APPROVED;
}
break;
@@ -405,7 +405,7 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
if (!$auth->acl_get('m_approve', $forum_id))
{
- $sql .= 'AND post_visibility = ' . ITEM_APPROVED;
+ $sql .= ' AND post_visibility = ' . ITEM_APPROVED;
}
break;
@@ -557,6 +557,11 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
// Default total to -1 to allow editing by the event
$total = -1;
+ $sort_by_sql_ary = $sort_by_sql;
+ $sort_days_val = $sort_days;
+ $sort_dir_val = $sort_dir;
+ $sort_key_val = $sort_key;
+ $total_val = $total;
/**
* This event allows you to control the SQL query used to get the total number
* of reports the user can access.
@@ -571,19 +576,20 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
* @var string type Which kind of information is this being used for displaying. Posts, topics, etc...
* @var int forum_id The forum id of the posts the user is trying to access, if not 0
* @var int topic_id The topic id of the posts the user is trying to access, if not 0
- * @var int sort_days The max age of the oldest report to be shown, in days
- * @var string sort_key The way the user has decided to sort the data.
+ * @var int sort_days_val The max age of the oldest report to be shown, in days
+ * @var string sort_key_val The way the user has decided to sort the data.
* The valid values must be in the keys of the sort_by_* variables
- * @var string sort_dir Either 'd' for "DESC" or 'a' for 'ASC' in the SQL query
+ * @var string sort_dir_val Either 'd' for "DESC" or 'a' for 'ASC' in the SQL query
* @var int limit_days The possible max ages of the oldest report for the user to choose, in days.
- * @var array sort_by_sql SQL text (values) for the possible names of the ways of sorting data (keys).
+ * @var array sort_by_sql_ary SQL text (values) for the possible names of the ways of sorting data (keys).
* @var array sort_by_text Language text (values) for the possible names of the ways of sorting data (keys).
* @var int min_time Integer with the minimum post time that the user is searching for
* @var int limit_time_sql Time limiting options used in the SQL query.
- * @var int total The total number of reports that exist. Only set if you want to override the result
+ * @var int total_val The total number of reports that exist. Only set if you want to override the result
* @var string where_sql Extra information included in the WHERE clause. It must end with "WHERE" or "AND" or "OR".
* Set to "WHERE" and set total above -1 to override the total value
* @since 3.1.4-RC1
+ * @change 3.2.0-a1 Replaced sort_days, sort_key, sort_dir, sort_by_sql, total with replacement variables
*/
$vars = array(
'sql',
@@ -591,18 +597,28 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
'type',
'forum_id',
'topic_id',
- 'sort_days',
- 'sort_key',
- 'sort_dir',
+ 'sort_days_val',
+ 'sort_key_val',
+ 'sort_dir_val',
'limit_days',
- 'sort_by_sql',
+ 'sort_by_sql_ary',
'sort_by_text',
'min_time',
'limit_time_sql',
- 'total',
+ 'total_val',
'where_sql',
);
extract($phpbb_dispatcher->trigger_event('core.mcp_sorting_query_before', compact($vars)));
+ $sort_by_sql = $sort_by_sql_ary;
+ $sort_days = $sort_days_val;
+ $sort_key = $sort_key_val;
+ $sort_dir = $sort_dir_val;
+ $total = $total_val;
+ unset($sort_by_sql_ary);
+ unset($sort_days_val);
+ unset($sort_key_val);
+ unset($sort_dir_val);
+ unset($total_val);
if (!isset($sort_by_sql[$sort_key]))
{
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index 3aa3f3d03f..810f2c0584 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -623,7 +623,7 @@ class messenger
*/
protected function setup_template()
{
- global $config, $phpbb_path_helper, $user, $phpbb_extension_manager, $phpbb_container;
+ global $config, $phpbb_path_helper, $user, $phpbb_extension_manager, $phpbb_container, $phpbb_filesystem;
if ($this->template instanceof \phpbb\template\template)
{
@@ -633,17 +633,20 @@ class messenger
$this->template = new \phpbb\template\twig\twig(
$phpbb_container->get('path_helper'),
$phpbb_container->get('config'),
- $phpbb_container->get('user'),
new \phpbb\template\context(),
new \phpbb\template\twig\environment(
$phpbb_container->get('config'),
+ $phpbb_container->get('filesystem'),
$phpbb_container->get('path_helper'),
$phpbb_container,
$phpbb_container->getParameter('core.root_path') . 'cache/',
$phpbb_container->get('ext.manager'),
- new \phpbb\template\twig\loader()
+ new \phpbb\template\twig\loader(
+ $phpbb_filesystem
+ )
),
$phpbb_container->getParameter('core.root_path') . 'cache/',
+ $phpbb_container->get('user'),
$phpbb_container->get('template.twig.extensions.collection'),
$phpbb_extension_manager
);
@@ -672,14 +675,20 @@ class queue
var $eol = "\n";
/**
+ * @var \phpbb\filesystem\filesystem_interface
+ */
+ protected $filesystem;
+
+ /**
* constructor
*/
function queue()
{
- global $phpEx, $phpbb_root_path;
+ global $phpEx, $phpbb_root_path, $phpbb_filesystem;
$this->data = array();
$this->cache_file = "{$phpbb_root_path}cache/queue.$phpEx";
+ $this->filesystem = $phpbb_filesystem;
}
/**
@@ -865,7 +874,14 @@ class queue
fwrite($fp, "<?php\nif (!defined('IN_PHPBB')) exit;\n\$this->queue_data = unserialize(" . var_export(serialize($this->queue_data), true) . ");\n\n?>");
fclose($fp);
- phpbb_chmod($this->cache_file, CHMOD_READ | CHMOD_WRITE);
+ try
+ {
+ $this->filesystem->phpbb_chmod($this->cache_file, CHMOD_READ | CHMOD_WRITE);
+ }
+ catch (\phpbb\filesystem\exception\filesystem_exception $e)
+ {
+ // Do nothing
+ }
}
}
@@ -907,7 +923,16 @@ class queue
fwrite($fp, "<?php\nif (!defined('IN_PHPBB')) exit;\n\$this->queue_data = unserialize(" . var_export(serialize($this->data), true) . ");\n\n?>");
fclose($fp);
- phpbb_chmod($this->cache_file, CHMOD_READ | CHMOD_WRITE);
+ try
+ {
+ $this->filesystem->phpbb_chmod($this->cache_file, CHMOD_READ | CHMOD_WRITE);
+ }
+ catch (\phpbb\filesystem\exception\filesystem_exception $e)
+ {
+ // Do nothing
+ }
+
+ $this->data = array();
}
$lock->release();
diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php
index d0d09fe9fb..144e6b4e7c 100644
--- a/phpBB/includes/functions_module.php
+++ b/phpBB/includes/functions_module.php
@@ -978,7 +978,7 @@ class p_master
*
* @param string $class module class (acp/mcp/ucp)
* @param string $name module name (class name of the module, or its basename
- * phpbb_ext_foo_acp_bar_module, ucp_zebra or zebra)
+ * phpbb_ext_foo_acp_bar_module, ucp_zebra or zebra)
* @param string $mode mode, as passed through to the module
*
*/
@@ -1088,7 +1088,7 @@ class p_master
->core_path('language/' . $user->lang_name . '/mods/')
->find();
- $lang_files = array_unique(array_merge($user_lang_files, $english_lang_files, $default_lang_files));
+ $lang_files = array_merge($english_lang_files, $default_lang_files, $user_lang_files);
foreach ($lang_files as $lang_file => $ext_name)
{
$user->add_lang_ext($ext_name, $lang_file);
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index 9c6ddffe9f..4f14dc8683 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -314,6 +314,7 @@ function posting_gen_topic_icons($mode, $icon_id)
'ICON_IMG' => $root_path . $config['icons_path'] . '/' . $data['img'],
'ICON_WIDTH' => $data['width'],
'ICON_HEIGHT' => $data['height'],
+ 'ICON_ALT' => $data['alt'],
'S_CHECKED' => ($id == $icon_id) ? true : false,
'S_ICON_CHECKED' => ($id == $icon_id) ? ' checked="checked"' : '')
@@ -337,18 +338,15 @@ function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL)
$toggle = false;
$topic_types = array(
- 'sticky' => array('const' => POST_STICKY, 'lang' => 'POST_STICKY'),
- 'announce' => array('const' => POST_ANNOUNCE, 'lang' => 'POST_ANNOUNCEMENT'),
- 'global' => array('const' => POST_GLOBAL, 'lang' => 'POST_GLOBAL')
+ 'sticky' => array('const' => POST_STICKY, 'lang' => 'POST_STICKY'),
+ 'announce' => array('const' => POST_ANNOUNCE, 'lang' => 'POST_ANNOUNCEMENT'),
+ 'announce_global' => array('const' => POST_GLOBAL, 'lang' => 'POST_GLOBAL')
);
$topic_type_array = array();
foreach ($topic_types as $auth_key => $topic_value)
{
- // We do not have a special post global announcement permission
- $auth_key = ($auth_key == 'global') ? 'announce' : $auth_key;
-
if ($auth->acl_get('f_' . $auth_key, $forum_id))
{
$toggle = true;
@@ -378,8 +376,8 @@ function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL)
$template->assign_vars(array(
'S_TOPIC_TYPE_STICKY' => ($auth->acl_get('f_sticky', $forum_id)),
- 'S_TOPIC_TYPE_ANNOUNCE' => ($auth->acl_get('f_announce', $forum_id)))
- );
+ 'S_TOPIC_TYPE_ANNOUNCE' => ($auth->acl_gets('f_announce', 'f_announce_global', $forum_id)),
+ ));
}
return $toggle;
@@ -393,183 +391,27 @@ function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL)
* Upload Attachment - filedata is generated here
* Uses upload class
*
+* @deprecated 3.2.0-a1 (To be removed: 3.4.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 \filespec $local_filedata A filespec object created for the local file
-* @param \phpbb\mimetype\guesser $mimetype_guesser The mimetype guesser object if used
-* @param \phpbb\plupload\plupload $plupload The plupload object if one is being used
+* @param array $local_filedata A filespec object created for the local file
*
-* @return object filespec
+* @return array File data array
*/
-function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null)
+function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false)
{
- global $auth, $user, $config, $db, $cache;
- global $phpbb_root_path, $phpEx, $phpbb_dispatcher;
-
- $filedata = array(
- 'error' => array()
- );
-
- include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
- $upload = new fileupload();
-
- if ($config['check_attachment_content'] && isset($config['mime_triggers']))
- {
- $upload->set_disallowed_content(explode('|', $config['mime_triggers']));
- }
- else if (!$config['check_attachment_content'])
- {
- $upload->set_disallowed_content(array());
- }
-
- $filedata['post_attach'] = $local || $upload->is_valid($form_name);
-
- if (!$filedata['post_attach'])
- {
- $filedata['error'][] = $user->lang['NO_UPLOAD_FORM_FOUND'];
- return $filedata;
- }
-
- $extensions = $cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id));
- $upload->set_allowed_extensions(array_keys($extensions['_allowed_']));
-
- $file = ($local) ? $upload->local_upload($local_storage, $local_filedata, $mimetype_guesser) : $upload->form_upload($form_name, $mimetype_guesser, $plupload);
-
- if ($file->init_error)
- {
- $filedata['post_attach'] = false;
- return $filedata;
- }
-
- // Whether the uploaded file is in the image category
- $is_image = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE : false;
-
- if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id))
- {
- // Check Image Size, if it is an image
- if ($is_image)
- {
- $file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
- }
-
- // Admins and mods are allowed to exceed the allowed filesize
- if (!empty($extensions[$file->get('extension')]['max_filesize']))
- {
- $allowed_filesize = $extensions[$file->get('extension')]['max_filesize'];
- }
- else
- {
- $allowed_filesize = ($is_message) ? $config['max_filesize_pm'] : $config['max_filesize'];
- }
-
- $file->upload->set_max_filesize($allowed_filesize);
- }
-
- $file->clean_filename('unique', $user->data['user_id'] . '_');
-
- // Are we uploading an image *and* this image being within the image category?
- // Only then perform additional image checks.
- $file->move_file($config['upload_path'], false, !$is_image);
-
- // Do we have to create a thumbnail?
- $filedata['thumbnail'] = ($is_image && $config['img_create_thumbnail']) ? 1 : 0;
-
- if (sizeof($file->error))
- {
- $file->remove();
- $filedata['error'] = array_merge($filedata['error'], $file->error);
- $filedata['post_attach'] = false;
-
- return $filedata;
- }
-
- // Make sure the image category only holds valid images...
- if ($is_image && !$file->is_image())
- {
- $file->remove();
-
- if ($plupload && $plupload->is_active())
- {
- $plupload->emit_error(104, 'ATTACHED_IMAGE_NOT_IMAGE');
- }
-
- // If this error occurs a user tried to exploit an IE Bug by renaming extensions
- // Since the image category is displaying content inline we need to catch this.
- trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
- }
+ global $phpbb_container;
- $filedata['filesize'] = $file->get('filesize');
- $filedata['mimetype'] = $file->get('mimetype');
- $filedata['extension'] = $file->get('extension');
- $filedata['physical_filename'] = $file->get('realname');
- $filedata['real_filename'] = $file->get('uploadname');
- $filedata['filetime'] = time();
-
- /**
- * Event to modify uploaded file before submit to the post
- *
- * @event core.modify_uploaded_file
- * @var array filedata Array containing uploaded file data
- * @var bool is_image Flag indicating if the file is an image
- * @since 3.1.0-RC3
- */
- $vars = array(
- 'filedata',
- 'is_image',
- );
- extract($phpbb_dispatcher->trigger_event('core.modify_uploaded_file', compact($vars)));
+ /** @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);
- // Check our complete quota
- if ($config['attachment_quota'])
- {
- if ($config['upload_dir_size'] + $file->get('filesize') > $config['attachment_quota'])
- {
- $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
- $filedata['post_attach'] = false;
-
- $file->remove();
-
- return $filedata;
- }
- }
-
- // Check free disk space
- if ($free_space = @disk_free_space($phpbb_root_path . $config['upload_path']))
- {
- if ($free_space <= $file->get('filesize'))
- {
- if ($auth->acl_get('a_'))
- {
- $filedata['error'][] = $user->lang['ATTACH_DISK_FULL'];
- }
- else
- {
- $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
- }
- $filedata['post_attach'] = false;
-
- $file->remove();
-
- return $filedata;
- }
- }
-
- // Create Thumbnail
- if ($filedata['thumbnail'])
- {
- $source = $file->get('destination_file');
- $destination = $file->get('destination_path') . '/thumb_' . $file->get('realname');
-
- if (!create_thumbnail($source, $destination, $file->get('mimetype')))
- {
- $filedata['thumbnail'] = 0;
- }
- }
-
- return $filedata;
+ return $file;
}
/**
@@ -668,7 +510,7 @@ function get_supported_image_types($type = false)
*/
function create_thumbnail($source, $destination, $mimetype)
{
- global $config;
+ global $config, $phpbb_filesystem;
$min_filesize = (int) $config['img_min_thumb_filesize'];
$img_filesize = (file_exists($source)) ? @filesize($source) : false;
@@ -820,7 +662,14 @@ function create_thumbnail($source, $destination, $mimetype)
return false;
}
- phpbb_chmod($destination, CHMOD_READ | CHMOD_WRITE);
+ try
+ {
+ $phpbb_filesystem->phpbb_chmod($destination, CHMOD_READ | CHMOD_WRITE);
+ }
+ catch (\phpbb\filesystem\exception\filesystem_exception $e)
+ {
+ // Do nothing
+ }
return true;
}
@@ -1186,6 +1035,8 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
'MESSAGE' => $message,
'DECODED_MESSAGE' => $decoded_message,
'POST_ID' => $row['post_id'],
+ 'POST_TIME' => $row['post_time'],
+ 'USER_ID' => $row['user_id'],
'U_MINI_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . '#p' . $row['post_id'],
'U_MCP_DETAILS' => ($auth->acl_get('m_info', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&amp;mode=post_details&amp;f=' . $forum_id . '&amp;p=' . $row['post_id'], true, $user->session_id) : '',
'POSTER_QUOTE' => ($show_quote_button && $auth->acl_get('f_reply', $forum_id)) ? addslashes(get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username'])) : '',
@@ -1513,6 +1364,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
{
global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher, $phpbb_log, $request;
+ $poll_ary = $poll;
+ $data_ary = $data;
/**
* Modify the data for post submitting
*
@@ -1521,23 +1374,28 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
* @var string subject Variable containing post subject value
* @var string username Variable containing post author name
* @var int topic_type Variable containing topic type value
- * @var array poll Array with the poll data for the post
- * @var array data Array with the data for the post
+ * @var array poll_ary Array with the poll data for the post
+ * @var array data_ary Array with the data for the post
* @var bool update_message Flag indicating if the post will be updated
* @var bool update_search_index Flag indicating if the search index will be updated
* @since 3.1.0-a4
+ * @change 3.2.0-a1 Replaced poll and data with poll_ary and data_ary
*/
$vars = array(
'mode',
'subject',
'username',
'topic_type',
- 'poll',
- 'data',
+ 'poll_ary',
+ 'data_ary',
'update_message',
'update_search_index',
);
extract($phpbb_dispatcher->trigger_event('core.modify_submit_post_data', compact($vars)));
+ $poll = $poll_ary;
+ $data = $data_ary;
+ unset($poll_ary);
+ unset($data_ary);
// We do not handle erasing posts here
if ($mode == 'delete')
@@ -1545,7 +1403,14 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
return false;
}
- $current_time = time();
+ if (!empty($data['post_time']))
+ {
+ $current_time = $data['post_time'];
+ }
+ else
+ {
+ $current_time = time();
+ }
if ($mode == 'post')
{
@@ -1687,6 +1552,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_POST_EDITED', false, array(
'forum_id' => $data['forum_id'],
'topic_id' => $data['topic_id'],
+ 'post_id' => $data['post_id'],
$log_subject,
(!empty($username)) ? $username : $user->lang['GUEST'],
$data['post_edit_reason']
@@ -1747,6 +1613,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
'topic_type' => $topic_type,
'topic_time_limit' => ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0,
'topic_attachment' => (!empty($data['attachment_data'])) ? 1 : 0,
+ 'topic_status' => (isset($data['topic_status'])) ? $data['topic_status'] : ITEM_UNLOCKED,
);
if (isset($poll['poll_options']) && !empty($poll['poll_options']))
@@ -1853,22 +1720,25 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
break;
}
+ $poll_ary = $poll;
+ $data_ary = $data;
/**
* Modify sql query data for post submitting
*
* @event core.submit_post_modify_sql_data
- * @var array data Array with the data for the post
- * @var array poll Array with the poll data for the post
+ * @var array data_ary Array with the data for the post
+ * @var array poll_ary Array with the poll data for the post
* @var string post_mode Variable containing posting mode value
* @var bool sql_data Array with the data for the posting SQL query
* @var string subject Variable containing post subject value
* @var int topic_type Variable containing topic type value
* @var string username Variable containing post author name
* @since 3.1.3-RC1
+ * @change 3.2.0-a1 Replace poll and data with poll_ary and data_ary
*/
$vars = array(
- 'data',
- 'poll',
+ 'data_ary',
+ 'poll_ary',
'post_mode',
'sql_data',
'subject',
@@ -1876,6 +1746,10 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
'username',
);
extract($phpbb_dispatcher->trigger_event('core.submit_post_modify_sql_data', compact($vars)));
+ $poll = $poll_ary;
+ $data = $data_ary;
+ unset($poll_ary);
+ unset($data_ary);
// Submit new topic
if ($post_mode == 'post')
@@ -2219,7 +2093,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
}
$error = false;
- $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
if ($error)
{
@@ -2423,6 +2297,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
$url = (!$params) ? "{$phpbb_root_path}viewforum.$phpEx" : "{$phpbb_root_path}viewtopic.$phpEx";
$url = append_sid($url, 'f=' . $data['forum_id'] . $params) . $add_anchor;
+ $poll_ary = $poll;
+ $data_ary = $data;
/**
* This event is used for performing actions directly after a post or topic
* has been submitted. When a new topic is posted, the topic ID is
@@ -2436,8 +2312,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
* @var string subject Variable containing post subject value
* @var string username Variable containing post author name
* @var int topic_type Variable containing topic type value
- * @var array poll Array with the poll data for the post
- * @var array data Array with the data for the post
+ * @var array poll_ary Array with the poll data for the post
+ * @var array data_ary Array with the data for the post
* @var int post_visibility Variable containing up to date post visibility
* @var bool update_message Flag indicating if the post will be updated
* @var bool update_search_index Flag indicating if the search index will be updated
@@ -2446,20 +2322,25 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
* @since 3.1.0-a3
* @change 3.1.0-RC3 Added vars mode, subject, username, topic_type,
* poll, update_message, update_search_index
+ * @change 3.2.0-a1 Replaced data and poll with data_ary and poll_ary
*/
$vars = array(
'mode',
'subject',
'username',
'topic_type',
- 'poll',
- 'data',
+ 'poll_ary',
+ 'data_ary',
'post_visibility',
'update_message',
'update_search_index',
'url',
);
extract($phpbb_dispatcher->trigger_event('core.submit_post_end', compact($vars)));
+ $data = $data_ary;
+ $poll = $poll_ary;
+ unset($data_ary);
+ unset($poll_ary);
return $url;
}
@@ -2652,6 +2533,7 @@ function phpbb_handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, (($is_soft) ? 'LOG_SOFTDELETE_POST' : 'LOG_DELETE_POST'), false, array(
'forum_id' => $forum_id,
'topic_id' => $topic_id,
+ 'post_id' => $post_id,
$post_data['post_subject'],
$post_username,
$delete_reason
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index c8b5280c8c..b2928d5df8 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -884,7 +884,7 @@ function update_unread_status($unread, $msg_id, $user_id, $folder_id)
/* @var $phpbb_notifications \phpbb\notification\manager */
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->mark_notifications_read('notification.type.pm', $msg_id, $user_id);
+ $phpbb_notifications->mark_notifications('notification.type.pm', $msg_id, $user_id);
$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
SET pm_unread = 0
@@ -1153,12 +1153,10 @@ function delete_pm($user_id, $msg_ids, $folder_id)
if (sizeof($delete_ids))
{
// Check if there are any attachments we need to remove
- if (!function_exists('delete_attachments'))
- {
- include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
- }
-
- delete_attachments('message', $delete_ids, false);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('message', $delete_ids, false);
+ unset($attachment_manager);
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
@@ -1363,12 +1361,10 @@ function phpbb_delete_users_pms($user_ids)
if (!empty($delete_ids))
{
// Check if there are any attachments we need to remove
- if (!function_exists('delete_attachments'))
- {
- include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
- }
-
- delete_attachments('message', $delete_ids, false);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('message', $delete_ids, false);
+ unset($attachment_manager);
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
@@ -1436,7 +1432,10 @@ function rebuild_header($check_ary)
*/
function write_pm_addresses($check_ary, $author_id, $plaintext = false)
{
- global $db, $user, $template, $phpbb_root_path, $phpEx;
+ global $db, $user, $template, $phpbb_root_path, $phpEx, $phpbb_container;
+
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
$addresses = array();
@@ -1497,7 +1496,7 @@ function write_pm_addresses($check_ary, $author_id, $plaintext = false)
{
if ($check_type == 'to' || $author_id == $user->data['user_id'] || $row['user_id'] == $user->data['user_id'])
{
- $address[] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
+ $address[] = $group_helper->get_name($row['group_name']);
}
}
$db->sql_freeresult($result);
@@ -1517,7 +1516,7 @@ function write_pm_addresses($check_ary, $author_id, $plaintext = false)
{
if ($check_type == 'to' || $author_id == $user->data['user_id'] || $row['user_id'] == $user->data['user_id'])
{
- $row['group_name'] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
+ $row['group_name'] = $group_helper->get_name($row['group_name']);
$address['group'][$row['group_id']] = array('name' => $row['group_name'], 'colour' => $row['group_colour']);
}
}
@@ -1621,17 +1620,21 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
$current_time = time();
+ $data_ary = $data;
/**
* Get all parts of the PM that are to be submited to the DB.
*
* @event core.submit_pm_before
* @var string mode PM Post mode - post|reply|quote|quotepost|forward|edit
* @var string subject Subject of the private message
- * @var array data The whole row data of the PM.
+ * @var array data_ary The whole row data of the PM.
* @since 3.1.0-b3
+ * @change 3.2.0-a1 Replaced data with data_ary
*/
- $vars = array('mode', 'subject', 'data');
+ $vars = array('mode', 'subject', 'data_ary');
extract($phpbb_dispatcher->trigger_event('core.submit_pm_before', compact($vars)));
+ $data = $data_ary;
+ unset($data_ary);
// Collect some basic information about which tables and which rows to update/insert
$sql_data = array();
@@ -1940,18 +1943,22 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
$phpbb_notifications->add_notifications('notification.type.pm', $pm_data);
}
+ $data_ary = $data;
/**
* Get PM message ID after submission to DB
*
* @event core.submit_pm_after
* @var string mode PM Post mode - post|reply|quote|quotepost|forward|edit
* @var string subject Subject of the private message
- * @var array data The whole row data of the PM.
+ * @var array data_ary The whole row data of the PM.
* @var array pm_data The data sent to notification class
* @since 3.1.0-b5
+ * @change 3.2.0-a1 Replaced data with data_ary
*/
- $vars = array('mode', 'subject', 'data', 'pm_data');
+ $vars = array('mode', 'subject', 'data_ary', 'pm_data');
extract($phpbb_dispatcher->trigger_event('core.submit_pm_after', compact($vars)));
+ $data = $data_ary;
+ unset($data_ary);
return $data['msg_id'];
}
@@ -2100,6 +2107,8 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode
'S_IN_POST_MODE' => $in_post_mode,
'MSG_ID' => $row['msg_id'],
+ 'MESSAGE_TIME' => $row['message_time'],
+ 'USER_ID' => $row['user_id'],
'U_VIEW_MESSAGE' => "$url&amp;f=$folder_id&amp;p=" . $row['msg_id'],
'U_QUOTE' => (!$in_post_mode && $auth->acl_get('u_sendpm') && $author_id != ANONYMOUS) ? "$url&amp;mode=compose&amp;action=quote&amp;f=" . $folder_id . "&amp;p=" . $row['msg_id'] : '',
'U_POST_REPLY_PM' => ($author_id != $user->data['user_id'] && $author_id != ANONYMOUS && $auth->acl_get('u_sendpm')) ? "$url&amp;mode=compose&amp;action=reply&amp;f=$folder_id&amp;p=" . $row['msg_id'] : '')
@@ -2127,17 +2136,42 @@ function set_user_message_limit()
{
global $user, $db, $config;
- // Get maximum about from user memberships - if it is 0, there is no limit set and we use the maximum value within the config.
- $sql = 'SELECT MAX(g.group_message_limit) as max_message_limit
+ // Get maximum about from user memberships
+ $message_limit = phpbb_get_max_setting_from_group($db, $user->data['user_id'], 'message_limit');
+
+ // If it is 0, there is no limit set and we use the maximum value within the config.
+ $user->data['message_limit'] = (!$message_limit) ? $config['pm_max_msgs'] : $message_limit;
+}
+
+/**
+ * Get the maximum PM setting for the groups of the user
+ *
+ * @param \phpbb\db\driver\driver_interface $db
+ * @param int $user_id
+ * @param string $setting Only 'max_recipients' and 'message_limit' are supported
+ * @return int The maximum setting for all groups of the user, unless one group has '0'
+ * @throws \InvalidArgumentException If selected group setting is not supported
+ */
+function phpbb_get_max_setting_from_group(\phpbb\db\driver\driver_interface $db, $user_id, $setting)
+{
+ if ($setting !== 'max_recipients' && $setting !== 'message_limit')
+ {
+ throw new InvalidArgumentException('Setting "' . $setting . '" is not supported');
+ }
+
+ // Get maximum number of allowed recipients
+ $sql = 'SELECT MIN(g.group_' . $setting . ') as min_setting, MAX(g.group_' . $setting . ') as max_setting
FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug
- WHERE ug.user_id = ' . $user->data['user_id'] . '
+ WHERE ug.user_id = ' . (int) $user_id . '
AND ug.user_pending = 0
AND ug.group_id = g.group_id';
$result = $db->sql_query($sql);
- $message_limit = (int) $db->sql_fetchfield('max_message_limit');
+ $row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
+ $max_setting = (int) $row['max_setting'];
+ $min_setting = (int) $row['min_setting'];
- $user->data['message_limit'] = (!$message_limit) ? $config['pm_max_msgs'] : $message_limit;
+ return ($min_setting > 0) ? $max_setting : 0;
}
/**
@@ -2151,7 +2185,10 @@ function set_user_message_limit()
*/
function get_recipient_strings($pm_by_id)
{
- global $db, $phpbb_root_path, $phpEx, $user;
+ global $db, $phpbb_root_path, $phpEx, $user, $phpbb_container;
+
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
$address_list = $recipient_list = $address = array();
@@ -2197,7 +2234,7 @@ function get_recipient_strings($pm_by_id)
{
if ($ug_type == 'g')
{
- $row['name'] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['name']] : $row['name'];
+ $row['name'] = $group_helper->get_name($row['name']);
}
$recipient_list[$ug_type][$row['id']] = array('name' => $row['name'], 'colour' => $row['colour']);
diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php
deleted file mode 100644
index f179b2fd70..0000000000
--- a/phpBB/includes/functions_upload.php
+++ /dev/null
@@ -1,1107 +0,0 @@
-<?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;
-}
-
-/**
-* Responsible for holding all file relevant information, as well as doing file-specific operations.
-* The {@link fileupload fileupload class} can be used to upload several files, each of them being this object to operate further on.
-*/
-class filespec
-{
- var $filename = '';
- var $realname = '';
- var $uploadname = '';
- var $mimetype = '';
- var $extension = '';
- var $filesize = 0;
- var $width = 0;
- var $height = 0;
- var $image_info = array();
-
- var $destination_file = '';
- var $destination_path = '';
-
- var $file_moved = false;
- var $init_error = false;
- var $local = false;
-
- var $error = array();
-
- var $upload = '';
-
- /**
- * The plupload object
- * @var \phpbb\plupload\plupload
- */
- protected $plupload;
-
- /**
- * phpBB Mimetype guesser
- * @var \phpbb\mimetype\guesser
- */
- protected $mimetype_guesser;
-
- /**
- * File Class
- * @access private
- */
- function filespec($upload_ary, $upload_namespace, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null)
- {
- if (!isset($upload_ary))
- {
- $this->init_error = true;
- return;
- }
-
- $this->filename = $upload_ary['tmp_name'];
- $this->filesize = $upload_ary['size'];
- $name = (STRIP) ? stripslashes($upload_ary['name']) : $upload_ary['name'];
- $name = trim(utf8_basename($name));
- $this->realname = $this->uploadname = $name;
- $this->mimetype = $upload_ary['type'];
-
- // Opera adds the name to the mime type
- $this->mimetype = (strpos($this->mimetype, '; name') !== false) ? str_replace(strstr($this->mimetype, '; name'), '', $this->mimetype) : $this->mimetype;
-
- if (!$this->mimetype)
- {
- $this->mimetype = 'application/octet-stream';
- }
-
- $this->extension = strtolower(self::get_extension($this->realname));
-
- // Try to get real filesize from temporary folder (not always working) ;)
- $this->filesize = (@filesize($this->filename)) ? @filesize($this->filename) : $this->filesize;
-
- $this->width = $this->height = 0;
- $this->file_moved = false;
-
- $this->local = (isset($upload_ary['local_mode'])) ? true : false;
- $this->upload = $upload_namespace;
- $this->plupload = $plupload;
- $this->mimetype_guesser = $mimetype_guesser;
- }
-
- /**
- * Cleans destination filename
- *
- * @param real|unique|unique_ext $mode real creates a realname, filtering some characters, lowering every character. Unique creates an unique filename
- * @param string $prefix Prefix applied to filename
- * @param string $user_id The user_id is only needed for when cleaning a user's avatar
- * @access public
- */
- function clean_filename($mode = 'unique', $prefix = '', $user_id = '')
- {
- if ($this->init_error)
- {
- return;
- }
-
- switch ($mode)
- {
- case 'real':
- // Remove every extension from filename (to not let the mime bug being exposed)
- if (strpos($this->realname, '.') !== false)
- {
- $this->realname = substr($this->realname, 0, strpos($this->realname, '.'));
- }
-
- // Replace any chars which may cause us problems with _
- $bad_chars = array("'", "\\", ' ', '/', ':', '*', '?', '"', '<', '>', '|');
-
- $this->realname = rawurlencode(str_replace($bad_chars, '_', strtolower($this->realname)));
- $this->realname = preg_replace("/%(\w{2})/", '_', $this->realname);
-
- $this->realname = $prefix . $this->realname . '.' . $this->extension;
- break;
-
- case 'unique':
- $this->realname = $prefix . md5(unique_id());
- break;
-
- case 'avatar':
- $this->extension = strtolower($this->extension);
- $this->realname = $prefix . $user_id . '.' . $this->extension;
-
- break;
-
- case 'unique_ext':
- default:
- $this->realname = $prefix . md5(unique_id()) . '.' . $this->extension;
- break;
- }
- }
-
- /**
- * Get property from file object
- */
- function get($property)
- {
- if ($this->init_error || !isset($this->$property))
- {
- return false;
- }
-
- return $this->$property;
- }
-
- /**
- * Check if file is an image (mimetype)
- *
- * @return true if it is an image, false if not
- */
- function is_image()
- {
- return (strpos($this->mimetype, 'image/') === 0);
- }
-
- /**
- * Check if the file got correctly uploaded
- *
- * @return true if it is a valid upload, false if not
- */
- function is_uploaded()
- {
- $is_plupload = $this->plupload && $this->plupload->is_active();
-
- if (!$this->local && !$is_plupload && !is_uploaded_file($this->filename))
- {
- return false;
- }
-
- if (($this->local || $is_plupload) && !file_exists($this->filename))
- {
- return false;
- }
-
- return true;
- }
-
- /**
- * Remove file
- */
- function remove()
- {
- if ($this->file_moved)
- {
- @unlink($this->destination_file);
- }
- }
-
- /**
- * Get file extension
- *
- * @param string Filename that needs to be checked
- * @return string Extension of the supplied filename
- */
- static public function get_extension($filename)
- {
- if (strpos($filename, '.') === false)
- {
- return '';
- }
-
- $filename = explode('.', $filename);
- return array_pop($filename);
- }
-
- /**
- * Get mimetype
- *
- * @param string $filename Filename that needs to be checked
- * @return string Mimetype of supplied filename
- */
- function get_mimetype($filename)
- {
- if ($this->mimetype_guesser !== null)
- {
- $mimetype = $this->mimetype_guesser->guess($filename, $this->uploadname);
-
- if ($mimetype !== 'application/octet-stream')
- {
- $this->mimetype = $mimetype;
- }
- }
-
- return $this->mimetype;
- }
-
- /**
- * Get filesize
- */
- function get_filesize($filename)
- {
- return @filesize($filename);
- }
-
-
- /**
- * Check the first 256 bytes for forbidden content
- */
- function check_content($disallowed_content)
- {
- if (empty($disallowed_content))
- {
- return true;
- }
-
- $fp = @fopen($this->filename, 'rb');
-
- if ($fp !== false)
- {
- $ie_mime_relevant = fread($fp, 256);
- fclose($fp);
- foreach ($disallowed_content as $forbidden)
- {
- if (stripos($ie_mime_relevant, '<' . $forbidden) !== false)
- {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Move file to destination folder
- * The phpbb_root_path variable will be applied to the destination path
- *
- * @param string $destination Destination path, for example $config['avatar_path']
- * @param bool $overwrite If set to true, an already existing file will be overwritten
- * @param bool $skip_image_check If set to true, the check for the file to be a valid image is skipped
- * @param string $chmod Permission mask for chmodding the file after a successful move. The mode entered here reflects the mode defined by {@link phpbb_chmod()}
- *
- * @access public
- */
- function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false)
- {
- global $user, $phpbb_root_path;
-
- if (sizeof($this->error))
- {
- return false;
- }
-
- $chmod = ($chmod === false) ? CHMOD_READ | CHMOD_WRITE : $chmod;
-
- // We need to trust the admin in specifying valid upload directories and an attacker not being able to overwrite it...
- $this->destination_path = $phpbb_root_path . $destination;
-
- // Check if the destination path exist...
- if (!file_exists($this->destination_path))
- {
- @unlink($this->filename);
- return false;
- }
-
- $upload_mode = (@ini_get('open_basedir') || @ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'on') ? 'move' : 'copy';
- $upload_mode = ($this->local) ? 'local' : $upload_mode;
- $this->destination_file = $this->destination_path . '/' . utf8_basename($this->realname);
-
- // Check if the file already exist, else there is something wrong...
- if (file_exists($this->destination_file) && !$overwrite)
- {
- @unlink($this->filename);
- $this->error[] = $user->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file);
- $this->file_moved = false;
- return false;
- }
- else
- {
- if (file_exists($this->destination_file))
- {
- @unlink($this->destination_file);
- }
-
- switch ($upload_mode)
- {
- case 'copy':
-
- if (!@copy($this->filename, $this->destination_file))
- {
- if (!@move_uploaded_file($this->filename, $this->destination_file))
- {
- $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
- }
- }
-
- break;
-
- case 'move':
-
- if (!@move_uploaded_file($this->filename, $this->destination_file))
- {
- if (!@copy($this->filename, $this->destination_file))
- {
- $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
- }
- }
-
- break;
-
- case 'local':
-
- if (!@copy($this->filename, $this->destination_file))
- {
- $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
- }
-
- break;
- }
-
- // Remove temporary filename
- @unlink($this->filename);
-
- if (sizeof($this->error))
- {
- return false;
- }
-
- phpbb_chmod($this->destination_file, $chmod);
- }
-
- // Try to get real filesize from destination folder
- $this->filesize = (@filesize($this->destination_file)) ? @filesize($this->destination_file) : $this->filesize;
-
- // Get mimetype of supplied file
- $this->mimetype = $this->get_mimetype($this->destination_file);
-
- if ($this->is_image() && !$skip_image_check)
- {
- $this->width = $this->height = 0;
-
- if (($this->image_info = @getimagesize($this->destination_file)) !== false)
- {
- $this->width = $this->image_info[0];
- $this->height = $this->image_info[1];
-
- if (!empty($this->image_info['mime']))
- {
- $this->mimetype = $this->image_info['mime'];
- }
-
- // Check image type
- $types = fileupload::image_types();
-
- if (!isset($types[$this->image_info[2]]) || !in_array($this->extension, $types[$this->image_info[2]]))
- {
- if (!isset($types[$this->image_info[2]]))
- {
- $this->error[] = sprintf($user->lang['IMAGE_FILETYPE_INVALID'], $this->image_info[2], $this->mimetype);
- }
- else
- {
- $this->error[] = sprintf($user->lang['IMAGE_FILETYPE_MISMATCH'], $types[$this->image_info[2]][0], $this->extension);
- }
- }
-
- // Make sure the dimensions match a valid image
- if (empty($this->width) || empty($this->height))
- {
- $this->error[] = $user->lang['ATTACHED_IMAGE_NOT_IMAGE'];
- }
- }
- else
- {
- $this->error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
- }
- }
-
- $this->file_moved = true;
- $this->additional_checks();
- unset($this->upload);
-
- return true;
- }
-
- /**
- * Performing additional checks
- */
- function additional_checks()
- {
- global $user;
-
- if (!$this->file_moved)
- {
- return false;
- }
-
- // Filesize is too big or it's 0 if it was larger than the maxsize in the upload form
- if ($this->upload->max_filesize && ($this->get('filesize') > $this->upload->max_filesize || $this->filesize == 0))
- {
- $max_filesize = get_formatted_filesize($this->upload->max_filesize, false);
-
- $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']);
-
- return false;
- }
-
- if (!$this->upload->valid_dimensions($this))
- {
- $this->error[] = $user->lang($this->upload->error_prefix . 'WRONG_SIZE',
- $user->lang('PIXELS', (int) $this->upload->min_width),
- $user->lang('PIXELS', (int) $this->upload->min_height),
- $user->lang('PIXELS', (int) $this->upload->max_width),
- $user->lang('PIXELS', (int) $this->upload->max_height),
- $user->lang('PIXELS', (int) $this->width),
- $user->lang('PIXELS', (int) $this->height));
-
- return false;
- }
-
- return true;
- }
-}
-
-/**
-* Class for assigning error messages before a real filespec class can be assigned
-*/
-class fileerror extends filespec
-{
- function fileerror($error_msg)
- {
- $this->error[] = $error_msg;
- }
-}
-
-/**
-* File upload class
-* Init class (all parameters optional and able to be set/overwritten separately) - scope is global and valid for all uploads
-*/
-class fileupload
-{
- var $allowed_extensions = array();
- var $disallowed_content = array('body', 'head', 'html', 'img', 'plaintext', 'a href', 'pre', 'script', 'table', 'title');
- var $max_filesize = 0;
- var $min_width = 0;
- var $min_height = 0;
- var $max_width = 0;
- var $max_height = 0;
- var $error_prefix = '';
-
- /** @var int Timeout for remote upload */
- var $upload_timeout = 6;
-
- /**
- * Init file upload class.
- *
- * @param string $error_prefix Used error messages will get prefixed by this string
- * @param array $allowed_extensions Array of allowed extensions, for example array('jpg', 'jpeg', 'gif', 'png')
- * @param int $max_filesize Maximum filesize
- * @param int $min_width Minimum image width (only checked for images)
- * @param int $min_height Minimum image height (only checked for images)
- * @param int $max_width Maximum image width (only checked for images)
- * @param int $max_height Maximum image height (only checked for images)
- * @param bool|array $disallowed_content If enabled, the first 256 bytes of the file must not
- * contain any of its values. Defaults to false.
- *
- */
- function fileupload($error_prefix = '', $allowed_extensions = false, $max_filesize = false, $min_width = false, $min_height = false, $max_width = false, $max_height = false, $disallowed_content = false)
- {
- $this->set_allowed_extensions($allowed_extensions);
- $this->set_max_filesize($max_filesize);
- $this->set_allowed_dimensions($min_width, $min_height, $max_width, $max_height);
- $this->set_error_prefix($error_prefix);
- $this->set_disallowed_content($disallowed_content);
- }
-
- /**
- * Reset vars
- */
- function reset_vars()
- {
- $this->max_filesize = 0;
- $this->min_width = $this->min_height = $this->max_width = $this->max_height = 0;
- $this->error_prefix = '';
- $this->allowed_extensions = array();
- $this->disallowed_content = array();
- }
-
- /**
- * Set allowed extensions
- */
- function set_allowed_extensions($allowed_extensions)
- {
- if ($allowed_extensions !== false && is_array($allowed_extensions))
- {
- $this->allowed_extensions = $allowed_extensions;
- }
- }
-
- /**
- * Set allowed dimensions
- */
- function set_allowed_dimensions($min_width, $min_height, $max_width, $max_height)
- {
- $this->min_width = (int) $min_width;
- $this->min_height = (int) $min_height;
- $this->max_width = (int) $max_width;
- $this->max_height = (int) $max_height;
- }
-
- /**
- * Set maximum allowed filesize
- */
- function set_max_filesize($max_filesize)
- {
- if ($max_filesize !== false && (int) $max_filesize)
- {
- $this->max_filesize = (int) $max_filesize;
- }
- }
-
- /**
- * Set disallowed strings
- */
- function set_disallowed_content($disallowed_content)
- {
- if ($disallowed_content !== false && is_array($disallowed_content))
- {
- $this->disallowed_content = array_diff($disallowed_content, array(''));
- }
- }
-
- /**
- * Set error prefix
- */
- function set_error_prefix($error_prefix)
- {
- $this->error_prefix = $error_prefix;
- }
-
- /**
- * Form upload method
- * Upload file from users harddisk
- *
- * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified)
- * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser
- * @param \phpbb\plupload\plupload $plupload The plupload object
- *
- * @return object $file Object "filespec" is returned, all further operations can be done with this object
- * @access public
- */
- function form_upload($form_name, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null)
- {
- global $user, $request;
-
- $upload = $request->file($form_name);
- unset($upload['local_mode']);
-
- if ($plupload)
- {
- $result = $plupload->handle_upload($form_name);
- if (is_array($result))
- {
- $upload = array_merge($upload, $result);
- }
- }
-
- $file = new filespec($upload, $this, $mimetype_guesser, $plupload);
-
- if ($file->init_error)
- {
- $file->error[] = '';
- return $file;
- }
-
- // Error array filled?
- if (isset($upload['error']))
- {
- $error = $this->assign_internal_error($upload['error']);
-
- if ($error !== false)
- {
- $file->error[] = $error;
- return $file;
- }
- }
-
- // Check if empty file got uploaded (not catched by is_uploaded_file)
- if (isset($upload['size']) && $upload['size'] == 0)
- {
- $file->error[] = $user->lang[$this->error_prefix . 'EMPTY_FILEUPLOAD'];
- return $file;
- }
-
- // PHP Upload filesize exceeded
- if ($file->get('filename') == 'none')
- {
- $max_filesize = @ini_get('upload_max_filesize');
- $unit = 'MB';
-
- if (!empty($max_filesize))
- {
- $unit = strtolower(substr($max_filesize, -1, 1));
- $max_filesize = (int) $max_filesize;
-
- $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB');
- }
-
- $file->error[] = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]);
- return $file;
- }
-
- // Not correctly uploaded
- if (!$file->is_uploaded())
- {
- $file->error[] = $user->lang[$this->error_prefix . 'NOT_UPLOADED'];
- return $file;
- }
-
- $this->common_checks($file);
-
- return $file;
- }
-
- /**
- * Move file from another location to phpBB
- */
- function local_upload($source_file, $filedata = false, \phpbb\mimetype\guesser $mimetype_guesser = null)
- {
- global $user, $request;
-
- $upload = array();
-
- $upload['local_mode'] = true;
- $upload['tmp_name'] = $source_file;
-
- if ($filedata === false)
- {
- $upload['name'] = utf8_basename($source_file);
- $upload['size'] = 0;
- }
- else
- {
- $upload['name'] = $filedata['realname'];
- $upload['size'] = $filedata['size'];
- $upload['type'] = $filedata['type'];
- }
-
- $file = new filespec($upload, $this, $mimetype_guesser);
-
- if ($file->init_error)
- {
- $file->error[] = '';
- return $file;
- }
-
- if (isset($upload['error']))
- {
- $error = $this->assign_internal_error($upload['error']);
-
- if ($error !== false)
- {
- $file->error[] = $error;
- return $file;
- }
- }
-
- // PHP Upload filesize exceeded
- if ($file->get('filename') == 'none')
- {
- $max_filesize = @ini_get('upload_max_filesize');
- $unit = 'MB';
-
- if (!empty($max_filesize))
- {
- $unit = strtolower(substr($max_filesize, -1, 1));
- $max_filesize = (int) $max_filesize;
-
- $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB');
- }
-
- $file->error[] = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]);
- return $file;
- }
-
- // Not correctly uploaded
- if (!$file->is_uploaded())
- {
- $file->error[] = $user->lang[$this->error_prefix . 'NOT_UPLOADED'];
- return $file;
- }
-
- $this->common_checks($file);
- $request->overwrite('local', $upload, \phpbb\request\request_interface::FILES);
-
- return $file;
- }
-
- /**
- * Remote upload method
- * Uploads file from given url
- *
- * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif
- * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser
- * @return object $file Object "filespec" is returned, all further operations can be done with this object
- * @access public
- */
- function remote_upload($upload_url, \phpbb\mimetype\guesser $mimetype_guesser = null)
- {
- global $user, $phpbb_root_path;
-
- $upload_ary = array();
- $upload_ary['local_mode'] = true;
-
- if (!preg_match('#^(https?://).*?\.(' . implode('|', $this->allowed_extensions) . ')$#i', $upload_url, $match))
- {
- $file = new fileerror($user->lang[$this->error_prefix . 'URL_INVALID']);
- return $file;
- }
-
- if (empty($match[2]))
- {
- $file = new fileerror($user->lang[$this->error_prefix . 'URL_INVALID']);
- return $file;
- }
-
- $url = parse_url($upload_url);
-
- $host = $url['host'];
- $path = $url['path'];
- $port = (!empty($url['port'])) ? (int) $url['port'] : 80;
-
- $upload_ary['type'] = 'application/octet-stream';
-
- $url['path'] = explode('.', $url['path']);
- $ext = array_pop($url['path']);
-
- $url['path'] = implode('', $url['path']);
- $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : '');
- $filename = $url['path'];
- $filesize = 0;
-
- $remote_max_filesize = $this->max_filesize;
- if (!$remote_max_filesize)
- {
- $max_filesize = @ini_get('upload_max_filesize');
-
- if (!empty($max_filesize))
- {
- $unit = strtolower(substr($max_filesize, -1, 1));
- $remote_max_filesize = (int) $max_filesize;
-
- switch ($unit)
- {
- case 'g':
- $remote_max_filesize *= 1024;
- // no break
- case 'm':
- $remote_max_filesize *= 1024;
- // no break
- case 'k':
- $remote_max_filesize *= 1024;
- // no break
- }
- }
- }
-
- $errno = 0;
- $errstr = '';
-
- if (!($fsock = @fsockopen($host, $port, $errno, $errstr)))
- {
- $file = new fileerror($user->lang[$this->error_prefix . 'NOT_UPLOADED']);
- return $file;
- }
-
- // Make sure $path not beginning with /
- if (strpos($path, '/') === 0)
- {
- $path = substr($path, 1);
- }
-
- fputs($fsock, 'GET /' . $path . " HTTP/1.1\r\n");
- fputs($fsock, "HOST: " . $host . "\r\n");
- fputs($fsock, "Connection: close\r\n\r\n");
-
- // Set a proper timeout for the socket
- socket_set_timeout($fsock, $this->upload_timeout);
-
- $get_info = false;
- $data = '';
- $length = false;
- $timer_stop = time() + $this->upload_timeout;
-
- while ((!$length || $filesize < $length) && !@feof($fsock))
- {
- if ($get_info)
- {
- if ($length)
- {
- // Don't attempt to read past end of file if server indicated length
- $block = @fread($fsock, min($length - $filesize, 1024));
- }
- else
- {
- $block = @fread($fsock, 1024);
- }
-
- $filesize += strlen($block);
-
- if ($remote_max_filesize && $filesize > $remote_max_filesize)
- {
- $max_filesize = get_formatted_filesize($remote_max_filesize, false);
-
- $file = new fileerror(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']));
- return $file;
- }
-
- $data .= $block;
- }
- else
- {
- $line = @fgets($fsock, 1024);
-
- if ($line == "\r\n")
- {
- $get_info = true;
- }
- else
- {
- if (stripos($line, 'content-type: ') !== false)
- {
- $upload_ary['type'] = rtrim(str_replace('content-type: ', '', strtolower($line)));
- }
- else if ($this->max_filesize && stripos($line, 'content-length: ') !== false)
- {
- $length = (int) str_replace('content-length: ', '', strtolower($line));
-
- if ($remote_max_filesize && $length && $length > $remote_max_filesize)
- {
- $max_filesize = get_formatted_filesize($remote_max_filesize, false);
-
- $file = new fileerror(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']));
- return $file;
- }
- }
- else if (stripos($line, '404 not found') !== false)
- {
- $file = new fileerror($user->lang[$this->error_prefix . 'URL_NOT_FOUND']);
- return $file;
- }
- }
- }
-
- $stream_meta_data = stream_get_meta_data($fsock);
-
- // Cancel upload if we exceed timeout
- if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop)
- {
- $file = new fileerror($user->lang[$this->error_prefix . 'REMOTE_UPLOAD_TIMEOUT']);
- return $file;
- }
- }
- @fclose($fsock);
-
- if (empty($data))
- {
- $file = new fileerror($user->lang[$this->error_prefix . 'EMPTY_REMOTE_DATA']);
- return $file;
- }
-
- $tmp_path = (!@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'off') ? false : $phpbb_root_path . 'cache';
- $filename = tempnam($tmp_path, unique_id() . '-');
-
- if (!($fp = @fopen($filename, 'wb')))
- {
- $file = new fileerror($user->lang[$this->error_prefix . 'NOT_UPLOADED']);
- return $file;
- }
-
- $upload_ary['size'] = fwrite($fp, $data);
- fclose($fp);
- unset($data);
-
- $upload_ary['tmp_name'] = $filename;
-
- $file = new filespec($upload_ary, $this, $mimetype_guesser);
- $this->common_checks($file);
-
- return $file;
- }
-
- /**
- * Assign internal error
- * @access private
- */
- function assign_internal_error($errorcode)
- {
- global $user;
-
- switch ($errorcode)
- {
- case 1:
- $max_filesize = @ini_get('upload_max_filesize');
- $unit = 'MB';
-
- if (!empty($max_filesize))
- {
- $unit = strtolower(substr($max_filesize, -1, 1));
- $max_filesize = (int) $max_filesize;
-
- $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB');
- }
-
- $error = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]);
- break;
-
- case 2:
- $max_filesize = get_formatted_filesize($this->max_filesize, false);
-
- $error = sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']);
- break;
-
- case 3:
- $error = $user->lang[$this->error_prefix . 'PARTIAL_UPLOAD'];
- break;
-
- case 4:
- $error = $user->lang[$this->error_prefix . 'NOT_UPLOADED'];
- break;
-
- case 6:
- $error = 'Temporary folder could not be found. Please check your PHP installation.';
- break;
-
- default:
- $error = false;
- break;
- }
-
- return $error;
- }
-
- /**
- * Perform common checks
- */
- function common_checks(&$file)
- {
- global $user;
-
- // Filesize is too big or it's 0 if it was larger than the maxsize in the upload form
- if ($this->max_filesize && ($file->get('filesize') > $this->max_filesize || $file->get('filesize') == 0))
- {
- $max_filesize = get_formatted_filesize($this->max_filesize, false);
-
- $file->error[] = sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']);
- }
-
- // check Filename
- if (preg_match("#[\\/:*?\"<>|]#i", $file->get('realname')))
- {
- $file->error[] = sprintf($user->lang[$this->error_prefix . 'INVALID_FILENAME'], $file->get('realname'));
- }
-
- // Invalid Extension
- if (!$this->valid_extension($file))
- {
- $file->error[] = sprintf($user->lang[$this->error_prefix . 'DISALLOWED_EXTENSION'], $file->get('extension'));
- }
-
- // MIME Sniffing
- if (!$this->valid_content($file))
- {
- $file->error[] = sprintf($user->lang[$this->error_prefix . 'DISALLOWED_CONTENT']);
- }
- }
-
- /**
- * Check for allowed extension
- */
- function valid_extension(&$file)
- {
- return (in_array($file->get('extension'), $this->allowed_extensions)) ? true : false;
- }
-
- /**
- * Check for allowed dimension
- */
- function valid_dimensions(&$file)
- {
- if (!$this->max_width && !$this->max_height && !$this->min_width && !$this->min_height)
- {
- return true;
- }
-
- if (($file->get('width') > $this->max_width && $this->max_width) ||
- ($file->get('height') > $this->max_height && $this->max_height) ||
- ($file->get('width') < $this->min_width && $this->min_width) ||
- ($file->get('height') < $this->min_height && $this->min_height))
- {
- return false;
- }
-
- return true;
- }
-
- /**
- * Check if form upload is valid
- */
- function is_valid($form_name)
- {
- global $request;
- $upload = $request->file($form_name);
-
- return (!empty($upload) && $upload['name'] !== 'none');
- }
-
-
- /**
- * Check for bad content (IE mime-sniffing)
- */
- function valid_content(&$file)
- {
- return ($file->check_content($this->disallowed_content));
- }
-
- /**
- * Get image type/extension mapping
- *
- * @return array Array containing the image types and their extensions
- */
- static public function image_types()
- {
- $result = array(
- IMAGETYPE_GIF => array('gif'),
- IMAGETYPE_JPEG => array('jpg', 'jpeg'),
- IMAGETYPE_PNG => array('png'),
- IMAGETYPE_SWF => array('swf'),
- IMAGETYPE_PSD => array('psd'),
- IMAGETYPE_BMP => array('bmp'),
- IMAGETYPE_TIFF_II => array('tif', 'tiff'),
- IMAGETYPE_TIFF_MM => array('tif', 'tiff'),
- IMAGETYPE_JPC => array('jpg', 'jpeg'),
- IMAGETYPE_JP2 => array('jpg', 'jpeg'),
- IMAGETYPE_JPX => array('jpg', 'jpeg'),
- IMAGETYPE_JB2 => array('jpg', 'jpeg'),
- IMAGETYPE_IFF => array('iff'),
- IMAGETYPE_WBMP => array('wbmp'),
- IMAGETYPE_XBM => array('xbm'),
- );
-
- if (defined('IMAGETYPE_SWC'))
- {
- $result[IMAGETYPE_SWC] = array('swc');
- }
-
- return $result;
- }
-}
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index c7234bb8e8..7620cf1ff7 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -502,6 +502,9 @@ function user_delete($mode, $user_ids, $retain_username = true)
$num_users_delta = 0;
+ // Get auth provider collection in case accounts might need to be unlinked
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
+
// Some things need to be done in the loop (if the query changes based
// on which user is currently being deleted)
$added_guest_posts = 0;
@@ -512,6 +515,38 @@ function user_delete($mode, $user_ids, $retain_username = true)
avatar_delete('user', $user_row);
}
+ // Unlink accounts
+ foreach ($provider_collection as $provider_name => $auth_provider)
+ {
+ $provider_data = $auth_provider->get_auth_link_data($user_id);
+
+ if ($provider_data !== null)
+ {
+ $link_data = array(
+ 'user_id' => $user_id,
+ 'link_method' => 'user_delete',
+ );
+
+ // BLOCK_VARS might contain hidden fields necessary for unlinking accounts
+ if (isset($provider_data['BLOCK_VARS']) && is_array($provider_data['BLOCK_VARS']))
+ {
+ foreach ($provider_data['BLOCK_VARS'] as $provider_service)
+ {
+ if (!array_key_exists('HIDDEN_FIELDS', $provider_service))
+ {
+ $provider_service['HIDDEN_FIELDS'] = array();
+ }
+
+ $auth_provider->unlink_account(array_merge($link_data, $provider_service['HIDDEN_FIELDS']));
+ }
+ }
+ else
+ {
+ $auth_provider->unlink_account($link_data);
+ }
+ }
+ }
+
// Decrement number of users if this user is active
if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE)
{
@@ -1385,7 +1420,7 @@ function user_ipwhois($ip)
$match = array();
// Test for referrals from $whois_host to other whois databases, roll on rwhois
- if (preg_match('#ReferralServer: whois://(.+)#im', $ipwhois, $match))
+ if (preg_match('#ReferralServer:[\x20]*whois://(.+)#im', $ipwhois, $match))
{
if (strpos($match[1], ':') !== false)
{
@@ -1647,89 +1682,37 @@ function validate_username($username, $allowed_username = false)
return 'INVALID_CHARS';
}
- $mbstring = $pcre = false;
-
- // generic UTF-8 character types supported?
- if (phpbb_pcre_utf8_support())
- {
- $pcre = true;
- }
- else if (function_exists('mb_ereg_match'))
- {
- mb_regex_encoding('UTF-8');
- $mbstring = true;
- }
-
switch ($config['allow_name_chars'])
{
case 'USERNAME_CHARS_ANY':
- $pcre = true;
$regex = '.+';
break;
case 'USERNAME_ALPHA_ONLY':
- $pcre = true;
$regex = '[A-Za-z0-9]+';
break;
case 'USERNAME_ALPHA_SPACERS':
- $pcre = true;
$regex = '[A-Za-z0-9-[\]_+ ]+';
break;
case 'USERNAME_LETTER_NUM':
- if ($pcre)
- {
- $regex = '[\p{Lu}\p{Ll}\p{N}]+';
- }
- else if ($mbstring)
- {
- $regex = '[[:upper:][:lower:][:digit:]]+';
- }
- else
- {
- $pcre = true;
- $regex = '[a-zA-Z0-9]+';
- }
+ $regex = '[\p{Lu}\p{Ll}\p{N}]+';
break;
case 'USERNAME_LETTER_NUM_SPACERS':
- if ($pcre)
- {
- $regex = '[-\]_+ [\p{Lu}\p{Ll}\p{N}]+';
- }
- else if ($mbstring)
- {
- $regex = '[-\]_+ \[[:upper:][:lower:][:digit:]]+';
- }
- else
- {
- $pcre = true;
- $regex = '[-\]_+ [a-zA-Z0-9]+';
- }
+ $regex = '[-\]_+ [\p{Lu}\p{Ll}\p{N}]+';
break;
case 'USERNAME_ASCII':
default:
- $pcre = true;
$regex = '[\x01-\x7F]+';
break;
}
- if ($pcre)
+ if (!preg_match('#^' . $regex . '$#u', $username))
{
- if (!preg_match('#^' . $regex . '$#u', $username))
- {
- return 'INVALID_CHARS';
- }
- }
- else if ($mbstring)
- {
- mb_ereg_search_init($username, '^' . $regex . '$');
- if (!mb_ereg_search())
- {
- return 'INVALID_CHARS';
- }
+ return 'INVALID_CHARS';
}
$sql = 'SELECT username
@@ -1784,35 +1767,10 @@ function validate_password($password)
return false;
}
- $pcre = $mbstring = false;
-
- // generic UTF-8 character types supported?
- if (phpbb_pcre_utf8_support())
- {
- $upp = '\p{Lu}';
- $low = '\p{Ll}';
- $num = '\p{N}';
- $sym = '[^\p{Lu}\p{Ll}\p{N}]';
- $pcre = true;
- }
- else if (function_exists('mb_ereg_match'))
- {
- mb_regex_encoding('UTF-8');
- $upp = '[[:upper:]]';
- $low = '[[:lower:]]';
- $num = '[[:digit:]]';
- $sym = '[^[:upper:][:lower:][:digit:]]';
- $mbstring = true;
- }
- else
- {
- $upp = '[A-Z]';
- $low = '[a-z]';
- $num = '[0-9]';
- $sym = '[^A-Za-z0-9]';
- $pcre = true;
- }
-
+ $upp = '\p{Lu}';
+ $low = '\p{Ll}';
+ $num = '\p{N}';
+ $sym = '[^\p{Lu}\p{Ll}\p{N}]';
$chars = array();
switch ($config['pass_complex'])
@@ -1835,24 +1793,11 @@ function validate_password($password)
$chars[] = $upp;
}
- if ($pcre)
- {
- foreach ($chars as $char)
- {
- if (!preg_match('#' . $char . '#u', $password))
- {
- return 'INVALID_CHARS';
- }
- }
- }
- else if ($mbstring)
+ foreach ($chars as $char)
{
- foreach ($chars as $char)
+ if (!preg_match('#' . $char . '#u', $password))
{
- if (mb_ereg($char, $password) === false)
- {
- return 'INVALID_CHARS';
- }
+ return 'INVALID_CHARS';
}
}
@@ -2270,6 +2215,9 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow
{
global $phpbb_root_path, $config, $db, $user, $file_upload, $phpbb_container, $phpbb_log;
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
$error = array();
// Attributes which also affect the users table
@@ -2521,7 +2469,7 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow
group_set_user_default($group_id, $user_ary, $sql_ary);
}
- $name = ($type == GROUP_SPECIAL) ? $user->lang['G_' . $name] : $name;
+ $name = $group_helper->get_name($name);
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, $log, false, array($name));
group_update_listings($group_id);
@@ -2923,6 +2871,19 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false,
// Clear permissions cache of relevant users
$auth->acl_clear_prefetch($user_id_ary);
+ /**
+ * Event after users are removed from a group
+ *
+ * @event core.group_delete_user_after
+ * @var int group_id ID of the group from which users are deleted
+ * @var string group_name Name of the group
+ * @var array user_id_ary IDs of the users which are removed
+ * @var array username_ary names of the users which are removed
+ * @since 3.1.7-RC1
+ */
+ $vars = array('group_id', 'group_name', 'user_id_ary', 'username_ary');
+ extract($phpbb_dispatcher->trigger_event('core.group_delete_user_after', compact($vars)));
+
if (!$group_name)
{
$group_name = get_group_name($group_id);
@@ -3375,7 +3336,7 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal
*/
function get_group_name($group_id)
{
- global $db, $user;
+ global $db, $user, $phpbb_container;
$sql = 'SELECT group_name, group_type
FROM ' . GROUPS_TABLE . '
@@ -3384,12 +3345,15 @@ function get_group_name($group_id)
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
- if (!$row || ($row['group_type'] == GROUP_SPECIAL && empty($user->lang)))
+ if (!$row)
{
return '';
}
- return ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
+ return $group_helper->get_name($row['group_name']);
}
/**
diff --git a/phpBB/includes/mcp/info/mcp_pm_reports.php b/phpBB/includes/mcp/info/mcp_pm_reports.php
index 6f8b8d9937..2a57c0c49a 100644
--- a/phpBB/includes/mcp/info/mcp_pm_reports.php
+++ b/phpBB/includes/mcp/info/mcp_pm_reports.php
@@ -19,9 +19,9 @@ class mcp_pm_reports_info
'filename' => 'mcp_pm_reports',
'title' => 'MCP_PM_REPORTS',
'modes' => array(
- 'pm_reports' => array('title' => 'MCP_PM_REPORTS_OPEN', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')),
- 'pm_reports_closed' => array('title' => 'MCP_PM_REPORTS_CLOSED', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')),
- 'pm_report_details' => array('title' => 'MCP_PM_REPORT_DETAILS', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')),
+ 'pm_reports' => array('title' => 'MCP_PM_REPORTS_OPEN', 'auth' => 'acl_m_pm_report', 'cat' => array('MCP_REPORTS')),
+ 'pm_reports_closed' => array('title' => 'MCP_PM_REPORTS_CLOSED', 'auth' => 'acl_m_pm_report', 'cat' => array('MCP_REPORTS')),
+ 'pm_report_details' => array('title' => 'MCP_PM_REPORT_DETAILS', 'auth' => 'acl_m_pm_report', 'cat' => array('MCP_REPORTS')),
),
);
}
diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php
index 9a280c0ea5..8237b834d6 100644
--- a/phpBB/includes/mcp/mcp_forum.php
+++ b/phpBB/includes/mcp/mcp_forum.php
@@ -35,15 +35,6 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
// merge_topic is the quickmod action, merge_topics is the mcp_forum action, and merge_select is the mcp_topic action
$merge_select = ($action == 'merge_select' || $action == 'merge_topic' || $action == 'merge_topics') ? true : false;
- if ($merge_select)
- {
- // Fixes a "bug" that makes forum_view use the same ordering as topic_view
- $request->overwrite('sk', null);
- $request->overwrite('sd', null);
- $request->overwrite('sk', null, \phpbb\request\request_interface::POST);
- $request->overwrite('sd', null, \phpbb\request\request_interface::POST);
- }
-
$forum_id = $forum_info['forum_id'];
$start = $request->variable('start', 0);
$topic_id_list = $request->variable('topic_id_list', array(0));
@@ -77,6 +68,30 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
break;
}
+ /**
+ * Get some data in order to execute other actions.
+ *
+ * @event core.mcp_forum_view_before
+ * @var string action The action
+ * @var array forum_info Array with forum infos
+ * @var int start Start value
+ * @var array topic_id_list Array of topics ids
+ * @var array post_id_list Array of posts ids
+ * @var array source_topic_ids Array of source topics ids
+ * @var int to_topic_id Array of destination topics ids
+ * @since 3.1.6-RC1
+ */
+ $vars = array(
+ 'action',
+ 'forum_info',
+ 'start',
+ 'topic_id_list',
+ 'post_id_list',
+ 'source_topic_ids',
+ 'to_topic_id',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_forum_view_before', compact($vars)));
+
/* @var $pagination \phpbb\pagination */
$pagination = $phpbb_container->get('pagination');
@@ -131,9 +146,10 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
'S_CAN_SYNC' => $auth->acl_get('m_', $forum_id),
'S_CAN_APPROVE' => $auth->acl_get('m_approve', $forum_id),
'S_MERGE_SELECT' => ($merge_select) ? true : false,
- 'S_CAN_MAKE_NORMAL' => $auth->acl_gets('f_sticky', 'f_announce', $forum_id),
+ 'S_CAN_MAKE_NORMAL' => $auth->acl_gets('f_sticky', 'f_announce', 'f_announce_global', $forum_id),
'S_CAN_MAKE_STICKY' => $auth->acl_get('f_sticky', $forum_id),
'S_CAN_MAKE_ANNOUNCE' => $auth->acl_get('f_announce', $forum_id),
+ 'S_CAN_MAKE_ANNOUNCE_GLOBAL' => $auth->acl_get('f_announce_global', $forum_id),
'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id),
'U_VIEW_FORUM_LOGS' => ($auth->acl_gets('a_', 'm_', $forum_id) && $module->loaded('logs')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=logs&amp;mode=forum_logs&amp;f=' . $forum_id) : '',
@@ -318,16 +334,20 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
));
}
+ $row_ary = $row;
/**
* Modify the topic data before it is assigned to the template in MCP
*
* @event core.mcp_view_forum_modify_topicrow
- * @var array row Array with topic data
+ * @var array row_ary Array with topic data
* @var array topic_row Template array with topic data
* @since 3.1.0-a1
+ * @change 3.2.0-a1 Replace row with row_ary
*/
- $vars = array('row', 'topic_row');
+ $vars = array('row_ary', 'topic_row');
extract($phpbb_dispatcher->trigger_event('core.mcp_view_forum_modify_topicrow', compact($vars)));
+ $row = $row_ary;
+ unset($row_ary);
$template->assign_block_vars('topicrow', $topic_row);
}
diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php
index ea17f55402..23a0604ccd 100644
--- a/phpBB/includes/mcp/mcp_front.php
+++ b/phpBB/includes/mcp/mcp_front.php
@@ -41,10 +41,27 @@ function mcp_front_view($id, $mode, $action)
if (!empty($forum_list))
{
- $sql = 'SELECT COUNT(post_id) AS total
- FROM ' . POSTS_TABLE . '
- WHERE ' . $db->sql_in_set('forum_id', $forum_list) . '
- AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE));
+ $sql_ary = array(
+ 'SELECT' => 'COUNT(post_id) AS total',
+ 'FROM' => array(
+ POSTS_TABLE => 'p',
+ ),
+ 'WHERE' => $db->sql_in_set('p.forum_id', $forum_list) . '
+ AND ' . $db->sql_in_set('p.post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE))
+ );
+
+ /**
+ * Allow altering the query to get the number of unapproved posts
+ *
+ * @event core.mcp_front_queue_unapproved_total_before
+ * @var int sql_ary Query to get the total number of unapproved posts
+ * @var array forum_list List of forums to look for unapproved posts
+ * @since 3.1.5-RC1
+ */
+ $vars = array('sql_ary', 'forum_list');
+ extract($phpbb_dispatcher->trigger_event('core.mcp_front_queue_unapproved_total_before', compact($vars)));
+
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query($sql);
$total = (int) $db->sql_fetchfield('total');
$db->sql_freeresult($result);
@@ -157,6 +174,18 @@ function mcp_front_view($id, $mode, $action)
AND r.pm_id = 0
AND r.report_closed = 0
AND ' . $db->sql_in_set('p.forum_id', $forum_list);
+
+ /**
+ * Alter sql query to count the number of reported posts
+ *
+ * @event core.mcp_front_reports_count_query_before
+ * @var int sql The query string used to get the number of reports that exist
+ * @var array forum_list List of forums that contain the posts
+ * @since 3.1.5-RC1
+ */
+ $vars = array('sql', 'forum_list');
+ extract($phpbb_dispatcher->trigger_event('core.mcp_front_reports_count_query_before', compact($vars)));
+
$result = $db->sql_query($sql);
$total = (int) $db->sql_fetchfield('total');
$db->sql_freeresult($result);
@@ -245,7 +274,7 @@ function mcp_front_view($id, $mode, $action)
}
// Latest 5 reported PMs
- if ($module->loaded('pm_reports') && $auth->acl_getf_global('m_report'))
+ if ($module->loaded('pm_reports') && $auth->acl_get('m_pm_report'))
{
$template->assign_var('S_SHOW_PM_REPORTS', true);
$user->add_lang(array('ucp'));
diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php
index 43327707b3..bf2d462801 100644
--- a/phpBB/includes/mcp/mcp_logs.php
+++ b/phpBB/includes/mcp/mcp_logs.php
@@ -205,7 +205,7 @@ class mcp_logs
{
$data = array();
- $checks = array('viewtopic', 'viewforum');
+ $checks = array('viewpost', 'viewtopic', 'viewforum');
foreach ($checks as $check)
{
if (isset($row[$check]) && $row[$check])
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index e3fbbc0418..b0579d8995 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -226,6 +226,31 @@ class mcp_main
break;
default:
+ if ($quickmod)
+ {
+ switch ($action)
+ {
+ case 'lock':
+ case 'unlock':
+ case 'make_announce':
+ case 'make_sticky':
+ case 'make_global':
+ case 'make_normal':
+ case 'make_onindex':
+ case 'move':
+ case 'fork':
+ case 'delete_topic':
+ trigger_error('TOPIC_NOT_EXIST');
+ break;
+
+ case 'lock_post':
+ case 'unlock_post':
+ case 'delete_post':
+ trigger_error('POST_NOT_EXIST');
+ break;
+ }
+ }
+
trigger_error('NO_MODE', E_USER_ERROR);
break;
}
@@ -297,6 +322,7 @@ function lock_unlock($action, $ids)
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_' . strtoupper($action), false, array(
'forum_id' => $row['forum_id'],
'topic_id' => $row['topic_id'],
+ 'post_id' => isset($row['post_id']) ? $row['post_id'] : 0,
$row['topic_title']
));
}
@@ -337,7 +363,7 @@ function change_topic_type($action, $topic_ids)
case 'make_global':
$new_topic_type = POST_GLOBAL;
- $check_acl = 'f_announce';
+ $check_acl = 'f_announce_global';
$l_new_type = (sizeof($topic_ids) == 1) ? 'MCP_MAKE_GLOBAL' : 'MCP_MAKE_GLOBALS';
break;
@@ -997,6 +1023,7 @@ function mcp_delete_post($post_ids, $is_soft = false, $soft_delete_reason = '',
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_SOFTDELETE_POST', false, array(
'forum_id' => $row['forum_id'],
'topic_id' => $row['topic_id'],
+ 'post_id' => $row['post_id'],
$row['post_subject'],
$post_username,
$soft_delete_reason
@@ -1046,6 +1073,7 @@ function mcp_delete_post($post_ids, $is_soft = false, $soft_delete_reason = '',
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_DELETE_POST', false, array(
'forum_id' => $row['forum_id'],
'topic_id' => $row['topic_id'],
+ 'post_id' => $row['post_id'],
$row['post_subject'],
$post_username,
$soft_delete_reason
@@ -1163,7 +1191,7 @@ function mcp_delete_post($post_ids, $is_soft = false, $soft_delete_reason = '',
function mcp_fork_topic($topic_ids)
{
global $auth, $user, $db, $template, $config;
- global $phpEx, $phpbb_root_path, $phpbb_log, $request;
+ global $phpEx, $phpbb_root_path, $phpbb_log, $request, $phpbb_dispatcher;
if (!phpbb_check_ids($topic_ids, TOPICS_TABLE, 'topic_id', array('m_')))
{
@@ -1241,7 +1269,7 @@ function mcp_fork_topic($topic_ids)
}
$error = false;
- $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
$search_mode = 'post';
if ($error)
diff --git a/phpBB/includes/mcp/mcp_pm_reports.php b/phpBB/includes/mcp/mcp_pm_reports.php
index cc8e48dc91..6e1d594135 100644
--- a/phpBB/includes/mcp/mcp_pm_reports.php
+++ b/phpBB/includes/mcp/mcp_pm_reports.php
@@ -97,7 +97,7 @@ class mcp_pm_reports
/* @var $phpbb_notifications \phpbb\notification\manager */
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->mark_notifications_read_by_parent('notification.type.report_pm', $report_id, $user->data['user_id']);
+ $phpbb_notifications->mark_notifications_by_parent('report_pm', $report_id, $user->data['user_id']);
$pm_id = $report['pm_id'];
$report_id = $report['report_id'];
diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php
index b70dfbb514..e59f0abb04 100644
--- a/phpBB/includes/mcp/mcp_post.php
+++ b/phpBB/includes/mcp/mcp_post.php
@@ -26,6 +26,7 @@ function mcp_post_details($id, $mode, $action)
{
global $phpEx, $phpbb_root_path, $config, $request;
global $template, $db, $user, $auth, $cache;
+ global $phpbb_dispatcher;
$user->add_lang('posting');
@@ -106,6 +107,21 @@ function mcp_post_details($id, $mode, $action)
}
break;
+
+ default:
+
+ /**
+ * This event allows you to handle custom post moderation options
+ *
+ * @event core.mcp_post_additional_options
+ * @var string action Post moderation action name
+ * @var array post_info Information on the affected post
+ * @since 3.1.5-RC1
+ */
+ $vars = array('action', 'post_info');
+ extract($phpbb_dispatcher->trigger_event('core.mcp_post_additional_options', compact($vars)));
+
+ break;
}
// Set some vars
@@ -197,7 +213,7 @@ function mcp_post_details($id, $mode, $action)
$l_deleted_by = '';
}
- $template->assign_vars(array(
+ $mcp_post_template_data = array(
'U_MCP_ACTION' => "$url&amp;i=main&amp;quickmod=1&amp;mode=post_details", // Use this for mode paramaters
'U_POST_ACTION' => "$url&amp;i=$id&amp;mode=post_details", // Use this for action parameters
'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&amp;p=$post_id&amp;f={$post_info['forum_id']}"),
@@ -249,7 +265,32 @@ function mcp_post_details($id, $mode, $action)
'U_LOOKUP_IP' => ($auth->acl_get('m_info', $post_info['forum_id'])) ? "$url&amp;i=$id&amp;mode=$mode&amp;lookup={$post_info['poster_ip']}#ip" : '',
'U_WHOIS' => ($auth->acl_get('m_info', $post_info['forum_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&amp;mode=$mode&amp;action=whois&amp;p=$post_id&amp;ip={$post_info['poster_ip']}") : '',
- ));
+ );
+
+ $s_additional_opts = false;
+
+ /**
+ * Event to add/modify MCP post template data
+ *
+ * @event core.mcp_post_template_data
+ * @var array post_info Array with the post information
+ * @var array mcp_post_template_data Array with the MCP post template data
+ * @var array attachments Array with the post attachments, if any
+ * @var bool s_additional_opts Must be set to true in extension if additional options are presented in MCP post panel
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'post_info',
+ 'mcp_post_template_data',
+ 'attachments',
+ 's_additional_opts',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_post_template_data', compact($vars)));
+
+ $template->assign_vars($mcp_post_template_data);
+ $template->assign_var('S_MCP_POST_ADDITIONAL_OPTS', $s_additional_opts);
+
+ unset($mcp_post_template_data);
// Get User Notes
$log_data = array();
@@ -420,7 +461,7 @@ function mcp_post_details($id, $mode, $action)
*/
function change_poster(&$post_info, $userdata)
{
- global $auth, $db, $config, $phpbb_root_path, $phpEx, $user, $phpbb_log;
+ global $auth, $db, $config, $phpbb_root_path, $phpEx, $user, $phpbb_log, $phpbb_dispatcher;
if (empty($userdata) || $userdata['user_id'] == $post_info['user_id'])
{
@@ -497,7 +538,7 @@ function change_poster(&$post_info, $userdata)
{
// We do some additional checks in the module to ensure it can actually be utilised
$error = false;
- $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
if (!$error && method_exists($search, 'destroy_cache'))
{
@@ -518,10 +559,22 @@ function change_poster(&$post_info, $userdata)
$post_info = $post_info[$post_id];
+ /**
+ * This event allows you to perform additional tasks after changing a post's poster
+ *
+ * @event core.mcp_change_poster_after
+ * @var array userdata Information on a post's new poster
+ * @var array post_info Information on the affected post
+ * @since 3.1.6-RC1
+ */
+ $vars = array('userdata', 'post_info');
+ extract($phpbb_dispatcher->trigger_event('core.mcp_change_poster_after', compact($vars)));
+
// Now add log entry
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_MCP_CHANGE_POSTER', false, array(
'forum_id' => $post_info['forum_id'],
'topic_id' => $post_info['topic_id'],
+ 'post_id' => $post_info['post_id'],
$post_info['topic_title'],
$from_username,
$to_username
diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php
index 84db205fec..132786818b 100644
--- a/phpBB/includes/mcp/mcp_queue.php
+++ b/phpBB/includes/mcp/mcp_queue.php
@@ -166,7 +166,7 @@ class mcp_queue
{
$post_id = (int) $topic_info[$topic_id]['topic_first_post_id'];
- $phpbb_notifications->mark_notifications_read('notification.type.topic_in_queue', $topic_id, $user->data['user_id']);
+ $phpbb_notifications->mark_notifications('topic_in_queue', $topic_id, $user->data['user_id']);
}
else
{
@@ -174,7 +174,7 @@ class mcp_queue
}
}
- $phpbb_notifications->mark_notifications_read('notification.type.post_in_queue', $post_id, $user->data['user_id']);
+ $phpbb_notifications->mark_notifications('post_in_queue', $post_id, $user->data['user_id']);
$post_info = phpbb_get_post_data(array($post_id), 'm_approve', true);
@@ -284,6 +284,7 @@ class mcp_queue
$template->assign_vars(array(
'S_MCP_QUEUE' => true,
'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&amp;p=$post_id&amp;f=$forum_id"),
+ 'S_CAN_DELETE_POST' => $auth->acl_get('m_delete', $post_info['forum_id']),
'S_CAN_VIEWIP' => $auth->acl_get('m_info', $post_info['forum_id']),
'S_POST_REPORTED' => $post_info['post_reported'],
'S_POST_UNAPPROVED' => $post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE,
@@ -407,7 +408,7 @@ class mcp_queue
$forum_options = '<option value="0"' . (($forum_id == 0) ? ' selected="selected"' : '') . '>' . $user->lang['ALL_FORUMS'] . '</option>';
foreach ($forum_list_approve as $row)
{
- $forum_options .= '<option value="' . $row['forum_id'] . '"' . (($forum_id == $row['forum_id']) ? ' selected="selected"' : '') . '>' . str_repeat('&nbsp; &nbsp;', $row['padding']) . $row['forum_name'] . '</option>';
+ $forum_options .= '<option value="' . $row['forum_id'] . '"' . (($forum_id == $row['forum_id']) ? ' selected="selected"' : '') . '>' . str_repeat('&nbsp; &nbsp;', $row['padding']) . truncate_string($row['forum_name'], 30, 255, false, $user->lang['ELLIPSIS']) . '</option>';
}
$sort_days = $total = 0;
@@ -678,6 +679,7 @@ class mcp_queue
$approve_log[] = array(
'forum_id' => $post_data['forum_id'],
'topic_id' => $post_data['topic_id'],
+ 'post_id' => $post_id,
'post_subject' => $post_data['post_subject'],
);
}
@@ -694,6 +696,7 @@ class mcp_queue
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_POST_' . strtoupper($action) . 'D', false, array(
'forum_id' => $log_data['forum_id'],
'topic_id' => $log_data['topic_id'],
+ 'post_id' => $log_data['post_id'],
$log_data['post_subject']
));
}
@@ -738,7 +741,7 @@ class mcp_queue
$phpbb_notifications->add_notifications(array('notification.type.quote'), $post_data);
$phpbb_notifications->delete_notifications('notification.type.post_in_queue', $post_id);
- $phpbb_notifications->mark_notifications_read(array(
+ $phpbb_notifications->mark_notifications(array(
'notification.type.quote',
'notification.type.bookmark',
'notification.type.post',
@@ -974,8 +977,8 @@ class mcp_queue
), $topic_data);
}
- $phpbb_notifications->mark_notifications_read('notification.type.quote', $topic_data['post_id'], $user->data['user_id']);
- $phpbb_notifications->mark_notifications_read('notification.type.topic', $topic_id, $user->data['user_id']);
+ $phpbb_notifications->mark_notifications('quote', $topic_data['post_id'], $user->data['user_id']);
+ $phpbb_notifications->mark_notifications('topic', $topic_id, $user->data['user_id']);
if ($notify_poster)
{
@@ -1267,7 +1270,7 @@ class mcp_queue
continue;
}
- $post_data['disapprove_reason'] = '';
+ $post_data['disapprove_reason'] = $disapprove_reason;
if (isset($disapprove_reason_lang))
{
// Okay we need to get the reason from the posters language
@@ -1402,11 +1405,6 @@ class mcp_queue
}
else
{
- if (!function_exists('display_reasons'))
- {
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
- }
-
$show_notify = false;
foreach ($post_info as $post_data)
@@ -1426,7 +1424,7 @@ class mcp_queue
$confirm_template = 'mcp_approve.html';
if ($is_disapproving)
{
- display_reasons($reason_id);
+ $phpbb_container->get('phpbb.report.report_reason_list_provider')->display_reasons($reason_id);
}
else
{
diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php
index bcfbd25c0f..45265c89e7 100644
--- a/phpBB/includes/mcp/mcp_reports.php
+++ b/phpBB/includes/mcp/mcp_reports.php
@@ -74,17 +74,66 @@ class mcp_reports
// closed reports are accessed by report id
$report_id = $request->variable('r', 0);
- $sql = 'SELECT r.post_id, r.user_id, r.report_id, r.report_closed, report_time, r.report_text, r.reported_post_text, r.reported_post_uid, r.reported_post_bitfield, r.reported_post_enable_magic_url, r.reported_post_enable_smilies, r.reported_post_enable_bbcode, rr.reason_title, rr.reason_description, u.username, u.username_clean, u.user_colour
- FROM ' . REPORTS_TABLE . ' r, ' . REPORTS_REASONS_TABLE . ' rr, ' . USERS_TABLE . ' u
- WHERE ' . (($report_id) ? 'r.report_id = ' . $report_id : "r.post_id = $post_id") . '
+ $sql_ary = array(
+ 'SELECT' => 'r.post_id, r.user_id, r.report_id, r.report_closed, report_time, r.report_text, r.reported_post_text, r.reported_post_uid, r.reported_post_bitfield, r.reported_post_enable_magic_url, r.reported_post_enable_smilies, r.reported_post_enable_bbcode, rr.reason_title, rr.reason_description, u.username, u.username_clean, u.user_colour',
+
+ 'FROM' => array(
+ REPORTS_TABLE => 'r',
+ REPORTS_REASONS_TABLE => 'rr',
+ USERS_TABLE => 'u',
+ ),
+
+ 'WHERE' => (($report_id) ? 'r.report_id = ' . $report_id : "r.post_id = $post_id") . '
AND rr.reason_id = r.reason_id
AND r.user_id = u.user_id
- AND r.pm_id = 0
- ORDER BY report_closed ASC';
+ AND r.pm_id = 0',
+
+ 'ORDER_BY' => 'report_closed ASC',
+ );
+
+ /**
+ * Allow changing the query to obtain the user-submitted report.
+ *
+ * @event core.mcp_reports_report_details_query_before
+ * @var array sql_ary The array in the format of the query builder with the query
+ * @var mixed forum_id The forum_id, the number in the f GET parameter
+ * @var int post_id The post_id of the report being viewed (if 0, it is meaningless)
+ * @var int report_id The report_id of the report being viewed
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'sql_ary',
+ 'forum_id',
+ 'post_id',
+ 'report_id',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_reports_report_details_query_before', compact($vars)));
+
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query_limit($sql, 1);
$report = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
+ /**
+ * Allow changing the data obtained from the user-submitted report.
+ *
+ * @event core.mcp_reports_report_details_query_after
+ * @var array sql_ary The array in the format of the query builder with the query that had been executted
+ * @var mixed forum_id The forum_id, the number in the f GET parameter
+ * @var int post_id The post_id of the report being viewed (if 0, it is meaningless)
+ * @var int report_id The report_id of the report being viewed
+ * @var int report The query's resulting row.
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'sql_ary',
+ 'forum_id',
+ 'post_id',
+ 'report_id',
+ 'report',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_reports_report_details_query_after', compact($vars)));
+
if (!$report)
{
trigger_error('NO_REPORT');
@@ -93,7 +142,7 @@ class mcp_reports
/* @var $phpbb_notifications \phpbb\notification\manager */
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->mark_notifications_read('notification.type.report_post', $post_id, $user->data['user_id']);
+ $phpbb_notifications->mark_notifications('report_post', $post_id, $user->data['user_id']);
if (!$report_id && $report['report_closed'])
{
@@ -491,6 +540,7 @@ function close_report($report_id_list, $mode, $action, $pm = false)
{
$post_id_list[] = $row[$id_column];
}
+ $db->sql_freeresult($result);
$post_id_list = array_unique($post_id_list);
if ($pm)
@@ -666,6 +716,7 @@ function close_report($report_id_list, $mode, $action, $pm = false)
$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_REPORT_' . strtoupper($action) . 'D', false, array(
'forum_id' => $post_info[$report['post_id']]['forum_id'],
'topic_id' => $post_info[$report['post_id']]['topic_id'],
+ 'post_id' => $report['post_id'],
$post_info[$report['post_id']]['post_subject']
));
$phpbb_notifications->delete_notifications('notification.type.report_post', $report['post_id']);
diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php
index 66bcdad72c..70794312f4 100644
--- a/phpBB/includes/mcp/mcp_topic.php
+++ b/phpBB/includes/mcp/mcp_topic.php
@@ -196,6 +196,30 @@ function mcp_topic_view($id, $mode, $action)
}
}
+ /**
+ * 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 $i => $row)
{
$message = $row['post_text'];
diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php
index 970bdc6174..d4c5486ed4 100644
--- a/phpBB/includes/mcp/mcp_warn.php
+++ b/phpBB/includes/mcp/mcp_warn.php
@@ -589,6 +589,7 @@ function add_warning($user_row, $warning, $send_pm = true, $post_id = 0)
$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']
));
}
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php
index ccb953adbe..059037168d 100644
--- a/phpBB/includes/message_parser.php
+++ b/phpBB/includes/message_parser.php
@@ -21,6 +21,19 @@ if (!defined('IN_PHPBB'))
if (!class_exists('bbcode'))
{
+ // The following lines are for extensions which include message_parser.php
+ // while $phpbb_root_path and $phpEx are out of the script scope
+ // which may lead to the 'Undefined variable' and 'failed to open stream' errors
+ if (!isset($phpbb_root_path))
+ {
+ global $phpbb_root_path;
+ }
+
+ if (!isset($phpEx))
+ {
+ global $phpEx;
+ }
+
include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
}
@@ -70,7 +83,14 @@ class bbcode_firstpass extends bbcode
// it should not demand recompilation
if (preg_match($regexp, $this->message))
{
- $this->message = preg_replace($regexp, $replacement, $this->message);
+ if (is_callable($replacement))
+ {
+ $this->message = preg_replace_callback($regexp, $replacement, $this->message);
+ }
+ else
+ {
+ $this->message = preg_replace($regexp, $replacement, $this->message);
+ }
$bitfield->set($bbcode_data['bbcode_id']);
}
}
@@ -110,25 +130,82 @@ class bbcode_firstpass extends bbcode
static $rowset;
+ $bbcode_class = $this;
+
// This array holds all bbcode data. BBCodes will be processed in this
// order, so it is important to keep [code] in first position and
// [quote] in second position.
// To parse multiline URL we enable dotall option setting only for URL text
// but not for link itself, thus [url][/url] is not affected.
+ //
+ // To perform custom validation in extension, use $this->validate_bbcode_by_extension()
+ // method which accepts variable number of parameters
$this->bbcodes = array(
- 'code' => array('bbcode_id' => 8, 'regexp' => array('#\[code(?:=([a-z]+))?\](.+\[/code\])#uise' => "\$this->bbcode_code('\$1', '\$2')")),
- 'quote' => array('bbcode_id' => 0, 'regexp' => array('#\[quote(?:=&quot;(.*?)&quot;)?\](.+)\[/quote\]#uise' => "\$this->bbcode_quote('\$0')")),
- 'attachment' => array('bbcode_id' => 12, 'regexp' => array('#\[attachment=([0-9]+)\](.*?)\[/attachment\]#uise' => "\$this->bbcode_attachment('\$1', '\$2')")),
- 'b' => array('bbcode_id' => 1, 'regexp' => array('#\[b\](.*?)\[/b\]#uise' => "\$this->bbcode_strong('\$1')")),
- 'i' => array('bbcode_id' => 2, 'regexp' => array('#\[i\](.*?)\[/i\]#uise' => "\$this->bbcode_italic('\$1')")),
- 'url' => array('bbcode_id' => 3, 'regexp' => array('#\[url(=(.*))?\](?(1)((?s).*(?-s))|(.*))\[/url\]#uiUe' => "\$this->validate_url('\$2', ('\$3') ? '\$3' : '\$4')")),
- 'img' => array('bbcode_id' => 4, 'regexp' => array('#\[img\](.*)\[/img\]#uiUe' => "\$this->bbcode_img('\$1')")),
- 'size' => array('bbcode_id' => 5, 'regexp' => array('#\[size=([\-\+]?\d+)\](.*?)\[/size\]#uise' => "\$this->bbcode_size('\$1', '\$2')")),
- 'color' => array('bbcode_id' => 6, 'regexp' => array('!\[color=(#[0-9a-f]{3}|#[0-9a-f]{6}|[a-z\-]+)\](.*?)\[/color\]!uise' => "\$this->bbcode_color('\$1', '\$2')")),
- 'u' => array('bbcode_id' => 7, 'regexp' => array('#\[u\](.*?)\[/u\]#uise' => "\$this->bbcode_underline('\$1')")),
- 'list' => array('bbcode_id' => 9, 'regexp' => array('#\[list(?:=(?:[a-z0-9]|disc|circle|square))?].*\[/list]#uise' => "\$this->bbcode_parse_list('\$0')")),
- 'email' => array('bbcode_id' => 10, 'regexp' => array('#\[email=?(.*?)?\](.*?)\[/email\]#uise' => "\$this->validate_email('\$1', '\$2')")),
- 'flash' => array('bbcode_id' => 11, 'regexp' => array('#\[flash=([0-9]+),([0-9]+)\](.*?)\[/flash\]#uie' => "\$this->bbcode_flash('\$1', '\$2', '\$3')"))
+ 'code' => array('bbcode_id' => 8, 'regexp' => array('#\[code(?:=([a-z]+))?\](.+\[/code\])#uis' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->bbcode_code($match[1], $match[2]);
+ }
+ )),
+ 'quote' => array('bbcode_id' => 0, 'regexp' => array('#\[quote(?:=&quot;(.*?)&quot;)?\](.+)\[/quote\]#uis' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->bbcode_quote($match[0]);
+ }
+ )),
+ 'attachment' => array('bbcode_id' => 12, 'regexp' => array('#\[attachment=([0-9]+)\](.*?)\[/attachment\]#uis' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->bbcode_attachment($match[1], $match[2]);
+ }
+ )),
+ 'b' => array('bbcode_id' => 1, 'regexp' => array('#\[b\](.*?)\[/b\]#uis' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->bbcode_strong($match[1]);
+ }
+ )),
+ 'i' => array('bbcode_id' => 2, 'regexp' => array('#\[i\](.*?)\[/i\]#uis' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->bbcode_italic($match[1]);
+ }
+ )),
+ 'url' => array('bbcode_id' => 3, 'regexp' => array('#\[url(=(.*))?\](?(1)((?s).*(?-s))|(.*))\[/url\]#uiU' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->validate_url($match[2], ($match[3]) ? $match[3] : $match[4]);
+ }
+ )),
+ 'img' => array('bbcode_id' => 4, 'regexp' => array('#\[img\](.*)\[/img\]#uiU' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->bbcode_img($match[1]);
+ }
+ )),
+ 'size' => array('bbcode_id' => 5, 'regexp' => array('#\[size=([\-\+]?\d+)\](.*?)\[/size\]#uis' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->bbcode_size($match[1], $match[2]);
+ }
+ )),
+ 'color' => array('bbcode_id' => 6, 'regexp' => array('!\[color=(#[0-9a-f]{3}|#[0-9a-f]{6}|[a-z\-]+)\](.*?)\[/color\]!uis' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->bbcode_color($match[1], $match[2]);
+ }
+ )),
+ 'u' => array('bbcode_id' => 7, 'regexp' => array('#\[u\](.*?)\[/u\]#uis' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->bbcode_underline($match[1]);
+ }
+ )),
+ 'list' => array('bbcode_id' => 9, 'regexp' => array('#\[list(?:=(?:[a-z0-9]|disc|circle|square))?].*\[/list]#uis' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->bbcode_parse_list($match[0]);
+ }
+ )),
+ 'email' => array('bbcode_id' => 10, 'regexp' => array('#\[email=?(.*?)?\](.*?)\[/email\]#uis' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->validate_email($match[1], $match[2]);
+ }
+ )),
+ 'flash' => array('bbcode_id' => 11, 'regexp' => array('#\[flash=([0-9]+),([0-9]+)\](.*?)\[/flash\]#ui' => function ($match) use($bbcode_class)
+ {
+ return $bbcode_class->bbcode_flash($match[1], $match[2], $match[3]);
+ }
+ ))
);
// Zero the parsed items array
@@ -326,22 +403,23 @@ class bbcode_firstpass extends bbcode
if ($config['max_' . $this->mode . '_img_height'] || $config['max_' . $this->mode . '_img_width'])
{
- $stats = @getimagesize(htmlspecialchars_decode($in));
+ $imagesize = new \FastImageSize\FastImageSize();
+ $size_info = $imagesize->getImageSize(htmlspecialchars_decode($in));
- if ($stats === false)
+ if ($size_info === false)
{
$error = true;
$this->warn_msg[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
}
else
{
- if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $stats[1])
+ if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $size_info['height'])
{
$error = true;
$this->warn_msg[] = $user->lang('MAX_IMG_HEIGHT_EXCEEDED', (int) $config['max_' . $this->mode . '_img_height']);
}
- if ($config['max_' . $this->mode . '_img_width'] && $config['max_' . $this->mode . '_img_width'] < $stats[0])
+ if ($config['max_' . $this->mode . '_img_width'] && $config['max_' . $this->mode . '_img_width'] < $size_info['width'])
{
$error = true;
$this->warn_msg[] = $user->lang('MAX_IMG_WIDTH_EXCEEDED', (int) $config['max_' . $this->mode . '_img_width']);
@@ -730,7 +808,9 @@ class bbcode_firstpass extends bbcode
}
// To let the parser not catch tokens within quote_username quotes we encode them before we start this...
- $in = preg_replace('#quote=&quot;(.*?)&quot;\]#ie', "'quote=&quot;' . str_replace(array('[', ']', '\\\"'), array('&#91;', '&#93;', '\"'), '\$1') . '&quot;]'", $in);
+ $in = preg_replace_callback('#quote=&quot;(.*?)&quot;\]#i', function ($match) {
+ return 'quote=&quot;' . str_replace(array('[', ']', '\\\"'), array('&#91;', '&#93;', '\"'), $match[1]) . '&quot;]';
+ }, $in);
$tok = ']';
$out = '[';
@@ -775,28 +855,6 @@ class bbcode_firstpass extends bbcode
else if (preg_match('#^quote(?:=&quot;(.*?)&quot;)?$#is', $buffer, $m) && substr($out, -1, 1) == '[')
{
$this->parsed_items['quote']++;
-
- // the buffer holds a valid opening tag
- if ($config['max_quote_depth'] && sizeof($close_tags) >= $config['max_quote_depth'])
- {
- if ($config['max_quote_depth'] == 1)
- {
- // Depth 1 - no nesting is allowed
- $error_ary['quote_depth'] = $user->lang('QUOTE_NO_NESTING');
- }
- else
- {
- // There are too many nested quotes
- $error_ary['quote_depth'] = $user->lang('QUOTE_DEPTH_EXCEEDED', (int) $config['max_quote_depth']);
- }
-
- $out .= $buffer . $tok;
- $tok = '[]';
- $buffer = '';
-
- continue;
- }
-
array_push($close_tags, '/quote:' . $this->bbcode_uid);
if (isset($m[1]) && $m[1])
@@ -1083,12 +1141,6 @@ class parse_message extends bbcode_firstpass
protected $plupload;
/**
- * The mimetype guesser object used for attachment mimetypes
- * @var \phpbb\mimetype\guesser
- */
- protected $mimetype_guesser;
-
- /**
* Init - give message here or manually
*/
function parse_message($message = '')
@@ -1103,7 +1155,7 @@ class parse_message extends bbcode_firstpass
*/
function parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $update_this_message = true, $mode = 'post')
{
- global $config, $db, $user, $phpbb_dispatcher;
+ global $config, $db, $user, $phpbb_dispatcher, $phpbb_container;
$this->mode = $mode;
@@ -1132,12 +1184,6 @@ class parse_message extends bbcode_firstpass
$this->decode_message();
}
- // Do some general 'cleanup' first before processing message,
- // e.g. remove excessive newlines(?), smilies(?)
- $match = array('#(script|about|applet|activex|chrome):#i');
- $replace = array("\\1&#058;");
- $this->message = preg_replace($match, $replace, trim($this->message));
-
// Store message length...
$message_length = ($mode == 'post') ? utf8_strlen($this->message) : utf8_strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#ius', ' ', $this->message));
@@ -1210,55 +1256,34 @@ class parse_message extends bbcode_firstpass
return (!$update_this_message) ? $return_message : $this->warn_msg;
}
- // Prepare BBcode (just prepares some tags for better parsing)
- if ($allow_bbcode && strpos($this->message, '[') !== false)
- {
- $this->bbcode_init();
- $disallow = array('img', 'flash', 'quote', 'url');
- foreach ($disallow as $bool)
- {
- if (!${'allow_' . $bool . '_bbcode'})
- {
- $this->bbcodes[$bool]['disabled'] = true;
- }
- }
-
- $this->prepare_bbcodes();
- }
+ // Get the parser
+ $parser = $phpbb_container->get('text_formatter.parser');
- // Parse smilies
- if ($allow_smilies)
- {
- $this->smilies($config['max_' . $mode . '_smilies']);
- }
+ // Set the parser's options
+ ($allow_bbcode) ? $parser->enable_bbcodes() : $parser->disable_bbcodes();
+ ($allow_magic_url) ? $parser->enable_magic_url() : $parser->disable_magic_url();
+ ($allow_smilies) ? $parser->enable_smilies() : $parser->disable_smilies();
+ ($allow_img_bbcode) ? $parser->enable_bbcode('img') : $parser->disable_bbcode('img');
+ ($allow_flash_bbcode) ? $parser->enable_bbcode('flash') : $parser->disable_bbcode('flash');
+ ($allow_quote_bbcode) ? $parser->enable_bbcode('quote') : $parser->disable_bbcode('quote');
+ ($allow_url_bbcode) ? $parser->enable_bbcode('url') : $parser->disable_bbcode('url');
- $num_urls = 0;
+ // Set some config values
+ $parser->set_vars(array(
+ 'max_font_size' => $config['max_' . $this->mode . '_font_size'],
+ 'max_img_height' => $config['max_' . $this->mode . '_img_height'],
+ 'max_img_width' => $config['max_' . $this->mode . '_img_width'],
+ 'max_smilies' => $config['max_' . $this->mode . '_smilies'],
+ 'max_urls' => $config['max_' . $this->mode . '_urls']
+ ));
- // Parse BBCode
- if ($allow_bbcode && strpos($this->message, '[') !== false)
- {
- $this->parse_bbcode();
- $num_urls += $this->parsed_items['url'];
- }
+ // Parse this message
+ $this->message = $parser->parse(htmlspecialchars_decode($this->message, ENT_QUOTES));
- // Parse URL's
- if ($allow_magic_url)
+ // Remove quotes that are nested too deep
+ if ($config['max_quote_depth'] > 0)
{
- $this->magic_url(generate_board_url());
-
- if ($config['max_' . $mode . '_urls'])
- {
- $num_urls += preg_match_all('#\<!-- ([lmwe]) --\>.*?\<!-- \1 --\>#', $this->message, $matches);
- }
- }
-
- // Check for out-of-bounds characters that are currently
- // not supported by utf8_bin in MySQL
- if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $this->message, $matches))
- {
- $character_list = implode('<br />', $matches[0]);
- $this->warn_msg[] = $user->lang('UNSUPPORTED_CHARACTERS_MESSAGE', $character_list);
- return $update_this_message ? $this->warn_msg : $return_message;
+ $this->remove_nested_quotes($config['max_quote_depth']);
}
// Check for "empty" message. We do not check here for maximum length, because bbcode, smilies, etc. can add to the length.
@@ -1269,10 +1294,27 @@ class parse_message extends bbcode_firstpass
return (!$update_this_message) ? $return_message : $this->warn_msg;
}
- // Check number of links
- if ($config['max_' . $mode . '_urls'] && $num_urls > $config['max_' . $mode . '_urls'])
+ // Remove quotes that are nested too deep
+ if ($config['max_quote_depth'] > 0)
{
- $this->warn_msg[] = sprintf($user->lang['TOO_MANY_URLS'], $config['max_' . $mode . '_urls']);
+ $this->message = $phpbb_container->get('text_formatter.utils')->remove_bbcode(
+ $this->message,
+ 'quote',
+ $config['max_quote_depth']
+ );
+ }
+
+ // Check for errors
+ $errors = $parser->get_errors();
+ if ($errors)
+ {
+ foreach ($errors as $i => $args)
+ {
+ // Translate each error with $user->lang()
+ $errors[$i] = call_user_func_array(array($user, 'lang'), $args);
+ }
+ $this->warn_msg = array_merge($this->warn_msg, $errors);
+
return (!$update_this_message) ? $return_message : $this->warn_msg;
}
@@ -1292,7 +1334,7 @@ class parse_message extends bbcode_firstpass
*/
function format_display($allow_bbcode, $allow_magic_url, $allow_smilies, $update_this_message = true)
{
- global $phpbb_dispatcher;
+ global $phpbb_container, $phpbb_dispatcher;
// If false, then the parsed message get returned but internal message not processed.
if (!$update_this_message)
@@ -1301,26 +1343,48 @@ class parse_message extends bbcode_firstpass
$return_message = &$this->message;
}
- if ($this->message_status == 'plain')
+ $text = $this->message;
+ $uid = $this->bbcode_uid;
+
+ /**
+ * Event to modify the text before it is parsed
+ *
+ * @event core.modify_format_display_text_before
+ * @var string text The message text to parse
+ * @var string uid The bbcode uid
+ * @var bool allow_bbcode Do we allow bbcodes
+ * @var bool allow_magic_url Do we allow magic urls
+ * @var bool allow_smilies Do we allow smilies
+ * @var bool update_this_message Do we update the internal message
+ * with the parsed result
+ * @since 3.1.6-RC1
+ */
+ $vars = array('text', 'uid', 'allow_bbcode', 'allow_magic_url', 'allow_smilies', 'update_this_message');
+ extract($phpbb_dispatcher->trigger_event('core.modify_format_display_text_before', compact($vars)));
+
+ $this->message = $text;
+ $this->bbcode_uid = $uid;
+ unset($text, $uid);
+
+ // NOTE: message_status is unreliable for detecting unparsed text because some callers
+ // change $this->message without resetting $this->message_status to 'plain' so we
+ // inspect the message instead
+ //if ($this->message_status == 'plain')
+ if (!preg_match('/^<[rt][ >]/', $this->message))
{
// Force updating message - of course.
$this->parse($allow_bbcode, $allow_magic_url, $allow_smilies, $this->allow_img_bbcode, $this->allow_flash_bbcode, $this->allow_quote_bbcode, $this->allow_url_bbcode, true);
}
- // Replace naughty words such as farty pants
- $this->message = censor_text($this->message);
-
- // Parse BBcode
- if ($allow_bbcode)
+ // There's a bug when previewing a topic with no poll, because the empty title of the poll
+ // gets parsed but $this->message still ends up empty. This fixes it, until a proper fix is
+ // devised
+ if ($this->message === '')
{
- $this->bbcode_cache_init();
-
- // We are giving those parameters to be able to use the bbcode class on its own
- $this->bbcode_second_pass($this->message, $this->bbcode_uid);
+ $this->message = $phpbb_container->get('text_formatter.parser')->parse($this->message);
}
- $this->message = bbcode_nl2br($this->message);
- $this->message = smiley_text($this->message, !$allow_smilies);
+ $this->message = $phpbb_container->get('text_formatter.renderer')->render($this->message);
$text = $this->message;
$uid = $this->bbcode_uid;
@@ -1471,6 +1535,7 @@ class parse_message extends bbcode_firstpass
function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false)
{
global $config, $auth, $user, $phpbb_root_path, $phpEx, $db, $request;
+ global $phpbb_container;
$error = array();
@@ -1506,7 +1571,9 @@ class parse_message extends bbcode_firstpass
{
if ($num_attachments < $cfg['max_attachments'] || $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id))
{
- $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $filedata = $attachment_manager->upload($form_name, $forum_id, false, '', $is_message);
$error = $filedata['error'];
if ($filedata['post_attach'] && !sizeof($error))
@@ -1536,7 +1603,9 @@ class parse_message extends bbcode_firstpass
);
$this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data);
- $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message);
+ $this->message = preg_replace_callback('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#', function ($match) {
+ return '[attachment='.($match[1] + 1).']' . $match[2] . '[/attachment]';
+ }, $this->message);
$this->filename_data['filecomment'] = '';
@@ -1574,6 +1643,9 @@ class parse_message extends bbcode_firstpass
if ($index !== false && !empty($this->attachment_data[$index]))
{
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+
// delete selected attachment
if ($this->attachment_data[$index]['is_orphan'])
{
@@ -1588,11 +1660,11 @@ class parse_message extends bbcode_firstpass
if ($row)
{
- phpbb_unlink($row['physical_filename'], 'file');
+ $attachment_manager->unlink($row['physical_filename'], 'file');
if ($row['thumbnail'])
{
- phpbb_unlink($row['physical_filename'], 'thumbnail');
+ $attachment_manager->unlink($row['physical_filename'], 'thumbnail');
}
$db->sql_query('DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id']);
@@ -1600,11 +1672,13 @@ class parse_message extends bbcode_firstpass
}
else
{
- delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id'])));
+ $attachment_manager->delete('attach', $this->attachment_data[$index]['attach_id']);
}
unset($this->attachment_data[$index]);
- $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "(\\1 == \$index) ? '' : ((\\1 > \$index) ? '[attachment=' . (\\1 - 1) . ']\\2[/attachment]' : '\\0')", $this->message);
+ $this->message = preg_replace_callback('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#', function ($match) use($index) {
+ return ($match[1] == $index) ? '' : (($match[1] > $index) ? '[attachment=' . ($match[1] - 1) . ']' . $match[2] . '[/attachment]' : $match[0]);
+ }, $this->message);
// Reindex Array
$this->attachment_data = array_values($this->attachment_data);
@@ -1618,7 +1692,9 @@ class parse_message extends bbcode_firstpass
{
if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_', $forum_id))
{
- $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message, false, $this->mimetype_guesser, $this->plupload);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $filedata = $attachment_manager->upload($form_name, $forum_id, false, '', $is_message);
$error = array_merge($error, $filedata['error']);
if (!sizeof($error))
@@ -1648,7 +1724,9 @@ class parse_message extends bbcode_firstpass
);
$this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data);
- $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message);
+ $this->message = preg_replace_callback('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#', function ($match) {
+ return '[attachment=' . ($match[1] + 1) . ']' . $match[2] . '[/attachment]';
+ }, $this->message);
$this->filename_data['filecomment'] = '';
if (isset($this->plupload) && $this->plupload->is_active())
@@ -1784,24 +1862,22 @@ class parse_message extends bbcode_firstpass
$poll_max_options = $poll['poll_max_options'];
- // Parse Poll Option text ;)
+ // Parse Poll Option text
$tmp_message = $this->message;
- $this->message = $poll['poll_option_text'];
- $bbcode_bitfield = $this->bbcode_bitfield;
- $poll['poll_option_text'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false, 'poll');
+ $poll['poll_options'] = explode("\n", trim($poll['poll_option_text']));
+ $poll['poll_options_size'] = sizeof($poll['poll_options']);
- $bbcode_bitfield = base64_encode(base64_decode($bbcode_bitfield) | base64_decode($this->bbcode_bitfield));
- $this->message = $tmp_message;
+ foreach ($poll['poll_options'] as &$poll_option)
+ {
+ $this->message = $poll_option;
+ $poll_option = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false, 'poll');
+ }
+ unset($poll_option);
+ $poll['poll_option_text'] = implode("\n", $poll['poll_options']);
// Parse Poll Title
- $tmp_message = $this->message;
$this->message = $poll['poll_title'];
- $this->bbcode_bitfield = $bbcode_bitfield;
-
- $poll['poll_options'] = explode("\n", trim($poll['poll_option_text']));
- $poll['poll_options_size'] = sizeof($poll['poll_options']);
-
if (!$poll['poll_title'] && $poll['poll_options_size'])
{
$this->warn_msg[] = $user->lang['NO_POLL_TITLE'];
@@ -1819,10 +1895,6 @@ class parse_message extends bbcode_firstpass
}
}
- $this->bbcode_bitfield = base64_encode(base64_decode($bbcode_bitfield) | base64_decode($this->bbcode_bitfield));
- $this->message = $tmp_message;
- unset($tmp_message);
-
if (sizeof($poll['poll_options']) == 1)
{
$this->warn_msg[] = $user->lang['TOO_FEW_POLL_OPTIONS'];
@@ -1837,6 +1909,65 @@ class parse_message extends bbcode_firstpass
}
$poll['poll_max_options'] = ($poll['poll_max_options'] < 1) ? 1 : (($poll['poll_max_options'] > $config['max_poll_options']) ? $config['max_poll_options'] : $poll['poll_max_options']);
+
+ $this->message = $tmp_message;
+ }
+
+ /**
+ * Remove nested quotes at given depth in current parsed message
+ *
+ * @param integer $max_depth Depth limit
+ * @return null
+ */
+ public function remove_nested_quotes($max_depth)
+ {
+ global $phpbb_container;
+
+ if (preg_match('#^<[rt][ >]#', $this->message))
+ {
+ $this->message = $phpbb_container->get('text_formatter.utils')->remove_bbcode(
+ $this->message,
+ 'quote',
+ $max_depth
+ );
+
+ return;
+ }
+
+ // Capture all [quote] and [/quote] tags
+ preg_match_all('(\\[/?quote(?:=&quot;(.*?)&quot;)?:' . $this->bbcode_uid . '\\])', $this->message, $matches, PREG_OFFSET_CAPTURE);
+
+ // Iterate over the quote tags to mark the ranges that must be removed
+ $depth = 0;
+ $ranges = array();
+ $start_pos = 0;
+ foreach ($matches[0] as $match)
+ {
+ if ($match[0][1] === '/')
+ {
+ --$depth;
+ if ($depth == $max_depth)
+ {
+ $end_pos = $match[1] + strlen($match[0]);
+ $length = $end_pos - $start_pos;
+ $ranges[] = array($start_pos, $length);
+ }
+ }
+ else
+ {
+ ++$depth;
+ if ($depth == $max_depth + 1)
+ {
+ $start_pos = $match[1];
+ }
+ }
+ }
+
+ foreach (array_reverse($ranges) as $range)
+ {
+ list($start_pos, $length) = $range;
+ $this->message = substr_replace($this->message, '', $start_pos, $length);
+ }
}
/**
@@ -1852,14 +1983,34 @@ class parse_message extends bbcode_firstpass
}
/**
- * Setter function for passing the mimetype_guesser object
+ * Function to perform custom bbcode validation by extensions
+ * can be used in bbcode_init() to assign regexp replacement
+ * Example: 'regexp' => array('#\[b\](.*?)\[/b\]#uise' => "\$this->validate_bbcode_by_extension('\$1')")
*
- * @param \phpbb\mimetype\guesser $mimetype_guesser The mimetype_guesser object
+ * Accepts variable number of parameters
*
- * @return null
+ * @return mixed Validation result
*/
- public function set_mimetype_guesser(\phpbb\mimetype\guesser $mimetype_guesser)
+ public function validate_bbcode_by_extension()
{
- $this->mimetype_guesser = $mimetype_guesser;
+ global $phpbb_dispatcher;
+
+ $return = false;
+ $params_array = func_get_args();
+
+ /**
+ * Event to validate bbcode with the custom validating methods
+ * provided by extensions
+ *
+ * @event core.validate_bbcode_by_extension
+ * @var array params_array Array with the function parameters
+ * @var mixed return Validation result to return
+ *
+ * @since 3.1.5-RC1
+ */
+ $vars = array('params_array', 'return');
+ extract($phpbb_dispatcher->trigger_event('core.validate_bbcode_by_extension', compact($vars)));
+
+ return $return;
}
}
diff --git a/phpBB/includes/startup.php b/phpBB/includes/startup.php
index c90fd79366..5900016c39 100644
--- a/phpBB/includes/startup.php
+++ b/phpBB/includes/startup.php
@@ -90,7 +90,11 @@ if (version_compare(PHP_VERSION, '5.4.0-dev', '>='))
}
else
{
- @set_magic_quotes_runtime(0);
+ if (get_magic_quotes_runtime())
+ {
+ // Deactivate
+ @set_magic_quotes_runtime(0);
+ }
// Be paranoid with passed vars
if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on' || !function_exists('ini_get'))
diff --git a/phpBB/includes/ucp/info/ucp_notifications.php b/phpBB/includes/ucp/info/ucp_notifications.php
index 0f6a7a8d71..94e0467ccb 100644
--- a/phpBB/includes/ucp/info/ucp_notifications.php
+++ b/phpBB/includes/ucp/info/ucp_notifications.php
@@ -20,7 +20,7 @@ class ucp_notifications_info
'title' => 'UCP_NOTIFICATION_OPTIONS',
'modes' => array(
'notification_options' => array('title' => 'UCP_NOTIFICATION_OPTIONS', 'auth' => '', 'cat' => array('UCP_PREFS')),
- 'notification_list' => array('title' => 'UCP_NOTIFICATION_LIST', 'auth' => '', 'cat' => array('UCP_MAIN')),
+ 'notification_list' => array('title' => 'UCP_NOTIFICATION_LIST', 'auth' => 'cfg_allow_board_notifications', 'cat' => array('UCP_MAIN')),
),
);
}
diff --git a/phpBB/includes/ucp/ucp_activate.php b/phpBB/includes/ucp/ucp_activate.php
index f535073434..5bfb688d3a 100644
--- a/phpBB/includes/ucp/ucp_activate.php
+++ b/phpBB/includes/ucp/ucp_activate.php
@@ -30,7 +30,7 @@ class ucp_activate
function main($id, $mode)
{
global $config, $phpbb_root_path, $phpEx, $request;
- global $db, $user, $auth, $template, $phpbb_container, $phpbb_log;
+ global $db, $user, $auth, $template, $phpbb_container, $phpbb_log, $phpbb_dispatcher;
$user_id = $request->variable('u', 0);
$key = $request->variable('k', '');
@@ -150,6 +150,17 @@ class ucp_activate
}
}
+ /**
+ * This event can be used to modify data after user account's activation
+ *
+ * @event core.ucp_activate_after
+ * @var array user_row Array with some user data
+ * @var string message Language string of the message that will be displayed to the user
+ * @since 3.1.6-RC1
+ */
+ $vars = array('user_row', 'message');
+ extract($phpbb_dispatcher->trigger_event('core.ucp_activate_after', compact($vars)));
+
meta_refresh(3, append_sid("{$phpbb_root_path}index.$phpEx"));
trigger_error($user->lang[$message]);
}
diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php
index 639f308091..b8cb3c4100 100644
--- a/phpBB/includes/ucp/ucp_attachments.php
+++ b/phpBB/includes/ucp/ucp_attachments.php
@@ -70,12 +70,10 @@ class ucp_attachments
if (confirm_box(true))
{
- if (!function_exists('delete_attachments'))
- {
- include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
- }
-
- delete_attachments('attach', $delete_ids);
+ /** @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 = ((sizeof($delete_ids) == 1) ? $user->lang['ATTACHMENT_DELETED'] : $user->lang['ATTACHMENTS_DELETED']) . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php
index 3228ffb469..2746e74ffe 100644
--- a/phpBB/includes/ucp/ucp_groups.php
+++ b/phpBB/includes/ucp/ucp_groups.php
@@ -41,6 +41,9 @@ class ucp_groups
$delete = $request->variable('delete', false, false, \phpbb\request\request_interface::POST);
$error = $data = array();
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
switch ($mode)
{
case 'membership':
@@ -65,7 +68,7 @@ class ucp_groups
$group_row = array();
while ($row = $db->sql_fetchrow($result))
{
- $row['group_name'] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
+ $row['group_name'] = $group_helper->get_name($row['group_name']);
$group_row[$row['group_id']] = $row;
}
$db->sql_freeresult($result);
@@ -307,7 +310,7 @@ class ucp_groups
$template->assign_block_vars($block, array(
'GROUP_ID' => $row['group_id'],
- 'GROUP_NAME' => ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'],
+ 'GROUP_NAME' => $group_helper->get_name($row['group_name']),
'GROUP_DESC' => ($row['group_type'] <> GROUP_SPECIAL) ? generate_text_for_display($row['group_desc'], $row['group_desc_uid'], $row['group_desc_bitfield'], $row['group_desc_options']) : $user->lang['GROUP_IS_SPECIAL'],
'GROUP_SPECIAL' => ($row['group_type'] <> GROUP_SPECIAL) ? false : true,
'GROUP_STATUS' => $user->lang['GROUP_IS_' . $group_status],
@@ -361,7 +364,7 @@ class ucp_groups
$template->assign_block_vars('nonmember', array(
'GROUP_ID' => $row['group_id'],
- 'GROUP_NAME' => ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'],
+ 'GROUP_NAME' => $group_helper->get_name($row['group_name']),
'GROUP_DESC' => ($row['group_type'] <> GROUP_SPECIAL) ? generate_text_for_display($row['group_desc'], $row['group_desc_uid'], $row['group_desc_bitfield'], $row['group_desc_options']) : $user->lang['GROUP_IS_SPECIAL'],
'GROUP_SPECIAL' => ($row['group_type'] <> GROUP_SPECIAL) ? false : true,
'GROUP_CLOSED' => ($row['group_type'] <> GROUP_CLOSED || $auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel')) ? false : true,
@@ -426,7 +429,7 @@ class ucp_groups
$avatar = phpbb_get_group_avatar($group_row, 'GROUP_AVATAR', true);
$template->assign_vars(array(
- 'GROUP_NAME' => ($group_type == GROUP_SPECIAL) ? $user->lang['G_' . $group_name] : $group_name,
+ 'GROUP_NAME' => $group_helper->get_name($group_name),
'GROUP_INTERNAL_NAME' => $group_name,
'GROUP_COLOUR' => (isset($group_row['group_colour'])) ? $group_row['group_colour'] : '',
'GROUP_DESC_DISP' => generate_text_for_display($group_row['group_desc'], $group_row['group_desc_uid'], $group_row['group_desc_bitfield'], $group_row['group_desc_options']),
@@ -901,7 +904,7 @@ class ucp_groups
trigger_error($user->lang['NOT_LEADER_OF_GROUP'] . $return_page);
}
- $group_row['group_name'] = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'];
+ $group_row['group_name'] = $group_helper->get_name($group_row['group_name']);
if (confirm_box(true))
{
@@ -980,7 +983,7 @@ class ucp_groups
trigger_error($user->lang['NOT_LEADER_OF_GROUP'] . $return_page);
}
- $group_row['group_name'] = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'];
+ $group_row['group_name'] = $group_helper->get_name($group_row['group_name']);
if (confirm_box(true))
{
@@ -1042,7 +1045,7 @@ class ucp_groups
}
$name_ary = array_unique(explode("\n", $names));
- $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'];
+ $group_name = $group_helper->get_name($group_row['group_name']);
$default = $request->variable('default', 0);
@@ -1088,7 +1091,7 @@ class ucp_groups
while ($value = $db->sql_fetchrow($result))
{
$template->assign_block_vars('leader', array(
- 'GROUP_NAME' => ($value['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $value['group_name']] : $value['group_name'],
+ 'GROUP_NAME' => $group_helper->get_name($value['group_name']),
'GROUP_DESC' => generate_text_for_display($value['group_desc'], $value['group_desc_uid'], $value['group_desc_bitfield'], $value['group_desc_options']),
'GROUP_TYPE' => $value['group_type'],
'GROUP_ID' => $value['group_id'],
diff --git a/phpBB/includes/ucp/ucp_notifications.php b/phpBB/includes/ucp/ucp_notifications.php
index b778ffdf12..51bd77bd4c 100644
--- a/phpBB/includes/ucp/ucp_notifications.php
+++ b/phpBB/includes/ucp/ucp_notifications.php
@@ -55,11 +55,11 @@ class ucp_notifications
$notification_methods = $phpbb_notifications->get_subscription_methods();
- foreach($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
+ foreach ($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
{
- foreach($subscription_types as $type => $data)
+ foreach ($subscription_types as $type => $data)
{
- foreach($notification_methods as $method => $method_data)
+ foreach ($notification_methods as $method => $method_data)
{
if ($request->is_set_post(str_replace('.', '_', $type . '_' . $method_data['id'])) && (!isset($subscriptions[$type]) || !in_array($method_data['id'], $subscriptions[$type])))
{
@@ -70,15 +70,6 @@ class ucp_notifications
$phpbb_notifications->delete_subscription($type, 0, $method_data['id']);
}
}
-
- if ($request->is_set_post(str_replace('.', '_', $type) . '_notification') && !isset($subscriptions[$type]))
- {
- $phpbb_notifications->add_subscription($type);
- }
- else if (!$request->is_set_post(str_replace('.', '_', $type) . '_notification') && isset($subscriptions[$type]))
- {
- $phpbb_notifications->delete_subscription($type);
- }
}
}
@@ -100,7 +91,7 @@ class ucp_notifications
// Mark all items read
if ($request->variable('mark', '') == 'all' && check_link_hash($request->variable('token', ''), 'mark_all_notifications_read'))
{
- $phpbb_notifications->mark_notifications_read(false, false, $user->data['user_id'], $form_time);
+ $phpbb_notifications->mark_notifications(false, false, $user->data['user_id'], $form_time);
meta_refresh(3, $this->u_action);
$message = $user->lang['NOTIFICATIONS_MARK_ALL_READ_SUCCESS'];
@@ -131,11 +122,11 @@ class ucp_notifications
if (!empty($mark_read))
{
- $phpbb_notifications->mark_notifications_read_by_id($mark_read, $form_time);
+ $phpbb_notifications->mark_notifications_by_id('notification.method.board', $mark_read, $form_time);
}
}
- $notifications = $phpbb_notifications->load_notifications(array(
+ $notifications = $phpbb_notifications->load_notifications('notification.method.board', array(
'start' => $start,
'limit' => $config['topics_per_page'],
'count_total' => true,
@@ -183,24 +174,22 @@ class ucp_notifications
{
$notification_methods = $phpbb_notifications->get_subscription_methods();
- foreach($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
+ foreach ($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
{
$template->assign_block_vars($block, array(
'GROUP_NAME' => $user->lang($group),
));
- foreach($subscription_types as $type => $data)
+ foreach ($subscription_types as $type => $data)
{
$template->assign_block_vars($block, array(
'TYPE' => $type,
'NAME' => $user->lang($data['lang']),
'EXPLAIN' => (isset($user->lang[$data['lang'] . '_EXPLAIN'])) ? $user->lang($data['lang'] . '_EXPLAIN') : '',
-
- 'SUBSCRIBED' => (isset($subscriptions[$type])) ? true : false,
));
- foreach($notification_methods as $method => $method_data)
+ foreach ($notification_methods as $method => $method_data)
{
$template->assign_block_vars($block . '.notification_methods', array(
'METHOD' => $method_data['id'],
@@ -230,7 +219,7 @@ class ucp_notifications
{
$notification_methods = $phpbb_notifications->get_subscription_methods();
- foreach($notification_methods as $method => $method_data)
+ foreach ($notification_methods as $method => $method_data)
{
$template->assign_block_vars($block, array(
'METHOD' => $method_data['id'],
diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php
index 59952182df..024a9c332f 100644
--- a/phpBB/includes/ucp/ucp_pm_compose.php
+++ b/phpBB/includes/ucp/ucp_pm_compose.php
@@ -55,7 +55,6 @@ function compose_pm($id, $mode, $action, $user_folders = array())
$address_list = $request->variable('address_list', array('' => array(0 => '')));
- $submit = (isset($_POST['post'])) ? true : false;
$preview = (isset($_POST['preview'])) ? true : false;
$save = (isset($_POST['save'])) ? true : false;
$load = (isset($_POST['load'])) ? true : false;
@@ -69,6 +68,7 @@ function compose_pm($id, $mode, $action, $user_folders = array())
$refresh = isset($_POST['add_file']) || isset($_POST['delete_file']) || $save || $load
|| $remove_u || $remove_g || $add_to || $add_bcc;
+ $submit = $request->is_set_post('post') && !$refresh && !$preview;
$action = ($delete && !$preview && !$refresh && $submit) ? 'delete' : $action;
$select_single = ($config['allow_mass_pm'] && $auth->acl_get('u_masspm')) ? false : true;
@@ -76,6 +76,9 @@ function compose_pm($id, $mode, $action, $user_folders = array())
$error = array();
$current_time = time();
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
+
// Was cancel pressed? If so then redirect to the appropriate page
if ($cancel || ($current_time - $lastclick < 2 && $submit))
{
@@ -145,7 +148,7 @@ function compose_pm($id, $mode, $action, $user_folders = array())
$group_options = '';
while ($row = $db->sql_fetchrow($result))
{
- $group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '">' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>';
+ $group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '">' . $group_helper->get_name($row['group_name']) . '</option>';
}
$db->sql_freeresult($result);
}
@@ -263,8 +266,6 @@ function compose_pm($id, $mode, $action, $user_folders = array())
*
* @event core.ucp_pm_compose_compose_pm_basic_info_query_before
* @var string sql String with the query to be executed
- * @var array forum_list List of forums that contain the posts
- * @var int visibility_const Integer with one of the possible ITEM_* constant values
* @var int msg_id topic_id in the page request
* @var int to_user_id The id of whom the message is to
* @var int to_group_id The id of the group whom the message is to
@@ -273,14 +274,11 @@ function compose_pm($id, $mode, $action, $user_folders = array())
* @var string action One of: post, reply, quote, forward, quotepost, edit, delete, smilies
* @var bool delete Whether the user is deleting the PM
* @var int reply_to_all Value of reply_to_all request variable.
- * @var string limit_time_sql String with the SQL code to limit the time interval of the post (Note: May be empty string)
- * @var string sort_order_sql String with the ORDER BY SQL code used in this query
* @since 3.1.0-RC5
+ * @change 3.2.0-a1 Removed undefined variables
*/
$vars = array(
'sql',
- 'forum_list',
- 'visibility_const',
'msg_id',
'to_user_id',
'to_group_id',
@@ -289,8 +287,6 @@ function compose_pm($id, $mode, $action, $user_folders = array())
'action',
'delete',
'reply_to_all',
- 'limit_time_sql',
- 'sort_order_sql',
);
extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_compose_pm_basic_info_query_before', compact($vars)));
@@ -335,8 +331,6 @@ function compose_pm($id, $mode, $action, $user_folders = array())
* @var string sql The original SQL used in the query
* @var array post Associative array with the data of the quoted post
* @var array msg_id The post_id that was searched to get the message for quoting
- * @var int visibility_const Visibility of the quoted post (one of the possible ITEM_* constant values)
- * @var int topic_id Topic ID of the quoted post
* @var int to_user_id Users the message is sent to
* @var int to_group_id Groups the message is sent to
* @var bool submit Whether the user is sending the PM or not
@@ -345,13 +339,12 @@ function compose_pm($id, $mode, $action, $user_folders = array())
* @var bool delete If deleting message
* @var int reply_to_all Value of reply_to_all request variable.
* @since 3.1.0-RC5
+ * @change 3.2.0-a1 Removed undefined variables
*/
$vars = array(
'sql',
'post',
'msg_id',
- 'visibility_const',
- 'topic_id',
'to_user_id',
'to_group_id',
'submit',
@@ -530,15 +523,9 @@ function compose_pm($id, $mode, $action, $user_folders = array())
}
// Get maximum number of allowed recipients
- $sql = 'SELECT MAX(g.group_max_recipients) as max_recipients
- FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug
- WHERE ug.user_id = ' . $user->data['user_id'] . '
- AND ug.user_pending = 0
- AND ug.group_id = g.group_id';
- $result = $db->sql_query($sql);
- $max_recipients = (int) $db->sql_fetchfield('max_recipients');
- $db->sql_freeresult($result);
+ $max_recipients = phpbb_get_max_setting_from_group($db, $user->data['user_id'], 'max_recipients');
+ // If it is 0, there is no limit set and we use the maximum value within the config.
$max_recipients = (!$max_recipients) ? $config['pm_max_recipients'] : $max_recipients;
// If this is a quote/reply "to all"... we may increase the max_recpients to the number of original recipients
@@ -947,7 +934,20 @@ function compose_pm($id, $mode, $action, $user_folders = array())
{
$message_link = '';
}
- $message_parser->message = $message_link . '[quote=&quot;' . $quote_username . '&quot;]' . censor_text(trim($message_parser->message)) . "[/quote]\n";
+ $quote_attributes = array(
+ 'author' => $quote_username,
+ 'time' => $post['message_time'],
+ 'user_id' => $post['author_id'],
+ );
+ if ($action === 'quotepost')
+ {
+ $quote_attributes['post_id'] = $post['msg_id'];
+ }
+ $quote_text = $phpbb_container->get('text_formatter.utils')->generate_quote(
+ censor_text($message_parser->message),
+ $quote_attributes
+ );
+ $message_parser->message = $message_link . $quote_text . "\n\n";
}
if (($action == 'reply' || $action == 'quote' || $action == 'quotepost') && !$preview && !$refresh)
@@ -975,7 +975,11 @@ function compose_pm($id, $mode, $action, $user_folders = array())
$forward_text[] = sprintf($user->lang['FWD_FROM'], $quote_username_text);
$forward_text[] = sprintf($user->lang['FWD_TO'], implode($user->lang['COMMA_SEPARATOR'], $fwd_to_field['to']));
- $message_parser->message = implode("\n", $forward_text) . "\n\n[quote=&quot;{$quote_username}&quot;]\n" . censor_text(trim($message_parser->message)) . "\n[/quote]";
+ $quote_text = $phpbb_container->get('text_formatter.utils')->generate_quote(
+ censor_text($message_parser->message),
+ array('author' => $quote_username)
+ );
+ $message_parser->message = implode("\n", $forward_text) . "\n\n" . $quote_text;
$message_subject = ((!preg_match('/^Fwd:/', $message_subject)) ? 'Fwd: ' : '') . censor_text($message_subject);
}
@@ -1048,7 +1052,7 @@ function compose_pm($id, $mode, $action, $user_folders = array())
{
if ($type == 'g')
{
- $row['name'] = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['name']] : $row['name'];
+ $row['name'] = $group_helper->get_name($row['name']);
}
${$type}[$row['id']] = array('name' => $row['name'], 'colour' => $row['colour']);
@@ -1157,7 +1161,7 @@ function compose_pm($id, $mode, $action, $user_folders = array())
'SUBJECT' => (isset($message_subject)) ? $message_subject : '',
'MESSAGE' => $message_text,
- 'BBCODE_STATUS' => $user->lang(($bbcode_status ? 'BBCODE_IS_ON' : 'BBCODE_IS_OFF'), '<a href="' . $controller_helper->route('phpbb_help_controller', array('mode' => 'bbcode')) . '">', '</a>'),
+ 'BBCODE_STATUS' => $user->lang(($bbcode_status ? 'BBCODE_IS_ON' : 'BBCODE_IS_OFF'), '<a href="' . $controller_helper->route('phpbb_help_bbcode_controller') . '">', '</a>'),
'IMG_STATUS' => ($img_status) ? $user->lang['IMAGES_ARE_ON'] : $user->lang['IMAGES_ARE_OFF'],
'FLASH_STATUS' => ($flash_status) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'],
'SMILIES_STATUS' => ($smilies_status) ? $user->lang['SMILIES_ARE_ON'] : $user->lang['SMILIES_ARE_OFF'],
diff --git a/phpBB/includes/ucp/ucp_pm_options.php b/phpBB/includes/ucp/ucp_pm_options.php
index 9c21971bf8..2ccd4a7728 100644
--- a/phpBB/includes/ucp/ucp_pm_options.php
+++ b/phpBB/includes/ucp/ucp_pm_options.php
@@ -507,7 +507,9 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit
$rule_lang = $action_lang = $check_lang = array();
// Build all three language arrays
- preg_replace('#^((RULE|ACTION|CHECK)_([A-Z0-9_]+))$#e', "\${strtolower('\\2') . '_lang'}[constant('\\1')] = \$user->lang['PM_\\2']['\\3']", array_keys(get_defined_constants()));
+ preg_replace_callback('#^((RULE|ACTION|CHECK)_([A-Z0-9_]+))$#', function ($match) use(&$rule_lang, &$action_lang, &$check_lang, $user) {
+ ${strtolower($match[2]) . '_lang'}[constant($match[1])] = $user->lang['PM_' . $match[2]][$match[3]];
+ }, array_keys(get_defined_constants()));
/*
Rule Ordering:
@@ -698,7 +700,10 @@ function define_rule_option($hardcoded, $rule_option, $rule_lang, $check_ary)
*/
function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule_conditions)
{
- global $db, $template, $auth, $user, $request;
+ global $db, $template, $auth, $user, $request, $phpbb_container;
+
+ /** @var \phpbb\group\helper $group_helper */
+ $group_helper = $phpbb_container->get('group_helper');
$template->assign_vars(array(
'S_COND_DEFINED' => true,
@@ -810,13 +815,13 @@ function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule
{
if ($rule_group_id && ($row['group_id'] == $rule_group_id))
{
- $rule_string = (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']);
+ $rule_string = $group_helper->get_name($row['group_name']);
}
$s_class = ($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '';
$s_selected = ($row['group_id'] == $rule_group_id) ? ' selected="selected"' : '';
- $s_group_options .= '<option value="' . $row['group_id'] . '"' . $s_class . $s_selected . '>' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>';
+ $s_group_options .= '<option value="' . $row['group_id'] . '"' . $s_class . $s_selected . '>' . $group_helper->get_name($row['group_name']) . '</option>';
}
$db->sql_freeresult($result);
diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php
index 52948cea19..3de3410ea8 100644
--- a/phpBB/includes/ucp/ucp_pm_viewmessage.php
+++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php
@@ -232,7 +232,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
'U_DELETE' => ($auth->acl_get('u_pm_delete')) ? "$url&amp;mode=compose&amp;action=delete&amp;f=$folder_id&amp;p=" . $message_row['msg_id'] : '',
'U_EMAIL' => $user_info['email'],
- 'U_REPORT' => ($config['allow_pm_report']) ? append_sid("{$phpbb_root_path}report.$phpEx", "pm=" . $message_row['msg_id']) : '',
+ 'U_REPORT' => ($config['allow_pm_report']) ? $phpbb_container->get('controller.helper')->route('phpbb_report_pm_controller', array('id' => $message_row['msg_id'])) : '',
'U_QUOTE' => ($auth->acl_get('u_sendpm') && $author_id != ANONYMOUS) ? "$url&amp;mode=compose&amp;action=quote&amp;f=$folder_id&amp;p=" . $message_row['msg_id'] : '',
'U_EDIT' => (($message_row['message_time'] > time() - ($config['pm_edit_time'] * 60) || !$config['pm_edit_time']) && $folder_id == PRIVMSGS_OUTBOX && $auth->acl_get('u_pm_edit')) ? "$url&amp;mode=compose&amp;action=edit&amp;f=$folder_id&amp;p=" . $message_row['msg_id'] : '',
'U_POST_REPLY_PM' => ($auth->acl_get('u_sendpm') && $author_id != ANONYMOUS) ? "$url&amp;mode=compose&amp;action=reply&amp;f=$folder_id&amp;p=" . $message_row['msg_id'] : '',
@@ -266,7 +266,9 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
* @var array message_row Array with message data
* @var array cp_row Array with senders custom profile field data
* @var array msg_data Template array with message data
+ * @var array user_info User data of the sender
* @since 3.1.0-a1
+ * @changed 3.1.6-RC1 Added user_info into event
*/
$vars = array(
'id',
@@ -277,6 +279,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
'message_row',
'cp_row',
'msg_data',
+ 'user_info',
);
extract($phpbb_dispatcher->trigger_event('core.ucp_pm_view_messsage', compact($vars)));
diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php
index cbaa71c33e..215a870007 100644
--- a/phpBB/includes/ucp/ucp_prefs.php
+++ b/phpBB/includes/ucp/ucp_prefs.php
@@ -69,7 +69,7 @@ class ucp_prefs
* @var array data Array with current ucp options data
* @var array error Array with list of errors
* @since 3.1.0-a1
- * @changed 3.1.4-rc1 Added error variable to the event
+ * @changed 3.1.4-RC1 Added error variable to the event
*/
$vars = array('submit', 'data', 'error');
extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_personal_data', compact($vars)));
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index 66eae22a1b..85a69a6b0f 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -518,7 +518,20 @@ class ucp_profile
}
$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);
+ $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 (sizeof($warn_msg))
{
@@ -572,7 +585,7 @@ class ucp_profile
'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_controller', array('mode' => 'bbcode')) . '">', '</a>'),
+ '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'],
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 7ff6506292..4f9639114f 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -178,6 +178,16 @@ class ucp_register
}
unset($lang_row);
+ /**
+ * 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
+ */
+ $phpbb_dispatcher->dispatch('core.ucp_register_agreement');
+
$this->tpl_name = 'ucp_agreement';
return;
}