r83812, r83814: Don't use cl_type at all when paging categorylinks
[lhc/web/wiklou.git] / includes / User.php
index 9cd33f9..c9d196d 100644 (file)
@@ -102,12 +102,15 @@ class User {
                'disableaccount',
                'edit',
                'editinterface',
-               'editusercssjs',
+               'editusercssjs', #deprecated
+               'editusercss',
+               'edituserjs',
                'hideuser',
                'import',
                'importupload',
                'ipblock-exempt',
                'markbotedits',
+               'mergehistory',
                'minoredit',
                'move',
                'movefile',
@@ -168,12 +171,22 @@ class User {
        var $mFrom;
 
        /**
-        * Lazy-initialized variables, invalidated with clearInstanceCache 
+        * Lazy-initialized variables, invalidated with clearInstanceCache
         */
-       var $mNewtalk, $mDatePreference, $mBlockedby, $mHash, $mSkin, $mRights,
-               $mBlockreason, $mBlock, $mEffectiveGroups, $mBlockedGlobally,
+       var $mNewtalk, $mDatePreference, $mBlockedby, $mHash, $mRights,
+               $mBlockreason, $mEffectiveGroups, $mBlockedGlobally,
                $mLocked, $mHideName, $mOptions;
 
+       /**
+        * @var Skin
+        */
+       var $mSkin;
+
+       /**
+        * @var Block
+        */
+       var $mBlock;
+
        static $idCacheByName = array();
 
        /**
@@ -190,6 +203,10 @@ class User {
                $this->clearInstanceCache( 'defaults' );
        }
 
+       function __toString(){
+               return $this->getName();
+       }
+
        /**
         * Load the user table data for this object from the source given by mFrom.
         */
@@ -582,10 +599,13 @@ class User {
                        return false;
                }
 
-               if( preg_match( '/[' . preg_quote( $wgInvalidUsernameCharacters, '/' ) . ']/', $name ) ) {
-                       wfDebugLog( 'username', __METHOD__ .
-                               ": '$name' invalid due to wgInvalidUsernameCharacters" );
-                       return false;
+               // Preg yells if you try to give it an empty string
+               if( $wgInvalidUsernameCharacters !== '' ) {
+                       if( preg_match( '/[' . preg_quote( $wgInvalidUsernameCharacters, '/' ) . ']/', $name ) ) {
+                               wfDebugLog( 'username', __METHOD__ .
+                                       ": '$name' invalid due to wgInvalidUsernameCharacters" );
+                               return false;
+                       }
                }
 
                return self::isUsableName( $name );
@@ -610,7 +630,7 @@ class User {
         */
        function getPasswordValidity( $password ) {
                global $wgMinimalPasswordLength, $wgContLang;
-               
+
                static $blockedLogins = array(
                        'Useruser' => 'Passpass', 'Useruser1' => 'Passpass1', # r75589
                        'Apitestsysop' => 'testpass', 'Apitestuser' => 'testpass' # r75605
@@ -673,8 +693,12 @@ class User {
                if( !wfRunHooks( 'isValidEmailAddr', array( $addr, &$result ) ) ) {
                        return $result;
                }
-               $rfc5322_atext   = "a-z0-9!#$%&'*+-\/=?^_`{|}~" ;
-               $rfc1034_ldh_str = "a-z0-9-" ;
+
+               // Please note strings below are enclosed in brackets [], this make the
+               // hyphen "-" a range indicator. Hence it is double backslashed below.
+               // See bug 26948
+               $rfc5322_atext   = "a-z0-9!#$%&'*+\\-\/=?^_`{|}~" ;
+               $rfc1034_ldh_str = "a-z0-9\\-" ;
 
                $HTML5_email_regexp = "/
                ^                      # start of string
@@ -863,32 +887,30 @@ class User {
                        }
                }
 
-               if ( $wgRequest->getCookie( 'UserID' ) !== null ) {
-                       $sId = intval( $wgRequest->getCookie( 'UserID' ) );
-                       if( isset( $_SESSION['wsUserID'] ) && $sId != $_SESSION['wsUserID'] ) {
+               $cookieId = $wgRequest->getCookie( 'UserID' );
+               $sessId = $wgRequest->getSessionData( 'wsUserID' );
+
+               if ( $cookieId !== null ) {
+                       $sId = intval( $cookieId );
+                       if( $sessId !== null && $cookieId != $sessId ) {
                                $this->loadDefaults(); // Possible collision!
-                               wfDebugLog( 'loginSessions', "Session user ID ({$_SESSION['wsUserID']}) and
+                               wfDebugLog( 'loginSessions', "Session user ID ($sessId) and
                                        cookie user ID ($sId) don't match!" );
                                return false;
                        }
-                       $_SESSION['wsUserID'] = $sId;
-               } else if ( isset( $_SESSION['wsUserID'] ) ) {
-                       if ( $_SESSION['wsUserID'] != 0 ) {
-                               $sId = $_SESSION['wsUserID'];
-                       } else {
-                               $this->loadDefaults();
-                               return false;
-                       }
+                       $wgRequest->setSessionData( 'wsUserID', $sId );
+               } else if ( $sessId !== null && $sessId != 0 ) {
+                       $sId = $sessId;
                } else {
                        $this->loadDefaults();
                        return false;
                }
 
-               if ( isset( $_SESSION['wsUserName'] ) ) {
-                       $sName = $_SESSION['wsUserName'];
-               } else if ( $wgRequest->getCookie('UserName') !== null ) {
-                       $sName = $wgRequest->getCookie('UserName');
-                       $_SESSION['wsUserName'] = $sName;
+               if ( $wgRequest->getSessionData( 'wsUserName' ) !== null ) {
+                       $sName = $wgRequest->getSessionData( 'wsUserName' );
+               } else if ( $wgRequest->getCookie( 'UserName' ) !== null ) {
+                       $sName = $wgRequest->getCookie( 'UserName' );
+                       $wgRequest->setSessionData( 'wsUserName', $sName );
                } else {
                        $this->loadDefaults();
                        return false;
@@ -907,8 +929,8 @@ class User {
                        return false;
                }
 
-               if ( isset( $_SESSION['wsToken'] ) ) {
-                       $passwordCorrect = $_SESSION['wsToken'] == $this->mToken;
+               if ( $wgRequest->getSessionData( 'wsToken' ) !== null ) {
+                       $passwordCorrect = $this->mToken == $wgRequest->getSessionData( 'wsToken' );
                        $from = 'session';
                } else if ( $wgRequest->getCookie( 'Token' ) !== null ) {
                        $passwordCorrect = $this->mToken == $wgRequest->getCookie( 'Token' );
@@ -920,7 +942,7 @@ class User {
                }
 
                if ( ( $sName == $this->mName ) && $passwordCorrect ) {
-                       $_SESSION['wsToken'] = $this->mToken;
+                       $wgRequest->setSessionData( 'wsToken', $this->mToken );
                        wfDebug( "User: logged in from $from\n" );
                        return true;
                } else {
@@ -1108,7 +1130,10 @@ class User {
                $this->mAllowUsertalk = 0;
 
                # Check if we are looking at an IP or a logged-in user
-               if ( $this->isIP( $this->getName() ) ) {
+               if ( $this->isAllowed( 'ipblock-exempt' ) ) {
+                       # Exempt from all types of IP-block
+                       $ip = '';
+               } elseif ( $this->isIP( $this->getName() ) ) {
                        $ip = $this->getName();
                } else {
                        # Check if we are looking at the current user
@@ -1122,11 +1147,6 @@ class User {
                        }
                }
 
-               if ( $this->isAllowed( 'ipblock-exempt' ) ) {
-                       # Exempt from all types of IP-block
-                       $ip = '';
-               }
-
                # User/IP blocking
                $this->mBlock = new Block();
                $this->mBlock->fromMaster( !$bFromSlave );
@@ -2030,7 +2050,7 @@ class User {
         * Reset all options to the site defaults
         */
        function resetOptions() {
-               $this->mOptions = User::getDefaultOptions();
+               $this->mOptions = self::getDefaultOptions();
        }
 
        /**
@@ -2240,21 +2260,16 @@ class User {
         * @todo: FIXME : need to check the old failback system [AV]
         */
        function getSkin( $t = null ) {
-               if ( $t ) {
+               if( !$this->mSkin ) {
+                       global $wgOut;
+                       $this->mSkin = $this->createSkinObject();
+                       $this->mSkin->setTitle( $wgOut->getTitle() );
+               }
+               if ( $t && ( !$this->mSkin->getTitle() || !$t->equals( $this->mSkin->getTitle() ) ) ) {
                        $skin = $this->createSkinObject();
                        $skin->setTitle( $t );
                        return $skin;
                } else {
-                       if ( !$this->mSkin ) {
-                               $this->mSkin = $this->createSkinObject();
-                       }
-
-                       if ( !$this->mSkin->getTitle() ) {
-                               global $wgOut;
-                               $t = $wgOut->getTitle();
-                               $this->mSkin->setTitle($t);
-                       }
-
                        return $this->mSkin;
                }
        }
@@ -2446,8 +2461,16 @@ class User {
 
        /**
         * Set the default cookies for this session on the user's client.
+        *
+        * @param $request WebRequest object to use; $wgRequest will be used if null
+        *        is passed.
         */
-       function setCookies() {
+       function setCookies( $request = null ) {
+               if ( $request === null ) {
+                       global $wgRequest;
+                       $request = $wgRequest;
+               }
+
                $this->load();
                if ( 0 == $this->mId ) return;
                $session = array(
@@ -2466,9 +2489,9 @@ class User {
                }
 
                wfRunHooks( 'UserSetCookies', array( $this, &$session, &$cookies ) );
-               #check for null, since the hook could cause a null value
-               if ( !is_null( $session ) && isset( $_SESSION ) ){
-                       $_SESSION = $session + $_SESSION;
+
+               foreach ( $session as $name => $value ) {
+                       $request->setSessionData( $name, $value );
                }
                foreach ( $cookies as $name => $value ) {
                        if ( $value === false ) {
@@ -2494,9 +2517,11 @@ class User {
         * @see logout()
         */
        function doLogout() {
+               global $wgRequest;
+
                $this->clearInstanceCache( 'defaults' );
 
-               $_SESSION['wsUserID'] = 0;
+               $wgRequest->setSessionData( 'wsUserID', 0 );
 
                $this->clearCookie( 'UserID' );
                $this->clearCookie( 'Token' );
@@ -2672,7 +2697,7 @@ class User {
         * which will give them a chance to modify this key based on their own
         * settings.
         *
-        * @deprecated @since 1.17 use the ParserOptions object to get the relevant options
+        * @deprecated since 1.17 use the ParserOptions object to get the relevant options
         * @return String Page rendering hash
         */
        function getPageRenderingHash() {
@@ -2789,7 +2814,7 @@ class User {
         * @return Boolean: True if the given password is correct, otherwise False.
         */
        function checkPassword( $password ) {
-               global $wgAuth;
+               global $wgAuth, $wgLegacyEncoding;
                $this->load();
 
                // Even though we stop people from creating passwords that
@@ -2812,11 +2837,13 @@ class User {
                }
                if ( self::comparePasswords( $this->mPassword, $password, $this->mId ) ) {
                        return true;
-               } elseif ( function_exists( 'iconv' ) ) {
+               } elseif ( $wgLegacyEncoding ) {
                        # Some wikis were converted from ISO 8859-1 to UTF-8, the passwords can't be converted
                        # Check for this with iconv
                        $cp1252Password = iconv( 'UTF-8', 'WINDOWS-1252//TRANSLIT', $password );
-                       if ( self::comparePasswords( $this->mPassword, $cp1252Password, $this->mId ) ) {
+                       if ( $cp1252Password != $password &&
+                               self::comparePasswords( $this->mPassword, $cp1252Password, $this->mId ) )
+                       {
                                return true;
                        }
                }
@@ -2848,17 +2875,22 @@ class User {
         * submission.
         *
         * @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
         */
-       function editToken( $salt = '' ) {
+       function editToken( $salt = '', $request = null ) {
+               if ( $request == null ) {
+                       global $wgRequest;
+                       $request = $wgRequest;
+               }
+
                if ( $this->isAnon() ) {
                        return EDIT_TOKEN_SUFFIX;
                } else {
-                       if( !isset( $_SESSION['wsEditToken'] ) ) {
+                       $token = $request->getSessionData( 'wsEditToken' );
+                       if ( $token === null ) {
                                $token = self::generateToken();
-                               $_SESSION['wsEditToken'] = $token;
-                       } else {
-                               $token = $_SESSION['wsEditToken'];
+                               $request->setSessionData( 'wsEditToken', $token );
                        }
                        if( is_array( $salt ) ) {
                                $salt = implode( '|', $salt );
@@ -2886,10 +2918,11 @@ class User {
         *
         * @param $val String Input value to compare
         * @param $salt String Optional function-specific data for hashing
+        * @param $request WebRequest object to use or null to use $wgRequest
         * @return Boolean: Whether the token matches
         */
-       function matchEditToken( $val, $salt = '' ) {
-               $sessionToken = $this->editToken( $salt );
+       function matchEditToken( $val, $salt = '', $request = null ) {
+               $sessionToken = $this->editToken( $salt, $request );
                if ( $val != $sessionToken ) {
                        wfDebug( "User::matchEditToken: broken session data\n" );
                }
@@ -2902,10 +2935,11 @@ class User {
         *
         * @param $val String Input value to compare
         * @param $salt String Optional function-specific data for hashing
+        * @param $request WebRequest object to use or null to use $wgRequest
         * @return Boolean: Whether the token matches
         */
-       function matchEditTokenNoSuffix( $val, $salt = '' ) {
-               $sessionToken = $this->editToken( $salt );
+       function matchEditTokenNoSuffix( $val, $salt = '', $request = null ) {
+               $sessionToken = $this->editToken( $salt, $request );
                return substr( $sessionToken, 0, 32 ) == substr( $val, 0, 32 );
        }
 
@@ -2913,10 +2947,10 @@ class User {
         * Generate a new e-mail confirmation token and send a confirmation/invalidation
         * mail to the user's given address.
         *
-        * @param $changed Boolean: whether the adress changed
+        * @param $type String: message to send, either "created", "changed" or "set"
         * @return Status object
         */
-       function sendConfirmationMail( $changed = false ) {
+       function sendConfirmationMail( $type = 'created' ) {
                global $wgLang;
                $expiration = null; // gets passed-by-ref and defined in next line.
                $token = $this->confirmationToken( $expiration );
@@ -2924,7 +2958,14 @@ class User {
                $invalidateURL = $this->invalidationTokenUrl( $token );
                $this->saveSettings();
 
-               $message = $changed ? 'confirmemail_body_changed' : 'confirmemail_body';
+               if ( $type == 'created' || $type === false ) {
+                       $message = 'confirmemail_body';
+               } elseif ( $type === true ) {
+                       $message = 'confirmemail_body_changed';
+               } else {
+                       $message = 'confirmemail_body_' . $type;
+               }
+
                return $this->sendMail( wfMsg( 'confirmemail_subject' ),
                        wfMsg( $message,
                                wfGetIP(),
@@ -2970,8 +3011,9 @@ class User {
         * @private
         */
        function confirmationToken( &$expiration ) {
+               global $wgUserEmailConfirmationTokenExpiry;
                $now = time();
-               $expires = $now + 7 * 24 * 60 * 60;
+               $expires = $now + $wgUserEmailConfirmationTokenExpiry;
                $expiration = wfTimestamp( TS_MW, $expires );
                $token = self::generateToken( $this->mId . $this->mEmail . $expires );
                $hash = md5( $token );
@@ -3486,7 +3528,7 @@ class User {
        static function getRightDescription( $right ) {
                $key = "right-$right";
                $name = wfMsg( $key );
-               return $name == '' || wfEmptyMsg( $key, $name )
+               return $name == '' || wfEmptyMsg( $key )
                        ? $right
                        : $name;
        }
@@ -3752,92 +3794,4 @@ class User {
 
                return $ret;
        }
-
-       /**
-        * Format the user message using a hook, a template, or, failing these, a static format.
-        * @param $subject   String the subject of the message
-        * @param $text      String the content of the message
-        * @param $signature String the signature, if provided.
-        */
-       static protected function formatUserMessage( $subject, $text, $signature ) {
-               if ( wfRunHooks( 'FormatUserMessage',
-                               array( $subject, &$text, $signature ) ) ) {
-
-                       $signature = empty($signature) ? "~~~~~" : "{$signature} ~~~~~";
-
-                       $template = Title::newFromText( wfMsgForContent( 'usermessage-template' ) );
-                       if ( !$template
-                                       || $template->getNamespace() !== NS_TEMPLATE
-                                       || !$template->exists() ) {
-                               $text = "\n== $subject ==\n\n$text\n\n-- $signature";
-                       } else {
-                               $text = '{{'. $template->getText()
-                                       . " | subject=$subject | body=$text | signature=$signature }}";
-                       }
-               }
-
-               return $text;
-       }
-
-       /**
-        * Leave a user a message
-        * @param $subject String the subject of the message
-        * @param $text String the message to leave
-        * @param $signature String Text to leave in the signature
-        * @param $summary String the summary for this change, defaults to
-        *                        "Leave system message."
-        * @param $editor User The user leaving the message, defaults to
-        *                        "{{MediaWiki:usermessage-editor}}"
-        * @param $flags Int default edit flags
-        *
-        * @return boolean true if it was successful
-        */
-       public function leaveUserMessage( $subject, $text, $signature = "",
-                       $summary = null, $editor = null, $flags = 0 ) {
-               if ( !isset( $summary ) ) {
-                       $summary = wfMsgForContent( 'usermessage-summary' );
-               }
-
-               if ( !isset( $editor ) ) {
-                       $editor = User::newFromName( wfMsgForContent( 'usermessage-editor' ) );
-                       if ( !$editor->isLoggedIn() ) {
-                               $editor->addToDatabase();
-                       }
-               }
-
-               $article = new Article( $this->getTalkPage() );
-               wfRunHooks( 'SetupUserMessageArticle',
-                       array( $this, &$article, $subject, $text, $signature, $summary, $editor ) );
-
-
-               $text = self::formatUserMessage( $subject, $text, $signature );
-               $flags = $article->checkFlags( $flags );
-
-               if ( $flags & EDIT_UPDATE ) {
-                       $text = $article->getContent() . $text;
-               }
-
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->begin();
-
-               try {
-                       $status = $article->doEdit( $text, $summary, $flags, false, $editor );
-               } catch ( DBQueryError $e ) {
-                       $status = Status::newFatal("DB Error");
-               }
-
-               if ( $status->isGood() ) {
-                       // Set newtalk with the right user ID
-                       $this->setNewtalk( true );
-                       wfRunHooks( 'AfterUserMessage',
-                               array( $this, $article, $summary, $text, $signature, $summary, $editor ) );
-                       $dbw->commit();
-               } else {
-                       // The article was concurrently created
-                       wfDebug( __METHOD__ . ": Error ".$status->getWikiText() );
-                       $dbw->rollback();
-               }
-
-               return $status->isGood();
-       }
 }