aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/acp/acp_attachments.php7
-rw-r--r--phpBB/includes/acp/acp_ban.php34
-rw-r--r--phpBB/includes/acp/acp_board.php29
-rw-r--r--phpBB/includes/acp/acp_captcha.php4
-rw-r--r--phpBB/includes/acp/acp_database.php9
-rw-r--r--phpBB/includes/acp/acp_email.php10
-rw-r--r--phpBB/includes/acp/acp_forums.php8
-rw-r--r--phpBB/includes/acp/acp_groups.php18
-rw-r--r--phpBB/includes/acp/acp_icons.php24
-rw-r--r--phpBB/includes/acp/acp_inactive.php10
-rw-r--r--phpBB/includes/acp/acp_language.php9
-rw-r--r--phpBB/includes/acp/acp_main.php11
-rw-r--r--phpBB/includes/acp/acp_modules.php103
-rw-r--r--phpBB/includes/acp/acp_search.php47
-rw-r--r--phpBB/includes/acp/acp_users.php22
-rw-r--r--phpBB/includes/bbcode.php5
-rw-r--r--phpBB/includes/captcha/captcha_factory.php42
-rw-r--r--phpBB/includes/captcha/plugins/captcha_abstract.php9
-rw-r--r--phpBB/includes/class_loader.php42
-rw-r--r--phpBB/includes/constants.php1
-rw-r--r--phpBB/includes/cron/manager.php121
-rw-r--r--phpBB/includes/cron/task/provider.php48
-rw-r--r--phpBB/includes/db/dbal.php2
-rw-r--r--phpBB/includes/extension/base.php57
-rw-r--r--phpBB/includes/extension/finder.php422
-rw-r--r--phpBB/includes/extension/interface.php65
-rw-r--r--phpBB/includes/extension/manager.php415
-rw-r--r--phpBB/includes/extension/provider.php68
-rw-r--r--phpBB/includes/functions.php271
-rw-r--r--phpBB/includes/functions_acp.php2
-rw-r--r--phpBB/includes/functions_admin.php61
-rw-r--r--phpBB/includes/functions_content.php16
-rw-r--r--phpBB/includes/functions_display.php31
-rw-r--r--phpBB/includes/functions_install.php19
-rw-r--r--phpBB/includes/functions_messenger.php21
-rw-r--r--phpBB/includes/functions_module.php180
-rw-r--r--phpBB/includes/functions_posting.php28
-rw-r--r--phpBB/includes/functions_privmsgs.php11
-rw-r--r--phpBB/includes/functions_profile_fields.php12
-rw-r--r--phpBB/includes/functions_upload.php8
-rw-r--r--phpBB/includes/functions_user.php43
-rw-r--r--phpBB/includes/mcp/mcp_forum.php2
-rw-r--r--phpBB/includes/mcp/mcp_front.php88
-rw-r--r--phpBB/includes/mcp/mcp_logs.php2
-rw-r--r--phpBB/includes/mcp/mcp_main.php17
-rw-r--r--phpBB/includes/mcp/mcp_notes.php2
-rw-r--r--phpBB/includes/mcp/mcp_pm_reports.php3
-rw-r--r--phpBB/includes/mcp/mcp_post.php2
-rw-r--r--phpBB/includes/mcp/mcp_queue.php15
-rw-r--r--phpBB/includes/mcp/mcp_reports.php10
-rw-r--r--phpBB/includes/mcp/mcp_topic.php6
-rw-r--r--phpBB/includes/mcp/mcp_warn.php2
-rw-r--r--phpBB/includes/message_parser.php20
-rw-r--r--phpBB/includes/search/base.php (renamed from phpBB/includes/search/search.php)4
-rw-r--r--phpBB/includes/search/fulltext_mysql.php19
-rw-r--r--phpBB/includes/search/fulltext_native.php22
-rw-r--r--phpBB/includes/session.php135
-rw-r--r--phpBB/includes/startup.php4
-rw-r--r--phpBB/includes/template/extension_path_provider.php130
-rw-r--r--phpBB/includes/template/locator.php97
-rw-r--r--phpBB/includes/template/path_provider.php102
-rw-r--r--phpBB/includes/template/path_provider_interface.php54
-rw-r--r--phpBB/includes/template/template.php71
-rw-r--r--phpBB/includes/ucp/ucp_activate.php5
-rw-r--r--phpBB/includes/ucp/ucp_groups.php60
-rw-r--r--phpBB/includes/ucp/ucp_main.php8
-rw-r--r--phpBB/includes/ucp/ucp_pm.php6
-rw-r--r--phpBB/includes/ucp/ucp_pm_compose.php2
-rw-r--r--phpBB/includes/ucp/ucp_pm_options.php6
-rw-r--r--phpBB/includes/ucp/ucp_pm_viewfolder.php2
-rw-r--r--phpBB/includes/ucp/ucp_pm_viewmessage.php2
-rw-r--r--phpBB/includes/ucp/ucp_profile.php25
-rw-r--r--phpBB/includes/ucp/ucp_register.php9
-rw-r--r--phpBB/includes/ucp/ucp_resend.php10
74 files changed, 2424 insertions, 863 deletions
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php
index c62fefae46..4295aa9d9f 100644
--- a/phpBB/includes/acp/acp_attachments.php
+++ b/phpBB/includes/acp/acp_attachments.php
@@ -1159,7 +1159,7 @@ class acp_attachments
// Issue warning message if files stats are inaccurate
if (($num_files != $num_files_real) || ($total_size != $total_size_real))
{
- $error[] = sprintf($user->lang['FILES_STATS_WRONG'], $num_files_real, get_formatted_filesize($total_size_real));
+ $error[] = $user->lang('FILES_STATS_WRONG', (int) $num_files_real, get_formatted_filesize($total_size_real));
$template->assign_vars(array(
'S_ACTION_OPTIONS' => ($auth->acl_get('a_board')) ? true : false,
@@ -1244,8 +1244,7 @@ class acp_attachments
$row['extension'] = strtolower(trim((string) $row['extension']));
$comment = ($row['attach_comment'] && !$row['in_message']) ? str_replace(array("\n", "\r"), array('<br />', "\n"), $row['attach_comment']) : '';
$display_cat = $extensions[$row['extension']]['display_cat'];
- $l_downloaded_viewed = ($display_cat == ATTACHMENT_CATEGORY_NONE) ? 'DOWNLOAD_COUNT' : 'VIEWED_COUNT';
- $l_download_count = (!isset($row['download_count']) || (int) $row['download_count'] == 0) ? $user->lang[$l_downloaded_viewed . '_NONE'] : (((int) $row['download_count'] == 1) ? sprintf($user->lang[$l_downloaded_viewed], $row['download_count']) : sprintf($user->lang[$l_downloaded_viewed . 'S'], $row['download_count']));
+ $l_downloaded_viewed = ($display_cat == ATTACHMENT_CATEGORY_NONE) ? 'DOWNLOAD_COUNTS' : 'VIEWED_COUNTS';
$template->assign_block_vars('attachments', array(
'ATTACHMENT_POSTER' => get_username_string('full', (int) $row['poster_id'], (string) $row['username'], (string) $row['user_colour'], (string) $row['username']),
@@ -1261,7 +1260,7 @@ class acp_attachments
'TOPIC_ID' => (int) $row['topic_id'],
'POST_IDS' => (!empty($post_ids[$row['attach_id']])) ? (int) $post_ids[$row['attach_id']] : '',
- 'L_DOWNLOAD_COUNT' => $l_download_count,
+ 'L_DOWNLOAD_COUNT' => $user->lang($l_downloaded_viewed, (int) $row['download_count']),
'S_IN_MESSAGE' => (bool) $row['in_message'],
diff --git a/phpBB/includes/acp/acp_ban.php b/phpBB/includes/acp/acp_ban.php
index 00e68367fd..d881fc6bdc 100644
--- a/phpBB/includes/acp/acp_ban.php
+++ b/phpBB/includes/acp/acp_ban.php
@@ -175,12 +175,21 @@ class acp_ban
}
$result = $db->sql_query($sql);
- $banned_options = '';
+ $banned_options = $excluded_options = array();
$ban_length = $ban_reasons = $ban_give_reasons = array();
while ($row = $db->sql_fetchrow($result))
{
- $banned_options .= '<option' . (($row['ban_exclude']) ? ' class="sep"' : '') . ' value="' . $row['ban_id'] . '">' . $row[$field] . '</option>';
+ $option = '<option value="' . $row['ban_id'] . '">' . $row[$field] . '</option>';
+
+ if ($row['ban_exclude'])
+ {
+ $excluded_options[] = $option;
+ }
+ else
+ {
+ $banned_options[] = $option;
+ }
$time_length = ($row['ban_end']) ? ($row['ban_end'] - $row['ban_start']) / 60 : 0;
@@ -241,10 +250,25 @@ class acp_ban
}
}
+ $options = '';
+ if ($excluded_options)
+ {
+ $options .= '<optgroup label="' . $user->lang['OPTIONS_EXCLUDED'] . '">';
+ $options .= implode('', $excluded_options);
+ $options .= '</optgroup>';
+ }
+
+ if ($banned_options)
+ {
+ $options .= '<optgroup label="' . $user->lang['OPTIONS_BANNED'] . '">';
+ $options .= implode('', $banned_options);
+ $options .= '</optgroup>';
+ }
+
$template->assign_vars(array(
'S_BAN_END_OPTIONS' => $ban_end_options,
- 'S_BANNED_OPTIONS' => ($banned_options) ? true : false,
- 'BANNED_OPTIONS' => $banned_options)
- );
+ 'S_BANNED_OPTIONS' => ($banned_options || $excluded_options) ? true : false,
+ 'BANNED_OPTIONS' => $options,
+ ));
}
}
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index f27a133eb5..c99541ea7a 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -99,6 +99,7 @@ class acp_board
'load_cpf_pm' => array('lang' => 'LOAD_CPF_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'load_cpf_viewprofile' => array('lang' => 'LOAD_CPF_VIEWPROFILE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'load_cpf_viewtopic' => array('lang' => 'LOAD_CPF_VIEWTOPIC', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ 'load_jquery_cdn' => array('lang' => 'LOAD_JQUERY_CDN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend3' => 'ACP_SUBMIT_CHANGES',
)
@@ -189,7 +190,7 @@ class acp_board
'hot_threshold' => array('lang' => 'HOT_THRESHOLD', 'validate' => 'int:0', 'type' => 'text:3:4', 'explain' => true),
'max_poll_options' => array('lang' => 'MAX_POLL_OPTIONS', 'validate' => 'int:2:127', 'type' => 'text:4:4', 'explain' => false),
'max_post_chars' => array('lang' => 'CHAR_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:6', 'explain' => true),
- 'min_post_chars' => array('lang' => 'MIN_CHAR_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:6', 'explain' => true),
+ 'min_post_chars' => array('lang' => 'MIN_CHAR_LIMIT', 'validate' => 'int:1', 'type' => 'text:4:6', 'explain' => true),
'max_post_smilies' => array('lang' => 'SMILIES_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true),
'max_post_urls' => array('lang' => 'MAX_POST_URLS', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true),
'max_post_font_size' => array('lang' => 'MAX_POST_FONT_SIZE', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' %'),
@@ -235,7 +236,7 @@ class acp_board
'max_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int:8:180', 'type' => false, 'method' => false, 'explain' => false,),
'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,),
- 'require_activation' => array('lang' => 'ACC_ACTIVATION', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_acc_activation', 'explain' => true),
+ 'require_activation' => array('lang' => 'ACC_ACTIVATION', 'validate' => 'int', 'type' => 'select', 'method' => 'select_acc_activation', 'explain' => true),
'new_member_post_limit' => array('lang' => 'NEW_MEMBER_POST_LIMIT', 'validate' => 'int:0:255', 'type' => 'text:4:4', 'explain' => true, 'append' => ' ' . $user->lang['POSTS']),
'new_member_group_default'=> array('lang' => 'NEW_MEMBER_GROUP_DEFAULT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'min_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int:1', 'type' => 'custom:5:180', 'method' => 'username_length', 'explain' => true),
@@ -771,24 +772,28 @@ class acp_board
/**
* Select account activation method
*/
- function select_acc_activation($value, $key = '')
+ function select_acc_activation($selected_value, $value)
{
global $user, $config;
- $radio_ary = array(
- USER_ACTIVATION_DISABLE => 'ACC_DISABLE',
- USER_ACTIVATION_NONE => 'ACC_NONE',
+ $act_ary = array(
+ 'ACC_DISABLE' => USER_ACTIVATION_DISABLE,
+ 'ACC_NONE' => USER_ACTIVATION_NONE,
);
-
if ($config['email_enable'])
{
- $radio_ary[USER_ACTIVATION_SELF] = 'ACC_USER';
- $radio_ary[USER_ACTIVATION_ADMIN] = 'ACC_ADMIN';
- }
+ $act_ary['ACC_USER'] = USER_ACTIVATION_SELF;
+ $act_ary['ACC_ADMIN'] = USER_ACTIVATION_ADMIN;
+ }
+ $act_options = '';
- $radio_text = h_radio('config[require_activation]', $radio_ary, $value, 'require_activation', $key, '<br />');
+ foreach ($act_ary as $key => $value)
+ {
+ $selected = ($selected_value == $value) ? ' selected="selected"' : '';
+ $act_options .= '<option value="' . $value . '"' . $selected . '>' . $user->lang[$key] . '</option>';
+ }
- return $radio_text;
+ return $act_options;
}
/**
diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php
index bef8ae0ea9..f051781547 100644
--- a/phpBB/includes/acp/acp_captcha.php
+++ b/phpBB/includes/acp/acp_captcha.php
@@ -104,13 +104,13 @@ class acp_captcha
foreach ($captchas['available'] as $value => $title)
{
$current = ($selected !== false && $value == $selected) ? ' selected="selected"' : '';
- $captcha_select .= '<option value="' . $value . '"' . $current . '>' . $user->lang[$title] . '</option>';
+ $captcha_select .= '<option value="' . $value . '"' . $current . '>' . $user->lang($title) . '</option>';
}
foreach ($captchas['unavailable'] as $value => $title)
{
$current = ($selected !== false && $value == $selected) ? ' selected="selected"' : '';
- $captcha_select .= '<option value="' . $value . '"' . $current . ' class="disabled-option">' . $user->lang[$title] . '</option>';
+ $captcha_select .= '<option value="' . $value . '"' . $current . ' class="disabled-option">' . $user->lang($title) . '</option>';
}
$demo_captcha = phpbb_captcha_factory::get_instance($selected);
diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php
index 632578ef2d..38d4d3c8e4 100644
--- a/phpBB/includes/acp/acp_database.php
+++ b/phpBB/includes/acp/acp_database.php
@@ -221,6 +221,7 @@ class acp_database
case 'submit':
$delete = request_var('delete', '');
$file = request_var('file', '');
+ $download = request_var('download', '');
if (!preg_match('#^backup_\d{10,}_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
{
@@ -247,10 +248,8 @@ class acp_database
confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file)));
}
}
- else
+ else if ($download || confirm_box(true))
{
- $download = request_var('download', '');
-
if ($download)
{
$name = $matches[0];
@@ -411,6 +410,10 @@ class acp_database
trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action));
break;
}
+ else if (!$download)
+ {
+ confirm_box(false, $user->lang['RESTORE_SELECTED_BACKUP'], build_hidden_fields(array('file' => $file)));
+ }
default:
$methods = array('sql');
diff --git a/phpBB/includes/acp/acp_email.php b/phpBB/includes/acp/acp_email.php
index b4755d3984..8812302601 100644
--- a/phpBB/includes/acp/acp_email.php
+++ b/phpBB/includes/acp/acp_email.php
@@ -136,8 +136,9 @@ class acp_email
$i = $j = 0;
- // Send with BCC, no more than 50 recipients for one mail (to not exceed the limit)
- $max_chunk_size = 50;
+ // Send with BCC
+ // Maximum number of bcc recipients
+ $max_chunk_size = (int) $config['email_max_chunk_size'];
$email_list = array();
$old_lang = $row['user_lang'];
$old_notify_type = $row['user_notify_type'];
@@ -194,10 +195,7 @@ class acp_email
$messenger->template('admin_send_email', $used_lang);
- $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
- $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
- $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
- $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
+ $messenger->anti_abuse_headers($config, $user);
$messenger->subject(htmlspecialchars_decode($subject));
$messenger->set_mail_priority($priority);
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index 854f262a0b..7fe8915ad1 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -212,15 +212,11 @@ class acp_forums
$message = ($action == 'add') ? $user->lang['FORUM_CREATED'] : $user->lang['FORUM_UPDATED'];
- // Redirect to permissions
- if ($auth->acl_get('a_fauth') && !$copied_permissions)
- {
- $message .= '<br /><br />' . sprintf($user->lang['REDIRECT_ACL'], '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url) . '">', '</a>');
- }
-
// redirect directly to permission settings screen if authed
if ($action == 'add' && !$copied_permissions && $auth->acl_get('a_fauth'))
{
+ $message .= '<br /><br />' . sprintf($user->lang['REDIRECT_ACL'], '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url) . '">', '</a>');
+
meta_refresh(4, append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url));
}
diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php
index 221dea2345..98b0e4dc56 100644
--- a/phpBB/includes/acp/acp_groups.php
+++ b/phpBB/includes/acp/acp_groups.php
@@ -371,7 +371,7 @@ class acp_groups
{
if ($data['width'] > $config['avatar_max_width'] || $data['height'] > $config['avatar_max_height'])
{
- $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $data['width'], $data['height']);
+ $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
}
}
@@ -381,7 +381,7 @@ class acp_groups
{
if ($data['width'] < $config['avatar_min_width'] || $data['height'] < $config['avatar_min_height'])
{
- $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $data['width'], $data['height']);
+ $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
}
}
}
@@ -627,7 +627,7 @@ class acp_groups
'U_BACK' => $u_back,
'U_SWATCH' => append_sid("{$phpbb_admin_path}swatch.$phpEx", 'form=settings&amp;name=group_colour'),
'U_ACTION' => "{$this->u_action}&amp;action=$action&amp;g=$group_id",
- 'L_AVATAR_EXPLAIN' => sprintf($user->lang['AVATAR_EXPLAIN'], $config['avatar_max_width'], $config['avatar_max_height'], round($config['avatar_filesize'] / 1024)),
+ 'L_AVATAR_EXPLAIN' => phpbb_avatar_explanation_string(),
));
return;
@@ -835,7 +835,7 @@ class acp_groups
case 'set_config_teampage':
set_config('teampage_forums', request_var('teampage_forums', 0));
- set_config('teampage_multiple', request_var('teampage_multiple', 0));
+ set_config('teampage_memberships', request_var('teampage_memberships', 0));
break;
case 'add':
@@ -916,11 +916,11 @@ class acp_groups
'U_ACTION_LEGEND' => $this->u_action . '&amp;field=legend',
'U_ACTION_TEAMPAGE' => $this->u_action . '&amp;field=teampage',
- 'S_GROUP_SELECT_LEGEND' => $s_group_select_legend,
- 'S_GROUP_SELECT_TEAMPAGE' => $s_group_select_teampage,
- 'DISPLAY_FORUMS' => ($config['teampage_forums']) ? true : false,
- 'DISPLAY_MULTIPLE' => ($config['teampage_multiple']) ? true : false,
- 'LEGEND_SORT_GROUPNAME' => ($config['legend_sort_groupname']) ? true : false,
+ 'S_GROUP_SELECT_LEGEND' => $s_group_select_legend,
+ 'S_GROUP_SELECT_TEAMPAGE' => $s_group_select_teampage,
+ 'DISPLAY_FORUMS' => ($config['teampage_forums']) ? true : false,
+ 'DISPLAY_MEMBERSHIPS' => $config['teampage_memberships'],
+ 'LEGEND_SORT_GROUPNAME' => ($config['legend_sort_groupname']) ? true : false,
));
}
}
diff --git a/phpBB/includes/acp/acp_icons.php b/phpBB/includes/acp/acp_icons.php
index c848039c66..e02124fb42 100644
--- a/phpBB/includes/acp/acp_icons.php
+++ b/phpBB/includes/acp/acp_icons.php
@@ -379,7 +379,7 @@ class acp_icons
if ($smiley_count + $addable_smileys_count > SMILEY_LIMIT)
{
- trigger_error(sprintf($user->lang['TOO_MANY_SMILIES'], SMILEY_LIMIT) . adm_back_link($this->u_action), E_USER_WARNING);
+ trigger_error($user->lang('TOO_MANY_SMILIES', SMILEY_LIMIT) . adm_back_link($this->u_action), E_USER_WARNING);
}
}
@@ -487,21 +487,7 @@ class acp_icons
$cache->destroy('_icons');
$cache->destroy('sql', $table);
- $level = E_USER_NOTICE;
- switch ($icons_updated)
- {
- case 0:
- $suc_lang = "{$lang}_NONE";
- $level = E_USER_WARNING;
- break;
-
- case 1:
- $suc_lang = "{$lang}_ONE";
- break;
-
- default:
- $suc_lang = $lang;
- }
+ $level = ($icons_updated) ? E_USER_NOTICE : E_USER_WARNING;
$errormsgs = '';
foreach ($errors as $img => $error)
{
@@ -509,11 +495,11 @@ class acp_icons
}
if ($action == 'modify')
{
- trigger_error($user->lang[$suc_lang . '_EDITED'] . $errormsgs . adm_back_link($this->u_action), $level);
+ trigger_error($user->lang($lang . '_EDITED', $icons_updated) . $errormsgs . adm_back_link($this->u_action), $level);
}
else
{
- trigger_error($user->lang[$suc_lang . '_ADDED'] . $errormsgs . adm_back_link($this->u_action), $level);
+ trigger_error($user->lang($lang . '_ADDED', $icons_updated) . $errormsgs . adm_back_link($this->u_action), $level);
}
break;
@@ -599,7 +585,7 @@ class acp_icons
$smiley_count = $this->item_count($table);
if ($smiley_count + sizeof($pak_ary) > SMILEY_LIMIT)
{
- trigger_error(sprintf($user->lang['TOO_MANY_SMILIES'], SMILEY_LIMIT) . adm_back_link($this->u_action), E_USER_WARNING);
+ trigger_error($user->lang('TOO_MANY_SMILIES', SMILEY_LIMIT) . adm_back_link($this->u_action), E_USER_WARNING);
}
}
diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php
index 0e4801f630..8df11f053a 100644
--- a/phpBB/includes/acp/acp_inactive.php
+++ b/phpBB/includes/acp/acp_inactive.php
@@ -118,10 +118,7 @@ class acp_inactive
$messenger->to($row['user_email'], $row['username']);
- $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
- $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
- $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
- $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
+ $messenger->anti_abuse_headers($config, $user);
$messenger->assign_vars(array(
'USERNAME' => htmlspecialchars_decode($row['username']))
@@ -209,10 +206,7 @@ class acp_inactive
$messenger->to($row['user_email'], $row['username']);
$messenger->im($row['user_jabber'], $row['username']);
- $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
- $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
- $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
- $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
+ $messenger->anti_abuse_headers($config, $user);
$messenger->assign_vars(array(
'USERNAME' => htmlspecialchars_decode($row['username']),
diff --git a/phpBB/includes/acp/acp_language.php b/phpBB/includes/acp/acp_language.php
index ffa8df1848..91b48f013e 100644
--- a/phpBB/includes/acp/acp_language.php
+++ b/phpBB/includes/acp/acp_language.php
@@ -869,6 +869,9 @@ class acp_language
$default_lang_id = (int) $db->sql_fetchfield('lang_id');
$db->sql_freeresult($result);
+ // We want to notify the admin that custom profile fields need to be updated for the new language.
+ $notify_cpf_update = false;
+
// From the mysql documentation:
// Prior to MySQL 4.0.14, the target table of the INSERT statement cannot appear in the FROM clause of the SELECT part of the query. This limitation is lifted in 4.0.14.
// Due to this we stay on the safe side if we do the insertion "the manual way"
@@ -882,6 +885,7 @@ class acp_language
{
$row['lang_id'] = $lang_id;
$db->sql_query('INSERT INTO ' . PROFILE_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $row));
+ $notify_cpf_update = true;
}
$db->sql_freeresult($result);
@@ -894,12 +898,15 @@ class acp_language
{
$row['lang_id'] = $lang_id;
$db->sql_query('INSERT INTO ' . PROFILE_FIELDS_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $row));
+ $notify_cpf_update = true;
}
$db->sql_freeresult($result);
add_log('admin', 'LOG_LANGUAGE_PACK_INSTALLED', $lang_pack['name']);
- trigger_error(sprintf($user->lang['LANGUAGE_PACK_INSTALLED'], $lang_pack['name']) . adm_back_link($this->u_action));
+ $message = sprintf($user->lang['LANGUAGE_PACK_INSTALLED'], $lang_pack['name']);
+ $message .= ($notify_cpf_update) ? '<br /><br />' . $user->lang['LANGUAGE_PACK_CPF_UPDATE'] : '';
+ trigger_error($message . adm_back_link($this->u_action));
break;
diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php
index a922ef570c..6304ff9d47 100644
--- a/phpBB/includes/acp/acp_main.php
+++ b/phpBB/includes/acp/acp_main.php
@@ -600,6 +600,17 @@ class acp_main
$template->assign_var('S_WRITABLE_CONFIG', (bool) (@fileperms($phpbb_root_path . 'config.' . $phpEx) & 0x0002));
}
+ if (extension_loaded('mbstring'))
+ {
+ $template->assign_vars(array(
+ 'S_MBSTRING_LOADED' => true,
+ 'S_MBSTRING_FUNC_OVERLOAD_FAIL' => (intval(@ini_get('mbstring.func_overload')) & (MB_OVERLOAD_MAIL | MB_OVERLOAD_STRING)),
+ 'S_MBSTRING_ENCODING_TRANSLATION_FAIL' => (@ini_get('mbstring.encoding_translation') != 0),
+ 'S_MBSTRING_HTTP_INPUT_FAIL' => (@ini_get('mbstring.http_input') != 'pass'),
+ 'S_MBSTRING_HTTP_OUTPUT_FAIL' => (@ini_get('mbstring.http_output') != 'pass'),
+ ));
+ }
+
// Fill dbms version if not yet filled
if (empty($config['dbms_version']))
{
diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php
index 52033b590c..e51b440d4d 100644
--- a/phpBB/includes/acp/acp_modules.php
+++ b/phpBB/includes/acp/acp_modules.php
@@ -111,7 +111,7 @@ class acp_modules
}
break;
-
+
case 'enable':
case 'disable':
if (!$module_id)
@@ -170,7 +170,7 @@ class acp_modules
add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname']), $move_module_name);
$this->remove_cache_file();
}
-
+
break;
case 'quickadd':
@@ -207,7 +207,7 @@ class acp_modules
if (!sizeof($errors))
{
$this->remove_cache_file();
-
+
trigger_error($user->lang['MODULE_ADDED'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
}
}
@@ -231,7 +231,7 @@ 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);
// no break
@@ -250,7 +250,7 @@ class acp_modules
'module_auth' => '',
);
}
-
+
$module_data = array();
$module_data['module_basename'] = request_var('module_basename', (string) $module_row['module_basename']);
@@ -295,7 +295,7 @@ class acp_modules
if (!sizeof($errors))
{
$this->remove_cache_file();
-
+
trigger_error((($action == 'add') ? $user->lang['MODULE_ADDED'] : $user->lang['MODULE_EDITED']) . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
}
}
@@ -316,7 +316,7 @@ class acp_modules
}
// Name options
- $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $this->lang_name($values['title']) . ' [' . $this->module_class . '_' . $option . ']</option>';
+ $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $this->lang_name($values['title']) . ' [' . $option . ']</option>';
$template->assign_block_vars('m_names', array('NAME' => $option, 'A_NAME' => addslashes($option)));
@@ -327,7 +327,7 @@ class acp_modules
{
$s_mode_options .= '<option value="' . $m_mode . '"' . (($m_mode == $module_data['module_mode']) ? ' selected="selected"' : '') . '>' . $this->lang_name($m_values['title']) . '</option>';
}
-
+
$template->assign_block_vars('m_names.modes', array(
'OPTION' => $m_mode,
'VALUE' => $this->lang_name($m_values['title']),
@@ -336,7 +336,7 @@ class acp_modules
);
}
}
-
+
$s_cat_option = '<option value="0"' . (($module_data['parent_id'] == 0) ? ' selected="selected"' : '') . '>' . $user->lang['NO_PARENT'] . '</option>';
$template->assign_vars(array_merge(array(
@@ -349,7 +349,7 @@ class acp_modules
'U_EDIT_ACTION' => $this->u_action . '&amp;parent_id=' . $this->parent_id,
'L_TITLE' => $user->lang[strtoupper($action) . '_MODULE'],
-
+
'MODULENAME' => $this->lang_name($module_data['module_langname']),
'ACTION' => $action,
'MODULE_ID' => $module_id,
@@ -480,7 +480,7 @@ class acp_modules
foreach ($module_infos as $option => $values)
{
// Name options
- $s_install_options .= '<optgroup label="' . $this->lang_name($values['title']) . ' [' . $this->module_class . '_' . $option . ']">';
+ $s_install_options .= '<optgroup label="' . $this->lang_name($values['title']) . ' [' . $option . ']">';
// Build module modes
foreach ($values['modes'] as $m_mode => $m_values)
@@ -516,7 +516,7 @@ class acp_modules
$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);
@@ -524,14 +524,14 @@ class acp_modules
return $row;
}
-
+
/**
* Get available module information from module files
*/
function get_module_infos($module = '', $module_class = false)
{
global $phpbb_root_path, $phpEx;
-
+
$module_class = ($module_class === false) ? $this->module_class : $module_class;
$directory = $phpbb_root_path . 'includes/' . $module_class . '/info/';
@@ -539,57 +539,72 @@ class acp_modules
if (!$module)
{
- $dh = @opendir($directory);
+ global $phpbb_extension_manager;
- if (!$dh)
- {
- return $fileinfo;
- }
+ $finder = $phpbb_extension_manager->get_finder();
+
+ $modules = $finder
+ ->extension_suffix('_module')
+ ->extension_directory("/$module_class")
+ ->core_path("includes/$module_class/info/")
+ ->core_prefix($module_class . '_')
+ ->get_classes();
- while (($file = readdir($dh)) !== false)
+ foreach ($modules as $module)
{
- // Is module?
- if (preg_match('/^' . $module_class . '_.+\.' . $phpEx . '$/', $file))
- {
- $class = str_replace(".$phpEx", '', $file) . '_info';
+ $info_class = preg_replace('/_module$/', '_info', $module);
- if (!class_exists($class))
+ // 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
+ if (!class_exists($info_class))
+ {
+ $info_class = str_replace("phpbb_{$module_class}_info_", '', $module) . '_info';
+ if (file_exists($directory . $info_class . '.' . $phpEx))
{
- include($directory . $file);
+ include($directory . $info_class . '.' . $phpEx);
}
+ }
- // Get module title tag
- if (class_exists($class))
- {
- $c_class = new $class();
- $module_info = $c_class->module();
- $fileinfo[str_replace($module_class . '_', '', $module_info['filename'])] = $module_info;
- }
+ if (class_exists($info_class))
+ {
+ $info = new $info_class();
+ $module_info = $info->module();
+
+ $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $module;
+
+ $fileinfo[$main_class] = $module_info;
}
}
- closedir($dh);
ksort($fileinfo);
}
else
{
- $filename = $module_class . '_' . basename($module);
- $class = $module_class . '_' . basename($module) . '_info';
+ $info_class = preg_replace('/_module$/', '_info', $module);
- if (!class_exists($class))
+ if (!class_exists($info_class))
{
- include($directory . $filename . '.' . $phpEx);
+ if (file_exists($directory . $module . '.' . $phpEx))
+ {
+ include($directory . $module . '.' . $phpEx);
+ }
+ $info_class = $module . '_info';
}
// Get module title tag
- if (class_exists($class))
+ if (class_exists($info_class))
{
- $c_class = new $class();
- $module_info = $c_class->module();
- $fileinfo[str_replace($module_class . '_', '', $module_info['filename'])] = $module_info;
+ $info = new $info_class();
+ $module_info = $info->module();
+
+ $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $module;
+
+ $fileinfo[$main_class] = $module_info;
}
}
-
+
return $fileinfo;
}
@@ -721,7 +736,7 @@ class acp_modules
// Sanitise for future path use, it's escaped as appropriate for queries
$p_class = str_replace(array('.', '/', '\\'), '', basename($this->module_class));
-
+
$cache->destroy('_modules_' . $p_class);
// Additionally remove sql cache
diff --git a/phpBB/includes/acp/acp_search.php b/phpBB/includes/acp/acp_search.php
index a3061ae2da..2de76187d5 100644
--- a/phpBB/includes/acp/acp_search.php
+++ b/phpBB/includes/acp/acp_search.php
@@ -77,7 +77,8 @@ class acp_search
continue;
}
- $name = ucfirst(strtolower(str_replace('_', ' ', $type)));
+ $name = $search->get_name();
+
$selected = ($config['search_type'] == $type) ? ' selected="selected"' : '';
$search_options .= '<option value="' . $type . '"' . $selected . '>' . $name . '</option>';
@@ -275,7 +276,7 @@ class acp_search
{
trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
}
- $name = ucfirst(strtolower(str_replace('_', ' ', $this->state[0])));
+ $name = $this->search->get_name();
$action = &$this->state[1];
@@ -337,7 +338,7 @@ class acp_search
$totaltime = $mtime[0] + $mtime[1] - $starttime;
$rows_per_second = $row_count / $totaltime;
meta_refresh(1, append_sid($this->u_action . '&amp;action=delete&amp;skip_rows=' . $post_counter));
- trigger_error(sprintf($user->lang['SEARCH_INDEX_DELETE_REDIRECT'], $post_counter, $row_count, $rows_per_second));
+ trigger_error($user->lang('SEARCH_INDEX_DELETE_REDIRECT', (int) $row_count, $post_counter, $rows_per_second));
}
}
@@ -427,7 +428,7 @@ class acp_search
$totaltime = $mtime[0] + $mtime[1] - $starttime;
$rows_per_second = $row_count / $totaltime;
meta_refresh(1, append_sid($this->u_action . '&amp;action=create&amp;skip_rows=' . $post_counter));
- trigger_error(sprintf($user->lang['SEARCH_INDEX_CREATE_REDIRECT'], $post_counter, $row_count, $rows_per_second));
+ trigger_error($user->lang('SEARCH_INDEX_CREATE_REDIRECT', (int) $row_count, $post_counter) . $user->lang('SEARCH_INDEX_CREATE_REDIRECT_RATE', $rows_per_second));
}
}
@@ -454,7 +455,7 @@ class acp_search
continue;
}
- $name = ucfirst(strtolower(str_replace('_', ' ', $type)));
+ $name = $search->get_name();
$data = array();
if (method_exists($search, 'index_stats'))
@@ -553,27 +554,15 @@ class acp_search
function get_search_types()
{
- global $phpbb_root_path, $phpEx;
-
- $search_types = array();
-
- $dp = @opendir($phpbb_root_path . 'includes/search');
-
- if ($dp)
- {
- while (($file = readdir($dp)) !== false)
- {
- if ((preg_match('#\.' . $phpEx . '$#', $file)) && ($file != "search.$phpEx"))
- {
- $search_types[] = preg_replace('#^(.*?)\.' . $phpEx . '$#', '\1', $file);
- }
- }
- closedir($dp);
+ global $phpbb_root_path, $phpEx, $phpbb_extension_manager;
- sort($search_types);
- }
+ $finder = $phpbb_extension_manager->get_finder();
- return $search_types;
+ return $finder
+ ->extension_suffix('_backend')
+ ->extension_directory('/search')
+ ->core_path('includes/search/')
+ ->get_classes();
}
function get_max_post_id()
@@ -610,15 +599,7 @@ class acp_search
{
global $phpbb_root_path, $phpEx, $user;
- if (!preg_match('#^\w+$#', $type) || !file_exists("{$phpbb_root_path}includes/search/$type.$phpEx"))
- {
- $error = $user->lang['NO_SUCH_SEARCH_MODULE'];
- return $error;
- }
-
- include_once("{$phpbb_root_path}includes/search/$type.$phpEx");
-
- if (!class_exists($type))
+ if (!class_exists($type) || !method_exists($type, 'get_name'))
{
$error = $user->lang['NO_SUCH_SEARCH_MODULE'];
return $error;
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 9bcf1b20db..c1ad28ca14 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -348,10 +348,7 @@ class acp_users
$messenger->to($user_row['user_email'], $user_row['username']);
- $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
- $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
- $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
- $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
+ $messenger->anti_abuse_headers($config, $user);
$messenger->assign_vars(array(
'WELCOME_MSG' => htmlspecialchars_decode(sprintf($user->lang['WELCOME_SUBJECT'], $config['sitename'])),
@@ -406,10 +403,7 @@ class acp_users
$messenger->to($user_row['user_email'], $user_row['username']);
- $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
- $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
- $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
- $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
+ $messenger->anti_abuse_headers($config, $user);
$messenger->assign_vars(array(
'USERNAME' => htmlspecialchars_decode($user_row['username']))
@@ -818,7 +812,7 @@ class acp_users
// Which updates do we need to do?
$update_username = ($user_row['username'] != $data['username']) ? $data['username'] : false;
- $update_password = ($data['new_password'] && !phpbb_check_hash($user_row['user_password'], $data['new_password'])) ? true : false;
+ $update_password = ($data['new_password'] && !phpbb_check_hash($data['new_password'], $user_row['user_password'])) ? true : false;
$update_email = ($data['email'] != $user_row['user_email']) ? $data['email'] : false;
if (!sizeof($error))
@@ -1016,8 +1010,8 @@ class acp_users
$db->sql_freeresult($result);
$template->assign_vars(array(
- 'L_NAME_CHARS_EXPLAIN' => sprintf($user->lang[$config['allow_name_chars'] . '_EXPLAIN'], $config['min_name_chars'], $config['max_name_chars']),
- 'L_CHANGE_PASSWORD_EXPLAIN' => sprintf($user->lang[$config['pass_complex'] . '_EXPLAIN'], $config['min_pass_chars'], $config['max_pass_chars']),
+ 'L_NAME_CHARS_EXPLAIN' => $user->lang($config['allow_name_chars'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_name_chars']), $user->lang('CHARACTERS', (int) $config['max_name_chars'])),
+ 'L_CHANGE_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars']), $user->lang('CHARACTERS', (int) $config['max_pass_chars'])),
'L_POSTS_IN_QUEUE' => $user->lang('NUM_POSTS_IN_QUEUE', $user_row['posts_in_queue']),
'S_FOUNDER' => ($user->data['user_type'] == USER_FOUNDER) ? true : false,
@@ -1754,8 +1748,8 @@ class acp_users
'USER_AVATAR_WIDTH' => $user_row['user_avatar_width'],
'USER_AVATAR_HEIGHT' => $user_row['user_avatar_height'],
- 'L_AVATAR_EXPLAIN' => sprintf($user->lang['AVATAR_EXPLAIN'], $config['avatar_max_width'], $config['avatar_max_height'], round($config['avatar_filesize'] / 1024)))
- );
+ 'L_AVATAR_EXPLAIN' => phpbb_avatar_explanation_string(),
+ ));
break;
@@ -1887,7 +1881,7 @@ class acp_users
'FLASH_STATUS' => ($config['allow_sig_flash']) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'],
'URL_STATUS' => ($config['allow_sig_links']) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'],
- 'L_SIGNATURE_EXPLAIN' => sprintf($user->lang['SIGNATURE_EXPLAIN'], $config['max_sig_chars']),
+ 'L_SIGNATURE_EXPLAIN' => $user->lang('SIGNATURE_EXPLAIN', (int) $config['max_sig_chars']),
'S_BBCODE_ALLOWED' => $config['allow_sig_bbcode'],
'S_SMILIES_ALLOWED' => $config['allow_sig_smilies'],
diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php
index c3367fbd46..929ea45c9b 100644
--- a/phpBB/includes/bbcode.php
+++ b/phpBB/includes/bbcode.php
@@ -127,14 +127,15 @@ class bbcode
*/
function bbcode_cache_init()
{
- global $phpbb_root_path, $phpEx, $config, $user;
+ global $phpbb_root_path, $phpEx, $config, $user, $phpbb_extension_manager;
if (empty($this->template_filename))
{
$this->template_bitfield = new bitfield($user->theme['bbcode_bitfield']);
$template_locator = new phpbb_template_locator();
- $template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $template_locator);
+ $template_path_provider = new phpbb_template_extension_path_provider($phpbb_extension_manager, new phpbb_template_path_provider());
+ $template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $template_locator, $template_path_provider);
$template->set_template();
$template_locator->set_filenames(array('bbcode.html' => 'bbcode.html'));
$this->template_filename = $template_locator->get_source_file_for_handle('bbcode.html');
diff --git a/phpBB/includes/captcha/captcha_factory.php b/phpBB/includes/captcha/captcha_factory.php
index c2ec8c5bda..e039e92054 100644
--- a/phpBB/includes/captcha/captcha_factory.php
+++ b/phpBB/includes/captcha/captcha_factory.php
@@ -59,38 +59,38 @@ class phpbb_captcha_factory
*/
function get_captcha_types()
{
- global $phpbb_root_path, $phpEx;
+ global $phpbb_root_path, $phpEx, $phpbb_extension_manager;
$captchas = array(
'available' => array(),
'unavailable' => array(),
);
- $dp = @opendir($phpbb_root_path . 'includes/captcha/plugins');
+ $finder = $phpbb_extension_manager->get_finder();
+ $captcha_plugin_classes = $finder
+ ->extension_directory('/captcha')
+ ->suffix('_plugin')
+ ->core_path('includes/captcha/plugins/')
+ ->get_classes();
- if ($dp)
+ foreach ($captcha_plugin_classes as $class)
{
- while (($file = readdir($dp)) !== false)
+ // check if this class needs to be loaded in legacy mode
+ $old_class = preg_replace('/^phpbb_captcha_plugins_/', '', $class);
+ if (file_exists($phpbb_root_path . "includes/captcha/plugins/$old_class.$phpEx") && !class_exists($old_class))
{
- if ((preg_match('#_plugin\.' . $phpEx . '$#', $file)))
- {
- $name = preg_replace('#^(.*?)_plugin\.' . $phpEx . '$#', '\1', $file);
- if (!class_exists($name))
- {
- include($phpbb_root_path . "includes/captcha/plugins/$file");
- }
+ include($phpbb_root_path . "includes/captcha/plugins/$old_class.$phpEx");
+ $class = preg_replace('/_plugin$/', '', $old_class);
+ }
- if (call_user_func(array($name, 'is_available')))
- {
- $captchas['available'][$name] = call_user_func(array($name, 'get_name'));
- }
- else
- {
- $captchas['unavailable'][$name] = call_user_func(array($name, 'get_name'));
- }
- }
+ if (call_user_func(array($class, 'is_available')))
+ {
+ $captchas['available'][$class] = call_user_func(array($class, 'get_name'));
+ }
+ else
+ {
+ $captchas['unavailable'][$class] = call_user_func(array($class, 'get_name'));
}
- closedir($dp);
}
return $captchas;
diff --git a/phpBB/includes/captcha/plugins/captcha_abstract.php b/phpBB/includes/captcha/plugins/captcha_abstract.php
index aea39b3123..07a0ea1279 100644
--- a/phpBB/includes/captcha/plugins/captcha_abstract.php
+++ b/phpBB/includes/captcha/plugins/captcha_abstract.php
@@ -22,7 +22,7 @@ if (!defined('IN_PHPBB'))
*
* @package VC
*/
-class phpbb_default_captcha
+class phpbb_captcha_plugins_captcha_abstract
{
var $confirm_id;
var $confirm_code;
@@ -364,3 +364,10 @@ class phpbb_default_captcha
}
}
+
+/**
+* Old class name for legacy use. The new class name is auto loadable.
+*/
+class phpbb_default_captcha extends phpbb_captcha_plugins_captcha_abstract
+{
+}
diff --git a/phpBB/includes/class_loader.php b/phpBB/includes/class_loader.php
index a28d745983..bc268d342e 100644
--- a/phpBB/includes/class_loader.php
+++ b/phpBB/includes/class_loader.php
@@ -31,22 +31,32 @@ if (!defined('IN_PHPBB'))
*/
class phpbb_class_loader
{
- private $phpbb_root_path;
+ private $prefix;
+ private $path;
private $php_ext;
private $cache;
+
+ /**
+ * A map of looked up class names to paths relative to $this->path.
+ * This map is stored in cache and looked up if the cache is available.
+ *
+ * @var array
+ */
private $cached_paths = array();
/**
* Creates a new phpbb_class_loader, which loads files with the given
- * file extension from the given phpbb root path.
+ * file extension from the given path.
*
- * @param string $phpbb_root_path phpBB's root directory containing includes/
- * @param string $php_ext The file extension for PHP files
+ * @param string $prefix Required class name prefix for files to be loaded
+ * @param string $path Directory to load files from
+ * @param string $php_ext The file extension for PHP files
* @param phpbb_cache_driver_interface $cache An implementation of the phpBB cache interface.
*/
- public function __construct($phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null)
+ public function __construct($prefix, $path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null)
{
- $this->phpbb_root_path = $phpbb_root_path;
+ $this->prefix = $prefix;
+ $this->path = $path;
$this->php_ext = $php_ext;
$this->set_cache($cache);
@@ -63,7 +73,7 @@ class phpbb_class_loader
{
if ($cache)
{
- $this->cached_paths = $cache->get('class_loader');
+ $this->cached_paths = $cache->get('class_loader_' . $this->prefix);
if ($this->cached_paths === false)
{
@@ -100,23 +110,21 @@ class phpbb_class_loader
*/
public function resolve_path($class)
{
- $path_prefix = $this->phpbb_root_path . 'includes/';
-
if (isset($this->cached_paths[$class]))
{
- return $path_prefix . $this->cached_paths[$class] . $this->php_ext;
+ return $this->path . $this->cached_paths[$class] . $this->php_ext;
}
- if (!preg_match('/phpbb_[a-zA-Z0-9_]+/', $class))
+ if (!preg_match('/^' . $this->prefix . '[a-zA-Z0-9_]+$/', $class))
{
return false;
}
- $parts = explode('_', substr($class, 6));
+ $parts = explode('_', substr($class, strlen($this->prefix)));
$dirs = '';
- for ($i = 0, $n = sizeof($parts); $i < $n && is_dir($path_prefix . $dirs . $parts[$i]); $i++)
+ for ($i = 0, $n = sizeof($parts); $i < $n && is_dir($this->path . $dirs . $parts[$i]); $i++)
{
$dirs .= $parts[$i] . '/';
}
@@ -129,7 +137,7 @@ class phpbb_class_loader
$relative_path = $dirs . implode(array_slice($parts, $i, sizeof($parts) - $i), '_');
- if (!file_exists($path_prefix . $relative_path . $this->php_ext))
+ if (!file_exists($this->path . $relative_path . $this->php_ext))
{
return false;
}
@@ -137,10 +145,10 @@ class phpbb_class_loader
if ($this->cache)
{
$this->cached_paths[$class] = $relative_path;
- $this->cache->put('class_loader', $this->cached_paths);
+ $this->cache->put('class_loader_' . $this->prefix, $this->cached_paths);
}
- return $path_prefix . $relative_path . $this->php_ext;
+ return $this->path . $relative_path . $this->php_ext;
}
/**
@@ -150,7 +158,7 @@ class phpbb_class_loader
*/
public function load_class($class)
{
- if (substr($class, 0, 6) === 'phpbb_')
+ if (substr($class, 0, strlen($this->prefix)) === $this->prefix)
{
$path = $this->resolve_path($class);
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index 8ef1a4655d..d5b398b7bf 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -226,6 +226,7 @@ define('CONFIG_TABLE', $table_prefix . 'config');
define('CONFIRM_TABLE', $table_prefix . 'confirm');
define('DISALLOW_TABLE', $table_prefix . 'disallow');
define('DRAFTS_TABLE', $table_prefix . 'drafts');
+define('EXT_TABLE', $table_prefix . 'ext');
define('EXTENSIONS_TABLE', $table_prefix . 'extensions');
define('EXTENSION_GROUPS_TABLE', $table_prefix . 'extension_groups');
define('FORUMS_TABLE', $table_prefix . 'forums');
diff --git a/phpBB/includes/cron/manager.php b/phpBB/includes/cron/manager.php
index 31be1a69cb..a0bf018b33 100644
--- a/phpBB/includes/cron/manager.php
+++ b/phpBB/includes/cron/manager.php
@@ -33,137 +33,24 @@ class phpbb_cron_manager
protected $tasks = array();
/**
- * Path to the root of directory tree with tasks.
- * For bundled phpBB tasks, this is the path to includes/cron/tasks
- * under phpBB root.
- * @var string
- */
- protected $task_path;
-
- /**
- * PHP file extension
- * @var string
- */
- protected $phpEx;
-
- /**
- * Cache driver
- * @var phpbb_cache_driver_interface
- */
- protected $cache;
-
- /**
* Constructor. Loads all available tasks.
*
- * Tasks will be looked up in directory tree rooted at $task_path.
- * Task classes will be autoloaded and must be named according to
- * autoloading naming conventions. To load cron tasks shipped with
- * phpbb, pass $phpbb_root_path . 'includes/cron/task' as $task_path.
- *
- * If $cache is given, names of found cron tasks will be cached in it
- * for one hour. Note that the cron task names are stored without
- * namespacing; if two different phbb_cron_manager instances are
- * constructed with different $task_path arguments but the same $cache,
- * the second instance will use task names found by the first instance.
- *
- * @param string $task_path Directory containing cron tasks
- * @param string $phpEx PHP file extension
- * @param phpbb_cache_driver_interface $cache Cache for task names (optional)
- * @return void
+ * @param array|Traversable $task_names Provides an iterable set of task names
*/
- public function __construct($task_path, $phpEx, phpbb_cache_driver_interface $cache = null)
+ public function __construct($task_names)
{
- if (DIRECTORY_SEPARATOR != '/')
- {
- // Need this on some platforms since the code elsewhere uses /
- // to separate directory components, but PHP iterators return
- // paths with platform-specific directory separators.
- $task_path = str_replace('/', DIRECTORY_SEPARATOR, $task_path);
- }
-
- $this->task_path = $task_path;
- $this->phpEx = $phpEx;
- $this->cache = $cache;
-
- $task_names = $this->find_cron_task_names();
$this->load_tasks($task_names);
}
/**
- * Finds cron task names.
- *
- * A cron task file must follow the naming convention:
- * includes/cron/task/$mod/$name.php.
- * $mod is core for tasks that are part of phpbb.
- * Modifications should use their name as $mod.
- * $name is the name of the cron task.
- * Cron task is expected to be a class named phpbb_cron_task_${mod}_${name}.
- *
- * @return array List of task names
- */
- public function find_cron_task_names()
- {
- if ($this->cache)
- {
- $task_names = $this->cache->get('_cron_tasks');
-
- if ($task_names !== false)
- {
- return $task_names;
- }
- }
-
- $task_names = array();
- $ext = '.' . $this->phpEx;
- $ext_length = strlen($ext);
-
- $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->task_path));
-
- foreach ($iterator as $fileinfo)
- {
- $file = preg_replace('#^' . preg_quote($this->task_path, '#') . '#', '', $fileinfo->getPathname());
-
- // skip directories and files direclty in the task root path
- if ($fileinfo->isFile() && strpos($file, DIRECTORY_SEPARATOR) !== false)
- {
- $task_name = str_replace(DIRECTORY_SEPARATOR, '_', substr($file, 0, -$ext_length));
- if (substr($file, -$ext_length) == $ext && $this->is_valid_name($task_name))
- {
- $task_names[] = 'phpbb_cron_task_' . $task_name;
- }
- }
- }
-
- if ($this->cache)
- {
- $this->cache->put('_cron_tasks', $task_names, 3600);
- }
-
- return $task_names;
- }
-
- /**
- * Checks whether $name is a valid identifier, and
- * therefore part of valid cron task class name.
- *
- * @param string $name Name to check
- *
- * @return bool
- */
- public function is_valid_name($name)
- {
- return (bool) preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $name);
- }
-
- /**
* Loads tasks given by name, wraps them
* and puts them into $this->tasks.
*
- * @param array $task_names Array of strings
+ * @param array|Traversable $task_names Array of strings
*
* @return void
*/
- public function load_tasks(array $task_names)
+ public function load_tasks($task_names)
{
foreach ($task_names as $task_name)
{
diff --git a/phpBB/includes/cron/task/provider.php b/phpBB/includes/cron/task/provider.php
new file mode 100644
index 0000000000..e6ae0f75ec
--- /dev/null
+++ b/phpBB/includes/cron/task/provider.php
@@ -0,0 +1,48 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Provides cron manager with tasks
+*
+* Finds installed cron tasks and makes them available to the cron manager.
+*
+* @package phpBB3
+*/
+class phpbb_cron_task_provider extends phpbb_extension_provider
+{
+ /**
+ * Finds cron task names using the extension manager.
+ *
+ * All PHP files in includes/cron/task/core/ are considered tasks. Tasks
+ * in extensions have to be located in a directory called cron or a subdir
+ * of a directory called cron. The class and filename must end in a _task
+ * suffix. Additionally all PHP files in includes/cron/task/core/ are
+ * tasks.
+ *
+ * @return array List of task names
+ */
+ protected function find()
+ {
+ $finder = $this->extension_manager->get_finder();
+
+ return $finder
+ ->extension_suffix('_task')
+ ->extension_directory('/cron')
+ ->core_path('includes/cron/task/core/')
+ ->get_classes();
+ }
+}
diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php
index a61dc5f58a..4f33a22a09 100644
--- a/phpBB/includes/db/dbal.php
+++ b/phpBB/includes/db/dbal.php
@@ -631,7 +631,7 @@ class dbal
}
}
- $sql .= $this->_sql_custom_build('FROM', implode(', ', $table_array));
+ $sql .= $this->_sql_custom_build('FROM', implode(' CROSS JOIN ', $table_array));
if (!empty($array['LEFT_JOIN']))
{
diff --git a/phpBB/includes/extension/base.php b/phpBB/includes/extension/base.php
new file mode 100644
index 0000000000..d9159d57d2
--- /dev/null
+++ b/phpBB/includes/extension/base.php
@@ -0,0 +1,57 @@
+<?php
+/**
+*
+* @package extension
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* A base class for extensions without custom enable/disable/purge code.
+*
+* @package extension
+*/
+class phpbb_extension_base implements phpbb_extension_interface
+{
+ /**
+ * Single enable step that does nothing
+ *
+ * @param mixed $old_state State returned by previous call of this method
+ * @return false Indicates no further steps are required
+ */
+ public function enable_step($old_state)
+ {
+ return false;
+ }
+
+ /**
+ * Single disable step that does nothing
+ *
+ * @param mixed $old_state State returned by previous call of this method
+ * @return false Indicates no further steps are required
+ */
+ public function disable_step($old_state)
+ {
+ return false;
+ }
+
+ /**
+ * Single purge step that does nothing
+ *
+ * @param mixed $old_state State returned by previous call of this method
+ * @return false Indicates no further steps are required
+ */
+ public function purge_step($old_state)
+ {
+ return false;
+ }
+}
diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php
new file mode 100644
index 0000000000..f4a0b7a371
--- /dev/null
+++ b/phpBB/includes/extension/finder.php
@@ -0,0 +1,422 @@
+<?php
+/**
+*
+* @package extension
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* The extension finder provides a simple way to locate files in active extensions
+*
+* @package extension
+*/
+class phpbb_extension_finder
+{
+ protected $extension_manager;
+ protected $phpbb_root_path;
+ protected $cache;
+ protected $phpEx;
+
+ /**
+ * The cache variable name used to store $this->cached_queries in $this->cache.
+ *
+ * Allows the use of multiple differently configured finders with the same cache.
+ * @var string
+ */
+ protected $cache_name;
+
+ /**
+ * An associative array, containing all search parameters set in methods.
+ * @var array
+ */
+ protected $query;
+
+ /**
+ * A map from md5 hashes of serialized queries to their previously retrieved
+ * results.
+ * @var array
+ */
+ protected $cached_queries;
+
+ /**
+ * Creates a new finder instance with its dependencies
+ *
+ * @param phpbb_extension_manager $extension_manager An extension manager
+ * instance that provides the finder with a list of active
+ * extensions and their locations
+ * @param string $phpbb_root_path Path to the phpbb root directory
+ * @param phpbb_cache_driver_interface $cache A cache instance or null
+ * @param string $phpEx php file extension
+ * @param string $cache_name The name of the cache variable, defaults to
+ * _ext_finder
+ */
+ public function __construct(phpbb_extension_manager $extension_manager, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $phpEx = '.php', $cache_name = '_ext_finder')
+ {
+ $this->extension_manager = $extension_manager;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->cache = $cache;
+ $this->phpEx = $phpEx;
+ $this->cache_name = $cache_name;
+
+ $this->query = array(
+ 'core_path' => false,
+ 'core_suffix' => false,
+ 'core_prefix' => false,
+ 'core_directory' => false,
+ 'extension_suffix' => false,
+ 'extension_prefix' => false,
+ 'extension_directory' => false,
+ );
+
+ $this->cached_queries = ($this->cache) ? $this->cache->get($this->cache_name) : false;
+ }
+
+ /**
+ * Sets a core path to be searched in addition to extensions
+ *
+ * @param string $core_path The path relative to phpbb_root_path
+ * @return phpbb_extension_finder This object for chaining calls
+ */
+ public function core_path($core_path)
+ {
+ $this->query['core_path'] = $core_path;
+ return $this;
+ }
+
+ /**
+ * Sets the suffix all files found in extensions and core must match.
+ *
+ * There is no default file extension, so to find PHP files only, you will
+ * have to specify .php as a suffix. However when using get_classes, the .php
+ * file extension is automatically added to suffixes.
+ *
+ * @param string $suffix A filename suffix
+ * @return phpbb_extension_finder This object for chaining calls
+ */
+ public function suffix($suffix)
+ {
+ $this->core_suffix($suffix);
+ $this->extension_suffix($suffix);
+ return $this;
+ }
+
+ /**
+ * Sets a suffix all files found in extensions must match
+ *
+ * There is no default file extension, so to find PHP files only, you will
+ * have to specify .php as a suffix. However when using get_classes, the .php
+ * file extension is automatically added to suffixes.
+ *
+ * @param string $extension_suffix A filename suffix
+ * @return phpbb_extension_finder This object for chaining calls
+ */
+ public function extension_suffix($extension_suffix)
+ {
+ $this->query['extension_suffix'] = $extension_suffix;
+ return $this;
+ }
+
+ /**
+ * Sets a suffix all files found in the core path must match
+ *
+ * There is no default file extension, so to find PHP files only, you will
+ * have to specify .php as a suffix. However when using get_classes, the .php
+ * file extension is automatically added to suffixes.
+ *
+ * @param string $core_suffix A filename suffix
+ * @return phpbb_extension_finder This object for chaining calls
+ */
+ public function core_suffix($core_suffix)
+ {
+ $this->query['core_suffix'] = $core_suffix;
+ return $this;
+ }
+
+ /**
+ * Sets the prefix all files found in extensions and core must match
+ *
+ * @param string $prefix A filename prefix
+ * @return phpbb_extension_finder This object for chaining calls
+ */
+ public function prefix($prefix)
+ {
+ $this->core_prefix($prefix);
+ $this->extension_prefix($prefix);
+ return $this;
+ }
+
+ /**
+ * Sets a prefix all files found in extensions must match
+ *
+ * @param string $extension_prefix A filename prefix
+ * @return phpbb_extension_finder This object for chaining calls
+ */
+ public function extension_prefix($extension_prefix)
+ {
+ $this->query['extension_prefix'] = $extension_prefix;
+ return $this;
+ }
+
+ /**
+ * Sets a prefix all files found in the core path must match
+ *
+ * @param string $core_prefix A filename prefix
+ * @return phpbb_extension_finder This object for chaining calls
+ */
+ public function core_prefix($core_prefix)
+ {
+ $this->query['core_prefix'] = $core_prefix;
+ return $this;
+ }
+
+ /**
+ * Sets a directory all files found in extensions and core must be contained in
+ *
+ * Automatically sets the core_directory if its value does not differ from
+ * the current directory.
+ *
+ * @param string $directory
+ * @return phpbb_extension_finder This object for chaining calls
+ */
+ public function directory($directory)
+ {
+ $this->core_directory($directory);
+ $this->extension_directory($directory);
+ return $this;
+ }
+
+ /**
+ * Sets a directory all files found in extensions must be contained in
+ *
+ * @param string $extension_directory
+ * @return phpbb_extension_finder This object for chaining calls
+ */
+ public function extension_directory($extension_directory)
+ {
+ $this->query['extension_directory'] = $this->sanitise_directory($extension_directory);
+ return $this;
+ }
+
+ /**
+ * Sets a directory all files found in the core path must be contained in
+ *
+ * @param string $core_directory
+ * @return phpbb_extension_finder This object for chaining calls
+ */
+ public function core_directory($core_directory)
+ {
+ $this->query['core_directory'] = $this->sanitise_directory($core_directory);
+ return $this;
+ }
+
+ /**
+ * Removes occurances of /./ and makes sure path ends without trailing slash
+ *
+ * @param string $directory A directory pattern
+ * @return string A cleaned up directory pattern
+ */
+ protected function sanitise_directory($directory)
+ {
+ $directory = preg_replace('#(?:^|/)\./#', '/', $directory);
+ $dir_len = strlen($directory);
+
+ if ($dir_len > 1 && $directory[$dir_len - 1] === '/')
+ {
+ $directory = substr($directory, 0, -1);
+ }
+
+ return $directory;
+ }
+
+ /**
+ * Finds classes matching the configured options if they follow phpBB naming rules.
+ *
+ * The php file extension is automatically added to suffixes.
+ *
+ * Note: If a file is matched but contains a class name not following the
+ * phpBB naming rules an incorrect class name will be returned.
+ *
+ * @param bool $cache Whether the result should be cached
+ * @return array An array of found class names
+ */
+ public function get_classes($cache = true)
+ {
+ $this->query['extension_suffix'] .= $this->phpEx;
+ $this->query['core_suffix'] .= $this->phpEx;
+
+ $files = $this->find($cache, false);
+
+ $classes = array();
+ foreach ($files as $file => $ext_name)
+ {
+ $file = preg_replace('#^includes/#', '', $file);
+
+ $classes[] = 'phpbb_' . str_replace('/', '_', substr($file, 0, -strlen($this->phpEx)));
+ }
+ return $classes;
+ }
+
+ /**
+ * Finds all directories matching the configured options
+ *
+ * @param bool $cache Whether the result should be cached
+ * @return array An array of paths to found directories
+ */
+ public function get_directories($cache = true)
+ {
+ return $this->find_with_root_path($cache, true);
+ }
+
+ /**
+ * Finds all files matching the configured options.
+ *
+ * @param bool $cache Whether the result should be cached
+ * @return array An array of paths to found files
+ */
+ public function get_files($cache = true)
+ {
+ return $this->find_with_root_path($cache, false);
+ }
+
+ /**
+ * A wrapper around the general find which prepends a root path to results
+ *
+ * @param bool $cache Whether the result should be cached
+ * @param bool $is_dir Directories will be returned when true, only files
+ * otherwise
+ * @return array An array of paths to found items
+ */
+ protected function find_with_root_path($cache = true, $is_dir = false)
+ {
+ $items = $this->find($cache, $is_dir);
+
+ $result = array();
+ foreach ($items as $item => $ext_name)
+ {
+ $result[] = $this->phpbb_root_path . $item;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Finds all file system entries matching the configured options
+ *
+ * @param bool $cache Whether the result should be cached
+ * @param bool $is_dir Directories will be returned when true, only files
+ * otherwise
+ * @return array An array of paths to found items
+ */
+ public function find($cache = true, $is_dir = false)
+ {
+ $this->query['is_dir'] = $is_dir;
+ $query = md5(serialize($this->query));
+
+ if (!defined('DEBUG') && $cache && isset($this->cached_queries[$query]))
+ {
+ return $this->cached_queries[$query];
+ }
+
+ $files = array();
+
+ $extensions = $this->extension_manager->all_enabled();
+
+ if ($this->query['core_path'])
+ {
+ $extensions['/'] = $this->phpbb_root_path . $this->query['core_path'];
+ }
+
+ foreach ($extensions as $name => $path)
+ {
+ $ext_name = $name;
+
+ if (!file_exists($path))
+ {
+ continue;
+ }
+
+ if ($name === '/')
+ {
+ $location = $this->query['core_path'];
+ $name = '';
+ $suffix = $this->query['core_suffix'];
+ $prefix = $this->query['core_prefix'];
+ $directory = $this->query['core_directory'];
+ }
+ else
+ {
+ $location = 'ext/';
+ $name .= '/';
+ $suffix = $this->query['extension_suffix'];
+ $prefix = $this->query['extension_prefix'];
+ $directory = $this->query['extension_directory'];
+ }
+
+ // match only first directory if leading slash is given
+ if ($directory === '/')
+ {
+ $directory_pattern = '^' . preg_quote(DIRECTORY_SEPARATOR, '#');
+ }
+ else if ($directory && $directory[0] === '/')
+ {
+ $directory_pattern = '^' . preg_quote(str_replace('/', DIRECTORY_SEPARATOR, $directory) . DIRECTORY_SEPARATOR, '#');
+ }
+ else
+ {
+ $directory_pattern = preg_quote(DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $directory) . DIRECTORY_SEPARATOR, '#');
+ }
+ $directory_pattern = '#' . $directory_pattern . '#';
+
+ $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
+ foreach ($iterator as $file_info)
+ {
+ $filename = $file_info->getFilename();
+ if ($filename == '.' || $filename == '..')
+ {
+ continue;
+ }
+
+ if ($file_info->isDir() == $is_dir)
+ {
+ if ($is_dir)
+ {
+ $relative_path = $iterator->getInnerIterator()->getSubPath() . DIRECTORY_SEPARATOR . basename($filename) . DIRECTORY_SEPARATOR;
+ if ($relative_path[0] !== DIRECTORY_SEPARATOR)
+ {
+ $relative_path = DIRECTORY_SEPARATOR . $relative_path;
+ }
+ }
+ else
+ {
+ $relative_path = DIRECTORY_SEPARATOR . $iterator->getInnerIterator()->getSubPathname();
+ }
+
+ if ((!$suffix || substr($relative_path, -strlen($suffix)) === $suffix) &&
+ (!$prefix || substr($filename, 0, strlen($prefix)) === $prefix) &&
+ (!$directory || preg_match($directory_pattern, $relative_path)))
+ {
+ $files[str_replace(DIRECTORY_SEPARATOR, '/', $location . $name . substr($relative_path, 1))] = $ext_name;
+ }
+ }
+ }
+ }
+
+ if ($cache && $this->cache)
+ {
+ $this->cached_queries[$query] = $files;
+ $this->cache->put($this->cache_name, $this->cached_queries);
+ }
+
+ return $files;
+ }
+}
diff --git a/phpBB/includes/extension/interface.php b/phpBB/includes/extension/interface.php
new file mode 100644
index 0000000000..b37cd24d77
--- /dev/null
+++ b/phpBB/includes/extension/interface.php
@@ -0,0 +1,65 @@
+<?php
+/**
+*
+* @package extension
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* The interface extension meta classes have to implement to run custom code
+* on enable/disable/purge.
+*
+* @package extension
+*/
+interface phpbb_extension_interface
+{
+ /**
+ * enable_step is executed on enabling an extension until it returns false.
+ *
+ * Calls to this function can be made in subsequent requests, when the
+ * function is invoked through a webserver with a too low max_execution_time.
+ *
+ * @param mixed $old_state The return value of the previous call
+ * of this method, or false on the first call
+ * @return mixed Returns false after last step, otherwise
+ * temporary state which is passed as an
+ * argument to the next step
+ */
+ public function enable_step($old_state);
+
+ /**
+ * Disables the extension.
+ *
+ * Calls to this function can be made in subsequent requests, when the
+ * function is invoked through a webserver with a too low max_execution_time.
+ *
+ * @param mixed $old_state The return value of the previous call
+ * of this method, or false on the first call
+ * @return null
+ */
+ public function disable_step($old_state);
+
+ /**
+ * purge_step is executed on purging an extension until it returns false.
+ *
+ * Calls to this function can be made in subsequent requests, when the
+ * function is invoked through a webserver with a too low max_execution_time.
+ *
+ * @param mixed $old_state The return value of the previous call
+ * of this method, or false on the first call
+ * @return mixed Returns false after last step, otherwise
+ * temporary state which is passed as an
+ * argument to the next step
+ */
+ public function purge_step($old_state);
+}
diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php
new file mode 100644
index 0000000000..bcdd21f7f1
--- /dev/null
+++ b/phpBB/includes/extension/manager.php
@@ -0,0 +1,415 @@
+<?php
+/**
+*
+* @package extension
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* The extension manager provides means to activate/deactivate extensions.
+*
+* @package extension
+*/
+class phpbb_extension_manager
+{
+ protected $cache;
+ protected $phpEx;
+ protected $extensions;
+ protected $extension_table;
+ protected $phpbb_root_path;
+ protected $cache_name;
+
+ /**
+ * Creates a manager and loads information from database
+ *
+ * @param dbal $db A database connection
+ * @param string $extension_table The name of the table holding extensions
+ * @param string $phpbb_root_path Path to the phpbb includes directory.
+ * @param string $phpEx php file extension
+ * @param phpbb_cache_driver_interface $cache A cache instance or null
+ * @param string $cache_name The name of the cache variable, defaults to _ext
+ */
+ public function __construct(dbal $db, $extension_table, $phpbb_root_path, $phpEx = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext')
+ {
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->db = $db;
+ $this->cache = $cache;
+ $this->phpEx = $phpEx;
+ $this->extension_table = $extension_table;
+ $this->cache_name = $cache_name;
+
+ $this->extensions = ($this->cache) ? $this->cache->get($this->cache_name) : false;
+
+ if ($this->extensions === false)
+ {
+ $this->load_extensions();
+ }
+ }
+
+ /**
+ * Loads all extension information from the database
+ *
+ * @return null
+ */
+ protected function load_extensions()
+ {
+ $sql = 'SELECT *
+ FROM ' . $this->extension_table;
+
+ $result = $this->db->sql_query($sql);
+ $extensions = $this->db->sql_fetchrowset($result);
+ $this->db->sql_freeresult($result);
+
+ $this->extensions = array();
+ foreach ($extensions as $extension)
+ {
+ $extension['ext_path'] = $this->get_extension_path($extension['ext_name']);
+ $this->extensions[$extension['ext_name']] = $extension;
+ }
+
+ ksort($this->extensions);
+
+ if ($this->cache)
+ {
+ $this->cache->put($this->cache_name, $this->extensions);
+ }
+ }
+
+ /**
+ * Generates the path to an extension
+ *
+ * @param string $name The name of the extension
+ * @param bool $phpbb_relative Whether the path should be relative to phpbb root
+ * @return string Path to an extension
+ */
+ public function get_extension_path($name, $phpbb_relative = false)
+ {
+ $name = str_replace('.', '', $name);
+
+ return (($phpbb_relative) ? $this->phpbb_root_path : '') . 'ext/' . $name . '/';
+ }
+
+ /**
+ * Instantiates the extension meta class for the extension with the given name
+ *
+ * @param string $name The extension name
+ * @return phpbb_extension_interface Instance of the extension meta class or
+ * phpbb_extension_base if the class does not exist
+ */
+ public function get_extension($name)
+ {
+ $extension_class_name = 'phpbb_ext_' . str_replace('/', '_', $name) . '_ext';
+
+ if (class_exists($extension_class_name))
+ {
+ return new $extension_class_name;
+ }
+ else
+ {
+ return new phpbb_extension_base;
+ }
+ }
+
+ /**
+ * Runs a step of the extension enabling process.
+ *
+ * Allows the exentension to enable in a long running script that works
+ * in multiple steps across requests. State is kept for the extension
+ * in the extensions table.
+ *
+ * @param string $name The extension's name
+ * @return bool False if enabling is finished, true otherwise
+ */
+ public function enable_step($name)
+ {
+ // ignore extensions that are already enabled
+ if (isset($this->extensions[$name]) && $this->extensions[$name]['ext_active'])
+ {
+ return false;
+ }
+
+ $old_state = (isset($this->extensions[$name]['ext_state'])) ? unserialize($this->extensions[$name]['ext_state']) : false;
+
+ $extension = $this->get_extension($name);
+ $state = $extension->enable_step($old_state);
+
+ $active = ($state === false);
+
+ $extension_data = array(
+ 'ext_name' => $name,
+ 'ext_active' => $active,
+ 'ext_state' => serialize($state),
+ );
+
+ $this->extensions[$name] = $extension_data;
+ $this->extensions[$name]['ext_path'] = $this->get_extension_path($extension_data['ext_name']);
+ ksort($this->extensions);
+
+ $sql = 'UPDATE ' . $this->extension_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
+ WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
+ $this->db->sql_query($sql);
+
+ if (!$this->db->sql_affectedrows())
+ {
+ $sql = 'INSERT INTO ' . $this->extension_table . '
+ ' . $this->db->sql_build_array('INSERT', $extension_data);
+ $this->db->sql_query($sql);
+ }
+
+ return !$active;
+ }
+
+ /**
+ * Enables an extension
+ *
+ * This method completely enables an extension. But it could be long running
+ * so never call this in a script that has a max_execution time.
+ *
+ * @param string $name The extension's name
+ * @return null
+ */
+ public function enable($name)
+ {
+ while ($this->enable_step($name));
+ }
+
+ /**
+ * Disables an extension
+ *
+ * Calls the disable method on the extension's meta class to allow it to
+ * process the event.
+ *
+ * @param string $name The extension's name
+ * @return bool False if disabling is finished, true otherwise
+ */
+ public function disable_step($name)
+ {
+ // ignore extensions that are already disabled
+ if (!isset($this->extensions[$name]) || !$this->extensions[$name]['ext_active'])
+ {
+ return false;
+ }
+
+ $old_state = unserialize($this->extensions[$name]['ext_state']);
+
+ $extension = $this->get_extension($name);
+ $state = $extension->disable_step($old_state);
+
+ // continue until the state is false
+ if ($state !== false)
+ {
+ $extension_data = array(
+ 'ext_state' => serialize($state),
+ );
+ $this->extensions[$name]['ext_state'] = serialize($state);
+
+ $sql = 'UPDATE ' . $this->extension_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
+ WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
+ $this->db->sql_query($sql);
+
+ return true;
+ }
+
+ $extension_data = array(
+ 'ext_active' => false,
+ 'ext_state' => serialize(false),
+ );
+ $this->extensions[$name]['ext_active'] = false;
+ $this->extensions[$name]['ext_state'] = serialize(false);
+
+ $sql = 'UPDATE ' . $this->extension_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
+ WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
+ $this->db->sql_query($sql);
+
+ return false;
+ }
+
+ /**
+ * Disables an extension
+ *
+ * Disables an extension completely at once. This process could run for a
+ * while so never call this in a script that has a max_execution time.
+ *
+ * @param string $name The extension's name
+ * @return null
+ */
+ public function disable($name)
+ {
+ while ($this->disable_step($name));
+ }
+
+ /**
+ * Purge an extension
+ *
+ * Disables the extension first if active, and then calls purge on the
+ * extension's meta class to delete the extension's database content.
+ *
+ * @param string $name The extension's name
+ * @return bool False if purging is finished, true otherwise
+ */
+ public function purge_step($name)
+ {
+ // ignore extensions that do not exist
+ if (!isset($this->extensions[$name]))
+ {
+ return false;
+ }
+
+ // disable first if necessary
+ if ($this->extensions[$name]['ext_active'])
+ {
+ $this->disable($name);
+ }
+
+ $old_state = unserialize($this->extensions[$name]['ext_state']);
+
+ $extension = $this->get_extension($name);
+ $state = $extension->purge_step($old_state);
+
+ // continue until the state is false
+ if ($state !== false)
+ {
+ $extension_data = array(
+ 'ext_state' => serialize($state),
+ );
+ $this->extensions[$name]['ext_state'] = serialize($state);
+
+ $sql = 'UPDATE ' . $this->extension_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
+ WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
+ $this->db->sql_query($sql);
+
+ return true;
+ }
+
+ unset($this->extensions[$name]);
+
+ $sql = 'DELETE FROM ' . $this->extension_table . "
+ WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
+ $this->db->sql_query($sql);
+
+ return false;
+ }
+
+ /**
+ * Purge an extension
+ *
+ * Purges an extension completely at once. This process could run for a while
+ * so never call this in a script that has a max_execution time.
+ *
+ * @param string $name The extension's name
+ * @return null
+ */
+ public function purge($name)
+ {
+ while ($this->purge_step($name));
+ }
+
+ /**
+ * Retrieves a list of all available extensions on the filesystem
+ *
+ * @return array An array with extension names as keys and paths to the
+ * extension as values
+ */
+ public function all_available()
+ {
+ $available = array();
+
+ $iterator = new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($this->phpbb_root_path . 'ext/'));
+ foreach ($iterator as $file_info)
+ {
+ if ($file_info->isFile() && $file_info->getFilename() == 'ext' . $this->phpEx)
+ {
+ $ext_name = $iterator->getInnerIterator()->getSubPath();
+
+ $ext_name = str_replace(DIRECTORY_SEPARATOR, '/', $ext_name);
+
+ $available[$ext_name] = $this->phpbb_root_path . 'ext/' . $ext_name . '/';
+ }
+ }
+ ksort($available);
+ return $available;
+ }
+
+ /**
+ * Retrieves all configured extensions.
+ *
+ * All enabled and disabled extensions are considered configured. A purged
+ * extension that is no longer in the database is not configured.
+ *
+ * @return array An array with extension names as keys and and the
+ * database stored extension information as values
+ */
+ public function all_configured()
+ {
+ $configured = array();
+ foreach ($this->extensions as $name => $data)
+ {
+ $data['ext_path'] = $this->phpbb_root_path . $data['ext_path'];
+ $configured[$name] = $data;
+ }
+ return $configured;
+ }
+
+ /**
+ * Retrieves all enabled extensions.
+ *
+ * @return array An array with extension names as keys and and the
+ * database stored extension information as values
+ */
+ public function all_enabled()
+ {
+ $enabled = array();
+ foreach ($this->extensions as $name => $data)
+ {
+ if ($data['ext_active'])
+ {
+ $enabled[$name] = $this->phpbb_root_path . $data['ext_path'];
+ }
+ }
+ return $enabled;
+ }
+
+ /**
+ * Retrieves all disabled extensions.
+ *
+ * @return array An array with extension names as keys and and the
+ * database stored extension information as values
+ */
+ public function all_disabled()
+ {
+ $disabled = array();
+ foreach ($this->extensions as $name => $data)
+ {
+ if (!$data['ext_active'])
+ {
+ $disabled[$name] = $this->phpbb_root_path . $data['ext_path'];
+ }
+ }
+ return $disabled;
+ }
+
+ /**
+ * Instantiates a phpbb_extension_finder.
+ *
+ * @return phpbb_extension_finder An extension finder instance
+ */
+ public function get_finder()
+ {
+ return new phpbb_extension_finder($this, $this->phpbb_root_path, $this->cache, $this->phpEx, $this->cache_name . '_finder');
+ }
+}
diff --git a/phpBB/includes/extension/provider.php b/phpBB/includes/extension/provider.php
new file mode 100644
index 0000000000..3939c2ef07
--- /dev/null
+++ b/phpBB/includes/extension/provider.php
@@ -0,0 +1,68 @@
+<?php
+/**
+*
+* @package extension
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Provides a set of items found in extensions
+*
+* @package extension
+*/
+abstract class phpbb_extension_provider implements IteratorAggregate
+{
+ /**
+ * Array holding all found items
+ * @var array|null
+ */
+ protected $items = null;
+
+ /**
+ * An extension manager to search for items in extensions
+ * @var phpbb_extension_manager
+ */
+ protected $extension_manager;
+
+ /**
+ * Constructor. Loads all available items.
+ *
+ * @param phpbb_extension_manager $extension_manager phpBB extension manager
+ */
+ public function __construct(phpbb_extension_manager $extension_manager)
+ {
+ $this->extension_manager = $extension_manager;
+ }
+
+ /**
+ * Finds template paths using the extension manager.
+ *
+ * @return array List of task names
+ */
+ abstract protected function find();
+
+ /**
+ * Retrieve an iterator over all items
+ *
+ * @return ArrayIterator An iterator for the array of template paths
+ */
+ public function getIterator()
+ {
+ if ($this->items === null)
+ {
+ $this->items = $this->find();
+ }
+
+ return new ArrayIterator($this->items);
+ }
+}
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 688c7f2000..86bd21b1fc 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -1654,7 +1654,7 @@ function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $s
*/
function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_time = false, $mark_time_forum = false)
{
- global $db, $tracking_topics, $user, $config, $request;
+ global $db, $tracking_topics, $user, $config, $auth, $request;
// Determine the users last forum mark time if not given.
if ($mark_time_forum === false)
@@ -1677,6 +1677,10 @@ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_ti
}
}
+ // Handle update of unapproved topics info.
+ // Only update for moderators having m_approve permission for the forum.
+ $sql_update_unapproved = ($auth->acl_get('m_approve', $forum_id)) ? '': 'AND t.topic_approved = 1';
+
// Check the forum for any left unread topics.
// If there are none, we mark the forum as read.
if ($config['load_db_lastread'] && $user->data['is_registered'])
@@ -1692,7 +1696,8 @@ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_ti
LEFT JOIN ' . TOPICS_TRACK_TABLE . ' tt ON (tt.topic_id = t.topic_id AND tt.user_id = ' . $user->data['user_id'] . ')
WHERE t.forum_id = ' . $forum_id . '
AND t.topic_last_post_time > ' . $mark_time_forum . '
- AND t.topic_moved_id = 0
+ AND t.topic_moved_id = 0 ' .
+ $sql_update_unapproved . '
AND (tt.topic_id IS NULL OR tt.mark_time < t.topic_last_post_time)
GROUP BY t.forum_id';
$result = $db->sql_query_limit($sql, 1);
@@ -1712,11 +1717,12 @@ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_ti
}
else
{
- $sql = 'SELECT topic_id
- FROM ' . TOPICS_TABLE . '
- WHERE forum_id = ' . $forum_id . '
- AND topic_last_post_time > ' . $mark_time_forum . '
- AND topic_moved_id = 0';
+ $sql = 'SELECT t.topic_id
+ FROM ' . TOPICS_TABLE . ' t
+ WHERE t.forum_id = ' . $forum_id . '
+ AND t.topic_last_post_time > ' . $mark_time_forum . '
+ AND t.topic_moved_id = 0 ' .
+ $sql_update_unapproved;
$result = $db->sql_query($sql);
$check_forum = $tracking_topics['tf'][$forum_id];
@@ -3256,6 +3262,10 @@ function get_preg_expression($mode)
$inline = ($mode == 'relative_url') ? ')' : '';
return "(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?";
break;
+
+ case 'table_prefix':
+ return '#^[a-zA-Z][a-zA-Z0-9_]*$#';
+ break;
}
return '';
@@ -4110,59 +4120,26 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum'
}
else if ($config['load_online_guests'])
{
- $l_online = ($online_users['guests_online'] === 1) ? $user->lang['BROWSING_' . $item_caps . '_GUEST'] : $user->lang['BROWSING_' . $item_caps . '_GUESTS'];
- $online_userlist = sprintf($l_online, $online_userlist, $online_users['guests_online']);
+ $online_userlist = $user->lang('BROWSING_' . $item_caps . '_GUESTS', $online_users['guests_online'], $online_userlist);
}
else
{
$online_userlist = sprintf($user->lang['BROWSING_' . $item_caps], $online_userlist);
}
// Build online listing
- $vars_online = array(
- 'ONLINE' => array('total_online', 'l_t_user_s', 0),
- 'REG' => array('visible_online', 'l_r_user_s', !$config['load_online_guests']),
- 'HIDDEN' => array('hidden_online', 'l_h_user_s', $config['load_online_guests']),
- 'GUEST' => array('guests_online', 'l_g_user_s', 0)
- );
+ $visible_online = $user->lang('REG_USERS_TOTAL', (int) $online_users['visible_online']);
+ $hidden_online = $user->lang('HIDDEN_USERS_TOTAL', (int) $online_users['hidden_online']);
- foreach ($vars_online as $l_prefix => $var_ary)
+ if ($config['load_online_guests'])
{
- if ($var_ary[2])
- {
- $l_suffix = '_AND';
- }
- else
- {
- $l_suffix = '';
- }
- switch ($online_users[$var_ary[0]])
- {
- case 0:
- ${$var_ary[1]} = $user->lang[$l_prefix . '_USERS_ZERO_TOTAL' . $l_suffix];
- break;
-
- case 1:
- ${$var_ary[1]} = $user->lang[$l_prefix . '_USER_TOTAL' . $l_suffix];
- break;
-
- default:
- ${$var_ary[1]} = $user->lang[$l_prefix . '_USERS_TOTAL' . $l_suffix];
- break;
- }
+ $guests_online = $user->lang('GUEST_USERS_TOTAL', (int) $online_users['guests_online']);
+ $l_online_users = $user->lang('ONLINE_USERS_TOTAL_GUESTS', (int) $online_users['total_online'], $visible_online, $hidden_online, $guests_online);
}
- unset($vars_online);
-
- $l_online_users = sprintf($l_t_user_s, $online_users['total_online']);
- $l_online_users .= sprintf($l_r_user_s, $online_users['visible_online']);
- $l_online_users .= sprintf($l_h_user_s, $online_users['hidden_online']);
-
- if ($config['load_online_guests'])
+ else
{
- $l_online_users .= sprintf($l_g_user_s, $online_users['guests_online']);
+ $l_online_users = $user->lang('ONLINE_USERS_TOTAL', (int) $online_users['total_online'], $visible_online, $hidden_online);
}
-
-
return array(
'online_userlist' => $online_userlist,
'l_online_users' => $l_online_users,
@@ -4205,6 +4182,178 @@ 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.
@@ -4312,7 +4461,7 @@ function phpbb_http_login($param)
*/
function page_header($page_title = '', $display_online_list = true, $item_id = 0, $item = 'forum')
{
- global $db, $config, $template, $SID, $_SID, $user, $auth, $phpEx, $phpbb_root_path;
+ global $db, $config, $template, $SID, $_SID, $_EXTRA_URL, $user, $auth, $phpEx, $phpbb_root_path;
if (defined('HEADER_INC'))
{
@@ -4383,10 +4532,9 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
set_config('record_online_date', time(), true);
}
- $l_online_record = sprintf($user->lang['RECORD_ONLINE_USERS'], $config['record_online_users'], $user->format_date($config['record_online_date'], false, true));
+ $l_online_record = $user->lang('RECORD_ONLINE_USERS', (int) $config['record_online_users'], $user->format_date($config['record_online_date'], false, true));
- $l_online_time = ($config['load_online_time'] == 1) ? 'VIEW_ONLINE_TIME' : 'VIEW_ONLINE_TIMES';
- $l_online_time = sprintf($user->lang[$l_online_time], $config['load_online_time']);
+ $l_online_time = $user->lang('VIEW_ONLINE_TIMES', (int) $config['load_online_time']);
}
$l_privmsgs_text = $l_privmsgs_text_unread = '';
@@ -4397,8 +4545,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
{
if ($user->data['user_new_privmsg'])
{
- $l_message_new = ($user->data['user_new_privmsg'] == 1) ? $user->lang['NEW_PM'] : $user->lang['NEW_PMS'];
- $l_privmsgs_text = sprintf($l_message_new, $user->data['user_new_privmsg']);
+ $l_privmsgs_text = $user->lang('NEW_PMS', (int) $user->data['user_new_privmsg']);
if (!$user->data['user_last_privmsg'] || $user->data['user_last_privmsg'] > $user->data['session_last_visit'])
{
@@ -4416,7 +4563,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
}
else
{
- $l_privmsgs_text = $user->lang['NO_NEW_PM'];
+ $l_privmsgs_text = $user->lang('NEW_PMS', 0);
$s_privmsg_new = false;
}
@@ -4424,8 +4571,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
if ($user->data['user_unread_privmsg'] && $user->data['user_unread_privmsg'] != $user->data['user_new_privmsg'])
{
- $l_message_unread = ($user->data['user_unread_privmsg'] == 1) ? $user->lang['UNREAD_PM'] : $user->lang['UNREAD_PMS'];
- $l_privmsgs_text_unread = sprintf($l_message_unread, $user->data['user_unread_privmsg']);
+ $l_privmsgs_text_unread = $user->lang('UNREAD_PMS', (int) $user->data['user_unread_privmsg']);
}
}
@@ -4465,6 +4611,15 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
$s_search_hidden_fields['sid'] = $_SID;
}
+ if (!empty($_EXTRA_URL))
+ {
+ foreach ($_EXTRA_URL as $url_param)
+ {
+ $url_param = explode('=', $url_param, 2);
+ $s_hidden_fields[$url_param[0]] = $url_param[1];
+ }
+ }
+
// The following assigns all _common_ variables that may be used at any point in a template.
$template->assign_vars(array(
'SITENAME' => $config['sitename'],
@@ -4570,6 +4725,8 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
'T_STYLESHEET_LINK' => "{$web_path}styles/" . $user->theme['theme_path'] . '/theme/stylesheet.css',
'T_STYLESHEET_LANG_LINK' => "{$web_path}styles/" . $user->theme['theme_path'] . '/theme/' . $user->lang_name . '/stylesheet.css',
'T_STYLESHEET_NAME' => $user->theme['theme_name'],
+ 'T_JQUERY_LINK' => ($config['load_jquery_cdn'] && !empty($config['load_jquery_url'])) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.js",
+ 'S_JQUERY_FALLBACK' => ($config['load_jquery_cdn']) ? true : false,
'T_THEME_NAME' => $user->theme['theme_path'],
'T_THEME_LANG_NAME' => $user->data['user_lang'],
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php
index 36e22e069f..4702f9939d 100644
--- a/phpBB/includes/functions_acp.php
+++ b/phpBB/includes/functions_acp.php
@@ -124,6 +124,8 @@ function adm_page_footer($copyright_html = true)
'DEBUG_OUTPUT' => (defined('DEBUG')) ? $debug_output : '',
'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '',
'S_COPYRIGHT_HTML' => $copyright_html,
+ 'T_JQUERY_LINK' => ($config['load_jquery_cdn'] && !empty($config['load_jquery_url'])) ? $config['load_jquery_url'] : "{$phpbb_root_path}assets/javascript/jquery.js",
+ 'S_JQUERY_FALLBACK' => ($config['load_jquery_cdn']) ? true : false,
'VERSION' => $config['version'])
);
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index 3f9e517fdf..f6378e331e 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -2295,41 +2295,6 @@ function auto_prune($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_fr
}
/**
-* remove_comments will strip the sql comment lines out of an uploaded sql file
-* specifically for mssql and postgres type files in the install....
-*/
-function remove_comments(&$output)
-{
- $lines = explode("\n", $output);
- $output = '';
-
- // try to keep mem. use down
- $linecount = sizeof($lines);
-
- $in_comment = false;
- for ($i = 0; $i < $linecount; $i++)
- {
- if (trim($lines[$i]) == '/*')
- {
- $in_comment = true;
- }
-
- if (!$in_comment)
- {
- $output .= $lines[$i] . "\n";
- }
-
- if (trim($lines[$i]) == '*/')
- {
- $in_comment = false;
- }
- }
-
- unset($lines);
- return $output;
-}
-
-/**
* Cache moderators, called whenever permissions are changed via admin_permissions. Changes of username
* and group names must be carried through for the moderators table
*/
@@ -2366,7 +2331,7 @@ function cache_moderators()
$ug_id_ary = array_keys($hold_ary);
// Remove users who have group memberships with DENY moderator permissions
- $sql = $db->sql_build_query('SELECT', array(
+ $sql_ary = array(
'SELECT' => 'a.forum_id, ug.user_id, g.group_id',
'FROM' => array(
@@ -2379,8 +2344,8 @@ function cache_moderators()
'LEFT_JOIN' => array(
array(
'FROM' => array(ACL_ROLES_DATA_TABLE => 'r'),
- 'ON' => 'a.auth_role_id = r.role_id'
- )
+ 'ON' => 'a.auth_role_id = r.role_id',
+ ),
),
'WHERE' => '(o.auth_option_id = a.auth_option_id OR o.auth_option_id = r.auth_option_id)
@@ -2392,7 +2357,8 @@ function cache_moderators()
AND ' . $db->sql_in_set('ug.user_id', $ug_id_ary) . "
AND ug.user_pending = 0
AND o.auth_option " . $db->sql_like_expression('m_' . $db->any_char),
- ));
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
@@ -2610,7 +2576,11 @@ function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id
$db->sql_freeresult($result);
}
- if ($log_count == 0)
+ // $log_count may be false here if false was passed in for it,
+ // because in this case we did not run the COUNT() query above.
+ // If we ran the COUNT() query and it returned zero rows, return;
+ // otherwise query for logs below.
+ if ($log_count === 0)
{
// Save the queries, because there are no logs to display
return 0;
@@ -2792,18 +2762,18 @@ function update_foes($group_id = false, $user_id = false)
if (is_array($group_id) && sizeof($group_id))
{
// Grab group settings...
- $sql = $db->sql_build_query('SELECT', array(
+ $sql_ary = array(
'SELECT' => 'a.group_id',
'FROM' => array(
ACL_OPTIONS_TABLE => 'ao',
- ACL_GROUPS_TABLE => 'a'
+ ACL_GROUPS_TABLE => 'a',
),
'LEFT_JOIN' => array(
array(
'FROM' => array(ACL_ROLES_DATA_TABLE => 'r'),
- 'ON' => 'a.auth_role_id = r.role_id'
+ 'ON' => 'a.auth_role_id = r.role_id',
),
),
@@ -2811,8 +2781,9 @@ function update_foes($group_id = false, $user_id = false)
AND ' . $db->sql_in_set('a.group_id', $group_id) . "
AND ao.auth_option IN ('a_', 'm_')",
- 'GROUP_BY' => 'a.group_id'
- ));
+ 'GROUP_BY' => 'a.group_id',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query($sql);
$groups = array();
diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php
index b1294a2f14..894e261c12 100644
--- a/phpBB/includes/functions_content.php
+++ b/phpBB/includes/functions_content.php
@@ -938,12 +938,12 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
}
$download_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id']);
+ $l_downloaded_viewed = 'VIEWED_COUNTS';
switch ($display_cat)
{
// Images
case ATTACHMENT_CATEGORY_IMAGE:
- $l_downloaded_viewed = 'VIEWED_COUNT';
$inline_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id']);
$download_link .= '&amp;mode=view';
@@ -957,7 +957,6 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
// Images, but display Thumbnail
case ATTACHMENT_CATEGORY_THUMB:
- $l_downloaded_viewed = 'VIEWED_COUNT';
$thumbnail_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id'] . '&amp;t=1');
$download_link .= '&amp;mode=view';
@@ -971,7 +970,6 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
// Windows Media Streams
case ATTACHMENT_CATEGORY_WM:
- $l_downloaded_viewed = 'VIEWED_COUNT';
// 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)
@@ -990,7 +988,6 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
// Real Media Streams
case ATTACHMENT_CATEGORY_RM:
case ATTACHMENT_CATEGORY_QUICKTIME:
- $l_downloaded_viewed = 'VIEWED_COUNT';
$block_array += array(
'S_RM_FILE' => ($display_cat == ATTACHMENT_CATEGORY_RM) ? true : false,
@@ -1007,8 +1004,6 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
case ATTACHMENT_CATEGORY_FLASH:
list($width, $height) = @getimagesize($filename);
- $l_downloaded_viewed = 'VIEWED_COUNT';
-
$block_array += array(
'S_FLASH_FILE' => true,
'WIDTH' => $width,
@@ -1021,7 +1016,7 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
break;
default:
- $l_downloaded_viewed = 'DOWNLOAD_COUNT';
+ $l_downloaded_viewed = 'DOWNLOAD_COUNTS';
$block_array += array(
'S_FILE' => true,
@@ -1029,11 +1024,14 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
break;
}
- $l_download_count = (!isset($attachment['download_count']) || $attachment['download_count'] == 0) ? $user->lang[$l_downloaded_viewed . '_NONE'] : (($attachment['download_count'] == 1) ? sprintf($user->lang[$l_downloaded_viewed], $attachment['download_count']) : sprintf($user->lang[$l_downloaded_viewed . 'S'], $attachment['download_count']));
+ if (!isset($attachment['download_count']))
+ {
+ $attachment['download_count'] = 0;
+ }
$block_array += array(
'U_DOWNLOAD_LINK' => $download_link,
- 'L_DOWNLOAD_COUNT' => $l_download_count
+ 'L_DOWNLOAD_COUNT' => $user->lang($l_downloaded_viewed, (int) $attachment['download_count']),
);
}
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index 4e8d8f7d34..2ec34e1084 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -110,7 +110,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$sql_array['SELECT'] .= ', fa.user_id';
}
- $sql = $db->sql_build_query('SELECT', array(
+ $sql_ary = array(
'SELECT' => $sql_array['SELECT'],
'FROM' => $sql_array['FROM'],
'LEFT_JOIN' => $sql_array['LEFT_JOIN'],
@@ -118,8 +118,9 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
'WHERE' => $sql_where,
'ORDER_BY' => 'f.left_id',
- ));
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query($sql);
$forum_tracking_info = array();
@@ -446,6 +447,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
'S_NO_CAT' => $catless && !$last_catless,
'S_IS_LINK' => ($row['forum_type'] == FORUM_LINK) ? true : false,
'S_UNREAD_FORUM' => $forum_unread,
+ 'S_AUTH_READ' => $auth->acl_get('f_read', $row['forum_id']),
'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,
@@ -1041,10 +1043,10 @@ function display_user_activity(&$userdata)
$template->assign_vars(array(
'ACTIVE_FORUM' => $active_f_name,
- 'ACTIVE_FORUM_POSTS' => ($active_f_count == 1) ? sprintf($user->lang['USER_POST'], 1) : sprintf($user->lang['USER_POSTS'], $active_f_count),
+ 'ACTIVE_FORUM_POSTS' => $user->lang('USER_POSTS', (int) $active_f_count),
'ACTIVE_FORUM_PCT' => sprintf($l_active_pct, $active_f_pct),
'ACTIVE_TOPIC' => censor_text($active_t_name),
- 'ACTIVE_TOPIC_POSTS' => ($active_t_count == 1) ? sprintf($user->lang['USER_POST'], 1) : sprintf($user->lang['USER_POSTS'], $active_t_count),
+ 'ACTIVE_TOPIC_POSTS' => $user->lang('USER_POSTS', (int) $active_t_count),
'ACTIVE_TOPIC_PCT' => sprintf($l_active_pct, $active_t_pct),
'U_ACTIVE_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $active_f_id),
'U_ACTIVE_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $active_t_id),
@@ -1065,6 +1067,7 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id,
$match_id = ($mode == 'forum') ? $forum_id : $topic_id;
$u_url = "uid={$user->data['user_id']}";
$u_url .= ($mode == 'forum') ? '&amp;f' : '&amp;f=' . $forum_id . '&amp;t';
+ $is_watching = 0;
// Is user watching this thread?
if ($user_id != ANONYMOUS)
@@ -1090,9 +1093,9 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id,
$uid = request_var('uid', 0);
$token = request_var('hash', '');
- if (($token && check_link_hash($token, "{$mode}_$match_id")) || confirm_box(true))
+ if ($token && check_link_hash($token, "{$mode}_$match_id") || confirm_box(true))
{
- if (($uid != $user_id) || ($request->variable('unwatch', '', false, phpbb_request_interface::GET) != $mode))
+ if ($uid != $user_id || $request->variable('unwatch', '', false, phpbb_request_interface::GET) != $mode)
{
$redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&amp;start=$start");
$message = $user->lang['ERR_UNWATCHING'] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>');
@@ -1105,7 +1108,8 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id,
$db->sql_query($sql);
$redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&amp;start=$start");
- $message = $user->lang['NOT_WATCHING_' . strtoupper($mode)] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>');
+ $message = $user->lang['NOT_WATCHING_' . strtoupper($mode)] . '<br /><br />';
+ $message .= sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>');
meta_refresh(3, $redirect_url);
trigger_error($message);
}
@@ -1122,7 +1126,14 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id,
$s_hidden_fields['t'] = $topic_id;
}
- $confirm_box_message = (($item_title == '') ? 'UNWATCH_' . strtoupper($mode) : $user->lang('UNWATCH_' . strtoupper($mode) . '_DETAILED', $item_title));
+ if ($item_title == '')
+ {
+ $confirm_box_message = 'UNWATCH_' . strtoupper($mode);
+ }
+ else
+ {
+ $confirm_box_message = $user->lang('UNWATCH_' . strtoupper($mode) . '_DETAILED', $item_title);
+ }
confirm_box(false, $confirm_box_message, build_hidden_fields($s_hidden_fields));
}
}
@@ -1147,9 +1158,9 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id,
$uid = request_var('uid', 0);
$token = request_var('hash', '');
- if (($token && check_link_hash($token, "{$mode}_$match_id")) || confirm_box(true))
+ if ($token && check_link_hash($token, "{$mode}_$match_id") || confirm_box(true))
{
- if (($uid != $user_id) || ($request->variable('watch', '', false, phpbb_request_interface::GET) != $mode))
+ if ($uid != $user_id || $request->variable('watch', '', false, phpbb_request_interface::GET) != $mode)
{
$redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&amp;start=$start");
$message = $user->lang['ERR_WATCHING'] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>');
diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php
index 7a99bca0e2..b0d8fb6720 100644
--- a/phpBB/includes/functions_install.php
+++ b/phpBB/includes/functions_install.php
@@ -50,7 +50,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
'SCHEMA' => 'firebird',
'MODULE' => 'interbase',
'DELIM' => ';;',
- 'COMMENTS' => 'remove_remarks',
'DRIVER' => 'firebird',
'AVAILABLE' => true,
'2.0.x' => false,
@@ -60,7 +59,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
'SCHEMA' => 'mysql_41',
'MODULE' => 'mysqli',
'DELIM' => ';',
- 'COMMENTS' => 'remove_remarks',
'DRIVER' => 'mysqli',
'AVAILABLE' => true,
'2.0.x' => true,
@@ -70,7 +68,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
'SCHEMA' => 'mysql',
'MODULE' => 'mysql',
'DELIM' => ';',
- 'COMMENTS' => 'remove_remarks',
'DRIVER' => 'mysql',
'AVAILABLE' => true,
'2.0.x' => true,
@@ -80,7 +77,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
'SCHEMA' => 'mssql',
'MODULE' => 'mssql',
'DELIM' => 'GO',
- 'COMMENTS' => 'remove_comments',
'DRIVER' => 'mssql',
'AVAILABLE' => true,
'2.0.x' => true,
@@ -90,7 +86,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
'SCHEMA' => 'mssql',
'MODULE' => 'odbc',
'DELIM' => 'GO',
- 'COMMENTS' => 'remove_comments',
'DRIVER' => 'mssql_odbc',
'AVAILABLE' => true,
'2.0.x' => true,
@@ -100,7 +95,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
'SCHEMA' => 'mssql',
'MODULE' => 'sqlsrv',
'DELIM' => 'GO',
- 'COMMENTS' => 'remove_comments',
'DRIVER' => 'mssqlnative',
'AVAILABLE' => true,
'2.0.x' => false,
@@ -110,7 +104,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
'SCHEMA' => 'oracle',
'MODULE' => 'oci8',
'DELIM' => '/',
- 'COMMENTS' => 'remove_comments',
'DRIVER' => 'oracle',
'AVAILABLE' => true,
'2.0.x' => false,
@@ -120,7 +113,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
'SCHEMA' => 'postgres',
'MODULE' => 'pgsql',
'DELIM' => ';',
- 'COMMENTS' => 'remove_comments',
'DRIVER' => 'postgres',
'AVAILABLE' => true,
'2.0.x' => true,
@@ -130,7 +122,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
'SCHEMA' => 'sqlite',
'MODULE' => 'sqlite',
'DELIM' => ';',
- 'COMMENTS' => 'remove_remarks',
'DRIVER' => 'sqlite',
'AVAILABLE' => true,
'2.0.x' => false,
@@ -473,11 +464,17 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
}
/**
-* remove_remarks will strip the sql comment lines out of an uploaded sql file
+* Removes comments from schema files
*/
-function remove_remarks(&$sql)
+function remove_comments($sql)
{
+ // Remove /* */ comments (http://ostermiller.org/findcomment.html)
+ $sql = preg_replace('#/\*(.|[\r\n])*?\*/#', "\n", $sql);
+
+ // Remove # style comments
$sql = preg_replace('/\n{2,}/', "\n", preg_replace('/^#.*$/m', "\n", $sql));
+
+ return $sql;
}
/**
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index b94957a85f..4797da5398 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -163,6 +163,22 @@ class messenger
}
/**
+ * Adds X-AntiAbuse headers
+ *
+ * @param array $config Configuration array
+ * @param user $user A user object
+ *
+ * @return null
+ */
+ function anti_abuse_headers($config, $user)
+ {
+ $this->headers('X-AntiAbuse: Board servername - ' . mail_encode($config['server_name']));
+ $this->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
+ $this->headers('X-AntiAbuse: Username - ' . mail_encode($user->data['username']));
+ $this->headers('X-AntiAbuse: User IP - ' . $user->ip);
+ }
+
+ /**
* Set the email priority
*/
function set_mail_priority($priority = MAIL_NORMAL_PRIORITY)
@@ -175,7 +191,7 @@ class messenger
*/
function template($template_file, $template_lang = '', $template_path = '')
{
- global $config, $phpbb_root_path, $phpEx, $user;
+ global $config, $phpbb_root_path, $phpEx, $user, $phpbb_extension_manager;
if (!trim($template_file))
{
@@ -194,7 +210,8 @@ class messenger
if (!isset($this->tpl_msg[$template_lang . $template_file]))
{
$template_locator = new phpbb_template_locator();
- $this->tpl_msg[$template_lang . $template_file] = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $template_locator);
+ $template_path_provider = new phpbb_template_extension_path_provider($phpbb_extension_manager, new phpbb_template_path_provider());
+ $this->tpl_msg[$template_lang . $template_file] = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $template_locator, $template_path_provider);
$tpl = &$this->tpl_msg[$template_lang . $template_file];
$fallback_template_path = false;
diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php
index 09c54422b0..1f451d392d 100644
--- a/phpBB/includes/functions_module.php
+++ b/phpBB/includes/functions_module.php
@@ -221,13 +221,15 @@ class p_master
// We need to prefix the functions to not create a naming conflict
// Function for building 'url_extra'
- $url_func = '_module_' . $row['module_basename'] . '_url';
+ $short_name = $this->get_short_name($row['module_basename']);
+
+ $url_func = '_module_' . $short_name . '_url';
// Function for building the language name
- $lang_func = '_module_' . $row['module_basename'] . '_lang';
+ $lang_func = '_module_' . $short_name . '_lang';
// Custom function for calling parameters on module init (for example assigning template variables)
- $custom_func = '_module_' . $row['module_basename'];
+ $custom_func = '_module_' . $short_name;
$names[$row['module_basename'] . '_' . $row['module_mode']][] = true;
@@ -275,6 +277,11 @@ class p_master
*/
function loaded($module_basename, $module_mode = false)
{
+ if (!$this->is_full_class($module_basename))
+ {
+ $module_basename = $this->p_class . '_' . $module_basename;
+ }
+
if (empty($this->loaded_cache))
{
$this->loaded_cache = array();
@@ -381,6 +388,11 @@ class p_master
$id = request_var('icat', '');
}
+ if ($id && !is_numeric($id) && !$this->is_full_class($id))
+ {
+ $id = $this->p_class . '_' . $id;
+ }
+
$category = false;
foreach ($this->module_ary as $row_id => $item_ary)
{
@@ -389,9 +401,9 @@ class p_master
// If this is a module and no mode selected, select first mode
// If no category or module selected, go active for first module in first category
if (
- (($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && (($item_ary['mode'] == $mode && !$item_ary['cat']) || ($icat && $item_ary['cat']))) ||
+ (($item_ary['name'] === $id || $item_ary['name'] === $this->p_class . '_' . $id || $item_ary['id'] === (int) $id) && (($item_ary['mode'] == $mode && !$item_ary['cat']) || ($icat && $item_ary['cat']))) ||
($item_ary['parent'] === $category && !$item_ary['cat'] && !$icat && $item_ary['display']) ||
- (($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && !$mode && !$item_ary['cat']) ||
+ (($item_ary['name'] === $id || $item_ary['name'] === $this->p_class . '_' . $id || $item_ary['id'] === (int) $id) && !$mode && !$item_ary['cat']) ||
(!$id && !$mode && !$item_ary['cat'] && $item_ary['display'])
)
{
@@ -440,75 +452,74 @@ class p_master
trigger_error('Module not accessible', E_USER_ERROR);
}
- if (!class_exists("{$this->p_class}_$this->p_name"))
+ // new modules use the full class names, old ones are always called <type>_<name>, e.g. acp_board
+ if (!class_exists($this->p_name))
{
- if (!file_exists("$module_path/{$this->p_class}_$this->p_name.$phpEx"))
+ if (!file_exists("$module_path/{$this->p_name}.$phpEx"))
{
- trigger_error("Cannot find module $module_path/{$this->p_class}_$this->p_name.$phpEx", E_USER_ERROR);
+ trigger_error("Cannot find module $module_path/{$this->p_name}.$phpEx", E_USER_ERROR);
}
- include("$module_path/{$this->p_class}_$this->p_name.$phpEx");
+ include("$module_path/{$this->p_name}.$phpEx");
- if (!class_exists("{$this->p_class}_$this->p_name"))
+ if (!class_exists($this->p_name))
{
- trigger_error("Module file $module_path/{$this->p_class}_$this->p_name.$phpEx does not contain correct class [{$this->p_class}_$this->p_name]", E_USER_ERROR);
+ trigger_error("Module file $module_path/{$this->p_name}.$phpEx does not contain correct class [{$this->p_name}]", E_USER_ERROR);
}
+ }
- if (!empty($mode))
- {
- $this->p_mode = $mode;
- }
+ if (!empty($mode))
+ {
+ $this->p_mode = $mode;
+ }
- // Create a new instance of the desired module ... if it has a
- // constructor it will of course be executed
- $instance = "{$this->p_class}_$this->p_name";
+ // Create a new instance of the desired module ...
+ $class_name = $this->p_name;
- $this->module = new $instance($this);
+ $this->module = new $class_name($this);
- // We pre-define the action parameter we are using all over the place
- if (defined('IN_ADMIN'))
+ // We pre-define the action parameter we are using all over the place
+ if (defined('IN_ADMIN'))
+ {
+ // Is first module automatically enabled a duplicate and the category not passed yet?
+ if (!$icat && $this->module_ary[$this->active_module_row_id]['is_duplicate'])
{
- // Is first module automatically enabled a duplicate and the category not passed yet?
- if (!$icat && $this->module_ary[$this->active_module_row_id]['is_duplicate'])
- {
- $icat = $this->module_ary[$this->active_module_row_id]['parent'];
- }
+ $icat = $this->module_ary[$this->active_module_row_id]['parent'];
+ }
- // Not being able to overwrite ;)
- $this->module->u_action = append_sid("{$phpbb_admin_path}index.$phpEx", "i={$this->p_name}") . (($icat) ? '&amp;icat=' . $icat : '') . "&amp;mode={$this->p_mode}";
+ // Not being able to overwrite ;)
+ $this->module->u_action = append_sid("{$phpbb_admin_path}index.$phpEx", "i={$this->p_name}") . (($icat) ? '&amp;icat=' . $icat : '') . "&amp;mode={$this->p_mode}";
+ }
+ else
+ {
+ // If user specified the module url we will use it...
+ if ($module_url !== false)
+ {
+ $this->module->u_action = $module_url;
}
else
{
- // If user specified the module url we will use it...
- if ($module_url !== false)
- {
- $this->module->u_action = $module_url;
- }
- else
- {
- $this->module->u_action = $phpbb_root_path . (($user->page['page_dir']) ? $user->page['page_dir'] . '/' : '') . $user->page['page_name'];
- }
-
- $this->module->u_action = append_sid($this->module->u_action, "i={$this->p_name}") . (($icat) ? '&amp;icat=' . $icat : '') . "&amp;mode={$this->p_mode}";
+ $this->module->u_action = $phpbb_root_path . (($user->page['page_dir']) ? $user->page['page_dir'] . '/' : '') . $user->page['page_name'];
}
- // Add url_extra parameter to u_action url
- if (!empty($this->module_ary) && $this->active_module !== false && $this->module_ary[$this->active_module_row_id]['url_extra'])
- {
- $this->module->u_action .= $this->module_ary[$this->active_module_row_id]['url_extra'];
- }
+ $this->module->u_action = append_sid($this->module->u_action, "i={$this->p_name}") . (($icat) ? '&amp;icat=' . $icat : '') . "&amp;mode={$this->p_mode}";
+ }
- // Assign the module path for re-usage
- $this->module->module_path = $module_path . '/';
+ // Add url_extra parameter to u_action url
+ if (!empty($this->module_ary) && $this->active_module !== false && $this->module_ary[$this->active_module_row_id]['url_extra'])
+ {
+ $this->module->u_action .= $this->module_ary[$this->active_module_row_id]['url_extra'];
+ }
- // Execute the main method for the new instance, we send the module id and mode as parameters
- // Users are able to call the main method after this function to be able to assign additional parameters manually
- if ($execute_module)
- {
- $this->module->main($this->p_name, $this->p_mode);
- }
+ // Assign the module path for re-usage
+ $this->module->module_path = $module_path . '/';
- return;
+ // Execute the main method for the new instance, we send the module id and mode as parameters
+ // Users are able to call the main method after this function to be able to assign additional parameters manually
+ if ($execute_module)
+ {
+ $short_name = preg_replace("#^{$this->p_class}_#", '', $this->p_name);
+ $this->module->main($short_name, $this->p_mode);
}
}
@@ -547,7 +558,7 @@ class p_master
// If we find a name by this id and being enabled we have our active one...
foreach ($this->module_ary as $row_id => $item_ary)
{
- if (($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && $item_ary['display'])
+ if (($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && $item_ary['display'] || $item_ary['name'] === $this->p_class . '_' . $id)
{
if ($mode === false || $mode === $item_ary['mode'])
{
@@ -841,7 +852,7 @@ class p_master
{
foreach ($this->module_ary as $row_id => $item_ary)
{
- if (($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && (!$mode || $item_ary['mode'] === $mode))
+ if (($item_ary['name'] === $id || $item_ary['name'] === $this->p_class . '_' . $id || $item_ary['id'] === (int) $id) && (!$mode || $item_ary['mode'] === $mode))
{
$this->module_ary[$row_id]['display'] = (int) $display;
}
@@ -855,28 +866,49 @@ class p_master
{
global $user, $phpEx;
- if (file_exists($user->lang_path . $user->lang_name . '/mods'))
- {
- $add_files = array();
+ global $phpbb_extension_manager;
- $dir = @opendir($user->lang_path . $user->lang_name . '/mods');
+ $finder = $phpbb_extension_manager->get_finder();
- if ($dir)
- {
- while (($entry = readdir($dir)) !== false)
- {
- if (strpos($entry, 'info_' . strtolower($module_class) . '_') === 0 && substr(strrchr($entry, '.'), 1) == $phpEx)
- {
- $add_files[] = 'mods/' . substr(basename($entry), 0, -(strlen($phpEx) + 1));
- }
- }
- closedir($dir);
- }
+ $lang_files = $finder
+ ->prefix('info_' . strtolower($module_class) . '_')
+ ->suffix(".$phpEx")
+ ->extension_directory('/language/' . $user->lang_name)
+ ->core_path('language/' . $user->lang_name . '/mods/')
+ ->find();
- if (sizeof($add_files))
- {
- $user->add_lang($add_files);
- }
+ foreach ($lang_files as $lang_file => $ext_name)
+ {
+ $user->add_lang_ext($ext_name, $lang_file);
}
}
+
+ /**
+ * Retrieve shortened module basename for legacy basenames (with xcp_ prefix)
+ *
+ * @param string $basename A module basename
+ * @return string The basename if it starts with phpbb_ or the basename with
+ * the current p_class (e.g. acp_) stripped.
+ */
+ protected function get_short_name($basename)
+ {
+ if (substr($basename, 0, 6) === 'phpbb_')
+ {
+ return $basename;
+ }
+
+ // strip xcp_ prefix from old classes
+ return substr($basename, strlen($this->p_class) + 1);
+ }
+
+ /**
+ * Checks whether the given module basename is a correct class name
+ *
+ * @param string $basename A module basename
+ * @return bool True if the basename starts with phpbb_ or (x)cp_, false otherwise
+ */
+ protected function is_full_class($basename)
+ {
+ return (substr($basename, 0, 6) === 'phpbb_' || substr($basename, 0, strlen($this->p_class) + 1) === $this->p_class . '_');
+ }
}
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index 4ca76344de..960359b936 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -1005,7 +1005,7 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
$mode = 'post_review';
}
- $sql = $db->sql_build_query('SELECT', array(
+ $sql_ary = array(
'SELECT' => 'u.username, u.user_id, u.user_colour, p.*, z.friend, z.foe',
'FROM' => array(
@@ -1016,14 +1016,15 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
'LEFT_JOIN' => array(
array(
'FROM' => array(ZEBRA_TABLE => 'z'),
- 'ON' => 'z.user_id = ' . $user->data['user_id'] . ' AND z.zebra_id = p.poster_id'
- )
+ 'ON' => 'z.user_id = ' . $user->data['user_id'] . ' AND z.zebra_id = p.poster_id',
+ ),
),
'WHERE' => $db->sql_in_set('p.post_id', $post_list) . '
- AND u.user_id = p.poster_id'
- ));
+ AND u.user_id = p.poster_id',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query($sql);
$bbcode_bitfield = '';
@@ -1855,9 +1856,9 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
case 'edit_topic':
case 'edit_first_post':
- if (isset($poll['poll_options']) && !empty($poll['poll_options']))
+ if (isset($poll['poll_options']))
{
- $poll_start = ($poll['poll_start']) ? $poll['poll_start'] : $current_time;
+ $poll_start = ($poll['poll_start'] || empty($poll['poll_options'])) ? $poll['poll_start'] : $current_time;
$poll_length = $poll['poll_length'] * 86400;
if ($poll_length < 0)
{
@@ -2005,11 +2006,11 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
}
// Update Poll Tables
- if (isset($poll['poll_options']) && !empty($poll['poll_options']))
+ if (isset($poll['poll_options']))
{
$cur_poll_options = array();
- if ($poll['poll_start'] && $mode == 'edit')
+ if ($mode == 'edit')
{
$sql = 'SELECT *
FROM ' . POLL_OPTIONS_TABLE . '
@@ -2350,16 +2351,11 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
if ($update_search_index && $data['enable_indexing'])
{
// Select the search method and do some additional checks to ensure it can actually be utilised
- $search_type = basename($config['search_type']);
-
- if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
- {
- trigger_error('NO_SUCH_SEARCH_MODULE');
- }
+ $search_type = $config['search_type'];
if (!class_exists($search_type))
{
- include("{$phpbb_root_path}includes/search/$search_type.$phpEx");
+ trigger_error('NO_SUCH_SEARCH_MODULE');
}
$error = false;
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index 32b57a9f2e..76f25da977 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -1330,7 +1330,7 @@ function get_folder_status($folder_id, $folder)
'percent' => ($user->data['message_limit']) ? (($user->data['message_limit'] > 0) ? round(($folder['num_messages'] / $user->data['message_limit']) * 100) : 100) : 0,
);
- $return['message'] = sprintf($user->lang['FOLDER_STATUS_MSG'], $return['percent'], $return['cur'], $return['max']);
+ $return['message'] = $user->lang('FOLDER_STATUS_MSG', (int) $return['max'], $return['cur'], $return['percent']);
return $return;
}
@@ -1652,7 +1652,7 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
// Send Notifications
if ($mode != 'edit')
{
- pm_notification($mode, $data['from_username'], $recipients, $subject, $data['message']);
+ pm_notification($mode, $data['from_username'], $recipients, $subject, $data['message'], $data['msg_id']);
}
return $data['msg_id'];
@@ -1661,7 +1661,7 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
/**
* PM Notification
*/
-function pm_notification($mode, $author, $recipients, $subject, $message)
+function pm_notification($mode, $author, $recipients, $subject, $message, $msg_id)
{
global $db, $user, $config, $phpbb_root_path, $phpEx, $auth;
@@ -1733,8 +1733,9 @@ function pm_notification($mode, $author, $recipients, $subject, $message)
'AUTHOR_NAME' => htmlspecialchars_decode($author),
'USERNAME' => htmlspecialchars_decode($addr['name']),
- 'U_INBOX' => generate_board_url() . "/ucp.$phpEx?i=pm&folder=inbox")
- );
+ 'U_INBOX' => generate_board_url() . "/ucp.$phpEx?i=pm&folder=inbox",
+ 'U_VIEW_MESSAGE' => generate_board_url() . "/ucp.$phpEx?i=pm&mode=view&p=$msg_id",
+ ));
$messenger->send($addr['method']);
}
diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php
index ec29a1732d..130a4dcae8 100644
--- a/phpBB/includes/functions_profile_fields.php
+++ b/phpBB/includes/functions_profile_fields.php
@@ -315,32 +315,32 @@ class custom_profile
case 'FIELD_INVALID_DATE':
case 'FIELD_INVALID_VALUE':
case 'FIELD_REQUIRED':
- $error = sprintf($user->lang[$cp_result], $row['lang_name']);
+ $error = $user->lang($cp_result, $row['lang_name']);
break;
case 'FIELD_TOO_SHORT':
case 'FIELD_TOO_SMALL':
- $error = sprintf($user->lang[$cp_result], $row['lang_name'], $row['field_minlen']);
+ $error = $user->lang($cp_result, (int) $row['field_minlen'], $row['lang_name']);
break;
case 'FIELD_TOO_LONG':
case 'FIELD_TOO_LARGE':
- $error = sprintf($user->lang[$cp_result], $row['lang_name'], $row['field_maxlen']);
+ $error = $user->lang($cp_result, (int) $row['field_maxlen'], $row['lang_name']);
break;
case 'FIELD_INVALID_CHARS':
switch ($row['field_validation'])
{
case '[0-9]+':
- $error = sprintf($user->lang[$cp_result . '_NUMBERS_ONLY'], $row['lang_name']);
+ $error = $user->lang($cp_result . '_NUMBERS_ONLY', $row['lang_name']);
break;
case '[\w]+':
- $error = sprintf($user->lang[$cp_result . '_ALPHA_ONLY'], $row['lang_name']);
+ $error = $user->lang($cp_result . '_ALPHA_ONLY', $row['lang_name']);
break;
case '[\w_\+\. \-\[\]]+':
- $error = sprintf($user->lang[$cp_result . '_SPACERS_ONLY'], $row['lang_name']);
+ $error = $user->lang($cp_result . '_SPACERS_ONLY', $row['lang_name']);
break;
}
break;
diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php
index f648c585f6..2322aa77bf 100644
--- a/phpBB/includes/functions_upload.php
+++ b/phpBB/includes/functions_upload.php
@@ -427,7 +427,13 @@ class filespec
if (!$this->upload->valid_dimensions($this))
{
- $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'WRONG_SIZE'], $this->upload->min_width, $this->upload->min_height, $this->upload->max_width, $this->upload->max_height, $this->width, $this->height);
+ $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;
}
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 930cd4625f..5631928f96 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -2039,7 +2039,7 @@ function avatar_remote($data, &$error)
{
if ($width > $config['avatar_max_width'] || $height > $config['avatar_max_height'])
{
- $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height);
+ $error[] = phpbb_avatar_error_wrong_size($width, $height);
return false;
}
}
@@ -2048,7 +2048,7 @@ function avatar_remote($data, &$error)
{
if ($width < $config['avatar_min_width'] || $height < $config['avatar_min_height'])
{
- $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height);
+ $error[] = phpbb_avatar_error_wrong_size($width, $height);
return false;
}
}
@@ -2388,7 +2388,7 @@ function avatar_process_user(&$error, $custom_userdata = false, $can_upload = nu
{
if ($data['width'] > $config['avatar_max_width'] || $data['height'] > $config['avatar_max_height'])
{
- $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $data['width'], $data['height']);
+ $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
}
}
@@ -2398,7 +2398,7 @@ function avatar_process_user(&$error, $custom_userdata = false, $can_upload = nu
{
if ($data['width'] < $config['avatar_min_width'] || $data['height'] < $config['avatar_min_height'])
{
- $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $data['width'], $data['height']);
+ $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
}
}
}
@@ -2444,6 +2444,41 @@ function avatar_process_user(&$error, $custom_userdata = false, $can_upload = nu
return (sizeof($error)) ? false : true;
}
+/**
+* Returns a language string with the avatar size of the new avatar and the allowed maximum and minimum
+*
+* @param $width int The width of the new uploaded/selected avatar
+* @param $height int The height of the new uploaded/selected avatar
+* @return string
+*/
+function phpbb_avatar_error_wrong_size($width, $height)
+{
+ global $config, $user;
+
+ return $user->lang('AVATAR_WRONG_SIZE',
+ $user->lang('PIXELS', (int) $config['avatar_min_width']),
+ $user->lang('PIXELS', (int) $config['avatar_min_height']),
+ $user->lang('PIXELS', (int) $config['avatar_max_width']),
+ $user->lang('PIXELS', (int) $config['avatar_max_height']),
+ $user->lang('PIXELS', (int) $width),
+ $user->lang('PIXELS', (int) $height));
+}
+
+/**
+* Returns an explanation string with maximum avatar settings
+*
+* @return string
+*/
+function phpbb_avatar_explanation_string()
+{
+ global $config, $user;
+
+ return $user->lang('AVATAR_EXPLAIN',
+ $user->lang('PIXELS', (int) $config['avatar_max_width']),
+ $user->lang('PIXELS', (int) $config['avatar_max_height']),
+ round($config['avatar_filesize'] / 1024));
+}
+
//
// Usergroup functions
//
diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php
index 8206a183f3..c823e0a0ee 100644
--- a/phpBB/includes/mcp/mcp_forum.php
+++ b/phpBB/includes/mcp/mcp_forum.php
@@ -132,7 +132,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
'PAGINATION' => generate_pagination($url . "&amp;i=$id&amp;action=$action&amp;mode=$mode&amp;sd=$sort_dir&amp;sk=$sort_key&amp;st=$sort_days" . (($merge_select) ? $selected_ids : ''), $forum_topics, $topics_per_page, $start),
'PAGE_NUMBER' => on_page($forum_topics, $topics_per_page, $start),
- 'TOTAL_TOPICS' => ($forum_topics == 1) ? $user->lang['VIEW_FORUM_TOPIC'] : sprintf($user->lang['VIEW_FORUM_TOPICS'], $forum_topics),
+ 'TOTAL_TOPICS' => $user->lang('VIEW_FORUM_TOPICS', (int) $forum_topics),
));
// Grab icons
diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php
index eca67c5ac1..4ae46f98a2 100644
--- a/phpBB/includes/mcp/mcp_front.php
+++ b/phpBB/includes/mcp/mcp_front.php
@@ -79,7 +79,7 @@ function mcp_front_view($id, $mode, $action)
if ($total)
{
- $sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.username, u.username_clean, u.user_colour, t.topic_id, t.topic_title, t.topic_first_post_id, p.forum_id
+ $sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.post_attachment, p.poster_id, p.post_username, u.username, u.username_clean, u.user_colour, t.topic_id, t.topic_title, t.topic_first_post_id, p.forum_id
FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t, ' . USERS_TABLE . ' u
WHERE ' . $db->sql_in_set('p.post_id', $post_list) . '
AND t.topic_id = p.topic_id
@@ -105,8 +105,9 @@ function mcp_front_view($id, $mode, $action)
'POST_ID' => $row['post_id'],
'TOPIC_TITLE' => $row['topic_title'],
'SUBJECT' => ($row['post_subject']) ? $row['post_subject'] : $user->lang['NO_SUBJECT'],
- 'POST_TIME' => $user->format_date($row['post_time']))
- );
+ 'POST_TIME' => $user->format_date($row['post_time']),
+ 'ATTACH_ICON_IMG' => ($auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id']) && $row['post_attachment']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '',
+ ));
}
$db->sql_freeresult($result);
}
@@ -118,22 +119,9 @@ function mcp_front_view($id, $mode, $action)
$template->assign_vars(array(
'S_HIDDEN_FIELDS' => $s_hidden_fields,
'S_MCP_QUEUE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue"),
+ 'L_UNAPPROVED_TOTAL' => $user->lang('UNAPPROVED_POSTS_TOTAL', (int) $total),
+ 'S_HAS_UNAPPROVED_POSTS'=> ($total != 0),
));
-
- if ($total == 0)
- {
- $template->assign_vars(array(
- 'L_UNAPPROVED_TOTAL' => $user->lang['UNAPPROVED_POSTS_ZERO_TOTAL'],
- 'S_HAS_UNAPPROVED_POSTS' => false)
- );
- }
- else
- {
- $template->assign_vars(array(
- 'L_UNAPPROVED_TOTAL' => ($total == 1) ? $user->lang['UNAPPROVED_POST_TOTAL'] : sprintf($user->lang['UNAPPROVED_POSTS_TOTAL'], $total),
- 'S_HAS_UNAPPROVED_POSTS' => true)
- );
- }
}
}
@@ -158,22 +146,22 @@ function mcp_front_view($id, $mode, $action)
if ($total)
{
- $sql = $db->sql_build_query('SELECT', array(
- 'SELECT' => 'r.report_time, p.post_id, p.post_subject, p.post_time, u.username, u.username_clean, u.user_colour, u.user_id, u2.username as author_name, u2.username_clean as author_name_clean, u2.user_colour as author_colour, u2.user_id as author_id, t.topic_id, t.topic_title, f.forum_id, f.forum_name',
+ $sql_ary = array(
+ 'SELECT' => 'r.report_time, p.post_id, p.post_subject, p.post_time, p.post_attachment, u.username, u.username_clean, u.user_colour, u.user_id, u2.username as author_name, u2.username_clean as author_name_clean, u2.user_colour as author_colour, u2.user_id as author_id, t.topic_id, t.topic_title, f.forum_id, f.forum_name',
'FROM' => array(
REPORTS_TABLE => 'r',
REPORTS_REASONS_TABLE => 'rr',
TOPICS_TABLE => 't',
USERS_TABLE => array('u', 'u2'),
- POSTS_TABLE => 'p'
+ POSTS_TABLE => 'p',
),
'LEFT_JOIN' => array(
array(
'FROM' => array(FORUMS_TABLE => 'f'),
- 'ON' => 'f.forum_id = p.forum_id'
- )
+ 'ON' => 'f.forum_id = p.forum_id',
+ ),
),
'WHERE' => 'r.post_id = p.post_id
@@ -185,8 +173,9 @@ function mcp_front_view($id, $mode, $action)
AND p.poster_id = u2.user_id
AND ' . $db->sql_in_set('p.forum_id', $forum_list),
- 'ORDER_BY' => 'p.post_time DESC'
- ));
+ 'ORDER_BY' => 'p.post_time DESC',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query_limit($sql, 5);
while ($row = $db->sql_fetchrow($result))
@@ -213,24 +202,15 @@ function mcp_front_view($id, $mode, $action)
'SUBJECT' => ($row['post_subject']) ? $row['post_subject'] : $user->lang['NO_SUBJECT'],
'REPORT_TIME' => $user->format_date($row['report_time']),
'POST_TIME' => $user->format_date($row['post_time']),
+ 'ATTACH_ICON_IMG' => ($auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id']) && $row['post_attachment']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '',
));
}
}
- if ($total == 0)
- {
- $template->assign_vars(array(
- 'L_REPORTS_TOTAL' => $user->lang['REPORTS_ZERO_TOTAL'],
- 'S_HAS_REPORTS' => false)
- );
- }
- else
- {
- $template->assign_vars(array(
- 'L_REPORTS_TOTAL' => ($total == 1) ? $user->lang['REPORT_TOTAL'] : sprintf($user->lang['REPORTS_TOTAL'], $total),
- 'S_HAS_REPORTS' => true)
- );
- }
+ $template->assign_vars(array(
+ 'L_REPORTS_TOTAL' => $user->lang('REPORTS_TOTAL', (int) $total),
+ 'S_HAS_REPORTS' => ($total != 0),
+ ));
}
}
@@ -253,14 +233,14 @@ function mcp_front_view($id, $mode, $action)
{
include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
- $sql = $db->sql_build_query('SELECT', array(
- 'SELECT' => 'r.report_id, r.report_time, p.msg_id, p.message_subject, p.message_time, p.to_address, p.bcc_address, u.username, u.username_clean, u.user_colour, u.user_id, u2.username as author_name, u2.username_clean as author_name_clean, u2.user_colour as author_colour, u2.user_id as author_id',
+ $sql_ary = array(
+ 'SELECT' => 'r.report_id, r.report_time, p.msg_id, p.message_subject, p.message_time, p.to_address, p.bcc_address, p.message_attachment, u.username, u.username_clean, u.user_colour, u.user_id, u2.username as author_name, u2.username_clean as author_name_clean, u2.user_colour as author_colour, u2.user_id as author_id',
'FROM' => array(
REPORTS_TABLE => 'r',
REPORTS_REASONS_TABLE => 'rr',
USERS_TABLE => array('u', 'u2'),
- PRIVMSGS_TABLE => 'p'
+ PRIVMSGS_TABLE => 'p',
),
'WHERE' => 'r.pm_id = p.msg_id
@@ -270,8 +250,9 @@ function mcp_front_view($id, $mode, $action)
AND r.user_id = u.user_id
AND p.author_id = u2.user_id',
- 'ORDER_BY' => 'p.message_time DESC'
- ));
+ 'ORDER_BY' => 'p.message_time DESC',
+ );
+ $sql_ary = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query_limit($sql, 5);
$pm_by_id = $pm_list = array();
@@ -304,24 +285,15 @@ function mcp_front_view($id, $mode, $action)
'REPORT_TIME' => $user->format_date($row['report_time']),
'PM_TIME' => $user->format_date($row['message_time']),
'RECIPIENTS' => implode(', ', $address_list[$row['msg_id']]),
+ 'ATTACH_ICON_IMG' => ($auth->acl_get('u_download') && $row['message_attachment']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '',
));
}
}
- if ($total == 0)
- {
- $template->assign_vars(array(
- 'L_PM_REPORTS_TOTAL' => $user->lang['PM_REPORTS_ZERO_TOTAL'],
- 'S_HAS_PM_REPORTS' => false)
- );
- }
- else
- {
- $template->assign_vars(array(
- 'L_PM_REPORTS_TOTAL' => ($total == 1) ? $user->lang['PM_REPORT_TOTAL'] : sprintf($user->lang['PM_REPORTS_TOTAL'], $total),
- 'S_HAS_PM_REPORTS' => true)
- );
- }
+ $template->assign_vars(array(
+ 'L_PM_REPORTS_TOTAL' => $user->lang('PM_REPORTS_TOTAL', (int) $total),
+ 'S_HAS_PM_REPORTS' => ($total != 0),
+ ));
}
// Latest 5 logs
diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php
index dc05ba4110..52f8259acf 100644
--- a/phpBB/includes/mcp/mcp_logs.php
+++ b/phpBB/includes/mcp/mcp_logs.php
@@ -174,7 +174,7 @@ class mcp_logs
$template->assign_vars(array(
'PAGE_NUMBER' => on_page($log_count, $config['topics_per_page'], $start),
- 'TOTAL' => ($log_count == 1) ? $user->lang['TOTAL_LOG'] : sprintf($user->lang['TOTAL_LOGS'], $log_count),
+ 'TOTAL' => $user->lang('TOTAL_LOGS', (int) $log_count),
'PAGINATION' => generate_pagination($this->u_action . "&amp;$u_sort_param$keywords_param", $log_count, $config['topics_per_page'], $start),
'L_TITLE' => $user->lang['MCP_LOGS'],
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index 6c6c5a5532..e0a1357213 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -286,14 +286,6 @@ function change_topic_type($action, $topic_ids)
{
global $auth, $user, $db, $phpEx, $phpbb_root_path;
- // For changing topic types, we only allow operations in one forum.
- $forum_id = check_ids($topic_ids, TOPICS_TABLE, 'topic_id', array('f_announce', 'f_sticky', 'm_'), true);
-
- if ($forum_id === false)
- {
- return;
- }
-
switch ($action)
{
case 'make_announce':
@@ -316,11 +308,18 @@ function change_topic_type($action, $topic_ids)
default:
$new_topic_type = POST_NORMAL;
- $check_acl = '';
+ $check_acl = false;
$l_new_type = (sizeof($topic_ids) == 1) ? 'MCP_MAKE_NORMAL' : 'MCP_MAKE_NORMALS';
break;
}
+ $forum_id = check_ids($topic_ids, TOPICS_TABLE, 'topic_id', $check_acl, true);
+
+ if ($forum_id === false)
+ {
+ return;
+ }
+
$redirect = request_var('redirect', build_url(array('action', 'quickmod')));
$s_hidden_fields = array(
diff --git a/phpBB/includes/mcp/mcp_notes.php b/phpBB/includes/mcp/mcp_notes.php
index dfb6ed3b68..1432e96a48 100644
--- a/phpBB/includes/mcp/mcp_notes.php
+++ b/phpBB/includes/mcp/mcp_notes.php
@@ -228,7 +228,7 @@ class mcp_notes
'PAGE_NUMBER' => on_page($log_count, $config['topics_per_page'], $start),
'PAGINATION' => generate_pagination($this->u_action . "&amp;$u_sort_param$keywords_param", $log_count, $config['topics_per_page'], $start),
- 'TOTAL_REPORTS' => ($log_count == 1) ? $user->lang['LIST_REPORT'] : sprintf($user->lang['LIST_REPORTS'], $log_count),
+ 'TOTAL_REPORTS' => $user->lang('LIST_REPORTS', (int) $log_count),
'RANK_TITLE' => $rank_title,
'JOINED' => $user->format_date($userrow['user_regdate']),
diff --git a/phpBB/includes/mcp/mcp_pm_reports.php b/phpBB/includes/mcp/mcp_pm_reports.php
index e61e8390c9..6bba71f0d9 100644
--- a/phpBB/includes/mcp/mcp_pm_reports.php
+++ b/phpBB/includes/mcp/mcp_pm_reports.php
@@ -293,6 +293,7 @@ class mcp_pm_reports
'REPORT_TIME' => $user->format_date($row['report_time']),
'RECIPIENTS' => implode(', ', $address_list[$row['msg_id']]),
+ 'ATTACH_ICON_IMG' => ($auth->acl_get('u_download') && $row['message_attachment']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '',
));
}
}
@@ -310,7 +311,7 @@ class mcp_pm_reports
'PAGINATION' => generate_pagination($this->u_action . "&amp;st=$sort_days&amp;sk=$sort_key&amp;sd=$sort_dir", $total, $config['topics_per_page'], $start),
'PAGE_NUMBER' => on_page($total, $config['topics_per_page'], $start),
'TOTAL' => $total,
- 'TOTAL_REPORTS' => ($total == 1) ? $user->lang['LIST_REPORT'] : sprintf($user->lang['LIST_REPORTS'], $total),
+ 'TOTAL_REPORTS' => $user->lang('LIST_REPORTS', (int) $total),
)
);
diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php
index 4e0aae1870..2abded4483 100644
--- a/phpBB/includes/mcp/mcp_post.php
+++ b/phpBB/includes/mcp/mcp_post.php
@@ -246,7 +246,7 @@ function mcp_post_details($id, $mode, $action)
}
// Get Reports
- if ($auth->acl_get('m_', $post_info['forum_id']))
+ if ($auth->acl_get('m_report', $post_info['forum_id']))
{
$sql = 'SELECT r.*, re.*, u.user_id, u.username
FROM ' . REPORTS_TABLE . ' r, ' . USERS_TABLE . ' u, ' . REPORTS_REASONS_TABLE . " re
diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php
index 0630f55b12..692d29dabb 100644
--- a/phpBB/includes/mcp/mcp_queue.php
+++ b/phpBB/includes/mcp/mcp_queue.php
@@ -216,6 +216,7 @@ class mcp_queue
'POST_IP' => $post_info['poster_ip'],
'POST_IPADDR' => ($auth->acl_get('m_info', $post_info['forum_id']) && request_var('lookup', '')) ? @gethostbyaddr($post_info['poster_ip']) : '',
'POST_ID' => $post_info['post_id'],
+ 'S_FIRST_POST' => ($post_info['topic_first_post_id'] == $post_id),
'U_LOOKUP_IP' => ($auth->acl_get('m_info', $post_info['forum_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=approve_details&amp;f=' . $post_info['forum_id'] . '&amp;p=' . $post_id . '&amp;lookup=' . $post_info['poster_ip']) . '#ip' : '',
));
@@ -331,7 +332,7 @@ class mcp_queue
if (sizeof($post_ids))
{
- $sql = 'SELECT t.topic_id, t.topic_title, t.forum_id, p.post_id, p.post_subject, p.post_username, p.poster_id, p.post_time, u.username, u.username_clean, u.user_colour
+ $sql = 'SELECT t.topic_id, t.topic_title, t.forum_id, p.post_id, p.post_subject, p.post_username, p.poster_id, p.post_time, p.post_attachment, u.username, u.username_clean, u.user_colour
FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t, ' . USERS_TABLE . ' u
WHERE ' . $db->sql_in_set('p.post_id', $post_ids) . '
AND t.topic_id = p.topic_id
@@ -360,7 +361,7 @@ class mcp_queue
}
else
{
- $sql = 'SELECT t.forum_id, t.topic_id, t.topic_title, t.topic_title AS post_subject, t.topic_time AS post_time, t.topic_poster AS poster_id, t.topic_first_post_id AS post_id, t.topic_first_poster_name AS username, t.topic_first_poster_colour AS user_colour
+ $sql = 'SELECT t.forum_id, t.topic_id, t.topic_title, t.topic_title AS post_subject, t.topic_time AS post_time, t.topic_poster AS poster_id, t.topic_first_post_id AS post_id, t.topic_attachment AS post_attachment, t.topic_first_poster_name AS username, t.topic_first_poster_colour AS user_colour
FROM ' . TOPICS_TABLE . " t
WHERE " . $db->sql_in_set('forum_id', $forum_list) . "
AND topic_approved = 0
@@ -415,8 +416,9 @@ class mcp_queue
'FORUM_NAME' => $forum_names[$row['forum_id']],
'POST_SUBJECT' => ($row['post_subject'] != '') ? $row['post_subject'] : $user->lang['NO_SUBJECT'],
'TOPIC_TITLE' => $row['topic_title'],
- 'POST_TIME' => $user->format_date($row['post_time']))
- );
+ 'POST_TIME' => $user->format_date($row['post_time']),
+ 'ATTACH_ICON_IMG' => ($auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id']) && $row['post_attachment']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '',
+ ));
}
unset($rowset, $forum_names);
@@ -434,7 +436,7 @@ class mcp_queue
'PAGINATION' => generate_pagination($this->u_action . "&amp;f=$forum_id&amp;st=$sort_days&amp;sk=$sort_key&amp;sd=$sort_dir", $total, $config['topics_per_page'], $start),
'PAGE_NUMBER' => on_page($total, $config['topics_per_page'], $start),
'TOPIC_ID' => $topic_id,
- 'TOTAL' => ($total == 1) ? (($mode == 'unapproved_posts') ? $user->lang['VIEW_TOPIC_POST'] : $user->lang['VIEW_FORUM_TOPIC']) : sprintf((($mode == 'unapproved_posts') ? $user->lang['VIEW_TOPIC_POSTS'] : $user->lang['VIEW_FORUM_TOPICS']), $total),
+ 'TOTAL' => $user->lang((($mode == 'unapproved_posts') ? 'VIEW_TOPIC_POSTS' : 'VIEW_FORUM_TOPICS'), (int) $total),
));
$this->tpl_name = 'mcp_queue';
@@ -754,7 +756,10 @@ function disapprove_post($post_id_list, $id, $mode)
if (!$row || (!$reason && strtolower($row['reason_title']) == 'other'))
{
$additional_msg = $user->lang['NO_REASON_DISAPPROVAL'];
+
$request->overwrite('confirm', null, phpbb_request_interface::POST);
+ $request->overwrite('confirm_key', null, phpbb_request_interface::POST);
+ $request->overwrite('confirm_key', null, phpbb_request_interface::REQUEST);
}
else
{
diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php
index a7275382e6..eb2b655dd3 100644
--- a/phpBB/includes/mcp/mcp_reports.php
+++ b/phpBB/includes/mcp/mcp_reports.php
@@ -148,6 +148,7 @@ class mcp_reports
$message = bbcode_nl2br($message);
$message = smiley_text($message);
+ $report['report_text'] = make_clickable(bbcode_nl2br($report['report_text']));
if ($post_info['post_attachment'] && $auth->acl_get('u_download') && $auth->acl_get('f_download', $post_info['forum_id']))
{
@@ -367,7 +368,7 @@ class mcp_reports
if (sizeof($report_ids))
{
- $sql = 'SELECT t.forum_id, t.topic_id, t.topic_title, p.post_id, p.post_subject, p.post_username, p.poster_id, p.post_time, u.username, u.username_clean, u.user_colour, r.user_id as reporter_id, ru.username as reporter_name, ru.user_colour as reporter_colour, r.report_time, r.report_id
+ $sql = 'SELECT t.forum_id, t.topic_id, t.topic_title, p.post_id, p.post_subject, p.post_username, p.poster_id, p.post_time, p.post_attachment, u.username, u.username_clean, u.user_colour, r.user_id as reporter_id, ru.username as reporter_name, ru.user_colour as reporter_colour, r.report_time, r.report_id
FROM ' . REPORTS_TABLE . ' r, ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t, ' . USERS_TABLE . ' u, ' . USERS_TABLE . ' ru
WHERE ' . $db->sql_in_set('r.report_id', $report_ids) . '
AND t.topic_id = p.topic_id
@@ -402,8 +403,9 @@ class mcp_reports
'POST_TIME' => $user->format_date($row['post_time']),
'REPORT_ID' => $row['report_id'],
'REPORT_TIME' => $user->format_date($row['report_time']),
- 'TOPIC_TITLE' => $row['topic_title'])
- );
+ 'TOPIC_TITLE' => $row['topic_title'],
+ 'ATTACH_ICON_IMG' => ($auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id']) && $row['post_attachment']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '',
+ ));
}
$db->sql_freeresult($result);
unset($report_ids, $row);
@@ -423,7 +425,7 @@ class mcp_reports
'PAGE_NUMBER' => on_page($total, $config['topics_per_page'], $start),
'TOPIC_ID' => $topic_id,
'TOTAL' => $total,
- 'TOTAL_REPORTS' => ($total == 1) ? $user->lang['LIST_REPORT'] : sprintf($user->lang['LIST_REPORTS'], $total),
+ 'TOTAL_REPORTS' => $user->lang('LIST_REPORTS', (int) $total),
)
);
diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php
index 8a8ef11289..463dd5868d 100644
--- a/phpBB/includes/mcp/mcp_topic.php
+++ b/phpBB/includes/mcp/mcp_topic.php
@@ -239,8 +239,8 @@ function mcp_topic_view($id, $mode, $action)
'MINI_POST_IMG' => ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'),
- 'S_POST_REPORTED' => ($row['post_reported']) ? true : false,
- 'S_POST_UNAPPROVED' => ($row['post_approved']) ? false : true,
+ 'S_POST_REPORTED' => ($row['post_reported'] && $auth->acl_get('m_report', $topic_info['forum_id'])),
+ 'S_POST_UNAPPROVED' => (!$row['post_approved'] && $auth->acl_get('m_approve', $topic_info['forum_id'])),
'S_CHECKED' => (($submitted_id_list && !in_array(intval($row['post_id']), $submitted_id_list)) || in_array(intval($row['post_id']), $checked_ids)) ? true : false,
'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false,
@@ -336,7 +336,7 @@ function mcp_topic_view($id, $mode, $action)
'PAGE_NUMBER' => on_page($total, $posts_per_page, $start),
'PAGINATION' => (!$posts_per_page) ? '' : generate_pagination(append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&amp;t={$topic_info['topic_id']}&amp;mode=$mode&amp;action=$action&amp;to_topic_id=$to_topic_id&amp;posts_per_page=$posts_per_page&amp;st=$sort_days&amp;sk=$sort_key&amp;sd=$sort_dir"), $total, $posts_per_page, $start),
- 'TOTAL_POSTS' => ($total == 1) ? $user->lang['VIEW_TOPIC_POST'] : sprintf($user->lang['VIEW_TOPIC_POSTS'], $total),
+ 'TOTAL_POSTS' => $user->lang('VIEW_TOPIC_POSTS', (int) $total),
));
}
diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php
index 9339389ea4..8cf435c293 100644
--- a/phpBB/includes/mcp/mcp_warn.php
+++ b/phpBB/includes/mcp/mcp_warn.php
@@ -185,7 +185,7 @@ class mcp_warn
'PAGE_NUMBER' => on_page($user_count, $config['topics_per_page'], $start),
'PAGINATION' => generate_pagination(append_sid("{$phpbb_root_path}mcp.$phpEx", "i=warn&amp;mode=list&amp;st=$st&amp;sk=$sk&amp;sd=$sd"), $user_count, $config['topics_per_page'], $start),
- 'TOTAL_USERS' => ($user_count == 1) ? $user->lang['LIST_USER'] : sprintf($user->lang['LIST_USERS'], $user_count),
+ 'TOTAL_USERS' => $user->lang('LIST_USERS', (int) $user_count),
));
}
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php
index b3a48112ea..5e8732e94d 100644
--- a/phpBB/includes/message_parser.php
+++ b/phpBB/includes/message_parser.php
@@ -210,7 +210,7 @@ class bbcode_firstpass extends bbcode
if ($config['max_' . $this->mode . '_font_size'] && $config['max_' . $this->mode . '_font_size'] < $stx)
{
- $this->warn_msg[] = sprintf($user->lang['MAX_FONT_SIZE_EXCEEDED'], $config['max_' . $this->mode . '_font_size']);
+ $this->warn_msg[] = $user->lang('MAX_FONT_SIZE_EXCEEDED', (int) $config['max_' . $this->mode . '_font_size']);
return '[size=' . $stx . ']' . $in . '[/size]';
}
@@ -319,13 +319,13 @@ class bbcode_firstpass extends bbcode
if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $stats[1])
{
$error = true;
- $this->warn_msg[] = sprintf($user->lang['MAX_IMG_HEIGHT_EXCEEDED'], $config['max_' . $this->mode . '_img_height']);
+ $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])
{
$error = true;
- $this->warn_msg[] = sprintf($user->lang['MAX_IMG_WIDTH_EXCEEDED'], $config['max_' . $this->mode . '_img_width']);
+ $this->warn_msg[] = $user->lang('MAX_IMG_WIDTH_EXCEEDED', (int) $config['max_' . $this->mode . '_img_width']);
}
}
}
@@ -374,13 +374,13 @@ class bbcode_firstpass extends bbcode
if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $height)
{
$error = true;
- $this->warn_msg[] = sprintf($user->lang['MAX_FLASH_HEIGHT_EXCEEDED'], $config['max_' . $this->mode . '_img_height']);
+ $this->warn_msg[] = $user->lang('MAX_FLASH_HEIGHT_EXCEEDED', (int) $config['max_' . $this->mode . '_img_height']);
}
if ($config['max_' . $this->mode . '_img_width'] && $config['max_' . $this->mode . '_img_width'] < $width)
{
$error = true;
- $this->warn_msg[] = sprintf($user->lang['MAX_FLASH_WIDTH_EXCEEDED'], $config['max_' . $this->mode . '_img_width']);
+ $this->warn_msg[] = $user->lang('MAX_FLASH_WIDTH_EXCEEDED', (int) $config['max_' . $this->mode . '_img_width']);
}
}
@@ -772,7 +772,7 @@ class bbcode_firstpass extends bbcode
if ($config['max_quote_depth'] && sizeof($close_tags) >= $config['max_quote_depth'])
{
// there are too many nested quotes
- $error_ary['quote_depth'] = sprintf($user->lang['QUOTE_DEPTH_EXCEEDED'], $config['max_quote_depth']);
+ $error_ary['quote_depth'] = $user->lang('QUOTE_DEPTH_EXCEEDED', (int) $config['max_quote_depth']);
$out .= $buffer . $tok;
$tok = '[]';
@@ -1117,7 +1117,7 @@ class parse_message extends bbcode_firstpass
// Maximum message length check. 0 disables this check completely.
if ((int) $config['max_' . $mode . '_chars'] > 0 && $message_length > (int) $config['max_' . $mode . '_chars'])
{
- $this->warn_msg[] = sprintf($user->lang['TOO_MANY_CHARS_' . strtoupper($mode)], $message_length, (int) $config['max_' . $mode . '_chars']);
+ $this->warn_msg[] = $user->lang('TOO_MANY_CHARS_' . strtoupper($mode), $message_length, (int) $config['max_' . $mode . '_chars']);
return (!$update_this_message) ? $return_message : $this->warn_msg;
}
@@ -1126,7 +1126,7 @@ class parse_message extends bbcode_firstpass
{
if (!$message_length || $message_length < (int) $config['min_post_chars'])
{
- $this->warn_msg[] = (!$message_length) ? $user->lang['TOO_FEW_CHARS'] : sprintf($user->lang['TOO_FEW_CHARS_LIMIT'], $message_length, (int) $config['min_post_chars']);
+ $this->warn_msg[] = (!$message_length) ? $user->lang['TOO_FEW_CHARS'] : $user->lang('TOO_FEW_CHARS_LIMIT', $message_length, (int) $config['min_post_chars']);
return (!$update_this_message) ? $return_message : $this->warn_msg;
}
}
@@ -1445,7 +1445,7 @@ class parse_message extends bbcode_firstpass
}
else
{
- $error[] = sprintf($user->lang['TOO_MANY_ATTACHMENTS'], $cfg['max_attachments']);
+ $error[] = $user->lang('TOO_MANY_ATTACHMENTS', (int) $cfg['max_attachments']);
}
}
@@ -1536,7 +1536,7 @@ class parse_message extends bbcode_firstpass
}
else
{
- $error[] = sprintf($user->lang['TOO_MANY_ATTACHMENTS'], $cfg['max_attachments']);
+ $error[] = $user->lang('TOO_MANY_ATTACHMENTS', (int) $cfg['max_attachments']);
}
}
}
diff --git a/phpBB/includes/search/search.php b/phpBB/includes/search/base.php
index 7c34ce9ff6..bb63957aba 100644
--- a/phpBB/includes/search/search.php
+++ b/phpBB/includes/search/base.php
@@ -24,12 +24,12 @@ define('SEARCH_RESULT_IN_CACHE', 1);
define('SEARCH_RESULT_INCOMPLETE', 2);
/**
-* search_backend
+* phpbb_search_base
* optional base class for search plugins providing simple caching based on ACM
* and functions to retrieve ignore_words and synonyms
* @package search
*/
-class search_backend
+class phpbb_search_base
{
var $ignore_words = array();
var $match_synonym = array();
diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php
index 827205f20d..4214de3d97 100644
--- a/phpBB/includes/search/fulltext_mysql.php
+++ b/phpBB/includes/search/fulltext_mysql.php
@@ -17,16 +17,11 @@ if (!defined('IN_PHPBB'))
}
/**
-* @ignore
-*/
-include_once($phpbb_root_path . 'includes/search/search.' . $phpEx);
-
-/**
* fulltext_mysql
* Fulltext search for MySQL
* @package search
*/
-class fulltext_mysql extends search_backend
+class phpbb_search_fulltext_mysql extends phpbb_search_base
{
var $stats = array();
var $word_length = array();
@@ -36,7 +31,7 @@ class fulltext_mysql extends search_backend
var $pcre_properties = false;
var $mbstring_regex = false;
- function fulltext_mysql(&$error)
+ public function __construct(&$error)
{
global $config;
@@ -58,6 +53,16 @@ class fulltext_mysql extends search_backend
}
/**
+ * Returns the name of this search backend to be displayed to administrators
+ *
+ * @return string Name
+ */
+ public function get_name()
+ {
+ return 'MySQL Fulltext';
+ }
+
+ /**
* Checks for correct MySQL version and stores min/max word length in the config
*/
function init()
diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php
index e749e86f68..a335ddab6e 100644
--- a/phpBB/includes/search/fulltext_native.php
+++ b/phpBB/includes/search/fulltext_native.php
@@ -17,16 +17,11 @@ if (!defined('IN_PHPBB'))
}
/**
-* @ignore
-*/
-include_once($phpbb_root_path . 'includes/search/search.' . $phpEx);
-
-/**
* fulltext_native
* phpBB's own db driven fulltext search, version 2
* @package search
*/
-class fulltext_native extends search_backend
+class phpbb_search_fulltext_native extends phpbb_search_base
{
var $stats = array();
var $word_length = array();
@@ -41,10 +36,8 @@ class fulltext_native extends search_backend
* Initialises the fulltext_native search backend with min/max word length and makes sure the UTF-8 normalizer is loaded.
*
* @param boolean|string &$error is passed by reference and should either be set to false on success or an error message on failure.
- *
- * @access public
*/
- function fulltext_native(&$error)
+ public function __construct(&$error)
{
global $phpbb_root_path, $phpEx, $config;
@@ -58,11 +51,20 @@ class fulltext_native extends search_backend
include($phpbb_root_path . 'includes/utf/utf_normalizer.' . $phpEx);
}
-
$error = false;
}
/**
+ * Returns the name of this search backend to be displayed to administrators
+ *
+ * @return string Name
+ */
+ public function get_name()
+ {
+ return 'phpBB Native Fulltext';
+ }
+
+ /**
* This function fills $this->search_query with the cleaned user search query.
*
* If $terms is 'any' then the words will be extracted from the search query
diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php
index bd2257c139..fcbe8aed2c 100644
--- a/phpBB/includes/session.php
+++ b/phpBB/includes/session.php
@@ -1821,6 +1821,9 @@ class user extends session
* This function/functionality is inspired by SHS` and Ashe.
*
* Example call: <samp>$user->lang('NUM_POSTS_IN_QUEUE', 1);</samp>
+ *
+ * If the first parameter is an array, the elements are used as keys and subkeys to get the language entry:
+ * Example: <samp>$user->lang(array('datetime', 'AGO'), 1)</samp> uses $user->lang['datetime']['AGO'] as language entry.
*/
function lang()
{
@@ -1859,6 +1862,11 @@ class user extends session
$args[0] = $lang;
return call_user_func_array('sprintf', $args);
}
+ else if (sizeof($lang) == 0)
+ {
+ // If the language entry is an empty array, we just return the language key
+ return $args[0];
+ }
// It is an array... now handle different nullar/singular/plural forms
$key_found = false;
@@ -1866,20 +1874,40 @@ class user extends session
// We now get the first number passed and will select the key based upon this number
for ($i = 1, $num_args = sizeof($args); $i < $num_args; $i++)
{
- if (is_int($args[$i]))
+ if (is_int($args[$i]) || is_float($args[$i]))
{
- $numbers = array_keys($lang);
-
- foreach ($numbers as $num)
+ if ($args[$i] == 0 && isset($lang[0]))
+ {
+ // We allow each translation using plural forms to specify a version for the case of 0 things,
+ // so that "0 users" may be displayed as "No users".
+ $key_found = 0;
+ break;
+ }
+ else
{
- if ($num > $args[$i])
+ $use_plural_form = $this->get_plural_form($args[$i]);
+ if (isset($lang[$use_plural_form]))
{
- break;
+ // The key we should use exists, so we use it.
+ $key_found = $use_plural_form;
}
+ else
+ {
+ // If the key we need to use does not exist, we fall back to the previous one.
+ $numbers = array_keys($lang);
- $key_found = $num;
+ foreach ($numbers as $num)
+ {
+ if ($num > $use_plural_form)
+ {
+ break;
+ }
+
+ $key_found = $num;
+ }
+ }
+ break;
}
- break;
}
}
@@ -1896,11 +1924,31 @@ class user extends session
}
/**
+ * Determine which plural form we should use.
+ * For some languages this is not as simple as for English.
+ *
+ * @param $number int|float The number we want to get the plural case for. Float numbers are floored.
+ * @param $force_rule mixed False to use the plural rule of the language package
+ * or an integer to force a certain plural rule
+ * @return int The plural-case we need to use for the number plural-rule combination
+ */
+ function get_plural_form($number, $force_rule = false)
+ {
+ $number = (int) $number;
+
+ // Default to English system
+ $plural_rule = ($force_rule !== false) ? $force_rule : ((isset($this->lang['PLURAL_RULE'])) ? $this->lang['PLURAL_RULE'] : 1);
+
+ return phpbb_get_plural_form($plural_rule, $number);
+ }
+
+ /**
* Add Language Items - use_db and use_help are assigned where needed (only use them to force inclusion)
*
* @param mixed $lang_set specifies the language entries to include
* @param bool $use_db internal variable for recursion, do not use
* @param bool $use_help internal variable for recursion, do not use
+ * @param string $ext_name The extension to load language from, or empty for core files
*
* Examples:
* <code>
@@ -1911,7 +1959,7 @@ class user extends session
* $lang_set = array('help' => 'faq', 'db' => array('help:faq', 'posting'))
* </code>
*/
- function add_lang($lang_set, $use_db = false, $use_help = false)
+ function add_lang($lang_set, $use_db = false, $use_help = false, $ext_name = '')
{
global $phpEx;
@@ -1925,36 +1973,54 @@ class user extends session
if ($key == 'db')
{
- $this->add_lang($lang_file, true, $use_help);
+ $this->add_lang($lang_file, true, $use_help, $ext_name);
}
else if ($key == 'help')
{
- $this->add_lang($lang_file, $use_db, true);
+ $this->add_lang($lang_file, $use_db, true, $ext_name);
}
else if (!is_array($lang_file))
{
- $this->set_lang($this->lang, $this->help, $lang_file, $use_db, $use_help);
+ $this->set_lang($this->lang, $this->help, $lang_file, $use_db, $use_help, $ext_name);
}
else
{
- $this->add_lang($lang_file, $use_db, $use_help);
+ $this->add_lang($lang_file, $use_db, $use_help, $ext_name);
}
}
unset($lang_set);
}
else if ($lang_set)
{
- $this->set_lang($this->lang, $this->help, $lang_set, $use_db, $use_help);
+ $this->set_lang($this->lang, $this->help, $lang_set, $use_db, $use_help, $ext_name);
}
}
/**
+ * Add Language Items from an extension - use_db and use_help are assigned where needed (only use them to force inclusion)
+ *
+ * @param string $ext_name The extension to load language from, or empty for core files
+ * @param mixed $lang_set specifies the language entries to include
+ * @param bool $use_db internal variable for recursion, do not use
+ * @param bool $use_help internal variable for recursion, do not use
+ */
+ function add_lang_ext($ext_name, $lang_set, $use_db = false, $use_help = false)
+ {
+ if ($ext_name === '/')
+ {
+ $ext_name = '';
+ }
+
+ $this->add_lang($lang_set, $use_db, $use_help, $ext_name);
+ }
+
+ /**
* Set language entry (called by add_lang)
* @access private
*/
- function set_lang(&$lang, &$help, $lang_file, $use_db = false, $use_help = false)
+ function set_lang(&$lang, &$help, $lang_file, $use_db = false, $use_help = false, $ext_name = '')
{
- global $phpEx;
+ global $phpbb_root_path, $phpEx;
// Make sure the language name is set (if the user setup did not happen it is not set)
if (!$this->lang_name)
@@ -1970,11 +2036,32 @@ class user extends session
{
if ($use_help && strpos($lang_file, '/') !== false)
{
- $language_filename = $this->lang_path . $this->lang_name . '/' . substr($lang_file, 0, stripos($lang_file, '/') + 1) . 'help_' . substr($lang_file, stripos($lang_file, '/') + 1) . '.' . $phpEx;
+ $filename = dirname($lang_file) . '/help_' . basename($lang_file);
+ }
+ else
+ {
+ $filename = (($use_help) ? 'help_' : '') . $lang_file;
+ }
+
+ if ($ext_name)
+ {
+ global $phpbb_extension_manager;
+ $ext_path = $phpbb_extension_manager->get_extension_path($ext_name, true);
+
+ $lang_path = $ext_path . 'language/';
+ }
+ else
+ {
+ $lang_path = $this->lang_path;
+ }
+
+ if (strpos($phpbb_root_path . $filename, $lang_path . $this->lang_name . '/') === 0)
+ {
+ $language_filename = $phpbb_root_path . $filename;
}
else
{
- $language_filename = $this->lang_path . $this->lang_name . '/' . (($use_help) ? 'help_' : '') . $lang_file . '.' . $phpEx;
+ $language_filename = $lang_path . $this->lang_name . '/' . $filename . '.' . $phpEx;
}
if (!file_exists($language_filename))
@@ -1984,24 +2071,24 @@ class user extends session
if ($this->lang_name == 'en')
{
// The user's selected language is missing the file, the board default's language is missing the file, and the file doesn't exist in /en.
- $language_filename = str_replace($this->lang_path . 'en', $this->lang_path . $this->data['user_lang'], $language_filename);
+ $language_filename = str_replace($lang_path . 'en', $lang_path . $this->data['user_lang'], $language_filename);
trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR);
}
else if ($this->lang_name == basename($config['default_lang']))
{
// Fall back to the English Language
$this->lang_name = 'en';
- $this->set_lang($lang, $help, $lang_file, $use_db, $use_help);
+ $this->set_lang($lang, $help, $lang_file, $use_db, $use_help, $ext_name);
}
else if ($this->lang_name == $this->data['user_lang'])
{
// Fall back to the board default language
$this->lang_name = basename($config['default_lang']);
- $this->set_lang($lang, $help, $lang_file, $use_db, $use_help);
+ $this->set_lang($lang, $help, $lang_file, $use_db, $use_help, $ext_name);
}
// Reset the lang name
- $this->lang_name = (file_exists($this->lang_path . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']);
+ $this->lang_name = (file_exists($lang_path . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']);
return;
}
@@ -2059,9 +2146,9 @@ class user extends session
// Zone offset
$zone_offset = $this->timezone + $this->dst;
- // Show date <= 1 hour ago as 'xx min ago' but not greater than 60 seconds in the future
+ // Show date < 1 hour ago as 'xx min ago' but not greater than 60 seconds in the future
// A small tolerence is given for times in the future but in the same minute are displayed as '< than a minute ago'
- if ($delta <= 3600 && $delta > -60 && ($delta >= -5 || (($now / 60) % 60) == (($gmepoch / 60) % 60)) && $date_cache[$format]['is_short'] !== false && !$forcedate && isset($this->lang['datetime']['AGO']))
+ if ($delta < 3600 && $delta > -60 && ($delta >= -5 || (($now / 60) % 60) == (($gmepoch / 60) % 60)) && $date_cache[$format]['is_short'] !== false && !$forcedate && isset($this->lang['datetime']['AGO']))
{
return $this->lang(array('datetime', 'AGO'), max(0, (int) floor($delta / 60)));
}
diff --git a/phpBB/includes/startup.php b/phpBB/includes/startup.php
index ca9665da29..bbe2f127f1 100644
--- a/phpBB/includes/startup.php
+++ b/phpBB/includes/startup.php
@@ -97,8 +97,8 @@ function deregister_globals()
unset($input);
}
-// If we are on PHP >= 6.0.0 we do not need some code
-if (version_compare(PHP_VERSION, '6.0.0-dev', '>='))
+// Register globals and magic quotes have been dropped in PHP 5.4
+if (version_compare(PHP_VERSION, '5.4.0-dev', '>='))
{
/**
* @ignore
diff --git a/phpBB/includes/template/extension_path_provider.php b/phpBB/includes/template/extension_path_provider.php
new file mode 100644
index 0000000000..0feeaafed0
--- /dev/null
+++ b/phpBB/includes/template/extension_path_provider.php
@@ -0,0 +1,130 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Provides a template locator with core template paths and extension template paths
+*
+* Finds installed template paths and makes them available to the locator.
+*
+* @package phpBB3
+*/
+class phpbb_template_extension_path_provider extends phpbb_extension_provider implements phpbb_template_path_provider_interface
+{
+ /**
+ * Optional prefix for template paths searched within extensions.
+ *
+ * Empty by default. Relative to the extension directory. As an example, it
+ * could be adm/ for admin templates.
+ *
+ * @var string
+ */
+ protected $ext_dir_prefix = '';
+
+ /**
+ * A provider of paths to be searched for templates
+ * @var phpbb_template_path_provider
+ */
+ protected $base_path_provider;
+
+ /**
+ * Constructor stores extension manager
+ *
+ * @param phpbb_extension_manager $extension_manager phpBB extension manager
+ * @param phpbb_template_path_provider $base_path_provider A simple path provider
+ * to provide paths to be located in extensions
+ */
+ public function __construct(phpbb_extension_manager $extension_manager, phpbb_template_path_provider $base_path_provider)
+ {
+ parent::__construct($extension_manager);
+ $this->base_path_provider = $base_path_provider;
+ }
+
+ /**
+ * Sets a prefix for template paths searched within extensions.
+ *
+ * The prefix is inserted between the extension's path e.g. ext/foo/ and
+ * the looked up template path, e.g. styles/bar/template/some.html. So it
+ * should not have a leading slash, but should have a trailing slash.
+ *
+ * @param string $ext_dir_prefix The prefix including trailing slash
+ * @return null
+ */
+ public function set_ext_dir_prefix($ext_dir_prefix)
+ {
+ $this->ext_dir_prefix = $ext_dir_prefix;
+ }
+
+ /**
+ * Finds template paths using the extension manager
+ *
+ * Locates a path (e.g. styles/prosilver/template/) in all active extensions.
+ * Then appends the core template paths based in the current working
+ * directory.
+ *
+ * @return array List of template paths
+ */
+ public function find()
+ {
+ $directories = array();
+
+ $finder = $this->extension_manager->get_finder();
+ foreach ($this->base_path_provider as $path)
+ {
+ if ($path && !phpbb_is_absolute($path))
+ {
+ $directories = array_merge($directories, $finder
+ ->directory('/' . $this->ext_dir_prefix . $path)
+ ->get_directories()
+ );
+ }
+ }
+
+ foreach ($this->base_path_provider as $path)
+ {
+ $directories[] = $path;
+ }
+
+ return $directories;
+ }
+
+ /**
+ * Overwrites the current template names and paths
+ *
+ * @param array $templates An associative map from template names to paths.
+ * The first element is the main template.
+ * If the path is false, it will be generated from
+ * the supplied name.
+ * @param string $style_root_path The root directory for styles identified
+ * by name only.
+ * @return null
+ */
+ public function set_templates(array $templates, $style_root_path)
+ {
+ $this->base_path_provider->set_templates($templates, $style_root_path);
+ $this->items = null;
+ }
+
+ /**
+ * Retrieves the path to the main template passed into set_templates()
+ *
+ * @return string Main template path
+ */
+ public function get_main_template_path()
+ {
+ return $this->base_path_provider->get_main_template_path();
+ }
+}
diff --git a/phpBB/includes/template/locator.php b/phpBB/includes/template/locator.php
index 35e33bb9e6..ee9bfa7d48 100644
--- a/phpBB/includes/template/locator.php
+++ b/phpBB/includes/template/locator.php
@@ -28,62 +28,70 @@ if (!defined('IN_PHPBB'))
class phpbb_template_locator
{
/**
- * @var string Path to directory that templates are stored in.
+ * Paths to directories that templates are stored in.
+ * @var array
*/
- private $root = '';
+ private $roots = array();
/**
- * @var string Path to parent/fallback template directory.
+ * Index of the main template in the roots array
+ * @var int
*/
- private $inherit_root = '';
+ private $main_root_id = 0;
/**
- * @var array Map from handles to source template file paths.
+ * Map from root index to handles to source template file paths.
* Normally it only contains paths for handles that are used
* (or are likely to be used) by the page being rendered and not
* all templates that exist on the filesystem.
+ * @var array
*/
private $files = array();
/**
- * @var array Map from handles to source template file names.
+ * Map from handles to source template file names.
* Covers the same data as $files property but maps to basenames
* instead of paths.
+ * @var array
*/
private $filenames = array();
/**
- * @var array Map from handles to parent/fallback source template
- * file paths. Covers the same data as $files.
+ * Set main template location (must have been added through set_paths first).
+ *
+ * @param string $template_path Path to template directory
+ * @return null
*/
- private $files_inherit = array();
+ public function set_main_template($template)
+ {
+ $this->main_root_id = array_search($template, $this->roots, true);
+ }
/**
- * Set custom template location (able to use directory outside of phpBB).
+ * Sets the list of template paths
*
- * Note: Templates are still compiled to phpBB's cache directory.
+ * These paths will be searched for template files in the provided order.
+ * Paths may be outside of phpBB, but templates loaded from these paths
+ * will still be cached.
*
- * @param string $template_path Path to template directory
- * @param string|bool $fallback_template_path Path to fallback template, or false to disable fallback
+ * @param array $template_paths An array of paths to template directories
+ * @return null
*/
- public function set_custom_template($template_path, $fallback_template_path = false)
+ public function set_paths($template_paths)
{
- // Make sure $template_path has no ending slash
- if (substr($template_path, -1) == '/')
- {
- $template_path = substr($template_path, 0, -1);
- }
-
- $this->root = $template_path;
+ $this->roots = array();
+ $this->files = array();
+ $this->filenames = array();
+ $this->main_root_id = 0;
- if ($fallback_template_path !== false)
+ foreach ($template_paths as $path)
{
- if (substr($fallback_template_path, -1) == '/')
+ // Make sure $path has no ending slash
+ if (substr($path, -1) === '/')
{
- $fallback_template_path = substr($fallback_template_path, 0, -1);
+ $path = substr($path, 0, -1);
}
-
- $this->inherit_root = $fallback_template_path;
+ $this->roots[] = $path;
}
}
@@ -103,11 +111,10 @@ class phpbb_template_locator
}
$this->filename[$handle] = $filename;
- $this->files[$handle] = $this->root . '/' . $filename;
- if ($this->inherit_root)
+ foreach ($this->roots as $root_index => $root)
{
- $this->files_inherit[$handle] = $this->inherit_root . '/' . $filename;
+ $this->files[$root_index][$handle] = $root . '/' . $filename;
}
}
}
@@ -154,12 +161,12 @@ class phpbb_template_locator
public function get_virtual_source_file_for_handle($handle)
{
// If we don't have a file assigned to this handle, die.
- if (!isset($this->files[$handle]))
+ if (!isset($this->files[$this->main_root_id][$handle]))
{
trigger_error("template locator: No file specified for handle $handle", E_USER_ERROR);
}
- $source_file = $this->files[$handle];
+ $source_file = $this->files[$this->main_root_id][$handle];
return $source_file;
}
@@ -182,30 +189,26 @@ class phpbb_template_locator
public function get_source_file_for_handle($handle)
{
// If we don't have a file assigned to this handle, die.
- if (!isset($this->files[$handle]))
+ if (!isset($this->files[$this->main_root_id][$handle]))
{
trigger_error("template locator: No file specified for handle $handle", E_USER_ERROR);
}
- $source_file = $this->files[$handle];
+ // locate a source file that exists
+ $source_file = $this->files[0][$handle];
+ $tried = $source_file;
+ for ($i = 1, $n = count($this->roots); $i < $n && !file_exists($source_file); $i++)
+ {
+ $source_file = $this->files[$i][$handle];
+ $tried .= ', ' . $source_file;
+ }
- // Try and open template for reading
+ // search failed
if (!file_exists($source_file))
{
- if (isset($this->files_inherit[$handle]) && $this->files_inherit[$handle])
- {
- $parent_source_file = $this->files_inherit[$handle];
- if (!file_exists($parent_source_file))
- {
- trigger_error("template locator: Neither $source_file nor $parent_source_file exist", E_USER_ERROR);
- }
- $source_file = $parent_source_file;
- }
- else
- {
- trigger_error("template locator: File $source_file does not exist", E_USER_ERROR);
- }
+ trigger_error("template locator: File for handle $handle does not exist. Could not find: $tried", E_USER_ERROR);
}
+
return $source_file;
}
}
diff --git a/phpBB/includes/template/path_provider.php b/phpBB/includes/template/path_provider.php
new file mode 100644
index 0000000000..c243d1b115
--- /dev/null
+++ b/phpBB/includes/template/path_provider.php
@@ -0,0 +1,102 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Provides a template locator with paths
+*
+* Finds installed template paths and makes them available to the locator.
+*
+* @package phpBB3
+*/
+class phpbb_template_path_provider implements IteratorAggregate, phpbb_template_path_provider_interface
+{
+ protected $main_template_name = '';
+ protected $paths = array();
+
+ /**
+ * Ignores the extension dir prefix
+ *
+ * @param string $ext_dir_prefix The prefix including trailing slash
+ * @return null
+ */
+ public function set_ext_dir_prefix($ext_dir_prefix)
+ {
+ }
+
+ /**
+ * Overwrites the current template names and paths
+ *
+ * The first element of the passed templates map, is considered the main
+ * template and can be retrieved through get_main_template_path().
+ *
+ * @param array $templates An associative map from template names to paths.
+ * The first element is the main template.
+ * If the path is false, it will be generated from
+ * the supplied name.
+ * @param string $style_root_path The root directory for styles identified
+ * by name only.
+ * @return null
+ */
+ public function set_templates(array $templates, $style_root_path)
+ {
+ $this->paths = array();
+
+ foreach ($templates as $name => $path)
+ {
+ if (!$path)
+ {
+ $path = $style_root_path . $this->template_root_for_style($name);
+ }
+
+ $this->paths[] = $path;
+ }
+
+ $this->main_template_path = $this->paths[0];
+ }
+
+ /**
+ * Retrieves the path to the main template passed into set_templates()
+ *
+ * @return string Main template path
+ */
+ public function get_main_template_path()
+ {
+ return $this->main_template_path;
+ }
+
+ /**
+ * Converts a style name to relative (to board root or extension) path to
+ * the style's template files.
+ *
+ * @param $style_name string Style name
+ * @return string Path to style template files
+ */
+ private function template_root_for_style($style_name)
+ {
+ return 'styles/' . $style_name . '/template';
+ }
+
+ /**
+ * Retrieve an iterator over all template paths
+ *
+ * @return ArrayIterator An iterator for the array of template paths
+ */
+ public function getIterator()
+ {
+ return new ArrayIterator($this->paths);
+ }
+}
diff --git a/phpBB/includes/template/path_provider_interface.php b/phpBB/includes/template/path_provider_interface.php
new file mode 100644
index 0000000000..822393a91e
--- /dev/null
+++ b/phpBB/includes/template/path_provider_interface.php
@@ -0,0 +1,54 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Provides a template locator with paths
+*
+* Finds installed template paths and makes them available to the locator.
+*
+* @package phpBB3
+*/
+interface phpbb_template_path_provider_interface extends Traversable
+{
+ /**
+ * Defines a prefix to use for template paths in extensions
+ *
+ * @param string $ext_dir_prefix The prefix including trailing slash
+ * @return null
+ */
+ public function set_ext_dir_prefix($ext_dir_prefix);
+
+ /**
+ * Overwrites the current template names and paths
+ *
+ * @param array $templates An associative map from template names to paths.
+ * The first element is the main template.
+ * If the path is false, it will be generated from
+ * the supplied name.
+ * @param string $style_root_path The root directory for styles identified
+ * by name only.
+ * @return null
+ */
+ public function set_templates(array $templates, $style_root_path);
+
+ /**
+ * Retrieves the path to the main template passed into set_templates()
+ *
+ * @return string Main template path
+ */
+ public function get_main_template_path();
+}
diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php
index ec5fbe2829..228ea93513 100644
--- a/phpBB/includes/template/template.php
+++ b/phpBB/includes/template/template.php
@@ -63,24 +63,33 @@ class phpbb_template
private $user;
/**
- * @var locator template locator
+ * Template locator
+ * @var phpbb_template_locator
*/
private $locator;
/**
+ * Template path provider
+ * @var phpbb_template_path_provider
+ */
+ private $provider;
+
+ /**
* Constructor.
*
* @param string $phpbb_root_path phpBB root path
* @param user $user current user
* @param phpbb_template_locator $locator template locator
+ * @param phpbb_template_path_provider $provider template path provider
*/
- public function __construct($phpbb_root_path, $phpEx, $config, $user, phpbb_template_locator $locator)
+ public function __construct($phpbb_root_path, $phpEx, $config, $user, phpbb_template_locator $locator, phpbb_template_path_provider_interface $provider)
{
$this->phpbb_root_path = $phpbb_root_path;
$this->phpEx = $phpEx;
$this->config = $config;
$this->user = $user;
$this->locator = $locator;
+ $this->provider = $provider;
}
/**
@@ -88,25 +97,21 @@ class phpbb_template
*/
public function set_template()
{
- $style_name = $this->user->theme['template_path'];
+ $template_name = $this->user->theme['template_path'];
+ $fallback_name = ($this->user->theme['template_inherits_id']) ? $this->user->theme['template_inherit_path'] : false;
- $relative_template_root = $this->relative_template_root_for_style($style_name);
- $template_root = $this->phpbb_root_path . $relative_template_root;
- if (!file_exists($template_root))
- {
- trigger_error('template locator: Template path could not be found: ' . $relative_template_root, E_USER_ERROR);
- }
-
- if ($this->user->theme['template_inherits_id'])
- {
- $fallback_template_path = $this->phpbb_root_path . $this->relative_template_root_for_style($this->user->theme['template_inherit_path']);
- }
- else
- {
- $fallback_template_path = null;
- }
+ return $this->set_custom_template(false, $template_name, false, $fallback_name);
+ }
- return $this->set_custom_template($template_root, $style_name, $fallback_template_path);
+ /**
+ * Defines a prefix to use for template paths in extensions
+ *
+ * @param string $ext_dir_prefix The prefix including trailing slash
+ * @return null
+ */
+ public function set_ext_dir_prefix($ext_dir_prefix)
+ {
+ $this->provider->set_ext_dir_prefix($ext_dir_prefix);
}
/**
@@ -117,12 +122,22 @@ class phpbb_template
* @param string $template_path Path to template directory
* @param string $template_name Name of template
* @param string $fallback_template_path Path to fallback template
+ * @param string $fallback_template_name Name of fallback template
*/
- public function set_custom_template($template_path, $style_name, $fallback_template_path = false)
+ public function set_custom_template($template_path, $template_name, $fallback_template_path = false, $fallback_template_name = false)
{
- $this->locator->set_custom_template($template_path, $fallback_template_path);
+ $templates = array($template_name => $template_path);
+
+ if ($fallback_template_path !== false)
+ {
+ $templates[$fallback_template_name] = $fallback_template_path;
+ }
+
+ $this->provider->set_templates($templates, $this->phpbb_root_path);
+ $this->locator->set_paths($this->provider);
+ $this->locator->set_main_template($this->provider->get_main_template_path());
- $this->cachepath = $this->phpbb_root_path . 'cache/tpl_' . str_replace('_', '-', $style_name) . '_';
+ $this->cachepath = $this->phpbb_root_path . 'cache/tpl_' . str_replace('_', '-', $template_name) . '_';
$this->context = new phpbb_template_context();
@@ -130,18 +145,6 @@ class phpbb_template
}
/**
- * Converts a style name to relative (to board root) path to
- * the style's template files.
- *
- * @param $style_name string Style name
- * @return string Path to style template files
- */
- private function relative_template_root_for_style($style_name)
- {
- return 'styles/' . $style_name . '/template';
- }
-
- /**
* Sets the template filenames for handles.
*
* @param array $filname_array Should be a hash of handle => filename pairs.
diff --git a/phpBB/includes/ucp/ucp_activate.php b/phpBB/includes/ucp/ucp_activate.php
index 34b0b6d879..e19451191c 100644
--- a/phpBB/includes/ucp/ucp_activate.php
+++ b/phpBB/includes/ucp/ucp_activate.php
@@ -117,10 +117,7 @@ class ucp_activate
$messenger->to($user_row['user_email'], $user_row['username']);
- $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
- $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
- $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
- $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
+ $messenger->anti_abuse_headers($config, $user);
$messenger->assign_vars(array(
'USERNAME' => htmlspecialchars_decode($user_row['username']))
diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php
index 676c0a8ef0..f2e2e616b7 100644
--- a/phpBB/includes/ucp/ucp_groups.php
+++ b/phpBB/includes/ucp/ucp_groups.php
@@ -194,47 +194,43 @@ class ucp_groups
if ($group_row[$group_id]['group_type'] == GROUP_FREE)
{
group_user_add($group_id, $user->data['user_id']);
-
- $email_template = 'group_added';
}
else
{
group_user_add($group_id, $user->data['user_id'], false, false, false, 0, 1);
- $email_template = 'group_request';
- }
+ include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ $messenger = new messenger();
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
- $messenger = new messenger();
+ $sql = 'SELECT u.username, u.username_clean, u.user_email, u.user_notify_type, u.user_jabber, u.user_lang
+ FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . " u
+ WHERE ug.user_id = u.user_id
+ AND ug.group_leader = 1
+ AND ug.group_id = $group_id";
+ $result = $db->sql_query($sql);
- $sql = 'SELECT u.username, u.username_clean, u.user_email, u.user_notify_type, u.user_jabber, u.user_lang
- FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . ' u
- WHERE ug.user_id = u.user_id
- AND ' . (($group_row[$group_id]['group_type'] == GROUP_FREE) ? "ug.user_id = {$user->data['user_id']}" : 'ug.group_leader = 1') . "
- AND ug.group_id = $group_id";
- $result = $db->sql_query($sql);
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $messenger->template('group_request', $row['user_lang']);
- while ($row = $db->sql_fetchrow($result))
- {
- $messenger->template($email_template, $row['user_lang']);
+ $messenger->to($row['user_email'], $row['username']);
+ $messenger->im($row['user_jabber'], $row['username']);
- $messenger->to($row['user_email'], $row['username']);
- $messenger->im($row['user_jabber'], $row['username']);
+ $messenger->assign_vars(array(
+ 'USERNAME' => htmlspecialchars_decode($row['username']),
+ 'GROUP_NAME' => htmlspecialchars_decode($group_row[$group_id]['group_name']),
+ 'REQUEST_USERNAME' => $user->data['username'],
- $messenger->assign_vars(array(
- 'USERNAME' => htmlspecialchars_decode($row['username']),
- 'GROUP_NAME' => htmlspecialchars_decode($group_row[$group_id]['group_name']),
- 'REQUEST_USERNAME' => $user->data['username'],
+ 'U_PENDING' => generate_board_url() . "/ucp.$phpEx?i=groups&mode=manage&action=list&g=$group_id",
+ 'U_GROUP' => generate_board_url() . "/memberlist.$phpEx?mode=group&g=$group_id")
+ );
- 'U_PENDING' => generate_board_url() . "/ucp.$phpEx?i=groups&mode=manage&action=list&g=$group_id",
- 'U_GROUP' => generate_board_url() . "/memberlist.$phpEx?mode=group&g=$group_id")
- );
+ $messenger->send($row['user_notify_type']);
+ }
+ $db->sql_freeresult($result);
- $messenger->send($row['user_notify_type']);
+ $messenger->save_queue();
}
- $db->sql_freeresult($result);
-
- $messenger->save_queue();
add_log('user', $user->data['user_id'], 'LOG_USER_GROUP_JOIN' . (($group_row[$group_id]['group_type'] == GROUP_FREE) ? '' : '_PENDING'), $group_row[$group_id]['group_name']);
@@ -565,7 +561,7 @@ class ucp_groups
{
if ($data['width'] > $config['avatar_max_width'] || $data['height'] > $config['avatar_max_height'])
{
- $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $data['width'], $data['height']);
+ $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
}
}
@@ -575,7 +571,7 @@ class ucp_groups
{
if ($data['width'] < $config['avatar_min_width'] || $data['height'] < $config['avatar_min_height'])
{
- $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $data['width'], $data['height']);
+ $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
}
}
}
@@ -736,7 +732,7 @@ class ucp_groups
'U_SWATCH' => append_sid("{$phpbb_root_path}adm/swatch.$phpEx", 'form=ucp&amp;name=group_colour'),
'S_UCP_ACTION' => $this->u_action . "&amp;action=$action&amp;g=$group_id",
- 'L_AVATAR_EXPLAIN' => sprintf($user->lang['AVATAR_EXPLAIN'], $config['avatar_max_width'], $config['avatar_max_height'], $config['avatar_filesize'] / 1024),
+ 'L_AVATAR_EXPLAIN' => phpbb_avatar_explanation_string(),
));
break;
@@ -1072,7 +1068,7 @@ class ucp_groups
'mode' => $mode,
'action' => $action
);
- confirm_box(false, sprintf($user->lang['GROUP_CONFIRM_ADD_USER' . ((sizeof($name_ary) == 1) ? '' : 'S')], implode(', ', $name_ary)), build_hidden_fields($s_hidden_fields));
+ confirm_box(false, $user->lang('GROUP_CONFIRM_ADD_USERS', sizeof($name_ary), implode(', ', $name_ary)), build_hidden_fields($s_hidden_fields));
}
trigger_error($user->lang['NO_USERS_ADDED'] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $this->u_action . '&amp;action=list&amp;g=' . $group_id . '">', '</a>'));
diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php
index 738da62158..2b8f662bb4 100644
--- a/phpBB/includes/ucp/ucp_main.php
+++ b/phpBB/includes/ucp/ucp_main.php
@@ -194,8 +194,8 @@ class ucp_main
'VISITED' => (empty($last_visit)) ? ' - ' : $user->format_date($last_visit),
'WARNINGS' => ($user->data['user_warnings']) ? $user->data['user_warnings'] : 0,
'POSTS' => ($user->data['user_posts']) ? $user->data['user_posts'] : 0,
- 'POSTS_DAY' => sprintf($user->lang['POST_DAY'], $posts_per_day),
- 'POSTS_PCT' => sprintf($user->lang['POST_PCT'], $percentage),
+ 'POSTS_DAY' => $user->lang('POST_DAY', $posts_per_day),
+ 'POSTS_PCT' => $user->lang('POST_PCT', $percentage),
'OCCUPATION' => (!empty($row['user_occ'])) ? $row['user_occ'] : '',
'INTERESTS' => (!empty($row['user_interests'])) ? $row['user_interests'] : '',
@@ -674,8 +674,8 @@ class ucp_main
$template->assign_vars(array(
'PAGINATION' => generate_pagination($this->u_action, $topics_count, $config['topics_per_page'], $start),
'PAGE_NUMBER' => on_page($topics_count, $config['topics_per_page'], $start),
- 'TOTAL_TOPICS' => ($topics_count == 1) ? $user->lang['VIEW_FORUM_TOPIC'] : sprintf($user->lang['VIEW_FORUM_TOPICS'], $topics_count))
- );
+ 'TOTAL_TOPICS' => $user->lang('VIEW_FORUM_TOPICS', (int) $topics_count),
+ ));
}
if ($mode == 'subscribed')
diff --git a/phpBB/includes/ucp/ucp_pm.php b/phpBB/includes/ucp/ucp_pm.php
index 87d51ca613..6dbf092604 100644
--- a/phpBB/includes/ucp/ucp_pm.php
+++ b/phpBB/includes/ucp/ucp_pm.php
@@ -243,7 +243,7 @@ class ucp_pm
$num_not_moved = $num_removed = 0;
$release = request_var('release', 0);
- if ($user->data['user_new_privmsg'] && $action == 'view_folder')
+ if ($user->data['user_new_privmsg'] && ($action == 'view_folder' || $action == 'view_message'))
{
$return = place_pm_into_folder($global_privmsgs_rules, $release);
$num_not_moved = $return['not_moved'];
@@ -345,8 +345,8 @@ class ucp_pm
'NUM_NOT_MOVED' => $num_not_moved,
'NUM_REMOVED' => $num_removed,
'RELEASE_MESSAGE_INFO' => sprintf($user->lang['RELEASE_MESSAGES'], '<a href="' . $this->u_action . '&amp;folder=' . $folder_id . '&amp;release=1">', '</a>'),
- 'NOT_MOVED_MESSAGES' => ($num_not_moved == 1) ? $user->lang['NOT_MOVED_MESSAGE'] : sprintf($user->lang['NOT_MOVED_MESSAGES'], $num_not_moved),
- 'RULE_REMOVED_MESSAGES' => ($num_removed == 1) ? $user->lang['RULE_REMOVED_MESSAGE'] : sprintf($user->lang['RULE_REMOVED_MESSAGES'], $num_removed),
+ 'NOT_MOVED_MESSAGES' => $user->lang('NOT_MOVED_MESSAGES', (int) $num_not_moved),
+ 'RULE_REMOVED_MESSAGES' => $user->lang('RULE_REMOVED_MESSAGES', (int) $num_removed),
'S_FOLDER_OPTIONS' => $s_folder_options,
'S_TO_FOLDER_OPTIONS' => $s_to_folder_options,
diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php
index 92297c1490..981c95a748 100644
--- a/phpBB/includes/ucp/ucp_pm_compose.php
+++ b/phpBB/includes/ucp/ucp_pm_compose.php
@@ -1053,7 +1053,7 @@ function compose_pm($id, $mode, $action, $user_folders = array())
$template->assign_vars(array(
'L_POST_A' => $page_title,
'L_ICON' => $user->lang['PM_ICON'],
- 'L_MESSAGE_BODY_EXPLAIN' => (intval($config['max_post_chars'])) ? sprintf($user->lang['MESSAGE_BODY_EXPLAIN'], intval($config['max_post_chars'])) : '',
+ 'L_MESSAGE_BODY_EXPLAIN' => $user->lang('MESSAGE_BODY_EXPLAIN', (int) $config['max_post_chars']),
'SUBJECT' => (isset($message_subject)) ? $message_subject : '',
'MESSAGE' => $message_text,
diff --git a/phpBB/includes/ucp/ucp_pm_options.php b/phpBB/includes/ucp/ucp_pm_options.php
index 49c727847a..7f854e422f 100644
--- a/phpBB/includes/ucp/ucp_pm_options.php
+++ b/phpBB/includes/ucp/ucp_pm_options.php
@@ -231,7 +231,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit
// Something went wrong, only partially moved?
if ($num_moved != $folder_row['pm_count'])
{
- trigger_error(sprintf($user->lang['MOVE_PM_ERROR'], $num_moved, $folder_row['pm_count']));
+ trigger_error($user->lang('MOVE_PM_ERROR', (int) $folder_row['pm_count'], $num_moved));
}
break;
@@ -409,7 +409,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit
$folder[PRIVMSGS_INBOX] = array(
'folder_name' => $user->lang['PM_INBOX'],
- 'message_status' => sprintf($user->lang['FOLDER_MESSAGE_STATUS'], $num_messages, $user->data['message_limit'])
+ 'message_status' => $user->lang('FOLDER_MESSAGE_STATUS', (int) $user->data['message_limit'], $num_messages),
);
$sql = 'SELECT folder_id, folder_name, pm_count
@@ -423,7 +423,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit
$num_user_folder++;
$folder[$row['folder_id']] = array(
'folder_name' => $row['folder_name'],
- 'message_status' => sprintf($user->lang['FOLDER_MESSAGE_STATUS'], $row['pm_count'], $user->data['message_limit'])
+ 'message_status' => $user->lang('FOLDER_MESSAGE_STATUS', (int) $user->data['message_limit'], $row['pm_count']),
);
}
$db->sql_freeresult($result);
diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php
index c74574f361..7b850cb436 100644
--- a/phpBB/includes/ucp/ucp_pm_viewfolder.php
+++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php
@@ -455,7 +455,7 @@ function get_pm_from($folder_id, $folder, $user_id)
$template->assign_vars(array(
'PAGINATION' => generate_pagination(append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&amp;mode=view&amp;action=view_folder&amp;f=$folder_id&amp;$u_sort_param"), $pm_count, $config['topics_per_page'], $start),
'PAGE_NUMBER' => on_page($pm_count, $config['topics_per_page'], $start),
- 'TOTAL_MESSAGES' => (($pm_count == 1) ? $user->lang['VIEW_PM_MESSAGE'] : sprintf($user->lang['VIEW_PM_MESSAGES'], $pm_count)),
+ 'TOTAL_MESSAGES' => $user->lang('VIEW_PM_MESSAGES', (int) $pm_count),
'POST_IMG' => (!$auth->acl_get('u_sendpm')) ? $user->img('button_topic_locked', 'POST_PM_LOCKED') : $user->img('button_pm_new', 'POST_NEW_PM'),
diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php
index c9451bd202..0458ff6579 100644
--- a/phpBB/includes/ucp/ucp_pm_viewmessage.php
+++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php
@@ -22,7 +22,7 @@ if (!defined('IN_PHPBB'))
function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
{
global $user, $template, $auth, $db, $cache;
- global $phpbb_root_path, $phpEx, $config;
+ global $phpbb_root_path, $request, $phpEx, $config;
$user->add_lang(array('viewtopic', 'memberlist'));
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index 4572dfd25d..6eb11e6e59 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -79,14 +79,14 @@ class ucp_profile
$error = validate_data($data, $check_ary);
- if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && $data['password_confirm'] != $data['new_password'])
+ if ($auth->acl_get('u_chgemail') && $data['email'] != $user->data['user_email'] && $data['email_confirm'] != $data['email'])
{
- $error[] = 'NEW_PASSWORD_ERROR';
+ $error[] = ($data['email_confirm']) ? 'NEW_EMAIL_ERROR' : 'NEW_EMAIL_CONFIRM_EMPTY';
}
- if (($data['new_password'] || ($auth->acl_get('u_chgemail') && $data['email'] != $user->data['user_email']) || ($data['username'] != $user->data['username'] && $auth->acl_get('u_chgname') && $config['allow_namechange'])) && !phpbb_check_hash($data['cur_password'], $user->data['user_password']))
+ if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && $data['password_confirm'] != $data['new_password'])
{
- $error[] = 'CUR_PASSWORD_ERROR';
+ $error[] = ($data['password_confirm']) ? 'NEW_PASSWORD_ERROR' : 'NEW_PASSWORD_CONFIRM_EMPTY';
}
// Only check the new password against the previous password if there have been no errors
@@ -95,9 +95,9 @@ class ucp_profile
$error[] = 'SAME_PASSWORD_ERROR';
}
- if ($auth->acl_get('u_chgemail') && $data['email'] != $user->data['user_email'] && $data['email_confirm'] != $data['email'])
+ if (!phpbb_check_hash($data['cur_password'], $user->data['user_password']))
{
- $error[] = 'NEW_EMAIL_ERROR';
+ $error[] = ($data['cur_password']) ? 'CUR_PASSWORD_ERROR' : 'CUR_PASSWORD_EMPTY';
}
if (!check_form_key('ucp_reg_details'))
@@ -151,10 +151,7 @@ class ucp_profile
$messenger->to($data['email'], $data['username']);
- $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
- $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
- $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
- $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
+ $messenger->anti_abuse_headers($config, $user);
$messenger->assign_vars(array(
'USERNAME' => htmlspecialchars_decode($data['username']),
@@ -251,8 +248,8 @@ class ucp_profile
'NEW_PASSWORD' => $data['new_password'],
'CUR_PASSWORD' => '',
- 'L_USERNAME_EXPLAIN' => sprintf($user->lang[$config['allow_name_chars'] . '_EXPLAIN'], $config['min_name_chars'], $config['max_name_chars']),
- 'L_CHANGE_PASSWORD_EXPLAIN' => sprintf($user->lang[$config['pass_complex'] . '_EXPLAIN'], $config['min_pass_chars'], $config['max_pass_chars']),
+ 'L_USERNAME_EXPLAIN' => $user->lang($config['allow_name_chars'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_name_chars']), $user->lang('CHARACTERS', (int) $config['max_name_chars'])),
+ 'L_CHANGE_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars']), $user->lang('CHARACTERS', (int) $config['max_pass_chars'])),
'S_FORCE_PASSWORD' => ($auth->acl_get('u_chgpasswd') && $config['chg_passforce'] && $user->data['user_passchg'] < time() - ($config['chg_passforce'] * 86400)) ? true : false,
'S_CHANGE_USERNAME' => ($config['allow_namechange'] && $auth->acl_get('u_chgname')) ? true : false,
@@ -540,7 +537,7 @@ class ucp_profile
'URL_STATUS' => ($config['allow_sig_links']) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'],
'MAX_FONT_SIZE' => (int) $config['max_sig_font_size'],
- 'L_SIGNATURE_EXPLAIN' => sprintf($user->lang['SIGNATURE_EXPLAIN'], $config['max_sig_chars']),
+ 'L_SIGNATURE_EXPLAIN' => $user->lang('SIGNATURE_EXPLAIN', (int) $config['max_sig_chars']),
'S_BBCODE_ALLOWED' => $config['allow_sig_bbcode'],
'S_SMILIES_ALLOWED' => $config['allow_sig_smilies'],
@@ -605,7 +602,7 @@ class ucp_profile
'S_FORM_ENCTYPE' => ($can_upload && ($config['allow_avatar_upload'] || $config['allow_avatar_remote_upload'])) ? ' enctype="multipart/form-data"' : '',
- 'L_AVATAR_EXPLAIN' => sprintf($user->lang['AVATAR_EXPLAIN'], $config['avatar_max_width'], $config['avatar_max_height'], $config['avatar_filesize'] / 1024),
+ 'L_AVATAR_EXPLAIN' => phpbb_avatar_explanation_string(),
));
if ($config['allow_avatar'] && $display_gallery && $auth->acl_get('u_chgavatar') && $config['allow_avatar_local'])
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 3781fc6b1c..fe09d0a9fe 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -366,10 +366,7 @@ class ucp_register
$messenger->to($data['email'], $data['username']);
- $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
- $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
- $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
- $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
+ $messenger->anti_abuse_headers($config, $user);
$messenger->assign_vars(array(
'WELCOME_MSG' => htmlspecialchars_decode(sprintf($user->lang['WELCOME_SUBJECT'], $config['sitename'])),
@@ -478,8 +475,8 @@ class ucp_register
'EMAIL_CONFIRM' => $data['email_confirm'],
'L_REG_COND' => $l_reg_cond,
- 'L_USERNAME_EXPLAIN' => sprintf($user->lang[$config['allow_name_chars'] . '_EXPLAIN'], $config['min_name_chars'], $config['max_name_chars']),
- 'L_PASSWORD_EXPLAIN' => sprintf($user->lang[$config['pass_complex'] . '_EXPLAIN'], $config['min_pass_chars'], $config['max_pass_chars']),
+ 'L_USERNAME_EXPLAIN' => $user->lang($config['allow_name_chars'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_name_chars']), $user->lang('CHARACTERS', (int) $config['max_name_chars'])),
+ 'L_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars']), $user->lang('CHARACTERS', (int) $config['max_pass_chars'])),
'S_LANG_OPTIONS' => language_select($data['lang']),
'S_TZ_OPTIONS' => tz_select($data['tz']),
diff --git a/phpBB/includes/ucp/ucp_resend.php b/phpBB/includes/ucp/ucp_resend.php
index 66677b9a4f..ab4f699668 100644
--- a/phpBB/includes/ucp/ucp_resend.php
+++ b/phpBB/includes/ucp/ucp_resend.php
@@ -94,10 +94,7 @@ class ucp_resend
$messenger->template(($coppa) ? 'coppa_resend_inactive' : 'user_resend_inactive', $user_row['user_lang']);
$messenger->to($user_row['user_email'], $user_row['username']);
- $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
- $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
- $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
- $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
+ $messenger->anti_abuse_headers($config, $user);
$messenger->assign_vars(array(
'WELCOME_MSG' => htmlspecialchars_decode(sprintf($user->lang['WELCOME_SUBJECT'], $config['sitename'])),
@@ -133,10 +130,7 @@ class ucp_resend
$messenger->to($row['user_email'], $row['username']);
$messenger->im($row['user_jabber'], $row['username']);
- $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
- $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
- $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
- $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
+ $messenger->anti_abuse_headers($config, $user);
$messenger->assign_vars(array(
'USERNAME' => htmlspecialchars_decode($user_row['username']),