Merge "Perform a permission check on the title when changing the page language"
[lhc/web/wiklou.git] / includes / specials / SpecialWatchlist.php
index 65131ec..1d76e36 100644 (file)
@@ -34,6 +34,8 @@ use Wikimedia\Rdbms\IDatabase;
 class SpecialWatchlist extends ChangesListSpecialPage {
        public function __construct( $page = 'Watchlist', $restriction = 'viewmywatchlist' ) {
                parent::__construct( $page, $restriction );
+
+               $this->maxDays = $this->getConfig()->get( 'RCMaxAge' ) / ( 3600 * 24 );
        }
 
        public function doesWrites() {
@@ -56,6 +58,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        'mediawiki.special.changeslist.visitedstatus',
                        'mediawiki.special.watchlist',
                ] );
+               $output->addModuleStyles( [ 'mediawiki.special.watchlist.styles' ] );
 
                $mode = SpecialEditWatchlist::getMode( $request, $subpage );
                if ( $mode !== false ) {
@@ -107,7 +110,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
        }
 
        /**
-        * @inheritdoc
+        * @inheritDoc
         */
        protected function transformFilterDefinition( array $filterDefinition ) {
                if ( isset( $filterDefinition['showHideSuffix'] ) ) {
@@ -118,7 +121,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
        }
 
        /**
-        * @inheritdoc
+        * @inheritDoc
         */
        protected function registerFilters() {
                parent::registerFilters();
@@ -173,6 +176,11 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                return $opts;
        }
 
+       public function validateOptions( FormOptions $opts ) {
+               $opts->validateBounds( 'days', 0, $this->maxDays );
+               parent::validateOptions( $opts );
+       }
+
        /**
         * Get all custom filters
         *
@@ -243,7 +251,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
        }
 
        /**
-        * @inheritdoc
+        * @inheritDoc
         */
        protected function buildQuery( &$tables, &$fields, &$conds, &$query_options,
                &$join_conds, FormOptions $opts
@@ -255,12 +263,12 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                // Calculate cutoff
                if ( $opts['days'] > 0 ) {
                        $conds[] = 'rc_timestamp > ' .
-                               $dbr->addQuotes( $dbr->timestamp( time() - intval( $opts['days'] * 86400 ) ) );
+                               $dbr->addQuotes( $dbr->timestamp( time() - $opts['days'] * 3600 * 24 ) );
                }
        }
 
        /**
-        * @inheritdoc
+        * @inheritDoc
         */
        protected function doMainQuery( $tables, $fields, $conds, $query_options,
                $join_conds, FormOptions $opts
@@ -270,7 +278,6 @@ class SpecialWatchlist extends ChangesListSpecialPage {
 
                # Toggle watchlist content (all recent edits or just the latest)
                if ( $opts['extended'] ) {
-                       $limitWatchlist = $user->getIntOption( 'wllimit' );
                        $usePage = false;
                } else {
                        # Top log Ids for a page are not stored
@@ -285,14 +292,16 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                                        LIST_OR
                                );
                        }
-                       $limitWatchlist = 0;
                        $usePage = true;
                }
 
                $tables = array_merge( [ 'recentchanges', 'watchlist' ], $tables );
                $fields = array_merge( RecentChange::selectFields(), $fields );
 
-               $query_options = array_merge( [ 'ORDER BY' => 'rc_timestamp DESC' ], $query_options );
+               $query_options = array_merge( [
+                       'ORDER BY' => 'rc_timestamp DESC',
+                       'LIMIT' => $user->getIntOption( 'wllimit' )
+               ], $query_options );
                $join_conds = array_merge(
                        [
                                'watchlist' => [
@@ -310,9 +319,6 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                if ( $this->getConfig()->get( 'ShowUpdatedMarker' ) ) {
                        $fields[] = 'wl_notificationtimestamp';
                }
-               if ( $limitWatchlist ) {
-                       $query_options['LIMIT'] = $limitWatchlist;
-               }
 
                $rollbacker = $user->isAllowed( 'rollback' );
                if ( $usePage || $rollbacker ) {
@@ -426,6 +432,23 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $list = ChangesList::newFromContext( $this->getContext(), $this->filterGroups );
                $list->setWatchlistDivs();
                $list->initChangesListRows( $rows );
+               if ( $user->getOption( 'watchlistunwatchlinks' ) ) {
+                       $list->setChangeLinePrefixer( function ( RecentChange $rc, ChangesList $cl, $grouped ) {
+                               // Don't show unwatch link if the line is a grouped log entry using EnhancedChangesList,
+                               // since EnhancedChangesList groups log entries by performer rather than by target article
+                               if ( $rc->mAttribs['rc_type'] == RC_LOG && $cl instanceof EnhancedChangesList &&
+                                       $grouped ) {
+                                       return '';
+                               } else {
+                                       return $this->getLinkRenderer()
+                                                       ->makeKnownLink( $rc->getTitle(),
+                                                               $this->msg( 'watchlist-unwatch' )->text(), [
+                                                                       'class' => 'mw-unwatch-link',
+                                                                       'title' => $this->msg( 'tooltip-ca-unwatch' )->text()
+                                                               ], [ 'action' => 'unwatch' ] ) . ' ';
+                               }
+                       } );
+               }
                $dbr->dataSeek( $rows, 0 );
 
                if ( $this->getConfig()->get( 'RCShowWatchingUsers' )
@@ -499,7 +522,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                if ( $opts['days'] > 0 ) {
                        $days = $opts['days'];
                } else {
-                       $days = $this->getConfig()->get( 'RCMaxAge' ) / ( 3600 * 24 );
+                       $days = $this->maxDays;
                }
                $timestamp = wfTimestampNow();
                $wlInfo = $this->msg( 'wlnote' )->numParams( $numRows, round( $days * 24 ) )->params(
@@ -591,7 +614,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                // default string representation, for example, and would confuse comparisons.
 
                // Misleadingly, the 'days' option supports hours too.
-               $days = array_map( 'strval', [ 1/24, 2/24, 6/24, 12/24, 1, 3, 7 ] );
+               $days = array_map( 'strval', [ 1 / 24, 2 / 24, 6 / 24, 12 / 24, 1, 3, 7 ] );
 
                $userWatchlistOption = (string)$this->getUser()->getOption( 'watchlistdays' );
                // add the user preference, if it isn't available already
@@ -599,7 +622,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        $days[] = $userWatchlistOption;
                }
 
-               $maxDays = (string)( $this->getConfig()->get( 'RCMaxAge' ) / ( 3600 * 24 ) );
+               $maxDays = (string)$this->maxDays;
                // add the maximum possible value, if it isn't available already
                if ( !in_array( $maxDays, $days ) ) {
                        $days[] = $maxDays;