/** * Render the diff page * @return boolean false when revision not exist * @param string $par Revision IDs separated by three points (e.g. 123...124) */ function executeWhenAvailable($par) { $ctx = MobileContext::singleton(); $this->setHeaders(); $output = $this->getOutput(); // @FIXME add full support for git-style notation (eg ...123, 123...) $revisions = $this->getRevisionsToCompare(explode('...', $par)); $rev = $revisions[1]; $prev = $revisions[0]; if (is_null($rev)) { $this->executeBadQuery(); return false; } $this->revId = $rev->getId(); $this->rev = $rev; $this->prevRev = $prev; $this->targetTitle = $this->rev->getTitle(); $output->setPageTitle($this->msg('mobile-frontend-diffview-title', $this->targetTitle->getPrefixedText())); $output->addModuleStyles(array('mobile.pagesummary.styles', 'mobile.special.pagefeed.styles')); // Allow other extensions to load more stuff here Hooks::run('BeforeSpecialMobileDiffDisplay', array(&$output, $ctx, $revisions)); $output->addHtml('<div id="mw-mf-diffview" class="content-unstyled"><div id="mw-mf-diffarea">'); $this->showHeader(); $this->showDiff(); $output->addHtml('</div>'); $this->showFooter(); $output->addHtml('</div>'); return true; }
/** * Callback function for each revision, preprocessToObj() * @param Revision $rev */ public function processRevision($rev) { $content = $rev->getContent(Revision::RAW); if ($content->getModel() !== CONTENT_MODEL_WIKITEXT) { return; } try { $this->mPreprocessor->preprocessToObj(strval($content->getNativeData()), 0); } catch (Exception $e) { $this->error("Caught exception " . $e->getMessage() . " in " . $rev->getTitle()->getPrefixedText()); } }
/** * Load revision metadata for the specified articles. If newid is 0, then compare * the old article in oldid to the current article; if oldid is 0, then * compare the current article to the immediately previous one (ignoring the * value of newid). * * If oldid is false, leave the corresponding revision object set * to false. This is impossible via ordinary user input, and is provided for * API convenience. * * @return bool */ public function loadRevisionData() { if ($this->mRevisionsLoaded) { return true; } // Whether it succeeds or fails, we don't want to try again $this->mRevisionsLoaded = true; $this->loadRevisionIds(); // Load the new revision object if ($this->mNewid) { $this->mNewRev = Revision::newFromId($this->mNewid); } else { $this->mNewRev = Revision::newFromTitle($this->getTitle(), false, Revision::READ_NORMAL); } if (!$this->mNewRev instanceof Revision) { return false; } // Update the new revision ID in case it was 0 (makes life easier doing UI stuff) $this->mNewid = $this->mNewRev->getId(); $this->mNewPage = $this->mNewRev->getTitle(); // Load the old revision object $this->mOldRev = false; if ($this->mOldid) { $this->mOldRev = Revision::newFromId($this->mOldid); } elseif ($this->mOldid === 0) { $rev = $this->mNewRev->getPrevious(); if ($rev) { $this->mOldid = $rev->getId(); $this->mOldRev = $rev; } else { // No previous revision; mark to show as first-version only. $this->mOldid = false; $this->mOldRev = false; } } /* elseif ( $this->mOldid === false ) leave mOldRev false; */ if (is_null($this->mOldRev)) { return false; } if ($this->mOldRev) { $this->mOldPage = $this->mOldRev->getTitle(); } // Load tags information for both revisions $dbr = wfGetDB(DB_SLAVE); if ($this->mOldid !== false) { $this->mOldTags = $dbr->selectField('tag_summary', 'ts_tags', array('ts_rev_id' => $this->mOldid), __METHOD__); } else { $this->mOldTags = false; } $this->mNewTags = $dbr->selectField('tag_summary', 'ts_tags', array('ts_rev_id' => $this->mNewid), __METHOD__); return true; }
/** * Callback function for each revision, turn into HTML and save * @param Revision $rev */ public function handleRevision($rev) { $title = $rev->getTitle(); if (!$title) { $this->error("Got bogus revision with null title!"); return; } $display = $title->getPrefixedText(); $this->count++; $sanitized = rawurlencode($display); $filename = sprintf("%s/%s-%07d-%s.html", $this->outputDirectory, $this->prefix, $this->count, $sanitized); $this->output(sprintf("%s\n", $filename, $display)); $user = new User(); $options = ParserOptions::newFromUser($user); $content = $rev->getContent(); $output = $content->getParserOutput($title, null, $options); file_put_contents($filename, "<!DOCTYPE html>\n" . "<html lang=\"en\" dir=\"ltr\">\n" . "<head>\n" . "<meta charset=\"UTF-8\" />\n" . "<title>" . htmlspecialchars($display) . "</title>\n" . "</head>\n" . "<body>\n" . $output->getText() . "</body>\n" . "</html>"); }
/** * 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(); }
/** * @param Revision $rev */ function handleRevision($rev) { $title = $rev->getTitle(); if (!$title) { $this->progress("Got bogus revision with null title!"); return; } if ($this->skippedNamespace($title)) { return; } $this->revCount++; $this->report(); if (!$this->dryRun) { call_user_func($this->importCallback, $rev); } }
/** * Parse the text from a given Revision * * @param Revision $revision */ function runParser(Revision $revision) { $content = $revision->getContent(); $content->getParserOutput($revision->getTitle(), $revision->getId()); if ($this->clearLinkCache) { $this->linkCache->clear(); } }
/** * Wrap and format the given revision's comment block, if the current * user is allowed to view it. * * @param $rev Revision object * @param $local Boolean: whether section links should refer to local page * @param $isPublic Boolean: show only if all users can see it * @return String: HTML fragment */ static function revComment(Revision $rev, $local = false, $isPublic = false) { if ($rev->getRawComment() == "") { return ""; } if ($rev->isDeleted(Revision::DELETED_COMMENT) && $isPublic) { $block = " <span class=\"comment\">" . wfMsgHtml('rev-deleted-comment') . "</span>"; } elseif ($rev->userCan(Revision::DELETED_COMMENT)) { $block = self::commentBlock($rev->getComment(Revision::FOR_THIS_USER), $rev->getTitle(), $local); } else { $block = " <span class=\"comment\">" . wfMsgHtml('rev-deleted-comment') . "</span>"; } if ($rev->isDeleted(Revision::DELETED_COMMENT)) { return " <span class=\"history-deleted\">{$block}</span>"; } return $block; }
/** * Render the contribution of the pagerevision (time, bytes added/deleted, pagename comment) * @param Revision $rev */ protected function showContributionsRow(Revision $rev) { $user = $this->getUser(); $userId = $rev->getUser(Revision::FOR_THIS_USER, $user); if ($userId === 0) { $username = IP::prettifyIP($rev->getUserText(Revision::RAW)); $isAnon = true; } else { $username = $rev->getUserText(Revision::FOR_THIS_USER, $user); $isAnon = false; } // FIXME: Style differently user comment when this is the case if ($rev->userCan(Revision::DELETED_COMMENT, $user)) { $comment = $rev->getComment(Revision::FOR_THIS_USER, $user); $comment = $this->formatComment($comment, $this->title); } else { $comment = $this->msg('rev-deleted-comment')->plain(); } $ts = $rev->getTimestamp(); $this->renderListHeaderWhereNeeded($this->getLanguage()->userDate($ts, $this->getUser())); $ts = new MWTimestamp($ts); if ($rev->userCan(Revision::DELETED_TEXT, $user)) { $diffLink = SpecialPage::getTitleFor('MobileDiff', $rev->getId())->getLocalUrl(); } else { $diffLink = false; } // FIXME: Style differently user comment when this is the case if (!$rev->userCan(Revision::DELETED_USER, $user)) { $username = $this->msg('rev-deleted-user')->plain(); } $bytes = null; if (isset($this->prevLengths[$rev->getParentId()])) { $bytes = $rev->getSize() - $this->prevLengths[$rev->getParentId()]; } $isMinor = $rev->isMinor(); $this->renderFeedItemHtml($ts, $diffLink, $username, $comment, $rev->getTitle(), $isAnon, $bytes, $isMinor); }
/** * Get a header for a specified revision. * * @param $rev Revision * @param $complete String: 'complete' to get the header wrapped depending * the visibility of the revision and a link to edit the page. * @return String HTML fragment */ protected function getRevisionHeader(Revision $rev, $complete = '') { $lang = $this->getLanguage(); $user = $this->getUser(); $revtimestamp = $rev->getTimestamp(); $timestamp = $lang->userTimeAndDate($revtimestamp, $user); $dateofrev = $lang->userDate($revtimestamp, $user); $timeofrev = $lang->userTime($revtimestamp, $user); $header = $this->msg($rev->isCurrent() ? 'currentrev-asof' : 'revisionasof', $timestamp, $dateofrev, $timeofrev)->escaped(); if ($complete !== 'complete') { return $header; } $title = $rev->getTitle(); $header = Linker::linkKnown($title, $header, array(), array('oldid' => $rev->getID())); if ($rev->userCan(Revision::DELETED_TEXT, $user)) { $editQuery = array('action' => 'edit'); if (!$rev->isCurrent()) { $editQuery['oldid'] = $rev->getID(); } $msg = $this->msg($title->quickUserCan('edit', $user) ? 'editold' : 'viewsourceold')->escaped(); $header .= ' ' . $this->msg('parentheses')->rawParams(Linker::linkKnown($title, $msg, array(), $editQuery))->plain(); if ($rev->isDeleted(Revision::DELETED_TEXT)) { $header = Html::rawElement('span', array('class' => 'history-deleted'), $header); } } else { $header = Html::rawElement('span', array('class' => 'history-deleted'), $header); } return $header; }
/** * Extract information from the Revision * * @param Revision $revision * @param object $row Should have a field 'ts_tags' if $this->fld_tags is set * @return array */ protected function extractRevisionInfo(Revision $revision, $row) { $title = $revision->getTitle(); $user = $this->getUser(); $vals = array(); $anyHidden = false; if ($this->fld_ids) { $vals['revid'] = intval($revision->getId()); if (!is_null($revision->getParentId())) { $vals['parentid'] = intval($revision->getParentId()); } } if ($this->fld_flags) { $vals['minor'] = $revision->isMinor(); } if ($this->fld_user || $this->fld_userid) { if ($revision->isDeleted(Revision::DELETED_USER)) { $vals['userhidden'] = true; $anyHidden = true; } if ($revision->userCan(Revision::DELETED_USER, $user)) { if ($this->fld_user) { $vals['user'] = $revision->getUserText(Revision::RAW); } $userid = $revision->getUser(Revision::RAW); if (!$userid) { $vals['anon'] = true; } if ($this->fld_userid) { $vals['userid'] = $userid; } } } if ($this->fld_timestamp) { $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $revision->getTimestamp()); } if ($this->fld_size) { if (!is_null($revision->getSize())) { $vals['size'] = intval($revision->getSize()); } else { $vals['size'] = 0; } } if ($this->fld_sha1) { if ($revision->isDeleted(Revision::DELETED_TEXT)) { $vals['sha1hidden'] = true; $anyHidden = true; } if ($revision->userCan(Revision::DELETED_TEXT, $user)) { if ($revision->getSha1() != '') { $vals['sha1'] = wfBaseConvert($revision->getSha1(), 36, 16, 40); } else { $vals['sha1'] = ''; } } } if ($this->fld_contentmodel) { $vals['contentmodel'] = $revision->getContentModel(); } if ($this->fld_comment || $this->fld_parsedcomment) { if ($revision->isDeleted(Revision::DELETED_COMMENT)) { $vals['commenthidden'] = true; $anyHidden = true; } if ($revision->userCan(Revision::DELETED_COMMENT, $user)) { $comment = $revision->getComment(Revision::RAW); if ($this->fld_comment) { $vals['comment'] = $comment; } if ($this->fld_parsedcomment) { $vals['parsedcomment'] = Linker::formatComment($comment, $title); } } } if ($this->fld_tags) { if ($row->ts_tags) { $tags = explode(',', $row->ts_tags); ApiResult::setIndexedTagName($tags, 'tag'); $vals['tags'] = $tags; } else { $vals['tags'] = array(); } } $content = null; global $wgParser; if ($this->fetchContent) { $content = $revision->getContent(Revision::FOR_THIS_USER, $this->getUser()); // Expand templates after getting section content because // template-added sections don't count and Parser::preprocess() // will have less input if ($content && $this->section !== false) { $content = $content->getSection($this->section, false); if (!$content) { $this->dieUsage("There is no section {$this->section} in r" . $revision->getId(), 'nosuchsection'); } } if ($revision->isDeleted(Revision::DELETED_TEXT)) { $vals['texthidden'] = true; $anyHidden = true; } elseif (!$content) { $vals['textmissing'] = true; } } if ($this->fld_content && $content) { $text = null; if ($this->generateXML) { if ($content->getModel() === CONTENT_MODEL_WIKITEXT) { $t = $content->getNativeData(); # note: don't set $text $wgParser->startExternalParse($title, ParserOptions::newFromContext($this->getContext()), Parser::OT_PREPROCESS); $dom = $wgParser->preprocessToDom($t); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } $vals['parsetree'] = $xml; } else { $vals['badcontentformatforparsetree'] = true; $this->setWarning("Conversion to XML is supported for wikitext only, " . $title->getPrefixedDBkey() . " uses content model " . $content->getModel()); } } if ($this->expandTemplates && !$this->parseContent) { #XXX: implement template expansion for all content types in ContentHandler? if ($content->getModel() === CONTENT_MODEL_WIKITEXT) { $text = $content->getNativeData(); $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext())); } else { $this->setWarning("Template expansion is supported for wikitext only, " . $title->getPrefixedDBkey() . " uses content model " . $content->getModel()); $vals['badcontentformat'] = true; $text = false; } } if ($this->parseContent) { $po = $content->getParserOutput($title, $revision->getId(), ParserOptions::newFromContext($this->getContext())); $text = $po->getText(); } if ($text === null) { $format = $this->contentFormat ? $this->contentFormat : $content->getDefaultFormat(); $model = $content->getModel(); if (!$content->isSupportedFormat($format)) { $name = $title->getPrefixedDBkey(); $this->setWarning("The requested format {$this->contentFormat} is not " . "supported for content model {$model} used by {$name}"); $vals['badcontentformat'] = true; $text = false; } else { $text = $content->serialize($format); // always include format and model. // Format is needed to deserialize, model is needed to interpret. $vals['contentformat'] = $format; $vals['contentmodel'] = $model; } } if ($text !== false) { ApiResult::setContentValue($vals, 'content', $text); } } if ($content && (!is_null($this->diffto) || !is_null($this->difftotext))) { static $n = 0; // Number of uncached diffs we've had if ($n < $this->getConfig()->get('APIMaxUncachedDiffs')) { $vals['diff'] = array(); $context = new DerivativeContext($this->getContext()); $context->setTitle($title); $handler = $revision->getContentHandler(); if (!is_null($this->difftotext)) { $model = $title->getContentModel(); if ($this->contentFormat && !ContentHandler::getForModelID($model)->isSupportedFormat($this->contentFormat)) { $name = $title->getPrefixedDBkey(); $this->setWarning("The requested format {$this->contentFormat} is not " . "supported for content model {$model} used by {$name}"); $vals['diff']['badcontentformat'] = true; $engine = null; } else { $difftocontent = ContentHandler::makeContent($this->difftotext, $title, $model, $this->contentFormat); $engine = $handler->createDifferenceEngine($context); $engine->setContent($content, $difftocontent); } } else { $engine = $handler->createDifferenceEngine($context, $revision->getID(), $this->diffto); $vals['diff']['from'] = $engine->getOldid(); $vals['diff']['to'] = $engine->getNewid(); } if ($engine) { $difftext = $engine->getDiffBody(); ApiResult::setContentValue($vals['diff'], 'body', $difftext); if (!$engine->wasCacheHit()) { $n++; } } } else { $vals['diff']['notcached'] = true; } } if ($anyHidden && $revision->isDeleted(Revision::DELETED_RESTRICTED)) { $vals['suppressed'] = true; } return $vals; }
/** * Build a raw rollback link, useful for collections of "tool" links * * @param Revision $rev * @param IContextSource|null $context Context to use or null for the main context. * @param int $editCount Number of edits that would be reverted * @return string HTML fragment */ public static function buildRollbackLink($rev, IContextSource $context = null, $editCount = false) { global $wgShowRollbackEditCount, $wgMiserMode; // To config which pages are affected by miser mode $disableRollbackEditCountSpecialPage = array('Recentchanges', 'Watchlist'); if ($context === null) { $context = RequestContext::getMain(); } $title = $rev->getTitle(); $query = array('action' => 'rollback', 'from' => $rev->getUserText(), 'token' => $context->getUser()->getEditToken(array($title->getPrefixedText(), $rev->getUserText()))); if ($context->getRequest()->getBool('bot')) { $query['bot'] = '1'; $query['hidediff'] = '1'; // bug 15999 } $disableRollbackEditCount = false; if ($wgMiserMode) { foreach ($disableRollbackEditCountSpecialPage as $specialPage) { if ($context->getTitle()->isSpecial($specialPage)) { $disableRollbackEditCount = true; break; } } } if (!$disableRollbackEditCount && is_int($wgShowRollbackEditCount) && $wgShowRollbackEditCount > 0) { if (!is_numeric($editCount)) { $editCount = self::getRollbackEditCount($rev, false); } if ($editCount > $wgShowRollbackEditCount) { $editCount_output = $context->msg('rollbacklinkcount-morethan')->numParams($wgShowRollbackEditCount)->parse(); } else { $editCount_output = $context->msg('rollbacklinkcount')->numParams($editCount)->parse(); } return self::link($title, $editCount_output, array('title' => $context->msg('tooltip-rollback')->text()), $query, array('known', 'noclasses')); } else { return self::link($title, $context->msg('rollbacklink')->escaped(), array('title' => $context->msg('tooltip-rollback')->text()), $query, array('known', 'noclasses')); } }
function compareEventRecordWithRevision($dbname, $oRow, $debug) { global $wgTitle, $wgLanguageCode; $langcode = WikiFactory::getVarValueByName('wgLanguageCode', $oRow->wiki_id); $lang_id = WikiFactory::LangCodeToId($langcode); $cats = WikiFactory::getCategory($oRow->wiki_id); $cat_id = !empty($cats) ? $cats->cat_id : 0; $result = false; if (is_object($oRow) && !empty($oRow->page_id) && !empty($oRow->rev_id)) { $data = loadFromDB($dbname, $oRow->page_id, $oRow->rev_id); if (is_object($data)) { $oRevision = new Revision($data); if ($oRow->rev_id > 0) { $wgTitle = Title::makeTitle($data->page_namespace, $data->page_title); } else { $wgTitle = $oRevision->getTitle(); } $content = $oRevision->getText(Revision::FOR_THIS_USER); $is_bot = _user_is_bot($data->rev_user_text); $is_content = _revision_is_content(); $is_redirect = _revision_is_redirect($content); $size = intval($oRevision->getSize()); $words = str_word_count($content); $links = _make_links($oRow->page_id, $oRow->rev_id, $content); $timestamp = $data->ts; if ($data->rev_page == $oRow->page_id && $data->page_namespace == $oRow->page_ns && $data->rev_id == $oRow->rev_id && $timestamp == $oRow->rev_timestamp && $data->rev_user == $oRow->user_id && $is_bot == $oRow->user_is_bot && $is_content == $oRow->is_content && $is_redirect == $oRow->is_redirect && $size == $oRow->rev_size && $words == $oRow->total_words && $cat_id == $oRow->wiki_cat_id && $lang_id == $oRow->wiki_lang_id && $links['image'] == $oRow->image_links && $links['video'] == $oRow->video_links) { $result = true; } else { if ($debug) { echo <<<TEXT \tpage: {$data->rev_page} == {$oRow->page_id} \tnamespage: {$data->page_namespace}\t== {$oRow->page_ns} \trevision: {$data->rev_id}\t== {$oRow->rev_id} \ttimestamp: {$timestamp} == {$oRow->rev_timestamp} \tuser: {$data->rev_user} == {$oRow->user_id} \tis_bot: {$is_bot} == {$oRow->user_is_bot} \tis_content: {$is_content} == {$oRow->is_content} \tis_redirect: {$is_redirect} == {$oRow->is_redirect} \tsize: {$size} == {$oRow->rev_size} \twords: {$words} == {$oRow->total_words} \tcategory: {$cat_id} == {$oRow->wiki_cat_id} \tlanguage: {$lang_id} == {$oRow->wiki_lang_id} \timage links:{$links['image']} == {$oRow->image_links} \tvideo links: {$links['video']} == {$oRow->video_links} TEXT; } } } else { echo "Not local data found for: page: {$oRow->page_id} && revision: {$oRow->rev_id} \n"; } } else { echo "Not events data found for: page: {$oRow->page_id} && revision: {$oRow->rev_id} \n"; } return $result; }
/** * Callback function for each revision, parse with both parsers and compare * @param Revision $rev */ public function processRevision($rev) { $title = $rev->getTitle(); $parser1Name = $this->getOption('parser1'); $parser2Name = $this->getOption('parser2'); self::checkParserLocally($parser1Name); self::checkParserLocally($parser2Name); $parser1 = new $parser1Name(); $parser2 = new $parser2Name(); $content = $rev->getContent(); if ($content->getModel() !== CONTENT_MODEL_WIKITEXT) { $this->error("Page {$title->getPrefixedText()} does not contain wikitext " . "but {$content->getModel()}\n"); return; } $text = strval($content->getNativeData()); $output1 = $parser1->parse($text, $title, $this->options); $output2 = $parser2->parse($text, $title, $this->options); if ($output1->getText() != $output2->getText()) { $this->failed++; $this->error("Parsing for {$title->getPrefixedText()} differs\n"); if ($this->saveFailed) { file_put_contents($this->saveFailed . '/' . rawurlencode($title->getPrefixedText()) . ".txt", $text); } if ($this->showDiff) { $this->output(wfDiff($this->stripParameters($output1->getText()), $this->stripParameters($output2->getText()), '')); } } else { $this->output($title->getPrefixedText() . "\tOK\n"); if ($this->showParsedOutput) { $this->output($this->stripParameters($output1->getText())); } } }
/** * Build a raw rollback link, useful for collections of "tool" links * * @param Revision $rev * @return string */ public function buildRollbackLink($rev) { global $wgRequest, $wgUser; $title = $rev->getTitle(); $extra = $wgRequest->getBool('bot') ? '&bot=1' : ''; $extra .= '&token=' . urlencode($wgUser->editToken(array($title->getPrefixedText(), $rev->getUserText()))); return $this->makeKnownLinkObj($title, wfMsgHtml('rollbacklink'), 'action=rollback&from=' . urlencode($rev->getUserText()) . $extra); }
/** * Get a header for a specified revision. * * @param $rev Revision * @param $complete String: 'complete' to get the header wrapped depending * the visibility of the revision and a link to edit the page. * @return String HTML fragment */ private function getRevisionHeader(Revision $rev, $complete = '') { $lang = $this->getLanguage(); $user = $this->getUser(); $revtimestamp = $rev->getTimestamp(); $timestamp = $lang->userTimeAndDate($revtimestamp, $user); $dateofrev = $lang->userDate($revtimestamp, $user); $timeofrev = $lang->userTime($revtimestamp, $user); $header = $this->msg($rev->isCurrent() ? 'currentrev-asof' : 'revisionasof', $timestamp, $dateofrev, $timeofrev)->escaped(); if ($complete !== 'complete') { return $header; } $title = $rev->getTitle(); $header = Linker::linkKnown($title, $header, array(), array('oldid' => $rev->getID())); if ($rev->userCan(Revision::DELETED_TEXT, $user)) { $editQuery = array('action' => 'edit'); if (!$rev->isCurrent()) { $editQuery['oldid'] = $rev->getID(); } $msg = $this->msg($title->userCan('edit', $user) ? 'editold' : 'viewsourceold')->escaped(); /* Wikia Change begin */ $header .= ' <span class="mw-rev-head-action">(' . Linker::linkKnown($title, $msg, array(), $editQuery) . ')</span>'; /* Wikia Change end */ if ($rev->isDeleted(Revision::DELETED_TEXT)) { $header = Html::rawElement('span', array('class' => 'history-deleted'), $header); } } else { $header = Html::rawElement('span', array('class' => 'history-deleted'), $header); } return $header; }
private function extractRowInfo($row) { $revision = new Revision($row); $title = $revision->getTitle(); $vals = array(); if ($this->fld_ids) { $vals['revid'] = intval($revision->getId()); // $vals['oldid'] = intval( $row->rev_text_id ); // todo: should this be exposed? if (!is_null($revision->getParentId())) { $vals['parentid'] = intval($revision->getParentId()); } } if ($this->fld_flags && $revision->isMinor()) { $vals['minor'] = ''; } if ($this->fld_user || $this->fld_userid) { if ($revision->isDeleted(Revision::DELETED_USER)) { $vals['userhidden'] = ''; } else { if ($this->fld_user) { $vals['user'] = $revision->getUserText(); } $userid = $revision->getUser(); if (!$userid) { $vals['anon'] = ''; } if ($this->fld_userid) { $vals['userid'] = $userid; } } } if ($this->fld_timestamp) { $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $revision->getTimestamp()); } if ($this->fld_size) { if (!is_null($revision->getSize())) { $vals['size'] = intval($revision->getSize()); } else { $vals['size'] = 0; } } if ($this->fld_sha1) { if ($revision->getSha1() != '') { $vals['sha1'] = wfBaseConvert($revision->getSha1(), 36, 16, 40); } else { $vals['sha1'] = ''; } } if ($this->fld_comment || $this->fld_parsedcomment) { if ($revision->isDeleted(Revision::DELETED_COMMENT)) { $vals['commenthidden'] = ''; } else { $comment = $revision->getComment(); if ($this->fld_comment) { $vals['comment'] = $comment; } if ($this->fld_parsedcomment) { $vals['parsedcomment'] = Linker::formatComment($comment, $title); } } } if ($this->fld_tags) { if ($row->ts_tags) { $tags = explode(',', $row->ts_tags); $this->getResult()->setIndexedTagName($tags, 'tag'); $vals['tags'] = $tags; } else { $vals['tags'] = array(); } } if (!is_null($this->token)) { $tokenFunctions = $this->getTokenFunctions(); foreach ($this->token as $t) { $val = call_user_func($tokenFunctions[$t], $title->getArticleID(), $title, $revision); if ($val === false) { $this->setWarning("Action '{$t}' is not allowed for the current user"); } else { $vals[$t . 'token'] = $val; } } } $text = null; global $wgParser; if ($this->fld_content || !is_null($this->difftotext)) { $text = $revision->getText(); // Expand templates after getting section content because // template-added sections don't count and Parser::preprocess() // will have less input if ($this->section !== false) { $text = $wgParser->getSection($text, $this->section, false); if ($text === false) { $this->dieUsage("There is no section {$this->section} in r" . $revision->getId(), 'nosuchsection'); } } } if ($this->fld_content && !$revision->isDeleted(Revision::DELETED_TEXT)) { if ($this->generateXML) { $wgParser->startExternalParse($title, ParserOptions::newFromContext($this->getContext()), OT_PREPROCESS); $dom = $wgParser->preprocessToDom($text); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } $vals['parsetree'] = $xml; } if ($this->expandTemplates && !$this->parseContent) { $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext())); } if ($this->parseContent) { $text = $wgParser->parse($text, $title, ParserOptions::newFromContext($this->getContext()))->getText(); } ApiResult::setContent($vals, $text); } elseif ($this->fld_content) { $vals['texthidden'] = ''; } if (!is_null($this->diffto) || !is_null($this->difftotext)) { global $wgAPIMaxUncachedDiffs; static $n = 0; // Number of uncached diffs we've had if ($n < $wgAPIMaxUncachedDiffs) { $vals['diff'] = array(); $context = new DerivativeContext($this->getContext()); $context->setTitle($title); if (!is_null($this->difftotext)) { $engine = new DifferenceEngine($context); $engine->setText($text, $this->difftotext); } else { $engine = new DifferenceEngine($context, $revision->getID(), $this->diffto); $vals['diff']['from'] = $engine->getOldid(); $vals['diff']['to'] = $engine->getNewid(); } $difftext = $engine->getDiffBody(); ApiResult::setContent($vals['diff'], $difftext); if (!$engine->wasCacheHit()) { $n++; } } else { $vals['diff']['notcached'] = ''; } } return $vals; }
/** * revisionInsertComplete * * static method called as hook * * @static * @access public * * @param Revision $revision revision object * @param string $url url to external object * @param string $flags flags for this revision * * @return true means process other hooks */ public static function revisionInsertComplete(&$revision, $url, $flags) { global $wgUser, $wgCityId, $wgCommandLineMode, $wgSharedDB, $wgErrorLog, $wgMemc, $wgRequest; //do nothing if the user clicked 'undo' if ($wgRequest->getVal('wpUndoEdit')) { return true; } wfProfileIn(__METHOD__); /* first edit? */ //if (User::edits($wgUser->getID()) == 1) { /** * Do not create task when DB is locked (rt#12229) * Do not create task when we are in $wgCommandLineMode */ $oldValue = $wgErrorLog; $wgErrorLog = true; if (!wfReadOnly() && !$wgCommandLineMode) { wfLoadExtensionMessages("HAWelcome"); /** * Revision has valid Title field but sometimes not filled */ $Title = $revision->getTitle(); if (!$Title) { $Title = Title::newFromId($revision->getPage(), GAID_FOR_UPDATE); $revision->setTitle($Title); } /** * get groups for user rt#12215 */ $groups = $wgUser->getEffectiveGroups(); $invalid = array("bot" => true, "staff" => true, "helper" => true, "sysop" => true, "bureaucrat" => true, "vstf" => true); $canWelcome = true; foreach ($groups as $group) { if (isset($invalid[$group]) && $invalid[$group]) { $canWelcome = false; break; } } /** * put possible welcomer into memcached, RT#14067 */ if ($wgUser->getId() && self::isWelcomer($wgUser)) { //$wgMemc->set( wfMemcKey( "last-sysop-id" ), $wgUser->getId(), 86400 ); $wgMemc->set(wfMemcKey("last-sysop-id"), $wgUser->getId(), 3600); } if ($Title && $canWelcome && !empty($wgSharedDB)) { $welcomer = trim(wfMsgForContent("welcome-user")); if ($welcomer !== "@disabled" && $welcomer !== "-") { /** * check if talk page for wgUser exists * * @todo check editcount for user */ $talkPage = $wgUser->getUserPage()->getTalkPage(); if ($talkPage) { $talkArticle = new Article($talkPage, 0); if (!$talkArticle->exists()) { //run the talk page stuff self::runEditThanks($Title); } } } } } //} $wgErrorLog = $oldValue; wfProfileOut(__METHOD__); return true; }
/** * revisionInsertComplete * * static method called as hook * * @static * @access public * * @param Revision $revision revision object * @param string $url url to external object * @param string $flags flags for this revision * * @return true means process other hooks */ public static function revisionInsertComplete(&$revision, $url, $flags) { global $wgUser, $wgCityId, $wgCommandLineMode, $wgSharedDB, $wgErrorLog, $wgMemc, $wgRequest; wfProfileIn(__METHOD__); /** * Do not create task when DB is locked (rt#12229) * Do not create task when we are in $wgCommandLineMode */ $oldValue = $wgErrorLog; $wgErrorLog = true; if (!wfReadOnly() && !$wgCommandLineMode) { /** * Revision has valid Title field but sometimes not filled */ $Title = $revision->getTitle(); if (!$Title) { $Title = Title::newFromId($revision->getPage(), Title::GAID_FOR_UPDATE); $revision->setTitle($Title); } /** * get groups for user rt#12215 */ $groups = $wgUser->getEffectiveGroups(); $invalid = array("bot" => true, "bot-global" => true, "staff" => true, "helper" => true, "sysop" => true, "bureaucrat" => true, "vstf" => true); $canWelcome = true; foreach ($groups as $group) { if (isset($invalid[$group]) && $invalid[$group]) { $canWelcome = false; Wikia::log(__METHOD__, $wgUser->getId(), "Skip welcome, user is at least in group: " . $group); break; } } /** * put possible welcomer into memcached, RT#14067 */ if ($wgUser->getId() && self::isWelcomer($wgUser)) { // BugId:41817 - if ( 1 == $wgUser->getId() ) { notify Mix } if (1 == $wgUser->getId()) { $oTo = $oFrom = new MailAddress('*****@*****.**'); UserMailer::send($oTo, $oFrom, 'BugId:41817 Occurrence Report', sprintf("File: %s\nLine: %s, Date: %s\nOutput: %s", __FILE__, __LINE__, date('Y-m-d H:i:s'), var_export($wgUser->getId(), true))); } $wgMemc->set(wfMemcKey("last-sysop-id"), $wgUser->getId(), 86400); Wikia::log(__METHOD__, $wgUser->getId(), "Store possible welcomer in memcached"); } if ($Title && $canWelcome && !empty($wgSharedDB)) { Wikia::log(__METHOD__, "title", $Title->getFullURL()); $welcomer = trim(wfMsgForContent("welcome-user")); Wikia::log(__METHOD__, "welcomer", $welcomer); if ($welcomer !== "@disabled" && $welcomer !== "-") { /** * check if talk page for wgUser exists * * @todo check editcount for user */ Wikia::log(__METHOD__, "user", $wgUser->getName()); $talkPage = $wgUser->getUserPage()->getTalkPage(); if ($talkPage) { $talkArticle = new Article($talkPage, 0); if (!self::isPosted($talkArticle, $wgUser)) { $welcomeJob = new HAWelcomeJob($Title, array("is_anon" => $wgUser->isAnon(), "user_id" => $wgUser->getId(), "user_ip" => $wgRequest->getIP(), "user_name" => $wgUser->getName())); $welcomeJob->insert(); Wikia::log(__METHOD__, "job"); /** * inform task manager */ $Task = new HAWelcomeTask(); $taskId = $Task->createTask(array("city_id" => $wgCityId), TASK_QUEUED); Wikia::log(__METHOD__, "task", $taskId); } else { Wikia::log(__METHOD__, "exists", sprintf("Talk page for user %s already exits", $wgUser->getName())); } } } else { Wikia::log(__METHOD__, "disabled"); } } } $wgErrorLog = $oldValue; wfProfileOut(__METHOD__); return true; }
/** * Page moving and page protection (and possibly other things) creates null * revisions. These revisions re-use the previous text already stored in * the database. Those however do not trigger re-parsing of the page and * thus the ready tag is not updated. This watches for new revisions, * checks if they reuse existing text, checks whether the parent version * is the latest version and has a ready tag. If that is the case, * also adds a ready tag for the new revision (which is safe, because * the text hasn't changed). The interface will say that there has been * a change, but shows no change in the content. This lets the user to * update the translation pages in the case, the non-text changes affect * the rendering of translation pages. I'm not aware of any such cases * at the moment. * Hook: RevisionInsertComplete * @since 2012-05-08 */ public static function updateTranstagOnNullRevisions(Revision $rev, $text, $flags) { $title = $rev->getTitle(); $newRevId = $rev->getId(); $oldRevId = $rev->getParentId(); $newTextId = $rev->getTextId(); /* This hook doesn't provide any way to detech null revisions * without extra query */ $dbw = wfGetDB(DB_MASTER); $table = 'revision'; $field = 'rev_text_id'; $conds = array('rev_page' => $rev->getPage(), 'rev_id' => $oldRevId); // FIXME: optimize away this query. Bug T38588. $oldTextId = $dbw->selectField($table, $field, $conds, __METHOD__); if (strval($newTextId) !== strval($oldTextId)) { // Not a null revision, bail out. return true; } $page = TranslatablePage::newFromTitle($title); if ($page->getReadyTag() === $oldRevId) { $page->addReadyTag($newRevId); } return true; }
function formatRevisionRow($row) { global $wgUser, $wgLang; $rev = new Revision($row); $stxt = ''; $last = $this->message['last']; $ts = wfTimestamp(TS_MW, $row->rev_timestamp); $checkBox = Xml::radio("mergepoint", $ts, false); $pageLink = $this->sk->makeKnownLinkObj($rev->getTitle(), htmlspecialchars($wgLang->timeanddate($ts)), 'oldid=' . $rev->getId()); if ($rev->isDeleted(Revision::DELETED_TEXT)) { $pageLink = '<span class="history-deleted">' . $pageLink . '</span>'; } # Last link if (!$rev->userCan(Revision::DELETED_TEXT)) { $last = $this->message['last']; } else { if (isset($this->prevId[$row->rev_id])) { $last = $this->sk->makeKnownLinkObj($rev->getTitle(), $this->message['last'], "diff=" . $row->rev_id . "&oldid=" . $this->prevId[$row->rev_id]); } } $userLink = $this->sk->revUserTools($rev); if (!is_null($size = $row->rev_len)) { $stxt = $this->sk->formatRevisionSize($size); } $comment = $this->sk->revComment($rev); return "<li>{$checkBox} ({$last}) {$pageLink} . . {$userLink} {$stxt} {$comment}</li>"; }
/** * @param Revision $rev * @param string $prefix * @return string */ private function diffHeader($rev, $prefix) { $isDeleted = !($rev->getId() && $rev->getTitle()); if ($isDeleted) { /// @todo FIXME: $rev->getTitle() is null for deleted revs...? $targetPage = $this->getTitle(); $targetQuery = array('target' => $this->mTargetObj->getPrefixedText(), 'timestamp' => wfTimestamp(TS_MW, $rev->getTimestamp())); } else { /// @todo FIXME: getId() may return non-zero for deleted revs... $targetPage = $rev->getTitle(); $targetQuery = array('oldid' => $rev->getId()); } // Add show/hide deletion links if available $user = $this->getUser(); $lang = $this->getLanguage(); $rdel = Linker::getRevDeleteLink($user, $rev, $this->mTargetObj); if ($rdel) { $rdel = " {$rdel}"; } return '<div id="mw-diff-' . $prefix . 'title1"><strong>' . Linker::link($targetPage, $this->msg('revisionasof', $lang->userTimeAndDate($rev->getTimestamp(), $user), $lang->userDate($rev->getTimestamp(), $user), $lang->userTime($rev->getTimestamp(), $user))->escaped(), array(), $targetQuery) . '</strong></div>' . '<div id="mw-diff-' . $prefix . 'title2">' . Linker::revUserTools($rev) . '<br />' . '</div>' . '<div id="mw-diff-' . $prefix . 'title3">' . Linker::revComment($rev) . $rdel . '<br />' . '</div>'; }
/** * Show a row in history, including: * time of edit * changed bytes * name of editor * comment of edit * @param Revision $rev Revision id of the row wants to show * @param Revision|null $prev Revision id of previous Revision to display the difference */ protected function showRow(Revision $rev, $prev) { $user = $this->getUser(); $userId = $rev->getUser(Revision::FOR_THIS_USER, $user); if ($userId === 0) { $username = IP::prettifyIP($rev->getUserText(Revision::RAW)); $isAnon = true; } else { $username = $rev->getUserText(Revision::FOR_THIS_USER, $user); $isAnon = false; } // FIXME: Style differently user comment when this is the case if ($rev->userCan(Revision::DELETED_COMMENT, $user)) { $comment = $rev->getComment(Revision::FOR_THIS_USER, $user); $comment = $this->formatComment($comment, $this->title); } else { $comment = $this->msg('rev-deleted-comment')->plain(); } $ts = $rev->getTimestamp(); $this->renderListHeaderWhereNeeded($this->getLanguage()->userDate($ts, $this->getUser())); $ts = new MWTimestamp($ts); $canSeeText = $rev->userCan(Revision::DELETED_TEXT, $user); if ($canSeeText && $prev && $prev->userCan(Revision::DELETED_TEXT, $user)) { $diffLink = SpecialPage::getTitleFor('MobileDiff', $rev->getId())->getLocalUrl(); } elseif ($canSeeText && $rev->getTitle() !== null) { $diffLink = $rev->getTitle()->getLocalUrl(array('oldid' => $rev->getId())); } else { $diffLink = false; } // FIXME: Style differently user comment when this is the case if (!$rev->userCan(Revision::DELETED_USER, $user)) { $username = $this->msg('rev-deleted-user')->plain(); } // When the page is named there is no need to print it in output if ($this->title) { $title = null; } else { $title = $rev->getTitle(); } $bytes = $rev->getSize(); if ($prev) { $bytes -= $prev->getSize(); } $isMinor = $rev->isMinor(); $this->renderFeedItemHtml($ts, $diffLink, $username, $comment, $title, $isAnon, $bytes, $isMinor); }
public static function contributionsLineEndingProcess(ContribsPager &$contribsPager, &$ret, $row) { wfProfileIn(__METHOD__); $rev = new Revision($row); $page = $rev->getTitle(); $page->resetArticleId($row->rev_page); $wfMsgOptsBase = self::getMessageOptions(null, $row); $isThread = $wfMsgOptsBase['isThread']; $isNew = $wfMsgOptsBase['isNew']; // Don't show useless link to people who cannot hide revisions $del = Linker::getRevDeleteLink($contribsPager->getUser(), $rev, $page); if ($del !== '') { $del .= ' '; } else { $del = ''; } // VOLDEV-40: remove html messages $ret = $del; $ret .= Linker::linkKnown($page, $contribsPager->getLanguage()->userTimeAndDate($row->rev_timestamp, $contribsPager->getUser()), [], ['oldid' => $row->rev_id]) . ' ('; if ($isNew) { $ret .= $contribsPager->msg('diff')->escaped(); } else { $ret .= Linker::linkKnown($page, $contribsPager->msg('diff')->escaped(), [], ['diff' => 'prev', 'oldid' => $row->rev_id]); } $wallMessage = new WallMessage($page); $threadId = $wallMessage->getMessagePageId(); $threadTitle = Title::newFromText($threadId, NS_USER_WALL_MESSAGE); $ret .= ' | ' . Linker::linkKnown($threadTitle, $contribsPager->msg('hist')->escaped(), [], ['action' => 'history']) . ') '; if ($isThread && $isNew) { $ret .= ChangesList::flag('newpage') . ' '; } if (MWNamespace::getSubject($row->page_namespace) === NS_WIKIA_FORUM_BOARD && empty($wfMsgOptsBase['articleTitleVal'])) { $wfMsgOptsBase['articleTitleTxt'] = $contribsPager->msg('forum-recentchanges-deleted-reply-title')->text(); } $prefix = MWNamespace::getSubject($row->page_namespace) === NS_WIKIA_FORUM_BOARD ? 'forum' : 'wall'; $ret .= $contribsPager->msg($prefix . '-contributions-line')->params($wfMsgOptsBase['articleTitle'])->rawParams(htmlspecialchars($wfMsgOptsBase['articleTitleTxt']))->params($wfMsgOptsBase['wallTitleTxt'], $wfMsgOptsBase['wallPageName'])->parse(); if (!$isNew) { $summary = $rev->getComment(); if (empty($summary)) { $msg = Linker::commentBlock($contribsPager->msg(static::getMessagePrefix($row->page_namespace) . '-edit')->inContentLanguage()->text()); } else { $msg = Linker::revComment($rev, false, true); } $ret .= ' ' . $contribsPager->getLanguage()->getDirMark() . $msg; } wfProfileOut(__METHOD__); return true; }
/** * @param Revision $rev * @param string $prefix * @return string */ private function diffHeader($rev, $prefix) { $isDeleted = !($rev->getId() && $rev->getTitle()); if ($isDeleted) { /// @todo FIXME: $rev->getTitle() is null for deleted revs...? $targetPage = $this->getPageTitle(); $targetQuery = array('target' => $this->mTargetObj->getPrefixedText(), 'timestamp' => wfTimestamp(TS_MW, $rev->getTimestamp())); } else { /// @todo FIXME: getId() may return non-zero for deleted revs... $targetPage = $rev->getTitle(); $targetQuery = array('oldid' => $rev->getId()); } // Add show/hide deletion links if available $user = $this->getUser(); $lang = $this->getLanguage(); $rdel = Linker::getRevDeleteLink($user, $rev, $this->mTargetObj); if ($rdel) { $rdel = " {$rdel}"; } $minor = $rev->isMinor() ? ChangesList::flag('minor') : ''; $tags = wfGetDB(DB_SLAVE)->selectField('tag_summary', 'ts_tags', array('ts_rev_id' => $rev->getId()), __METHOD__); $tagSummary = ChangeTags::formatSummaryRow($tags, 'deleteddiff'); // FIXME This is reimplementing DifferenceEngine#getRevisionHeader // and partially #showDiffPage, but worse return '<div id="mw-diff-' . $prefix . 'title1"><strong>' . Linker::link($targetPage, $this->msg('revisionasof', $lang->userTimeAndDate($rev->getTimestamp(), $user), $lang->userDate($rev->getTimestamp(), $user), $lang->userTime($rev->getTimestamp(), $user))->escaped(), array(), $targetQuery) . '</strong></div>' . '<div id="mw-diff-' . $prefix . 'title2">' . Linker::revUserTools($rev) . '<br />' . '</div>' . '<div id="mw-diff-' . $prefix . 'title3">' . $minor . Linker::revComment($rev) . $rdel . '<br />' . '</div>' . '<div id="mw-diff-' . $prefix . 'title5">' . $tagSummary[0] . '<br />' . '</div>'; }
/** * @param Revision $rev */ public function processRevision($rev) { if (preg_match($this->getOption('regex'), $rev->getContent()->getTextForSearchIndex())) { $this->output($rev->getTitle() . " matches at edit from " . $rev->getTimestamp() . "\n"); } }
function formatRevisionRow($row) { $rev = new Revision($row); $stxt = ''; $last = $this->msg('last')->escaped(); $ts = wfTimestamp(TS_MW, $row->rev_timestamp); $checkBox = Xml::radio('mergepoint', $ts, $this->mTimestamp === $ts); $user = $this->getUser(); $pageLink = Linker::linkKnown($rev->getTitle(), htmlspecialchars($this->getLanguage()->userTimeAndDate($ts, $user)), [], ['oldid' => $rev->getId()]); if ($rev->isDeleted(Revision::DELETED_TEXT)) { $pageLink = '<span class="history-deleted">' . $pageLink . '</span>'; } # Last link if (!$rev->userCan(Revision::DELETED_TEXT, $user)) { $last = $this->msg('last')->escaped(); } elseif (isset($this->prevId[$row->rev_id])) { $last = Linker::linkKnown($rev->getTitle(), $this->msg('last')->escaped(), [], ['diff' => $row->rev_id, 'oldid' => $this->prevId[$row->rev_id]]); } $userLink = Linker::revUserTools($rev); $size = $row->rev_len; if (!is_null($size)) { $stxt = Linker::formatRevisionSize($size); } $comment = Linker::revComment($rev); return Html::rawElement('li', [], $this->msg('mergehistory-revisionrow')->rawParams($checkBox, $last, $pageLink, $userLink, $stxt, $comment)->escaped()); }
/** * @brief Adjusting Special:Contributions * * @param ContribsPager $contribsPager * @param String $ret string passed to wgOutput * @param Object $row Std Object with values from database table * * @return true */ public function onContributionsLineEnding(&$contribsPager, &$ret, $row) { wfProfileIn(__METHOD__); $app = F::app(); if (isset($row->page_namespace) && in_array(MWNamespace::getSubject($row->page_namespace), $app->wg->WallNS)) { $topmarktext = ''; $rev = new Revision($row); $page = $rev->getTitle(); $page->resetArticleId($row->rev_page); $skin = $app->wg->User->getSkin(); $wfMsgOptsBase = $this->getMessageOptions(null, $row, true); $isThread = $wfMsgOptsBase['isThread']; $isNew = $wfMsgOptsBase['isNew']; $wfMsgOptsBase['createdAt'] = Xml::element('a', array('href' => $wfMsgOptsBase['articleUrl']), $app->wg->Lang->timeanddate($app->wf->Timestamp(TS_MW, $row->rev_timestamp), true)); if ($isNew) { $wfMsgOptsBase['DiffLink'] = $app->wf->Msg('diff'); } else { $query = array('diff' => 'prev', 'oldid' => $row->rev_id); $wfMsgOptsBase['DiffLink'] = Xml::element('a', array('href' => $rev->getTitle()->getLocalUrl($query)), $app->wf->Msg('diff')); } $wallMessage = F::build('WallMessage', array($page)); $historyLink = $wallMessage->getMessagePageUrl(true) . '?action=history'; $wfMsgOptsBase['historyLink'] = Xml::element('a', array('href' => $historyLink), $app->wf->Msg('hist')); // Don't show useless link to people who cannot hide revisions $canHide = $app->wg->User->isAllowed('deleterevision'); if ($canHide || $rev->getVisibility() && $app->wg->User->isAllowed('deletedhistory')) { if (!$rev->userCan(Revision::DELETED_RESTRICTED)) { $del = $skin->revDeleteLinkDisabled($canHide); // revision was hidden from sysops } else { $query = array('type' => 'revision', 'target' => $page->getPrefixedDbkey(), 'ids' => $rev->getId()); $del = $skin->revDeleteLink($query, $rev->isDeleted(Revision::DELETED_RESTRICTED), $canHide); } $del .= ' '; } else { $del = ''; } $ret = $del; if (wfRunHooks('WallContributionsLine', array(MWNamespace::getSubject($row->page_namespace), $wallMessage, $wfMsgOptsBase, &$ret))) { $wfMsgOpts = array($wfMsgOptsBase['articleUrl'], $wfMsgOptsBase['articleTitleTxt'], $wfMsgOptsBase['wallPageUrl'], $wfMsgOptsBase['wallPageName'], $wfMsgOptsBase['createdAt'], $wfMsgOptsBase['DiffLink'], $wfMsgOptsBase['historyLink']); if ($isThread && $isNew) { $wfMsgOpts[7] = Xml::element('strong', array(), wfMsg('newpageletter') . ' '); } else { $wfMsgOpts[7] = ''; } $ret .= $app->wf->Msg('wall-contributions-wall-line', $wfMsgOpts); } if (!$isNew) { $summary = $rev->getComment(); if (empty($summary)) { $msg = $app->wf->MsgForContent($this->getMessagePrefix($row->page_namespace) . '-edit'); } else { $msg = $app->wf->MsgForContent('wall-recentchanges-summary', $summary); } $ret .= ' ' . Xml::openElement('span', array('class' => 'comment')) . $msg . Xml::closeElement('span'); } } wfProfileOut(__METHOD__); return true; }
/** * Parse the text from a given Revision * * @param Revision $revision */ function runParser(Revision $revision) { $content = $revision->getContent(); $content->getParserOutput($revision->getTitle(), $revision->getId()); }
/** * Build a raw rollback link, useful for collections of "tool" links * * @param Revision $rev * @return string */ public function buildRollbackLink($rev) { global $wgRequest, $wgUser; $title = $rev->getTitle(); $query = array('action' => 'rollback', 'from' => $rev->getUserText()); if ($wgRequest->getBool('bot')) { $query['bot'] = '1'; $query['hidediff'] = '1'; // bug 15999 } $query['token'] = $wgUser->editToken(array($title->getPrefixedText(), $rev->getUserText())); return $this->link($title, wfMsgHtml('rollbacklink'), array('title' => wfMsg('tooltip-rollback')), $query, array('known', 'noclasses')); }