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();
         }
     }
 }