Ejemplo n.º 1
13
    function showDiffPage($diffOnly = false)
    {
        global $wgUser, $wgOut, $wgUseExternalEditor, $wgUseRCPatrol, $wgRequest, $wgTitle, $wgLanguageCode;
        $fname = 'DifferenceEngine::showDiffPage';
        wfProfileIn($fname);
        # If external diffs are enabled both globally and for the user,
        # we'll use the application/x-external-editor interface to call
        # an external diff tool like kompare, kdiff3, etc.
        if ($wgUseExternalEditor && $wgUser->getOption('externaldiff')) {
            global $wgInputEncoding, $wgServer, $wgScript, $wgLang;
            $wgOut->disable();
            header("Content-type: application/x-external-editor; charset=" . $wgInputEncoding);
            $url1 = $this->mTitle->getFullURL("action=raw&oldid=" . $this->mOldid);
            $url2 = $this->mTitle->getFullURL("action=raw&oldid=" . $this->mNewid);
            $special = $wgLang->getNsText(NS_SPECIAL);
            $control = <<<CONTROL
[Process]
Type=Diff text
Engine=MediaWiki
Script={$wgServer}{$wgScript}
Special namespace={$special}

[File]
Extension=wiki
URL={$url1}

[File 2]
Extension=wiki
URL={$url2}
CONTROL;
            echo $control;
            return;
        }
        $wgOut->setArticleFlag(false);
        if (!$this->loadRevisionData()) {
            $t = $this->mTitle->getPrefixedText() . " (Diff: {$this->mOldid}, {$this->mNewid})";
            $wgOut->setPagetitle(wfMsg('errorpagetitle'));
            $wgOut->addWikiMsg('missingarticle', "<nowiki>{$t}</nowiki>");
            wfProfileOut($fname);
            return;
        }
        wfRunHooks('DiffViewHeader', array($this, $this->mOldRev, $this->mNewRev));
        if ($this->mNewRev->isCurrent()) {
            $wgOut->setArticleFlag(true);
        }
        # mOldid is false if the difference engine is called with a "vague" query for
        # a diff between a version V and its previous version V' AND the version V
        # is the first version of that article. In that case, V' does not exist.
        if ($this->mOldid === false && false) {
            $this->showFirstRevision();
            $this->renderNewRevision();
            // should we respect $diffOnly here or not?
            wfProfileOut($fname);
            return;
        }
        $wgOut->suppressQuickbar();
        if (!$this->mOldPage) {
            $this->mOldPage = $this->mNewPage;
        }
        $oldTitle = $this->mOldPage->getPrefixedText();
        $newTitle = $this->mNewPage->getPrefixedText();
        if ($oldTitle == $newTitle) {
            $wgOut->setPageTitle($newTitle);
        } else {
            $wgOut->setPageTitle($oldTitle . ', ' . $newTitle);
        }
        $wgOut->setSubtitle(wfMsg('difference'));
        $wgOut->setRobotpolicy('noindex,nofollow');
        if (!($this->mOldPage->userCanRead() && $this->mNewPage->userCanRead())) {
            $wgOut->loginToUse();
            $wgOut->output();
            wfProfileOut($fname);
            exit;
        }
        $sk = $wgUser->getSkin();
        if ($this->mNewRev->isCurrent() && $wgUser->isAllowed('rollback') && $this->mTitle->userCanEdit()) {
            $rollback = $sk->generateRollback($this->mNewRev);
        } else {
            $rollback = '';
        }
        // Prepare a change patrol link, if applicable
        if ($wgUseRCPatrol && $wgUser->isAllowed('patrol')) {
            // If we've been given an explicit change identifier, use it; saves time
            if ($this->mRcidMarkPatrolled) {
                $rcid = $this->mRcidMarkPatrolled;
            } else {
                // Look for an unpatrolled change corresponding to this diff
                $db = wfGetDB(DB_SLAVE);
                $change = RecentChange::newFromConds(array('rc_user_text' => $this->mNewRev->getRawUserText(), 'rc_timestamp' => $db->timestamp($this->mNewRev->getTimestamp()), 'rc_this_oldid' => $this->mNewid, 'rc_last_oldid' => $this->mOldid, 'rc_patrolled' => 0), __METHOD__);
                if ($change instanceof RecentChange) {
                    $rcid = $change->mAttribs['rc_id'];
                } else {
                    // None found
                    $rcid = 0;
                }
            }
            // Build the link
            if ($rcid) {
                //XXCHANGED for recent changes patrolling
                $show_namespace = $wgRequest->getVal('show_namespace');
                $invert = $wgRequest->getVal('invert');
                $featured = $wgRequest->getVal('featured');
                $reverse = $wgRequest->getVal('reverse');
                //XXCHANGED
                $fromrc = "";
                if ($wgRequest->getVal('fromrc', null) != null) {
                    $fromrc = "&fromrc=1";
                }
                if ($this->mRcidMarkPatrolledCount > 1) {
                    $msg = wfMsg('markaspatrolleddiff_multiple', $this->mRcidMarkPatrolledCount);
                    $patrol = '[' . $sk->makeKnownLinkObj($this->mTitle, $msg, "action=markpatrolled&rcid={$this->mRcidMarkPatrolled}&show_namespace={$show_namespace}" . "&invert={$invert}&reverse={$reverse}&featured={$featured}" . "&rchi={$this->mRcidMarkPatrolledMax}&rclow={$this->mRcidMarkPatrolledMin}{$fromrc}", '', '', "accesskey='p'") . ']';
                    $patrol .= '[' . $sk->makeKnownLinkObj($this->mTitle, wfMsg('skip'), "action=markpatrolled&rcid={$this->mRcidMarkPatrolled}&show_namespace={$show_namespace}" . "&invert={$invert}&reverse={$reverse}&featured={$featured}" . "&rchi={$this->mRcidMarkPatrolledMax}&rclow={$this->mRcidMarkPatrolledMin}{$fromrc}&skip=1", '', '', "") . ']';
                } else {
                    $patrol = '[' . $sk->makeKnownLinkObj($this->mTitle, wfMsg('markaspatrolleddiff'), "action=markpatrolled&rcid={$rcid}&show_namespace={$show_namespace}&invert={$invert}&reverse={$reverse}&featured={$featured}{$fromrc}", '', '', "accesskey='p'") . ']';
                    $patrol .= ' [' . $sk->makeKnownLinkObj($this->mTitle, wfMsg('skip'), "action=markpatrolled&rcid={$this->mRcidMarkPatrolled}&show_namespace={$show_namespace}&invert={$invert}&reverse={$reverse}&featured={$featured}&skip=1{$fromrc}") . ']';
                }
                $patrol = "<span id='markaspatrolledlinks'>{$patrol}</span>";
                //XXADDED
            } else {
                $patrol = '';
            }
        } else {
            $patrol = '';
        }
        //XXADDED
        if ($wgUser->isAllowed('rollback') && $this->mTitle->userCanEdit()) {
            //$rollback .= '<br/>&nbsp;&nbsp;&nbsp;<strong>' . SpamDiffTool::getDiffLink($this->mTitle) . '</strong>';
        }
        $prevlink = $sk->makeKnownLinkObj($this->mTitle, wfMsgHtml('previousdiff'), 'diff=prev&oldid=' . $this->mOldid, '', '', 'id="differences-prevlink"');
        if ($this->mNewRev->isCurrent()) {
            $nextlink = '';
        } else {
            $nextlink = $sk->makeKnownLinkObj($this->mTitle, wfMsgHtml('nextdiff'), 'diff=next&oldid=' . $this->mNewid, '', '', 'id="differences-nextlink"');
        }
        $oldminor = '';
        $newminor = '';
        if ($this->mOldRev->mMinorEdit == 1) {
            $oldminor = wfElement('span', array('class' => 'minor'), wfMsg('minoreditletter')) . ' ';
        }
        if ($this->mNewRev->mMinorEdit == 1) {
            $newminor = wfElement('span', array('class' => 'minor'), wfMsg('minoreditletter')) . ' ';
        }
        $rdel = '';
        $ldel = '';
        if ($wgUser->isAllowed('deleterevision')) {
            $revdel = SpecialPage::getTitleFor('Revisiondelete');
            if (!$this->mOldRev->userCan(Revision::DELETED_RESTRICTED)) {
                // If revision was hidden from sysops
                $ldel = wfMsgHtml('rev-delundel');
            } else {
                $ldel = $sk->makeKnownLinkObj($revdel, wfMsgHtml('rev-delundel'), 'target=' . urlencode($this->mOldRev->mTitle->getPrefixedDbkey()) . '&oldid=' . urlencode($this->mOldRev->getId()));
                // Bolden oversighted content
                if ($this->mOldRev->isDeleted(Revision::DELETED_RESTRICTED)) {
                    $ldel = "<strong>{$ldel}</strong>";
                }
            }
            $ldel = "&nbsp;&nbsp;&nbsp;<tt>(<small>{$ldel}</small>)</tt> ";
            // We don't currently handle well changing the top revision's settings
            if ($this->mNewRev->isCurrent()) {
                // If revision was hidden from sysops
                $rdel = wfMsgHtml('rev-delundel');
            } else {
                if (!$this->mNewRev->userCan(Revision::DELETED_RESTRICTED)) {
                    // If revision was hidden from sysops
                    $rdel = wfMsgHtml('rev-delundel');
                } else {
                    $rdel = $sk->makeKnownLinkObj($revdel, wfMsgHtml('rev-delundel'), 'target=' . urlencode($this->mNewRev->mTitle->getPrefixedDbkey()) . '&oldid=' . urlencode($this->mNewRev->getId()));
                    // Bolden oversighted content
                    if ($this->mNewRev->isDeleted(Revision::DELETED_RESTRICTED)) {
                        $rdel = "<strong>{$rdel}</strong>";
                    }
                }
            }
            $rdel = "&nbsp;&nbsp;&nbsp;<tt>(<small>{$rdel}</small>)</tt> ";
        }
        if ($this->mOldRev) {
            /*$oldHeader = '<div id="mw-diff-otitle1"><strong>'.$this->mOldtitle.'</strong></div>' .
            		'<div id="mw-diff-otitle2">' . $sk->revUserTools( $this->mOldRev, true ) . "</div>" .
            		'<div id="mw-diff-otitle3">' . $oldminor . $sk->revComment( $this->mOldRev, !$diffOnly, true ) . $ldel . "</div>" .
            		'<div id="mw-diff-otitle4">' . $prevlink .'</div>';*/
            $comment = $oldminor . $sk->revComment($this->mOldRev, !$diffOnly, true) . $ldel;
            //INTL: Avatar database data doesn't exist for sites other than English
            if ($wgLanguageCode == 'en') {
                $av = '<img src="' . Avatar::getAvatarURL($this->mOldRev->mUserText) . '" class="diff_avatar" />';
            }
            //$userToolsString = $sk->revUserTools( $this->mOldRev, true );
            //$userParts = explode("(", $userToolsString, 2);
            //$userName = $userParts[0];
            //$userTools = "(" . $userParts[1];
            $userName = $sk->userLink($this->mOldRev->getUser(), $this->mOldRev->getUserText());
            $userTools = $sk->userToolLinks($this->mOldRev->getUser(), $this->mOldRev->getUserText());
            $oldHeader = '<div id="mw-diff-otitle1"><h4>' . $prevlink . $this->mOldtitle . '</h4></div>' . '<div class="diff_details">' . $av . '<div id="mw-diff-otitle1a">' . wfMsg('diff_by') . ' ' . $userName . '</div>' . '<div id="mw-diff-otitle2">' . $this->mOldDate . "</div>" . '<div id="mw-diff-otitle2b">' . $userTools . "</div>";
            if ($comment != "") {
                $oldHeader .= '<div id="mw-diff-otitle3" class="rccomment"><div class="">' . $comment . '</div></div>';
            }
            $oldHeader .= '</div>';
        } else {
            $oldHeader = wfMsg('diff_noprev');
        }
        /*$newHeader = '<div id="mw-diff-ntitle1"><strong>'.$this->mNewtitle.'</strong></div>' .
        		'<div id="mw-diff-ntitle2">' . $sk->revUserTools( $this->mNewRev, true ) . "</div>" .
        		'<div id="mw-diff-ntitle2a">' . $rollback . "</div>" .
        		'<div id="mw-diff-ntitle3">' . $newminor . $sk->revComment( $this->mNewRev, !$diffOnly, true ) . $rdel . "</div>" .
        		'<div id="mw-diff-ntitle4">' . $nextlink . $patrol . '</div>';*/
        $comment = $newminor . $sk->revComment($this->mNewRev, !$diffOnly, true) . $rdel;
        //INTL: Avatar database data doesn't exist for sites other than English
        if ($wgLanguageCode == 'en') {
            $av = '<img src="' . Avatar::getAvatarURL($this->mNewRev->mUserText) . '" class="diff_avatar" />';
        }
        //$userToolsString = $sk->revUserTools( $this->mNewRev, true );
        //$userParts = explode("(", $userToolsString, 2);
        //$userName = $userParts[0];
        //$userTools = "(" . $userParts[1];
        $userName = $sk->userLink($this->mNewRev->getUser(), $this->mNewRev->getUserText());
        $userTools = $sk->userToolLinks($this->mNewRev->getUser(), $this->mNewRev->getUserText());
        $thumbsHtml = "";
        $thumbHeader = "";
        $th_diff_div = "";
        if ($wgUser->getId() != 0 && $wgTitle->getText() != "RCPatrol" && $wgTitle->getText() != "RCPatrolGuts" && $this->mNewRev->getTitle()->getNamespace() == NS_MAIN) {
            $oldId = $this->mNewRev->getPrevious();
            $oldId = $oldId ? $oldId->getId() : -1;
            // Only show thumbs up for diffs that look back one revision
            if (class_exists('ThumbsUp')) {
                if ($oldId == -1 || $this->mOldRev && $oldId == $this->mOldRev->getId()) {
                    $params = array('title' => $this->mNewRev->getTitle(), 'new' => $this->mNewid, 'old' => $oldId, 'vandal' => 0);
                    $thumbsHtml = ThumbsUp::getThumbsUpButton($params, true);
                    //$thumbHeader = 'class="th_diff_h4"';
                    $th_diff_div = 'class="th_diff_div"';
                }
            }
        }
        $newHeader = '<div id="mw-diff-ntitle1" ' . $th_diff_div . '><h4 ' . $thumbHeader . '>' . $this->mNewtitle . ' ' . $nextlink . '</h4></div>' . '<div class="diff_details">' . $av . $thumbsHtml . '<div id="mw-diff-ntitle1a">' . wfMsg('diff_by') . ' ' . $userName . '</div>' . '<div id="mw-diff-ntitle2">' . $this->mNewDate . "</div>" . '<div id="mw-diff-ntitle2b">' . $userTools . "</div>" . '<div id="mw-diff-ntitle4" style="text-align:left">' . $rollback . $nextlink . $patrol . '</div>';
        if ($comment != "") {
            $newHeader .= '<div id="mw-diff-ntitle3" class="rccomment"><div class="">' . $comment . '</div></div>';
        }
        $newHeader .= '</div>';
        $this->showDiff($oldHeader, $newHeader);
        if (!$diffOnly) {
            $this->renderNewRevision();
        }
        wfProfileOut($fname);
    }
