/**
  * Patrols the article or provides the reason the patrol failed.
  */
 public function execute()
 {
     $params = $this->extractRequestParams();
     $this->requireOnlyOneParameter($params, 'rcid', 'revid');
     if (isset($params['rcid'])) {
         $rc = RecentChange::newFromId($params['rcid']);
         if (!$rc) {
             $this->dieUsageMsg(array('nosuchrcid', $params['rcid']));
         }
     } else {
         $rev = Revision::newFromId($params['revid']);
         if (!$rev) {
             $this->dieUsageMsg(array('nosuchrevid', $params['revid']));
         }
         $rc = $rev->getRecentChange();
         if (!$rc) {
             $this->dieUsage('The revision ' . $params['revid'] . " can't be patrolled as it's too old", 'notpatrollable');
         }
     }
     $retval = $rc->doMarkPatrolled($this->getUser());
     if ($retval) {
         $this->dieUsageMsg(reset($retval));
     }
     $result = array('rcid' => intval($rc->getAttribute('rc_id')));
     ApiQueryBase::addTitleInfo($result, $rc->getTitle());
     $this->getResult()->addValue(null, $this->getModuleName(), $result);
 }
Beispiel #2
0
 /**
  * Record a log event for a change being patrolled
  *
  * @param mixed $rc Change identifier or RecentChange object
  * @param bool $auto Was this patrol event automatic?
  * @param User $user User performing the action or null to use $wgUser
  *
  * @return bool
  */
 public static function record($rc, $auto = false, User $user = null)
 {
     global $wgLogAutopatrol;
     // do not log autopatrolled edits if setting disables it
     if ($auto && !$wgLogAutopatrol) {
         return false;
     }
     if (!$rc instanceof RecentChange) {
         $rc = RecentChange::newFromId($rc);
         if (!is_object($rc)) {
             return false;
         }
     }
     if (!$user) {
         global $wgUser;
         $user = $wgUser;
     }
     $entry = new ManualLogEntry('patrol', 'patrol');
     $entry->setTarget($rc->getTitle());
     $entry->setParameters(self::buildParams($rc, $auto));
     $entry->setPerformer($user);
     $logid = $entry->insert();
     if (!$auto) {
         $entry->publish($logid, 'udp');
     }
     return true;
 }
 public function onView()
 {
     $rc = RecentChange::newFromId($this->getRequest()->getInt('rcid'));
     if (is_null($rc)) {
         throw new ErrorPageError('markedaspatrollederror', 'markedaspatrollederrortext');
     }
     $errors = $rc->doMarkPatrolled($this->getUser());
     if (in_array(array('rcpatroldisabled'), $errors)) {
         throw new ErrorPageError('rcpatroldisabled', 'rcpatroldisabledtext');
     }
     if (in_array(array('hookaborted'), $errors)) {
         // The hook itself has handled any output
         return;
     }
     # It would be nice to see where the user had actually come from, but for now just guess
     $returnto = $rc->getAttribute('rc_type') == RC_NEW ? 'Newpages' : 'Recentchanges';
     $return = SpecialPage::getTitleFor($returnto);
     if (in_array(array('markedaspatrollederror-noautopatrol'), $errors)) {
         $this->getOutput()->setPageTitle(wfMsg('markedaspatrollederror'));
         $this->getOutput()->addWikiMsg('markedaspatrollederror-noautopatrol');
         $this->getOutput()->returnToMain(null, $return);
         return;
     }
     if (!empty($errors)) {
         $this->getOutput()->showPermissionsErrorPage($errors);
         return;
     }
     # Inform the user
     $this->getOutput()->setPageTitle(wfMsg('markedaspatrolled'));
     $this->getOutput()->addWikiMsg('markedaspatrolledtext', $rc->getTitle()->getPrefixedText());
     $this->getOutput()->returnToMain(null, $return);
 }
