* @file
*/
+use IPSet\IPSet;
use MediaWiki\MediaWikiServices;
use MediaWiki\Session\SessionManager;
use MediaWiki\Session\Token;
$ttl = $cache->adaptiveTTL( wfTimestamp( TS_UNIX, $this->mTouched ), $ttl );
- return $data;
+ // if a user group membership is about to expire, the cache needs to
+ // expire at that time (T163691)
+ foreach ( $this->mGroupMemberships as $ugm ) {
+ if ( $ugm->getExpiry() ) {
+ $secondsUntilExpiry = wfTimestamp( TS_UNIX, $ugm->getExpiry() ) - time();
+ if ( $secondsUntilExpiry > 0 && $secondsUntilExpiry < $ttl ) {
+ $ttl = $secondsUntilExpiry;
+ }
+ }
+ }
+ return $data;
},
[ 'pcTTL' => $cache::TTL_PROC_LONG, 'version' => self::VERSION ]
);
$wgProxyList = array_map( 'trim', file( $wgProxyList ) );
}
- if ( is_array( $wgProxyList ) ) {
- if (
- // Look for IP as value
- array_search( $ip, $wgProxyList ) !== false ||
- // Look for IP as key (for backwards-compatility)
- array_key_exists( $ip, $wgProxyList )
- ) {
- return true;
+ $resultProxyList = [];
+ $deprecatedIPEntries = [];
+
+ // backward compatibility: move all ip addresses in keys to values
+ foreach ( $wgProxyList as $key => $value ) {
+ $keyIsIP = IP::isIPAddress( $key );
+ $valueIsIP = IP::isIPAddress( $value );
+ if ( $keyIsIP && !$valueIsIP ) {
+ $deprecatedIPEntries[] = $key;
+ $resultProxyList[] = $key;
+ } elseif ( $keyIsIP && $valueIsIP ) {
+ $deprecatedIPEntries[] = $key;
+ $resultProxyList[] = $key;
+ $resultProxyList[] = $value;
+ } else {
+ $resultProxyList[] = $value;
}
}
- return false;
+ if ( $deprecatedIPEntries ) {
+ wfDeprecated(
+ 'IP addresses in the keys of $wgProxyList (found the following IP addresses in keys: ' .
+ implode( ', ', $deprecatedIPEntries ) . ', please move them to values)', '1.30' );
+ }
+
+ $proxyListIPSet = new IPSet( $resultProxyList );
+ return $proxyListIPSet->match( $ip );
}
/**
$id = $this->getId();
$userLimit = false;
$isNewbie = $this->isNewbie();
+ $cache = ObjectCache::getLocalClusterInstance();
if ( $id == 0 ) {
// limits for anons
if ( isset( $limits['anon'] ) ) {
- $keys[wfMemcKey( 'limiter', $action, 'anon' )] = $limits['anon'];
+ $keys[$cache->makeKey( 'limiter', $action, 'anon' )] = $limits['anon'];
}
} else {
// limits for logged-in users
}
// limits for newbie logged-in users
if ( $isNewbie && isset( $limits['newbie'] ) ) {
- $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $limits['newbie'];
+ $keys[$cache->makeKey( 'limiter', $action, 'user', $id )] = $limits['newbie'];
}
}
if ( $userLimit !== false ) {
list( $max, $period ) = $userLimit;
wfDebug( __METHOD__ . ": effective user limit: $max in {$period}s\n" );
- $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $userLimit;
+ $keys[$cache->makeKey( 'limiter', $action, 'user', $id )] = $userLimit;
}
// ip-based limits for all ping-limitable users
}
}
- $cache = ObjectCache::getLocalClusterInstance();
-
$triggered = false;
foreach ( $keys as $key => $limit ) {
list( $max, $period ) = $limit;
public function touch() {
$id = $this->getId();
if ( $id ) {
- $key = wfMemcKey( 'user-quicktouched', 'id', $id );
- ObjectCache::getMainWANInstance()->touchCheckKey( $key );
+ $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+ $key = $cache->makeKey( 'user-quicktouched', 'id', $id );
+ $cache->touchCheckKey( $key );
$this->mQuickTouched = null;
}
}
if ( $this->mId ) {
if ( $this->mQuickTouched === null ) {
- $key = wfMemcKey( 'user-quicktouched', 'id', $this->mId );
- $cache = ObjectCache::getMainWANInstance();
+ $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+ $key = $cache->makeKey( 'user-quicktouched', 'id', $this->mId );
$this->mQuickTouched = wfTimestamp( TS_MW, $cache->getCheckKeyTime( $key ) );
}
$this->setToken(); // init token
}
+ if ( !is_string( $this->mName ) ) {
+ throw new RuntimeException( "User name field is not set." );
+ }
+
$this->mTouched = $this->newTouchedTimestamp();
$noPass = PasswordFactory::newInvalidPassword()->toString();
/**
* Deferred version of incEditCountImmediate()
+ *
+ * This function, rather than incEditCountImmediate(), should be used for
+ * most cases as it avoids potential deadlocks caused by concurrent editing.
*/
public function incEditCount() {
wfGetDB( DB_MASTER )->onTransactionPreCommitOrIdle(