Ejemplo n.º 2
0
    function showDiffPage($diffOnly = false)
    {
        global $wgUser, $wgOut, $wgUseExternalEditor, $wgUseRCPatrol;
        wfProfileIn(__METHOD__);
        # Allow frames except in certain special cases
        $wgOut->allowClickjacking();
        # If external diffs are enabled both globally and for the user,
        # we'll use the application/x-external-editor interface to call
        # an external diff tool like kompare, kdiff3, etc.
        if ($wgUseExternalEditor && $wgUser->getOption('externaldiff')) {
            global $wgCanonicalServer, $wgScript, $wgLang;
            $wgOut->disable();
            header("Content-type: application/x-external-editor; charset=UTF-8");
            $url1 = $this->mTitle->getCanonical(array('action' => 'raw', 'oldid' => $this->mOldid));
            $url2 = $this->mTitle->getCanonical(array('action' => 'raw', 'oldid' => $this->mNewid));
            $special = $wgLang->getNsText(NS_SPECIAL);
            $control = <<<CONTROL
\t\t\t[Process]
\t\t\tType=Diff text
\t\t\tEngine=MediaWiki
\t\t\tScript={$wgCanonicalServer}{$wgScript}
\t\t\tSpecial namespace={$special}

\t\t\t[File]
\t\t\tExtension=wiki
\t\t\tURL={$url1}

\t\t\t[File 2]
\t\t\tExtension=wiki
\t\t\tURL={$url2}
CONTROL;
            echo $control;
            wfProfileOut(__METHOD__);
            return;
        }
        $wgOut->setArticleFlag(false);
        if (!$this->loadRevisionData()) {
            // Sounds like a deleted revision... Let's see what we can do.
            $t = $this->mTitle->getPrefixedText();
            $d = wfMsgExt('missingarticle-diff', array('escape'), $this->deletedIdMarker($this->mOldid), $this->deletedIdMarker($this->mNewid));
            $wgOut->setPagetitle(wfMsg('errorpagetitle'));
            $wgOut->addWikiMsg('missing-article', "<nowiki>{$t}</nowiki>", "<span class='plainlinks'>{$d}</span>");
            wfProfileOut(__METHOD__);
            return;
        }
        wfRunHooks('DiffViewHeader', array($this, $this->mOldRev, $this->mNewRev));
        if ($this->mNewRev->isCurrent()) {
            $wgOut->setArticleFlag(true);
        }
        # mOldid is false if the difference engine is called with a "vague" query for
        # a diff between a version V and its previous version V' AND the version V
        # is the first version of that article. In that case, V' does not exist.
        if ($this->mOldid === false) {
            $this->showFirstRevision();
            $this->renderNewRevision();
            // should we respect $diffOnly here or not?
            wfProfileOut(__METHOD__);
            return;
        }
        $oldTitle = $this->mOldPage->getPrefixedText();
        $newTitle = $this->mNewPage->getPrefixedText();
        if ($oldTitle == $newTitle) {
            $wgOut->setPageTitle($newTitle);
        } else {
            $wgOut->setPageTitle($oldTitle . ', ' . $newTitle);
        }
        if ($this->mNewPage->equals($this->mOldPage)) {
            $wgOut->setSubtitle(wfMsgExt('difference', array('parseinline')));
        } else {
            $wgOut->setSubtitle(wfMsgExt('difference-multipage', array('parseinline')));
        }
        $wgOut->setRobotPolicy('noindex,nofollow');
        if (!$this->mOldPage->userCanRead() || !$this->mNewPage->userCanRead()) {
            $wgOut->loginToUse();
            $wgOut->output();
            $wgOut->disable();
            wfProfileOut(__METHOD__);
            return;
        }
        $sk = $wgUser->getSkin();
        if (method_exists($sk, 'suppressQuickbar')) {
            $sk->suppressQuickbar();
        }
        // Check if page is editable
        $editable = $this->mNewRev->getTitle()->userCan('edit');
        if ($editable && $this->mNewRev->isCurrent() && $wgUser->isAllowed('rollback')) {
            $wgOut->preventClickjacking();
            $rollback = '&#160;&#160;&#160;' . $sk->generateRollback($this->mNewRev);
        } else {
            $rollback = '';
        }
        // Prepare a change patrol link, if applicable
        if ($wgUseRCPatrol && $this->mTitle->userCan('patrol')) {
            // If we've been given an explicit change identifier, use it; saves time
            if ($this->mRcidMarkPatrolled) {
                $rcid = $this->mRcidMarkPatrolled;
                $rc = RecentChange::newFromId($rcid);
                // Already patrolled?
                $rcid = is_object($rc) && !$rc->getAttribute('rc_patrolled') ? $rcid : 0;
            } else {
                // Look for an unpatrolled change corresponding to this diff
                $db = wfGetDB(DB_SLAVE);
                $change = RecentChange::newFromConds(array('rc_user_text' => $this->mNewRev->getRawUserText(), 'rc_timestamp' => $db->timestamp($this->mNewRev->getTimestamp()), 'rc_this_oldid' => $this->mNewid, 'rc_last_oldid' => $this->mOldid, 'rc_patrolled' => 0), __METHOD__);
                if ($change instanceof RecentChange) {
                    $rcid = $change->mAttribs['rc_id'];
                    $this->mRcidMarkPatrolled = $rcid;
                } else {
                    // None found
                    $rcid = 0;
                }
            }
            // Build the link
            if ($rcid) {
                $wgOut->preventClickjacking();
                $token = $wgUser->editToken($rcid);
                $patrol = ' <span class="patrollink">[' . $sk->link($this->mTitle, wfMsgHtml('markaspatrolleddiff'), array(), array('action' => 'markpatrolled', 'rcid' => $rcid, 'token' => $token), array('known', 'noclasses')) . ']</span>';
            } else {
                $patrol = '';
            }
        } else {
            $patrol = '';
        }
        # Carry over 'diffonly' param via navigation links
        if ($diffOnly != $wgUser->getBoolOption('diffonly')) {
            $query['diffonly'] = $diffOnly;
        }
        # Make "previous revision link"
        $query['diff'] = 'prev';
        $query['oldid'] = $this->mOldid;
        # Cascade unhide param in links for easy deletion browsing
        if ($this->unhide) {
            $query['unhide'] = 1;
        }
        if (!$this->mOldRev->getPrevious()) {
            $prevlink = '&#160;';
        } else {
            $prevlink = $sk->link($this->mTitle, wfMsgHtml('previousdiff'), array('id' => 'differences-prevlink'), $query, array('known', 'noclasses'));
        }
        # Make "next revision link"
        $query['diff'] = 'next';
        $query['oldid'] = $this->mNewid;
        # Skip next link on the top revision
        if ($this->mNewRev->isCurrent()) {
            $nextlink = '&#160;';
        } else {
            $nextlink = $sk->link($this->mTitle, wfMsgHtml('nextdiff'), array('id' => 'differences-nextlink'), $query, array('known', 'noclasses'));
        }
        $oldminor = '';
        $newminor = '';
        if ($this->mOldRev->isMinor()) {
            $oldminor = ChangesList::flag('minor');
        }
        if ($this->mNewRev->isMinor()) {
            $newminor = ChangesList::flag('minor');
        }
        # Handle RevisionDelete links...
        $ldel = $this->revisionDeleteLink($this->mOldRev);
        $rdel = $this->revisionDeleteLink($this->mNewRev);
        $oldHeader = '<div id="mw-diff-otitle1"><strong>' . $this->mOldtitle . '</strong></div>' . '<div id="mw-diff-otitle2">' . $sk->revUserTools($this->mOldRev, !$this->unhide) . '</div>' . '<div id="mw-diff-otitle3">' . $oldminor . $sk->revComment($this->mOldRev, !$diffOnly, !$this->unhide) . $ldel . '</div>' . '<div id="mw-diff-otitle4">' . $prevlink . '</div>';
        $newHeader = '<div id="mw-diff-ntitle1"><strong>' . $this->mNewtitle . '</strong></div>' . '<div id="mw-diff-ntitle2">' . $sk->revUserTools($this->mNewRev, !$this->unhide) . " {$rollback}</div>" . '<div id="mw-diff-ntitle3">' . $newminor . $sk->revComment($this->mNewRev, !$diffOnly, !$this->unhide) . $rdel . '</div>' . '<div id="mw-diff-ntitle4">' . $nextlink . $patrol . '</div>';
        # Check if this user can see the revisions
        $allowed = $this->mOldRev->userCan(Revision::DELETED_TEXT) && $this->mNewRev->userCan(Revision::DELETED_TEXT);
        # Check if one of the revisions is deleted/suppressed
        $deleted = $suppressed = false;
        if ($this->mOldRev->isDeleted(Revision::DELETED_TEXT)) {
            $deleted = true;
            // old revisions text is hidden
            if ($this->mOldRev->isDeleted(Revision::DELETED_RESTRICTED)) {
                $suppressed = true;
            }
            // also suppressed
        }
        if ($this->mNewRev->isDeleted(Revision::DELETED_TEXT)) {
            $deleted = true;
            // new revisions text is hidden
            if ($this->mNewRev->isDeleted(Revision::DELETED_RESTRICTED)) {
                $suppressed = true;
            }
            // also suppressed
        }
        # If the diff cannot be shown due to a deleted revision, then output
        # the diff header and links to unhide (if available)...
        if ($deleted && (!$this->unhide || !$allowed)) {
            $this->showDiffStyle();
            $multi = $this->getMultiNotice();
            $wgOut->addHTML($this->addHeader('', $oldHeader, $newHeader, $multi));
            if (!$allowed) {
                $msg = $suppressed ? 'rev-suppressed-no-diff' : 'rev-deleted-no-diff';
                # Give explanation for why revision is not visible
                $wgOut->wrapWikiMsg("<div id='mw-{$msg}' class='mw-warning plainlinks'>\n\$1\n</div>\n", array($msg));
            } else {
                # Give explanation and add a link to view the diff...
                $link = $this->mTitle->getFullUrl(array('diff' => $this->mNewid, 'oldid' => $this->mOldid, 'unhide' => 1));
                $msg = $suppressed ? 'rev-suppressed-unhide-diff' : 'rev-deleted-unhide-diff';
                $wgOut->wrapWikiMsg("<div id='mw-{$msg}' class='mw-warning plainlinks'>\n\$1\n</div>\n", array($msg, $link));
            }
            # Otherwise, output a regular diff...
        } else {
            # Add deletion notice if the user is viewing deleted content
            $notice = '';
            if ($deleted) {
                $msg = $suppressed ? 'rev-suppressed-diff-view' : 'rev-deleted-diff-view';
                $notice = "<div id='mw-{$msg}' class='mw-warning plainlinks'>\n" . wfMsgExt($msg, 'parseinline') . "</div>\n";
            }
            $this->showDiff($oldHeader, $newHeader, $notice);
            if (!$diffOnly) {
                $this->renderNewRevision();
            }
        }
        wfProfileOut(__METHOD__);
    }