Beispiel #4
0
 /**
  * Record a log event for a change being patrolled
  *
  * @param $rc Mixed: change identifier or RecentChange object
  * @param $auto Boolean: was this patrol event automatic?
  */
 public static function record($rc, $auto = false)
 {
     if (!$rc instanceof RecentChange) {
         $rc = RecentChange::newFromId($rc);
         if (!is_object($rc)) {
             return false;
         }
     }
     $title = Title::makeTitleSafe($rc->getAttribute('rc_namespace'), $rc->getAttribute('rc_title'));
     if (is_object($title)) {
         $params = self::buildParams($rc, $auto);
         $log = new LogPage('patrol', false, $auto ? "skipUDP" : "UDP");
         # False suppresses RC entries
         $log->addEntry('patrol', $title, '', $params);
         return true;
     }
     return false;
 }
 public function onView()
 {
     $request = $this->getRequest();
     $rcId = $request->getInt('rcid');
     $rc = RecentChange::newFromId($rcId);
     if (is_null($rc)) {
         throw new ErrorPageError('markedaspatrollederror', 'markedaspatrollederrortext');
     }
     $user = $this->getUser();
     if (!$user->matchEditToken($request->getVal('token'), $rcId)) {
         throw new ErrorPageError('sessionfailure-title', 'sessionfailure');
     }
     $errors = $rc->doMarkPatrolled($user);
     if (in_array(['rcpatroldisabled'], $errors)) {
         throw new ErrorPageError('rcpatroldisabled', 'rcpatroldisabledtext');
     }
     if (in_array(['hookaborted'], $errors)) {
         // The hook itself has handled any output
         return;
     }
     # It would be nice to see where the user had actually come from, but for now just guess
     if ($rc->getAttribute('rc_type') == RC_NEW) {
         $returnTo = 'Newpages';
     } elseif ($rc->getAttribute('rc_log_type') == 'upload') {
         $returnTo = 'Newfiles';
     } else {
         $returnTo = 'Recentchanges';
     }
     $return = SpecialPage::getTitleFor($returnTo);
     if (in_array(['markedaspatrollederror-noautopatrol'], $errors)) {
         $this->getOutput()->setPageTitle($this->msg('markedaspatrollederror'));
         $this->getOutput()->addWikiMsg('markedaspatrollederror-noautopatrol');
         $this->getOutput()->returnToMain(null, $return);
         return;
     }
     if (count($errors)) {
         throw new PermissionsError('patrol', $errors);
     }
     # Inform the user
     $this->getOutput()->setPageTitle($this->msg('markedaspatrolled'));
     $this->getOutput()->addWikiMsg('markedaspatrolledtext', $rc->getTitle()->getPrefixedText());
     $this->getOutput()->returnToMain(null, $return);
 }
Beispiel #6
0
 protected function processIndividual($type, $params, $id)
 {
     $idResult = array($type => $id);
     // validate the ID
     $valid = false;
     switch ($type) {
         case 'rcid':
             $valid = RecentChange::newFromId($id);
             break;
         case 'revid':
             $valid = Revision::newFromId($id);
             break;
         case 'logid':
             $valid = self::validateLogId($id);
             break;
     }
     if (!$valid) {
         $idResult['status'] = 'error';
         $idResult += $this->parseMsg(array("nosuch{$type}", $id));
         return $idResult;
     }
     $status = ChangeTags::updateTagsWithChecks($params['add'], $params['remove'], $type === 'rcid' ? $id : null, $type === 'revid' ? $id : null, $type === 'logid' ? $id : null, null, $params['reason'], $this->getUser());
     if (!$status->isOK()) {
         if ($status->hasMessage('actionthrottledtext')) {
             $idResult['status'] = 'skipped';
         } else {
             $idResult['status'] = 'failure';
             $idResult['errors'] = $this->getErrorFormatter()->arrayFromStatus($status, 'error');
         }
     } else {
         $idResult['status'] = 'success';
         if (is_null($status->value->logId)) {
             $idResult['noop'] = '';
         } else {
             $idResult['actionlogid'] = $status->value->logId;
             $idResult['added'] = $status->value->addedTags;
             ApiResult::setIndexedTagName($idResult['added'], 't');
             $idResult['removed'] = $status->value->removedTags;
             ApiResult::setIndexedTagName($idResult['removed'], 't');
         }
     }
     return $idResult;
 }
