/**
  * 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;
 }
Esempio n. 2
0
 /**
  * Get the text of the current revision. No side-effects...
  *
  * @param int $audience 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 User object to check for, only if FOR_THIS_USER is passed
  *   to the $audience parameter
  * @return string|bool The text of the current revision
  * @deprecated since 1.21, getContent() should be used instead.
  */
 public function getText($audience = Revision::FOR_PUBLIC, User $user = null)
 {
     wfDeprecated(__METHOD__, '1.21');
     $this->loadLastEdit();
     if ($this->mLastRevision) {
         return $this->mLastRevision->getText($audience, $user);
     }
     return false;
 }
Esempio n. 3
0
	/**
	 * Get the text of the current revision. No side-effects...
	 *
	 * @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|false The text of the current revision
	 * @deprecated as of 1.21, getContent() should be used instead.
	 */
	public function getText( $audience = Revision::FOR_PUBLIC, User $user = null ) { // @todo deprecated, replace usage!
		ContentHandler::deprecated( __METHOD__, '1.21' );

		$this->loadLastEdit();
		if ( $this->mLastRevision ) {
			return $this->mLastRevision->getText( $audience, $user );
		}
		return false;
	}
 public static function runForTitleInternal(Title $title, Revision $revision, $fname)
 {
     global $wgParser, $wgContLang;
     wfProfileIn($fname . '-parse');
     $options = ParserOptions::newFromUserAndLang(new User(), $wgContLang);
     $parserOutput = $wgParser->parse($revision->getText(), $title, $options, true, true, $revision->getId());
     wfProfileOut($fname . '-parse');
     wfProfileIn($fname . '-update');
     $updates = $parserOutput->getSecondaryDataUpdates($title, false);
     DataUpdate::runUpdates($updates);
     wfProfileOut($fname . '-update');
 }
Esempio n. 5
0
 /**
  * Get text of an article from database
  * Does *NOT* follow redirects.
  *
  * @return mixed string containing article contents, or false if null
  */
 function fetchContent()
 {
     if ($this->mContentLoaded) {
         return $this->mContent;
     }
     wfProfileIn(__METHOD__);
     $this->mContentLoaded = true;
     $oldid = $this->getOldID();
     # Pre-fill content with error message so that if something
     # fails we'll have something telling us what we intended.
     $t = $this->getTitle()->getPrefixedText();
     $d = $oldid ? wfMsgExt('missingarticle-rev', array('escape'), $oldid) : '';
     $this->mContent = wfMsgNoTrans('missing-article', $t, $d);
     if ($oldid) {
         # $this->mRevision might already be fetched by getOldIDFromRequest()
         if (!$this->mRevision) {
             $this->mRevision = Revision::newFromId($oldid);
             if (!$this->mRevision) {
                 wfDebug(__METHOD__ . " failed to retrieve specified revision, id {$oldid}\n");
                 Wikia::log(__METHOD__, 1, "failed to retrieve specified revision, title '{$t}', id {$oldid}", true);
                 # Wikia change - @author macbre
                 wfProfileOut(__METHOD__);
                 return false;
             }
         }
     } else {
         if (!$this->mPage->getLatest()) {
             wfDebug(__METHOD__ . " failed to find page data for title " . $this->getTitle()->getPrefixedText() . "\n");
             wfProfileOut(__METHOD__);
             return false;
         }
         $this->mRevision = $this->mPage->getRevision();
         if (!$this->mRevision) {
             wfDebug(__METHOD__ . " failed to retrieve current page, rev_id " . $this->mPage->getLatest() . "\n");
             Wikia::log(__METHOD__, 3, "failed to retrieve current page, title '{$t}', rev_id " . $this->mPage->getLatest(), true);
             # Wikia change - @author macbre
             wfProfileOut(__METHOD__);
             return false;
         }
     }
     // @todo FIXME: Horrible, horrible! This content-loading interface just plain sucks.
     // We should instead work with the Revision object when we need it...
     $this->mContent = $this->mRevision->getText(Revision::FOR_THIS_USER);
     // Loads if user is allowed
     $this->mRevIdFetched = $this->mRevision->getId();
     wfRunHooks('ArticleAfterFetchContent', array(&$this, &$this->mContent));
     wfProfileOut(__METHOD__);
     return $this->mContent;
 }
