/**
  * @deprecated since 1.24
  * @param int $pageid
  * @param Title $title
  * @param Revision $rev
  * @return bool|string
  */
 public static function getRollbackToken($pageid, $title, $rev)
 {
     global $wgUser;
     if (!$wgUser->isAllowed('rollback')) {
         return false;
     }
     return $wgUser->getEditToken(array($title->getPrefixedText(), $rev->getUserText()));
 }
Esempio n. 2
0
	/**
	 * @param $audience Integer: one of:
	 *      Revision::FOR_PUBLIC       to be displayed to all users
	 *      Revision::FOR_THIS_USER    to be displayed to the given user
	 *      Revision::RAW              get the text regardless of permissions
	 * @param $user User object to check for, only if FOR_THIS_USER is passed
	 *              to the $audience parameter
	 * @return string username of the user that made the last article revision
	 */
	public function getUserText( $audience = Revision::FOR_PUBLIC, User $user = null ) {
		$this->loadLastEdit();
		if ( $this->mLastRevision ) {
			return $this->mLastRevision->getUserText( $audience, $user );
		} else {
			return '';
		}
	}
 /**
  * Render the footer including userinfos (Name, Role, Editcount)
  */
 function showFooter()
 {
     $output = $this->getOutput();
     $output->addHtml(Html::openElement('div', array('id' => 'mw-mf-userinfo', 'class' => 'position-fixed')));
     $userId = $this->rev->getUser();
     if ($userId) {
         $user = User::newFromId($userId);
         $edits = $user->getEditCount();
         $attrs = array('class' => MobileUI::iconClass('user', 'before', 'mw-mf-user icon-16px'), 'data-revision-id' => $this->revId, 'data-user-name' => $user->getName(), 'data-user-gender' => $user->getOption('gender'));
         $userLink = SpecialPage::getTitleFor('UserProfile', $user->getName());
         $output->addHtml(Html::openElement('div', $attrs) . Linker::link($userLink, htmlspecialchars($user->getName()), array('class' => 'mw-mf-user-link')) . '</div>' . '<div class="mw-mf-roles meta">' . $this->listGroups($user) . '</div>' . '<div class="mw-mf-edit-count meta">' . $this->msg('mobile-frontend-diffview-editcount', $this->getLanguage()->formatNum($edits))->parse() . '</div>');
     } else {
         $ipAddr = $this->rev->getUserText();
         $userPage = SpecialPage::getTitleFor('Contributions', $ipAddr);
         $output->addHtml(Html::element('div', array('class' => MobileUI::iconClass('anonymous', 'before', 'mw-mf-user icon-16px mw-mf-anon')), $this->msg('mobile-frontend-diffview-anonymous')) . '<div>' . Linker::link($userPage, htmlspecialchars($ipAddr)) . '</div>');
     }
     $output->addHtml(Html::closeElement('div'));
 }
