parent::execute( $subpage );
if ( $this->isStructuredFilterUiEnabled() ) {
- $jsData = $this->getStructuredFilterJsData();
-
- $messages = [];
- foreach ( $jsData['messageKeys'] as $key ) {
- $messages[$key] = $this->msg( $key )->plain();
- }
-
- $out->addHTML(
- ResourceLoader::makeInlineScript(
- ResourceLoader::makeMessageSetScript( $messages )
- )
- );
-
- $experimentalStructuredChangeFilters =
- $this->getConfig()->get( 'StructuredChangeFiltersEnableExperimentalViews' );
-
- $out->addJsConfigVars( 'wgStructuredChangeFilters', $jsData['groups'] );
- $out->addJsConfigVars(
- 'wgStructuredChangeFiltersEnableSaving',
- $this->getConfig()->get( 'StructuredChangeFiltersEnableSaving' )
- );
+ $out->addJsConfigVars( 'wgStructuredChangeFiltersLiveUpdateSupported', true );
$out->addJsConfigVars(
- 'wgStructuredChangeFiltersEnableExperimentalViews',
- $experimentalStructuredChangeFilters
+ 'wgStructuredChangeFiltersSavedQueriesPreferenceName',
+ 'rcfilters-saved-queries'
);
- $out->addJsConfigVars(
- 'wgStructuredChangeFiltersEnableLiveUpdate',
- $this->getConfig()->get( 'StructuredChangeFiltersEnableLiveUpdate' )
- );
- if ( $experimentalStructuredChangeFilters ) {
- $out->addJsConfigVars(
- 'wgRCFiltersChangeTags',
- $this->buildChangeTagList()
- );
- }
- }
- }
-
- /**
- * Fetch the change tags list for the front end
- *
- * @return Array Tag data
- */
- protected function buildChangeTagList() {
- $explicitlyDefinedTags = array_fill_keys( ChangeTags::listExplicitlyDefinedTags(), 0 );
- $softwareActivatedTags = array_fill_keys( ChangeTags::listSoftwareActivatedTags(), 0 );
-
- // Hit counts disabled for perf reasons, see T169997
- /*
- $tagStats = ChangeTags::tagUsageStatistics();
- $tagHitCounts = array_merge( $explicitlyDefinedTags, $softwareActivatedTags, $tagStats );
-
- // Sort by hits
- arsort( $tagHitCounts );
- */
- $tagHitCounts = array_merge( $explicitlyDefinedTags, $softwareActivatedTags );
-
- // Build the list and data
- $result = [];
- foreach ( $tagHitCounts as $tagName => $hits ) {
- if (
- // Only get active tags
- isset( $explicitlyDefinedTags[ $tagName ] ) ||
- isset( $softwareActivatedTags[ $tagName ] )
- ) {
- // Parse description
- $desc = ChangeTags::tagLongDescriptionMessage( $tagName, $this->getContext() );
-
- $result[] = [
- 'name' => $tagName,
- 'label' => Sanitizer::stripAllTags(
- ChangeTags::tagDescription( $tagName, $this->getContext() )
- ),
- 'description' => $desc ? Sanitizer::stripAllTags( $desc->parse() ) : '',
- 'cssClass' => Sanitizer::escapeClass( 'mw-tag-' . $tagName ),
- 'hits' => $hits,
- ];
- }
}
-
- // Instead of sorting by hit count (disabled, see above), sort by display name
- usort( $result, function ( $a, $b ) {
- return strcasecmp( $a['label'], $b['label'] );
- } );
-
- return $result;
}
/**
- * @inheritdoc
+ * @inheritDoc
*/
protected function transformFilterDefinition( array $filterDefinition ) {
if ( isset( $filterDefinition['showHideSuffix'] ) ) {
}
/**
- * @inheritdoc
+ * @inheritDoc
*/
protected function registerFilters() {
parent::registerFilters();
public function validateOptions( FormOptions $opts ) {
$opts->validateIntBounds( 'limit', 0, 5000 );
+ $opts->validateBounds( 'days', 0, $this->getConfig()->get( 'RCMaxAge' ) / ( 3600 * 24 ) );
parent::validateOptions( $opts );
}
/**
- * @inheritdoc
+ * @inheritDoc
*/
protected function buildQuery( &$tables, &$fields, &$conds,
&$query_options, &$join_conds, FormOptions $opts
$query_options, $join_conds, $opts );
// Calculate cutoff
- $cutoff_unixtime = time() - ( $opts['days'] * 86400 );
+ $cutoff_unixtime = time() - $opts['days'] * 3600 * 24;
$cutoff = $dbr->timestamp( $cutoff_unixtime );
$fromValid = preg_match( '/^[0-9]{14}$/', $opts['from'] );
}
/**
- * @inheritdoc
+ * @inheritDoc
*/
protected function doMainQuery( $tables, $fields, $conds, $query_options,
$join_conds, FormOptions $opts
&& $this->getUser()->getOption( 'shownumberswatching' );
$watcherCache = [];
- $dbr = $this->getDB();
-
$counter = 1;
$list = ChangesList::newFromContext( $this->getContext(), $this->filterGroups );
$list->initChangesListRows( $rows );
++$count;
$addSubmit = ( $count === $extraOptsCount ) ? $submit : '';
- $out .= Xml::openElement( 'tr' );
+ $out .= Xml::openElement( 'tr', [ 'class' => $name . 'Form' ] );
if ( is_array( $optionRow ) ) {
$out .= Xml::tags(
'td',
$rcoptions = Xml::fieldset(
$this->msg( 'recentchanges-legend' )->text(),
$panelString,
- [ 'class' => 'rcoptions' ]
+ [ 'class' => 'rcoptions cloptions' ]
);
// Insert a placeholder for RCFilters
- if ( $this->getUser()->getOption( 'rcenhancedfilters' ) ) {
+ if ( $this->isStructuredFilterUiEnabled() ) {
$rcfilterContainer = Html::element(
'div',
[ 'class' => 'rcfilters-container' ]
$message = $this->msg( 'recentchangestext' )->inContentLanguage();
if ( !$message->isDisabled() ) {
- $this->getOutput()->addWikiText(
- Html::rawElement( 'div',
- [
- 'class' => 'mw-recentchanges-toplinks',
- 'lang' => $wgContLang->getHtmlCode(),
- 'dir' => $wgContLang->getDir()
- ],
- "\n" . $message->plain() . "\n"
- ),
- /* $lineStart */ true,
- /* $interface */ false
+ $content = $message->parse();
+
+ $langAttributes = [
+ 'lang' => $wgContLang->getHtmlCode(),
+ 'dir' => $wgContLang->getDir(),
+ ];
+
+ $topLinksAttributes = [ 'class' => 'mw-recentchanges-toplinks' ];
+
+ if ( $this->isStructuredFilterUiEnabled() ) {
+ $contentTitle = Html::rawElement( 'div',
+ [ 'class' => 'mw-recentchanges-toplinks-title' ],
+ $this->msg( 'rcfilters-other-review-tools' )->parse()
+ );
+ $contentWrapper = Html::rawElement( 'div',
+ array_merge( [ 'class' => 'mw-collapsible-content' ], $langAttributes ),
+ $content
+ );
+ $content = $contentTitle . $contentWrapper;
+ } else {
+ // Language direction should be on the top div only
+ // if the title is not there. If it is there, it's
+ // interface direction, and the language/dir attributes
+ // should be on the content itself
+ $topLinksAttributes = array_merge( $topLinksAttributes, $langAttributes );
+ }
+
+ $this->getOutput()->addHTML(
+ Html::rawElement( 'div', $topLinksAttributes, $content )
);
}
}
return $extraOpts;
}
- /**
- * Check whether the structured filter UI is enabled
- *
- * @return bool
- */
- protected function isStructuredFilterUiEnabled() {
- return $this->getUser()->getOption(
- 'rcenhancedfilters'
- );
- }
-
/**
* Add page-specific modules.
*/
parent::addModules();
$out = $this->getOutput();
$out->addModules( 'mediawiki.special.recentchanges' );
- if ( $this->isStructuredFilterUiEnabled() ) {
- $out->addModules( 'mediawiki.rcfilters.filters.ui' );
- $out->addModuleStyles( 'mediawiki.rcfilters.filters.base.styles' );
- }
}
/**
/**
* Filter $rows by categories set in $opts
*
- * @param ResultWrapper $rows Database rows
+ * @param ResultWrapper &$rows Database rows
* @param FormOptions $opts
*/
function filterByCategories( &$rows, FormOptions $opts ) {
$resetLink = $this->makeOptionsLink( $this->msg( 'rclistfromreset' ),
[ 'from' => '' ], $nondefaults );
- $note .= $this->msg( 'rcnotefrom' )
+ $noteFromMsg = $this->msg( 'rcnotefrom' )
->numParams( $options['limit'] )
->params(
$lang->userTimeAndDate( $options['from'], $user ),
$lang->userDate( $options['from'], $user ),
$lang->userTime( $options['from'], $user )
)
- ->numParams( $numRows )
- ->parse() . ' ' .
+ ->numParams( $numRows );
+ $note .= Html::rawElement(
+ 'span',
+ [ 'class' => 'rcnotefrom' ],
+ $noteFromMsg->parse()
+ ) .
+ ' ' .
Html::rawElement(
'span',
[ 'class' => 'rcoptions-listfromreset' ],
$filterGroups = $this->getFilterGroups();
- $context = $this->getContext();
foreach ( $filterGroups as $groupName => $group ) {
if ( !$group->isPerGroupRequestParameter() ) {
foreach ( $group->getFilters() as $key => $filter ) {
[ $key => 1 - $options[$key] ], $nondefaults );
$attribs = [
- 'class' => "$msg rcshowhideoption",
+ 'class' => "$msg rcshowhideoption clshowhideoption",
'data-filter-name' => $filter->getName(),
];