Esempio n. 6
0
/**
 * 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();
}
 /**
  * Render the inline difference between two revisions
  * using InlineDiffEngine
  */
 function showDiff()
 {
     $ctx = MobileContext::singleton();
     $prevId = $this->prevRev ? $this->prevRev->getId() : 0;
     $unhide = (bool) $this->getRequest()->getVal('unhide');
     $contentHandler = $this->rev->getContentHandler();
     $de = $contentHandler->createDifferenceEngine($this->getContext(), $prevId, $this->revId);
     // HACK:
     if (get_class($de) == 'DifferenceEngine') {
         $de = new $this->diffClass($this->getContext(), $prevId, $this->revId, 0, false, $unhide);
     } else {
         $de->showDiffPage();
         return;
     }
     $this->mDiffEngine = $de;
     $diff = $de->getDiffBody();
     if (!$prevId) {
         $audience = $unhide ? Revision::FOR_THIS_USER : Revision::FOR_PUBLIC;
         $diff = '<ins>' . nl2br(htmlspecialchars($this->rev->getText($audience))) . '</ins>';
     }
     $warnings = $de->getWarningMessageText();
     if ($warnings) {
         $warnings = MobileUI::warningBox($warnings);
     }
     $this->getOutput()->addHtml($warnings . '<div id="mw-mf-minidiff">' . $diff . '</div>');
     $prev = $this->rev->getPrevious();
     $next = $this->rev->getNext();
     if ($prev || $next) {
         $history = Html::openElement('ul', array('class' => 'hlist revision-history-links'));
         if ($prev) {
             $history .= Html::openElement('li') . Html::element('a', array('href' => SpecialPage::getTitleFor('MobileDiff', $prev->getId())->getLocalUrl()), $this->msg('previousdiff')) . Html::closeElement('li');
         }
         if ($next) {
             $history .= Html::openElement('li') . Html::element('a', array('href' => SpecialPage::getTitleFor('MobileDiff', $next->getId())->getLocalUrl()), $this->msg('nextdiff')) . Html::closeElement('li');
         }
         $history .= Html::closeElement('ul');
         $this->getOutput()->addHtml($history);
     }
 }
Esempio n. 8
0
 /**
  * Get the text that needs to be saved in order to undo all revisions
  * between $undo and $undoafter. Revisions must belong to the same page,
  * must exist and must not be deleted
  * @param $undo Revision
  * @param $undoafter Revision Must be an earlier revision than $undo
  * @return mixed string on success, false on failure
  */
 public function getUndoText(Revision $undo, Revision $undoafter = null)
 {
     $currentRev = Revision::newFromTitle($this->mTitle);
     if (!$currentRev) {
         return false;
         // no page
     }
     $undo_text = $undo->getText();
     $undoafter_text = $undoafter->getText();
     $cur_text = $currentRev->getText();
     if ($cur_text == $undo_text) {
         # No use doing a merge if it's just a straight revert.
         return $undoafter_text;
     }
     $undone_text = '';
     if (!wfMerge($undo_text, $undoafter_text, $cur_text, $undone_text)) {
         return false;
     }
     return $undone_text;
 }
Esempio n. 9
0
 /**
  * Lazy initialization of article text from DB
  */
 protected function initText()
 {
     if (!isset($this->mText)) {
         if ($this->mRevision != null) {
             $this->mText = $this->mRevision->getText();
         } else {
             // TODO: can we fetch raw wikitext for commons images?
             $this->mText = '';
         }
     }
 }
