User: Migrate from foreign cache to global cache for UserRightsProxy
[lhc/web/wiklou.git] / includes / User.php
index e1c9e35..b09e4e4 100644 (file)
@@ -185,8 +185,6 @@ class User implements IDBAccessObject {
        public $mName;
        /** @var string */
        public $mRealName;
-       /** @var Password|null */
-       private $mPassword = null;
 
        /** @var string */
        public $mEmail;
@@ -389,6 +387,25 @@ class User implements IDBAccessObject {
                return true;
        }
 
+       /**
+        * @since 1.27
+        * @param string $wikiId
+        * @param integer $userId
+        */
+       public static function purge( $wikiId, $userId ) {
+               $cache = ObjectCache::getMainWANInstance();
+               $cache->delete( $cache->makeGlobalKey( 'user', 'id', $wikiId, $userId ) );
+       }
+
+       /**
+        * @since 1.27
+        * @param WANObjectCache $cache
+        * @return string
+        */
+       protected function getCacheKey( WANObjectCache $cache ) {
+               return $cache->makeGlobalKey( 'user', 'id', wfWikiID(), $this->mId );
+       }
+
        /**
         * Load user data from shared cache, given mId has already been set.
         *
@@ -401,8 +418,8 @@ class User implements IDBAccessObject {
                        return false;
                }
 
-               $key = wfMemcKey( 'user', 'id', $this->mId );
-               $data = ObjectCache::getMainWANInstance()->get( $key );
+               $cache = ObjectCache::getMainWANInstance();
+               $data = $cache->get( $this->getCacheKey( $cache ) );
                if ( !is_array( $data ) || $data['mVersion'] < self::VERSION ) {
                        // Object is expired
                        return false;
@@ -438,10 +455,11 @@ class User implements IDBAccessObject {
                        $data[$name] = $this->$name;
                }
                $data['mVersion'] = self::VERSION;
-               $key = wfMemcKey( 'user', 'id', $this->mId );
-
                $opts = Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
-               ObjectCache::getMainWANInstance()->set( $key, $data, 3600, $opts );
+
+               $cache = ObjectCache::getMainWANInstance();
+               $key = $this->getCacheKey( $cache );
+               $cache->set( $key, $data, $cache::TTL_HOUR, $opts );
        }
 
        /** @name newFrom*() static factory methods */
@@ -1739,8 +1757,6 @@ class User implements IDBAccessObject {
                        return false;
                }
 
-               global $wgMemc;
-
                $limits = $wgRateLimits[$action];
                $keys = array();
                $id = $this->getId();
@@ -1795,11 +1811,13 @@ class User implements IDBAccessObject {
                        $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $userLimit;
                }
 
+               $cache = ObjectCache::getLocalClusterInstance();
+
                $triggered = false;
                foreach ( $keys as $key => $limit ) {
                        list( $max, $period ) = $limit;
                        $summary = "(limit $max in {$period}s)";
-                       $count = $wgMemc->get( $key );
+                       $count = $cache->get( $key );
                        // Already pinged?
                        if ( $count ) {
                                if ( $count >= $max ) {
@@ -1812,11 +1830,11 @@ class User implements IDBAccessObject {
                        } else {
                                wfDebug( __METHOD__ . ": adding record for $key $summary\n" );
                                if ( $incrBy > 0 ) {
-                                       $wgMemc->add( $key, 0, intval( $period ) ); // first ping
+                                       $cache->add( $key, 0, intval( $period ) ); // first ping
                                }
                        }
                        if ( $incrBy > 0 ) {
-                               $wgMemc->incr( $key, $incrBy );
+                               $cache->incr( $key, $incrBy );
                        }
                }
 
@@ -2229,17 +2247,17 @@ class User implements IDBAccessObject {
         * @param string $mode Use 'refresh' to clear now; otherwise before DB commit
         */
        public function clearSharedCache( $mode = 'changed' ) {
-               $id = $this->getId();
-               if ( !$id ) {
+               if ( !$this->getId() ) {
                        return;
                }
 
-               $key = wfMemcKey( 'user', 'id', $id );
+               $cache = ObjectCache::getMainWANInstance();
+               $key = $this->getCacheKey( $cache );
                if ( $mode === 'refresh' ) {
-                       ObjectCache::getMainWANInstance()->delete( $key, 1 );
+                       $cache->delete( $key, 1 );
                } else {
-                       wfGetDB( DB_MASTER )->onTransactionPreCommitOrIdle( function() use ( $key ) {
-                               ObjectCache::getMainWANInstance()->delete( $key );
+                       wfGetDB( DB_MASTER )->onTransactionPreCommitOrIdle( function() use ( $cache, $key ) {
+                               $cache->delete( $key );
                        } );
                }
        }
@@ -2399,32 +2417,32 @@ class User implements IDBAccessObject {
 
        /**
         * Actually set the password and such
+        * @since 1.27 cannot set a password for a user not in the database
         * @param string|null $str New password to set or null to set an invalid
         *  password hash meaning that the user will not be able to log in
         *  through the web interface.
         */
        private function setPasswordInternal( $str ) {
                $id = self::idFromName( $this->getName() );
-               if ( $id ) {
-                       $passwordFactory = new PasswordFactory();
-                       $passwordFactory->init( RequestContext::getMain()->getConfig() );
-                       $dbw = wfGetDB( DB_MASTER );
-                       $dbw->update(
-                               'user',
-                               array(
-                                       'user_password' => $passwordFactory->newFromPlaintext( $str )->toString(),
-                                       'user_newpassword' => PasswordFactory::newInvalidPassword()->toString(),
-                                       'user_newpass_time' => $dbw->timestampOrNull( null ),
-                               ),
-                               array(
-                                       'user_id' => $id,
-                               ),
-                               __METHOD__
-                       );
-                       $this->mPassword = null;
-               } else {
-                       $this->mPassword = $str;
+               if ( $id == 0 ) {
+                       throw new LogicException( 'Cannot set a password for a user that is not in the database.' );
                }
+
+               $passwordFactory = new PasswordFactory();
+               $passwordFactory->init( RequestContext::getMain()->getConfig() );
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->update(
+                       'user',
+                       array(
+                               'user_password' => $passwordFactory->newFromPlaintext( $str )->toString(),
+                               'user_newpassword' => PasswordFactory::newInvalidPassword()->toString(),
+                               'user_newpass_time' => $dbw->timestampOrNull( null ),
+                       ),
+                       array(
+                               'user_id' => $id,
+                       ),
+                       __METHOD__
+               );
        }
 
        /**
@@ -3881,11 +3899,6 @@ class User implements IDBAccessObject {
                }
                $this->mId = $dbw->insertId();
 
-               // Set the password now that it's in the DB, if applicable
-               if ( $this->mPassword !== null ) {
-                       $this->setPasswordInternal( $this->mPassword );
-               }
-
                // Clear instance cache other than user table data, which is already accurate
                $this->clearInstanceCache();