Beispiel #7
0
 /**
  * Record a log event for a change being patrolled
  *
  * @param $rc Mixed: change identifier or RecentChange object
  * @param $auto Boolean: was this patrol event automatic?
  *
  * @return bool
  */
 public static function record($rc, $auto = false)
 {
     if (!$rc instanceof RecentChange) {
         $rc = RecentChange::newFromId($rc);
         if (!is_object($rc)) {
             return false;
         }
     }
     $title = Title::makeTitleSafe($rc->getAttribute('rc_namespace'), $rc->getAttribute('rc_title'));
     if ($title) {
         $entry = new ManualLogEntry('patrol', 'patrol');
         $entry->setTarget($title);
         $entry->setParameters(self::buildParams($rc, $auto));
         $entry->setPerformer(User::newFromName($rc->getAttribute('rc_user_text'), false));
         $logid = $entry->insert();
         if (!$auto) {
             $entry->publish($logid, 'udp');
         }
         return true;
     }
     return false;
 }
Beispiel #8
0
 /**
  * Patrols the article or provides the reason the patrol failed.
  */
 public function execute()
 {
     $params = $this->extractRequestParams();
     $this->requireOnlyOneParameter($params, 'rcid', 'revid');
     if (isset($params['rcid'])) {
         $rc = RecentChange::newFromId($params['rcid']);
         if (!$rc) {
             $this->dieUsageMsg(['nosuchrcid', $params['rcid']]);
         }
     } else {
         $rev = Revision::newFromId($params['revid']);
         if (!$rev) {
             $this->dieUsageMsg(['nosuchrevid', $params['revid']]);
         }
         $rc = $rev->getRecentChange();
         if (!$rc) {
             $this->dieUsage('The revision ' . $params['revid'] . " can't be patrolled as it's too old", 'notpatrollable');
         }
     }
     $user = $this->getUser();
     $tags = $params['tags'];
     // Check if user can add tags
     if (!is_null($tags)) {
         $ableToTag = ChangeTags::canAddTagsAccompanyingChange($tags, $user);
         if (!$ableToTag->isOK()) {
             $this->dieStatus($ableToTag);
         }
     }
     $retval = $rc->doMarkPatrolled($user, false, $tags);
     if ($retval) {
         $this->dieUsageMsg(reset($retval));
     }
     $result = ['rcid' => intval($rc->getAttribute('rc_id'))];
     ApiQueryBase::addTitleInfo($result, $rc->getTitle());
     $this->getResult()->addValue(null, $this->getModuleName(), $result);
 }
 /**
  * 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;
 }
Beispiel #10
0
 /**
  * Mark this particular edit/page as patrolled
  */
 public function markpatrolled()
 {
     global $wgOut, $wgUser, $wgRequest;
     $wgOut->setRobotPolicy('noindex,nofollow');
     # If we haven't been given an rc_id value, we can't do anything
     $rcid = (int) $wgRequest->getVal('rcid');
     if (!$wgUser->matchEditToken($wgRequest->getVal('token'), $rcid)) {
         $wgOut->showErrorPage('sessionfailure-title', 'sessionfailure');
         return;
     }
     $rc = RecentChange::newFromId($rcid);
     if (is_null($rc)) {
         $wgOut->showErrorPage('markedaspatrollederror', 'markedaspatrollederrortext');
         return;
     }
     # It would be nice to see where the user had actually come from, but for now just guess
     $returnto = $rc->getAttribute('rc_type') == RC_NEW ? 'Newpages' : 'Recentchanges';
     $return = SpecialPage::getTitleFor($returnto);
     $errors = $rc->doMarkPatrolled();
     if (in_array(array('rcpatroldisabled'), $errors)) {
         $wgOut->showErrorPage('rcpatroldisabled', 'rcpatroldisabledtext');
         return;
     }
     if (in_array(array('hookaborted'), $errors)) {
         // The hook itself has handled any output
         return;
     }
     if (in_array(array('markedaspatrollederror-noautopatrol'), $errors)) {
         $wgOut->setPageTitle(wfMsg('markedaspatrollederror'));
         $wgOut->addWikiMsg('markedaspatrollederror-noautopatrol');
         $wgOut->returnToMain(false, $return);
         return;
     }
     if (!empty($errors)) {
         $wgOut->showPermissionsErrorPage($errors);
         return;
     }
     # Inform the user
     $wgOut->setPageTitle(wfMsg('markedaspatrolled'));
     $wgOut->addWikiMsg('markedaspatrolledtext', $rc->getTitle()->getPrefixedText());
     $wgOut->returnToMain(false, $return);
 }
    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__);
    }
 /**
  * Turn a RecentChange id into a revision ID.
  * Note: if the requested revision is a rolled back revision, don't return it.
  */
 public static function getRevFromRC($pageid, $rcid)
 {
     $rc = RecentChange::newFromId($rcid, true);
     if ($rc) {
         // Check if there was a rollback on any of the more
         // recent changes to the article. If there was a
         // rollback, just return 0 so that it looks to any
         // calling function like there is no associated
         // revision ID to assign.
         $rollbackCommentPrefix = wfMsgForContent('rollback_comment_prefix');
         $dbr = self::getDB('read');
         $res = $dbr->select('recentchanges', array('rc_comment'), array('rc_cur_id' => $pageid, 'rc_id > ' . $rcid), __METHOD__);
         foreach ($res as $row) {
             $isRollback = strpos($row->rc_comment, $rollbackCommentPrefix) === 0;
             if ($isRollback) {
                 return 0;
             }
         }
         return $rc->getAttribute('rc_this_oldid');
     } else {
         return 0;
     }
 }
