diff options
Diffstat (limited to 'phpBB/includes')
27 files changed, 448 insertions, 172 deletions
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..fcc2bd7641 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) @@ -272,7 +319,7 @@ class acp_email '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&form=acp_email&field=usernames'), 'SUBJECT' => $subject, 'MESSAGE' => $message, 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_styles.php b/phpBB/includes/acp/acp_styles.php index 42c67a88b5..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) @@ -70,11 +87,6 @@ class acp_styles $action = $this->request->variable('action', ''); $post_actions = array('install', 'activate', 'deactivate', 'uninstall'); - if ($action && in_array($action, $post_actions) && !check_link_hash($request->variable('hash', ''), $action)) - { - trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); - } - foreach ($post_actions as $key) { if ($this->request->is_set_post($key)) @@ -83,6 +95,18 @@ class acp_styles } } + // The uninstall action uses confirm_box() to verify the validity of the request, + // so there is no need to check for a valid token here. + if (in_array($action, $post_actions) && $action != 'uninstall') + { + $is_valid_request = check_link_hash($request->variable('hash', ''), $action) || check_form_key('styles_management'); + + if (!$is_valid_request) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); + } + } + if ($action != '') { $this->s_hidden_fields['action'] = $action; @@ -122,6 +146,8 @@ class acp_styles */ protected function frontend() { + add_form_key('styles_management'); + // Check mode switch ($this->mode) { @@ -155,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) { @@ -800,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) @@ -1082,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..881e50dd5a 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) 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 6693b822fe..0ac9208aa4 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.0-RC6-dev'); +define('PHPBB_VERSION', '3.1.3-RC1-dev'); // QA-related // define('PHPBB_QA', 1); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 169c741ecf..97429a0be4 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2903,6 +2903,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 @@ -3308,23 +3321,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': @@ -5235,7 +5258,7 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler = // Call cron-type script $call_cron = false; - if (!defined('IN_CRON') && !$config['use_system_cron'] && $run_cron && !$config['board_disable'] && !$user->data['is_bot'] && !$cache->get('cron.lock_check')) + if (!defined('IN_CRON') && !$config['use_system_cron'] && $run_cron && !$config['board_disable'] && !$user->data['is_bot'] && !$cache->get('_cron.lock_check')) { $call_cron = true; $time_now = (!empty($user->time_now) && is_int($user->time_now)) ? $user->time_now : time(); @@ -5267,7 +5290,7 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler = } else { - $cache->put('cron.lock_check', true, 300); + $cache->put('_cron.lock_check', true, 60); } } 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_compatibility.php b/phpBB/includes/functions_compatibility.php index fbb1f0e03d..43952ae57a 100644 --- a/phpBB/includes/functions_compatibility.php +++ b/phpBB/includes/functions_compatibility.php @@ -101,18 +101,21 @@ function phpbb_clean_path($path) } else if (!$phpbb_path_helper) { + global $phpbb_root_path, $phpEx; + // The container is not yet loaded, use a new instance if (!class_exists('\phpbb\path_helper')) { - global $phpbb_root_path, $phpEx; require($phpbb_root_path . 'phpbb/path_helper.' . $phpEx); } + $request = new phpbb\request\request(); $phpbb_path_helper = new phpbb\path_helper( new phpbb\symfony_request( - new phpbb\request\request() + $request ), new phpbb\filesystem(), + $request, $phpbb_root_path, $phpEx ); diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php index 25ca50e8f1..87cf34bd9d 100644 --- a/phpBB/includes/functions_content.php +++ b/phpBB/includes/functions_content.php @@ -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_display.php b/phpBB/includes/functions_display.php index 745eb20c77..31cf43e599 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -1491,7 +1491,7 @@ function phpbb_get_user_rank($user_data, $user_posts) /** * Prepare profile data */ -function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabled = false) +function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabled = false, $check_can_receive_pm = true) { global $config, $auth, $user, $phpEx, $phpbb_root_path, $phpbb_dispatcher; @@ -1559,7 +1559,7 @@ function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabl } // Can this user receive a Private Message? - $can_receive_pm = ( + $can_receive_pm = $check_can_receive_pm && ( // They must be a "normal" user $data['user_type'] != USER_IGNORE && @@ -1608,8 +1608,8 @@ function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabl 'U_EMAIL' => $email, 'U_JABBER' => ($data['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=jabber&u=' . $user_id) : '', - 'USER_JABBER' => $data['user_jabber'], - 'USER_JABBER_IMG' => ($data['user_jabber']) ? $user->img('icon_contact_jabber', $data['user_jabber']) : '', + 'USER_JABBER' => ($config['jab_enable']) ? $data['user_jabber'] : '', + 'USER_JABBER_IMG' => ($config['jab_enable'] && $data['user_jabber']) ? $user->img('icon_contact_jabber', $data['user_jabber']) : '', 'L_SEND_EMAIL_USER' => $user->lang('SEND_EMAIL_USER', $username), 'L_CONTACT_USER' => $user->lang('CONTACT_USER', $username), diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index af44f6270e..22ade15b48 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -1825,6 +1825,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 ad142b1cca..838c6a0fec 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -914,6 +914,24 @@ function update_unread_status($unread, $msg_id, $user_id, $folder_id) } } +function mark_folder_read($user_id, $folder_id) +{ + global $db; + + $sql = 'SELECT msg_id + FROM ' . PRIVMSGS_TO_TABLE . ' + WHERE folder_id = ' . ((int) $folder_id) . ' + AND user_id = ' . ((int) $user_id) . ' + AND pm_unread = 1'; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + update_unread_status(true, $row['msg_id'], $user_id, $folder_id); + } + $db->sql_freeresult($result); +} + /** * Handle all actions possible with marked messages */ diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index e4479f07b0..f79a8998c4 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -161,9 +161,10 @@ function user_update_name($old_name, $new_name) * * @param mixed $user_row An array containing the following keys (and the appropriate values): username, group_id (the group to place the user in), user_email and the user_type(usually 0). Additional entries not overridden by defaults will be forwarded. * @param string $cp_data custom profile fields, see custom_profile::build_insert_sql_array +* @param array $notifications_data The notifications settings for the new user * @return the new user's ID. */ -function user_add($user_row, $cp_data = false) +function user_add($user_row, $cp_data = false, $notifications_data = null) { global $db, $user, $auth, $config, $phpbb_root_path, $phpEx; global $phpbb_dispatcher, $phpbb_container; @@ -347,6 +348,31 @@ function user_add($user_row, $cp_data = false) set_config('newest_user_colour', $row['group_colour'], true); } + // Use default notifications settings if notifications_data is not set + if ($notifications_data === null) + { + $notifications_data = array( + array( + 'item_type' => 'notification.type.post', + 'method' => 'notification.method.email', + ), + array( + 'item_type' => 'notification.type.topic', + 'method' => 'notification.method.email', + ), + ); + } + + // Subscribe user to notifications if necessary + if (!empty($notifications_data)) + { + $phpbb_notifications = $phpbb_container->get('notification_manager'); + foreach ($notifications_data as $subscription) + { + $phpbb_notifications->add_subscription($subscription['item_type'], 0, $subscription['method'], $user_id); + } + } + /** * Event that returns user id, user detals and user CPF of newly registared user * 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_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..227ae84bd6 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'; } 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_auth_link.php b/phpBB/includes/ucp/ucp_auth_link.php index a595ce46c3..748f0fdec2 100644 --- a/phpBB/includes/ucp/ucp_auth_link.php +++ b/phpBB/includes/ucp/ucp_auth_link.php @@ -34,11 +34,12 @@ class ucp_auth_link */ public function main($id, $mode) { - global $config, $request, $template, $phpbb_container, $user; + global $request, $template, $phpbb_container, $user; $error = array(); - $auth_provider = $phpbb_container->get('auth.provider.' . $config['auth_method']); + $provider_collection = $phpbb_container->get('auth.provider_collection'); + $auth_provider = $provider_collection->get_provider(); // confirm that the auth provider supports this page $provider_data = $auth_provider->get_auth_link_data(); diff --git a/phpBB/includes/ucp/ucp_login_link.php b/phpBB/includes/ucp/ucp_login_link.php index 5ca5df00f7..bfe4804286 100644 --- a/phpBB/includes/ucp/ucp_login_link.php +++ b/phpBB/includes/ucp/ucp_login_link.php @@ -39,7 +39,7 @@ class ucp_login_link */ function main($id, $mode) { - global $config, $phpbb_container, $request, $template, $user; + global $phpbb_container, $request, $template, $user; global $phpbb_root_path, $phpEx; // Initialize necessary variables @@ -57,8 +57,8 @@ class ucp_login_link } // Use the auth_provider requested even if different from configured - $auth_provider = 'auth.provider.' . $request->variable('auth_provider', $config['auth_method']); - $auth_provider = $phpbb_container->get($auth_provider); + $provider_collection = $phpbb_container->get('auth.provider_collection'); + $auth_provider = $provider_collection->get_provider($request->variable('auth_provider', '')); // Set the link_method to login_link $data['link_method'] = 'login_link'; @@ -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_pm.php b/phpBB/includes/ucp/ucp_pm.php index 7a8c694870..425a56cf6c 100644 --- a/phpBB/includes/ucp/ucp_pm.php +++ b/phpBB/includes/ucp/ucp_pm.php @@ -45,7 +45,7 @@ class ucp_pm function main($id, $mode) { - global $user, $template, $phpbb_root_path, $auth, $phpEx, $db, $config; + global $user, $template, $phpbb_root_path, $auth, $phpEx, $db, $config, $request; if (!$user->data['is_registered']) { @@ -246,6 +246,27 @@ class ucp_pm $folder_id = (int) $row['folder_id']; } + if ($request->variable('mark', '') == 'all' && check_link_hash($request->variable('token', ''), 'mark_all_pms_read')) + { + mark_folder_read($user->data['user_id'], $folder_id); + + meta_refresh(3, $this->u_action); + $message = $user->lang['PM_MARK_ALL_READ_SUCCESS']; + + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response(); + $json_response->send(array( + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], + 'MESSAGE_TEXT' => $message, + 'success' => true, + )); + } + $message .= '<br /><br />' . $user->lang('RETURN_UCP', '<a href="' . $this->u_action . '">', '</a>'); + + trigger_error($message); + } + $message_row = array(); if ($action == 'view_message' && $msg_id) { @@ -332,6 +353,7 @@ class ucp_pm 'U_SENTBOX' => $this->u_action . '&folder=sentbox', 'U_CREATE_FOLDER' => $this->u_action . '&mode=options', 'U_CURRENT_FOLDER' => $this->u_action . '&folder=' . $folder_id, + 'U_MARK_ALL' => $this->u_action . '&folder=' . $folder_id . '&mark=all&token=' . generate_link_hash('mark_all_pms_read'), 'S_IN_INBOX' => ($folder_id == PRIVMSGS_INBOX) ? true : false, 'S_IN_OUTBOX' => ($folder_id == PRIVMSGS_OUTBOX) ? true : false, diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index 2f34fd64a5..888c2e6825 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -197,7 +197,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) $u_pm = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose&u=' . $author_id); } - if ($user_info['user_jabber'] && $auth->acl_get('u_sendim')) + if ($config['jab_enable'] && $user_info['user_jabber'] && $auth->acl_get('u_sendim')) { $u_jabber = append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=jabber&u=' . $author_id); } @@ -213,6 +213,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) 'AUTHOR_AVATAR' => (isset($user_info['avatar'])) ? $user_info['avatar'] : '', 'AUTHOR_JOINED' => $user->format_date($user_info['user_regdate']), 'AUTHOR_POSTS' => (int) $user_info['user_posts'], + 'U_AUTHOR_POSTS' => ($config['load_search'] && $auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id=$author_id&sr=posts") : '', 'CONTACT_USER' => $user->lang('CONTACT_USER', get_username_string('username', $author_id, $user_info['username'], $user_info['user_colour'], $user_info['username'])), 'ONLINE_IMG' => (!$config['load_onlinetrack']) ? '' : ((isset($user_info['online']) && $user_info['online']) ? $user->img('icon_user_online', $user->lang['ONLINE']) : $user->img('icon_user_offline', $user->lang['OFFLINE'])), diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 361dc831aa..a876d0133a 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -655,9 +655,14 @@ class ucp_profile { if (!empty($keys)) { + foreach ($keys as $key => $id) + { + $keys[$key] = $db->sql_like_expression($id . $db->get_any_char()); + } + $sql_where = '(key_id ' . implode(' OR key_id ', $keys) . ')'; $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . ' WHERE user_id = ' . (int) $user->data['user_id'] . ' - AND ' . $db->sql_in_set('key_id', $keys) ; + AND ' . $sql_where ; $db->sql_query($sql); @@ -681,7 +686,7 @@ class ucp_profile while ($row = $db->sql_fetchrow($result)) { $template->assign_block_vars('sessions', array( - 'KEY' => $row['key_id'], + 'KEY' => substr($row['key_id'], 0, 8), 'IP' => $row['last_ip'], 'LOGIN_TIME' => $user->format_date($row['last_login']), )); diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 9a15967bae..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'); } @@ -87,8 +88,8 @@ class ucp_register if (!empty($login_link_data)) { // Confirm that we have all necessary data - $auth_provider = 'auth.provider.' . $request->variable('auth_provider', $config['auth_method']); - $auth_provider = $phpbb_container->get($auth_provider); + $provider_collection = $phpbb_container->get('auth.provider_collection'); + $auth_provider = $provider_collection->get_provider($request->variable('auth_provider', '')); $result = $auth_provider->login_link_has_necessary_data($login_link_data); if ($result !== null) |