本文整理汇总了PHP中ObjectCache::getLocalClusterInstance方法的典型用法代码示例。如果您正苦于以下问题:PHP ObjectCache::getLocalClusterInstance方法的具体用法?PHP ObjectCache::getLocalClusterInstance怎么用?PHP ObjectCache::getLocalClusterInstance使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ObjectCache
的用法示例。
在下文中一共展示了ObjectCache::getLocalClusterInstance方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: applyDefaultConfig
/**
* @param array $lbConf Config for LBFactory::__construct()
* @param Config $mainConfig Main config object from MediaWikiServices
* @return array
*/
public static function applyDefaultConfig(array $lbConf, Config $mainConfig)
{
global $wgCommandLineMode;
$lbConf += ['localDomain' => new DatabaseDomain($mainConfig->get('DBname'), null, $mainConfig->get('DBprefix')), 'profiler' => Profiler::instance(), 'trxProfiler' => Profiler::instance()->getTransactionProfiler(), 'replLogger' => LoggerFactory::getInstance('DBReplication'), 'queryLogger' => LoggerFactory::getInstance('DBQuery'), 'connLogger' => LoggerFactory::getInstance('DBConnection'), 'perfLogger' => LoggerFactory::getInstance('DBPerformance'), 'errorLogger' => [MWExceptionHandler::class, 'logException'], 'cliMode' => $wgCommandLineMode, 'hostname' => wfHostname(), 'readOnlyReason' => wfConfiguredReadOnlyReason()];
if ($lbConf['class'] === 'LBFactorySimple') {
if (isset($lbConf['servers'])) {
// Server array is already explicitly configured; leave alone
} elseif (is_array($mainConfig->get('DBservers'))) {
foreach ($mainConfig->get('DBservers') as $i => $server) {
if ($server['type'] === 'sqlite') {
$server += ['dbDirectory' => $mainConfig->get('SQLiteDataDir')];
} elseif ($server['type'] === 'postgres') {
$server += ['port' => $mainConfig->get('DBport')];
}
$lbConf['servers'][$i] = $server + ['schema' => $mainConfig->get('DBmwschema'), 'tablePrefix' => $mainConfig->get('DBprefix'), 'flags' => DBO_DEFAULT, 'sqlMode' => $mainConfig->get('SQLMode'), 'utf8Mode' => $mainConfig->get('DBmysql5')];
}
} else {
$flags = DBO_DEFAULT;
$flags |= $mainConfig->get('DebugDumpSql') ? DBO_DEBUG : 0;
$flags |= $mainConfig->get('DBssl') ? DBO_SSL : 0;
$flags |= $mainConfig->get('DBcompress') ? DBO_COMPRESS : 0;
$server = ['host' => $mainConfig->get('DBserver'), 'user' => $mainConfig->get('DBuser'), 'password' => $mainConfig->get('DBpassword'), 'dbname' => $mainConfig->get('DBname'), 'schema' => $mainConfig->get('DBmwschema'), 'tablePrefix' => $mainConfig->get('DBprefix'), 'type' => $mainConfig->get('DBtype'), 'load' => 1, 'flags' => $flags, 'sqlMode' => $mainConfig->get('SQLMode'), 'utf8Mode' => $mainConfig->get('DBmysql5')];
if ($server['type'] === 'sqlite') {
$server['dbDirectory'] = $mainConfig->get('SQLiteDataDir');
} elseif ($server['type'] === 'postgres') {
$server['port'] = $mainConfig->get('DBport');
}
$lbConf['servers'] = [$server];
}
if (!isset($lbConf['externalClusters'])) {
$lbConf['externalClusters'] = $mainConfig->get('ExternalServers');
}
} elseif ($lbConf['class'] === 'LBFactoryMulti') {
if (isset($lbConf['serverTemplate'])) {
$lbConf['serverTemplate']['schema'] = $mainConfig->get('DBmwschema');
$lbConf['serverTemplate']['sqlMode'] = $mainConfig->get('SQLMode');
$lbConf['serverTemplate']['utf8Mode'] = $mainConfig->get('DBmysql5');
}
}
// Use APC/memcached style caching, but avoids loops with CACHE_DB (T141804)
$sCache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
if ($sCache->getQoS($sCache::ATTR_EMULATION) > $sCache::QOS_EMULATION_SQL) {
$lbConf['srvCache'] = $sCache;
}
$cCache = ObjectCache::getLocalClusterInstance();
if ($cCache->getQoS($cCache::ATTR_EMULATION) > $cCache::QOS_EMULATION_SQL) {
$lbConf['memCache'] = $cCache;
}
$wCache = MediaWikiServices::getInstance()->getMainWANObjectCache();
if ($wCache->getQoS($wCache::ATTR_EMULATION) > $wCache::QOS_EMULATION_SQL) {
$lbConf['wanCache'] = $wCache;
}
return $lbConf;
}
示例2: __construct
/**
* @param array $conditions An array of arrays describing throttling conditions.
* Defaults to $wgPasswordAttemptThrottle. See documentation of that variable for format.
* @param array $params Parameters (all optional):
* - type: throttle type, used as a namespace for counters,
* - cache: a BagOStuff object where throttle counters are stored.
* - warningLimit: the log level will be raised to warning when rejecting an attempt after
* no less than this many failures.
*/
public function __construct(array $conditions = null, array $params = [])
{
$invalidParams = array_diff_key($params, array_fill_keys(['type', 'cache', 'warningLimit'], true));
if ($invalidParams) {
throw new \InvalidArgumentException('unrecognized parameters: ' . implode(', ', array_keys($invalidParams)));
}
if ($conditions === null) {
$config = \ConfigFactory::getDefaultInstance()->makeConfig('main');
$conditions = $config->get('PasswordAttemptThrottle');
$params += ['type' => 'password', 'cache' => \ObjectCache::getLocalClusterInstance(), 'warningLimit' => 50];
} else {
$params += ['type' => 'custom', 'cache' => \ObjectCache::getLocalClusterInstance(), 'warningLimit' => INF];
}
$this->type = $params['type'];
$this->conditions = static::normalizeThrottleConditions($conditions);
$this->cache = $params['cache'];
$this->warningLimit = $params['warningLimit'];
$this->setLogger(LoggerFactory::getInstance('throttler'));
}
示例3: testAutoCreateUser
//.........这里部分代码省略.........
$user = User::newFromName('UTDoesNotExist');
$this->assertFalse($manager->autoCreateUser($user));
$this->assertSame(0, $user->getId());
$this->assertNotSame('UTDoesNotExist', $user->getName());
$this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST));
$this->setMwGlobals(array('wgReadOnly' => false));
$session->clear();
$this->assertSame(array(array(LogLevel::DEBUG, 'denied by wfReadOnly()')), $logger->getBuffer());
$logger->clearBuffer();
// Test prevention by a previous session
$session->set('MWSession::AutoCreateBlacklist', 'test');
$user = User::newFromName('UTDoesNotExist');
$this->assertFalse($manager->autoCreateUser($user));
$this->assertSame(0, $user->getId());
$this->assertNotSame('UTDoesNotExist', $user->getName());
$this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST));
$session->clear();
$this->assertSame(array(array(LogLevel::DEBUG, 'blacklisted in session (test)')), $logger->getBuffer());
$logger->clearBuffer();
// Test uncreatable name
$user = User::newFromName('UTDoesNotExist@');
$this->assertFalse($manager->autoCreateUser($user));
$this->assertSame(0, $user->getId());
$this->assertNotSame('UTDoesNotExist@', $user->getName());
$this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST));
$session->clear();
$this->assertSame(array(array(LogLevel::DEBUG, 'Invalid username, blacklisting')), $logger->getBuffer());
$logger->clearBuffer();
// Test AbortAutoAccount hook
$mock = $this->getMock(__CLASS__, array('onAbortAutoAccount'));
$mock->expects($this->once())->method('onAbortAutoAccount')->will($this->returnCallback(function (User $user, &$msg) {
$msg = 'No way!';
return false;
}));
$this->mergeMwGlobalArrayValue('wgHooks', array('AbortAutoAccount' => array($mock)));
$user = User::newFromName('UTDoesNotExist');
$this->assertFalse($manager->autoCreateUser($user));
$this->assertSame(0, $user->getId());
$this->assertNotSame('UTDoesNotExist', $user->getName());
$this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST));
$this->mergeMwGlobalArrayValue('wgHooks', array('AbortAutoAccount' => array()));
$session->clear();
$this->assertSame(array(array(LogLevel::DEBUG, 'denied by hook: No way!')), $logger->getBuffer());
$logger->clearBuffer();
// Test AbortAutoAccount hook screwing up the name
$mock = $this->getMock('stdClass', array('onAbortAutoAccount'));
$mock->expects($this->once())->method('onAbortAutoAccount')->will($this->returnCallback(function (User $user) {
$user->setName('UTDoesNotExistEither');
}));
$this->mergeMwGlobalArrayValue('wgHooks', array('AbortAutoAccount' => array($mock)));
try {
$user = User::newFromName('UTDoesNotExist');
$manager->autoCreateUser($user);
$this->fail('Expected exception not thrown');
} catch (\UnexpectedValueException $ex) {
$this->assertSame('AbortAutoAccount hook tried to change the user name', $ex->getMessage());
}
$this->assertSame(0, $user->getId());
$this->assertNotSame('UTDoesNotExist', $user->getName());
$this->assertNotSame('UTDoesNotExistEither', $user->getName());
$this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST));
$this->assertEquals(0, User::idFromName('UTDoesNotExistEither', User::READ_LATEST));
$this->mergeMwGlobalArrayValue('wgHooks', array('AbortAutoAccount' => array()));
$session->clear();
$this->assertSame(array(), $logger->getBuffer());
$logger->clearBuffer();
// Test for "exception backoff"
$user = User::newFromName('UTDoesNotExist');
$cache = \ObjectCache::getLocalClusterInstance();
$backoffKey = wfMemcKey('MWSession', 'autocreate-failed', md5($user->getName()));
$cache->set($backoffKey, 1, 60 * 10);
$this->assertFalse($manager->autoCreateUser($user));
$this->assertSame(0, $user->getId());
$this->assertNotSame('UTDoesNotExist', $user->getName());
$this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST));
$cache->delete($backoffKey);
$session->clear();
$this->assertSame(array(array(LogLevel::DEBUG, 'denied by prior creation attempt failures')), $logger->getBuffer());
$logger->clearBuffer();
// Sanity check that creation still works, and test completion hook
$cb = $this->callback(function (User $user) use($that) {
$that->assertNotEquals(0, $user->getId());
$that->assertSame('UTSessionAutoCreate4', $user->getName());
$that->assertEquals($user->getId(), User::idFromName('UTSessionAutoCreate4', User::READ_LATEST));
return true;
});
$mock = $this->getMock('stdClass', array('onAuthPluginAutoCreate', 'onLocalUserCreated'));
$mock->expects($this->once())->method('onAuthPluginAutoCreate')->with($cb);
$mock->expects($this->once())->method('onLocalUserCreated')->with($cb, $this->identicalTo(true));
$this->mergeMwGlobalArrayValue('wgHooks', array('AuthPluginAutoCreate' => array($mock), 'LocalUserCreated' => array($mock)));
$user = User::newFromName('UTSessionAutoCreate4');
$this->assertSame(0, $user->getId(), 'sanity check');
$this->assertTrue($manager->autoCreateUser($user));
$this->assertNotEquals(0, $user->getId());
$this->assertSame('UTSessionAutoCreate4', $user->getName());
$this->assertEquals($user->getId(), User::idFromName('UTSessionAutoCreate4', User::READ_LATEST));
$this->mergeMwGlobalArrayValue('wgHooks', array('AuthPluginAutoCreate' => array(), 'LocalUserCreated' => array()));
$this->assertSame(array(array(LogLevel::INFO, 'creating new user (UTSessionAutoCreate4) - from: XXX')), $logger->getBuffer());
$logger->clearBuffer();
}
示例4: checkCache
/**
* Check that a prepared edit is in cache and still up-to-date
*
* This method blocks if the prepared edit is already being rendered,
* waiting until rendering finishes before doing final validity checks.
*
* The cache is rejected if template or file changes are detected.
* Note that foreign template or file transclusions are not checked.
*
* The result is a map (pstContent,output,timestamp) with fields
* extracted directly from WikiPage::prepareContentForEdit().
*
* @param Title $title
* @param Content $content
* @param User $user User to get parser options from
* @return stdClass|bool Returns false on cache miss
*/
public static function checkCache(Title $title, Content $content, User $user)
{
if ($user->isBot()) {
return false;
// bots never stash - don't pollute stats
}
$cache = ObjectCache::getLocalClusterInstance();
$logger = LoggerFactory::getInstance('StashEdit');
$stats = RequestContext::getMain()->getStats();
$key = self::getStashKey($title, $content, $user);
$editInfo = $cache->get($key);
if (!is_object($editInfo)) {
$start = microtime(true);
// We ignore user aborts and keep parsing. Block on any prior parsing
// so as to use its results and make use of the time spent parsing.
// Skip this logic if there no master connection in case this method
// is called on an HTTP GET request for some reason.
$lb = wfGetLB();
$dbw = $lb->getAnyOpenConnection($lb->getWriterIndex());
if ($dbw && $dbw->lock($key, __METHOD__, 30)) {
$editInfo = $cache->get($key);
$dbw->unlock($key, __METHOD__);
}
$timeMs = 1000 * max(0, microtime(true) - $start);
$stats->timing('editstash.lock_wait_time', $timeMs);
}
if (!is_object($editInfo) || !$editInfo->output) {
$stats->increment('editstash.cache_misses.no_stash');
$logger->debug("No cache value for key '{$key}'.");
return false;
}
$age = time() - wfTimestamp(TS_UNIX, $editInfo->output->getCacheTime());
if ($age <= self::PRESUME_FRESH_TTL_SEC) {
$stats->increment('editstash.cache_hits.presumed_fresh');
$logger->debug("Timestamp-based cache hit for key '{$key}' (age: {$age} sec).");
return $editInfo;
// assume nothing changed
} elseif (isset($editInfo->edits) && $editInfo->edits === $user->getEditCount()) {
// Logged-in user made no local upload/template edits in the meantime
$stats->increment('editstash.cache_hits.presumed_fresh');
$logger->debug("Edit count based cache hit for key '{$key}' (age: {$age} sec).");
return $editInfo;
} elseif ($user->isAnon() && self::lastEditTime($user) < $editInfo->output->getCacheTime()) {
// Logged-out user made no local upload/template edits in the meantime
$stats->increment('editstash.cache_hits.presumed_fresh');
$logger->debug("Edit check based cache hit for key '{$key}' (age: {$age} sec).");
return $editInfo;
}
$dbr = wfGetDB(DB_SLAVE);
$templates = [];
// conditions to find changes/creations
$templateUses = 0;
// expected existing templates
foreach ($editInfo->output->getTemplateIds() as $ns => $stuff) {
foreach ($stuff as $dbkey => $revId) {
$templates[(string) $ns][$dbkey] = (int) $revId;
++$templateUses;
}
}
// Check that no templates used in the output changed...
if (count($templates)) {
$res = $dbr->select('page', ['ns' => 'page_namespace', 'dbk' => 'page_title', 'page_latest'], $dbr->makeWhereFrom2d($templates, 'page_namespace', 'page_title'), __METHOD__);
$changed = false;
foreach ($res as $row) {
$changed = $changed || $row->page_latest != $templates[$row->ns][$row->dbk];
}
if ($changed || $res->numRows() != $templateUses) {
$stats->increment('editstash.cache_misses.proven_stale');
$logger->info("Stale cache for key '{$key}'; template changed. (age: {$age} sec)");
return false;
}
}
$files = [];
// conditions to find changes/creations
foreach ($editInfo->output->getFileSearchOptions() as $name => $options) {
$files[$name] = (string) $options['sha1'];
}
// Check that no files used in the output changed...
if (count($files)) {
$res = $dbr->select('image', ['name' => 'img_name', 'img_sha1'], ['img_name' => array_keys($files)], __METHOD__);
$changed = false;
foreach ($res as $row) {
$changed = $changed || $row->img_sha1 != $files[$row->name];
//.........这里部分代码省略.........
示例5: __construct
/**
* @see FileBackendStore::__construct()
* Additional $config params include:
* - swiftAuthUrl : Swift authentication server URL
* - swiftUser : Swift user used by MediaWiki (account:username)
* - swiftKey : Swift authentication key for the above user
* - swiftAuthTTL : Swift authentication TTL (seconds)
* - swiftTempUrlKey : Swift "X-Account-Meta-Temp-URL-Key" value on the account.
* Do not set this until it has been set in the backend.
* - shardViaHashLevels : Map of container names to sharding config with:
* - base : base of hash characters, 16 or 36
* - levels : the number of hash levels (and digits)
* - repeat : hash subdirectories are prefixed with all the
* parent hash directory names (e.g. "a/ab/abc")
* - cacheAuthInfo : Whether to cache authentication tokens in APC, XCache, ect.
* If those are not available, then the main cache will be used.
* This is probably insecure in shared hosting environments.
* - rgwS3AccessKey : Rados Gateway S3 "access key" value on the account.
* Do not set this until it has been set in the backend.
* This is used for generating expiring pre-authenticated URLs.
* Only use this when using rgw and to work around
* http://tracker.newdream.net/issues/3454.
* - rgwS3SecretKey : Rados Gateway S3 "secret key" value on the account.
* Do not set this until it has been set in the backend.
* This is used for generating expiring pre-authenticated URLs.
* Only use this when using rgw and to work around
* http://tracker.newdream.net/issues/3454.
*/
public function __construct(array $config)
{
parent::__construct($config);
// Required settings
$this->swiftAuthUrl = $config['swiftAuthUrl'];
$this->swiftUser = $config['swiftUser'];
$this->swiftKey = $config['swiftKey'];
// Optional settings
$this->authTTL = isset($config['swiftAuthTTL']) ? $config['swiftAuthTTL'] : 15 * 60;
// some sane number
$this->swiftTempUrlKey = isset($config['swiftTempUrlKey']) ? $config['swiftTempUrlKey'] : '';
$this->shardViaHashLevels = isset($config['shardViaHashLevels']) ? $config['shardViaHashLevels'] : '';
$this->rgwS3AccessKey = isset($config['rgwS3AccessKey']) ? $config['rgwS3AccessKey'] : '';
$this->rgwS3SecretKey = isset($config['rgwS3SecretKey']) ? $config['rgwS3SecretKey'] : '';
// HTTP helper client
$this->http = new MultiHttpClient(array());
// Cache container information to mask latency
if (isset($config['wanCache']) && $config['wanCache'] instanceof WANObjectCache) {
$this->memCache = $config['wanCache'];
}
// Process cache for container info
$this->containerStatCache = new ProcessCacheLRU(300);
// Cache auth token information to avoid RTTs
if (!empty($config['cacheAuthInfo'])) {
if (PHP_SAPI === 'cli') {
// Preferrably memcached
$this->srvCache = ObjectCache::getLocalClusterInstance();
} else {
// Look for APC, XCache, WinCache, ect...
$this->srvCache = ObjectCache::getLocalServerInstance(CACHE_NONE);
}
} else {
$this->srvCache = new EmptyBagOStuff();
}
}
示例6: pingLimiter
/**
* Primitive rate limits: enforce maximum actions per time period
* to put a brake on flooding.
*
* The method generates both a generic profiling point and a per action one
* (suffix being "-$action".
*
* @note When using a shared cache like memcached, IP-address
* last-hit counters will be shared across wikis.
*
* @param string $action Action to enforce; 'edit' if unspecified
* @param int $incrBy Positive amount to increment counter by [defaults to 1]
* @return bool True if a rate limiter was tripped
*/
public function pingLimiter($action = 'edit', $incrBy = 1)
{
// Call the 'PingLimiter' hook
$result = false;
if (!Hooks::run('PingLimiter', array(&$this, $action, &$result, $incrBy))) {
return $result;
}
global $wgRateLimits;
if (!isset($wgRateLimits[$action])) {
return false;
}
// Some groups shouldn't trigger the ping limiter, ever
if (!$this->isPingLimitable()) {
return false;
}
$limits = $wgRateLimits[$action];
$keys = array();
$id = $this->getId();
$userLimit = false;
if (isset($limits['anon']) && $id == 0) {
$keys[wfMemcKey('limiter', $action, 'anon')] = $limits['anon'];
}
if (isset($limits['user']) && $id != 0) {
$userLimit = $limits['user'];
}
if ($this->isNewbie()) {
if (isset($limits['newbie']) && $id != 0) {
$keys[wfMemcKey('limiter', $action, 'user', $id)] = $limits['newbie'];
}
if (isset($limits['ip'])) {
$ip = $this->getRequest()->getIP();
$keys["mediawiki:limiter:{$action}:ip:{$ip}"] = $limits['ip'];
}
if (isset($limits['subnet'])) {
$ip = $this->getRequest()->getIP();
$matches = array();
$subnet = false;
if (IP::isIPv6($ip)) {
$parts = IP::parseRange("{$ip}/64");
$subnet = $parts[0];
} elseif (preg_match('/^(\\d+\\.\\d+\\.\\d+)\\.\\d+$/', $ip, $matches)) {
// IPv4
$subnet = $matches[1];
}
if ($subnet !== false) {
$keys["mediawiki:limiter:{$action}:subnet:{$subnet}"] = $limits['subnet'];
}
}
}
// Check for group-specific permissions
// If more than one group applies, use the group with the highest limit
foreach ($this->getGroups() as $group) {
if (isset($limits[$group])) {
if ($userLimit === false || $limits[$group][0] / $limits[$group][1] > $userLimit[0] / $userLimit[1]) {
$userLimit = $limits[$group];
}
}
}
// Set the user limit key
if ($userLimit !== false) {
list($max, $period) = $userLimit;
wfDebug(__METHOD__ . ": effective user limit: {$max} in {$period}s\n");
$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 = $cache->get($key);
// Already pinged?
if ($count) {
if ($count >= $max) {
wfDebugLog('ratelimit', "User '{$this->getName()}' " . "(IP {$this->getRequest()->getIP()}) tripped {$key} at {$count} {$summary}");
$triggered = true;
} else {
wfDebug(__METHOD__ . ": ok. {$key} at {$count} {$summary}\n");
}
} else {
wfDebug(__METHOD__ . ": adding record for {$key} {$summary}\n");
if ($incrBy > 0) {
$cache->add($key, 0, intval($period));
// first ping
}
}
if ($incrBy > 0) {
//.........这里部分代码省略.........
示例7: testAutoAccountCreation
//.........这里部分代码省略.........
$this->hook('LocalUserCreated', $this->never());
$ret = $this->manager->autoCreateUser($user, AuthManager::AUTOCREATE_SOURCE_SESSION, true);
$this->unhook('LocalUserCreated');
$this->assertEquals(\Status::newFatal('authmanager-autocreate-noperm'), $ret);
$this->assertEquals(0, $user->getId());
$this->assertNotEquals($username, $user->getName());
$this->assertEquals(0, $session->getUser()->getId());
$this->assertSame([[LogLevel::DEBUG, 'IP lacks the ability to create or autocreate accounts']], $logger->getBuffer());
$logger->clearBuffer();
$this->assertSame('authmanager-autocreate-noperm', $session->get('AuthManager::AutoCreateBlacklist'));
// Test that both permutations of permissions are allowed
// (this hits the two "ok" entries in $mocks['pre'])
$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['autocreateaccount'] = true;
$session->clear();
$user = \User::newFromName($username);
$this->hook('LocalUserCreated', $this->never());
$ret = $this->manager->autoCreateUser($user, AuthManager::AUTOCREATE_SOURCE_SESSION, true);
$this->unhook('LocalUserCreated');
$this->assertEquals(\Status::newFatal('ok'), $ret);
$wgGroupPermissions['*']['createaccount'] = true;
$wgGroupPermissions['*']['autocreateaccount'] = false;
$session->clear();
$user = \User::newFromName($username);
$this->hook('LocalUserCreated', $this->never());
$ret = $this->manager->autoCreateUser($user, AuthManager::AUTOCREATE_SOURCE_SESSION, true);
$this->unhook('LocalUserCreated');
$this->assertEquals(\Status::newFatal('ok'), $ret);
$logger->clearBuffer();
// Test lock fail
$session->clear();
$user = \User::newFromName($username);
$this->hook('LocalUserCreated', $this->never());
$cache = \ObjectCache::getLocalClusterInstance();
$lock = $cache->getScopedLock($cache->makeGlobalKey('account', md5($username)));
$ret = $this->manager->autoCreateUser($user, AuthManager::AUTOCREATE_SOURCE_SESSION, true);
unset($lock);
$this->unhook('LocalUserCreated');
$this->assertEquals(\Status::newFatal('usernameinprogress'), $ret);
$this->assertEquals(0, $user->getId());
$this->assertNotEquals($username, $user->getName());
$this->assertEquals(0, $session->getUser()->getId());
$this->assertSame([[LogLevel::DEBUG, 'Could not acquire account creation lock']], $logger->getBuffer());
$logger->clearBuffer();
// Test pre-authentication provider fail
$session->clear();
$user = \User::newFromName($username);
$this->hook('LocalUserCreated', $this->never());
$ret = $this->manager->autoCreateUser($user, AuthManager::AUTOCREATE_SOURCE_SESSION, true);
$this->unhook('LocalUserCreated');
$this->assertEquals(\Status::newFatal('fail-in-pre'), $ret);
$this->assertEquals(0, $user->getId());
$this->assertNotEquals($username, $user->getName());
$this->assertEquals(0, $session->getUser()->getId());
$this->assertSame([[LogLevel::DEBUG, 'Provider denied creation of {username}: {reason}']], $logger->getBuffer());
$logger->clearBuffer();
$this->assertEquals(StatusValue::newFatal('fail-in-pre'), $session->get('AuthManager::AutoCreateBlacklist'));
$session->clear();
$user = \User::newFromName($username);
$this->hook('LocalUserCreated', $this->never());
$ret = $this->manager->autoCreateUser($user, AuthManager::AUTOCREATE_SOURCE_SESSION, true);
$this->unhook('LocalUserCreated');
$this->assertEquals(\Status::newFatal('fail-in-primary'), $ret);
$this->assertEquals(0, $user->getId());
$this->assertNotEquals($username, $user->getName());
$this->assertEquals(0, $session->getUser()->getId());
示例8: wfGlobalCacheKey
/**
* Make a cache key with database-agnostic prefix.
*
* Doesn't have a wiki-specific namespace. Uses a generic 'global' prefix
* instead. Must have a prefix as otherwise keys that use a database name
* in the first segment will clash with wfMemcKey/wfForeignMemcKey.
*
* @since 1.26
* @param string $args,...
* @return string
*/
function wfGlobalCacheKey()
{
return call_user_func_array(array(ObjectCache::getLocalClusterInstance(), 'makeGlobalKey'), func_get_args());
}
示例9: getMissesRecent
/**
* Roughly gets the cache misses in the last hour by unique visitors
* @return int
*/
public function getMissesRecent()
{
$cache = ObjectCache::getLocalClusterInstance();
return self::MISS_FACTOR * $cache->get($this->cacheMissKey());
}
示例10: getCachedConfigVar
/**
* @param string $name
* @return mixed
*/
private function getCachedConfigVar($name)
{
global $wgConf;
if ($this->wiki === wfWikiID()) {
return $GLOBALS[$name];
// common case
} else {
$cache = ObjectCache::getLocalClusterInstance();
list($db, $prefix) = wfSplitWikiID($this->wiki);
$key = wfForeignMemcKey($db, $prefix, 'configvalue', $name);
$value = $cache->get($key);
// ('v' => ...) or false
if (is_array($value)) {
return $value['v'];
} else {
$value = $wgConf->getConfig($this->wiki, $name);
$cache->set($key, array('v' => $value), $cache::TTL_DAY + mt_rand(0, $cache::TTL_DAY));
return $value;
}
}
}
示例11: wfGenerateThumbnail
/**
* Actually try to generate a new thumbnail
*
* @param File $file
* @param array $params
* @param string $thumbName
* @param string $thumbPath
* @return array (MediaTransformOutput|bool, string|bool error message HTML)
*/
function wfGenerateThumbnail(File $file, array $params, $thumbName, $thumbPath)
{
global $wgAttemptFailureEpoch;
$cache = ObjectCache::getLocalClusterInstance();
$key = $cache->makeKey('attempt-failures', $wgAttemptFailureEpoch, $file->getRepo()->getName(), $file->getSha1(), md5($thumbName));
// Check if this file keeps failing to render
if ($cache->get($key) >= 4) {
return array(false, wfMessage('thumbnail_image-failure-limit', 4));
}
$done = false;
// Record failures on PHP fatals in addition to caching exceptions
register_shutdown_function(function () use($cache, &$done, $key) {
if (!$done) {
// transform() gave a fatal
// Randomize TTL to reduce stampedes
$cache->incrWithInit($key, $cache::TTL_HOUR + mt_rand(0, 300));
}
});
$thumb = false;
$errorHtml = false;
// guard thumbnail rendering with PoolCounter to avoid stampedes
// expensive files use a separate PoolCounter config so it is possible
// to set up a global limit on them
if ($file->isExpensiveToThumbnail()) {
$poolCounterType = 'FileRenderExpensive';
} else {
$poolCounterType = 'FileRender';
}
// Thumbnail isn't already there, so create the new thumbnail...
try {
$work = new PoolCounterWorkViaCallback($poolCounterType, sha1($file->getName()), array('doWork' => function () use($file, $params) {
return $file->transform($params, File::RENDER_NOW);
}, 'doCachedWork' => function () use($file, $params, $thumbPath) {
// If the worker that finished made this thumbnail then use it.
// Otherwise, it probably made a different thumbnail for this file.
return $file->getRepo()->fileExists($thumbPath) ? $file->transform($params, File::RENDER_NOW) : false;
// retry once more in exclusive mode
}, 'error' => function (Status $status) {
return wfMessage('generic-pool-error')->parse() . '<hr>' . $status->getHTML();
}));
$result = $work->execute();
if ($result instanceof MediaTransformOutput) {
$thumb = $result;
} elseif (is_string($result)) {
// error
$errorHtml = $result;
}
} catch (Exception $e) {
// Tried to select a page on a non-paged file?
}
/** @noinspection PhpUnusedLocalVariableInspection */
$done = true;
// no PHP fatal occured
if (!$thumb || $thumb->isError()) {
// Randomize TTL to reduce stampedes
$cache->incrWithInit($key, $cache::TTL_HOUR + mt_rand(0, 300));
}
return array($thumb, $errorHtml);
}
示例12: __construct
/**
* @param array $params
* - accountCreationThrottle: (array) Condition array for the account creation throttle; an array
* of arrays in a format like $wgPasswordAttemptThrottle, passed to the Throttler constructor.
* - passwordAttemptThrottle: (array) Condition array for the password attempt throttle, in the
* same format as accountCreationThrottle.
* - cache: (BagOStuff) Where to store the throttle, defaults to the local cluster instance.
*/
public function __construct($params = [])
{
$this->throttleSettings = array_intersect_key($params, ['accountCreationThrottle' => true, 'passwordAttemptThrottle' => true]);
$this->cache = isset($params['cache']) ? $params['cache'] : \ObjectCache::getLocalClusterInstance();
}
示例13: autoCreateUser
/**
* Auto-create an account, and log into that account
* @param User $user User to auto-create
* @param string $source What caused the auto-creation? This must be the ID
* of a PrimaryAuthenticationProvider or the constant self::AUTOCREATE_SOURCE_SESSION.
* @param bool $login Whether to also log the user in
* @return Status Good if user was created, Ok if user already existed, otherwise Fatal
*/
public function autoCreateUser(User $user, $source, $login = true)
{
if ($source !== self::AUTOCREATE_SOURCE_SESSION && !$this->getAuthenticationProvider($source) instanceof PrimaryAuthenticationProvider) {
throw new \InvalidArgumentException("Unknown auto-creation source: {$source}");
}
$username = $user->getName();
// Try the local user from the slave DB
$localId = User::idFromName($username);
$flags = User::READ_NORMAL;
// Fetch the user ID from the master, so that we don't try to create the user
// when they already exist, due to replication lag
// @codeCoverageIgnoreStart
if (!$localId && wfGetLB()->getReaderIndex() != 0) {
$localId = User::idFromName($username, User::READ_LATEST);
$flags = User::READ_LATEST;
}
// @codeCoverageIgnoreEnd
if ($localId) {
$this->logger->debug(__METHOD__ . ': {username} already exists locally', ['username' => $username]);
$user->setId($localId);
$user->loadFromId($flags);
if ($login) {
$this->setSessionDataForUser($user);
}
$status = Status::newGood();
$status->warning('userexists');
return $status;
}
// Wiki is read-only?
if (wfReadOnly()) {
$this->logger->debug(__METHOD__ . ': denied by wfReadOnly(): {reason}', ['username' => $username, 'reason' => wfReadOnlyReason()]);
$user->setId(0);
$user->loadFromId();
return Status::newFatal('readonlytext', wfReadOnlyReason());
}
// Check the session, if we tried to create this user already there's
// no point in retrying.
$session = $this->request->getSession();
if ($session->get('AuthManager::AutoCreateBlacklist')) {
$this->logger->debug(__METHOD__ . ': blacklisted in session {sessionid}', ['username' => $username, 'sessionid' => $session->getId()]);
$user->setId(0);
$user->loadFromId();
$reason = $session->get('AuthManager::AutoCreateBlacklist');
if ($reason instanceof StatusValue) {
return Status::wrap($reason);
} else {
return Status::newFatal($reason);
}
}
// Is the username creatable?
if (!User::isCreatableName($username)) {
$this->logger->debug(__METHOD__ . ': name "{username}" is not creatable', ['username' => $username]);
$session->set('AuthManager::AutoCreateBlacklist', 'noname', 600);
$user->setId(0);
$user->loadFromId();
return Status::newFatal('noname');
}
// Is the IP user able to create accounts?
$anon = new User();
if (!$anon->isAllowedAny('createaccount', 'autocreateaccount')) {
$this->logger->debug(__METHOD__ . ': IP lacks the ability to create or autocreate accounts', ['username' => $username, 'ip' => $anon->getName()]);
$session->set('AuthManager::AutoCreateBlacklist', 'authmanager-autocreate-noperm', 600);
$session->persist();
$user->setId(0);
$user->loadFromId();
return Status::newFatal('authmanager-autocreate-noperm');
}
// Avoid account creation races on double submissions
$cache = \ObjectCache::getLocalClusterInstance();
$lock = $cache->getScopedLock($cache->makeGlobalKey('account', md5($username)));
if (!$lock) {
$this->logger->debug(__METHOD__ . ': Could not acquire account creation lock', ['user' => $username]);
$user->setId(0);
$user->loadFromId();
return Status::newFatal('usernameinprogress');
}
// Denied by providers?
$providers = $this->getPreAuthenticationProviders() + $this->getPrimaryAuthenticationProviders() + $this->getSecondaryAuthenticationProviders();
foreach ($providers as $provider) {
$status = $provider->testUserForCreation($user, $source);
if (!$status->isGood()) {
$ret = Status::wrap($status);
$this->logger->debug(__METHOD__ . ': Provider denied creation of {username}: {reason}', ['username' => $username, 'reason' => $ret->getWikiText(null, null, 'en')]);
$session->set('AuthManager::AutoCreateBlacklist', $status, 600);
$user->setId(0);
$user->loadFromId();
return $ret;
}
}
// Ignore warnings about master connections/writes...hard to avoid here
\Profiler::instance()->getTransactionProfiler()->resetExpectations();
$backoffKey = wfMemcKey('AuthManager', 'autocreate-failed', md5($username));
//.........这里部分代码省略.........
示例14: pingLimiter
/**
* Primitive rate limits: enforce maximum actions per time period
* to put a brake on flooding.
*
* The method generates both a generic profiling point and a per action one
* (suffix being "-$action".
*
* @note When using a shared cache like memcached, IP-address
* last-hit counters will be shared across wikis.
*
* @param string $action Action to enforce; 'edit' if unspecified
* @param int $incrBy Positive amount to increment counter by [defaults to 1]
* @return bool True if a rate limiter was tripped
*/
public function pingLimiter($action = 'edit', $incrBy = 1)
{
// Call the 'PingLimiter' hook
$result = false;
if (!Hooks::run('PingLimiter', [&$this, $action, &$result, $incrBy])) {
return $result;
}
global $wgRateLimits;
if (!isset($wgRateLimits[$action])) {
return false;
}
// Some groups shouldn't trigger the ping limiter, ever
if (!$this->isPingLimitable()) {
return false;
}
$limits = $wgRateLimits[$action];
$keys = [];
$id = $this->getId();
$userLimit = false;
$isNewbie = $this->isNewbie();
if ($id == 0) {
// limits for anons
if (isset($limits['anon'])) {
$keys[wfMemcKey('limiter', $action, 'anon')] = $limits['anon'];
}
} else {
// limits for logged-in users
if (isset($limits['user'])) {
$userLimit = $limits['user'];
}
// limits for newbie logged-in users
if ($isNewbie && isset($limits['newbie'])) {
$keys[wfMemcKey('limiter', $action, 'user', $id)] = $limits['newbie'];
}
}
// limits for anons and for newbie logged-in users
if ($isNewbie) {
// ip-based limits
if (isset($limits['ip'])) {
$ip = $this->getRequest()->getIP();
$keys["mediawiki:limiter:{$action}:ip:{$ip}"] = $limits['ip'];
}
// subnet-based limits
if (isset($limits['subnet'])) {
$ip = $this->getRequest()->getIP();
$subnet = IP::getSubnet($ip);
if ($subnet !== false) {
$keys["mediawiki:limiter:{$action}:subnet:{$subnet}"] = $limits['subnet'];
}
}
}
// Check for group-specific permissions
// If more than one group applies, use the group with the highest limit ratio (max/period)
foreach ($this->getGroups() as $group) {
if (isset($limits[$group])) {
if ($userLimit === false || $limits[$group][0] / $limits[$group][1] > $userLimit[0] / $userLimit[1]) {
$userLimit = $limits[$group];
}
}
}
// Set the user limit key
if ($userLimit !== false) {
list($max, $period) = $userLimit;
wfDebug(__METHOD__ . ": effective user limit: {$max} in {$period}s\n");
$keys[wfMemcKey('limiter', $action, 'user', $id)] = $userLimit;
}
// ip-based limits for all ping-limitable users
if (isset($limits['ip-all'])) {
$ip = $this->getRequest()->getIP();
// ignore if user limit is more permissive
if ($isNewbie || $userLimit === false || $limits['ip-all'][0] / $limits['ip-all'][1] > $userLimit[0] / $userLimit[1]) {
$keys["mediawiki:limiter:{$action}:ip-all:{$ip}"] = $limits['ip-all'];
}
}
// subnet-based limits for all ping-limitable users
if (isset($limits['subnet-all'])) {
$ip = $this->getRequest()->getIP();
$subnet = IP::getSubnet($ip);
if ($subnet !== false) {
// ignore if user limit is more permissive
if ($isNewbie || $userLimit === false || $limits['ip-all'][0] / $limits['ip-all'][1] > $userLimit[0] / $userLimit[1]) {
$keys["mediawiki:limiter:{$action}:subnet-all:{$subnet}"] = $limits['subnet-all'];
}
}
}
$cache = ObjectCache::getLocalClusterInstance();
//.........这里部分代码省略.........
示例15: getStashKey
/**
* Get the temporary prepared edit stash key for a user
*
* This key can be used for caching prepared edits provided:
* - a) The $user was used for PST options
* - b) The parser output was made from the PST using cannonical matching options
*
* @param Title $title
* @param string $contentHash Result of getContentHash()
* @param User $user User to get parser options from
* @return string
*/
private static function getStashKey(Title $title, $contentHash, User $user)
{
return ObjectCache::getLocalClusterInstance()->makeKey('prepared-edit', md5($title->getPrefixedDBkey()), $contentHash, md5($user->getId() . "\n" . $user->getName()));
}