Merge "RCFilters: Add 'advanced filters' label to the view selection"
[lhc/web/wiklou.git] / includes / specials / SpecialRecentchanges.php
index a05900b..157c3ed 100644 (file)
@@ -181,10 +181,6 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                                $this->getConfig()->get( 'StructuredChangeFiltersEnableExperimentalViews' );
 
                        $out->addJsConfigVars( 'wgStructuredChangeFilters', $jsData['groups'] );
-                       $out->addJsConfigVars(
-                               'wgStructuredChangeFiltersEnableSaving',
-                               $this->getConfig()->get( 'StructuredChangeFiltersEnableSaving' )
-                       );
                        $out->addJsConfigVars(
                                'wgStructuredChangeFiltersEnableExperimentalViews',
                                $experimentalStructuredChangeFilters
@@ -193,12 +189,10 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                                'wgStructuredChangeFiltersEnableLiveUpdate',
                                $this->getConfig()->get( 'StructuredChangeFiltersEnableLiveUpdate' )
                        );
-                       if ( $experimentalStructuredChangeFilters ) {
-                               $out->addJsConfigVars(
-                                       'wgRCFiltersChangeTags',
-                                       $this->buildChangeTagList()
-                               );
-                       }
+                       $out->addJsConfigVars(
+                               'wgRCFiltersChangeTags',
+                               $this->buildChangeTagList()
+                       );
                }
        }
 
@@ -373,6 +367,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
 
        public function validateOptions( FormOptions $opts ) {
                $opts->validateIntBounds( 'limit', 0, 5000 );
+               $opts->validateBounds( 'days', 0, $this->getConfig()->get( 'RCMaxAge' ) / ( 3600 * 24 ) );
                parent::validateOptions( $opts );
        }
 
@@ -387,7 +382,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                        $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'] );
@@ -429,13 +424,14 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                $fields[] = 'page_latest';
                $join_conds['page'] = [ 'LEFT JOIN', 'rc_cur_id=page_id' ];
 
+               $tagFilter = $opts['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,
@@ -448,13 +444,24 @@ class SpecialRecentChanges 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); 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,
@@ -705,17 +712,35 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
 
                $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->getUser()->getOption( 'rcenhancedfilters' ) ) {
+                               $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 )
                        );
                }
        }
@@ -942,15 +967,20 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                        $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' ],