Ejemplo n.º 3
0
 /**
  * Returns an array of meta data needed to build a "mark as patrolled" link and
  * adds the mediawiki.page.patrol.ajax to the output.
  *
  * @return array|false An array of meta data for a patrol link (rcid & token)
  *  or false if no link is needed
  */
 protected function getMarkPatrolledLinkInfo()
 {
     global $wgUseRCPatrol, $wgEnableAPI, $wgEnableWriteAPI;
     $user = $this->getUser();
     // Prepare a change patrol link, if applicable
     if ($wgUseRCPatrol && $this->mNewPage->quickUserCan('patrol', $user) && RecentChange::isInRCLifespan($this->mNewRev->getTimestamp(), 21600)) {
         // Look for an unpatrolled change corresponding to this diff
         $db = wfGetDB(DB_SLAVE);
         $change = RecentChange::newFromConds(array('rc_timestamp' => $db->timestamp($this->mNewRev->getTimestamp()), 'rc_this_oldid' => $this->mNewid, 'rc_patrolled' => 0), __METHOD__);
         if ($change && !$change->getPerformer()->equals($user)) {
             $rcid = $change->getAttribute('rc_id');
         } else {
             // None found or the page has been created by the current user.
             // If the user could patrol this it already would be patrolled
             $rcid = 0;
         }
         // Build the link
         if ($rcid) {
             $this->getOutput()->preventClickjacking();
             if ($wgEnableAPI && $wgEnableWriteAPI && $user->isAllowed('writeapi')) {
                 $this->getOutput()->addModules('mediawiki.page.patrol.ajax');
             }
             $token = $user->getEditToken($rcid);
             return array('rcid' => $rcid, 'token' => $token);
         }
     }
     // No mark as patrolled link applicable
     return false;
 }
