LogPager: Use normalized value for log_user_text in query condition
[lhc/web/wiklou.git] / includes / logging / LogPager.php
index 3583599..eeea789 100644 (file)
@@ -28,7 +28,7 @@
  */
 class LogPager extends ReverseChronologicalPager {
        /** @var array Log types */
-       private $types = array();
+       private $types = [];
 
        /** @var string Events limited to those by performer when set */
        private $performer = '';
@@ -42,6 +42,9 @@ class LogPager extends ReverseChronologicalPager {
        /** @var string */
        private $typeCGI = '';
 
+       /** @var string */
+       private $action = '';
+
        /** @var LogEventsList */
        public $mLogEventsList;
 
@@ -57,9 +60,12 @@ class LogPager extends ReverseChronologicalPager {
         * @param int|bool $year The year to start from. Default: false
         * @param int|bool $month The month to start from. Default: false
         * @param string $tagFilter Tag
+        * @param string $action Specific action (subtype) requested
         */
-       public function __construct( $list, $types = array(), $performer = '', $title = '', $pattern = '',
-               $conds = array(), $year = false, $month = false, $tagFilter = '' ) {
+       public function __construct( $list, $types = [], $performer = '', $title = '',
+               $pattern = '', $conds = [], $year = false, $month = false, $tagFilter = '',
+               $action = ''
+       ) {
                parent::__construct( $list->getContext() );
                $this->mConds = $conds;
 
@@ -68,6 +74,7 @@ class LogPager extends ReverseChronologicalPager {
                $this->limitType( $types ); // also excludes hidden types
                $this->limitPerformer( $performer );
                $this->limitTitle( $title, $pattern );
+               $this->limitAction( $action );
                $this->getDateCond( $year, $month );
                $this->mTagFilter = $tagFilter;
 
@@ -87,7 +94,7 @@ class LogPager extends ReverseChronologicalPager {
        // Call ONLY after calling $this->limitType() already!
        public function getFilterParams() {
                global $wgFilterLogTypes;
-               $filters = array();
+               $filters = [];
                if ( count( $this->types ) ) {
                        return $filters;
                }
@@ -117,7 +124,7 @@ class LogPager extends ReverseChronologicalPager {
 
                $user = $this->getUser();
                // If $types is not an array, make it an array
-               $types = ( $types === '' ) ? array() : (array)$types;
+               $types = ( $types === '' ) ? [] : (array)$types;
                // Don't even show header for private logs; don't recognize it...
                $needReindex = false;
                foreach ( $types as $type ) {
@@ -125,7 +132,7 @@ class LogPager extends ReverseChronologicalPager {
                                && !$user->isAllowed( $wgLogRestrictions[$type] )
                        ) {
                                $needReindex = true;
-                               $types = array_diff( $types, array( $type ) );
+                               $types = array_diff( $types, [ $type ] );
                        }
                }
                if ( $needReindex ) {
@@ -164,6 +171,9 @@ class LogPager extends ReverseChronologicalPager {
                if ( is_null( $usertitle ) ) {
                        return;
                }
+               // Normalize username first so that non-existent users used
+               // in maintenance scripts work
+               $name = $usertitle->getText();
                /* Fetch userid at first, if known, provides awesome query plan afterwards */
                $userid = User::idFromName( $name );
                if ( !$userid ) {
@@ -180,7 +190,7 @@ class LogPager extends ReverseChronologicalPager {
                                ' != ' . LogPage::SUPPRESSED_USER;
                }
 
-               $this->performer = $usertitle->getText();
+               $this->performer = $name;
        }
 
        /**
@@ -208,8 +218,8 @@ class LogPager extends ReverseChronologicalPager {
                $db = $this->mDb;
 
                $doUserRightsLogLike = false;
-               if ( $this->types == array( 'rights' ) ) {
-                       $parts = explode( $wgUserrightsInterwikiDelimiter, $title->getDBKey() );
+               if ( $this->types == [ 'rights' ] ) {
+                       $parts = explode( $wgUserrightsInterwikiDelimiter, $title->getDBkey() );
                        if ( count( $parts ) == 2 ) {
                                list( $name, $database ) = array_map( 'trim', $parts );
                                if ( strstr( $database, '*' ) ) { // Search for wildcard in database name
@@ -233,7 +243,7 @@ class LogPager extends ReverseChronologicalPager {
                 */
                $this->mConds['log_namespace'] = $ns;
                if ( $doUserRightsLogLike ) {
-                       $params = array( $name . $wgUserrightsInterwikiDelimiter );
+                       $params = [ $name . $wgUserrightsInterwikiDelimiter ];
                        foreach ( explode( '*', $database ) as $databasepart ) {
                                $params[] = $databasepart;
                                $params[] = $db->anyString();
@@ -256,6 +266,31 @@ class LogPager extends ReverseChronologicalPager {
                }
        }
 
+       /**
+        * Set the log_action field to a specified value (or values)
+        *
+        * @param string $action
+        */
+       private function limitAction( $action ) {
+               global $wgActionFilteredLogs;
+               // Allow to filter the log by actions
+               $type = $this->typeCGI;
+               if ( $type === '' ) {
+                       // nothing to do
+                       return;
+               }
+               $actions = $wgActionFilteredLogs;
+               if ( isset( $actions[$type] ) ) {
+                       // log type can be filtered by actions
+                       $this->mLogEventsList->setAllowedActions( array_keys( $actions[$type] ) );
+                       if ( $action !== '' && isset( $actions[$type][$action] ) ) {
+                               // add condition to query
+                               $this->mConds['log_action'] = $actions[$type][$action];
+                               $this->action = $action;
+                       }
+               }
+       }
+
        /**
         * Constructs the most part of the query. Extra conditions are sprinkled in
         * all over this class.
@@ -270,7 +305,7 @@ class LogPager extends ReverseChronologicalPager {
                $options = $basic['options'];
                $joins = $basic['join_conds'];
 
-               $index = array();
+               $index = [];
                # Add log_search table if there are conditions on it.
                # This filters the results to only include log rows that have
                # log_search records with the specified ls_field and ls_value values.
@@ -291,15 +326,15 @@ class LogPager extends ReverseChronologicalPager {
                        $options['USE INDEX'] = $index;
                }
                # Don't show duplicate rows when using log_search
-               $joins['log_search'] = array( 'INNER JOIN', 'ls_log_id=log_id' );
+               $joins['log_search'] = [ 'INNER JOIN', 'ls_log_id=log_id' ];
 
-               $info = array(
+               $info = [
                        'tables' => $tables,
                        'fields' => $fields,
                        'conds' => array_merge( $conds, $this->mConds ),
                        'options' => $options,
                        'join_conds' => $joins,
-               );
+               ];
                # Add ChangeTags filter query
                ChangeTags::modifyDisplayQuery( $info['tables'], $info['fields'], $info['conds'],
                        $info['join_conds'], $info['options'], $this->mTagFilter );
@@ -352,6 +387,8 @@ class LogPager extends ReverseChronologicalPager {
        }
 
        /**
+        * Guaranteed to either return a valid title string or a Zero-Length String
+        *
         * @return string
         */
        public function getPerformer() {
@@ -381,6 +418,10 @@ class LogPager extends ReverseChronologicalPager {
                return $this->mTagFilter;
        }
 
+       public function getAction() {
+               return $this->action;
+       }
+
        public function doQuery() {
                // Workaround MySQL optimizer bug
                $this->mDb->setBigSelects();