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); }
/** * @param string $wiki * @param DatabaseBase $dbw * @return stdClass[] */ protected function findUsers($wiki, DatabaseBase $dbw) { $rowsToRename = array(); $updates = new UsersToRenameDatabaseUpdates($dbw); $rows = $updates->findUsers($wiki, UsersToRenameDatabaseUpdates::NOTIFIED, $this->mBatchSize); foreach ($rows as $row) { $user = User::newFromName($row->utr_name); $caUser = new CentralAuthUser($row->utr_name); if (!$user->getId()) { $this->log("'{$row->utr_name}' has been renamed since the last was list generated."); $updates->remove($row->utr_name, $row->utr_wiki); } elseif ($caUser->attachedOn($row->utr_wiki)) { $this->log("'{$row->utr_name}' has become attached to a global account since the list as last generated."); $updates->remove($row->utr_name, $row->utr_wiki); } elseif (!User::isUsableName($row->utr_name)) { // Reserved for a system account, ignore $this->log("'{$row->utr_name}' is a reserved username, skipping."); $updates->remove($row->utr_name, $row->utr_wiki); } else { $rowsToRename[] = $row; } } return $rowsToRename; }
public function execute() { if (!class_exists('MassMessageServerSideJob')) { $this->error('This script requires the MassMessage extension', 1); } $message = $this->getLocalizedText($this->getOption('message')); $message = str_replace('{{WIKI}}', wfWikiID(), $message); $message .= " ~~~~~\n<!-- SUL finalisation notification -->"; $dbw = CentralAuthUser::getCentralDB(); $updates = new UsersToRenameDatabaseUpdates($dbw); $commonParams = array('subject' => $this->getLocalizedText($this->getOption('subject'))); while (true) { $jobs = array(); $markNotified = array(); $rows = $updates->findUsers(wfWikiID(), 0, $this->mBatchSize); if ($rows->numRows() === 0) { break; } $lb = new LinkBatch(); foreach ($rows as $row) { $title = Title::makeTitleSafe(NS_USER_TALK, $row->utr_name); if (!$title) { $this->output("ERROR: Invalid username for {$row->utr_name}\n"); continue; } $lb->addObj($title); } $lb->execute(); foreach ($rows as $row) { $title = 'User talk:' . $row->utr_name; $titleObj = Title::newFromText($title); if ($titleObj->isRedirect()) { // @fixme find a way to notify users with a redirected user-talk $this->output("Skipping {$title} because it is a redirect\n"); $updates->markRedirectSkipped($row->utr_name, $row->utr_wiki); continue; } $jobs[] = new MassMessageServerSideJob(Title::newFromText($title), array('title' => $title, 'message' => str_replace('{{subst:PAGENAME}}', $row->utr_name, $message)) + $commonParams); $this->output("Will notify {$row->utr_name}\n"); $markNotified[] = $row; } $count = count($jobs); $this->output("Queued job for {$count} users.\n"); JobQueueGroup::singleton()->push($jobs); foreach ($markNotified as $row) { $updates->markNotified($row->utr_name, $row->utr_wiki); } $this->output("Waiting for slaves..."); CentralAuthUser::waitForSlaves(); // users_to_rename wfWaitForSlaves(); // And on the local wiki! $this->output(" done.\n"); $queued = $this->getQueuedCount(); while ($queued > 100000) { $this->output("Currently {$queued} jobs, sleeping for 5 seconds...\n"); sleep(5); $queued = $this->getQueuedCount(); } } }