Esempio n. 10
0
 /**
  * Do standard deferred updates after page edit.
  * Update links tables, site stats, search index and message cache.
  * Purges pages that include this page if the text was changed here.
  * Every 100th edit, prune the recent changes table.
  *
  * @private
  * @param $revision Revision object
  * @param $user User object that did the revision
  * @param $options Array of options, following indexes are used:
  * - changed: boolean, whether the revision changed the content (default true)
  * - created: boolean, whether the revision created the page (default false)
  * - oldcountable: boolean or null (default null):
  *   - boolean: whether the page was counted as an article before that
  *     revision, only used in changed is true and created is false
  *   - null: don't change the article count
  */
 public function doEditUpdates(Revision $revision, User $user, array $options = array())
 {
     global $wgDeferredUpdateList, $wgEnableParserCache;
     wfProfileIn(__METHOD__);
     $options += array('changed' => true, 'created' => false, 'oldcountable' => null);
     $text = $revision->getText();
     # Parse the text
     # Be careful not to double-PST: $text is usually already PST-ed once
     if (!$this->mPreparedEdit || $this->mPreparedEdit->output->getFlag('vary-revision')) {
         wfDebug(__METHOD__ . ": No prepared edit or vary-revision is set...\n");
         $editInfo = $this->prepareTextForEdit($text, $revision->getId(), $user);
     } else {
         wfDebug(__METHOD__ . ": No vary-revision, using prepared edit...\n");
         $editInfo = $this->mPreparedEdit;
     }
     # Save it to the parser cache
     if ($wgEnableParserCache) {
         $parserCache = ParserCache::singleton();
         $parserCache->save($editInfo->output, $this, $editInfo->popts);
     }
     # Update the links tables
     $u = new LinksUpdate($this->mTitle, $editInfo->output);
     $u->doUpdate();
     wfRunHooks('ArticleEditUpdates', array(&$this, &$editInfo, $options['changed']));
     if (wfRunHooks('ArticleEditUpdatesDeleteFromRecentchanges', array(&$this))) {
         if (0 == mt_rand(0, 99)) {
             // Flush old entries from the `recentchanges` table; we do this on
             // random requests so as to avoid an increase in writes for no good reason
             global $wgRCMaxAge;
             $dbw = wfGetDB(DB_MASTER);
             $cutoff = $dbw->timestamp(time() - $wgRCMaxAge);
             $dbw->delete('recentchanges', array("rc_timestamp < '{$cutoff}'"), __METHOD__);
         }
     }
     $id = $this->getId();
     $title = $this->mTitle->getPrefixedDBkey();
     $shortTitle = $this->mTitle->getDBkey();
     if (0 == $id) {
         wfProfileOut(__METHOD__);
         return;
     }
     if (!$options['changed']) {
         $good = 0;
         $total = 0;
     } elseif ($options['created']) {
         $good = (int) $this->isCountable($editInfo);
         $total = 1;
     } elseif ($options['oldcountable'] !== null) {
         $good = (int) $this->isCountable($editInfo) - (int) $options['oldcountable'];
         $total = 0;
     } else {
         $good = 0;
         $total = 0;
     }
     $wgDeferredUpdateList[] = new SiteStatsUpdate(0, 1, $good, $total);
     $wgDeferredUpdateList[] = new SearchUpdate($id, $title, $text);
     # If this is another user's talk page, update newtalk.
     # Don't do this if $options['changed'] = false (null-edits) nor if
     # it's a minor edit and the user doesn't want notifications for those.
     if ($options['changed'] && $this->mTitle->getNamespace() == NS_USER_TALK && $shortTitle != $user->getTitleKey() && !($revision->isMinor() && $user->isAllowed('nominornewtalk'))) {
         if (wfRunHooks('ArticleEditUpdateNewTalk', array(&$this))) {
             $other = User::newFromName($shortTitle, false);
             if (!$other) {
                 wfDebug(__METHOD__ . ": invalid username\n");
             } elseif (User::isIP($shortTitle)) {
                 // An anonymous user
                 $other->setNewtalk(true);
             } elseif ($other->isLoggedIn()) {
                 $other->setNewtalk(true);
             } else {
                 wfDebug(__METHOD__ . ": don't need to notify a nonexistent user\n");
             }
         }
     }
     if ($this->mTitle->getNamespace() == NS_MEDIAWIKI) {
         MessageCache::singleton()->replace($shortTitle, $text);
     }
     if ($options['created']) {
         self::onArticleCreate($this->mTitle);
     } else {
         self::onArticleEdit($this->mTitle);
     }
     wfProfileOut(__METHOD__);
 }