Ejemplo n.º 4
0
 /**
  * Get a link to mark the change as patrolled, or '' if there's either no
  * revision to patrol or the user is not allowed to to it.
  * Side effect: this method will call OutputPage::preventClickjacking()
  * when a link is builded.
  *
  * @return String
  */
 protected function markPatrolledLink()
 {
     global $wgUseRCPatrol;
     if ($this->mMarkPatrolledLink === null) {
         // Prepare a change patrol link, if applicable
         if ($wgUseRCPatrol && $this->mNewPage->quickUserCan('patrol', $this->getUser())) {
             // If we've been given an explicit change identifier, use it; saves time
             if ($this->mRcidMarkPatrolled) {
                 $rcid = $this->mRcidMarkPatrolled;
                 $rc = RecentChange::newFromId($rcid);
                 // Already patrolled?
                 $rcid = is_object($rc) && !$rc->getAttribute('rc_patrolled') ? $rcid : 0;
             } else {
                 // Look for an unpatrolled change corresponding to this diff
                 $db = wfGetDB(DB_SLAVE);
                 $change = RecentChange::newFromConds(array('rc_user_text' => $this->mNewRev->getRawUserText(), 'rc_timestamp' => $db->timestamp($this->mNewRev->getTimestamp()), 'rc_this_oldid' => $this->mNewid, 'rc_last_oldid' => $this->mOldid, 'rc_patrolled' => 0), __METHOD__);
                 if ($change instanceof RecentChange) {
                     $rcid = $change->mAttribs['rc_id'];
                     $this->mRcidMarkPatrolled = $rcid;
                 } else {
                     // None found
                     $rcid = 0;
                 }
             }
             // Build the link
             if ($rcid) {
                 $this->getOutput()->preventClickjacking();
                 $token = $this->getUser()->getEditToken($rcid);
                 $this->mMarkPatrolledLink = ' <span class="patrollink">[' . Linker::linkKnown($this->mNewPage, $this->msg('markaspatrolleddiff')->escaped(), array(), array('action' => 'markpatrolled', 'rcid' => $rcid, 'token' => $token)) . ']</span>';
             } else {
                 $this->mMarkPatrolledLink = '';
             }
         } else {
             $this->mMarkPatrolledLink = '';
         }
     }
     return $this->mMarkPatrolledLink;
 }
