diff options
Diffstat (limited to 'phpBB/includes')
81 files changed, 2456 insertions, 639 deletions
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index eccc935a6e..9d6c2d5de1 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -1163,7 +1163,7 @@ class acp_attachments $template->assign_vars(array( 'S_ACTION_OPTIONS' => ($auth->acl_get('a_board')) ? true : false, 'U_ACTION' => $this->u_action,) - ); + ); } // Make sure $start is set to the last page if it exceeds the amount @@ -1224,7 +1224,7 @@ class acp_attachments $base_url = $this->u_action . "&$u_sort_param"; phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_files, $attachments_per_page, $start); - + $template->assign_vars(array( 'TOTAL_FILES' => $num_files, 'TOTAL_SIZE' => get_formatted_filesize($total_size), diff --git a/phpBB/includes/acp/acp_ban.php b/phpBB/includes/acp/acp_ban.php index d275c7f10c..3ed9c225f5 100644 --- a/phpBB/includes/acp/acp_ban.php +++ b/phpBB/includes/acp/acp_ban.php @@ -97,7 +97,7 @@ class acp_ban break; } - $this->display_ban_options($mode); + self::display_ban_options($mode); $template->assign_vars(array( 'L_TITLE' => $this->page_title, @@ -118,7 +118,7 @@ class acp_ban /** * Display ban options */ - function display_ban_options($mode) + static public function display_ban_options($mode) { global $user, $db, $template; diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 575d05933f..322e1c55d8 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -53,6 +53,8 @@ class acp_board 'legend1' => 'ACP_BOARD_SETTINGS', 'sitename' => array('lang' => 'SITE_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false), 'site_desc' => array('lang' => 'SITE_DESC', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false), + 'site_home_url' => array('lang' => 'SITE_HOME_URL', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), + 'site_home_text' => array('lang' => 'SITE_HOME_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'board_disable' => array('lang' => 'DISABLE_BOARD', 'validate' => 'bool', 'type' => 'custom', 'method' => 'board_disable', 'explain' => true), 'board_disable_msg' => false, 'default_lang' => array('lang' => 'DEFAULT_LANGUAGE', 'validate' => 'lang', 'type' => 'select', 'function' => 'language_select', 'params' => array('{CONFIG_VALUE}'), 'explain' => false), diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php index 51b5dd3301..c7c64ae56b 100644 --- a/phpBB/includes/acp/acp_captcha.php +++ b/phpBB/includes/acp/acp_captcha.php @@ -29,7 +29,8 @@ class acp_captcha $user->add_lang('acp/board'); include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx); - $captchas = phpbb_captcha_factory::get_captcha_types(); + $factory = new phpbb_captcha_factory(); + $captchas = $factory->get_captcha_types(); $selected = request_var('select_captcha', $config['captcha_plugin']); $selected = (isset($captchas['available'][$selected]) || isset($captchas['unavailable'][$selected])) ? $selected : $config['captcha_plugin']; diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php new file mode 100644 index 0000000000..a0bcf62ecc --- /dev/null +++ b/phpBB/includes/acp/acp_extensions.php @@ -0,0 +1,303 @@ +<?php +/** +* +* @package acp +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* @package acp +*/ +class acp_extensions +{ + var $u_action; + + private $db; + private $config; + private $template; + private $user; + + function main() + { + // Start the page + global $config, $user, $template, $request, $phpbb_extension_manager, $db, $phpbb_root_path, $phpEx; + + $this->db = $db; + $this->config = $config; + $this->template = $template; + $this->user = $user; + + $user->add_lang(array('install', 'acp/extensions')); + + $this->page_title = 'ACP_EXTENSIONS'; + + $action = $request->variable('action', 'list'); + $ext_name = $request->variable('ext_name', ''); + + // Cancel action + if ($request->is_set_post('cancel')) + { + $action = 'list'; + $ext_name = ''; + } + + // If they've specified an extension, let's load the metadata manager and validate it. + if ($ext_name) + { + $md_manager = new phpbb_extension_metadata_manager($ext_name, $db, $phpbb_extension_manager, $phpbb_root_path, ".$phpEx", $template, $config); + + try + { + $md_manager->get_metadata('all'); + } + catch(phpbb_extension_exception $e) + { + trigger_error($e); + } + } + + // What are we doing? + switch ($action) + { + case 'list': + default: + $this->list_enabled_exts($phpbb_extension_manager); + $this->list_disabled_exts($phpbb_extension_manager); + $this->list_available_exts($phpbb_extension_manager); + + $this->tpl_name = 'acp_ext_list'; + break; + + case 'enable_pre': + if (!$md_manager->validate_enable()) + { + trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action)); + } + + if ($phpbb_extension_manager->enabled($ext_name)) + { + redirect($this->u_action); + } + + $this->tpl_name = 'acp_ext_enable'; + + $template->assign_vars(array( + 'PRE' => true, + 'U_ENABLE' => $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name), + )); + break; + + case 'enable': + if (!$md_manager->validate_enable()) + { + trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action)); + } + + if ($phpbb_extension_manager->enable_step($ext_name)) + { + $template->assign_var('S_NEXT_STEP', true); + + meta_refresh(0, $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name)); + } + + $this->tpl_name = 'acp_ext_enable'; + + $template->assign_vars(array( + 'U_RETURN' => $this->u_action . '&action=list', + )); + break; + + case 'disable_pre': + if (!$phpbb_extension_manager->enabled($ext_name)) + { + redirect($this->u_action); + } + + $this->tpl_name = 'acp_ext_disable'; + + $template->assign_vars(array( + 'PRE' => true, + 'U_DISABLE' => $this->u_action . '&action=disable&ext_name=' . urlencode($ext_name), + )); + break; + + case 'disable': + if ($phpbb_extension_manager->disable_step($ext_name)) + { + $template->assign_var('S_NEXT_STEP', true); + + meta_refresh(0, $this->u_action . '&action=disable&ext_name=' . urlencode($ext_name)); + } + + $this->tpl_name = 'acp_ext_disable'; + + $template->assign_vars(array( + 'U_RETURN' => $this->u_action . '&action=list', + )); + break; + + case 'purge_pre': + $this->tpl_name = 'acp_ext_purge'; + + $template->assign_vars(array( + 'PRE' => true, + 'U_PURGE' => $this->u_action . '&action=purge&ext_name=' . urlencode($ext_name), + )); + break; + + case 'purge': + if ($phpbb_extension_manager->purge_step($ext_name)) + { + $template->assign_var('S_NEXT_STEP', true); + + meta_refresh(0, $this->u_action . '&action=purge&ext_name=' . urlencode($ext_name)); + } + + $this->tpl_name = 'acp_ext_purge'; + + $template->assign_vars(array( + 'U_RETURN' => $this->u_action . '&action=list', + )); + break; + + case 'details': + // Output it to the template + $md_manager->output_template_data(); + + $template->assign_var('U_BACK', $this->u_action . '&action=list'); + + $this->tpl_name = 'acp_ext_details'; + break; + } + } + + /** + * Lists all the enabled extensions and dumps to the template + * + * @param $phpbb_extension_manager An instance of the extension manager + * @return null + */ + public function list_enabled_exts(phpbb_extension_manager $phpbb_extension_manager) + { + foreach ($phpbb_extension_manager->all_enabled() as $name => $location) + { + $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template); + + try + { + $this->template->assign_block_vars('enabled', array( + 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), + + 'U_DETAILS' => $this->u_action . '&action=details&ext_name=' . urlencode($name), + )); + + $this->output_actions('enabled', array( + 'DISABLE' => $this->u_action . '&action=disable_pre&ext_name=' . urlencode($name), + 'PURGE' => $this->u_action . '&action=purge_pre&ext_name=' . urlencode($name), + )); + } + catch(phpbb_extension_exception $e) + { + $this->template->assign_block_vars('disabled', array( + 'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $e), + )); + } + } + } + + /** + * Lists all the disabled extensions and dumps to the template + * + * @param $phpbb_extension_manager An instance of the extension manager + * @return null + */ + public function list_disabled_exts(phpbb_extension_manager $phpbb_extension_manager) + { + foreach ($phpbb_extension_manager->all_disabled() as $name => $location) + { + $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template); + + try + { + $this->template->assign_block_vars('disabled', array( + 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), + + 'U_DETAILS' => $this->u_action . '&action=details&ext_name=' . urlencode($name), + )); + + $this->output_actions('disabled', array( + 'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name), + 'PURGE' => $this->u_action . '&action=purge_pre&ext_name=' . urlencode($name), + )); + } + catch(phpbb_extension_exception $e) + { + $this->template->assign_block_vars('disabled', array( + 'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $e), + )); + } + } + } + + /** + * Lists all the available extensions and dumps to the template + * + * @param $phpbb_extension_manager An instance of the extension manager + * @return null + */ + public function list_available_exts(phpbb_extension_manager $phpbb_extension_manager) + { + $uninstalled = array_diff_key($phpbb_extension_manager->all_available(), $phpbb_extension_manager->all_configured()); + + foreach ($uninstalled as $name => $location) + { + $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template); + + try + { + $this->template->assign_block_vars('disabled', array( + 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), + + 'U_DETAILS' => $this->u_action . '&action=details&ext_name=' . urlencode($name), + )); + + $this->output_actions('disabled', array( + 'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name), + )); + } + catch(phpbb_extension_exception $e) + { + $this->template->assign_block_vars('disabled', array( + 'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $e), + )); + } + } + } + + /** + * Output actions to a block + * + * @param string $block + * @param array $actions + */ + private function output_actions($block, $actions) + { + foreach ($actions as $lang => $url) + { + $this->template->assign_block_vars($block . '.actions', array( + 'L_ACTION' => $this->user->lang($lang), + 'U_ACTION' => $url, + )); + } + } +} diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index f88fa76df1..9621407211 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -683,8 +683,8 @@ class acp_groups } $base_url = $this->u_action . "&action=$action&g=$group_id"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start); - + phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start); + $template->assign_vars(array( 'S_LIST' => true, 'S_GROUP_SPECIAL' => ($group_row['group_type'] == GROUP_SPECIAL) ? true : false, diff --git a/phpBB/includes/acp/acp_icons.php b/phpBB/includes/acp/acp_icons.php index b7be92d477..db4b4263b0 100644 --- a/phpBB/includes/acp/acp_icons.php +++ b/phpBB/includes/acp/acp_icons.php @@ -927,8 +927,8 @@ class acp_icons } } $db->sql_freeresult($result); - - phpbb_generate_template_pagination($template, $this->u_action, 'pagination', 'start', $item_count, $config['smilies_per_page'], $pagination_start); + + phpbb_generate_template_pagination($template, $this->u_action, 'pagination', 'start', $item_count, $config['smilies_per_page'], $pagination_start); } /** diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index 1e23c2e6cf..e61115f681 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -155,10 +155,7 @@ class acp_inactive trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } - foreach ($mark as $user_id) - { - user_delete('retain', $user_id, $user_affected[$user_id]); - } + user_delete('retain', $mark, true); add_log('admin', 'LOG_INACTIVE_' . strtoupper($action), implode(', ', $user_affected)); @@ -289,8 +286,8 @@ class acp_inactive } $base_url = $this->u_action . "&$u_sort_param&users_per_page=$per_page"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $inactive_count, $per_page, $start); - + phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $inactive_count, $per_page, $start); + $template->assign_vars(array( 'S_INACTIVE_USERS' => true, 'S_INACTIVE_OPTIONS' => build_select($option_ary), @@ -299,7 +296,6 @@ class acp_inactive 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir, 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $inactive_count, $per_page, $start), - 'USERS_PER_PAGE' => $per_page, 'U_ACTION' => $this->u_action . "&$u_sort_param&users_per_page=$per_page&start=$start", diff --git a/phpBB/includes/acp/acp_language.php b/phpBB/includes/acp/acp_language.php index 2b19f93c75..2be1ccfc41 100644 --- a/phpBB/includes/acp/acp_language.php +++ b/phpBB/includes/acp/acp_language.php @@ -100,11 +100,25 @@ class acp_language switch ($method) { case 'ftp': - $transfer = new ftp(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); + $transfer = new ftp( + request_var('host', ''), + request_var('username', ''), + htmlspecialchars_decode($request->untrimmed_variable('password', '')), + request_var('root_path', ''), + request_var('port', ''), + request_var('timeout', '') + ); break; case 'ftp_fsock': - $transfer = new ftp_fsock(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); + $transfer = new ftp_fsock( + request_var('host', ''), + request_var('username', ''), + htmlspecialchars_decode($request->untrimmed_variable('password', '')), + request_var('root_path', ''), + request_var('port', ''), + request_var('timeout', '') + ); break; default: @@ -404,7 +418,14 @@ class acp_language trigger_error($user->lang['INVALID_UPLOAD_METHOD'], E_USER_ERROR); } - $transfer = new $method(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', '')); + $transfer = new $method( + request_var('host', ''), + request_var('username', ''), + htmlspecialchars_decode($request->untrimmed_variable('password', '')), + request_var('root_path', ''), + request_var('port', ''), + request_var('timeout', '') + ); if (($result = $transfer->open_session()) !== true) { diff --git a/phpBB/includes/acp/acp_logs.php b/phpBB/includes/acp/acp_logs.php index 4538633d6c..d86521532c 100644 --- a/phpBB/includes/acp/acp_logs.php +++ b/phpBB/includes/acp/acp_logs.php @@ -131,7 +131,7 @@ class acp_logs $base_url = $this->u_action . "&$u_sort_param$keywords_param"; phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); - + $template->assign_vars(array( 'L_TITLE' => $l_title, 'L_EXPLAIN' => $l_title_explain, diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index 0584bb510e..27813b1cc7 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -426,7 +426,7 @@ class acp_main // Version check $user->add_lang('install'); - if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.3.2', '<')) + if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.3.3', '<')) { $template->assign_vars(array( 'S_PHP_VERSION_OLD' => true, diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php index 240e3596ba..a5dc02849a 100644 --- a/phpBB/includes/acp/acp_prune.php +++ b/phpBB/includes/acp/acp_prune.php @@ -242,8 +242,8 @@ class acp_prune if (confirm_box(true)) { $user_ids = $usernames = array(); - $this->get_prune_users($user_ids, $usernames); + $this->get_prune_users($user_ids, $usernames); if (sizeof($user_ids)) { if ($action == 'deactivate') @@ -255,19 +255,13 @@ class acp_prune { if ($deleteposts) { - foreach ($user_ids as $user_id) - { - user_delete('remove', $user_id); - } + user_delete('remove', $user_ids); $l_log = 'LOG_PRUNE_USER_DEL_DEL'; } else { - foreach ($user_ids as $user_id) - { - user_delete('retain', $user_id, $usernames[$user_id]); - } + user_delete('retain', $user_ids, true); $l_log = 'LOG_PRUNE_USER_DEL_ANON'; } @@ -299,6 +293,7 @@ class acp_prune { $template->assign_block_vars('users', array( 'USERNAME' => $usernames[$user_id], + 'USER_ID' => $user_id, 'U_PROFILE' => append_sid($phpbb_root_path . 'memberlist.' . $phpEx, 'mode=viewprofile&u=' . $user_id), 'U_USER_ADMIN' => ($auth->acl_get('a_user')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&mode=overview&u=' . $user_id, true, $user->session_id) : '', )); @@ -314,17 +309,7 @@ class acp_prune 'mode' => $mode, 'prune' => 1, - 'users' => utf8_normalize_nfc(request_var('users', '', true)), - 'username' => utf8_normalize_nfc(request_var('username', '', true)), - 'email' => request_var('email', ''), - 'joined_select' => request_var('joined_select', ''), - 'joined' => request_var('joined', ''), - 'active_select' => request_var('active_select', ''), - 'active' => request_var('active', ''), - 'count_select' => request_var('count_select', ''), - 'count' => request_var('count', ''), 'deleteposts' => request_var('deleteposts', 0), - 'action' => request_var('action', ''), )), 'confirm_body_prune.html'); } @@ -340,22 +325,29 @@ class acp_prune } $find_time = array('lt' => $user->lang['BEFORE'], 'gt' => $user->lang['AFTER']); - $s_find_join_time = ''; - foreach ($find_time as $key => $value) - { - $s_find_join_time .= '<option value="' . $key . '">' . $value . '</option>'; - } - $s_find_active_time = ''; foreach ($find_time as $key => $value) { $s_find_active_time .= '<option value="' . $key . '">' . $value . '</option>'; } + $s_group_list = ''; + $sql = 'SELECT group_id, group_name + FROM ' . GROUPS_TABLE . ' + WHERE group_type <> ' . GROUP_SPECIAL . ' + ORDER BY group_name ASC'; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $s_group_list .= '<option value="' . $row['group_id'] . '">' . $row['group_name'] . '</select>'; + } + $db->sql_freeresult($result); + $template->assign_vars(array( 'U_ACTION' => $this->u_action, - 'S_JOINED_OPTIONS' => $s_find_join_time, 'S_ACTIVE_OPTIONS' => $s_find_active_time, + 'S_GROUP_LIST' => $s_group_list, 'S_COUNT_OPTIONS' => $s_find_count, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_prune&field=users'), )); @@ -368,33 +360,70 @@ class acp_prune { global $user, $db; - $users = utf8_normalize_nfc(request_var('users', '', true)); - - if ($users) + $users_by_name = request_var('users', '', true); + $users_by_id = request_var('user_ids', array(0)); + $group_id = request_var('group_id', 0); + $posts_on_queue = request_var('posts_on_queue', 0); + + if ($users_by_name) { - $users = explode("\n", $users); + $users = explode("\n", $users_by_name); $where_sql = ' AND ' . $db->sql_in_set('username_clean', array_map('utf8_clean_string', $users)); } + else if (!empty($users_by_id)) + { + $user_ids = $users_by_id; + user_get_id_name($user_ids, $usernames); + + $where_sql = ' AND ' . $db->sql_in_set('user_id', $user_ids); + } else { - $username = utf8_normalize_nfc(request_var('username', '', true)); + $username = request_var('username', '', true); $email = request_var('email', ''); + $website = request_var('website', ''); - $joined_select = request_var('joined_select', 'lt'); $active_select = request_var('active_select', 'lt'); $count_select = request_var('count_select', 'eq'); - $joined = request_var('joined', ''); + $queue_select = request_var('queue_select', 'gt'); + $joined_before = request_var('joined_before', ''); + $joined_after = request_var('joined_after', ''); $active = request_var('active', ''); + $count = request_var('count', 0); + $active = ($active) ? explode('-', $active) : array(); - $joined = ($joined) ? explode('-', $joined) : array(); + $joined_before = ($joined_before) ? explode('-', $joined_before) : array(); + $joined_after = ($joined_after) ? explode('-', $joined_after) : array(); - if ((sizeof($active) && sizeof($active) != 3) || (sizeof($joined) && sizeof($joined) != 3)) + // calculate the conditions required by the join time criteria + $joined_sql = ''; + if (!empty($joined_before) && !empty($joined_after)) { - trigger_error($user->lang['WRONG_ACTIVE_JOINED_DATE'] . adm_back_link($this->u_action), E_USER_WARNING); + // if the two entered dates are equal, we need to adjust + // so that our time range is a full day instead of 1 second + if ($joined_after == $joined_before) + { + $joined_after[2] += 1; + } + + $joined_sql = ' AND user_regdate BETWEEN ' . gmmktime(0, 0, 0, (int) $joined_after[1], (int) $joined_after[2], (int) $joined_after[0]) . + ' AND ' . gmmktime(0, 0, 0, (int) $joined_before[1], (int) $joined_before[2], (int) $joined_before[0]); } + else if (empty($joined_before) && !empty($joined_after)) + { + $joined_sql = ' AND user_regdate > ' . gmmktime(0, 0, 0, (int) $joined_after[1], (int) $joined_after[2], (int) $joined_after[0]); + } + else if (empty($joined_after) && !empty($joined_before)) + { + $joined_sql = ' AND user_regdate < ' . gmmktime(0, 0, 0, (int) $joined_before[1], (int) $joined_before[2], (int) $joined_before[0]); + } + // implicit else when both arrays are empty do nothing - $count = request_var('count', ''); + if ((sizeof($active) && sizeof($active) != 3) || (sizeof($joined_before) && sizeof($joined_before) != 3) || (sizeof($joined_after) && sizeof($joined_after) != 3)) + { + trigger_error($user->lang['WRONG_ACTIVE_JOINED_DATE'] . adm_back_link($this->u_action), E_USER_WARNING); + } $key_match = array('lt' => '<', 'gt' => '>', 'eq' => '='); $sort_by_types = array('username', 'user_email', 'user_posts', 'user_regdate', 'user_lastvisit'); @@ -402,8 +431,9 @@ class acp_prune $where_sql = ''; $where_sql .= ($username) ? ' AND username_clean ' . $db->sql_like_expression(str_replace('*', $db->any_char, utf8_clean_string($username))) : ''; $where_sql .= ($email) ? ' AND user_email ' . $db->sql_like_expression(str_replace('*', $db->any_char, $email)) . ' ' : ''; - $where_sql .= (sizeof($joined)) ? " AND user_regdate " . $key_match[$joined_select] . ' ' . gmmktime(0, 0, 0, (int) $joined[1], (int) $joined[2], (int) $joined[0]) : ''; - $where_sql .= ($count !== '') ? " AND user_posts " . $key_match[$count_select] . ' ' . (int) $count . ' ' : ''; + $where_sql .= ($website) ? ' AND user_website ' . $db->sql_like_expression(str_replace('*', $db->any_char, $website)) . ' ' : ''; + $where_sql .= $joined_sql; + $where_sql .= ($count) ? " 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) @@ -446,7 +476,6 @@ class acp_prune $where_sql"; $result = $db->sql_query($sql); - $where_sql = ''; $user_ids = $usernames = array(); while ($row = $db->sql_fetchrow($result)) @@ -459,5 +488,53 @@ class acp_prune } } $db->sql_freeresult($result); + + if ($group_id) + { + $sql = 'SELECT user_id + FROM ' . USER_GROUP_TABLE . ' + WHERE group_id = ' . (int) $group_id . ' + AND user_pending = 0 + AND ' . $db->sql_in_set('user_id', $user_ids, false, true); + $result = $db->sql_query($sql); + + // we're performing an intersection operation, so all the relevant users + // come from this most recent query (which was limited to the results of the + // previous query) + $user_ids = $usernames = array(); + while ($row = $db->sql_fetchrow($result)) + { + $user_ids[] = $row['poster_id']; + } + $db->sql_freeresult($result); + + // only get usernames if they are needed (not part of some later query) + if (!$posts_on_queue) + { + // this is an additional query aginst the users table + user_get_id_name($user_ids, $usernames); + } + } + + if ($posts_on_queue) + { + $sql = 'SELECT poster_id, COUNT(post_id) AS queue_posts + FROM ' . POSTS_TABLE . ' + WHERE ' . $db->sql_in_set('poster_id', $user_ids, false, true) . ' + GROUP BY poster_id + HAVING queue_posts ' . $key_match[$queue_select] . ' ' . $posts_on_queue; + $result = $db->sql_query($result); + + // same intersection logic as the above group ID portion + $user_ids = $usernames = array(); + while ($row = $db->sql_fetchrow($result)) + { + $user_ids[] = $row['poster_id']; + } + $db->sql_freeresult($result); + + // do an additional query to get the correct set of usernames + user_get_id_name($user_ids, $usernames); + } } } diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index bb5b4a04d5..3dd57905ed 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -32,7 +32,7 @@ class acp_users { global $config, $db, $user, $auth, $template, $cache; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix, $file_uploads; - global $phpbb_dispatcher; + global $phpbb_dispatcher, $request; $user->add_lang(array('posting', 'ucp', 'acp/users')); $this->tpl_name = 'acp_users'; @@ -772,8 +772,8 @@ class acp_users 'username' => utf8_normalize_nfc(request_var('user', $user_row['username'], true)), 'user_founder' => request_var('user_founder', ($user_row['user_type'] == USER_FOUNDER) ? 1 : 0), 'email' => strtolower(request_var('user_email', $user_row['user_email'])), - 'new_password' => request_var('new_password', '', true), - 'password_confirm' => request_var('password_confirm', '', true), + 'new_password' => $request->variable('new_password', '', true), + 'password_confirm' => $request->variable('password_confirm', '', true), ); // Validation data - we do not check the password complexity setting here @@ -1161,7 +1161,7 @@ class acp_users $base_url = $this->u_action . "&u=$user_id&$u_sort_param"; phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); - + $template->assign_vars(array( 'S_FEEDBACK' => true, 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start), @@ -2077,7 +2077,7 @@ class acp_users $base_url = $this->u_action . "&u=$user_id&sk=$sort_key&sd=$sort_dir"; phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); - + $template->assign_vars(array( 'S_ATTACHMENTS' => true, 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $num_attachments, $config['topics_per_page'], $start), diff --git a/phpBB/includes/acp/info/acp_extensions.php b/phpBB/includes/acp/info/acp_extensions.php new file mode 100644 index 0000000000..f5953fb1dd --- /dev/null +++ b/phpBB/includes/acp/info/acp_extensions.php @@ -0,0 +1,34 @@ +<?php +/** +* +* @package acp +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @package module_install +*/ +class acp_extensions_info +{ + function module() + { + return array( + 'filename' => 'acp_extensions', + 'title' => 'ACP_EXTENSIONS', + 'version' => '1.0.0', + 'modes' => array( + 'main' => array('title' => 'ACP_EXTENSIONS', 'auth' => 'acl_a_extensions', 'cat' => array('ACP_GENERAL_TASKS')), + ), + ); + } + + function install() + { + } + + function uninstall() + { + } +} diff --git a/phpBB/includes/auth/auth_db.php b/phpBB/includes/auth/auth_db.php index 76790e4dad..ac944532a5 100644 --- a/phpBB/includes/auth/auth_db.php +++ b/phpBB/includes/auth/auth_db.php @@ -41,6 +41,10 @@ function login_db($username, $password, $ip = '', $browser = '', $forwarded_for global $db, $config; global $request; + // Auth plugins get the password untrimmed. + // For compatibility we trim() here. + $password = trim($password); + // do not allow empty password if (!$password) { diff --git a/phpBB/includes/auth/auth_ldap.php b/phpBB/includes/auth/auth_ldap.php index 26029efe1e..24823f9ce7 100644 --- a/phpBB/includes/auth/auth_ldap.php +++ b/phpBB/includes/auth/auth_ldap.php @@ -309,35 +309,35 @@ function acp_ldap(&$new) $tpl = ' <dl> - <dt><label for="ldap_server">' . $user->lang['LDAP_SERVER'] . ':</label><br /><span>' . $user->lang['LDAP_SERVER_EXPLAIN'] . '</span></dt> + <dt><label for="ldap_server">' . $user->lang['LDAP_SERVER'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_SERVER_EXPLAIN'] . '</span></dt> <dd><input type="text" id="ldap_server" size="40" name="config[ldap_server]" value="' . $new['ldap_server'] . '" /></dd> </dl> <dl> - <dt><label for="ldap_port">' . $user->lang['LDAP_PORT'] . ':</label><br /><span>' . $user->lang['LDAP_PORT_EXPLAIN'] . '</span></dt> + <dt><label for="ldap_port">' . $user->lang['LDAP_PORT'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_PORT_EXPLAIN'] . '</span></dt> <dd><input type="text" id="ldap_port" size="40" name="config[ldap_port]" value="' . $new['ldap_port'] . '" /></dd> </dl> <dl> - <dt><label for="ldap_dn">' . $user->lang['LDAP_DN'] . ':</label><br /><span>' . $user->lang['LDAP_DN_EXPLAIN'] . '</span></dt> + <dt><label for="ldap_dn">' . $user->lang['LDAP_DN'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_DN_EXPLAIN'] . '</span></dt> <dd><input type="text" id="ldap_dn" size="40" name="config[ldap_base_dn]" value="' . $new['ldap_base_dn'] . '" /></dd> </dl> <dl> - <dt><label for="ldap_uid">' . $user->lang['LDAP_UID'] . ':</label><br /><span>' . $user->lang['LDAP_UID_EXPLAIN'] . '</span></dt> + <dt><label for="ldap_uid">' . $user->lang['LDAP_UID'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_UID_EXPLAIN'] . '</span></dt> <dd><input type="text" id="ldap_uid" size="40" name="config[ldap_uid]" value="' . $new['ldap_uid'] . '" /></dd> </dl> <dl> - <dt><label for="ldap_user_filter">' . $user->lang['LDAP_USER_FILTER'] . ':</label><br /><span>' . $user->lang['LDAP_USER_FILTER_EXPLAIN'] . '</span></dt> + <dt><label for="ldap_user_filter">' . $user->lang['LDAP_USER_FILTER'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_USER_FILTER_EXPLAIN'] . '</span></dt> <dd><input type="text" id="ldap_user_filter" size="40" name="config[ldap_user_filter]" value="' . $new['ldap_user_filter'] . '" /></dd> </dl> <dl> - <dt><label for="ldap_email">' . $user->lang['LDAP_EMAIL'] . ':</label><br /><span>' . $user->lang['LDAP_EMAIL_EXPLAIN'] . '</span></dt> + <dt><label for="ldap_email">' . $user->lang['LDAP_EMAIL'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_EMAIL_EXPLAIN'] . '</span></dt> <dd><input type="text" id="ldap_email" size="40" name="config[ldap_email]" value="' . $new['ldap_email'] . '" /></dd> </dl> <dl> - <dt><label for="ldap_user">' . $user->lang['LDAP_USER'] . ':</label><br /><span>' . $user->lang['LDAP_USER_EXPLAIN'] . '</span></dt> + <dt><label for="ldap_user">' . $user->lang['LDAP_USER'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_USER_EXPLAIN'] . '</span></dt> <dd><input type="text" id="ldap_user" size="40" name="config[ldap_user]" value="' . $new['ldap_user'] . '" /></dd> </dl> <dl> - <dt><label for="ldap_password">' . $user->lang['LDAP_PASSWORD'] . ':</label><br /><span>' . $user->lang['LDAP_PASSWORD_EXPLAIN'] . '</span></dt> + <dt><label for="ldap_password">' . $user->lang['LDAP_PASSWORD'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_PASSWORD_EXPLAIN'] . '</span></dt> <dd><input type="password" id="ldap_password" size="40" name="config[ldap_password]" value="' . $new['ldap_password'] . '" autocomplete="off" /></dd> </dl> '; diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index 444446e9c3..b9ffa8091c 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -134,7 +134,7 @@ class bbcode $style_resource_locator = new phpbb_style_resource_locator(); $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); - $template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator); + $template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, new phpbb_template_context()); $style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $template); $style->set_style(); $template->set_filenames(array('bbcode.html' => 'bbcode.html')); diff --git a/phpBB/includes/cache/driver/memory.php b/phpBB/includes/cache/driver/memory.php index 92971c6cb2..e0771ab1d3 100644 --- a/phpBB/includes/cache/driver/memory.php +++ b/phpBB/includes/cache/driver/memory.php @@ -19,7 +19,7 @@ if (!defined('IN_PHPBB')) * ACM Abstract Memory Class * @package acm */ -class phpbb_cache_driver_memory extends phpbb_cache_driver_base +abstract class phpbb_cache_driver_memory extends phpbb_cache_driver_base { var $key_prefix; diff --git a/phpBB/includes/cache/driver/redis.php b/phpBB/includes/cache/driver/redis.php index a768885962..a768885962 100755..100644 --- a/phpBB/includes/cache/driver/redis.php +++ b/phpBB/includes/cache/driver/redis.php diff --git a/phpBB/includes/cache/factory.php b/phpBB/includes/cache/factory.php deleted file mode 100644 index 01c4d0b901..0000000000 --- a/phpBB/includes/cache/factory.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** -* -* @package acm -* @copyright (c) 2010 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* @package acm -*/ -class phpbb_cache_factory -{ - private $acm_type; - - public function __construct($acm_type) - { - $this->acm_type = $acm_type; - } - - public function get_driver() - { - $class_name = 'phpbb_cache_driver_' . $this->acm_type; - return new $class_name(); - } - - public function get_service() - { - $driver = $this->get_driver(); - $service = new phpbb_cache_service($driver); - return $service; - } -} diff --git a/phpBB/includes/captcha/captcha_factory.php b/phpBB/includes/captcha/captcha_factory.php index d57b333c69..1ed8e119b5 100644 --- a/phpBB/includes/captcha/captcha_factory.php +++ b/phpBB/includes/captcha/captcha_factory.php @@ -25,7 +25,7 @@ class phpbb_captcha_factory /** * return an instance of class $name in file $name_plugin.php */ - public static function get_instance($name) + static public function get_instance($name) { global $phpbb_root_path, $phpEx; diff --git a/phpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php index 6c1f3bf00b..4ad34f2a26 100644 --- a/phpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php +++ b/phpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php @@ -49,13 +49,13 @@ class phpbb_captcha_gd extends phpbb_default_captcha } } - public static function get_instance() + static public function get_instance() { $instance = new phpbb_captcha_gd(); return $instance; } - function is_available() + static public function is_available() { global $phpbb_root_path, $phpEx; @@ -80,7 +80,7 @@ class phpbb_captcha_gd extends phpbb_default_captcha return true; } - function get_name() + static public function get_name() { return 'CAPTCHA_GD'; } diff --git a/phpBB/includes/captcha/plugins/phpbb_captcha_gd_wave_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_gd_wave_plugin.php index a5588178bb..26383c76a8 100644 --- a/phpBB/includes/captcha/plugins/phpbb_captcha_gd_wave_plugin.php +++ b/phpBB/includes/captcha/plugins/phpbb_captcha_gd_wave_plugin.php @@ -39,12 +39,12 @@ class phpbb_captcha_gd_wave extends phpbb_default_captcha } } - public static function get_instance() + static public function get_instance() { return new phpbb_captcha_gd_wave(); } - function is_available() + static public function is_available() { global $phpbb_root_path, $phpEx; @@ -61,7 +61,7 @@ class phpbb_captcha_gd_wave extends phpbb_default_captcha return can_load_dll('gd'); } - function get_name() + static public function get_name() { return 'CAPTCHA_GD_3D'; } diff --git a/phpBB/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php index 96f13fbe1b..c5ef8c78b0 100644 --- a/phpBB/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php +++ b/phpBB/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php @@ -39,18 +39,18 @@ class phpbb_captcha_nogd extends phpbb_default_captcha } } - public static function get_instance() + static public function get_instance() { $instance = new phpbb_captcha_nogd(); return $instance; } - function is_available() + static public function is_available() { return true; } - function get_name() + static public function get_name() { return 'CAPTCHA_NO_GD'; } diff --git a/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php index 99813189d7..ec7636f511 100644 --- a/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php +++ b/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php @@ -98,7 +98,7 @@ class phpbb_captcha_qa /** * API function */ - public static function get_instance() + static public function get_instance() { $instance = new phpbb_captcha_qa(); @@ -108,7 +108,7 @@ class phpbb_captcha_qa /** * See if the captcha has created its tables. */ - function is_installed() + static public function is_installed() { global $db, $phpbb_root_path, $phpEx; @@ -124,14 +124,14 @@ class phpbb_captcha_qa /** * API function - for the captcha to be available, it must have installed itself and there has to be at least one question in the board's default lang */ - function is_available() + static public function is_available() { global $config, $db, $phpbb_root_path, $phpEx, $user; // load language file for pretty display in the ACP dropdown $user->add_lang('captcha_qa'); - if (!phpbb_captcha_qa::is_installed()) + if (!self::is_installed()) { return false; } @@ -157,7 +157,7 @@ class phpbb_captcha_qa /** * API function */ - function get_name() + static public function get_name() { return 'CAPTCHA_QA'; } @@ -612,7 +612,7 @@ class phpbb_captcha_qa $user->add_lang('acp/board'); $user->add_lang('captcha_qa'); - if (!$this->is_installed()) + if (!self::is_installed()) { $this->install(); } diff --git a/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php b/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php index 70c24a8c30..83d40bbba7 100644 --- a/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php +++ b/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php @@ -54,13 +54,13 @@ class phpbb_recaptcha extends phpbb_default_captcha $this->response = request_var('recaptcha_response_field', ''); } - public static function get_instance() + static public function get_instance() { $instance = new phpbb_recaptcha(); return $instance; } - function is_available() + static public function is_available() { global $config, $user; $user->add_lang('captcha_recaptcha'); @@ -75,7 +75,7 @@ class phpbb_recaptcha extends phpbb_default_captcha return true; } - function get_name() + static public function get_name() { return 'CAPTCHA_RECAPTCHA'; } @@ -163,7 +163,7 @@ class phpbb_recaptcha extends phpbb_default_captcha 'RECAPTCHA_SERVER' => $this->recaptcha_server, 'RECAPTCHA_PUBKEY' => isset($config['recaptcha_pubkey']) ? $config['recaptcha_pubkey'] : '', 'RECAPTCHA_ERRORGET' => '', - 'S_RECAPTCHA_AVAILABLE' => $this->is_available(), + 'S_RECAPTCHA_AVAILABLE' => self::is_available(), 'S_CONFIRM_CODE' => true, 'S_TYPE' => $this->type, 'L_CONFIRM_EXPLAIN' => $explain, diff --git a/phpBB/includes/cron/manager.php b/phpBB/includes/cron/manager.php index 7a78a1b054..ccaa4f3764 100644 --- a/phpBB/includes/cron/manager.php +++ b/phpBB/includes/cron/manager.php @@ -32,31 +32,35 @@ class phpbb_cron_manager */ protected $tasks = array(); + protected $phpbb_root_path; + protected $php_ext; + /** * Constructor. Loads all available tasks. * - * @param array|Traversable $task_names Provides an iterable set of task names + * @param array|Traversable $tasks Provides an iterable set of task names */ - public function __construct($task_names) + public function __construct($tasks, $phpbb_root_path, $php_ext) { - $this->load_tasks($task_names); + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + $this->load_tasks($tasks); } /** * Loads tasks given by name, wraps them * and puts them into $this->tasks. * - * @param array|Traversable $task_names Array of strings + * @param array|Traversable $tasks Array of instances of phpbb_cron_task * * @return void */ - public function load_tasks($task_names) + public function load_tasks($tasks) { - foreach ($task_names as $task_name) + foreach ($tasks as $task) { - $task = new $task_name(); - $wrapper = new phpbb_cron_task_wrapper($task); - $this->tasks[] = $wrapper; + $this->tasks[] = $this->wrap_task($task); } } @@ -122,25 +126,13 @@ class phpbb_cron_manager } /** - * Creates an instance of parametrized cron task $name with args $args. - * The constructed task is wrapped with cron task wrapper before being returned. - * - * @param string $name The task name, which is the same as cron task class name. - * @param array $args Will be passed to the task class's constructor. + * Wraps a task inside an instance of phpbb_cron_task_wrapper. * - * @return phpbb_cron_task_wrapper|null + * @param phpbb_cron_task $task The task. + * @return phpbb_cron_task_wrapper The wrapped task. */ - public function instantiate_task($name, array $args) + public function wrap_task(phpbb_cron_task $task) { - $task = $this->find_task($name); - if ($task) - { - // task here is actually an instance of cron task wrapper - $class = $task->get_name(); - $task = new $class($args); - // need to wrap the new task too - $task = new phpbb_cron_task_wrapper($task); - } - return $task; + return new phpbb_cron_task_wrapper($task, $this->phpbb_root_path, $this->php_ext); } } diff --git a/phpBB/includes/cron/task/base.php b/phpBB/includes/cron/task/base.php index c05fb9a87c..94a2f267b4 100644 --- a/phpBB/includes/cron/task/base.php +++ b/phpBB/includes/cron/task/base.php @@ -28,6 +28,28 @@ if (!defined('IN_PHPBB')) */ abstract class phpbb_cron_task_base implements phpbb_cron_task { + private $name; + + /** + * Returns the name of the task. + * + * @return string Name of wrapped task. + */ + public function get_name() + { + return $this->name; + } + + /** + * Sets the name of the task. + * + * @param string $name The task name + */ + public function set_name($name) + { + $this->name = $name; + } + /** * Returns whether this cron task can run, given current board configuration. * diff --git a/phpBB/includes/cron/task/core/prune_all_forums.php b/phpBB/includes/cron/task/core/prune_all_forums.php index 15b93a9ca6..252e16e57d 100644 --- a/phpBB/includes/cron/task/core/prune_all_forums.php +++ b/phpBB/includes/cron/task/core/prune_all_forums.php @@ -26,6 +26,27 @@ if (!defined('IN_PHPBB')) */ class phpbb_cron_task_core_prune_all_forums extends phpbb_cron_task_base { + protected $phpbb_root_path; + protected $php_ext; + protected $config; + protected $db; + + /** + * Constructor. + * + * @param string $phpbb_root_path The root path + * @param string $php_ext The PHP extension + * @param phpbb_config $config The config + * @param dbal $db The db connection + */ + public function __construct($phpbb_root_path, $php_ext, phpbb_config $config, dbal $db) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->config = $config; + $this->db = $db; + } + /** * Runs this cron task. * @@ -33,19 +54,17 @@ class phpbb_cron_task_core_prune_all_forums extends phpbb_cron_task_base */ public function run() { - global $phpbb_root_path, $phpEx, $db; - if (!function_exists('auto_prune')) { - include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); + include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext); } $sql = 'SELECT forum_id, prune_next, enable_prune, prune_days, prune_viewed, forum_flags, prune_freq FROM ' . FORUMS_TABLE . " - WHERE enable_prune = 1 + WHERE enable_prune = 1 AND prune_next < " . time(); - $result = $db->sql_query($sql); - while ($row = $db->sql_fetchrow($result)) + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) { if ($row['prune_days']) { @@ -57,7 +76,7 @@ class phpbb_cron_task_core_prune_all_forums extends phpbb_cron_task_base auto_prune($row['forum_id'], 'viewed', $row['forum_flags'], $row['prune_viewed'], $row['prune_freq']); } } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); } /** @@ -69,7 +88,6 @@ class phpbb_cron_task_core_prune_all_forums extends phpbb_cron_task_base */ public function is_runnable() { - global $config; - return (bool) $config['use_system_cron']; + return (bool) $this->config['use_system_cron']; } } diff --git a/phpBB/includes/cron/task/core/prune_forum.php b/phpBB/includes/cron/task/core/prune_forum.php index 7686fd4281..41d60af921 100644 --- a/phpBB/includes/cron/task/core/prune_forum.php +++ b/phpBB/includes/cron/task/core/prune_forum.php @@ -26,31 +26,45 @@ if (!defined('IN_PHPBB')) */ class phpbb_cron_task_core_prune_forum extends phpbb_cron_task_base implements phpbb_cron_task_parametrized { - private $forum_data; + protected $phpbb_root_path; + protected $php_ext; + protected $config; + protected $db; /** - * Constructor. - * * If $forum_data is given, it is assumed to contain necessary information * about a single forum that is to be pruned. * * If $forum_data is not given, forum id will be retrieved via request_var * and a database query will be performed to load the necessary information * about the forum. + */ + protected $forum_data; + + /** + * Constructor. + * + * @param string $phpbb_root_path The root path + * @param string $php_ext The PHP extension + * @param phpbb_config $config The config + * @param dbal $db The db connection + */ + public function __construct($phpbb_root_path, $php_ext, phpbb_config $config, dbal $db) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->config = $config; + $this->db = $db; + } + + /** + * Manually set forum data. * * @param array $forum_data Information about a forum to be pruned. */ - public function __construct($forum_data = null) + public function set_forum_data($forum_data) { - global $db; - if ($forum_data) - { - $this->forum_data = $forum_data; - } - else - { - $this->forum_data = null; - } + $this->forum_data = $forum_data; } /** @@ -60,10 +74,9 @@ class phpbb_cron_task_core_prune_forum extends phpbb_cron_task_base implements p */ public function run() { - global $phpbb_root_path, $phpEx; if (!function_exists('auto_prune')) { - include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); + include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext); } if ($this->forum_data['prune_days']) @@ -90,8 +103,7 @@ class phpbb_cron_task_core_prune_forum extends phpbb_cron_task_base implements p */ public function is_runnable() { - global $config; - return !$config['use_system_cron'] && $this->forum_data; + return !$this->config['use_system_cron'] && $this->forum_data; } /** @@ -130,8 +142,6 @@ class phpbb_cron_task_core_prune_forum extends phpbb_cron_task_base implements p */ public function parse_parameters(phpbb_request_interface $request) { - global $db; - $this->forum_data = null; if ($request->is_set('f')) { @@ -140,9 +150,9 @@ class phpbb_cron_task_core_prune_forum extends phpbb_cron_task_base implements p $sql = 'SELECT forum_id, prune_next, enable_prune, prune_days, prune_viewed, forum_flags, prune_freq FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id"; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); if ($row) { diff --git a/phpBB/includes/cron/task/core/queue.php b/phpBB/includes/cron/task/core/queue.php index 1c72eec7c7..c765660906 100644 --- a/phpBB/includes/cron/task/core/queue.php +++ b/phpBB/includes/cron/task/core/queue.php @@ -22,6 +22,24 @@ if (!defined('IN_PHPBB')) */ class phpbb_cron_task_core_queue extends phpbb_cron_task_base { + protected $phpbb_root_path; + protected $php_ext; + protected $config; + + /** + * Constructor. + * + * @param string $phpbb_root_path The root path + * @param string $php_ext The PHP extension + * @param phpbb_config $config The config + */ + public function __construct($phpbb_root_path, $php_ext, phpbb_config $config) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->config = $config; + } + /** * Runs this cron task. * @@ -29,10 +47,9 @@ class phpbb_cron_task_core_queue extends phpbb_cron_task_base */ public function run() { - global $phpbb_root_path, $phpEx; if (!class_exists('queue')) { - include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + include($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext); } $queue = new queue(); $queue->process(); @@ -47,8 +64,7 @@ class phpbb_cron_task_core_queue extends phpbb_cron_task_base */ public function is_runnable() { - global $phpbb_root_path, $phpEx; - return file_exists($phpbb_root_path . 'cache/queue.' . $phpEx); + return file_exists($this->phpbb_root_path . 'cache/queue.' . $this->php_ext); } /** @@ -61,7 +77,6 @@ class phpbb_cron_task_core_queue extends phpbb_cron_task_base */ public function should_run() { - global $config; - return $config['last_queue_run'] < time() - $config['queue_interval_config']; + return $this->config['last_queue_run'] < time() - $this->config['queue_interval_config']; } } diff --git a/phpBB/includes/cron/task/core/tidy_cache.php b/phpBB/includes/cron/task/core/tidy_cache.php index f6cf77d01d..6017eea561 100644 --- a/phpBB/includes/cron/task/core/tidy_cache.php +++ b/phpBB/includes/cron/task/core/tidy_cache.php @@ -22,6 +22,21 @@ if (!defined('IN_PHPBB')) */ class phpbb_cron_task_core_tidy_cache extends phpbb_cron_task_base { + protected $config; + protected $cache; + + /** + * Constructor. + * + * @param phpbb_config $config The config + * @param phpbb_cache_driver_interface $cache The cache driver + */ + public function __construct(phpbb_config $config, phpbb_cache_driver_interface $cache) + { + $this->config = $config; + $this->cache = $cache; + } + /** * Runs this cron task. * @@ -29,8 +44,7 @@ class phpbb_cron_task_core_tidy_cache extends phpbb_cron_task_base */ public function run() { - global $cache; - $cache->tidy(); + $this->cache->tidy(); } /** @@ -57,7 +71,6 @@ class phpbb_cron_task_core_tidy_cache extends phpbb_cron_task_base */ public function should_run() { - global $config; - return $config['cache_last_gc'] < time() - $config['cache_gc']; + return $this->config['cache_last_gc'] < time() - $this->config['cache_gc']; } } diff --git a/phpBB/includes/cron/task/core/tidy_database.php b/phpBB/includes/cron/task/core/tidy_database.php index 80a1901b1e..1d256f964f 100644 --- a/phpBB/includes/cron/task/core/tidy_database.php +++ b/phpBB/includes/cron/task/core/tidy_database.php @@ -22,6 +22,24 @@ if (!defined('IN_PHPBB')) */ class phpbb_cron_task_core_tidy_database extends phpbb_cron_task_base { + protected $phpbb_root_path; + protected $php_ext; + protected $config; + + /** + * Constructor. + * + * @param string $phpbb_root_path The root path + * @param string $php_ext The PHP extension + * @param phpbb_config $config The config + */ + public function __construct($phpbb_root_path, $php_ext, phpbb_config $config) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->config = $config; + } + /** * Runs this cron task. * @@ -29,10 +47,9 @@ class phpbb_cron_task_core_tidy_database extends phpbb_cron_task_base */ public function run() { - global $phpbb_root_path, $phpEx; if (!function_exists('tidy_database')) { - include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); + include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext); } tidy_database(); } @@ -48,7 +65,6 @@ class phpbb_cron_task_core_tidy_database extends phpbb_cron_task_base */ public function should_run() { - global $config; - return $config['database_last_gc'] < time() - $config['database_gc']; + return $this->config['database_last_gc'] < time() - $this->config['database_gc']; } } diff --git a/phpBB/includes/cron/task/core/tidy_search.php b/phpBB/includes/cron/task/core/tidy_search.php index 7855c3760a..2e5f3d79d5 100644 --- a/phpBB/includes/cron/task/core/tidy_search.php +++ b/phpBB/includes/cron/task/core/tidy_search.php @@ -24,6 +24,33 @@ if (!defined('IN_PHPBB')) */ class phpbb_cron_task_core_tidy_search extends phpbb_cron_task_base { + protected $phpbb_root_path; + protected $php_ext; + protected $auth; + protected $config; + protected $db; + protected $user; + + /** + * Constructor. + * + * @param string $phpbb_root_path The root path + * @param string $php_ext The PHP extension + * @param phpbb_auth $auth The auth + * @param phpbb_config $config The config + * @param dbal $db The db connection + * @param phpbb_user $user The user + */ + public function __construct($phpbb_root_path, $php_ext, phpbb_auth $auth, phpbb_config $config, dbal $db, phpbb_user $user) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->auth = $auth; + $this->config = $config; + $this->db = $db; + $this->user = $user; + } + /** * Runs this cron task. * @@ -31,19 +58,17 @@ class phpbb_cron_task_core_tidy_search extends phpbb_cron_task_base */ public function run() { - global $phpbb_root_path, $phpEx, $config, $error, $auth, $db, $user; - // Select the search method - $search_type = basename($config['search_type']); + $search_type = basename($this->config['search_type']); if (!class_exists($search_type)) { - include("{$phpbb_root_path}includes/search/$search_type.$phpEx"); + include($this->phpbb_root_path . "includes/search/$search_type." . $this->php_ext); } // We do some additional checks in the module to ensure it can actually be utilised $error = false; - $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user); + $search = new $search_type($error, $this->phpbb_root_path, $this->php_ext, $this->auth, $this->config, $this->db, $this->user); if (!$error) { @@ -62,12 +87,10 @@ class phpbb_cron_task_core_tidy_search extends phpbb_cron_task_base */ public function is_runnable() { - global $phpbb_root_path, $phpEx, $config; - // Select the search method - $search_type = basename($config['search_type']); + $search_type = basename($this->config['search_type']); - return file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx); + return file_exists($this->phpbb_root_path . 'includes/search/' . $search_type . '.' . $this->php_ext); } /** @@ -81,7 +104,6 @@ class phpbb_cron_task_core_tidy_search extends phpbb_cron_task_base */ public function should_run() { - global $config; - return $config['search_last_gc'] < time() - $config['search_gc']; + return $this->config['search_last_gc'] < time() - $this->config['search_gc']; } } diff --git a/phpBB/includes/cron/task/core/tidy_sessions.php b/phpBB/includes/cron/task/core/tidy_sessions.php index ae7bb242b8..13531aa30b 100644 --- a/phpBB/includes/cron/task/core/tidy_sessions.php +++ b/phpBB/includes/cron/task/core/tidy_sessions.php @@ -22,6 +22,21 @@ if (!defined('IN_PHPBB')) */ class phpbb_cron_task_core_tidy_sessions extends phpbb_cron_task_base { + protected $config; + protected $user; + + /** + * Constructor. + * + * @param phpbb_config $config The config + * @param phpbb_user $user The user + */ + public function __construct(phpbb_config $config, phpbb_user $user) + { + $this->config = $config; + $this->user = $user; + } + /** * Runs this cron task. * @@ -29,8 +44,7 @@ class phpbb_cron_task_core_tidy_sessions extends phpbb_cron_task_base */ public function run() { - global $user; - $user->session_gc(); + $this->user->session_gc(); } /** @@ -44,7 +58,6 @@ class phpbb_cron_task_core_tidy_sessions extends phpbb_cron_task_base */ public function should_run() { - global $config; - return $config['session_last_gc'] < time() - $config['session_gc']; + return $this->config['session_last_gc'] < time() - $this->config['session_gc']; } } diff --git a/phpBB/includes/cron/task/core/tidy_warnings.php b/phpBB/includes/cron/task/core/tidy_warnings.php index e1434e7087..8dd0674fe5 100644 --- a/phpBB/includes/cron/task/core/tidy_warnings.php +++ b/phpBB/includes/cron/task/core/tidy_warnings.php @@ -24,6 +24,24 @@ if (!defined('IN_PHPBB')) */ class phpbb_cron_task_core_tidy_warnings extends phpbb_cron_task_base { + protected $phpbb_root_path; + protected $php_ext; + protected $config; + + /** + * Constructor. + * + * @param string $phpbb_root_path The root path + * @param string $php_ext The PHP extension + * @param phpbb_config $config The config + */ + public function __construct($phpbb_root_path, $php_ext, phpbb_config $config) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->config = $config; + } + /** * Runs this cron task. * @@ -31,10 +49,9 @@ class phpbb_cron_task_core_tidy_warnings extends phpbb_cron_task_base */ public function run() { - global $phpbb_root_path, $phpEx; if (!function_exists('tidy_warnings')) { - include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); + include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext); } tidy_warnings(); } @@ -48,8 +65,7 @@ class phpbb_cron_task_core_tidy_warnings extends phpbb_cron_task_base */ public function is_runnable() { - global $config; - return (bool) $config['warnings_expire_days']; + return (bool) $this->config['warnings_expire_days']; } /** @@ -63,7 +79,6 @@ class phpbb_cron_task_core_tidy_warnings extends phpbb_cron_task_base */ public function should_run() { - global $config; - return $config['warnings_last_gc'] < time() - $config['warnings_gc']; + return $this->config['warnings_last_gc'] < time() - $this->config['warnings_gc']; } } diff --git a/phpBB/includes/cron/task/provider.php b/phpBB/includes/cron/task/provider.php index 1482051699..134723ebd1 100644 --- a/phpBB/includes/cron/task/provider.php +++ b/phpBB/includes/cron/task/provider.php @@ -15,6 +15,8 @@ if (!defined('IN_PHPBB')) exit; } +use Symfony\Component\DependencyInjection\TaggedContainerInterface; + /** * Provides cron manager with tasks * @@ -22,27 +24,36 @@ if (!defined('IN_PHPBB')) * * @package phpBB3 */ -class phpbb_cron_task_provider extends phpbb_extension_provider +class phpbb_cron_task_provider implements IteratorAggregate { + private $container; + + public function __construct(TaggedContainerInterface $container) + { + $this->container = $container; + } + /** - * Finds cron task names using the extension manager. - * - * All PHP files in includes/cron/task/core/ are considered tasks. Tasks - * in extensions have to be located in a directory called cron or a subdir - * of a directory called cron. The class and filename must end in a _task - * suffix. Additionally all PHP files in includes/cron/task/core/ are - * tasks. + * Retrieve an iterator over all items * - * @return array List of task names + * @return ArrayIterator An iterator for the array of cron tasks */ - protected function find() + public function getIterator() { - $finder = $this->extension_manager->get_finder(); + $definitions = $this->container->findTaggedServiceIds('cron.task'); + + $tasks = array(); + foreach ($definitions as $name => $definition) + { + $task = $this->container->get($name); + if ($task instanceof phpbb_cron_task_base) + { + $task->set_name($name); + } + + $tasks[] = $task; + } - return $finder - ->extension_suffix('_task') - ->extension_directory('/cron') - ->core_path('includes/cron/task/core/') - ->get_classes(); + return new ArrayIterator($tasks); } } diff --git a/phpBB/includes/cron/task/task.php b/phpBB/includes/cron/task/task.php index 2f2a9e51f9..7b08fed413 100644 --- a/phpBB/includes/cron/task/task.php +++ b/phpBB/includes/cron/task/task.php @@ -22,6 +22,13 @@ if (!defined('IN_PHPBB')) interface phpbb_cron_task { /** + * Returns the name of the task. + * + * @return string Name of wrapped task. + */ + public function get_name(); + + /** * Runs this cron task. * * @return void diff --git a/phpBB/includes/cron/task/wrapper.php b/phpBB/includes/cron/task/wrapper.php index 66c45189e5..386fb5b383 100644 --- a/phpBB/includes/cron/task/wrapper.php +++ b/phpBB/includes/cron/task/wrapper.php @@ -23,6 +23,10 @@ if (!defined('IN_PHPBB')) */ class phpbb_cron_task_wrapper { + protected $task; + protected $phpbb_root_path; + protected $php_ext; + /** * Constructor. * @@ -30,9 +34,11 @@ class phpbb_cron_task_wrapper * * @param phpbb_cron_task $task The cron task to wrap. */ - public function __construct(phpbb_cron_task $task) + public function __construct(phpbb_cron_task $task, $phpbb_root_path, $php_ext) { $this->task = $task; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; } /** @@ -62,16 +68,6 @@ class phpbb_cron_task_wrapper } /** - * Returns the name of wrapped task. It is the same as the wrapped class's class name. - * - * @return string Class name of wrapped task. - */ - public function get_name() - { - return get_class($this->task); - } - - /** * Returns a url through which this task may be invoked via web. * * When system cron is not in use, running a cron task is accomplished @@ -82,8 +78,6 @@ class phpbb_cron_task_wrapper */ public function get_url() { - global $phpbb_root_path, $phpEx; - $name = $this->get_name(); if ($this->is_parametrized()) { @@ -98,7 +92,7 @@ class phpbb_cron_task_wrapper { $extra = ''; } - $url = append_sid($phpbb_root_path . 'cron.' . $phpEx, 'cron_type=' . $name . $extra); + $url = append_sid($this->phpbb_root_path . 'cron.' . $this->php_ext, 'cron_type=' . $name . $extra); return $url; } diff --git a/phpBB/includes/di/processor/config.php b/phpBB/includes/di/processor/config.php new file mode 100644 index 0000000000..22b6252a6d --- /dev/null +++ b/phpBB/includes/di/processor/config.php @@ -0,0 +1,76 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** +* Configure the container for phpBB's services though +* user-defined parameters defined in the config.php file. +*/ +class phpbb_di_processor_config implements phpbb_di_processor_interface +{ + private $config_file; + private $phpbb_root_path; + private $php_ext; + + /** + * Constructor. + * + * @param string $config_file The config file + * @param string $phpbb_root_path The root path + * @param string $php_ext The PHP extension + */ + public function __construct($config_file, $phpbb_root_path, $php_ext) + { + $this->config_file = $config_file; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + } + + /** + * @inheritdoc + */ + public function process(ContainerBuilder $container) + { + require $this->config_file; + + $container->setParameter('core.root_path', $this->phpbb_root_path); + $container->setParameter('core.php_ext', $this->php_ext); + + $container->setParameter('core.table_prefix', $table_prefix); + $container->setParameter('cache.driver.class', $this->fix_acm_type($acm_type)); + $container->setParameter('dbal.driver.class', 'dbal_'.$dbms); + $container->setParameter('dbal.dbhost', $dbhost); + $container->setParameter('dbal.dbuser', $dbuser); + $container->setParameter('dbal.dbpasswd', $dbpasswd); + $container->setParameter('dbal.dbname', $dbname); + $container->setParameter('dbal.dbport', $dbport); + $container->setParameter('dbal.new_link', defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK); + + $container->set('container', $container); + } + + protected function fix_acm_type($acm_type) + { + if (preg_match('#^[a-z]+$#', $acm_type)) + { + return 'phpbb_cache_driver_'.$acm_type; + } + + return $acm_type; + } +} diff --git a/phpBB/includes/di/processor/ext.php b/phpBB/includes/di/processor/ext.php new file mode 100644 index 0000000000..e69a3d73b3 --- /dev/null +++ b/phpBB/includes/di/processor/ext.php @@ -0,0 +1,54 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + +/** +* Load the service configurations from all extensions into the container. +*/ +class phpbb_di_processor_ext implements phpbb_di_processor_interface +{ + private $extension_manager; + + /** + * Constructor. + * + * @param string $extension_manager The extension manager + */ + public function __construct($extension_manager) + { + $this->extension_manager = $extension_manager; + } + + /** + * @inheritdoc + */ + public function process(ContainerBuilder $container) + { + $enabled_exts = $this->extension_manager->all_enabled(); + foreach ($enabled_exts as $name => $path) + { + if (file_exists($path . '/config/services.yml')) + { + $loader = new YamlFileLoader($container, new FileLocator($path . '/config')); + $loader->load('services.yml'); + } + } + } +} diff --git a/phpBB/includes/di/processor/interface.php b/phpBB/includes/di/processor/interface.php new file mode 100644 index 0000000000..b8563791cc --- /dev/null +++ b/phpBB/includes/di/processor/interface.php @@ -0,0 +1,28 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +interface phpbb_di_processor_interface +{ + /** + * Mutate the container. + * + * @param ContainerBuilder $container The container + */ + public function process(ContainerBuilder $container); +} diff --git a/phpBB/includes/extension/exception.php b/phpBB/includes/extension/exception.php new file mode 100644 index 0000000000..e08a8912ea --- /dev/null +++ b/phpBB/includes/extension/exception.php @@ -0,0 +1,27 @@ +<?php +/** +* +* @package extension +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** + * Exception class for metadata + */ +class phpbb_extension_exception extends UnexpectedValueException +{ + public function __toString() + { + return $this->getMessage(); + } +}
\ No newline at end of file diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index 86d8fab64b..cfa6a0e000 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -22,6 +22,8 @@ if (!defined('IN_PHPBB')) */ class phpbb_extension_manager { + protected $db; + protected $config; protected $cache; protected $php_ext; protected $extensions; @@ -33,16 +35,18 @@ class phpbb_extension_manager * Creates a manager and loads information from database * * @param dbal $db A database connection + * @param phpbb_config $config phpbb_config * @param string $extension_table The name of the table holding extensions * @param string $phpbb_root_path Path to the phpbb includes directory. * @param string $php_ext php file extension * @param phpbb_cache_driver_interface $cache A cache instance or null * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(dbal $db, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext') + public function __construct(dbal $db, phpbb_config $config, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext') { $this->phpbb_root_path = $phpbb_root_path; $this->db = $db; + $this->config = $config; $this->cache = $cache; $this->php_ext = $php_ext; $this->extension_table = $extension_table; @@ -63,6 +67,17 @@ class phpbb_extension_manager */ public function load_extensions() { + $this->extensions = array(); + + // Do not try to load any extensions when installing or updating + // Note: database updater invokes this code, and in 3.0 + // there is no extension table therefore the rest of this function + // fails + if (defined('IN_INSTALL')) + { + return; + } + $sql = 'SELECT * FROM ' . $this->extension_table; @@ -70,7 +85,6 @@ class phpbb_extension_manager $extensions = $this->db->sql_fetchrowset($result); $this->db->sql_freeresult($result); - $this->extensions = array(); foreach ($extensions as $extension) { $extension['ext_path'] = $this->get_extension_path($extension['ext_name']); @@ -121,6 +135,18 @@ class phpbb_extension_manager } /** + * Instantiates the metadata manager for the extension with the given name + * + * @param string $name The extension name + * @param string $template The template manager + * @return phpbb_extension_metadata_manager Instance of the metadata manager + */ + public function create_extension_metadata_manager($name, phpbb_template $template) + { + return new phpbb_extension_metadata_manager($name, $this->db, $this, $this->phpbb_root_path, $this->php_ext, $template, $this->config); + } + + /** * Runs a step of the extension enabling process. * * Allows the exentension to enable in a long running script that works diff --git a/phpBB/includes/extension/metadata_manager.php b/phpBB/includes/extension/metadata_manager.php new file mode 100644 index 0000000000..ea85bd3c4e --- /dev/null +++ b/phpBB/includes/extension/metadata_manager.php @@ -0,0 +1,338 @@ +<?php +/** +* +* @package extension +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* The extension metadata manager validates and gets meta-data for extensions +* +* @package extension +*/ +class phpbb_extension_metadata_manager +{ + protected $phpEx; + protected $extension_manager; + protected $db; + protected $phpbb_root_path; + protected $template; + protected $ext_name; + protected $metadata; + protected $metadata_file; + + /** + * Creates the metadata manager + * + * @param dbal $db A database connection + * @param string $extension_manager An instance of the phpbb extension manager + * @param string $phpbb_root_path Path to the phpbb includes directory. + * @param string $phpEx php file extension + */ + public function __construct($ext_name, dbal $db, phpbb_extension_manager $extension_manager, $phpbb_root_path, $phpEx = '.php', phpbb_template $template, phpbb_config $config) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->db = $db; + $this->config = $config; + $this->phpEx = $phpEx; + $this->template = $template; + $this->extension_manager = $extension_manager; + $this->ext_name = $ext_name; + $this->metadata = array(); + $this->metadata_file = ''; + } + + /** + * Processes and gets the metadata requested + * + * @param string $element All for all metadata that it has and is valid, otherwise specify which section you want by its shorthand term. + * @return array Contains all of the requested metadata, throws an exception on failure + */ + public function get_metadata($element = 'all') + { + $this->set_metadata_file(); + + // Fetch the metadata + $this->fetch_metadata(); + + // Clean the metadata + $this->clean_metadata_array(); + + switch ($element) + { + case 'all': + default: + // Validate the metadata + if (!$this->validate()) + { + return false; + } + + return $this->metadata; + break; + + case 'name': + return ($this->validate('name')) ? $this->metadata['name'] : false; + break; + + case 'display-name': + if (isset($this->metadata['extra']['display-name'])) + { + return $this->metadata['extra']['display-name']; + } + else + { + return ($this->validate('name')) ? $this->metadata['name'] : false; + } + break; + } + } + + /** + * Sets the filepath of the metadata file + * + * @return boolean Set to true if it exists, throws an exception on failure + */ + private function set_metadata_file() + { + $ext_filepath = $this->extension_manager->get_extension_path($this->ext_name); + $metadata_filepath = $this->phpbb_root_path . $ext_filepath . 'composer.json'; + + $this->metadata_file = $metadata_filepath; + + if (!file_exists($this->metadata_file)) + { + throw new phpbb_extension_exception('The required file does not exist: ' . $this->metadata_file); + } + } + + /** + * Gets the contents of the composer.json file + * + * @return bool True if success, throws an exception on failure + */ + private function fetch_metadata() + { + if (!file_exists($this->metadata_file)) + { + throw new phpbb_extension_exception('The required file does not exist: ' . $this->metadata_file); + } + else + { + if (!($file_contents = file_get_contents($this->metadata_file))) + { + throw new phpbb_extension_exception('file_get_contents failed on ' . $this->metadata_file); + } + + if (($metadata = json_decode($file_contents, true)) === NULL) + { + throw new phpbb_extension_exception('json_decode failed on ' . $this->metadata_file); + } + + $this->metadata = $metadata; + + return true; + } + } + + /** + * This array handles the cleaning of the array + * + * @return array Contains the cleaned metadata array + */ + private function clean_metadata_array() + { + return $this->metadata; + } + + /** + * Validate fields + * + * @param string $name ("all" for display and enable validation + * "display" for name, type, and authors + * "name", "type") + * @return Bool True if valid, throws an exception if invalid + */ + public function validate($name = 'display') + { + // Basic fields + $fields = array( + 'name' => '#^[a-zA-Z0-9_\x7f-\xff]{2,}/[a-zA-Z0-9_\x7f-\xff]{2,}$#', + 'type' => '#^phpbb3-extension$#', + 'licence' => '#.+#', + 'version' => '#.+#', + ); + + switch ($name) + { + case 'all': + $this->validate('display'); + + $this->validate_enable(); + break; + + case 'display': + foreach ($fields as $field => $data) + { + $this->validate($field); + } + + $this->validate_authors(); + break; + + default: + if (isset($fields[$name])) + { + if (!isset($this->metadata[$name])) + { + throw new phpbb_extension_exception("Required meta field '$name' has not been set."); + } + + if (!preg_match($fields[$name], $this->metadata[$name])) + { + throw new phpbb_extension_exception("Meta field '$name' is invalid."); + } + } + break; + } + + return true; + } + + /** + * Validates the contents of the authors field + * + * @return boolean True when passes validation, throws exception if invalid + */ + public function validate_authors() + { + if (empty($this->metadata['authors'])) + { + throw new phpbb_extension_exception("Required meta field 'authors' has not been set."); + } + + foreach ($this->metadata['authors'] as $author) + { + if (!isset($author['name'])) + { + throw new phpbb_extension_exception("Required meta field 'author name' has not been set."); + } + } + + return true; + } + + /** + * This array handles the verification that this extension can be enabled on this board + * + * @return bool True if validation succeeded, False if failed + */ + public function validate_enable() + { + // Check for phpBB, PHP versions + if (!$this->validate_require_phpbb() || !$this->validate_require_php()) + { + return false; + } + + return true; + } + + + /** + * Validates the contents of the phpbb requirement field + * + * @return boolean True when passes validation + */ + public function validate_require_phpbb() + { + if (!isset($this->metadata['require']['phpbb'])) + { + return true; + } + + return $this->_validate_version($this->metadata['require']['phpbb'], $this->config['version']); + } + + /** + * Validates the contents of the php requirement field + * + * @return boolean True when passes validation + */ + public function validate_require_php() + { + if (!isset($this->metadata['require']['php'])) + { + return true; + } + + return $this->_validate_version($this->metadata['require']['php'], phpversion()); + } + + /** + * Version validation helper + * + * @param string $string The string for comparing to a version + * @param string $current_version The version to compare to + * @return bool True/False if meets version requirements + */ + private function _validate_version($string, $current_version) + { + // Allow them to specify their own comparison operator (ex: <3.1.2, >=3.1.0) + $comparison_matches = false; + preg_match('#[=<>]+#', $string, $comparison_matches); + + if (!empty($comparison_matches)) + { + return version_compare($current_version, str_replace(array($comparison_matches[0], ' '), '', $string), $comparison_matches[0]); + } + + return version_compare($current_version, $string, '>='); + } + + /** + * Outputs the metadata into the template + * + * @return null + */ + public function output_template_data() + { + $this->template->assign_vars(array( + 'META_NAME' => htmlspecialchars($this->metadata['name']), + 'META_TYPE' => htmlspecialchars($this->metadata['type']), + 'META_DESCRIPTION' => (isset($this->metadata['description'])) ? htmlspecialchars($this->metadata['description']) : '', + 'META_HOMEPAGE' => (isset($this->metadata['homepage'])) ? $this->metadata['homepage'] : '', + 'META_VERSION' => (isset($this->metadata['version'])) ? htmlspecialchars($this->metadata['version']) : '', + 'META_TIME' => (isset($this->metadata['time'])) ? htmlspecialchars($this->metadata['time']) : '', + 'META_LICENCE' => htmlspecialchars($this->metadata['licence']), + + 'META_REQUIRE_PHP' => (isset($this->metadata['require']['php'])) ? htmlspecialchars($this->metadata['require']['php']) : '', + 'META_REQUIRE_PHP_FAIL' => !$this->validate_require_php(), + + 'META_REQUIRE_PHPBB' => (isset($this->metadata['require']['phpbb'])) ? htmlspecialchars($this->metadata['require']['phpbb']) : '', + 'META_REQUIRE_PHPBB_FAIL' => !$this->validate_require_phpbb(), + + 'META_DISPLAY_NAME' => (isset($this->metadata['extra']['display-name'])) ? htmlspecialchars($this->metadata['extra']['display-name']) : '', + )); + + foreach ($this->metadata['authors'] as $author) + { + $this->template->assign_block_vars('meta_authors', array( + 'AUTHOR_NAME' => htmlspecialchars($author['name']), + 'AUTHOR_EMAIL' => (isset($author['email'])) ? $author['email'] : '', + 'AUTHOR_HOMEPAGE' => (isset($author['homepage'])) ? $author['homepage'] : '', + 'AUTHOR_ROLE' => (isset($author['role'])) ? htmlspecialchars($author['role']) : '', + )); + } + } +} diff --git a/phpBB/includes/extension/provider.php b/phpBB/includes/extension/provider.php index d0541fa007..45b55e5cab 100644 --- a/phpBB/includes/extension/provider.php +++ b/phpBB/includes/extension/provider.php @@ -16,7 +16,15 @@ if (!defined('IN_PHPBB')) } /** -* Provides a set of items found in extensions +* Provides a set of items found in extensions. +* +* This abstract class is essentially a wrapper around item-specific +* finding logic. It handles storing the extension manager via constructor +* for the finding logic to use to find the items, and provides an +* iterator interface over the items found by the finding logic. +* +* Items could be anything, for example template paths or cron task names. +* Derived classes completely define what the items are. * * @package extension */ @@ -45,7 +53,7 @@ abstract class phpbb_extension_provider implements IteratorAggregate } /** - * Finds template paths using the extension manager. + * Finds items using the extension manager. * * @return array List of task names */ diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 4b7b3d5057..469574b153 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1018,6 +1018,36 @@ else } } +/** +* Eliminates useless . and .. components from specified path. +* +* @param string $path Path to clean +* @return string Cleaned path +*/ +function phpbb_clean_path($path) +{ + $exploded = explode('/', $path); + $filtered = array(); + foreach ($exploded as $part) + { + if ($part === '.' && !empty($filtered)) + { + continue; + } + + if ($part === '..' && !empty($filtered) && $filtered[sizeof($filtered) - 1] !== '..') + { + array_pop($filtered); + } + else + { + $filtered[] = $part; + } + } + $path = implode('/', $filtered); + return $path; +} + // functions used for building option fields /** @@ -1280,6 +1310,10 @@ function phpbb_timezone_select($user, $default = '', $truncate = false) * Marks a topic/forum as read * Marks a topic as posted to * +* @param string $mode (all, topics, topic, post) +* @param int|bool $forum_id Used in all, topics, and topic mode +* @param int|bool $topic_id Used in topic and post mode +* @param int $post_time 0 means current time(), otherwise to set a specific mark time * @param int $user_id can only be used with $mode == 'post' */ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $user_id = 0) @@ -1287,6 +1321,8 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ global $db, $user, $config; global $request; + $post_time = ($post_time === 0 || $post_time > time()) ? time() : (int) $post_time; + if ($mode == 'all') { if ($forum_id === false || !sizeof($forum_id)) @@ -1294,9 +1330,20 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ if ($config['load_db_lastread'] && $user->data['is_registered']) { // Mark all forums read (index page) - $db->sql_query('DELETE FROM ' . TOPICS_TRACK_TABLE . " WHERE user_id = {$user->data['user_id']}"); - $db->sql_query('DELETE FROM ' . FORUMS_TRACK_TABLE . " WHERE user_id = {$user->data['user_id']}"); - $db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_lastmark = ' . time() . " WHERE user_id = {$user->data['user_id']}"); + $tables = array(TOPICS_TRACK_TABLE, FORUMS_TRACK_TABLE); + foreach ($tables as $table) + { + $sql = 'DELETE FROM ' . $table . " + WHERE user_id = {$user->data['user_id']} + AND mark_time < $post_time"; + $db->sql_query($sql); + } + + $sql = 'UPDATE ' . USERS_TABLE . " + SET user_lastmark = $post_time + WHERE user_id = {$user->data['user_id']} + AND user_lastmark < $post_time"; + $db->sql_query($sql); } else if ($config['load_anon_lastread'] || $user->data['is_registered']) { @@ -1306,16 +1353,20 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ unset($tracking_topics['tf']); unset($tracking_topics['t']); unset($tracking_topics['f']); - $tracking_topics['l'] = base_convert(time() - $config['board_startdate'], 10, 36); + $tracking_topics['l'] = base_convert($post_time - $config['board_startdate'], 10, 36); - $user->set_cookie('track', tracking_serialize($tracking_topics), time() + 31536000); + $user->set_cookie('track', tracking_serialize($tracking_topics), $post_time + 31536000); $request->overwrite($config['cookie_name'] . '_track', tracking_serialize($tracking_topics), phpbb_request_interface::COOKIE); unset($tracking_topics); if ($user->data['is_registered']) { - $db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_lastmark = ' . time() . " WHERE user_id = {$user->data['user_id']}"); + $sql = 'UPDATE ' . USERS_TABLE . " + SET user_lastmark = $post_time + WHERE user_id = {$user->data['user_id']} + AND user_lastmark < $post_time"; + $db->sql_query($sql); } } } @@ -1337,12 +1388,14 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ { $sql = 'DELETE FROM ' . TOPICS_TRACK_TABLE . " WHERE user_id = {$user->data['user_id']} + AND mark_time < $post_time AND " . $db->sql_in_set('forum_id', $forum_id); $db->sql_query($sql); $sql = 'SELECT forum_id FROM ' . FORUMS_TRACK_TABLE . " WHERE user_id = {$user->data['user_id']} + AND mark_time < $post_time AND " . $db->sql_in_set('forum_id', $forum_id); $result = $db->sql_query($sql); @@ -1355,9 +1408,10 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ if (sizeof($sql_update)) { - $sql = 'UPDATE ' . FORUMS_TRACK_TABLE . ' - SET mark_time = ' . time() . " + $sql = 'UPDATE ' . FORUMS_TRACK_TABLE . " + SET mark_time = $post_time WHERE user_id = {$user->data['user_id']} + AND mark_time < $post_time AND " . $db->sql_in_set('forum_id', $sql_update); $db->sql_query($sql); } @@ -1370,7 +1424,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ $sql_ary[] = array( 'user_id' => (int) $user->data['user_id'], 'forum_id' => (int) $f_id, - 'mark_time' => time() + 'mark_time' => $post_time, ); } @@ -1401,7 +1455,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ unset($tracking['f'][$f_id]); } - $tracking['f'][$f_id] = base_convert(time() - $config['board_startdate'], 10, 36); + $tracking['f'][$f_id] = base_convert($post_time - $config['board_startdate'], 10, 36); } if (isset($tracking['tf']) && empty($tracking['tf'])) @@ -1409,7 +1463,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ unset($tracking['tf']); } - $user->set_cookie('track', tracking_serialize($tracking), time() + 31536000); + $user->set_cookie('track', tracking_serialize($tracking), $post_time + 31536000); $request->overwrite($config['cookie_name'] . '_track', tracking_serialize($tracking), phpbb_request_interface::COOKIE); unset($tracking); @@ -1426,9 +1480,10 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ if ($config['load_db_lastread'] && $user->data['is_registered']) { - $sql = 'UPDATE ' . TOPICS_TRACK_TABLE . ' - SET mark_time = ' . (($post_time) ? $post_time : time()) . " + $sql = 'UPDATE ' . TOPICS_TRACK_TABLE . " + SET mark_time = $post_time WHERE user_id = {$user->data['user_id']} + AND mark_time < $post_time AND topic_id = $topic_id"; $db->sql_query($sql); @@ -1441,7 +1496,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ 'user_id' => (int) $user->data['user_id'], 'topic_id' => (int) $topic_id, 'forum_id' => (int) $forum_id, - 'mark_time' => ($post_time) ? (int) $post_time : time(), + 'mark_time' => $post_time, ); $db->sql_query('INSERT INTO ' . TOPICS_TRACK_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); @@ -1461,7 +1516,6 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ $tracking['tf'][$forum_id][$topic_id36] = true; } - $post_time = ($post_time) ? $post_time : time(); $tracking['t'][$topic_id36] = base_convert($post_time - $config['board_startdate'], 10, 36); // If the cookie grows larger than 10000 characters we will remove the smallest value @@ -1497,7 +1551,12 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ if ($user->data['is_registered']) { $user->data['user_lastmark'] = intval(base_convert(max($time_keys) + $config['board_startdate'], 36, 10)); - $db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_lastmark = ' . $user->data['user_lastmark'] . " WHERE user_id = {$user->data['user_id']}"); + + $sql = 'UPDATE ' . USERS_TABLE . " + SET user_lastmark = $post_time + WHERE user_id = {$user->data['user_id']} + AND mark_time < $post_time"; + $db->sql_query($sql); } else { @@ -1505,7 +1564,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ } } - $user->set_cookie('track', tracking_serialize($tracking), time() + 31536000); + $user->set_cookie('track', tracking_serialize($tracking), $post_time + 31536000); $request->overwrite($config['cookie_name'] . '_track', tracking_serialize($tracking), phpbb_request_interface::COOKIE); } @@ -1527,7 +1586,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ $sql_ary = array( 'user_id' => (int) $use_user_id, 'topic_id' => (int) $topic_id, - 'topic_posted' => 1 + 'topic_posted' => 1, ); $db->sql_query('INSERT INTO ' . TOPICS_POSTED_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); @@ -2086,7 +2145,7 @@ function phpbb_generate_template_pagination($template, $base_url, $block_var_nam $on_page = floor($start_item / $per_page) + 1; $url_delim = (strpos($base_url, '?') === false) ? '?' : ((strpos($base_url, '?') === strlen($base_url) - 1) ? '' : '&'); - + if ($reverse_count) { $start_page = ($total_pages > 5) ? $total_pages - 4 : 1; @@ -2095,9 +2154,9 @@ function phpbb_generate_template_pagination($template, $base_url, $block_var_nam else { // What we're doing here is calculating what the "start" and "end" pages should be. We - // do this by assuming pagination is "centered" around the currently active page with - // the three previous and three next page links displayed. Anything more than that and - // we display the ellipsis, likewise anything less. + // do this by assuming pagination is "centered" around the currently active page with + // the three previous and three next page links displayed. Anything more than that and + // we display the ellipsis, likewise anything less. // // $start_page is the page at which we start creating the list. When we have five or less // pages we start at page 1 since there will be no ellipsis displayed. Anymore than that @@ -2113,21 +2172,21 @@ function phpbb_generate_template_pagination($template, $base_url, $block_var_nam $end_page = ($total_pages > 5) ? max(min($total_pages, $on_page + 3), 5) : $total_pages; } - if ($on_page != $total_pages) + if ($on_page != 1) { $template->assign_block_vars($block_var_name, array( - 'PAGE_NUMBER' => '', - 'PAGE_URL' => $base_url . $url_delim . $start_name . '=' . ($on_page * $per_page), - 'S_IS_CURRENT' => false, - 'S_IS_PREV' => false, - 'S_IS_NEXT' => true, - 'S_IS_ELLIPSIS' => false, + 'PAGE_NUMBER' => '', + 'PAGE_URL' => $base_url . $url_delim . $start_name . '=' . (($on_page - 2) * $per_page), + 'S_IS_CURRENT' => false, + 'S_IS_PREV' => true, + 'S_IS_NEXT' => false, + 'S_IS_ELLIPSIS' => false, )); - } + } // This do...while exists purely to negate the need for start and end assign_block_vars, i.e. - // to display the first and last page in the list plus any ellipsis. We use this loop to jump - // around a little within the list depending on where we're starting (and ending). + // to display the first and last page in the list plus any ellipsis. We use this loop to jump + // around a little within the list depending on where we're starting (and ending). $at_page = 1; do { @@ -2138,17 +2197,17 @@ function phpbb_generate_template_pagination($template, $base_url, $block_var_nam // of those points and of course do we even need to display it, i.e. is the list starting // on at least page 3 and ending three pages before the final item. $template->assign_block_vars($block_var_name, array( - 'PAGE_NUMBER' => $at_page, + 'PAGE_NUMBER' => $at_page, 'PAGE_URL' => $page_url, - 'S_IS_CURRENT' => (!$ignore_on_page && $at_page == $on_page), - 'S_IS_NEXT' => false, - 'S_IS_PREV' => false, - 'S_IS_ELLIPSIS' => ($at_page == 2 && $start_page > 2) || ($at_page == $total_pages - 1 && $end_page < $total_pages - 1), + 'S_IS_CURRENT' => (!$ignore_on_page && $at_page == $on_page), + 'S_IS_NEXT' => false, + 'S_IS_PREV' => false, + 'S_IS_ELLIPSIS' => ($at_page == 2 && $start_page > 2) || ($at_page == $total_pages - 1 && $end_page < $total_pages - 1), )); - // We may need to jump around in the list depending on whether we have or need to display + // We may need to jump around in the list depending on whether we have or need to display // the ellipsis. Are we on page 2 and are we more than one page away from the start - // of the list? Yes? Then we jump to the start of the list. Likewise are we at the end of + // of the list? Yes? Then we jump to the start of the list. Likewise are we at the end of // the list and are there more than two pages left in total? Yes? Then jump to the penultimate // page (so we can display the ellipsis next pass). Else, increment the counter and keep // going @@ -2167,21 +2226,60 @@ function phpbb_generate_template_pagination($template, $base_url, $block_var_nam } while ($at_page <= $total_pages); - if ($on_page != 1) + if ($on_page != $total_pages) { $template->assign_block_vars($block_var_name, array( - 'PAGE_NUMBER' => '', - 'PAGE_URL' => $base_url . $url_delim . $start_name . '=' . (($on_page - 2) * $per_page), - 'S_IS_CURRENT' => false, - 'S_IS_PREV' => true, - 'S_IS_NEXT' => false, - 'S_IS_ELLIPSIS' => false, + 'PAGE_NUMBER' => '', + 'PAGE_URL' => $base_url . $url_delim . $start_name . '=' . ($on_page * $per_page), + 'S_IS_CURRENT' => false, + 'S_IS_PREV' => false, + 'S_IS_NEXT' => true, + 'S_IS_ELLIPSIS' => false, )); } + + // If the block_var_name is a nested block, we will use the last (most + // inner) block as a prefix for the template variables. If the last block + // name is pagination, the prefix is empty. If the rest of the + // block_var_name is not empty, we will modify the last row of that block + // and add our pagination items. + $tpl_block_name = $tpl_prefix = ''; + if (strrpos($block_var_name, '.') !== false) + { + $tpl_block_name = substr($block_var_name, 0, strrpos($block_var_name, '.')); + $tpl_prefix = strtoupper(substr($block_var_name, strrpos($block_var_name, '.') + 1)); + } + else + { + $tpl_prefix = strtoupper($block_var_name); + } + $tpl_prefix = ($tpl_prefix == 'PAGINATION') ? '' : $tpl_prefix . '_'; + + $previous_page = ($on_page != 1) ? $base_url . $url_delim . $start_name . '=' . (($on_page - 2) * $per_page) : ''; + + $template_array = array( + $tpl_prefix . 'BASE_URL' => $base_url, + 'A_' . $tpl_prefix . 'BASE_URL' => addslashes($base_url), + $tpl_prefix . 'PER_PAGE' => $per_page, + $tpl_prefix . 'PREVIOUS_PAGE' => $previous_page, + $tpl_prefix . 'PREV_PAGE' => $previous_page, + $tpl_prefix . 'NEXT_PAGE' => ($on_page != $total_pages) ? $base_url . $url_delim . $start_name . '=' . ($on_page * $per_page) : '', + $tpl_prefix . 'TOTAL_PAGES' => $total_pages, + $tpl_prefix . 'CURRENT_PAGE' => $on_page, + ); + + if ($tpl_block_name) + { + $template->alter_block_array($tpl_block_name, $template_array, true, 'change'); + } + else + { + $template->assign_vars($template_array); + } } /** -* Return current page +* Return current page * This function also sets certain specific template variables * * @param object $template the template object @@ -2201,9 +2299,8 @@ function phpbb_on_page($template, $user, $base_url, $num_items, $per_page, $star $template->assign_vars(array( 'PER_PAGE' => $per_page, - 'ON_PAGE' => $on_page, - - 'A_BASE_URL' => addslashes($base_url), + 'ON_PAGE' => $on_page, + 'A_BASE_URL' => addslashes($base_url), )); return sprintf($user->lang['PAGE_OF'], $on_page, max(ceil($num_items / $per_page), 1)); @@ -2232,6 +2329,7 @@ function phpbb_on_page($template, $user, $base_url, $num_items, $per_page, $star function append_sid($url, $params = false, $is_amp = true, $session_id = false) { global $_SID, $_EXTRA_URL, $phpbb_hook; + global $phpbb_dispatcher; if ($params === '' || (is_array($params) && empty($params))) { @@ -2239,6 +2337,39 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false) $params = false; } + $append_sid_overwrite = false; + + /** + * This event can either supplement or override the append_sid() function + * + * To override this function, the event must set $append_sid_overwrite to + * the new URL value, which will be returned following the event + * + * @event core.append_sid + * @var string url The url the session id needs + * to be appended to (can have + * params) + * @var mixed params String or array of additional + * url parameters + * @var bool is_amp Is url using & (true) or + * & (false) + * @var bool|string session_id Possibility to use a custom + * session id (string) instead of + * the global one (false) + * @var bool|string append_sid_overwrite Overwrite function (string + * URL) or not (false) + * @since 3.1-A1 + */ + $vars = array('url', 'params', 'is_amp', 'session_id', 'append_sid_overwrite'); + extract($phpbb_dispatcher->trigger_event('core.append_sid', compact($vars))); + + if ($append_sid_overwrite) + { + return $append_sid_overwrite; + } + + // The following hook remains for backwards compatibility, though use of + // the event above is preferred. // Developers using the hook function need to globalise the $_SID and $_EXTRA_URL on their own and also handle it appropriately. // They could mimic most of what is within this function if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__, $url, $params, $is_amp, $session_id)) @@ -2822,7 +2953,7 @@ function check_form_key($form_name, $timespan = false, $return_page = '', $trigg $diff = time() - $creation_time; // If creation_time and the time() now is zero we can assume it was not a human doing this (the check for if ($diff)... - if ($diff && ($diff <= $timespan || $timespan === -1)) + if (defined('DEBUG_TEST') || $diff && ($diff <= $timespan || $timespan === -1)) { $token_sid = ($user->data['user_id'] == ANONYMOUS && !empty($config['form_token_sid_guests'])) ? $user->session_id : ''; $key = sha1($creation_time . $user->data['user_form_salt'] . $form_name . $token_sid); @@ -3011,11 +3142,11 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa trigger_error('NO_AUTH_ADMIN'); } - $password = request_var('password_' . $credential, '', true); + $password = $request->untrimmed_variable('password_' . $credential, '', true); } else { - $password = request_var('password', '', true); + $password = $request->untrimmed_variable('password', '', true); } $username = request_var('username', '', true); @@ -3344,7 +3475,7 @@ function parse_cfg_file($filename, $lines = false) $parsed_items[$key] = $value; } - + if (isset($parsed_items['parent']) && isset($parsed_items['name']) && $parsed_items['parent'] == $parsed_items['name']) { unset($parsed_items['parent']); @@ -4114,7 +4245,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline) echo ' </div>'; echo ' </div>'; echo ' <div id="page-footer">'; - echo ' Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group'; + echo ' Powered by <a href="https://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group'; echo ' </div>'; echo '</div>'; echo '</body>'; @@ -4961,6 +5092,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'L_LOGIN_LOGOUT' => $l_login_logout, 'L_INDEX' => $user->lang['FORUM_INDEX'], + 'L_SITE_HOME' => ($config['site_home_text'] !== '') ? $config['site_home_text'] : $user->lang['HOME'], 'L_ONLINE_EXPLAIN' => $l_online_time, 'U_PRIVATEMSGS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox'), @@ -4972,6 +5104,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'U_LOGIN_LOGOUT' => $u_login_logout, 'U_INDEX' => append_sid("{$phpbb_root_path}index.$phpEx"), 'U_SEARCH' => append_sid("{$phpbb_root_path}search.$phpEx"), + 'U_SITE_HOME' => $config['site_home_url'], 'U_REGISTER' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register'), 'U_PROFILE' => append_sid("{$phpbb_root_path}ucp.$phpEx"), 'U_MODCP' => append_sid("{$phpbb_root_path}mcp.$phpEx", false, true, $user->session_id), @@ -5135,7 +5268,7 @@ function page_footer($run_cron = true) $template->assign_vars(array( 'DEBUG_OUTPUT' => (defined('DEBUG')) ? $debug_output : '', 'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '', - 'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group'), + 'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group'), 'U_ACP' => ($auth->acl_get('a_') && !empty($user->data['is_registered'])) ? append_sid("{$phpbb_root_path}adm/index.$phpEx", false, true, $user->session_id) : '') ); diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php index 2f0188289b..11cc1f6dd8 100644 --- a/phpBB/includes/functions_acp.php +++ b/phpBB/includes/functions_acp.php @@ -172,7 +172,7 @@ function adm_page_footer($copyright_html = true) 'DEBUG_OUTPUT' => (defined('DEBUG')) ? $debug_output : '', 'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '', 'S_COPYRIGHT_HTML' => $copyright_html, - 'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group'), + 'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group'), 'T_JQUERY_LINK' => ($config['load_jquery_cdn'] && !empty($config['load_jquery_url'])) ? $config['load_jquery_url'] : "{$phpbb_root_path}assets/javascript/jquery.js", 'S_JQUERY_FALLBACK' => ($config['load_jquery_cdn']) ? true : false, 'VERSION' => $config['version']) diff --git a/phpBB/includes/functions_compress.php b/phpBB/includes/functions_compress.php index 8e07e6d1b8..c79a31930e 100644 --- a/phpBB/includes/functions_compress.php +++ b/phpBB/includes/functions_compress.php @@ -159,8 +159,10 @@ class compress /** * Return available methods + * + * @return array Array of strings of available compression methods (.tar, .tar.gz, .zip, etc.) */ - function methods() + static public function methods() { $methods = array('.tar'); $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib'); diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php index 6b2ee98d7a..c54cc25f34 100644 --- a/phpBB/includes/functions_content.php +++ b/phpBB/includes/functions_content.php @@ -408,16 +408,34 @@ function strip_bbcode(&$text, $uid = '') * For display of custom parsed text on user-facing pages * Expects $text to be the value directly from the database (stored value) */ -function generate_text_for_display($text, $uid, $bitfield, $flags) +function generate_text_for_display($text, $uid, $bitfield, $flags, $censor_text = true) { static $bbcode; + global $phpbb_dispatcher; if (!$text) { return ''; } - $text = censor_text($text); + /** + * Use this event to modify the text before it is parsed + * + * @event core.modify_text_for_display_before + * @var string text The text to parse + * @var string uid The BBCode UID + * @var string bitfield The BBCode Bitfield + * @var int flags The BBCode Flags + * @var bool censor_text Whether or not to apply word censors + * @since 3.1-A1 + */ + $vars = array('text', 'uid', 'bitfield', 'flags', 'censor_text'); + extract($phpbb_dispatcher->trigger_event('core.modify_text_for_display_before', compact($vars))); + + if ($censor_text) + { + $text = censor_text($text); + } // Parse bbcode if bbcode uid stored and bbcode enabled if ($uid && ($flags & OPTION_FLAG_BBCODE)) @@ -443,6 +461,19 @@ function generate_text_for_display($text, $uid, $bitfield, $flags) $text = bbcode_nl2br($text); $text = smiley_text($text, !($flags & OPTION_FLAG_SMILIES)); + /** + * Use this event to modify the text after it is parsed + * + * @event core.modify_text_for_display_after + * @var string text The text to parse + * @var string uid The BBCode UID + * @var string bitfield The BBCode Bitfield + * @var int flags The BBCode Flags + * @since 3.1-A1 + */ + $vars = array('text', 'uid', 'bitfield', 'flags'); + extract($phpbb_dispatcher->trigger_event('core.modify_text_for_display_after', compact($vars))); + return $text; } @@ -453,7 +484,23 @@ function generate_text_for_display($text, $uid, $bitfield, $flags) */ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bbcode = false, $allow_urls = false, $allow_smilies = false) { - global $phpbb_root_path, $phpEx; + global $phpbb_root_path, $phpEx, $phpbb_dispatcher; + + /** + * Use this event to modify the text before it is prepared for storage + * + * @event core.modify_text_for_storage_before + * @var string text The text to parse + * @var string uid The BBCode UID + * @var string bitfield The BBCode Bitfield + * @var int flags The BBCode Flags + * @var bool allow_bbcode Whether or not to parse BBCode + * @var bool allow_urls Whether or not to parse URLs + * @var bool allow_smilies Whether or not to parse Smilies + * @since 3.1-A1 + */ + $vars = array('text', 'uid', 'bitfield', 'flags', 'allow_bbcode', 'allow_urls', 'allow_smilies'); + extract($phpbb_dispatcher->trigger_event('core.modify_text_for_storage_before', compact($vars))); $uid = $bitfield = ''; $flags = (($allow_bbcode) ? OPTION_FLAG_BBCODE : 0) + (($allow_smilies) ? OPTION_FLAG_SMILIES : 0) + (($allow_urls) ? OPTION_FLAG_LINKS : 0); @@ -482,6 +529,19 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb $bitfield = $message_parser->bbcode_bitfield; + /** + * Use this event to modify the text after it is prepared for storage + * + * @event core.modify_text_for_storage_after + * @var string text The text to parse + * @var string uid The BBCode UID + * @var string bitfield The BBCode Bitfield + * @var int flags The BBCode Flags + * @since 3.1-A1 + */ + $vars = array('text', 'uid', 'bitfield', 'flags'); + extract($phpbb_dispatcher->trigger_event('core.modify_text_for_storage_after', compact($vars))); + return; } @@ -491,10 +551,33 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb */ function generate_text_for_edit($text, $uid, $flags) { - global $phpbb_root_path, $phpEx; + global $phpbb_root_path, $phpEx, $phpbb_dispatcher; + + /** + * Use this event to modify the text before it is decoded for editing + * + * @event core.modify_text_for_edit_before + * @var string text The text to parse + * @var string uid The BBCode UID + * @var int flags The BBCode Flags + * @since 3.1-A1 + */ + $vars = array('text', 'uid', 'flags'); + extract($phpbb_dispatcher->trigger_event('core.modify_text_for_edit_before', compact($vars))); decode_message($text, $uid); + /** + * Use this event to modify the text after it is decoded for editing + * + * @event core.modify_text_for_edit_after + * @var string text The text to parse + * @var int flags The BBCode Flags + * @since 3.1-A1 + */ + $vars = array('text', 'flags'); + extract($phpbb_dispatcher->trigger_event('core.modify_text_for_edit_after', compact($vars))); + return array( 'allow_bbcode' => ($flags & OPTION_FLAG_BBCODE) ? 1 : 0, 'allow_smilies' => ($flags & OPTION_FLAG_SMILIES) ? 1 : 0, @@ -1175,6 +1258,7 @@ function truncate_string($string, $max_length = 60, $max_store_length = 255, $al function get_username_string($mode, $user_id, $username, $username_colour = '', $guest_username = false, $custom_profile_url = false) { static $_profile_cache; + global $phpbb_dispatcher; // We cache some common variables we need within this function if (empty($_profile_cache)) @@ -1252,10 +1336,34 @@ function get_username_string($mode, $user_id, $username, $username_colour = '', if (($mode == 'full' && !$profile_url) || $mode == 'no_profile') { - return str_replace(array('{USERNAME_COLOUR}', '{USERNAME}'), array($username_colour, $username), (!$username_colour) ? $_profile_cache['tpl_noprofile'] : $_profile_cache['tpl_noprofile_colour']); + $username_string = str_replace(array('{USERNAME_COLOUR}', '{USERNAME}'), array($username_colour, $username), (!$username_colour) ? $_profile_cache['tpl_noprofile'] : $_profile_cache['tpl_noprofile_colour']); + } + else + { + $username_string = str_replace(array('{PROFILE_URL}', '{USERNAME_COLOUR}', '{USERNAME}'), array($profile_url, $username_colour, $username), (!$username_colour) ? $_profile_cache['tpl_profile'] : $_profile_cache['tpl_profile_colour']); } + + /** + * Use this event to change the output of get_username_string() + * + * @event core.modify_username_string + * @var string mode profile|username|colour|full|no_profile + * @var int user_id String or array of additional url + * parameters + * @var string username The user's username + * @var string username_colour The user's colour + * @var string guest_username Optional parameter to specify the + * guest username. + * @var string custom_profile_url Optional parameter to specify a + * profile url. + * @var string username_string The string that has been generated + * @var array _profile_cache Array of original return templates + * @since 3.1-A1 + */ + $vars = array('mode', 'user_id', 'username', 'username_colour', 'guest_username', 'custom_profile_url', 'username_string', '_profile_cache'); + extract($phpbb_dispatcher->trigger_event('core.modify_username_string', compact($vars))); - return str_replace(array('{PROFILE_URL}', '{USERNAME_COLOUR}', '{USERNAME}'), array($profile_url, $username_colour, $username), (!$username_colour) ? $_profile_cache['tpl_profile'] : $_profile_cache['tpl_profile_colour']); + return $username_string; } /** diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 6f166e2a14..7e7e625e91 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -54,12 +54,12 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod // Handle marking everything read if ($mark_read == 'all') { - $redirect = build_url(array('mark', 'hash')); + $redirect = build_url(array('mark', 'hash', 'mark_time')); meta_refresh(3, $redirect); if (check_link_hash(request_var('hash', ''), 'global')) { - markread('all'); + markread('all', false, false, request_var('mark_time', 0)); trigger_error( $user->lang['FORUMS_MARKED'] . '<br /><br />' . @@ -306,11 +306,11 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod // Handle marking posts if ($mark_read == 'forums') { - $redirect = build_url(array('mark', 'hash')); + $redirect = build_url(array('mark', 'hash', 'mark_time')); $token = request_var('hash', ''); if (check_link_hash($token, 'global')) { - markread('topics', $forum_ids); + markread('topics', $forum_ids, false, request_var('mark_time', 0)); $message = sprintf($user->lang['RETURN_FORUM'], '<a href="' . $redirect . '">', '</a>'); meta_refresh(3, $redirect); @@ -552,7 +552,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod } $template->assign_vars(array( - 'U_MARK_FORUMS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . '&f=' . $root_data['forum_id'] . '&mark=forums') : '', + 'U_MARK_FORUMS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . '&f=' . $root_data['forum_id'] . '&mark=forums&mark_time=' . time()) : '', 'S_HAS_SUBFORUM' => ($visible_forums) ? true : false, 'L_SUBFORUM' => ($visible_forums == 1) ? $user->lang['SUBFORUM'] : $user->lang['SUBFORUMS'], 'LAST_POST_IMG' => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'), @@ -1401,7 +1401,8 @@ function phpbb_gen_download_links($param_key, $param_val, $phpbb_root_path, $php foreach ($methods as $method) { - $type = array_pop(explode('.', $method)); + $exploded = explode('.', $method); + $type = array_pop($exploded); $params = array('archive' => $method); $params[$param_key] = $param_val; diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index 46541acd44..10ec13669b 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -522,10 +522,12 @@ function adjust_language_keys_callback($matches) * @param string $dbms The name of the DBAL class to use * @param array $load_extensions Array of additional extensions that should be loaded * @param bool $debug If the debug constants should be enabled by default or not +* @param bool $debug_test If the DEBUG_TEST constant should be added +* NOTE: Only for use within the testing framework * * @return string The output to write to the file */ -function phpbb_create_config_file_data($data, $dbms, $load_extensions, $debug = false) +function phpbb_create_config_file_data($data, $dbms, $load_extensions, $debug = false, $debug_test = false) { $load_extensions = implode(',', $load_extensions); @@ -540,7 +542,7 @@ function phpbb_create_config_file_data($data, $dbms, $load_extensions, $debug = 'dbuser' => $data['dbuser'], 'dbpasswd' => htmlspecialchars_decode($data['dbpasswd']), 'table_prefix' => $data['table_prefix'], - 'acm_type' => 'file', + 'acm_type' => 'phpbb_cache_driver_file', 'load_extensions' => $load_extensions, ); @@ -562,5 +564,10 @@ function phpbb_create_config_file_data($data, $dbms, $load_extensions, $debug = $config_data .= "// @define('DEBUG_EXTRA', true);\n"; } + if ($debug_test) + { + $config_data .= "@define('DEBUG_TEST', true);\n"; + } + return $config_data; } diff --git a/phpBB/includes/functions_jabber.php b/phpBB/includes/functions_jabber.php index d76309d5bb..3d8e403f4b 100644 --- a/phpBB/includes/functions_jabber.php +++ b/phpBB/includes/functions_jabber.php @@ -68,7 +68,7 @@ class jabber } $this->password = $password; - $this->use_ssl = ($use_ssl && $this->can_use_ssl()) ? true : false; + $this->use_ssl = ($use_ssl && self::can_use_ssl()) ? true : false; // Change port if we use SSL if ($this->port == 5222 && $this->use_ssl) @@ -83,7 +83,7 @@ class jabber /** * Able to use the SSL functionality? */ - function can_use_ssl() + static public function can_use_ssl() { // Will not work with PHP >= 5.2.1 or < 5.2.3RC2 until timeout problem with ssl hasn't been fixed (http://bugs.php.net/41236) return ((version_compare(PHP_VERSION, '5.2.1', '<') || version_compare(PHP_VERSION, '5.2.3RC2', '>=')) && @extension_loaded('openssl')) ? true : false; @@ -92,7 +92,7 @@ class jabber /** * Able to use TLS? */ - function can_use_tls() + static public function can_use_tls() { if (!@extension_loaded('openssl') || !function_exists('stream_socket_enable_crypto') || !function_exists('stream_get_meta_data') || !function_exists('socket_set_blocking') || !function_exists('stream_get_wrappers')) { @@ -442,7 +442,7 @@ class jabber } // Let's use TLS if SSL is not enabled and we can actually use it - if (!$this->session['ssl'] && $this->can_use_tls() && $this->can_use_ssl() && isset($xml['stream:features'][0]['#']['starttls'])) + if (!$this->session['ssl'] && self::can_use_tls() && self::can_use_ssl() && isset($xml['stream:features'][0]['#']['starttls'])) { $this->add_to_log('Switching to TLS.'); $this->send("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\n"); diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index e9073553d0..cf03de08c4 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -210,7 +210,7 @@ class messenger { $style_resource_locator = new phpbb_style_resource_locator(); $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); - $tpl = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator); + $tpl = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, new phpbb_template_context()); $style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $tpl); $this->tpl_msg[$template_lang . $template_file] = $tpl; diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 53beb6ac76..fbe1422dad 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -296,13 +296,15 @@ function posting_gen_topic_icons($mode, $icon_id) if (sizeof($icons)) { + $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_root_path; + foreach ($icons as $id => $data) { if ($data['display']) { $template->assign_block_vars('topic_icon', array( 'ICON_ID' => $id, - 'ICON_IMG' => $phpbb_root_path . $config['icons_path'] . '/' . $data['img'], + 'ICON_IMG' => $root_path . $config['icons_path'] . '/' . $data['img'], 'ICON_WIDTH' => $data['width'], 'ICON_HEIGHT' => $data['height'], @@ -1176,7 +1178,7 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id /** * User Notification */ -function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id, $topic_id, $post_id) +function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id, $topic_id, $post_id, $author_name = '') { global $db, $user, $config, $phpbb_root_path, $phpEx, $auth; @@ -1347,6 +1349,7 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id 'USERNAME' => htmlspecialchars_decode($addr['name']), 'TOPIC_TITLE' => htmlspecialchars_decode($topic_title), 'FORUM_NAME' => htmlspecialchars_decode($forum_name), + 'AUTHOR_NAME' => htmlspecialchars_decode($author_name), 'U_FORUM' => generate_board_url() . "/viewforum.$phpEx?f=$forum_id", 'U_TOPIC' => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id", @@ -2400,7 +2403,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u // Send Notifications if (($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $post_visibility == ITEM_APPROVED) { - user_notification($mode, $subject, $data['topic_title'], $data['forum_name'], $data['forum_id'], $data['topic_id'], $data['post_id']); + $username = ($username) ? $username : $user->data['username']; + user_notification($mode, $subject, $data['topic_title'], $data['forum_name'], $data['forum_id'], $data['topic_id'], $data['post_id'], $username); } $params = $add_anchor = ''; diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 9e055a319f..ba939d490e 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -269,46 +269,46 @@ function check_rule(&$rules, &$rule_row, &$message_row, $user_id) case RULE_IS_LIKE: $result = preg_match("/" . preg_quote($rule_row['rule_string'], '/') . '/i', $check0); break; - + case RULE_IS_NOT_LIKE: $result = !preg_match("/" . preg_quote($rule_row['rule_string'], '/') . '/i', $check0); break; - + case RULE_IS: $result = ($check0 == $rule_row['rule_string']); break; - + case RULE_IS_NOT: $result = ($check0 != $rule_row['rule_string']); break; - + case RULE_BEGINS_WITH: $result = preg_match("/^" . preg_quote($rule_row['rule_string'], '/') . '/i', $check0); break; - + case RULE_ENDS_WITH: $result = preg_match("/" . preg_quote($rule_row['rule_string'], '/') . '$/i', $check0); break; - + case RULE_IS_FRIEND: case RULE_IS_FOE: case RULE_ANSWERED: case RULE_FORWARDED: $result = ($check0 == 1); break; - + case RULE_IS_USER: $result = ($check0 == $rule_row['rule_user_id']); break; - + case RULE_IS_GROUP: $result = in_array($rule_row['rule_group_id'], $check0); break; - + case RULE_TO_GROUP: $result = (in_array('g_' . $message_row[$check_ary['check2']], $check0) || in_array('g_' . $message_row[$check_ary['check2']], $message_row[$check_ary['check1']])); break; - + case RULE_TO_ME: $result = (in_array('u_' . $user_id, $check0) || in_array('u_' . $user_id, $message_row[$check_ary['check1']])); break; @@ -1145,6 +1145,23 @@ function phpbb_delete_user_pms($user_id) return false; } + return phpbb_delete_users_pms(array($user_id)); +} + +/** +* Delete all PM(s) for given users and delete the ones without references +* +* @param array $user_ids IDs of the users whose private messages we want to delete +* +* @return boolean False if there were no pms found, true otherwise. +*/ +function phpbb_delete_users_pms($user_ids) +{ + global $db, $user, $phpbb_root_path, $phpEx; + + $user_id_sql = $db->sql_in_set('user_id', $user_ids); + $author_id_sql = $db->sql_in_set('author_id', $user_ids); + // Get PM Information for later deleting // The two queries where split, so we can use our indexes $undelivered_msg = $delete_ids = array(); @@ -1152,7 +1169,7 @@ function phpbb_delete_user_pms($user_id) // Part 1: get PMs the user received $sql = 'SELECT msg_id FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE user_id = ' . $user_id; + WHERE ' . $user_id_sql; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) @@ -1162,12 +1179,12 @@ function phpbb_delete_user_pms($user_id) } $db->sql_freeresult($result); - // Part 2: get PMs the user sent, but have yet to be received - // We cannot simply delete them. First we have to check, + // Part 2: get PMs the users sent, but are yet to be received. + // We cannot simply delete them. First we have to check // whether another user already received and read the message. $sql = 'SELECT msg_id FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE author_id = ' . $user_id . ' + WHERE ' . $author_id_sql . ' AND folder_id = ' . PRIVMSGS_NO_BOX; $result = $db->sql_query($sql); @@ -1193,7 +1210,7 @@ function phpbb_delete_user_pms($user_id) // received them. $sql = 'SELECT msg_id FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE author_id = ' . $user_id . ' + WHERE ' . $author_id_sql . ' AND folder_id <> ' . PRIVMSGS_NO_BOX . ' AND folder_id <> ' . PRIVMSGS_OUTBOX . ' AND folder_id <> ' . PRIVMSGS_SENTBOX; @@ -1213,7 +1230,7 @@ function phpbb_delete_user_pms($user_id) // Count the messages we delete, so we can correct the user pm data $sql = 'SELECT user_id, COUNT(msg_id) as num_undelivered_privmsgs FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE author_id = ' . $user_id . ' + WHERE ' . $author_id_sql . ' AND folder_id = ' . PRIVMSGS_NO_BOX . ' AND ' . $db->sql_in_set('msg_id', array_merge($undelivered_msg, $delivered_msg)) . ' GROUP BY user_id'; @@ -1271,12 +1288,12 @@ function phpbb_delete_user_pms($user_id) $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new_privmsg = 0, user_unread_privmsg = 0 - WHERE user_id = ' . $user_id; + WHERE ' . $user_id_sql; $db->sql_query($sql); // Delete private message data of the user $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE user_id = ' . (int) $user_id; + WHERE ' . $user_id_sql; $db->sql_query($sql); if (!empty($delete_ids)) @@ -1313,12 +1330,12 @@ function phpbb_delete_user_pms($user_id) // This way users are still able to read messages from users being removed $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' SET author_id = ' . ANONYMOUS . ' - WHERE author_id = ' . $user_id; + WHERE ' . $author_id_sql; $db->sql_query($sql); $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' SET author_id = ' . ANONYMOUS . ' - WHERE author_id = ' . $user_id; + WHERE ' . $author_id_sql; $db->sql_query($sql); $db->sql_transaction('commit'); diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 9e33a5122e..0e347fe477 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -162,6 +162,7 @@ function user_update_name($old_name, $new_name) function user_add($user_row, $cp_data = false) { global $db, $user, $auth, $config, $phpbb_root_path, $phpEx; + global $phpbb_dispatcher; if (empty($user_row['username']) || !isset($user_row['group_id']) || !isset($user_row['user_email']) || !isset($user_row['user_type'])) { @@ -255,6 +256,16 @@ function user_add($user_row, $cp_data = false) } } + /** + * Use this event to modify the values to be inserted when a user is added + * + * @event core.user_add_modify_data + * @var array sql_ary Array of data to be inserted when a user is added + * @since 3.1-A1 + */ + $vars = array('sql_ary'); + extract($phpbb_dispatcher->trigger_event('core.user_add_modify_data', compact($vars))); + $sql = 'INSERT INTO ' . USERS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); $db->sql_query($sql); @@ -339,20 +350,34 @@ function user_add($user_row, $cp_data = false) /** * Remove User +* @param $mode Either 'retain' or 'remove' */ -function user_delete($mode, $user_id, $post_username = false) +function user_delete($mode, $user_ids, $retain_username = true) { global $cache, $config, $db, $user, $auth, $phpbb_dispatcher; global $phpbb_root_path, $phpEx; + $db->sql_transaction('begin'); + + $user_rows = array(); + if (!is_array($user_ids)) + { + $user_ids = array($user_ids); + } + + $user_id_sql = $db->sql_in_set('user_id', $user_ids); + $sql = 'SELECT * FROM ' . USERS_TABLE . ' - WHERE user_id = ' . $user_id; + WHERE ' . $user_id_sql; $result = $db->sql_query($sql); - $user_row = $db->sql_fetchrow($result); + while ($row = $db->sql_fetchrow($result)) + { + $user_rows[(int) $row['user_id']] = $row; + } $db->sql_freeresult($result); - if (!$user_row) + if (empty($user_rows)) { return false; } @@ -372,7 +397,7 @@ function user_delete($mode, $user_id, $post_username = false) // Before we begin, we will remove the reports the user issued. $sql = 'SELECT r.post_id, p.topic_id FROM ' . REPORTS_TABLE . ' r, ' . POSTS_TABLE . ' p - WHERE r.user_id = ' . $user_id . ' + WHERE ' . $db->sql_in_set('r.user_id', $user_ids) . ' AND p.post_id = r.post_id'; $result = $db->sql_query($sql); @@ -426,97 +451,124 @@ function user_delete($mode, $user_id, $post_username = false) } // Remove reports - $db->sql_query('DELETE FROM ' . REPORTS_TABLE . ' WHERE user_id = ' . $user_id); + $db->sql_query('DELETE FROM ' . REPORTS_TABLE . ' WHERE ' . $user_id_sql); - if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == AVATAR_UPLOAD) - { - avatar_delete('user', $user_row); - } + $num_users_delta = 0; - switch ($mode) + // Some things need to be done in the loop (if the query changes based + // on which user is currently being deleted) + $added_guest_posts = 0; + foreach ($user_rows as $user_id => $user_row) { - case 'retain': - - $db->sql_transaction('begin'); - - if ($post_username === false) - { - $post_username = $user->lang['GUEST']; - } + if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == AVATAR_UPLOAD) + { + avatar_delete('user', $user_row); + } - // If the user is inactive and newly registered we assume no posts from this user being there... - if ($user_row['user_type'] == USER_INACTIVE && $user_row['user_inactive_reason'] == INACTIVE_REGISTER && !$user_row['user_posts']) - { - } - else - { - $sql = 'UPDATE ' . FORUMS_TABLE . ' - SET forum_last_poster_id = ' . ANONYMOUS . ", forum_last_poster_name = '" . $db->sql_escape($post_username) . "', forum_last_poster_colour = '' - WHERE forum_last_poster_id = $user_id"; - $db->sql_query($sql); + // Decrement number of users if this user is active + if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE) + { + --$num_users_delta; + } - $sql = 'UPDATE ' . POSTS_TABLE . ' - SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "' - WHERE poster_id = $user_id"; - $db->sql_query($sql); + switch ($mode) + { + case 'retain': + if ($retain_username === false) + { + $post_username = $user->lang['GUEST']; + } + else + { + $post_username = $user_row['username']; + } - $sql = 'UPDATE ' . POSTS_TABLE . ' - SET post_edit_user = ' . ANONYMOUS . " - WHERE post_edit_user = $user_id"; - $db->sql_query($sql); + // If the user is inactive and newly registered + // we assume no posts from the user, and save + // the queries + if ($user_row['user_type'] != USER_INACTIVE || $user_row['user_inactive_reason'] != INACTIVE_REGISTER || $user_row['user_posts']) + { + // When we delete these users and retain the posts, we must assign all the data to the guest user + $sql = 'UPDATE ' . FORUMS_TABLE . ' + SET forum_last_poster_id = ' . ANONYMOUS . ", forum_last_poster_name = '" . $db->sql_escape($post_username) . "', forum_last_poster_colour = '' + WHERE forum_last_poster_id = $user_id"; + $db->sql_query($sql); - $sql = 'UPDATE ' . TOPICS_TABLE . ' - SET topic_poster = ' . ANONYMOUS . ", topic_first_poster_name = '" . $db->sql_escape($post_username) . "', topic_first_poster_colour = '' - WHERE topic_poster = $user_id"; - $db->sql_query($sql); + $sql = 'UPDATE ' . POSTS_TABLE . ' + SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "' + WHERE poster_id = $user_id"; + $db->sql_query($sql); - $sql = 'UPDATE ' . TOPICS_TABLE . ' - SET topic_last_poster_id = ' . ANONYMOUS . ", topic_last_poster_name = '" . $db->sql_escape($post_username) . "', topic_last_poster_colour = '' - WHERE topic_last_poster_id = $user_id"; - $db->sql_query($sql); + $sql = 'UPDATE ' . TOPICS_TABLE . ' + SET topic_poster = ' . ANONYMOUS . ", topic_first_poster_name = '" . $db->sql_escape($post_username) . "', topic_first_poster_colour = '' + WHERE topic_poster = $user_id"; + $db->sql_query($sql); - $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' - SET poster_id = ' . ANONYMOUS . " - WHERE poster_id = $user_id"; - $db->sql_query($sql); + $sql = 'UPDATE ' . TOPICS_TABLE . ' + SET topic_last_poster_id = ' . ANONYMOUS . ", topic_last_poster_name = '" . $db->sql_escape($post_username) . "', topic_last_poster_colour = '' + WHERE topic_last_poster_id = $user_id"; + $db->sql_query($sql); - // Since we change every post by this author, we need to count this amount towards the anonymous user + // Since we change every post by this author, we need to count this amount towards the anonymous user - // Update the post count for the anonymous user - if ($user_row['user_posts']) - { - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_posts = user_posts + ' . $user_row['user_posts'] . ' - WHERE user_id = ' . ANONYMOUS; - $db->sql_query($sql); + if ($user_row['user_posts']) + { + $added_guest_posts += $user_row['user_posts']; + } } - } - - $db->sql_transaction('commit'); + break; - break; + case 'remove': + // there is nothing variant specific to deleting posts + break; + } + } - case 'remove': + if ($num_users_delta != 0) + { + set_config_count('num_users', $num_users_delta, true); + } - if (!function_exists('delete_posts')) - { - include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); - } + // Now do the invariant tasks + // all queries performed in one call of this function are in a single transaction + // so this is kosher + if ($mode == 'retain') + { + // Assign more data to the Anonymous user + $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' + SET poster_id = ' . ANONYMOUS . ' + WHERE ' . $db->sql_in_set('poster_id', $user_ids); + $db->sql_query($sql); - // Delete posts, attachments, etc. - delete_posts('poster_id', $user_id); + $sql = 'UPDATE ' . POSTS_TABLE . ' + SET post_edit_user = ' . ANONYMOUS . ' + WHERE ' . $db->sql_in_set('post_edit_user', $user_ids); + $db->sql_query($sql); - break; + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_posts = user_posts + ' . $added_guest_posts . ' + WHERE user_id = ' . ANONYMOUS; + $db->sql_query($sql); } + else if ($mode == 'remove') + { + if (!function_exists('delete_posts')) + { + include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); + } - $db->sql_transaction('begin'); + // Delete posts, attachments, etc. + // delete_posts can handle any number of IDs in its second argument + delete_posts('poster_id', $user_ids); + } $table_ary = array(USERS_TABLE, USER_GROUP_TABLE, TOPICS_WATCH_TABLE, FORUMS_WATCH_TABLE, ACL_USERS_TABLE, TOPICS_TRACK_TABLE, TOPICS_POSTED_TABLE, FORUMS_TRACK_TABLE, PROFILE_FIELDS_DATA_TABLE, MODERATOR_CACHE_TABLE, DRAFTS_TABLE, BOOKMARKS_TABLE, SESSIONS_KEYS_TABLE, PRIVMSGS_FOLDER_TABLE, PRIVMSGS_RULES_TABLE); + // Delete the miscellaneous (non-post) data for the user foreach ($table_ary as $table) { $sql = "DELETE FROM $table - WHERE user_id = $user_id"; + WHERE " . $user_id_sql; $db->sql_query($sql); } @@ -524,29 +576,29 @@ function user_delete($mode, $user_id, $post_username = false) // Delete user log entries about this user $sql = 'DELETE FROM ' . LOG_TABLE . ' - WHERE reportee_id = ' . $user_id; + WHERE ' . $db->sql_in_set('reportee_id', $user_ids); $db->sql_query($sql); // Change user_id to anonymous for this users triggered events $sql = 'UPDATE ' . LOG_TABLE . ' SET user_id = ' . ANONYMOUS . ' - WHERE user_id = ' . $user_id; + WHERE ' . $user_id_sql; $db->sql_query($sql); // Delete the user_id from the zebra table $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' - WHERE user_id = ' . $user_id . ' - OR zebra_id = ' . $user_id; + WHERE ' . $user_id_sql . ' + OR ' . $db->sql_in_set('zebra_id', $user_ids); $db->sql_query($sql); // Delete the user_id from the banlist $sql = 'DELETE FROM ' . BANLIST_TABLE . ' - WHERE ban_userid = ' . $user_id; + WHERE ' . $db->sql_in_set('ban_userid', $user_ids); $db->sql_query($sql); // Delete the user_id from the session table $sql = 'DELETE FROM ' . SESSIONS_TABLE . ' - WHERE session_user_id = ' . $user_id; + WHERE ' . $db->sql_in_set('session_user_id', $user_ids); $db->sql_query($sql); // Clean the private messages tables from the user @@ -554,7 +606,7 @@ function user_delete($mode, $user_id, $post_username = false) { include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx); } - phpbb_delete_user_pms($user_id); + phpbb_delete_users_pms($user_ids); $db->sql_transaction('commit'); @@ -571,17 +623,11 @@ function user_delete($mode, $user_id, $post_username = false) extract($phpbb_dispatcher->trigger_event('core.delete_user_after', compact($vars))); // Reset newest user info if appropriate - if ($config['newest_user_id'] == $user_id) + if (in_array($config['newest_user_id'], $user_ids)) { update_last_username(); } - // Decrement number of users if this user is active - if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE) - { - set_config_count('num_users', -1, true); - } - return false; } diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index e8c5550cb7..693a9d77e2 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -103,7 +103,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) $base_url = $url . "&i=$id&action=$action&mode=$mode&sd=$sort_dir&sk=$sort_key&st=$sort_days" . (($merge_select) ? $selected_ids : ''); phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $forum_topics, $topics_per_page, $start); - + $template->assign_vars(array( 'ACTION' => $action, 'FORUM_NAME' => $forum_info['forum_name'], @@ -451,7 +451,7 @@ function merge_topics($forum_id, $topic_ids, $to_topic_id) confirm_box(false, 'MERGE_TOPICS', $s_hidden_fields); } - $redirect = request_var('redirect', "index.$phpEx"); + $redirect = request_var('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id"); $redirect = reapply_sid($redirect); if (!$success_msg) @@ -460,7 +460,7 @@ function merge_topics($forum_id, $topic_ids, $to_topic_id) } else { - meta_refresh(3, append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$to_forum_id&t=$to_topic_id")); + meta_refresh(3, $redirect); trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link); } } diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php index 1b9521674d..44cab5d910 100644 --- a/phpBB/includes/mcp/mcp_front.php +++ b/phpBB/includes/mcp/mcp_front.php @@ -251,7 +251,7 @@ function mcp_front_view($id, $mode, $action) 'ORDER_BY' => 'p.message_time DESC', ); - $sql_ary = $db->sql_build_query('SELECT', $sql_ary); + $sql = $db->sql_build_query('SELECT', $sql_ary); $result = $db->sql_query_limit($sql, 5); $pm_by_id = $pm_list = array(); diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php index c1724b20d9..f706840492 100644 --- a/phpBB/includes/mcp/mcp_logs.php +++ b/phpBB/includes/mcp/mcp_logs.php @@ -172,8 +172,8 @@ class mcp_logs $start = view_log('mod', $log_data, $log_count, $config['topics_per_page'], $start, $forum_list, $topic_id, 0, $sql_where, $sql_sort, $keywords); $base_url = $this->u_action . "&$u_sort_param$keywords_param"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); - + phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); + $template->assign_vars(array( 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start), 'TOTAL' => $user->lang('TOTAL_LOGS', (int) $log_count), diff --git a/phpBB/includes/mcp/mcp_notes.php b/phpBB/includes/mcp/mcp_notes.php index bbf618ebef..59cdf3c27e 100644 --- a/phpBB/includes/mcp/mcp_notes.php +++ b/phpBB/includes/mcp/mcp_notes.php @@ -217,7 +217,7 @@ class mcp_notes $base_url = $this->u_action . "&$u_sort_param$keywords_param"; phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); - + $template->assign_vars(array( 'U_POST_ACTION' => $this->u_action, 'S_CLEAR_ALLOWED' => ($auth->acl_get('a_clearlogs')) ? true : false, diff --git a/phpBB/includes/mcp/mcp_pm_reports.php b/phpBB/includes/mcp/mcp_pm_reports.php index 24e531517c..be18dba944 100644 --- a/phpBB/includes/mcp/mcp_pm_reports.php +++ b/phpBB/includes/mcp/mcp_pm_reports.php @@ -297,10 +297,10 @@ class mcp_pm_reports } } } - + $base_url = $this->u_action . "&st=$sort_days&sk=$sort_key&sd=$sort_dir"; phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); - + // Now display the page $template->assign_vars(array( 'L_EXPLAIN' => ($mode == 'pm_reports') ? $user->lang['MCP_PM_REPORTS_OPEN_EXPLAIN'] : $user->lang['MCP_PM_REPORTS_CLOSED_EXPLAIN'], diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 38d2ea48fa..7b038b476b 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -71,7 +71,7 @@ class mcp_reports // closed reports are accessed by report id $report_id = request_var('r', 0); - $sql = 'SELECT r.post_id, r.user_id, r.report_id, r.report_closed, report_time, r.report_text, r.reported_post_text, rr.reason_title, rr.reason_description, u.username, u.username_clean, u.user_colour + $sql = 'SELECT r.post_id, r.user_id, r.report_id, r.report_closed, report_time, r.report_text, r.reported_post_text, r.reported_post_uid, r.reported_post_bitfield, rr.reason_title, rr.reason_description, u.username, u.username_clean, u.user_colour FROM ' . REPORTS_TABLE . ' r, ' . REPORTS_REASONS_TABLE . ' rr, ' . USERS_TABLE . ' u WHERE ' . (($report_id) ? 'r.report_id = ' . $report_id : "r.post_id = $post_id") . ' AND rr.reason_id = r.reason_id @@ -227,7 +227,7 @@ class mcp_reports 'REPORTER_NAME' => get_username_string('username', $report['user_id'], $report['username'], $report['user_colour']), 'U_VIEW_REPORTER_PROFILE' => get_username_string('profile', $report['user_id'], $report['username'], $report['user_colour']), - 'POST_PREVIEW' => bbcode_nl2br($report['reported_post_text']), + 'POST_PREVIEW' => generate_text_for_display($report['reported_post_text'], $report['reported_post_uid'], $report['reported_post_bitfield'], OPTION_FLAG_BBCODE | OPTION_FLAG_SMILIES, false), 'POST_SUBJECT' => ($post_info['post_subject']) ? $post_info['post_subject'] : $user->lang['NO_SUBJECT'], 'POST_DATE' => $user->format_date($post_info['post_time']), 'POST_IP' => $post_info['poster_ip'], @@ -413,7 +413,7 @@ class mcp_reports $base_url = $this->u_action . "&f=$forum_id&t=$topic_id&st=$sort_days&sk=$sort_key&sd=$sort_dir"; phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); - + // Now display the page $template->assign_vars(array( 'L_EXPLAIN' => ($mode == 'reports') ? $user->lang['MCP_REPORTS_OPEN_EXPLAIN'] : $user->lang['MCP_REPORTS_CLOSED_EXPLAIN'], diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index cea5b9db8c..e507afdf2a 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -535,7 +535,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) confirm_box(false, ($action == 'split_all') ? 'SPLIT_TOPIC_ALL' : 'SPLIT_TOPIC_BEYOND', $s_hidden_fields); } - $redirect = request_var('redirect', "index.$phpEx"); + $redirect = request_var('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id"); $redirect = reapply_sid($redirect); if (!$success_msg) @@ -544,7 +544,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) } else { - meta_refresh(3, append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$to_forum_id&t=$to_topic_id")); + meta_refresh(3, $redirect); trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link); } } @@ -641,7 +641,7 @@ function merge_posts($topic_id, $to_topic_id) confirm_box(false, 'MERGE_POSTS', $s_hidden_fields); } - $redirect = request_var('redirect', "index.$phpEx"); + $redirect = request_var('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id"); $redirect = reapply_sid($redirect); if (!$success_msg) @@ -650,7 +650,7 @@ function merge_posts($topic_id, $to_topic_id) } else { - meta_refresh(3, append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$to_forum_id&t=$to_topic_id")); + meta_refresh(3, $redirect); trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link); } } diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php index aefddb7c01..6a8fb4c5d5 100644 --- a/phpBB/includes/mcp/mcp_warn.php +++ b/phpBB/includes/mcp/mcp_warn.php @@ -177,7 +177,7 @@ class mcp_warn $base_url = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=warn&mode=list&st=$st&sk=$sk&sd=$sd"); phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $user_count, $config['topics_per_page'], $start); - + $template->assign_vars(array( 'U_POST_ACTION' => $this->u_action, 'S_CLEAR_ALLOWED' => ($auth->acl_get('a_clearlogs')) ? true : false, diff --git a/phpBB/includes/request/request.php b/phpBB/includes/request/request.php index 4e425dbd27..a06fc0d85d 100644 --- a/phpBB/includes/request/request.php +++ b/phpBB/includes/request/request.php @@ -200,46 +200,31 @@ class phpbb_request implements phpbb_request_interface */ public function variable($var_name, $default, $multibyte = false, $super_global = phpbb_request_interface::REQUEST) { - $path = false; - - // deep direct access to multi dimensional arrays - if (is_array($var_name)) - { - $path = $var_name; - // make sure at least the variable name is specified - if (empty($path)) - { - return (is_array($default)) ? array() : $default; - } - // the variable name is the first element on the path - $var_name = array_shift($path); - } - - if (!isset($this->input[$super_global][$var_name])) - { - return (is_array($default)) ? array() : $default; - } - $var = $this->input[$super_global][$var_name]; - - if ($path) - { - // walk through the array structure and find the element we are looking for - foreach ($path as $key) - { - if (is_array($var) && isset($var[$key])) - { - $var = $var[$key]; - } - else - { - return (is_array($default)) ? array() : $default; - } - } - } - - $this->type_cast_helper->recursive_set_var($var, $default, $multibyte); + return $this->_variable($var_name, $default, $multibyte, $super_global, true); + } - return $var; + /** + * Get a variable, but without trimming strings. + * Same functionality as variable(), except does not run trim() on strings. + * This method should be used when handling passwords. + * + * @param string|array $var_name The form variable's name from which data shall be retrieved. + * If the value is an array this may be an array of indizes which will give + * direct access to a value at any depth. E.g. if the value of "var" is array(1 => "a") + * then specifying array("var", 1) as the name will return "a". + * @param mixed $default A default value that is returned if the variable was not set. + * This function will always return a value of the same type as the default. + * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters + * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks + * @param phpbb_request_interface::POST|GET|REQUEST|COOKIE $super_global + * Specifies which super global should be used + * + * @return mixed The value of $_REQUEST[$var_name] run through {@link set_var set_var} to ensure that the type is the + * the same as that of $default. If the variable is not set $default is returned. + */ + public function untrimmed_variable($var_name, $default, $multibyte, $super_global = phpbb_request_interface::REQUEST) + { + return $this->_variable($var_name, $default, $multibyte, $super_global, false); } /** @@ -351,4 +336,66 @@ class phpbb_request implements phpbb_request_interface return array_keys($this->input[$super_global]); } + + /** + * Helper function used by variable() and untrimmed_variable(). + * + * @param string|array $var_name The form variable's name from which data shall be retrieved. + * If the value is an array this may be an array of indizes which will give + * direct access to a value at any depth. E.g. if the value of "var" is array(1 => "a") + * then specifying array("var", 1) as the name will return "a". + * @param mixed $default A default value that is returned if the variable was not set. + * This function will always return a value of the same type as the default. + * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters + * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks + * @param phpbb_request_interface::POST|GET|REQUEST|COOKIE $super_global + * Specifies which super global should be used + * @param bool $trim Indicates whether trim() should be applied to string values. + * + * @return mixed The value of $_REQUEST[$var_name] run through {@link set_var set_var} to ensure that the type is the + * the same as that of $default. If the variable is not set $default is returned. + */ + protected function _variable($var_name, $default, $multibyte = false, $super_global = phpbb_request_interface::REQUEST, $trim = true) + { + $path = false; + + // deep direct access to multi dimensional arrays + if (is_array($var_name)) + { + $path = $var_name; + // make sure at least the variable name is specified + if (empty($path)) + { + return (is_array($default)) ? array() : $default; + } + // the variable name is the first element on the path + $var_name = array_shift($path); + } + + if (!isset($this->input[$super_global][$var_name])) + { + return (is_array($default)) ? array() : $default; + } + $var = $this->input[$super_global][$var_name]; + + if ($path) + { + // walk through the array structure and find the element we are looking for + foreach ($path as $key) + { + if (is_array($var) && isset($var[$key])) + { + $var = $var[$key]; + } + else + { + return (is_array($default)) ? array() : $default; + } + } + } + + $this->type_cast_helper->recursive_set_var($var, $default, $multibyte, $trim); + + return $var; + } } diff --git a/phpBB/includes/request/type_cast_helper.php b/phpBB/includes/request/type_cast_helper.php index 561e8fc251..1a5274ed14 100644 --- a/phpBB/includes/request/type_cast_helper.php +++ b/phpBB/includes/request/type_cast_helper.php @@ -93,15 +93,23 @@ class phpbb_request_type_cast_helper implements phpbb_request_type_cast_helper_i * @param mixed $type The variable type. Will be used with {@link settype()} * @param bool $multibyte Indicates whether string values may contain UTF-8 characters. * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks. + * @param bool $trim Indicates whether trim() should be applied to string values. + * Default is true. */ - public function set_var(&$result, $var, $type, $multibyte = false) + public function set_var(&$result, $var, $type, $multibyte = false, $trim = true) { settype($var, $type); $result = $var; if ($type == 'string') { - $result = trim(str_replace(array("\r\n", "\r", "\0"), array("\n", "\n", ''), $result)); + $result = str_replace(array("\r\n", "\r", "\0"), array("\n", "\n", ''), $result); + + if ($trim) + { + $result = trim($result); + } + $result = htmlspecialchars($result, ENT_COMPAT, 'UTF-8'); if ($multibyte) @@ -141,8 +149,10 @@ class phpbb_request_type_cast_helper implements phpbb_request_type_cast_helper_i * @param bool $multibyte Indicates whether string keys and values may contain UTF-8 characters. * Default is false, causing all bytes outside the ASCII range (0-127) to * be replaced with question marks. + * @param bool $trim Indicates whether trim() should be applied to string values. + * Default is true. */ - public function recursive_set_var(&$var, $default, $multibyte) + public function recursive_set_var(&$var, $default, $multibyte, $trim = true) { if (is_array($var) !== is_array($default)) { @@ -153,7 +163,7 @@ class phpbb_request_type_cast_helper implements phpbb_request_type_cast_helper_i if (!is_array($default)) { $type = gettype($default); - $this->set_var($var, $var, $type, $multibyte); + $this->set_var($var, $var, $type, $multibyte, $trim); } else { @@ -174,9 +184,9 @@ class phpbb_request_type_cast_helper implements phpbb_request_type_cast_helper_i foreach ($_var as $k => $v) { - $this->set_var($k, $k, $key_type, $multibyte, $multibyte); + $this->set_var($k, $k, $key_type, $multibyte); - $this->recursive_set_var($v, $default_value, $multibyte); + $this->recursive_set_var($v, $default_value, $multibyte, $trim); $var[$k] = $v; } } diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index 81fb82de93..9f7e8a2195 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -22,18 +22,59 @@ if (!defined('IN_PHPBB')) */ class phpbb_search_fulltext_mysql extends phpbb_search_base { + /** + * Associative array holding index stats + * @var array + */ protected $stats = array(); + + /** + * Holds the words entered by user, obtained by splitting the entered query on whitespace + * @var array + */ protected $split_words = array(); + + /** + * Config object + * @var phpbb_config + */ protected $config; + + /** + * DBAL object + * @var dbal + */ protected $db; + + /** + * User object + * @var phpbb_user + */ protected $user; - public $word_length = array(); - public $search_query; - public $common_words = array(); + + /** + * Associative array stores the min and max word length to be searched + * @var array + */ + protected $word_length = array(); + + /** + * Contains tidied search query. + * Operators are prefixed in search query and common words excluded + * @var string + */ + protected $search_query; + + /** + * Contains common words. + * Common words are words with length less/more than min/max length + * @var array + */ + protected $common_words = array(); /** * Constructor - * Creates a new phpbb_search_fulltext_mysql, which is used as a search backend. + * Creates a new phpbb_search_fulltext_mysql, which is used as a search backend * * @param string|bool $error Any error that occurs is passed on through this reference variable otherwise false */ @@ -59,6 +100,36 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base } /** + * Returns the search_query + * + * @return string search query + */ + public function get_search_query() + { + return $this->search_query; + } + + /** + * Returns the common_words array + * + * @return array common words that are ignored by search backend + */ + public function get_common_words() + { + return $this->common_words; + } + + /** + * Returns the word_length array + * + * @return array min and max word length for searching + */ + public function get_word_length() + { + return $this->word_length; + } + + /** * Checks for correct MySQL version and stores min/max word length in the config * * @return string|bool Language key of the error/incompatiblity occured @@ -255,7 +326,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base } /** - * Performs a search on keywords depending on display specific params. You have to run split_keywords() first. + * Performs a search on keywords depending on display specific params. You have to run split_keywords() first * * @param string $type contains either posts or topics depending on what should be searched for * @param string $fields contains either titleonly (topic titles should be searched), msgonly (only message bodies should be searched), firstpost (only subject and body of the first post should be searched) or all (all post bodies and subjects should be searched) @@ -276,7 +347,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base */ public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) { - // No keywords? No posts. + // No keywords? No posts if (!$this->search_query) { return false; @@ -443,7 +514,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base */ public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) { - // No author? No posts. + // No author? No posts if (!sizeof($author_ary)) { return 0; @@ -581,7 +652,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base } /** - * Destroys cached search results, that contained one of the new words in a post so the results won't be outdated. + * Destroys cached search results, that contained one of the new words in a post so the results won't be outdated * * @param string $mode contains the post mode: edit, post, reply, quote ... * @param int $post_id contains the post id of the post to index @@ -810,11 +881,11 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base { $tpl = ' <dl> - <dt><label>' . $this->user->lang['MIN_SEARCH_CHARS'] . ':</label><br /><span>' . $this->user->lang['FULLTEXT_MYSQL_MIN_SEARCH_CHARS_EXPLAIN'] . '</span></dt> + <dt><label>' . $this->user->lang['MIN_SEARCH_CHARS'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_MYSQL_MIN_SEARCH_CHARS_EXPLAIN'] . '</span></dt> <dd>' . $this->config['fulltext_mysql_min_word_len'] . '</dd> </dl> <dl> - <dt><label>' . $this->user->lang['MAX_SEARCH_CHARS'] . ':</label><br /><span>' . $this->user->lang['FULLTEXT_MYSQL_MAX_SEARCH_CHARS_EXPLAIN'] . '</span></dt> + <dt><label>' . $this->user->lang['MAX_SEARCH_CHARS'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_MYSQL_MAX_SEARCH_CHARS_EXPLAIN'] . '</span></dt> <dd>' . $this->config['fulltext_mysql_max_word_len'] . '</dd> </dl> '; diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php index 0e520b63a2..d0e660451c 100644 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -22,25 +22,84 @@ if (!defined('IN_PHPBB')) */ class phpbb_search_fulltext_native extends phpbb_search_base { + /** + * Associative array holding index stats + * @var array + */ protected $stats = array(); - public $word_length = array(); - public $search_query; - public $common_words = array(); + /** + * Associative array stores the min and max word length to be searched + * @var array + */ + protected $word_length = array(); + + /** + * Contains tidied search query. + * Operators are prefixed in search query and common words excluded + * @var string + */ + protected $search_query; + + /** + * Contains common words. + * Common words are words with length less/more than min/max length + * @var array + */ + protected $common_words = array(); + + /** + * Post ids of posts containing words that are to be included + * @var array + */ protected $must_contain_ids = array(); + + /** + * Post ids of posts containing words that should not be included + * @var array + */ protected $must_not_contain_ids = array(); + + /** + * Post ids of posts containing atleast one word that needs to be excluded + * @var array + */ protected $must_exclude_one_ids = array(); + /** + * Relative path to board root + * @var string + */ protected $phpbb_root_path; + + /** + * PHP Extension + * @var string + */ protected $php_ext; + + /** + * Config object + * @var phpbb_config + */ protected $config; + + /** + * DBAL object + * @var dbal + */ protected $db; + + /** + * User object + * @var phpbb_user + */ protected $user; /** - * Initialises the fulltext_native search backend with min/max word length and makes sure the UTF-8 normalizer is loaded. + * Initialises the fulltext_native search backend with min/max word length and makes sure the UTF-8 normalizer is loaded * - * @param boolean|string &$error is passed by reference and should either be set to false on success or an error message on failure. + * @param boolean|string &$error is passed by reference and should either be set to false on success or an error message on failure */ public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user) { @@ -59,6 +118,10 @@ class phpbb_search_fulltext_native extends phpbb_search_base { include($this->phpbb_root_path . 'includes/utf/utf_normalizer.' . $this->php_ext); } + if (!function_exists('utf8_decode_ncr')) + { + include($this->phpbb_root_path . 'includes/utf/utf_tools.' . $this->php_ext); + } $error = false; } @@ -74,14 +137,44 @@ class phpbb_search_fulltext_native extends phpbb_search_base } /** - * This function fills $this->search_query with the cleaned user search query. + * Returns the search_query + * + * @return string search query + */ + public function get_search_query() + { + return $this->search_query; + } + + /** + * Returns the common_words array + * + * @return array common words that are ignored by search backend + */ + public function get_common_words() + { + return $this->common_words; + } + + /** + * Returns the word_length array + * + * @return array min and max word length for searching + */ + public function get_word_length() + { + return $this->word_length; + } + + /** + * This function fills $this->search_query with the cleaned user search query * * If $terms is 'any' then the words will be extracted from the search query * and combined with | inside brackets. They will afterwards be treated like * an standard search query. * * Then it analyses the query and fills the internal arrays $must_not_contain_ids, - * $must_contain_ids and $must_exclude_one_ids which are later used by keyword_search(). + * $must_contain_ids and $must_exclude_one_ids which are later used by keyword_search() * * @param string $keywords contains the search query string as entered by the user * @param string $terms is either 'all' (use search query as entered, default words to 'must be contained in post') @@ -404,7 +497,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base } /** - * Performs a search on keywords depending on display specific params. You have to run split_keywords() first. + * Performs a search on keywords depending on display specific params. You have to run split_keywords() first * * @param string $type contains either posts or topics depending on what should be searched for * @param string $fields contains either titleonly (topic titles should be searched), msgonly (only message bodies should be searched), firstpost (only subject and body of the first post should be searched) or all (all post bodies and subjects should be searched) @@ -763,7 +856,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base // if we use mysql and the total result count is not cached yet, retrieve it from the db if (!$total_results && $is_mysql) { - // Count rows for the executed queries. Replace $select within $sql with SQL_CALC_FOUND_ROWS, and run it. + // Count rows for the executed queries. Replace $select within $sql with SQL_CALC_FOUND_ROWS, and run it $sql_array_copy = $sql_array; $sql_array_copy['SELECT'] = 'SQL_CALC_FOUND_ROWS p.post_id '; @@ -812,7 +905,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base */ public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) { - // No author? No posts. + // No author? No posts if (!sizeof($author_ary)) { return 0; @@ -1679,19 +1772,19 @@ class phpbb_search_fulltext_native extends phpbb_search_base $tpl = ' <dl> - <dt><label for="fulltext_native_load_upd">' . $this->user->lang['YES_SEARCH_UPDATE'] . ':</label><br /><span>' . $this->user->lang['YES_SEARCH_UPDATE_EXPLAIN'] . '</span></dt> + <dt><label for="fulltext_native_load_upd">' . $this->user->lang['YES_SEARCH_UPDATE'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['YES_SEARCH_UPDATE_EXPLAIN'] . '</span></dt> <dd><label><input type="radio" id="fulltext_native_load_upd" name="config[fulltext_native_load_upd]" value="1"' . (($this->config['fulltext_native_load_upd']) ? ' checked="checked"' : '') . ' class="radio" /> ' . $this->user->lang['YES'] . '</label><label><input type="radio" name="config[fulltext_native_load_upd]" value="0"' . ((!$this->config['fulltext_native_load_upd']) ? ' checked="checked"' : '') . ' class="radio" /> ' . $this->user->lang['NO'] . '</label></dd> </dl> <dl> - <dt><label for="fulltext_native_min_chars">' . $this->user->lang['MIN_SEARCH_CHARS'] . ':</label><br /><span>' . $this->user->lang['MIN_SEARCH_CHARS_EXPLAIN'] . '</span></dt> + <dt><label for="fulltext_native_min_chars">' . $this->user->lang['MIN_SEARCH_CHARS'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['MIN_SEARCH_CHARS_EXPLAIN'] . '</span></dt> <dd><input id="fulltext_native_min_chars" type="text" size="3" maxlength="3" name="config[fulltext_native_min_chars]" value="' . (int) $this->config['fulltext_native_min_chars'] . '" /></dd> </dl> <dl> - <dt><label for="fulltext_native_max_chars">' . $this->user->lang['MAX_SEARCH_CHARS'] . ':</label><br /><span>' . $this->user->lang['MAX_SEARCH_CHARS_EXPLAIN'] . '</span></dt> + <dt><label for="fulltext_native_max_chars">' . $this->user->lang['MAX_SEARCH_CHARS'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['MAX_SEARCH_CHARS_EXPLAIN'] . '</span></dt> <dd><input id="fulltext_native_max_chars" type="text" size="3" maxlength="3" name="config[fulltext_native_max_chars]" value="' . (int) $this->config['fulltext_native_max_chars'] . '" /></dd> </dl> <dl> - <dt><label for="fulltext_native_common_thres">' . $this->user->lang['COMMON_WORD_THRESHOLD'] . ':</label><br /><span>' . $this->user->lang['COMMON_WORD_THRESHOLD_EXPLAIN'] . '</span></dt> + <dt><label for="fulltext_native_common_thres">' . $this->user->lang['COMMON_WORD_THRESHOLD'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['COMMON_WORD_THRESHOLD_EXPLAIN'] . '</span></dt> <dd><input id="fulltext_native_common_thres" type="text" size="3" maxlength="3" name="config[fulltext_native_common_thres]" value="' . (double) $this->config['fulltext_native_common_thres'] . '" /> %</dd> </dl> '; diff --git a/phpBB/includes/search/fulltext_postgres.php b/phpBB/includes/search/fulltext_postgres.php index dfe90db0f0..dd1b2359e0 100644 --- a/phpBB/includes/search/fulltext_postgres.php +++ b/phpBB/includes/search/fulltext_postgres.php @@ -22,22 +22,84 @@ if (!defined('IN_PHPBB')) */ class phpbb_search_fulltext_postgres extends phpbb_search_base { + /** + * Associative array holding index stats + * @var array + */ protected $stats = array(); + + /** + * Holds the words entered by user, obtained by splitting the entered query on whitespace + * @var array + */ protected $split_words = array(); + + /** + * True if PostgreSQL version supports tsearch + * @var boolean + */ protected $tsearch_usable = false; + + /** + * Stores the PostgreSQL version + * @var string + */ protected $version; + + /** + * Stores the tsearch query + * @var string + */ protected $tsearch_query; + + /** + * True if phrase search is supported. + * PostgreSQL fulltext currently doesn't support it + * @var boolean + */ protected $phrase_search = false; + + /** + * Config object + * @var phpbb_config + */ protected $config; + + /** + * DBAL object + * @var dbal + */ protected $db; + + /** + * User object + * @var phpbb_user + */ protected $user; - public $search_query; - public $common_words = array(); - public $word_length = array(); + + /** + * Contains tidied search query. + * Operators are prefixed in search query and common words excluded + * @var string + */ + protected $search_query; + + /** + * Contains common words. + * Common words are words with length less/more than min/max length + * @var array + */ + protected $common_words = array(); + + /** + * Associative array stores the min and max word length to be searched + * @var array + */ + protected $word_length = array(); /** * Constructor - * Creates a new phpbb_search_fulltext_postgres, which is used as a search backend. + * Creates a new phpbb_search_fulltext_postgres, which is used as a search backend * * @param string|bool $error Any error that occurs is passed on through this reference variable otherwise false */ @@ -73,6 +135,36 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base } /** + * Returns the search_query + * + * @return string search query + */ + public function get_search_query() + { + return $this->search_query; + } + + /** + * Returns the common_words array + * + * @return array common words that are ignored by search backend + */ + public function get_common_words() + { + return $this->common_words; + } + + /** + * Returns the word_length array + * + * @return array min and max word length for searching + */ + public function get_word_length() + { + return $this->word_length; + } + + /** * Returns if phrase search is supported or not * * @return bool @@ -224,7 +316,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base } /** - * Performs a search on keywords depending on display specific params. You have to run split_keywords() first. + * Performs a search on keywords depending on display specific params. You have to run split_keywords() first * * @param string $type contains either posts or topics depending on what should be searched for * @param string $fields contains either titleonly (topic titles should be searched), msgonly (only message bodies should be searched), firstpost (only subject and body of the first post should be searched) or all (all post bodies and subjects should be searched) @@ -245,12 +337,18 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base */ public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) { - // No keywords? No posts. + // No keywords? No posts if (!$this->search_query) { return false; } + // When search query contains queries like -foo + if (strpos($this->search_query, '+') === false) + { + return false; + } + // generate a search_key from all the options to identify the results $search_key = md5(implode('#', array( implode(', ', $this->split_words), @@ -416,7 +514,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base */ public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) { - // No author? No posts. + // No author? No posts if (!sizeof($author_ary)) { return 0; @@ -548,7 +646,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base } /** - * Destroys cached search results, that contained one of the new words in a post so the results won't be outdated. + * Destroys cached search results, that contained one of the new words in a post so the results won't be outdated * * @param string $mode contains the post mode: edit, post, reply, quote ... * @param int $post_id contains the post id of the post to index @@ -762,11 +860,11 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base $tpl .= '</select></dd> </dl> <dl> - <dt><label for="fulltext_postgres_min_word_len">' . $this->user->lang['FULLTEXT_POSTGRES_MIN_WORD_LEN'] . ':</label><br /><span>' . $this->user->lang['FULLTEXT_POSTGRES_MIN_WORD_LEN_EXPLAIN'] . '</span></dt> + <dt><label for="fulltext_postgres_min_word_len">' . $this->user->lang['FULLTEXT_POSTGRES_MIN_WORD_LEN'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_POSTGRES_MIN_WORD_LEN_EXPLAIN'] . '</span></dt> <dd><input id="fulltext_postgres_min_word_len" type="text" size="3" maxlength="3" name="config[fulltext_postgres_min_word_len]" value="' . (int) $this->config['fulltext_postgres_min_word_len'] . '" /></dd> </dl> <dl> - <dt><label for="fulltext_postgres_max_word_len">' . $this->user->lang['FULLTEXT_POSTGRES_MAX_WORD_LEN'] . ':</label><br /><span>' . $this->user->lang['FULLTEXT_POSTGRES_MAX_WORD_LEN_EXPLAIN'] . '</span></dt> + <dt><label for="fulltext_postgres_max_word_len">' . $this->user->lang['FULLTEXT_POSTGRES_MAX_WORD_LEN'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_POSTGRES_MAX_WORD_LEN_EXPLAIN'] . '</span></dt> <dd><input id="fulltext_postgres_max_word_len" type="text" size="3" maxlength="3" name="config[fulltext_postgres_max_word_len]" value="' . (int) $this->config['fulltext_postgres_max_word_len'] . '" /></dd> </dl> '; diff --git a/phpBB/includes/search/fulltext_sphinx.php b/phpBB/includes/search/fulltext_sphinx.php index ad9854071d..5f5ff15b07 100644 --- a/phpBB/includes/search/fulltext_sphinx.php +++ b/phpBB/includes/search/fulltext_sphinx.php @@ -28,26 +28,101 @@ define('SPHINX_CONNECT_WAIT_TIME', 300); */ class phpbb_search_fulltext_sphinx { + /** + * Associative array holding index stats + * @var array + */ protected $stats = array(); + + /** + * Holds the words entered by user, obtained by splitting the entered query on whitespace + * @var array + */ protected $split_words = array(); + + /** + * Holds unique sphinx id + * @var string + */ protected $id; + + /** + * Stores the names of both main and delta sphinx indexes + * separated by a semicolon + * @var string + */ protected $indexes; + + /** + * Sphinx searchd client object + * @var SphinxClient + */ protected $sphinx; + + /** + * Relative path to board root + * @var string + */ protected $phpbb_root_path; + + /** + * PHP Extension + * @var string + */ protected $php_ext; + + /** + * Auth object + * @var phpbb_auth + */ protected $auth; + + /** + * Config object + * @var phpbb_config + */ protected $config; + + /** + * DBAL object + * @var dbal + */ protected $db; + + /** + * Database Tools object + * @var phpbb_db_tools + */ protected $db_tools; + + /** + * Stores the database type if supported by sphinx + * @var string + */ protected $dbtype; + + /** + * User object + * @var phpbb_user + */ protected $user; + + /** + * Stores the generated content of the sphinx config file + * @var string + */ protected $config_file_data = ''; - public $search_query; - public $common_words = array(); + + /** + * Contains tidied search query. + * Operators are prefixed in search query and common words excluded + * @var string + */ + protected $search_query; /** * Constructor - * Creates a new phpbb_search_fulltext_postgres, which is used as a search backend. + * Creates a new phpbb_search_fulltext_postgres, which is used as a search backend * * @param string|bool $error Any error that occurs is passed on through this reference variable otherwise false */ @@ -87,7 +162,7 @@ class phpbb_search_fulltext_sphinx $error = false; } - + /** * Returns the name of this search backend to be displayed to administrators * @@ -99,6 +174,36 @@ class phpbb_search_fulltext_sphinx } /** + * Returns the search_query + * + * @return string search query + */ + public function get_search_query() + { + return $this->search_query; + } + + /** + * Returns false as there is no word_len array + * + * @return false + */ + public function get_word_length() + { + return false; + } + + /** + * Returns an empty array as there are no common_words + * + * @return array common words that are ignored by search backend + */ + public function get_common_words() + { + return array(); + } + + /** * Checks permissions and paths, if everything is correct it generates the config file * * @return string|bool Language key of the error/incompatiblity encountered, or false if successful @@ -330,7 +435,7 @@ class phpbb_search_fulltext_sphinx } /** - * Performs a search on keywords depending on display specific params. You have to run split_keywords() first. + * Performs a search on keywords depending on display specific params. You have to run split_keywords() first * * @param string $type contains either posts or topics depending on what should be searched for * @param string $fields contains either titleonly (topic titles should be searched), msgonly (only message bodies should be searched), firstpost (only subject and body of the first post should be searched) or all (all post bodies and subjects should be searched) @@ -759,23 +864,23 @@ class phpbb_search_fulltext_sphinx $tpl = ' <span class="error">' . $this->user->lang['FULLTEXT_SPHINX_CONFIGURE']. '</span> <dl> - <dt><label for="fulltext_sphinx_data_path">' . $this->user->lang['FULLTEXT_SPHINX_DATA_PATH'] . ':</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_DATA_PATH_EXPLAIN'] . '</span></dt> + <dt><label for="fulltext_sphinx_data_path">' . $this->user->lang['FULLTEXT_SPHINX_DATA_PATH'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_DATA_PATH_EXPLAIN'] . '</span></dt> <dd><input id="fulltext_sphinx_data_path" type="text" size="40" maxlength="255" name="config[fulltext_sphinx_data_path]" value="' . $this->config['fulltext_sphinx_data_path'] . '" /></dd> </dl> <dl> - <dt><label for="fulltext_sphinx_host">' . $this->user->lang['FULLTEXT_SPHINX_HOST'] . ':</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_HOST_EXPLAIN'] . '</span></dt> + <dt><label for="fulltext_sphinx_host">' . $this->user->lang['FULLTEXT_SPHINX_HOST'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_HOST_EXPLAIN'] . '</span></dt> <dd><input id="fulltext_sphinx_host" type="text" size="40" maxlength="255" name="config[fulltext_sphinx_host]" value="' . $this->config['fulltext_sphinx_host'] . '" /></dd> </dl> <dl> - <dt><label for="fulltext_sphinx_port">' . $this->user->lang['FULLTEXT_SPHINX_PORT'] . ':</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_PORT_EXPLAIN'] . '</span></dt> + <dt><label for="fulltext_sphinx_port">' . $this->user->lang['FULLTEXT_SPHINX_PORT'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_PORT_EXPLAIN'] . '</span></dt> <dd><input id="fulltext_sphinx_port" type="text" size="4" maxlength="10" name="config[fulltext_sphinx_port]" value="' . $this->config['fulltext_sphinx_port'] . '" /></dd> </dl> <dl> - <dt><label for="fulltext_sphinx_indexer_mem_limit">' . $this->user->lang['FULLTEXT_SPHINX_INDEXER_MEM_LIMIT'] . ':</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_INDEXER_MEM_LIMIT_EXPLAIN'] . '</span></dt> + <dt><label for="fulltext_sphinx_indexer_mem_limit">' . $this->user->lang['FULLTEXT_SPHINX_INDEXER_MEM_LIMIT'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_INDEXER_MEM_LIMIT_EXPLAIN'] . '</span></dt> <dd><input id="fulltext_sphinx_indexer_mem_limit" type="text" size="4" maxlength="10" name="config[fulltext_sphinx_indexer_mem_limit]" value="' . $this->config['fulltext_sphinx_indexer_mem_limit'] . '" />' . $this->user->lang['MIB'] . '</dd> </dl> <dl> - <dt><label for="fulltext_sphinx_config_file">' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE'] . ':</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE_EXPLAIN'] . '</dt> + <dt><label for="fulltext_sphinx_config_file">' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE_EXPLAIN'] . '</dt> <dd>' . (($this->config_generate()) ? '<textarea readonly="readonly" rows="6">' . $this->config_file_data . '</textarea>' : $this->config_file_data) . '</dd> <dl> '; diff --git a/phpBB/includes/style/resource_locator.php b/phpBB/includes/style/resource_locator.php index fafa11c352..8658fe4a36 100644 --- a/phpBB/includes/style/resource_locator.php +++ b/phpBB/includes/style/resource_locator.php @@ -94,10 +94,7 @@ class phpbb_style_resource_locator implements phpbb_template_locator } /** - * Sets the template filenames for handles. $filename_array - * should be a hash of handle => filename pairs. - * - * @param array $filname_array Should be a hash of handle => filename pairs. + * {@inheritDoc} */ public function set_filenames(array $filename_array) { @@ -121,14 +118,7 @@ class phpbb_style_resource_locator implements phpbb_template_locator } /** - * Determines the filename for a template handle. - * - * The filename comes from array used in a set_filenames call, - * which should have been performed prior to invoking this function. - * Return value is a file basename (without path). - * - * @param $handle string Template handle - * @return string Filename corresponding to the template handle + * {@inheritDoc} */ public function get_filename_for_handle($handle) { @@ -140,24 +130,7 @@ class phpbb_style_resource_locator implements phpbb_template_locator } /** - * Determines the source file path for a template handle without - * regard for styles tree. - * - * This function returns the path in "primary" style directory - * corresponding to the given template handle. That path may or - * may not actually exist on the filesystem. Because this function - * does not perform stat calls to determine whether the path it - * returns actually exists, it is faster than get_source_file_for_handle. - * - * Use get_source_file_for_handle to obtain the actual path that is - * guaranteed to exist (which might come from the parent style - * directory if primary style has parent styles). - * - * This function will trigger an error if the handle was never - * associated with a template file via set_filenames. - * - * @param $handle string Template handle - * @return string Path to source file path in primary style directory + * {@inheritDoc} */ public function get_virtual_source_file_for_handle($handle) { @@ -172,23 +145,7 @@ class phpbb_style_resource_locator implements phpbb_template_locator } /** - * Determines the source file path for a template handle, accounting - * for styles tree and verifying that the path exists. - * - * This function returns the actual path that may be compiled for - * the specified template handle. It will trigger an error if - * the template handle was never associated with a template path - * via set_filenames or if the template file does not exist on the - * filesystem. - * - * Use get_virtual_source_file_for_handle to just resolve a template - * handle to a path without any filesystem or styles tree checks. - * - * @param string $handle Template handle (i.e. "friendly" template name) - * @param bool $find_all If true, each root path will be checked and function - * will return array of files instead of string and will not - * trigger a error if template does not exist - * @return string Source file path + * {@inheritDoc} */ public function get_source_file_for_handle($handle, $find_all = false) { @@ -239,23 +196,7 @@ class phpbb_style_resource_locator implements phpbb_template_locator } /** - * Locates source file path, accounting for styles tree and verifying that - * the path exists. - * - * Unlike previous functions, this function works without template handle - * and it can search for more than one file. If more than one file name is - * specified, it will return location of file that it finds first. - * - * @param array $files List of files to locate. - * @param bool $return_default Determines what to return if file does not - * exist. If true, function will return location where file is - * supposed to be. If false, function will return false. - * @param bool $return_full_path If true, function will return full path - * to file. If false, function will return file name. This - * parameter can be used to check which one of set of files - * is available. - * @return string or boolean Source file path if file exists or $return_default is - * true. False if file does not exist and $return_default is false + * {@inheritDoc} */ public function get_first_file_location($files, $return_default = false, $return_full_path = true) { diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 6b7cd31cb3..36298b49ec 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -124,8 +124,6 @@ class phpbb_style $this->template->cachepath = $this->phpbb_root_path . 'cache/tpl_' . str_replace('_', '-', $name) . '_'; - $this->template->context = new phpbb_template_context(); - if ($template_path !== false) { $this->template->template_path = $this->locator->template_path = $template_path; diff --git a/phpBB/includes/template/filter.php b/phpBB/includes/template/filter.php index ad2e35de6a..abee32c8f7 100644 --- a/phpBB/includes/template/filter.php +++ b/phpBB/includes/template/filter.php @@ -209,7 +209,7 @@ class phpbb_template_filter extends php_user_filter */ - $data = preg_replace('~(?<!^)(<\?php(?:(?<!\?>).)+(?<!/\*\*/)\?>)$~m', "$1\n", $data); + $data = preg_replace('~(?<!^)(<\?php.+(?<!/\*\*/)\?>)$~m', "$1\n", $data); $data = str_replace('/**/?>', "?>\n", $data); $data = str_replace('?><?php', '', $data); return $data; diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index b7c3e00dee..5d3ce4c82b 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -36,7 +36,7 @@ class phpbb_template * Stores template data used during template rendering. * @var phpbb_template_context */ - public $context; + private $context; /** * Path of the cache directory for the template @@ -86,8 +86,9 @@ class phpbb_template * @param string $phpbb_root_path phpBB root path * @param user $user current user * @param phpbb_template_locator $locator template locator + * @param phpbb_template_context $context template context */ - public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_locator $locator) + public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_locator $locator, phpbb_template_context $context) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; @@ -95,6 +96,7 @@ class phpbb_template $this->user = $user; $this->locator = $locator; $this->template_path = $this->locator->template_path; + $this->context = $context; } /** @@ -457,8 +459,40 @@ class phpbb_template } /** - * Locates source template path, accounting for styles tree and verifying that - * the path exists. + * Obtains filesystem path for a template file. + * + * The simplest use is specifying a single template file as a string + * in the first argument. This template file should be a basename + * of a template file in the selected style, or its parent styles + * if template inheritance is being utilized. + * + * Note: "selected style" is whatever style the style resource locator + * is configured for. + * + * The return value then will be a path, relative to the current + * directory or absolute, to the template file in the selected style + * or its closest parent. + * + * If the selected style does not have the template file being searched, + * (and if inheritance is involved, none of the parents have it either), + * false will be returned. + * + * Specifying true for $return_default will cause the function to + * return the first path which was checked for existence in the event + * that the template file was not found, instead of false. + * This is the path in the selected style itself, not any of its + * parents. + * + * $files can be given an array of templates instead of a single + * template. When given an array, the function will try to resolve + * each template in the array to a path, and will return the first + * path that exists, or false if none exist. + * + * If $return_full_path is false, then instead of returning a usable + * path (when the template is found) only the template's basename + * will be returned. This can be used to check which of the templates + * specified in $files exists, provided different file names are + * used for different templates. * * @param string or array $files List of templates to locate. If there is only * one template, $files can be a string to make code easier to read. @@ -474,7 +508,7 @@ class phpbb_template */ public function locate($files, $return_default = false, $return_full_path = true) { - // add tempalte path prefix + // add template path prefix $templates = array(); if (is_string($files)) { diff --git a/phpBB/includes/ucp/info/ucp_profile.php b/phpBB/includes/ucp/info/ucp_profile.php index 968538a178..201216e9fd 100644 --- a/phpBB/includes/ucp/info/ucp_profile.php +++ b/phpBB/includes/ucp/info/ucp_profile.php @@ -20,7 +20,7 @@ class ucp_profile_info 'version' => '1.0.0', 'modes' => array( 'profile_info' => array('title' => 'UCP_PROFILE_PROFILE_INFO', 'auth' => '', 'cat' => array('UCP_PROFILE')), - 'signature' => array('title' => 'UCP_PROFILE_SIGNATURE', 'auth' => '', 'cat' => array('UCP_PROFILE')), + 'signature' => array('title' => 'UCP_PROFILE_SIGNATURE', 'auth' => 'acl_u_sig', 'cat' => array('UCP_PROFILE')), 'avatar' => array('title' => 'UCP_PROFILE_AVATAR', 'auth' => 'cfg_allow_avatar && (cfg_allow_avatar_local || cfg_allow_avatar_remote || cfg_allow_avatar_upload || cfg_allow_avatar_remote_upload)', 'cat' => array('UCP_PROFILE')), 'reg_details' => array('title' => 'UCP_PROFILE_REG_DETAILS', 'auth' => '', 'cat' => array('UCP_PROFILE')), 'autologin_keys'=> array('title' => 'UCP_PROFILE_AUTOLOGIN_KEYS', 'auth' => '', 'cat' => array('UCP_PROFILE')), diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php index e4c351709b..dc095e7b73 100644 --- a/phpBB/includes/ucp/ucp_attachments.php +++ b/phpBB/includes/ucp/ucp_attachments.php @@ -171,8 +171,8 @@ class ucp_attachments $db->sql_freeresult($result); $base_url = $this->u_action . "&sk=$sort_key&sd=$sort_dir"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); - + phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); + $template->assign_vars(array( 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $num_attachments, $config['topics_per_page'], $start), 'TOTAL_ATTACHMENTS' => $num_attachments, diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index d8bcd374fe..5577e8dab3 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -749,7 +749,8 @@ function compose_pm($id, $mode, $action, $user_folders = array()) $return_box_lang = ($action === 'post' || $action === 'edit') ? 'PM_OUTBOX' : 'PM_INBOX'; - $message = $user->lang['MESSAGE_STORED'] . '<br /><br />' . sprintf($user->lang['VIEW_PRIVATE_MESSAGE'], '<a href="' . $return_message_url . '">', '</a>'); + $save_message = ($action === 'edit') ? $user->lang['MESSAGE_EDITED'] : $user->lang['MESSAGE_STORED']; + $message = $save_message . '<br /><br />' . $user->lang('VIEW_PRIVATE_MESSAGE', '<a href="' . $return_message_url . '">', '</a>'); $last_click_type = 'CLICK_RETURN_FOLDER'; if ($folder_url) @@ -837,11 +838,11 @@ function compose_pm($id, $mode, $action, $user_folders = array()) $post_id = request_var('p', 0); if ($config['allow_post_links']) { - $message_link = "[url=" . generate_board_url() . "/viewtopic.$phpEx?p={$post_id}#p{$post_id}]{$user->lang['SUBJECT']}: {$message_subject}[/url]\n\n"; + $message_link = "[url=" . generate_board_url() . "/viewtopic.$phpEx?p={$post_id}#p{$post_id}]{$user->lang['SUBJECT']}{$user->lang['COLON']} {$message_subject}[/url]\n\n"; } else { - $message_link = $user->lang['SUBJECT'] . ': ' . $message_subject . " (" . generate_board_url() . "/viewtopic.$phpEx?p={$post_id}#p{$post_id})\n\n"; + $message_link = $user->lang['SUBJECT'] . $user->lang['COLON'] . ' ' . $message_subject . " (" . generate_board_url() . "/viewtopic.$phpEx?p={$post_id}#p{$post_id})\n\n"; } } else diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php index 1026f24699..625da23736 100644 --- a/phpBB/includes/ucp/ucp_pm_viewfolder.php +++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php @@ -453,7 +453,7 @@ function get_pm_from($folder_id, $folder, $user_id) $base_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&mode=view&action=view_folder&f=$folder_id&$u_sort_param"); phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $pm_count, $config['topics_per_page'], $start); - + $template->assign_vars(array( 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $pm_count, $config['topics_per_page'], $start), 'TOTAL_MESSAGES' => $user->lang('VIEW_PM_MESSAGES', (int) $pm_count), diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 2ac82fb52f..89bf20a30f 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -46,9 +46,9 @@ class ucp_profile $data = array( 'username' => utf8_normalize_nfc(request_var('username', $user->data['username'], true)), 'email' => strtolower(request_var('email', $user->data['user_email'])), - 'new_password' => request_var('new_password', '', true), - 'cur_password' => request_var('cur_password', '', true), - 'password_confirm' => request_var('password_confirm', '', true), + 'new_password' => $request->variable('new_password', '', true), + 'cur_password' => $request->variable('cur_password', '', true), + 'password_confirm' => $request->variable('password_confirm', '', true), ); add_form_key('ucp_reg_details'); diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 6ce53a79ab..c57aec00a0 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -170,8 +170,8 @@ class ucp_register $data = array( 'username' => utf8_normalize_nfc(request_var('username', '', true)), - 'new_password' => request_var('new_password', '', true), - 'password_confirm' => request_var('password_confirm', '', true), + 'new_password' => $request->variable('new_password', '', true), + 'password_confirm' => $request->variable('password_confirm', '', true), 'email' => strtolower(request_var('email', '')), 'lang' => basename(request_var('lang', $user->lang_name)), 'tz' => request_var('tz', $timezone), |