Esempio n. 11
0
 /**
  * Perform article updates on a special page creation.
  *
  * @param Revision $rev
  *
  * @fixme This is a shitty interface function. Kill it and replace the
  * other shitty functions like editUpdates and such so it's not needed
  * anymore.
  */
 function createUpdates($rev)
 {
     $this->mGoodAdjustment = $this->isCountable($rev->getText());
     $this->mTotalAdjustment = 1;
     $this->editUpdates($rev->getText(), $rev->getComment(), $rev->isMinor(), wfTimestamp(), $rev->getId(), true);
 }
Esempio n. 12
0
 public function testConstructWithContent()
 {
     $this->hideDeprecated("Revision::getText");
     $title = Title::newFromText('RevisionTest_testConstructWithContent');
     $rev = new Revision(array('content' => ContentHandler::makeContent('hello world.', $title, CONTENT_MODEL_JAVASCRIPT)));
     $this->assertNotNull($rev->getText(), 'no content text');
     $this->assertNotNull($rev->getContent(), 'no content object available');
     $this->assertEquals(CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModel());
     $this->assertEquals(CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel());
 }
	public function fetchTranslatorsPortal( $natives ) {
		$titles = array();
		foreach ( $natives as $code => $_ ) {
			$titles[] = Title::capitalize( $code, NS_PORTAL ) . '/translators';
		}

		$dbr = wfGetDB( DB_SLAVE );
		$tables = array( 'page', 'revision', 'text' );
		$vars = array_merge( Revision::selectTextFields(), array( 'page_title', 'page_namespace' ), Revision::selectFields() );
		$conds = array(
			'page_latest = rev_id',
			'rev_text_id = old_id',
			'page_namespace' => NS_PORTAL,
			'page_title' => $titles,
		);

		$res = $dbr->select( $tables, $vars, $conds, __METHOD__ );

		$users = array();
		$lb = new LinkBatch;

		foreach ( $res as $row ) {
			$rev = new Revision( $row );
			$text = $rev->getText();
			$code = strtolower( preg_replace( '!/translators$!', '', $row->page_title ) );

			preg_match_all( '!{{[Uu]ser\|([^}|]+)!', $text, $matches,  PREG_SET_ORDER );
			foreach ( $matches as $match ) {
				$user = Title::capitalize( $match[1], NS_USER );
				$lb->add( NS_USER, $user );
				$lb->add( NS_USER_TALK, $user );
				if ( !isset( $users[$code] ) ) $users[$code] = array();
				$users[$code][strtr( $user, '_', ' ' )] = -1;
			}
		}

		$lb->execute();
		return $users;
	}
 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;
 }
