From 725c51246822320ad8a723ac73c7ea4dd61bed39 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 12 Dec 2013 02:30:56 +0100 Subject: [ticket/11849] Replace pagination in viewforum.php with class PHPBB3-11849 --- phpBB/phpbb/pagination.php | 41 ++++++++++++++++++++++++++-- phpBB/viewforum.php | 33 ++++++++++------------- tests/pagination/pagination_test.php | 52 ++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 21 deletions(-) diff --git a/phpBB/phpbb/pagination.php b/phpBB/phpbb/pagination.php index 134e503c5d..467dc2157f 100644 --- a/phpBB/phpbb/pagination.php +++ b/phpBB/phpbb/pagination.php @@ -222,7 +222,7 @@ class pagination * @param int $start the item which should be considered currently active, used to determine the page we're on * @return int Current page number */ - protected function get_on_page($per_page, $start) + public function get_on_page($per_page, $start) { return floor($start / $per_page) + 1; } @@ -253,8 +253,9 @@ class pagination /** * Get current page number * - * @param int $per_page the number of items, posts, etc. per page * @param int $start the item which should be considered currently active, used to determine the page we're on + * @param int $per_page the number of items, posts, etc. per page + * @param int $num_items the total number of items, posts, topics, etc. * @return int Current page number */ public function validate_start($start, $per_page, $num_items) @@ -266,4 +267,40 @@ class pagination return $start; } + + /** + * Get new start when searching from the end + * + * If the user is trying to reach late pages, start searching from the end. + * + * @param int $start the item which should be considered currently active, used to determine the page we're on + * @param int $limit the number of items, posts, etc. to display + * @param int $num_items the total number of items, posts, topics, etc. + * @return int Current page number + */ + public function reverse_start($start, $limit, $num_items) + { + return max(0, $num_items - $limit - $start); + } + + /** + * Get new item limit when searching from the end + * + * If the user is trying to reach late pages, start searching from the end. + * In this case the items to display might be lower then the actual per_page setting. + * + * @param int $start the item which should be considered currently active, used to determine the page we're on + * @param int $per_page the number of items, posts, etc. per page + * @param int $num_items the total number of items, posts, topics, etc. + * @return int Current page number + */ + public function reverse_limit($start, $per_page, $num_items) + { + if ($start + $per_page > $num_items) + { + return min($per_page, max(1, $num_items - $start)); + } + + return $per_page; + } } diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index c6712db46c..6936080d58 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -33,6 +33,8 @@ $sort_days = request_var('st', $default_sort_days); $sort_key = request_var('sk', $default_sort_key); $sort_dir = request_var('sd', $default_sort_dir); +$pagination = $phpbb_container->get('pagination'); + // Check if the user has actually sent a forum ID with his/her request // If not give them a nice error page. if (!$forum_id) @@ -140,8 +142,13 @@ else } } +$phpbb_content_visibility = $phpbb_container->get('content.visibility'); + // Dump out the page header and load viewforum template -page_header($forum_data['forum_name'] . ($start ? ' - ' . sprintf($user->lang['PAGE_TITLE_NUMBER'], floor($start / $config['topics_per_page']) + 1) : ''), true, $forum_id); +$topics_count = $phpbb_content_visibility->get_count('forum_topics', $forum_data, $forum_id); +$start = $pagination->validate_start($start, $config['topics_per_page'], $topics_count); + +page_header($forum_data['forum_name'] . ($start ? ' - ' . $user->lang('PAGE_TITLE_NUMBER', $pagination->get_on_page($config['topics_per_page'], $start)) : ''), true, $forum_id); $template->set_filenames(array( 'body' => 'viewforum_body.html') @@ -246,8 +253,6 @@ $sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_po $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = ''; gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param, $default_sort_days, $default_sort_key, $default_sort_dir); -$phpbb_content_visibility = $phpbb_container->get('content.visibility'); - // Limit topics to certain time frame, obtain correct topic count if ($sort_days) { @@ -275,16 +280,9 @@ if ($sort_days) } else { - $topics_count = $phpbb_content_visibility->get_count('forum_topics', $forum_data, $forum_id); $sql_limit_time = ''; } -// Make sure $start is set to the last page if it exceeds the amount -if ($start < 0 || $start > $topics_count) -{ - $start = ($start < 0) ? 0 : floor(($topics_count - 1) / $config['topics_per_page']) * $config['topics_per_page']; -} - // Basic pagewide vars $post_alt = ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->lang['FORUM_LOCKED'] : $user->lang['POST_NEW_TOPIC']; @@ -480,14 +478,11 @@ if ($start > $topics_count / 2) { $store_reverse = true; - if ($start + $config['topics_per_page'] > $topics_count) - { - $sql_limit = min($config['topics_per_page'], max(1, $topics_count - $start)); - } - // Select the sort order $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'ASC' : 'DESC'); - $sql_start = max(0, $topics_count - $sql_limit - $start); + + $sql_limit = $pagination->reverse_limit($start, $per_page, $num_items); + $sql_start = $pagination->reverse_start($start, $sql_limit, $num_items); } else { @@ -631,10 +626,10 @@ if ($s_display_active) $total_topic_count = $topics_count - sizeof($global_announce_forums); $base_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '')); -phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $topics_count, $config['topics_per_page'], $start); +$pagination->generate_template_pagination($base_url, 'pagination', 'start', $topics_count, $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $topics_count, $config['topics_per_page'], $start), + 'PAGE_NUMBER' => $pagination->on_page($base_url, $topics_count, $config['topics_per_page'], $start), 'TOTAL_TOPICS' => ($s_display_active) ? false : $user->lang('VIEW_FORUM_TOPICS', (int) $total_topic_count), )); @@ -802,7 +797,7 @@ if (sizeof($topic_list)) $template->assign_block_vars('topicrow', $topic_row); - phpbb_generate_template_pagination($template, $view_topic_url, 'topicrow.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true); + $pagination->generate_template_pagination($view_topic_url, 'topicrow.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true); $s_type_switch = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0; diff --git a/tests/pagination/pagination_test.php b/tests/pagination/pagination_test.php index 69e003db6b..4e8083b47f 100644 --- a/tests/pagination/pagination_test.php +++ b/tests/pagination/pagination_test.php @@ -185,4 +185,56 @@ class phpbb_pagination_pagination_test extends phpbb_template_template_test_case { $this->assertEquals($expect, $this->pagination->validate_start($start, 10, 20)); } + + public function reverse_start_data() + { + return array( + array( + 10, + 5, + 15, + 0, + ), + array( + 10, + 10, + 25, + 5, + ), + ); + } + + /** + * @dataProvider reverse_start_data + */ + public function test_reverse_start($start, $limit, $num_items, $expect) + { + $this->assertEquals($expect, $this->pagination->reverse_start($start, $limit, $num_items)); + } + + public function reverse_limit_data() + { + return array( + array( + 10, + 10, + 15, + 5, + ), + array( + 20, + 10, + 15, + 1, + ), + ); + } + + /** + * @dataProvider reverse_limit_data + */ + public function test_reverse_limit($start, $per_page, $num_items, $expect) + { + $this->assertEquals($expect, $this->pagination->reverse_limit($start, $per_page, $num_items)); + } } -- cgit v1.2.1