From: Geoffrey Mon Date: Mon, 12 Dec 2016 14:26:15 +0000 (-0500) Subject: Use PHP DateInputWidget in Contribs and use for range filtering X-Git-Tag: 1.31.0-rc.0~3095^2 X-Git-Url: http://git.cyclocoop.org/fichier?a=commitdiff_plain;h=b66888733c182fd02478c0d351682b15c3f114df;p=lhc%2Fweb%2Fwiklou.git Use PHP DateInputWidget in Contribs and use for range filtering * Add two DateInputWidgets to Special:Contributions, one for start and one for end ** If start input is empty but end input is not, display edits up to end input, and vice versa ** If both inputs are specified, display edits between the two dates ** If both inputs are empty, no date range is used * Legacy options (year=/month=) are converted to use for the end timestamp, so URLs with them should still work. * Unit tests! Bug: T120733 Change-Id: Id15f2b2ce2954fe98dfbbb7b0e86c0e4e5713f5e --- diff --git a/includes/specials/SpecialContributions.php b/includes/specials/SpecialContributions.php index 167a025786..cc399b6890 100644 --- a/includes/specials/SpecialContributions.php +++ b/includes/specials/SpecialContributions.php @@ -40,8 +40,11 @@ class SpecialContributions extends IncludableSpecialPage { $out->addModuleStyles( [ 'mediawiki.special', 'mediawiki.special.changeslist', + 'mediawiki.widgets.DateInputWidget', ] ); + $out->addModules( 'mediawiki.special.contributions' ); $this->addHelpLink( 'Help:User contributions' ); + $out->enableOOUI(); $this->opts = []; $request = $this->getRequest(); @@ -130,8 +133,12 @@ class SpecialContributions extends IncludableSpecialPage { $this->opts['year'] = ''; $this->opts['month'] = ''; } else { - $this->opts['year'] = $request->getIntOrNull( 'year' ); - $this->opts['month'] = $request->getIntOrNull( 'month' ); + $this->opts['year'] = $request->getVal( 'year' ); + $this->opts['month'] = $request->getVal( 'month' ); + + $this->opts['start'] = $request->getVal( 'start' ); + $this->opts['end'] = $request->getVal( 'end' ); + $this->opts = SpecialContributions::processDateFilter( $this->opts ); } $feedType = $request->getVal( 'feed' ); @@ -190,8 +197,8 @@ class SpecialContributions extends IncludableSpecialPage { 'contribs' => $this->opts['contribs'], 'namespace' => $this->opts['namespace'], 'tagfilter' => $this->opts['tagfilter'], - 'year' => $this->opts['year'], - 'month' => $this->opts['month'], + 'start' => $this->opts['start'], + 'end' => $this->opts['end'], 'deletedOnly' => $this->opts['deletedOnly'], 'topOnly' => $this->opts['topOnly'], 'newOnly' => $this->opts['newOnly'], @@ -432,12 +439,12 @@ class SpecialContributions extends IncludableSpecialPage { $this->opts['contribs'] = 'user'; } - if ( !isset( $this->opts['year'] ) ) { - $this->opts['year'] = ''; + if ( !isset( $this->opts['start'] ) ) { + $this->opts['start'] = ''; } - if ( !isset( $this->opts['month'] ) ) { - $this->opts['month'] = ''; + if ( !isset( $this->opts['end'] ) ) { + $this->opts['end'] = ''; } if ( $this->opts['contribs'] == 'newbie' ) { @@ -478,6 +485,8 @@ class SpecialContributions extends IncludableSpecialPage { 'contribs', 'year', 'month', + 'start', + 'end', 'topOnly', 'newOnly', 'hideMinor', @@ -652,15 +661,32 @@ class SpecialContributions extends IncludableSpecialPage { implode( '', $filters ) ); - $dateSelectionAndSubmit = Xml::tags( 'div', [], - Xml::dateMenu( - $this->opts['year'] === '' ? MWTimestamp::getInstance()->format( 'Y' ) : $this->opts['year'], - $this->opts['month'] - ) . ' ' . - Html::submitButton( - $this->msg( 'sp-contributions-submit' )->text(), - [ 'class' => 'mw-submit' ], [ 'mw-ui-progressive' ] - ) + $dateRangeSelection = Html::rawElement( + 'div', + [], + Xml::label( wfMessage( 'date-range-from' )->text(), 'mw-date-start' ) . ' ' . + new \Mediawiki\Widget\DateInputWidget( [ + 'infusable' => true, + 'id' => 'mw-date-start', + 'name' => 'start', + 'value' => $this->opts['start'], + 'longDisplayFormat' => true, + ] ) . '
' . + Xml::label( wfMessage( 'date-range-to' )->text(), 'mw-date-end' ) . ' ' . + new \Mediawiki\Widget\DateInputWidget( [ + 'infusable' => true, + 'id' => 'mw-date-end', + 'name' => 'end', + 'value' => $this->opts['end'], + 'longDisplayFormat' => true, + ] ) + ); + + $submit = Xml::tags( 'div', [], + Html::submitButton( + $this->msg( 'sp-contributions-submit' )->text(), + [ 'class' => 'mw-submit' ], [ 'mw-ui-progressive' ] + ) ); $form .= Xml::fieldset( @@ -669,7 +695,8 @@ class SpecialContributions extends IncludableSpecialPage { $namespaceSelection . $filterSelection . $extraOptions . - $dateSelectionAndSubmit, + $dateRangeSelection . + $submit, [ 'class' => 'mw-contributions-table' ] ); @@ -701,6 +728,46 @@ class SpecialContributions extends IncludableSpecialPage { return UserNamePrefixSearch::search( 'public', $search, $limit, $offset ); } + /** + * Set up date filter options, given request data. + * + * @param array $opts Options array + * @return array Options array with processed start and end date filter options + */ + public static function processDateFilter( $opts ) { + $start = $opts['start'] ?: ''; + $end = $opts['end'] ?: ''; + $year = $opts['year'] ?: ''; + $month = $opts['month'] ?: ''; + + if ( $start !== '' && $end !== '' && + $start > $end + ) { + $temp = $start; + $start = $end; + $end = $temp; + } + + // If year/month legacy filtering options are set, convert them to display the new stamp + if ( $year !== '' || $month !== '' ) { + // Reuse getDateCond logic, but subtract a day because + // the endpoints of our date range appear inclusive + // but the internal end offsets are always exclusive + $legacyTimestamp = ReverseChronologicalPager::getOffsetDate( $year, $month ); + $legacyDateTime = new DateTime( $legacyTimestamp->getTimestamp( TS_ISO_8601 ) ); + $legacyDateTime = $legacyDateTime->modify( '-1 day' ); + + // Clear the new timestamp range options if used and + // replace with the converted legacy timestamp + $start = ''; + $end = $legacyDateTime->format( 'Y-m-d' ); + } + + $opts['start'] = $start; + $opts['end'] = $end; + return $opts; + } + protected function getGroupName() { return 'users'; } diff --git a/includes/specials/pagers/ContribsPager.php b/includes/specials/pagers/ContribsPager.php index ea93f1f893..415c07faed 100644 --- a/includes/specials/pagers/ContribsPager.php +++ b/includes/specials/pagers/ContribsPager.php @@ -28,7 +28,7 @@ use Wikimedia\Rdbms\ResultWrapper; use Wikimedia\Rdbms\FakeResultWrapper; use Wikimedia\Rdbms\IDatabase; -class ContribsPager extends ReverseChronologicalPager { +class ContribsPager extends RangeChronologicalPager { public $mDefaultDirection = IndexPager::DIR_DESCENDING; public $messages; @@ -76,9 +76,16 @@ class ContribsPager extends ReverseChronologicalPager { $this->newOnly = !empty( $options['newOnly'] ); $this->hideMinor = !empty( $options['hideMinor'] ); - $year = isset( $options['year'] ) ? $options['year'] : false; - $month = isset( $options['month'] ) ? $options['month'] : false; - $this->getDateCond( $year, $month ); + // Date filtering: use timestamp if available + $startTimestamp = ''; + $endTimestamp = ''; + if ( $options['start'] ) { + $startTimestamp = $options['start'] . ' 00:00:00'; + } + if ( $options['end'] ) { + $endTimestamp = $options['end'] . ' 23:59:59'; + } + $this->getDateRangeCond( $startTimestamp, $endTimestamp ); // Most of this code will use the 'contributions' group DB, which can map to replica DBs // with extra user based indexes or partioning by user. The additional metadata diff --git a/resources/Resources.php b/resources/Resources.php index 976b1fb4e2..d58a9623ab 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1958,6 +1958,13 @@ return [ 'mediawiki.special.comparepages.styles' => [ 'styles' => 'resources/src/mediawiki.special/mediawiki.special.comparepages.styles.less', ], + 'mediawiki.special.contributions' => [ + 'scripts' => 'resources/src/mediawiki.special/mediawiki.special.contributions.js', + 'dependencies' => [ + 'mediawiki.widgets.DateInputWidget', + 'mediawiki.jqueryMsg', + ] + ], 'mediawiki.special.edittags' => [ 'scripts' => 'resources/src/mediawiki.special/mediawiki.special.edittags.js', 'dependencies' => [ diff --git a/resources/src/mediawiki.special/mediawiki.special.contributions.js b/resources/src/mediawiki.special/mediawiki.special.contributions.js new file mode 100644 index 0000000000..3f34951687 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.contributions.js @@ -0,0 +1,7 @@ +/* jshint -W024*/ +( function ( mw, $ ) { + $( function () { + mw.widgets.DateInputWidget.static.infuse( 'mw-date-start' ); + mw.widgets.DateInputWidget.static.infuse( 'mw-date-end' ); + } ); +}( mediaWiki, jQuery ) ); diff --git a/tests/phpunit/includes/specials/SpecialContributionsTest.php b/tests/phpunit/includes/specials/SpecialContributionsTest.php new file mode 100644 index 0000000000..6e692a7060 --- /dev/null +++ b/tests/phpunit/includes/specials/SpecialContributionsTest.php @@ -0,0 +1,50 @@ +assertArraySubset( $expectedOpts, SpecialContributions::processDateFilter( $inputOpts ) ); + } + + public static function dateFilterOptionProcessingProvider() { + return [ + [ [ 'start' => '2016-05-01', + 'end' => '2016-06-01', + 'year' => null, + 'month' => null ], + [ 'start' => '2016-05-01', + 'end' => '2016-06-01' ] ], + [ [ 'start' => '2016-05-01', + 'end' => '2016-06-01', + 'year' => '', + 'month' => '' ], + [ 'start' => '2016-05-01', + 'end' => '2016-06-01' ] ], + [ [ 'start' => '2016-05-01', + 'end' => '2016-06-01', + 'year' => '2012', + 'month' => '5' ], + [ 'start' => '', + 'end' => '2012-05-31' ] ], + [ [ 'start' => '', + 'end' => '', + 'year' => '2012', + 'month' => '5' ], + [ 'start' => '', + 'end' => '2012-05-31' ] ], + [ [ 'start' => '', + 'end' => '', + 'year' => '2012', + 'month' => '' ], + [ 'start' => '', + 'end' => '2012-12-31' ] ], + ]; + } +}