From 9db2cc13e0c023202845616d181cc84cd5e2d7d8 Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Mon, 24 Jul 2017 16:38:59 -0700 Subject: [PATCH] SpecialRecentchanges: Handle ?days= parameter more sanely Allow fractional values (e.g ?days=0.25). Previously, fractional values were rounded down (truncated) to integers. When computing the cutoff timestamp, don't round down to midnight UTC. This caused a strange phenomenon where ?days=1 would display between 24 and 48 hours' worth of changes depending on when you used it: if the current time was 2017-07-24 23:59 UTC, the cutoff would be set at 2017-07-23 00:00 UTC so you would see almost 48 hours' worth, but if you refreshed two minutes later, the cutoff would be set at 2017-07-24 00:00 UTC and you should see just over 24 hours' worth. In addition to this strangeness, it also made fractional values somewhat meaningless and made a feature like "show only the last 3 hours" impossible to implement. Bug: T162784 Change-Id: I75b71324e29a4da09939c4b00feeb4cb556f797c --- includes/specials/SpecialRecentchanges.php | 5 ++--- tests/phpunit/includes/specials/SpecialRecentchangesTest.php | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/includes/specials/SpecialRecentchanges.php b/includes/specials/SpecialRecentchanges.php index c9c24759a4..a05900b1e3 100644 --- a/includes/specials/SpecialRecentchanges.php +++ b/includes/specials/SpecialRecentchanges.php @@ -315,7 +315,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage { $opts = parent::getDefaultOptions(); $user = $this->getUser(); - $opts->add( 'days', $user->getIntOption( 'rcdays' ) ); + $opts->add( 'days', $user->getIntOption( 'rcdays' ), FormOptions::FLOAT ); $opts->add( 'limit', $user->getIntOption( 'rclimit' ) ); $opts->add( 'from', '' ); @@ -359,7 +359,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage { if ( preg_match( '/^limit=(\d+)$/', $bit, $m ) ) { $opts['limit'] = $m[1]; } - if ( preg_match( '/^days=(\d+)$/', $bit, $m ) ) { + if ( preg_match( '/^days=(\d+(?:\.\d+)?)$/', $bit, $m ) ) { $opts['days'] = $m[1]; } if ( preg_match( '/^namespace=(.*)$/', $bit, $m ) ) { @@ -388,7 +388,6 @@ class SpecialRecentChanges extends ChangesListSpecialPage { // Calculate cutoff $cutoff_unixtime = time() - ( $opts['days'] * 86400 ); - $cutoff_unixtime = $cutoff_unixtime - ( $cutoff_unixtime % 86400 ); $cutoff = $dbr->timestamp( $cutoff_unixtime ); $fromValid = preg_match( '/^[0-9]{14}$/', $opts['from'] ); diff --git a/tests/phpunit/includes/specials/SpecialRecentchangesTest.php b/tests/phpunit/includes/specials/SpecialRecentchangesTest.php index 85becff665..a9a612d51f 100644 --- a/tests/phpunit/includes/specials/SpecialRecentchangesTest.php +++ b/tests/phpunit/includes/specials/SpecialRecentchangesTest.php @@ -27,6 +27,8 @@ class SpecialRecentchangesTest extends AbstractChangesListSpecialPageTestCase { [ 'days=3', [ 'days' => '3' ] ], + [ 'days=0.25', [ 'days' => '0.25'] ], + [ 'namespace=5', [ 'namespace' => '5' ] ], [ 'namespace=5|3', [ 'namespace' => '5|3' ] ], -- 2.20.1