Ejemplo n.º 5
0
 /**
  * If patrol is possible, output a patrol UI box. This is called from the
  * footer section of ordinary page views. If patrol is not possible or not
  * desired, does nothing.
  * Side effect: When the patrol link is build, this method will call
  * OutputPage::preventClickjacking() and load mediawiki.page.patrol.ajax.
  *
  * @return bool
  */
 public function showPatrolFooter()
 {
     global $wgUseNPPatrol, $wgUseRCPatrol, $wgEnableAPI, $wgEnableWriteAPI;
     $outputPage = $this->getContext()->getOutput();
     $user = $this->getContext()->getUser();
     $cache = wfGetMainCache();
     $rc = false;
     if (!$this->getTitle()->quickUserCan('patrol', $user) || !($wgUseRCPatrol || $wgUseNPPatrol)) {
         // Patrolling is disabled or the user isn't allowed to
         return false;
     }
     // New page patrol: Get the timestamp of the oldest revison which
     // the revision table holds for the given page. Then we look
     // whether it's within the RC lifespan and if it is, we try
     // to get the recentchanges row belonging to that entry
     // (with rc_new = 1).
     if ($this->mRevision && !RecentChange::isInRCLifespan($this->mRevision->getTimestamp(), 21600)) {
         // The current revision is already older than what could be in the RC table
         // 6h tolerance because the RC might not be cleaned out regularly
         return false;
     }
     // Check for cached results
     $key = wfMemcKey('NotPatrollablePage', $this->getTitle()->getArticleID());
     if ($cache->get($key)) {
         return false;
     }
     $dbr = wfGetDB(DB_SLAVE);
     $oldestRevisionTimestamp = $dbr->selectField('revision', 'MIN( rev_timestamp )', array('rev_page' => $this->getTitle()->getArticleID()), __METHOD__);
     if ($oldestRevisionTimestamp && RecentChange::isInRCLifespan($oldestRevisionTimestamp, 21600)) {
         // 6h tolerance because the RC might not be cleaned out regularly
         $rc = RecentChange::newFromConds(array('rc_new' => 1, 'rc_timestamp' => $oldestRevisionTimestamp, 'rc_namespace' => $this->getTitle()->getNamespace(), 'rc_cur_id' => $this->getTitle()->getArticleID()), __METHOD__, array('USE INDEX' => 'new_name_timestamp'));
     } else {
         // Cache the information we gathered above in case we can't patrol
         // Don't cache in case we can patrol as this could change
         $cache->set($key, '1');
     }
     if (!$rc) {
         // Don't cache: This can be hit if the page gets accessed very fast after
         // its creation or in case we have high slave lag. In case the revision is
         // too old, we will already return above.
         return false;
     }
     if ($rc->getAttribute('rc_patrolled')) {
         // Patrolled RC entry around
         // Cache the information we gathered above in case we can't patrol
         // Don't cache in case we can patrol as this could change
         $cache->set($key, '1');
         return false;
     }
     if ($rc->getPerformer()->equals($user)) {
         // Don't show a patrol link for own creations. If the user could
         // patrol them, they already would be patrolled
         return false;
     }
     $rcid = $rc->getAttribute('rc_id');
     $token = $user->getEditToken($rcid);
     $outputPage->preventClickjacking();
     if ($wgEnableAPI && $wgEnableWriteAPI && $user->isAllowed('writeapi')) {
         $outputPage->addModules('mediawiki.page.patrol.ajax');
     }
     $link = Linker::linkKnown($this->getTitle(), wfMessage('markaspatrolledtext')->escaped(), array(), array('action' => 'markpatrolled', 'rcid' => $rcid, 'token' => $token));
     $outputPage->addHTML("<div class='patrollink'>" . wfMessage('markaspatrolledlink')->rawParams($link)->escaped() . '</div>');
     return true;
 }
    function showDiffPage($diffOnly = false)
    {
        global $wgUser, $wgOut, $wgUseExternalEditor, $wgUseRCPatrol, $wgEnableHtmlDiff;
        wfProfileIn(__METHOD__);
        # If external diffs are enabled both globally and for the user,
        # we'll use the application/x-external-editor interface to call
        # an external diff tool like kompare, kdiff3, etc.
        if ($wgUseExternalEditor && $wgUser->getOption('externaldiff')) {
            global $wgInputEncoding, $wgServer, $wgScript, $wgLang;
            $wgOut->disable();
            header("Content-type: application/x-external-editor; charset=" . $wgInputEncoding);
            $url1 = $this->mTitle->getFullURL("action=raw&oldid=" . $this->mOldid);
            $url2 = $this->mTitle->getFullURL("action=raw&oldid=" . $this->mNewid);
            $special = $wgLang->getNsText(NS_SPECIAL);
            $control = <<<CONTROL
\t\t\t[Process]
\t\t\tType=Diff text
\t\t\tEngine=MediaWiki
\t\t\tScript={$wgServer}{$wgScript}
\t\t\tSpecial namespace={$special}

\t\t\t[File]
\t\t\tExtension=wiki
\t\t\tURL={$url1}

\t\t\t[File 2]
\t\t\tExtension=wiki
\t\t\tURL={$url2}
CONTROL;
            echo $control;
            return;
        }
        $wgOut->setArticleFlag(false);
        if (!$this->loadRevisionData()) {
            $t = $this->mTitle->getPrefixedText();
            $d = wfMsgExt('missingarticle-diff', array('escape'), $this->mOldid, $this->mNewid);
            $wgOut->setPagetitle(wfMsg('errorpagetitle'));
            $wgOut->addWikiMsg('missing-article', "<nowiki>{$t}</nowiki>", $d);
            wfProfileOut(__METHOD__);
            return;
        }
        wfRunHooks('DiffViewHeader', array($this, $this->mOldRev, $this->mNewRev));
        if ($this->mNewRev->isCurrent()) {
            $wgOut->setArticleFlag(true);
        }
        # mOldid is false if the difference engine is called with a "vague" query for
        # a diff between a version V and its previous version V' AND the version V
        # is the first version of that article. In that case, V' does not exist.
        if ($this->mOldid === false) {
            $this->showFirstRevision();
            $this->renderNewRevision();
            // should we respect $diffOnly here or not?
            wfProfileOut(__METHOD__);
            return;
        }
        $wgOut->suppressQuickbar();
        $oldTitle = $this->mOldPage->getPrefixedText();
        $newTitle = $this->mNewPage->getPrefixedText();
        if ($oldTitle == $newTitle) {
            $wgOut->setPageTitle($newTitle);
        } else {
            $wgOut->setPageTitle($oldTitle . ', ' . $newTitle);
        }
        $wgOut->setSubtitle(wfMsgExt('difference', array('parseinline')));
        $wgOut->setRobotPolicy('noindex,nofollow');
        if (!$this->mOldPage->userCanRead() || !$this->mNewPage->userCanRead()) {
            $wgOut->loginToUse();
            $wgOut->output();
            $wgOut->disable();
            wfProfileOut(__METHOD__);
            return;
        }
        $sk = $wgUser->getSkin();
        // Check if page is editable
        $editable = $this->mNewRev->getTitle()->userCan('edit');
        if ($editable && $this->mNewRev->isCurrent() && $wgUser->isAllowed('rollback')) {
            $rollback = '&nbsp;&nbsp;&nbsp;' . $sk->generateRollback($this->mNewRev);
        } else {
            $rollback = '';
        }
        // Prepare a change patrol link, if applicable
        if ($wgUseRCPatrol && $this->mTitle->userCan('patrol')) {
            // If we've been given an explicit change identifier, use it; saves time
            if ($this->mRcidMarkPatrolled) {
                $rcid = $this->mRcidMarkPatrolled;
                $rc = RecentChange::newFromId($rcid);
                // Already patrolled?
                $rcid = is_object($rc) && !$rc->getAttribute('rc_patrolled') ? $rcid : 0;
            } else {
                // Look for an unpatrolled change corresponding to this diff
                $db = wfGetDB(DB_SLAVE);
                $change = RecentChange::newFromConds(array('rc_user_text' => $this->mNewRev->getRawUserText(), 'rc_timestamp' => $db->timestamp($this->mNewRev->getTimestamp()), 'rc_this_oldid' => $this->mNewid, 'rc_last_oldid' => $this->mOldid, 'rc_patrolled' => 0), __METHOD__);
                if ($change instanceof RecentChange) {
                    $rcid = $change->mAttribs['rc_id'];
                    $this->mRcidMarkPatrolled = $rcid;
                } else {
                    // None found
                    $rcid = 0;
                }
            }
            // Build the link
            if ($rcid) {
                $patrol = ' <span class="patrollink">[' . $sk->makeKnownLinkObj($this->mTitle, wfMsgHtml('markaspatrolleddiff'), "action=markpatrolled&rcid={$rcid}") . ']</span>';
            } else {
                $patrol = '';
            }
        } else {
            $patrol = '';
        }
        $diffOnlyArg = '';
        # Carry over 'diffonly' param via navigation links
        if ($diffOnly != $wgUser->getBoolOption('diffonly')) {
            $diffOnlyArg = '&diffonly=' . $diffOnly;
        }
        $htmldiffarg = $this->htmlDiffArgument();
        # Make "previous revision link"
        $prevlink = $sk->makeKnownLinkObj($this->mTitle, wfMsgHtml('previousdiff'), "diff=prev&oldid={$this->mOldid}{$htmldiffarg}{$diffOnlyArg}", '', '', 'id="differences-prevlink"');
        # Make "next revision link"
        if ($this->mNewRev->isCurrent()) {
            $nextlink = '&nbsp;';
        } else {
            $nextlink = $sk->makeKnownLinkObj($this->mTitle, wfMsgHtml('nextdiff'), "diff=next&oldid={$this->mNewid}{$htmldiffarg}{$diffOnlyArg}", '', '', 'id="differences-nextlink"');
        }
        $oldminor = '';
        $newminor = '';
        if ($this->mOldRev->isMinor()) {
            $oldminor = Xml::span(wfMsg('minoreditletter'), 'minor') . ' ';
        }
        if ($this->mNewRev->isMinor()) {
            $newminor = Xml::span(wfMsg('minoreditletter'), 'minor') . ' ';
        }
        $rdel = '';
        $ldel = '';
        if ($wgUser->isAllowed('deleterevision')) {
            if (!$this->mOldRev->userCan(Revision::DELETED_RESTRICTED)) {
                // If revision was hidden from sysops
                $ldel = Xml::tags('span', array('class' => 'mw-revdelundel-link'), '(' . wfMsgHtml('rev-delundel') . ')');
            } else {
                $query = array('target' => $this->mOldRev->mTitle->getPrefixedDbkey(), 'oldid' => $this->mOldRev->getId());
                $ldel = $sk->revDeleteLink($query, $this->mOldRev->isDeleted(Revision::DELETED_RESTRICTED));
            }
            $ldel = "&nbsp;&nbsp;&nbsp;{$ldel} ";
            // We don't currently handle well changing the top revision's settings
            if ($this->mNewRev->isCurrent()) {
                $rdel = Xml::tags('span', array('class' => 'mw-revdelundel-link'), '(' . wfMsgHtml('rev-delundel') . ')');
            } else {
                if (!$this->mNewRev->userCan(Revision::DELETED_RESTRICTED)) {
                    // If revision was hidden from sysops
                    $rdel = Xml::tags('span', array('class' => 'mw-revdelundel-link'), '(' . wfMsgHtml('rev-delundel') . ')');
                } else {
                    $query = array('target' => $this->mNewRev->mTitle->getPrefixedDbkey(), 'oldid' => $this->mNewRev->getId());
                    $rdel = $sk->revDeleteLink($query, $this->mNewRev->isDeleted(Revision::DELETED_RESTRICTED));
                }
            }
            $rdel = "&nbsp;&nbsp;&nbsp;{$rdel} ";
        }
        $oldHeader = '<div id="mw-diff-otitle1"><strong>' . $this->mOldtitle . '</strong></div>' . '<div id="mw-diff-otitle2">' . $sk->revUserTools($this->mOldRev, !$this->unhide) . "</div>" . '<div id="mw-diff-otitle3">' . $oldminor . $sk->revComment($this->mOldRev, !$diffOnly, !$this->unhide) . $ldel . "</div>" . '<div id="mw-diff-otitle4">' . $prevlink . '</div>';
        $newHeader = '<div id="mw-diff-ntitle1"><strong>' . $this->mNewtitle . '</strong></div>' . '<div id="mw-diff-ntitle2">' . $sk->revUserTools($this->mNewRev, !$this->unhide) . " {$rollback}</div>" . '<div id="mw-diff-ntitle3">' . $newminor . $sk->revComment($this->mNewRev, !$diffOnly, !$this->unhide) . $rdel . "</div>" . '<div id="mw-diff-ntitle4">' . $nextlink . $patrol . '</div>';
        # Check if this user can see the revisions
        $allowed = $this->mOldRev->userCan(Revision::DELETED_TEXT) && $this->mNewRev->userCan(Revision::DELETED_TEXT);
        $deleted = $this->mOldRev->isDeleted(Revision::DELETED_TEXT) || $this->mNewRev->isDeleted(Revision::DELETED_TEXT);
        # Output the diff if allowed...
        if ($deleted && (!$this->unhide || !$allowed)) {
            $this->showDiffStyle();
            $multi = $this->getMultiNotice();
            $wgOut->addHTML($this->addHeader('', $oldHeader, $newHeader, $multi));
            if (!$allowed) {
                # Give explanation for why revision is not visible
                $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1</div>\n", array('rev-deleted-no-diff'));
            } else {
                # Give explanation and add a link to view the diff...
                $link = $this->mTitle->getFullUrl("diff={$this->mNewid}&oldid={$this->mOldid}" . '&unhide=1&token=' . urlencode($wgUser->editToken($this->mNewid)));
                $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1</div>\n", array('rev-deleted-unhide-diff', $link));
            }
        } else {
            if ($wgEnableHtmlDiff && $this->htmldiff) {
                $multi = $this->getMultiNotice();
                $wgOut->addHTML('<div class="diff-switchtype">' . $sk->makeKnownLinkObj($this->mTitle, wfMsgHtml('wikicodecomparison'), 'diff=' . $this->mNewid . '&oldid=' . $this->mOldid . '&htmldiff=0', '', '', 'id="differences-switchtype"') . '</div>');
                $wgOut->addHTML($this->addHeader('', $oldHeader, $newHeader, $multi));
                $this->renderHtmlDiff();
            } else {
                if ($wgEnableHtmlDiff) {
                    $wgOut->addHTML('<div class="diff-switchtype">' . $sk->makeKnownLinkObj($this->mTitle, wfMsgHtml('visualcomparison'), 'diff=' . $this->mNewid . '&oldid=' . $this->mOldid . '&htmldiff=1', '', '', 'id="differences-switchtype"') . '</div>');
                }
                $this->showDiff($oldHeader, $newHeader);
                if (!$diffOnly) {
                    $this->renderNewRevision();
                }
            }
        }
        wfProfileOut(__METHOD__);
    }
