* @ingroup SpecialPage
*/
class SpecialWatchlist extends ChangesListSpecialPage {
+ protected static $savedQueriesPreferenceName = 'rcfilters-wl-saved-queries';
+ protected static $daysPreferenceName = 'watchlistdays';
+ protected static $limitPreferenceName = 'wllimit';
+
private $maxDays;
public function __construct( $page = 'Watchlist', $restriction = 'viewmywatchlist' ) {
if ( $this->isStructuredFilterUiEnabled() ) {
$output->addModuleStyles( [ 'mediawiki.rcfilters.highlightCircles.seenunseen.styles' ] );
- $output->addJsConfigVars( 'wgStructuredChangeFiltersLiveUpdateSupported', false );
- $output->addJsConfigVars(
- 'wgStructuredChangeFiltersSavedQueriesPreferenceName',
- 'rcfilters-wl-saved-queries'
- );
$output->addJsConfigVars(
'wgStructuredChangeFiltersEditWatchlistUrl',
SpecialPage::getTitleFor( 'EditWatchlist' )->getLocalURL()
}
}
- public function isStructuredFilterUiEnabled() {
- return $this->getRequest()->getBool( 'rcfilters' ) || (
- $this->getConfig()->get( 'StructuredChangeFiltersOnWatchlist' ) &&
- $this->getUser()->getOption( 'rcenhancedfilters' )
+ public static function checkStructuredFilterUiEnabled( Config $config, User $user ) {
+ return (
+ $config->get( 'StructuredChangeFiltersOnWatchlist' ) &&
+ $user->getOption( 'rcenhancedfilters' )
);
}
- public function isStructuredFilterUiEnabledByDefault() {
- return $this->getConfig()->get( 'StructuredChangeFiltersOnWatchlist' ) &&
- $this->getUser()->getDefaultOption( 'rcenhancedfilters' );
- }
-
/**
* Return an array of subpages that this special page will accept.
*
$hideLiu = $registration->getFilter( 'hideliu' );
$hideLiu->setDefault( $user->getBoolOption( 'watchlisthideliu' ) );
+ // Selecting both hideanons and hideliu on watchlist preferances
+ // gives mutually exclusive filters, so those are ignored
+ if ( $user->getBoolOption( 'watchlisthideanons' ) &&
+ !$user->getBoolOption( 'watchlisthideliu' )
+ ) {
+ $this->getFilterGroup( 'userExpLevel' )
+ ->setDefault( 'registered' );
+ }
+
+ if ( $user->getBoolOption( 'watchlisthideliu' ) &&
+ !$user->getBoolOption( 'watchlisthideanons' )
+ ) {
+ $this->getFilterGroup( 'userExpLevel' )
+ ->setDefault( 'unregistered' );
+ }
+
$reviewStatus = $this->getFilterGroup( 'reviewStatus' );
if ( $reviewStatus !== null ) {
// Conditional on feature being available and rights
}
}
- /**
- * Get a FormOptions object containing the default options
- *
- * @return FormOptions
- */
- public function getDefaultOptions() {
- $opts = parent::getDefaultOptions();
-
- $opts->add( 'days', $this->getDefaultDays(), FormOptions::FLOAT );
- $opts->add( 'limit', $this->getDefaultLimit(), FormOptions::INT );
-
- return $opts;
- }
-
- public function validateOptions( FormOptions $opts ) {
- $opts->validateBounds( 'days', 0, $this->maxDays );
- $opts->validateIntBounds( 'limit', 0, 5000 );
- parent::validateOptions( $opts );
- }
-
/**
* Get all custom filters
*
// This is how we handle the fact that HTML forms don't submit
// unchecked boxes.
- foreach ( $this->filterGroups as $filterGroup ) {
- if ( $filterGroup instanceof ChangesListBooleanFilterGroup ) {
- /** @var ChangesListBooleanFilter $filter */
- foreach ( $filterGroup->getFilters() as $filter ) {
- if ( $filter->displaysOnUnstructuredUi() ) {
- $allBooleansFalse[$filter->getName()] = false;
- }
- }
- }
+ foreach ( $this->getLegacyShowHideFilters() as $filter ) {
+ $allBooleansFalse[ $filter->getName() ] = false;
}
$params = $params + $allBooleansFalse;
return $opts;
}
- /**
- * @inheritDoc
- */
- protected function buildQuery( &$tables, &$fields, &$conds, &$query_options,
- &$join_conds, FormOptions $opts
- ) {
- $dbr = $this->getDB();
- parent::buildQuery( $tables, $fields, $conds, $query_options, $join_conds,
- $opts );
-
- // Calculate cutoff
- if ( $opts['days'] > 0 ) {
- $conds[] = 'rc_timestamp > ' .
- $dbr->addQuotes( $dbr->timestamp( time() - $opts['days'] * 3600 * 24 ) );
- }
- }
-
/**
* @inheritDoc
*/
$dbr = $this->getDB();
$user = $this->getUser();
- $tables = array_merge( [ 'recentchanges', 'watchlist' ], $tables );
- $fields = array_merge( RecentChange::selectFields(), $fields );
+ $rcQuery = RecentChange::getQueryInfo();
+ $tables = array_merge( $tables, $rcQuery['tables'], [ 'watchlist' ] );
+ $fields = array_merge( $rcQuery['fields'], $fields );
$join_conds = array_merge(
[
],
],
],
+ $rcQuery['joins'],
$join_conds
);
'id' => 'mw-watchlist-form'
] );
$form .= Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() );
- $form .= Xml::fieldset(
- $this->msg( 'watchlist-options' )->text(),
- false,
+ $form .= Xml::openElement(
+ 'fieldset',
[ 'id' => 'mw-watchlist-options', 'class' => 'cloptions' ]
);
+ $form .= Xml::element(
+ 'legend', null, $this->msg( 'watchlist-options' )->text()
+ );
if ( !$this->isStructuredFilterUiEnabled() ) {
$form .= $this->makeLegend();
}
$lang = $this->getLanguage();
- if ( $opts['days'] > 0 ) {
- $days = $opts['days'];
- } else {
- $days = $this->maxDays;
- }
$timestamp = wfTimestampNow();
$wlInfo = Html::rawElement(
'span',
- [ 'class' => 'wlinfo' ],
- $this->msg( 'wlnote' )->numParams( $numRows, round( $days * 24 ) )->params(
+ [
+ 'class' => 'wlinfo',
+ 'data-params' => json_encode( [ 'from' => $timestamp ] ),
+ ],
+ $this->msg( 'wlnote' )->numParams( $numRows, round( $opts['days'] * 24 ) )->params(
$lang->userDate( $timestamp, $user ), $lang->userTime( $timestamp, $user )
)->parse()
) . "<br />\n";
# Spit out some control panel links
$links = [];
$namesOfDisplayedFilters = [];
- foreach ( $this->getFilterGroups() as $groupName => $group ) {
- if ( !$group->isPerGroupRequestParameter() ) {
- foreach ( $group->getFilters() as $filterName => $filter ) {
- if ( $filter->displaysOnUnstructuredUi( $this ) ) {
- $namesOfDisplayedFilters[] = $filterName;
- $links[] = $this->showHideCheck(
- $nondefaults,
- $filter->getShowHide(),
- $filterName,
- $opts[$filterName],
- $filter->isFeatureAvailableOnStructuredUi( $this )
- );
- }
- }
- }
+ foreach ( $this->getLegacyShowHideFilters() as $filterName => $filter ) {
+ $namesOfDisplayedFilters[] = $filterName;
+ $links[] = $this->showHideCheck(
+ $nondefaults,
+ $filter->getShowHide(),
+ $filterName,
+ $opts[ $filterName ],
+ $filter->isFeatureAvailableOnStructuredUi( $this )
+ );
}
$hiddenFields = $nondefaults;
return Html::rawElement(
'span',
$attribs,
- Xml::checkLabel(
- $this->msg( $message, '' )->text(),
- $name,
- $name,
- (int)$value
+ // not using Html::checkLabel because that would escape the contents
+ Html::check( $name, (int)$value, [ 'id' => $name ] ) . Html::rawElement(
+ 'label',
+ $attribs + [ 'for' => $name ],
+ // <nowiki/> at beginning to avoid messages with "$1 ..." being parsed as pre tags
+ $this->msg( $message, '<nowiki/>' )->parse()
)
);
}
$count = $store->countWatchedItems( $this->getUser() );
return floor( $count / 2 );
}
-
- function getDefaultLimit() {
- return $this->getUser()->getIntOption( 'wllimit' );
- }
-
- function getDefaultDays() {
- return floatval( $this->getUser()->getOption( 'watchlistdays' ) );
- }
}