protected function showStableList()
 {
     $out = $this->getOutput();
     # Must be a content page
     if (!FlaggedRevs::inReviewNamespace($this->page)) {
         $out->addWikiMsg('reviewedversions-none', $this->page->getPrefixedText());
         return;
     }
     $pager = new ReviewedVersionsPager($this, array(), $this->page);
     $num = $pager->getNumRows();
     if ($num) {
         $out->addWikiMsg('reviewedversions-list', $this->page->getPrefixedText(), $this->getLang()->formatNum($num));
         $out->addHTML($pager->getNavigationBar());
         $out->addHTML("<ul>" . $pager->getBody() . "</ul>");
         $out->addHTML($pager->getNavigationBar());
     } else {
         $out->addHTML(wfMsgExt('reviewedversions-none', array('parse'), $this->page->getPrefixedText()));
     }
 }
 /**
  * Modify an array of tab links to include flagged revs UI elements
  * @param string $type ('flat' for SkinTemplateTabs, 'nav' for SkinTemplateNavigation)
  */
 public function setViewTabs(Skin $skin, array &$views, $type)
 {
     $this->load();
     if (!FlaggedRevs::inReviewNamespace($this->article->getTitle())) {
         return true;
         // short-circuit for non-reviewable pages
     }
     # Hack for bug 16734 (some actions update and view all at once)
     if ($this->pageWriteOpRequested() && wfGetDB(DB_MASTER)->doneWrites()) {
         # Tabs need to reflect the new stable version so users actually
         # see the results of their action (i.e. "delete"/"rollback")
         $this->article->loadPageData('fromdbmaster');
     }
     $srev = $this->article->getStableRev();
     if (!$srev) {
         return true;
         // No stable revision exists
     }
     $synced = $this->article->stableVersionIsSynced();
     $pendingEdits = !$synced && $this->article->isStableShownByDefault();
     // Set the edit tab names as needed...
     if ($pendingEdits) {
         if (isset($views['edit'])) {
             $views['edit']['text'] = wfMsg('revreview-edit');
             if ($this->showingStable()) {
                 // bug 31489; direct user to current
                 $views['edit']['href'] = $skin->getTitle()->getFullURL('action=edit');
             }
         }
         if (isset($views['viewsource'])) {
             $views['viewsource']['text'] = wfMsg('revreview-source');
             if ($this->showingStable()) {
                 // bug 31489; direct user to current
                 $views['viewsource']['href'] = $skin->getTitle()->getFullURL('action=edit');
             }
         }
     }
     # Add "pending changes" tab if the page is not synced
     if (!$synced) {
         $this->addDraftTab($views, $srev, $type);
     }
     return true;
 }
 /**
  * Set the page field data loaded from some source
  * @param $data Database row object or "fromdb"
  * @return void
  */
 public function loadPageData($data = 'fromdb')
 {
     $this->mDataLoaded = true;
     // sanity
     # Fetch data from DB as needed...
     if ($data === 'fromdb' || $data === 'fromdbmaster') {
         $db = $data == 'fromdbmaster' ? wfGetDB(DB_MASTER) : wfGetDB(DB_SLAVE);
         $data = $this->pageDataFromTitle($db, $this->mTitle);
     }
     # Load in primary page data...
     parent::loadPageData($data);
     # Load in FlaggedRevs page data...
     $this->stable = 0;
     // 0 => "found nothing"
     $this->stableRev = null;
     // defer this one...
     $this->revsArePending = false;
     // false => "found nothing" or "none pending"
     $this->pendingRevCount = null;
     // defer this one...
     $this->pageConfig = FRPageConfig::getDefaultVisibilitySettings();
     // default
     $this->syncedInTracking = true;
     // false => "unreviewed" or "synced"
     # Load in flaggedrevs Row data if the page exists...(sanity check NS)
     if ($data && FlaggedRevs::inReviewNamespace($this->mTitle)) {
         if ($data->fpc_override !== null) {
             // page config row found
             $this->pageConfig = FRPageConfig::getVisibilitySettingsFromRow($data);
         }
         if ($data->fp_stable !== null) {
             // stable rev found
             $this->stable = (int) $data->fp_stable;
             $this->revsArePending = $data->fp_pending_since !== null;
             // revs await review
             $this->syncedInTracking = (bool) $data->fp_reviewed;
         }
     }
 }
 /**
  * Get a FlaggedRevision of the stable version of a title.
  * Skips tracking tables to figure out new stable version.
  * @param Title $title, page title
  * @param int $flags (FR_MASTER, FR_FOR_UPDATE)
  * @param array $config, optional page config (use to skip queries)
  * @param string $precedence (latest,quality,pristine)
  * @return FlaggedRevision|null (null on failure)
  */
 public static function determineStable(Title $title, $flags = 0, $config = array(), $precedence = 'latest')
 {
     if (!FlaggedRevs::inReviewNamespace($title)) {
         return null;
         // short-circuit
     }
     $options = array();
     # User master/slave as appropriate...
     if ($flags & FR_FOR_UPDATE || $flags & FR_MASTER) {
         $db = wfGetDB(DB_MASTER);
         if ($flags & FR_FOR_UPDATE) {
             $options[] = 'FOR UPDATE';
         }
         $pageId = $title->getArticleID(Title::GAID_FOR_UPDATE);
     } else {
         $db = wfGetDB(DB_SLAVE);
         $pageId = $title->getArticleID();
     }
     if (!$pageId) {
         return null;
         // short-circuit query
     }
     # Get visiblity settings to see if page is reviewable...
     if (FlaggedRevs::useOnlyIfProtected()) {
         if (empty($config)) {
             $config = FRPageConfig::getStabilitySettings($title, $flags);
         }
         if (!$config['override']) {
             return null;
             // page is not reviewable; no stable version
         }
     }
     $baseConds = array('fr_page_id' => $pageId, 'rev_id = fr_rev_id', 'rev_page = fr_page_id', $db->bitAnd('rev_deleted', Revision::DELETED_TEXT) . ' = 0');
     $options['ORDER BY'] = 'fr_rev_timestamp DESC';
     $row = null;
     if ($precedence !== 'latest') {
         # Look for the latest pristine revision...
         if (FlaggedRevs::pristineVersions()) {
             $prow = $db->selectRow(array('flaggedrevs', 'revision'), self::selectFields(), array_merge($baseConds, array('fr_quality' => FR_PRISTINE)), __METHOD__, $options);
             # Looks like a plausible revision
             $row = $prow ? $prow : $row;
         }
         if ($row && $precedence === 'pristine') {
             // we have what we want already
             # Look for the latest quality revision...
         } elseif (FlaggedRevs::qualityVersions()) {
             // If we found a pristine rev above, this one must be newer...
             $newerClause = $row ? array('fr_rev_timestamp > ' . $db->addQuotes($row->fr_rev_timestamp)) : array();
             $qrow = $db->selectRow(array('flaggedrevs', 'revision'), self::selectFields(), array_merge($baseConds, array('fr_quality' => FR_QUALITY), $newerClause), __METHOD__, $options);
             $row = $qrow ? $qrow : $row;
         }
     }
     # Do we have one? If not, try the latest reviewed revision...
     if (!$row) {
         $row = $db->selectRow(array('flaggedrevs', 'revision'), self::selectFields(), $baseConds, __METHOD__, $options);
         if (!$row) {
             return null;
         }
     }
     $frev = new self($row);
     $frev->mTitle = $title;
     return $frev;
 }
 /**
  * Check page move and patrol permissions for FlaggedRevs
  */
 public static function onGetUserPermissionsErrors(Title $title, $user, $action, &$result)
 {
     if ($result === false) {
         return true;
         // nothing to do
     }
     # Don't let users vandalize pages by moving them...
     if ($action === 'move') {
         if (!FlaggedRevs::inReviewNamespace($title) || !$title->exists()) {
             return true;
             // extra short-circuit
         }
         $flaggedArticle = FlaggableWikiPage::getTitleInstance($title);
         # If the draft shows by default anyway, nothing to do...
         if (!$flaggedArticle->isStableShownByDefault()) {
             return true;
         }
         $frev = $flaggedArticle->getStableRev();
         if ($frev && !$user->isAllowed('review') && !$user->isAllowed('movestable')) {
             # Allow for only editors/reviewers to move this page
             $result = false;
             return false;
         }
         # Enforce autoreview/review restrictions
     } elseif ($action === 'autoreview' || $action === 'review') {
         # Get autoreview restriction settings...
         $fa = FlaggableWikiPage::getTitleInstance($title);
         $config = $fa->getStabilitySettings();
         # Convert Sysop -> protect
         $right = $config['autoreview'];
         if ($right === 'sysop') {
             // Backwards compatibility, rewrite sysop -> editprotected
             $right = 'editprotected';
         }
         if ($right === 'autoconfirmed') {
             // Backwards compatibility, rewrite autoconfirmed -> editsemiprotected
             $right = 'editsemiprotected';
         }
         # Check if the user has the required right, if any
         if ($right != '' && !$user->isAllowed($right)) {
             $result = false;
             return false;
         }
         # Respect page protection to handle cases of "review wars".
         # If a page is restricted from editing such that a user cannot
         # edit it, then said user should not be able to review it.
         foreach ($title->getRestrictions('edit') as $right) {
             if ($right === 'sysop') {
                 // Backwards compatibility, rewrite sysop -> editprotected
                 $right = 'editprotected';
             }
             if ($right === 'autoconfirmed') {
                 // Backwards compatibility, rewrite autoconfirmed -> editsemiprotected
                 $right = 'editsemiprotected';
             }
             if ($right != '' && !$user->isAllowed($right)) {
                 $result = false;
                 return false;
             }
         }
     }
     return true;
 }
 protected function doCheckTarget($flags = 0)
 {
     $flgs = $flags & self::FOR_SUBMISSION ? Title::GAID_FOR_UPDATE : 0;
     if (!$this->page->getArticleId($flgs)) {
         return 'stabilize_page_notexists';
     } elseif (!FlaggedRevs::inReviewNamespace($this->page)) {
         return 'stabilize_page_unreviewable';
     }
     return true;
 }
 public static function onProtectionSave(Page $article, &$errorMsg)
 {
     global $wgUser, $wgRequest;
     if (!$article->exists()) {
         return true;
         // simple custom levels set for action=protect
     } elseif (!FlaggedRevs::inReviewNamespace($article->getTitle())) {
         return true;
         // not a reviewable page
     } elseif (wfReadOnly() || !$wgUser->isAllowed('stablesettings')) {
         return true;
         // user cannot change anything
     }
     $form = new PageStabilityProtectForm($wgUser);
     $form->setPage($article->getTitle());
     // target page
     $permission = $wgRequest->getVal('mwStabilityLevel');
     if ($permission == "none") {
         $permission = '';
         // 'none' => ''
     }
     $form->setAutoreview($permission);
     // protection level (autoreview restriction)
     $form->setWatchThis(null);
     // protection form already has a watch check
     $form->setReasonExtra($wgRequest->getText('mwProtect-reason'));
     // manual
     $form->setReasonSelection($wgRequest->getVal('wpProtectReasonSelection'));
     // dropdown
     $form->setExpiryCustom($wgRequest->getVal('mwStabilizeExpiryOther'));
     // manual
     $form->setExpirySelection($wgRequest->getVal('mwStabilizeExpirySelection'));
     // dropdown
     $form->ready();
     // params all set
     if ($wgRequest->wasPosted() && $form->isAllowed()) {
         $status = $form->submit();
         if ($status !== true) {
             $errorMsg = wfMsg($status);
             // some error message
         }
     }
     return true;
 }
 /**
  * Check page move and patrol permissions for FlaggedRevs
  */
 public static function onUserCan(Title $title, $user, $action, &$result)
 {
     if ($result === false) {
         return true;
         // nothing to do
     }
     # Don't let users vandalize pages by moving them...
     if ($action === 'move') {
         if (!FlaggedRevs::inReviewNamespace($title) || !$title->exists()) {
             return true;
             // extra short-circuit
         }
         $flaggedArticle = FlaggableWikiPage::getTitleInstance($title);
         # If the draft shows by default anyway, nothing to do...
         if (!$flaggedArticle->isStableShownByDefault()) {
             return true;
         }
         $frev = $flaggedArticle->getStableRev();
         if ($frev && !$user->isAllowed('review') && !$user->isAllowed('movestable')) {
             # Allow for only editors/reviewers to move this page
             $result = false;
             return false;
         }
         # Don't let users patrol reviewable pages (where reviewed <=> patrolled)
     } elseif ($action === 'patrol' || $action === 'autopatrol') {
         $flaggedArticle = FlaggableWikiPage::getTitleInstance($title);
         # For a page to be patrollable it must not be reviewable.
         if ($flaggedArticle->isReviewable()) {
             $result = false;
             return false;
             // patrol by "accepting"
         }
         # Enforce autoreview/review restrictions
     } elseif ($action === 'autoreview' || $action === 'review') {
         # Get autoreview restriction settings...
         $fa = FlaggableWikiPage::getTitleInstance($title);
         $config = $fa->getStabilitySettings();
         # Convert Sysop -> protect
         $right = $config['autoreview'] === 'sysop' ? 'protect' : $config['autoreview'];
         # Check if the user has the required right, if any
         if ($right != '' && !$user->isAllowed($right)) {
             $result = false;
             return false;
         }
     }
     return true;
 }