Add day to date filter for ReverseChronologicalPager
authorGeoffrey Mon <geofbot@gmail.com>
Tue, 22 Dec 2015 20:48:19 +0000 (15:48 -0500)
committerAddshore <addshorewiki@gmail.com>
Mon, 12 Sep 2016 07:16:40 +0000 (07:16 +0000)
* ReverseChronologicalPager::getDateCond now accepts a day parameter
* Make year parameter of getDateCond optional (current year used)
* Make month parameter of getDateCond optional (end of year used)
* Tests for ReverseChronologicalPager::getDateCond

Depends-On: I587f1f4402ba2964ff23c0d4b06e41accbe05c10
Bug: T120733
Change-Id: I8e684f067d792b07137341d63cd2e54a18c51a7d

includes/pager/ReverseChronologicalPager.php
tests/phpunit/includes/pager/ReverseChronologicalPagerTest.php [new file with mode: 0644]

index 31c9c6d..af6d039 100644 (file)
@@ -29,6 +29,7 @@ abstract class ReverseChronologicalPager extends IndexPager {
        public $mDefaultDirection = IndexPager::DIR_DESCENDING;
        public $mYear;
        public $mMonth;
+       public $mDay;
 
        function getNavigationBar() {
                if ( !$this->isNavigationBarShown() ) {
@@ -60,23 +61,29 @@ abstract class ReverseChronologicalPager extends IndexPager {
                return $this->mNavigationBar;
        }
 
-       function getDateCond( $year, $month ) {
+       /**
+        * Set and return the mOffset timestamp such that we can get all revisions with
+        * a timestamp up to the specified parameters.
+        * @param int $year [optional] Year up to which we want revisions. Default is current year.
+        * @param int $month [optional] Month up to which we want revisions. Default is end of year.
+        * @param int $day [optional] Day up to which we want revisions. Default is end of month.
+        * @return string Timestamp
+        */
+       function getDateCond( $year = -1, $month = -1, $day = -1 ) {
                $year = intval( $year );
                $month = intval( $month );
+               $day = intval( $day );
 
-               // Basic validity checks
+               // Basic validity checks for year and month
                $this->mYear = $year > 0 ? $year : false;
                $this->mMonth = ( $month > 0 && $month < 13 ) ? $month : false;
 
-               // Given an optional year and month, we need to generate a timestamp
+               // Given an optional year, month, and day, we need to generate a timestamp
                // to use as "WHERE rev_timestamp <= result"
-               // Examples: year = 2006 equals < 20070101 (+000000)
-               // year=2005, month=1    equals < 20050201
-               // year=2005, month=12   equals < 20060101
-               if ( !$this->mYear && !$this->mMonth ) {
-                       return;
-               }
-
+               // Examples: year = 2006      equals < 20070101 (+000000)
+               // year=2005, month=1         equals < 20050201
+               // year=2005, month=12        equals < 20060101
+               // year=2005, month=12, day=5 equals < 20051206
                if ( $this->mYear ) {
                        $year = $this->mYear;
                } else {
@@ -90,15 +97,36 @@ abstract class ReverseChronologicalPager extends IndexPager {
                }
 
                if ( $this->mMonth ) {
-                       $month = $this->mMonth + 1;
-                       // For December, we want January 1 of the next year
+                       $month = $this->mMonth;
+
+                       // Day validity check after we have month and year checked
+                       $this->mDay = checkdate( $month, $day, $year ) ? $day : false;
+
+                       if ( $this->mDay ) {
+                               // If we have a day, we want up to the day immediately afterward
+                               $day = $this->mDay + 1;
+
+                               // Did we overflow the current month?
+                               if ( !checkdate( $month, $day, $year ) ) {
+                                       $day = 1;
+                                       $month++;
+                               }
+                       } else {
+                               // If no day, assume beginning of next month
+                               $day = 1;
+                               $month++;
+                       }
+
+                       // Did we overflow the current year?
                        if ( $month > 12 ) {
                                $month = 1;
                                $year++;
                        }
+
                } else {
                        // No month implies we want up to the end of the year in question
                        $month = 1;
+                       $day = 1;
                        $year++;
                }
 
@@ -107,7 +135,7 @@ abstract class ReverseChronologicalPager extends IndexPager {
                        $year = 2032;
                }
 
-               $ymd = (int)sprintf( "%04d%02d01", $year, $month );
+               $ymd = (int)sprintf( "%04d%02d%02d", $year, $month, $day );
 
                if ( $ymd > 20320101 ) {
                        $ymd = 20320101;
@@ -118,5 +146,6 @@ abstract class ReverseChronologicalPager extends IndexPager {
                $timestamp->setTimezone( $this->getConfig()->get( 'Localtimezone' ) );
 
                $this->mOffset = $this->mDb->timestamp( $timestamp->getTimestamp() );
+               return $this->mOffset;
        }
 }
diff --git a/tests/phpunit/includes/pager/ReverseChronologicalPagerTest.php b/tests/phpunit/includes/pager/ReverseChronologicalPagerTest.php
new file mode 100644 (file)
index 0000000..824b5c4
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * Test class for ReverseChronologicalPagerTest methods.
+ *
+ * @group Pager
+ *
+ * @author Geoffrey Mon <geofbot@gmail.com>
+ */
+class ReverseChronologicalPagerTest extends MediaWikiLangTestCase {
+
+       /**
+        * @covers ReverseChronologicalPager::getDateCond
+        */
+       public function testGetDateCond() {
+               $pager = $this->getMockForAbstractClass( 'ReverseChronologicalPager' );
+               $timestamp = MWTimestamp::getInstance();
+               $db = wfGetDB( DB_MASTER );
+
+               $currYear = $timestamp->format( 'Y' );
+               $currMonth = $timestamp->format( 'n' );
+               $currYearTimestamp = $db->timestamp( $currYear + 1 . '0101000000' );
+
+               // Test that getDateCond sets and returns mOffset
+               $this->assertEquals( $pager->getDateCond( 2006 ), $pager->mOffset );
+
+               // Test year
+               $pager->getDateCond( 2006 );
+               $this->assertEquals( $pager->mOffset, $db->timestamp( '20070101000000' ) );
+
+               // Test year and month
+               $pager->getDateCond( 2006, 6 );
+               $this->assertEquals( $pager->mOffset, $db->timestamp( '20060701000000' ) );
+
+               // Test year, month, and day
+               $pager->getDateCond( 2006, 6, 5 );
+               $this->assertEquals( $pager->mOffset, $db->timestamp( '20060606000000' ) );
+
+               // Test month overflow into the next year
+               $pager->getDateCond( 2006, 12 );
+               $this->assertEquals( $pager->mOffset, $db->timestamp( '20070101000000' ) );
+
+               // Test day overflow to the next month
+               $pager->getDateCond( 2006, 6, 30 );
+               $this->assertEquals( $pager->mOffset, $db->timestamp( '20060701000000' ) );
+
+               // Test invalid year (should use current year)
+               $pager->getDateCond( -1337 );
+               $this->assertEquals( $pager->mOffset, $currYearTimestamp );
+
+               // Test invalid month
+               $pager->getDateCond( 2006, -1 );
+               $this->assertEquals( $pager->mOffset, $db->timestamp( '20070101000000' ) );
+
+               // Test invalid day
+               $pager->getDateCond( 2006, 6, 1337 );
+               $this->assertEquals( $pager->mOffset, $db->timestamp( '20060701000000' ) );
+
+               // Test no year or month (should use end of current year)
+               $pager->getDateCond();
+               $this->assertEquals( $pager->mOffset, $currYearTimestamp );
+
+               // Test last day of year
+               $pager->getDateCond( 2006, 12, 31 );
+               $this->assertEquals( $pager->mOffset, $db->timestamp( '20070101000000' ) );
+
+               // Test invalid day that overflows to next year
+               $pager->getDateCond( 2006, 12, 32 );
+               $this->assertEquals( $pager->mOffset, $db->timestamp( '20070101000000' ) );
+
+               // Test month past current month (should use previous year)
+               if ( $currMonth < 5 ) {
+                       $pager->getDateCond( -1, 5 );
+                       $this->assertEquals( $pager->mOffset, $db->timestamp( $currYear - 1 . '0601000000' ) );
+               }
+               if ( $currMonth < 12 ) {
+                       $pager->getDateCond( -1, 12 );
+                       $this->assertEquals( $pager->mOffset, $db->timestamp( $currYear . '0101000000' ) );
+               }
+       }
+}
+