Ejemplo n.º 7
0
 /**
  * Get the RC object belonging to the current revision, if there's one
  *
  * @param int $flags (optional) $flags include:
  *      Revision::READ_LATEST  : Select the data from the master
  *
  * @since 1.22
  * @return RecentChange|null
  */
 public function getRecentChange($flags = 0)
 {
     $dbr = wfGetDB(DB_SLAVE);
     list($dbType, ) = DBAccessObjectUtils::getDBOptions($flags);
     return RecentChange::newFromConds(array('rc_user_text' => $this->getUserText(Revision::RAW), 'rc_timestamp' => $dbr->timestamp($this->getTimestamp()), 'rc_this_oldid' => $this->getId()), __METHOD__, $dbType);
 }
    function showDiffPage($diffOnly = false)
    {
        global $wgUser, $wgOut, $wgUseExternalEditor, $wgUseRCPatrol;
        $fname = 'DifferenceEngine::showDiffPage';
        wfProfileIn($fname);
        # If external diffs are enabled both globally and for the user,
        # we'll use the application/x-external-editor interface to call
        # an external diff tool like kompare, kdiff3, etc.
        if ($wgUseExternalEditor && $wgUser->getOption('externaldiff')) {
            global $wgInputEncoding, $wgServer, $wgScript, $wgLang;
            $wgOut->disable();
            header("Content-type: application/x-external-editor; charset=" . $wgInputEncoding);
            $url1 = $this->mTitle->getFullURL("action=raw&oldid=" . $this->mOldid);
            $url2 = $this->mTitle->getFullURL("action=raw&oldid=" . $this->mNewid);
            $special = $wgLang->getNsText(NS_SPECIAL);
            $control = <<<CONTROL
[Process]
Type=Diff text
Engine=MediaWiki
Script={$wgServer}{$wgScript}
Special namespace={$special}

[File]
Extension=wiki
URL={$url1}

[File 2]
Extension=wiki
URL={$url2}
CONTROL;
            echo $control;
            return;
        }
        $wgOut->setArticleFlag(false);
        if (!$this->loadRevisionData()) {
            $t = $this->mTitle->getPrefixedText() . " (Diff: {$this->mOldid}, {$this->mNewid})";
            $wgOut->setPagetitle(wfMsg('errorpagetitle'));
            $wgOut->addWikiMsg('missingarticle', "<nowiki>{$t}</nowiki>");
            wfProfileOut($fname);
            return;
        }
        wfRunHooks('DiffViewHeader', array($this, $this->mOldRev, $this->mNewRev));
        if ($this->mNewRev->isCurrent()) {
            $wgOut->setArticleFlag(true);
        }
        # mOldid is false if the difference engine is called with a "vague" query for
        # a diff between a version V and its previous version V' AND the version V
        # is the first version of that article. In that case, V' does not exist.
        if ($this->mOldid === false) {
            $this->showFirstRevision();
            $this->renderNewRevision();
            // should we respect $diffOnly here or not?
            wfProfileOut($fname);
            return;
        }
        $wgOut->suppressQuickbar();
        $oldTitle = $this->mOldPage->getPrefixedText();
        $newTitle = $this->mNewPage->getPrefixedText();
        if ($oldTitle == $newTitle) {
            $wgOut->setPageTitle($newTitle);
        } else {
            $wgOut->setPageTitle($oldTitle . ', ' . $newTitle);
        }
        $wgOut->setSubtitle(wfMsg('difference'));
        $wgOut->setRobotpolicy('noindex,nofollow');
        if (!($this->mOldPage->userCanRead() && $this->mNewPage->userCanRead())) {
            $wgOut->loginToUse();
            $wgOut->output();
            wfProfileOut($fname);
            exit;
        }
        $sk = $wgUser->getSkin();
        if ($this->mNewRev->isCurrent() && $wgUser->isAllowed('rollback')) {
            $rollback = '&nbsp;&nbsp;&nbsp;' . $sk->generateRollback($this->mNewRev);
        } else {
            $rollback = '';
        }
        // Prepare a change patrol link, if applicable
        if ($wgUseRCPatrol && $wgUser->isAllowed('patrol')) {
            // If we've been given an explicit change identifier, use it; saves time
            if ($this->mRcidMarkPatrolled) {
                $rcid = $this->mRcidMarkPatrolled;
            } else {
                // Look for an unpatrolled change corresponding to this diff
                $db = wfGetDB(DB_SLAVE);
                $change = RecentChange::newFromConds(array('rc_user_text' => $this->mNewRev->getRawUserText(), 'rc_timestamp' => $db->timestamp($this->mNewRev->getTimestamp()), 'rc_this_oldid' => $this->mNewid, 'rc_last_oldid' => $this->mOldid, 'rc_patrolled' => 0), __METHOD__);
                if ($change instanceof RecentChange) {
                    $rcid = $change->mAttribs['rc_id'];
                } else {
                    // None found
                    $rcid = 0;
                }
            }
            // Build the link
            if ($rcid) {
                $patrol = ' [' . $sk->makeKnownLinkObj($this->mTitle, wfMsgHtml('markaspatrolleddiff'), "action=markpatrolled&rcid={$rcid}") . ']';
            } else {
                $patrol = '';
            }
        } else {
            $patrol = '';
        }
        $prevlink = $sk->makeKnownLinkObj($this->mTitle, wfMsgHtml('previousdiff'), 'diff=prev&oldid=' . $this->mOldid, '', '', 'id="differences-prevlink"');
        if ($this->mNewRev->isCurrent()) {
            $nextlink = '&nbsp;';
        } else {
            $nextlink = $sk->makeKnownLinkObj($this->mTitle, wfMsgHtml('nextdiff'), 'diff=next&oldid=' . $this->mNewid, '', '', 'id="differences-nextlink"');
        }
        $oldminor = '';
        $newminor = '';
        if ($this->mOldRev->mMinorEdit == 1) {
            $oldminor = wfElement('span', array('class' => 'minor'), wfMsg('minoreditletter')) . ' ';
        }
        if ($this->mNewRev->mMinorEdit == 1) {
            $newminor = wfElement('span', array('class' => 'minor'), wfMsg('minoreditletter')) . ' ';
        }
        $rdel = '';
        $ldel = '';
        if ($wgUser->isAllowed('deleterevision')) {
            $revdel = SpecialPage::getTitleFor('Revisiondelete');
            if (!$this->mOldRev->userCan(Revision::DELETED_RESTRICTED)) {
                // If revision was hidden from sysops
                $ldel = wfMsgHtml('rev-delundel');
            } else {
                $ldel = $sk->makeKnownLinkObj($revdel, wfMsgHtml('rev-delundel'), 'target=' . urlencode($this->mOldRev->mTitle->getPrefixedDbkey()) . '&oldid=' . urlencode($this->mOldRev->getId()));
                // Bolden oversighted content
                if ($this->mOldRev->isDeleted(Revision::DELETED_RESTRICTED)) {
                    $ldel = "<strong>{$ldel}</strong>";
                }
            }
            $ldel = "&nbsp;&nbsp;&nbsp;<tt>(<small>{$ldel}</small>)</tt> ";
            // We don't currently handle well changing the top revision's settings
            if ($this->mNewRev->isCurrent()) {
                // If revision was hidden from sysops
                $rdel = wfMsgHtml('rev-delundel');
            } else {
                if (!$this->mNewRev->userCan(Revision::DELETED_RESTRICTED)) {
                    // If revision was hidden from sysops
                    $rdel = wfMsgHtml('rev-delundel');
                } else {
                    $rdel = $sk->makeKnownLinkObj($revdel, wfMsgHtml('rev-delundel'), 'target=' . urlencode($this->mNewRev->mTitle->getPrefixedDbkey()) . '&oldid=' . urlencode($this->mNewRev->getId()));
                    // Bolden oversighted content
                    if ($this->mNewRev->isDeleted(Revision::DELETED_RESTRICTED)) {
                        $rdel = "<strong>{$rdel}</strong>";
                    }
                }
            }
            $rdel = "&nbsp;&nbsp;&nbsp;<tt>(<small>{$rdel}</small>)</tt> ";
        }
        $oldHeader = '<div id="mw-diff-otitle1"><strong>' . $this->mOldtitle . '</strong></div>' . '<div id="mw-diff-otitle2">' . $sk->revUserTools($this->mOldRev, true) . "</div>" . '<div id="mw-diff-otitle3">' . $oldminor . $sk->revComment($this->mOldRev, !$diffOnly, true) . $ldel . "</div>" . '<div id="mw-diff-otitle4">' . $prevlink . '</div>';
        $newHeader = '<div id="mw-diff-ntitle1"><strong>' . $this->mNewtitle . '</strong></div>' . '<div id="mw-diff-ntitle2">' . $sk->revUserTools($this->mNewRev, true) . " {$rollback}</div>" . '<div id="mw-diff-ntitle3">' . $newminor . $sk->revComment($this->mNewRev, !$diffOnly, true) . $rdel . "</div>" . '<div id="mw-diff-ntitle4">' . $nextlink . $patrol . '</div>';
        $this->showDiff($oldHeader, $newHeader);
        if (!$diffOnly) {
            $this->renderNewRevision();
        }
        wfProfileOut($fname);
    }
