Ejemplo n.º 1
0
 /**
  * This function does essentially the same as RevisionReview::AjaxReview,
  * except that it generates the template and image parameters itself.
  */
 public function execute()
 {
     global $wgUser;
     $params = $this->extractRequestParams();
     // Check basic permissions
     if (!$wgUser->isAllowed('review')) {
         $this->dieUsage("You don't have the right to review revisions.", 'permissiondenied');
     } elseif ($wgUser->isBlocked(false)) {
         $this->dieUsageMsg(array('blockedtext'));
     }
     // Get target rev and title
     $revid = (int) $params['revid'];
     $rev = Revision::newFromId($revid);
     if (!$rev) {
         $this->dieUsage("Cannot find a revision with the specified ID.", 'notarget');
     }
     $title = $rev->getTitle();
     // Construct submit form...
     $form = new RevisionReviewForm($wgUser);
     $form->setPage($title);
     $form->setOldId($revid);
     $form->setApprove(empty($params['unapprove']));
     $form->setUnapprove(!empty($params['unapprove']));
     if (isset($params['comment'])) {
         $form->setComment($params['comment']);
     }
     // The flagging parameters have the form 'flag_$name'.
     // Extract them and put the values into $form->dims
     foreach (FlaggedRevs::getTags() as $tag) {
         $form->setDim($tag, (int) $params['flag_' . $tag]);
     }
     if ($form->getAction() === 'approve') {
         $article = new FlaggableWikiPage($title);
         // Get the file version used for File: pages
         $file = $article->getFile();
         if ($file) {
             $fileVer = array('time' => $file->getTimestamp(), 'sha1' => $file->getSha1());
         } else {
             $fileVer = null;
         }
         // Now get the template and image parameters needed
         list($templateIds, $fileTimeKeys) = FRInclusionCache::getRevIncludes($article, $rev, $wgUser);
         // Get version parameters for review submission (flat strings)
         list($templateParams, $imageParams, $fileParam) = RevisionReviewForm::getIncludeParams($templateIds, $fileTimeKeys, $fileVer);
         // Set the version parameters...
         $form->setTemplateParams($templateParams);
         $form->setFileParams($imageParams);
         $form->setFileVersion($fileParam);
         $form->bypassValidationKey();
         // always OK; uses current templates/files
     }
     $status = $form->ready();
     // all params set
     # Try to do the actual review
     $status = $form->submit();
     # Approve/de-approve success
     if ($status === true) {
         $this->getResult()->addValue(null, $this->getModuleName(), array('result' => 'Success'));
         # Approve-specific failures
     } elseif ($form->getAction() === 'approve') {
         if ($status === 'review_denied') {
             $this->dieUsage("You don't have the necessary rights to set the specified flags.", 'permissiondenied');
         } elseif ($status === 'review_too_low') {
             $this->dieUsage("Either all or none of the flags have to be set to zero.", 'mixedapproval');
         } elseif ($status === 'review_bad_key') {
             $this->dieUsage("You don't have the necessary rights to set the specified flags.", 'permissiondenied');
         } elseif ($status === 'review_bad_tags') {
             $this->dieUsage("The specified flags are not valid.", 'invalidtags');
         } elseif ($status === 'review_bad_oldid') {
             $this->dieUsage("No revision with the specified ID.", 'notarget');
         } else {
             // FIXME: review_param_missing? better msg?
             $this->dieUsageMsg(array('unknownerror', ''));
         }
         # De-approve specific failure
     } elseif ($form->getAction() === 'unapprove') {
         if ($status === 'review_denied') {
             $this->dieUsage("You don't have the necessary rights to remove the flags.", 'permissiondenied');
         } elseif ($status === 'review_not_flagged') {
             $this->dieUsage("No flagged revision with the specified ID.", 'notarget');
         } else {
             // FIXME: review_param_missing? better msg?
             $this->dieUsageMsg(array('unknownerror', ''));
         }
         # Generic failures
     } else {
         if ($status === 'review_page_unreviewable') {
             $this->dieUsage("Provided page is not reviewable.", 'notreviewable');
         } elseif ($status === 'review_page_notexists') {
             $this->dieUsage("Provided page does not exist.", 'notarget');
         }
     }
 }
 public static function AjaxReview()
 {
     global $wgUser, $wgOut, $wgRequest;
     $args = func_get_args();
     if (wfReadOnly()) {
         return '<err#>' . wfMsgExt('revreview-failed', 'parseinline') . wfMsgExt('revreview-submission-invalid', 'parseinline');
     }
     $tags = FlaggedRevs::getTags();
     // Make review interface object
     $form = new RevisionReviewForm($wgUser);
     $title = null;
     // target page
     $editToken = '';
     // edit token
     // Each ajax url argument is of the form param|val.
     // This means that there is no ugly order dependance.
     foreach ($args as $arg) {
         $set = explode('|', $arg, 2);
         if (count($set) != 2) {
             return '<err#>' . wfMsgExt('revreview-failed', 'parseinline') . wfMsgExt('revreview-submission-invalid', 'parseinline');
         }
         list($par, $val) = $set;
         switch ($par) {
             case "target":
                 $title = Title::newFromURL($val);
                 break;
             case "oldid":
                 $form->setOldId($val);
                 break;
             case "refid":
                 $form->setRefId($val);
                 break;
             case "validatedParams":
                 $form->setValidatedParams($val);
                 break;
             case "templateParams":
                 $form->setTemplateParams($val);
                 break;
             case "imageParams":
                 $form->setFileParams($val);
                 break;
             case "fileVersion":
                 $form->setFileVersion($val);
                 break;
             case "wpApprove":
                 $form->setApprove($val);
                 break;
             case "wpUnapprove":
                 $form->setUnapprove($val);
                 break;
             case "wpReject":
                 $form->setReject($val);
                 break;
             case "wpReason":
                 $form->setComment($val);
                 break;
             case "changetime":
                 $form->setLastChangeTime($val);
                 break;
             case "wpEditToken":
                 $editToken = $val;
                 break;
             default:
                 $p = preg_replace('/^wp/', '', $par);
                 // kill any "wp" prefix
                 if (in_array($p, $tags)) {
                     $form->setDim($p, $val);
                 }
                 break;
         }
     }
     # Valid target title?
     if (!$title) {
         return '<err#>' . wfMsgExt('notargettext', 'parseinline');
     }
     $form->setPage($title);
     $form->setSessionKey($wgRequest->getSessionData('wsFlaggedRevsKey'));
     $status = $form->ready();
     // all params loaded
     # Check session via user token
     if (!$wgUser->matchEditToken($editToken)) {
         return '<err#>' . wfMsgExt('sessionfailure', 'parseinline');
     }
     # Basic permission checks...
     $permErrors = $title->getUserPermissionsErrors('review', $wgUser, false);
     if (!$permErrors) {
         $permErrors = $title->getUserPermissionsErrors('edit', $wgUser, false);
     }
     if ($permErrors) {
         return '<err#>' . $wgOut->parse($wgOut->formatPermissionsErrorMessage($permErrors, 'review'));
     }
     # Try submission...
     $status = $form->submit();
     # Success...
     if ($status === true) {
         # Sent new lastChangeTime TS to client for later submissions...
         $changeTime = $form->getNewLastChangeTime();
         if ($form->getAction() === 'approve') {
             // approve
             return "<suc#><lct#{$changeTime}>";
         } elseif ($form->getAction() === 'unapprove') {
             // de-approve
             return "<suc#><lct#{$changeTime}>";
         } elseif ($form->getAction() === 'reject') {
             // revert
             return "<suc#><lct#{$changeTime}>";
         }
         # Failure...
     } else {
         return '<err#>' . wfMsgExt('revreview-failed', 'parse') . '<p>' . wfMsgHtml($status) . '</p>';
     }
 }
 /**
  * Generates a brief review form for a page
  * @return array (html string, error string or true)
  */
 public function getHtml()
 {
     global $wgLang;
     $revId = $this->rev->getId();
     if ($this->rev->isDeleted(Revision::DELETED_TEXT)) {
         return array('', 'review_bad_oldid');
         # The revision must be valid and public
     }
     $article = $this->article;
     // convenience
     $srev = $article->getStableRev();
     # See if the version being displayed is flagged...
     if ($revId == $article->getStable()) {
         $frev = $srev;
         // avoid query
     } else {
         $frev = FlaggedRevision::newFromTitle($article->getTitle(), $revId);
     }
     $oldFlags = $frev ? $frev->getTags() : FlaggedRevs::quickTags(FR_CHECKED);
     // basic tags
     $reviewTime = $frev ? $frev->getTimestamp() : '';
     // last review of rev
     $priorRevId = $this->refRev ? $this->refRev->getId() : 0;
     # If we are reviewing updates to a page, start off with the stable revision's
     # flags. Otherwise, we just fill them in with the selected revision's flags.
     # @TODO: do we want to carry over info for other diffs?
     if ($srev && $srev->getRevId() == $priorRevId) {
         // diff-to-stable
         $flags = $srev->getTags();
         # Check if user is allowed to renew the stable version.
         # If not, then get the flags for the new revision itself.
         if (!FlaggedRevs::userCanSetFlags($this->user, $oldFlags)) {
             $flags = $oldFlags;
         }
         # Re-review button is need for template/file only review case
         $reviewIncludes = $srev->getRevId() == $revId && !$article->stableVersionIsSynced();
     } else {
         // views
         $flags = $oldFlags;
         $reviewIncludes = false;
         // re-review button not needed
     }
     # Disable form for unprivileged users
     $disabled = array();
     if (!$article->getTitle()->quickUserCan('review') || !FlaggedRevs::userCanSetFlags($this->user, $flags)) {
         $disabled = array('disabled' => 'disabled');
     }
     # Begin form...
     $reviewTitle = SpecialPage::getTitleFor('RevisionReview');
     $action = $reviewTitle->getLocalUrl('action=submit');
     $params = array('method' => 'post', 'action' => $action, 'id' => 'mw-fr-reviewform');
     $form = Xml::openElement('form', $params) . "\n";
     $form .= Xml::openElement('fieldset', array('class' => 'flaggedrevs_reviewform noprint')) . "\n";
     # Add appropriate legend text
     $legendMsg = $frev ? 'revreview-reflag' : 'revreview-flag';
     $form .= Xml::openElement('legend', array('id' => 'mw-fr-reviewformlegend'));
     $form .= "<strong>" . wfMessage($legendMsg)->escaped() . "</strong>";
     $form .= Xml::closeElement('legend') . "\n";
     # Show explanatory text
     $form .= $this->topNotice;
     # Check if anyone is reviewing this already and
     # show a conflict warning message as needed...
     if ($priorRevId) {
         list($u, $ts) = FRUserActivity::getUserReviewingDiff($priorRevId, $this->rev->getId());
     } else {
         list($u, $ts) = FRUserActivity::getUserReviewingPage($this->rev->getPage());
     }
     $form .= Xml::openElement('p');
     // Page under review (and not by this user)...
     if ($u !== null && $u != $this->user->getName()) {
         $form .= '<span class="fr-under-review">';
         $msg = $priorRevId ? 'revreview-poss-conflict-c' : 'revreview-poss-conflict-p';
         $form .= wfMessage($msg, $u, $wgLang->date($ts, true), $wgLang->time($ts, true))->parse();
         $form .= "</span>";
         // Page not under review or under review by this user...
     } elseif (!$frev) {
         // rev not already reviewed
         $form .= '<span id="mw-fr-reviewing-status" style="display:none;"></span>';
         // JS widget
     }
     $form .= Xml::closeElement('p') . "\n";
     # Start rating controls
     $css = $disabled ? 'fr-rating-controls-disabled' : 'fr-rating-controls';
     $form .= Xml::openElement('p', array('class' => $css, 'id' => 'fr-rating-controls')) . "\n";
     # Add main checkboxes/selects
     $form .= Xml::openElement('span', array('id' => 'mw-fr-ratingselects', 'class' => 'fr-rating-options')) . "\n";
     $form .= self::ratingInputs($this->user, $flags, (bool) $disabled, (bool) $frev) . "\n";
     $form .= Xml::closeElement('span') . "\n";
     # Don't put buttons & comment field on the same line as tag inputs.
     if (!$disabled && !FlaggedRevs::binaryFlagging()) {
         // $disabled => no comment/buttons
         $form .= "<br />";
     }
     # Start comment & buttons
     $form .= Xml::openElement('span', array('id' => 'mw-fr-confirmreview')) . "\n";
     # Hide comment input if needed
     if (!$disabled) {
         $form .= Xml::inputLabel(wfMessage('revreview-log')->text(), 'wpReason', 'mw-fr-commentbox', 40, '', array('maxlength' => 255, 'class' => 'fr-comment-box'));
     }
     # Add the submit buttons...
     $rejectId = $this->rejectRefRevId();
     // determine if there will be reject button
     $form .= self::submitButtons($rejectId, $frev, (bool) $disabled, $reviewIncludes);
     # Show stability log if there is anything interesting...
     if ($article->isPageLocked()) {
         $form .= ' ' . FlaggedRevsXML::logToggle('revreview-log-toggle-show');
     }
     # End comment & buttons
     $form .= Xml::closeElement('span') . "\n";
     # ..add the actual stability log body here
     if ($article->isPageLocked()) {
         $form .= FlaggedRevsXML::stabilityLogExcerpt($article);
     }
     # End rating controls
     $form .= Xml::closeElement('p') . "\n";
     # Show explanatory text
     $form .= $this->bottomNotice;
     # Get the file version used for File: pages as needed
     $fileKey = $this->getFileVersion();
     # Get template/file version info as needed
     list($templateIDs, $imageSHA1Keys) = $this->getIncludeVersions();
     # Convert these into flat string params
     list($templateParams, $imageParams, $fileVersion) = RevisionReviewForm::getIncludeParams($templateIDs, $imageSHA1Keys, $fileKey);
     # Hidden params
     $form .= Html::hidden('title', $reviewTitle->getPrefixedText()) . "\n";
     $form .= Html::hidden('target', $article->getTitle()->getPrefixedDBKey()) . "\n";
     $form .= Html::hidden('refid', $priorRevId, array('id' => 'mw-fr-input-refid')) . "\n";
     $form .= Html::hidden('oldid', $revId, array('id' => 'mw-fr-input-oldid')) . "\n";
     $form .= Html::hidden('wpEditToken', $this->user->getEditToken()) . "\n";
     $form .= Html::hidden('changetime', $reviewTime, array('id' => 'mw-fr-input-changetime')) . "\n";
     // id for JS
     $form .= Html::hidden('userreviewing', (int) ($u === $this->user->getName()), array('id' => 'mw-fr-user-reviewing')) . "\n";
     // id for JS
     # Add review parameters
     $form .= Html::hidden('templateParams', $templateParams) . "\n";
     $form .= Html::hidden('imageParams', $imageParams) . "\n";
     $form .= Html::hidden('fileVersion', $fileVersion) . "\n";
     # Special token to discourage fiddling...
     $key = $this->request->getSessionData('wsFlaggedRevsKey');
     $checkCode = RevisionReviewForm::validationKey($templateParams, $imageParams, $fileVersion, $revId, $key);
     $form .= Html::hidden('validatedParams', $checkCode) . "\n";
     $form .= Xml::closeElement('fieldset') . "\n";
     $form .= Xml::closeElement('form') . "\n";
     return array($form, true);
 }
 /**
  * Mark auto-reviewed edits as patrolled
  */
 public static function autoMarkPatrolled(RecentChange &$rc)
 {
     if (empty($rc->mAttribs['rc_this_oldid'])) {
         return true;
     }
     $fa = FlaggableWikiPage::getTitleInstance($rc->getTitle());
     $fa->loadPageData('fromdbmaster');
     // Is the page reviewable?
     if ($fa->isReviewable()) {
         $revId = $rc->mAttribs['rc_this_oldid'];
         // If the edit we just made was reviewed, then it's the stable rev
         $frev = FlaggedRevision::newFromTitle($rc->getTitle(), $revId, FR_MASTER);
         // Reviewed => patrolled
         if ($frev) {
             RevisionReviewForm::updateRecentChanges($rc, 'patrol', $frev);
             $rc->mAttribs['rc_patrolled'] = 1;
             // make sure irc/email notifs know status
         }
         return true;
     }
     return true;
 }
 public function __construct(RevisionReviewForm $form)
 {
     $this->form = $form;
     $this->newRev = Revision::newFromTitle($form->getPage(), $form->getOldId());
     $this->oldRev = Revision::newFromTitle($form->getPage(), $form->getRefId());
 }
 /**
  * When an edit is made to a page:
  * (a) If the page is reviewable, silently mark the edit patrolled if it was auto-reviewed
  * (b) If the page can be patrolled, auto-patrol the edit patrolled as normal
  * (c) If the page is new and $wgUseNPPatrol is on, auto-patrol the edit patrolled as normal
  * (d) If the edit is neither reviewable nor patrolleable, silently mark it patrolled
  */
 public static function autoMarkPatrolled(RecentChange &$rc)
 {
     if (empty($rc->mAttribs['rc_this_oldid'])) {
         return true;
     }
     $fa = FlaggableWikiPage::getTitleInstance($rc->getTitle());
     $fa->loadPageData('fromdbmaster');
     // Is the page reviewable?
     if ($fa->isReviewable()) {
         $revId = $rc->mAttribs['rc_this_oldid'];
         $quality = FlaggedRevision::getRevQuality($revId, FR_MASTER);
         // Reviewed => patrolled
         if ($quality !== false && $quality >= FR_CHECKED) {
             RevisionReviewForm::updateRecentChanges($rc, 'patrol', $fa->getStableRev());
             $rc->mAttribs['rc_patrolled'] = 1;
             // make sure irc/email notifs know status
         }
         return true;
     }
     return true;
 }