Beispiel #13
0
 /**
  * Mark this particular edit as patrolled
  */
 function markpatrolled()
 {
     global $wgOut, $wgRequest, $wgUseRCPatrol, $wgUser;
     $wgOut->setRobotPolicy('noindex,nofollow');
     # Check RC patrol config. option
     if (!$wgUseRCPatrol) {
         $wgOut->errorPage('rcpatroldisabled', 'rcpatroldisabledtext');
         return;
     }
     # Check permissions
     if (!$wgUser->isAllowed('patrol')) {
         $wgOut->permissionRequired('patrol');
         return;
     }
     # If we haven't been given an rc_id value, we can't do anything
     $rcid = $wgRequest->getVal('rcid');
     if (!$rcid) {
         $wgOut->errorPage('markedaspatrollederror', 'markedaspatrollederrortext');
         return;
     }
     # Handle the 'MarkPatrolled' hook
     if (!wfRunHooks('MarkPatrolled', array($rcid, &$wgUser, false))) {
         return;
     }
     $return = SpecialPage::getTitleFor('Recentchanges');
     # If it's left up to us, check that the user is allowed to patrol this edit
     # If the user has the "autopatrol" right, then we'll assume there are no
     # other conditions stopping them doing so
     if (!$wgUser->isAllowed('autopatrol')) {
         $rc = RecentChange::newFromId($rcid);
         # Graceful error handling, as we've done before here...
         # (If the recent change doesn't exist, then it doesn't matter whether
         # the user is allowed to patrol it or not; nothing is going to happen
         if (is_object($rc) && $wgUser->getName() == $rc->getAttribute('rc_user_text')) {
             # The user made this edit, and can't patrol it
             # Tell them so, and then back off
             $wgOut->setPageTitle(wfMsg('markedaspatrollederror'));
             $wgOut->addWikiText(wfMsgNoTrans('markedaspatrollederror-noautopatrol'));
             $wgOut->returnToMain(false, $return);
             return;
         }
     }
     # Mark the edit as patrolled
     RecentChange::markPatrolled($rcid);
     wfRunHooks('MarkPatrolledComplete', array(&$rcid, &$wgUser, false));
     # Inform the user
     $wgOut->setPageTitle(wfMsg('markedaspatrolled'));
     $wgOut->addWikiText(wfMsgNoTrans('markedaspatrolledtext'));
     $wgOut->returnToMain(false, $return);
 }
 static function getMarkPatrolledLink()
 {
     global $wgRequest, $wgUser;
     // Append a [Mark as Patrolled] link in certain cases
     $markPatrolledLink = '';
     $rcid = $wgRequest->getInt('rcid');
     $fromRC = $wgRequest->getInt('fromrc');
     if ($wgUser && $rcid > 0 && $fromRC && $wgUser->isAllowed('patrol')) {
         $rc = RecentChange::newFromId($rcid);
         if ($rc) {
             $oldRevId = $rc->getAttribute('rc_last_oldid');
             $newRevId = $rc->getAttribute('rc_this_oldid');
             $diff = new DifferenceEngine(null, $oldRevId, $newRevId);
             if ($diff->loadRevisionData()) {
                 $markPatrolledLink = $diff->markPatrolledLink();
             } else {
                 throw new MWException("wikiHow internal error: we know there is an rcid ({$rcid}) and newrevid ({$newRevId}), but couldn't find the revision");
             }
         }
     }
     return $markPatrolledLink;
 }
    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__);
    }