Ejemplo n.º 9
0
 /**
  * Get the RC object belonging to the current revision, if there's one
  *
  * @since 1.22
  * @return RecentChange|null
  */
 public function getRecentChange()
 {
     $dbr = wfGetDB(DB_SLAVE);
     return RecentChange::newFromConds(array('rc_user_text' => $this->getUserText(Revision::RAW), 'rc_timestamp' => $dbr->timestamp($this->getTimestamp()), 'rc_this_oldid' => $this->getId()), __METHOD__);
 }
Ejemplo n.º 10
0
 /**
  * Get a link to mark the change as patrolled, or '' if there's either no
  * revision to patrol or the user is not allowed to to it.
  * Side effect: When the patrol link is build, this method will call
  * OutputPage::preventClickjacking() and load mediawiki.page.patrol.ajax.
  *
  * @return string
  */
 protected function markPatrolledLink()
 {
     global $wgUseRCPatrol, $wgEnableAPI, $wgEnableWriteAPI;
     $user = $this->getUser();
     if ($this->mMarkPatrolledLink === null) {
         // Prepare a change patrol link, if applicable
         if ($wgUseRCPatrol && $this->mNewPage->quickUserCan('patrol', $user) && RecentChange::isInRCLifespan($this->mNewRev->getTimestamp(), 21600)) {
             // Look for an unpatrolled change corresponding to this diff
             $db = wfGetDB(DB_SLAVE);
             $change = RecentChange::newFromConds(array('rc_timestamp' => $db->timestamp($this->mNewRev->getTimestamp()), 'rc_this_oldid' => $this->mNewid, 'rc_patrolled' => 0), __METHOD__, array('USE INDEX' => 'rc_timestamp'));
             if ($change && $change->getPerformer()->getName() !== $user->getName()) {
                 $rcid = $change->getAttribute('rc_id');
             } else {
                 // None found or the page has been created by the current user.
                 // If the user could patrol this it already would be patrolled
                 $rcid = 0;
             }
             // Build the link
             if ($rcid) {
                 $this->getOutput()->preventClickjacking();
                 if ($wgEnableAPI && $wgEnableWriteAPI && $user->isAllowed('writeapi')) {
                     $this->getOutput()->addModules('mediawiki.page.patrol.ajax');
                 }
                 $token = $user->getEditToken($rcid);
                 $this->mMarkPatrolledLink = ' <span class="patrollink">[' . Linker::linkKnown($this->mNewPage, $this->msg('markaspatrolleddiff')->escaped(), array(), array('action' => 'markpatrolled', 'rcid' => $rcid, 'token' => $token)) . ']</span>';
             } else {
                 $this->mMarkPatrolledLink = '';
             }
         } else {
             $this->mMarkPatrolledLink = '';
         }
     }
     return $this->mMarkPatrolledLink;
 }
