if (wfRunHooks('WatchArticle', array(&$wgUser, &$this))) {
$wgUser->addWatch( $this->mTitle );
- $wgUser->saveSettings();
return wfRunHooks('WatchArticleComplete', array(&$wgUser, &$this));
}
if (wfRunHooks('UnwatchArticle', array(&$wgUser, &$this))) {
$wgUser->removeWatch( $this->mTitle );
- $wgUser->saveSettings();
return wfRunHooks('UnwatchArticleComplete', array(&$wgUser, &$this));
}
{
case self::SUCCESS:
# We've verified now, update the real record
- $wgUser->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 );
+ if( (bool)$this->mRemember != (bool)$wgUser->getOption( 'rememberpassword' ) ) {
+ $wgUser->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 );
+ $wgUser->saveSettings();
+ } else {
+ $wgUser->invalidateCache();
+ }
$wgUser->setCookies();
- $wgUser->saveSettings();
if( $this->hasSessionCookie() ) {
return $this->successfulLogin( wfMsg( 'loginsuccess', $wgUser->getName() ) );
}
}
$this->invalidateCache();
- $this->saveSettings();
+ }
+ }
+
+ /**
+ * Generate a current or new-future timestamp to be stored in the
+ * user_touched field when we update things.
+ */
+ private static function newTouchedTimestamp() {
+ global $wgClockSkewFudge;
+ return wfTimestamp( TS_MW, time() + $wgClockSkewFudge );
+ }
+
+ /**
+ * Clear user data from memcached.
+ * Use after applying fun updates to the database; caller's
+ * responsibility to update user_touched if appropriate.
+ *
+ * Called implicitly from invalidateCache() and saveSettings().
+ */
+ private function clearUserCache() {
+ if( $this->mId ) {
+ global $wgMemc, $wgDBname;
+ $wgMemc->delete( "$wgDBname:user:id:$this->mId" );
}
}
+ /**
+ * Immediately touch the user data cache for this account.
+ * Updates user_touched field, and removes account data from memcached
+ * for reload on the next hit.
+ */
function invalidateCache() {
- global $wgClockSkewFudge;
- $this->loadFromDatabase();
- $this->mTouched = wfTimestamp(TS_MW, time() + $wgClockSkewFudge );
- # Don't forget to save the options after this or
- # it won't take effect!
+ if( $this->mId ) {
+ $this->mTouched = self::newTouchedTimestamp();
+
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->update( 'user',
+ array( 'user_touched' => $dbw->timestamp( $this->mTouched ) ),
+ array( 'user_id' => $this->mId ),
+ __METHOD__ );
+
+ $this->clearUserCache();
+ }
}
function validateCache( $timestamp ) {
$val = str_replace( "\r", "\n", $val );
$val = str_replace( "\n", " ", $val );
$this->mOptions[$oname] = $val;
- $this->invalidateCache();
}
function getRights() {
$this->mRights = User::getGroupPermissions( $this->getEffectiveGroups() );
$this->invalidateCache();
- $this->saveSettings();
}
/**
$this->mRights = User::getGroupPermissions( $this->getEffectiveGroups() );
$this->invalidateCache();
- $this->saveSettings();
}
/**
* Save object settings into database
+ * @fixme Only rarely do all these fields need to be set!
*/
function saveSettings() {
- global $wgMemc, $wgDBname;
$fname = 'User::saveSettings';
if ( wfReadOnly() ) { return; }
if ( 0 == $this->mId ) { return; }
+
+ $this->mTouched = self::newTouchedTimestamp();
$dbw =& wfGetDB( DB_MASTER );
$dbw->update( 'user',
'user_id' => $this->mId
), $fname
);
- $wgMemc->delete( "$wgDBname:user:id:$this->mId" );
+ $this->clearUserCache();
}