Esempio n. 15
0
 function showDiff($revision)
 {
     global $wgOut;
     $dbr = wfGetDB(DB_SLAVE);
     $result = $this->getRevisions($dbr, array('hidden_rev_id' => $revision));
     while ($row = $dbr->fetchObject($result)) {
         $info = $this->listRow($row);
         $list = $this->revisionInfo($row);
         $rev = new Revision($row);
         $rev->mTitle = Title::makeTitle($row->page_namespace, $row->page_title);
         $prevId = $rev->mTitle->getPreviousRevisionID($row->rev_id);
         if ($prevId) {
             $prev = Revision::newFromTitle($rev->mTitle, $prevId);
             $otext = strval($prev->getText());
         } else {
             $wgOut->addHtml("<ul>" . $info . "</ul>\n" . $list);
             $wgOut->addWikiText(wfMsgNoTrans('oversight-nodiff'));
             return;
         }
         $ntext = strval($rev->getText());
         $diffEngine = new DifferenceEngine();
         $diffEngine->showDiffStyle();
         $wgOut->addHtml("<ul>" . $info . "</ul>\n" . $list . "<p><strong>" . wfMsgHTML('oversight-difference') . "</strong>" . "</p>" . "<div>" . "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" . "<col class='diff-marker' />" . "<col class='diff-content' />" . "<col class='diff-marker' />" . "<col class='diff-content' />" . "<tr>" . "<td colspan='2' width='50%' align='center' class='diff-otitle'>" . wfMsgHTML('oversight-prev') . " (#{$prevId})" . "</td>" . "<td colspan='2' width='50%' align='center' class='diff-ntitle'>" . wfMsgHTML('oversight-hidden') . "</td>" . "</tr>" . $diffEngine->generateDiffBody($otext, $ntext) . "</table>" . "</div>\n");
     }
     $dbr->freeResult($result);
 }
 protected function parseRevisionText(\Revision $revision)
 {
     $options = $this->getParserOptions();
     return $this->getParser()->parse($revision->getText(), $this->title, $options, true, true, $revision->getId());
 }
Esempio n. 17
0
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;
}
 /**
  * Automatically review an revision and add a log entry in the review log.
  *
  * This is called during edit operations after the new revision is added
  * and the page tables updated, but before LinksUpdate is called.
  *
  * $auto is here for revisions checked off to be reviewed. Auto-review
  * triggers on edit, but we don't want those to count as just automatic.
  * This also makes it so the user's name shows up in the page history.
  *
  * If $flags is given, then they will be the review tags. If not, the one
  * from the stable version will be used or minimal tags if that's not possible.
  * If no appropriate tags can be found, then the review will abort.
  */
 public static function autoReviewEdit(Page $article, $user, Revision $rev, array $flags = null, $auto = true)
 {
     wfProfileIn(__METHOD__);
     $title = $article->getTitle();
     // convenience
     # Get current stable version ID (for logging)
     $oldSv = FlaggedRevision::newFromStable($title, FR_MASTER);
     $oldSvId = $oldSv ? $oldSv->getRevId() : 0;
     # Set the auto-review tags from the prior stable version.
     # Normally, this should already be done and given here...
     if (!is_array($flags)) {
         if ($oldSv) {
             # Use the last stable version if $flags not given
             if ($user->isAllowed('bot')) {
                 $flags = $oldSv->getTags();
                 // no change for bot edits
             } else {
                 # Account for perms/tags...
                 $flags = self::getAutoReviewTags($user, $oldSv->getTags());
             }
         } else {
             // new page?
             $flags = self::quickTags(FR_CHECKED);
             // use minimal level
         }
         if (!is_array($flags)) {
             wfProfileOut(__METHOD__);
             return false;
             // can't auto-review this revision
         }
     }
     # Get review property flags
     $propFlags = $auto ? array('auto') : array();
     # Rev ID is not put into parser on edit, so do the same here.
     # Also, a second parse would be triggered otherwise.
     $editInfo = $article->prepareTextForEdit($rev->getText());
     $poutput = $editInfo->output;
     // revision HTML output
     # If this is an image page, store corresponding file info
     $fileData = array('name' => null, 'timestamp' => null, 'sha1' => null);
     if ($title->getNamespace() == NS_FILE) {
         # We must use WikiFilePage process cache on upload or get bitten by slave lag
         $file = $article instanceof WikiFilePage || $article instanceof ImagePage ? $article->getFile() : wfFindFile($title, array('bypassCache' => true));
         // skip cache; bug 31056
         if (is_object($file) && $file->exists()) {
             $fileData['name'] = $title->getDBkey();
             $fileData['timestamp'] = $file->getTimestamp();
             $fileData['sha1'] = $file->getSha1();
         }
     }
     # Our review entry
     $flaggedRevision = new FlaggedRevision(array('rev' => $rev, 'user_id' => $user->getId(), 'timestamp' => $rev->getTimestamp(), 'quality' => FlaggedRevs::getQualityTier($flags, 0), 'tags' => FlaggedRevision::flattenRevisionTags($flags), 'img_name' => $fileData['name'], 'img_timestamp' => $fileData['timestamp'], 'img_sha1' => $fileData['sha1'], 'templateVersions' => $poutput->getTemplateIds(), 'fileVersions' => $poutput->getFileSearchOptions(), 'flags' => implode(',', $propFlags)));
     $flaggedRevision->insert();
     # Update the article review log
     FlaggedRevsLog::updateReviewLog($title, $flags, array(), '', $rev->getId(), $oldSvId, true, $auto);
     # Update page and tracking tables and clear cache
     FlaggedRevs::stableVersionUpdates($title);
     wfProfileOut(__METHOD__);
     return true;
 }