Ejemplo n.º 11
0
 /**
  * If patrol is possible, output a patrol UI box. This is called from the
  * footer section of ordinary page views. If patrol is not possible or not
  * desired, does nothing.
  * Side effect: When the patrol link is build, this method will call
  * OutputPage::preventClickjacking() and load mediawiki.page.patrol.ajax.
  *
  * @return bool
  */
 public function showPatrolFooter()
 {
     global $wgUseNPPatrol, $wgUseRCPatrol, $wgUseFilePatrol, $wgEnableAPI, $wgEnableWriteAPI;
     $outputPage = $this->getContext()->getOutput();
     $user = $this->getContext()->getUser();
     $title = $this->getTitle();
     $rc = false;
     if (!$title->quickUserCan('patrol', $user) || !($wgUseRCPatrol || $wgUseNPPatrol || $wgUseFilePatrol && $title->inNamespace(NS_FILE))) {
         // Patrolling is disabled or the user isn't allowed to
         return false;
     }
     if ($this->mRevision && !RecentChange::isInRCLifespan($this->mRevision->getTimestamp(), 21600)) {
         // The current revision is already older than what could be in the RC table
         // 6h tolerance because the RC might not be cleaned out regularly
         return false;
     }
     // Check for cached results
     $key = wfMemcKey('unpatrollable-page', $title->getArticleID());
     $cache = ObjectCache::getMainWANInstance();
     if ($cache->get($key)) {
         return false;
     }
     $dbr = wfGetDB(DB_SLAVE);
     $oldestRevisionTimestamp = $dbr->selectField('revision', 'MIN( rev_timestamp )', ['rev_page' => $title->getArticleID()], __METHOD__);
     // New page patrol: Get the timestamp of the oldest revison which
     // the revision table holds for the given page. Then we look
     // whether it's within the RC lifespan and if it is, we try
     // to get the recentchanges row belonging to that entry
     // (with rc_new = 1).
     $recentPageCreation = false;
     if ($oldestRevisionTimestamp && RecentChange::isInRCLifespan($oldestRevisionTimestamp, 21600)) {
         // 6h tolerance because the RC might not be cleaned out regularly
         $recentPageCreation = true;
         $rc = RecentChange::newFromConds(['rc_new' => 1, 'rc_timestamp' => $oldestRevisionTimestamp, 'rc_namespace' => $title->getNamespace(), 'rc_cur_id' => $title->getArticleID()], __METHOD__);
         if ($rc) {
             // Use generic patrol message for new pages
             $markPatrolledMsg = wfMessage('markaspatrolledtext');
         }
     }
     // File patrol: Get the timestamp of the latest upload for this page,
     // check whether it is within the RC lifespan and if it is, we try
     // to get the recentchanges row belonging to that entry
     // (with rc_type = RC_LOG, rc_log_type = upload).
     $recentFileUpload = false;
     if ((!$rc || $rc->getAttribute('rc_patrolled')) && $wgUseFilePatrol && $title->getNamespace() === NS_FILE) {
         // Retrieve timestamp of most recent upload
         $newestUploadTimestamp = $dbr->selectField('image', 'MAX( img_timestamp )', ['img_name' => $title->getDBkey()], __METHOD__);
         if ($newestUploadTimestamp && RecentChange::isInRCLifespan($newestUploadTimestamp, 21600)) {
             // 6h tolerance because the RC might not be cleaned out regularly
             $recentFileUpload = true;
             $rc = RecentChange::newFromConds(['rc_type' => RC_LOG, 'rc_log_type' => 'upload', 'rc_timestamp' => $newestUploadTimestamp, 'rc_namespace' => NS_FILE, 'rc_cur_id' => $title->getArticleID()], __METHOD__, ['USE INDEX' => 'rc_timestamp']);
             if ($rc) {
                 // Use patrol message specific to files
                 $markPatrolledMsg = wfMessage('markaspatrolledtext-file');
             }
         }
     }
     if (!$recentPageCreation && !$recentFileUpload) {
         // Page creation and latest upload (for files) is too old to be in RC
         // We definitely can't patrol so cache the information
         // When a new file version is uploaded, the cache is cleared
         $cache->set($key, '1');
         return false;
     }
     if (!$rc) {
         // Don't cache: This can be hit if the page gets accessed very fast after
         // its creation / latest upload or in case we have high slave lag. In case
         // the revision is too old, we will already return above.
         return false;
     }
     if ($rc->getAttribute('rc_patrolled')) {
         // Patrolled RC entry around
         // Cache the information we gathered above in case we can't patrol
         // Don't cache in case we can patrol as this could change
         $cache->set($key, '1');
         return false;
     }
     if ($rc->getPerformer()->equals($user)) {
         // Don't show a patrol link for own creations/uploads. If the user could
         // patrol them, they already would be patrolled
         return false;
     }
     $rcid = $rc->getAttribute('rc_id');
     $token = $user->getEditToken($rcid);
     $outputPage->preventClickjacking();
     if ($wgEnableAPI && $wgEnableWriteAPI && $user->isAllowed('writeapi')) {
         $outputPage->addModules('mediawiki.page.patrol.ajax');
     }
     $link = Linker::linkKnown($title, $markPatrolledMsg->escaped(), [], ['action' => 'markpatrolled', 'rcid' => $rcid, 'token' => $token]);
     $outputPage->addHTML("<div class='patrollink' data-mw='interface'>" . wfMessage('markaspatrolledlink')->rawParams($link)->escaped() . '</div>');
     return true;
 }
Ejemplo n.º 12
0
 /**
  * Returns an array of meta data needed to build a "mark as patrolled" link and
  * adds the mediawiki.page.patrol.ajax to the output.
  *
  * @return array|false An array of meta data for a patrol link (rcid & token)
  *  or false if no link is needed
  */
 protected function getMarkPatrolledLinkInfo()
 {
     global $wgUseRCPatrol, $wgEnableAPI, $wgEnableWriteAPI;
     $user = $this->getUser();
     // Prepare a change patrol link, if applicable
     if ($wgUseRCPatrol && $this->mNewPage->quickUserCan('patrol', $user) && RecentChange::isInRCLifespan($this->mNewRev->getTimestamp(), 21600)) {
         // Look for an unpatrolled change corresponding to this diff
         $db = wfGetDB(DB_REPLICA);
         $change = RecentChange::newFromConds(['rc_timestamp' => $db->timestamp($this->mNewRev->getTimestamp()), 'rc_this_oldid' => $this->mNewid, 'rc_patrolled' => 0], __METHOD__);
         if ($change && !$change->getPerformer()->equals($user)) {
             $rcid = $change->getAttribute('rc_id');
         } else {
             // None found or the page has been created by the current user.
             // If the user could patrol this it already would be patrolled
             $rcid = 0;
         }
         // Allow extensions to possibly change the rcid here
         // For example the rcid might be set to zero due to the user
         // being the same as the performer of the change but an extension
         // might still want to show it under certain conditions
         Hooks::run('DifferenceEngineMarkPatrolledRCID', [&$rcid, $this, $change, $user]);
         // Build the link
         if ($rcid) {
             $this->getOutput()->preventClickjacking();
             if ($wgEnableAPI && $wgEnableWriteAPI && $user->isAllowed('writeapi')) {
                 $this->getOutput()->addModules('mediawiki.page.patrol.ajax');
             }
             $token = $user->getEditToken($rcid);
             return ['rcid' => $rcid, 'token' => $token];
         }
     }
     // No mark as patrolled link applicable
     return false;
 }
Ejemplo n.º 13
0
 public function markPatrolledLink()
 {
     global $wgUseRCPatrol, $wgEnableAPI, $wgEnableWriteAPI;
     $user = $this->getUser();
     if ($this->mMarkPatrolledLink === null) {
         // Prepare a change patrol link, if applicable
         if ($wgUseRCPatrol && $this->mNewPage->quickUserCan('patrol', $user) && RecentChange::isInRCLifespan($this->mNewRev->getTimestamp(), 21600)) {
             // Look for an unpatrolled change corresponding to this diff
             $db = wfGetDB(DB_SLAVE);
             $change = RecentChange::newFromConds(array('rc_timestamp' => $db->timestamp($this->mNewRev->getTimestamp()), 'rc_this_oldid' => $this->mNewid, 'rc_patrolled' => 0), __METHOD__, array('USE INDEX' => 'rc_timestamp'));
             if ($change && $change->getPerformer()->getName() !== $user->getName()) {
                 $rcid = $change->getAttribute('rc_id');
             } else {
                 // None found or the page has been created by the current user.
                 // If the user could patrol this it already would be patrolled
                 $rcid = 0;
             }
             // WIKIHOW - we might want to change the rcid here
             // for example the rcid might be set to zero due to the user being the same
             // as the performer of the change but on wikihow we still want to show it
             // under certain conditions
             wfRunHooks('DifferenceEngineMarkPatrolledRCID', array(&$rcid, $this, $change, $user));
             // Build the link
             if ($rcid) {
                 $this->getOutput()->preventClickjacking();
                 if ($wgEnableAPI && $wgEnableWriteAPI && $user->isAllowed('writeapi')) {
                     $this->getOutput()->addModules('mediawiki.page.patrol.ajax');
                 }
                 $token = $user->getEditToken($rcid);
                 $this->mMarkPatrolledLink = ' <span class="patrollink">[' . Linker::linkKnown($this->mNewPage, $this->msg('markaspatrolleddiff')->escaped(), array(), array('action' => 'markpatrolled', 'rcid' => $rcid, 'token' => $token)) . ']</span>';
                 // WIKIHOW - added this hook to change the markpatrolled link
                 wfRunHooks('DifferenceEngineMarkPatrolledLink', array($this, &$this->mMarkPatrolledLink, $rcid, $token));
             } else {
                 $this->mMarkPatrolledLink = '';
             }
         } else {
             $this->mMarkPatrolledLink = '';
         }
     }
     return $this->mMarkPatrolledLink;
 }
 /**
  * @param int $revId
  *
  * @return RecentChange|null
  */
 private function getCategorizeRecentChangeForRevId($revId)
 {
     return RecentChange::newFromConds(['rc_type' => RC_CATEGORIZE, 'rc_this_oldid' => $revId], __METHOD__);
 }