*/
protected $queryCallable;
+ /**
+ * Value that defined when this filter is considered active
+ *
+ * @var bool $activeValue
+ */
+ protected $activeValue;
+
+ /**
+ * Whether this filter is visible somewhere (legacy form or structured UI).
+ *
+ * @var bool $isVisible
+ */
+ protected $isVisible;
+
/**
* Create a new filter with the specified configuration.
*
* to true. It does not need to be set if the exact same filter is simply visible
* on both.
* * $filterDefinition['default'] bool Default
+ * * $filterDefinition['activeValue'] bool This filter is considered active when
+ * its value is equal to its activeValue. Default is true.
+ * * $filterDefinition['isVisible'] bool This filter is visible in the legacy form or
+ * structured UI. Default is true.
* * $filterDefinition['priority'] int Priority integer. Higher value means higher
* up in the group's filter list.
* * $filterDefinition['queryCallable'] callable Callable accepting parameters, used
if ( isset( $filterDefinition['queryCallable'] ) ) {
$this->queryCallable = $filterDefinition['queryCallable'];
}
+
+ if ( isset( $filterDefinition['activeValue'] ) ) {
+ $this->activeValue = $filterDefinition['activeValue'];
+ } else {
+ $this->activeValue = true;
+ }
+
+ if ( isset( $filterDefinition['isVisible'] ) ) {
+ $this->isVisible = $filterDefinition['isVisible'];
+ } else {
+ $this->isVisible = true;
+ }
}
/**
*/
public function getDefault( $structuredUI = false ) {
return $this->isReplacedInStructuredUi && $structuredUI ?
- false :
+ !$this->activeValue :
$this->defaultValue;
}
return $opts[ $sibling->getName() ];
} );
}
+
+ /**
+ * @param FormOptions $opts Query parameters merged with defaults
+ * @param bool $isStructuredUI Whether the structured UI is currently enabled
+ * @return bool Whether this filter should be considered active
+ */
+ public function isActive( FormOptions $opts, $isStructuredUI ) {
+ if ( $this->isReplacedInStructuredUi && $isStructuredUI ) {
+ return false;
+ }
+
+ return $opts[ $this->getName() ] === $this->activeValue;
+ }
+
+ /**
+ * @return bool Whether this filter is visible anywhere
+ */
+ public function isVisible() {
+ return $this->isVisible;
+ }
}
[
'maxDays' => (int)$this->getConfig()->get( 'RCMaxAge' ) / ( 24 * 3600 ), // Translate to days
'limitArray' => $this->getConfig()->get( 'RCLinkLimits' ),
+ 'limitDefault' => $this->getDefaultLimit(),
'daysArray' => $this->getConfig()->get( 'RCLinkDays' ),
+ 'daysDefault' => $this->getDefaultDays(),
]
);
}
&$join_conds, FormOptions $opts
) {
$dbr = $this->getDB();
+ $isStructuredUI = $this->isStructuredFilterUiEnabled();
foreach ( $this->filterGroups as $filterGroup ) {
// URL parameters can be per-group, like 'userExpLevel',
$query_options, $join_conds, $opts[$filterGroup->getName()] );
} else {
foreach ( $filterGroup->getFilters() as $filter ) {
- if ( $opts[$filter->getName()] ) {
+ if ( $filter->isActive( $opts, $isStructuredUI ) ) {
$filter->modifyQuery( $dbr, $this, $tables, $fields, $conds,
$query_options, $join_conds );
}
protected function isStructuredFilterUiEnabled() {
return $this->getUser()->getOption( 'rcenhancedfilters' );
}
+
+ abstract function getDefaultLimit();
+
+ abstract function getDefaultDays();
}
protected function getCacheTTL() {
return 60 * 5;
}
+
+ function getDefaultLimit() {
+ return $this->getUser()->getIntOption( 'rclimit' );
+ }
+
+ function getDefaultDays() {
+ return $this->getUser()->getIntOption( 'rcdays' );
+ }
}
protected function registerFilters() {
parent::registerFilters();
+ // legacy 'extended' filter
+ $this->registerFilterGroup( new ChangesListBooleanFilterGroup( [
+ 'name' => 'extended-group',
+ 'filters' => [
+ [
+ 'name' => 'extended',
+ 'isReplacedInStructuredUi' => true,
+ 'isVisible' => false,
+ 'activeValue' => false,
+ 'default' => $this->getUser()->getBoolOption( 'extendwatchlist' ),
+ 'queryCallable' => function ( $specialClassName, $ctx, $dbr, &$tables,
+ &$fields, &$conds, &$query_options, &$join_conds ) {
+ $nonRevisionTypes = [ RC_LOG ];
+ Hooks::run( 'SpecialWatchlistGetNonRevisionTypes', [ &$nonRevisionTypes ] );
+ if ( $nonRevisionTypes ) {
+ $conds[] = $dbr->makeList(
+ [
+ 'rc_this_oldid=page_latest',
+ 'rc_type' => $nonRevisionTypes,
+ ],
+ LIST_OR
+ );
+ }
+ },
+ ]
+ ],
+
+ ] ) );
+
+ if ( $this->isStructuredFilterUiEnabled() ) {
+ $this->getFilterGroup( 'lastRevision' )
+ ->getFilter( 'hidepreviousrevisions' )
+ ->setDefault( !$this->getUser()->getBoolOption( 'extendwatchlist' ) );
+ }
+
$this->registerFilterGroup( new ChangesListStringOptionsFilterGroup( [
'name' => 'watchlistactivity',
'title' => 'rcfilters-filtergroup-watchlistactivity',
$user = $this->getUser();
$opts->add( 'days', $user->getOption( 'watchlistdays' ), FormOptions::FLOAT );
- $opts->add( 'extended', $user->getBoolOption( 'extendwatchlist' ) );
$opts->add( 'limit', $user->getIntOption( 'wllimit' ), FormOptions::INT );
return $opts;
foreach ( $this->filterGroups as $filterGroup ) {
if ( $filterGroup instanceof ChangesListBooleanFilterGroup ) {
foreach ( $filterGroup->getFilters() as $filter ) {
- $allBooleansFalse[$filter->getName()] = false;
+ if ( $filter->isVisible() ) {
+ $allBooleansFalse[$filter->getName()] = false;
+ }
}
}
}
$dbr = $this->getDB();
$user = $this->getUser();
- # Toggle watchlist content (all recent edits or just the latest)
- if ( !$opts['extended'] ) {
- # Top log Ids for a page are not stored
- $nonRevisionTypes = [ RC_LOG ];
- Hooks::run( 'SpecialWatchlistGetNonRevisionTypes', [ &$nonRevisionTypes ] );
- if ( $nonRevisionTypes ) {
- $conds[] = $dbr->makeList(
- [
- 'rc_this_oldid=page_latest',
- 'rc_type' => $nonRevisionTypes,
- ],
- LIST_OR
- );
- }
- }
-
$tables = array_merge( [ 'recentchanges', 'watchlist' ], $tables );
$fields = array_merge( RecentChange::selectFields(), $fields );
$count = $store->countWatchedItems( $this->getUser() );
return floor( $count / 2 );
}
+
+ function getDefaultLimit() {
+ return $this->getUser()->getIntOption( 'wllimit' );
+ }
+
+ function getDefaultDays() {
+ return $this->getUser()->getIntOption( 'watchlistdays' );
+ }
}
* @param {Object} [tagList] Tag definition
*/
mw.rcfilters.Controller.prototype.initialize = function ( filterStructure, namespaceStructure, tagList ) {
- var parsedSavedQueries, limitDefault,
+ var parsedSavedQueries,
displayConfig = mw.config.get( 'StructuredChangeFiltersDisplayConfig' ),
controller = this,
views = {},
};
}
- // Convert the default from the old preference
- // since the limit preference actually affects more
- // than just the RecentChanges page
- limitDefault = Number( mw.user.options.get( 'rclimit', '50' ) );
-
// Add parameter range operations
views.range = {
groups: [
max: 1000
},
sortFunc: function ( a, b ) { return Number( a.name ) - Number( b.name ); },
- 'default': String( limitDefault ),
+ 'default': displayConfig.limitDefault,
// Temporarily making this not sticky until we resolve the problem
// with the misleading preference. Note that if this is to be permanent
// we should remove all sticky behavior methods completely
( Number( i ) * 24 ).toFixed( 2 ) :
Number( i );
},
- 'default': mw.user.options.get( 'rcdays', '30' ),
+ 'default': displayConfig.daysDefault,
// Temporarily making this not sticky while limit is not sticky, see above
// isSticky: true,
excludedFromSavedQueries: true,