Esempio n. 19
0
 /**
  * Propagate an article undelete
  * Sets xml property and calls the abstract function propagateUndeleteData($title)
  * @param Revision $revision being undeleted
  * @return bool true if propagate succeeded
  */
 public function propagateUndelete($revision)
 {
     global $wgUser, $wrBotUserID;
     $result = true;
     // we do propagate bot edits
     //	   if ($wgUser->getID() != $wrBotUserID) {
     if (!$revision) {
         error_log("Undeleted revision not found: " . $revision->getTitle()->getPrefixedText() . "\n");
         return true;
     }
     $text =& $revision->getText();
     $this->xml = StructuredData::getXml($this->tagName, $text);
     $titleString = $revision->getTitle()->getText();
     $ns = $revision->getTitle()->getNamespace();
     $textChanged = false;
     // Sometimes the article being undeleted has been re-created, in which case nothing should be changed by undelete
     // (only previous revisions are restored), so make sure propagateUndeleteData is idempotent
     $result = $this->propagateMoveDeleteUndelete($titleString, $ns, $text, $textChanged);
     if ($result && $textChanged) {
         // clear the link cache so we get the right page id for the undeleted article
         //$linkCache =& LinkCache::singleton();
         //$linkCache->clearBadLink($revision->getTitle()->getPrefixedDBkey());
         $newTitle = Title::makeTitle($revision->getTitle()->getNamespace(), $revision->getTitle()->getDBkey());
         $newTitle->resetArticleID(0);
         // clears link cache
         $newTitle->getArticleID(GAID_FOR_UPDATE);
         // make sure you read the master db for the pageid
         $article = new Article($newTitle, 0);
         PropagationManager::enablePropagation(false);
         $result = $article->doEdit($text, self::PROPAGATE_MESSAGE, PROPAGATE_EDIT_FLAGS);
         PropagationManager::enablePropagation(true);
     }
     //	   }
     return $result;
 }