Esempio n. 4
0
 /**
  * Generate a FeedItem object from a given revision table row
  * Borrows Recent Changes' feed generation functions for formatting;
  * includes a diff to the previous revision (if any).
  *
  * @param $row
  * @return FeedItem
  */
 function feedItem($row)
 {
     $rev = new Revision($row);
     $rev->setTitle($this->mTitle);
     $text = rcFormatDiffRow($this->mTitle, $this->mTitle->getPreviousRevisionID($rev->getId()), $rev->getId(), $rev->getTimestamp(), $rev->getComment());
     if ($rev->getComment() == '') {
         global $wgContLang;
         $title = wfMsgForContent('history-feed-item-nocomment', $rev->getUserText(), $wgContLang->timeanddate($rev->getTimestamp()));
     } else {
         $title = $rev->getUserText() . ": " . $this->stripComment($rev->getComment());
     }
     return new FeedItem($title, $text, $this->mTitle->getFullUrl('diff=' . $rev->getId() . '&oldid=prev'), $rev->getTimestamp(), $rev->getUserText(), $this->mTitle->getTalkPage()->getFullUrl());
 }
 /**
  * @param Revision $revision
  * @return string
  */
 protected function feedItemDesc($revision)
 {
     if ($revision) {
         $msg = wfMessage('colon-separator')->inContentLanguage()->text();
         $content = $revision->getContent();
         if ($content instanceof TextContent) {
             // only textual content has a "source view".
             $html = nl2br(htmlspecialchars($content->getNativeData()));
         } else {
             //XXX: we could get an HTML representation of the content via getParserOutput, but that may
             //     contain JS magic and generally may not be suitable for inclusion in a feed.
             //     Perhaps Content should have a getDescriptiveHtml method and/or a getSourceText method.
             //Compare also FeedUtils::formatDiffRow.
             $html = '';
         }
         return '<p>' . htmlspecialchars($revision->getUserText()) . $msg . htmlspecialchars(FeedItem::stripComment($revision->getComment())) . "</p>\n<hr />\n<div>" . $html . "</div>";
     }
     return '';
 }
 /**
  * Generate a FeedItem object from a given revision table row
  * Borrows Recent Changes' feed generation functions for formatting;
  * includes a diff to the previous revision (if any).
  *
  * @param stdClass|array $row Database row
  * @return FeedItem
  */
 function feedItem($row)
 {
     $rev = new Revision($row);
     $rev->setTitle($this->getTitle());
     $text = FeedUtils::formatDiffRow($this->getTitle(), $this->getTitle()->getPreviousRevisionID($rev->getId()), $rev->getId(), $rev->getTimestamp(), $rev->getComment());
     if ($rev->getComment() == '') {
         global $wgContLang;
         $title = $this->msg('history-feed-item-nocomment', $rev->getUserText(), $wgContLang->timeanddate($rev->getTimestamp()), $wgContLang->date($rev->getTimestamp()), $wgContLang->time($rev->getTimestamp()))->inContentLanguage()->text();
     } else {
         $title = $rev->getUserText() . $this->msg('colon-separator')->inContentLanguage()->text() . FeedItem::stripComment($rev->getComment());
     }
     return new FeedItem($title, $text, $this->getTitle()->getFullURL('diff=' . $rev->getId() . '&oldid=prev'), $rev->getTimestamp(), $rev->getUserText(), $this->getTitle()->getTalkPage()->getFullURL());
 }
 /**
  * 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);
 }
 /**
  * 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;
 }
Esempio n. 9
0
File: Linker.php Progetto: paladox/2
 /**
  * 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'));
     }
 }
Esempio n. 10
0
 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;
 }
 private function extractRowInfo($oRow, $deleted = 0)
 {
     wfProfileIn(__METHOD__);
     $vals = array();
     if ($deleted == 0) {
         $oRevision = new Revision($oRow);
         if (isset($oRow->is_archive) && $oRow->is_archive == 1) {
             $this->mTitle = Title::makeTitle($oRow->page_namespace, $oRow->page_title);
         } else {
             $this->mTitle = $oRevision->getTitle();
         }
         $this->mContent = $oRevision->getText(Revision::FOR_THIS_USER);
         # revision id
         $vals['revid'] = intval($oRevision->getId());
         # username
         $vals['username'] = $oRevision->getUserText();
         # user id
         $vals['userid'] = $oRevision->getUser();
         # user ip
         $vals['user_ip'] = IP::isIPAddress($vals['username']) ? $vals['username'] : $this->_get_user_ip($vals['userid'], $oRow->page_title, $oRow->page_namespace);
         # user is bot
         $vals['userisbot'] = intval($this->_user_is_bot($vals['username']));
         # is new
         $is_archive = isset($oRow->is_archive);
         $vals['isnew'] = $this->checkIsNew($is_archive);
         # timestamp
         $vals['timestamp'] = wfTimestamp(TS_DB, $oRevision->getTimestamp());
         $vals['date'] = gmdate('Y-m-d', wfTimestamp(TS_UNIX, $oRevision->getTimestamp()));
         # size
         $vals['size'] = intval($oRevision->getSize());
         #words
         $vals['words'] = str_word_count($this->mContent);
         # revision is redirect
         $vals['isredirect'] = intval($this->_revision_is_redirect());
         # revision is content
         $vals['iscontent'] = intval($this->_revision_is_content());
         # is deleted
         $vals['isdeleted'] = $deleted;
         # links
         $links = $this->_make_links();
         $vals['imagelinks'] = $links['image'];
         $vals['video'] = $links['video'];
     } else {
         $this->mTitle = Title::makeTitle($oRow->page_namespace, $oRow->page_title);
         # revision id
         $vals['revid'] = intval($oRow->rev_id);
         # username
         $vals['username'] = $oRow->rev_user_text;
         # user id
         $vals['userid'] = intval($oRow->rev_user);
         # user ip
         $vals['user_ip'] = IP::isIPAddress($vals['username']) ? $vals['username'] : $this->_get_user_ip($vals['userid'], $oRow->page_title, $oRow->page_namespace);
         # user is bot
         $vals['userisbot'] = intval($this->_user_is_bot($vals['username']));
         # is new
         $vals['isnew'] = 0;
         # timestamp
         $vals['timestamp'] = wfTimestamp(TS_DB, $oRow->rev_timestamp);
         # size
         $vals['size'] = intval($oRow->rev_len);
         # words
         $vals['words'] = 0;
         # revision is redirect
         $vals['isredirect'] = 0;
         # revision is content
         $vals['iscontent'] = intval($this->_revision_is_content());
         # is deleted
         $vals['isdeleted'] = $deleted;
         # links
         $vals['imagelinks'] = 0;
         $vals['video'] = 0;
     }
     $vals['media_type'] = $this->getMediaType($oRow->page_namespace);
     $vals['page_latest'] = $this->mTitle->getLatestRevID();
     wfProfileOut(__METHOD__);
     return $vals;
 }
 /**
  * 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);
 }
 /**
  * Update the revision's recentchanges record if fields have been hidden
  * @param Revision $rev
  * @param int $bitfield new rev_deleted bitfield value
  */
 function updateRecentChanges($rev, $bitfield)
 {
     $this->db->update('recentchanges', array('rc_user' => $bitfield & Revision::DELETED_USER ? 0 : $rev->getUser(), 'rc_user_text' => $bitfield & Revision::DELETED_USER ? wfMsg('rev-deleted-user') : $rev->getUserText(), 'rc_comment' => $bitfield & Revision::DELETED_COMMENT ? wfMsg('rev-deleted-comment') : $rev->getComment()), array('rc_this_oldid' => $rev->getId()), 'RevisionDeleter::updateRecentChanges');
 }
