/** * Marshal & execute the RenameUserProcess functions to rename a user * * @param array $wikiCityIds * @param array $params * requestor_id => ID of the user requesting this rename action * requestor_name => Name of the user requesting this rename action * rename_user_id => ID of the user to rename * rename_old_name => Current username of the user to rename * rename_new_name => New username for the user to rename * reason => Reason for requesting username change * rename_fake_user_id => Repeated rename process special case (TODO: Don't know what this is) * phalanx_block_id => Phalanx login block ID * @return bool */ public function renameUser(array $wikiCityIds, array $params) { global $IP; $renameIP = !empty($params['rename_ip']); $loadBalancerFactory = wfGetLBFactory(); $process = RenameUserProcess::newFromData($params); $process->setLogDestination(\RenameUserProcess::LOG_BATCH_TASK, $this); $process->setRequestorUser(); $noErrors = true; // ComSup wants the StaffLogger to keep track of renames... $this->staffLog('start', $params, \RenameUserLogFormatter::start($params['requestor_name'], $params['rename_old_name'], $params['rename_new_name'], $params['reason'], [$this->getTaskId()])); try { foreach ($wikiCityIds as $cityId) { /** * execute maintenance script */ $cmd = sprintf("SERVER_ID=%s php {$IP}/maintenance/wikia/RenameUser_local.php", $cityId); $opts = ['rename-user-id' => $params['rename_user_id'], 'requestor-id' => $params['requestor_id'], 'reason' => $params['reason']]; if ($renameIP) { $opts['rename-old-name'] = $params['rename_old_name']; $opts['rename-new-name'] = $params['rename_new_name']; } else { $opts['rename-old-name-enc'] = rawurlencode($params['rename_old_name']); $opts['rename-new-name-enc'] = rawurlencode($params['rename_new_name']); $opts['rename-fake-user-id'] = $params['rename_fake_user_id']; $opts['phalanx-block-id'] = $params['phalanx_block_id']; } foreach ($opts as $opt => $val) { $cmd .= sprintf(' --%s %s', $opt, escapeshellarg($val)); } if ($renameIP) { $cmd .= ' --rename-ip-address'; } $exitCode = null; $output = wfShellExec($cmd, $exitCode); $logMessage = sprintf("Rename user %s to %s on city id %s", $params['rename_old_name'], $params['rename_new_name'], $cityId); $logContext = ['command' => $cmd, 'exitStatus' => $exitCode, 'output' => $output]; if ($exitCode > 0) { $this->error($logMessage, $logContext); $noErrors = false; } else { $this->info($logMessage, $logContext); } $this->staffLog('log', $params, \RenameUserLogFormatter::wiki($params['requestor_name'], $params['rename_old_name'], $params['rename_new_name'], $cityId, $params['reason'], $exitCode > 0)); $loadBalancerFactory->forEachLBCallMethod('commitMasterChanges'); $loadBalancerFactory->forEachLBCallMethod('closeAll'); } } catch (Exception $e) { $noErrors = false; $this->error("error while renaming user", ['message' => $e->getMessage(), 'stack' => $e->getTraceAsString()]); } // clean up pre-process setup $process->cleanup(); $this->notifyUser(\User::newFromId($params['requestor_id']), $params['rename_old_name'], $params['rename_new_name']); if (!$renameIP) { //mark user as renamed $renamedUser = \User::newFromName($params['rename_new_name']); $renamedUser->setGlobalFlag('wasRenamed', true); $renamedUser->saveSettings(); if ($params['notify_renamed']) { //send e-mail to the user that rename process has finished $this->notifyUser($renamedUser, $params['rename_old_name'], $params['rename_new_name']); } } if ($noErrors) { $this->staffLog('finish', $params, \RenameUserLogFormatter::finish($params['requestor_name'], $params['rename_old_name'], $params['rename_new_name'], $params['reason'], [$this->getTaskId()])); } else { $this->staffLog('fail', $params, \RenameUserLogFormatter::fail($params['requestor_name'], $params['rename_old_name'], $params['rename_new_name'], $params['reason'], [$this->getTaskId()])); } return $noErrors; }
/** * Processes specific local wiki database and makes all needed changes for an IP address * * Important: should only be run within maintenace script (bound to specified wiki) */ public function updateLocalIP() { global $wgCityId, $wgUser; wfProfileIn(__METHOD__); if ($this->mUserId !== 0 || !IP::isIPAddress($this->mOldUsername) || !IP::isIPAddress($this->mNewUsername)) { $this->addError(wfMessage('userrenametool-error-invalid-ip')->escaped()); wfProfileOut(__METHOD__); return; } $wgOldUser = $wgUser; $wgUser = User::newFromName('Wikia'); $cityDb = WikiFactory::IDtoDB($wgCityId); $this->addLog("Processing wiki database: {$cityDb}."); $dbw = wfGetDB(DB_MASTER); $dbw->begin(); $tasks = self::$mLocalIpDefaults; $hookName = 'UserRename::LocalIP'; $this->addLog("Broadcasting hook: {$hookName}"); wfRunHooks($hookName, [$dbw, $this->mUserId, $this->mOldUsername, $this->mNewUsername, $this, $wgCityId, &$tasks]); foreach ($tasks as $task) { $this->addLog("Updating wiki \"{$cityDb}\": {$task['table']}:{$task['username_column']}"); $this->renameInTable($dbw, $task['table'], $this->mUserId, $this->mOldUsername, $this->mNewUsername, $task); } $hookName = 'UserRename::AfterLocalIP'; $this->addLog("Broadcasting hook: {$hookName}"); wfRunHooks($hookName, [$dbw, $this->mUserId, $this->mOldUsername, $this->mNewUsername, $this, $wgCityId, &$tasks]); $dbw->commit(); $this->addLog("Finished updating wiki database: {$cityDb}"); $this->addMainLog("log", RenameUserLogFormatter::wiki($this->mRequestorName, $this->mOldUsername, $this->mNewUsername, $wgCityId, $this->mReason, !empty($this->warnings) || !empty($this->errors))); $wgUser = $wgOldUser; wfProfileOut(__METHOD__); }
/** * Processes specific local wiki database and makes all needed changes * * Important: should only be run within maintenace script (bound to specified wiki) * * @param $cityId int Wiki ID */ public function updateLocal() { global $wgCityId, $wgUser; wfProfileIn(__METHOD__); $wgOldUser = $wgUser; $wgUser = User::newFromName('Wikia'); $cityDb = WikiFactory::IDtoDB($wgCityId); $this->addLog("Processing wiki database: {$cityDb}."); $dbw = wfGetDB(DB_MASTER); $dbw->begin(); $tasks = self::$mLocalDefaults; $hookName = 'UserRename::Local'; $this->addLog("Broadcasting hook: {$hookName}"); wfRunHooks($hookName, array($dbw, $this->mUserId, $this->mOldUsername, $this->mNewUsername, $this, $wgCityId, &$tasks)); /* Move user pages */ $this->addLog("Moving user pages."); try { $oldTitle = Title::makeTitle(NS_USER, $this->mOldUsername); $newTitle = Title::makeTitle(NS_USER, $this->mNewUsername); // Determine all namespaces which need processing $allowedNamespaces = array(NS_USER, NS_USER_TALK); // Blogs extension if (defined('NS_BLOG_ARTICLE')) { $allowedNamespaces = array_merge($allowedNamespaces, array(NS_BLOG_ARTICLE, NS_BLOG_ARTICLE_TALK)); } // NY User profile if (defined('NS_USER_WIKI')) { $allowedNamespaces = array_merge($allowedNamespaces, array(NS_USER_WIKI, 201, NS_USER_PROFILE)); } if (defined('NS_USER_WALL')) { $allowedNamespaces = array_merge($allowedNamespaces, array(NS_USER_WALL, NS_USER_WALL_MESSAGE, NS_USER_WALL_MESSAGE_GREETING)); } $oldKey = $oldTitle->getDBkey(); $like = $dbw->buildLike(sprintf("%s/", $oldKey), $dbw->anyString()); $pages = $dbw->select('page', array('page_namespace', 'page_title'), array('page_namespace' => $allowedNamespaces, '(page_title ' . $like . ' OR page_title = ' . $dbw->addQuotes($oldKey) . ')'), __METHOD__); $this->addLog("SQL: " . $dbw->lastQuery()); while ($row = $dbw->fetchObject($pages)) { $oldPage = Title::makeTitleSafe($row->page_namespace, $row->page_title); $newPage = Title::makeTitleSafe($row->page_namespace, preg_replace('!^[^/]+!', $newTitle->getDBkey(), $row->page_title)); //Do not autodelete or anything, title must not exist //Info: The other case is when renaming is repeated - no action should be taken if ($newPage->exists() && !$oldPage->isValidMoveTarget($newPage)) { $this->addLog("Updating wiki \"{$cityDb}\": User page " . $newPage->getText() . " already exists, moving cancelled."); $this->addWarning(wfMsgForContent('userrenametool-page-exists', $newPage->getText())); } else { $this->addLog("Moving page " . $oldPage->getText() . " in namespace {$row->page_namespace} to " . $newTitle->getText()); $success = $oldPage->moveTo($newPage, false, wfMsgForContent('userrenametool-move-log', $oldTitle->getText(), $newTitle->getText())); if ($success === true) { $this->addLog("Updating wiki \"{$cityDb}\": User page " . $oldPage->getText() . " moved to " . $newPage->getText() . '.'); } else { $this->addLog("Updating wiki \"{$cityDb}\": User page " . $oldPage->getText() . " could not be moved to " . $newPage->getText() . '.'); $this->addWarning(wfMsgForContent('userrenametool-page-unmoved', array($oldPage->getText(), $newPage->getText()))); } } } $dbw->freeResult($pages); } catch (Exception $e) { $this->addLog("Exception while moving pages: " . $e->getMessage() . ' in ' . $e->getFile() . ' at line ' . $e->getLine()); } /* End of move user pages */ foreach ($tasks as $task) { $this->addLog("Updating wiki \"{$cityDb}\": {$task['table']}:{$task['username_column']}"); $this->renameInTable($dbw, $task['table'], $this->mUserId, $this->mOldUsername, $this->mNewUsername, $task); } $hookName = 'UserRename::AfterLocal'; $this->addLog("Broadcasting hook: {$hookName}"); wfRunHooks($hookName, array($dbw, $this->mUserId, $this->mOldUsername, $this->mNewUsername, $this, $wgCityId, &$tasks)); $dbw->commit(); // Save entry in local Special:Log // Important: assuming that run inside the maintenance script $this->addLocalLog(wfMsgExt('userrenametool-success', array('content'), $this->mOldUsername, $this->mNewUsername)); $this->addLog("Finished updating wiki database: {$cityDb}"); $this->addMainLog("log", RenameUserLogFormatter::wiki($this->mRequestorName, $this->mOldUsername, $this->mNewUsername, $wgCityId, $this->mReason, !empty($this->warnings) || !empty($this->errors))); $wgUser = $wgOldUser; wfProfileOut(__METHOD__); }