Use local context to get messages
[lhc/web/wiklou.git] / includes / User.php
index 9404414..229868f 100644 (file)
@@ -143,7 +143,6 @@ class User {
                'reupload',
                'reupload-shared',
                'rollback',
-               'selenium',
                'sendemail',
                'siteadmin',
                'suppressionlog',
@@ -200,7 +199,7 @@ class User {
         */
        var $mNewtalk, $mDatePreference, $mBlockedby, $mHash, $mRights,
                $mBlockreason, $mEffectiveGroups, $mImplicitGroups, $mFormerGroups, $mBlockedGlobally,
-               $mLocked, $mHideName, $mOptions;
+               $mLocked, $mHideName, $mOptions, $mDisplayName;
 
        /**
         * @var WebRequest
@@ -448,9 +447,9 @@ class User {
        /**
         * Get the username corresponding to a given user ID
         * @param $id Int User ID
-        * @return String The corresponding username
+        * @return String|false The corresponding username
         */
-       static function whoIs( $id ) {
+       public static function whoIs( $id ) {
                $dbr = wfGetDB( DB_SLAVE );
                return $dbr->selectField( 'user', 'user_name', array( 'user_id' => $id ), __METHOD__ );
        }
@@ -459,7 +458,7 @@ class User {
         * Get the real name of a user given their user ID
         *
         * @param $id Int User ID
-        * @return String The corresponding user's real name
+        * @return String|false The corresponding user's real name
         */
        public static function whoIsReal( $id ) {
                $dbr = wfGetDB( DB_SLAVE );
@@ -1053,6 +1052,8 @@ class User {
        public function loadFromRow( $row ) {
                $all = true;
 
+               $this->mGroups = null; // deferred
+
                if ( isset( $row->user_name ) ) {
                        $this->mName = $row->user_name;
                        $this->mFrom = 'name';
@@ -1076,19 +1077,26 @@ class User {
                        $all = false;
                }
 
+               if ( isset( $row->user_editcount ) ) {
+                       $this->mEditCount = $row->user_editcount;
+               } else {
+                       $all = false;
+               }
+
                if ( isset( $row->user_password ) ) {
                        $this->mPassword = $row->user_password;
                        $this->mNewpassword = $row->user_newpassword;
                        $this->mNewpassTime = wfTimestampOrNull( TS_MW, $row->user_newpass_time );
                        $this->mEmail = $row->user_email;
-                       $this->decodeOptions( $row->user_options );
-                       $this->mTouched = wfTimestamp(TS_MW,$row->user_touched);
+                       if ( isset( $row->user_options ) ) {
+                               $this->decodeOptions( $row->user_options );
+                       }
+                       $this->mTouched = wfTimestamp( TS_MW, $row->user_touched );
                        $this->mToken = $row->user_token;
                        $this->mEmailAuthenticated = wfTimestampOrNull( TS_MW, $row->user_email_authenticated );
                        $this->mEmailToken = $row->user_email_token;
                        $this->mEmailTokenExpires = wfTimestampOrNull( TS_MW, $row->user_email_token_expires );
                        $this->mRegistration = wfTimestampOrNull( TS_MW, $row->user_registration );
-                       $this->mEditCount = $row->user_editcount;
                } else {
                        $all = false;
                }
@@ -1183,6 +1191,7 @@ class User {
                $this->mEffectiveGroups = null;
                $this->mImplicitGroups = null;
                $this->mOptions = null;
+               $this->mDisplayName = null;
 
                if ( $reloadFrom ) {
                        $this->mLoadedItems = array();
@@ -1209,6 +1218,14 @@ class User {
                }
                $defOpt['skin'] = $wgDefaultSkin;
 
+               // FIXME: Ideally we'd cache the results of this function so the hook is only run once,
+               // but that breaks the parser tests because they rely on being able to change $wgContLang
+               // mid-request and see that change reflected in the return value of this function.
+               // Which is insane and would never happen during normal MW operation, but is also not
+               // likely to get fixed unless and until we context-ify everything.
+               // See also https://www.mediawiki.org/wiki/Special:Code/MediaWiki/101488#c25275
+               wfRunHooks( 'UserGetDefaultOptions', array( &$defOpt ) );
+
                return $defOpt;
        }
 
@@ -1273,9 +1290,6 @@ class User {
                        $this->mBlockreason = $this->mBlock->mReason;
                        $this->mHideName = $this->mBlock->mHideName;
                        $this->mAllowUsertalk = !$this->mBlock->prevents( 'editownusertalk' );
-                       if ( $this->isLoggedIn() && $wgUser->getID() == $this->getID() ) {
-                               $this->spreadBlock();
-                       }
                }
 
                # Proxy blocking
@@ -2122,6 +2136,32 @@ class User {
                $this->mRealName = $str;
        }
 
+       /**
+        * Return the name of this user we should used to display in the user interface
+        * @return String The user's display name
+        */
+       public function getDisplayName() {
+               global $wgRealNameInInterface;
+               if ( is_null( $this->mDisplayName ) ) {
+                       $displayName = null;
+                       
+                       // Allow hooks to set a display name
+                       wfRunHooks( 'UserDisplayName', array( $this, &$displayName ) );
+
+                       if ( is_null( $displayName ) && $wgRealNameInInterface && $this->getRealName() ) {
+                               // If $wgRealNameInInterface is true use the real name as the display name if it's set
+                               $displayName = $this->getRealName();
+                       }
+                       
+                       if ( is_null( $displayName ) ) {
+                               $displayName = $this->getName();
+                       }
+
+                       $this->mDisplayName = $displayName;
+               }
+               return $this->mDisplayName;
+       }
+
        /**
         * Get the user's current setting for a given option.
         *
@@ -2305,6 +2345,7 @@ class User {
         */
        public function getGroups() {
                $this->load();
+               $this->loadGroups();
                return $this->mGroups;
        }
 
@@ -2596,6 +2637,14 @@ class User {
                $this->invalidateCache();
        }
 
+       /**
+        * Cleans up watchlist by removing invalid entries from it
+        */
+       public function cleanupWatchlist() {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'watchlist', array( 'wl_namespace < 0', 'wl_user' => $this->getId() ), __METHOD__ );
+       }
+
        /**
         * Clear the user's notification timestamp for the given title.
         * If e-notif e-mails are on, they will receive notification mails on
@@ -2683,8 +2732,10 @@ class User {
        /**
         * Set this user's options from an encoded string
         * @param $str String Encoded options to import
+        *
+        * @deprecated in 1.19 due to removal of user_options from the user table
         */
-       public function decodeOptions( $str ) {
+       private function decodeOptions( $str ) {
                if( !$str )
                        return;
 
@@ -2812,7 +2863,6 @@ class User {
                                'user_real_name' => $this->mRealName,
                                'user_email' => $this->mEmail,
                                'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
-                               'user_options' => '',
                                'user_touched' => $dbw->timestamp( $this->mTouched ),
                                'user_token' => $this->mToken,
                                'user_email_token' => $this->mEmailToken,
@@ -2880,7 +2930,6 @@ class User {
                        'user_email' => $user->mEmail,
                        'user_email_authenticated' => $dbw->timestampOrNull( $user->mEmailAuthenticated ),
                        'user_real_name' => $user->mRealName,
-                       'user_options' => '',
                        'user_token' => $user->mToken,
                        'user_registration' => $dbw->timestamp( $user->mRegistration ),
                        'user_editcount' => 0,
@@ -2914,7 +2963,6 @@ class User {
                                'user_email' => $this->mEmail,
                                'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
                                'user_real_name' => $this->mRealName,
-                               'user_options' => '',
                                'user_token' => $this->mToken,
                                'user_registration' => $dbw->timestamp( $this->mRegistration ),
                                'user_editcount' => 0,
@@ -2929,22 +2977,35 @@ class User {
        }
 
        /**
-        * If this (non-anonymous) user is blocked, block any IP address
-        * they've successfully logged in from.
+        * If this user is logged-in and blocked,
+        * block any IP address they've successfully logged in from.
+        * @return bool A block was spread
+        */
+       public function spreadAnyEditBlock() {
+               if ( $this->isLoggedIn() && $this->isBlocked() ) {
+                       return $this->spreadBlock();
+               }
+               return false;
+       }
+
+       /**
+        * If this (non-anonymous) user is blocked,
+        * block the IP address they've successfully logged in from.
+        * @return bool A block was spread
         */
-       public function spreadBlock() {
+       protected function spreadBlock() {
                wfDebug( __METHOD__ . "()\n" );
                $this->load();
                if ( $this->mId == 0 ) {
-                       return;
+                       return false;
                }
 
                $userblock = Block::newFromTarget( $this->getName() );
                if ( !$userblock ) {
-                       return;
+                       return false;
                }
 
-               $userblock->doAutoblock( $this->getRequest()->getIP() );
+               return (bool)$userblock->doAutoblock( $this->getRequest()->getIP() );
        }
 
        /**
@@ -3130,17 +3191,31 @@ class User {
                }
        }
 
+       /**
+        * Alias for getEditToken.
+        * @deprecated since 1.19, use getEditToken instead. 
+        * 
+        * @param $salt String|Array of Strings Optional function-specific data for hashing
+        * @param $request WebRequest object to use or null to use $wgRequest
+        * @return String The new edit token
+        */
+       public function editToken( $salt = '', $request = null ) {
+               return $this->getEditToken( $salt, $request );
+       }
+       
        /**
         * Initialize (if necessary) and return a session token value
         * which can be used in edit forms to show that the user's
         * login credentials aren't being hijacked with a foreign form
         * submission.
         *
+        * @since 1.19
+        *
         * @param $salt String|Array of Strings Optional function-specific data for hashing
         * @param $request WebRequest object to use or null to use $wgRequest
         * @return String The new edit token
         */
-       public function editToken( $salt = '', $request = null ) {
+       public function getEditToken( $salt = '', $request = null ) {
                if ( $request == null ) {
                        $request = $this->getRequest();
                }
@@ -3183,7 +3258,7 @@ class User {
         * @return Boolean: Whether the token matches
         */
        public function matchEditToken( $val, $salt = '', $request = null ) {
-               $sessionToken = $this->editToken( $salt, $request );
+               $sessionToken = $this->getEditToken( $salt, $request );
                if ( $val != $sessionToken ) {
                        wfDebug( "User::matchEditToken: broken session data\n" );
                }
@@ -3200,7 +3275,7 @@ class User {
         * @return Boolean: Whether the token matches
         */
        public function matchEditTokenNoSuffix( $val, $salt = '', $request = null ) {
-               $sessionToken = $this->editToken( $salt, $request );
+               $sessionToken = $this->getEditToken( $salt, $request );
                return substr( $sessionToken, 0, 32 ) == substr( $val, 0, 32 );
        }
 
@@ -3470,7 +3545,7 @@ class User {
         *
         * @return Array of Strings List of permission key names for given groups combined
         */
-       public static function getGroupPermissions( $groups, $ns = null ) {
+       public static function getGroupPermissions( array $groups, $ns = null ) {
                global $wgGroupPermissions, $wgRevokePermissions;
                $rights = array();
 
@@ -3551,10 +3626,11 @@ class User {
         * Get the localized descriptive name for a member of a group, if it exists
         *
         * @param $group String Internal group name
+        * @param $username String Username for gender (since 1.19)
         * @return String Localized name for group member
         */
-       public static function getGroupMember( $group ) {
-               $msg = wfMessage( "group-$group-member" );
+       public static function getGroupMember( $group, $username = '#' ) {
+               $msg = wfMessage( "group-$group-member", $username );
                return $msg->isBlank() ? $group : $msg->text();
        }
 
@@ -3902,7 +3978,7 @@ class User {
         * @param $byEmail Boolean: account made by email?
         * @param $reason String: user supplied reason
         *
-        * @return true
+        * @return int|bool True if not $wgNewUserLog; otherwise ID of log item or 0 on failure
         */
        public function addNewUserLogEntry( $byEmail = false, $reason = '' ) {
                global $wgUser, $wgContLang, $wgNewUserLog;
@@ -3924,13 +4000,12 @@ class User {
                        }
                }
                $log = new LogPage( 'newusers' );
-               $log->addEntry(
+               return (int)$log->addEntry(
                        $action,
                        $this->getUserPage(),
                        $reason,
                        array( $this->getId() )
                );
-               return true;
        }
 
        /**
@@ -4032,10 +4107,8 @@ class User {
                        }
                }
 
-               $dbw->begin();
                $dbw->delete( 'user_properties', array( 'up_user' => $this->getId() ), __METHOD__ );
                $dbw->insert( 'user_properties', $insert_rows, __METHOD__ );
-               $dbw->commit();
        }
 
        /**