Don't force edit encoding when LanguageEo.php is loaded; defer until $wgContLang...
[lhc/web/wiklou.git] / includes / User.php
index c1cfa84..e5aa81f 100644 (file)
@@ -153,7 +153,7 @@ class User {
                $fname = 'User::loadDefaults' . $n;
                wfProfileIn( $fname );
                
-               global $wgContLang, $wgIP;
+               global $wgContLang, $wgIP, $wgDBname;
                global $wgNamespacesToBeSearchedDefault;
 
                $this->mId = 0;
@@ -175,9 +175,16 @@ class User {
                unset( $this->mSkin );
                $this->mDataLoaded = false;
                $this->mBlockedby = -1; # Unset
-               $this->mTouched = '0'; # Allow any pages to be cached
                $this->setToken(); # Random
                $this->mHash = false;
+
+               if ( isset( $_COOKIE[$wgDBname.'LoggedOut'] ) ) {
+                       $this->mTouched = wfTimestamp( TS_MW, $_COOKIE[$wgDBname.'LoggedOut'] );
+               }
+               else {
+                       $this->mTouched = '0'; # Allow any pages to be cached
+               }
+
                wfProfileOut( $fname );
        }
 
@@ -235,8 +242,16 @@ class User {
        /**
         * Get blocking information
         * @access private
+        * @param bool $bFromSlave Specify whether to check slave or master. To improve performance,
+        *  non-critical checks are done against slaves. Check when actually saving should be done against
+        *  master.
+        *
+        * Note that even if $bFromSlave is false, the check is done first against slave, then master.
+        * The logic is that if blocked on slave, we'll assume it's either blocked on master or
+        * just slightly outta sync and soon corrected - safer to block slightly more that less.
+        * And it's cheaper to check slave first, then master if needed, than master always.
         */
-       function getBlockedStatus() {
+       function getBlockedStatus( $bFromSlave = false ) {
                global $wgIP, $wgBlockCache, $wgProxyList;
 
                if ( -1 != $this->mBlockedby ) { return; }
@@ -246,7 +261,8 @@ class User {
                # User blocking
                if ( $this->mId ) {
                        $block = new Block();
-                       if ( $block->load( $wgIP , $this->mId ) ) {
+                       $block->forUpdate( $bFromSlave );
+                       if ( $block->load( $wgIP , $this->mId ) ) {
                                $this->mBlockedby = $block->mBy;
                                $this->mBlockreason = $block->mReason;
                        }
@@ -254,7 +270,14 @@ class User {
 
                # IP/range blocking
                if ( !$this->mBlockedby ) {
-                       $block = $wgBlockCache->get( $wgIP );
+                       # Check first against slave, and optionally from master.
+                       $block = $wgBlockCache->get( $wgIP, true );
+                       if ( !$block && !$bFromSlave )
+                               {
+                               # Not blocked: check against master, to make sure.
+                               $wgBlockCache->clearLocal( );
+                               $block = $wgBlockCache->get( $wgIP, false );
+                               }
                        if ( $block !== false ) {
                                $this->mBlockedby = $block->mBy;
                                $this->mBlockreason = $block->mReason;
@@ -264,8 +287,8 @@ class User {
                # Proxy blocking
                if ( !$this->mBlockedby ) {
                        if ( array_key_exists( $wgIP, $wgProxyList ) ) {
+                               $this->mBlockedby = wfMsg( 'proxyblocker' );
                                $this->mBlockreason = wfMsg( 'proxyblockreason' );
-                               $this->mBlockedby = "Proxy blocker";
                        }
                }
        }
@@ -274,8 +297,8 @@ class User {
         * Check if user is blocked
         * @return bool True if blocked, false otherwise
         */
-       function isBlocked() {
-               $this->getBlockedStatus();
+       function isBlocked( $bFromSlave = false ) {
+               $this->getBlockedStatus( $bFromSlave );
                if ( 0 === $this->mBlockedby ) { return false; }
                return true;
        }
@@ -381,7 +404,11 @@ class User {
        function loadFromDatabase() {
                global $wgCommandLineMode, $wgAnonGroupId, $wgLoggedInGroupId;
                $fname = "User::loadFromDatabase";
-               if ( $this->mDataLoaded || $wgCommandLineMode ) {
+               
+               # Counter-intuitive, breaks various things, use User::setLoaded() if you want to suppress 
+               # loading in a command line script, don't assume all command line scripts need it like this
+               #if ( $this->mDataLoaded || $wgCommandLineMode ) {
+               if ( $this->mDataLoaded ) {
                        return;
                }
 
@@ -654,6 +681,26 @@ class User {
                $this->invalidateCache();
        }
 
+       /**
+        * A more legible check for non-anonymousness.
+        * Returns true if the user is not an anonymous visitor.
+        *
+        * @return bool
+        */
+       function isLoggedIn() {
+               return( $this->getID() != 0 );
+       }
+       
+       /**
+        * A more legible check for anonymousness.
+        * Returns true if the user is an anonymous visitor.
+        *
+        * @return bool
+        */
+       function isAnon() {
+               return !$this->isLoggedIn();
+       }
+       
        /**
         * Check if a user is sysop
         * Die with backtrace. Use User:isAllowed() instead.
@@ -910,6 +957,9 @@ class User {
 
                setcookie( $wgDBname.'UserID', '', time() - 3600, $wgCookiePath, $wgCookieDomain );
                setcookie( $wgDBname.'Token', '', time() - 3600, $wgCookiePath, $wgCookieDomain );
+
+               # Remember when user logged out, to prevent seeing cached pages
+               setcookie( $wgDBname.'LoggedOut', wfTimestampNow(), time() + 86400, $wgCookiePath, $wgCookieDomain );
        }
 
        /**
@@ -1118,9 +1168,26 @@ class User {
                return wfSetVar( $this->mDataLoaded, $loaded );
        }
 
+       /**
+        * Get this user's personal page title.
+        *
+        * @return Title
+        * @access public
+        */
        function getUserPage() {
                return Title::makeTitle( NS_USER, $this->mName );
        }
+       
+       /**
+        * Get this user's talk page title.
+        *
+        * @return Title
+        * @access public
+        */
+       function getTalkPage() {
+               $title = $this->getUserPage();
+               return $title->getTalkPage();
+       }
 
        /**
         * @static
@@ -1173,6 +1240,45 @@ class User {
                }
                return false;
        }
+       
+       /**
+        * 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.
+        *
+        * @param mixed $salt - Optional function-specific data for hash.
+        *                      Use a string or an array of strings.
+        * @return string
+        * @access public
+        */
+       function editToken( $salt = '' ) {
+               if( !isset( $_SESSION['wsEditToken'] ) ) {
+                       $token = dechex( mt_rand() ) . dechex( mt_rand() );
+                       $_SESSION['wsEditToken'] = $token;
+               } else {
+                       $token = $_SESSION['wsEditToken'];
+               }
+               if( is_array( $salt ) ) {
+                       $salt = implode( '|', $salt );
+               }
+               return md5( $token . $salt );
+       }
+       
+       /**
+        * Check given value against the token value stored in the session.
+        * A match should confirm that the form was submitted from the
+        * user's own login session, not a form submission from a third-party
+        * site.
+        *
+        * @param string $val - the input value to compare
+        * @param string $salt - Optional function-specific data for hash
+        * @return bool
+        * @access public
+        */
+       function matchEditToken( $val, $salt = '' ) {
+               return ( $val == $this->editToken( $salt ) );
+       }
 }
 
 ?>