/** * When viewing a diff: * (a) Add the review form to the top of the page * (b) Mark off which versions are checked or not * (c) When comparing the stable revision to the current: * (i) Show a tag with some explanation for the diff * (ii) List any template/file changes pending review */ public function addToDiffView($diff, $oldRev, $newRev) { global $wgMemc, $wgParserCacheExpireTime; $request = $this->getRequest(); $reqUser = $this->getUser(); $this->load(); # Exempt printer-friendly output if ($this->out->isPrintable()) { return true; # Multi-page diffs are useless and misbehave (bug 19327). Sanity check $newRev. } elseif ($this->isMultiPageDiff || !$newRev) { return true; # Page must be reviewable. } elseif (!$this->article->isReviewable()) { return true; } $srev = $this->article->getStableRev(); if ($srev && $this->isReviewableDiff) { $this->reviewFormRev = $newRev; } # Check if this is a diff-to-stable. If so: # (a) prompt reviewers to review the changes # (b) list template/file changes if only includes are pending if ($srev && $this->isDiffFromStable && !$this->article->stableVersionIsSynced()) { $changeText = ''; $changeList = array(); # Page not synced only due to includes? if (!$this->article->revsArePending()) { # Add a list of links to each changed template... $changeList = self::fetchTemplateChanges($srev); # Add a list of links to each changed file... $changeList = array_merge($changeList, self::fetchFileChanges($srev)); # Correct bad cache which said they were not synced... if (!count($changeList)) { $key = wfMemcKey('flaggedrevs', 'includesSynced', $this->article->getId()); $data = FlaggedRevs::makeMemcObj("true"); $wgMemc->set($key, $data, $wgParserCacheExpireTime); } # Otherwise, check for includes pending on top of edits pending... } else { $incs = FRInclusionCache::getRevIncludes($this->article, $newRev, $reqUser); $this->oldRevIncludes = $incs; // process cache # Add a list of links to each changed template... $changeList = self::fetchTemplateChanges($srev, $incs[0]); # Add a list of links to each changed file... $changeList = array_merge($changeList, self::fetchFileChanges($srev, $incs[1])); } # If there are pending revs or templates/files changes, notify the user... if ($this->article->revsArePending() || count($changeList)) { # If the user can review then prompt them to review them... if ($reqUser->isAllowed('review')) { // Reviewer just edited... if ($request->getInt('shownotice') && $newRev->isCurrent() && $newRev->getRawUserText() == $reqUser->getName()) { $title = $this->article->getTitle(); // convenience // @TODO: make diff class cache this $n = $title->countRevisionsBetween($oldRev, $newRev); if ($n) { $msg = 'revreview-update-edited-prev'; // previous pending edits } else { $msg = 'revreview-update-edited'; // just couldn't autoreview } // All other cases... } else { $msg = 'revreview-update'; // generic "please review" notice... } $this->diffNoticeBox = wfMsgExt($msg, 'parse'); // add as part of form } # Add include change list... if (count($changeList)) { // just inclusion changes $changeText .= "<p>" . wfMsgExt('revreview-update-includes', 'parseinline') . ' ' . implode(', ', $changeList) . "</p>\n"; } } # template/file change list if ($changeText != '') { if ($reqUser->isAllowed('review')) { $this->diffIncChangeBox = "<p>{$changeText}</p>"; } else { $css = 'flaggedrevs_diffnotice plainlinks'; $this->out->addHTML("<div id='mw-fr-difftostable' class='{$css}'>{$changeText}</div>\n"); } } } # Add a link to diff from stable to current as needed. # Show review status of the diff revision(s). Uses a <table>. $this->out->addHTML('<div id="mw-fr-diff-headeritems">' . self::diffLinkAndMarkers($this->article, $oldRev, $newRev) . '</div>'); return true; }
/** * Set template and image versions from parsing a revision * @param Title $title * @param int $revId * @param ParserOutput $rev * @return void */ public static function setRevIncludes(Title $title, $revId, ParserOutput $pOut) { global $wgMemc; $key = self::getCacheKey($title, $revId); # Get the template/file versions used... $versions = array($pOut->getTemplateIds(), $pOut->getFileSearchOptions()); # Save to cache (check cache expiry for dynamic elements)... $data = FlaggedRevs::makeMemcObj($versions); $wgMemc->set($key, $data, $pOut->getCacheExpiry()); }
/** * Checks if the stable version is synced with the current revision * Note: slower than getPendingRevCount() * @return bool */ public function stableVersionIsSynced() { global $wgMemc, $wgParserCacheExpireTime; $srev = $this->getStableRev(); if (!$srev) { return true; } # Stable text revision must be the same as the current if ($this->revsArePending()) { return false; # Stable file revision must be the same as the current } elseif ($this->mTitle->getNamespace() == NS_FILE) { $file = $this->getFile(); // current upload version if ($file && $file->getTimestamp() > $srev->getFileTimestamp()) { return false; } } # If using the current version of includes, there is nothing else to check. if (FlaggedRevs::inclusionSetting() == FR_INCLUDES_CURRENT) { return true; // short-circuit } # Try the cache... $key = wfMemcKey('flaggedrevs', 'includesSynced', $this->getId()); $value = FlaggedRevs::getMemcValue($wgMemc->get($key), $this); if ($value === "true") { return true; } elseif ($value === "false") { return false; } # Since the stable and current revisions have the same text and only outputs, # the only other things to check for are template and file differences in the output. # (a) Check if the current output has a newer template/file used # (b) Check if the stable version has a file/template that was deleted $synced = !$srev->findPendingTemplateChanges() && !$srev->findPendingFileChanges('noForeign'); # Save to cache. This will be updated whenever the page is touched. $data = FlaggedRevs::makeMemcObj($synced ? "true" : "false"); $wgMemc->set($key, $data, $wgParserCacheExpireTime); return $synced; }
public static function overrideRedirect(Title $title, WebRequest $request, &$ignoreRedirect, &$target, Article &$article) { global $wgMemc, $wgParserCacheExpireTime; $fa = FlaggableWikiPage::getTitleInstance($title); // on $wgTitle if (!$fa->isReviewable()) { return true; // nothing to do } # Viewing an old reviewed version... if ($request->getVal('stableid')) { $ignoreRedirect = true; // don't redirect (same as ?oldid=x) return true; } $srev = $fa->getStableRev(); $view = FlaggablePageView::singleton(); # Check if we are viewing an unsynced stable version... if ($srev && $view->showingStable() && $srev->getRevId() != $article->getLatest()) { # Check the stable redirect properties from the cache... $key = wfMemcKey('flaggedrevs', 'overrideRedirect', $article->getId()); $tuple = FlaggedRevs::getMemcValue($wgMemc->get($key), $article); if (is_array($tuple)) { // cache hit list($ignoreRedirect, $target) = $tuple; } else { // cache miss; fetch the stable rev text... $text = $srev->getRevText(); $redirect = $fa->getRedirectURL(Title::newFromRedirectRecurse($text)); if ($redirect) { $target = $redirect; // use stable redirect } else { $ignoreRedirect = true; // make MW skip redirection } $data = FlaggedRevs::makeMemcObj(array($ignoreRedirect, $target)); $wgMemc->set($key, $data, $wgParserCacheExpireTime); // cache results } $clearEnvironment = (bool) $target; # Check if the we are viewing a draft or synced stable version... } else { # In both cases, we can just let MW use followRedirect() # on the draft as normal, avoiding any page text hits. $clearEnvironment = $article->isRedirect(); } # Environment (e.g. $wgTitle) will change in MediaWiki::initializeArticle if ($clearEnvironment) { $view->clear(); } return true; }