r66704 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r66703‎ | r66704 | r66705 >
Date:19:27, 20 May 2010
Author:aaron
Status:ok
Tags:
Comment:
Modified paths:
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedArticleView.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevision.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevs.class.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevs.hooks.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevs.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevsLogs.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevsXML.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/api/ApiReview.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/api/ApiStabilize.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/client/flaggedrevs.css (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/client/flaggedrevs.js (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/forms (added) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/ConfiguredPages.i18n.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/FlaggedRevs.alias.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/FlaggedRevs.i18n.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/OldReviewedPages.i18n.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/ProblemChanges.i18n.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/QualityOversight.i18n.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/ReviewedPages.i18n.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/ReviewedVersions.i18n.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/Stabilization.i18n.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/StablePages.i18n.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/UnreviewedPages.i18n.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/ValidationStatistics.i18n.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/maintenance/pruneRevData.inc (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/specialpages/OldReviewedPages_body.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/specialpages/ProblemChanges_body.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/specialpages/RevisionReview_body.php (modified) (history)
  • /branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/specialpages/Stabilization_body.php (modified) (history)

Diff [purge]

Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/forms/RevisionReviewForm.php
@@ -0,0 +1,702 @@
 2+<?php
 3+# (c) Aaron Schulz 2010 GPL
 4+if ( !defined( 'MEDIAWIKI' ) ) {
 5+ echo "FlaggedRevs extension\n";
 6+ exit( 1 );
 7+}
 8+/**
 9+ * Class containing revision review form business logic
 10+ * Note: edit tokens are the responsibility of caller
 11+ * Usage: (a) set ALL form params before doing anything else
 12+ * (b) call ready() when all params are set
 13+ * (c) call submit() as needed
 14+ */
 15+class RevisionReviewForm
 16+{
 17+ /* Form parameters which can be user given */
 18+ protected $page = null;
 19+ protected $rcid = 0;
 20+ protected $approve = false;
 21+ protected $unapprove = false;
 22+ protected $oldid = 0;
 23+ protected $templateParams = '';
 24+ protected $imageParams = '';
 25+ protected $fileVersion = '';
 26+ protected $validatedParams = '';
 27+ protected $notes = '';
 28+ protected $comment = '';
 29+ protected $dims = array();
 30+
 31+ protected $unapprovedTags = 0;
 32+ protected $oflags = array();
 33+ protected $inputLock = 0; # Disallow bad submissions
 34+
 35+ protected $skin = null;
 36+
 37+ public function __construct() {
 38+ global $wgUser;
 39+ $this->skin = $wgUser->getSkin();
 40+ foreach ( FlaggedRevs::getTags() as $tag ) {
 41+ $this->dims[$tag] = 0;
 42+ }
 43+ }
 44+
 45+ public function getPage() {
 46+ return $this->page;
 47+ }
 48+
 49+ public function setPage( Title $value ) {
 50+ $this->trySet( $this->page, $value );
 51+ }
 52+
 53+ public function getRCId() {
 54+ return $this->page;
 55+ }
 56+
 57+ public function setRCId( $value ) {
 58+ $this->trySet( $this->rcid, (int)$value );
 59+ }
 60+
 61+ public function setApprove( $value ) {
 62+ $this->trySet( $this->approve, $value );
 63+ }
 64+
 65+ public function setUnapprove( $value ) {
 66+ $this->trySet( $this->unapprove, $value );
 67+ }
 68+
 69+ public function getOldId() {
 70+ return $this->oldid;
 71+ }
 72+
 73+ public function setOldId( $value ) {
 74+ $this->trySet( $this->oldid, (int)$value );
 75+ }
 76+
 77+ public function getTemplateParams() {
 78+ return $this->templateParams;
 79+ }
 80+
 81+ public function setTemplateParams( $value ) {
 82+ $this->trySet( $this->templateParams, $value );
 83+ }
 84+
 85+ public function getFileParams() {
 86+ return $this->imageParams;
 87+ }
 88+
 89+ public function setFileParams( $value ) {
 90+ $this->trySet( $this->imageParams, $value );
 91+ }
 92+
 93+ public function getFileVersion() {
 94+ return $this->fileVersion;
 95+ }
 96+
 97+ public function setFileVersion( $value ) {
 98+ $this->trySet( $this->fileVersion, $value );
 99+ }
 100+
 101+ public function getValidatedParams() {
 102+ return $this->validatedParams;
 103+ }
 104+
 105+ public function setValidatedParams( $value ) {
 106+ $this->trySet( $this->validatedParams, $value );
 107+ }
 108+
 109+ public function getComment() {
 110+ return $this->comment;
 111+ }
 112+
 113+ public function setComment( $value ) {
 114+ $this->trySet( $this->comment, $value );
 115+ }
 116+
 117+ public function getNotes() {
 118+ return $this->notes;
 119+ }
 120+
 121+ public function setNotes( $value ) {
 122+ global $wgUser;
 123+ if ( !FlaggedRevs::allowComments() || !$wgUser->isAllowed( 'validate' ) ) {
 124+ $value = '';
 125+ }
 126+ $this->trySet( $this->notes, $value );
 127+ }
 128+
 129+ public function getDims() {
 130+ return $this->dims;
 131+ }
 132+
 133+ public function setDim( $tag, $value ) {
 134+ if ( !in_array( $tag, FlaggedRevs::getTags() ) ) {
 135+ throw new MWException( "FlaggedRevs tag $tag does not exist.\n" );
 136+ }
 137+ $this->trySet( $this->dims[$tag], (int)$value );
 138+ }
 139+
 140+ /**
 141+ * Set a member field to a value if the fields are unlocked
 142+ */
 143+ protected function trySet( &$field, $value ) {
 144+ if ( $this->inputLock ) {
 145+ throw new MWException( __CLASS__ . " fields cannot be set anymore.\n");
 146+ } else {
 147+ $field = $value; // still allowing input
 148+ }
 149+ }
 150+
 151+ /**
 152+ * Signal that inputs are starting
 153+ */
 154+ public function start() {
 155+ $this->inputLock = 0;
 156+ }
 157+
 158+ /**
 159+ * Signal that inputs are done and load old config
 160+ * @return mixed (true on success, error string on target failure)
 161+ */
 162+ public function ready() {
 163+ $this->inputLock = 1;
 164+ $status = $this->checkTarget();
 165+ if ( $status !== true ) {
 166+ return $status; // bad target
 167+ }
 168+ # Get the revision's current flags, if any
 169+ $this->oflags = FlaggedRevs::getRevisionTags( $this->page, $this->oldid );
 170+ return $status;
 171+ }
 172+
 173+ /*
 174+ * Check that the target page is valid
 175+ * @return mixed (true on success, error string on failure)
 176+ */
 177+ protected function checkTarget() {
 178+ if ( is_null( $this->page ) ) {
 179+ return 'review_page_invalid';
 180+ } elseif ( !$this->page->exists() ) {
 181+ return 'review_page_notexists';
 182+ }
 183+ $fa = FlaggedArticle::getTitleInstance( $this->page );
 184+ if ( !$fa->isReviewable() ) {
 185+ return 'review_page_unreviewable';
 186+ }
 187+ return true;
 188+ }
 189+
 190+ /*
 191+ * Verify and clean up parameters (e.g. from POST request).
 192+ * @return mixed (true on success, error string on failure)
 193+ */
 194+ protected function checkSettings() {
 195+ $status = $this->checkTarget();
 196+ if ( $status !== true ) {
 197+ return $status; // bad target
 198+ }
 199+ if ( !$this->oldid ) {
 200+ return 'review_no_oldid';
 201+ }
 202+ # Check that this is an approval or de-approval
 203+ if ( $this->isApproval() === null ) {
 204+ return 'review_param_missing'; // user didn't say
 205+ }
 206+ # Fill in implicit tag data for binary flag case
 207+ if ( $iDims = $this->implicitDims() ) {
 208+ $this->dims = $iDims;
 209+ } else {
 210+ foreach ( FlaggedRevs::getDimensions() as $tag => $levels ) {
 211+ if ( $this->dims[$tag] === 0 ) {
 212+ $this->unapprovedTags++;
 213+ }
 214+ }
 215+ }
 216+ # We must at least rate each category as 1, the minimum
 217+ # Exception: we can rate ALL as unapproved to depreciate a revision
 218+ if ( $this->unapprovedTags
 219+ && $this->unapprovedTags < count( FlaggedRevs::getDimensions() ) )
 220+ {
 221+ return 'review_too_low';
 222+ }
 223+ # Special token to discourage fiddling...
 224+ $k = self::validationKey(
 225+ $this->templateParams, $this->imageParams, $this->fileVersion, $this->oldid );
 226+ if ( $this->validatedParams !== $k ) {
 227+ return 'review_bad_key';
 228+ }
 229+ # Check permissions and validate
 230+ # FIXME: invalid vs denied
 231+ if ( !FlaggedRevs::userCanSetFlags( $this->dims, $this->oflags ) ) {
 232+ return 'review_denied';
 233+ }
 234+ return true;
 235+ }
 236+
 237+ public function isAllowed() {
 238+ // Basic permission check
 239+ return ( $this->page
 240+ && $this->page->userCan( 'review' )
 241+ && $this->page->userCan( 'edit' )
 242+ );
 243+ }
 244+
 245+ // implicit dims for binary flag case
 246+ private function implicitDims() {
 247+ $tag = FlaggedRevs::binaryTagName();
 248+ if ( $tag ) {
 249+ if ( $this->approve ) {
 250+ return array( $tag => 1 );
 251+ } else if ( $this->unapprove ) {
 252+ return array( $tag => 0 );
 253+ }
 254+ }
 255+ return null;
 256+ }
 257+
 258+ public function isApproval() {
 259+ # If all values are set to zero, this has been unapproved
 260+ if ( FlaggedRevs::dimensionsEmpty() ) {
 261+ if ( $this->approve && !$this->unapprove ) {
 262+ return true; // no tags & approve param given
 263+ } elseif ( $this->unapprove && !$this->approve ) {
 264+ return false;
 265+ }
 266+ return null; // nothing valid asserted
 267+ } else {
 268+ foreach ( $this->dims as $quality => $value ) {
 269+ if ( $value ) return true;
 270+ }
 271+ return false;
 272+ }
 273+ }
 274+
 275+ /**
 276+ * Submit the form parameters for the page config to the DB.
 277+ *
 278+ * @return mixed (true on success, error string on failure)
 279+ */
 280+ public function submit() {
 281+ global $wgUser;
 282+ if ( !$this->inputLock ) {
 283+ throw new MWException( __CLASS__ . " input fields not set yet.\n");
 284+ }
 285+ $status = $this->checkSettings();
 286+ if ( $status !== true ) {
 287+ return $status; // cannot submit - broken params
 288+ }
 289+ # Double-check permissions
 290+ if ( !$this->isAllowed() ) {
 291+ return 'review_denied';
 292+ }
 293+ # We can only approve actual revisions...
 294+ if ( $this->isApproval() ) {
 295+ $rev = Revision::newFromTitle( $this->page, $this->oldid );
 296+ # Do not mess with archived/deleted revisions
 297+ if ( is_null( $rev ) || $rev->mDeleted ) {
 298+ return 'review_bad_oldid';
 299+ }
 300+ $status = $this->approveRevision( $rev );
 301+ # We can only unapprove approved revisions...
 302+ } else {
 303+ $frev = FlaggedRevision::newFromTitle( $this->page, $this->oldid );
 304+ # If we can't find this flagged rev, return to page???
 305+ if ( is_null( $frev ) ) {
 306+ return 'review_bad_oldid';
 307+ }
 308+ $status = $this->unapproveRevision( $frev );
 309+ }
 310+ # Watch page if set to do so
 311+ if ( $status === true ) {
 312+ if ( $wgUser->getOption( 'flaggedrevswatch' ) && !$this->page->userIsWatching() ) {
 313+ $wgUser->addWatch( $this->page );
 314+ }
 315+ }
 316+ return $status;
 317+ }
 318+
 319+ /**
 320+ * Adds or updates the flagged revision table for this page/id set
 321+ * @param Revision $rev
 322+ * @returns true on success, array of errors on failure
 323+ */
 324+ private function approveRevision( $rev ) {
 325+ global $wgUser, $wgMemc, $wgParser, $wgEnableParserCache;
 326+ wfProfileIn( __METHOD__ );
 327+
 328+ $article = new Article( $this->page );
 329+
 330+ $quality = 0;
 331+ if ( FlaggedRevs::isQuality( $this->dims ) ) {
 332+ $quality = FlaggedRevs::isPristine( $this->dims ) ? 2 : 1;
 333+ }
 334+ # Our flags
 335+ $flags = $this->dims;
 336+ # Some validation vars to make sure nothing changed during
 337+ $lastTempId = 0;
 338+ $lastImgTime = "0";
 339+ # Our template version pointers
 340+ $tmpset = $tmpParams = array();
 341+ $templateMap = explode( '#', trim( $this->templateParams ) );
 342+ foreach ( $templateMap as $template ) {
 343+ if ( !$template )
 344+ continue;
 345+
 346+ $m = explode( '|', $template, 2 );
 347+ if ( !isset( $m[0] ) || !isset( $m[1] ) || !$m[0] )
 348+ continue;
 349+
 350+ list( $prefixed_text, $rev_id ) = $m;
 351+
 352+ $tmp_title = Title::newFromText( $prefixed_text ); // Normalize this to be sure...
 353+ if ( is_null( $tmp_title ) )
 354+ continue; // Page must be valid!
 355+
 356+ if ( $rev_id > $lastTempId )
 357+ $lastTempId = $rev_id;
 358+
 359+ $tmpset[] = array(
 360+ 'ft_rev_id' => $rev->getId(),
 361+ 'ft_namespace' => $tmp_title->getNamespace(),
 362+ 'ft_title' => $tmp_title->getDBkey(),
 363+ 'ft_tmp_rev_id' => $rev_id
 364+ );
 365+ if ( !isset( $tmpParams[$tmp_title->getNamespace()] ) ) {
 366+ $tmpParams[$tmp_title->getNamespace()] = array();
 367+ }
 368+ $tmpParams[$tmp_title->getNamespace()][$tmp_title->getDBkey()] = $rev_id;
 369+ }
 370+ # Our image version pointers
 371+ $imgset = $imgParams = array();
 372+ $imageMap = explode( '#', trim( $this->imageParams ) );
 373+ foreach ( $imageMap as $image ) {
 374+ if ( !$image )
 375+ continue;
 376+ $m = explode( '|', $image, 3 );
 377+ # Expand our parameters ... <name>#<timestamp>#<key>
 378+ if ( !isset( $m[0] ) || !isset( $m[1] ) || !isset( $m[2] ) || !$m[0] )
 379+ continue;
 380+
 381+ list( $dbkey, $timestamp, $key ) = $m;
 382+
 383+ $img_title = Title::makeTitle( NS_IMAGE, $dbkey ); // Normalize
 384+ if ( is_null( $img_title ) )
 385+ continue; // Page must be valid!
 386+
 387+ if ( $timestamp > $lastImgTime )
 388+ $lastImgTime = $timestamp;
 389+
 390+ $imgset[] = array(
 391+ 'fi_rev_id' => $rev->getId(),
 392+ 'fi_name' => $img_title->getDBkey(),
 393+ 'fi_img_timestamp' => $timestamp,
 394+ 'fi_img_sha1' => $key
 395+ );
 396+ if ( !isset( $imgParams[$img_title->getDBkey()] ) ) {
 397+ $imgParams[$img_title->getDBkey()] = array();
 398+ }
 399+ $imgParams[$img_title->getDBkey()][$timestamp] = $key;
 400+ }
 401+ # If this is an image page, store corresponding file info
 402+ $fileData = array();
 403+ if ( $this->page->getNamespace() == NS_IMAGE && $this->fileVersion ) {
 404+ $data = explode( '#', $this->fileVersion, 2 );
 405+ if ( count( $data ) == 2 ) {
 406+ $fileData['name'] = $this->page->getDBkey();
 407+ $fileData['timestamp'] = $data[0];
 408+ $fileData['sha1'] = $data[1];
 409+ }
 410+ }
 411+
 412+ # Get current stable version ID (for logging)
 413+ $oldSv = FlaggedRevision::newFromStable( $this->page, FR_MASTER );
 414+ $oldSvId = $oldSv ? $oldSv->getRevId() : 0;
 415+
 416+ # Is this rev already flagged?
 417+ $flaggedOutput = false;
 418+ $oldfrev = FlaggedRevision::newFromTitle( $this->page, $rev->getId(), FR_MASTER );
 419+ if ( $oldfrev ) {
 420+ $flaggedOutput = FlaggedRevs::parseStableText( $article,
 421+ $oldfrev->getRevText(), $oldfrev->getRevId() );
 422+ }
 423+
 424+ # Be loose on templates that includes other files/templates dynamically.
 425+ # Strict checking breaks randomized images/metatemplates...(bug 14580)
 426+ global $wgUseCurrentTemplates, $wgUseCurrentImages;
 427+ $mustMatch = !( $wgUseCurrentTemplates && $wgUseCurrentImages );
 428+
 429+ # Set our versioning params cache
 430+ FlaggedRevs::setIncludeVersionCache( $rev->getId(), $tmpParams, $imgParams );
 431+ # Parse the text and check if all templates/files match up
 432+ $text = $rev->getText();
 433+ $stableOutput = FlaggedRevs::parseStableText( $article, $text, $rev->getId() );
 434+ $err =& $stableOutput->fr_includeErrors;
 435+ if ( $mustMatch ) { // if template/files must all be specified...
 436+ if ( !empty( $err )
 437+ || $stableOutput->fr_newestImageTime > $lastImgTime
 438+ || $stableOutput->fr_newestTemplateID > $lastTempId )
 439+ {
 440+ wfProfileOut( __METHOD__ );
 441+ return $err; // return templates/files with no version specified
 442+ }
 443+ }
 444+ # Clear our versioning params cache
 445+ FlaggedRevs::clearIncludeVersionCache( $rev->getId() );
 446+
 447+ # Is this a duplicate review?
 448+ if ( $oldfrev && $flaggedOutput ) {
 449+ $synced = true;
 450+ if ( $stableOutput->fr_newestImageTime != $flaggedOutput->fr_newestImageTime )
 451+ $synced = false;
 452+ elseif ( $stableOutput->fr_newestTemplateID != $flaggedOutput->fr_newestTemplateID )
 453+ $synced = false;
 454+ elseif ( $oldfrev->getTags() != $flags )
 455+ $synced = false;
 456+ elseif ( $oldfrev->getFileSha1() != @$fileData['sha1'] )
 457+ $synced = false;
 458+ elseif ( $oldfrev->getComment() != $this->notes )
 459+ $synced = false;
 460+ elseif ( $oldfrev->getQuality() != $quality )
 461+ $synced = false;
 462+ # Don't review if the same
 463+ if ( $synced ) {
 464+ wfProfileOut( __METHOD__ );
 465+ return true;
 466+ }
 467+ }
 468+
 469+ $dbw = wfGetDB( DB_MASTER );
 470+ # Our review entry
 471+ $flaggedRevision = new FlaggedRevision( array(
 472+ 'fr_rev_id' => $rev->getId(),
 473+ 'fr_page_id' => $rev->getPage(),
 474+ 'fr_user' => $wgUser->getId(),
 475+ 'fr_timestamp' => wfTimestampNow(),
 476+ 'fr_comment' => $this->notes,
 477+ 'fr_quality' => $quality,
 478+ 'fr_tags' => FlaggedRevision::flattenRevisionTags( $flags ),
 479+ 'fr_img_name' => $fileData ? $fileData['name'] : null,
 480+ 'fr_img_timestamp' => $fileData ? $fileData['timestamp'] : null,
 481+ 'fr_img_sha1' => $fileData ? $fileData['sha1'] : null
 482+ ) );
 483+
 484+ $dbw->begin();
 485+ $flaggedRevision->insertOn( $tmpset, $imgset );
 486+ # Avoid any lag issues
 487+ $this->page->resetArticleId( $rev->getPage() );
 488+ # Update recent changes
 489+ self::updateRecentChanges( $this->page, $rev->getId(), $this->rcid, true );
 490+ # Update the article review log
 491+ FlaggedRevsLogs::updateLog( $this->page, $this->dims, $this->oflags,
 492+ $this->comment, $this->oldid, $oldSvId, true );
 493+
 494+ # Update the links tables as the stable version may now be the default page.
 495+ # Try using the parser cache first since we didn't actually edit the current version.
 496+ $parserCache = ParserCache::singleton();
 497+ $poutput = $parserCache->get( $article, $wgUser );
 498+ if ( !$poutput
 499+ || !isset( $poutput->fr_newestTemplateID )
 500+ || !isset( $poutput->fr_newestImageTime ) )
 501+ {
 502+ $options = FlaggedRevs::makeParserOptions();
 503+ $poutput = $wgParser->parse( $article->getContent(), $article->mTitle, $options );
 504+ }
 505+ # Prepare for a link tracking update
 506+ $u = new LinksUpdate( $this->page, $poutput );
 507+ # If we know that this is now the new stable version
 508+ # (which it probably is), save it to the stable cache...
 509+ $sv = FlaggedRevision::newFromStable( $this->page, FR_MASTER/*consistent*/ );
 510+ if ( $sv && $sv->getRevId() == $rev->getId() ) {
 511+ global $wgParserCacheExpireTime;
 512+ $this->page->invalidateCache();
 513+ # Update stable cache with the revision we reviewed.
 514+ # Don't cache redirects; it would go unused and complicate things.
 515+ if ( !Title::newFromRedirect( $text ) ) {
 516+ FlaggedRevs::updatePageCache( $article, $wgUser, $stableOutput );
 517+ }
 518+ # We can set the sync cache key already
 519+ $includesSynced = true;
 520+ if ( $poutput->fr_newestImageTime > $stableOutput->fr_newestImageTime ) {
 521+ $includesSynced = false;
 522+ } elseif ( $poutput->fr_newestTemplateID > $stableOutput->fr_newestTemplateID ) {
 523+ $includesSynced = false;
 524+ }
 525+ $u->fr_stableRev = $sv; // no need to re-fetch this!
 526+ $u->fr_stableParserOut = $stableOutput; // no need to re-fetch this!
 527+ # We can set the sync cache key already.
 528+ $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $article->getId() );
 529+ $data = FlaggedRevs::makeMemcObj( $includesSynced ? "true" : "false" );
 530+ $wgMemc->set( $key, $data, $wgParserCacheExpireTime );
 531+ } else {
 532+ # Get the old stable cache
 533+ $stableOutput = FlaggedRevs::getPageCache( $article, $wgUser );
 534+ # Clear the cache...(for page histories)
 535+ $this->page->invalidateCache();
 536+ if ( $stableOutput !== false ) {
 537+ # Reset stable cache if it existed, since we know it is the same.
 538+ FlaggedRevs::updatePageCache( $article, $wgUser, $stableOutput );
 539+ }
 540+ }
 541+ # Update link tracking. This will trigger extraLinksUpdate()...
 542+ $u->doUpdate();
 543+
 544+ $dbw->commit();
 545+ # Purge cache/squids for this page and any page that uses it
 546+ Article::onArticleEdit( $this->page );
 547+
 548+ wfProfileOut( __METHOD__ );
 549+ return true;
 550+ }
 551+
 552+ /**
 553+ * @param FlaggedRevision $frev
 554+ * Removes flagged revision data for this page/id set
 555+ */
 556+ private function unapproveRevision( $frev ) {
 557+ global $wgUser, $wgParser, $wgMemc;
 558+ wfProfileIn( __METHOD__ );
 559+
 560+ $dbw = wfGetDB( DB_MASTER );
 561+ $dbw->begin();
 562+ # Delete from flaggedrevs table
 563+ $dbw->delete( 'flaggedrevs',
 564+ array( 'fr_page_id' => $frev->getPage(), 'fr_rev_id' => $frev->getRevId() ) );
 565+ # Wipe versioning params
 566+ $dbw->delete( 'flaggedtemplates', array( 'ft_rev_id' => $frev->getRevId() ) );
 567+ $dbw->delete( 'flaggedimages', array( 'fi_rev_id' => $frev->getRevId() ) );
 568+ # Update recent changes
 569+ self::updateRecentChanges( $this->page, $frev->getRevId(), false, false );
 570+
 571+ # Get current stable version ID (for logging)
 572+ $oldSv = FlaggedRevision::newFromStable( $this->page, FR_MASTER );
 573+ $oldSvId = $oldSv ? $oldSv->getRevId() : 0;
 574+
 575+ # Update the article review log
 576+ FlaggedRevsLogs::updateLog( $this->page, $this->dims, $this->oflags,
 577+ $this->comment, $this->oldid, $oldSvId, false );
 578+
 579+ $article = new Article( $this->page );
 580+ # Update the links tables as a new stable version
 581+ # may now be the default page.
 582+ $parserCache = ParserCache::singleton();
 583+ $poutput = $parserCache->get( $article, $wgUser );
 584+ if ( $poutput == false ) {
 585+ $text = $article->getContent();
 586+ $options = FlaggedRevs::makeParserOptions();
 587+ $poutput = $wgParser->parse( $text, $article->mTitle, $options );
 588+ }
 589+ $u = new LinksUpdate( $this->page, $poutput );
 590+ $u->doUpdate();
 591+
 592+ # Clear the cache...
 593+ $this->page->invalidateCache();
 594+ # Purge cache/squids for this page and any page that uses it
 595+ $dbw->commit();
 596+ Article::onArticleEdit( $article->getTitle() );
 597+
 598+ wfProfileOut( __METHOD__ );
 599+ return true;
 600+ }
 601+
 602+ /**
 603+ * Get a validation key from versioning metadata
 604+ * @param string $tmpP
 605+ * @param string $imgP
 606+ * @param string $imgV
 607+ * @param integer $rid rev ID
 608+ * @return string
 609+ */
 610+ public static function validationKey( $tmpP, $imgP, $imgV, $rid ) {
 611+ global $wgReviewCodes;
 612+ # Fall back to $wgSecretKey/$wgProxyKey
 613+ if ( empty( $wgReviewCodes ) ) {
 614+ global $wgSecretKey, $wgProxyKey;
 615+ $key = $wgSecretKey ? $wgSecretKey : $wgProxyKey;
 616+ $p = md5( $key . $imgP . $tmpP . $rid . $imgV );
 617+ } else {
 618+ $p = md5( $wgReviewCodes[0] . $imgP . $rid . $tmpP . $imgV . $wgReviewCodes[1] );
 619+ }
 620+ return $p;
 621+ }
 622+
 623+ public static function updateRecentChanges( $title, $revId, $rcId = false, $patrol = true ) {
 624+ wfProfileIn( __METHOD__ );
 625+ $revId = intval( $revId );
 626+ $dbw = wfGetDB( DB_MASTER );
 627+ # Olders edits be marked as patrolled now...
 628+ $dbw->update( 'recentchanges',
 629+ array( 'rc_patrolled' => $patrol ? 1 : 0 ),
 630+ array( 'rc_cur_id' => $title->getArticleId(),
 631+ $patrol ? "rc_this_oldid <= $revId" : "rc_this_oldid = $revId" ),
 632+ __METHOD__,
 633+ // Performance
 634+ array( 'USE INDEX' => 'rc_cur_id', 'LIMIT' => 50 )
 635+ );
 636+ # New page patrol may be enabled. If so, the rc_id may be the first
 637+ # edit and not this one. If it is different, mark it too.
 638+ if ( $rcId && $rcId != $revId ) {
 639+ $dbw->update( 'recentchanges',
 640+ array( 'rc_patrolled' => 1 ),
 641+ array( 'rc_id' => $rcId,
 642+ 'rc_type' => RC_NEW ),
 643+ __METHOD__
 644+ );
 645+ }
 646+ wfProfileOut( __METHOD__ );
 647+ }
 648+
 649+ ########## Common form elements ##########
 650+
 651+ public function approvalSuccessHTML( $showlinks = false ) {
 652+ global $wgUser;
 653+ # Show success message
 654+ $form = "<div class='plainlinks'>";
 655+ $form .= wfMsgExt( 'revreview-successful', 'parse',
 656+ $this->page->getPrefixedText(), $this->page->getPrefixedUrl() );
 657+ $form .= wfMsgExt( 'revreview-stable1', 'parse',
 658+ $this->page->getPrefixedUrl(), $this->getOldId() );
 659+ $form .= "</div>";
 660+ # Handy links to special pages
 661+ if ( $showlinks && $wgUser->isAllowed( 'unreviewedpages' ) ) {
 662+ $form .= $this->getSpecialLinks();
 663+ }
 664+ return $form;
 665+ }
 666+
 667+ public function deapprovalSuccessHTML( $showlinks = false ) {
 668+ global $wgUser;
 669+ # Show success message
 670+ $form = "<div class='plainlinks'>";
 671+ $form .= wfMsgExt( 'revreview-successful2', 'parse',
 672+ $this->page->getPrefixedText(), $this->page->getPrefixedUrl() );
 673+ $form .= wfMsgExt( 'revreview-stable2', 'parse',
 674+ $this->page->getPrefixedUrl(), $this->getOldId() );
 675+ $form .= "</div>";
 676+ # Handy links to special pages
 677+ if ( $showlinks && $wgUser->isAllowed( 'unreviewedpages' ) ) {
 678+ $form .= $this->getSpecialLinks();
 679+ }
 680+ return $form;
 681+ }
 682+
 683+ public function syncFailureHTML( array $status, $showlinks = false ) {
 684+ $form = wfMsgExt( 'revreview-changed', 'parse', $this->page->getPrefixedText() );
 685+ $form .= "<ul>";
 686+ foreach ( $status as $n => $text ) {
 687+ $form .= "<li><i>$text</i></li>\n";
 688+ }
 689+ $form .= "</ul>";
 690+ if ( $showlinks ) {
 691+ $form .= wfMsg( 'returnto', $this->skin->makeLinkObj( $this->page ) );
 692+ }
 693+ return $form;
 694+ }
 695+
 696+ private function getSpecialLinks() {
 697+ $s = '<p>' . wfMsg( 'returnto',
 698+ $this->skin->makeLinkObj( SpecialPage::getTitleFor( 'UnreviewedPages' ) ) ) . '</p>';
 699+ $s .= '<p>' . wfMsg( 'returnto',
 700+ $this->skin->makeLinkObj( SpecialPage::getTitleFor( 'OldReviewedPages' ) ) ) . '</p>';
 701+ return $s;
 702+ }
 703+}
Property changes on: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/forms/RevisionReviewForm.php
___________________________________________________________________
Added: svn:eol-style
1704 + native
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/forms/PageStabilityForm.php
@@ -0,0 +1,661 @@
 2+<?php
 3+# (c) Aaron Schulz 2010 GPL
 4+if ( !defined( 'MEDIAWIKI' ) ) {
 5+ echo "FlaggedRevs extension\n";
 6+ exit( 1 );
 7+}
 8+/**
 9+ * Class containing stability settings form business logic
 10+ * Note: edit tokens are the responsibility of caller
 11+ * Usage: (a) set ALL form params before doing anything else
 12+ * (b) call ready() when all params are set
 13+ * (c) call preloadSettings() or submit() as needed
 14+ */
 15+abstract class PageStabilityForm
 16+{
 17+ /* Form parameters which can be user given */
 18+ protected $page = false; # Target page obj
 19+ protected $watchThis = null; # Watch checkbox
 20+ protected $reviewThis = null; # Auto-review option...
 21+ protected $reason = ''; # Custom/extra reason
 22+ protected $reasonSelection = ''; # Reason dropdown key
 23+ protected $expiry = ''; # Custom expiry
 24+ protected $expirySelection = ''; # Expiry dropdown key
 25+ protected $override = -1; # Default version
 26+ protected $autoreview = ''; # Autoreview restrictions...
 27+
 28+ protected $oldConfig = array(); # Old page config
 29+ protected $oldExpiry = ''; # Old page config expiry (GMT)
 30+ protected $inputLock = 0; # Disallow bad submissions
 31+
 32+ protected $skin = null;
 33+
 34+ public function __construct() {
 35+ global $wgUser;
 36+ $this->skin = $wgUser->getSkin();
 37+ }
 38+
 39+ public function getPage() {
 40+ return $this->page;
 41+ }
 42+
 43+ public function setPage( Title $value ) {
 44+ $this->trySet( $this->page, $value );
 45+ }
 46+
 47+ public function getWatchThis() {
 48+ return $this->watchThis;
 49+ }
 50+
 51+ public function setWatchThis( $value ) {
 52+ $this->trySet( $this->watchThis, $value );
 53+ }
 54+
 55+ public function getReason() {
 56+ return $this->reason;
 57+ }
 58+
 59+ public function setReason( $value ) {
 60+ $this->trySet( $this->reason, $value );
 61+ }
 62+
 63+ public function getReasonSelection() {
 64+ return $this->reasonSelection;
 65+ }
 66+
 67+ public function setReasonSelection( $value ) {
 68+ $this->trySet( $this->reasonSelection, $value );
 69+ }
 70+
 71+ public function getExpiry() {
 72+ return $this->expiry;
 73+ }
 74+
 75+ public function setExpiry( $value ) {
 76+ $this->trySet( $this->expiry, $value );
 77+ }
 78+
 79+ public function getExpirySelection() {
 80+ return $this->expirySelection;
 81+ }
 82+
 83+ public function setExpirySelection( $value ) {
 84+ $this->trySet( $this->expirySelection, $value );
 85+ }
 86+
 87+ public function getAutoreview() {
 88+ return $this->autoreview;
 89+ }
 90+
 91+ public function setAutoreview( $value ) {
 92+ $this->trySet( $this->autoreview, $value );
 93+ }
 94+
 95+ /**
 96+ * Set a member field to a value if the fields are unlocked
 97+ */
 98+ protected function trySet( &$field, $value ) {
 99+ if ( $this->inputLock ) {
 100+ throw new MWException( __CLASS__ . " fields cannot be set anymore.\n");
 101+ } else {
 102+ $field = $value; // still allowing input
 103+ }
 104+ }
 105+
 106+ /**
 107+ * Signal that inputs are starting
 108+ */
 109+ public function start() {
 110+ $this->inputLock = 0;
 111+ }
 112+
 113+ /**
 114+ * Signal that inputs are done and load old config
 115+ * @return mixed (true on success, error string on target failure)
 116+ */
 117+ public function ready() {
 118+ $this->inputLock = 1;
 119+ $status = $this->checkTarget();
 120+ if ( $status !== true ) {
 121+ return $status; // bad target
 122+ }
 123+ $this->loadOldConfig(); // current settings from DB
 124+ return $status;
 125+ }
 126+
 127+ /*
 128+ * Preload existing page settings (e.g. from GET request).
 129+ * @return mixed (true on success, error string on failure)
 130+ */
 131+ public function preloadSettings() {
 132+ if ( !$this->inputLock ) {
 133+ throw new MWException( __CLASS__ . " input fields not set yet.\n");
 134+ }
 135+ $status = $this->checkTarget();
 136+ if ( $status !== true ) {
 137+ return $status; // bad target
 138+ }
 139+ return $this->reallyPreloadSettings(); // load the params...
 140+ }
 141+
 142+ /*
 143+ * @return mixed (true on success, error string on failure)
 144+ */
 145+ protected function reallyPreloadSettings() {
 146+ return true;
 147+ }
 148+
 149+ /*
 150+ * Verify and clean up parameters (e.g. from POST request).
 151+ * @return mixed (true on success, error string on failure)
 152+ */
 153+ protected function checkSettings() {
 154+ $status = $this->checkTarget();
 155+ if ( $status !== true ) {
 156+ return $status; // bad target
 157+ }
 158+ $status = $this->reallyCheckSettings(); // check other params...
 159+ return $status;
 160+ }
 161+
 162+ /*
 163+ * @return mixed (true on success, error string on failure)
 164+ */
 165+ protected function reallyCheckSettings() {
 166+ return true;
 167+ }
 168+
 169+ /*
 170+ * Check that the target page is valid
 171+ * @return mixed (true on success, error string on failure)
 172+ */
 173+ protected function checkTarget() {
 174+ if ( is_null( $this->page ) ) {
 175+ return 'stabilize_page_invalid';
 176+ } elseif ( !$this->page->exists() ) {
 177+ return 'stabilize_page_notexists';
 178+ } elseif ( !FlaggedRevs::inReviewNamespace( $this->page ) ) {
 179+ return 'stabilize_page_unreviewable';
 180+ }
 181+ return true;
 182+ }
 183+
 184+ protected function loadOldConfig() {
 185+ # Get the current page config and GMT expiry
 186+ $this->oldConfig = FlaggedRevs::getPageVisibilitySettings( $this->page, FR_MASTER );
 187+ $this->oldExpiry = $this->oldConfig['expiry'] === 'infinity'
 188+ ? 'infinite'
 189+ : wfTimestamp( TS_RFC2822, $this->oldConfig['expiry'] );
 190+ }
 191+
 192+ /*
 193+ * Gets the current config expiry in GMT (or 'infinite')
 194+ * @return string
 195+ */
 196+ public function getOldExpiryGMT() {
 197+ if ( !$this->inputLock ) {
 198+ throw new MWException( __CLASS__ . " input fields not set yet.\n");
 199+ }
 200+ return $this->oldExpiry;
 201+ }
 202+
 203+ /*
 204+ * Can the user change the settings for this page?
 205+ * Note: if the current autoreview restriction is too high for this user
 206+ * then this will return false. Useful for form selectors.
 207+ * @return bool
 208+ */
 209+ public function isAllowed() {
 210+ # Users who cannot edit or review the page cannot set this
 211+ return ( $this->page
 212+ && $this->page->userCan( 'stablesettings' )
 213+ && $this->page->userCan( 'edit' )
 214+ && $this->page->userCan( 'review' )
 215+ );
 216+ }
 217+
 218+ /**
 219+ * Submit the form parameters for the page config to the DB.
 220+ *
 221+ * @return mixed (true on success, error string on failure)
 222+ */
 223+ public function submit() {
 224+ global $wgUser;
 225+ if ( !$this->inputLock ) {
 226+ throw new MWException( __CLASS__ . " input fields not set yet.\n");
 227+ }
 228+ $status = $this->checkSettings();
 229+ if ( $status !== true ) {
 230+ return $status; // cannot submit - broken params
 231+ }
 232+ # Double-check permissions
 233+ if ( !$this->isAllowed() ) {
 234+ return 'stablize_denied';
 235+ }
 236+ # Are we are going back to site defaults?
 237+ $reset = $this->newConfigIsReset();
 238+ # Parse and cleanup the expiry time given...
 239+ if ( $reset || $this->expiry == 'infinite' || $this->expiry == 'indefinite' ) {
 240+ $this->expiry = Block::infinity(); // normalize to 'infinity'
 241+ } else {
 242+ # Convert GNU-style date, on error returns -1 for PHP <5.1 and false for PHP >=5.1
 243+ $this->expiry = strtotime( $this->expiry );
 244+ if ( $this->expiry < 0 || $this->expiry === false ) {
 245+ return 'stabilize_expiry_invalid';
 246+ }
 247+ # Convert date to MW timestamp format
 248+ $this->expiry = wfTimestamp( TS_MW, $this->expiry );
 249+ if ( $this->expiry < wfTimestampNow() ) {
 250+ return 'stabilize_expiry_old';
 251+ }
 252+ }
 253+ # Update the DB row with the new config...
 254+ $changed = $this->updateConfigRow( $reset );
 255+ # Log if this actually changed anything...
 256+ if ( $changed ) {
 257+ # Update logs and make a null edit
 258+ $nullRev = $this->updateLogsAndHistory( $reset );
 259+ # Null edit may have been autoreviewed already
 260+ $frev = FlaggedRevision::newFromTitle( $this->page, $nullRev->getId(), FR_MASTER );
 261+ # We may need to invalidate the page links after changing the stable version.
 262+ # Only do so if not already done, such as by an auto-review of the null edit.
 263+ $invalidate = !$frev;
 264+ # Check if this null edit is to be reviewed...
 265+ if ( !$frev && $this->reviewThis ) {
 266+ $flags = null;
 267+ $article = new Article( $this->page );
 268+ # Review this revision of the page...
 269+ $ok = FlaggedRevs::autoReviewEdit(
 270+ $article, $wgUser, $nullRev->getText(), $nullRev, $flags, true );
 271+ if( $ok ) {
 272+ FlaggedRevs::markRevisionPatrolled( $nullRev ); // reviewed -> patrolled
 273+ $invalidate = false; // links invalidated (with auto-reviewed)
 274+ }
 275+ }
 276+ # Update the links tables as the stable version may now be the default page...
 277+ if ( $invalidate ) {
 278+ FlaggedRevs::titleLinksUpdate( $this->page );
 279+ }
 280+ }
 281+ # Apply watchlist checkbox value (may be NULL)
 282+ $this->updateWatchlist();
 283+ # Take this opportunity to purge out expired configurations
 284+ FlaggedRevs::purgeExpiredConfigurations();
 285+ return true;
 286+ }
 287+
 288+ /*
 289+ * Do history & log updates:
 290+ * (a) Add a new stability log entry
 291+ * (b) Add a null edit like the log entry
 292+ * @return Revision
 293+ */
 294+ protected function updateLogsAndHistory( $reset ) {
 295+ global $wgContLang;
 296+ $article = new Article( $this->page );
 297+ $latest = $this->page->getLatestRevID( GAID_FOR_UPDATE );
 298+ # Config may have changed to allow stable versions.
 299+ # Refresh tracking to account for any hidden reviewed versions...
 300+ $frev = FlaggedRevision::newFromStable( $this->page, FR_MASTER );
 301+ if ( $frev ) {
 302+ FlaggedRevs::updateStableVersion( $article, $frev->getRevision(), $latest );
 303+ } else {
 304+ FlaggedRevs::clearTrackingRows( $article->getId() );
 305+ }
 306+ # Insert stability log entry...
 307+ $log = new LogPage( 'stable' );
 308+ if ( $reset ) {
 309+ $log->addEntry( 'reset', $this->page, $this->reason );
 310+ $type = "stable-logentry-reset";
 311+ $settings = ''; // no level, expiry info
 312+ } else {
 313+ $params = $this->getLogParams();
 314+ $action = ( $this->oldConfig === FlaggedRevs::getDefaultVisibilitySettings() )
 315+ ? 'config' // set a custom configuration
 316+ : 'modify'; // modified an existing custom configuration
 317+ $log->addEntry( $action, $this->page, $this->reason,
 318+ FlaggedRevsLogs::collapseParams( $params ) );
 319+ $type = "stable-logentry-config";
 320+ // Settings message in text form (e.g. [x=a,y=b,z])
 321+ $settings = FlaggedRevsLogs::stabilitySettings( $params, true /*content*/ );
 322+ }
 323+ # Build null-edit comment...<action: reason [settings] (expiry)>
 324+ $comment = $wgContLang->ucfirst(
 325+ wfMsgForContent( $type, $this->page->getPrefixedText() ) ); // action
 326+ if ( $this->reason != '' ) {
 327+ $comment .= wfMsgForContent( 'colon-separator' ) . $this->reason; // add reason
 328+ }
 329+ if ( $settings != '' ) {
 330+ $comment .= " {$settings}"; // add settings
 331+ }
 332+ # Insert a null revision...
 333+ $dbw = wfGetDB( DB_MASTER );
 334+ $nullRev = Revision::newNullRevision( $dbw, $article->getId(), $comment, true );
 335+ $nullRevId = $nullRev->insertOn( $dbw );
 336+ # Update page record and touch page
 337+ $article->updateRevisionOn( $dbw, $nullRev, $latest );
 338+ wfRunHooks( 'NewRevisionFromEditComplete', array( $article, $nullRev, $latest ) );
 339+ # Return null Revision object for autoreview check
 340+ return $nullRev;
 341+ }
 342+
 343+ /*
 344+ * Checks if new config is the same as the site default
 345+ * @return bool
 346+ */
 347+ protected function newConfigIsReset() {
 348+ return false;
 349+ }
 350+
 351+ /*
 352+ * Get assoc. array of log params
 353+ * @return array
 354+ */
 355+ protected function getLogParams() {
 356+ return array();
 357+ }
 358+
 359+ /*
 360+ * (a) Watch page if $watchThis is true
 361+ * (b) Unwatch if $watchThis is false
 362+ */
 363+ protected function updateWatchlist() {
 364+ global $wgUser;
 365+ # Apply watchlist checkbox value (may be NULL)
 366+ if ( $this->watchThis === true ) {
 367+ $wgUser->addWatch( $this->page );
 368+ } elseif ( $this->watchThis === false ) {
 369+ $wgUser->removeWatch( $this->page );
 370+ }
 371+ }
 372+
 373+ protected function loadExpiry() {
 374+ # Custom expiry takes precedence
 375+ if ( $this->expiry == '' ) {
 376+ $this->expiry = $this->expirySelection;
 377+ if ( $this->expiry == 'existing' ) {
 378+ $this->expiry = $this->oldExpiry;
 379+ }
 380+ }
 381+ }
 382+
 383+ protected function loadReason() {
 384+ # Custom reason takes precedence
 385+ if ( $this->reasonSelection != 'other' ) {
 386+ $comment = $this->reasonSelection; // start with dropdown reason
 387+ if ( $this->reason != '' ) {
 388+ # Append custom reason
 389+ $comment .= wfMsgForContent( 'colon-separator' ) . $this->reason;
 390+ }
 391+ } else {
 392+ $comment = $this->reason; // just use custom reason
 393+ }
 394+ $this->reason = $comment;
 395+ }
 396+
 397+ // Same JS used for expiry for either $wgFlaggedRevsProtection case
 398+ public static function addProtectionJS() {
 399+ global $wgOut;
 400+ $wgOut->addScript(
 401+ "<script type=\"text/javascript\">
 402+ function onFRChangeExpiryDropdown() {
 403+ document.getElementById('mwStabilizeExpiryOther').value = '';
 404+ }
 405+ function onFRChangeExpiryField() {
 406+ document.getElementById('mwStabilizeExpirySelection').value = 'othertime';
 407+ }
 408+ </script>"
 409+ );
 410+ }
 411+}
 412+
 413+// Assumes $wgFlaggedRevsProtection is off
 414+class PageStabilityGeneralForm extends PageStabilityForm {
 415+ /* Form parameters which can be user given */
 416+ public $select = -1; # Precedence
 417+
 418+ public function getReviewThis() {
 419+ return $this->reviewThis;
 420+ }
 421+
 422+ public function setReviewThis( $value ) {
 423+ $this->trySet( $this->reviewThis, $value );
 424+ }
 425+
 426+ public function getPrecedence() {
 427+ return $this->select;
 428+ }
 429+
 430+ public function setPrecedence( $value ) {
 431+ $this->trySet( $this->select, $value );
 432+ }
 433+
 434+ public function getOverride() {
 435+ return $this->override;
 436+ }
 437+
 438+ public function setOverride( $value ) {
 439+ $this->trySet( $this->override, $value );
 440+ }
 441+
 442+ protected function reallyPreloadSettings() {
 443+ $this->select = $this->oldConfig['select'];
 444+ $this->override = $this->oldConfig['override'];
 445+ $this->autoreview = $this->oldConfig['autoreview'];
 446+ $this->expiry = $this->oldExpiry;
 447+ $this->expirySelection = 'existing';
 448+ $this->watchThis = $this->page->userIsWatching();
 449+ return true;
 450+ }
 451+
 452+ protected function reallyCheckSettings() {
 453+ $this->loadReason();
 454+ $this->loadExpiry();
 455+ $this->override = $this->override ? 1 : 0; // default version settings is 0 or 1
 456+ if ( !FlaggedRevs::isValidPrecedence( $this->select ) ) {
 457+ return 'stabilize_invalid_precedence'; // invalid precedence value
 458+ }
 459+ // Check autoreview restriction setting
 460+ if ( $this->autoreview != '' // restriction other than 'none'
 461+ && !in_array( $this->autoreview, FlaggedRevs::getRestrictionLevels() ) )
 462+ {
 463+ return 'stabilize_invalid_autoreview'; // invalid value
 464+ }
 465+ if ( !FlaggedRevs::userCanSetAutoreviewLevel( $this->autoreview ) ) {
 466+ return 'stabilize_denied'; // invalid value
 467+ }
 468+ return true;
 469+ }
 470+
 471+ protected function getLogParams() {
 472+ return array(
 473+ 'override' => $this->override,
 474+ 'autoreview' => $this->autoreview,
 475+ 'expiry' => $this->expiry, // TS_MW/infinity
 476+ 'precedence' => $this->select
 477+ );
 478+ }
 479+
 480+ // Return current config array
 481+ public function getOldConfig() {
 482+ if ( !$this->inputLock ) {
 483+ throw new MWException( __CLASS__ . " input fields not set yet.\n");
 484+ }
 485+ return $this->oldConfig;
 486+ }
 487+
 488+ // returns whether row changed
 489+ protected function updateConfigRow( $reset ) {
 490+ $changed = false;
 491+ $dbw = wfGetDB( DB_MASTER );
 492+ # If setting to site default values and there is a row then erase it
 493+ if ( $reset ) {
 494+ $dbw->delete( 'flaggedpage_config',
 495+ array( 'fpc_page_id' => $this->page->getArticleID() ),
 496+ __METHOD__
 497+ );
 498+ $changed = ( $dbw->affectedRows() != 0 ); // did this do anything?
 499+ # Otherwise, add/replace row if we are not just setting it to the site default
 500+ } elseif ( !$reset ) {
 501+ $dbExpiry = Block::encodeExpiry( $this->expiry, $dbw );
 502+ # Get current config...
 503+ $oldRow = $dbw->selectRow( 'flaggedpage_config',
 504+ array( 'fpc_select', 'fpc_override', 'fpc_level', 'fpc_expiry' ),
 505+ array( 'fpc_page_id' => $this->page->getArticleID() ),
 506+ __METHOD__,
 507+ 'FOR UPDATE'
 508+ );
 509+ # Check if this is not the same config as the existing row (if any)
 510+ $changed = self::configIsDifferent( $oldRow,
 511+ $this->select, $this->override, $this->autoreview, $dbExpiry );
 512+ # If the new config is different, replace the old row...
 513+ if ( $changed ) {
 514+ $dbw->replace( 'flaggedpage_config',
 515+ array( 'PRIMARY' ),
 516+ array(
 517+ 'fpc_page_id' => $this->page->getArticleID(),
 518+ 'fpc_select' => (int)$this->select,
 519+ 'fpc_override' => (int)$this->override,
 520+ 'fpc_level' => $this->autoreview,
 521+ 'fpc_expiry' => $dbExpiry
 522+ ),
 523+ __METHOD__
 524+ );
 525+ }
 526+ }
 527+ return $changed;
 528+ }
 529+
 530+ protected function newConfigIsReset() {
 531+ return ( $this->select == FlaggedRevs::getPrecedence()
 532+ && $this->override == FlaggedRevs::isStableShownByDefault()
 533+ && $this->autoreview == '' );
 534+ }
 535+
 536+ // Checks if new config is different than the existing row
 537+ protected function configIsDifferent( $oldRow, $select, $override, $autoreview, $dbExpiry ) {
 538+ if( !$oldRow ) {
 539+ return true; // no previous config
 540+ }
 541+ return ( $oldRow->fpc_select != $select // ...precedence changed, or...
 542+ || $oldRow->fpc_override != $override // ...override changed, or...
 543+ || $oldRow->fpc_level != $autoreview // ...autoreview level changed, or...
 544+ || $oldRow->fpc_expiry != $dbExpiry // ...expiry changed
 545+ );
 546+ }
 547+}
 548+
 549+// Assumes $wgFlaggedRevsProtection is on
 550+class PageStabilityProtectForm extends PageStabilityForm {
 551+ protected function reallyPreloadSettings() {
 552+ $this->autoreview = $this->oldConfig['autoreview']; // protect level
 553+ $this->expiry = $this->oldExpiry;
 554+ $this->expirySelection = 'existing';
 555+ $this->watchThis = $this->page->userIsWatching();
 556+ return true;
 557+ }
 558+
 559+ protected function reallyCheckSettings() {
 560+ # WMF temp hack...protection limit quota
 561+ global $wgFlaggedRevsProtectQuota;
 562+ if ( isset( $wgFlaggedRevsProtectQuota ) // quota exists
 563+ && $this->autoreview != '' // and we are protecting
 564+ && FlaggedRevs::getProtectionLevel( $this->oldConfig ) == 'none' ) // and page is unprotected
 565+ {
 566+ $dbw = wfGetDB( DB_MASTER );
 567+ $count = $dbw->selectField( 'flaggedpage_config', 'COUNT(*)', '', __METHOD__ );
 568+ if ( $count >= $wgFlaggedRevsProtectQuota ) {
 569+ return 'stabilize_protect_quota';
 570+ }
 571+ }
 572+ $this->loadReason();
 573+ $this->loadExpiry();
 574+ # Autoreview only when protecting currently unprotected pages
 575+ $this->reviewThis = ( FlaggedRevs::getProtectionLevel( $this->oldConfig ) == 'none' );
 576+ # Autoreview restriction => use stable
 577+ # No autoreview restriction => site default
 578+ $this->override = ( $this->autoreview != '' )
 579+ ? 1 // edits require review before being published
 580+ : (int)FlaggedRevs::isStableShownByDefault(); // site default
 581+ # Check that settings are a valid protection level...
 582+ $newConfig = array(
 583+ 'override' => $this->override,
 584+ 'autoreview' => $this->autoreview
 585+ );
 586+ if ( FlaggedRevs::getProtectionLevel( $newConfig ) == 'invalid' ) {
 587+ return 'stabilize_invalid_level'; // double-check configuration
 588+ }
 589+ # Check autoreview restriction setting
 590+ if ( !FlaggedRevs::userCanSetAutoreviewLevel( $this->autoreview ) ) {
 591+ return 'stabilize_denied'; // invalid value
 592+ }
 593+ return true;
 594+ }
 595+
 596+ // Doesn't include 'precedence'; checked in FlaggedRevsLogs
 597+ protected function getLogParams() {
 598+ return array(
 599+ 'override' => $this->override, // in case of site changes
 600+ 'autoreview' => $this->autoreview,
 601+ 'expiry' => $this->expiry // TS_MW/infinity
 602+ );
 603+ }
 604+
 605+ protected function updateConfigRow( $reset ) {
 606+ $changed = false;
 607+ $dbw = wfGetDB( DB_MASTER );
 608+ # If setting to site default values and there is a row then erase it
 609+ if ( $reset ) {
 610+ $dbw->delete( 'flaggedpage_config',
 611+ array( 'fpc_page_id' => $this->page->getArticleID() ),
 612+ __METHOD__
 613+ );
 614+ $changed = ( $dbw->affectedRows() != 0 ); // did this do anything?
 615+ # Otherwise, add/replace row if we are not just setting it to the site default
 616+ } elseif ( !$reset ) {
 617+ $dbExpiry = Block::encodeExpiry( $this->expiry, $dbw );
 618+ # Get current config...
 619+ $oldRow = $dbw->selectRow( 'flaggedpage_config',
 620+ array( 'fpc_override', 'fpc_level', 'fpc_expiry' ),
 621+ array( 'fpc_page_id' => $this->page->getArticleID() ),
 622+ __METHOD__,
 623+ 'FOR UPDATE'
 624+ );
 625+ # Check if this is not the same config as the existing row (if any)
 626+ $changed = self::configIsDifferent( $oldRow,
 627+ $this->override, $this->autoreview, $dbExpiry );
 628+ # If the new config is different, replace the old row...
 629+ if ( $changed ) {
 630+ $dbw->replace( 'flaggedpage_config',
 631+ array( 'PRIMARY' ),
 632+ array(
 633+ 'fpc_page_id' => $this->page->getArticleID(),
 634+ 'fpc_select' => -1, // ignored
 635+ 'fpc_override' => (int)$this->override,
 636+ 'fpc_level' => $this->autoreview,
 637+ 'fpc_expiry' => $dbExpiry
 638+ ),
 639+ __METHOD__
 640+ );
 641+ }
 642+ }
 643+ return $changed;
 644+ }
 645+
 646+ protected function newConfigIsReset() {
 647+ # For protection config, just ignore the fpc_select column
 648+ return ( $this->autoreview == '' );
 649+ }
 650+
 651+ // Checks if new config is different than the existing row
 652+ protected function configIsDifferent( $oldRow, $override, $autoreview, $dbExpiry ) {
 653+ if ( !$oldRow ) {
 654+ return true; // no previous config
 655+ }
 656+ # For protection config, just ignore the fpc_select column
 657+ return ( $oldRow->fpc_override != $override // ...override changed, or...
 658+ || $oldRow->fpc_level != $autoreview // ...autoreview level changed, or...
 659+ || $oldRow->fpc_expiry != $dbExpiry // ...expiry changed
 660+ );
 661+ }
 662+}
\ No newline at end of file
Property changes on: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/forms/PageStabilityForm.php
___________________________________________________________________
Added: svn:eol-style
1663 + native
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevision.php
@@ -380,7 +380,7 @@
381381 * @returns bool
382382 */
383383 public function userCanSetFlags() {
384 - return RevisionReview::userCanSetFlags( $this->mTags );
 384+ return FlaggedRevs::userCanSetFlags( $this->mTags );
385385 }
386386
387387 /**
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevsXML.php
@@ -292,15 +292,14 @@
293293 $frev->getRevId(), $time, $revsSince );
294294 }
295295 # Make fancy box...
296 - $box = '<div class="flaggedrevs_short_basic">' . $shtml .
297 - '&nbsp;' . self::ratingArrow() . "</div>\n";
298 - $box .= '<div style="position: relative;">'; // for rel-absolute child div
 296+ $box = '<div class="flaggedrevs_short_basic">';
 297+ $box .= $shtml . self::ratingArrow();
 298+ $box .= "</div>\n";
 299+ $box .= '<div style="position:relative;">'; // for rel-absolute child div
299300 $box .= Xml::openElement( 'div',
300301 array(
301 - 'id' => 'mw-fr-revisionratings',
302 - 'class' => 'flaggedrevs_short_details',
303 - 'onMouseOver' => 'FlaggedRevs.showBoxDetails()',
304 - 'onMouseOut' => 'FlaggedRevs.hideBoxDetails()'
 302+ 'id' => 'mw-fr-revisiondetails',
 303+ 'class' => 'flaggedrevs_short_details',
305304 )
306305 );
307306 $box .= $html; // details text
@@ -311,7 +310,7 @@
312311 $box .= '<p>' . self::addTagRatings( $flags, true, $color ) . '</p>';
313312 }
314313 }
315 - $box .= Xml::closeElement( 'div' );
 314+ $box .= Xml::closeElement( 'div' ) . "\n";
316315 $box .= "</div>\n";
317316 return $box;
318317 }
@@ -325,7 +324,6 @@
326325 $img = '<img id="mw-fr-revisiontoggle" class="fr-toggle-arrow"';
327326 $img .= " src=\"{$encPath}/arrow-down.png\" style=\"display:none;\"";
328327 $img .= ' onMouseOver="FlaggedRevs.showBoxDetails()"';
329 - $img .= ' onMouseOut="FlaggedRevs.hideBoxDetails()"';
330328 $img .= ' title="' . wfMsgHtml( 'revreview-toggle-title' ) . '"';
331329 $img .= ' alt="' . wfMsgHtml( 'revreview-toggle-show' ) . '" />';
332330 return $img;
@@ -361,7 +359,7 @@
362360 public static function logToggle() {
363361 $toggle = '<a id="mw-fr-logtoggle" class="fr-toggle-text" style="display:none;"' .
364362 ' onclick="FlaggedRevs.toggleLog()" title="' .
365 - wfMsgHtml( 'revreview-log-toggle-show' ) . '" >' .
 363+ wfMsgHtml( 'revreview-log-toggle-title' ) . '" >' .
366364 wfMsgHtml( 'revreview-log-toggle-show' ) . '</a>';
367365 return wfMsgHtml( 'parentheses', $toggle );
368366 }
@@ -373,23 +371,22 @@
374372 public static function logDetailsToggle() {
375373 $toggle = '<a id="mw-fr-logtoggle" class="fr-toggle-text" style="display:none;"' .
376374 ' onclick="FlaggedRevs.toggleLogDetails()" title="' .
377 - wfMsgHtml( 'revreview-log-details-show' ) . '" >' .
 375+ wfMsgHtml( 'revreview-log-details-title' ) . '" >' .
378376 wfMsgHtml( 'revreview-log-details-show' ) . '</a>';
379377 return wfMsgHtml( 'parentheses', $toggle );
380378 }
381379
382380 /**
383381 * @param array $flags, selected flags
384 - * @param array $config, page config
385382 * @param bool $disabled, form disabled
386383 * @param bool $reviewed, rev already reviewed
387384 * @returns string
388385 * Generates a main tag inputs (checkboxes/radios/selects) for review form
389386 */
390 - public static function ratingInputs( $flags, $config, $disabled, $reviewed ) {
 387+ public static function ratingInputs( $flags, $disabled, $reviewed ) {
391388 $form = '';
392389 # Get all available tags for this page/user
393 - list( $labels, $minLevels ) = self::ratingFormTags( $flags, $config );
 390+ list( $labels, $minLevels ) = self::ratingFormTags( $flags );
394391 if ( $labels === false ) {
395392 $disabled = true; // a tag is unsettable
396393 }
@@ -464,13 +461,13 @@
465462 return $form;
466463 }
467464
468 - protected static function ratingFormTags( $selected, $config ) {
 465+ protected static function ratingFormTags( $selected ) {
469466 $labels = array();
470467 $minLevels = array();
471468 # Build up all levels available to user
472469 foreach ( FlaggedRevs::getDimensions() as $tag => $levels ) {
473470 if ( isset( $selected[$tag] ) &&
474 - !RevisionReview::userCan( $tag, $selected[$tag], $config ) )
 471+ !FlaggedRevs::userCanSetTag( $tag, $selected[$tag] ) )
475472 {
476473 return array( false, false ); // form will have to be disabled
477474 }
@@ -478,7 +475,7 @@
479476 $minLevels[$tag] = false; // first non-zero level number
480477 foreach ( $levels as $i => $msg ) {
481478 # Some levels may be restricted or not applicable...
482 - if ( !RevisionReview::userCan( $tag, $i, $config ) ) {
 479+ if ( !FlaggedRevs::userCanSetTag( $tag, $i ) ) {
483480 continue; // skip this level
484481 } else if ( $i > 0 && !$minLevels[$tag] ) {
485482 $minLevels[$tag] = $i; // first non-zero level number
@@ -632,7 +629,6 @@
633630 # Do we need to get inclusion IDs from parser output?
634631 $getPOut = ( $templateIDs && $imageSHA1Keys );
635632
636 - $config = $article->getVisibilitySettings();
637633 # Variable for sites with no flags, otherwise discarded
638634 $approve = $wgRequest->getBool( 'wpApprove' );
639635 # See if the version being displayed is flagged...
@@ -647,7 +643,7 @@
648644 $flags = $srev->getTags();
649645 # Check if user is allowed to renew the stable version.
650646 # If not, then get the flags for the new revision itself.
651 - if ( !RevisionReview::userCanSetFlags( $oldFlags ) ) {
 647+ if ( !FlaggedRevs::userCanSetFlags( $oldFlags ) ) {
652648 $flags = $oldFlags;
653649 }
654650 $reviewNotes = $srev->getComment();
@@ -682,7 +678,7 @@
683679
684680 # Disable form for unprivileged users
685681 $uneditable = !$article->getTitle()->quickUserCan( 'edit' );
686 - $disabled = !RevisionReview::userCanSetFlags( $flags ) || $uneditable;
 682+ $disabled = !FlaggedRevs::userCanSetFlags( $flags ) || $uneditable;
687683 if ( $disabled ) {
688684 $form .= Xml::openElement( 'div', array( 'class' => 'fr-rating-controls-disabled',
689685 'id' => 'fr-rating-controls-disabled' ) );
@@ -695,7 +691,7 @@
696692
697693 # Add main checkboxes/selects
698694 $form .= Xml::openElement( 'span', array( 'id' => 'mw-fr-ratingselects' ) );
699 - $form .= FlaggedRevsXML::ratingInputs( $flags, $config, $disabled, (bool)$frev );
 695+ $form .= FlaggedRevsXML::ratingInputs( $flags, $disabled, (bool)$frev );
700696 $form .= Xml::closeElement( 'span' );
701697 # Add review notes input
702698 if ( FlaggedRevs::allowComments() && $wgUser->isAllowed( 'validate' ) ) {
@@ -771,7 +767,7 @@
772768 # Pass this in if given; useful for new page patrol
773769 $form .= Xml::hidden( 'rcid', $wgRequest->getVal( 'rcid' ) ) . "\n";
774770 # Special token to discourage fiddling...
775 - $checkCode = RevisionReview::validationKey(
 771+ $checkCode = RevisionReviewForm::validationKey(
776772 $templateParams, $imageParams, $fileVersion, $id
777773 );
778774 $form .= Xml::hidden( 'validatedParams', $checkCode ) . "\n";
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/specialpages/OldReviewedPages_body.php
@@ -213,8 +213,9 @@
214214 'diff=cur&oldid='.intval($row->stable).'&diffonly=0' );
215215 # Show quality level if there are several
216216 if ( FlaggedRevs::qualityVersions() ) {
217 - $quality = $row->quality ?
218 - wfMsgHtml( 'revreview-lev-quality' ) : wfMsgHtml( 'revreview-lev-basic' );
 217+ $quality = $row->quality
 218+ ? wfMsgHtml( 'revreview-lev-quality' )
 219+ : wfMsgHtml( 'revreview-lev-basic' );
219220 $quality = " <b>[{$quality}]</b>";
220221 }
221222 # Is anybody watching?
@@ -253,33 +254,15 @@
254255 }
255256 $key = wfMemcKey( 'stableDiffs', 'underReview', $row->stable, $row->page_latest );
256257 # Show if a user is looking at this page
257 - if ( ( $val = $wgMemc->get( $key ) ) ) {
258 - $underReview = " <b class='fr-under-review'>" .
259 - wfMsgHtml( 'oldreviewedpages-viewing' ) . '</b>';
 258+ if ( $wgMemc->get( $key ) ) {
 259+ $underReview = ' <span class="fr-under-review">' .
 260+ wfMsgHtml( 'oldreviewedpages-viewing' ) . '</span>';
260261 }
261262
262263 return( "<li{$css}>{$link} ({$hist}) {$stxt} ({$review}) <i>{$age}</i>" .
263264 "{$quality}{$watching}{$underReview}</li>" );
264265 }
265266
266 - /**
267 - * Get the timestamp of the next revision
268 - *
269 - * @param integer $revision Revision ID. Get the revision that was after this one.
270 - * @param integer $page, page ID
271 - */
272 - protected function getNextRevisionTimestamp( $revision, $page ) {
273 - $dbr = wfGetDB( DB_SLAVE );
274 - return $dbr->selectField( 'revision', 'rev_timestamp',
275 - array(
276 - 'rev_page' => $page,
277 - 'rev_id > ' . intval( $revision )
278 - ),
279 - __METHOD__,
280 - array( 'ORDER BY' => 'rev_id' )
281 - );
282 - }
283 -
284267 protected static function getLineClass( $hours, $uw ) {
285268 if ( $uw == 0 )
286269 return 'fr-unreviewed-unwatched';
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/specialpages/ProblemChanges_body.php
@@ -173,19 +173,26 @@
174174
175175 public function formatRow( $row ) {
176176 global $wgLang, $wgUser, $wgMemc;
177 -
178 - $css = $stxt = $quality = $underReview = '';
179 - $title = Title::makeTitle( $row->page_namespace, $row->page_title );
 177+ $css = $quality = $tags = $underReview = '';
 178+
 179+ $title = Title::newFromRow( $row );
180180 $link = $this->skin->makeKnownLinkObj( $title );
181181 $review = $this->skin->makeKnownLinkObj( $title,
182182 wfMsg( 'oldreviewed-diff' ),
183 - 'diff=cur&oldid='.intval($row->stable).'&diffonly=0' );
 183+ 'diff=cur&oldid=' . intval($row->stable) . '&diffonly=0' );
184184 # Show quality level if there are several
185185 if ( FlaggedRevs::qualityVersions() ) {
186 - $quality = $row->quality ?
187 - wfMsgHtml( 'revreview-lev-quality' ) : wfMsgHtml( 'revreview-lev-basic' );
 186+ $quality = $row->quality
 187+ ? wfMsgHtml( 'revreview-lev-quality' )
 188+ : wfMsgHtml( 'revreview-lev-basic' );
188189 $quality = " <b>[{$quality}]</b>";
189190 }
 191+ # What are the tags?
 192+ $dbTags = self::getRevisionTags( $title->getArticleID(), $row->stable );
 193+ if ( $dbTags ) {
 194+ $tags = htmlspecialchars( implode( ', ', $dbTags ) );
 195+ $tags = ' <b>' . wfMsgHtml( 'parentheses', $tags ) . '</b>';
 196+ }
190197 # Is anybody watching?
191198 if ( !$this->including() && $wgUser->isAllowed( 'unreviewedpages' ) ) {
192199 $uw = UnreviewedPages::usersWatching( $title );
@@ -222,32 +229,34 @@
223230 }
224231 $key = wfMemcKey( 'stableDiffs', 'underReview', $row->stable, $row->page_latest );
225232 # Show if a user is looking at this page
226 - if ( ( $val = $wgMemc->get( $key ) ) ) {
227 - $underReview = " <b class='fr-under-review'>" .
228 - wfMsgHtml( 'oldreviewedpages-viewing' ) . '</b>';
 233+ if ( $wgMemc->get( $key ) ) {
 234+ $underReview = ' <span class="fr-under-review">' .
 235+ wfMsgHtml( 'oldreviewedpages-viewing' ) . '</span>';
229236 }
230237
231 - return( "<li{$css}>{$link} {$stxt} ({$review}) <i>{$age}</i>" .
232 - "{$quality}{$watching}{$underReview}</li>" );
 238+ return( "<li{$css}>{$link} ({$review}) <i>{$age}</i>" .
 239+ "{$quality}{$tags}{$watching}{$underReview}</li>" );
233240 }
234241
235242 /**
236 - * Get the timestamp of the next revision
237 - *
238 - * @param integer $revision Revision ID. Get the revision that was after this one.
239 - * @param integer $page, page ID
 243+ * Get the tags of the revisions of a page after a certain rev
 244+ * @param integer $pageId, page ID
 245+ * @param integer $revId, rev ID
240246 */
241 - protected function getNextRevisionTimestamp( $revision, $page ) {
 247+ protected static function getRevisionTags( $pageId, $revId ) {
 248+ $tags = array();
242249 $dbr = wfGetDB( DB_SLAVE );
243 -
244 - return $dbr->selectField( 'revision', 'rev_timestamp',
245 - array(
246 - 'rev_page' => $page,
247 - 'rev_id > ' . intval( $revision )
248 - ),
249 - __METHOD__,
250 - array( 'ORDER BY' => 'rev_id' )
 250+ $res = $dbr->select(
 251+ array( 'revision', 'change_tag' ),
 252+ 'DISTINCT(ct_tag)', // unique tags
 253+ array( 'rev_page' => $pageId, 'rev_id > ' . intval($revId),
 254+ 'rev_id = ct_rev_id' ),
 255+ __METHOD__
251256 );
 257+ foreach( $res as $row ) {
 258+ $tags[] = $row->ct_tag;
 259+ }
 260+ return $tags;
252261 }
253262
254263 protected static function getLineClass( $hours, $uw ) {
@@ -293,7 +302,8 @@
294303 $conds = $this->mConds;
295304 $tables = array( 'revision', 'change_tag', 'page' );
296305 $fields = array( 'page_namespace' , 'page_title', 'page_latest' );
297 - $ctIndex = $wgOldChangeTagsIndex ? 'ct_rev_id' : 'change_tag_rev_tag';
 306+ $ctIndex = $wgOldChangeTagsIndex ?
 307+ 'ct_rev_id' : 'change_tag_rev_tag';
298308 # Show outdated "stable" pages
299309 if ( $this->level < 0 ) {
300310 $fields[] = 'fp_stable AS stable';
@@ -308,7 +318,8 @@
309319 $conds['ct_tag'] = $this->tag;
310320 }
311321 $conds[] = 'page_id = fp_page_id';
312 - $useIndex = array( 'flaggedpages' => 'fp_pending_since', 'change_tag' => $ctIndex );
 322+ $useIndex = array(
 323+ 'flaggedpages' => 'fp_pending_since', 'change_tag' => $ctIndex );
313324 # Filter by category
314325 if ( $this->category != '' ) {
315326 array_unshift( $tables, 'categorylinks' ); // order matters
@@ -331,8 +342,8 @@
332343 $conds[] = 'rev_id > fpp_rev_id';
333344 $conds[] = 'rev_id = ct_rev_id';
334345 $conds['ct_tag'] = $this->tag;
335 - $useIndex = array( 'flaggedpage_pending' => 'fpp_quality_pending',
336 - 'change_tag' => $ctIndex );
 346+ $useIndex = array(
 347+ 'flaggedpage_pending' => 'fpp_quality_pending', 'change_tag' => $ctIndex );
337348 # Filter by review level
338349 $conds['fpp_quality'] = $this->level;
339350 # Filter by category
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/specialpages/Stabilization_body.php
@@ -4,25 +4,30 @@
55 exit( 1 );
66 }
77
 8+// Assumes $wgFlaggedRevsProtection is off
89 class Stabilization extends UnlistedSpecialPage
910 {
 11+ protected $form = null;
 12+ protected $skin;
 13+
1014 public function __construct() {
 15+ global $wgUser;
1116 parent::__construct( 'Stabilization', 'stablesettings' );
 17+ $this->skin = $wgUser->getSkin();
1218 }
1319
1420 public function execute( $par ) {
1521 global $wgRequest, $wgUser, $wgOut;
1622 # Check user token
17 - $confirm = $wgRequest->wasPosted() &&
18 - $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );
19 - # Allow unprivileged users to at least view the settings
20 - $this->isAllowed = $wgUser->isAllowed( 'stablesettings' );
 23+ $confirmed = false;
2124 # Let anyone view, but not submit...
2225 if ( $wgRequest->wasPosted() ) {
23 - if ( $wgUser->isBlocked( !$confirm ) ) {
 26+ # Check user token
 27+ $confirmed = $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );
 28+ if ( $wgUser->isBlocked( !$confirmed ) ) {
2429 $wgOut->blockedPage();
2530 return;
26 - } elseif ( !$this->isAllowed ) {
 31+ } elseif ( !$wgUser->isAllowed( 'stablesettings' ) ) {
2732 $wgOut->permissionRequired( 'stablesettings' );
2833 return;
2934 } elseif ( wfReadOnly() ) {
@@ -32,216 +37,95 @@
3338 }
3439 # Set page title
3540 $this->setHeaders();
36 -
37 - $this->skin = $wgUser->getSkin();
38 - # Our target page
39 - $this->target = $wgRequest->getVal( 'page', $par );
 41+
 42+ $this->form = new PageStabilityGeneralForm();
 43+ $form = $this->form; // convenience
 44+ # Target page
 45+ $title = Title::newFromURL( $wgRequest->getVal( 'page', $par ) );
 46+ if ( !$title ) {
 47+ $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
 48+ return;
 49+ }
 50+ $form->setPage( $title );
4051 # Watch checkbox
41 - $this->watchThis = (bool)$wgRequest->getCheck( 'wpWatchthis' );
 52+ $form->setWatchThis( (bool)$wgRequest->getCheck( 'wpWatchthis' ) );
 53+ # Get auto-review option...
 54+ $form->setReviewThis( $wgRequest->getBool( 'wpReviewthis', true ) );
4255 # Reason
43 - $this->reason = $wgRequest->getText( 'wpReason' );
44 - $this->reasonSelection = $wgRequest->getVal( 'wpReasonSelection' );
 56+ $form->setReason( $wgRequest->getText( 'wpReason' ) );
 57+ $form->setReasonSelection( $wgRequest->getVal( 'wpReasonSelection' ) );
4558 # Expiry
46 - $this->expiry = $wgRequest->getText( 'mwStabilize-expiry' );
47 - $this->expirySelection = $wgRequest->getVal( 'wpExpirySelection' );
 59+ $form->setExpiry( $wgRequest->getText( 'mwStabilize-expiry' ) );
 60+ $form->setExpirySelection( $wgRequest->getVal( 'wpExpirySelection' ) );
4861 # Precedence
49 - $this->select = $wgRequest->getInt( 'wpStableconfig-select' );
50 - $this->override = (int)$wgRequest->getBool( 'wpStableconfig-override' );
 62+ $form->setPrecedence( $wgRequest->getInt( 'wpStableconfig-select' ) );
 63+ $form->setOverride( (int)$wgRequest->getBool( 'wpStableconfig-override' ) );
5164 # Get autoreview restrictions...
52 - $this->autoreview = $wgRequest->getVal( 'mwProtect-level-autoreview' );
53 - # Get auto-review option...
54 - $this->reviewThis = $wgRequest->getBool( 'wpReviewthis', true );
55 - $this->wasPosted = $wgRequest->wasPosted();
 65+ $form->setAutoreview( $wgRequest->getVal( 'mwProtect-level-autoreview' ) );
5666
57 - # Fill in & validate some parameters
58 - $isValid = $this->handleParams();
59 -
60 - # We need a page...
61 - if ( is_null( $this->page ) ) {
62 - $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
63 - return;
64 - } elseif ( !$this->page->exists() ) {
 67+ $status = $form->ready(); // params all set
 68+ if ( $status === 'stabilize_page_notexists' ) {
6569 $wgOut->addWikiText(
66 - wfMsg( 'stabilization-notexists', $this->page->getPrefixedText() ) );
 70+ wfMsg( 'stabilization-notexists', $title->getPrefixedText() ) );
6771 return;
68 - } elseif ( !FlaggedRevs::inReviewNamespace( $this->page ) ) {
 72+ } elseif ( $status === 'stabilize_page_unreviewable' ) {
6973 $wgOut->addWikiText(
70 - wfMsg( 'stabilization-notcontent', $this->page->getPrefixedText() ) );
 74+ wfMsg( 'stabilization-notcontent', $title->getPrefixedText() ) );
7175 return;
7276 }
73 - # Users who cannot edit or review the page cannot set this
74 - if ( !$this->page->userCan( 'edit' ) || !$this->page->userCan( 'review' ) ) {
75 - $this->isAllowed = false;
76 - }
77 -
78 - # Disable some elements as needed
79 - $this->disabledAttrib = $this->isAllowed ?
80 - array() : array( 'disabled' => 'disabled' );
81 - # Show form or submit...
82 - if ( $this->isAllowed && $isValid && $confirm ) {
83 - $status = $this->submit();
 77+ # Form POST request...
 78+ if ( $confirmed && $form->isAllowed() ) {
 79+ $status = $form->submit();
8480 if ( $status === true ) {
85 - $wgOut->redirect( $this->page->getFullUrl() );
 81+ $wgOut->redirect( $title->getFullUrl() );
8682 } else {
87 - $this->showSettings( wfMsg( $status ) );
 83+ $this->showForm( wfMsg( $status ) );
8884 }
 85+ # Form GET request...
8986 } else {
90 - $this->showSettings();
 87+ $form->preloadSettings();
 88+ $this->showForm();
9189 }
9290 }
9391
94 - /**
95 - * Verify and clean up parameters and preload data from DB.
96 - * Note: if false is returned items may not all be set.
97 - * TODO: return error keywords?
98 - * @return bool success
99 - */
100 - public function handleParams() {
101 - $this->page = Title::newFromURL( $this->target );
102 - if ( is_null( $this->page ) ) {
103 - return false; // page title is invalid
104 - }
105 - # Get the current page config and GMT expiry
106 - $this->config = FlaggedRevs::getPageVisibilitySettings( $this->page, FR_MASTER );
107 - $this->oldExpiry = $this->config['expiry'] === 'infinity'
108 - ? 'infinite'
109 - : wfTimestamp( TS_RFC2822, $this->config['expiry'] );
110 - # Handle views (GET)
111 - if ( !$this->wasPosted ) {
112 - # Fill in existing settings
113 - $this->preloadSettings( $this->config );
114 - # Handle submission data (POST)
115 - } else {
116 - $this->loadReason();
117 - $this->loadExpiry();
118 - // Protection level case...
119 - if ( FlaggedRevs::useProtectionLevels() ) {
120 - # Autoreview restriction => use stable
121 - # No autoreview restriction => site default
122 - $this->override = ( $this->autoreview != '' )
123 - ? 1 // edits require review before being published
124 - : (int)FlaggedRevs::isStableShownByDefault();
125 - # Leave the selection precedence to the site default
126 - $this->select = FlaggedRevs::getPrecedence();
127 - # Autoreview only when protecting currently unprotected pages
128 - $this->reviewThis = ( FlaggedRevs::getProtectionLevel( $this->config ) == 'none' );
129 - # Check that settings are a valid protection level...
130 - $newConfig = array(
131 - 'override' => $this->override,
132 - 'autoreview' => $this->autoreview
133 - );
134 - if ( FlaggedRevs::getProtectionLevel( $newConfig ) == 'invalid' ) {
135 - return false; // this is not a valid configuration
136 - }
137 - // General case...
138 - } else {
139 - if ( $this->override !== 0 && $this->override !== 1 ) {
140 - return false; // default version settings is 0 or 1
141 - }
142 - if ( !FlaggedRevs::isValidPrecedence( $this->select ) ) {
143 - return false; // invalid precedence value
144 - }
145 - // Check autoreview restriction setting
146 - if ( !self::userCanSetAutoreviewLevel( $this->autoreview ) ) {
147 - return false; // invalid value
148 - }
149 - }
150 - }
151 - return true;
152 - }
153 -
154 - private function preloadSettings( $config ) {
155 - # Get visiblity settings...
156 - $this->select = $config['select'];
157 - $this->override = $config['override'];
158 - # Get autoreview restrictions...
159 - $this->autoreview = $config['autoreview'];
160 - }
161 -
162 - private function loadExpiry() {
163 - // Custom expiry takes precedence
164 - if ( $this->expiry == '' ) {
165 - $this->expiry = $this->expirySelection;
166 - if ( $this->expiry == 'existing' ) {
167 - $this->expiry = $this->oldExpiry;
168 - }
169 - }
170 - }
171 -
172 - private function loadReason() {
173 - // Custom reason takes precedence
174 - if ( $this->reasonSelection != 'other' ) {
175 - $comment = $this->reasonSelection; // start with dropdown reason
176 - if ( $this->reason != '' ) {
177 - // Append custom reason
178 - $comment .= wfMsgForContent( 'colon-separator' ) . $this->reason;
179 - }
180 - } else {
181 - $comment = $this->reason; // just use custom reason
182 - }
183 - $this->reason = $comment;
184 - }
185 -
186 - /**
187 - * Check if a user can set the autoreview restiction level to $right
188 - * @param string $right the level
189 - * @returns bool
190 - */
191 - public static function userCanSetAutoreviewLevel( $right ) {
192 - global $wgUser;
193 - if ( $right == '' ) {
194 - return true; // no restrictions (none)
195 - }
196 - if ( !in_array( $right, FlaggedRevs::getRestrictionLevels() ) ) {
197 - return false; // invalid restriction level
198 - }
199 - # Don't let them choose levels above their own rights
200 - if ( $right == 'sysop' ) {
201 - // special case, rewrite sysop to protect and editprotected
202 - if ( !$wgUser->isAllowed( 'protect' ) && !$wgUser->isAllowed( 'editprotected' ) ) {
203 - return false;
204 - }
205 - } else if ( !$wgUser->isAllowed( $right ) ) {
206 - return false;
207 - }
208 - return true;
209 - }
210 -
211 - protected function showSettings( $err = null ) {
 92+ public function showForm( $err = null ) {
21293 global $wgOut, $wgLang, $wgUser;
 94+ $form = $this->form; // convenience
 95+ $title = $this->form->getPage();
 96+ $oldConfig = $form->getOldConfig();
 97+
 98+ $s = ''; // form HTML string
21399 # Add any error messages
214100 if ( "" != $err ) {
215101 $wgOut->setSubtitle( wfMsgHtml( 'formerror' ) );
216102 $wgOut->addHTML( "<p class='error'>{$err}</p>\n" );
217103 }
218104 # Add header text
219 - if ( !$this->isAllowed ) {
220 - $form = wfMsgExt( 'stabilization-perm', array( 'parse' ),
221 - $this->page->getPrefixedText() );
 105+ if ( !$form->isAllowed() ) {
 106+ $s .= wfMsgExt( 'stabilization-perm', 'parse', $title->getPrefixedText() );
222107 } else {
223 - $form = wfMsgExt( 'stabilization-text', array( 'parse' ),
224 - $this->page->getPrefixedText() );
 108+ $s .= wfMsgExt( 'stabilization-text', 'parse', $title->getPrefixedText() );
225109 }
226110 # Borrow some protection messages for dropdowns
227111 $reasonDropDown = Xml::listDropDown( 'wpReasonSelection',
228112 wfMsgForContent( 'protect-dropdown' ),
229113 wfMsgForContent( 'protect-otherreason-op' ),
230 - $this->reasonSelection,
 114+ $form->getReasonSelection(),
231115 'mwStabilize-reason', 4
232116 );
233117 $scExpiryOptions = wfMsgForContent( 'protect-expiry-options' );
234 - $showProtectOptions = ( $scExpiryOptions !== '-' && $this->isAllowed );
 118+ $showProtectOptions = ( $scExpiryOptions !== '-' && $form->isAllowed() );
235119 # Add the current expiry as an option
236120 $expiryFormOptions = '';
237 - if ( $this->config['expiry'] && $this->config['expiry'] != 'infinity' ) {
238 - $timestamp = $wgLang->timeanddate( $this->config['expiry'] );
239 - $d = $wgLang->date( $this->config['expiry'] );
240 - $t = $wgLang->time( $this->config['expiry'] );
 121+ if ( $oldConfig['expiry'] && $oldConfig['expiry'] != 'infinity' ) {
 122+ $timestamp = $wgLang->timeanddate( $oldConfig['expiry'] );
 123+ $d = $wgLang->date( $oldConfig['expiry'] );
 124+ $t = $wgLang->time( $oldConfig['expiry'] );
241125 $expiryFormOptions .=
242126 Xml::option(
243127 wfMsg( 'protect-existing-expiry', $timestamp, $d, $t ),
244128 'existing',
245 - $this->config['expiry'] == 'existing'
 129+ $oldConfig['expiry'] == 'existing'
246130 ) . "\n";
247131 }
248132 $expiryFormOptions .= Xml::option( wfMsg( 'protect-othertime-op' ), "othertime" ) . "\n";
@@ -254,41 +138,46 @@
255139 }
256140 $show = htmlspecialchars( $show );
257141 $value = htmlspecialchars( $value );
258 - $expiryFormOptions .= Xml::option( $show, $value,
259 - $this->config['expiry'] === $value ) . "\n";
 142+ $expiryFormOptions .= Xml::option( $show, $value, $oldConfig['expiry'] === $value );
 143+ $expiryFormOptions .= "\n";
260144 }
261145 # Add stable version override and selection options
262146 $special = SpecialPage::getTitleFor( 'Stabilization' );
263 - $form .= Xml::openElement( 'form', array( 'name' => 'stabilization',
264 - 'action' => $special->getLocalUrl(), 'method' => 'post' ) ) .
 147+ $s .= Xml::openElement( 'form', array( 'name' => 'stabilization',
 148+ 'action' => $special->getLocalUrl(), 'method' => 'post' ) );
 149+ $s .=
265150 Xml::fieldset( wfMsg( 'stabilization-def' ), false ) . "\n" .
266151 Xml::radioLabel( wfMsg( 'stabilization-def1' ), 'wpStableconfig-override', 1,
267 - 'default-stable', 1 == $this->override, $this->disabledAttrib ) . '<br />' . "\n" .
 152+ 'default-stable', 1 == $form->getOverride(), $this->disabledAttr() ) .
 153+ '<br />' . "\n" .
268154 Xml::radioLabel( wfMsg( 'stabilization-def2' ), 'wpStableconfig-override', 0,
269 - 'default-current', 0 == $this->override, $this->disabledAttrib ) . "\n" .
 155+ 'default-current', 0 == $form->getOverride(), $this->disabledAttr() ) . "\n" .
270156 Xml::closeElement( 'fieldset' ) .
271157
272158 Xml::fieldset( wfMsg( 'stabilization-select' ), false ) .
273159 Xml::radioLabel( wfMsg( 'stabilization-select3' ), 'wpStableconfig-select',
274 - FLAGGED_VIS_PRISTINE, 'stable-select3', FLAGGED_VIS_PRISTINE == $this->select,
275 - $this->disabledAttrib ) . '<br />' . "\n" .
 160+ FLAGGED_VIS_PRISTINE, 'stable-select3',
 161+ FLAGGED_VIS_PRISTINE == $form->getPrecedence(),
 162+ $this->disabledAttr() ) . '<br />' . "\n" .
276163 Xml::radioLabel( wfMsg( 'stabilization-select1' ), 'wpStableconfig-select',
277 - FLAGGED_VIS_QUALITY, 'stable-select1', FLAGGED_VIS_QUALITY == $this->select,
278 - $this->disabledAttrib ) . '<br />' . "\n" .
 164+ FLAGGED_VIS_QUALITY, 'stable-select1',
 165+ FLAGGED_VIS_QUALITY == $form->getPrecedence(),
 166+ $this->disabledAttr() ) . '<br />' . "\n" .
279167 Xml::radioLabel( wfMsg( 'stabilization-select2' ), 'wpStableconfig-select',
280 - FLAGGED_VIS_LATEST, 'stable-select2', FLAGGED_VIS_LATEST == $this->select,
281 - $this->disabledAttrib ) . '<br />' . "\n" .
 168+ FLAGGED_VIS_LATEST, 'stable-select2',
 169+ FLAGGED_VIS_LATEST == $form->getPrecedence(),
 170+ $this->disabledAttr() ) . '<br />' . "\n" .
282171 Xml::closeElement( 'fieldset' );
283172 # Add autoreview restriction select
284 - $form .= Xml::fieldset( wfMsg( 'stabilization-restrict' ), false ) .
285 - $this->buildSelector( $this->autoreview ) .
 173+ $s .= Xml::fieldset( wfMsg( 'stabilization-restrict' ), false ) .
 174+ $this->buildSelector( $form->getAutoreview() ) .
286175 Xml::closeElement( 'fieldset' ) .
287176
288177 Xml::fieldset( wfMsg( 'stabilization-leg' ), false ) .
289178 Xml::openElement( 'table' );
290179 # Add expiry dropdown
291 - if ( $showProtectOptions && $this->isAllowed ) {
292 - $form .= "
 180+ if ( $showProtectOptions && $form->isAllowed() ) {
 181+ $s .= "
293182 <tr>
294183 <td class='mw-label'>" .
295184 Xml::label( wfMsg( 'stabilization-expiry' ), 'mwStabilizeExpirySelection' ) .
@@ -299,34 +188,35 @@
300189 'id' => 'mwStabilizeExpirySelection',
301190 'name' => 'wpExpirySelection',
302191 'onchange' => 'onFRChangeExpiryDropdown()',
303 - ) + $this->disabledAttrib,
 192+ ) + $this->disabledAttr(),
304193 $expiryFormOptions ) .
305194 "</td>
306195 </tr>";
307196 }
308197 # Add custom expiry field
309198 $attribs = array( 'id' => "mwStabilizeExpiryOther",
310 - 'onkeyup' => 'onFRChangeExpiryField()' ) + $this->disabledAttrib;
311 - $form .= "
 199+ 'onkeyup' => 'onFRChangeExpiryField()' ) + $this->disabledAttr();
 200+ $formExpiry = $form->getExpiry() ?
 201+ $form->getExpiry() : $form->getOldExpiryGMT();
 202+ $s .= "
312203 <tr>
313204 <td class='mw-label'>" .
314205 Xml::label( wfMsg( 'stabilization-othertime' ), 'mwStabilizeExpiryOther' ) .
315206 '</td>
316207 <td class="mw-input">' .
317 - Xml::input( "mwStabilize-expiry", 50,
318 - $this->expiry ? $this->expiry : $this->oldExpiry, $attribs ) .
 208+ Xml::input( "mwStabilize-expiry", 50, $formExpiry, $attribs ) .
319209 '</td>
320210 </tr>';
321211 # Add comment input and submit button
322 - if ( $this->isAllowed ) {
 212+ if ( $form->isAllowed() ) {
323213 $watchLabel = wfMsgExt( 'watchthis', array( 'parseinline' ) );
324214 $watchAttribs = array( 'accesskey' => wfMsg( 'accesskey-watch' ),
325215 'id' => 'wpWatchthis' );
326216 $watchChecked = ( $wgUser->getOption( 'watchdefault' )
327 - || $this->page->userIsWatching() );
 217+ || $title->userIsWatching() );
328218 $reviewLabel = wfMsgExt( 'stabilization-review', array( 'parseinline' ) );
329219
330 - $form .= ' <tr>
 220+ $s .= ' <tr>
331221 <td class="mw-label">' .
332222 xml::label( wfMsg( 'stabilization-comment' ), 'wpReasonSelection' ) .
333223 '</td>
@@ -339,13 +229,13 @@
340230 Xml::label( wfMsg( 'stabilization-otherreason' ), 'wpReason' ) .
341231 '</td>
342232 <td class="mw-input">' .
343 - Xml::input( 'wpReason', 70, $this->reason, array( 'id' => 'wpReason' ) ) .
 233+ Xml::input( 'wpReason', 70, $form->getReason(), array( 'id' => 'wpReason' ) ) .
344234 '</td>
345235 </tr>
346236 <tr>
347237 <td></td>
348238 <td class="mw-input">' .
349 - Xml::check( 'wpReviewthis', $this->reviewThis,
 239+ Xml::check( 'wpReviewthis', $form->getReviewThis(),
350240 array( 'id' => 'wpReviewthis' ) ) .
351241 "<label for='wpReviewthis'>{$reviewLabel}</label>" .
352242 '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' .
@@ -361,46 +251,33 @@
362252 '</td>
363253 </tr>' . Xml::closeElement( 'table' ) .
364254 Xml::hidden( 'title', $this->getTitle()->getPrefixedDBKey() ) .
365 - Xml::hidden( 'page', $this->page->getPrefixedText() ) .
 255+ Xml::hidden( 'page', $title->getPrefixedText() ) .
366256 Xml::hidden( 'wpEditToken', $wgUser->editToken() );
367257 } else {
368 - $form .= Xml::closeElement( 'table' );
 258+ $s .= Xml::closeElement( 'table' );
369259 }
370 - $form .= Xml::closeElement( 'fieldset' ) . Xml::closeElement( 'form' );
 260+ $s .= Xml::closeElement( 'fieldset' ) . Xml::closeElement( 'form' );
371261
372 - $wgOut->addHTML( $form );
 262+ $wgOut->addHTML( $s );
373263
374264 $wgOut->addHTML( Xml::element( 'h2', null,
375265 htmlspecialchars( LogPage::logName( 'stable' ) ) ) );
376 - LogEventsList::showLogExtract( $wgOut, 'stable', $this->page->getPrefixedText() );
 266+ LogEventsList::showLogExtract( $wgOut, 'stable', $title->getPrefixedText() );
377267
378 - # Add some script for expiry dropdowns
379 - self::addProtectionJS();
 268+ # Add some javascript for expiry dropdowns
 269+ PageStabilityForm::addProtectionJS();
380270 }
381271
382 - public static function addProtectionJS() {
383 - global $wgOut;
384 - $wgOut->addScript(
385 - "<script type=\"text/javascript\">
386 - function onFRChangeExpiryDropdown() {
387 - document.getElementById('mwStabilizeExpiryOther').value = '';
388 - }
389 - function onFRChangeExpiryField() {
390 - document.getElementById('mwStabilizeExpirySelection').value = 'othertime';
391 - }
392 - </script>"
393 - );
394 - }
395 -
396272 protected function buildSelector( $selected ) {
397 - global $wgUser;
398273 $allowedLevels = array();
399274 $levels = FlaggedRevs::getRestrictionLevels();
400275 array_unshift( $levels, '' ); // Add a "none" level
401276 foreach ( $levels as $key ) {
402277 # Don't let them choose levels they can't set,
403278 # but *show* them all when the form is disabled.
404 - if ( $this->isAllowed && !self::userCanSetAutoreviewLevel( $key ) ) {
 279+ if ( $this->form->isAllowed()
 280+ && !FlaggedRevs::userCanSetAutoreviewLevel( $key ) )
 281+ {
405282 continue;
406283 }
407284 $allowedLevels[] = $key;
@@ -410,7 +287,7 @@
411288 'id' => $id,
412289 'name' => $id,
413290 'size' => count( $allowedLevels ),
414 - ) + $this->disabledAttrib;
 291+ ) + $this->disabledAttr();
415292
416293 $out = Xml::openElement( 'select', $attribs );
417294 foreach ( $allowedLevels as $key ) {
@@ -439,183 +316,10 @@
440317 }
441318 }
442319
443 - public function submit() {
444 - global $wgUser, $wgContLang;
445 - # Take this opportunity to purge out expired configurations
446 - FlaggedRevs::purgeExpiredConfigurations();
447 - # Are we are going back to site defaults?
448 - $reset = self::configIsReset( $this->select, $this->override, $this->autoreview );
449 - # Parse and cleanup the expiry time given...
450 - if ( $reset || $this->expiry == 'infinite' || $this->expiry == 'indefinite' ) {
451 - $this->expiry = Block::infinity(); // normalize to 'infinity'
452 - } else {
453 - # Convert GNU-style date, on error returns -1 for PHP <5.1 and false for PHP >=5.1
454 - $this->expiry = strtotime( $this->expiry );
455 - if ( $this->expiry < 0 || $this->expiry === false ) {
456 - return 'stabilize_expiry_invalid';
457 - }
458 - # Convert date to MW timestamp format
459 - $this->expiry = wfTimestamp( TS_MW, $this->expiry );
460 - if ( $this->expiry < wfTimestampNow() ) {
461 - return 'stabilize_expiry_old';
462 - }
463 - }
464 - # Update the DB row with the new config...
465 - $changed = $this->updateConfigRow( $reset );
466 - # Log if this actually changed anything...
467 - if ( $changed ) {
468 - $article = new Article( $this->page );
469 - $latest = $this->page->getLatestRevID( GAID_FOR_UPDATE );
470 - # Config may have changed to allow stable versions.
471 - # Refresh tracking to account for any hidden reviewed versions...
472 - $frev = FlaggedRevision::newFromStable( $this->page, FR_MASTER );
473 - if ( $frev ) {
474 - FlaggedRevs::updateStableVersion( $article, $frev->getRevision(), $latest );
475 - } else {
476 - FlaggedRevs::clearTrackingRows( $article->getId() );
477 - }
478 - # Insert stability log entry...
479 - $log = new LogPage( 'stable' );
480 - if ( $reset ) {
481 - $log->addEntry( 'reset', $this->page, $this->reason );
482 - $type = "stable-logentry-reset";
483 - $settings = ''; // no level, expiry info
484 - } else {
485 - $params = array(
486 - 'override' => $this->override,
487 - 'autoreview' => $this->autoreview,
488 - 'expiry' => $this->expiry // TS_MW/infinity
489 - );
490 - // Precedence unchanged by protection (stabilityLogLinks checks this)
491 - if( !FlaggedRevs::useProtectionLevels() ) {
492 - $params['precedence'] = $this->select;
493 - }
494 - $log->addEntry( 'config', $this->page, $this->reason,
495 - FlaggedRevsLogs::collapseParams( $params ) );
496 - $type = "stable-logentry-config";
497 - $settings = FlaggedRevsLogs::stabilitySettings( $params, true /*content*/ );
498 - }
499 - # Build null-edit comment...<action: reason [settings] (expiry)>
500 - $comment = $wgContLang->ucfirst(
501 - wfMsgForContent( $type, $this->page->getPrefixedText() ) ); // action
502 - if ( $this->reason != '' ) {
503 - $comment .= wfMsgForContent( 'colon-separator' ) . $this->reason; // add reason
504 - }
505 - if ( $settings != '' ) {
506 - $comment .= " {$settings}"; // add settings
507 - }
508 - # Insert a null revision...
509 - $dbw = wfGetDB( DB_MASTER );
510 - $nullRev = Revision::newNullRevision( $dbw, $article->getId(), $comment, true );
511 - $nullRevId = $nullRev->insertOn( $dbw );
512 - # Update page record and touch page
513 - $article->updateRevisionOn( $dbw, $nullRev, $latest );
514 - wfRunHooks( 'NewRevisionFromEditComplete',
515 - array( $article, $nullRev, $latest ) );
516 -
517 - # Null edit may have been autoreviewed already
518 - $frev = FlaggedRevision::newFromTitle( $this->page, $nullRevId, FR_MASTER );
519 - # We may need to invalidate the page links after changing the stable version.
520 - # Only do so if not already done, such as by an auto-review of the null edit.
521 - $invalidate = !$frev;
522 - # Check if this null edit is to be reviewed...
523 - if ( !$frev && $this->reviewThis ) {
524 - $flags = null;
525 - # Review this revision of the page...
526 - $ok = FlaggedRevs::autoReviewEdit(
527 - $article, $wgUser, $nullRev->getText(), $nullRev, $flags, true );
528 - if( $ok ) {
529 - FlaggedRevs::markRevisionPatrolled( $nullRev ); // reviewed -> patrolled
530 - $invalidate = false; // links invalidated (with auto-reviewed)
531 - }
532 - }
533 - # Update the links tables as the stable version may now be the default page...
534 - if ( $invalidate ) {
535 - FlaggedRevs::titleLinksUpdate( $this->page );
536 - }
537 - }
538 - # Apply watchlist checkbox value (may be NULL)
539 - if ( $this->watchThis === true ) {
540 - $wgUser->addWatch( $this->page );
541 - } else if ( $this->watchThis === false ) {
542 - $wgUser->removeWatch( $this->page );
543 - }
544 - return true;
 320+ // If the this form is disabled, then return the "disabled" attr array
 321+ protected function disabledAttr() {
 322+ return $this->form->isAllowed()
 323+ ? array()
 324+ : array( 'disabled' => 'disabled' );
545325 }
546 -
547 - protected function updateConfigRow( $reset ) {
548 - $changed = false;
549 - $dbw = wfGetDB( DB_MASTER );
550 - # If setting to site default values and there is a row then erase it
551 - if ( $reset ) {
552 - $dbw->delete( 'flaggedpage_config',
553 - array( 'fpc_page_id' => $this->page->getArticleID() ),
554 - __METHOD__
555 - );
556 - $changed = ( $dbw->affectedRows() != 0 ); // did this do anything?
557 - # Otherwise, add/replace row if we are not just setting it to the site default
558 - } elseif ( !$reset ) {
559 - $dbExpiry = Block::encodeExpiry( $this->expiry, $dbw );
560 - $precedence = FlaggedRevs::useProtectionLevels()
561 - ? -1 // site default; fpc_select "don't care"
562 - : $this->select;
563 - # Get current config...
564 - $oldRow = $dbw->selectRow( 'flaggedpage_config',
565 - array( 'fpc_select', 'fpc_override', 'fpc_level', 'fpc_expiry' ),
566 - array( 'fpc_page_id' => $this->page->getArticleID() ),
567 - __METHOD__,
568 - 'FOR UPDATE'
569 - );
570 - # Check if this is not the same config as the existing row (if any)
571 - $changed = self::configIsDifferent( $oldRow,
572 - $precedence, $this->override, $this->autoreview, $dbExpiry );
573 - # If the new config is different, replace the old row...
574 - if ( $changed ) {
575 - $dbw->replace( 'flaggedpage_config',
576 - array( 'PRIMARY' ),
577 - array(
578 - 'fpc_page_id' => $this->page->getArticleID(),
579 - 'fpc_select' => intval( $precedence ),
580 - 'fpc_override' => intval( $this->override ),
581 - 'fpc_level' => $this->autoreview,
582 - 'fpc_expiry' => $dbExpiry
583 - ),
584 - __METHOD__
585 - );
586 - }
587 - }
588 - return $changed;
589 - }
590 -
591 - // Checks if new config is the same as the site default
592 - protected function configIsReset( $select, $override, $autoreview ) {
593 - # For protection config, just ignore the fpc_select column
594 - if( FlaggedRevs::useProtectionLevels() ) {
595 - return ( $autoreview == '' );
596 - } else {
597 - return ( $select == FlaggedRevs::getPrecedence()
598 - && $override == FlaggedRevs::isStableShownByDefault()
599 - && $autoreview == '' );
600 - }
601 - }
602 -
603 - // Checks if new config is different than the existing row
604 - protected function configIsDifferent( $oldRow, $select, $override, $autoreview, $dbExpiry ) {
605 - if( !$oldRow ) {
606 - return true; // no previous config
607 - }
608 - # For protection config, just ignore the fpc_select column
609 - if( FlaggedRevs::useProtectionLevels() ) {
610 - return ( $oldRow->fpc_override != $override // ...override changed, or...
611 - || $oldRow->fpc_level != $autoreview // ...autoreview level changed, or...
612 - || $oldRow->fpc_expiry != $dbExpiry // ...expiry changed
613 - );
614 - } else {
615 - return ( $oldRow->fpc_select != $select // ...precedence changed, or...
616 - || $oldRow->fpc_override != $override // ...override changed, or...
617 - || $oldRow->fpc_level != $autoreview // ...autoreview level changed, or...
618 - || $oldRow->fpc_expiry != $dbExpiry // ...expiry changed
619 - );
620 - }
621 - }
622 -}
 326+}
\ No newline at end of file
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/specialpages/RevisionReview_body.php
@@ -8,34 +8,18 @@
99
1010 class RevisionReview extends UnlistedSpecialPage
1111 {
12 - // Initialize vars in case of broken AJAX input
13 - var $patrolonly = false;
14 - var $page = null;
15 - var $rcid = 0;
16 - var $approve = false;
17 - var $unapprove = false;
18 - var $oldid = 0;
19 - var $templateParams = '';
20 - var $imageParams = '';
21 - var $fileVersion = '';
22 - var $validatedParams = '';
23 - var $notes = '';
24 - var $comment = '';
25 - var $dims = array();
26 - var $unapprovedTags = 0;
27 -
 12+ private $form;
 13+ private $page;
 14+
2815 public function __construct() {
29 - global $wgUser;
3016 parent::__construct( 'RevisionReview', 'review' );
31 - $this->skin = $wgUser->getSkin();
3217 }
3318
3419 public function execute( $par ) {
3520 global $wgRequest, $wgUser, $wgOut;
36 - $confirm = $wgRequest->wasPosted()
37 - && $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );
 21+ $confirmed = $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );
3822 if ( $wgUser->isAllowed( 'review' ) ) {
39 - if ( $wgUser->isBlocked( !$confirm ) ) {
 23+ if ( $wgUser->isBlocked( !$confirmed ) ) {
4024 $wgOut->blockedPage();
4125 return;
4226 }
@@ -48,143 +32,114 @@
4933 return;
5034 }
5135 $this->setHeaders();
 36+
 37+ $this->form = new RevisionReviewForm();
 38+ $form = $this->form; // convenience
5239 # Our target page
5340 $this->page = Title::newFromURL( $wgRequest->getVal( 'target' ) );
54 - if ( is_null( $this->page ) ) {
 41+ if ( !$this->page ) {
5542 $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
5643 return;
5744 }
 45+ $form->setPage( $this->page );
5846 # Param for sites with binary flagging
59 - $this->approve = $wgRequest->getCheck( 'wpApprove' );
60 - $this->unapprove = $wgRequest->getCheck( 'wpUnapprove' );
61 - # Patrol the edit if requested...
62 - $this->markReviewed();
63 - }
64 -
65 - // implicit dims for binary flag case
66 - public function implicitDims() {
67 - $tag = FlaggedRevs::binaryTagName();
68 - if ( $tag ) {
69 - if ( $this->approve ) {
70 - return array( $tag => 1 );
71 - } else if ( $this->unapprove ) {
72 - return array( $tag => 0 );
73 - }
74 - }
75 - return null;
76 - }
77 -
78 - // non-JS submission code...
79 - private function markReviewed() {
80 - global $wgRequest, $wgOut, $wgUser;
81 - # Must be in reviewable namespace
82 - if ( !FlaggedRevs::inReviewNamespace( $this->page ) ) {
83 - $wgOut->addHTML( wfMsgExt( 'revreview-main', array( 'parse' ) ) );
84 - return;
85 - }
86 - # Get revision ID
87 - $this->oldid = $wgRequest->getIntOrNull( 'oldid' );
88 - if ( !$this->oldid ) {
89 - $wgOut->showErrorPage( 'internalerror', 'revreview-revnotfound' );
90 - return;
91 - }
92 - # Check if page is protected
93 - if ( !$this->page->quickUserCan( 'edit' ) ) {
94 - $wgOut->permissionRequired( 'badaccess-group0' );
95 - return;
96 - }
 47+ $form->setApprove( $wgRequest->getCheck( 'wpApprove' ) );
 48+ $form->setUnapprove( $wgRequest->getCheck( 'wpUnapprove' ) );
 49+ # Rev ID
 50+ $oldid = $wgRequest->getInt( 'oldid' );
 51+ $form->setOldId( $oldid );
9752 # Special parameter mapping
98 - $this->templateParams = $wgRequest->getVal( 'templateParams' );
99 - $this->imageParams = $wgRequest->getVal( 'imageParams' );
100 - $this->fileVersion = $wgRequest->getVal( 'fileVersion' );
101 - $this->validatedParams = $wgRequest->getVal( 'validatedParams' );
 53+ $form->setTemplateParams( $wgRequest->getVal( 'templateParams' ) );
 54+ $form->setFileParams( $wgRequest->getVal( 'imageParams' ) );
 55+ $form->setFileVersion( $wgRequest->getVal( 'fileVersion' ) );
10256 # Special token to discourage fiddling...
103 - $k = self::validationKey( $this->templateParams, $this->imageParams,
104 - $this->fileVersion, $this->oldid );
105 - if ( $this->validatedParams !== $k ) {
106 - $wgOut->permissionRequired( 'badaccess-group0' );
107 - return;
 57+ $form->setValidatedParams( $wgRequest->getVal( 'validatedParams' ) );
 58+ # Tag values
 59+ foreach ( FlaggedRevs::getDimensions() as $tag => $levels ) {
 60+ # This can be NULL if we uncheck a checkbox
 61+ $val = $wgRequest->getInt( "wp$tag" );
 62+ $form->setDim( $tag, $val );
10863 }
10964 # Log comment
110 - $this->comment = $wgRequest->getText( 'wpReason' );
 65+ $form->setComment( $wgRequest->getText( 'wpReason' ) );
11166 # Additional notes (displayed at bottom of page)
112 - $this->retrieveNotes( $wgRequest->getText( 'wpNotes' ) );
113 - # Get the revision's current flags, if any
114 - $this->oflags = FlaggedRevs::getRevisionTags( $this->page, $this->oldid );
115 - # Get our accuracy/quality dimensions
116 - $this->dims = array();
117 - $this->unapprovedTags = 0;
118 - # Fill in implicit tag data for binary flag case
119 - if ( $iDims = $this->implicitDims() ) {
120 - $this->dims = $iDims;
121 - } else {
122 - foreach ( FlaggedRevs::getDimensions() as $tag => $levels ) {
123 - $this->dims[$tag] = $wgRequest->getIntOrNull( "wp$tag" );
124 - if ( $this->dims[$tag] === 0 ) {
125 - $this->unapprovedTags++;
126 - } elseif ( is_null( $this->dims[$tag] ) ) {
127 - # This happens if we uncheck a checkbox
128 - $this->unapprovedTags++;
129 - $this->dims[$tag] = 0;
130 - }
131 - }
132 - }
133 - $fa = FlaggedArticle::getTitleInstance( $this->page );
134 - $this->config = $fa->getVisibilitySettings();
135 - # Check permissions and validate
136 - if ( !self::userCanSetFlags( $this->dims, $this->oflags, $this->config ) ) {
137 - $wgOut->permissionRequired( 'badaccess-group0' );
 67+ $form->setNotes( $wgRequest->getText( 'wpNotes' ) );
 68+
 69+ $status = $form->ready();
 70+ # Page must exist and be in reviewable namespace
 71+ if ( $status === 'review_page_unreviewable' ) {
 72+ $wgOut->addWikiText( wfMsg( 'revreview-main' ) );
13873 return;
 74+ } elseif ( $status === 'review_page_notexists' ) {
 75+ $wgOut->showErrorPage( 'internalerror', 'nopagetext' );
 76+ return;
13977 }
140 - # We must at least rate each category as 1, the minimum
141 - # Exception: we can rate ALL as unapproved to depreciate a revision
142 - if ( $this->unapprovedTags && $this->unapprovedTags < count( FlaggedRevs::getDimensions() ) ) {
143 - $wgOut->addWikiText( wfMsg( 'revreview-toolow' ) );
144 - $wgOut->returnToMain( false, $this->page );
 78+ # Basic page permission checks...
 79+ $permErrors = $this->page->getUserPermissionsErrors( 'review', $wgUser, false );
 80+ if ( !$permErrors ) {
 81+ $permErrors = $this->page->getUserPermissionsErrors( 'edit', $wgUser, false );
 82+ }
 83+ if ( $permErrors ) {
 84+ $wgOut->showPermissionsErrorPage( $permErrors, 'review' );
14585 return;
146 - } elseif ( !$wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
147 - $wgOut->addWikiText( wfMsg( 'sessionfailure' ) );
148 - $wgOut->returnToMain( false, $this->page );
149 - return;
15086 }
151 - # Submit or display info on failure
 87+
 88+ # Review the edit if requested (POST)...
15289 if ( $wgRequest->wasPosted() ) {
153 - list( $approved, $status ) = $this->submit();
 90+ // Check the edit token...
 91+ if ( !$confirmed ) {
 92+ $wgOut->addWikiText( wfMsg( 'sessionfailure' ) );
 93+ $wgOut->returnToMain( false, $this->page );
 94+ return;
 95+ }
 96+ $status = $form->submit();
15497 // Success for either flagging or unflagging
15598 if ( $status === true ) {
15699 $wgOut->setPageTitle( wfMsgHtml( 'actioncomplete' ) );
157 - $wgOut->addHTML( $this->showSuccess( $approved, true ) );
 100+ if ( $form->isApproval() ) {
 101+ $wgOut->addHTML( $form->approvalSuccessHTML( true ) );
 102+ } else {
 103+ $wgOut->addHTML( $form->deapprovalSuccessHTML( true ) );
 104+ }
 105+ // Failure for unflagging
 106+ } elseif ( !$form->isApproval() ) {
 107+ $wgOut->redirect( $this->page->getFullUrl() ); // already unflagged
158108 // Sync failure for flagging
159 - } elseif ( is_array( $status ) && $approved ) {
 109+ } elseif ( is_array( $status ) ) {
160110 $wgOut->setPageTitle( wfMsgHtml( 'internalerror' ) );
161 - $wgOut->addHTML( $this->showSyncFailure( $status, true ) );
162 - // Failure for unflagging
163 - } elseif ( $status === false && !$approved ) {
164 - $wgOut->redirect( $this->page->getFullUrl() );
165 - // Any other fail...
 111+ $wgOut->addHTML( $form->syncFailureHTML( $status, true ) );
 112+ // Any other fails for flagging...
166113 } else {
167 - $wgOut->setPageTitle( wfMsgHtml( 'internalerror' ) );
168 - $wgOut->showErrorPage( 'internalerror', 'revreview-revnotfound' );
 114+ if ( $status === 'review_denied' ) {
 115+ $wgOut->permissionRequired( 'badaccess-group0' ); // protected?
 116+ } elseif ( $status === 'review_bad_key' ) {
 117+ $wgOut->permissionRequired( 'badaccess-group0' ); // fiddling
 118+ } elseif ( $status === 'review_bad_oldid' ) {
 119+ $wgOut->showErrorPage( 'internalerror', 'revreview-revnotfound' );
 120+ } elseif ( $status === 'review_too_low' ) {
 121+ $wgOut->addWikiText( wfMsg( 'revreview-toolow' ) );
 122+ } else {
 123+ $wgOut->showErrorPage( 'internalerror', $status );
 124+ }
169125 $wgOut->returnToMain( false, $this->page );
170126 }
 127+ // No form to view (GET)
 128+ } else {
 129+ $wgOut->returnToMain( false, $this->page );
171130 }
172131 }
173 -
174 - private function retrieveNotes( $notes = '' ) {
175 - global $wgUser;
176 - $this->notes = ( FlaggedRevs::allowComments() && $wgUser->isAllowed( 'validate' ) ) ?
177 - $notes : '';
178 - }
179 -
 132+
180133 public static function AjaxReview( /*$args...*/ ) {
181 - global $wgUser;
 134+ global $wgUser, $wgOut;
182135 $args = func_get_args();
183136 if ( wfReadOnly() ) {
184137 return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' );
185138 }
186139 $tags = FlaggedRevs::getDimensions();
187140 // Make review interface object
188 - $form = new RevisionReview();
 141+ $form = new RevisionReviewForm();
 142+ $title = null; // target page
 143+ $editToken = ''; // edit token
189144 // Each ajax url argument is of the form param|val.
190145 // This means that there is no ugly order dependance.
191146 foreach ( $args as $x => $arg ) {
@@ -196,598 +151,95 @@
197152 switch( $par )
198153 {
199154 case "target":
200 - $form->page = Title::newFromURL( $val );
201 - if ( is_null( $form->page ) || !FlaggedRevs::inReviewNamespace( $form->page ) ) {
202 - return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' );
203 - }
 155+ $title = Title::newFromURL( $val );
204156 break;
205157 case "oldid":
206 - $form->oldid = intval( $val );
207 - if ( !$form->oldid ) {
208 - return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' );
209 - }
 158+ $form->setOldId( $val );
210159 break;
211160 case "rcid":
212 - $form->rcid = intval( $val );
 161+ $form->setRCId( $val );
213162 break;
214163 case "validatedParams":
215 - $form->validatedParams = $val;
 164+ $form->setValidatedParams( $val );
216165 break;
217166 case "templateParams":
218 - $form->templateParams = $val;
 167+ $form->setTemplateParams( $val);
219168 break;
220169 case "imageParams":
221 - $form->imageParams = $val;
 170+ $form->setFileParams( $val );
222171 break;
223172 case "fileVersion":
224 - $form->fileVersion = $val;
 173+ $form->setFileVersion( $val );
225174 break;
226175 case "wpApprove":
227 - $form->approve = $val;
 176+ $form->setApprove( $val );
228177 break;
229178 case "wpUnapprove":
230 - $form->unapprove = $val;
 179+ $form->setUnapprove( $val );
231180 break;
232181 case "wpReason":
233 - $form->comment = $val;
 182+ $form->setComment( $val );
234183 break;
235184 case "wpNotes":
236 - $form->retrieveNotes( $val );
 185+ $form->setNotes( $val );
237186 break;
238187 case "wpEditToken":
239 - if ( !$wgUser->matchEditToken( $val ) ) {
240 - return '<err#>' . wfMsgExt( 'sessionfailure', 'parseinline' );
241 - }
 188+ $editToken = $val;
242189 break;
243190 default:
244191 $p = preg_replace( '/^wp/', '', $par ); // kill any "wp" prefix
245192 if ( array_key_exists( $p, $tags ) ) {
246 - $form->dims[$p] = intval( $val );
247 - if ( $form->dims[$p] === 0 ) {
248 - $form->unapprovedTags++;
249 - }
 193+ $form->setDim( $p, $val );
250194 }
251195 break;
252196 }
253197 }
254 - // No page?
255 - if ( !$form->page ) {
256 - return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' );
 198+ # Valid target title?
 199+ if ( !$title ) {
 200+ return '<err#>' . wfMsgExt( 'notargettext', 'parseinline' );
257201 }
258 - // Basic permission check
259 - $permErrors = $form->page->getUserPermissionsErrors( 'review', $wgUser );
 202+ $form->setPage( $title );
 203+
 204+ $status = $form->ready(); // all params loaded
 205+ # Page must exist and be in reviewable namespace
 206+ if ( $status === 'review_page_unreviewable' ) {
 207+ return '<err#>' . wfMsgExt( 'revreview-main', 'parseinline' );
 208+ } elseif ( $status === 'review_page_notexists' ) {
 209+ return '<err#>' . wfMsgExt( 'nopagetext', 'parseinline' );
 210+ }
 211+ # Check session via user token
 212+ if ( !$wgUser->matchEditToken( $editToken ) ) {
 213+ return '<err#>' . wfMsgExt( 'sessionfailure', 'parseinline' );
 214+ }
 215+ # Basic permission checks...
 216+ $permErrors = $title->getUserPermissionsErrors( 'review', $wgUser, false );
260217 if ( !$permErrors ) {
261 - // User must be able to edit this page
262 - $permErrors = $form->page->getUserPermissionsErrors( 'edit', $wgUser );
 218+ $permErrors = $title->getUserPermissionsErrors( 'edit', $wgUser, false );
263219 }
264220 if ( $permErrors ) {
265 - global $wgOut;
266221 return '<err#>' . $wgOut->parse(
267222 $wgOut->formatPermissionsErrorMessage( $permErrors, 'review' )
268223 );
269224 }
270 - # Fill in implicit tag data for binary flag case
271 - if ( $iDims = $form->implicitDims() ) {
272 - $form->dims = $iDims;
273 - }
274 - // Missing params?
275 - if ( count( $form->dims ) != count( $tags ) ) {
276 - return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' );
277 - }
278 - // Incomplete review?
279 - if ( !$form->oldid || is_null( $form->page ) ) {
280 - return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' );
281 - }
282 - if ( $form->unapprovedTags
283 - && $form->unapprovedTags < count( FlaggedRevs::getDimensions() ) )
284 - {
285 - return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' );
286 - }
287 - // Doesn't match up?
288 - $k = self::validationKey( $form->templateParams, $form->imageParams,
289 - $form->fileVersion, $form->oldid );
290 - if ( $form->validatedParams !== $k ) {
291 - return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' );
292 - }
293 - $fa = FlaggedArticle::getTitleInstance( $form->page );
294 - $form->config = $fa->getVisibilitySettings();
295 - # Get the revision's current flags, if any
296 - $form->oflags = FlaggedRevs::getRevisionTags( $form->page, $form->oldid );
297 - # Check tag permissions
298 - if ( !self::userCanSetFlags( $form->dims, $form->oflags, $form->config ) ) {
299 - return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' );
300 - }
301 - list( $approved, $status ) = $form->submit();
 225+ # Try submission...
 226+ $status = $form->submit();
 227+ # Approve/de-approve success
302228 if ( $status === true ) {
303 - $tier = FlaggedRevs::getLevelTier( $form->dims ) + 1; // shift to 0-3
304 - return "<suc#><t#$tier>" . $form->showSuccess( $approved );
305 - } elseif ( $approved && is_array( $status ) ) {
306 - return '<err#>' . $form->showSyncFailure( $status );
307 - } elseif ( $approved ) {
308 - return '<err#>' . wfMsg( 'revreview-revnotfound' );
 229+ $tier = FlaggedRevs::getLevelTier( $form->getDims() ) + 1; // shift to 0-3
 230+ if ( $form->isApproval() ) {
 231+ return "<suc#><t#$tier>" . $form->approvalSuccessHTML( false );
 232+ } else {
 233+ return "<suc#><t#$tier>" . $form->deapprovalSuccessHTML( false );
 234+ }
 235+ # De-approve failure
 236+ } elseif ( !$form->isApproval() ) {
 237+ return "<suc#><t#0>"; // failure -> already unflagged
 238+ # Approve sync failure
 239+ } elseif ( is_array( $status ) ) {
 240+ return '<err#>' . $form->syncFailureHTML( $status, false );
 241+ # Other approval failures
309242 } else { // hmmm?
310243 return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' );
311244 }
312245 }
313 -
314 - public function isApproval() {
315 - # If all values are set to zero, this has been unapproved
316 - if ( FlaggedRevs::dimensionsEmpty() ) {
317 - if ( $this->approve && !$this->unapprove )
318 - return true; // no tags & approve param given
319 - if ( $this->unapprove && !$this->approve )
320 - return false;
321 - else
322 - return null; // nothing valid asserted
323 - }
324 - foreach ( $this->dims as $quality => $value ) {
325 - if ( $value ) return true;
326 - }
327 - return false;
328 - }
329 -
330 - public function submit() {
331 - global $wgUser;
332 - # If all values are set to zero, this has been unapproved
333 - $approved = $this->isApproval();
334 - if ( $approved === null ) {
335 - return array( true, false ); // user didn't say
336 - }
337 - # Double-check permissions
338 - if ( !$this->page->quickUserCan( 'edit' )
339 - || !self::userCanSetFlags( $this->dims, $this->oflags, $this->config ) )
340 - {
341 - return array( $approved, false );
342 - }
343 - # We can only approve actual revisions...
344 - if ( $approved ) {
345 - $rev = Revision::newFromTitle( $this->page, $this->oldid );
346 - # Do not mess with archived/deleted revisions
347 - if ( is_null( $rev ) || $rev->mDeleted ) {
348 - return array( $approved, false );
349 - }
350 - $status = $this->approveRevision( $rev );
351 - # We can only unapprove approved revisions...
352 - } else {
353 - $frev = FlaggedRevision::newFromTitle( $this->page, $this->oldid );
354 - # If we can't find this flagged rev, return to page???
355 - if ( is_null( $frev ) ) {
356 - return array( $approved, true );
357 - }
358 - $status = $this->unapproveRevision( $frev );
359 - }
360 - # Watch page if set to do so
361 - if ( $status === true ) {
362 - if ( $wgUser->getOption( 'flaggedrevswatch' ) && !$this->page->userIsWatching() ) {
363 - $dbw = wfGetDB( DB_MASTER );
364 - $dbw->begin();
365 - $wgUser->addWatch( $this->page );
366 - $dbw->commit();
367 - }
368 - }
369 - return array( $approved, $status );
370 - }
371 -
372 - private function showSuccess( $approved, $showlinks = false ) {
373 - global $wgUser;
374 - # Show success message
375 - $msg = $approved ? 'revreview-successful' : 'revreview-successful2';
376 - $form = "<div class='plainlinks'>" . wfMsgExt( $msg, array( 'parseinline' ),
377 - $this->page->getPrefixedText(), $this->page->getPrefixedUrl() );
378 - $msg = $approved ? 'revreview-stable1' : 'revreview-stable2';
379 - $form .= wfMsgExt( $msg, array( 'parse' ), $this->page->getPrefixedUrl(), $this->oldid );
380 - $form .= "</div>";
381 - # Handy links to special pages
382 - if ( $showlinks && $wgUser->isAllowed( 'unreviewedpages' ) ) {
383 - $form .= '<p>' . wfMsg( 'returnto',
384 - $this->skin->makeLinkObj( SpecialPage::getTitleFor( 'UnreviewedPages' ) ) ) . '</p>';
385 - $form .= '<p>' . wfMsg( 'returnto',
386 - $this->skin->makeLinkObj( SpecialPage::getTitleFor( 'OldReviewedPages' ) ) ) . '</p>';
387 - }
388 - return $form;
389 - }
390 -
391 - private function showSyncFailure( $status, $showlinks = false ) {
392 - $form = wfMsgExt( 'revreview-changed', array( 'parse' ), $this->page->getPrefixedText() );
393 - $form .= "<ul>";
394 - foreach ( $status as $n => $text ) {
395 - $form .= "<li><i>$text</i></li>\n";
396 - }
397 - $form .= "</ul>";
398 - if ( $showlinks ) {
399 - $form .= wfMsg( 'returnto', $this->skin->makeLinkObj( $this->page ) );
400 - }
401 - return $form;
402 - }
403 -
404 - /**
405 - * Adds or updates the flagged revision table for this page/id set
406 - * @param Revision $rev
407 - * @returns true on success, array of errors on failure
408 - */
409 - private function approveRevision( $rev ) {
410 - global $wgUser, $wgMemc, $wgParser, $wgEnableParserCache;
411 - wfProfileIn( __METHOD__ );
412 -
413 - $article = new Article( $this->page );
414 -
415 - $quality = 0;
416 - if ( FlaggedRevs::isQuality( $this->dims ) ) {
417 - $quality = FlaggedRevs::isPristine( $this->dims ) ? 2 : 1;
418 - }
419 - # Our flags
420 - $flags = $this->dims;
421 - # Some validation vars to make sure nothing changed during
422 - $lastTempId = 0;
423 - $lastImgTime = "0";
424 - # Our template version pointers
425 - $tmpset = $tmpParams = array();
426 - $templateMap = explode( '#', trim( $this->templateParams ) );
427 - foreach ( $templateMap as $template ) {
428 - if ( !$template )
429 - continue;
430 -
431 - $m = explode( '|', $template, 2 );
432 - if ( !isset( $m[0] ) || !isset( $m[1] ) || !$m[0] )
433 - continue;
434 -
435 - list( $prefixed_text, $rev_id ) = $m;
436 -
437 - $tmp_title = Title::newFromText( $prefixed_text ); // Normalize this to be sure...
438 - if ( is_null( $tmp_title ) )
439 - continue; // Page must be valid!
440 -
441 - if ( $rev_id > $lastTempId )
442 - $lastTempId = $rev_id;
443 -
444 - $tmpset[] = array(
445 - 'ft_rev_id' => $rev->getId(),
446 - 'ft_namespace' => $tmp_title->getNamespace(),
447 - 'ft_title' => $tmp_title->getDBkey(),
448 - 'ft_tmp_rev_id' => $rev_id
449 - );
450 - if ( !isset( $tmpParams[$tmp_title->getNamespace()] ) ) {
451 - $tmpParams[$tmp_title->getNamespace()] = array();
452 - }
453 - $tmpParams[$tmp_title->getNamespace()][$tmp_title->getDBkey()] = $rev_id;
454 - }
455 - # Our image version pointers
456 - $imgset = $imgParams = array();
457 - $imageMap = explode( '#', trim( $this->imageParams ) );
458 - foreach ( $imageMap as $image ) {
459 - if ( !$image )
460 - continue;
461 - $m = explode( '|', $image, 3 );
462 - # Expand our parameters ... <name>#<timestamp>#<key>
463 - if ( !isset( $m[0] ) || !isset( $m[1] ) || !isset( $m[2] ) || !$m[0] )
464 - continue;
465 -
466 - list( $dbkey, $timestamp, $key ) = $m;
467 -
468 - $img_title = Title::makeTitle( NS_IMAGE, $dbkey ); // Normalize
469 - if ( is_null( $img_title ) )
470 - continue; // Page must be valid!
471 -
472 - if ( $timestamp > $lastImgTime )
473 - $lastImgTime = $timestamp;
474 -
475 - $imgset[] = array(
476 - 'fi_rev_id' => $rev->getId(),
477 - 'fi_name' => $img_title->getDBkey(),
478 - 'fi_img_timestamp' => $timestamp,
479 - 'fi_img_sha1' => $key
480 - );
481 - if ( !isset( $imgParams[$img_title->getDBkey()] ) ) {
482 - $imgParams[$img_title->getDBkey()] = array();
483 - }
484 - $imgParams[$img_title->getDBkey()][$timestamp] = $key;
485 - }
486 - # If this is an image page, store corresponding file info
487 - $fileData = array();
488 - if ( $this->page->getNamespace() == NS_IMAGE && $this->fileVersion ) {
489 - $data = explode( '#', $this->fileVersion, 2 );
490 - if ( count( $data ) == 2 ) {
491 - $fileData['name'] = $this->page->getDBkey();
492 - $fileData['timestamp'] = $data[0];
493 - $fileData['sha1'] = $data[1];
494 - }
495 - }
496 -
497 - # Get current stable version ID (for logging)
498 - $oldSv = FlaggedRevision::newFromStable( $this->page, FR_MASTER );
499 - $oldSvId = $oldSv ? $oldSv->getRevId() : 0;
500 -
501 - # Is this rev already flagged?
502 - $flaggedOutput = false;
503 - $oldfrev = FlaggedRevision::newFromTitle( $this->page, $rev->getId(), FR_MASTER );
504 - if ( $oldfrev ) {
505 - $flaggedOutput = FlaggedRevs::parseStableText( $article,
506 - $oldfrev->getRevText(), $oldfrev->getRevId() );
507 - }
508 -
509 - # Be loose on templates that includes other files/templates dynamically.
510 - # Strict checking breaks randomized images/metatemplates...(bug 14580)
511 - global $wgUseCurrentTemplates, $wgUseCurrentImages;
512 - $mustMatch = !( $wgUseCurrentTemplates && $wgUseCurrentImages );
513 -
514 - # Set our versioning params cache
515 - FlaggedRevs::setIncludeVersionCache( $rev->getId(), $tmpParams, $imgParams );
516 - # Parse the text and check if all templates/files match up
517 - $text = $rev->getText();
518 - $stableOutput = FlaggedRevs::parseStableText( $article, $text, $rev->getId() );
519 - $err =& $stableOutput->fr_includeErrors;
520 - if ( $mustMatch ) { // if template/files must all be specified...
521 - if ( !empty( $err )
522 - || $stableOutput->fr_newestImageTime > $lastImgTime
523 - || $stableOutput->fr_newestTemplateID > $lastTempId )
524 - {
525 - wfProfileOut( __METHOD__ );
526 - return $err; // return templates/files with no version specified
527 - }
528 - }
529 - # Clear our versioning params cache
530 - FlaggedRevs::clearIncludeVersionCache( $rev->getId() );
531 -
532 - # Is this a duplicate review?
533 - if ( $oldfrev && $flaggedOutput ) {
534 - $synced = true;
535 - if ( $stableOutput->fr_newestImageTime != $flaggedOutput->fr_newestImageTime )
536 - $synced = false;
537 - elseif ( $stableOutput->fr_newestTemplateID != $flaggedOutput->fr_newestTemplateID )
538 - $synced = false;
539 - elseif ( $oldfrev->getTags() != $flags )
540 - $synced = false;
541 - elseif ( $oldfrev->getFileSha1() != @$fileData['sha1'] )
542 - $synced = false;
543 - elseif ( $oldfrev->getComment() != $this->notes )
544 - $synced = false;
545 - elseif ( $oldfrev->getQuality() != $quality )
546 - $synced = false;
547 - # Don't review if the same
548 - if ( $synced ) {
549 - wfProfileOut( __METHOD__ );
550 - return true;
551 - }
552 - }
553 -
554 - $dbw = wfGetDB( DB_MASTER );
555 - # Our review entry
556 - $flaggedRevision = new FlaggedRevision( array(
557 - 'fr_rev_id' => $rev->getId(),
558 - 'fr_page_id' => $rev->getPage(),
559 - 'fr_user' => $wgUser->getId(),
560 - 'fr_timestamp' => wfTimestampNow(),
561 - 'fr_comment' => $this->notes,
562 - 'fr_quality' => $quality,
563 - 'fr_tags' => FlaggedRevision::flattenRevisionTags( $flags ),
564 - 'fr_img_name' => $fileData ? $fileData['name'] : null,
565 - 'fr_img_timestamp' => $fileData ? $fileData['timestamp'] : null,
566 - 'fr_img_sha1' => $fileData ? $fileData['sha1'] : null
567 - ) );
568 -
569 - $dbw->begin();
570 - $flaggedRevision->insertOn( $tmpset, $imgset );
571 - # Avoid any lag issues
572 - $this->page->resetArticleId( $rev->getPage() );
573 - # Update recent changes
574 - self::updateRecentChanges( $this->page, $rev->getId(), $this->rcid, true );
575 - # Update the article review log
576 - FlaggedRevsLogs::updateLog( $this->page, $this->dims, $this->oflags,
577 - $this->comment, $this->oldid, $oldSvId, true );
578 -
579 - # Update the links tables as the stable version may now be the default page.
580 - # Try using the parser cache first since we didn't actually edit the current version.
581 - $parserCache = ParserCache::singleton();
582 - $poutput = $parserCache->get( $article, $wgUser );
583 - if ( !$poutput
584 - || !isset( $poutput->fr_newestTemplateID )
585 - || !isset( $poutput->fr_newestImageTime ) )
586 - {
587 - $options = FlaggedRevs::makeParserOptions();
588 - $poutput = $wgParser->parse( $article->getContent(), $article->mTitle, $options );
589 - }
590 - # Prepare for a link tracking update
591 - $u = new LinksUpdate( $this->page, $poutput );
592 - # If we know that this is now the new stable version
593 - # (which it probably is), save it to the stable cache...
594 - $sv = FlaggedRevision::newFromStable( $this->page, FR_MASTER/*consistent*/ );
595 - if ( $sv && $sv->getRevId() == $rev->getId() ) {
596 - global $wgParserCacheExpireTime;
597 - $this->page->invalidateCache();
598 - # Update stable cache with the revision we reviewed.
599 - # Don't cache redirects; it would go unused and complicate things.
600 - if ( !Title::newFromRedirect( $text ) ) {
601 - FlaggedRevs::updatePageCache( $article, $wgUser, $stableOutput );
602 - }
603 - # We can set the sync cache key already
604 - $includesSynced = true;
605 - if ( $poutput->fr_newestImageTime > $stableOutput->fr_newestImageTime ) {
606 - $includesSynced = false;
607 - } elseif ( $poutput->fr_newestTemplateID > $stableOutput->fr_newestTemplateID ) {
608 - $includesSynced = false;
609 - }
610 - $u->fr_stableRev = $sv; // no need to re-fetch this!
611 - $u->fr_stableParserOut = $stableOutput; // no need to re-fetch this!
612 - # We can set the sync cache key already.
613 - $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $article->getId() );
614 - $data = FlaggedRevs::makeMemcObj( $includesSynced ? "true" : "false" );
615 - $wgMemc->set( $key, $data, $wgParserCacheExpireTime );
616 - } else {
617 - # Get the old stable cache
618 - $stableOutput = FlaggedRevs::getPageCache( $article, $wgUser );
619 - # Clear the cache...(for page histories)
620 - $this->page->invalidateCache();
621 - if ( $stableOutput !== false ) {
622 - # Reset stable cache if it existed, since we know it is the same.
623 - FlaggedRevs::updatePageCache( $article, $wgUser, $stableOutput );
624 - }
625 - }
626 - # Update link tracking. This will trigger extraLinksUpdate()...
627 - $u->doUpdate();
628 -
629 - $dbw->commit();
630 - # Purge cache/squids for this page and any page that uses it
631 - Article::onArticleEdit( $this->page );
632 -
633 - wfProfileOut( __METHOD__ );
634 - return true;
635 - }
636 -
637 - /**
638 - * @param FlaggedRevision $frev
639 - * Removes flagged revision data for this page/id set
640 - */
641 - private function unapproveRevision( $frev ) {
642 - global $wgUser, $wgParser, $wgMemc;
643 - wfProfileIn( __METHOD__ );
644 -
645 - $dbw = wfGetDB( DB_MASTER );
646 - $dbw->begin();
647 - # Delete from flaggedrevs table
648 - $dbw->delete( 'flaggedrevs',
649 - array( 'fr_page_id' => $frev->getPage(), 'fr_rev_id' => $frev->getRevId() ) );
650 - # Wipe versioning params
651 - $dbw->delete( 'flaggedtemplates', array( 'ft_rev_id' => $frev->getRevId() ) );
652 - $dbw->delete( 'flaggedimages', array( 'fi_rev_id' => $frev->getRevId() ) );
653 - # Update recent changes
654 - self::updateRecentChanges( $this->page, $frev->getRevId(), false, false );
655 -
656 - # Get current stable version ID (for logging)
657 - $oldSv = FlaggedRevision::newFromStable( $this->page, FR_MASTER );
658 - $oldSvId = $oldSv ? $oldSv->getRevId() : 0;
659 -
660 - # Update the article review log
661 - FlaggedRevsLogs::updateLog( $this->page, $this->dims, $this->oflags,
662 - $this->comment, $this->oldid, $oldSvId, false );
663 -
664 - $article = new Article( $this->page );
665 - # Update the links tables as a new stable version
666 - # may now be the default page.
667 - $parserCache = ParserCache::singleton();
668 - $poutput = $parserCache->get( $article, $wgUser );
669 - if ( $poutput == false ) {
670 - $text = $article->getContent();
671 - $options = FlaggedRevs::makeParserOptions();
672 - $poutput = $wgParser->parse( $text, $article->mTitle, $options );
673 - }
674 - $u = new LinksUpdate( $this->page, $poutput );
675 - $u->doUpdate();
676 -
677 - # Clear the cache...
678 - $this->page->invalidateCache();
679 - # Purge cache/squids for this page and any page that uses it
680 - $dbw->commit();
681 - Article::onArticleEdit( $article->getTitle() );
682 -
683 - wfProfileOut( __METHOD__ );
684 - return true;
685 - }
686 -
687 - /**
688 - * Get a validation key from versioning metadata
689 - * @param string $tmpP
690 - * @param string $imgP
691 - * @param string $imgV
692 - * @param integer $rid rev ID
693 - * @return string
694 - */
695 - public static function validationKey( $tmpP, $imgP, $imgV, $rid ) {
696 - global $wgReviewCodes;
697 - # Fall back to $wgSecretKey/$wgProxyKey
698 - if ( empty( $wgReviewCodes ) ) {
699 - global $wgSecretKey, $wgProxyKey;
700 - $key = $wgSecretKey ? $wgSecretKey : $wgProxyKey;
701 - $p = md5( $key . $imgP . $tmpP . $rid . $imgV );
702 - } else {
703 - $p = md5( $wgReviewCodes[0] . $imgP . $rid . $tmpP . $imgV . $wgReviewCodes[1] );
704 - }
705 - return $p;
706 - }
707 -
708 - /**
709 - * Returns true if a user can set $tag to $value.
710 - * @param string $tag
711 - * @param int $value
712 - * @param array $config (optional page config)
713 - * @returns bool
714 - */
715 - public static function userCan( $tag, $value, $config = null ) {
716 - global $wgUser;
717 - # Sanity check tag and value
718 - $levels = FlaggedRevs::getTagLevels( $tag );
719 - $highest = count( $levels ) - 1;
720 - if( !$levels || $value < 0 || $value > $highest ) {
721 - return false; // flag range is invalid
722 - }
723 - $restrictions = FlaggedRevs::getTagRestrictions();
724 - # No restrictions -> full access
725 - if ( !isset( $restrictions[$tag] ) ) {
726 - return true;
727 - }
728 - # Validators always have full access
729 - if ( $wgUser->isAllowed( 'validate' ) ) {
730 - return true;
731 - }
732 - # Check if this user has any right that lets him/her set
733 - # up to this particular value
734 - foreach ( $restrictions[$tag] as $right => $level ) {
735 - if ( $value <= $level && $level > 0 && $wgUser->isAllowed( $right ) ) {
736 - return true;
737 - }
738 - }
739 - return false;
740 - }
741 -
742 - /**
743 - * Returns true if a user can set $flags.
744 - * This checks if the user has the right to review
745 - * to the given levels for each tag.
746 - * @param array $flags, suggested flags
747 - * @param array $oldflags, pre-existing flags
748 - * @param array $config, visibility settings
749 - * @returns bool
750 - */
751 - public static function userCanSetFlags( $flags, $oldflags = array(), $config = null ) {
752 - global $wgUser;
753 - if ( !$wgUser->isAllowed( 'review' ) )
754 - return false; // User is not able to review pages
755 - # Check if all of the required site flags have a valid value
756 - # that the user is allowed to set.
757 - foreach ( FlaggedRevs::getDimensions() as $qal => $levels ) {
758 - $level = isset( $flags[$qal] ) ? $flags[$qal] : 0;
759 - $highest = count( $levels ) - 1; // highest valid level
760 - if ( !self::userCan( $qal, $level, $config ) ) {
761 - return false; // user cannot set proposed flag
762 - } elseif ( isset( $oldflags[$qal] ) && !self::userCan( $qal, $oldflags[$qal] ) ) {
763 - return false; // user cannot change old flag ($config is ignored here)
764 - }
765 - }
766 - return true;
767 - }
768 -
769 - public static function updateRecentChanges( $title, $revId, $rcId = false, $patrol = true ) {
770 - wfProfileIn( __METHOD__ );
771 - $revId = intval( $revId );
772 - $dbw = wfGetDB( DB_MASTER );
773 - # Olders edits be marked as patrolled now...
774 - $dbw->update( 'recentchanges',
775 - array( 'rc_patrolled' => $patrol ? 1 : 0 ),
776 - array( 'rc_cur_id' => $title->getArticleId(),
777 - $patrol ? "rc_this_oldid <= $revId" : "rc_this_oldid = $revId" ),
778 - __METHOD__,
779 - // Performance
780 - array( 'USE INDEX' => 'rc_cur_id', 'LIMIT' => 50 )
781 - );
782 - # New page patrol may be enabled. If so, the rc_id may be the first
783 - # edit and not this one. If it is different, mark it too.
784 - if ( $rcId && $rcId != $revId ) {
785 - $dbw->update( 'recentchanges',
786 - array( 'rc_patrolled' => 1 ),
787 - array( 'rc_id' => $rcId,
788 - 'rc_type' => RC_NEW ),
789 - __METHOD__
790 - );
791 - }
792 - wfProfileOut( __METHOD__ );
793 - }
794246 }
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevs.hooks.php
@@ -1,5 +1,11 @@
22 <?php
3 -
 3+if ( !defined( 'MEDIAWIKI' ) ) {
 4+ echo "FlaggedRevs extension\n";
 5+ exit( 1 );
 6+}
 7+/**
 8+ * Class containing hooked functions for a FlaggedRevs environment
 9+ */
410 class FlaggedRevsHooks {
511 /*
612 * Register FlaggedRevs special pages as needed.
@@ -78,7 +84,7 @@
7985
8086 return true;
8187 }
82 -
 88+
8389 public static function injectGlobalJSVars( &$globalVars ) {
8490 global $wgUser;
8591 $fa = FlaggedArticleView::globalArticleInstance();
@@ -112,7 +118,7 @@
113119 }
114120 return true;
115121 }
116 -
 122+
117123 /**
118124 * Add FlaggedRevs css for relevant special pages.
119125 */
@@ -121,8 +127,8 @@
122128 if ( empty( $wgTitle ) || $wgTitle->getNamespace() !== NS_SPECIAL ) {
123129 return true;
124130 }
125 - $spPages = array( 'UnreviewedPages', 'OldReviewedPages', 'Watchlist',
126 - 'Recentchanges', 'Contributions' );
 131+ $spPages = array( 'UnreviewedPages', 'OldReviewedPages', 'ProblemChanges',
 132+ 'Watchlist', 'Recentchanges', 'Contributions' );
127133 foreach ( $spPages as $n => $key ) {
128134 if ( $wgTitle->isSpecial( $key ) ) {
129135 global $wgScriptPath, $wgFlaggedRevsStylePath, $wgFlaggedRevStyleVersion;
@@ -136,7 +142,7 @@
137143 }
138144 return true;
139145 }
140 -
 146+
141147 /*
142148 * Add tag notice, CSS/JS, and set robots policy
143149 */
@@ -225,7 +231,7 @@
226232
227233 return true;
228234 }
229 -
 235+
230236 /**
231237 * Update flaggedrevs tracking tables
232238 */
@@ -233,7 +239,7 @@
234240 FlaggedRevs::clearTrackingRows( $id );
235241 return true;
236242 }
237 -
 243+
238244 /**
239245 * Update stable version selection
240246 */
@@ -241,7 +247,7 @@
242248 FlaggedRevs::titleLinksUpdate( $title );
243249 return true;
244250 }
245 -
 251+
246252 /**
247253 * Update pending revision table
248254 * Autoreview pages moved into content NS
@@ -388,7 +394,7 @@
389395 }
390396 $links[$ns][$dbKey] = 1;
391397 }
392 -
 398+
393399 protected static function getExistingLinks( $pageId ) {
394400 $dbr = wfGetDB( DB_SLAVE );
395401 $res = $dbr->select( 'flaggedrevs_tracking',
@@ -404,13 +410,13 @@
405411 }
406412 return $arr;
407413 }
408 -
 414+
409415 protected static function makeWhereFrom2d( &$arr ) {
410416 $lb = new LinkBatch();
411417 $lb->setArray( $arr );
412418 return $lb->constructSet( 'ftr', wfGetDB( DB_SLAVE ) );
413419 }
414 -
 420+
415421 protected static function getLinkInsertions( $existing, $new, $pageId ) {
416422 $arr = array();
417423 foreach ( $new as $ns => $dbkeys ) {
@@ -426,7 +432,7 @@
427433 }
428434 return $arr;
429435 }
430 -
 436+
431437 protected static function getLinkDeletions( $existing, $new ) {
432438 $del = array();
433439 foreach ( $existing as $ns => $dbkeys ) {
@@ -438,7 +444,7 @@
439445 }
440446 return $del;
441447 }
442 -
 448+
443449 /*
444450 * Update pages where only the stable version links to a page
445451 * that was just changed in some way.
@@ -448,7 +454,7 @@
449455 $update->doUpdate();
450456 return true;
451457 }
452 -
 458+
453459 /**
454460 * Add special fields to parser.
455461 */
@@ -706,7 +712,7 @@
707713 }
708714 return true;
709715 }
710 -
 716+
711717 /**
712718 * Insert image timestamps/SHA-1 keys into parser output
713719 */
@@ -820,7 +826,7 @@
821827 }
822828 return true;
823829 }
824 -
 830+
825831 /**
826832 * Allow users to view reviewed pages
827833 */
@@ -857,7 +863,7 @@
858864 }
859865 return true;
860866 }
861 -
 867+
862868 /**
863869 * When an edit is made by a reviewer, if the base revision the
864870 * edit was made from is the stable version, or the edit is a reversion
@@ -1013,7 +1019,7 @@
10141020 # Confirm the text because we can't trust this user.
10151021 return ( $rev->getText() == $srev->getRevText() );
10161022 }
1017 -
 1023+
10181024 /**
10191025 * When an user makes a null-edit we sometimes want to review it...
10201026 * (a) Null undo or rollback
@@ -1128,7 +1134,7 @@
11291135 }
11301136 return true;
11311137 }
1132 -
 1138+
11331139 public static function incrementRollbacks( $this, $user, $target, $current ) {
11341140 # Mark when a user reverts another user, but not self-reverts
11351141 if ( $current->getRawUser() && $user->getId() != $current->getRawUser() ) {
@@ -1139,7 +1145,7 @@
11401146 }
11411147 return true;
11421148 }
1143 -
 1149+
11441150 public static function incrementReverts( $article, $rev, $baseRevId = false, $user = null ) {
11451151 global $wgRequest;
11461152 # Was this an edit by an auto-sighter that undid another edit?
@@ -1156,7 +1162,7 @@
11571163 }
11581164 return true;
11591165 }
1160 -
 1166+
11611167 protected static function editSpacingCheck( $spacing, $points, $user ) {
11621168 # Convert days to seconds...
11631169 $spacing = $spacing * 24 * 3600;
@@ -1183,7 +1189,7 @@
11841190 }
11851191 return ( $benchmarks >= $needed );
11861192 }
1187 -
 1193+
11881194 /**
11891195 * Checks if $user was previously blocked
11901196 */
@@ -1199,7 +1205,7 @@
12001206 array( 'USE INDEX' => 'page_time' )
12011207 );
12021208 }
1203 -
 1209+
12041210 /**
12051211 * Check for 'autoreview' permission. This lets people who opt-out as
12061212 * Editors still have their own edits automatically reviewed. Bot
@@ -1535,7 +1541,7 @@
15361542
15371543 return true;
15381544 }
1539 -
 1545+
15401546 /**
15411547 * Record demotion so that auto-promote will be disabled
15421548 */
@@ -1555,7 +1561,7 @@
15561562 }
15571563 return true;
15581564 }
1559 -
 1565+
15601566 /** Add user preferences */
15611567 public static function onGetPreferences( $user, &$preferences ) {
15621568 // Box or bar UI
@@ -1602,17 +1608,18 @@
16031609 }
16041610 return true;
16051611 }
1606 -
 1612+
16071613 public static function logLineLinks(
1608 - $type, $action, $title = null, $params, &$comment, &$rv, $ts
 1614+ $type, $action, $title, $params, &$comment, &$rv, $ts
16091615 ) {
16101616 if ( !$title ) {
1611 - return true; // nothing to do
 1617+ return true; // sanity check
 1618+ }
16121619 // Stability log
1613 - } else if ( $type == 'stable' ) {
 1620+ if ( $type == 'stable' && FlaggedRevsLogs::isStabilityAction( $action ) ) {
16141621 $rv .= FlaggedRevsLogs::stabilityLogLinks( $title, $ts, $params );
16151622 // Review log
1616 - } else if ( $type == 'review' && FlaggedRevsLogs::isReviewAction( $action ) ) {
 1623+ } elseif ( $type == 'review' && FlaggedRevsLogs::isReviewAction( $action ) ) {
16171624 $rv .= FlaggedRevsLogs::reviewLogLinks( $action, $title, $params );
16181625 }
16191626 return true;
@@ -1651,7 +1658,7 @@
16521659 $view->setPageContent( $outputDone, $pcache );
16531660 return true;
16541661 }
1655 -
 1662+
16561663 public static function overrideRedirect(
16571664 &$title, $request, &$ignoreRedirect, &$target, &$article
16581665 ) {
@@ -1690,31 +1697,31 @@
16911698 }
16921699 return true;
16931700 }
1694 -
 1701+
16951702 public static function addToEditView( &$editPage ) {
16961703 $view = FlaggedArticleView::singleton();
16971704 $view->addToEditView( $editPage );
16981705 return true;
16991706 }
1700 -
 1707+
17011708 public static function onNoSuchSection( &$editPage, &$s ) {
17021709 $view = FlaggedArticleView::singleton();
17031710 $view->addToNoSuchSection( $editPage, $s );
17041711 return true;
17051712 }
1706 -
 1713+
17071714 public static function addToHistView( &$article ) {
17081715 $view = FlaggedArticleView::singleton();
17091716 $view->addToHistView();
17101717 return true;
17111718 }
1712 -
 1719+
17131720 public static function onCategoryPageView( &$category ) {
17141721 $view = FlaggedArticleView::singleton();
17151722 $view->addToCategoryView();
17161723 return true;
17171724 }
1718 -
 1725+
17191726 public static function onSkinAfterContent( &$data ) {
17201727 global $wgOut;
17211728 if ( $wgOut->isArticleRelated()
@@ -1727,7 +1734,7 @@
17281735 }
17291736 return true;
17301737 }
1731 -
 1738+
17321739 public static function addToHistQuery( $pager, &$queryInfo ) {
17331740 $flaggedArticle = FlaggedArticle::getArticleInstance( $pager->getArticle() );
17341741 # Non-content pages cannot be validated. Stable version must exist.
@@ -1748,7 +1755,7 @@
17491756 }
17501757 return true;
17511758 }
1752 -
 1759+
17531760 public static function addToFileHistQuery(
17541761 $file, &$tables, &$fields, &$conds, &$opts, &$join_conds
17551762 ) {
@@ -1767,7 +1774,7 @@
17681775 }
17691776 return true;
17701777 }
1771 -
 1778+
17721779 public static function addToContribsQuery( $pager, &$queryInfo ) {
17731780 # Highlight flaggedrevs
17741781 $queryInfo['tables'][] = 'flaggedrevs';
@@ -1780,13 +1787,13 @@
17811788 $queryInfo['join_conds']['flaggedpages'] = array( 'LEFT JOIN', "fp_page_id = rev_page" );
17821789 return true;
17831790 }
1784 -
 1791+
17851792 public static function addToRCQuery( &$conds, &$tables, &$join_conds, $opts ) {
17861793 $tables[] = 'flaggedpages';
17871794 $join_conds['flaggedpages'] = array( 'LEFT JOIN', 'fp_page_id = rc_cur_id' );
17881795 return true;
17891796 }
1790 -
 1797+
17911798 public static function addToWatchlistQuery( &$conds, &$tables, &$join_conds, &$fields ) {
17921799 global $wgUser;
17931800 if ( $wgUser->isAllowed( 'review' ) ) {
@@ -1796,7 +1803,7 @@
17971804 }
17981805 return true;
17991806 }
1800 -
 1807+
18011808 public static function addToHistLine( $history, $row, &$s, &$liClasses ) {
18021809 $fa = FlaggedArticle::getArticleInstance( $history->getArticle() );
18031810 if ( !$fa->isReviewable() ) {
@@ -1838,8 +1845,7 @@
18391846 if ( $link ) $s .= " <small>$link</small>";
18401847 return true;
18411848 }
1842 -
1843 -
 1849+
18441850 /**
18451851 * Make stable version link and return the css
18461852 * @param Title $title
@@ -1873,7 +1879,7 @@
18741880 $link = "<span class='$css plainlinks'>[$link]</span>";
18751881 return array( $link, $liCss );
18761882 }
1877 -
 1883+
18781884 public static function addToFileHistLine( $hist, $file, &$s, &$rowClass ) {
18791885 if ( !$file->isVisible() ) {
18801886 return true; // Don't bother showing notice for deleted revs
@@ -1896,7 +1902,7 @@
18971903 }
18981904 return true;
18991905 }
1900 -
 1906+
19011907 public static function addToContribsLine( $contribs, &$ret, $row ) {
19021908 $namespaces = FlaggedRevs::getReviewNamespaces();
19031909 if ( !in_array( $row->page_namespace, $namespaces ) ) {
@@ -1911,7 +1917,7 @@
19121918 }
19131919 return true;
19141920 }
1915 -
 1921+
19161922 public static function addToChangeListLine(
19171923 &$list, &$articlelink, &$s, &$rc, $unpatrolled, $watched
19181924 ) {
@@ -1944,13 +1950,13 @@
19451951 }
19461952 return true;
19471953 }
1948 -
 1954+
19491955 public static function injectPostEditURLParams( $article, &$sectionAnchor, &$extraQuery ) {
19501956 $view = FlaggedArticleView::singleton();
19511957 $view->injectPostEditURLParams( $sectionAnchor, $extraQuery );
19521958 return true;
19531959 }
1954 -
 1960+
19551961 // diff=review param (bug 16923)
19561962 public static function checkDiffUrl( $titleObj, &$mOldid, &$mNewid, $old, $new ) {
19571963 if ( $new === 'review' && isset( $titleObj ) ) {
@@ -1976,7 +1982,7 @@
19771983 $view->addRevisionIDField( $editPage, $out );
19781984 return true;
19791985 }
1980 -
 1986+
19811987 public static function addReviewCheck( $editPage, &$checkboxes, &$tabindex ) {
19821988 global $wgUser, $wgRequest;
19831989 if ( !$wgUser->isAllowed( 'review' ) ) {
@@ -2001,7 +2007,7 @@
20022008 }
20032009 return true;
20042010 }
2005 -
 2011+
20062012 public static function addBacklogNotice( &$notice ) {
20072013 global $wgUser, $wgTitle;
20082014 $namespaces = FlaggedRevs::getReviewNamespaces();
@@ -2054,7 +2060,7 @@
20552061 }
20562062 return true;
20572063 }
2058 -
 2064+
20592065 public static function stableDumpQuery( &$tables, &$opts, &$join ) {
20602066 $namespaces = FlaggedRevs::getReviewNamespaces();
20612067 $tables = array( 'flaggedpages', 'page', 'revision' );
@@ -2066,12 +2072,12 @@
20672073 $join['revision'] = array( 'INNER JOIN', 'rev_page = fp_page_id AND rev_id = fp_stable' );
20682074 return false; // final
20692075 }
2070 -
 2076+
20712077 // Add selector of review "protection" options
20722078 // Code stolen from Stabilization (which was stolen from ProtectionForm)
20732079 public static function onProtectionForm( $article, &$output ) {
20742080 global $wgUser, $wgRequest, $wgLang;
2075 - if ( !FlaggedRevs::useProtectionLevels() || !$article->exists() ) {
 2081+ if ( !$article->exists() ) {
20762082 return true; // nothing to do
20772083 } elseif ( !FlaggedRevs::inReviewNamespace( $article->getTitle() ) ) {
20782084 return true; // not a reviewable page
@@ -2086,7 +2092,7 @@
20872093 $oldExpirySelect = ( $config['expiry'] == 'infinity' ) ? 'infinite' : 'existing';
20882094
20892095 # Load requested restriction level, default to current level...
2090 - $restriction = $wgRequest->getVal( 'mwStabilityConfig',
 2096+ $restriction = $wgRequest->getVal( 'mwStabilityLevel',
20912097 FlaggedRevs::getProtectionLevel( $config ) );
20922098 # Load the requested expiry time (dropdown)
20932099 $expirySelect = $wgRequest->getVal( 'mwStabilizeExpirySelection', $oldExpirySelect );
@@ -2105,8 +2111,8 @@
21062112 array_unshift( $effectiveLevels, "none" );
21072113 # Show all restriction levels in a <select>...
21082114 $attribs = array(
2109 - 'id' => 'mwStabilityConfig',
2110 - 'name' => 'mwStabilityConfig',
 2115+ 'id' => 'mwStabilityLevel',
 2116+ 'name' => 'mwStabilityLevel',
21112117 'size' => count( $effectiveLevels ),
21122118 ) + $disabledAttrib;
21132119 $output .= Xml::openElement( 'select', $attribs );
@@ -2190,15 +2196,15 @@
21912197 # Close field set and table row
21922198 $output .= Xml::closeElement( 'fieldset' );
21932199 $output .= "</td></tr>";
2194 -
2195 - # Add some script for expiry dropdowns
2196 - Stabilization::addProtectionJS();
 2200+
 2201+ # Add some javascript for expiry dropdowns
 2202+ PageStabilityProtectForm::addProtectionJS();
21972203 return true;
21982204 }
21992205
22002206 // Add stability log extract to protection form
22012207 public static function insertStabilityLog( $article, $out ) {
2202 - if ( !FlaggedRevs::useProtectionLevels() || !$article->exists() ) {
 2208+ if ( !$article->exists() ) {
22032209 return true; // nothing to do
22042210 } else if ( !FlaggedRevs::inReviewNamespace( $article->getTitle() ) ) {
22052211 return true; // not a reviewable page
@@ -2212,36 +2218,27 @@
22132219 // Update stability config from request
22142220 public static function onProtectionSave( $article, &$errorMsg ) {
22152221 global $wgUser, $wgRequest;
2216 - if ( !FlaggedRevs::useProtectionLevels() || !$article->exists() ) {
 2222+ if ( !$article->exists() ) {
22172223 return true; // simple custom levels set for action=protect
2218 - }
2219 - if ( !FlaggedRevs::inReviewNamespace( $article->getTitle() ) ) {
 2224+ } elseif ( !FlaggedRevs::inReviewNamespace( $article->getTitle() ) ) {
22202225 return true; // not a reviewable page
2221 - }
2222 - if ( wfReadOnly() || !$wgUser->isAllowed( 'stablesettings' ) ) {
 2226+ } elseif ( wfReadOnly() || !$wgUser->isAllowed( 'stablesettings' ) ) {
22232227 return true; // user cannot change anything
22242228 }
2225 - $form = new Stabilization();
2226 - $form->target = $article->getTitle(); # Our target page
2227 - $form->watchThis = null; # protection form already has a watch check
2228 - $form->reason = $wgRequest->getText( 'mwProtect-reason' ); # Reason
2229 - $form->reasonSelection = $wgRequest->getVal( 'wpProtectReasonSelection' ); # Reason dropdown
2230 - $form->expiry = $wgRequest->getVal( 'mwStabilizeExpiryOther' ); # Expiry
2231 - $form->expirySelection = $wgRequest->getVal( 'mwStabilizeExpirySelection' ); # Expiry dropdown
2232 - # Fill in config from the protection level...
2233 - $permission = $wgRequest->getVal( 'mwStabilityConfig' );
 2229+ $form = new PageStabilityProtectForm();
 2230+ $form->setPage( $article->getTitle() ); // target page
 2231+ $permission = $wgRequest->getVal( 'mwStabilityLevel' );
22342232 if ( $permission == "none" ) {
2235 - $form->autoreview = ''; // default
2236 - } else if ( in_array( $permission, FlaggedRevs::getRestrictionLevels() ) ) {
2237 - $form->autoreview = $permission; // autoreview restriction
2238 - } else {
2239 - return false; // bad level, don't save!
 2233+ $permission = ''; // 'none' => ''
22402234 }
2241 - $form->reviewThis = null; // autoreview if not currently protected state
2242 - $form->override = null; // implied by autoreview level
2243 - $form->select = null; // site default
2244 - $form->wasPosted = $wgRequest->wasPosted();
2245 - if ( $form->handleParams() ) {
 2235+ $form->setAutoreview( $permission ); // protection level (autoreview restriction)
 2236+ $form->setWatchThis( null ); // protection form already has a watch check
 2237+ $form->setReason( $wgRequest->getText( 'mwProtect-reason' ) ); // manual
 2238+ $form->setReasonSelection( $wgRequest->getVal( 'wpProtectReasonSelection' ) ); // dropdown
 2239+ $form->setExpiry( $wgRequest->getVal( 'mwStabilizeExpiryOther' ) ); // manual
 2240+ $form->setExpirySelection( $wgRequest->getVal( 'mwStabilizeExpirySelection' ) ); // dropdown
 2241+ $form->ready(); // params all set
 2242+ if ( $wgRequest->wasPosted() && $form->isAllowed() ) {
22462243 $status = $form->submit();
22472244 if ( $status !== true ) {
22482245 $errorMsg = wfMsg( $status ); // some error message
@@ -2261,7 +2258,7 @@
22622259 $tables[] = 'flaggedrevs_tracking';
22632260 return true;
22642261 }
2265 -
 2262+
22662263 public static function addSchemaUpdates() {
22672264 global $wgDBtype, $wgExtNewFields, $wgExtPGNewFields, $wgExtNewIndexes, $wgExtNewTables;
22682265 $base = dirname( __FILE__ );
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevsLogs.php
@@ -3,13 +3,21 @@
44 class FlaggedRevsLogs {
55 /**
66 * $action is a valid review log action
7 - * @returns bool $action is a valid review log action
 7+ * @returns bool
88 */
99 public static function isReviewAction( $action ) {
1010 return preg_match( '/^(approve2?(-i|-a|-ia)?|unapprove2?)$/', $action );
1111 }
1212
1313 /**
 14+ * $action is a valid stability log action
 15+ * @returns bool
 16+ */
 17+ public static function isStabilityAction( $action ) {
 18+ return preg_match( '/^(config|modify|reset)$/', $action );
 19+ }
 20+
 21+ /**
1422 * $action is a valid review log deprecate action
1523 * @returns bool
1624 */
@@ -17,9 +25,33 @@
1826 return ( $action == 'unapprove' || $action == 'unapprove2' );
1927 }
2028
 29+ /**
 30+ * Add setting change description to log line
 31+ * @returns string
 32+ */
 33+ public static function stabilityLogText(
 34+ $type, $action, $title = null, $skin = null, $params = array()
 35+ ) {
 36+ if ( !$title ) {
 37+ return ''; // sanity check
 38+ }
 39+ $text = '';
 40+ if ( $skin ) {
 41+ $titleLink = $skin->link( $title, $title->getPrefixedText() );
 42+ $text = wfMsgHtml( "stable-logentry-{$action}", $titleLink );
 43+ } else { // for content (e.g. IRC...)
 44+ $text = wfMsgExt( "stable-logentry-{$action}",
 45+ array( 'parsemag', 'escape', 'replaceafter', 'content' ),
 46+ $title->getPrefixedText() );
 47+ }
 48+ $pars = self::expandParams( $params ); // list -> assoc array
 49+ $details = self::stabilitySettings( $pars, !$skin ); // list of setting values
 50+ $text .= " $details";
 51+ return $text;
 52+ }
 53+
2154 /**
22 - * (a) Add setting change description
23 - * (b) Add history page link
 55+ * Add history page link to log line
2456 *
2557 * @param Title $title
2658 * @param string $timestamp
@@ -28,8 +60,6 @@
2961 */
3062 public static function stabilityLogLinks( $title, $timestamp, $params ) {
3163 global $wgUser;
32 - $pars = self::expandParams( $params ); // list -> assoc array
33 - $settings = self::stabilitySettings( $pars, false ); // list of setting values
3464 # Add history link showing edits right before the config change
3565 $hist = $wgUser->getSkin()->link(
3666 $title,
@@ -38,7 +68,7 @@
3969 array( 'action' => 'history', 'offset' => $timestamp )
4070 );
4171 $hist = wfMsgHtml( 'parentheses', $hist );
42 - return "$settings $hist";
 72+ return $hist;
4373 }
4474
4575 /**
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/api/ApiReview.php
@@ -35,51 +35,36 @@
3636 public function execute() {
3737 global $wgUser;
3838 $params = $this->extractRequestParams();
39 -
40 - // Check permissions
41 - if ( !$wgUser->isAllowed( 'review' ) )
 39+ // Check basic permissions
 40+ if ( !$wgUser->isAllowed( 'review' ) ) {
 41+ // FIXME: better msg?
4242 $this->dieUsageMsg( array( 'badaccess-group0' ) );
43 - if ( $wgUser->isBlocked() )
 43+ } elseif ( $wgUser->isBlocked( false ) ) {
4444 $this->dieUsageMsg( array( 'blockedtext' ) );
45 -
 45+ }
4646 // Construct submit form
47 - $form = new RevisionReview();
48 - $revid = intval( $params['revid'] );
 47+ $form = new RevisionReviewForm();
 48+ $revid = (int)$params['revid'];
4949 $rev = Revision::newFromId( $revid );
50 - if ( !$rev )
 50+ if ( !$rev ) {
5151 $this->dieUsage( "Cannot find a revision with the specified ID.", 'notarget' );
52 - $form->oldid = $revid;
 52+ }
5353 $title = $rev->getTitle();
54 - $form->page = $title;
55 - if ( !FlaggedRevs::inReviewNamespace( $title ) )
56 - $this->dieUsage( "Provided revision or page can not be reviewed.", 'notreviewable' );
57 -
58 - if ( isset( $params['unapprove'] ) )
59 - $form->approve = !$params['unapprove'];
 54+ $form->setPage( $title );
 55+ $form->setOldId( $revid );
 56+ if ( FlaggedRevs::dimensionsEmpty() ) {
 57+ $form->setApprove( empty( $params['unapprove'] ) );
 58+ $form->setUnapprove( !empty( $params['unapprove'] ) );
 59+ }
6060 if ( isset( $params['comment'] ) )
61 - $form->comment = $params['comment'];
 61+ $form->setComment( $params['comment'] );
6262 if ( isset( $params['notes'] ) )
63 - $form->notes = $wgUser->isAllowed( 'validate' ) ? $params['notes'] : '';
64 -
 63+ $form->setNotes( $params['notes'] );
6564 // The flagging parameters have the form 'flag_$name'.
6665 // Extract them and put the values into $form->dims
67 - $flags = FlaggedRevs::getDimensions();
68 - foreach ( $flags as $name => $levels ) {
69 - if ( !( $form->dims[$name] = intval( $params['flag_' . $name] ) ) )
70 - $form->unapprovedTags++;
 66+ foreach ( FlaggedRevs::getDimensions() as $tag => $levels ) {
 67+ $form->setDim( $tag, intval( $params['flag_' . $tag] ) );
7168 }
72 -
73 - // Check if this is a valid approval/unapproval of the revision
74 - if ( $form->unapprovedTags && $form->unapprovedTags < count( $flags ) )
75 - $this->dieUsage( "Either all or none of the flags have to be set to zero.", 'mixedapproval' );
76 -
77 - // Check if user is even allowed to set the flags
78 - $form->oflags = FlaggedRevs::getRevisionTags( $title, $form->oldid );
79 - $fa = FlaggedArticle::getTitleInstance( $form->page );
80 - $form->config = $fa->getVisibilitySettings();
81 - if ( !$title->quickUserCan( 'edit' ) || !RevisionReview::userCanSetFlags( $form->dims, $form->oflags, $form->config ) )
82 - $this->dieUsage( "You don't have the necessary rights to set the specified flags.", 'permissiondenied' );
83 -
8469 if ( $form->isApproval() ) {
8570 // Now get the template and image parameters needed
8671 // If it is the current revision, try the parser cache first
@@ -96,20 +81,51 @@
9782 $parserOutput = $wgParser->parse( $text, $title, $options );
9883 }
9984 // Set version parameters for review submission
100 - list( $form->templateParams, $form->imageParams, $form->fileVersion ) =
101 - FlaggedRevs::getIncludeParams( $article, $parserOutput->mTemplateIds, $parserOutput->fr_ImageSHA1Keys );
 85+ list( $templateParams, $imageParams, $fileVersion ) =
 86+ FlaggedRevs::getIncludeParams( $article,
 87+ $parserOutput->mTemplateIds, $parserOutput->fr_ImageSHA1Keys );
 88+ $form->setTemplateParams( $templateParams );
 89+ $form->setFileParams( $imageParams );
 90+ $form->setFileVersion( $fileVersion );
10291 }
103 -
104 - // Do the actual review
105 - list( $approved, $status ) = $form->submit();
 92+
 93+ $status = $form->ready(); // all params set
 94+ if ( $status === 'review_page_unreviewable' ) {
 95+ $this->dieUsage( "Provided revision or page can not be reviewed.",
 96+ 'notreviewable' );
 97+ // Check basic page permissions
 98+ } elseif ( !$title->quickUserCan( 'review' ) || !$title->quickUserCan( 'edit' ) ) {
 99+ $this->dieUsage( "You don't have the necessary rights to set the specified flags.",
 100+ 'permissiondenied' );
 101+ }
 102+
 103+ # Try to do the actual review
 104+ $status = $form->submit();
 105+ # Approve/de-approve success
106106 if ( $status === true ) {
107 - $this->getResult()->addValue( null, $this->getModuleName(), array( 'result' => 'Success' ) );
108 - } elseif ( $approved && is_array( $status ) ) {
109 - $this->dieUsage( "A sync failure has occured while reviewing. Please try again.", 'syncfailure' );
110 - } elseif ( $approved ) {
111 - $this->dieUsage( "Cannot find a revision with the specified ID.", 'notarget' );
 107+ $this->getResult()->addValue(
 108+ null, $this->getModuleName(), array( 'result' => 'Success' ) );
 109+ # De-approve failure
 110+ } elseif ( !$form->isApproval() ) {
 111+ $this->dieUsage( "Cannot find a flagged revision with the specified ID.", 'notarget' );
 112+ # Approval failures
112113 } else {
113 - $this->dieUsageMsg( array( 'unknownerror' ) );
 114+ if ( is_array( $status ) ) {
 115+ $this->dieUsage( "A sync failure has occured while reviewing. Please try again.",
 116+ 'syncfailure' );
 117+ } elseif ( $status === 'review_too_low' ) {
 118+ $this->dieUsage( "Either all or none of the flags have to be set to zero.",
 119+ 'mixedapproval' );
 120+ } elseif ( $status === 'review_denied' ) {
 121+ $this->dieUsage( "You don't have the necessary rights to set the specified flags.",
 122+ 'permissiondenied' );
 123+ } elseif ( $status === 'review_bad_key' ) {
 124+ $this->dieUsage( "You don't have the necessary rights to set the specified flags.",
 125+ 'permissiondenied' );
 126+ } else {
 127+ // FIXME: review_param_missing? better msg?
 128+ $this->dieUsage( array( 'unknownerror' ) );
 129+ }
114130 }
115131 }
116132
@@ -123,8 +139,8 @@
124140
125141 public function getAllowedParams() {
126142 $pars = array(
127 - 'revid' => null,
128 - 'token' => null,
 143+ 'revid' => null,
 144+ 'token' => null,
129145 'comment' => null,
130146 );
131147 if ( FlaggedRevs::allowComments() )
@@ -144,16 +160,19 @@
145161
146162 public function getParamDescription() {
147163 $desc = array(
148 - 'revid' => 'The revision ID for which to set the flags',
149 - 'token' => 'An edit token retrieved through prop=info',
150 - 'comment' => 'Comment for the review (optional)',
151 - // Only if FlaggedRevs::allowComments() is true:
152 - 'notes' => "Additional notes for the review. The ``validate'' right is needed to set this parameter.",
153 - // Will only show if FlaggedRevs::dimensionsEmpty() is true:
154 - 'unapprove' => "If set, revision will be unapproved"
 164+ 'revid' => 'The revision ID for which to set the flags',
 165+ 'token' => 'An edit token retrieved through prop=info',
 166+ 'comment' => 'Comment for the review (optional)'
155167 );
156 - foreach ( FlaggedRevs::getDimensions() as $flagname => $levels )
157 - $desc['flag_' . $flagname] = "Set the flag ''{$flagname}'' to the specified value";
 168+ if ( FlaggedRevs::allowComments() )
 169+ $desc['notes'] = "Additional notes for the review. The ''validate'' right is needed to set this parameter.";
 170+ if ( FlaggedRevs::dimensionsEmpty() ) {
 171+ $desc['unapprove'] = "If set, revision will be unapproved rather than approved.";
 172+ } else {
 173+ foreach ( FlaggedRevs::getDimensions() as $flagname => $levels ) {
 174+ $desc['flag_' . $flagname] = "Set the flag ''{$flagname}'' to the specified value";
 175+ }
 176+ }
158177 return $desc;
159178 }
160179
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/api/ApiStabilize.php
@@ -31,86 +31,68 @@
3232 global $wgUser, $wgContLang;
3333 $params = $this->extractRequestParams();
3434
35 - if ( !isset( $params['title'] ) )
 35+ if ( !isset( $params['title'] ) ) {
3636 $this->dieUsageMsg( array( 'missingparam', 'title' ) );
37 - if ( !isset( $params['token'] ) )
 37+ } elseif ( !isset( $params['token'] ) ) {
3838 $this->dieUsageMsg( array( 'missingparam', 'token' ) );
 39+ }
3940
4041 $title = Title::newFromText( $params['title'] );
4142 if ( $title == null ) {
4243 $this->dieUsage( "Invalid title given.", "invalidtitle" );
4344 }
44 - if ( !FlaggedRevs::inReviewNamespace( $title ) ) {
45 - $this->dieUsage( "Title given does not correspond to a reviewable page.", "invalidtitle" );
46 - }
4745 $errors = $title->getUserPermissionsErrors( 'stablesettings', $wgUser );
4846 if ( $errors ) {
4947 // We don't care about multiple errors, just report one of them
5048 $this->dieUsageMsg( reset( $errors ) );
5149 }
52 -
53 - $article = new Article( $title );
54 - if ( !$article->exists() ) {
55 - $this->dieUsage( "Target page does not exist.", "invalidtitle" );
56 - }
 50+ // TODO: factory function?
 51+ $form = FlaggedRevs::useProtectionLevels()
 52+ ? new PageStabilityProtectForm()
 53+ : new PageStabilityGeneralForm();
5754
58 - $form = new Stabilization();
59 - $form->target = $title; # Our target page
60 - $form->watchThis = $params['watch']; # Watch this page
61 - $form->reviewThis = $params['review']; # Auto-review option
62 - $form->reason = $params['reason']; # Reason
63 - $form->reasonSelection = 'other'; # Reason dropdown
64 - $form->expiry = $params['expiry']; # Expiry
65 - $form->expirySelection = 'other'; # Expiry dropdown
66 -
67 - // Check if protection levels are enabled
 55+ $form->setPage( $title ); # Our target page
 56+ $form->setWatchThis( $params['watch'] ); # Watch this page
 57+ $form->setReason( $params['reason'] ); # Reason
 58+ $form->setReasonSelection( 'other' ); # Reason dropdown
 59+ $form->setExpiry( $params['expiry'] ); # Expiry
 60+ $form->setExpirySelection( 'other' ); # Expiry dropdown
6861 if ( FlaggedRevs::useProtectionLevels() ) {
69 - $levels = FlaggedRevs::getRestrictionLevels();
70 - # Fill in config from the protection level...
71 - $selected = $params['protectlevel'];
72 - if ( $selected == "none" ) {
73 - $form->autoreview = ''; // default
74 - } else if ( in_array( $selected, $levels ) ) {
75 - $form->autoreview = $selected; // autoreview restriction
76 - } else {
77 - $this->dieUsage( "Invalid protection level given.", 'badprotectlevel' );
78 - }
79 - $form->override = null; // implied by autoreview level
80 - $form->select = null; // site default
 62+ $restriction = $params['protectlevel'];
8163 } else {
 64+ $restriction = $params['autoreview'];
8265 // Fill in config fields from URL params
83 - $form->select = $this->precendenceFromKey( $params['precedence'] );
 66+ $form->setPrecedence( $this->precendenceFromKey( $params['precedence'] ) );
8467 if ( $params['default'] === null ) {
 68+ // Default version setting not optional
8569 $this->dieUsageMsg( array( 'missingparam', 'default' ) );
8670 } else {
87 - $form->override = $this->defaultFromKey( $params['default'] );
 71+ $form->setOverride( $this->defaultFromKey( $params['default'] ) );
8872 }
89 - if ( $params['autoreview'] == 'none' ) {
90 - $form->autoreview = ''; // 'none' -> ''
91 - } else {
92 - $form->autoreview = $params['autoreview'];
93 - }
 73+ $form->setReviewThis( $params['review'] ); # Auto-review option
9474 }
95 - $form->wasPosted = true; // already validated
96 - if ( $form->handleParams() ) {
97 - $status = $form->submit(); // true/error message key
98 - if ( $status !== true ) {
99 - $this->dieUsage( wfMsg( $status ) );
100 - }
101 - } else {
102 - $this->dieUsage( "Invalid config parameters given. The precendence level may beyond your rights.", 'invalidconfig' );
 75+ if ( $restriction == 'none' ) {
 76+ $restriction = ''; // 'none' => ''
10377 }
 78+ $form->setAutoreview( $restriction ); # Autoreview restriction
 79+ $form->ready();
 80+
 81+ $status = $form->submit(); // true/error message key
 82+ if ( $status !== true ) {
 83+ $this->dieUsage( wfMsg( $status ) );
 84+ }
 85+
10486 # Output success line with the title and config parameters
10587 $res = array();
10688 $res['title'] = $title->getPrefixedText();
107 - if ( count( $levels ) ) {
 89+ if ( FlaggedRevs::useProtectionLevels() ) {
10890 $res['protectlevel'] = $params['protectlevel'];
10991 } else {
11092 $res['default'] = $params['default'];
11193 $res['precedence'] = $params['precedence'];
11294 $res['autoreview'] = $params['autoreview'];
11395 }
114 - $res['expiry'] = $form->expiry;
 96+ $res['expiry'] = $form->getExpiry();
11597 $this->getResult()->addValue( null, $this->getModuleName(), $res );
11698 }
11799
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedArticleView.php
@@ -159,10 +159,10 @@
160160 $tag = wfMsgExt( $msg, array( 'parseinline' ), $frev->getRevId(), $time );
161161 # Hide clutter
162162 if ( !FlaggedRevs::useSimpleUI() && !empty( $flags ) ) {
163 - $tag .= " " . FlaggedRevsXML::ratingToggle() .
164 - "<span id='mw-fr-revisionratings' style='display:block;'><br />" .
 163+ $tag .= FlaggedRevsXML::ratingToggle() .
 164+ "<div id='mw-fr-revisiondetails' style='display:block;'>" .
165165 wfMsgHtml( 'revreview-oldrating' ) .
166 - FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
 166+ FlaggedRevsXML::addTagRatings( $flags ) . '</div>';
167167 }
168168 $css = 'flaggedrevs_notice plainlinks noprint';
169169 $tag = "<div id='mw-fr-revisiontag-old' class='$css'>$tag</div>";
@@ -269,17 +269,26 @@
270270 } else {
271271 $this->showDraftVersion( $srev, $tag, $prot );
272272 }
 273+ $encJS = ''; // JS events to use
273274 # Some checks for which tag CSS to use
274 - if ( FlaggedRevs::useSimpleUI() ) $tagClass = 'flaggedrevs_short';
275 - elseif ( $simpleTag ) $tagClass = 'flaggedrevs_notice';
276 - elseif ( $pristine ) $tagClass = 'flaggedrevs_pristine';
277 - elseif ( $quality ) $tagClass = 'flaggedrevs_quality';
278 - else $tagClass = 'flaggedrevs_basic';
 275+ if ( FlaggedRevs::useSimpleUI() ) {
 276+ $tagClass = 'flaggedrevs_short';
 277+ # Collapse the box details on mouseOut
 278+ $encJS .= ' onMouseOut="FlaggedRevs.onBoxMouseOut(event)"';
 279+ } elseif ( $simpleTag ) {
 280+ $tagClass = 'flaggedrevs_notice';
 281+ } elseif ( $pristine ) {
 282+ $tagClass = 'flaggedrevs_pristine';
 283+ } elseif ( $quality ) {
 284+ $tagClass = 'flaggedrevs_quality';
 285+ } else {
 286+ $tagClass = 'flaggedrevs_basic';
 287+ }
279288 # Wrap tag contents in a div
280289 if ( $tag != '' ) {
281290 $rtl = $wgContLang->isRTL() ? " rtl" : ""; // RTL langauges
282291 $css = "{$tagClass}{$rtl} plainlinks noprint";
283 - $notice = "<div id=\"mw-fr-revisiontag\" class=\"$css\">$tag</div>\n";
 292+ $notice = "<div id=\"mw-fr-revisiontag\" class=\"{$css}\"{$encJS}>{$tag}</div>\n";
284293 $this->reviewNotice .= $notice;
285294 }
286295 return true;
@@ -478,14 +487,14 @@
479488 $msg = $quality
480489 ? 'revreview-quality-old'
481490 : 'revreview-basic-old';
482 - $tag = $prot . $icon .
483 - wfMsgExt( $msg, array( 'parseinline' ), $frev->getRevId(), $time );
 491+ $tag = $prot . $icon;
 492+ $tag .= wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $time );
484493 # Hide clutter
485494 if ( !empty( $flags ) ) {
486 - $tag .= " " . FlaggedRevsXML::ratingToggle();
487 - $tag .= "<span id='mw-fr-revisionratings' style='display:block;'><br />" .
 495+ $tag .= FlaggedRevsXML::ratingToggle();
 496+ $tag .= "<div id='mw-fr-revisiondetails' style='display:block;'>" .
488497 wfMsgHtml( 'revreview-oldrating' ) .
489 - FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
 498+ FlaggedRevsXML::addTagRatings( $flags ) . '</div>';
490499 }
491500 }
492501 }
@@ -565,12 +574,12 @@
566575 # uses messages 'revreview-quality-i', 'revreview-basic-i'
567576 $msg .= '-i';
568577 }
569 - $tag = $prot . $icon .
570 - wfMsgExt( $msg, array( 'parseinline' ), $srev->getRevId(), $time, $revsSince );
 578+ $tag = $prot . $icon;
 579+ $tag .= wfMsgExt( $msg, 'parseinline', $srev->getRevId(), $time, $revsSince );
571580 if ( !empty( $flags ) ) {
572 - $tag .= " " . FlaggedRevsXML::ratingToggle();
573 - $tag .= "<span id='mw-fr-revisionratings' style='display:block;'><br />" .
574 - FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
 581+ $tag .= FlaggedRevsXML::ratingToggle();
 582+ $tag .= "<div id='mw-fr-revisiondetails' style='display:block;'>" .
 583+ FlaggedRevsXML::addTagRatings( $flags ) . '</div>';
575584 }
576585 }
577586 }
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/client/flaggedrevs.css
@@ -119,9 +119,9 @@
120120 div.flaggedrevs_short_details {
121121 border: 1px solid #aaa;
122122 background-color: #f9f9f9;
123 - padding: 4px;
 123+ padding: 5px;
124124 position: absolute;
125 - top: 0;
 125+ top: -1px;
126126 right: 0;
127127 width: 25em;
128128 }
@@ -192,6 +192,7 @@
193193 font-family: monospace;
194194 font-weight: bold;
195195 cursor: pointer;
 196+ margin: 0 .3em 0 .3em;
196197 }
197198
198199 a.fr-toggle-text {
@@ -260,8 +261,9 @@
261262 background-color: #faebd7;
262263 }
263264
264 -.fr-under-review {
 265+span.fr-under-review {
265266 background-color: yellow;
 267+ font-weight: bold;
266268 }
267269
268270 .mw-fr-reviewlink {
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/client/flaggedrevs.js
@@ -19,7 +19,7 @@
2020 var toggle = document.getElementById('mw-fr-revisiontoggle');
2121 if( toggle ) {
2222 toggle.style.display = 'inline';
23 - var ratings = document.getElementById('mw-fr-revisionratings');
 23+ var ratings = document.getElementById('mw-fr-revisiondetails');
2424 if( ratings ) {
2525 ratings.style.display = 'none';
2626 }
@@ -44,9 +44,9 @@
4545 }
4646 },
4747
48 - /* Expands ratings */
 48+ /* Expands flag info box details */
4949 'showBoxDetails': function() {
50 - var ratings = document.getElementById('mw-fr-revisionratings');
 50+ var ratings = document.getElementById('mw-fr-revisiondetails');
5151 if( !ratings ) return;
5252 var toggle = document.getElementById('mw-fr-revisiontoggle');
5353 if( !toggle ) return;
@@ -54,9 +54,9 @@
5555 toggle.innerHTML = this.messages.toggleHide;
5656 },
5757
58 - /* Collapses ratings */
59 - 'hideBoxDetails': function() {
60 - var ratings = document.getElementById('mw-fr-revisionratings');
 58+ /* Collapses flag info box details */
 59+ 'hideBoxDetails': function( event ) {
 60+ var ratings = document.getElementById('mw-fr-revisiondetails');
6161 if( !ratings ) return;
6262 var toggle = document.getElementById('mw-fr-revisiontoggle');
6363 if( !toggle ) return;
@@ -64,9 +64,9 @@
6565 toggle.innerHTML = this.messages.toggleShow;
6666 },
6767
68 - /* Toggles ratings */
 68+ /* Toggles flag info box details */
6969 'toggleBoxDetails': function() {
70 - var ratings = document.getElementById('mw-fr-revisionratings');
 70+ var ratings = document.getElementById('mw-fr-revisiondetails');
7171 if( !ratings ) return;
7272 // Collapsed -> expand
7373 if( ratings.style.display == 'none' ) {
@@ -77,6 +77,33 @@
7878 }
7979 },
8080
 81+ /* Hides flag info box details on mouseOut *except* for event bubbling */
 82+ 'onBoxMouseOut': function( event ) {
 83+ if( !this.isMouseOutBubble( event, 'mw-fr-revisiontag' ) ) {
 84+ this.hideBoxDetails();
 85+ }
 86+ },
 87+
 88+ /* Checks is mouseOut event is for a child of parentId */
 89+ 'isMouseOutBubble': function( event, parentId ) {
 90+ var toNode = null;
 91+ if( event.relatedTarget === undefined ) {
 92+ toNode = event.toElement; // IE
 93+ } else {
 94+ toNode = event.relatedTarget; // FF/Opera/Safari
 95+ }
 96+ if( toNode ) {
 97+ var nextParent = toNode.parentNode;
 98+ while( nextParent ) {
 99+ if( nextParent.id == parentId ) {
 100+ return true; // event bubbling
 101+ }
 102+ nextParent = nextParent.parentNode; // next up
 103+ }
 104+ }
 105+ return false;
 106+ },
 107+
81108 /* Toggles diffs */
82109 'toggleDiff': function() {
83110 var diff = document.getElementById('mw-fr-stablediff');
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevs.php
@@ -301,7 +301,7 @@
302302 $wgAvailableRights[] = 'stablesettings';
303303
304304 # Bump this number every time you change flaggedrevs.css/flaggedrevs.js
305 -$wgFlaggedRevStyleVersion = 72;
 305+$wgFlaggedRevStyleVersion = 73;
306306
307307 $wgExtensionFunctions[] = 'efLoadFlaggedRevs';
308308
@@ -332,9 +332,15 @@
333333 # Load FlaggedRevision object class
334334 $wgAutoloadClasses['FlaggedRevision'] = $dir . 'FlaggedRevision.php';
335335
336 -# Load review UI
 336+# Load review form
 337+$wgAutoloadClasses['RevisionReviewForm'] = $dir . 'forms/RevisionReviewForm.php';
 338+# Load protection/stability form
 339+$wgAutoloadClasses['PageStabilityForm'] = $dir . 'forms/PageStabilityForm.php';
 340+$wgAutoloadClasses['PageStabilityGeneralForm'] = $dir . 'forms/PageStabilityForm.php';
 341+$wgAutoloadClasses['PageStabilityProtectForm'] = $dir . 'forms/PageStabilityForm.php';
 342+
 343+# Load revision review UI
337344 $wgAutoloadClasses['RevisionReview'] = $dir . 'specialpages/RevisionReview_body.php';
338 -
339345 # Load reviewed versions UI
340346 $wgAutoloadClasses['ReviewedVersions'] = $dir . 'specialpages/ReviewedVersions_body.php';
341347 $wgExtensionMessagesFiles['ReviewedVersions'] = $langDir . 'ReviewedVersions.i18n.php';
@@ -373,6 +379,7 @@
374380 $wgAutoloadClasses['ValidationStatistics'] = $dir . 'specialpages/ValidationStatistics_body.php';
375381 $wgExtensionMessagesFiles['ValidationStatistics'] = $langDir . 'ValidationStatistics.i18n.php';
376382 $wgSpecialPageGroups['ValidationStatistics'] = 'quality';
 383+
377384 # API Modules
378385 $wgAutoloadClasses['FlaggedRevsApiHooks'] = $dir . 'api/FlaggedRevsApi.hooks.php';
379386 # OldReviewedPages for API
@@ -380,10 +387,8 @@
381388 $wgAPIListModules['oldreviewedpages'] = 'ApiQueryOldreviewedpages';
382389 # UnreviewedPages for API
383390 $wgAutoloadClasses['ApiQueryUnreviewedpages'] = $dir . 'api/ApiQueryUnreviewedpages.php';
384 -$wgAPIListModules['unreviewedpages'] = 'ApiQueryUnreviewedpages';
385391 # ReviewedPages for API
386392 $wgAutoloadClasses['ApiQueryReviewedpages'] = $dir . 'api/ApiQueryReviewedpages.php';
387 -$wgAPIListModules['reviewedpages'] = 'ApiQueryReviewedpages';
388393 # Flag metadata for pages for API
389394 $wgAutoloadClasses['ApiQueryFlagged'] = $dir . 'api/ApiQueryFlagged.php';
390395 $wgAPIPropModules['flagged'] = 'ApiQueryFlagged';
@@ -417,9 +422,6 @@
418423 $wgHooks['PageHistoryBeforeList'][] = 'FlaggedRevsHooks::addToHistView';
419424 # Add review form and visiblity settings link
420425 $wgHooks['SkinAfterContent'][] = 'FlaggedRevsHooks::onSkinAfterContent';
421 -# Add protection form field
422 -$wgHooks['ProtectionForm::buildForm'][] = 'FlaggedRevsHooks::onProtectionForm';
423 -$wgHooks['ProtectionForm::showLogExtract'][] = 'FlaggedRevsHooks::insertStabilityLog';
424426 # Mark items in page history
425427 $wgHooks['PageHistoryPager::getQueryInfo'][] = 'FlaggedRevsHooks::addToHistQuery';
426428 $wgHooks['PageHistoryLineEnding'][] = 'FlaggedRevsHooks::addToHistLine';
@@ -481,8 +483,6 @@
482484 # User edit tallies
483485 $wgHooks['ArticleRollbackComplete'][] = 'FlaggedRevsHooks::incrementRollbacks';
484486 $wgHooks['NewRevisionFromEditComplete'][] = 'FlaggedRevsHooks::incrementReverts';
485 -# Save stability settings
486 -$wgHooks['ProtectionForm::save'][] = 'FlaggedRevsHooks::onProtectionSave';
487487 # Extra cache updates for stable versions
488488 $wgHooks['HTMLCacheUpdate::doUpdate'][] = 'FlaggedRevsHooks::doCacheUpdate';
489489 # Updates stable version tracking data
@@ -529,6 +529,13 @@
530530 if ( !empty( $wgFlaggedRevsVisible ) ) {
531531 $wgHooks['getUserPermissionsErrors'][] = 'FlaggedRevsHooks::userCanView';
532532 }
 533+ if ( FlaggedRevs::useProtectionLevels() ) {
 534+ # Add protection form field
 535+ $wgHooks['ProtectionForm::buildForm'][] = 'FlaggedRevsHooks::onProtectionForm';
 536+ $wgHooks['ProtectionForm::showLogExtract'][] = 'FlaggedRevsHooks::insertStabilityLog';
 537+ # Save stability settings
 538+ $wgHooks['ProtectionForm::save'][] = 'FlaggedRevsHooks::onProtectionSave';
 539+ }
533540 }
534541
535542 # ####### END HOOK TRIGGERED FUNCTIONS #########
@@ -553,6 +560,12 @@
554561 # Don't show autoreview group everywhere
555562 global $wgImplicitGroups;
556563 $wgImplicitGroups[] = 'autoreview';
 564+ # Conditional API modules
 565+ global $wgAPIListModules;
 566+ if ( !FlaggedRevs::stableOnlyIfConfigured() ) {
 567+ $wgAPIListModules['reviewedpages'] = 'ApiQueryReviewedpages';
 568+ $wgAPIListModules['unreviewedpages'] = 'ApiQueryUnreviewedpages';
 569+ }
557570 }
558571
559572 # Add review log
@@ -576,8 +589,9 @@
577590 $wgLogTypes[] = 'stable';
578591 $wgLogNames['stable'] = 'stable-logpage';
579592 $wgLogHeaders['stable'] = 'stable-logpagetext';
580 -$wgLogActions['stable/config'] = 'stable-logentry-config';
581 -$wgLogActions['stable/reset'] = 'stable-logentry-reset';
 593+$wgLogActionsHandlers['stable/config'] = 'FlaggedRevsLogs::stabilityLogText'; // customize
 594+$wgLogActionsHandlers['stable/modify'] = 'FlaggedRevsLogs::stabilityLogText'; // re-customize
 595+$wgLogActionsHandlers['stable/reset'] = 'FlaggedRevsLogs::stabilityLogText'; // reset
582596
583597 # AJAX functions
584598 $wgAjaxExportList[] = 'RevisionReview::AjaxReview';
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/maintenance/pruneRevData.inc
@@ -27,8 +27,6 @@
2828
2929 $newerRevs = 50;
3030 $cutoff = $db->timestamp( time() - 30*24*3600 );
31 - // DEV
32 - $newerRevs = 1;
3331 $cutoff = $db->timestamp( time() - 3600 );
3432 while( $blockEnd <= $end ) {
3533 echo "...doing fp_page_id from $blockStart to $blockEnd\n";
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/FlaggedRevs.alias.php
@@ -26,11 +26,11 @@
2727
2828 /** Aragonese (Aragonés) */
2929 $aliases['an'] = array(
30 - 'OldReviewedPages' => array( 'PachinasSuperbisatasAntigas' ),
31 - 'QualityOversight' => array( 'SuperbisataDeCalidat' ),
32 - 'ReviewedPages' => array( 'PachinasSuberbisatas' ),
 30+ 'OldReviewedPages' => array( 'PachinasSupervisatasAntigas' ),
 31+ 'QualityOversight' => array( 'SupervisataDeCalidat' ),
 32+ 'ReviewedPages' => array( 'PachinasSubervisatas' ),
3333 'StablePages' => array( 'PachinasEstables' ),
34 - 'UnreviewedPages' => array( 'PachinasNoRebisatas' ),
 34+ 'UnreviewedPages' => array( 'PachinasNoRevisatas' ),
3535 );
3636
3737 /** Arabic (العربية) */
@@ -50,16 +50,16 @@
5151
5252 /** Egyptian Spoken Arabic (مصرى) */
5353 $aliases['arz'] = array(
54 - 'OldReviewedPages' => array( 'صفحات_مراجعة_قديمة' ),
 54+ 'OldReviewedPages' => array( 'صفح_مراجعه_قديمه' ),
5555 'ProblemChanges' => array( 'تغييرات_المشاكل' ),
56 - 'QualityOversight' => array( 'نظر_الجودة' ),
57 - 'ReviewedPages' => array( 'صفحات_مراجعة' ),
58 - 'RevisionReview' => array( 'مراجعة_نسخة' ),
 56+ 'QualityOversight' => array( 'مراقبة_الجوده' ),
 57+ 'ReviewedPages' => array( 'صفح_مراجعه' ),
 58+ 'RevisionReview' => array( 'مراجعة_نسخه' ),
5959 'Stabilization' => array( 'استقرار' ),
60 - 'StablePages' => array( 'صفحات_مستقرة' ),
61 - 'ReviewedVersions' => array( 'نسخ_مراجعة', 'نسخ_مستقرة' ),
62 - 'UnreviewedPages' => array( 'صفحات_مش_مراجعة' ),
63 - 'ValidationStatistics' => array( 'إحصاءات_التحقق' ),
 60+ 'StablePages' => array( 'صفح_مستقر' ),
 61+ 'ReviewedVersions' => array( 'نسخ_مراجعه', 'نسخ_مستقره' ),
 62+ 'UnreviewedPages' => array( 'صفح_مش_متراجعه' ),
 63+ 'ValidationStatistics' => array( 'احصائيات_الصلاحيه' ),
6464 );
6565
6666 /** Southern Balochi (بلوچی مکرانی) */
@@ -114,16 +114,21 @@
115115
116116 /** Esperanto (Esperanto) */
117117 $aliases['eo'] = array(
118 - 'OldReviewedPages' => array( 'MalfreŝeKontrolitajPaĝoj' ),
119 - 'QualityOversight' => array( 'KvalitKontrolo' ),
120 - 'ReviewedPages' => array( 'KontrolitajPaĝoj' ),
121 - 'StablePages' => array( 'StabilajPaĝoj' ),
122 - 'UnreviewedPages' => array( 'NekontrolitajPaĝoj' ),
 118+ 'OldReviewedPages' => array( 'Malfreŝe kontrolitaj paĝoj' ),
 119+ 'QualityOversight' => array( 'Kvalita kontrolo' ),
 120+ 'ReviewedPages' => array( 'Kontrolitaj paĝoj' ),
 121+ 'StablePages' => array( 'Stabilaj paĝoj' ),
 122+ 'UnreviewedPages' => array( 'Nekontrolitaj paĝoj' ),
123123 );
124124
125125 /** Spanish (Español) */
126126 $aliases['es'] = array(
 127+ 'OldReviewedPages' => array( 'Páginas revisadas antiguas' ),
 128+ 'Stabilization' => array( 'Estabilización' ),
 129+ 'StablePages' => array( 'Páginas publicadas' ),
 130+ 'ReviewedVersions' => array( 'Versiones revisadas' ),
127131 'UnreviewedPages' => array( 'Páginas_sin_revisar' ),
 132+ 'ValidationStatistics' => array( 'Estadísticas de validación' ),
128133 );
129134
130135 /** Persian (فارسی) */
@@ -278,6 +283,8 @@
279284 'RevisionReview' => array( '特定版の査読' ),
280285 'Stabilization' => array( '固定', '採択', 'ページの採択' ),
281286 'StablePages' => array( '固定ページ', '安定ページ', '採用ページ' ),
 287+ 'ConfiguredPages' => array( '査読設定のあるページ' ),
 288+ 'ReviewedVersions' => array( '固定版', '安定版', '採用版' ),
282289 'UnreviewedPages' => array( '未査読ページ', '査読待ちページ' ),
283290 'ValidationStatistics' => array( '判定統計' ),
284291 );
@@ -324,7 +331,8 @@
325332 'ReviewedPages' => array( 'സംശോധനംചെയ്തതാളുകൾ' ),
326333 'RevisionReview' => array( 'നാൾപ്പതിപ്പ്സംശോധനം' ),
327334 'Stabilization' => array( 'സ്ഥിരപ്പെടുത്തൽ' ),
328 - 'StablePages' => array( 'സ്ഥിരതാളുകള്‍' ),
 335+ 'StablePages' => array( 'സ്ഥിരതാളുകൾ' ),
 336+ 'ConfiguredPages' => array( 'ക്രമീകരിച്ചതാളുകൾ' ),
329337 'ReviewedVersions' => array( 'സംശോധിതപതിപ്പുകൾ', 'സ്ഥിരതയുള്ള പതിപ്പുകൾ' ),
330338 'UnreviewedPages' => array( 'സംശോധനംചെയ്യാത്തതാളുകൾ' ),
331339 'ValidationStatistics' => array( 'മൂല്യനിർണ്ണയസ്ഥിതിവിവരം' ),
@@ -447,6 +455,7 @@
448456 'RevisionReview' => array( 'Revisão de edições' ),
449457 'Stabilization' => array( 'Estabilização' ),
450458 'StablePages' => array( 'Páginas_estáveis' ),
 459+ 'ConfiguredPages' => array( 'Páginas configuradas' ),
451460 'UnreviewedPages' => array( 'Páginas_a_analisar' ),
452461 'ValidationStatistics' => array( 'Estatísticas de validação' ),
453462 );
@@ -519,7 +528,7 @@
520529 'QualityOversight' => array( 'Maingat na pamamahala ng kalidad' ),
521530 'ReviewedPages' => array( 'Sinuring mga pahina' ),
522531 'RevisionReview' => array( 'Pagsusuri ng pagbabago' ),
523 - 'Stabilization' => array( 'Pagpapatatag', 'pagpapatibay' ),
 532+ 'Stabilization' => array( 'Pagpapatatag', 'Pagpapatibay' ),
524533 'StablePages' => array( 'Matatag na mga pahina' ),
525534 'UnreviewedPages' => array( 'Mga pahina hindi pa nasusuri' ),
526535 'ValidationStatistics' => array( 'Mga estadistika ng pagtitiyak' ),
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/QualityOversight.i18n.php
@@ -114,11 +114,12 @@
115115 );
116116
117117 /** German (Deutsch)
 118+ * @author Kghbln
118119 * @author Raimond Spekking
119120 * @author Umherirrender
120121 */
121122 $messages['de'] = array(
122 - 'qualityoversight' => 'Übersicht über markierte Versionen',
 123+ 'qualityoversight' => 'Erweitertes Versionsmarkierungs-Logbuch',
123124 'qualityoversight-list' => 'Diese Seite zeigt die aktuellen Freigaben sowie den Widerruf markierter Versionen.',
124125 'qualityoversight-legend' => 'Suche in Versionsmarkierungen',
125126 );
@@ -468,8 +469,8 @@
469470 * @author Mihai
470471 */
471472 $messages['ro'] = array(
472 - 'qualityoversight-list' => 'Această pagină afişează cele mai recente aprobări şi deprecieri ale reviziilor.',
473 - 'qualityoversight-legend' => 'Căutaţi jurnalele recente ale revizuirilor',
 473+ 'qualityoversight-list' => 'Această pagină afișează cele mai recente aprobări și deprecieri ale reviziilor.',
 474+ 'qualityoversight-legend' => 'Căutați jurnalele recente ale revizuirilor',
474475 );
475476
476477 /** Tarandíne (Tarandíne)
@@ -626,11 +627,12 @@
627628 );
628629
629630 /** Traditional Chinese (‪中文(繁體)‬)
 631+ * @author Horacewai2
630632 * @author Liangent
631633 * @author Shinjiman
632634 */
633635 $messages['zh-hant'] = array(
634 - 'qualityoversight' => '品質管理',
 636+ 'qualityoversight' => '品質管理日誌',
635637 'qualityoversight-list' => '這個頁面列示出最近核准修訂以及最近品質修訂之折舊。',
636638 'qualityoversight-legend' => '搜索最近審核記錄',
637639 );
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/ReviewedVersions.i18n.php
@@ -871,8 +871,8 @@
872872 * @author Mihai
873873 */
874874 $messages['ro'] = array(
875 - 'reviewedversions' => 'Vizualizaţi versiunile stabile',
876 - 'reviewedversions-leg1' => 'Afişează reviziile revizuite pentru o pagină',
 875+ 'reviewedversions' => 'Vizualizați versiunile stabile',
 876+ 'reviewedversions-leg1' => 'Afișează reviziile revizuite pentru o pagină',
877877 'reviewedversions-page' => 'Numele paginii:',
878878 'reviewedversions-none' => '"[[:$1]]" nu are revizii revizuite.',
879879 );
@@ -992,12 +992,13 @@
993993 );
994994
995995 /** Swedish (Svenska)
 996+ * @author Dafer45
996997 * @author Lejonel
997998 * @author M.M.S.
998999 * @author Najami
9991000 */
10001001 $messages['sv'] = array(
1001 - 'reviewedversions' => 'Visa stabila versioner',
 1002+ 'reviewedversions' => 'Granskade versioner',
10021003 'reviewedversions-leg1' => 'Lista granskade versioner av en sida',
10031004 'reviewedversions-page' => 'Sidnamn:',
10041005 'reviewedversions-none' => '"[[:$1]]" har inga granskade versioner.',
@@ -1194,14 +1195,15 @@
11951196 );
11961197
11971198 /** Traditional Chinese (‪中文(繁體)‬)
 1199+ * @author Horacewai2
11981200 * @author Liangent
11991201 */
12001202 $messages['zh-hant'] = array(
1201 - 'reviewedversions' => '穩定版',
 1203+ 'reviewedversions' => '穩定版本',
12021204 'reviewedversions-leg1' => '列示一版已複審的修訂',
12031205 'reviewedversions-page' => '頁面名',
12041206 'reviewedversions-none' => '[[:$1]]沒有已複審過的修訂。',
1205 - 'reviewedversions-list' => '以下是[[:$1]]已複審的修訂列表:',
 1207+ 'reviewedversions-list' => '以下是[[:$1]]的{{PLURAL:$2|此唯一|此}}版本{{PLURAL:$2|已|已}}複審的修訂列表:',
12061208 'reviewedversions-review' => '由$2於<i>$1</i>進行了複審',
12071209 );
12081210
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/ConfiguredPages.i18n.php
@@ -116,12 +116,22 @@
117117 'configuredpages-prec-pristine' => 'čistá přednost',
118118 );
119119
120 -/** German (Deutsch) */
 120+/** German (Deutsch)
 121+ * @author Kghbln
 122+ */
121123 $messages['de'] = array(
 124+ 'configuredpages' => 'Seiten die hinsichtlich der Versionsmarkierung konfiguriert wurden',
 125+ 'configuredpages-text' => 'Es folgt eine Liste der Seiten, deren Konfiguration zur Versionsmarkierung vom Standard der Website abweicht.
 126+
 127+Einige Einstellungen können eine Abweichung hinsichtlich der Version bewirken, die dem Leser angezeigt wird. Sie können auch den Kreis derjenigen weiter einschränken, deren Bearbeitungen keine weitere Durchsicht erfordert.',
 128+ 'configuredpages-none' => 'Diese Liste enthält keine Seiten.',
122129 'configuredpages-config' => 'Konfiguration',
 130+ 'configuredpages-precedence' => 'Priorität:',
123131 'configuredpages-prec-none' => 'zuletzt überprüft',
124 - 'configuredpages-prec-quality' => 'Qualitätsrangordnung',
125 - 'configuredpages-prec-pristine' => 'ursprüngliche Rangordnung',
 132+ 'configuredpages-prec-quality' => 'aktueller Qualitätsstatus',
 133+ 'configuredpages-prec-pristine' => 'neueste markierte Version',
 134+ 'configuredpages-def-draft' => 'neueste Version',
 135+ 'configuredpages-def-stable' => 'veröffentlichte Version',
126136 );
127137
128138 /** Zazaki (Zazaki) */
@@ -593,7 +603,7 @@
594604 /** Romanian (Română) */
595605 $messages['ro'] = array(
596606 'configuredpages-prec-none' => 'nicio prioritate',
597 - 'configuredpages-prec-quality' => 'preferinţă pentru calitate',
 607+ 'configuredpages-prec-quality' => 'preferință pentru calitate',
598608 );
599609
600610 /** Tarandíne (Tarandíne) */
@@ -628,8 +638,11 @@
629639 'configuredpages-prec-pristine' => 'эрдэтээҥҥитэ баһыйыылаах',
630640 );
631641
632 -/** Slovak (Slovenčina) */
 642+/** Slovak (Slovenčina)
 643+ * @author Helix84
 644+ */
633645 $messages['sk'] = array(
 646+ 'configuredpages' => 'Stránky s nastavením kontroly',
634647 'configuredpages-prec-none' => 'bez precedencie',
635648 'configuredpages-prec-quality' => 'precedencia podľa kvality',
636649 'configuredpages-prec-pristine' => 'čistá precedencia',
@@ -714,11 +727,17 @@
715728 'configuredpages-prec-pristine' => 'koskmatomuden tobmuz',
716729 );
717730
718 -/** Vietnamese (Tiếng Việt) */
 731+/** Vietnamese (Tiếng Việt)
 732+ * @author Minh Nguyen
 733+ */
719734 $messages['vi'] = array(
 735+ 'configuredpages-none' => 'Danh sách không có trang nào.',
 736+ 'configuredpages-config' => 'Thiết lập',
720737 'configuredpages-prec-none' => 'không có bản trước',
721738 'configuredpages-prec-quality' => 'bản chất lượng trước',
722739 'configuredpages-prec-pristine' => 'bản trong sạch trước',
 740+ 'configuredpages-def-draft' => 'phiên bản mới nhất',
 741+ 'configuredpages-def-stable' => 'phiên bản xuất bản',
723742 );
724743
725744 /** Simplified Chinese (‪中文(简体)‬) */
@@ -728,10 +747,21 @@
729748 'configuredpages-prec-pristine' => '原始优先级',
730749 );
731750
732 -/** Traditional Chinese (‪中文(繁體)‬) */
 751+/** Traditional Chinese (‪中文(繁體)‬)
 752+ * @author Horacewai2
 753+ */
733754 $messages['zh-hant'] = array(
 755+ 'configuredpages' => '頁面已有複審設定',
 756+ 'configuredpages-text' => '下面是已有和站點預設設定不同的審核設定。
 757+
 758+部份設定的更改是向讀者展示的。',
 759+ 'configuredpages-none' => '沒有頁面在這個清單中',
 760+ 'configuredpages-config' => '設定',
 761+ 'configuredpages-precedence' => '優先級:',
734762 'configuredpages-prec-none' => '沒有優先級',
735763 'configuredpages-prec-quality' => '質量優先級',
736764 'configuredpages-prec-pristine' => '原始優先級',
 765+ 'configuredpages-def-draft' => '最新版本',
 766+ 'configuredpages-def-stable' => '已出版的內容',
737767 );
738768
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/ValidationStatistics.i18n.php
@@ -1544,10 +1544,10 @@
15451545 */
15461546 $messages['ro'] = array(
15471547 'validationstatistics-users' => "'''{{SITENAME}}''' are în prezent '''[[Special:ListUsers/editor|$1]]''' {{PLURAL:$1|utilizator|utilizatori}} cu drepturi de [[{{MediaWiki:Validationpage}}|editare]]
1548 -şi '''[[Special:ListUsers/reviewer|$2]]''' {{PLURAL:$2|utilizator|utilizatori}} cu drepturi de [[{{MediaWiki:Validationpage}}|recenzie]].
 1548+și '''[[Special:ListUsers/reviewer|$2]]''' {{PLURAL:$2|utilizator|utilizatori}} cu drepturi de [[{{MediaWiki:Validationpage}}|recenzie]].
15491549
1550 -Editorii şi recenzorii sunt utilizatori stabiliţi care pot verifica modificările din pagini.",
1551 - 'validationstatistics-ns' => 'Spaţiu de nume',
 1550+Editorii și recenzorii sunt utilizatori stabiliți care pot verifica modificările din pagini.",
 1551+ 'validationstatistics-ns' => 'Spațiu de nume',
15521552 'validationstatistics-total' => 'Pagini',
15531553 'validationstatistics-stable' => 'Revizualizată',
15541554 'validationstatistics-latest' => 'Sincronizată',
@@ -1712,12 +1712,13 @@
17131713
17141714 /** Swedish (Svenska)
17151715 * @author Boivie
 1716+ * @author Dafer45
17161717 * @author M.M.S.
17171718 * @author Rotsee
17181719 * @author Skalman
17191720 */
17201721 $messages['sv'] = array(
1721 - 'validationstatistics' => 'Valideringsstatistik',
 1722+ 'validationstatistics' => 'Statistik över sidgranskning',
17221723 'validationstatistics-users' => "'''{{SITENAME}}''' har just nu '''[[Special:ListUsers/editor|$1]]''' {{PLURAL:$1|användare|användare}} med [[{{MediaWiki:Validationpage}}|skribenträttigheter]].
17231724
17241725 Skribenter är etablerade användare som kan granska sidversioner.",
@@ -2026,12 +2027,13 @@
20272028
20282029 /** Traditional Chinese (‪中文(繁體)‬)
20292030 * @author Gaoxuewei
 2031+ * @author Horacewai2
20302032 * @author Mark85296341
20312033 * @author Tomchiukc
20322034 */
20332035 $messages['zh-hant'] = array(
2034 - 'validationstatistics' => '判定統計',
2035 - 'validationstatistics-users' => "'''{{SITENAME}}'''現時有'''[[Special:ListUsers/editor|$1]]'''個用戶具有[[{{MediaWiki:Validationpage}}|編輯]]的權限,而'''[[Special:ListUsers/reviewer|$2]]'''個用戶有[[{{MediaWiki:Validationpage}}|審定]]的權限。
 2036+ 'validationstatistics' => '審核統計',
 2037+ 'validationstatistics-users' => "'''{{SITENAME}}'''現時有'''[[Special:ListUsers/editor|$1]]'''{{PLURAL:$1|個|個}}用戶具有[[{{MediaWiki:Validationpage}}|編輯]]的權限。
20362038
20372039 編輯及審定皆為已確認的用戶,並可以檢查各頁面的修定。",
20382040 'validationstatistics-time' => "''下列資訊於 $5 $6 進行了最後更新。 ''
@@ -2041,7 +2043,7 @@
20422044 ''未登錄用戶''的編輯平均等待審核時間為'''$1''';中值時間為'''$3'''。
20432045 $4
20442046 [[Special:OldReviewedPages|未審核的頁面編輯等待]]平均滯後時間為'''$2'''。
2045 -這些頁面被認為''過期''了。同樣的,如果[[{{MediaWiki:Validationpage}}|完美版本]]是目前的待定版本,這些頁面就被認為''已同步''。
 2047+這些頁面被認為''過期''了。同樣的,如果完美版本是目前的待定版本,這些頁面就被認為''已同步''。
20462048 頁面的完美版本是被讀者普遍接受的最新版本。",
20472049 'validationstatistics-table' => "各名稱空間的統計資訊顯示如下,''不包含''轉向頁。",
20482050 'validationstatistics-ns' => '名稱空間',
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/FlaggedRevs.i18n.php
@@ -55,8 +55,10 @@
5656 'revreview-diff-toggle-title' => 'Toggle display of pending changes to the published version',
5757 'revreview-log-toggle-show' => 'show stability log',
5858 'revreview-log-toggle-hide' => 'hide stability log',
 59+ 'revreview-log-toggle-title' => 'Toggle display of stability settings log',
5960 'revreview-log-details-show' => 'show details',
6061 'revreview-log-details-hide' => 'hide details',
 62+ 'revreview-log-details-title' => 'Toggle display of stability settings log',
6163 'review-diff2stable' => 'View all pending changes',
6264 'review-logentry-app' => 'reviewed a version of [[$1]]',
6365 'review-logentry-dis' => 'deprecated a version of [[$1]]',
@@ -89,6 +91,17 @@
9092 A template or file may have been requested when no specific version was specified.
9193 This can happen if a dynamic template transcludes another file or template depending on a variable that changed since you started reviewing this page.
9294 Refreshing the page and rereviewing can solve this problem.',
 95+
 96+ 'review_page_invalid' => 'The target page title is invalid.',
 97+ 'review_page_notexists' => 'The target page does not exist.',
 98+ 'review_page_unreviewable' => 'The target page is not reviewable.',
 99+ 'review_no_oldid' => 'No revision ID specified.',
 100+ 'review_bad_oldid' => 'There is no such target revision.',
 101+ 'review_too_low' => 'Revision cannot be reviewed with some fields left unapproved.',
 102+ 'review_bad_key' => 'Invalid inclusion parameter key.',
 103+ 'review_denied' => 'Permission denied.',
 104+ 'review_param_missing' => 'A parameter is missing or invalid.',
 105+
93106 'revreview-current' => 'Pending changes',
94107 'revreview-depth' => 'Depth',
95108 'revreview-depth-0' => 'Unapproved',
@@ -168,6 +181,7 @@
169182 'revreview-toggle-hide' => '(-)',
170183 'revreview-toggle-title' => 'show/hide details',
171184 'revreview-toolow' => '\'\'\'You must rate each of the attributes higher than "unapproved" in order for a revision to be considered reviewed.\'\'\'
 185+
172186 To remove the review status of a revision, set all fields to "unapproved".
173187
174188 Please hit the "back" button in your browser and try again.',
@@ -191,8 +205,9 @@
192206 'rights-editor-autosum' => 'autopromoted',
193207 'rights-editor-revoke' => 'removed editor status from [[$1]]', # B/C
194208 'specialpages-group-quality' => 'Edit approval',
195 - 'stable-logentry-config' => 'configured publication settings for [[$1]]',
196 - 'stable-logentry-reset' => 'reset publication settings for [[$1]]',
 209+ 'stable-logentry-config' => 'set publication settings for $1',
 210+ 'stable-logentry-modify' => 'changed publication settings for $1',
 211+ 'stable-logentry-reset' => 'reset publication settings for $1',
197212 'stable-log-restriction' => 'Publish: require "$1" permission',
198213 'stable-logpage' => 'Stability log',
199214 'stable-logpagetext' => 'This is a log of changes to the [[{{MediaWiki:Validationpage}}|published version]] configuration of content pages.',
@@ -1527,8 +1542,10 @@
15281543 'revreview-diff-toggle-title' => 'Пераключэньне паказу неравераных зьменаў апублікаванай вэрсіяй',
15291544 'revreview-log-toggle-show' => 'паказаць журнал стабілізацыяў',
15301545 'revreview-log-toggle-hide' => 'схаваць журнал стабілізацыяў',
 1546+ 'revreview-log-toggle-title' => 'Уключыць паказ журнала ўстановак стабілізацыі',
15311547 'revreview-log-details-show' => 'паказаць падрабязнасьці',
15321548 'revreview-log-details-hide' => 'схаваць падрабязнасьці',
 1549+ 'revreview-log-details-title' => 'Уключыць паказ журнала ўстановак стабілізацыі',
15331550 'review-diff2stable' => 'Паказаць непрагледжаныя зьмены апублікаванай вэрсіі',
15341551 'review-logentry-app' => 'праверыў вэрсію старонкі [[$1]]',
15351552 'review-logentry-dis' => 'састарэлая вэрсія старонкі [[$1]]',
@@ -3709,8 +3726,10 @@
37103727 'revreview-diff-toggle-title' => 'Muestra u oculta los cambios pendientes en la versión publicada',
37113728 'revreview-log-toggle-show' => 'mostrar registro de estabilidad',
37123729 'revreview-log-toggle-hide' => 'ocultar registro de estabilidad',
 3730+ 'revreview-log-toggle-title' => 'Mostrar u ocultar el registro de configuración de estabilidad',
37133731 'revreview-log-details-show' => 'mostrar detalles',
37143732 'revreview-log-details-hide' => 'ocultar detalles',
 3733+ 'revreview-log-details-title' => 'Mostrar u ocultar el registro de configuración de estabilidad',
37153734 'review-diff2stable' => 'Ver los cambios pendientes de la versión publicada',
37163735 'review-logentry-app' => 'Revisado una versión de [[$1]]',
37173736 'review-logentry-dis' => 'desaprobada una versión de [[$1]]',
@@ -3870,7 +3889,7 @@
38713890 'tooltip-ca-current' => 'Ver esta página con los cambios pendientes',
38723891 'tooltip-ca-stable' => 'Ver la versión publicada de esta página',
38733892 'tooltip-ca-default' => 'Opciones de control de calidad',
3874 - 'flaggedrevs-protect-legend' => 'Publicar ediciones',
 3893+ 'flaggedrevs-protect-legend' => 'Publicar ediciones ([[{{MediaWiki:Validationpage}}|?]])',
38753894 'flaggedrevs-protect-none' => 'Permitir todos los usuarios',
38763895 'flaggedrevs-protect-basic' => 'Configuraciones por defecto',
38773896 'revreview-locked-title' => 'Las ediciones deben ser revisadas antes de ser mostradas en esta página!',
@@ -4406,8 +4425,10 @@
44074426 'revreview-diff-toggle-title' => "Basculer l'affichage entre les modifications en attente et la version publiée",
44084427 'revreview-log-toggle-show' => 'afficher le journal de stabilité',
44094428 'revreview-log-toggle-hide' => 'cacher le journal de stabilité',
 4429+ 'revreview-log-toggle-title' => "Basculer l'affichage du journal des paramètres de stabilité",
44104430 'revreview-log-details-show' => 'afficher les détails',
44114431 'revreview-log-details-hide' => 'masquer les détails',
 4432+ 'revreview-log-details-title' => "Basculer l'affichage du journal des paramètres de stabilité",
44124433 'review-diff2stable' => 'Voir les modifications en cours par rapport à la version publiée',
44134434 'review-logentry-app' => 'a relu une version de [[$1]]',
44144435 'review-logentry-dis' => 'a déprécié une version de [[$1]]',
@@ -4872,8 +4893,10 @@
48734894 'revreview-diff-toggle-title' => 'Cambiar a visualización de cambios entre os cambios pendentes e a versión publicada',
48744895 'revreview-log-toggle-show' => 'mostrar o rexistro de estabilidade',
48754896 'revreview-log-toggle-hide' => 'agochar o rexistro de estabilidade',
 4897+ 'revreview-log-toggle-title' => 'Conmutar a presentación do rexistro de configuración de estabilidade',
48764898 'revreview-log-details-show' => 'mostrar os detalles',
48774899 'revreview-log-details-hide' => 'agochar os detalles',
 4900+ 'revreview-log-details-title' => 'Conmutar a presentación do rexistro de configuración de estabilidade',
48784901 'review-diff2stable' => 'Ver os cambios pendentes feitos á versión publicada',
48794902 'review-logentry-app' => 'revisou unha versión de "[[$1]]"',
48804903 'review-logentry-dis' => 'rexeitou unha versión de "[[$1]]"',
@@ -4959,7 +4982,7 @@
49604983 'revreview-quick-quality-same' => "'''[[{{MediaWiki:Validationpage}}|Calidade]]'''",
49614984 'revreview-quick-see-basic' => '[[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} revisar os cambios pendentes]]',
49624985 'revreview-quick-see-quality' => '[[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} revisar os cambios pendentes]]',
4963 - 'revreview-selected' => "Seleccionada a revisión de '''$1:'''",
 4986+ 'revreview-selected' => "Revisión seleccionada de \"'''\$1'''\":",
49644987 'revreview-source' => 'Ver o código fonte',
49654988 'revreview-stable' => 'Páxina publicada',
49664989 'revreview-basic-title' => 'Esta é unha versión comprobada desta páxina',
@@ -5984,8 +6007,10 @@
59856008 'revreview-diff-toggle-title' => 'Zwobraznjenje nječinjenych změnow wozjewjeneje wersije přepinyć',
59866009 'revreview-log-toggle-show' => 'protokol stabilnosće pokazać',
59876010 'revreview-log-toggle-hide' => 'protokol stabilnosće schować',
 6011+ 'revreview-log-toggle-title' => 'Zwobraznjenje protokola nastajenjow stabilnosće přepinyć',
59886012 'revreview-log-details-show' => 'podrobnosće pokazać',
59896013 'revreview-log-details-hide' => 'podrobnosće schować',
 6014+ 'revreview-log-details-title' => 'Zwobraznjenje protokola nastajenjow stabilnosće přepinyć',
59906015 'review-diff2stable' => 'Nječinjene změny wozjewjeneje wersije wobhladać',
59916016 'review-logentry-app' => 'je wersiju wot [[$1]] přepruwował',
59926017 'review-logentry-dis' => 'je wersiju wot [[$1]] wothódnoćił',
@@ -6324,7 +6349,7 @@
63256350 'revreview-successful2' => "'''A(z) [[:$1|$1]] változatáról sikeresen eltávolítottad a jelölést.'''",
63266351 'revreview-text' => "''Az [[{{MediaWiki:Validationpage}}|ellenőrzött változatok]] olyan átnézett lapok, amiken a közzétett változat alapul.''",
63276352 'revreview-toggle-title' => 'részletek megjelenítése/elrejtése',
6328 - 'revreview-toolow' => "'''Ahhoz, hogy egy változat ellenőrzöttnek tekinthető legyen, minden alábbi tulajdonságot magasabbra kell értékelned a „nem ellenőrzött szintnél.'''
 6353+ 'revreview-toolow' => "'''Ahhoz, hogy egy változat ellenőrzöttnek tekinthető legyen, minden tulajdonságot magasabbra kell értékelned a „nem ellenőrzött” szintnél.'''
63296354 Nem ellenőrzöttnek való visszaminősítéshez állítsd az összes mezőt „nem ellenőrzött” értékre.
63306355
63316356 Kattints a böngésződ „Vissza” gombjára, majd próbáld újra.",
@@ -6358,7 +6383,7 @@
63596384 'revreview-statusfilter' => 'Állapot változtatás:',
63606385 'revreview-filter-approved' => 'ellenőrzött',
63616386 'revreview-filter-reapproved' => 'újraellenőrzött',
6362 - 'revreview-filter-unapproved' => 'ellenőrizetlen',
 6387+ 'revreview-filter-unapproved' => 'ellenőrizetlennek jelölt',
63636388 'revreview-typefilter' => 'Típus:',
63646389 'revreview-filter-auto' => 'automatikus',
63656390 'revreview-filter-manual' => 'kézi',
@@ -6377,10 +6402,11 @@
63786403 'revreview-restriction-none' => 'egyik sem',
63796404 'revreview-reviewlink' => 'ellenőrzésre váró szerkesztések',
63806405 'revreview-reviewlink-title' => 'Változások az összes ellenőrzésre váró szerkesztést figyelembe véve',
 6406+ 'revreview-unreviewedpage' => 'ellenőrizetlen lap',
63816407 'tooltip-ca-current' => 'Lap megjelenítése az ellenőrzésre váró változtatásokkal együtt',
63826408 'tooltip-ca-stable' => 'A lap közzétett változatának megjelenítése',
63836409 'tooltip-ca-default' => 'Minőségbiztosítási beállítások',
6384 - 'flaggedrevs-protect-legend' => 'Szerkesztések közzététele',
 6410+ 'flaggedrevs-protect-legend' => 'Szerkesztések közzététele ([[{{MediaWiki:Validationpage}}|?]])',
63856411 'flaggedrevs-protect-none' => 'Összes felhasználó engedélyezése',
63866412 'flaggedrevs-protect-basic' => 'Alapértelmezett beállítások',
63876413 'revreview-locked-title' => 'A szerkesztéseket ellenőrizni kell, mielőtt megjelennének ezen a lapon.',
@@ -6443,8 +6469,10 @@
64446470 'revreview-diff-toggle-title' => 'Alternar le presentation de modificationes pendente del version publicate',
64456471 'revreview-log-toggle-show' => 'monstrar registro de stabilitate',
64466472 'revreview-log-toggle-hide' => 'celar registro de stabilitate',
 6473+ 'revreview-log-toggle-title' => 'Alternar le presentation del registro de configurationes de stabilitate',
64476474 'revreview-log-details-show' => 'monstrar detalios',
64486475 'revreview-log-details-hide' => 'celar detalios',
 6476+ 'revreview-log-details-title' => 'Alternar le presentation del registro de configurationes de stabilitate',
64496477 'review-diff2stable' => 'Vider modificationes pendente al version publicate',
64506478 'review-logentry-app' => 'revideva un version de [[$1]]',
64516479 'review-logentry-dis' => 'depreciava un version de [[$1]]',
@@ -7067,8 +7095,10 @@
70687096 'revreview-diff-toggle-title' => '採用候補と公開中の版の間の変更の表示を切り替える',
70697097 'revreview-log-toggle-show' => '安定版のログを表示',
70707098 'revreview-log-toggle-hide' => '安定版のログを隠す',
 7099+ 'revreview-log-toggle-title' => '安定版の設定ログの表示を切り替える',
70717100 'revreview-log-details-show' => '詳細を表示',
70727101 'revreview-log-details-hide' => '詳細を非表示',
 7102+ 'revreview-log-details-title' => '安定版の設定ログの表示を切り替える',
70737103 'review-diff2stable' => '査読待ちの変更点をすべて見る',
70747104 'review-logentry-app' => '[[$1]] の特定版を査読承認',
70757105 'review-logentry-dis' => '[[$1]] の特定版を棄却',
@@ -8618,8 +8648,10 @@
86198649 'revreview-diff-toggle-title' => 'Префлување од приказ на промените во исчекување на објавената верзија',
86208650 'revreview-log-toggle-show' => 'прикажи дневник на стабилизација',
86218651 'revreview-log-toggle-hide' => 'сокриј дневник на стабилност',
 8652+ 'revreview-log-toggle-title' => 'Превклучување на приказ на дневник на поставки за стабилност',
86228653 'revreview-log-details-show' => 'покажи подробности',
86238654 'revreview-log-details-hide' => 'сокриј подробности',
 8655+ 'revreview-log-details-title' => 'Превклучување на приказ на дневник на поставки за стабилност',
86248656 'review-diff2stable' => 'Покажи и сите промени во исчекување',
86258657 'review-logentry-app' => 'оценета верзија на [[$1]]',
86268658 'review-logentry-dis' => 'означи како застарена верзија на [[$1]]',
@@ -8819,7 +8851,7 @@
88208852 'prefs-flaggedrevs' => 'തിരുത്തൽ അംഗീകരണം',
88218853 'prefs-flaggedrevs-ui' => 'തിരുത്തൽ അംഗീകരണം',
88228854 'flaggedrevs-prefs-stable' => 'ഉള്ളടക്ക താളിന്റെ പ്രസിദ്ധപ്പെടുത്തിയ പതിപ്പ് എപ്പോഴും സ്വതവേ പ്രദർശിപ്പിക്കുക (ഒന്നുണ്ടെങ്കിൽ)',
8823 - 'flaggedrevs-prefs-watch' => 'ഞാൻ സം‌ശോധം ചെയ്യുന്ന താളുകൾ എന്റെ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിലേക്ക് ചേർക്കുക',
 8855+ 'flaggedrevs-prefs-watch' => 'ഞാൻ സം‌ശോധം ചെയ്യുന്ന താളുകൾ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിലേക്ക് ചേർക്കുക',
88248856 'flaggedrevs-prefs-editdiffs' => 'താളുകൾ തിരുത്തുമ്പോൾ അവശേഷിക്കുന്ന വ്യത്യാസങ്ങൾ പ്രദർശിപ്പിക്കുക',
88258857 'flaggedrevs-prefs-viewdiffs' => 'സംശോധനം പ്രതീക്ഷിക്കുന്ന ഏറ്റവും പുതിയ നാൾപ്പതിപ്പുകൾ എടുത്തുനോക്കുമ്പോൾ അവശേഷിക്കുന്ന മാറ്റങ്ങളുമായുള്ള വ്യത്യാസം പ്രദർശിപ്പിക്കുക',
88268858 'group-editor' => 'എഡിറ്റർമാർ',
@@ -9456,8 +9488,10 @@
94579489 'revreview-diff-toggle-title' => 'Weergevave van verschillen met de gepubliceerde versie weergeven of verbergen',
94589490 'revreview-log-toggle-show' => 'stabiliteitslogboek weergeven',
94599491 'revreview-log-toggle-hide' => 'stabiliteitslogboek verbergen',
 9492+ 'revreview-log-toggle-title' => 'Weergave van stabiliteitsinstellingenlogboek in- of uitschakelen',
94609493 'revreview-log-details-show' => 'details weergeven',
94619494 'revreview-log-details-hide' => 'details verbergen',
 9495+ 'revreview-log-details-title' => 'Weergave van stabiliteitsinstellingenlogboek in- of uitschakelen',
94629496 'review-diff2stable' => 'Ongecontroleerde verschillen met de gepubliceerde versie bekijken',
94639497 'review-logentry-app' => 'heeft een versie van [[$1]] gecontroleerd',
94649498 'review-logentry-dis' => 'heeft een versie van [[$1]] ongeldig gemaakt',
@@ -10755,8 +10789,10 @@
1075610790 'revreview-depth-1' => 'بنسټيز',
1075710791 'revreview-depth-2' => 'منځوی',
1075810792 'revreview-depth-3' => 'لوړ',
10759 - 'revreview-source' => 'د ګارليک سرچينه',
 10793+ 'revreview-source' => 'سرچينه کتل',
1076010794 'revreview-style-1' => 'د منلو وړ',
 10795+ 'revreview-submit' => 'سپارل',
 10796+ 'revreview-submitting' => 'د سپارلو په حال کې ...',
1076110797 'revreview-filter-all' => 'ټول',
1076210798 'revreview-statusfilter' => 'د دريځ بدلون:',
1076310799 'revreview-reviewlink' => 'مخليدنه',
@@ -10813,8 +10849,10 @@
1081410850 'revreview-diff-toggle-title' => 'Alternar entre a apresentação das alterações pendentes e da versão publicada',
1081510851 'revreview-log-toggle-show' => 'mostrar registo de estabilidade',
1081610852 'revreview-log-toggle-hide' => 'esconder registo de estabilidade',
 10853+ 'revreview-log-toggle-title' => 'Alternar a apresentação do registo das configurações de estabilidade',
1081710854 'revreview-log-details-show' => 'mostrar detalhes',
1081810855 'revreview-log-details-hide' => 'esconder detalhes',
 10856+ 'revreview-log-details-title' => 'Alternar a apresentação do registo das configurações de estabilidade',
1081910857 'review-diff2stable' => 'Ver alterações pendentes à versão publicada',
1082010858 'review-logentry-app' => 'reviu uma versão de [[$1]]',
1082110859 'review-logentry-dis' => 'reprovou uma versão da página [[$1]]',
@@ -11109,43 +11147,43 @@
1111011148 'prefs-flaggedrevs-ui' => 'Revizie marcată',
1111111149 'group-editor' => 'Editori',
1111211150 'group-editor-member' => 'editor',
11113 - 'group-reviewer' => 'Recenzenţi',
 11151+ 'group-reviewer' => 'Recenzenți',
1111411152 'group-reviewer-member' => 'recenzent',
1111511153 'grouppage-editor' => '{{ns:project}}:Editor',
1111611154 'grouppage-reviewer' => '{{ns:project}}:Recenzent',
11117 - 'group-autoreview' => 'Autorecenzenţi',
 11155+ 'group-autoreview' => 'Autorecenzenți',
1111811156 'group-autoreview-member' => 'autorecenzent',
1111911157 'grouppage-autoreview' => '{{ns:project}}:Autorecenzent',
11120 - 'revreview-hist-draft' => 'revizie-schiţă',
 11158+ 'revreview-hist-draft' => 'revizie-schiță',
1112111159 'revreview-hist-quality' => 'revizie de calitate',
1112211160 'revreview-hist-basic' => 'revizie observată',
11123 - 'revreview-diff-toggle-title' => 'Toggle afişează modificări până la versiunea curentă.',
11124 - 'review-diff2stable' => 'Vedeţi schimbări între reviziile stabile şi curente',
 11161+ 'revreview-diff-toggle-title' => 'Toggle afișează modificări până la versiunea curentă.',
 11162+ 'review-diff2stable' => 'Vedeți schimbări între reviziile stabile și curente',
1112511163 'review-logentry-id' => 'vezi: $2',
1112611164 'review-logpage' => 'Jurnal de revizualizări',
11127 - 'revreview-accuracy' => 'Acurateţe',
 11165+ 'revreview-accuracy' => 'Acuratețe',
1112811166 'revreview-accuracy-0' => 'Neaprobat',
1112911167 'revreview-accuracy-1' => 'Văzut',
1113011168 'revreview-accuracy-2' => 'Exact',
11131 - 'revreview-accuracy-3' => 'Bine referenţiat',
 11169+ 'revreview-accuracy-3' => 'Bine referențiat',
1113211170 'revreview-accuracy-4' => 'Remarcabil',
1113311171 'revreview-approved' => 'Aprobat',
1113411172 'revreview-auto' => '(automat)',
11135 - 'revreview-current' => 'Schiţă',
 11173+ 'revreview-current' => 'Schiță',
1113611174 'revreview-depth' => 'Profunzime',
1113711175 'revreview-depth-0' => 'Neaprobat',
1113811176 'revreview-depth-1' => 'De bază',
1113911177 'revreview-depth-2' => 'Moderat',
1114011178 'revreview-depth-3' => 'Înalt',
1114111179 'revreview-depth-4' => 'Remarcabil',
11142 - 'revreview-draft-title' => 'Pagină schiţă',
11143 - 'revreview-edit' => 'Editează schiţa',
11144 - 'revreview-flag' => 'Revizuieşte această revizie',
11145 - 'revreview-legend' => 'Conţinut rată de revizie',
 11180+ 'revreview-draft-title' => 'Pagină schiță',
 11181+ 'revreview-edit' => 'Editează schița',
 11182+ 'revreview-flag' => 'Revizuiește această revizie',
 11183+ 'revreview-legend' => 'Conținut rată de revizie',
1114611184 'revreview-log' => 'Comentariu:',
1114711185 'revreview-oldrating' => 'A fost evaluat:',
1114811186 'revreview-quality-title' => 'Pagină de calitate',
11149 - 'revreview-source' => 'Sursa schiţei',
 11187+ 'revreview-source' => 'Sursa schiței',
1115011188 'revreview-stable' => 'Pagină stabilă',
1115111189 'revreview-style' => 'Lizibilitate',
1115211190 'revreview-style-0' => 'Neaprobat',
@@ -11156,7 +11194,7 @@
1115711195 'revreview-submit' => 'Trimite',
1115811196 'revreview-submitting' => 'Trimit ...',
1115911197 'revreview-toggle-title' => 'arată/ascunde detalii',
11160 - 'revreview-revnotfound' => 'Versiunea mai veche a paginii pe care aţi cerut-o nu a fost găsită. Vă rugăm să verificaţi legătura pe care aţi folosit-o pentru a accesa această pagină.',
 11198+ 'revreview-revnotfound' => 'Versiunea mai veche a paginii pe care ați cerut-o nu a fost găsită. Vă rugăm să verificați legătura pe care ați folosit-o pentru a accesa această pagină.',
1116111199 'rights-editor-autosum' => 'autopromovat',
1116211200 'specialpages-group-quality' => 'Asigurare calitate',
1116311201 'stable-logpage' => 'Jurnal de versiuni stabile',
@@ -11175,14 +11213,14 @@
1117611214 'revreview-lev-quality' => 'calitate',
1117711215 'revreview-lev-pristine' => 'primitiv',
1117811216 'revreview-reviewlink' => 'revizie',
11179 - 'tooltip-ca-current' => 'Vedeţi schiţa curentă a acestei pagini',
11180 - 'tooltip-ca-stable' => 'Vedeţi versiunea stabilă a acestei pagini',
 11217+ 'tooltip-ca-current' => 'Vedeți schița curentă a acestei pagini',
 11218+ 'tooltip-ca-stable' => 'Vedeți versiunea stabilă a acestei pagini',
1118111219 'tooltip-ca-default' => 'Setările asigurării de calitate',
11182 - 'flaggedrevs-protect-legend' => 'Publicaţi editările',
11183 - 'flaggedrevs-protect-none' => 'Permiteţi tuturor utilizatorilor',
 11220+ 'flaggedrevs-protect-legend' => 'Publicați editările',
 11221+ 'flaggedrevs-protect-none' => 'Permiteți tuturor utilizatorilor',
1118411222 'flaggedrevs-protect-basic' => 'Setări implicite',
1118511223 'log-show-hide-review' => 'jurnal de revizualizare $1',
11186 - 'revreview-tt-review' => 'Revizuieşte această pagină',
 11224+ 'revreview-tt-review' => 'Revizuiește această pagină',
1118711225 'validationpage' => '{{ns:help}}:Validare pagină',
1118811226 );
1118911227
@@ -11455,8 +11493,10 @@
1145611494 'revreview-diff-toggle-title' => 'Переключить отображение непроверенных изменений к опубликованной версии',
1145711495 'revreview-log-toggle-show' => 'показать журнал стабилизации',
1145811496 'revreview-log-toggle-hide' => 'скрыть журнал стабильности',
 11497+ 'revreview-log-toggle-title' => 'Включить отображение журнала настроек стабилизации',
1145911498 'revreview-log-details-show' => 'показать подробности',
1146011499 'revreview-log-details-hide' => 'скрыть подробности',
 11500+ 'revreview-log-details-title' => 'Включить отображение журнала настроек стабилизации',
1146111501 'review-diff2stable' => 'Показывать непроверенные изменения опубликованной версии',
1146211502 'review-logentry-app' => 'проверил версию [[$1]]',
1146311503 'review-logentry-dis' => 'отметил устаревшую версию [[$1]]',
@@ -12084,11 +12124,11 @@
1208512125 'revreview-style-3' => 'Jedrnato',
1208612126 'revreview-style-4' => 'Izbrano',
1208712127 'revreview-submit' => 'Potrdi',
12088 - 'revreview-submit-review' => 'Označi kot preverjeno',
12089 - 'revreview-submit-unreview' => 'Označi kot nepreverjeno',
 12128+ 'revreview-submit-review' => 'Potrdi',
 12129+ 'revreview-submit-unreview' => 'Od-potrdi',
1209012130 'revreview-submitting' => 'Potrjevanje ...',
12091 - 'revreview-submit-reviewed' => 'Končano. Preverjeno!',
12092 - 'revreview-submit-unreviewed' => 'Končano. Nepreverjeno!',
 12131+ 'revreview-submit-reviewed' => 'Končano. Potrjeno!',
 12132+ 'revreview-submit-unreviewed' => 'Končano. Od-potrjeno!',
1209312133 'revreview-toggle-title' => 'prikaži/skrij podrobnosti',
1209412134 'revreview-revnotfound' => 'Redakcije strani, ki ste jo poskušali pridobiti, ni mogoče najti. Prosimo, preverite spletni naslov, ki ste ga uporabili za dostop do strani.',
1209512135 'log-show-hide-review' => '$1 dnevnik pregledov',
@@ -12500,7 +12540,9 @@
1250112541 'revreview-hist-basic-auto' => '[{{fullurl:$1|stableis=$2}} automatiskt synad]',
1250212542 'revreview-diff-toggle-show' => '(visa ändringar)',
1250312543 'revreview-diff-toggle-hide' => '(dölj ändringar)',
12504 - 'revreview-log-details-show' => '(visa detaljer)',
 12544+ 'revreview-log-toggle-show' => 'visa stabilitetslogg',
 12545+ 'revreview-log-toggle-hide' => 'dölj stabilitetslogg',
 12546+ 'revreview-log-details-show' => 'visa detaljer',
1250512547 'revreview-log-details-hide' => 'dölj detaljer',
1250612548 'review-diff2stable' => 'Visa ändringar mellan den stabila och den senaste versionen',
1250712549 'review-logentry-app' => 'granskat en version av [[$1]]',
@@ -12595,7 +12637,9 @@
1259612638 'revreview-style-3' => 'Koncis',
1259712639 'revreview-style-4' => 'Utmärkt',
1259812640 'revreview-submit' => 'Spara',
 12641+ 'revreview-submit-review' => 'Godkänn',
1259912642 'revreview-submitting' => 'Levererar...',
 12643+ 'revreview-submit-reviewed' => 'Klar. Godkänd!',
1260012644 'revreview-successful' => "'''Vald sidversion av [[:$1|$1]] har flaggats. ([{{fullurl:{{#Special:ReviewedVersions}}|page=$2}} visa alla stabila sidversioner])'''",
1260112645 'revreview-successful2' => "'''Vald sidversion av [[:$1|$1]] har avflaggats.'''",
1260212646 'revreview-text' => "''[[{{MediaWiki:Validationpage}}|Stabila versioner]] är standardinnehåll i sidor i stället för den nyaste sidversionen.''",
@@ -12610,20 +12654,20 @@
1261112655 'revreview-visibility3' => "'''Den här sidan har inte en [[{{MediaWiki:Validationpage}}|stabil version]]; inställningarna för sidstabilitet kan [{{fullurl:{{#Special:Stabilization}}|page={{FULLPAGENAMEE}}}} konfigureras].'''",
1261212656 'revreview-revnotfound' => 'Den gamla versionen av den sida du frågade efter kan inte hittas. Kontrollera den URL du använde för att nå den här sidan.',
1261312657 'right-autoreview' => 'Automatiskt märka sidversioner som synade',
12614 - 'right-movestable' => 'Flytta stabila sidor',
 12658+ 'right-movestable' => 'Flytta publicerade sidor',
1261512659 'right-review' => 'Markera sidversioner som synade',
12616 - 'right-stablesettings' => 'Ställa in hur stabila versioner väljs och visas',
 12660+ 'right-stablesettings' => 'Ställa in hur den publicerade versionen väljs och visas',
1261712661 'right-validate' => 'Markera sidversioner som validerade',
1261812662 'right-unreviewedpages' => 'Visa [[Special:UnreviewedPages|lista över ogranskade sidor]]',
1261912663 'rights-editor-autosum' => 'autobefodring',
1262012664 'rights-editor-revoke' => 'tog bort redaktörsstatus från [[$1]]',
1262112665 'specialpages-group-quality' => 'Kvalitetsförsäkring',
12622 - 'stable-logentry-config' => 'ändrade inställningar för stabila versioner av [[$1]]',
12623 - 'stable-logentry-reset' => 'återställde inställningar för stabila versioner av [[$1]]',
 12666+ 'stable-logentry-config' => 'konfigurera publikationsinställningar för [[$1]]',
 12667+ 'stable-logentry-reset' => 'återställ publikationsinställningar för [[$1]]',
1262412668 'stable-logpage' => 'Versionsstabiliseringslogg',
1262512669 'stable-logpagetext' => 'Det här är en logg över ändringar av inställningar för [[{{MediaWiki:Validationpage}}|stabila versioner]] av innehållssidor.',
1262612670 'revreview-filter-all' => 'Alla',
12627 - 'revreview-filter-stable' => 'stabil',
 12671+ 'revreview-filter-stable' => 'publicerad',
1262812672 'revreview-statusfilter' => 'Ändring av status:',
1262912673 'revreview-filter-approved' => 'Godkända',
1263012674 'revreview-filter-reapproved' => 'Åter godkända',
@@ -12636,12 +12680,16 @@
1263712681 'revreview-lev-basic' => 'synad',
1263812682 'revreview-lev-quality' => 'kvalitet',
1263912683 'revreview-lev-pristine' => 'orörd',
 12684+ 'revreview-defaultfilter' => 'Standardversion:',
1264012685 'revreview-def-draft' => 'senaste',
 12686+ 'revreview-def-stable' => 'publicerad',
1264112687 'revreview-restriction-none' => 'ingen',
1264212688 'revreview-reviewlink' => 'granska',
 12689+ 'revreview-unreviewedpage' => 'ej kontrollerad sida',
1264312690 'tooltip-ca-current' => 'Visa det senaste utkastet för denna sida',
1264412691 'tooltip-ca-stable' => 'Visa den publicerade versionen av denna sida',
1264512692 'tooltip-ca-default' => 'Inställningar för kvalitetssäkring',
 12693+ 'flaggedrevs-protect-none' => 'Tillåt alla användare',
1264612694 'flaggedrevs-protect-basic' => 'Standardinställning',
1264712695 'revreview-locked-title' => 'Redigeringar måste granskas innan de visas på den här sidan!',
1264812696 'revreview-unlocked-title' => 'Redigeringar behöver inte granskas innan de visas på den här sidan!',
@@ -13448,8 +13496,10 @@
1344913497 'revreview-diff-toggle-title' => 'Yayımlanmış sürüme bekleyen değişikliklerin görüntülenmesini değiştir',
1345013498 'revreview-log-toggle-show' => 'kararlılık günlüğünü göster',
1345113499 'revreview-log-toggle-hide' => 'kararlılık günlüğünü gizle',
 13500+ 'revreview-log-toggle-title' => 'Kararlılık ayarları günlüğünün görünümünü değiştir',
1345213501 'revreview-log-details-show' => 'ayrıntıları göster',
1345313502 'revreview-log-details-hide' => 'detayları gizle',
 13503+ 'revreview-log-details-title' => 'Kararlılık ayarları günlüğünün görünümünü değiştir',
1345413504 'review-diff2stable' => 'Yayımlanmış sürüme bekleyen değişiklikleri göster',
1345513505 'review-logentry-app' => '[[$1]] sayfasının bir sürümü incelendi',
1345613506 'review-logentry-dis' => '[[$1]] sayfasının bir sürümü onaylanmadı',
@@ -13469,9 +13519,9 @@
1347013520 'revreview-approved' => 'Onaylı',
1347113521 'revreview-auto' => '(otomatik)',
1347213522 'revreview-basic' => 'Bu [[{{MediaWiki:Validationpage}}|yayımlanmış sürümdür]], <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} kontrol edilmiştir].
13473 -[{{fullurl:{{FULLPAGENAMEE}}|stable=0}} Taslak] [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 bekleyen {{PLURAL:$3|değişiklik|değişiklik}}] içermektedir.',
 13523+Gözden geçirme bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 {{PLURAL:$3|değişiklik|değişiklik}}] bulunmaktadır.',
1347413524 'revreview-basic-i' => 'Bu [[{{MediaWiki:Validationpage}}|yayımlanmış]] sürümdür, <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} kontrol edilmiştir].
13475 -[{{fullurl:{{FULLPAGENAMEE}}|stable=0}} Taslak] gözden geçirilmeyi bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} şablon/dosya değişikliği] içermektedir.',
 13525+Gözden geçirilmeyi bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} şablon/dosya değişiklikleri] bulunmaktadır.',
1347613526 'revreview-basic-old' => 'Bu bir [[{{MediaWiki:Validationpage}}|kontrol edilmiş]] revizyondur ([{{fullurl:{{#Special:ReviewedVersions}}|page={{FULLPAGENAMEE}}}} hepsini listele]), <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylanmıştır].
1347713527 Yeni [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} değişiklikler] yapılmış olabilir.',
1347813528 'revreview-basic-same' => 'Bu en son [[{{MediaWiki:Validationpage}}|yayımlanmış sürümdür]], <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} kontrol edilmiştir].',
@@ -13491,10 +13541,11 @@
1349213542 'revreview-depth-4' => 'Özellikli',
1349313543 'revreview-draft-title' => 'Bekleyen değişiklikler bu sayfada görünür',
1349413544 'revreview-edit' => 'Değiştir',
13495 - 'revreview-editnotice' => "'''Değişiklikleriniz, yetkili bir kullanıcı [[{{MediaWiki:Validationpage}}|inceledikten]] sonra [[{{MediaWiki:Validationpage}}|yayınlanacak]].'''",
 13545+ 'revreview-editnotice' => "'''Değişiklikleriniz, yetkili bir kullanıcı inceledikten sonra yayınlanacak. ([[{{MediaWiki:Validationpage}}|?]])'''",
1349613546 'revreview-check-flag' => 'Şuanda bekleyen değişiklikleri yayınla',
13497 - 'revreview-edited' => "'''Değişiklikler, yetkili bir kullanıcı [[{{MediaWiki:Validationpage}}|inceledikten]] sonra [[{{MediaWiki:Validationpage}}|yayınlanacak]].'''
13498 -Aşağıda gösterilen ''taslak'', önerilmiş [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $2 {{PLURAL:$2|değişikliği|değişikliği}}] içermektedir.",
 13547+ 'revreview-edited' => "'''Değişiklikler, yetkili bir kullanıcı inceledikten sonra yayınlanacak. ([[{{MediaWiki:Validationpage}}|?]])'''
 13548+
 13549+Gözden geçirme bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $2 {{PLURAL:$2|değişiklik|değişiklik}}] ''(aşağıda gösterilen)'' bulunmaktadır.",
1349913550 'revreview-edited-section' => '"[[#$1|$2]]" adındaki sayfa bölümüne geri dön.',
1350013551 'revreview-flag' => 'Bu revizyonu gözden geçir',
1350113552 'revreview-reflag' => 'Bu revizyonu tekrar gözden geçir',
@@ -13504,25 +13555,23 @@
1350513556 'revreview-main' => 'Gözden geçirmek için, içerik sayfasından belirli bir revizyon seçmelisiniz.
1350613557
1350713558 [[Special:Unreviewedpages|Gözden geçirilmemiş sayfalar listesine]] göz atın.',
13508 - 'revreview-newest-basic' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} kontrol edilmiş].
13509 -Taslak [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 bekleyen {{PLURAL:$3|değişiklik|değişiklik}}] içeriyor.',
13510 - 'revreview-newest-basic-i' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} kontrol edilmiş].
13511 -Taslak gözden geçirilmeyi bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} Şablon/dosya değişiklikleri] içeriyor.',
13512 - 'revreview-newest-quality' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylanmış]. Taslak
13513 -[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 bekleyen {{PLURAL:$3|değişiklik|değişiklik}}] içeriyor.',
13514 - 'revreview-newest-quality-i' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylanmış]. Taslak gözden geçirilmeyi bekleyen
13515 -[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} şablon/dosya değişikliği] içeriyor.',
13516 - 'revreview-pending-basic' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} kontrol edilmiş]. [{{fullurl:{{FULLPAGENAMEE}}|stable=0}} Taslak] [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 bekleyen {{PLURAL:$3|değişiklik|değişiklik}}] içeriyor.',
13517 - 'revreview-pending-quality' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylanmış]. [{{fullurl:{{FULLPAGENAMEE}}|stable=0}} Taslak] [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 bekleyen {{PLURAL:$3|değişiklik|değişiklik}}] içeriyor.',
13518 - 'revreview-pending-nosection' => 'Bölümün taşındığını veya silindiğini görmek için [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $2 bekleyen {{PLURAL:$2|değişiklik|değişiklik}}] içeren [{{fullurl:{{FULLPAGENAMEE}}|stable=0}} taslağı] görüntülemeyi deneyin.',
 13559+ 'revreview-newest-basic' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} kontrol edilmiş]. Gözden geçirme bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 {{PLURAL:$3|değişiklik|değişiklik}}] bulunmaktadır.',
 13560+ 'revreview-newest-basic-i' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} kontrol edilmiş]. Gözden geçirilmeyi bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} şablon/dosya değişiklikleri] bulunmaktadır.',
 13561+ 'revreview-newest-quality' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylanmış]. Gözden geçirmeyi bekleyen
 13562+[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 {{PLURAL:$3|değişiklik|değişiklik}}] bulunmaktadır.',
 13563+ 'revreview-newest-quality-i' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylanmış]. Gözden geçirilmeyi bekleyen
 13564+[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} şablon/dosya değişiklikleri] bulunmaktadır.',
 13565+ 'revreview-pending-basic' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} kontrol edilmiş]. Gözden geçirilmeyi bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 {{PLURAL:$3|değişiklik|değişiklik}}] bulunmaktadır.',
 13566+ 'revreview-pending-quality' => '[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} Yayımlanmış sürüm] <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylanmış]. Gözden geçirilmeyi bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 {{PLURAL:$3|değişiklik|değişiklik}}] bulunmaktadır.',
 13567+ 'revreview-pending-nosection' => 'Bölümün taşındığını veya silindiğini görmek için [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $2 bekleyen {{PLURAL:$2|değişiklik|değişiklik}}] içeren [{{fullurl:{{FULLPAGENAMEE}}|stable=0}} en son revizyonu] görüntülemeyi deneyin.',
1351913568 'revreview-noflagged' => "Bu sayfanın hiç [[{{MediaWiki:Validationpage}}|gözden geçirilmiş]] revizyonu yok, bu yüzden kalite için [[{{MediaWiki:Validationpage}}|'''denetlenmemiş''']] olabilir.",
1352013569 'revreview-note' => '[[User:$1|$1]] bu revizyonu [[{{MediaWiki:Validationpage}}|gözden geçirerek]] şu notu bıraktı:',
1352113570 'revreview-notes' => 'Görüntülenecek gözlem ve notlar:',
1352213571 'revreview-oldrating' => 'Derecelendirme:',
1352313572 'revreview-quality' => 'Bu, <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylanan] [[{{MediaWiki:Validationpage}}|yayımlanmış sürümdür]].
13524 -[{{fullurl:{{FULLPAGENAMEE}}|stable=0}} Taslak], incelenmeyi bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 bekleyen {{PLURAL:$3|değişiklik|değişiklik}}] içermektedir.',
 13573+İncelenmeyi bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3 {{PLURAL:$3|değişiklik|değişiklik}}] bulunmaktadır.',
1352513574 'revreview-quality-i' => 'Bu, <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylanan] [[{{MediaWiki:Validationpage}}|yayımlanmış sürümdür]].
13526 -[{{fullurl:{{FULLPAGENAMEE}}|stable=0}} Taslak], incelenmeyi bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} şablon/dosya değişikliklerine] sahiptir.',
 13575+İncelenmeyi bekleyen [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} şablon/dosya değişiklikleri] bulunmaktadır.',
1352713576 'revreview-quality-old' => 'Bu bir [[{{MediaWiki:Validationpage}}|kaliteli]] revizyondur ([{{fullurl:{{#Special:ReviewedVersions}}|page={{FULLPAGENAMEE}}}} hepsini listele]), <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylanmıştır].
1352813577 Yeni [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} değişiklikler] yapılmış olabilir.',
1352913578 'revreview-quality-same' => 'Bu, <i>$2</i> tarihinde [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylanan] [[{{MediaWiki:Validationpage}}|yayımlanmış sürümdür]].',
@@ -13533,19 +13582,17 @@
1353413583 'revreview-quick-basic-same' => "'''[[{{MediaWiki:Validationpage}}|Kontrol edilmiş]]'''",
1353513584 'revreview-quick-invalid' => "'''Geçersiz revizyon IDsi'''",
1353613585 'revreview-quick-none' => "'''[[{{MediaWiki:Validationpage}}|Kontrol edilmemiş]]'''",
13537 - 'revreview-quick-quality' => "'''[[{{MediaWiki:Validationpage}}|Kaliteli sayfa]]''' [[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} karalamayı gör]]",
 13586+ 'revreview-quick-quality' => "'''[[{{MediaWiki:Validationpage}}|Kaliteli]]''' [[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} bekleyen değişiklikleri gözden geçir]]",
1353813587 'revreview-quick-quality-old' => "'''[[{{MediaWiki:Validationpage}}|Kaliteli]]'''",
1353913588 'revreview-quick-quality-same' => "'''[[{{MediaWiki:Validationpage}}|Kaliteli]]'''",
13540 - 'revreview-quick-see-basic' => "'''[[{{MediaWiki:Validationpage}}|Taslak]]''' [[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} yayımlanmış sürüm]]
13541 -[[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} karşılaştır]]",
13542 - 'revreview-quick-see-quality' => "'''[[{{MediaWiki:Validationpage}}|Taslak]]''' [[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} yayımlanmış sürüm]]
13543 -[[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} karşılaştır]]",
 13589+ 'revreview-quick-see-basic' => '[[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} bekleyen değişiklikleri gözden geçir]]',
 13590+ 'revreview-quick-see-quality' => '[[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} bekleyen değişiklikleri gözden geçir]]',
1354413591 'revreview-selected' => "'''$1 için seçili revizyon:'''",
1354513592 'revreview-source' => 'Kaynağı gör',
1354613593 'revreview-stable' => 'Yayımlanmış sayfa',
1354713594 'revreview-basic-title' => 'Bu, bu sayfanın kontrol edilmiş bir sürümüdür',
1354813595 'revreview-stable1' => '[{{fullurl:$1|stableid=$2}} Bu işaretli sürümü] görüp, şimdi bu sayfanın [{{fullurl:$1|stable=1}} yayımlanmış sürümü] olup olmadığını görmek isteyebilirsiniz.',
13549 - 'revreview-stable2' => 'Bu sayfanın [{{fullurl:$1|stable=1}} yayımlanmış sürümünü] (eğer hala bir tane varsa) görmek isteyebilirsiniz.',
 13596+ 'revreview-stable2' => 'Bu sayfanın [{{fullurl:$1|stable=1}} yayımlanmış sürümünü] görmek isteyebilirsiniz.',
1355013597 'revreview-style' => 'Okunaklılık',
1355113598 'revreview-style-0' => 'Onaylanmamış',
1355213599 'revreview-style-1' => 'Geçerli',
@@ -13556,23 +13603,22 @@
1355713604 'revreview-submit-review' => 'Onayla',
1355813605 'revreview-submit-unreview' => 'Onayı iptal et',
1355913606 'revreview-submitting' => 'Gönderiliyor...',
13560 - 'revreview-submit-reviewed' => 'Tamam. Kontrol edildi!',
13561 - 'revreview-submit-unreviewed' => 'Tamam. Kontrol edilmedi!',
 13607+ 'revreview-submit-reviewed' => 'Tamam. Onaylandı!',
 13608+ 'revreview-submit-unreviewed' => 'Tamam. Onay kaldırıldı!',
1356213609 'revreview-successful' => "'''[[:$1|$1]] için revizyonu başarıyla işaretlendi. ([{{fullurl:{{#Special:ReviewedVersions}}|page=$2}} kararlı sürümleri gör])'''",
1356313610 'revreview-successful2' => "'''[[:$1|$1]] için revizyonun işareti başarıyla kaldırıldı.'''",
1356413611 'revreview-text' => "''[[{{MediaWiki:Validationpage}}|Gözden geçirilmiş sürümler]] yayımlanmış sürümü belirlemek için kullanılan, sayfaların kontrol edilmiş sürümleridir.''",
1356513612 'revreview-toggle-title' => 'detayları göster/gizle',
13566 - 'revreview-toolow' => '\'\'\'Bir revizyonun gözden geçirilmiş sayılabilmesi için aşağıdaki özniteliklerden her birini "onaylanmamış"dan yüksek oylamalısınız.\'\'\'
13567 -Bir revizyonu aşındırmak için, tüm alanları "onaylanmamış" seçin.
 13613+ 'revreview-toolow' => '\'\'\'Bir revizyonun gözden geçirilmiş sayılabilmesi için özniteliklerden her birini "onaylanmamış"dan yüksek oylamalısınız.\'\'\'
 13614+Bir revizyonun gözden geçirme durumunu çıkarmak için, tüm alanları "onaylanmamış" seçin.
1356813615
1356913616 Lütfen tarayıcınızdaki "geri" tuşuna basın ve tekrar deneyin.',
13570 - 'revreview-update' => "Lütfen yayımlanmış sürümün [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} onaylandığından] beri yapılan her değişikliği ''(aşağıda gösterilmiş)'' [[{{MediaWiki:Validationpage}}|gözden geçirin]].<br />
13571 -'''Bazı şablonlar/dosyalar güncellenmiş:'''",
13572 - 'revreview-update-edited' => "Bu sayfayı değiştirdiğinizde, bazı ''diğer'' değişiklikler zaten gözden geçirme bekliyordu.
 13617+ 'revreview-update' => "Lütfen yayımlanmış sürüme yapılan bekleyen her değişikliği ''(aşağıda gösterilmiş)'' [[{{MediaWiki:Validationpage}}|gözden geçirin]].",
 13618+ 'revreview-update-edited' => '<span class="flaggedrevs_important">Değişiklikleriniz henüz yayınlanmadı.</span>
1357313619
13574 -Değişikliklerinizi yayınlamak için, lütfen ''(aşağıda gösterilen)'' bekleyen ''tüm'' değişiklikleri ''[[{{MediaWiki:Validationpage}}|gözden geçirin]]''.",
 13620+Gözden geçirme bekleyen önceki değişiklikler var. Değişikliklerinizi yayınlamak için, lütfen aşağıda gösterilen tüm değişiklikleri gözden geçirin.',
1357513621 'revreview-update-includes' => "'''Bazı şablonlar/dosyalar güncellenmiş:'''",
13576 - 'revreview-update-use' => "'''NOT:''' Eğer bu şablonların/dosyaların herhangi birisinin yayımlanmış sürümü varsa, zaten bu sayfanın yayımlanmış sürümünde kullanılmıştır.",
 13622+ 'revreview-update-use' => "'''NOT:''' Her şablon/dosyanın yayımlanmış sürümleri, bu sayfanın yayımlanmış sürümünde kullanılmıştır.",
1357713623 'revreview-visibility' => "'''Bu sayfanın güncellenmiş bir [[{{MediaWiki:Validationpage}}|yayımlanmış sürümü]] mevcut; sayfa kararlılık ayarları [{{fullurl:{{#Special:Stabilization}}|page={{FULLPAGENAMEE}}}} yapılandırılabilir].'''",
1357813624 'revreview-visibility2' => "'''Bu sayfanın tarihi geçmiş bir [[{{MediaWiki:Validationpage}}|yayımlanmış sürümü]] vardır; sayfa kararlılık ayarları [{{fullurl:{{#Special:Stabilization}}|page={{FULLPAGENAMEE}}}} yapılandırılabilir].'''",
1357913625 'revreview-visibility3' => "'''Bu sayfanın bir [[{{MediaWiki:Validationpage}}|yayımlanmış sürümü]] yoktur; sayfa kararlılık ayarları [{{fullurl:{{#Special:Stabilization}}|page={{FULLPAGENAMEE}}}} yapılandırılabilir].'''",
@@ -13619,7 +13665,7 @@
1362013666 'tooltip-ca-current' => 'Bu sayfanın güncel karalamasını gör',
1362113667 'tooltip-ca-stable' => 'Bu sayfanın yayımlanmış sürümünü gör',
1362213668 'tooltip-ca-default' => 'Kalite güvencesi ayarları',
13623 - 'flaggedrevs-protect-legend' => 'Değişiklikleri yayınla',
 13669+ 'flaggedrevs-protect-legend' => 'Değişiklikleri yayınla ([[{{MediaWiki:Validationpage}}|?]])',
1362413670 'flaggedrevs-protect-none' => 'Tüm kullanıcılara izin ver',
1362513671 'flaggedrevs-protect-basic' => 'Varsayılan ayarlar',
1362613672 'revreview-locked-title' => 'Bu sayfada gösterilmeden önce, değişiklikler gözden geçirilmeli!',
@@ -13844,10 +13890,11 @@
1384513891 'revreview-restriction-any' => 'будь-яка',
1384613892 'revreview-restriction-none' => 'немає',
1384713893 'revreview-reviewlink' => 'нерецензовані редагування',
 13894+ 'revreview-unreviewedpage' => 'неперевірена сторінка',
1384813895 'tooltip-ca-current' => 'Переглянути цю сторінку з нерецензованими змінами',
1384913896 'tooltip-ca-stable' => 'Переглянути опубліковану версію цієї сторінки',
1385013897 'tooltip-ca-default' => 'Налаштування контролю якості',
13851 - 'flaggedrevs-protect-legend' => 'Опублікувати редагування',
 13898+ 'flaggedrevs-protect-legend' => 'Опубліковані редагування ([[{{MediaWiki:Validationpage}}|?]])',
1385213899 'flaggedrevs-protect-none' => 'Дозволено всім користувачам',
1385313900 'flaggedrevs-protect-basic' => 'Установки за умовчанням',
1385413901 'revreview-locked-title' => 'Редагування мають бути перевірені перед тим, як будуть показані на цій сторінці!',
@@ -14291,7 +14338,7 @@
1429214339 'flaggedrevs-backlog' => "Hiện đang lạc hậu về [[Special:OldReviewedPages|trang cần duyệt lại]]. '''Cần bạn chú ý!'''",
1429314340 'flaggedrevs-watched-pending' => "Hiện có [{{fullurl:{{#Special:OldReviewedPages}}|watched=1}} sửa đổi chưa duyệt] tại trang đã duyệt trong danh sách theo dõi của bạn. '''Cần bạn chú ý!'''",
1429414341 'flaggedrevs-desc' => 'Cung cấp cho người viết và người duyệt bài khả năng phê chuẩn phiên bản và ổn định trang',
14295 - 'flaggedrevs-pref-UI' => 'Giao diện phiên bản ổn định:',
 14342+ 'flaggedrevs-pref-UI' => 'Giao diện cơ bản:',
1429614343 'flaggedrevs-pref-UI-0' => 'Sử dụng giao diện người dùng phiên bản ổn định chi tiết',
1429714344 'flaggedrevs-pref-UI-1' => 'Sử dụng giao diện người dùng phiên bản ổn định đơn giản',
1429814345 'prefs-flaggedrevs' => 'Ổn định',
@@ -14315,6 +14362,10 @@
1431614363 'revreview-hist-quality-user' => '[[User:$3|$3]] [{{fullurl:$1|stableid=$2}} đã phê chuẩn]',
1431714364 'revreview-hist-basic-user' => '[[User:$3|$3]] [{{fullurl:$1|stableid=$2}} đã xem qua]',
1431814365 'revreview-hist-basic-auto' => '[{{fullurl:$1|stableid=$2}} được xem qua tự động]',
 14366+ 'revreview-diff-toggle-show' => 'hiện thay đổi',
 14367+ 'revreview-diff-toggle-hide' => 'ẩn thay đổi',
 14368+ 'revreview-log-details-show' => 'hiện chi tiết',
 14369+ 'revreview-log-details-hide' => 'ẩn chi tiết',
1431914370 'review-diff2stable' => 'So sánh phiên bản ổn định với bản hiện hành',
1432014371 'review-logentry-app' => 'đã duyệt phiên bản $2 của [[$1]]',
1432114372 'review-logentry-dis' => 'đã đánh giá thấp hơn cho phiên bản $2 của [[$1]]',
@@ -14355,7 +14406,7 @@
1435614407 'revreview-depth-3' => 'Cao',
1435714408 'revreview-depth-4' => 'Rất tốt',
1435814409 'revreview-draft-title' => 'Đây là trang nháp',
14359 - 'revreview-edit' => 'Sửa đổi bản nháp',
 14410+ 'revreview-edit' => 'Sửa đổi',
1436014411 'revreview-editnotice' => "'''Các sửa đổi tại trang này sẽ vào bản [[{{MediaWiki:Validationpage}}|ổn định]] lúc khi chúng được duyệt bởi một thành viên được quyền.'''",
1436114412 'revreview-edited' => "'''Những sửa đổi sẽ được đưa vào [[{{MediaWiki:Validationpage}}|bản ổn định]] ngay khi được một thành viên được chỉ định duyệt qua.
1436214413 Dưới đây là ''bản nháp''.''' Có [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $2 {{PLURAL:$2|thay đổi|thay đổi}}] đề nghị.",
@@ -14408,6 +14459,7 @@
1440914460 'revreview-style-3' => 'Súc tích',
1441014461 'revreview-style-4' => 'Rất tốt',
1441114462 'revreview-submit' => 'Đăng bản duyệt',
 14463+ 'revreview-submit-review' => 'Chấp nhận',
1441214464 'revreview-submitting' => 'Đang gửi thông tin…',
1441314465 'revreview-successful' => "'''Phiên bản của [[:$1|$1]] đã được gắn cờ. ([{{fullurl:{{#Special:ReviewedVersions}}|page=$2}} xem các phiên bản có cờ])'''",
1441414466 'revreview-successful2' => "'''Phiên bản của [[:$1|$1]] đã được bỏ cờ thành công.'''",
@@ -14887,6 +14939,7 @@
1488814940 /** Traditional Chinese (‪中文(繁體)‬)
1488914941 * @author Alexsh
1489014942 * @author Gaoxuewei
 14943+ * @author Horacewai2
1489114944 * @author Liangent
1489214945 * @author Mark85296341
1489314946 * @author Wrightbus
@@ -14898,7 +14951,13 @@
1489914952 'flaggedrevs-backlog' => "目前有積壓的[[Special:OldReviewedPages|編輯]]未複查。'''需要您的注意!'''",
1490014953 'flaggedrevs-watched-pending' => "您監視列表上有積壓的[{{fullurl:{{#Special:OldReviewedPages}}|watched=1}} 編輯]未複查。'''需要您的注意!'''",
1490114954 'flaggedrevs-desc' => '給予編輯者與評論家能力去核實修訂以及穩定化頁面',
14902 - 'prefs-flaggedrevs' => '穩定性',
 14955+ 'flaggedrevs-pref-UI' => '基本界面:',
 14956+ 'flaggedrevs-pref-UI-0' => '使用詳細的審批狀態框來顯示此頁面的複審狀態',
 14957+ 'flaggedrevs-pref-UI-1' => '使用小圖標和顯示最小的文字來表示頁面的審批狀態',
 14958+ 'prefs-flaggedrevs' => '編輯審核',
 14959+ 'prefs-flaggedrevs-ui' => '編輯審批',
 14960+ 'flaggedrevs-prefs-stable' => '始終顯示已發布的版本的內容(如果有)',
 14961+ 'flaggedrevs-prefs-watch' => '將我評審的頁面添加到我的監視列表中',
1490314962 'flaggedrevs-prefs-editdiffs' => '在編輯時顯示與穩定版本的差異',
1490414963 'flaggedrevs-prefs-viewdiffs' => '在顯示頁面草稿時顯示與穩定版本的差異',
1490514964 'group-editor' => '編輯',
@@ -14909,17 +14968,31 @@
1491014969 'grouppage-reviewer' => '{{ns:project}}:評論家',
1491114970 'group-autoreview' => '自動複查員',
1491214971 'group-autoreview-member' => '自動複查員',
 14972+ 'grouppage-autoreview' => '{{ns:project}}:自動複審',
 14973+ 'revreview-hist-draft' => '未經檢查的修訂',
1491314974 'revreview-hist-quality' => '[質素]',
14914 - 'revreview-hist-basic' => '[已察]',
 14975+ 'revreview-hist-basic' => '已察版本',
1491514976 'revreview-hist-quality-user' => '[{{fullurl:$1|stableid=$2}} 已驗證]由[[User:$3|$3]]',
14916 - 'revreview-hist-basic-user' => '[{{fullurl:$1|stableid=$2}} 已複查]由[[User:$3|$3]]',
 14977+ 'revreview-hist-basic-user' => '已由[[User:$3|$3]][{{fullurl:$1|stableid=$2}} 複查]',
1491714978 'revreview-hist-basic-auto' => '[{{fullurl:$1|stableid=$2}} 已自動複查]',
14918 - 'review-diff2stable' => '跟上次穩定修訂的差異',
 14979+ 'revreview-hist-quality-auto' => '[{{fullurl:$1|stableid=$2}} 已自動複查]',
 14980+ 'revreview-hist-pending' => "'''[[{{fullurl:$1|oldid=$2&diff=$3}} 等待審核]]'''",
 14981+ 'review-edit-diff' => "'''注意:一些懸而未決的更改已發布的版本納入編輯下面的表格。'''",
 14982+ 'revreview-diff-toggle-show' => '顯示變化',
 14983+ 'revreview-diff-toggle-hide' => '隱藏變化',
 14984+ 'revreview-diff-toggle-title' => '切換顯示掛起的更改已發布的版本',
 14985+ 'revreview-log-toggle-show' => '顯示穩定版本日誌',
 14986+ 'revreview-log-toggle-hide' => '隱藏穩定版本日誌',
 14987+ 'revreview-log-toggle-title' => '切換至顯示穩定性設置日誌',
 14988+ 'revreview-log-details-show' => '顯示詳情',
 14989+ 'revreview-log-details-hide' => '隱藏細節',
 14990+ 'revreview-log-details-title' => '切換至顯示穩定性設置日誌',
 14991+ 'review-diff2stable' => '查看所有懸而未決的變化',
1491914992 'review-logentry-app' => '[[$1]]的已複查版本',
1492014993 'review-logentry-dis' => '[[$1]]的不推薦版本',
1492114994 'review-logentry-id' => '修訂 ID: $2',
1492214995 'review-logentry-diff' => '修改已複查',
14923 - 'review-logentry-diff2' => '修改未複查',
 14996+ 'review-logentry-diff2' => '修改過時',
1492414997 'review-logpage' => '文章複審記錄',
1492514998 'review-logpagetext' => '這個是內容頁[[{{MediaWiki:Validationpage}}|批准]]狀態的更改記錄。',
1492614999 'reviewer' => '評論家',
@@ -14971,16 +15044,22 @@
1497215045 於<i>$2</i>[{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} 批准]。[{{fullurl:{{FULLPAGENAMEE}}|stable=0}} 現時修訂]
1497315046 可以[{{fullurl:{{FULLPAGENAMEE}}|action=edit}} 更改]];[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $3次更改]
1497415047 正等候複審。',
 15048+ 'revreview-quality-same' => '這是於<i>$2</i>被[{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} 審核]的[[{{MediaWiki:Validationpage}}|已審核版本]]',
 15049+ 'revreview-quality-source' => '這是一個[{{fullurl:{{FULLPAGENAMEE}}|stableid=$1}} 本頁的質數版本],於<i>$2</i>[{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} 被審核]。',
1497515050 'revreview-quality-title' => '這是一個高質量頁面',
14976 - 'revreview-quick-basic' => "'''[[{{MediaWiki:Validationpage}}|視察過的]]'''。[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} 看現時修訂]]",
 15051+ 'revreview-quick-basic' => "''[[{{MediaWiki:Validationpage}}|視察過的]]'''。[[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} 看現時修訂]]",
 15052+ 'revreview-quick-basic-old' => "'''[[{{MediaWiki:Validationpage}}|已審查]]'''",
 15053+ 'revreview-quick-basic-same' => "'''[[{{MediaWiki:Validationpage}}|已審核]]'''",
1497715054 'revreview-quick-invalid' => "'''修訂版本號碼錯誤'''",
14978 - 'revreview-quick-none' => "'''現時的'''。沒有已複審的修訂。",
 15055+ 'revreview-quick-none' => "'''[[{{MediaWiki:Validationpage}}|現時的]]'''。沒有已複審的修訂。",
1497915056 'revreview-quick-quality' => "'''[[{{MediaWiki:Validationpage}}|有質素的]]'''。[[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} 看現時修訂]]",
14980 - 'revreview-quick-see-basic' => "'''現時的'''。[[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} 看最後檢查過的修訂]]",
14981 - 'revreview-quick-see-quality' => "'''現時的'''。[[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} 看睇最後的質素修訂]]",
 15057+ 'revreview-quick-quality-old' => "'''[[{{MediaWiki:Validationpage}}|有質數的]]'''",
 15058+ 'revreview-quick-quality-same' => "'''[[{{MediaWiki:Validationpage}}|有質數的]]'''",
 15059+ 'revreview-quick-see-basic' => "'''現時的'''。[[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} 看最後檢查過的修訂]]",
 15060+ 'revreview-quick-see-quality' => "'''現時的'''。[[{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} 看睇最後的質素修訂]]",
1498215061 'revreview-selected' => "已經選擇 '''$1''' 的修訂:",
14983 - 'revreview-source' => '草稿原始碼',
14984 - 'revreview-stable' => '穩定',
 15062+ 'revreview-source' => '檢視原始碼',
 15063+ 'revreview-stable' => '穩定頁面',
1498515064 'revreview-basic-title' => '這是一個已複查頁面',
1498615065 'revreview-style' => '可讀性',
1498715066 'revreview-style-0' => '未批准',
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/OldReviewedPages.i18n.php
@@ -348,6 +348,7 @@
349349 );
350350
351351 /** German (Deutsch)
 352+ * @author Kghbln
352353 * @author Melancholie
353354 * @author Michawiki
354355 * @author Raimond Spekking
@@ -355,7 +356,7 @@
356357 * @author Umherirrender
357358 */
358359 $messages['de'] = array(
359 - 'oldreviewedpages' => 'Alte, gesichtete Seiten',
 360+ 'oldreviewedpages' => 'Seiten mit unmarkierten Änderungen',
360361 'oldreviewedpages-legend' => 'Liste gesichteter Seiten mit ungesichteten Versionen',
361362 'oldreviewedpages-list' => 'Diese Spezialseite zeigt {{PLURAL:$1|eine gesichtete Seite|gesichtete Seiten}}, die noch ungesichtete Bearbeitungen {{PLURAL:$1|hat|haben}}.',
362363 'oldreviewedpages-none' => 'Gegenwärtig gibt es keine Seiten, auf die diese Kriterien zutreffen.',
@@ -1300,19 +1301,19 @@
13011302 */
13021303 $messages['ro'] = array(
13031304 'oldreviewedpages' => 'Pagini revizuite expirate',
1304 - 'oldreviewedpages-legend' => 'Lista de pagini revizuite, cu revizuiri în aşteptarea revizuirii',
1305 - 'oldreviewedpages-list' => 'Această pagină afişează {{PLURAL:$1|o pagină revizuită care are|paginile revizuite care au}} modificări în aşteptare.',
 1305+ 'oldreviewedpages-legend' => 'Lista de pagini revizuite, cu revizuiri în așteptarea revizuirii',
 1306+ 'oldreviewedpages-list' => 'Această pagină afișează {{PLURAL:$1|o pagină revizuită care are|paginile revizuite care au}} modificări în așteptare.',
13061307 'oldreviewedpages-none' => 'Momentan nu există pagini care satisfac aceste criterii',
13071308 'oldreviewedpages-hours' => '($1 {{PLURAL:$1|oră|ore}})',
13081309 'oldreviewedpages-days' => '($1 {{PLURAL:$1|zi|zile}})',
1309 - 'oldreviewedpages-recent' => '(mai puţin de 1 oră)',
 1310+ 'oldreviewedpages-recent' => '(mai puțin de 1 oră)',
13101311 'oldreviewed-category' => 'Categorie:',
13111312 'oldreviewed-watched' => 'În lista mea de urmărire',
13121313 'oldreviewed-stable' => 'Stabilit',
13131314 'oldreviewed-diff' => 'revizuire',
1314 - 'oldreviewed-size' => 'Schimbare maximă (baiţi):',
 1315+ 'oldreviewed-size' => 'Schimbare maximă (baiți):',
13151316 'oldreviewedpages-unwatched' => '(neurmărite)',
1316 - 'oldreviewedpages-watched' => '($1 {{PLURAL:$1|utilizator activ care urmăreşte|utilizatori activi care urmăresc}})',
 1317+ 'oldreviewedpages-watched' => '($1 {{PLURAL:$1|utilizator activ care urmărește|utilizatori activi care urmăresc}})',
13171318 'oldreviewedpages-viewing' => '(în curs de revizuire)',
13181319 );
13191320
@@ -1702,6 +1703,7 @@
17031704
17041705 /** Traditional Chinese (‪中文(繁體)‬)
17051706 * @author Gzdavidwong
 1707+ * @author Horacewai2
17061708 * @author Liangent
17071709 * @author Shinjiman
17081710 * @author Wrightbus
@@ -1709,13 +1711,13 @@
17101712 $messages['zh-hant'] = array(
17111713 'oldreviewedpages' => '已過時複審過的頁面',
17121714 'oldreviewedpages-legend' => '列示有未複審修訂之複審過的頁面',
1713 - 'oldreviewedpages-list' => '這個頁面列示出有正等候編輯之評論頁面。',
 1715+ 'oldreviewedpages-list' => '這個頁面列示出{{PLURAL:$1|一個|一些}}正等候編輯之評論頁面。',
17141716 'oldreviewedpages-none' => '這裏現時沒有頁面係合乎這些條件',
17151717 'oldreviewedpages-hours' => '($1小時)',
17161718 'oldreviewedpages-days' => '($1日)',
17171719 'oldreviewedpages-recent' => '(少於1小時)',
17181720 'oldreviewed-category' => '分類:',
1719 - 'oldreviewed-watched' => '在我的監視列表上',
 1721+ 'oldreviewed-watched' => '在我的監視列表上的頁面',
17201722 'oldreviewed-stable' => '穩定的',
17211723 'oldreviewed-diff' => '複審',
17221724 'oldreviewed-size' => '最大變動(位元組):',
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/ProblemChanges.i18n.php
@@ -114,11 +114,12 @@
115115
116116 /** German (Deutsch)
117117 * @author Jens Liebenau
 118+ * @author Kghbln
118119 * @author Khaledelmansoury
119120 * @author Umherirrender
120121 */
121122 $messages['de'] = array(
122 - 'problemchanges' => 'Nachprüfung der markierten Veränderungen',
 123+ 'problemchanges' => 'gekennzeichnete unmarkierte Änderungen',
123124 'problemchanges-legend' => 'Liste der Seiten mit markierten Bearbeitungen, für die noch eine Nachprüfung notwendig ist',
124125 'problemchanges-none' => 'Es gibt zurzeit keine Seiten, die diese Kriterien erfüllen.',
125126 'problemchanges-category' => 'Kategorie:',
@@ -517,7 +518,7 @@
518519 * @author Stelistcristi
519520 */
520521 $messages['ro'] = array(
521 - 'problemchanges' => 'Revizualizaţi schimbările etichetate',
 522+ 'problemchanges' => 'Revizualizați schimbările etichetate',
522523 'problemchanges-category' => 'Categorie:',
523524 );
524525
@@ -672,9 +673,12 @@
673674 );
674675
675676 /** Traditional Chinese (‪中文(繁體)‬)
 677+ * @author Horacewai2
676678 * @author Liangent
677679 */
678680 $messages['zh-hant'] = array(
 681+ 'problemchanges' => '標記審核',
 682+ 'problemchanges-legend' => '列出頁面正等待審核',
679683 'problemchanges-none' => '目前沒有頁面符合這些條件',
680684 'problemchanges-category' => '分類:',
681685 );
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/ReviewedPages.i18n.php
@@ -225,13 +225,15 @@
226226
227227 /** German (Deutsch)
228228 * @author Imre
 229+ * @author Kghbln
229230 * @author Umherirrender
230231 */
231232 $messages['de'] = array(
232 - 'reviewedpages' => 'Liste der gesichteten Seiten',
 233+ 'reviewedpages' => 'Liste der markierten Seiten',
233234 'reviewedpages-leg' => 'Seiten nach Prüfungsstufe auflisten',
234 - 'reviewedpages-list' => 'Diese Spezialseite zeigt Seiten, die bisher mit dem angegebenem Level als höchstes markiert wurden.',
235 - 'reviewedpages-none' => 'Die Liste ist leer.',
 235+ 'reviewedpages-list' => 'Diese Listen enthalten [[{{MediaWiki:Validationpage}}|markierte]] Seiten, deren höchster Qualitätsstatus (einer Version) dem angegebenen Status entspricht.
 236+Der Link zu neuesten Version dieses Status ist angegeben.',
 237+ 'reviewedpages-none' => 'Diese Liste enthält keine Seiten.',
236238 'reviewedpages-lev-0' => 'Gesichtet',
237239 'reviewedpages-lev-1' => 'Geprüft',
238240 'reviewedpages-lev-2' => 'Exzellent',
@@ -952,7 +954,7 @@
953955 */
954956 $messages['ro'] = array(
955957 'reviewedpages' => 'Pagini revizuite',
956 - 'reviewedpages-list' => 'Această pagină afişează paginile care au fost revizuite (la cel mai mare nivel) la nivelul specificat.',
 958+ 'reviewedpages-list' => 'Această pagină afișează paginile care au fost revizuite (la cel mai mare nivel) la nivelul specificat.',
957959 'reviewedpages-none' => 'Nu există pagini în această listă',
958960 'reviewedpages-lev-1' => 'Calitate',
959961 'reviewedpages-all' => 'versiuni revizuite',
@@ -1095,6 +1097,7 @@
10961098
10971099 /** Swedish (Svenska)
10981100 * @author Boivie
 1101+ * @author Dafer45
10991102 * @author Lejonel
11001103 * @author M.M.S.
11011104 * @author McDutchie
@@ -1103,7 +1106,7 @@
11041107 */
11051108 $messages['sv'] = array(
11061109 'reviewedpages' => 'Granskade sidor',
1107 - 'reviewedpages-leg' => 'Lista sidor efter högsta granskningsnivå',
 1110+ 'reviewedpages-leg' => 'Lista sidor som har blivit granskade',
11081111 'reviewedpages-list' => 'Följande {{PLURAL:$1|sida|sidor}} har granskats till (högst) den angivna nivån.',
11091112 'reviewedpages-none' => 'Den här listan innehåller inga sidor',
11101113 'reviewedpages-lev-0' => '{{int:revreview-lev-basic}}',
@@ -1305,12 +1308,13 @@
13061309 );
13071310
13081311 /** Traditional Chinese (‪中文(繁體)‬)
 1312+ * @author Horacewai2
13091313 * @author Shinjiman
13101314 */
13111315 $messages['zh-hant'] = array(
13121316 'reviewedpages' => '複審過的頁面',
13131317 'reviewedpages-leg' => '列示複審過到指定級數之頁面',
1314 - 'reviewedpages-list' => '以下的頁面已經複審到一個指定的級數',
 1318+ 'reviewedpages-list' => '以下的頁面[[{{MediaWiki:Validationpage}}|已經複審]]到一個指定的級數',
13151319 'reviewedpages-none' => '沒有頁面在這個清單中',
13161320 'reviewedpages-lev-0' => '視察過',
13171321 'reviewedpages-lev-1' => '質素',
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/StablePages.i18n.php
@@ -146,14 +146,15 @@
147147 );
148148
149149 /** German (Deutsch)
 150+ * @author Kghbln
150151 * @author MF-Warburg
151152 * @author Purodha
152153 * @author Umherirrender
153154 */
154155 $messages['de'] = array(
155 - 'stablepages' => 'Konfigurierte Seiten',
156 - 'stablepages-text' => 'Es folgt eine Liste der Seiten, die individuell konfiguriert wurden, damit diese die markierte Version als Standardinhalt für Leser anzeigen.',
157 - 'stablepages-none' => 'Diese Liste ist leer.',
 156+ 'stablepages' => 'Seiten die nur mit Bearbeitungsfreigabe bearbeitet werden können',
 157+ 'stablepages-text' => 'Es folgt eine Liste der Seiten, die nur von Benutzern bearbeitet werden können, deren Bearbeitungen keine weitere Durchsicht erfordert. Derartige Bearbeitungen werden nicht veröffentlicht bis ein entsprechend berechtigter Benutzer sie markiert.',
 158+ 'stablepages-none' => 'Diese Liste enthält keine Seiten.',
158159 'stablepages-config' => 'Konfiguration',
159160 );
160161
@@ -591,7 +592,7 @@
592593 $messages['ro'] = array(
593594 'stablepages' => 'Pagini stabile',
594595 'stablepages-none' => 'Nu există pagini în această listă',
595 - 'stablepages-config' => 'Configuraţie',
 596+ 'stablepages-config' => 'Configurație',
596597 );
597598
598599 /** Tarandíne (Tarandíne)
@@ -784,11 +785,12 @@
785786
786787 /** Traditional Chinese (‪中文(繁體)‬)
787788 * @author Gaoxuewei
 789+ * @author Horacewai2
788790 * @author Shinjiman
789791 */
790792 $messages['zh-hant'] = array(
791 - 'stablepages' => '穩定頁面',
792 - 'stablepages-text' => '以下的頁面列示出一些頁面是手動地設定去顯示穩定版作為觀看者做預設頁面版內容。',
 793+ 'stablepages' => '頁面已經通過審核',
 794+ 'stablepages-text' => '以下的頁面列示出一些頁面是手動地設定去顯示穩定版作為觀看者做預設頁面版內容,只有指定用戶的編輯才不需要通過審核。',
793795 'stablepages-none' => '沒有頁面在這個清單中',
794796 'stablepages-config' => '設定',
795797 );
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/Stabilization.i18n.php
@@ -42,10 +42,18 @@
4343 'stabilization-def-short' => 'Default',
4444 'stabilization-def-short-0' => 'Current',
4545 'stabilization-def-short-1' => 'Published',
46 - 'stabilize_expiry_invalid' => 'Invalid expiration date.',
47 - 'stabilize_expiry_old' => 'This expiration time has already passed.',
48 - 'stabilize-expiring' => 'expires $1 (UTC)',
49 - 'stabilization-review' => 'Mark the current revision checked',
 46+ 'stabilize_page_invalid' => 'The target page title is invalid.',
 47+ 'stabilize_page_notexists' => 'The target page does not exist.',
 48+ 'stabilize_page_unreviewable' => 'The target page is not in reviewable namespace.',
 49+ 'stabilize_invalid_precedence' => 'Invalid version precedence.',
 50+ 'stabilize_invalid_autoreview' => 'Invalid autoreview restriction.',
 51+ 'stabilize_invalid_level' => 'Invalid protection level.',
 52+ 'stabilize_expiry_invalid' => 'Invalid expiration date.',
 53+ 'stabilize_expiry_old' => 'This expiration time has already passed.',
 54+ 'stabilize_denied' => 'Permission denied.',
 55+ 'stabilize_protect_quota' => 'The maximum number of currently flag-protected pages has already been reached.', # do not translate
 56+ 'stabilize-expiring' => 'expires $1 (UTC)',
 57+ 'stabilization-review' => 'Mark the current revision checked',
5058 );
5159
5260 /** Message documentation (Message documentation)
@@ -422,8 +430,15 @@
423431 'stabilization-def-short' => 'Па змоўчваньні',
424432 'stabilization-def-short-0' => 'Цяперашняя',
425433 'stabilization-def-short-1' => 'Апублікаваная',
 434+ 'stabilize_page_invalid' => 'Няслушная назва мэтавай старонкі.',
 435+ 'stabilize_page_notexists' => 'Мэтавая старонка не існуе.',
 436+ 'stabilize_page_unreviewable' => 'Мэтавай старонкі няма ў прасторы назваў, якую можна рэцэнзаваць.',
 437+ 'stabilize_invalid_precedence' => 'Няслушны прыярытэт вэрсіяў.',
 438+ 'stabilize_invalid_autoreview' => 'Няслушнае абмежаваньне аўтаматычнага рэцэнзаваньня',
 439+ 'stabilize_invalid_level' => 'Няслушны ўзровень абароны.',
426440 'stabilize_expiry_invalid' => 'Няслушны тэрмін.',
427441 'stabilize_expiry_old' => 'Час сканчэньня ўжо прайшоў.',
 442+ 'stabilize_denied' => 'Доступ забаронены.',
428443 'stabilize-expiring' => 'канчаецца $1 (UTC)',
429444 'stabilization-review' => 'Пазначыць цяперашнюю вэрсію як правераную',
430445 );
@@ -651,6 +666,7 @@
652667
653668 /** German (Deutsch)
654669 * @author Als-Holder
 670+ * @author Kghbln
655671 * @author Metalhead64
656672 * @author Purodha
657673 * @author Steef389
@@ -659,21 +675,21 @@
660676 $messages['de'] = array(
661677 'stabilization-tab' => 'Konfig.',
662678 'stabilization' => 'Seitenkonfiguration',
663 - 'stabilization-text' => "'''Ändere die Einstellungen um festzulegen, wie die markierte Version von „[[:$1|$1]]“ ausgewählt und angezeigt werden soll.'''
 679+ 'stabilization-text' => "'''Ändere die folgenden Einstellungen, um festzulegen, wie die zu veröffentlichende Version von „[[:$1|$1]]“ ausgewählt und angezeigt werden soll.'''
664680
665 -Bei einer Änderung der Konfiguration der standardmäßig angezeigten Version auf „geprüft“ oder „ursprünglich“, sollte darauf geachtet werden, dass die Seite eine solche Version enthält, andernfalls hat die Änderung keine große Auswirkung.",
 681+'''Hinweis:''' Die Änderung der Konfiguration hinsichtlich der standardmäßig anzuzeigenden Version, auf „geprüft“ oder „neueste markierte“, hat keinerlei Auswirkungen, sofern derartige Versionen nicht vorhanden sind. Bedenke, dass in diesem Zusammenhang eine „markierte“ Version als „geprüfte“ Version angesehen wird.",
666682 'stabilization-perm' => 'Du hast nicht die erforderliche Berechtigung, um die Einstellungen der markierten Version zu ändern.
667683 Die aktuellen Einstellungen für „[[:$1|$1]]“ sind:',
668684 'stabilization-page' => 'Seitenname:',
669 - 'stabilization-leg' => 'Einstellungen der markierten Version für eine Seite',
 685+ 'stabilization-leg' => 'Bestätige die Einstellungen bezüglich der zu veröffentlichenden Version',
670686 'stabilization-select' => 'Vorzugsweise stabile Versionen auswählen',
671687 'stabilization-select1' => 'Die letzte geprüfte Version; wenn keine vorhanden ist, dann die letzte gesichtete Version',
672688 'stabilization-select2' => 'Die letzte markierte Version, unabhängig vom Markierungslevel',
673689 'stabilization-select3' => 'Die letzte ursprüngliche Version; wenn keine vorhanden ist, dann die letzte gesichtete oder geprüfte Version',
674690 'stabilization-def' => 'Angezeigte Version in der normalen Seitenansicht',
675 - 'stabilization-def1' => 'Die markierte Version; wenn keine vorhanden ist, dann die aktuelle Version/der Entwurf',
 691+ 'stabilization-def1' => 'Die veröffentlichte Version. Sofern keine vorhanden ist, die aktuelle Version/der aktuelle Entwurf',
676692 'stabilization-def2' => 'Die aktuelle Version/der Entwurf',
677 - 'stabilization-restrict' => 'Einschränkung der automatischen Markierung',
 693+ 'stabilization-restrict' => 'Einschränkungen bezüglich des Markierens/des automatischen Markierens',
678694 'stabilization-restrict-none' => 'Keine zusätzlichen Einschränkungen',
679695 'stabilization-submit' => 'Bestätigen',
680696 'stabilization-notexists' => 'Es gibt keine Seite „[[:$1|$1]]“. Keine Einstellungen möglich.',
@@ -689,8 +705,15 @@
690706 'stabilization-def-short' => 'Standard',
691707 'stabilization-def-short-0' => 'Aktuell',
692708 'stabilization-def-short-1' => 'Markiert',
 709+ 'stabilize_page_invalid' => 'Der gewählte Seitentitel ist ungültig.',
 710+ 'stabilize_page_notexists' => 'Die gewählte Seite existiert nicht.',
 711+ 'stabilize_page_unreviewable' => 'Die gewählte Seite befindet sich nicht in einem Namensraum, in dem Markierungen gesetzt werden können.',
 712+ 'stabilize_invalid_precedence' => 'Ungültige Versionspriorität.',
 713+ 'stabilize_invalid_autoreview' => 'Ungültige Einschränkung bezüglich automatischer Markierungen.',
 714+ 'stabilize_invalid_level' => 'Ungültige Seitenschutzart',
693715 'stabilize_expiry_invalid' => 'Ungültiges Ablaufdatum.',
694716 'stabilize_expiry_old' => 'Das Ablaufdatum wurde überschritten.',
 717+ 'stabilize_denied' => 'Zugriff verweigert.',
695718 'stabilize-expiring' => 'erlischt am $2, $3 Uhr (UTC)',
696719 'stabilization-review' => 'Überprüfe die aktuelle Version',
697720 );
@@ -886,6 +909,8 @@
887910 'stabilization-def-short' => 'Defaŭlta',
888911 'stabilization-def-short-0' => 'Nuna',
889912 'stabilization-def-short-1' => 'Publikigita',
 913+ 'stabilize_page_invalid' => 'La titolo de la cela paĝo estas malvalida.',
 914+ 'stabilize_page_notexists' => 'La cela paĝo ne ekzistas.',
890915 'stabilize_expiry_invalid' => 'Malvalida findato.',
891916 'stabilize_expiry_old' => 'Ĉi tiu findato jam estas pasita.',
892917 'stabilize-expiring' => 'findato $1 (UTC)',
@@ -938,6 +963,12 @@
939964 'stabilization-def-short' => 'Por defecto',
940965 'stabilization-def-short-0' => 'Actual',
941966 'stabilization-def-short-1' => 'Publicado',
 967+ 'stabilize_page_invalid' => 'El título de la página de destino es inválido.',
 968+ 'stabilize_page_notexists' => 'La página de destino es no existe.',
 969+ 'stabilize_page_unreviewable' => 'La página de destino no está en un espacio de nombre en el que sea posible una revisión.',
 970+ 'stabilize_invalid_precedence' => 'Precedencia de versión inválida.',
 971+ 'stabilize_invalid_autoreview' => 'Restricciión e autorevisión inválida.',
 972+ 'stabilize_invalid_level' => 'Nivel de protección inválido.',
942973 'stabilize_expiry_invalid' => 'La fecha de caducidad no es válida.',
943974 'stabilize_expiry_old' => 'Este tiempo de expiración ya ha pasado',
944975 'stabilize-expiring' => 'caduca el $1 (UTC)',
@@ -1124,6 +1155,12 @@
11251156 'stabilization-def-short' => 'Défaut',
11261157 'stabilization-def-short-0' => 'Courante',
11271158 'stabilization-def-short-1' => 'Publié',
 1159+ 'stabilize_page_invalid' => 'Le titre de la page cible est incorrect',
 1160+ 'stabilize_page_notexists' => "La page cible n'existe pas.",
 1161+ 'stabilize_page_unreviewable' => "La page cible n'est pas dans un espace de noms qui peut être relu.",
 1162+ 'stabilize_invalid_precedence' => 'Priorité de version invalide.',
 1163+ 'stabilize_invalid_autoreview' => 'Restriction de relecture automatique invalide',
 1164+ 'stabilize_invalid_level' => 'Niveau de protection invalide.',
11281165 'stabilize_expiry_invalid' => "Date d'expiration invalide.",
11291166 'stabilize_expiry_old' => "Cette durée d'expiration est déjà écoulée.",
11301167 'stabilize-expiring' => 'Expire le $1 (UTC)',
@@ -1231,8 +1268,15 @@
12321269 'stabilization-def-short' => 'Por defecto',
12331270 'stabilization-def-short-0' => 'Actual',
12341271 'stabilization-def-short-1' => 'Publicada',
1235 - 'stabilize_expiry_invalid' => 'Data non válida de caducidade.',
 1272+ 'stabilize_page_invalid' => 'O título da páxina de destino non é correcto.',
 1273+ 'stabilize_page_notexists' => 'A páxina de destino non existe.',
 1274+ 'stabilize_page_unreviewable' => 'A páxina de destino non está nun espazo de nomes que se poida revisar.',
 1275+ 'stabilize_invalid_precedence' => 'Prioridade de versión incorrecta.',
 1276+ 'stabilize_invalid_autoreview' => 'Restrición de revisión automática incorrecta',
 1277+ 'stabilize_invalid_level' => 'Nivel de protección incorrecto.',
 1278+ 'stabilize_expiry_invalid' => 'Data de caducidade non válida.',
12361279 'stabilize_expiry_old' => 'O tempo de caducidade xa pasou.',
 1280+ 'stabilize_denied' => 'Permisos rexeitados.',
12371281 'stabilize-expiring' => 'caduca o $2 ás $3 (UTC)',
12381282 'stabilization-review' => 'Marcar a revisión actual como comprobada',
12391283 );
@@ -1478,8 +1522,15 @@
14791523 'stabilization-def-short' => 'Standard',
14801524 'stabilization-def-short-0' => 'Aktualny',
14811525 'stabilization-def-short-1' => 'Wozjewjeny',
 1526+ 'stabilize_page_invalid' => 'Titul ciloweje strony je njepłaćiwy.',
 1527+ 'stabilize_page_notexists' => 'Cilowa strona njeeksistuje.',
 1528+ 'stabilize_page_unreviewable' => 'Cilowa strona w přepruwujomnym mjenowym rumje njeje.',
 1529+ 'stabilize_invalid_precedence' => 'Njepłaćiwa wersijowa priorita.',
 1530+ 'stabilize_invalid_autoreview' => 'Njepłaćiwe wobmjezowanje awtomatiskeho přepruwowanja',
 1531+ 'stabilize_invalid_level' => 'Njepłaćiwy škitny schodźenk.',
14821532 'stabilize_expiry_invalid' => 'Njepłaćiwy datum spadnjenja.',
14831533 'stabilize_expiry_old' => 'Tutón čas spadnjenja je hižo zańdźeny.',
 1534+ 'stabilize_denied' => 'Prawo zapowědźene.',
14841535 'stabilize-expiring' => 'spadnje $1 hodź. (UTC)',
14851536 'stabilization-review' => 'Aktualnu wersiju jako skontrolowanu markěrować',
14861537 );
@@ -1570,6 +1621,12 @@
15711622 'stabilization-def-short' => 'Predefinition',
15721623 'stabilization-def-short-0' => 'Actual',
15731624 'stabilization-def-short-1' => 'Publicate',
 1625+ 'stabilize_page_invalid' => 'Le titulo del pagina de destination es invalide.',
 1626+ 'stabilize_page_notexists' => 'Le pagina de destination non existe.',
 1627+ 'stabilize_page_unreviewable' => 'Le pagina de destination non es in un spatio de nomines revisibile.',
 1628+ 'stabilize_invalid_precedence' => 'Precedentia de versiones invalide.',
 1629+ 'stabilize_invalid_autoreview' => 'Restriction de autorevision invalide.',
 1630+ 'stabilize_invalid_level' => 'Nivello de protection invalide.',
15741631 'stabilize_expiry_invalid' => 'Data de expiration invalide.',
15751632 'stabilize_expiry_old' => 'Iste tempore de expiration ha ja passate.',
15761633 'stabilize-expiring' => 'expira le $1 (UTC)',
@@ -1701,6 +1758,7 @@
17021759 * @author Hosiryuhosi
17031760 * @author JtFuruhata
17041761 * @author Whym
 1762+ * @author 青子守歌
17051763 */
17061764 $messages['ja'] = array(
17071765 'stabilization-tab' => '固定',
@@ -1734,8 +1792,15 @@
17351793 'stabilization-def-short' => '既定表示',
17361794 'stabilization-def-short-0' => '最新版',
17371795 'stabilization-def-short-1' => '公開済み',
 1796+ 'stabilize_page_invalid' => '指定したページ名が無効です。',
 1797+ 'stabilize_page_notexists' => '指定したページ名が存在しません。',
 1798+ 'stabilize_page_unreviewable' => '指定したページは査読可能な名前空間にありません。',
 1799+ 'stabilize_invalid_precedence' => '無効なバージョン優先度。',
 1800+ 'stabilize_invalid_autoreview' => '無効な自動査読の制限。',
 1801+ 'stabilize_invalid_level' => '不正な保護レベル。',
17381802 'stabilize_expiry_invalid' => '有効期限に不正な日時が設定されました。',
17391803 'stabilize_expiry_old' => '有効期限に指定された日時を過ぎています。',
 1804+ 'stabilize_denied' => '許可されていません。',
17401805 'stabilize-expiring' => '有効期限: $1 (UTC)',
17411806 'stabilization-review' => '現在の版を査読済みとする',
17421807 );
@@ -2121,6 +2186,12 @@
21222187 'stabilization-def-short' => 'Основно',
21232188 'stabilization-def-short-0' => 'Моментално',
21242189 'stabilization-def-short-1' => 'Објавена',
 2190+ 'stabilize_page_invalid' => 'Целната страница е неважечка.',
 2191+ 'stabilize_page_notexists' => 'Целната страница не постои.',
 2192+ 'stabilize_page_unreviewable' => 'Целната страница не е во проверлив именски простор.',
 2193+ 'stabilize_invalid_precedence' => 'Неважечко првенство на верзија.',
 2194+ 'stabilize_invalid_autoreview' => 'Неважечко ограничување на автопрегледот',
 2195+ 'stabilize_invalid_level' => 'Неважечко ниво на заштита.',
21252196 'stabilize_expiry_invalid' => 'Погрешен датум на важност.',
21262197 'stabilize_expiry_old' => 'Времето на важност веќе е поминато.',
21272198 'stabilize-expiring' => 'истекува $1 (UTC)',
@@ -2159,6 +2230,11 @@
21602231 'stabilization-def-short' => 'സ്വതവെ',
21612232 'stabilization-def-short-0' => 'നിലവിലുള്ളത്',
21622233 'stabilization-def-short-1' => 'പ്രസിദ്ധീകരിക്കപ്പെട്ടത്',
 2234+ 'stabilize_page_invalid' => 'താളിനു ലക്ഷ്യമിട്ട പേര് അസാധുവാണ്.',
 2235+ 'stabilize_page_notexists' => 'ലക്ഷ്യമിട്ട താൾ നിലവിലില്ല.',
 2236+ 'stabilize_page_unreviewable' => 'ലക്ഷ്യമിട്ട താൾ സംശോധനം ചെയ്യാവുന്ന നാമമേഖലയിലല്ല.',
 2237+ 'stabilize_invalid_autoreview' => 'അസാധുവായ സ്വയംസംശോധന പരിമിതപ്പെടുത്തൽ',
 2238+ 'stabilize_invalid_level' => 'അസാധുവായ സംരക്ഷണ മാനം.',
21632239 'stabilize_expiry_invalid' => 'അസാധുവായ കാലാവധി തീയതി.',
21642240 'stabilize_expiry_old' => 'ഈ കാലാവധി സമയം കഴിഞ്ഞു പോയി.',
21652241 'stabilize-expiring' => 'കാലാവധി തീരുന്നത് - $1 (UTC)',
@@ -2327,6 +2403,12 @@
23282404 'stabilization-def-short' => 'Standaard',
23292405 'stabilization-def-short-0' => 'Huidig',
23302406 'stabilization-def-short-1' => 'Gepubliceerd',
 2407+ 'stabilize_page_invalid' => 'De naam van de doelpagina is ongeldig.',
 2408+ 'stabilize_page_notexists' => 'De doelpagina bestaat niet.',
 2409+ 'stabilize_page_unreviewable' => 'De doelpagina is bevindt zich niet in een te controleren naamruimte.',
 2410+ 'stabilize_invalid_precedence' => 'Ongeldig versievoorvoegsel.',
 2411+ 'stabilize_invalid_autoreview' => 'Ongeldige beperking voor automatische controle',
 2412+ 'stabilize_invalid_level' => 'Ongeldig beschermingsniveau.',
23312413 'stabilize_expiry_invalid' => 'Ongeldige vervaldatum.',
23322414 'stabilize_expiry_old' => 'Deze vervaldatum is al verstreken.',
23332415 'stabilize-expiring' => 'vervalt $1 (UTC)',
@@ -2418,6 +2500,12 @@
24192501 'stabilization-def-short' => 'Standard',
24202502 'stabilization-def-short-0' => 'Nåværende',
24212503 'stabilization-def-short-1' => 'Publisert',
 2504+ 'stabilize_page_invalid' => 'Målsidetittelen er ugyldig.',
 2505+ 'stabilize_page_notexists' => 'Målsiden finnes ikke.',
 2506+ 'stabilize_page_unreviewable' => 'Målsiden er ikke i et reviderbart navnerom.',
 2507+ 'stabilize_invalid_precedence' => 'Ugyldig versjonsforrang.',
 2508+ 'stabilize_invalid_autoreview' => 'Ugyldig autorevideringsbegrensning',
 2509+ 'stabilize_invalid_level' => 'Ugyldig beskyttelsesnivå.',
24222510 'stabilize_expiry_invalid' => 'Ugyldig varighet.',
24232511 'stabilize_expiry_old' => 'Varigheten har allerede utløpt.',
24242512 'stabilize-expiring' => 'utgår $1 (UTC)',
@@ -2647,6 +2735,12 @@
26482736 'stabilization-def-short' => 'Padrão',
26492737 'stabilization-def-short-0' => 'Actual',
26502738 'stabilization-def-short-1' => 'Publicada',
 2739+ 'stabilize_page_invalid' => 'O título da página de destino é inválido.',
 2740+ 'stabilize_page_notexists' => 'A página de destino não existe.',
 2741+ 'stabilize_page_unreviewable' => 'A página de destino não está num espaço nominal sujeito a revisão.',
 2742+ 'stabilize_invalid_precedence' => 'Precedência de versões inválida.',
 2743+ 'stabilize_invalid_autoreview' => 'Restrição de auto-revisão é inválida',
 2744+ 'stabilize_invalid_level' => 'Nível de protecção é inválido.',
26512745 'stabilize_expiry_invalid' => 'Data de expiração inválida.',
26522746 'stabilize_expiry_old' => 'Esta data de expiração já passou.',
26532747 'stabilize-expiring' => 'expira às $1 (UTC)',
@@ -2707,16 +2801,16 @@
27082802 */
27092803 $messages['ro'] = array(
27102804 'stabilization-tab' => 'config.',
2711 - 'stabilization-perm' => 'Contul tău nu are permisiunea de a schimba versiunea stabilă a configuraţiei.
2712 -Iată configuraţia curentă pentru [[:$1|$1]]:',
 2805+ 'stabilization-perm' => 'Contul tău nu are permisiunea de a schimba versiunea stabilă a configurației.
 2806+Iată configurația curentă pentru [[:$1|$1]]:',
27132807 'stabilization-page' => 'Numele paginii:',
2714 - 'stabilization-leg' => 'Confirmaţi setările versiunii stabile',
2715 - 'stabilization-select' => 'Precedenta selecţie a versiunii stabile',
2716 - 'stabilization-def' => 'Revizie afişată pe vizualizarea paginii implicite',
 2808+ 'stabilization-leg' => 'Confirmați setările versiunii stabile',
 2809+ 'stabilization-select' => 'Precedenta selecție a versiunii stabile',
 2810+ 'stabilization-def' => 'Revizie afișată pe vizualizarea paginii implicite',
27172811 'stabilization-def1' => 'Revizia stabilă; dacă nu există, atunci cea curentă',
27182812 'stabilization-def2' => 'Revizia curentă',
2719 - 'stabilization-restrict' => 'Restricţii pentru revizualizarea automată',
2720 - 'stabilization-restrict-none' => 'Nicio restricţie suplimentară',
 2813+ 'stabilization-restrict' => 'Restricții pentru revizualizarea automată',
 2814+ 'stabilization-restrict-none' => 'Nicio restricție suplimentară',
27212815 'stabilization-submit' => 'Confirmă',
27222816 'stabilization-comment' => 'Motiv:',
27232817 'stabilization-otherreason' => 'Alt motiv',
@@ -2732,7 +2826,7 @@
27332827 'stabilize_expiry_invalid' => 'Data expirării incorectă.',
27342828 'stabilize_expiry_old' => 'Această dată de expirare a trecut deja.',
27352829 'stabilize-expiring' => 'expiră $1 (UTC)',
2736 - 'stabilization-review' => 'Revizuieşte versiunea curentă',
 2830+ 'stabilization-review' => 'Revizuiește versiunea curentă',
27372831 );
27382832
27392833 /** Tarandíne (Tarandíne)
@@ -2820,8 +2914,15 @@
28212915 'stabilization-def-short' => 'по умолчанию',
28222916 'stabilization-def-short-0' => 'текущая',
28232917 'stabilization-def-short-1' => 'Опубликованная',
 2918+ 'stabilize_page_invalid' => 'Целевое название страницы ошибочно.',
 2919+ 'stabilize_page_notexists' => 'Целевой страницы не существует.',
 2920+ 'stabilize_page_unreviewable' => 'Целевая страница не находится в проверяемом пространстве имён.',
 2921+ 'stabilize_invalid_precedence' => 'Ошибочный приоритет версий.',
 2922+ 'stabilize_invalid_autoreview' => 'Ошибочные ограничения автопроверки',
 2923+ 'stabilize_invalid_level' => 'Ошибочный уровень защиты.',
28242924 'stabilize_expiry_invalid' => 'Ошибочная дата истечения.',
28252925 'stabilize_expiry_old' => 'Указанное время окончания действия уже прошло.',
 2926+ 'stabilize_denied' => 'Доступ запрещён.',
28262927 'stabilize-expiring' => 'истекает $1 (UTC)',
28272928 'stabilization-review' => 'Отметить текущую версию как проверенную',
28282929 );
@@ -3102,6 +3203,7 @@
31033204
31043205 /** Swedish (Svenska)
31053206 * @author Boivie
 3207+ * @author Dafer45
31063208 * @author Lejonel
31073209 * @author M.M.S.
31083210 * @author Najami
@@ -3140,10 +3242,13 @@
31413243 'stabilization-def-short' => 'Standard',
31423244 'stabilization-def-short-0' => 'Senaste',
31433245 'stabilization-def-short-1' => 'Publicerad',
 3246+ 'stabilize_page_invalid' => 'Målsidans titel är ogiltig.',
 3247+ 'stabilize_page_notexists' => 'Målsidan finns ej.',
 3248+ 'stabilize_invalid_level' => 'Ogiltig skyddsnivå.',
31443249 'stabilize_expiry_invalid' => 'Ogiltig varaktighet.',
31453250 'stabilize_expiry_old' => 'Varaktigheten har redan löpt ut.',
31463251 'stabilize-expiring' => 'upphör den $1 (UTC)',
3147 - 'stabilization-review' => 'Granska den nuvarande versionen',
 3252+ 'stabilization-review' => 'Markera den nuvarande revisionen som kontrollerad',
31483253 );
31493254
31503255 /** Silesian (Ślůnski)
@@ -3403,6 +3508,12 @@
34043509 'stabilization-def-short' => 'Varsayılan',
34053510 'stabilization-def-short-0' => 'Şuanki',
34063511 'stabilization-def-short-1' => 'Yayımlandı',
 3512+ 'stabilize_page_invalid' => 'Hedef sayfa başlığı geçersiz.',
 3513+ 'stabilize_page_notexists' => 'Hedef sayfa mevcut değil.',
 3514+ 'stabilize_page_unreviewable' => 'Hedef sayfa incelenebilir ad alanında değil.',
 3515+ 'stabilize_invalid_precedence' => 'Geçersiz sürüm önceliği.',
 3516+ 'stabilize_invalid_autoreview' => 'Geçersiz oto-inceleme kısıtlaması',
 3517+ 'stabilize_invalid_level' => 'Geçersiz koruma seviyesi.',
34073518 'stabilize_expiry_invalid' => 'Geçersiz sona erme tarihi.',
34083519 'stabilize_expiry_old' => 'Sona erme tarihi zaten geçmiş.',
34093520 'stabilize-expiring' => '$1 (UTC) tarihinde sona eriyor',
@@ -3722,13 +3833,16 @@
37233834 /** Traditional Chinese (‪中文(繁體)‬)
37243835 * @author Alexsh
37253836 * @author Gaoxuewei
 3837+ * @author Horacewai2
37263838 * @author Liangent
37273839 * @author Shinjiman
37283840 */
37293841 $messages['zh-hant'] = array(
37303842 'stabilization-tab' => '調查',
37313843 'stabilization' => '穩定頁面',
3732 - 'stabilization-text' => "'''更改以下的設定去調節所選擇的[[:$1|$1]]之穩定版本如何顯示。'''",
 3844+ 'stabilization-text' => "'''更改以下的設定去調節所選擇的[[:$1|$1]]之穩定版本如何顯示。'''
 3845+
 3846+注意:如果那麼沒有這樣的版本,更改出版版本設定去選擇「已審核」或是「原始」版本是不會影響的。而且,有質數的版本是已被檢查的。",
37333847 'stabilization-perm' => '您的賬戶並沒有權限去更改穩定版本設定。
37343848 這是[[:$1|$1]]當前的設定:',
37353849 'stabilization-page' => '頁面名稱:',
@@ -3738,8 +3852,8 @@
37393853 'stabilization-select2' => '最近複審過的修訂',
37403854 'stabilization-select3' => '最近原始的修訂;如果未有,則是最近有質素或視察過的',
37413855 'stabilization-def' => '在預設頁視的修訂顯示',
3742 - 'stabilization-def1' => '穩定修訂;如果未有,則是現時的',
3743 - 'stabilization-def2' => '現時的修訂',
 3856+ 'stabilization-def1' => '穩定修訂;如果未有,則是現時或草稿',
 3857+ 'stabilization-def2' => '!現時的修訂',
37443858 'stabilization-restrict' => '自動審核限制',
37453859 'stabilization-restrict-none' => '無其他限制',
37463860 'stabilization-submit' => '確認',
@@ -3758,8 +3872,15 @@
37593873 'stabilization-def-short' => '預設',
37603874 'stabilization-def-short-0' => '現時',
37613875 'stabilization-def-short-1' => '穩定',
 3876+ 'stabilize_page_invalid' => '目標頁面名稱是無效的',
 3877+ 'stabilize_page_notexists' => '目標頁面不存在',
 3878+ 'stabilize_page_unreviewable' => '目標頁面的名字空間不是一個需要審查的名字空間。',
 3879+ 'stabilize_invalid_precedence' => '無效的修訂版本。',
 3880+ 'stabilize_invalid_autoreview' => '沒有自動複查權限',
 3881+ 'stabilize_invalid_level' => '無效的保護水平。',
37623882 'stabilize_expiry_invalid' => '無效的到期日。',
37633883 'stabilize_expiry_old' => '到期日已過。',
37643884 'stabilize-expiring' => '於 $1 (UTC) 到期',
 3885+ 'stabilization-review' => '將此當前版本標記為已查閱',
37653886 );
37663887
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/language/UnreviewedPages.i18n.php
@@ -1240,6 +1240,7 @@
12411241
12421242 /** Brazilian Portuguese (Português do Brasil)
12431243 * @author Eduardo.mps
 1244+ * @author Giro720
12441245 */
12451246 $messages['pt-br'] = array(
12461247 'unreviewedpages' => 'Páginas não analisadas',
@@ -1248,7 +1249,7 @@
12491250 'unreviewed-diff' => 'analisar',
12501251 'unreviewed-unwatched' => '(não-vigiada)',
12511252 'unreviewed-watched' => '($1 {{PLURAL:$1|utilizador ativo|utilizadores ativos}} a vigiar)',
1252 - 'unreviewed-list' => 'Esta página lista as páginas de conteúdo que ainda não foram analisadas.',
 1253+ 'unreviewed-list' => 'Esta página lista as páginas de conteúdo que não foram revistas até ao nível escolhido.',
12531254 'unreviewed-none' => 'No momento não há páginas que se enquadrem nestes critérios',
12541255 'unreviewed-viewing' => '(sob análise)',
12551256 'unreviewed-hours' => '($1 {{PLURAL:$1|hora|horas}})',
@@ -1262,14 +1263,14 @@
12631264 */
12641265 $messages['ro'] = array(
12651266 'unreviewedpages' => 'Pagini nerevizuite',
1266 - 'unreviewed-legend' => 'Afişează pagini cu conţinut nerevizuit',
 1267+ 'unreviewed-legend' => 'Afișează pagini cu conținut nerevizuit',
12671268 'unreviewed-category' => 'Categorie:',
12681269 'unreviewed-diff' => 'recenzie',
12691270 'unreviewed-unwatched' => '(neurmărit)',
1270 - 'unreviewed-watched' => '($1 {{PLURAL:$1|utilizator activ care urmăreşte|utilizatori activi care urmăresc}})',
 1271+ 'unreviewed-watched' => '($1 {{PLURAL:$1|utilizator activ care urmărește|utilizatori activi care urmăresc}})',
12711272 'unreviewed-hours' => '($1 {{PLURAL:$1|oră|ore}})',
12721273 'unreviewed-days' => '($1 {{PLURAL:$1|zi|zile}})',
1273 - 'unreviewed-recent' => '(mai puţin de 1 oră)',
 1274+ 'unreviewed-recent' => '(mai puțin de 1 oră)',
12741275 );
12751276
12761277 /** Tarandíne (Tarandíne)
Index: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha/FlaggedRevs.class.php
@@ -96,7 +96,7 @@
9797 self::$patrolNamespaces = $wgFlaggedRevsPatrolNamespaces;
9898 }
9999
100 - # ################ Basic accessors #################
 100+ # ################ Basic config accessors #################
101101
102102 /**
103103 * Is there only one tag and it has only one level?
@@ -255,32 +255,6 @@
256256 }
257257
258258 /**
259 - * Find what protection level a config is in
260 - * @param array $config
261 - * @returns string
262 - */
263 - public static function getProtectionLevel( array $config ) {
264 - if ( !self::useProtectionLevels() ) {
265 - throw new MWException( 'getProtectionLevel() called with $wgFlaggedRevsProtection off' );
266 - }
267 - $defaultConfig = self::getDefaultVisibilitySettings();
268 - # Check if the page is not protected at all...
269 - if ( $config['override'] == $defaultConfig['override']
270 - && $config['autoreview'] == $defaultConfig['autoreview'] )
271 - {
272 - return "none"; // not protected
273 - }
274 - # All protection levels have 'override' on
275 - if ( $config['override'] ) {
276 - # The levels are defined by the 'autoreview' settings
277 - if ( in_array( $config['autoreview'], self::getRestrictionLevels() ) ) {
278 - return $config['autoreview'];
279 - }
280 - }
281 - return "invalid";
282 - }
283 -
284 - /**
285259 * Get the autoreview restriction levels available
286260 * @returns array
287261 */
@@ -419,82 +393,92 @@
420394 return str_replace( '$wgScriptPath', $wgScriptPath, $wgFlaggedRevsStylePath );
421395 }
422396
 397+ # ################ Permission functions #################
 398+
423399 /**
424 - * Get global revision status precedence setting
425 - * or a specific one if given a tag tier (e.g. FR_QUALITY).
426 - * Returns one of FLAGGED_VIS_PRISTINE, FLAGGED_VIS_QUALITY, FLAGGED_VIS_LATEST.
427 - *
428 - * @param int config tier, optional (FR_PRISTINE,FR_QUALITY,FR_SIGHTED)
429 - * @return int
 400+ * Returns true if a user can set $tag to $value.
 401+ * @param string $tag
 402+ * @param int $value
 403+ * @returns bool
430404 */
431 - public static function getPrecedence( $configTier = null ) {
432 - global $wgFlaggedRevsPrecedence;
433 - if ( is_null( $configTier ) ) {
434 - $configTier = (int)$wgFlaggedRevsPrecedence;
 405+ public static function userCanSetTag( $tag, $value ) {
 406+ global $wgUser;
 407+ # Sanity check tag and value
 408+ $levels = self::getTagLevels( $tag );
 409+ $highest = count( $levels ) - 1;
 410+ if( !$levels || $value < 0 || $value > $highest ) {
 411+ return false; // flag range is invalid
435412 }
436 - switch( $configTier )
437 - {
438 - case FR_PRISTINE:
439 - $select = FLAGGED_VIS_PRISTINE;
440 - break;
441 - case FR_QUALITY:
442 - $select = FLAGGED_VIS_QUALITY;
443 - break;
444 - default:
445 - $select = FLAGGED_VIS_LATEST;
446 - break;
 413+ $restrictions = self::getTagRestrictions();
 414+ # No restrictions -> full access
 415+ if ( !isset( $restrictions[$tag] ) ) {
 416+ return true;
447417 }
448 - return $select;
 418+ # Validators always have full access
 419+ if ( $wgUser->isAllowed( 'validate' ) ) {
 420+ return true;
 421+ }
 422+ # Check if this user has any right that lets him/her set
 423+ # up to this particular value
 424+ foreach ( $restrictions[$tag] as $right => $level ) {
 425+ if ( $value <= $level && $level > 0 && $wgUser->isAllowed( $right ) ) {
 426+ return true;
 427+ }
 428+ }
 429+ return false;
449430 }
450 -
 431+
451432 /**
452 - * Get minimum level tags for a tier
453 - * @return array
 433+ * Returns true if a user can set $flags.
 434+ * This checks if the user has the right to review
 435+ * to the given levels for each tag.
 436+ * @param array $flags, suggested flags
 437+ * @param array $oldflags, pre-existing flags
 438+ * @returns bool
454439 */
455 - public static function quickTags( $tier ) {
456 - self::load();
457 - switch( $tier ) // select reference levels
458 - {
459 - case FR_PRISTINE:
460 - $minLevels = self::$minPL;
461 - case FR_QUALITY:
462 - $minLevels = self::$minQL;
463 - default:
464 - $minLevels = self::$minSL;
 440+ public static function userCanSetFlags( $flags, $oldflags = array() ) {
 441+ global $wgUser;
 442+ if ( !$wgUser->isAllowed( 'review' ) )
 443+ return false; // User is not able to review pages
 444+ # Check if all of the required site flags have a valid value
 445+ # that the user is allowed to set.
 446+ foreach ( self::getDimensions() as $qal => $levels ) {
 447+ $level = isset( $flags[$qal] ) ? $flags[$qal] : 0;
 448+ $highest = count( $levels ) - 1; // highest valid level
 449+ if ( !self::userCanSetTag( $qal, $level ) ) {
 450+ return false; // user cannot set proposed flag
 451+ } elseif ( isset( $oldflags[$qal] )
 452+ && !self::userCanSetTag( $qal, $oldflags[$qal] ) )
 453+ {
 454+ return false; // user cannot change old flag
 455+ }
465456 }
466 - $flags = array();
467 - foreach ( self::getDimensions() as $tag => $x ) {
468 - $flags[$tag] = $minLevels[$tag];
469 - }
470 - return $flags;
 457+ return true;
471458 }
472459
473460 /**
474 - * Get minimum tags that are closest to $oldFlags
475 - * given the site, page, and user rights limitations.
476 - * @param array $oldFlags previous stable rev flags
477 - * @param array $config
478 - * @return mixed array or null
479 - */
480 - public static function getAutoReviewTags( $oldFlags, array $config = array() ) {
481 - if ( !FlaggedRevs::autoReviewEdits() ) {
482 - return null; // shouldn't happen
 461+ * Check if a user can set the autoreview restiction level to $right
 462+ * @param string $right the level
 463+ * @returns bool
 464+ */
 465+ public static function userCanSetAutoreviewLevel( $right ) {
 466+ global $wgUser;
 467+ if ( $right == '' ) {
 468+ return true; // no restrictions (none)
483469 }
484 - $flags = array();
485 - foreach ( self::getDimensions() as $tag => $levels ) {
486 - # Try to keep this tag val the same as the stable rev's
487 - $val = isset( $oldFlags[$tag] ) ? $oldFlags[$tag] : 1;
488 - $val = min( $val, self::maxAutoReviewLevel( $tag ) );
489 - # Dial down the level to one the user has permission to set
490 - while ( !RevisionReview::userCan( $tag, $val ) ) {
491 - $val--;
492 - if ( $val <= 0 ) {
493 - return null; // all tags vals must be > 0
494 - }
 470+ if ( !in_array( $right, FlaggedRevs::getRestrictionLevels() ) ) {
 471+ return false; // invalid restriction level
 472+ }
 473+ # Don't let them choose levels above their own rights
 474+ if ( $right == 'sysop' ) {
 475+ // special case, rewrite sysop to protect and editprotected
 476+ if ( !$wgUser->isAllowed( 'protect' ) && !$wgUser->isAllowed( 'editprotected' ) ) {
 477+ return false;
495478 }
496 - $flags[$tag] = $val;
 479+ } else if ( !$wgUser->isAllowed( $right ) ) {
 480+ return false;
497481 }
498 - return $flags;
 482+ return true;
499483 }
500484
501485 # ################ Parsing functions #################
@@ -510,7 +494,7 @@
511495 global $wgParser;
512496 # Make our hooks trigger (force unstub so setting doesn't get lost)
513497 $wgParser->firstCallInit();
514 - $wgParser->fr_isStable = ( FlaggedRevs::inclusionSetting() != FR_INCLUDES_CURRENT );
 498+ $wgParser->fr_isStable = ( self::inclusionSetting() != FR_INCLUDES_CURRENT );
515499 # Parse with default options
516500 $options = self::makeParserOptions();
517501 $outputText = $wgParser->preprocess( $text, $title, $options, $id );
@@ -535,7 +519,7 @@
536520 $title = $article->getTitle(); // avoid pass-by-reference error
537521 # Make our hooks trigger (force unstub so setting doesn't get lost)
538522 $wgParser->firstCallInit();
539 - $wgParser->fr_isStable = ( FlaggedRevs::inclusionSetting() != FR_INCLUDES_CURRENT );
 523+ $wgParser->fr_isStable = ( self::inclusionSetting() != FR_INCLUDES_CURRENT );
540524 # Don't show section-edit links, they can be old and misleading
541525 $options = self::makeParserOptions();
542526 # Parse the new body, wikitext -> html
@@ -760,7 +744,7 @@
761745 }
762746 }
763747 # If using the current version of includes, there is nothing else to check.
764 - if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_CURRENT ) {
 748+ if ( self::inclusionSetting() == FR_INCLUDES_CURRENT ) {
765749 return true;
766750 }
767751 # Try the cache...
@@ -1221,7 +1205,34 @@
12221206 );
12231207 }
12241208
 1209+
12251210 /**
 1211+ * Find what protection level a config is in
 1212+ * @param array $config
 1213+ * @returns string
 1214+ */
 1215+ public static function getProtectionLevel( array $config ) {
 1216+ if ( !self::useProtectionLevels() ) {
 1217+ throw new MWException( 'getProtectionLevel() called with $wgFlaggedRevsProtection off' );
 1218+ }
 1219+ $defaultConfig = self::getDefaultVisibilitySettings();
 1220+ # Check if the page is not protected at all...
 1221+ if ( $config['override'] == $defaultConfig['override']
 1222+ && $config['autoreview'] == '' )
 1223+ {
 1224+ return "none"; // not protected
 1225+ }
 1226+ # All protection levels have 'override' on
 1227+ if ( $config['override'] ) {
 1228+ # The levels are defined by the 'autoreview' settings
 1229+ if ( in_array( $config['autoreview'], self::getRestrictionLevels() ) ) {
 1230+ return $config['autoreview'];
 1231+ }
 1232+ }
 1233+ return "invalid";
 1234+ }
 1235+
 1236+ /**
12261237 * Check if an fpc_select value is valid
12271238 * @param int $select
12281239 */
@@ -1238,7 +1249,7 @@
12391250 if ( $right == '' ) {
12401251 return true; // no restrictions (none)
12411252 }
1242 - return in_array( $right, FlaggedRevs::getRestrictionLevels(), true );
 1253+ return in_array( $right, self::getRestrictionLevels(), true );
12431254 }
12441255
12451256 /**
@@ -1261,7 +1272,7 @@
12621273 // If FlaggedRevs got "turned off" for this page (due to not
12631274 // having the stable version as the default), then clear it
12641275 // from the tracking tables...
1265 - if ( !$config['override'] && FlaggedRevs::forDefaultVersionOnly() ) {
 1276+ if ( !$config['override'] && self::forDefaultVersionOnly() ) {
12661277 $pagesClearTracking[] = $row->fpc_page_id; // no stable version
12671278 // Check if the new (default) config has a different way
12681279 // of selecting the stable version of this page...
@@ -1350,6 +1361,84 @@
13511362 }
13521363
13531364 /**
 1365+ * Get global revision status precedence setting
 1366+ * or a specific one if given a tag tier (e.g. FR_QUALITY).
 1367+ * Returns one of FLAGGED_VIS_PRISTINE, FLAGGED_VIS_QUALITY, FLAGGED_VIS_LATEST.
 1368+ *
 1369+ * @param int config tier, optional (FR_PRISTINE,FR_QUALITY,FR_SIGHTED)
 1370+ * @return int
 1371+ */
 1372+ public static function getPrecedence( $configTier = null ) {
 1373+ global $wgFlaggedRevsPrecedence;
 1374+ if ( is_null( $configTier ) ) {
 1375+ $configTier = (int)$wgFlaggedRevsPrecedence;
 1376+ }
 1377+ switch( $configTier )
 1378+ {
 1379+ case FR_PRISTINE:
 1380+ $select = FLAGGED_VIS_PRISTINE;
 1381+ break;
 1382+ case FR_QUALITY:
 1383+ $select = FLAGGED_VIS_QUALITY;
 1384+ break;
 1385+ default:
 1386+ $select = FLAGGED_VIS_LATEST;
 1387+ break;
 1388+ }
 1389+ return $select;
 1390+ }
 1391+
 1392+ /**
 1393+ * Get minimum level tags for a tier
 1394+ * @return array
 1395+ */
 1396+ public static function quickTags( $tier ) {
 1397+ self::load();
 1398+ switch( $tier ) // select reference levels
 1399+ {
 1400+ case FR_PRISTINE:
 1401+ $minLevels = self::$minPL;
 1402+ case FR_QUALITY:
 1403+ $minLevels = self::$minQL;
 1404+ default:
 1405+ $minLevels = self::$minSL;
 1406+ }
 1407+ $flags = array();
 1408+ foreach ( self::getDimensions() as $tag => $x ) {
 1409+ $flags[$tag] = $minLevels[$tag];
 1410+ }
 1411+ return $flags;
 1412+ }
 1413+
 1414+ /**
 1415+ * Get minimum tags that are closest to $oldFlags
 1416+ * given the site, page, and user rights limitations.
 1417+ * @param array $oldFlags previous stable rev flags
 1418+ * @param array $config
 1419+ * @return mixed array or null
 1420+ */
 1421+ public static function getAutoReviewTags( $oldFlags, array $config = array() ) {
 1422+ if ( !self::autoReviewEdits() ) {
 1423+ return null; // shouldn't happen
 1424+ }
 1425+ $flags = array();
 1426+ foreach ( self::getDimensions() as $tag => $levels ) {
 1427+ # Try to keep this tag val the same as the stable rev's
 1428+ $val = isset( $oldFlags[$tag] ) ? $oldFlags[$tag] : 1;
 1429+ $val = min( $val, self::maxAutoReviewLevel( $tag ) );
 1430+ # Dial down the level to one the user has permission to set
 1431+ while ( !self::userCanSetTag( $tag, $val ) ) {
 1432+ $val--;
 1433+ if ( $val <= 0 ) {
 1434+ return null; // all tags vals must be > 0
 1435+ }
 1436+ }
 1437+ $flags[$tag] = $val;
 1438+ }
 1439+ return $flags;
 1440+ }
 1441+
 1442+ /**
13541443 * Get the list of reviewable namespaces
13551444 * @return array
13561445 */
@@ -1590,7 +1679,7 @@
15911680 # We can set the sync cache key already.
15921681 global $wgParserCacheExpireTime;
15931682 $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $article->getId() );
1594 - $data = FlaggedRevs::makeMemcObj( "true" );
 1683+ $data = self::makeMemcObj( "true" );
15951684 $wgMemc->set( $key, $data, $wgParserCacheExpireTime );
15961685 } else if ( $sv ) {
15971686 # Update tracking table
Property changes on: branches/wmf/1.16wmf4/extensions/FlaggedRevs_alpha
___________________________________________________________________
Modified: svn:mergeinfo
15981687 Merged /trunk/extensions/FlaggedRevs:r66345,66384-66669

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r66384Refactored userCanSetTag/userCanSetFlags functions into FlaggedRevs classaaron19:51, 13 May 2010
r66669* Added stable-logentry-modify action...aaron23:57, 19 May 2010

Status & tagging log