Beispiel #16
0
 function markRevisionsPatrolled($article)
 {
     global $wgOut;
     $request = $this->getRequest();
     // some sanity checks
     $rcid = $request->getInt('rcid');
     $rc = RecentChange::newFromId($rcid);
     if (is_null($rc)) {
         throw new ErrorPageError('markedaspatrollederror', 'markedaspatrollederrortext');
     }
     $user = $this->getUser();
     if (!$user->matchEditToken($request->getVal('token'), $rcid)) {
         throw new ErrorPageError('sessionfailure-title', 'sessionfailure');
     }
     // check if skip has been passed to us
     if ($request->getInt('skip') != 1) {
         // find his and lows
         $rcids = array();
         $rcids[] = $rcid;
         if ($request->getVal('rchi', null) && $request->getVal('rclow', null)) {
             $hilos = wfGetRCPatrols($rcid, $request->getVal('rchi'), $request->getVal('rclow'), $article->mTitle->getArticleID());
             $rcids = array_merge($rcids, $hilos);
         }
         $rcids = array_unique($rcids);
         foreach ($rcids as $id) {
             RecentChange::markPatrolled($id, false);
         }
         wfRunHooks('MarkPatrolledBatchComplete', array(&$article, &$rcids, &$user));
     } else {
         RCPatrol::skipPatrolled($article);
     }
 }
Beispiel #17
0
 /**
  * Mark a given change as patrolled
  *
  * @param $change Mixed: RecentChange or corresponding rc_id
  * @param $auto Boolean: for automatic patrol
  * @return Array See doMarkPatrolled(), or null if $change is not an existing rc_id
  */
 public static function markPatrolled($change, $auto = false, $force = false)
 {
     global $wgUser;
     $change = $change instanceof RecentChange ? $change : RecentChange::newFromId($change);
     if (!$change instanceof RecentChange) {
         return null;
     }
     return $change->doMarkPatrolled($wgUser, $auto, $force);
 }
Beispiel #18
0
 /**
  * Mark this particular edit/page as patrolled
  */
 public function markpatrolled()
 {
     global $wgOut, $wgRequest, $wgUseRCPatrol, $wgUseNPPatrol, $wgUser;
     $wgOut->setRobotPolicy('noindex,nofollow');
     # If we haven't been given an rc_id value, we can't do anything
     $rcid = (int) $wgRequest->getVal('rcid');
     $rc = RecentChange::newFromId($rcid);
     if (is_null($rc)) {
         $wgOut->showErrorPage('markedaspatrollederror', 'markedaspatrollederrortext');
         return;
     }
     #It would be nice to see where the user had actually come from, but for now just guess
     $returnto = $rc->getAttribute('rc_type') == RC_NEW ? 'Newpages' : 'Recentchanges';
     $return = Title::makeTitle(NS_SPECIAL, $returnto);
     $dbw = wfGetDB(DB_MASTER);
     $errors = $rc->doMarkPatrolled();
     if (in_array(array('rcpatroldisabled'), $errors)) {
         $wgOut->showErrorPage('rcpatroldisabled', 'rcpatroldisabledtext');
         return;
     }
     if (in_array(array('hookaborted'), $errors)) {
         // The hook itself has handled any output
         return;
     }
     if (in_array(array('markedaspatrollederror-noautopatrol'), $errors)) {
         $wgOut->setPageTitle(wfMsg('markedaspatrollederror'));
         $wgOut->addWikiMsg('markedaspatrollederror-noautopatrol');
         $wgOut->returnToMain(false, $return);
         return;
     }
     if (!empty($errors)) {
         $wgOut->showPermissionsErrorPage($errors);
         return;
     }
     # Inform the user
     $wgOut->setPageTitle(wfMsg('markedaspatrolled'));
     $wgOut->addWikiMsg('markedaspatrolledtext');
     $wgOut->returnToMain(false, $return);
 }
