Merge "Move section ID fallbacks into headers themselves"
[lhc/web/wiklou.git] / includes / specials / SpecialWatchlist.php
index cecc182..ba3cb87 100644 (file)
@@ -97,11 +97,17 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                parent::execute( $subpage );
 
                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()
+                       );
                }
        }
 
@@ -142,6 +148,40 @@ class SpecialWatchlist extends ChangesListSpecialPage {
        protected function registerFilters() {
                parent::registerFilters();
 
+               // legacy 'extended' filter
+               $this->registerFilterGroup( new ChangesListBooleanFilterGroup( [
+                       'name' => 'extended-group',
+                       'filters' => [
+                               [
+                                       'name' => 'extended',
+                                       'isReplacedInStructuredUi' => true,
+                                       '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',
@@ -234,7 +274,6 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $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;
@@ -298,8 +337,11 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        // unchecked boxes.
                        foreach ( $this->filterGroups as $filterGroup ) {
                                if ( $filterGroup instanceof ChangesListBooleanFilterGroup ) {
+                                       /** @var ChangesListBooleanFilter $filter */
                                        foreach ( $filterGroup->getFilters() as $filter ) {
-                                               $allBooleansFalse[$filter->getName()] = false;
+                                               if ( $filter->displaysOnUnstructuredUi() ) {
+                                                       $allBooleansFalse[$filter->getName()] = false;
+                                               }
                                        }
                                }
                        }
@@ -341,29 +383,9 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $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 );
 
-               $query_options = array_merge( [
-                       'ORDER BY' => 'rc_timestamp DESC',
-                       'LIMIT' => $opts['limit']
-               ], $query_options );
                $join_conds = array_merge(
                        [
                                'watchlist' => [
@@ -400,13 +422,14 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        ], LIST_OR );
                }
 
+               $tagFilter = $opts['tagfilter'] ? explode( '|', $opts['tagfilter'] ) : [];
                ChangeTags::modifyDisplayQuery(
                        $tables,
                        $fields,
                        $conds,
                        $join_conds,
                        $query_options,
-                       ''
+                       $tagFilter
                );
 
                $this->runMainQueryHook( $tables, $fields, $conds, $query_options, $join_conds, $opts );
@@ -415,6 +438,23 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        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)
+               $query_options = array_merge( $orderByAndLimit, $query_options );
+
                return $dbr->select(
                        $tables,
                        $fields,
@@ -793,21 +833,29 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $showUpdatedMarker = $this->getConfig()->get( 'ShowUpdatedMarker' );
 
                // Show watchlist header
-               $form .= "<p>";
+               $watchlistHeader = '';
                if ( $numItems == 0 ) {
-                       $form .= $this->msg( 'nowatchlist' )->parse() . "\n";
+                       $watchlistHeader = $this->msg( 'nowatchlist' )->parse();
                } else {
-                       $form .= $this->msg( 'watchlist-details' )->numParams( $numItems )->parse() . "\n";
+                       $watchlistHeader .= $this->msg( 'watchlist-details' )->numParams( $numItems )->parse() . "\n";
                        if ( $this->getConfig()->get( 'EnotifWatchlist' )
                                && $user->getOption( 'enotifwatchlistpages' )
                        ) {
-                               $form .= $this->msg( 'wlheader-enotif' )->parse() . "\n";
+                               $watchlistHeader .= $this->msg( 'wlheader-enotif' )->parse() . "\n";
                        }
                        if ( $showUpdatedMarker ) {
-                               $form .= $this->msg( 'wlheader-showupdated' )->parse() . "\n";
+                               $watchlistHeader .= $this->msg(
+                                       $this->isStructuredFilterUiEnabled() ?
+                                               'rcfilters-watchlist-showupdated' :
+                                               'wlheader-showupdated'
+                               )->parse() . "\n";
                        }
                }
-               $form .= "</p>";
+               $form .= Html::rawElement(
+                       'div',
+                       [ 'class' => 'watchlistDetails' ],
+                       $watchlistHeader
+               );
 
                if ( $numItems > 0 && $showUpdatedMarker ) {
                        $form .= Xml::openElement( 'form', [ 'method' => 'post',
@@ -858,4 +906,12 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $count = $store->countWatchedItems( $this->getUser() );
                return floor( $count / 2 );
        }
+
+       function getDefaultLimit() {
+               return $this->getUser()->getIntOption( 'wllimit' );
+       }
+
+       function getDefaultDays() {
+               return $this->getUser()->getIntOption( 'watchlistdays' );
+       }
 }