RangeChronologicalPager.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <?php
  2. /**
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along
  14. * with this program; if not, write to the Free Software Foundation, Inc.,
  15. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. * http://www.gnu.org/copyleft/gpl.html
  17. *
  18. * @file
  19. * @ingroup Pager
  20. */
  21. use Wikimedia\Timestamp\TimestampException;
  22. /**
  23. * Pager for filtering by a range of dates.
  24. * @ingroup Pager
  25. */
  26. abstract class RangeChronologicalPager extends ReverseChronologicalPager {
  27. /** @var string[] */
  28. protected $rangeConds = [];
  29. /**
  30. * Set and return a date range condition using timestamps provided by the user.
  31. * We want the revisions between the two timestamps.
  32. * Also supports only having a start or end timestamp.
  33. * Assumes that the start timestamp comes before the end timestamp.
  34. *
  35. * @param string $startStamp Timestamp of the beginning of the date range (or empty)
  36. * @param string $endStamp Timestamp of the end of the date range (or empty)
  37. * @return array|null Database conditions to satisfy the specified date range
  38. * or null if dates are invalid
  39. */
  40. public function getDateRangeCond( $startStamp, $endStamp ) {
  41. $this->rangeConds = [];
  42. try {
  43. if ( $startStamp !== '' ) {
  44. $startTimestamp = MWTimestamp::getInstance( $startStamp );
  45. $startOffset = $this->mDb->timestamp( $startTimestamp->getTimestamp() );
  46. $this->rangeConds[] = $this->mIndexField . '>=' . $this->mDb->addQuotes( $startOffset );
  47. }
  48. if ( $endStamp !== '' ) {
  49. $endTimestamp = MWTimestamp::getInstance( $endStamp );
  50. $endOffset = $this->mDb->timestamp( $endTimestamp->getTimestamp() );
  51. $this->rangeConds[] = $this->mIndexField . '<=' . $this->mDb->addQuotes( $endOffset );
  52. // populate existing variables for compatibility with parent
  53. $this->mYear = (int)$endTimestamp->format( 'Y' );
  54. $this->mMonth = (int)$endTimestamp->format( 'm' );
  55. $this->mDay = (int)$endTimestamp->format( 'd' );
  56. $this->mOffset = $endOffset;
  57. }
  58. } catch ( TimestampException $ex ) {
  59. return null;
  60. }
  61. return $this->rangeConds;
  62. }
  63. /**
  64. * Takes ReverseChronologicalPager::getDateCond parameters and repurposes
  65. * them to work with timestamp-based getDateRangeCond.
  66. *
  67. * @param int $year Year up to which we want revisions
  68. * @param int $month Month up to which we want revisions
  69. * @param int $day [optional] Day up to which we want revisions. Default is end of month.
  70. * @return string|null Timestamp or null if year and month are false/invalid
  71. */
  72. public function getDateCond( $year, $month, $day = -1 ) {
  73. // run through getDateRangeCond so rangeConds, mOffset, ... are set
  74. $legacyTimestamp = self::getOffsetDate( $year, $month, $day );
  75. // ReverseChronologicalPager uses strict inequality for the end date ('<'),
  76. // but this class uses '<=' and expects extending classes to handle modifying the end date.
  77. // Therefore, we need to subtract one second from the output of getOffsetDate to make it
  78. // work with the '<=' inequality used in this class.
  79. $legacyTimestamp->timestamp = $legacyTimestamp->timestamp->modify( '-1 second' );
  80. $this->getDateRangeCond( '', $legacyTimestamp->getTimestamp( TS_MW ) );
  81. return $this->mOffset;
  82. }
  83. /**
  84. * Build variables to use by the database wrapper.
  85. *
  86. * @param string $offset Index offset, inclusive
  87. * @param int $limit Exact query limit
  88. * @param bool $order IndexPager::QUERY_ASCENDING or IndexPager::QUERY_DESCENDING
  89. * @return array
  90. */
  91. protected function buildQueryInfo( $offset, $limit, $order ) {
  92. list( $tables, $fields, $conds, $fname, $options, $join_conds ) = parent::buildQueryInfo(
  93. $offset,
  94. $limit,
  95. $order
  96. );
  97. if ( $this->rangeConds ) {
  98. $conds = array_merge( $conds, $this->rangeConds );
  99. }
  100. return [ $tables, $fields, $conds, $fname, $options, $join_conds ];
  101. }
  102. }