Beispiel #19
0
 /**
  * Mark a given change as patrolled
  *
  * @param $change Mixed: RecentChange or corresponding rc_id
  * @param $auto Boolean: for automatic patrol
  * @return Array See doMarkPatrolled(), or null if $change is not an existing rc_id
  */
 public static function markPatrolled($change, $auto = false)
 {
     $change = $change instanceof RecentChange ? $change : RecentChange::newFromId($change);
     if (!$change instanceof RecentChange) {
         return null;
     }
     return $change->doMarkPatrolled($auto);
 }
Beispiel #20
0
 /**
  * Mark this particular edit/page as patrolled
  */
 function markpatrolled()
 {
     global $wgOut, $wgRequest, $wgUseRCPatrol, $wgUseNPPatrol, $wgUser;
     $wgOut->setRobotPolicy('noindex,nofollow');
     # Check patrol config options
     if (!($wgUseNPPatrol || $wgUseRCPatrol)) {
         $wgOut->errorPage('rcpatroldisabled', 'rcpatroldisabledtext');
         return;
     }
     if ($wgUser->isBlocked()) {
         $wgOut->blockedPage();
         return;
     }
     # If we haven't been given an rc_id value, we can't do anything
     $rcid = (int) $wgRequest->getVal('rcid');
     $rc = $rcid ? RecentChange::newFromId($rcid) : null;
     if (is_null($rc)) {
         $wgOut->errorPage('markedaspatrollederror', 'markedaspatrollederrortext');
         return;
     }
     if (!$wgUseRCPatrol && $rc->mAttribs['rc_type'] != RC_NEW) {
         // Only new pages can be patrolled if the general patrolling is off....???
         // @fixme -- is this necessary? Shouldn't we only bother controlling the
         // front end here?
         $wgOut->errorPage('rcpatroldisabled', 'rcpatroldisabledtext');
         return;
     }
     # Check permissions
     $permission_errors = $this->mTitle->getUserPermissionsErrors('patrol', $wgUser);
     if (count($permission_errors) > 0) {
         $wgOut->showPermissionsErrorPage($permission_errors);
         return;
     }
     # Handle the 'MarkPatrolled' hook
     if (!wfRunHooks('MarkPatrolled', array($rcid, &$wgUser, false))) {
         return;
     }
     #It would be nice to see where the user had actually come from, but for now just guess
     $returnto = $rc->mAttribs['rc_type'] == RC_NEW ? 'Newpages' : 'Recentchanges';
     $return = Title::makeTitle(NS_SPECIAL, $returnto);
     # If it's left up to us, check that the user is allowed to patrol this edit
     # If the user has the "autopatrol" right, then we'll assume there are no
     # other conditions stopping them doing so
     if (!$wgUser->isAllowed('autopatrol') && $wgRequest->getVal('skip') != 1) {
         $rc = RecentChange::newFromId($rcid);
         # Graceful error handling, as we've done before here...
         # (If the recent change doesn't exist, then it doesn't matter whether
         # the user is allowed to patrol it or not; nothing is going to happen
         if (is_object($rc) && $wgUser->getName() == $rc->getAttribute('rc_user_text')) {
             # The user made this edit, and can't patrol it
             # Tell them so, and then back off
             $wgOut->setPageTitle(wfMsg('markedaspatrollederror'));
             $wgOut->addWikiMsg('markedaspatrollederror-noautopatrol');
             $wgOut->returnToMain(false, $return);
             return;
         }
     }
     # Mark the edit as patrolled
     if (!wfRunHooks('ArticleMarkPatrolled', array(&$this, $rcid))) {
         return;
     }
     wfRunHooks('MarkPatrolledComplete', array(&$rcid, &$wgUser, false));
     # Inform the user
     $wgOut->setPageTitle(wfMsg('markedaspatrolled'));
     $wgOut->addWikiMsg('markedaspatrolledtext');
     $wgOut->returnToMain(false, $return);
 }