public function addDBDataOnce() { $info = $this->insertPage(self::$pageName); $title = $info['title']; $page = WikiPage::factory($title); self::$pageRev = $page->getRevision(); self::$revUser = User::newFromId(self::$pageRev->getUser(Revision::RAW)); }
/** * Get template and image versions from parsing a revision * @param Page $article * @param Revision $rev * @param User $user * @param string $regen use 'regen' to force regeneration * @return array( templateIds, fileSHA1Keys ) * templateIds like ParserOutput->mTemplateIds * fileSHA1Keys like ParserOutput->mImageTimeKeys */ public static function getRevIncludes(Page $article, Revision $rev, User $user, $regen = '') { global $wgParser, $wgMemc; wfProfileIn(__METHOD__); $versions = false; $key = self::getCacheKey($article->getTitle(), $rev->getId()); if ($regen !== 'regen') { // check cache $versions = FlaggedRevs::getMemcValue($wgMemc->get($key), $article, 'allowStale'); } if (!is_array($versions)) { // cache miss $pOut = false; if ($rev->isCurrent()) { $parserCache = ParserCache::singleton(); # Try current version parser cache (as anon)... $pOut = $parserCache->get($article, $article->makeParserOptions($user)); if ($pOut == false && $rev->getUser()) { // try the user who saved the change $author = User::newFromId($rev->getUser()); $pOut = $parserCache->get($article, $article->makeParserOptions($author)); } } // ParserOutput::mImageTimeKeys wasn't always there if ($pOut == false || !FlaggedRevs::parserOutputIsVersioned($pOut)) { $title = $article->getTitle(); $pOpts = ParserOptions::newFromUser($user); // Note: tidy off $pOut = $wgParser->parse($rev->getText(), $title, $pOpts, true, true, $rev->getId()); } # Get the template/file versions used... $versions = array($pOut->getTemplateIds(), $pOut->getFileSearchOptions()); # Save to cache (check cache expiry for dynamic elements)... $data = FlaggedRevs::makeMemcObj($versions); $wgMemc->set($key, $data, $pOut->getCacheExpiry()); } else { $tVersions =& $versions[0]; // templates # Do a link batch query for page_latest... $lb = new LinkBatch(); foreach ($tVersions as $ns => $tmps) { foreach ($tmps as $dbKey => $revIdDraft) { $lb->add($ns, $dbKey); } } $lb->execute(); # Update array with the current page_latest values. # This kludge is there since $newTemplates (thus $revIdDraft) is cached. foreach ($tVersions as $ns => &$tmps) { foreach ($tmps as $dbKey => &$revIdDraft) { $title = Title::makeTitle($ns, $dbKey); $revIdDraft = (int) $title->getLatestRevID(); } } } wfProfileOut(__METHOD__); return $versions; }
/** * Get template and image versions from parsing a revision * @param Page $article * @param Revision $rev * @param User $user * @param string $regen use 'regen' to force regeneration * @return array( templateIds, fileSHA1Keys ) * templateIds like ParserOutput->mTemplateIds * fileSHA1Keys like ParserOutput->mImageTimeKeys */ public static function getRevIncludes(Page $article, Revision $rev, User $user, $regen = '') { global $wgMemc; wfProfileIn(__METHOD__); $key = self::getCacheKey($article->getTitle(), $rev->getId()); if ($regen === 'regen') { $versions = false; // skip cache } elseif ($rev->isCurrent()) { // Check cache entry against page_touched $versions = FlaggedRevs::getMemcValue($wgMemc->get($key), $article); } else { // Old revs won't always be invalidated with template/file changes. // Also, we don't care if page_touched changed due to a direct edit. $versions = FlaggedRevs::getMemcValue($wgMemc->get($key), $article, 'allowStale'); if (is_array($versions)) { // entry exists // Sanity check that the cache is reasonably up to date list($templates, $files) = $versions; if (self::templatesStale($templates) || self::filesStale($files)) { $versions = false; // no good } } } if (!is_array($versions)) { // cache miss $pOut = false; if ($rev->isCurrent()) { $parserCache = ParserCache::singleton(); # Try current version parser cache for this user... $pOut = $parserCache->get($article, $article->makeParserOptions($user)); if ($pOut == false) { # Try current version parser cache for the revision author... $optsUser = $rev->getUser() ? User::newFromId($rev->getUser()) : 'canonical'; $pOut = $parserCache->get($article, $article->makeParserOptions($optsUser)); } } // ParserOutput::mImageTimeKeys wasn't always there if ($pOut == false || !FlaggedRevs::parserOutputIsVersioned($pOut)) { $content = $rev->getContent(Revision::RAW); if (!$content) { // Just for extra sanity $pOut = new ParserOutput(); } else { $pOut = $content->getParserOutput($article->getTitle(), $rev->getId(), ParserOptions::newFromUser($user)); } } # Get the template/file versions used... $versions = array($pOut->getTemplateIds(), $pOut->getFileSearchOptions()); # Save to cache (check cache expiry for dynamic elements)... $data = FlaggedRevs::makeMemcObj($versions); $wgMemc->set($key, $data, $pOut->getCacheExpiry()); } wfProfileOut(__METHOD__); return $versions; }
/** * @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 int user ID for the user that made the last article revision */ public function getUser( $audience = Revision::FOR_PUBLIC, User $user = null ) { $this->loadLastEdit(); if ( $this->mLastRevision ) { return $this->mLastRevision->getUser( $audience, $user ); } else { return -1; } }
protected function assertRevEquals(Revision $orig, Revision $rev = null) { $this->assertNotNull($rev, 'missing revision'); $this->assertEquals($orig->getId(), $rev->getId()); $this->assertEquals($orig->getPage(), $rev->getPage()); $this->assertEquals($orig->getTimestamp(), $rev->getTimestamp()); $this->assertEquals($orig->getUser(), $rev->getUser()); $this->assertEquals($orig->getSha1(), $rev->getSha1()); }
/** * 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')); }
public function onRevisionUndeleted(&$oTitle, Revision $oRevision, $page_id) { $this->app->wf->ProfileIn(__METHOD__); if (!is_object($oTitle)) { Wikia::log(__METHOD__, "error", "Cannot send log using scribe ({$this->app}->wg->CityId): invalid title object"); $this->app->wf->ProfileOut(__METHOD__); return true; } $oPage = WikiPage::factory($oTitle); $oUser = User::newFromId($oRevision->getUser()); $oScribeProducer = F::build('ScribeEventProducer', array('key' => 'edit')); /* @var $oScribeProducer ScribeEventProducer */ if (is_object($oScribeProducer)) { if ($oScribeProducer->buildEditPackage($oPage, $oUser, $oRevision)) { $oScribeProducer->sendLog(); } } $this->app->wf->ProfileOut(__METHOD__); return true; }
/** * Generate a user tool link cluster if the current user is allowed to view it * @param Revision $rev * @param bool $isPublic Show only if all users can see it * @return string HTML */ public static function revUserTools($rev, $isPublic = false) { if ($rev->isDeleted(Revision::DELETED_USER) && $isPublic) { $link = wfMessage('rev-deleted-user')->escaped(); } elseif ($rev->userCan(Revision::DELETED_USER)) { $userId = $rev->getUser(Revision::FOR_THIS_USER); $userText = $rev->getUserText(Revision::FOR_THIS_USER); $link = self::userLink($userId, $userText) . self::userToolLinks($userId, $userText); } else { $link = wfMessage('rev-deleted-user')->escaped(); } if ($rev->isDeleted(Revision::DELETED_USER)) { return ' <span class="history-deleted">' . $link . '</span>'; } return $link; }
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; }
/** * 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'); }
public function loadDataFromRev(Revision $rev, $wiki) { $this->id = $rev->getId() . '_' . $wiki; $title = $rev->getTitle(); $ac = F::build('WallMessage', array($rev->getTitle()), 'newFromTitle'); /* @var $ac WallMessage */ $ac->load(); $app = F::app(); $walluser = $ac->getWallOwner(); $authoruser = User::newFromId($rev->getUser()); if (empty($walluser)) { error_log('WALL_NO_OWNER: (entityId)' . $this->id); $this->data = null; $this->data_noncached = null; return; } $this->data->wiki = $wiki; $this->data->wikiname = $app->wg->sitename; $this->data->rev_id = $rev->getId(); $wallTitle = $ac->getWallTitle(); if (!empty($wallTitle) && $wallTitle->exists()) { $this->data->article_title_ns = $wallTitle->getNamespace(); $this->data->article_title_text = $wallTitle->getText(); $this->data->article_title_dbkey = $wallTitle->getDBkey(); $this->data->article_title_id = $wallTitle->getArticleId(); } else { $this->data->article_title_ns = null; $this->data->article_title_text = null; $this->data->article_title_dbkey = null; $this->data->article_title_id = null; } $this->data->timestamp = $rev->getTimestamp(); $this->data->parent_id = null; if ($authoruser instanceof User) { $this->data->msg_author_id = $authoruser->getId(); $this->data->msg_author_username = $authoruser->getName(); if ($authoruser->getId() > 0) { $this->data->msg_author_displayname = $this->data->msg_author_username; } else { $this->data->msg_author_displayname = $app->wf->Msg('oasis-anon-user'); } } else { //annon $this->data->msg_author_displayname = $app->wf->Msg('oasis-anon-user'); $this->data->msg_author_id = 0; } $this->data->wall_username = $walluser->getName(); $this->data->wall_userid = $walluser->getId(); $this->data->wall_displayname = $this->data->wall_username; //TODO: double ? $this->data->title_id = $ac->getTitle()->getArticleId(); $this->data_non_cached->title = $ac->getTitle(); $acParent = $ac->getTopParentObj(); $this->data->parent_username = ''; $this->data->thread_title = ''; $this->data_non_cached->parent_title_dbkey = ''; $this->data_non_cached->msg_text = $ac->getText(); $this->data->notifyeveryone = $ac->getNotifyeveryone(); if ($ac->isEdited()) { $this->data->reason = $ac->getLastEditSummery(); } else { $this->data->reason = ''; } if (!empty($acParent)) { $acParent->load(); $parentUser = $acParent->getUser(); if ($parentUser instanceof User) { $this->data->parent_username = $parentUser->getName(); if ($parentUser->getId() > 0) { $this->data->parent_displayname = $this->data->parent_username; } else { $this->data->parent_displayname = $app->wf->Msg('oasis-anon-user'); } $this->data->parent_user_id = $acParent->getUser()->getId(); } else { //parent was deleted and somehow reply stays in the system //the only way I've reproduced it was: I deleted a thread //then I went to Special:Log/delete and restored only its reply //an edge case but it needs to be handled //--nAndy $this->data->parent_username = $this->data->parent_displayname = $app->wf->Msg('oasis-anon-user'); $this->data->parent_user_id = 0; } $this->data_non_cached->thread_title_full = $acParent->getMetaTitle(); $this->data->thread_title = $acParent->getMetaTitle(); $this->data_noncached->parent_title_dbkey = $acParent->getTitle()->getDBkey(); $this->data->parent_id = $acParent->getTitle()->getArticleId(); $this->data->url = $ac->getMessagePageUrl(); } else { $this->data->url = $ac->getMessagePageUrl(); $this->data->parent_username = $walluser->getName(); $this->data_non_cached->thread_title_full = $ac->getMetaTitle(); $this->data->thread_title = $ac->getMetaTitle(); } return true; }
/** * 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); }
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; }
/** * @param Revision $rev * @param bool $useMasterDB * * @return bool */ public function loadDataFromRev(Revision $rev, $useMasterDB = false) { // Reset any existing info stored in $this->data and start collecting in a new $data var $this->data = null; $data = new StdClass(); $data->wiki = F::app()->wg->CityId; $data->wikiname = F::app()->wg->Sitename; $this->setMessageAuthorData($data, $rev->getUser()); $data->rev_id = $rev->getId(); $this->id = $data->rev_id . '_' . $data->wiki; $data->timestamp = $rev->getTimestamp(); // Set all data related to the WallMessage $wm = $this->getWallMessageFromRev($rev); if (!$this->setWallUserData($data, $wm, $useMasterDB)) { return false; } $this->setArticleTitleData($data, $wm); $this->msgText = $wm->getText(); $data->title_id = $wm->getTitle()->getArticleId(); $data->url = $wm->getMessagePageUrl(); $data->notifyeveryone = $wm->getNotifyeveryone(); $data->reason = $wm->isEdited() ? $wm->getLastEditSummary() : ''; $this->setMessageParentData($data, $wm); $this->data = $data; return true; }
/** * Validates review action by checking permissions and other things. * @param User $user * @param Revision $revision * @return string Error key or empty string if review is allowed. * @since 2012-09-24 */ public static function getReviewBlockers(User $user, Revision $revision) { if (!$user->isAllowed(self::$right)) { return 'permissiondenied'; } if ($user->isBlocked()) { return 'blocked'; } $title = $revision->getTitle(); $handle = new MessageHandle($title); if (!$handle->isValid()) { return 'unknownmessage'; } if ($revision->getUser() == $user->getId()) { return 'owntranslation'; } if ($handle->isFuzzy()) { return 'fuzzymessage'; } return ''; }
/** * 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; }
/** * 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); }
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; }
public static function onRevisionUndeleted(&$oTitle, Revision $oRevision, $page_id) { global $wgCityId; wfProfileIn(__METHOD__); if (!is_object($oTitle)) { Wikia::log(__METHOD__, "error", "Cannot send log using scribe ({$wgCityId}): invalid title object"); wfProfileOut(__METHOD__); return true; } $oPage = WikiPage::factory($oTitle); $oUser = User::newFromId($oRevision->getUser()); $oScribeProducer = new ScribeEventProducer('edit'); if (is_object($oScribeProducer)) { if ($oScribeProducer->buildEditPackage($oPage, $oUser, $oRevision)) { $oScribeProducer->sendLog(); } } wfProfileOut(__METHOD__); return true; }
/** * 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; }