From bb12d885368116825df4ce8914251e2c09308b9b Mon Sep 17 00:00:00 2001 From: Rohan Date: Mon, 14 Jul 2014 19:46:50 +0530 Subject: [PATCH] Fix off-by-one error in the "previous 200" link in category listings with until=param When an until parameter is given i.e. going to a previous page, the category page does the sql query in descending order. In that case, the previous page link was given an until paramter that was one more than the last needed result, since until= is interpreted as up-to but not including, unlike from=, which is starting from and including. Bug: 36964 Change-Id: I7eaf58d78136ac069a2d9122bca03f87863d2c0b --- includes/CategoryViewer.php | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/includes/CategoryViewer.php b/includes/CategoryViewer.php index cd9eaa9c10..1c7e60461a 100644 --- a/includes/CategoryViewer.php +++ b/includes/CategoryViewer.php @@ -54,6 +54,9 @@ class CategoryViewer extends ContextSource { /** @var array */ protected $nextPage; + /** @var array */ + protected $prevPage; + /** @var array */ protected $flip; @@ -288,6 +291,12 @@ class CategoryViewer extends ContextSource { 'subcat' => null, 'file' => null, ); + $this->prevPage = array( + 'page' => null, + 'subcat' => null, + 'file' => null, + ); + $this->flip = array( 'page' => false, 'subcat' => false, 'file' => false ); foreach ( array( 'page', 'subcat', 'file' ) as $type ) { @@ -344,6 +353,9 @@ class CategoryViewer extends ContextSource { $this->nextPage[$type] = $humanSortkey; break; } + if ( $count == $this->limit ) { + $this->prevPage[$type] = $humanSortkey; + } if ( $title->getNamespace() == NS_CATEGORY ) { $cat = Category::newFromRow( $row, $title ); @@ -458,7 +470,17 @@ class CategoryViewer extends ContextSource { */ private function getSectionPagingLinks( $type ) { if ( isset( $this->until[$type] ) && $this->until[$type] !== null ) { - return $this->pagingLinks( $this->nextPage[$type], $this->until[$type], $type ); + // The new value for the until parameter should be pointing to the first + // result displayed on the page which is the second last result retrieved + // from the database.The next link should have a from parameter pointing + // to the until parameter of the current page. + if ( $this->nextPage[$type] !== null ) { + return $this->pagingLinks( $this->prevPage[$type], $this->until[$type], $type ); + } else { + // If the nextPage variable is null, it means that we have reached the first page + // and therefore the previous link should be disabled. + return $this->pagingLinks( null, $this->until[$type], $type ); + } } elseif ( $this->nextPage[$type] !== null || ( isset( $this->from[$type] ) && $this->from[$type] !== null ) ) { -- 2.20.1