public function createPage(Title $title) { $page = new \WikiPage($title); $pageContent = 'Content of ' . $title->getFullText(); $editMessage = 'SPL system test: create page'; if (class_exists('WikitextContent')) { $page->doEditContent(new \WikitextContent($pageContent), $editMessage); } else { $page->doEdit($pageContent, $editMessage); } }
protected function createPage($page, $text, $model = null) { if (is_string($page)) { $page = Title::newFromText($page); } if ($page instanceof Title) { $page = new WikiPage($page); } if ($page->exists()) { $page->doDeleteArticle("done"); } $page->doEdit($text, "testing", EDIT_NEW); return $page; }
/** * Find the latest revision of the article that does not contain spam and revert to it */ function cleanupArticle(Revision $rev, $regexes, $match) { $title = $rev->getTitle(); $revId = $rev->getId(); while ($rev) { $matches = false; foreach ($regexes as $regex) { $matches = $matches || preg_match($regex, $rev->getText()); } if (!$matches) { // Didn't find any spam break; } # Revision::getPrevious can't be used in this way before MW 1.6 (Revision.php 1.26) #$rev = $rev->getPrevious(); $revId = $title->getPreviousRevisionID($revId); if ($revId) { $rev = Revision::newFromTitle($title, $revId); } else { $rev = false; } } $dbw = wfGetDB(DB_MASTER); $dbw->begin(); if (!$rev) { // Didn't find a non-spammy revision, delete the page /* print "All revisions are spam, deleting...\n"; $article = new Article( $title ); $article->doDeleteArticle( "All revisions matched the spam blacklist" ); */ // Too scary, blank instead print "All revisions are spam, blanking...\n"; $text = ''; $comment = "All revisions matched the spam blacklist ({$match}), blanking"; } else { // Revert to this revision $text = $rev->getText(); $comment = "Cleaning up links to {$match}"; } $wikiPage = new WikiPage($title); $wikiPage->doEdit($text, $comment); $dbw->commit(); }
/** * Create category. * * @param $category String: Name of category to create. * @param $code String: Code of language that the category is for. * @param $level String: Level that the category is for. */ public static function create($category, $code, $level = null) { wfProfileIn(__METHOD__); $category = strip_tags($category); $title = Title::makeTitleSafe(NS_CATEGORY, $category); if ($title === null || $title->exists()) { wfProfileOut(__METHOD__); return; } global $wgLanguageCode; $language = BabelLanguageCodes::getName($code, $wgLanguageCode); $params = array($language, $code); if ($level === null) { $text = wfMessage('babel-autocreate-text-main', $params)->inContentLanguage()->text(); } else { array_unshift($params, $level); $text = wfMessage('babel-autocreate-text-levels', $params)->inContentLanguage()->text(); } $user = self::user(); # Do not add a message if the username is invalid or if the account that adds it, is blocked if (!$user || $user->isBlocked()) { wfProfileOut(__METHOD__); return; } if (!$title->quickUserCan('create', $user)) { wfProfileOut(__METHOD__); return; # The Babel AutoCreate account is not allowed to create the page } /* $article->doEdit will call $wgParser->parse. * Calling Parser::parse recursively is baaaadd... (bug 29245) * @todo FIXME: surely there is a better way? */ global $wgParser, $wgParserConf; $oldParser = $wgParser; $parserClass = $wgParserConf['class']; $wgParser = new $parserClass($wgParserConf); $url = wfMessage('babel-url')->inContentLanguage()->plain(); $article = new WikiPage($title); $article->doEdit($text, wfMessage('babel-autocreate-reason', $url)->text(), EDIT_FORCE_BOT, false, $user); $wgParser = $oldParser; wfProfileOut(__METHOD__); }
static function refreshAll() { $dbw = wfGetDB(DB_MASTER); print "Refreshing right definitions...\n"; $res = $dbw->select('page', '*', array('page_namespace' => HACL_NS_ACL), __METHOD__); $titles = array(); foreach ($res as $row) { $titles[] = Title::newFromRow($row); } foreach ($titles as $title) { $article = new WikiPage($title); $article->doEdit($article->getText(), 'Re-parse right definition', EDIT_UPDATE); } }
/** * Submit the form parameters for the page config to the DB. * * @return mixed (true on success, error string on failure) */ public function doSubmit() { # Double-check permissions if (!$this->isAllowed()) { return 'review_denied'; } # We can only approve actual revisions... if ($this->getAction() === 'approve') { $rev = Revision::newFromTitle($this->page, $this->oldid); # Check for archived/deleted revisions... if (!$rev || $rev->getVisibility()) { return 'review_bad_oldid'; } # Check for review conflicts... if ($this->lastChangeTime !== null) { // API uses null $lastChange = $this->oldFrev ? $this->oldFrev->getTimestamp() : ''; if ($lastChange !== $this->lastChangeTime) { return 'review_conflict_oldid'; } } $status = $this->approveRevision($rev, $this->oldFrev); # We can only unapprove approved revisions... } elseif ($this->getAction() === 'unapprove') { # Check for review conflicts... if ($this->lastChangeTime !== null) { // API uses null $lastChange = $this->oldFrev ? $this->oldFrev->getTimestamp() : ''; if ($lastChange !== $this->lastChangeTime) { return 'review_conflict_oldid'; } } # Check if we can find this flagged rev... if (!$this->oldFrev) { return 'review_not_flagged'; } $status = $this->unapproveRevision($this->oldFrev); } elseif ($this->getAction() === 'reject') { $newRev = Revision::newFromTitle($this->page, $this->oldid); $oldRev = Revision::newFromTitle($this->page, $this->refid); # Do not mess with archived/deleted revisions if (!$oldRev || $oldRev->isDeleted(Revision::DELETED_TEXT)) { return 'review_bad_oldid'; } elseif (!$newRev || $newRev->isDeleted(Revision::DELETED_TEXT)) { return 'review_bad_oldid'; } # Check that the revs are in order if ($oldRev->getTimestamp() > $newRev->getTimestamp()) { return 'review_cannot_undo'; } # Make sure we are only rejecting pending changes $srev = FlaggedRevision::newFromStable($this->page, FR_MASTER); if ($srev && $oldRev->getTimestamp() < $srev->getRevTimestamp()) { return 'review_cannot_reject'; // not really a use case } $article = new WikiPage($this->page); # Get text with changes after $oldRev up to and including $newRev removed $new_text = $article->getUndoText($newRev, $oldRev); if ($new_text === false) { return 'review_cannot_undo'; } $baseRevId = $newRev->isCurrent() ? $oldRev->getId() : 0; # Actually make the edit... $editStatus = $article->doEdit($new_text, $this->getComment(), 0, $baseRevId, $this->user); $status = $editStatus->isOK() ? true : 'review_cannot_undo'; if ($editStatus->isOK() && class_exists('EchoEvent') && $editStatus->value['revision']) { $affectedRevisions = array(); // revid -> userid $revisions = wfGetDB(DB_SLAVE)->select('revision', array('rev_id', 'rev_user'), array('rev_id <= ' . $newRev->getId(), 'rev_timestamp <= ' . $newRev->getTimestamp(), 'rev_id > ' . $oldRev->getId(), 'rev_timestamp > ' . $oldRev->getTimestamp(), 'rev_page' => $article->getId()), __METHOD__); foreach ($revisions as $row) { $affectedRevisions[$row->rev_id] = $row->rev_user; } EchoEvent::create(array('type' => 'reverted', 'title' => $this->page, 'extra' => array('revid' => $editStatus->value['revision']->getId(), 'reverted-users-ids' => array_values($affectedRevisions), 'reverted-revision-ids' => array_keys($affectedRevisions), 'method' => 'flaggedrevs-reject'), 'agent' => $this->user)); } # If this undid one edit by another logged-in user, update user tallies if ($status === true && $newRev->getParentId() == $oldRev->getId() && $newRev->getRawUser()) { if ($newRev->getRawUser() != $this->user->getId()) { // no self-reverts FRUserCounters::incCount($newRev->getRawUser(), 'revertedEdits'); } } } # Watch page if set to do so if ($status === true) { if ($this->user->getOption('flaggedrevswatch') && !$this->page->userIsWatching()) { $this->user->addWatch($this->page); } } return $status; }
/** * @covers WikiPage::doEdit */ public function testDoEdit() { $this->hideDeprecated("WikiPage::doEdit"); $this->hideDeprecated("WikiPage::getText"); $this->hideDeprecated("Revision::getText"); //NOTE: assume help namespace will default to wikitext $title = Title::newFromText("Help:WikiPageTest_testDoEdit"); $page = $this->newPage($title); $text = "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam " . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat."; $page->doEdit($text, "[[testing]] 1"); $this->assertTrue($title->getArticleID() > 0, "Title object should have new page id"); $this->assertTrue($page->getId() > 0, "WikiPage should have new page id"); $this->assertTrue($title->exists(), "Title object should indicate that the page now exists"); $this->assertTrue($page->exists(), "WikiPage object should indicate that the page now exists"); $id = $page->getId(); # ------------------------ $dbr = wfGetDB(DB_SLAVE); $res = $dbr->select('pagelinks', '*', array('pl_from' => $id)); $n = $res->numRows(); $res->free(); $this->assertEquals(1, $n, 'pagelinks should contain one link from the page'); # ------------------------ $page = new WikiPage($title); $retrieved = $page->getText(); $this->assertEquals($text, $retrieved, 'retrieved text doesn\'t equal original'); # ------------------------ $text = "At vero eos et accusam et justo duo [[dolores]] et ea rebum. " . "Stet clita kasd [[gubergren]], no sea takimata sanctus est."; $page->doEdit($text, "testing 2"); # ------------------------ $page = new WikiPage($title); $retrieved = $page->getText(); $this->assertEquals($text, $retrieved, 'retrieved text doesn\'t equal original'); # ------------------------ $dbr = wfGetDB(DB_SLAVE); $res = $dbr->select('pagelinks', '*', array('pl_from' => $id)); $n = $res->numRows(); $res->free(); $this->assertEquals(2, $n, 'pagelinks should contain two links from the page'); }
public function getDefinitions() { global $wgTranslateWorkflowStates; $defs = array(); foreach (array_keys($wgTranslateWorkflowStates) as $state) { $titleString = "Translate-workflow-state-{$state}"; $definitionText = $state; // Automatically create pages for workflow states in the original language $title = Title::makeTitle($this->getNamespace(), $titleString); if (!$title->exists()) { $page = new WikiPage($title); $page->doEdit($state, wfMessage('translate-workflow-autocreated-summary', $state)->inContentLanguage()->text(), 0, false, FuzzyBot::getUser()); } else { $definitionText = Revision::newFromTitle($title)->getText(); } $defs[$titleString] = $definitionText; } return $defs; }
/** * Verwijdert een waarde uit een argument van een blok op een wiki-pagina. * Bijvoorbeeld {{Context|Supercontext=te_verwijderen_waarde}} */ static function verwijderUitBlokargumentVanArtikel($artikel, $bloknaam, $argument, $te_verwijderen_inhoud, $samenvatting) { $titel_te_bewerken_artikel = Title::newFromText($artikel); $te_bewerken_artikel = new WikiPage($titel_te_bewerken_artikel); $inhoud = $te_bewerken_artikel->getText(); $blockstring = '{{' . $bloknaam; $eindstring = '}}'; $posblock = strpos($inhoud, $blockstring); $poseind = strpos($inhoud, $eindstring, $posblock + 1); $preblock = substr($inhoud, 0, $posblock); // De eindstring }} zit in het postblock! $postblock = trim(substr($inhoud, $poseind)); $block = substr($inhoud, $posblock, $poseind); $argumentblockintro = $argument . '='; $argumentblockoutro = '|'; $posintro = strpos($block, $argumentblockintro); $posoutro = strpos($block, $argumentblockoutro, $posintro); $argumentpreblock = substr($block, 0, $posintro); if ($posoutro) { $argumentblock = substr($block, $posintro, $posoutro); $argumentpostblock = substr($block, $posoutro); } else { $argumentblock = substr($block, $posintro); $argumentpostblock = ''; } $argumentblock = strtr($argumentblock, array($te_verwijderen_inhoud => '')); $argumentblock = strtr($argumentblock, array(',,' => ',')); $block = $argumentpreblock . $argumentblock . $argumentpostblock; $nieuwe_inhoud = $preblock . $block . $postblock; $te_bewerken_artikel->doEdit($nieuwe_inhoud, $samenvatting, EDIT_UPDATE); }
/** * Usage example: * $this->createWikiPage("Bla", array( * 'LENGTH' => 'serh sehr lagn', * 'VIDEO_PATH' => 'usw', * ); **/ function createWikiPage($newpage_title_str, $template_vars) { $newpage_title = Title::newFromText($newpage_title_str); $newpage = new WikiPage($newpage_title); $user = $this->getUser(); $newtext = $this->getRawContent("RiedbergTV:Videoseitenvorlage"); foreach ($template_vars as $key => $value) { $newtext = str_replace("@{$key}@", $value, $newtext); } $ret = $newpage->doEdit($newtext, "Seite angelegt durch [[Spezial:VideoUpload]].", 0, false, $user); return $newpage; }
private function createCardPage($gatherer) { $title = Title::newFromText($this->name); $info = array(); $i = 0; foreach ($gatherer->sets as $set => $stuff) { $image = wfStripIllegalFilenameChars(str_replace(':', '', $this->name)) . ' ' . $gatherer->rels[$set]['abbr'] . '.jpg'; if (isset($gatherer->borders[$set]) && $gatherer->borders[$set]) { $border = $gatherer->rels[$set]['border']; $info['image' . ++$i] = "{{Border|[[Image:{$image}]]|{$border}}}"; } else { $info['image' . ++$i] = "[[Image:{$image}]]"; } foreach ($stuff as $rarity => $meh) { switch ($rarity) { case 'R': $rarity = 'Rare'; break; case 'U': $rarity = 'Uncommon'; break; case 'C': $rarity = 'Common'; break; case 'S': if ($set == 'Time Spiral "Timeshifted"') { $rarity = 'Timeshifted'; $set = 'Time Spiral'; } else { $rarity = 'Special'; } break; case 'M': $rarity = 'Mythic Rare'; break; case 'L': $rarity = 'Land'; break; } $set = wfStripIllegalFilenameChars(str_replace(':', '', $set)); $info['p/r' . $i] = "{{Rarity|{$set}|{$rarity}}}"; } } for ($i = 1; $i <= 15; $i++) { if (!isset($info['image' . $i])) { $info['image' . $i] = ''; } if (!isset($info['p/r' . $i])) { $info['p/r' . $i] = ''; } } $article = new WikiPage($title); $article->doEdit(wfMsgForContentNoTrans('gatherer-cardpage', array($gatherer->info['name'], $gatherer->info['type'], $gatherer->info['cost'], $gatherer->info['cmc'], $gatherer->info['rules'], $gatherer->info['flavor'], $gatherer->info['p/t'], $gatherer->info['planeswalker'], $info['image1'], $info['p/r1'], $info['image2'], $info['p/r2'], $info['image3'], $info['p/r3'], $info['image4'], $info['p/r4'], $info['image5'], $info['p/r5'], $info['image6'], $info['p/r6'], $info['image7'], $info['p/r7'], $info['image8'], $info['p/r8'], $info['image9'], $info['p/r9'], $info['image10'], $info['p/r10'], $info['image11'], $info['p/r11'], $info['image12'], $info['p/r12'], $info['image13'], $info['p/r13'], $info['image14'], $info['p/r14'], $info['image15'], $info['p/r15'])), wfMsg('gatherer-cardpage-com')); }
/** * @desc Saving CSS content * If there is more recent edit it will try to merge text and save. * Returns false when conflict is found and cannot be resolved * * @param string $content * @param string $summary * @param bool $isMinor * @param int $editTime timestamp * @param User $user * @return Status|bool */ public function saveCssFileContent($content, $summary, $isMinor, $editTime, $user) { $cssTitle = $this->getCssFileTitle(); $flags = 0; if ($cssTitle instanceof Title) { $aid = $cssTitle->getArticleID(Title::GAID_FOR_UPDATE); $flags |= $aid == 0 ? EDIT_NEW : EDIT_UPDATE; if ($isMinor) { $flags |= EDIT_MINOR; } $db = wfGetDB(DB_MASTER); $currentRevision = Revision::loadFromTitle($db, $cssTitle); // we handle both - edit and creation conflicts below if (!empty($currentRevision) && $editTime != $currentRevision->getTimestamp()) { $result = ''; $currentText = $currentRevision->getText(); if (!$editTime) { // the css did not exist when the editor was started, so the base revision for // parallel edits is an empty file $baseText = ''; } else { $baseText = Revision::loadFromTimestamp($db, $this->getCssFileTitle(), $editTime)->getText(); } // remove windows endlines from input before merging texts $content = str_replace("\r", "", $content); if (wfMerge($baseText, $content, $currentText, $result)) { // This conflict can be resolved $content = $result; } else { // We have real conflict here return false; } } $page = new WikiPage($cssTitle); $status = $page->doEdit($content, $summary, $flags, false, $user); return $status; } return Status::newFatal('special-css-saving-internal-error'); }
/** * wfMaintenance -- wiki factory maintenance * * @static */ public static function wfMaintenance() { $results = []; // VOLDEV-96: Do not credit edits to localhost $wikiaUser = User::newFromName('Wikia'); /** * create Blog:Recent posts page if not exists */ $recentPosts = wfMessage('create-blog-post-recent-listing')->text(); if ($recentPosts) { $recentPostsKey = "Creating {$recentPosts}"; $oTitle = Title::newFromText($recentPosts, NS_BLOG_LISTING); if ($oTitle) { $page = new WikiPage($oTitle); if (!$page->exists()) { $page->doEdit('<bloglist summary="true" count=50><title>' . wfMessage('create-blog-post-recent-listing-title ')->text() . '</title><type>plain</type><order>date</order></bloglist>', wfMessage('create-blog-post-recent-listing-log')->text(), EDIT_NEW | EDIT_MINOR | EDIT_FORCE_BOT, false, $wikiaUser); $results[$recentPostsKey] = 'done'; } else { $results[$recentPostsKey] = 'already exists'; } } } /** * create Category:Blog page if not exists */ $catName = wfMessage('create-blog-post-category')->text(); if ($catName && $catName !== "-") { $catNameKey = "Creating {$catName}"; $oTitle = Title::newFromText($catName, NS_CATEGORY); if ($oTitle) { $page = new WikiPage($oTitle); if (!$page->exists()) { $page->doEdit(wfMessage('create-blog-post-category-body')->text(), wfMessage('create-blog-post-category-log')->text(), EDIT_NEW | EDIT_MINOR | EDIT_FORCE_BOT, false, $wikiaUser); $results[$catNameKey] = 'done'; } else { $results[$catNameKey] = 'already exists'; } } } return $results; }
protected function createUserTalkPage(User $user) { global $wgAutoWelcomeNewUsers; if ($wgAutoWelcomeNewUsers) { $msgObj = wfMessage("confirmaccount-welc-pos{$this->type}"); $welcome = $msgObj->isDisabled() ? wfMessage('confirmaccount-welc')->text() : $msgObj->text(); // custom message # Add user welcome message! $article = new WikiPage($user->getTalkPage()); $article->doEdit("{$welcome} ~~~~", wfMessage('confirmaccount-wsum')->inContentLanguage()->text(), EDIT_MINOR, false, $this->admin); } }
/** * @todo FIXME: the above rollback test is better, but it keeps failing in jenkins for some reason. */ public function testDoRollback() { $admin = new User(); $admin->setName("Admin"); $text = "one"; $page = $this->newPage("WikiPageTest_testDoRollback"); $page->doEdit($text, "section one", EDIT_NEW, false, $admin); $rev1 = $page->getRevision(); $user1 = new User(); $user1->setName("127.0.1.11"); $text .= "\n\ntwo"; $page = new WikiPage($page->getTitle()); $page->doEdit($text, "adding section two", 0, false, $user1); # now, try the rollback $admin->addGroup("sysop"); #XXX: make the test user a sysop... $token = $admin->getEditToken(array($page->getTitle()->getPrefixedText(), $user1->getName()), null); $errors = $page->doRollback($user1->getName(), "testing revert", $token, false, $details, $admin); if ($errors) { $this->fail("Rollback failed:\n" . print_r($errors, true) . ";\n" . print_r($details, true)); } $page = new WikiPage($page->getTitle()); $this->assertEquals($rev1->getSha1(), $page->getRevision()->getSha1(), "rollback did not revert to the correct revision"); $this->assertEquals("one", $page->getText()); }
/** * This method handles embedded content protection. * Must be set onto ArticleSaveComplete hook AFTER articleSaveComplete_SaveSD * in order to handle newly created page SDs. */ public static function articleSaveComplete_SaveEmbedded(&$article, &$user, $text) { // Flag to prevent recursion static $InsideSaveEmbedded; if ($InsideSaveEmbedded) { return true; } $InsideSaveEmbedded = true; global $wgRequest, $wgOut, $haclgContLang, $wgUser; $isACL = $article->getTitle()->getNamespace() == HACL_NS_ACL; if ($isACL) { $articleSD = IACLDefinition::newFromTitle($article->getTitle(), false); if (!$articleSD || $articleSD['pe_type'] != IACL::PE_PAGE) { // This is not a page SD, do nothing. return true; } } else { // FIXME possibly use the category SD for category pages // the problem here is that in ACL editor two different SDs // may be created and queried for embedded content: // for category article and for category itself $articleSD = IACLDefinition::getSDForPE(IACL::PE_PAGE, $article->getId()); if (!$articleSD) { return true; } } // Handle embedded content protection $errors = array(); foreach ($wgRequest->getValues() as $k => $v) { if (substr($k, 0, 7) == 'sd_emb_' && $v) { $wgRequest->setVal($k, false); // clear value to handle embedded content only one time $emb_pe_id = intval(substr($k, 7)); $emb_title = Title::newFromId($emb_pe_id); list($req_sd_type, $req_sd_id, $emb_sd_revid) = explode('-', $v, 3); if ($emb_title) { $emb_sd_title = Title::newFromText(IACLDefinition::nameOfSD(IACL::PE_PAGE, $emb_title)); $emb_sd_article = new WikiPage($emb_sd_title); } // Check for errors: if (!$emb_title || !$emb_title->getArticleId() || !$emb_sd_title->userCan('edit')) { // Embedded content deleted || Manage access denied $errors[] = array($emb_title, 'canedit'); } elseif ($req_sd_type && $req_sd_id && "{$req_sd_type}-{$req_sd_id}" != $articleSD['key']) { // Invalid SD requested for protection $errors[] = array($emb_title, 'invalidsd'); } elseif (!$emb_sd_revid && $emb_sd_title->exists() || $emb_sd_revid && $emb_sd_title->getLatestRevId() != $emb_sd_revid) { // Mid-air collision: SD created/changed by someone in the meantime $errors[] = array($emb_title, 'midair'); } else { // Save embedded element SD $emb_sd_article->doEdit('{{#predefined right: ' . $articleSD['def_title'] . '}}', wfMsg('hacl_comment_protect_embedded', '' . $articleSD['def_title']), EDIT_FORCE_BOT); } } } // Display errors to the user, if any // This is safe to do as we are definitely in interactive non-batch edit mode if ($errors) { foreach ($errors as &$e) { $e = "[[:" . $e[0]->getPrefixedText() . "]] (" . wfMsg('hacl_embedded_error_' . $e[1]) . ")"; } $wgOut->setTitle(Title::newFromText('Special:IntraACL')); $wgOut->addWikiText(wfMsgNoTrans('hacl_embedded_not_saved', implode(", ", $errors), $article->getTitle()->getPrefixedText())); $wgOut->setPageTitle(wfMsg('hacl_embedded_not_saved_title')); $wgOut->output(); // FIXME terminate MediaWiki more correctly wfGetDB(DB_MASTER)->commit(); exit; } // Clear flag and continue hook processing $InsideSaveEmbedded = false; return true; }
protected function createUserTalkPage(User $user) { global $wgAutoWelcomeNewUsers; if ($wgAutoWelcomeNewUsers) { $msg = "confirmaccount-welc-pos{$this->type}"; $welcome = wfEmptyMsg($msg) ? wfMsg('confirmaccount-welc') : wfMsg($msg); // custom message # Add user welcome message! $article = new WikiPage($user->getTalkPage()); $article->doEdit("{$welcome} ~~~~", wfMsg('confirmaccount-wsum'), EDIT_MINOR, false, $this->admin); } }
/** * Submit the form parameters for the page config to the DB. * * @return mixed (true on success, error string on failure) */ public function doSubmit() { # Double-check permissions if (!$this->isAllowed()) { return 'review_denied'; } # We can only approve actual revisions... if ($this->getAction() === 'approve') { $rev = Revision::newFromTitle($this->page, $this->oldid); # Check for archived/deleted revisions... if (!$rev || $rev->getVisibility()) { return 'review_bad_oldid'; } # Check for review conflicts... if ($this->lastChangeTime !== null) { // API uses null $lastChange = $this->oldFrev ? $this->oldFrev->getTimestamp() : ''; if ($lastChange !== $this->lastChangeTime) { return 'review_conflict_oldid'; } } $status = $this->approveRevision($rev, $this->oldFrev); # We can only unapprove approved revisions... } elseif ($this->getAction() === 'unapprove') { # Check for review conflicts... if ($this->lastChangeTime !== null) { // API uses null $lastChange = $this->oldFrev ? $this->oldFrev->getTimestamp() : ''; if ($lastChange !== $this->lastChangeTime) { return 'review_conflict_oldid'; } } # Check if we can find this flagged rev... if (!$this->oldFrev) { return 'review_not_flagged'; } $status = $this->unapproveRevision($this->oldFrev); } elseif ($this->getAction() === 'reject') { $newRev = Revision::newFromTitle($this->page, $this->oldid); $oldRev = Revision::newFromTitle($this->page, $this->refid); # Do not mess with archived/deleted revisions if (!$oldRev || $oldRev->isDeleted(Revision::DELETED_TEXT)) { return 'review_bad_oldid'; } elseif (!$newRev || $newRev->isDeleted(Revision::DELETED_TEXT)) { return 'review_bad_oldid'; } # Check that the revs are in order if ($oldRev->getTimestamp() > $newRev->getTimestamp()) { return 'review_cannot_undo'; } # Make sure we are only rejecting pending changes $srev = FlaggedRevision::newFromStable($this->page, FR_MASTER); if ($srev && $oldRev->getTimestamp() < $srev->getRevTimestamp()) { return 'review_cannot_reject'; // not really a use case } $article = new WikiPage($this->page); # Get text with changes after $oldRev up to and including $newRev removed $new_text = $article->getUndoText($newRev, $oldRev); if ($new_text === false) { return 'review_cannot_undo'; } $baseRevId = $newRev->isCurrent() ? $oldRev->getId() : 0; # Actually make the edit... $editStatus = $article->doEdit($new_text, $this->getComment(), 0, $baseRevId, $this->user); $status = $editStatus->isOK() ? true : 'review_cannot_undo'; # If this undid one edit by another logged-in user, update user tallies if ($status === true && $newRev->getParentId() == $oldRev->getId() && $newRev->getRawUser()) { if ($newRev->getRawUser() != $this->user->getId()) { // no self-reverts FRUserCounters::incCount($newRev->getRawUser(), 'revertedEdits'); } } } # Watch page if set to do so if ($status === true) { if ($this->user->getOption('flaggedrevswatch') && !$this->page->userIsWatching()) { $this->user->addWatch($this->page); } } return $status; }