/** * @param Title $title */ public function addBadLinkObj($title) { $dbkey = $title->getPrefixedDBkey(); if (!$this->isBadLink($dbkey)) { $this->mBadLinks->set($dbkey, 1); } }
public function execute() { $dbw = CentralAuthUser::getCentralDB(); $databaseUpdates = new UsersToRenameDatabaseUpdates($dbw); // CentralAuthUser::chooseHomeWiki is expensive and called // multiple times, so lets cache it. $cache = new MapCacheLRU($this->mBatchSize); do { $rows = $this->doQuery(); $insertRows = array(); foreach ($rows as $row) { $this->lName = $row->name; $this->lWiki = $row->wiki; if ($cache->has($row->name)) { $attachableWikis = $cache->get($row->name); } else { $ca = new CentralAuthUser($row->name); $attachableWikis = array(); $unattached = $ca->queryUnattached(); if ($ca->exists()) { $home = $ca->getHomeWiki(); $attachableWikis[] = $home; foreach ($unattached as $wiki => $info) { if ($ca->getEmailAuthenticationTimestamp() && $info['email'] === $ca->getEmail() && !is_null($info['emailAuthenticated'])) { $attachableWikis[] = $wiki; } } } else { $home = $ca->chooseHomeWiki($unattached); $attachableWikis[] = $home; if ($unattached[$home]['email'] && isset($unattached[$home]['emailAuthenticated'])) { foreach ($unattached as $wiki => $info) { if ($wiki !== $home && $unattached[$home]['email'] === $info['email'] && isset($info['emailAuthenticated'])) { $attachableWikis[] = $wiki; } } } } $cache->set($row->name, $attachableWikis); } if (!in_array($row->wiki, $attachableWikis)) { // Unattached account which is not attachable, // so they're getting renamed :( $this->output("{$row->name}@{$row->wiki} is going to be renamed.\n"); $insertRows[] = (array) $row; } } $databaseUpdates->batchInsert($insertRows); $count = $dbw->affectedRows(); $this->output("Inserted {$count} users who we will rename\n"); $this->output("Waiting for slaves...\n"); CentralAuthUser::waitForSlaves(); } while ($count !== 0); }
/** * Get an array of language names, indexed by code. * @param null|string $inLanguage Code of language in which to return the names * Use null for autonyms (native names) * @param string $include One of: * 'all' all available languages * 'mw' only if the language is defined in MediaWiki or wgExtraLanguageNames (default) * 'mwfile' only if the language is in 'mw' *and* has a message file * @return array Language code => language name * @since 1.20 */ public static function fetchLanguageNames($inLanguage = null, $include = 'mw') { $cacheKey = $inLanguage === null ? 'null' : $inLanguage; $cacheKey .= ":{$include}"; if (self::$languageNameCache === null) { self::$languageNameCache = new MapCacheLRU(20); } if (self::$languageNameCache->has($cacheKey)) { $ret = self::$languageNameCache->get($cacheKey); } else { $ret = self::fetchLanguageNamesUncached($inLanguage, $include); self::$languageNameCache->set($cacheKey, $ret); } return $ret; }
/** * Get the grammar transformations data for the language. * Used like grammar forms, with {{GRAMMAR}} and cases, * but uses pairs of regexes and replacements instead of code. * * @return array[] Array of grammar transformations. * @throws MWException * @since 1.28 */ public function getGrammarTransformations() { $languageCode = $this->getCode(); if (self::$grammarTransformations === null) { self::$grammarTransformations = new MapCacheLRU(10); } if (self::$grammarTransformations->has($languageCode)) { return self::$grammarTransformations->get($languageCode); } $data = []; $grammarDataFile = __DIR__ . "/data/grammarTransformations/{$languageCode}.json"; if (is_readable($grammarDataFile)) { $data = FormatJson::decode(file_get_contents($grammarDataFile), true); if ($data === null) { throw new MWException("Invalid grammar data for \"{$languageCode}\"."); } self::$grammarTransformations->set($languageCode, $data); } return $data; }
/** * Fetch the current revision of a given title. Note that the revision * (and even the title) may not exist in the database, so everything * contributing to the output of the parser should use this method * where possible, rather than getting the revisions themselves. This * method also caches its results, so using it benefits performance. * * @since 1.24 * @param Title $title * @return Revision */ public function fetchCurrentRevisionOfTitle($title) { $cacheKey = $title->getPrefixedDBkey(); if (!$this->currentRevisionCache) { $this->currentRevisionCache = new MapCacheLRU(100); } if (!$this->currentRevisionCache->has($cacheKey)) { $this->currentRevisionCache->set($cacheKey, call_user_func($this->mOptions->getCurrentRevisionCallback(), $title, $this)); } return $this->currentRevisionCache->get($cacheKey); }
/** * Fetched the current revision of the given title and return this. * Will increment the expensive function count and * add a template link to get the value refreshed on changes. * For a given title, which is equal to the current parser title, * the revision object from the parser is used, when that is the current one * * @param Parser $parser * @param Title $title * @return Revision * @since 1.23 */ private static function getCachedRevisionObject($parser, $title = null) { static $cache = null; if ($cache == null) { $cache = new MapCacheLRU(50); } if (is_null($title)) { return null; } // Use the revision from the parser itself, when param is the current page // and the revision is the current one if ($title->equals($parser->getTitle())) { $parserRev = $parser->getRevisionObject(); if ($parserRev && $parserRev->isCurrent()) { // force reparse after edit with vary-revision flag $parser->getOutput()->setFlag('vary-revision'); wfDebug(__METHOD__ . ": use current revision from parser, setting vary-revision...\n"); return $parserRev; } } // Normalize name for cache $page = $title->getPrefixedDBkey(); if ($cache->has($page)) { // cache contains null values return $cache->get($page); } if ($parser->incrementExpensiveFunctionCount()) { $rev = Revision::newFromTitle($title, false, Revision::READ_NORMAL); $pageID = $rev ? $rev->getPage() : 0; $revID = $rev ? $rev->getId() : 0; $cache->set($page, $rev); // maybe null // Register dependency in templatelinks $parser->getOutput()->addTemplate($title, $pageID, $revID); return $rev; } $cache->set($page, null); return null; }
/** * Lazy-load the revision's text. * Currently hardcoded to the 'text' table storage engine. * * @return string|bool The revision's text, or false on failure */ protected function loadText() { // Caching may be beneficial for massive use of external storage global $wgRevisionCacheExpiry; static $processCache = null; if (!$processCache) { $processCache = new MapCacheLRU(10); } $cache = ObjectCache::getMainWANInstance(); $textId = $this->getTextId(); $key = wfMemcKey('revisiontext', 'textid', $textId); if ($wgRevisionCacheExpiry) { if ($processCache->has($key)) { return $processCache->get($key); } $text = $cache->get($key); if (is_string($text)) { $processCache->set($key, $text); return $text; } } // If we kept data for lazy extraction, use it now... if ($this->mTextRow !== null) { $row = $this->mTextRow; $this->mTextRow = null; } else { $row = null; } if (!$row) { // Text data is immutable; check slaves first. $dbr = wfGetDB(DB_SLAVE); $row = $dbr->selectRow('text', ['old_text', 'old_flags'], ['old_id' => $textId], __METHOD__); } // Fallback to the master in case of slave lag. Also use FOR UPDATE if it was // used to fetch this revision to avoid missing the row due to REPEATABLE-READ. $forUpdate = $this->mQueryFlags & self::READ_LOCKING == self::READ_LOCKING; if (!$row && ($forUpdate || wfGetLB()->getServerCount() > 1)) { $dbw = wfGetDB(DB_MASTER); $row = $dbw->selectRow('text', ['old_text', 'old_flags'], ['old_id' => $textId], __METHOD__, $forUpdate ? ['FOR UPDATE'] : []); } if (!$row) { wfDebugLog('Revision', "No text row with ID '{$textId}' (revision {$this->getId()})."); } $text = self::getRevisionText($row); if ($row && $text === false) { wfDebugLog('Revision', "No blob for text row '{$textId}' (revision {$this->getId()})."); } # No negative caching -- negative hits on text rows may be due to corrupted slave servers if ($wgRevisionCacheExpiry && $text !== false) { $processCache->set($key, $text); $cache->set($key, $text, $wgRevisionCacheExpiry); } return $text; }