aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/acp/acp_attachments.php2
-rw-r--r--phpBB/includes/acp/acp_bbcodes.php4
-rw-r--r--phpBB/includes/acp/acp_board.php29
-rw-r--r--phpBB/includes/acp/acp_email.php117
-rw-r--r--phpBB/includes/acp/acp_extensions.php2
-rw-r--r--phpBB/includes/acp/acp_profile.php2
-rw-r--r--phpBB/includes/acp/acp_prune.php4
-rw-r--r--phpBB/includes/acp/acp_styles.php27
-rw-r--r--phpBB/includes/acp/acp_users.php41
-rw-r--r--phpBB/includes/bbcode.php22
-rw-r--r--phpBB/includes/constants.php2
-rw-r--r--phpBB/includes/functions.php120
-rw-r--r--phpBB/includes/functions_admin.php84
-rw-r--r--phpBB/includes/functions_content.php16
-rw-r--r--phpBB/includes/functions_convert.php1
-rw-r--r--phpBB/includes/functions_download.php10
-rw-r--r--phpBB/includes/functions_messenger.php2
-rw-r--r--phpBB/includes/functions_posting.php58
-rw-r--r--phpBB/includes/functions_privmsgs.php4
-rw-r--r--phpBB/includes/functions_user.php40
-rw-r--r--phpBB/includes/mcp/mcp_forum.php16
-rw-r--r--phpBB/includes/mcp/mcp_front.php2
-rw-r--r--phpBB/includes/mcp/mcp_logs.php2
-rw-r--r--phpBB/includes/mcp/mcp_main.php15
-rw-r--r--phpBB/includes/mcp/mcp_queue.php92
-rw-r--r--phpBB/includes/mcp/mcp_topic.php36
-rw-r--r--phpBB/includes/message_parser.php66
-rw-r--r--phpBB/includes/startup.php28
-rw-r--r--phpBB/includes/ucp/ucp_login_link.php2
-rw-r--r--phpBB/includes/ucp/ucp_prefs.php8
-rw-r--r--phpBB/includes/ucp/ucp_profile.php46
-rw-r--r--phpBB/includes/ucp/ucp_register.php3
32 files changed, 694 insertions, 209 deletions
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php
index 2372c1f73c..2873b48fa4 100644
--- a/phpBB/includes/acp/acp_attachments.php
+++ b/phpBB/includes/acp/acp_attachments.php
@@ -153,7 +153,7 @@ class acp_attachments
'img_create_thumbnail' => array('lang' => 'CREATE_THUMBNAIL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'img_max_thumb_width' => array('lang' => 'MAX_THUMB_WIDTH', 'validate' => 'int:0:999999999999999', 'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'img_min_thumb_filesize' => array('lang' => 'MIN_THUMB_FILESIZE', 'validate' => 'int:0:999999999999999', 'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),
- 'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'string', 'type' => 'text:20:200', 'explain' => true, 'append' => '&nbsp;&nbsp;<span>[ <a href="' . $this->u_action . '&amp;action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'),
+ 'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'path', 'type' => 'text:20:200', 'explain' => true, 'append' => '&nbsp;&nbsp;<span>[ <a href="' . $this->u_action . '&amp;action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'),
'img_max' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int:0:9999', 'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'img_link' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int:0:9999', 'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
)
diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php
index 130a3ef542..e245eea069 100644
--- a/phpBB/includes/acp/acp_bbcodes.php
+++ b/phpBB/includes/acp/acp_bbcodes.php
@@ -409,7 +409,9 @@ class acp_bbcodes
{
$bbcode_match = trim($bbcode_match);
$bbcode_tpl = trim($bbcode_tpl);
- $utf8 = strpos($bbcode_match, 'INTTEXT') !== false;
+
+ // Allow unicode characters for URL|LOCAL_URL|RELATIVE_URL|INTTEXT tokens
+ $utf8 = preg_match('/(URL|LOCAL_URL|RELATIVE_URL|INTTEXT)/', $bbcode_match);
$utf8_pcre_properties = phpbb_pcre_utf8_support();
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index f4f7512f0c..63e2647f02 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -615,7 +615,15 @@ class acp_board
{
add_log('admin', 'LOG_CONFIG_' . strtoupper($mode));
- trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
+ $message = $user->lang('CONFIG_UPDATED');
+ $message_type = E_USER_NOTICE;
+ if (!$config['email_enable'] && in_array($mode, array('email', 'registration')) &&
+ in_array($config['require_activation'], array(USER_ACTIVATION_SELF, USER_ACTIVATION_ADMIN)))
+ {
+ $message .= '<br /><br />' . $user->lang('ACC_ACTIVATION_WARNING');
+ $message_type = E_USER_WARNING;
+ }
+ trigger_error($message . adm_back_link($this->u_action), $message_type);
}
$this->tpl_name = 'acp_board';
@@ -792,20 +800,19 @@ class acp_board
global $user, $config;
$act_ary = array(
- 'ACC_DISABLE' => USER_ACTIVATION_DISABLE,
- 'ACC_NONE' => USER_ACTIVATION_NONE,
+ 'ACC_DISABLE' => array(true, USER_ACTIVATION_DISABLE),
+ 'ACC_NONE' => array(true, USER_ACTIVATION_NONE),
+ 'ACC_USER' => array($config['email_enable'], USER_ACTIVATION_SELF),
+ 'ACC_ADMIN' => array($config['email_enable'], USER_ACTIVATION_ADMIN),
);
- if ($config['email_enable'])
- {
- $act_ary['ACC_USER'] = USER_ACTIVATION_SELF;
- $act_ary['ACC_ADMIN'] = USER_ACTIVATION_ADMIN;
- }
- $act_options = '';
- foreach ($act_ary as $key => $value)
+ $act_options = '';
+ foreach ($act_ary as $key => $data)
{
+ list($available, $value) = $data;
$selected = ($selected_value == $value) ? ' selected="selected"' : '';
- $act_options .= '<option value="' . $value . '"' . $selected . '>' . $user->lang[$key] . '</option>';
+ $class = (!$available) ? ' class="disabled-option"' : '';
+ $act_options .= '<option value="' . $value . '"' . $selected . $class . '>' . $user->lang($key) . '</option>';
}
return $act_options;
diff --git a/phpBB/includes/acp/acp_email.php b/phpBB/includes/acp/acp_email.php
index fe55b36e67..fda9d50779 100644
--- a/phpBB/includes/acp/acp_email.php
+++ b/phpBB/includes/acp/acp_email.php
@@ -26,7 +26,7 @@ class acp_email
function main($id, $mode)
{
global $config, $db, $user, $auth, $template, $cache;
- global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix;
+ global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix, $phpbb_dispatcher;
$user->add_lang('acp/email');
$this->tpl_name = 'acp_email';
@@ -40,6 +40,7 @@ class acp_email
$error = array();
$usernames = request_var('usernames', '', true);
+ $usernames = (!empty($usernames)) ? explode("\n", $usernames) : array();
$group_id = request_var('g', 0);
$subject = utf8_normalize_nfc(request_var('subject', '', true));
$message = utf8_normalize_nfc(request_var('message', '', true));
@@ -69,14 +70,18 @@ class acp_email
if (!sizeof($error))
{
- if ($usernames)
+ if (!empty($usernames))
{
// If giving usernames the admin is able to email inactive users too...
- $sql = 'SELECT username, user_email, user_jabber, user_notify_type, user_lang
- FROM ' . USERS_TABLE . '
- WHERE ' . $db->sql_in_set('username_clean', array_map('utf8_clean_string', explode("\n", $usernames))) . '
- AND user_allow_massemail = 1
- ORDER BY user_lang, user_notify_type'; // , SUBSTRING(user_email FROM INSTR(user_email, '@'))
+ $sql_ary = array(
+ 'SELECT' => 'username, user_email, user_jabber, user_notify_type, user_lang',
+ 'FROM' => array(
+ USERS_TABLE => '',
+ ),
+ 'WHERE' => $db->sql_in_set('username_clean', array_map('utf8_clean_string', $usernames)) . '
+ AND user_allow_massemail = 1',
+ 'ORDER_BY' => 'user_lang, user_notify_type',
+ );
}
else
{
@@ -123,8 +128,18 @@ class acp_email
),
);
}
- $sql = $db->sql_build_query('SELECT', $sql_ary);
}
+ /**
+ * Modify sql query to change the list of users the email is sent to
+ *
+ * @event core.acp_email_modify_sql
+ * @var array sql_ary Array which is used to build the sql query
+ * @since 3.1.2-RC1
+ */
+ $vars = array('sql_ary');
+ extract($phpbb_dispatcher->trigger_event('core.acp_email_modify_sql', compact($vars)));
+
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
@@ -180,6 +195,39 @@ class acp_email
$errored = false;
+ $email_template = 'admin_send_email';
+ $template_data = array(
+ 'CONTACT_EMAIL' => phpbb_get_board_contact($config, $phpEx),
+ 'MESSAGE' => htmlspecialchars_decode($message),
+ );
+ $generate_log_entry = true;
+
+ /**
+ * Modify email template data before the emails are sent
+ *
+ * @event core.acp_email_send_before
+ * @var string email_template The template to be used for sending the email
+ * @var string subject The subject of the email
+ * @var array template_data Array with template data assigned to email template
+ * @var bool generate_log_entry If false, no log entry will be created
+ * @var array usernames Usernames which will be displayed in log entry, if it will be created
+ * @var int group_id The group this email will be sent to
+ * @var bool use_queue If true, email queue will be used for sending
+ * @var int priority Priority of sent emails
+ * @since 3.1.3-RC1
+ */
+ $vars = array(
+ 'email_template',
+ 'subject',
+ 'template_data',
+ 'generate_log_entry',
+ 'usernames',
+ 'group_id',
+ 'use_queue',
+ 'priority',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.acp_email_send_before', compact($vars)));
+
for ($i = 0, $size = sizeof($email_list); $i < $size; $i++)
{
$used_lang = $email_list[$i][0]['lang'];
@@ -193,17 +241,14 @@ class acp_email
$messenger->im($email_row['jabber'], $email_row['name']);
}
- $messenger->template('admin_send_email', $used_lang);
+ $messenger->template($email_template, $used_lang);
$messenger->anti_abuse_headers($config, $user);
$messenger->subject(htmlspecialchars_decode($subject));
$messenger->set_mail_priority($priority);
- $messenger->assign_vars(array(
- 'CONTACT_EMAIL' => phpbb_get_board_contact($config, $phpEx),
- 'MESSAGE' => htmlspecialchars_decode($message))
- );
+ $messenger->assign_vars($template_data);
if (!($messenger->send($used_method)))
{
@@ -214,24 +259,26 @@ class acp_email
$messenger->save_queue();
- if ($usernames)
+ if ($generate_log_entry)
{
- $usernames = explode("\n", $usernames);
- add_log('admin', 'LOG_MASS_EMAIL', implode(', ', utf8_normalize_nfc($usernames)));
- }
- else
- {
- if ($group_id)
+ if (!empty($usernames))
{
- $group_name = get_group_name($group_id);
+ add_log('admin', 'LOG_MASS_EMAIL', implode(', ', utf8_normalize_nfc($usernames)));
}
else
{
- // Not great but the logging routine doesn't cope well with localising on the fly
- $group_name = $user->lang['ALL_USERS'];
- }
+ if ($group_id)
+ {
+ $group_name = get_group_name($group_id);
+ }
+ else
+ {
+ // Not great but the logging routine doesn't cope well with localising on the fly
+ $group_name = $user->lang['ALL_USERS'];
+ }
- add_log('admin', 'LOG_MASS_EMAIL', $group_name);
+ add_log('admin', 'LOG_MASS_EMAIL', $group_name);
+ }
}
if (!$errored)
@@ -267,17 +314,31 @@ class acp_email
$s_priority_options .= '<option value="' . MAIL_NORMAL_PRIORITY . '" selected="selected">' . $user->lang['MAIL_NORMAL_PRIORITY'] . '</option>';
$s_priority_options .= '<option value="' . MAIL_HIGH_PRIORITY . '">' . $user->lang['MAIL_HIGH_PRIORITY'] . '</option>';
- $template->assign_vars(array(
+ $template_data = array(
'S_WARNING' => (sizeof($error)) ? true : false,
'WARNING_MSG' => (sizeof($error)) ? implode('<br />', $error) : '',
'U_ACTION' => $this->u_action,
'S_GROUP_OPTIONS' => $select_list,
- 'USERNAMES' => $usernames,
+ 'USERNAMES' => implode("\n", $usernames),
'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&amp;form=acp_email&amp;field=usernames'),
'SUBJECT' => $subject,
'MESSAGE' => $message,
- 'S_PRIORITY_OPTIONS' => $s_priority_options)
+ 'S_PRIORITY_OPTIONS' => $s_priority_options,
);
+ /**
+ * Modify custom email template data before we display the form
+ *
+ * @event core.acp_email_display
+ * @var array template_data Array with template data assigned to email template
+ * @var array exclude Array with groups which are excluded from group selection
+ * @var array usernames Usernames which will be displayed in form
+ *
+ * @since 3.1.4-RC1
+ */
+ $vars = array('template_data', 'exclude', 'usernames');
+ extract($phpbb_dispatcher->trigger_event('core.acp_email_display', compact($vars)));
+
+ $template->assign_vars($template_data);
}
}
diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php
index 9bdd8eb458..89fdc8b863 100644
--- a/phpBB/includes/acp/acp_extensions.php
+++ b/phpBB/includes/acp/acp_extensions.php
@@ -537,7 +537,7 @@ class acp_extensions
$version_check = $meta['extra']['version-check'];
- $version_helper = new \phpbb\version_helper($this->cache, $this->config, $this->user);
+ $version_helper = new \phpbb\version_helper($this->cache, $this->config, new \phpbb\file_downloader(), $this->user);
$version_helper->set_current_version($meta['version']);
$version_helper->set_file_location($version_check['host'], $version_check['directory'], $version_check['filename']);
$version_helper->force_stability($this->config['extension_force_unstable'] ? 'unstable' : null);
diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php
index 046281596c..97c1f62077 100644
--- a/phpBB/includes/acp/acp_profile.php
+++ b/phpBB/includes/acp/acp_profile.php
@@ -460,7 +460,7 @@ class acp_profile
if (!$cp->vars[$key] && $action == 'edit')
{
- $cp->vars[$key] = $$key;
+ $cp->vars[$key] = ${$key};
}
$field_data = $cp->vars;
diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php
index a10b248324..59f15c4890 100644
--- a/phpBB/includes/acp/acp_prune.php
+++ b/phpBB/includes/acp/acp_prune.php
@@ -397,7 +397,7 @@ class acp_prune
$joined_after = request_var('joined_after', '');
$active = request_var('active', '');
- $count = request_var('count', 0);
+ $count = ($request->variable('count', '') === '') ? false : $request->variable('count', 0);
$active = ($active) ? explode('-', $active) : array();
$joined_before = ($joined_before) ? explode('-', $joined_before) : array();
@@ -439,7 +439,7 @@ class acp_prune
$where_sql .= ($username) ? ' AND username_clean ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), utf8_clean_string($username))) : '';
$where_sql .= ($email) ? ' AND user_email ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), $email)) . ' ' : '';
$where_sql .= $joined_sql;
- $where_sql .= ($count) ? " AND user_posts " . $key_match[$count_select] . ' ' . (int) $count . ' ' : '';
+ $where_sql .= ($count !== false) ? " AND user_posts " . $key_match[$count_select] . ' ' . (int) $count . ' ' : '';
// First handle pruning of users who never logged in, last active date is 0000-00-00
if (sizeof($active) && (int) $active[0] == 0 && (int) $active[1] == 0 && (int) $active[2] == 0)
diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php
index af3fd7937c..6bd27a8bca 100644
--- a/phpBB/includes/acp/acp_styles.php
+++ b/phpBB/includes/acp/acp_styles.php
@@ -29,14 +29,31 @@ class acp_styles
protected $styles_path;
protected $styles_path_absolute = 'styles';
protected $default_style = 0;
+ protected $styles_list_cols = 0;
+ protected $reserved_style_names = array('adm', 'admin', 'all');
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
+
+ /** @var \phpbb\user */
protected $user;
+
+ /** @var \phpbb\template\template */
protected $template;
+
+ /** @var \phpbb\request\request_interface */
protected $request;
+
+ /** @var \phpbb\cache\driver\driver_interface */
protected $cache;
+
+ /** @var \phpbb\auth\auth */
protected $auth;
+
+ /** @var string */
protected $phpbb_root_path;
+
+ /** @var string */
protected $php_ext;
public function main($id, $mode)
@@ -164,6 +181,12 @@ class acp_styles
$last_installed = false;
foreach ($dirs as $dir)
{
+ if (in_array($dir, $this->reserved_style_names))
+ {
+ $messages[] = $this->user->lang('STYLE_NAME_RESERVED', htmlspecialchars($dir));
+ continue;
+ }
+
$found = false;
foreach ($styles as &$style)
{
@@ -809,7 +832,7 @@ class acp_styles
* Update styles tree
*
* @param array $styles Styles list, passed as reference
- * @param array $style Current style, false if root
+ * @param array|false $style Current style, false if root
* @return bool True if something was updated, false if not
*/
protected function update_styles_tree(&$styles, $style = false)
@@ -1091,7 +1114,7 @@ class acp_styles
/**
* Install style
*
- * @param $style style data
+ * @param array $style style data
* @return int Style id
*/
protected function install_style($style)
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 31b033604d..3c957a7093 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -173,6 +173,21 @@ class acp_users
$delete_type = request_var('delete_type', '');
$ip = request_var('ip', 'ip');
+ /**
+ * Run code at beginning of ACP users overview
+ *
+ * @event core.acp_users_overview_before
+ * @var array user_row Current user data
+ * @var string mode Active module
+ * @var string action Module that should be run
+ * @var bool submit Do we display the form only
+ * or did the user press submit
+ * @var array error Array holding error messages
+ * @since 3.1.3-RC1
+ */
+ $vars = array('user_row', 'mode', 'action', 'submit', 'error');
+ extract($phpbb_dispatcher->trigger_event('core.acp_users_overview_before', compact($vars)));
+
if ($submit)
{
if ($delete)
@@ -1362,6 +1377,19 @@ class acp_users
$data['bday_year'] = request_var('bday_year', $data['bday_year']);
$data['user_birthday'] = sprintf('%2d-%2d-%4d', $data['bday_day'], $data['bday_month'], $data['bday_year']);
+ /**
+ * Modify user data on editing profile in ACP
+ *
+ * @event core.acp_users_modify_profile
+ * @var array data Array with user profile data
+ * @var bool submit Flag indicating if submit button has been pressed
+ * @var int user_id The user id
+ * @var array user_row Array with the full user data
+ * @since 3.1.4-RC1
+ */
+ $vars = array('data', 'submit', 'user_id', 'user_row');
+ extract($phpbb_dispatcher->trigger_event('core.acp_users_modify_profile', compact($vars)));
+
if ($submit)
{
$error = validate_data($data, array(
@@ -1393,6 +1421,19 @@ class acp_users
'user_birthday' => $data['user_birthday'],
);
+ /**
+ * Modify profile data in ACP before submitting to the database
+ *
+ * @event core.acp_users_profile_modify_sql_ary
+ * @var array cp_data Array with the user custom profile fields data
+ * @var array data Array with user profile data
+ * @var int user_id The user id
+ * @var array user_row Array with the full user data
+ * @since 3.1.4-RC1
+ */
+ $vars = array('cp_data', 'data', 'user_id', 'user_row');
+ extract($phpbb_dispatcher->trigger_event('core.acp_users_profile_modify_sql_ary', compact($vars)));
+
$sql = 'UPDATE ' . USERS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
WHERE user_id = $user_id";
diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php
index 3460db4882..5f6dcde448 100644
--- a/phpBB/includes/bbcode.php
+++ b/phpBB/includes/bbcode.php
@@ -129,7 +129,7 @@ class bbcode
*/
function bbcode_cache_init()
{
- global $phpbb_root_path, $phpEx, $config, $user, $phpbb_extension_manager, $phpbb_path_helper;
+ global $phpbb_root_path, $phpEx, $config, $user, $phpbb_dispatcher, $phpbb_extension_manager, $phpbb_path_helper;
if (empty($this->template_filename))
{
@@ -388,6 +388,26 @@ class bbcode
break;
}
}
+
+ $bbcode_cache = $this->bbcode_cache;
+ $bbcode_bitfield = $this->bbcode_bitfield;
+ $bbcode_uid = $this->bbcode_uid;
+
+ /**
+ * Use this event to modify the bbcode_cache
+ *
+ * @event core.bbcode_cache_init_end
+ * @var array bbcode_cache The array of cached search and replace patterns of bbcodes
+ * @var string bbcode_bitfield The bbcode bitfield
+ * @var string bbcode_uid The bbcode uid
+ * @since 3.1.3-RC1
+ */
+ $vars = array('bbcode_cache', 'bbcode_bitfield', 'bbcode_uid');
+ extract($phpbb_dispatcher->trigger_event('core.bbcode_cache_init_end', compact($vars)));
+
+ $this->bbcode_cache = $bbcode_cache;
+ $this->bbcode_bitfield = $bbcode_bitfield;
+ $this->bbcode_uid = $bbcode_uid;
}
/**
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index 2d4cb727a7..321a87b4b0 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))
*/
// phpBB Version
-define('PHPBB_VERSION', '3.1.2-RC1-dev');
+define('PHPBB_VERSION', '3.1.4-dev');
// QA-related
// define('PHPBB_QA', 1);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 1a3560dbb1..940484a0ea 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -1150,10 +1150,43 @@ function phpbb_timezone_select($template, $user, $default = '', $truncate = fals
function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $user_id = 0)
{
global $db, $user, $config;
- global $request, $phpbb_container;
+ global $request, $phpbb_container, $phpbb_dispatcher;
$post_time = ($post_time === 0 || $post_time > time()) ? time() : (int) $post_time;
+ $should_markread = true;
+
+ /**
+ * This event is used for performing actions directly before marking forums,
+ * topics or posts as read.
+ *
+ * It is also possible to prevent the marking. For that, the $should_markread parameter
+ * should be set to FALSE.
+ *
+ * @event core.markread_before
+ * @var string mode Variable containing marking mode value
+ * @var mixed forum_id Variable containing forum id, or false
+ * @var mixed topic_id Variable containing topic id, or false
+ * @var int post_time Variable containing post time
+ * @var int user_id Variable containing the user id
+ * @var bool should_markread Flag indicating if the markread should be done or not.
+ * @since 3.1.4-RC1
+ */
+ $vars = array(
+ 'mode',
+ 'forum_id',
+ 'topic_id',
+ 'post_time',
+ 'user_id',
+ 'should_markread',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.markread_before', compact($vars)));
+
+ if (!$should_markread)
+ {
+ return;
+ }
+
if ($mode == 'all')
{
if ($forum_id === false || !sizeof($forum_id))
@@ -1648,6 +1681,7 @@ function get_complete_topic_tracking($forum_id, $topic_ids, $global_announce_lis
function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $sql_limit = 1001, $sql_limit_offset = 0)
{
global $config, $db, $user;
+ global $phpbb_dispatcher;
$user_id = ($user_id === false) ? (int) $user->data['user_id'] : (int) $user_id;
@@ -1691,6 +1725,24 @@ function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $s
$sql_sort",
);
+ /**
+ * Change SQL query for fetching unread topics data
+ *
+ * @event core.get_unread_topics_modify_sql
+ * @var array sql_array Fully assembled SQL query with keys SELECT, FROM, LEFT_JOIN, WHERE
+ * @var int last_mark User's last_mark time
+ * @var string sql_extra Extra WHERE SQL statement
+ * @var string sql_sort ORDER BY SQL sorting statement
+ * @since 3.1.4-RC1
+ */
+ $vars = array(
+ 'sql_array',
+ 'last_mark',
+ 'sql_extra',
+ 'sql_sort',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.get_unread_topics_modify_sql', compact($vars)));
+
$sql = $db->sql_build_query('SELECT', $sql_array);
$result = $db->sql_query_limit($sql, $sql_limit, $sql_limit_offset);
@@ -2396,26 +2448,7 @@ function build_url($strip_vars = false)
{
global $config, $user, $phpbb_path_helper;
- $php_ext = $phpbb_path_helper->get_php_ext();
- $page = $user->page['page'];
-
- // We need to be cautious here.
- // On some situations, the redirect path is an absolute URL, sometimes a relative path
- // For a relative path, let's prefix it with $phpbb_root_path to point to the correct location,
- // else we use the URL directly.
- $url_parts = parse_url($page);
-
- // URL
- if ($url_parts === false || empty($url_parts['scheme']) || empty($url_parts['host']))
- {
- // Remove 'app.php/' from the page, when rewrite is enabled
- if ($config['enable_mod_rewrite'] && strpos($page, 'app.' . $php_ext . '/') === 0)
- {
- $page = substr($page, strlen('app.' . $php_ext . '/'));
- }
-
- $page = $phpbb_path_helper->get_phpbb_root_path() . $page;
- }
+ $page = $phpbb_path_helper->get_valid_page($user->page['page'], $config['enable_mod_rewrite']);
// Append SID
$redirect = append_sid($page, false, false);
@@ -2657,7 +2690,7 @@ function check_form_key($form_name, $timespan = false)
function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_body.html', $u_action = '')
{
global $user, $template, $db, $request;
- global $phpEx, $phpbb_root_path, $request;
+ global $config, $phpbb_path_helper;
if (isset($_POST['cancel']))
{
@@ -2719,8 +2752,8 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
}
// re-add sid / transform & to &amp; for user->page (user->page is always using &)
- $use_page = ($u_action) ? $phpbb_root_path . $u_action : $phpbb_root_path . str_replace('&', '&amp;', $user->page['page']);
- $u_action = reapply_sid($use_page);
+ $use_page = ($u_action) ? $u_action : str_replace('&', '&amp;', $user->page['page']);
+ $u_action = reapply_sid($phpbb_path_helper->get_valid_page($use_page, $config['enable_mod_rewrite']));
$u_action .= ((strpos($u_action, '?') === false) ? '?' : '&amp;') . 'confirm_key=' . $confirm_key;
$template->assign_vars(array(
@@ -2922,6 +2955,19 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
break;
}
+
+ /**
+ * This event allows an extension to process when a user fails a login attempt
+ *
+ * @event core.login_box_failed
+ * @var array result Login result data
+ * @var string username User name used to login
+ * @var string password Password used to login
+ * @var string err Error message
+ * @since 3.1.3-RC1
+ */
+ $vars = array('result', 'username', 'password', 'err');
+ extract($phpbb_dispatcher->trigger_event('core.login_box_failed', compact($vars)));
}
// Assign credential for username/password pair
@@ -3327,23 +3373,33 @@ function get_preg_expression($mode)
break;
case 'url':
+ // generated with regex_idn.php file in the develop folder
+ return "[a-z][a-z\d+\-.]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?";
+ break;
+
case 'url_inline':
- $inline = ($mode == 'url') ? ')' : '';
- $scheme = ($mode == 'url') ? '[a-z\d+\-.]' : '[a-z\d+]'; // avoid automatic parsing of "word" in "last word.http://..."
- // generated with regex generation file in the develop folder
- return "[a-z]$scheme*:/{2}(?:(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?";
+ // generated with regex_idn.php file in the develop folder
+ return "[a-z][a-z\d+]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?";
break;
case 'www_url':
+ // generated with regex_idn.php file in the develop folder
+ return "www\.(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?";
+ break;
+
case 'www_url_inline':
- $inline = ($mode == 'www_url') ? ')' : '';
- return "www\.(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?";
+ // generated with regex_idn.php file in the develop folder
+ return "www\.(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?";
break;
case 'relative_url':
+ // generated with regex_idn.php file in the develop folder
+ return "(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?";
+ break;
+
case 'relative_url_inline':
- $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})*)?";
+ // generated with regex_idn.php file in the develop folder
+ return "(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?";
break;
case 'table_prefix':
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index e3e8657afb..b016659541 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -2311,7 +2311,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false,
*/
function prune($forum_id, $prune_mode, $prune_date, $prune_flags = 0, $auto_sync = true)
{
- global $db;
+ global $db, $phpbb_dispatcher;
if (!is_array($forum_id))
{
@@ -2351,6 +2351,21 @@ function prune($forum_id, $prune_mode, $prune_date, $prune_flags = 0, $auto_sync
$sql_and .= ' AND topic_status = ' . ITEM_MOVED . " AND topic_last_post_time < $prune_date";
}
+ /**
+ * Use this event to modify the SQL that selects topics to be pruned
+ *
+ * @event core.prune_sql
+ * @var string forum_id The forum id
+ * @var string prune_mode The prune mode
+ * @var string prune_date The prune date
+ * @var int prune_flags The prune flags
+ * @var bool auto_sync Whether or not to perform auto sync
+ * @var string sql_and SQL text appended to where clause
+ * @since 3.1.3-RC1
+ */
+ $vars = array('forum_id', 'prune_mode', 'prune_date', 'prune_flags', 'auto_sync', 'sql_and');
+ extract($phpbb_dispatcher->trigger_event('core.prune_sql', compact($vars)));
+
$sql = 'SELECT topic_id
FROM ' . TOPICS_TABLE . '
WHERE ' . $db->sql_in_set('forum_id', $forum_id) . "
@@ -2512,6 +2527,7 @@ function phpbb_cache_moderators($db, $cache, $auth)
{
$usernames_ary[$row['user_id']] = $row['username'];
}
+ $db->sql_freeresult($result);
foreach ($hold_ary as $user_id => $forum_id_ary)
{
@@ -2806,6 +2822,7 @@ function view_inactive_users(&$users, &$user_count, $limit = 0, $offset = 0, $li
$users[] = $row;
}
+ $db->sql_freeresult($result);
return $offset;
}
@@ -2980,68 +2997,21 @@ function get_database_size()
/**
* Retrieve contents from remotely stored file
+*
+* @deprecated 3.1.2 Use file_downloader instead
*/
function get_remote_file($host, $directory, $filename, &$errstr, &$errno, $port = 80, $timeout = 6)
{
- global $user;
-
- if ($fsock = @fsockopen($host, $port, $errno, $errstr, $timeout))
- {
- @fputs($fsock, "GET $directory/$filename HTTP/1.0\r\n");
- @fputs($fsock, "HOST: $host\r\n");
- @fputs($fsock, "Connection: close\r\n\r\n");
-
- $timer_stop = time() + $timeout;
- stream_set_timeout($fsock, $timeout);
-
- $file_info = '';
- $get_info = false;
-
- while (!@feof($fsock))
- {
- if ($get_info)
- {
- $file_info .= @fread($fsock, 1024);
- }
- else
- {
- $line = @fgets($fsock, 1024);
- if ($line == "\r\n")
- {
- $get_info = true;
- }
- else if (stripos($line, '404 not found') !== false)
- {
- $errstr = $user->lang('FILE_NOT_FOUND', $filename);
- return false;
- }
- }
+ global $phpbb_container;
- $stream_meta_data = stream_get_meta_data($fsock);
+ // Get file downloader and assign $errstr and $errno
+ $file_downloader = $phpbb_container->get('file_downloader');
- if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop)
- {
- $errstr = $user->lang['FSOCK_TIMEOUT'];
- return false;
- }
- }
- @fclose($fsock);
- }
- else
- {
- if ($errstr)
- {
- $errstr = utf8_convert_message($errstr);
- return false;
- }
- else
- {
- $errstr = $user->lang['FSOCK_DISABLED'];
- return false;
- }
- }
+ $file_data = $file_downloader->get($host, $directory, $filename, $port, $timeout);
+ $errstr = $file_downloader->get_error_string();
+ $errno = $file_downloader->get_error_number();
- return $file_info;
+ return $file_data;
}
/*
diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php
index 25ca50e8f1..6f861b8607 100644
--- a/phpBB/includes/functions_content.php
+++ b/phpBB/includes/functions_content.php
@@ -78,7 +78,7 @@ function gen_sort_selects(&$limit_days, &$sort_by_text, &$sort_days, &$sort_key,
foreach ($sorts as $name => $sort_ary)
{
$key = $sort_ary['key'];
- $selected = $$sort_ary['key'];
+ $selected = ${$sort_ary['key']};
// Check if the key is selectable. If not, we reset to the default or first key found.
// This ensures the values are always valid. We also set $sort_dir/sort_key/etc. to the
@@ -87,12 +87,12 @@ function gen_sort_selects(&$limit_days, &$sort_by_text, &$sort_days, &$sort_key,
{
if ($sort_ary['default'] !== false)
{
- $selected = $$key = $sort_ary['default'];
+ $selected = ${$key} = $sort_ary['default'];
}
else
{
@reset($sort_ary['options']);
- $selected = $$key = key($sort_ary['options']);
+ $selected = ${$key} = key($sort_ary['options']);
}
}
@@ -712,7 +712,7 @@ function make_clickable_callback($type, $whitespace, $url, $relative_url, $class
break;
}
- $short_url = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url;
+ $short_url = (utf8_strlen($url) > 55) ? utf8_substr($url, 0, 39) . ' ... ' . utf8_substr($url, -10) : $url;
switch ($type)
{
@@ -788,28 +788,28 @@ function make_clickable($text, $server_url = false, $class = 'postlink')
// relative urls for this board
$magic_url_match_args[$server_url][] = array(
- '#(^|[\n\t (>.])(' . preg_quote($server_url, '#') . ')/(' . get_preg_expression('relative_url_inline') . ')#i',
+ '#(^|[\n\t (>.])(' . preg_quote($server_url, '#') . ')/(' . get_preg_expression('relative_url_inline') . ')#iu',
MAGIC_URL_LOCAL,
$local_class,
);
// matches a xxxx://aaaaa.bbb.cccc. ...
$magic_url_match_args[$server_url][] = array(
- '#(^|[\n\t (>.])(' . get_preg_expression('url_inline') . ')#i',
+ '#(^|[\n\t (>.])(' . get_preg_expression('url_inline') . ')#iu',
MAGIC_URL_FULL,
$class,
);
// matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
$magic_url_match_args[$server_url][] = array(
- '#(^|[\n\t (>])(' . get_preg_expression('www_url_inline') . ')#i',
+ '#(^|[\n\t (>])(' . get_preg_expression('www_url_inline') . ')#iu',
MAGIC_URL_WWW,
$class,
);
// matches an email@domain type address at the start of a line, or after a space or after what might be a BBCode.
$magic_url_match_args[$server_url][] = array(
- '/(^|[\n\t (>])(' . get_preg_expression('email') . ')/i',
+ '/(^|[\n\t (>])(' . get_preg_expression('email') . ')/iu',
MAGIC_URL_EMAIL,
'',
);
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index 9d480692e9..61ab4721c4 100644
--- a/phpBB/includes/functions_convert.php
+++ b/phpBB/includes/functions_convert.php
@@ -2148,6 +2148,7 @@ function fix_empty_primary_groups()
}
$sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . ' WHERE group_id = ' . get_group_id('global_moderators');
+ $result = $db->sql_query($sql);
$user_ids = array();
while ($row = $db->sql_fetchrow($result))
diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php
index fbeae50f55..254e65ae3d 100644
--- a/phpBB/includes/functions_download.php
+++ b/phpBB/includes/functions_download.php
@@ -210,11 +210,6 @@ function send_file_to_browser($attachment, $upload_dir, $category)
}
}
- if ($size)
- {
- header("Content-Length: $size");
- }
-
// Close the db connection before sending the file etc.
file_gc(false);
@@ -238,6 +233,11 @@ function send_file_to_browser($attachment, $upload_dir, $category)
exit;
}
+ if ($size)
+ {
+ header("Content-Length: $size");
+ }
+
// Try to deliver in chunks
@set_time_limit(0);
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index 045e555d05..fbac3e6f1d 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -510,7 +510,7 @@ class messenger
foreach ($address_ary as $which_ary)
{
- $$type .= (($$type != '') ? ', ' : '') . (($which_ary['name'] != '') ? mail_encode($which_ary['name'], $encode_eol) . ' <' . $which_ary['email'] . '>' : $which_ary['email']);
+ ${$type} .= ((${$type} != '') ? ', ' : '') . (($which_ary['name'] != '') ? mail_encode($which_ary['name'], $encode_eol) . ' <' . $which_ary['email'] . '>' : $which_ary['email']);
}
}
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index af44f6270e..f3c49badfe 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -1037,7 +1037,7 @@ function load_drafts($topic_id = 0, $forum_id = 0, $id = 0, $pm_action = '', $ms
function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id = 0, $show_quote_button = true)
{
global $user, $auth, $db, $template, $bbcode, $cache;
- global $config, $phpbb_root_path, $phpEx, $phpbb_container;
+ global $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
$phpbb_content_visibility = $phpbb_container->get('content.visibility');
$sql_sort = ($mode == 'post_review') ? 'ASC' : 'DESC';
@@ -1176,7 +1176,7 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
$post_anchor = ($mode == 'post_review') ? 'ppr' . $row['post_id'] : 'pr' . $row['post_id'];
$u_show_post = append_sid($phpbb_root_path . 'viewtopic.' . $phpEx, "f=$forum_id&amp;t=$topic_id&amp;p={$row['post_id']}&amp;view=show#p{$row['post_id']}");
- $template->assign_block_vars($mode . '_row', array(
+ $post_row = array(
'POST_AUTHOR_FULL' => get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
'POST_AUTHOR_COLOUR' => get_username_string('colour', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
'POST_AUTHOR' => get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
@@ -1195,9 +1195,37 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
'POST_ID' => $row['post_id'],
'U_MINI_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . '#p' . $row['post_id'],
'U_MCP_DETAILS' => ($auth->acl_get('m_info', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&amp;mode=post_details&amp;f=' . $forum_id . '&amp;p=' . $row['post_id'], true, $user->session_id) : '',
- 'POSTER_QUOTE' => ($show_quote_button && $auth->acl_get('f_reply', $forum_id)) ? addslashes(get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username'])) : '')
+ 'POSTER_QUOTE' => ($show_quote_button && $auth->acl_get('f_reply', $forum_id)) ? addslashes(get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username'])) : '',
);
+ $current_row_number = $i;
+
+ /**
+ * Event to modify the template data block for topic reviews
+ *
+ * @event core.topic_review_modify_row
+ * @var string mode The review mode
+ * @var int topic_id The topic that is being reviewed
+ * @var int forum_id The topic's forum
+ * @var int cur_post_id Post offset id
+ * @var int current_row_number Number of the current row being iterated
+ * @var array post_row Template block array of the current post
+ * @var array row Array with original post and user data
+ * @since 3.1.4-RC1
+ */
+ $vars = array(
+ 'mode',
+ 'topic_id',
+ 'forum_id',
+ 'cur_post_id',
+ 'current_row_number',
+ 'post_row',
+ 'row',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.topic_review_modify_row', compact($vars)));
+
+ $template->assign_block_vars($mode . '_row', $post_row);
+
// Display not already displayed Attachments for this post, we already parsed them. ;)
if (!empty($attachments[$row['post_id']]))
{
@@ -1825,6 +1853,30 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
break;
}
+ /**
+ * Modify sql query data for post submitting
+ *
+ * @event core.submit_post_modify_sql_data
+ * @var array data Array with the data for the post
+ * @var array poll Array with the poll data for the post
+ * @var string post_mode Variable containing posting mode value
+ * @var bool sql_data Array with the data for the posting SQL query
+ * @var string subject Variable containing post subject value
+ * @var int topic_type Variable containing topic type value
+ * @var string username Variable containing post author name
+ * @since 3.1.3-RC1
+ */
+ $vars = array(
+ 'data',
+ 'poll',
+ 'post_mode',
+ 'sql_data',
+ 'subject',
+ 'topic_type',
+ 'username',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.submit_post_modify_sql_data', compact($vars)));
+
// Submit new topic
if ($post_mode == 'post')
{
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index 838c6a0fec..e693305246 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -1415,9 +1415,9 @@ function rebuild_header($check_ary)
$_types = array('u', 'g');
foreach ($_types as $type)
{
- if (sizeof($$type))
+ if (sizeof(${$type}))
{
- foreach ($$type as $id)
+ foreach (${$type} as $id)
{
$address[$type][$id] = $check_type;
}
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index f79a8998c4..acf5649ed5 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -44,13 +44,13 @@ function user_get_id_name(&$user_id_ary, &$username_ary, $user_type = false)
$which_ary = ($user_id_ary) ? 'user_id_ary' : 'username_ary';
- if ($$which_ary && !is_array($$which_ary))
+ if (${$which_ary} && !is_array(${$which_ary}))
{
- $$which_ary = array($$which_ary);
+ ${$which_ary} = array(${$which_ary});
}
- $sql_in = ($which_ary == 'user_id_ary') ? array_map('intval', $$which_ary) : array_map('utf8_clean_string', $$which_ary);
- unset($$which_ary);
+ $sql_in = ($which_ary == 'user_id_ary') ? array_map('intval', ${$which_ary}) : array_map('utf8_clean_string', ${$which_ary});
+ unset(${$which_ary});
$user_id_ary = $username_ary = array();
@@ -703,7 +703,7 @@ function user_delete($mode, $user_ids, $retain_username = true)
*/
function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL)
{
- global $config, $db, $user, $auth;
+ global $config, $db, $user, $auth, $phpbb_dispatcher;
$deactivated = $activated = 0;
$sql_statements = array();
@@ -756,6 +756,21 @@ function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL)
}
$db->sql_freeresult($result);
+ /**
+ * Check or modify activated/deactivated users data before submitting it to the database
+ *
+ * @event core.user_active_flip_before
+ * @var string mode User type changing mode, can be: flip|activate|deactivate
+ * @var int reason Reason for changing user type, can be: INACTIVE_REGISTER|INACTIVE_PROFILE|INACTIVE_MANUAL|INACTIVE_REMIND
+ * @var int activated The number of users to be activated
+ * @var int deactivated The number of users to be deactivated
+ * @var array user_id_ary Array with user ids to change user type
+ * @var array sql_statements Array with users data to submit to the database, keys: user ids, values: arrays with user data
+ * @since 3.1.4-RC1
+ */
+ $vars = array('mode', 'reason', 'activated', 'deactivated', 'user_id_ary', 'sql_statements');
+ extract($phpbb_dispatcher->trigger_event('core.user_active_flip_before', compact($vars)));
+
if (sizeof($sql_statements))
{
foreach ($sql_statements as $user_id => $sql_ary)
@@ -769,6 +784,21 @@ function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL)
$auth->acl_clear_prefetch(array_keys($sql_statements));
}
+ /**
+ * Perform additional actions after the users have been activated/deactivated
+ *
+ * @event core.user_active_flip_after
+ * @var string mode User type changing mode, can be: flip|activate|deactivate
+ * @var int reason Reason for changing user type, can be: INACTIVE_REGISTER|INACTIVE_PROFILE|INACTIVE_MANUAL|INACTIVE_REMIND
+ * @var int activated The number of users to be activated
+ * @var int deactivated The number of users to be deactivated
+ * @var array user_id_ary Array with user ids to change user type
+ * @var array sql_statements Array with users data to submit to the database, keys: user ids, values: arrays with user data
+ * @since 3.1.4-RC1
+ */
+ $vars = array('mode', 'reason', 'activated', 'deactivated', 'user_id_ary', 'sql_statements');
+ extract($phpbb_dispatcher->trigger_event('core.user_active_flip_after', compact($vars)));
+
if ($deactivated)
{
set_config_count('num_users', $deactivated * (-1), true);
diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php
index 0c6acaa908..c18ca1aa1d 100644
--- a/phpBB/includes/mcp/mcp_forum.php
+++ b/phpBB/includes/mcp/mcp_forum.php
@@ -165,6 +165,22 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.') . "
$limit_time_sql
ORDER BY t.topic_type DESC, $sort_order_sql";
+
+ /**
+ * Modify SQL query before MCP forum view topic list is queried
+ *
+ * @event core.mcp_view_forum_modify_sql
+ * @var string sql SQL query for forum view topic list
+ * @var int forum_id ID of the forum
+ * @var string limit_time_sql SQL query part for limit time
+ * @var string sort_order_sql SQL query part for sort order
+ * @var int topics_per_page Number of topics per page
+ * @var int start Start value
+ * @since 3.1.2-RC1
+ */
+ $vars = array('sql', 'forum_id', 'limit_time_sql', 'sort_order_sql', 'topics_per_page', 'start');
+ extract($phpbb_dispatcher->trigger_event('core.mcp_view_forum_modify_sql', compact($vars)));
+
$result = $db->sql_query_limit($sql, $topics_per_page, $start);
$topic_list = $topic_tracking_info = array();
diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php
index ebcf7ce643..500db55456 100644
--- a/phpBB/includes/mcp/mcp_front.php
+++ b/phpBB/includes/mcp/mcp_front.php
@@ -234,6 +234,7 @@ function mcp_front_view($id, $mode, $action)
'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);
}
$template->assign_vars(array(
@@ -290,6 +291,7 @@ function mcp_front_view($id, $mode, $action)
$pm_by_id[(int) $row['msg_id']] = $row;
$pm_list[] = (int) $row['msg_id'];
}
+ $db->sql_freeresult($result);
$address_list = get_recipient_strings($pm_by_id);
diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php
index 92dcdb5499..9c76f0df90 100644
--- a/phpBB/includes/mcp/mcp_logs.php
+++ b/phpBB/includes/mcp/mcp_logs.php
@@ -137,7 +137,7 @@ class mcp_logs
if ($mode == 'topic_logs')
{
- $conditions['topic_logs'] = $topic_id;
+ $conditions['topic_id'] = $topic_id;
}
$phpbb_log->delete('mod', $conditions);
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index 19a0ee3051..1241b8bd0e 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -813,8 +813,17 @@ function mcp_delete_topic($topic_ids, $is_soft = false, $soft_delete_reason = ''
$user->add_lang('posting');
+ // If there are only shadow topics, we neither need a reason nor softdelete
+ $sql = 'SELECT topic_id
+ FROM ' . TOPICS_TABLE . '
+ WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . '
+ AND topic_moved_id = 0';
+ $result = $db->sql_query_limit($sql, 1);
+ $only_shadow = !$db->sql_fetchfield('topic_id');
+ $db->sql_freeresult($result);
+
$only_softdeleted = false;
- if ($auth->acl_get('m_delete', $forum_id) && $auth->acl_get('m_softdelete', $forum_id))
+ if (!$only_shadow && $auth->acl_get('m_delete', $forum_id) && $auth->acl_get('m_softdelete', $forum_id))
{
// If there are only soft deleted topics, we display a message why the option is not available
$sql = 'SELECT topic_id
@@ -827,6 +836,7 @@ function mcp_delete_topic($topic_ids, $is_soft = false, $soft_delete_reason = ''
}
$template->assign_vars(array(
+ 'S_SHADOW_TOPICS' => $only_shadow,
'S_SOFTDELETED' => $only_softdeleted,
'S_TOPIC_MODE' => true,
'S_ALLOWED_DELETE' => $auth->acl_get('m_delete', $forum_id),
@@ -839,7 +849,7 @@ function mcp_delete_topic($topic_ids, $is_soft = false, $soft_delete_reason = ''
$l_confirm .= '_PERMANENTLY';
$s_hidden_fields['delete_permanent'] = '1';
}
- else if (!$auth->acl_get('m_softdelete', $forum_id))
+ else if ($only_shadow || !$auth->acl_get('m_softdelete', $forum_id))
{
$s_hidden_fields['delete_permanent'] = '1';
}
@@ -1266,6 +1276,7 @@ function mcp_fork_topic($topic_ids)
$db->sql_query('INSERT INTO ' . POLL_OPTIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
}
+ $db->sql_freeresult($result);
}
$sql = 'SELECT *
diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php
index f9c00da3ec..82c3bc9ab0 100644
--- a/phpBB/includes/mcp/mcp_queue.php
+++ b/phpBB/includes/mcp/mcp_queue.php
@@ -616,7 +616,7 @@ class mcp_queue
*/
static public function approve_posts($action, $post_id_list, $id, $mode)
{
- global $db, $template, $user, $config, $request, $phpbb_container;
+ global $db, $template, $user, $config, $request, $phpbb_container, $phpbb_dispatcher;
global $phpEx, $phpbb_root_path;
if (!phpbb_check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve')))
@@ -764,6 +764,30 @@ class mcp_queue
$success_msg = (sizeof($post_info) == 1) ? 'POST_' . strtoupper($action) . 'D_SUCCESS' : 'POSTS_' . strtoupper($action) . 'D_SUCCESS';
}
+ /**
+ * Perform additional actions during post(s) approval
+ *
+ * @event core.approve_posts_after
+ * @var string action Variable containing the action we perform on the posts ('approve' or 'restore')
+ * @var array post_info Array containing info for all posts being approved
+ * @var array topic_info Array containing info for all parent topics of the posts
+ * @var int num_topics Variable containing number of topics
+ * @var bool notify_poster Variable telling if the post should be notified or not
+ * @var string success_msg Variable containing the language key for the success message
+ * @var string redirect Variable containing the redirect url
+ * @since 3.1.4-RC1
+ */
+ $vars = array(
+ 'action',
+ 'post_info',
+ 'topic_info',
+ 'num_topics',
+ 'notify_poster',
+ 'success_msg',
+ 'redirect',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.approve_posts_after', compact($vars)));
+
meta_refresh(3, $redirect);
$message = $user->lang[$success_msg];
@@ -840,7 +864,7 @@ class mcp_queue
static public function approve_topics($action, $topic_id_list, $id, $mode)
{
global $db, $template, $user, $config;
- global $phpEx, $phpbb_root_path, $request, $phpbb_container;
+ global $phpEx, $phpbb_root_path, $request, $phpbb_container, $phpbb_dispatcher;
if (!phpbb_check_ids($topic_id_list, TOPICS_TABLE, 'topic_id', array('m_approve')))
{
@@ -945,6 +969,28 @@ class mcp_queue
}
}
+ /**
+ * Perform additional actions during topics(s) approval
+ *
+ * @event core.approve_topics_after
+ * @var string action Variable containing the action we perform on the posts ('approve' or 'restore')
+ * @var mixed topic_info Array containing info for all topics being approved
+ * @var array first_post_ids Array containing ids of all first posts
+ * @var bool notify_poster Variable telling if the poster should be notified or not
+ * @var string success_msg Variable containing the language key for the success message
+ * @var string redirect Variable containing the redirect url
+ * @since 3.1.4-RC1
+ */
+ $vars = array(
+ 'action',
+ 'topic_info',
+ 'first_post_ids',
+ 'notify_poster',
+ 'success_msg',
+ 'redirect',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.approve_topics_after', compact($vars)));
+
meta_refresh(3, $redirect);
$message = $user->lang[$success_msg];
@@ -1008,7 +1054,7 @@ class mcp_queue
*/
static public function disapprove_posts($post_id_list, $id, $mode)
{
- global $db, $template, $user, $config, $phpbb_container;
+ global $db, $template, $user, $config, $phpbb_container, $phpbb_dispatcher;
global $phpEx, $phpbb_root_path, $request;
if (!phpbb_check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve')))
@@ -1239,8 +1285,6 @@ class mcp_queue
}
}
- unset($lang_reasons, $post_info, $disapprove_reason, $disapprove_reason_lang);
-
if ($num_disapproved_topics)
{
$success_msg = ($num_disapproved_topics == 1) ? 'TOPIC' : 'TOPICS';
@@ -1275,6 +1319,44 @@ class mcp_queue
}
}
+ /**
+ * Perform additional actions during post(s) disapproval
+ *
+ * @event core.disapprove_posts_after
+ * @var array post_info Array containing info for all posts being disapproved
+ * @var array topic_information Array containing information for the topics
+ * @var array topic_posts_unapproved Array containing list of topic ids and the count of disapproved posts in them
+ * @var array post_disapprove_list Array containing list of posts and their topic id
+ * @var int num_disapproved_topics Variable containing the number of disapproved topics
+ * @var int num_disapproved_posts Variable containing the number of disapproved posts
+ * @var array lang_reasons Array containing the language keys for reasons
+ * @var string disapprove_reason Variable containing the language key for the success message
+ * @var string disapprove_reason_lang Variable containing the language key for the success message
+ * @var bool is_disapproving Variable telling if anything is going to be disapproved
+ * @var bool notify_poster Variable telling if the post should be notified or not
+ * @var string success_msg Variable containing the language key for the success message
+ * @var string redirect Variable containing the redirect url
+ * @since 3.1.4-RC1
+ */
+ $vars = array(
+ 'post_info',
+ 'topic_information',
+ 'topic_posts_unapproved',
+ 'post_disapprove_list',
+ 'num_disapproved_topics',
+ 'num_disapproved_posts',
+ 'lang_reasons',
+ 'disapprove_reason',
+ 'disapprove_reason_lang',
+ 'is_disapproving',
+ 'notify_poster',
+ 'success_msg',
+ 'redirect',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.disapprove_posts_after', compact($vars)));
+
+ unset($lang_reasons, $post_info, $disapprove_reason, $disapprove_reason_lang);
+
meta_refresh(3, $redirect);
$message = $user->lang[$success_msg];
diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php
index 1698b080c9..3a456169d5 100644
--- a/phpBB/includes/mcp/mcp_topic.php
+++ b/phpBB/includes/mcp/mcp_topic.php
@@ -25,7 +25,7 @@ if (!defined('IN_PHPBB'))
function mcp_topic_view($id, $mode, $action)
{
global $phpEx, $phpbb_root_path, $config;
- global $template, $db, $user, $auth, $cache, $phpbb_container;
+ global $template, $db, $user, $auth, $cache, $phpbb_container, $phpbb_dispatcher;
$url = append_sid("{$phpbb_root_path}mcp.$phpEx?" . phpbb_extra_url());
@@ -228,7 +228,7 @@ function mcp_topic_view($id, $mode, $action)
$post_unread = (isset($topic_tracking_info[$topic_id]) && $row['post_time'] > $topic_tracking_info[$topic_id]) ? true : false;
- $template->assign_block_vars('postrow', array(
+ $post_row = array(
'POST_AUTHOR_FULL' => get_username_string('full', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
'POST_AUTHOR_COLOUR' => get_username_string('colour', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
'POST_AUTHOR' => get_username_string('username', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
@@ -250,9 +250,39 @@ function mcp_topic_view($id, $mode, $action)
'U_POST_DETAILS' => "$url&amp;i=$id&amp;p={$row['post_id']}&amp;mode=post_details" . (($forum_id) ? "&amp;f=$forum_id" : ''),
'U_MCP_APPROVE' => ($auth->acl_get('m_approve', $topic_info['forum_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=approve_details&amp;f=' . $topic_info['forum_id'] . '&amp;p=' . $row['post_id']) : '',
- 'U_MCP_REPORT' => ($auth->acl_get('m_report', $topic_info['forum_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=report_details&amp;f=' . $topic_info['forum_id'] . '&amp;p=' . $row['post_id']) : '')
+ 'U_MCP_REPORT' => ($auth->acl_get('m_report', $topic_info['forum_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=report_details&amp;f=' . $topic_info['forum_id'] . '&amp;p=' . $row['post_id']) : '',
);
+ $current_row_number = $i;
+
+ /**
+ * Event to modify the template data block for topic reviews in the MCP
+ *
+ * @event core.mcp_topic_review_modify_row
+ * @var int id ID of the tab we are displaying
+ * @var string mode Mode of the MCP page we are displaying
+ * @var int topic_id The topic ID we are currently reviewing
+ * @var int forum_id The forum ID we are currently in
+ * @var int start Start item of this page
+ * @var int current_row_number Number of the post on this page
+ * @var array post_row Template block array of the current post
+ * @var array row Array with original post and user data
+ * @since 3.1.4-RC1
+ */
+ $vars = array(
+ 'id',
+ 'mode',
+ 'topic_id',
+ 'forum_id',
+ 'start',
+ 'current_row_number',
+ 'post_row',
+ 'row',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_topic_review_modify_row', compact($vars)));
+
+ $template->assign_block_vars('postrow', $post_row);
+
// Display not already displayed Attachments for this post, we already parsed them. ;)
if (!empty($attachments[$row['post_id']]))
{
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php
index 92ace7b585..04a2726d22 100644
--- a/phpBB/includes/message_parser.php
+++ b/phpBB/includes/message_parser.php
@@ -313,7 +313,7 @@ class bbcode_firstpass extends bbcode
$in = str_replace(' ', '%20', $in);
// Checking urls
- if (!preg_match('#^' . get_preg_expression('url') . '$#i', $in) && !preg_match('#^' . get_preg_expression('www_url') . '$#i', $in))
+ if (!preg_match('#^' . get_preg_expression('url') . '$#iu', $in) && !preg_match('#^' . get_preg_expression('www_url') . '$#iu', $in))
{
return '[img]' . $in . '[/img]';
}
@@ -381,8 +381,8 @@ class bbcode_firstpass extends bbcode
$in = str_replace(' ', '%20', $in);
// Make sure $in is a URL.
- if (!preg_match('#^' . get_preg_expression('url') . '$#i', $in) &&
- !preg_match('#^' . get_preg_expression('www_url') . '$#i', $in))
+ if (!preg_match('#^' . get_preg_expression('url') . '$#iu', $in) &&
+ !preg_match('#^' . get_preg_expression('www_url') . '$#iu', $in))
{
return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
}
@@ -973,9 +973,9 @@ class bbcode_firstpass extends bbcode
$url = str_replace(' ', '%20', $url);
// Checking urls
- if (preg_match('#^' . get_preg_expression('url') . '$#i', $url) ||
- preg_match('#^' . get_preg_expression('www_url') . '$#i', $url) ||
- preg_match('#^' . preg_quote(generate_board_url(), '#') . get_preg_expression('relative_url') . '$#i', $url))
+ if (preg_match('#^' . get_preg_expression('url') . '$#iu', $url) ||
+ preg_match('#^' . get_preg_expression('www_url') . '$#iu', $url) ||
+ preg_match('#^' . preg_quote(generate_board_url(), '#') . get_preg_expression('relative_url') . '$#iu', $url))
{
$valid = true;
}
@@ -1103,7 +1103,7 @@ class parse_message extends bbcode_firstpass
*/
function parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $update_this_message = true, $mode = 'post')
{
- global $config, $db, $user;
+ global $config, $db, $user, $phpbb_dispatcher;
$this->mode = $mode;
@@ -1158,6 +1158,58 @@ class parse_message extends bbcode_firstpass
}
}
+ /**
+ * This event can be used for additional message checks/cleanup before parsing
+ *
+ * @event core.message_parser_check_message
+ * @var bool allow_bbcode Do we allow BBCodes
+ * @var bool allow_magic_url Do we allow magic urls
+ * @var bool allow_smilies Do we allow smilies
+ * @var bool allow_img_bbcode Do we allow image BBCode
+ * @var bool allow_flash_bbcode Do we allow flash BBCode
+ * @var bool allow_quote_bbcode Do we allow quote BBCode
+ * @var bool allow_url_bbcode Do we allow url BBCode
+ * @var bool update_this_message Do we alter the parsed message
+ * @var string mode Posting mode
+ * @var string message The message text to parse
+ * @var string bbcode_bitfield The bbcode_bitfield before parsing
+ * @var string bbcode_uid The bbcode_uid before parsing
+ * @var bool return Do we return after the event is triggered if $warn_msg is not empty
+ * @var array warn_msg Array of the warning messages
+ * @since 3.1.2-RC1
+ * @change 3.1.3-RC1 Added vars $bbcode_bitfield and $bbcode_uid
+ */
+ $message = $this->message;
+ $warn_msg = $this->warn_msg;
+ $return = false;
+ $bbcode_bitfield = $this->bbcode_bitfield;
+ $bbcode_uid = $this->bbcode_uid;
+ $vars = array(
+ 'allow_bbcode',
+ 'allow_magic_url',
+ 'allow_smilies',
+ 'allow_img_bbcode',
+ 'allow_flash_bbcode',
+ 'allow_quote_bbcode',
+ 'allow_url_bbcode',
+ 'update_this_message',
+ 'mode',
+ 'message',
+ 'bbcode_bitfield',
+ 'bbcode_uid',
+ 'return',
+ 'warn_msg',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.message_parser_check_message', compact($vars)));
+ $this->message = $message;
+ $this->warn_msg = $warn_msg;
+ $this->bbcode_bitfield = $bbcode_bitfield;
+ $this->bbcode_uid = $bbcode_uid;
+ if ($return && !empty($this->warn_msg))
+ {
+ return (!$update_this_message) ? $return_message : $this->warn_msg;
+ }
+
// Prepare BBcode (just prepares some tags for better parsing)
if ($allow_bbcode && strpos($this->message, '[') !== false)
{
diff --git a/phpBB/includes/startup.php b/phpBB/includes/startup.php
index 50fcd11bee..2885c80541 100644
--- a/phpBB/includes/startup.php
+++ b/phpBB/includes/startup.php
@@ -69,31 +69,13 @@ function deregister_globals()
{
if (isset($not_unset[$varname]))
{
- // Hacking attempt. No point in continuing unless it's a COOKIE (so a cookie called GLOBALS doesn't lock users out completely)
- if ($varname !== 'GLOBALS' || isset($_GET['GLOBALS']) || isset($_POST['GLOBALS']) || isset($_SERVER['GLOBALS']) || isset($_SESSION['GLOBALS']) || isset($_ENV['GLOBALS']) || isset($_FILES['GLOBALS']))
+ // Hacking attempt. No point in continuing.
+ if (isset($_COOKIE[$varname]))
{
- exit;
- }
- else
- {
- $cookie = &$_COOKIE;
- while (isset($cookie['GLOBALS']))
- {
- if (!is_array($cookie['GLOBALS']))
- {
- break;
- }
-
- foreach ($cookie['GLOBALS'] as $registered_var => $value)
- {
- if (!isset($not_unset[$registered_var]))
- {
- unset($GLOBALS[$registered_var]);
- }
- }
- $cookie = &$cookie['GLOBALS'];
- }
+ echo "Clear your cookies. ";
}
+ echo "Malicious variable name detected. Contact the administrator and ask them to disable register_globals.";
+ exit;
}
unset($GLOBALS[$varname]);
diff --git a/phpBB/includes/ucp/ucp_login_link.php b/phpBB/includes/ucp/ucp_login_link.php
index 27d59c56b7..bfe4804286 100644
--- a/phpBB/includes/ucp/ucp_login_link.php
+++ b/phpBB/includes/ucp/ucp_login_link.php
@@ -75,7 +75,7 @@ class ucp_login_link
{
if ($request->is_set_post('login'))
{
- $login_username = $request->variable('login_username', '', false, \phpbb\request\request_interface::POST);
+ $login_username = $request->variable('login_username', '', true, \phpbb\request\request_interface::POST);
$login_password = $request->untrimmed_variable('login_password', '', true, \phpbb\request\request_interface::POST);
$login_result = $auth_provider->login($login_username, $login_password);
diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php
index 2195500b57..1d3fb19f67 100644
--- a/phpBB/includes/ucp/ucp_prefs.php
+++ b/phpBB/includes/ucp/ucp_prefs.php
@@ -67,9 +67,11 @@ class ucp_prefs
* @var bool submit Do we display the form only
* or did the user press submit
* @var array data Array with current ucp options data
+ * @var array error Array with list of errors
* @since 3.1.0-a1
+ * @changed 3.1.4-rc1 Added error variable to the event
*/
- $vars = array('submit', 'data');
+ $vars = array('submit', 'data', 'error');
extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_personal_data', compact($vars)));
if ($submit)
@@ -83,11 +85,11 @@ class ucp_prefs
$data['user_style'] = (int) $user->data['user_style'];
}
- $error = validate_data($data, array(
+ $error = array_merge(validate_data($data, array(
'dateformat' => array('string', false, 1, 30),
'lang' => array('language_iso_name'),
'tz' => array('timezone'),
- ));
+ )), $error);
if (!check_form_key('ucp_prefs_personal'))
{
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index a876d0133a..c1cdcf88ca 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -32,7 +32,7 @@ class ucp_profile
function main($id, $mode)
{
global $cache, $config, $db, $user, $auth, $template, $phpbb_root_path, $phpEx;
- global $request, $phpbb_container;
+ global $request, $phpbb_container, $phpbb_dispatcher;
$user->add_lang('posting');
@@ -54,6 +54,17 @@ class ucp_profile
'password_confirm' => $request->variable('password_confirm', '', true),
);
+ /**
+ * Modify user registration data on editing account settings in UCP
+ *
+ * @event core.ucp_profile_reg_details_data
+ * @var array data Array with current or updated user registration data
+ * @var bool submit Flag indicating if submit button has been pressed
+ * @since 3.1.4-RC1
+ */
+ $vars = array('data', 'submit');
+ extract($phpbb_dispatcher->trigger_event('core.ucp_profile_reg_details_data', compact($vars)));
+
add_form_key('ucp_reg_details');
if ($submit)
@@ -200,6 +211,17 @@ class ucp_profile
$sql_ary['user_newpasswd'] = '';
}
+ /**
+ * Modify user registration data before submitting it to the database
+ *
+ * @event core.ucp_profile_reg_details_sql_ary
+ * @var array data Array with current or updated user registration data
+ * @var array sql_ary Array with user registration data to submit to the database
+ * @since 3.1.4-RC1
+ */
+ $vars = array('data', 'sql_ary');
+ extract($phpbb_dispatcher->trigger_event('core.ucp_profile_reg_details_sql_ary', compact($vars)));
+
if (sizeof($sql_ary))
{
$sql = 'UPDATE ' . USERS_TABLE . '
@@ -285,6 +307,17 @@ class ucp_profile
$data['user_birthday'] = sprintf('%2d-%2d-%4d', $data['bday_day'], $data['bday_month'], $data['bday_year']);
}
+ /**
+ * Modify user data on editing profile in UCP
+ *
+ * @event core.ucp_profile_modify_profile_info
+ * @var array data Array with user profile data
+ * @var bool submit Flag indicating if submit button has been pressed
+ * @since 3.1.4-RC1
+ */
+ $vars = array('data', 'submit');
+ extract($phpbb_dispatcher->trigger_event('core.ucp_profile_modify_profile_info', compact($vars)));
+
add_form_key('ucp_profile_info');
if ($submit)
@@ -341,6 +374,17 @@ class ucp_profile
$sql_ary['user_birthday'] = $data['user_birthday'];
}
+ /**
+ * Modify profile data in UCP before submitting to the database
+ *
+ * @event core.ucp_profile_info_modify_sql_ary
+ * @var array cp_data Array with the user custom profile fields data
+ * @var array data Array with user profile data
+ * @since 3.1.4-RC1
+ */
+ $vars = array('cp_data', 'data');
+ extract($phpbb_dispatcher->trigger_event('core.ucp_profile_info_modify_sql_ary', compact($vars)));
+
$sql = 'UPDATE ' . USERS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
WHERE user_id = ' . $user->data['user_id'];
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 88078c10af..14f6a8bc02 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -33,7 +33,8 @@ class ucp_register
global $request, $phpbb_container;
//
- if ($config['require_activation'] == USER_ACTIVATION_DISABLE)
+ if ($config['require_activation'] == USER_ACTIVATION_DISABLE ||
+ (in_array($config['require_activation'], array(USER_ACTIVATION_SELF, USER_ACTIVATION_ADMIN)) && !$config['email_enable']))
{
trigger_error('UCP_REGISTER_DISABLE');
}