Esempio n. 20
0
    $untilHappy = false;
} else {
    $limit = 1000;
    $untilHappy = true;
}
$type = isset($options['type']) ? $options['type'] : 'ConcatenatedGzipHistoryBlob';
$dbr = wfGetDB(DB_SLAVE);
$res = $dbr->select(array('page', 'revision', 'text'), '*', array('page_namespace' => $title->getNamespace(), 'page_title' => $title->getDBkey(), 'page_id=rev_page', 'rev_timestamp > ' . $dbr->addQuotes($dbr->timestamp($start)), 'rev_text_id=old_id'), __FILE__, array('LIMIT' => $limit));
$blob = new $type();
$hashes = array();
$keys = array();
$uncompressedSize = 0;
$t = -microtime(true);
foreach ($res as $row) {
    $revision = new Revision($row);
    $text = $revision->getText();
    $uncompressedSize += strlen($text);
    $hashes[$row->rev_id] = md5($text);
    $keys[$row->rev_id] = $blob->addItem($text);
    if ($untilHappy && !$blob->isHappy()) {
        break;
    }
}
$serialized = serialize($blob);
$t += microtime(true);
# print_r( $blob->mDiffMap );
printf("%s\nCompression ratio for %d revisions: %5.2f, %s -> %d\n", $type, count($hashes), $uncompressedSize / strlen($serialized), $wgLang->formatSize($uncompressedSize), strlen($serialized));
printf("Compression time: %5.2f ms\n", $t * 1000);
$t = -microtime(true);
$blob = unserialize($serialized);
foreach ($keys as $id => $key) {
Esempio n. 21
0
 /**
  * Get the text that needs to be saved in order to undo all revisions
  * between $undo and $undoafter. Revisions must belong to the same page,
  * must exist and must not be deleted
  * @param $undo Revision
  * @param $undoafter Revision Must be an earlier revision than $undo
  * @return mixed string on success, false on failure
  */
 public function getUndoText(Revision $undo, Revision $undoafter = null)
 {
     $undo_text = $undo->getText();
     $undoafter_text = $undoafter->getText();
     $cur_text = $this->getContent();
     if ($cur_text == $undo_text) {
         # No use doing a merge if it's just a straight revert.
         return $undoafter_text;
     }
     $undone_text = '';
     if (!wfMerge($undo_text, $undoafter_text, $cur_text, $undone_text)) {
         return false;
     }
     return $undone_text;
 }
 /**
  * Look up some text of a revision from its revision id
  *
  * Note that this is really *some* text, we do not make *any* guarantee
  * that this text will be even close to what the user actually sees, or
  * that the form is fit for any intended purpose.
  *
  * Note also that if the revision for any reason is not an Revision
  * the function returns with an empty string.
  *
  * @param Revision $revision a valid revision
  * @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
  * @return string|null the content of the revision as some kind of string,
  * 		or an empty string if it can not be found
  */
 static function revisionToString($revision, $audience = Revision::FOR_THIS_USER)
 {
     if (!$revision instanceof Revision) {
         return '';
     }
     if (defined('MW_SUPPORTS_CONTENTHANDLER')) {
         $content = $revision->getContent($audience);
         if ($content === null) {
             return '';
         }
         $result = self::contentToString($content);
     } else {
         // For MediaWiki without contenthandler support (< 1.21)
         $result = $revision->getText();
     }
     return $result;
 }
Esempio n. 23
0
 /**
 * Update the page record to point to a newly saved revision.
 *
 * @param Database $dbw
 * @param Revision $revision For ID number, and text used to set
                             length and redirect status fields
 * @param int $lastRevision If given, will not overwrite the page field
 *                          when different from the currently set value.
 *                          Giving 0 indicates the new page flag should
 *                          be set on.
 * @return bool true on success, false on failure
 * @private
 */
 function updateRevisionOn(&$dbw, $revision, $lastRevision = null)
 {
     wfProfileIn(__METHOD__);
     $conditions = array('page_id' => $this->getId());
     if (!is_null($lastRevision)) {
         # An extra check against threads stepping on each other
         $conditions['page_latest'] = $lastRevision;
     }
     $text = $revision->getText();
     $dbw->update('page', array('page_latest' => $revision->getId(), 'page_touched' => $dbw->timestamp(), 'page_is_new' => $lastRevision === 0 ? 1 : 0, 'page_is_redirect' => Article::isRedirect($text) ? 1 : 0, 'page_len' => strlen($text)), $conditions, __METHOD__);
     wfProfileOut(__METHOD__);
     return $dbw->affectedRows() != 0;
 }
 /**
  * Check if a user reverted himself to the stable version
  */
 protected static function isSelfRevertToStable(Revision $rev, $srev, $baseRevId, $user)
 {
     if (!$srev || $baseRevId != $srev->getRevId()) {
         return false;
         // user reports they are not the same
     }
     $dbw = wfGetDB(DB_MASTER);
     # Such a revert requires 1+ revs between it and the stable
     $revertedRevs = $dbw->selectField('revision', '1', array('rev_page' => $rev->getPage(), 'rev_id > ' . intval($baseRevId), 'rev_id < ' . intval($rev->getId()), 'rev_user_text' => $user->getName()), __METHOD__);
     if (!$revertedRevs) {
         return false;
         // can't be a revert
     }
     # Check that this user is ONLY reverting his/herself.
     $otherUsers = $dbw->selectField('revision', '1', array('rev_page' => $rev->getPage(), 'rev_id > ' . intval($baseRevId), 'rev_user_text != ' . $dbw->addQuotes($user->getName())), __METHOD__);
     if ($otherUsers) {
         return false;
         // only looking for self-reverts
     }
     # Confirm the text because we can't trust this user.
     return $rev->getText() == $srev->getRevText();
 }
Esempio n. 25
0
	public function execute() {
		global $wgContLang;

		$dbw = TranslationMemoryUpdater::getDatabaseHandle();
		if ( $dbw === null ) {
			$this->error( "Database file not configured" );
			$this->exit();
		}
		$dbw->setFlag( DBO_TRX ); // HUGE speed improvement

		$groups = MessageGroups::singleton()->getGroups();
		// TODO: encapsulate list of valid language codes
		$languages = Language::getLanguageNames( false );
		unset( $languages['en'] );

		foreach ( $groups as $id => $group ) {
			if ( $group->isMeta() ) {
				continue;
			}

			$this->output( "Processing: {$group->getLabel()} ", $id );
			$capitalized = MWNamespace::isCapitalized( $group->getNamespace() );
			$ns_text = $wgContLang->getNsText( $group->getNamespace() );

			$definitions = $group->load( $group->getSourceLanguage() );
			foreach ( $definitions as $key => $definition ) {
				// TODO: would be nice to do key normalisation closer to the message groups, to avoid transforming back and forth.
				// But how to preserve the original keys...
				$key = strtr( $key, ' ', '_' );
				$key = $capitalized ? $wgContLang->ucfirst( $key ) : $key;

				$dbr = wfGetDB( DB_SLAVE );
				$tables = array( 'page', 'revision', 'text' );
				// selectFields to stfu Revision class
				$vars = array_merge( Revision::selectTextFields(), array( 'page_title' ), Revision::selectFields() );
				$conds = array(
					'page_latest = rev_id',
					'rev_text_id = old_id',
					'page_namespace' => $group->getNamespace(),
					'page_title ' . $dbr->buildLike( "$key/", $dbr->anyString() )
				);

				$res = $dbr->select( $tables, $vars, $conds, __METHOD__ );
				// Assure that there is at least one translation
				if ( $res->numRows() < 1 ) {
					continue;
				}

				$insert = array(
					'text' => $definition,
					'context' => "$ns_text:$key",
					'length' => strlen( $definition ),
					'lang' => $group->getSourceLanguage(),
				);

				$source_id = $dbw->selectField( '`sources`', 'sid', $insert, __METHOD__ );
				if ( $source_id === false ) {
					$dbw->insert( '`sources`', $insert, __METHOD__ );
					$source_id = $dbw->insertId();
				}

				$this->output( ' ', $id );

				foreach ( $res as $row ) {
					list( , $code ) = TranslateUtils::figureMessage( $row->page_title );
					$revision = new Revision( $row );
					$insert = array(
						'text' => $revision->getText(),
						'lang' => $code,
						'time' => wfTimestamp(),
						'sid' => $source_id );
					// We only do SQlite which doesn't need to know unique indexes
					$dbw->replace( '`targets`', null, $insert, __METHOD__ );
				}
				$this->output( "{$res->numRows()}", $id );

			} // each translation>

			$dbw->commit();
		} // each group>
	}