Esempio n. 14
0
 /**
  * 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);
 }
Esempio n. 15
0
 /**
  * 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'));
 }
 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_contentmodel) {
         $vals['contentmodel'] = $revision->getContentModel();
     }
     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;
             }
         }
     }
     $content = null;
     global $wgParser;
     if ($this->fld_content || !is_null($this->difftotext)) {
         $content = $revision->getContent();
         // Expand templates after getting section content because
         // template-added sections don't count and Parser::preprocess()
         // will have less input
         if ($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 ($this->fld_content && !$revision->isDeleted(Revision::DELETED_TEXT)) {
         $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()), OT_PREPROCESS);
                 $dom = $wgParser->preprocessToDom($t);
                 if (is_callable(array($dom, 'saveXML'))) {
                     $xml = $dom->saveXML();
                 } else {
                     $xml = $dom->__toString();
                 }
                 $vals['parsetree'] = $xml;
             } else {
                 $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() . ")");
                 $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();
             if (!$content->isSupportedFormat($format)) {
                 $model = $content->getModel();
                 $name = $title->getPrefixedDBkey();
                 $this->dieUsage("The requested format {$this->contentFormat} is not supported " . "for content model {$model} used by {$name}", 'badformat');
             }
             $text = $content->serialize($format);
             $vals['contentformat'] = $format;
         }
         if ($text !== false) {
             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);
             $handler = $revision->getContentHandler();
             if (!is_null($this->difftotext)) {
                 $model = $title->getContentModel();
                 if ($this->contentFormat && !ContentHandler::getForModelID($model)->isSupportedFormat($this->contentFormat)) {
                     $name = $title->getPrefixedDBkey();
                     $this->dieUsage("The requested format {$this->contentFormat} is not supported for " . "content model {$model} used by {$name}", 'badformat');
                 }
                 $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();
             }
             $difftext = $engine->getDiffBody();
             ApiResult::setContent($vals['diff'], $difftext);
             if (!$engine->wasCacheHit()) {
                 $n++;
             }
         } else {
             $vals['diff']['notcached'] = '';
         }
     }
     return $vals;
 }
 /**
  * Get the "are you sure you want to reject these changes?" form
  * @return array (html string, error string or true)
  */
 public function getHtml()
 {
     global $wgLang, $wgContLang;
     $status = $this->form->checkTarget();
     if ($status !== true) {
         return array('', $status);
         // not a reviewable existing page
     }
     $oldRev = $this->oldRev;
     // convenience
     $newRev = $this->newRev;
     // convenience
     # Do not mess with archived/deleted revisions
     if (!$oldRev || $newRev->isDeleted(Revision::DELETED_TEXT)) {
         return array('', 'review_bad_oldid');
     } elseif (!$newRev || $newRev->isDeleted(Revision::DELETED_TEXT)) {
         return array('', 'review_bad_oldid');
     }
     $form = '<div class="plainlinks">';
     $dbr = wfGetDB(DB_SLAVE);
     $res = $dbr->select('revision', Revision::selectFields(), array('rev_page' => $oldRev->getPage(), 'rev_timestamp > ' . $dbr->addQuotes($dbr->timestamp($oldRev->getTimestamp())), 'rev_timestamp <= ' . $dbr->addQuotes($dbr->timestamp($newRev->getTimestamp()))), __METHOD__, array('ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 251));
     if (!$dbr->numRows($res)) {
         return array('', 'review_bad_oldid');
     } elseif ($dbr->numRows($res) > 250) {
         return array('', 'review_reject_excessive');
     }
     $contribs = SpecialPage::getTitleFor('Contributions')->getPrefixedText();
     $lastTextId = 0;
     $rejectIds = $rejectAuthors = array();
     foreach ($res as $row) {
         $rev = new Revision($row);
         if ($rev->getTextId() != $lastTextId) {
             // skip null edits
             $rejectIds[] = $rev->getId();
             $rejectAuthors[] = $rev->isDeleted(Revision::DELETED_USER) ? wfMsg('rev-deleted-user') : "[[{$contribs}/{$rev->getUserText()}|{$rev->getUserText()}]]";
         }
         $lastTextId = $rev->getTextId();
     }
     $rejectAuthors = array_values(array_unique($rejectAuthors));
     if (!$rejectIds) {
         // all null edits? (this shouldn't happen)
         return array('', 'review_reject_nulledits');
     }
     // List of revisions being undone...
     $form .= wfMsgExt('revreview-reject-text-list', 'parseinline', $wgLang->formatNum(count($rejectIds)), $oldRev->getTitle()->getPrefixedText());
     $form .= '<ul>';
     $list = new RevisionList(RequestContext::getMain(), $oldRev->getTitle());
     $list->filterByIds($rejectIds);
     for ($list->reset(); $list->current(); $list->next()) {
         $item = $list->current();
         if ($item->canView()) {
             $form .= $item->getHTML();
         }
     }
     $form .= '</ul>';
     if ($newRev->isCurrent()) {
         // Revision this will revert to (when reverting the top X revs)...
         $form .= wfMsgExt('revreview-reject-text-revto', 'parseinline', $oldRev->getTitle()->getPrefixedDBKey(), $oldRev->getId(), $wgLang->timeanddate($oldRev->getTimestamp(), true));
     }
     $comment = $this->form->getComment();
     // convenience
     // Determine the default edit summary...
     $oldRevAuthor = $oldRev->isDeleted(Revision::DELETED_USER) ? wfMsg('rev-deleted-user') : $oldRev->getUserText();
     // NOTE: *-cur msg wording not safe for (unlikely) edit auto-merge
     $msg = $newRev->isCurrent() ? 'revreview-reject-summary-cur' : 'revreview-reject-summary-old';
     $defaultSummary = wfMsgExt($msg, array('parsemag', 'content'), $wgContLang->formatNum(count($rejectIds)), $wgContLang->listToText($rejectAuthors), $oldRev->getId(), $oldRevAuthor);
     // If the message is too big, then fallback to the shorter one
     $colonSeparator = wfMsgForContent('colon-separator');
     $maxLen = 255 - count($colonSeparator) - count($comment);
     if (strlen($defaultSummary) > $maxLen) {
         $msg = $newRev->isCurrent() ? 'revreview-reject-summary-cur-short' : 'revreview-reject-summary-old-short';
         $defaultSummary = wfMsgExt($msg, array('parsemag', 'content'), $wgContLang->formatNum(count($rejectIds)), $oldRev->getId(), $oldRevAuthor);
     }
     // Append any review comment...
     if ($comment != '') {
         if ($defaultSummary != '') {
             $defaultSummary .= $colonSeparator;
         }
         $defaultSummary .= $comment;
     }
     $form .= '</div>';
     $skin = $this->form->getUser()->getSkin();
     $reviewTitle = SpecialPage::getTitleFor('RevisionReview');
     $form .= Xml::openElement('form', array('method' => 'POST', 'action' => $reviewTitle->getFullUrl()));
     $form .= Html::hidden('action', 'reject');
     $form .= Html::hidden('wpReject', 1);
     $form .= Html::hidden('wpRejectConfirm', 1);
     $form .= Html::hidden('oldid', $this->form->getOldId());
     $form .= Html::hidden('refid', $this->form->getRefId());
     $form .= Html::hidden('target', $oldRev->getTitle()->getPrefixedDBKey());
     $form .= Html::hidden('wpEditToken', $this->form->getUser()->editToken());
     $form .= Html::hidden('changetime', $newRev->getTimestamp());
     $form .= Xml::inputLabel(wfMsg('revreview-reject-summary'), 'wpReason', 'wpReason', 120, $defaultSummary, array('maxlength' => 200)) . "<br />";
     $form .= Html::input('wpSubmit', wfMsg('revreview-reject-confirm'), 'submit');
     $form .= ' ';
     $form .= $skin->link($this->form->getPage(), wfMsg('revreview-reject-cancel'), array('onClick' => 'history.back(); return history.length <= 1;'), array('oldid' => $this->form->getRefId(), 'diff' => $this->form->getOldId()));
     $form .= Xml::closeElement('form');
     return array($form, true);
 }
 /**
  * Walks the line of revisions to find first editor that is not on blacklist
  * @param string $sOriginatorUserName
  * @param Revision $oRevision
  * @return string The originators username
  */
 private function checkOriginatorForBlacklist($sOriginatorUserName, $oRevision, $aBlacklist)
 {
     if ($oRevision instanceof Revision == false) {
         return $sOriginatorUserName;
     }
     $sOriginatorUserName = $oRevision->getUserText();
     if (in_array($sOriginatorUserName, $aBlacklist)) {
         return $this->checkOriginatorForBlacklist($sOriginatorUserName, $oRevision->getNext(), $aBlacklist);
     }
     return $sOriginatorUserName;
 }
Esempio n. 19
0
 /**
  * Get data about revision
  * Who and when made last edition
  *
  * @param Revision $rev
  * @return mixed
  */
 public function prepareRevisionData(Revision $rev)
 {
     $data['timestamp'] = wfTimestamp(TS_UNIX, $rev->getTimestamp());
     $user = $rev->getUserText();
     if ($rev->getUser()) {
         $userpage = Title::newFromText($user, NS_USER)->getFullURL();
     } else {
         $userpage = SpecialPage::getTitleFor('Contributions', $user)->getFullUrl();
     }
     $data['username'] = $user;
     $data['userpage'] = $userpage;
     return $data;
 }