* @param string $subpage
*/
public function execute( $subpage ) {
- global $wgStructuredChangeFiltersEnableSaving;
+ global $wgStructuredChangeFiltersEnableSaving,
+ $wgStructuredChangeFiltersEnableExperimentalViews,
+ $wgStructuredChangeFiltersEnableLiveUpdate;
// Backwards-compatibility: redirect to new feed URLs
$feedFormat = $this->getRequest()->getVal( 'feed' );
'wgStructuredChangeFiltersEnableSaving',
$wgStructuredChangeFiltersEnableSaving
);
+ $out->addJsConfigVars(
+ 'wgStructuredChangeFiltersEnableExperimentalViews',
+ $wgStructuredChangeFiltersEnableExperimentalViews
+ );
+ $out->addJsConfigVars(
+ 'wgStructuredChangeFiltersEnableLiveUpdate',
+ $wgStructuredChangeFiltersEnableLiveUpdate
+ );
+ $out->addJsConfigVars(
+ 'wgRCFiltersChangeTags',
+ $this->buildChangeTagList()
+ );
}
}
+ /**
+ * Fetch the change tags list for the front end
+ *
+ * @return Array Tag data
+ */
+ protected function buildChangeTagList() {
+ function stripAllHtml( $input ) {
+ return trim( html_entity_decode( strip_tags( $input ) ) );
+ }
+
+ $explicitlyDefinedTags = array_fill_keys( ChangeTags::listExplicitlyDefinedTags(), 0 );
+ $softwareActivatedTags = array_fill_keys( ChangeTags::listSoftwareActivatedTags(), 0 );
+ $tagStats = ChangeTags::tagUsageStatistics();
+
+ $tagHitCounts = array_merge( $explicitlyDefinedTags, $softwareActivatedTags, $tagStats );
+
+ // Sort by hits
+ arsort( $tagHitCounts );
+
+ // 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' => stripAllHtml( ChangeTags::tagDescription( $tagName, $this->getContext() ) ),
+ 'description' => $desc ? stripAllHtml( $desc->parse() ) : '',
+ 'cssClass' => Sanitizer::escapeClass( 'mw-tag-' . $tagName ),
+ 'hits' => $hits,
+ ];
+ }
+ }
+
+ return $result;
+ }
+
/**
* @inheritdoc
*/
* @inheritdoc
*/
protected function buildQuery( &$tables, &$fields, &$conds,
- &$query_options, &$join_conds, FormOptions $opts ) {
-
+ &$query_options, &$join_conds, FormOptions $opts
+ ) {
$dbr = $this->getDB();
parent::buildQuery( $tables, $fields, $conds,
$query_options, $join_conds, $opts );
* @inheritdoc
*/
protected function doMainQuery( $tables, $fields, $conds, $query_options,
- $join_conds, FormOptions $opts ) {
-
+ $join_conds, FormOptions $opts
+ ) {
$dbr = $this->getDB();
$user = $this->getUser();
$fields[] = 'page_latest';
$join_conds['page'] = [ 'LEFT JOIN', 'rc_cur_id=page_id' ];
+ $tagFilter = explode( '|', $opts['tagfilter'] );
ChangeTags::modifyDisplayQuery(
$tables,
$fields,
$conds,
$join_conds,
$query_options,
- $opts['tagfilter']
+ $tagFilter
);
if ( !$this->runMainQueryHook( $tables, $fields, $conds, $query_options, $join_conds,
return false;
}
+ $orderByAndLimit = [
+ 'ORDER BY' => 'rc_timestamp DESC',
+ 'LIMIT' => $opts['limit']
+ ];
+ if ( in_array( 'DISTINCT', $query_options ) ) {
+ // ChangeTags::modifyDisplayQuery() adds DISTINCT when filtering on multiple tags.
+ // In order to prevent DISTINCT from causing query performance problems,
+ // we have to GROUP BY the primary key. This in turn requires us to add
+ // the primary key to the end of the ORDER BY, and the old ORDER BY to the
+ // start of the GROUP BY
+ $orderByAndLimit['ORDER BY'] = 'rc_timestamp DESC, rc_id DESC';
+ $orderByAndLimit['GROUP BY'] = 'rc_timestamp, rc_id';
+ }
// array_merge() is used intentionally here so that hooks can, should
// they so desire, override the ORDER BY / LIMIT condition(s); prior to
// MediaWiki 1.26 this used to use the plus operator instead, which meant
// that extensions weren't able to change these conditions
- $query_options = array_merge( [
- 'ORDER BY' => 'rc_timestamp DESC',
- 'LIMIT' => $opts['limit'] ], $query_options );
+ $query_options = array_merge( $orderByAndLimit, $query_options );
$rows = $dbr->select(
$tables,
$fields,
$userShowHiddenCats = $this->getUser()->getBoolOption( 'showhiddencats' );
$rclistOutput = $list->beginRecentChangesList();
+ if ( $this->isStructuredFilterUiEnabled() ) {
+ $rclistOutput .= $this->makeLegend();
+ }
+
foreach ( $rows as $obj ) {
if ( $limit == 0 ) {
break;
$nondefaults = $opts->getChangedValues();
$panel = [];
- $panel[] = $this->makeLegend();
+ if ( !$this->isStructuredFilterUiEnabled() ) {
+ $panel[] = $this->makeLegend();
+ }
$panel[] = $this->optionsPanel( $defaults, $nondefaults, $numRows );
$panel[] = '<hr />';