Index: trunk/extensions/FlaggedRevs/FlaggedRevs.php |
— | — | @@ -249,6 +249,7 @@ |
250 | 250 | |
251 | 251 | # Event handler classes... |
252 | 252 | $wgAutoloadClasses['FlaggedRevsHooks'] = $dir . 'FlaggedRevs.hooks.php'; |
| 253 | +$wgAutoloadClasses['FlaggedRevsUIHooks'] = $dir . 'presentation/FlaggedRevsUI.hooks.php'; |
253 | 254 | $wgAutoloadClasses['FlaggedRevsApiHooks'] = $dir . 'api/FlaggedRevsApi.hooks.php'; |
254 | 255 | $wgAutoloadClasses['FlaggedRevsUpdaterHooks'] = $dir . 'updater/FlaggedRevsUpdater.hooks.php'; |
255 | 256 | |
— | — | @@ -272,8 +273,8 @@ |
273 | 274 | $wgAutoloadClasses['FlaggedPageView'] = $dir . 'presentation/FlaggedPageView.php'; |
274 | 275 | $wgAutoloadClasses['FlaggedRevsLogView'] = $dir . 'presentation/FlaggedRevsLogView.php'; |
275 | 276 | $wgAutoloadClasses['FlaggedRevsXML'] = $dir . 'presentation/FlaggedRevsXML.php'; |
276 | | -$wgAutoloadClasses['RevisionReviewFormGUI'] = $dir . 'presentation/RevisionReviewFormGUI.php'; |
277 | | -$wgAutoloadClasses['RejectConfirmationFormGUI'] = $dir . 'presentation/RejectConfirmationFormGUI.php'; |
| 277 | +$wgAutoloadClasses['RevisionReviewFormUI'] = $dir . 'presentation/RevisionReviewFormUI.php'; |
| 278 | +$wgAutoloadClasses['RejectConfirmationFormUI'] = $dir . 'presentation/RejectConfirmationFormUI.php'; |
278 | 279 | |
279 | 280 | $specialActionDir = $dir . 'presentation/specialpages/actions/'; |
280 | 281 | # Load revision review UI |
— | — | @@ -393,52 +394,52 @@ |
394 | 395 | |
395 | 396 | # ######## User interface ######### |
396 | 397 | # Override current revision, add patrol links, set cache... |
397 | | -$wgHooks['ArticleViewHeader'][] = 'FlaggedRevsHooks::onArticleViewHeader'; |
398 | | -$wgHooks['ImagePageFindFile'][] = 'FlaggedRevsHooks::onImagePageFindFile'; |
| 398 | +$wgHooks['ArticleViewHeader'][] = 'FlaggedRevsUIHooks::onArticleViewHeader'; |
| 399 | +$wgHooks['ImagePageFindFile'][] = 'FlaggedRevsUIHooks::onImagePageFindFile'; |
399 | 400 | # Override redirect behavior... |
400 | | -$wgHooks['InitializeArticleMaybeRedirect'][] = 'FlaggedRevsHooks::overrideRedirect'; |
| 401 | +$wgHooks['InitializeArticleMaybeRedirect'][] = 'FlaggedRevsUIHooks::overrideRedirect'; |
401 | 402 | # Set page view tabs |
402 | | -$wgHooks['SkinTemplateTabs'][] = 'FlaggedRevsHooks::onSkinTemplateTabs'; // All skins |
403 | | -$wgHooks['SkinTemplateNavigation'][] = 'FlaggedRevsHooks::onSkinTemplateNavigation'; // Vector |
| 403 | +$wgHooks['SkinTemplateTabs'][] = 'FlaggedRevsUIHooks::onSkinTemplateTabs'; // All skins |
| 404 | +$wgHooks['SkinTemplateNavigation'][] = 'FlaggedRevsUIHooks::onSkinTemplateNavigation'; // Vector |
404 | 405 | # Add notice tags to edit view |
405 | | -$wgHooks['EditPage::showEditForm:initial'][] = 'FlaggedRevsHooks::addToEditView'; |
| 406 | +$wgHooks['EditPage::showEditForm:initial'][] = 'FlaggedRevsUIHooks::addToEditView'; |
406 | 407 | # Tweak submit button name/title |
407 | | -$wgHooks['EditPageBeforeEditButtons'][] = 'FlaggedRevsHooks::onBeforeEditButtons'; |
| 408 | +$wgHooks['EditPageBeforeEditButtons'][] = 'FlaggedRevsUIHooks::onBeforeEditButtons'; |
408 | 409 | # Autoreview information from form |
409 | | -$wgHooks['EditPageBeforeEditChecks'][] = 'FlaggedRevsHooks::addReviewCheck'; |
410 | | -$wgHooks['EditPage::showEditForm:fields'][] = 'FlaggedRevsHooks::addRevisionIDField'; |
| 410 | +$wgHooks['EditPageBeforeEditChecks'][] = 'FlaggedRevsUIHooks::addReviewCheck'; |
| 411 | +$wgHooks['EditPage::showEditForm:fields'][] = 'FlaggedRevsUIHooks::addRevisionIDField'; |
411 | 412 | # Add draft link to section edit error |
412 | | -$wgHooks['EditPageNoSuchSection'][] = 'FlaggedRevsHooks::onNoSuchSection'; |
| 413 | +$wgHooks['EditPageNoSuchSection'][] = 'FlaggedRevsUIHooks::onNoSuchSection'; |
413 | 414 | # Add notice tags to history |
414 | | -$wgHooks['PageHistoryBeforeList'][] = 'FlaggedRevsHooks::addToHistView'; |
| 415 | +$wgHooks['PageHistoryBeforeList'][] = 'FlaggedRevsUIHooks::addToHistView'; |
415 | 416 | # Add review form and visiblity settings link |
416 | | -$wgHooks['SkinAfterContent'][] = 'FlaggedRevsHooks::onSkinAfterContent'; |
| 417 | +$wgHooks['SkinAfterContent'][] = 'FlaggedRevsUIHooks::onSkinAfterContent'; |
417 | 418 | # Mark items in page history |
418 | | -$wgHooks['PageHistoryPager::getQueryInfo'][] = 'FlaggedRevsHooks::addToHistQuery'; |
419 | | -$wgHooks['PageHistoryLineEnding'][] = 'FlaggedRevsHooks::addToHistLine'; |
420 | | -$wgHooks['LocalFile::getHistory'][] = 'FlaggedRevsHooks::addToFileHistQuery'; |
421 | | -$wgHooks['ImagePageFileHistoryLine'][] = 'FlaggedRevsHooks::addToFileHistLine'; |
| 419 | +$wgHooks['PageHistoryPager::getQueryInfo'][] = 'FlaggedRevsUIHooks::addToHistQuery'; |
| 420 | +$wgHooks['PageHistoryLineEnding'][] = 'FlaggedRevsUIHooks::addToHistLine'; |
| 421 | +$wgHooks['LocalFile::getHistory'][] = 'FlaggedRevsUIHooks::addToFileHistQuery'; |
| 422 | +$wgHooks['ImagePageFileHistoryLine'][] = 'FlaggedRevsUIHooks::addToFileHistLine'; |
422 | 423 | # Mark items in RC |
423 | | -$wgHooks['SpecialRecentChangesQuery'][] = 'FlaggedRevsHooks::addToRCQuery'; |
424 | | -$wgHooks['SpecialWatchlistQuery'][] = 'FlaggedRevsHooks::addToWatchlistQuery'; |
425 | | -$wgHooks['ChangesListInsertArticleLink'][] = 'FlaggedRevsHooks::addToChangeListLine'; |
| 424 | +$wgHooks['SpecialRecentChangesQuery'][] = 'FlaggedRevsUIHooks::addToRCQuery'; |
| 425 | +$wgHooks['SpecialWatchlistQuery'][] = 'FlaggedRevsUIHooks::addToWatchlistQuery'; |
| 426 | +$wgHooks['ChangesListInsertArticleLink'][] = 'FlaggedRevsUIHooks::addToChangeListLine'; |
426 | 427 | # Page review on edit |
427 | | -$wgHooks['ArticleUpdateBeforeRedirect'][] = 'FlaggedRevsHooks::injectPostEditURLParams'; |
| 428 | +$wgHooks['ArticleUpdateBeforeRedirect'][] = 'FlaggedRevsUIHooks::injectPostEditURLParams'; |
428 | 429 | # Diff-to-stable |
429 | | -$wgHooks['DiffViewHeader'][] = 'FlaggedRevsHooks::onDiffViewHeader'; |
| 430 | +$wgHooks['DiffViewHeader'][] = 'FlaggedRevsUIHooks::onDiffViewHeader'; |
430 | 431 | # Add diff=review url param alias |
431 | | -$wgHooks['NewDifferenceEngine'][] = 'FlaggedRevsHooks::checkDiffUrl'; |
| 432 | +$wgHooks['NewDifferenceEngine'][] = 'FlaggedRevsUIHooks::checkDiffUrl'; |
432 | 433 | # Local user account preference |
433 | | -$wgHooks['GetPreferences'][] = 'FlaggedRevsHooks::onGetPreferences'; |
| 434 | +$wgHooks['GetPreferences'][] = 'FlaggedRevsUIHooks::onGetPreferences'; |
434 | 435 | # Show unreviewed pages links |
435 | | -$wgHooks['CategoryPageView'][] = 'FlaggedRevsHooks::onCategoryPageView'; |
| 436 | +$wgHooks['CategoryPageView'][] = 'FlaggedRevsUIHooks::onCategoryPageView'; |
436 | 437 | # Review/stability log links |
437 | | -$wgHooks['LogLine'][] = 'FlaggedRevsHooks::logLineLinks'; |
| 438 | +$wgHooks['LogLine'][] = 'FlaggedRevsUIHooks::logLineLinks'; |
438 | 439 | |
439 | 440 | # Add review notice, backlog notices and CSS/JS and set robots |
440 | | -$wgHooks['BeforePageDisplay'][] = 'FlaggedRevsHooks::onBeforePageDisplay'; |
| 441 | +$wgHooks['BeforePageDisplay'][] = 'FlaggedRevsUIHooks::onBeforePageDisplay'; |
441 | 442 | # Add global JS vars |
442 | | -$wgHooks['MakeGlobalVariablesScript'][] = 'FlaggedRevsHooks::injectGlobalJSVars'; |
| 443 | +$wgHooks['MakeGlobalVariablesScript'][] = 'FlaggedRevsUIHooks::injectGlobalJSVars'; |
443 | 444 | |
444 | 445 | # Add flagging data to ApiQueryRevisions |
445 | 446 | $wgHooks['APIGetAllowedParams'][] = 'FlaggedRevsApiHooks::addApiRevisionParams'; |
— | — | @@ -489,10 +490,10 @@ |
490 | 491 | $wgHooks['GetAutoPromoteGroups'][] = 'FlaggedRevsHooks::checkAutoPromote'; |
491 | 492 | |
492 | 493 | # Check if a page is currently being reviewed |
493 | | -$wgHooks['MediaWikiPerformAction'][] = 'FlaggedRevsHooks::onMediaWikiPerformAction'; |
| 494 | +$wgHooks['MediaWikiPerformAction'][] = 'FlaggedRevsUIHooks::onMediaWikiPerformAction'; |
494 | 495 | |
495 | 496 | # Actually register special pages |
496 | | -$wgHooks['SpecialPage_initList'][] = 'FlaggedRevsHooks::defineSpecialPages'; |
| 497 | +$wgHooks['SpecialPage_initList'][] = 'FlaggedRevsUIHooks::defineSpecialPages'; |
497 | 498 | |
498 | 499 | # Stable dump hook |
499 | 500 | $wgHooks['WikiExporter::dumpStableQuery'][] = 'FlaggedRevsHooks::stableDumpQuery'; |
— | — | @@ -506,7 +507,7 @@ |
507 | 508 | $wgHooks['LoadExtensionSchemaUpdates'][] = 'FlaggedRevsUpdaterHooks::addSchemaUpdates'; |
508 | 509 | |
509 | 510 | # Performance Don't show content on diff |
510 | | -$wgHooks['ArticleContentOnDiff'][] = 'FlaggedRevsHooks::onArticleContentOnDiff'; |
| 511 | +$wgHooks['ArticleContentOnDiff'][] = 'FlaggedRevsUIHooks::onArticleContentOnDiff'; |
511 | 512 | |
512 | 513 | # ######## |
513 | 514 | |
— | — | @@ -514,15 +515,15 @@ |
515 | 516 | global $wgHooks; |
516 | 517 | # Mark items in user contribs |
517 | 518 | if ( !FlaggedRevs::useOnlyIfProtected() ) { |
518 | | - $wgHooks['ContribsPager::getQueryInfo'][] = 'FlaggedRevsHooks::addToContribsQuery'; |
519 | | - $wgHooks['ContributionsLineEnding'][] = 'FlaggedRevsHooks::addToContribsLine'; |
| 519 | + $wgHooks['ContribsPager::getQueryInfo'][] = 'FlaggedRevsUIHooks::addToContribsQuery'; |
| 520 | + $wgHooks['ContributionsLineEnding'][] = 'FlaggedRevsUIHooks::addToContribsLine'; |
520 | 521 | } |
521 | 522 | if ( FlaggedRevs::useProtectionLevels() ) { |
522 | 523 | # Add protection form field |
523 | | - $wgHooks['ProtectionForm::buildForm'][] = 'FlaggedRevsHooks::onProtectionForm'; |
524 | | - $wgHooks['ProtectionForm::showLogExtract'][] = 'FlaggedRevsHooks::insertStabilityLog'; |
| 524 | + $wgHooks['ProtectionForm::buildForm'][] = 'FlaggedRevsUIHooks::onProtectionForm'; |
| 525 | + $wgHooks['ProtectionForm::showLogExtract'][] = 'FlaggedRevsUIHooks::insertStabilityLog'; |
525 | 526 | # Save stability settings |
526 | | - $wgHooks['ProtectionForm::save'][] = 'FlaggedRevsHooks::onProtectionSave'; |
| 527 | + $wgHooks['ProtectionForm::save'][] = 'FlaggedRevsUIHooks::onProtectionSave'; |
527 | 528 | # Parser stuff |
528 | 529 | $wgHooks['ParserFirstCallInit'][] = 'FlaggedRevsHooks::onParserFirstCallInit'; |
529 | 530 | $wgHooks['LanguageGetMagic'][] = 'FlaggedRevsHooks::onLanguageGetMagic'; |
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php |
— | — | @@ -3,148 +3,7 @@ |
4 | 4 | * Class containing hooked functions for a FlaggedRevs environment |
5 | 5 | */ |
6 | 6 | class FlaggedRevsHooks { |
7 | | - /* |
8 | | - * Register FlaggedRevs special pages as needed. |
9 | | - * Also sets $wgSpecialPages just to be consistent. |
10 | | - */ |
11 | | - public static function defineSpecialPages( array &$list ) { |
12 | | - global $wgSpecialPages, $wgUseTagFilter; |
13 | | - // Show special pages only if FlaggedRevs is enabled on some namespaces |
14 | | - if ( !FlaggedRevs::getReviewNamespaces() ) { |
15 | | - return true; |
16 | | - } |
17 | | - $list['RevisionReview'] = $wgSpecialPages['RevisionReview'] = 'RevisionReview'; |
18 | | - $list['ReviewedVersions'] = $wgSpecialPages['ReviewedVersions'] = 'ReviewedVersions'; |
19 | | - $list['PendingChanges'] = $wgSpecialPages['PendingChanges'] = 'PendingChanges'; |
20 | | - // Show tag filtered pending edit page if there are tags |
21 | | - if ( $wgUseTagFilter && ChangeTags::listDefinedTags() ) { |
22 | | - $list['ProblemChanges'] = $wgSpecialPages['ProblemChanges'] = 'ProblemChanges'; |
23 | | - } |
24 | | - if ( !FlaggedRevs::useOnlyIfProtected() ) { |
25 | | - $list['ReviewedPages'] = $wgSpecialPages['ReviewedPages'] = 'ReviewedPages'; |
26 | | - $list['UnreviewedPages'] = $wgSpecialPages['UnreviewedPages'] = 'UnreviewedPages'; |
27 | | - } |
28 | | - $list['QualityOversight'] = $wgSpecialPages['QualityOversight'] = 'QualityOversight'; |
29 | | - $list['ValidationStatistics'] = $wgSpecialPages['ValidationStatistics'] = 'ValidationStatistics'; |
30 | | - // Protect levels define allowed stability settings |
31 | | - if ( FlaggedRevs::useProtectionLevels() ) { |
32 | | - $list['StablePages'] = $wgSpecialPages['StablePages'] = 'StablePages'; |
33 | | - } else { |
34 | | - $list['ConfiguredPages'] = $wgSpecialPages['ConfiguredPages'] = 'ConfiguredPages'; |
35 | | - $list['Stabilization'] = $wgSpecialPages['Stabilization'] = 'Stabilization'; |
36 | | - } |
37 | | - return true; |
38 | | - } |
39 | | - |
40 | 7 | /** |
41 | | - * Add FlaggedRevs css/js. |
42 | | - */ |
43 | | - protected static function injectStyleAndJS() { |
44 | | - global $wgOut, $wgUser; |
45 | | - static $loadedModules = false; |
46 | | - if ( $loadedModules ) { |
47 | | - return true; // don't double-load |
48 | | - } |
49 | | - $loadedModules = true; |
50 | | - $fa = FlaggedPageView::globalArticleInstance(); |
51 | | - # Try to only add to relevant pages |
52 | | - if ( !$fa || !$fa->isReviewable() ) { |
53 | | - return true; |
54 | | - } |
55 | | - # Add main CSS & JS files |
56 | | - $wgOut->addModuleStyles( 'ext.flaggedRevs.basic' ); |
57 | | - $wgOut->addModules( 'ext.flaggedRevs.advanced' ); |
58 | | - # Add review form JS for reviewers |
59 | | - if ( $wgUser->isAllowed( 'review' ) ) { |
60 | | - $wgOut->addModules( 'ext.flaggedRevs.review' ); |
61 | | - } |
62 | | - return true; |
63 | | - } |
64 | | - |
65 | | - public static function injectGlobalJSVars( array &$globalVars ) { |
66 | | - # Get the review tags on this wiki |
67 | | - $rTags = FlaggedRevs::getJSTagParams(); |
68 | | - $globalVars['wgFlaggedRevsParams'] = $rTags; |
69 | | - # Get page-specific meta-data |
70 | | - $fa = FlaggedPageView::globalArticleInstance(); |
71 | | - # Try to only add to relevant pages |
72 | | - if ( $fa && $fa->isReviewable() ) { |
73 | | - $frev = $fa->getStableRev(); |
74 | | - $stableId = $frev ? $frev->getRevId() : 0; |
75 | | - } else { |
76 | | - $stableId = null; |
77 | | - } |
78 | | - $globalVars['wgStableRevisionId'] = $stableId; |
79 | | - $revisionContents = (object) array( |
80 | | - 'error' => wfMsgHtml( 'revcontents-error' ), |
81 | | - 'waiting' => wfMsgHtml( 'revcontents-waiting' ) |
82 | | - ); |
83 | | - $globalVars['wgRevContents'] = $revisionContents; |
84 | | - return true; |
85 | | - } |
86 | | - |
87 | | - /** |
88 | | - * Add FlaggedRevs css for relevant special pages. |
89 | | - * @param OutputPage $out |
90 | | - */ |
91 | | - protected static function injectStyleForSpecial( &$out ) { |
92 | | - $title = $out->getTitle(); |
93 | | - if ( $title->getNamespace() !== NS_SPECIAL ) { |
94 | | - return true; |
95 | | - } |
96 | | - $spPages = array( 'UnreviewedPages', 'PendingChanges', 'ProblemChanges', |
97 | | - 'Watchlist', 'Recentchanges', 'Contributions', 'Recentchangeslinked' ); |
98 | | - foreach ( $spPages as $key ) { |
99 | | - if ( $title->isSpecial( $key ) ) { |
100 | | - $out->addModuleStyles( 'ext.flaggedRevs.basic' ); // CSS only |
101 | | - break; |
102 | | - } |
103 | | - } |
104 | | - return true; |
105 | | - } |
106 | | - |
107 | | - /* |
108 | | - * Add tag notice, CSS/JS, and set robots policy |
109 | | - */ |
110 | | - public static function onBeforePageDisplay( &$out, &$skin ) { |
111 | | - if ( $out->isArticleRelated() ) { |
112 | | - $view = FlaggedPageView::singleton(); |
113 | | - $view->displayTag(); // show notice bar/icon in subtitle |
114 | | - $view->setRobotPolicy(); // set indexing policy |
115 | | - self::injectStyleAndJS(); // full CSS/JS |
116 | | - } else { |
117 | | - self::maybeAddBacklogNotice( $out ); // RC/Watchlist notice |
118 | | - self::injectStyleForSpecial( $out ); // try special page CSS |
119 | | - } |
120 | | - return true; |
121 | | - } |
122 | | - |
123 | | - // Note: $user may be stubbed |
124 | | - public static function onMediaWikiPerformAction( |
125 | | - $output, $article, Title $title, $user, $request |
126 | | - ) { |
127 | | - $fa = FlaggedPage::getTitleInstance( $title ); |
128 | | - self::maybeMarkUnderReview( $fa, $request ); |
129 | | - return true; |
130 | | - } |
131 | | - |
132 | | - // Mark when an unreviewed page is being reviewed |
133 | | - protected static function maybeMarkUnderReview( FlaggedPage $fa, WebRequest $request ) { |
134 | | - global $wgUser; |
135 | | - if ( !$request->getInt( 'reviewing' ) && !$request->getInt( 'rcid' ) ) { |
136 | | - return true; // not implied by URL |
137 | | - } |
138 | | - # Set a key to note when someone is reviewing this. |
139 | | - # NOTE: diff-to-stable views already handled elsewhere. |
140 | | - if ( $fa->isReviewable() && !$fa->getStable() // not reviewed yet |
141 | | - && $fa->getTitle()->userCan( 'review' ) ) |
142 | | - { |
143 | | - FRUserActivity::setUserReviewingPage( $wgUser, $fa->getID() ); |
144 | | - } |
145 | | - return true; |
146 | | - } |
147 | | - |
148 | | - /** |
149 | 8 | * Update flaggedrevs table on revision restore |
150 | 9 | */ |
151 | 10 | public static function onRevisionRestore( $title, Revision $revision, $oldPageID ) { |
— | — | @@ -1133,526 +992,6 @@ |
1134 | 993 | return true; |
1135 | 994 | } |
1136 | 995 | |
1137 | | - /** Add user preferences */ |
1138 | | - public static function onGetPreferences( $user, array &$preferences ) { |
1139 | | - // Box or bar UI |
1140 | | - $preferences['flaggedrevssimpleui'] = |
1141 | | - array( |
1142 | | - 'type' => 'radio', |
1143 | | - 'section' => 'flaggedrevs/flaggedrevs-ui', |
1144 | | - 'label-message' => 'flaggedrevs-pref-UI', |
1145 | | - 'options' => array( |
1146 | | - wfMsg( 'flaggedrevs-pref-UI-0' ) => 0, |
1147 | | - wfMsg( 'flaggedrevs-pref-UI-1' ) => 1, |
1148 | | - ), |
1149 | | - ); |
1150 | | - // Default versions... |
1151 | | - $preferences['flaggedrevsstable'] = |
1152 | | - array( |
1153 | | - 'type' => 'toggle', |
1154 | | - 'section' => 'flaggedrevs/flaggedrevs-ui', |
1155 | | - 'label-message' => 'flaggedrevs-prefs-stable', |
1156 | | - ); |
1157 | | - // Review-related rights... |
1158 | | - if ( $user->isAllowed( 'review' ) ) { |
1159 | | - // Watching reviewed pages |
1160 | | - $preferences['flaggedrevswatch'] = |
1161 | | - array( |
1162 | | - 'type' => 'toggle', |
1163 | | - 'section' => 'watchlist/advancedwatchlist', |
1164 | | - 'label-message' => 'flaggedrevs-prefs-watch', |
1165 | | - ); |
1166 | | - // Diff-to-stable on edit |
1167 | | - $preferences['flaggedrevseditdiffs'] = |
1168 | | - array( |
1169 | | - 'type' => 'toggle', |
1170 | | - 'section' => 'editing/advancedediting', |
1171 | | - 'label-message' => 'flaggedrevs-prefs-editdiffs', |
1172 | | - ); |
1173 | | - // Diff-to-stable on draft view |
1174 | | - $preferences['flaggedrevsviewdiffs'] = |
1175 | | - array( |
1176 | | - 'type' => 'toggle', |
1177 | | - 'section' => 'flaggedrevs/flaggedrevs-ui', |
1178 | | - 'label-message' => 'flaggedrevs-prefs-viewdiffs', |
1179 | | - ); |
1180 | | - } |
1181 | | - return true; |
1182 | | - } |
1183 | | - |
1184 | | - public static function logLineLinks( |
1185 | | - $type, $action, $title, $params, &$comment, &$rv, $ts |
1186 | | - ) { |
1187 | | - if ( !$title ) { |
1188 | | - return true; // sanity check |
1189 | | - } |
1190 | | - // Stability log |
1191 | | - if ( $type == 'stable' && FlaggedRevsLog::isStabilityAction( $action ) ) { |
1192 | | - $rv .= FlaggedRevsLogView::stabilityLogLinks( $title, $ts, $params ); |
1193 | | - // Review log |
1194 | | - } elseif ( $type == 'review' && FlaggedRevsLog::isReviewAction( $action ) ) { |
1195 | | - $rv .= FlaggedRevsLogView::reviewLogLinks( $action, $title, $params ); |
1196 | | - } |
1197 | | - return true; |
1198 | | - } |
1199 | | - |
1200 | | - public static function onImagePageFindFile( $imagePage, &$normalFile, &$displayFile ) { |
1201 | | - $view = FlaggedPageView::singleton(); |
1202 | | - $view->imagePageFindFile( $normalFile, $displayFile ); |
1203 | | - return true; |
1204 | | - } |
1205 | | - |
1206 | | - // MonoBook et al: $contentActions is all the tabs |
1207 | | - // Vector et al: $contentActions is all the action tabs...unused |
1208 | | - public static function onSkinTemplateTabs( Skin $skin, array &$contentActions ) { |
1209 | | - if ( $skin instanceof SkinVector ) { |
1210 | | - // *sigh*...skip, dealt with in setNavigation() |
1211 | | - return true; |
1212 | | - } |
1213 | | - // Note: $wgArticle sometimes not set here |
1214 | | - if ( FlaggedPageView::globalArticleInstance() != null ) { |
1215 | | - $view = FlaggedPageView::singleton(); |
1216 | | - $view->setActionTabs( $skin, $contentActions ); |
1217 | | - $view->setViewTabs( $skin, $contentActions, 'flat' ); |
1218 | | - } |
1219 | | - return true; |
1220 | | - } |
1221 | | - |
1222 | | - // Vector et al: $links is all the tabs (2 levels) |
1223 | | - public static function onSkinTemplateNavigation( Skin $skin, array &$links ) { |
1224 | | - // Note: $wgArticle sometimes not set here |
1225 | | - if ( FlaggedPageView::globalArticleInstance() != null ) { |
1226 | | - $view = FlaggedPageView::singleton(); |
1227 | | - $view->setActionTabs( $skin, $links['actions'] ); |
1228 | | - $view->setViewTabs( $skin, $links['views'], 'nav' ); |
1229 | | - } |
1230 | | - return true; |
1231 | | - } |
1232 | | - |
1233 | | - public static function onArticleViewHeader( &$article, &$outputDone, &$useParserCache ) { |
1234 | | - $view = FlaggedPageView::singleton(); |
1235 | | - $view->addStableLink( $outputDone, $useParserCache ); |
1236 | | - $view->setPageContent( $outputDone, $useParserCache ); |
1237 | | - return true; |
1238 | | - } |
1239 | | - |
1240 | | - public static function overrideRedirect( |
1241 | | - Title $title, WebRequest $request, &$ignoreRedirect, &$target, Article &$article |
1242 | | - ) { |
1243 | | - global $wgMemc, $wgParserCacheExpireTime; |
1244 | | - $fa = FlaggedPage::getTitleInstance( $title ); // on $wgTitle |
1245 | | - if ( !$fa->isReviewable() ) { |
1246 | | - return true; // nothing to do |
1247 | | - } |
1248 | | - # Viewing an old reviewed version... |
1249 | | - if ( $request->getVal( 'stableid' ) ) { |
1250 | | - $ignoreRedirect = true; // don't redirect (same as ?oldid=x) |
1251 | | - return true; |
1252 | | - } |
1253 | | - $srev = $fa->getStableRev(); |
1254 | | - $view = FlaggedPageView::singleton(); |
1255 | | - # Check if we are viewing an unsynced stable version... |
1256 | | - if ( $srev && $view->showingStable() && $srev->getRevId() != $article->getLatest() ) { |
1257 | | - # Check the stable redirect properties from the cache... |
1258 | | - $key = wfMemcKey( 'flaggedrevs', 'overrideRedirect', $article->getId() ); |
1259 | | - $tuple = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $article ); |
1260 | | - if ( is_array( $tuple ) ) { // cache hit |
1261 | | - list( $ignoreRedirect, $target ) = $tuple; |
1262 | | - } else { // cache miss; fetch the stable rev text... |
1263 | | - $text = $srev->getRevText(); |
1264 | | - $redirect = $fa->getRedirectURL( Title::newFromRedirectRecurse( $text ) ); |
1265 | | - if ( $redirect ) { |
1266 | | - $target = $redirect; // use stable redirect |
1267 | | - } else { |
1268 | | - $ignoreRedirect = true; // make MW skip redirection |
1269 | | - } |
1270 | | - $data = FlaggedRevs::makeMemcObj( array( $ignoreRedirect, $target ) ); |
1271 | | - $wgMemc->set( $key, $data, $wgParserCacheExpireTime ); // cache results |
1272 | | - } |
1273 | | - $clearEnvironment = (bool)$target; |
1274 | | - # Check if the we are viewing a draft or synced stable version... |
1275 | | - } else { |
1276 | | - # In both cases, we can just let MW use followRedirect() |
1277 | | - # on the draft as normal, avoiding any page text hits. |
1278 | | - $clearEnvironment = $article->isRedirect(); |
1279 | | - } |
1280 | | - # Environment (e.g. $wgTitle) will change in MediaWiki::initializeArticle |
1281 | | - if ( $clearEnvironment ) $view->clear(); |
1282 | | - return true; |
1283 | | - } |
1284 | | - |
1285 | | - public static function addToEditView( &$editPage ) { |
1286 | | - $view = FlaggedPageView::singleton(); |
1287 | | - $view->addToEditView( $editPage ); |
1288 | | - return true; |
1289 | | - } |
1290 | | - |
1291 | | - public static function onBeforeEditButtons( &$editPage, &$buttons ) { |
1292 | | - $view = FlaggedPageView::singleton(); |
1293 | | - $view->changeSaveButton( $editPage, $buttons ); |
1294 | | - return true; |
1295 | | - } |
1296 | | - |
1297 | | - public static function onNoSuchSection( &$editPage, &$s ) { |
1298 | | - $view = FlaggedPageView::singleton(); |
1299 | | - $view->addToNoSuchSection( $editPage, $s ); |
1300 | | - return true; |
1301 | | - } |
1302 | | - |
1303 | | - public static function addToHistView( &$article ) { |
1304 | | - $view = FlaggedPageView::singleton(); |
1305 | | - $view->addToHistView(); |
1306 | | - return true; |
1307 | | - } |
1308 | | - |
1309 | | - public static function onCategoryPageView( &$category ) { |
1310 | | - $view = FlaggedPageView::singleton(); |
1311 | | - $view->addToCategoryView(); |
1312 | | - return true; |
1313 | | - } |
1314 | | - |
1315 | | - public static function onSkinAfterContent( &$data ) { |
1316 | | - global $wgOut; |
1317 | | - if ( $wgOut->isArticleRelated() |
1318 | | - && FlaggedPageView::globalArticleInstance() != null ) |
1319 | | - { |
1320 | | - $view = FlaggedPageView::singleton(); |
1321 | | - $view->addReviewNotes( $data ); |
1322 | | - $view->addReviewForm( $data ); |
1323 | | - $view->addVisibilityLink( $data ); |
1324 | | - } |
1325 | | - return true; |
1326 | | - } |
1327 | | - |
1328 | | - public static function addToHistQuery( HistoryPager $pager, array &$queryInfo ) { |
1329 | | - $flaggedArticle = FlaggedPage::getArticleInstance( $pager->getArticle() ); |
1330 | | - # Non-content pages cannot be validated. Stable version must exist. |
1331 | | - if ( $flaggedArticle->isReviewable() && $flaggedArticle->getStableRev() ) { |
1332 | | - # Highlight flaggedrevs |
1333 | | - $queryInfo['tables'][] = 'flaggedrevs'; |
1334 | | - $queryInfo['fields'][] = 'fr_quality'; |
1335 | | - $queryInfo['fields'][] = 'fr_user'; |
1336 | | - $queryInfo['fields'][] = 'fr_flags'; |
1337 | | - $queryInfo['join_conds']['flaggedrevs'] = array( 'LEFT JOIN', |
1338 | | - "fr_page_id = rev_page AND fr_rev_id = rev_id" ); |
1339 | | - # Find reviewer name. Sanity check that no extensions added a `user` query. |
1340 | | - if ( !in_array( 'user', $queryInfo['tables'] ) ) { |
1341 | | - $queryInfo['tables'][] = 'user'; |
1342 | | - $queryInfo['fields'][] = 'user_name AS reviewer'; |
1343 | | - $queryInfo['join_conds']['user'] = array( 'LEFT JOIN', "user_id = fr_user" ); |
1344 | | - } |
1345 | | - } |
1346 | | - return true; |
1347 | | - } |
1348 | | - |
1349 | | - public static function addToFileHistQuery( |
1350 | | - File $file, array &$tables, array &$fields, &$conds, array &$opts, array &$join_conds |
1351 | | - ) { |
1352 | | - if ( !$file->isLocal() ) { |
1353 | | - return true; // local files only |
1354 | | - } |
1355 | | - $flaggedArticle = FlaggedPage::getTitleInstance( $file->getTitle() ); |
1356 | | - # Non-content pages cannot be validated. Stable version must exist. |
1357 | | - if ( $flaggedArticle->isReviewable() && $flaggedArticle->getStableRev() ) { |
1358 | | - $tables[] = 'flaggedrevs'; |
1359 | | - $fields[] = 'MAX(fr_quality) AS fr_quality'; |
1360 | | - # Avoid duplicate rows due to multiple revs with the same sha-1 key |
1361 | | - |
1362 | | - # This is a stupid hack to get all the field names in our GROUP BY |
1363 | | - # clause. Postgres yells at you for not including all of the selected |
1364 | | - # columns, so grab the full list, unset the two we actually want to |
1365 | | - # order by, then append the rest of them to our two. It would be |
1366 | | - # REALLY nice if we handled this automagically in makeSelectOptions() |
1367 | | - # or something *sigh* |
1368 | | - $groupBy = OldLocalFile::selectFields(); |
1369 | | - unset( $groupBy[ array_search( 'oi_name', $groupBy ) ] ); |
1370 | | - unset( $groupBy[ array_search( 'oi_timestamp', $groupBy ) ] ); |
1371 | | - $opts['GROUP BY'] = 'oi_name,oi_timestamp,' . implode( ',', $groupBy ); |
1372 | | - |
1373 | | - $join_conds['flaggedrevs'] = array( 'LEFT JOIN', |
1374 | | - 'oi_sha1 = fr_img_sha1 AND oi_timestamp = fr_img_timestamp' ); |
1375 | | - } |
1376 | | - return true; |
1377 | | - } |
1378 | | - |
1379 | | - public static function addToContribsQuery( $pager, array &$queryInfo ) { |
1380 | | - # Highlight flaggedrevs |
1381 | | - $queryInfo['tables'][] = 'flaggedrevs'; |
1382 | | - $queryInfo['fields'][] = 'fr_quality'; |
1383 | | - $queryInfo['join_conds']['flaggedrevs'] = array( 'LEFT JOIN', |
1384 | | - "fr_page_id = rev_page AND fr_rev_id = rev_id" ); |
1385 | | - # Highlight unchecked content |
1386 | | - $queryInfo['tables'][] = 'flaggedpages'; |
1387 | | - $queryInfo['fields'][] = 'fp_stable'; |
1388 | | - $queryInfo['fields'][] = 'fp_pending_since'; |
1389 | | - $queryInfo['join_conds']['flaggedpages'] = array( 'LEFT JOIN', "fp_page_id = rev_page" ); |
1390 | | - return true; |
1391 | | - } |
1392 | | - |
1393 | | - public static function addToRCQuery( |
1394 | | - &$conds, array &$tables, array &$join_conds, $opts, &$query_opts, &$select |
1395 | | - ) { |
1396 | | - $tables[] = 'flaggedpages'; |
1397 | | - $join_conds['flaggedpages'] = array( 'LEFT JOIN', 'fp_page_id = rc_cur_id' ); |
1398 | | - if ( is_array( $select ) ) { // RCL |
1399 | | - $select[] = 'fp_stable'; |
1400 | | - $select[] = 'fp_pending_since'; |
1401 | | - } |
1402 | | - return true; |
1403 | | - } |
1404 | | - |
1405 | | - public static function addToWatchlistQuery( |
1406 | | - &$conds, array &$tables, array &$join_conds, array &$fields |
1407 | | - ) { |
1408 | | - global $wgUser; |
1409 | | - if ( $wgUser->isAllowed( 'review' ) ) { |
1410 | | - $fields[] = 'fp_stable'; |
1411 | | - $fields[] = 'fp_pending_since'; |
1412 | | - $tables[] = 'flaggedpages'; |
1413 | | - $join_conds['flaggedpages'] = array( 'LEFT JOIN', 'fp_page_id = rc_cur_id' ); |
1414 | | - } |
1415 | | - return true; |
1416 | | - } |
1417 | | - |
1418 | | - public static function addToHistLine( HistoryPager $history, $row, &$s, &$liClasses ) { |
1419 | | - $fa = FlaggedPage::getArticleInstance( $history->getArticle() ); |
1420 | | - if ( !$fa->isReviewable() ) { |
1421 | | - return true; // nothing to do here |
1422 | | - } |
1423 | | - # Fetch and process cache the stable revision |
1424 | | - if ( !isset( $history->fr_stableRevId ) ) { |
1425 | | - $srev = $fa->getStableRev(); |
1426 | | - $history->fr_stableRevId = $srev ? $srev->getRevId() : null; |
1427 | | - $history->fr_stableRevUTS = $srev ? // bug 15515 |
1428 | | - wfTimestamp( TS_UNIX, $srev->getRevTimestamp() ) : null; |
1429 | | - $history->fr_pendingRevs = false; |
1430 | | - } |
1431 | | - if ( !$history->fr_stableRevId ) { |
1432 | | - return true; // nothing to do here |
1433 | | - } |
1434 | | - $title = $history->getArticle()->getTitle(); |
1435 | | - $revId = (int)$row->rev_id; |
1436 | | - // Pending revision: highlight and add diff link |
1437 | | - $link = $class = ''; |
1438 | | - if ( wfTimestamp( TS_UNIX, $row->rev_timestamp ) > $history->fr_stableRevUTS ) { |
1439 | | - $class = 'flaggedrevs-pending'; |
1440 | | - $link = wfMsgExt( 'revreview-hist-pending-difflink', 'parseinline', |
1441 | | - $title->getPrefixedText(), $history->fr_stableRevId, $revId ); |
1442 | | - $link = '<span class="plainlinks">' . $link . '</span>'; |
1443 | | - $history->fr_pendingRevs = true; // pending rev shown above stable |
1444 | | - // Reviewed revision: highlight and add link |
1445 | | - } elseif ( isset( $row->fr_quality ) ) { |
1446 | | - if ( !( $row->rev_deleted & Revision::DELETED_TEXT ) ) { |
1447 | | - # Add link to stable version of *this* rev, if any |
1448 | | - list( $link, $class ) = self::markHistoryRow( $title, $row ); |
1449 | | - # Space out and demark the stable revision |
1450 | | - if ( $revId == $history->fr_stableRevId && $history->fr_pendingRevs ) { |
1451 | | - $liClasses[] = 'fr-hist-stable-margin'; |
1452 | | - } |
1453 | | - } |
1454 | | - } |
1455 | | - # Style the row as needed |
1456 | | - if ( $class ) $s = "<span class='$class'>$s</span>"; |
1457 | | - # Add stable old version link |
1458 | | - if ( $link ) $s .= " <small>$link</small>"; |
1459 | | - return true; |
1460 | | - } |
1461 | | - |
1462 | | - /** |
1463 | | - * Make stable version link and return the css |
1464 | | - * @param Title $title |
1465 | | - * @param Row $row, from history page |
1466 | | - * @return array (string,string) |
1467 | | - */ |
1468 | | - protected static function markHistoryRow( Title $title, $row ) { |
1469 | | - if ( !isset( $row->fr_quality ) ) { |
1470 | | - return array( "", "" ); // not reviewed |
1471 | | - } |
1472 | | - $liCss = FlaggedRevsXML::getQualityColor( $row->fr_quality ); |
1473 | | - $flags = explode( ',', $row->fr_flags ); |
1474 | | - if ( in_array( 'auto', $flags ) ) { |
1475 | | - $msg = ( $row->fr_quality >= 1 ) |
1476 | | - ? 'revreview-hist-quality-auto' |
1477 | | - : 'revreview-hist-basic-auto'; |
1478 | | - $css = ( $row->fr_quality >= 1 ) |
1479 | | - ? 'fr-hist-quality-auto' |
1480 | | - : 'fr-hist-basic-auto'; |
1481 | | - } else { |
1482 | | - $msg = ( $row->fr_quality >= 1 ) |
1483 | | - ? 'revreview-hist-quality-user' |
1484 | | - : 'revreview-hist-basic-user'; |
1485 | | - $css = ( $row->fr_quality >= 1 ) |
1486 | | - ? 'fr-hist-quality-user' |
1487 | | - : 'fr-hist-basic-user'; |
1488 | | - } |
1489 | | - $name = isset( $row->reviewer ) ? |
1490 | | - $row->reviewer : User::whoIs( $row->fr_user ); |
1491 | | - $link = wfMsgExt( $msg, 'parseinline', $title->getPrefixedDBkey(), $row->rev_id, $name ); |
1492 | | - $link = "<span class='$css plainlinks'>[$link]</span>"; |
1493 | | - return array( $link, $liCss ); |
1494 | | - } |
1495 | | - |
1496 | | - public static function addToFileHistLine( $hist, File $file, &$s, &$rowClass ) { |
1497 | | - if ( !$file->isVisible() ) { |
1498 | | - return true; // Don't bother showing notice for deleted revs |
1499 | | - } |
1500 | | - # Quality level for old versions selected all at once. |
1501 | | - # Commons queries cannot be done all at once... |
1502 | | - if ( !$file->isOld() || !$file->isLocal() ) { |
1503 | | - $dbr = wfGetDB( DB_SLAVE ); |
1504 | | - $quality = $dbr->selectField( 'flaggedrevs', 'fr_quality', |
1505 | | - array( 'fr_img_sha1' => $file->getSha1(), |
1506 | | - 'fr_img_timestamp' => $dbr->timestamp( $file->getTimestamp() ) ), |
1507 | | - __METHOD__ |
1508 | | - ); |
1509 | | - } else { |
1510 | | - $quality = is_null( $file->quality ) ? false : $file->quality; |
1511 | | - } |
1512 | | - # If reviewed, class the line |
1513 | | - if ( $quality !== false ) { |
1514 | | - $rowClass = FlaggedRevsXML::getQualityColor( $quality ); |
1515 | | - } |
1516 | | - return true; |
1517 | | - } |
1518 | | - |
1519 | | - public static function addToContribsLine( $contribs, &$ret, $row ) { |
1520 | | - $namespaces = FlaggedRevs::getReviewNamespaces(); |
1521 | | - if ( !in_array( $row->page_namespace, $namespaces ) ) { |
1522 | | - // do nothing |
1523 | | - } elseif ( isset( $row->fr_quality ) ) { |
1524 | | - $ret = '<span class="' . FlaggedRevsXML::getQualityColor( $row->fr_quality ) . |
1525 | | - '">' . $ret . '</span>'; |
1526 | | - } elseif ( isset( $row->fp_pending_since ) |
1527 | | - && $row->rev_timestamp >= $row->fp_pending_since ) // bug 15515 |
1528 | | - { |
1529 | | - $ret = '<span class="flaggedrevs-pending">' . $ret . '</span>'; |
1530 | | - } elseif ( !isset( $row->fp_stable ) ) { |
1531 | | - $ret = '<span class="flaggedrevs-unreviewed">' . $ret . '</span>'; |
1532 | | - } |
1533 | | - return true; |
1534 | | - } |
1535 | | - |
1536 | | - public static function addToChangeListLine( &$list, &$articlelink, &$s, RecentChange &$rc ) { |
1537 | | - global $wgUser; |
1538 | | - $title = $rc->getTitle(); // convenience |
1539 | | - if ( !FlaggedRevs::inReviewNamespace( $title ) |
1540 | | - || empty( $rc->mAttribs['rc_this_oldid'] ) // rev, not log |
1541 | | - || !array_key_exists( 'fp_stable', $rc->mAttribs ) ) |
1542 | | - { |
1543 | | - return true; // confirm that page is in reviewable namespace |
1544 | | - } |
1545 | | - $rlink = ''; |
1546 | | - // page is not reviewed |
1547 | | - if ( $rc->mAttribs['fp_stable'] == null ) { |
1548 | | - // Is this a config were pages start off reviewable? |
1549 | | - // Hide notice from non-reviewers due to vandalism concerns (bug 24002). |
1550 | | - if ( !FlaggedRevs::useOnlyIfProtected() && $wgUser->isAllowed( 'review' ) ) { |
1551 | | - $rlink = wfMsgHtml( 'revreview-unreviewedpage' ); |
1552 | | - $css = 'flaggedrevs-unreviewed'; |
1553 | | - } |
1554 | | - // page is reviewed and has pending edits (use timestamps; bug 15515) |
1555 | | - } elseif ( isset( $rc->mAttribs['fp_pending_since'] ) && |
1556 | | - $rc->mAttribs['rc_timestamp'] >= $rc->mAttribs['fp_pending_since'] ) |
1557 | | - { |
1558 | | - $rlink = $list->skin->link( |
1559 | | - $title, |
1560 | | - wfMsgHtml( 'revreview-reviewlink' ), |
1561 | | - array( 'title' => wfMsg( 'revreview-reviewlink-title' ) ), |
1562 | | - array( 'oldid' => $rc->mAttribs['fp_stable'], 'diff' => 'cur' ) |
1563 | | - ); |
1564 | | - $css = 'flaggedrevs-pending'; |
1565 | | - } |
1566 | | - if ( $rlink != '' ) { |
1567 | | - $articlelink .= " <span class=\"mw-fr-reviewlink $css\">[$rlink]</span>"; |
1568 | | - } |
1569 | | - return true; |
1570 | | - } |
1571 | | - |
1572 | | - public static function injectPostEditURLParams( $article, &$sectionAnchor, &$extraQuery ) { |
1573 | | - // Note: $wgArticle sometimes not set here |
1574 | | - if ( FlaggedPageView::globalArticleInstance() != null ) { |
1575 | | - $view = FlaggedPageView::singleton(); |
1576 | | - $view->injectPostEditURLParams( $sectionAnchor, $extraQuery ); |
1577 | | - } |
1578 | | - return true; |
1579 | | - } |
1580 | | - |
1581 | | - // diff=review param (bug 16923) |
1582 | | - public static function checkDiffUrl( $titleObj, &$mOldid, &$mNewid, $old, $new ) { |
1583 | | - if ( $new === 'review' && isset( $titleObj ) ) { |
1584 | | - $frev = FlaggedRevision::newFromStable( $titleObj ); |
1585 | | - if ( $frev ) { |
1586 | | - $mOldid = $frev->getRevId(); // stable |
1587 | | - $mNewid = 0; // cur |
1588 | | - } |
1589 | | - } |
1590 | | - return true; |
1591 | | - } |
1592 | | - |
1593 | | - public static function onDiffViewHeader( $diff, $oldRev, $newRev ) { |
1594 | | - self::injectStyleAndJS(); |
1595 | | - $view = FlaggedPageView::singleton(); |
1596 | | - $view->setViewFlags( $diff, $oldRev, $newRev ); |
1597 | | - $view->addToDiffView( $diff, $oldRev, $newRev ); |
1598 | | - return true; |
1599 | | - } |
1600 | | - |
1601 | | - /* |
1602 | | - * If an article is reviewable, get custom article contents from the FlaggedPageView |
1603 | | - */ |
1604 | | - public static function onArticleContentOnDiff( $diffEngine, $out ) { |
1605 | | - $fa = FlaggedPage::getTitleInstance( $out->getTitle() ); |
1606 | | - if ( !$fa->isReviewable() ) { |
1607 | | - return true; // nothing to do |
1608 | | - } |
1609 | | - $view = FlaggedPageView::singleton(); |
1610 | | - $view->addCustomContentHtml( $out, $diffEngine->getNewid() ); |
1611 | | - return false; |
1612 | | - } |
1613 | | - |
1614 | | - public static function addRevisionIDField( $editPage, $out ) { |
1615 | | - $view = FlaggedPageView::singleton(); |
1616 | | - $view->addRevisionIDField( $editPage, $out ); |
1617 | | - return true; |
1618 | | - } |
1619 | | - |
1620 | | - public static function addReviewCheck( $editPage, &$checkboxes, &$tabindex ) { |
1621 | | - $view = FlaggedPageView::singleton(); |
1622 | | - $view->addReviewCheck( $editPage, $checkboxes, $tabindex ); |
1623 | | - return true; |
1624 | | - } |
1625 | | - |
1626 | | - protected static function maybeAddBacklogNotice( OutputPage &$out ) { |
1627 | | - global $wgUser; |
1628 | | - if ( !$wgUser->isAllowed( 'review' ) ) { |
1629 | | - return true; // not relevant to user |
1630 | | - } |
1631 | | - $namespaces = FlaggedRevs::getReviewNamespaces(); |
1632 | | - $watchlist = SpecialPage::getTitleFor( 'Watchlist' ); |
1633 | | - # Add notice to watchlist about pending changes... |
1634 | | - if ( $out->getTitle()->equals( $watchlist ) && $namespaces ) { |
1635 | | - $dbr = wfGetDB( DB_SLAVE, 'watchlist' ); // consistency with watchlist |
1636 | | - $watchedOutdated = (bool)$dbr->selectField( |
1637 | | - array( 'watchlist', 'page', 'flaggedpages' ), |
1638 | | - '1', // existence |
1639 | | - array( 'wl_user' => $wgUser->getId(), // this user |
1640 | | - 'wl_namespace' => $namespaces, // reviewable |
1641 | | - 'wl_namespace = page_namespace', |
1642 | | - 'wl_title = page_title', |
1643 | | - 'fp_page_id = page_id', |
1644 | | - 'fp_pending_since IS NOT NULL', // edits pending |
1645 | | - ), __METHOD__ |
1646 | | - ); |
1647 | | - # Give a notice if pages on the users's wachlist have pending edits |
1648 | | - if ( $watchedOutdated ) { |
1649 | | - $css = 'plainlinks fr-watchlist-pending-notice'; |
1650 | | - $out->prependHTML( "<div id='mw-fr-watchlist-pending-notice' class='$css'>" . |
1651 | | - wfMsgExt( 'flaggedrevs-watched-pending', 'parseinline' ) . "</div>" ); |
1652 | | - } |
1653 | | - } |
1654 | | - return true; |
1655 | | - } |
1656 | | - |
1657 | 996 | public static function stableDumpQuery( array &$tables, array &$opts, array &$join ) { |
1658 | 997 | $namespaces = FlaggedRevs::getReviewNamespaces(); |
1659 | 998 | if ( $namespaces ) { |
— | — | @@ -1668,189 +1007,6 @@ |
1669 | 1008 | return false; // final |
1670 | 1009 | } |
1671 | 1010 | |
1672 | | - // Add selector of review "protection" options |
1673 | | - // Code stolen from Stabilization (which was stolen from ProtectionForm) |
1674 | | - public static function onProtectionForm( Article $article, &$output ) { |
1675 | | - global $wgUser, $wgOut, $wgRequest, $wgLang; |
1676 | | - if ( !$article->exists() ) { |
1677 | | - return true; // nothing to do |
1678 | | - } elseif ( !FlaggedRevs::inReviewNamespace( $article->getTitle() ) ) { |
1679 | | - return true; // not a reviewable page |
1680 | | - } |
1681 | | - $form = new PageStabilityProtectForm( $wgUser ); |
1682 | | - $form->setPage( $article->getTitle() ); |
1683 | | - # Can the user actually do anything? |
1684 | | - $isAllowed = $form->isAllowed(); |
1685 | | - $disabledAttrib = $isAllowed ? |
1686 | | - array() : array( 'disabled' => 'disabled' ); |
1687 | | - |
1688 | | - # Get the current config/expiry |
1689 | | - $config = FlaggedPageConfig::getStabilitySettings( $article->getTitle(), FR_MASTER ); |
1690 | | - $oldExpirySelect = ( $config['expiry'] == 'infinity' ) ? 'infinite' : 'existing'; |
1691 | | - |
1692 | | - # Load requested restriction level, default to current level... |
1693 | | - $restriction = $wgRequest->getVal( 'mwStabilityLevel', |
1694 | | - FlaggedPageConfig::getProtectionLevel( $config ) ); |
1695 | | - # Load the requested expiry time (dropdown) |
1696 | | - $expirySelect = $wgRequest->getVal( 'mwStabilizeExpirySelection', $oldExpirySelect ); |
1697 | | - # Load the requested expiry time (field) |
1698 | | - $expiryOther = $wgRequest->getVal( 'mwStabilizeExpiryOther', '' ); |
1699 | | - if ( $expiryOther != '' ) $expirySelect = 'othertime'; // mutual exclusion |
1700 | | - |
1701 | | - # Add an extra row to the protection fieldset tables. |
1702 | | - # Includes restriction dropdown and expiry dropdown & field. |
1703 | | - $output .= "<tr><td>"; |
1704 | | - $output .= Xml::openElement( 'fieldset' ); |
1705 | | - $legendMsg = wfMsgExt( 'flaggedrevs-protect-legend', 'parseinline' ); |
1706 | | - $output .= "<legend>{$legendMsg}</legend>"; |
1707 | | - # Add a "no restrictions" level |
1708 | | - $effectiveLevels = FlaggedRevs::getRestrictionLevels(); |
1709 | | - array_unshift( $effectiveLevels, "none" ); |
1710 | | - # Show all restriction levels in a <select>... |
1711 | | - $attribs = array( |
1712 | | - 'id' => 'mwStabilityLevel', |
1713 | | - 'name' => 'mwStabilityLevel', |
1714 | | - 'size' => count( $effectiveLevels ), |
1715 | | - ) + $disabledAttrib; |
1716 | | - $output .= Xml::openElement( 'select', $attribs ); |
1717 | | - foreach ( $effectiveLevels as $limit ) { |
1718 | | - if ( $limit == 'none' ) { |
1719 | | - $label = wfMsg( 'flaggedrevs-protect-none' ); |
1720 | | - } else { |
1721 | | - $label = wfMsg( 'flaggedrevs-protect-' . $limit ); |
1722 | | - } |
1723 | | - // Default to the key itself if no UI message |
1724 | | - if ( wfEmptyMsg( 'flaggedrevs-protect-' . $limit, $label ) ) { |
1725 | | - $label = 'flaggedrevs-protect-' . $limit; |
1726 | | - } |
1727 | | - $output .= Xml::option( $label, $limit, $limit == $restriction ); |
1728 | | - } |
1729 | | - $output .= Xml::closeElement( 'select' ); |
1730 | | - |
1731 | | - # Get expiry dropdown <select>... |
1732 | | - $scExpiryOptions = wfMsgForContent( 'protect-expiry-options' ); |
1733 | | - $showProtectOptions = ( $scExpiryOptions !== '-' && $isAllowed ); |
1734 | | - # Add the current expiry as an option |
1735 | | - $expiryFormOptions = ''; |
1736 | | - if ( $config['expiry'] != 'infinity' ) { |
1737 | | - $timestamp = $wgLang->timeanddate( $config['expiry'] ); |
1738 | | - $d = $wgLang->date( $config['expiry'] ); |
1739 | | - $t = $wgLang->time( $config['expiry'] ); |
1740 | | - $expiryFormOptions .= |
1741 | | - Xml::option( |
1742 | | - wfMsg( 'protect-existing-expiry', $timestamp, $d, $t ), |
1743 | | - 'existing', |
1744 | | - $expirySelect == 'existing' |
1745 | | - ) . "\n"; |
1746 | | - } |
1747 | | - $expiryFormOptions .= Xml::option( wfMsg( 'protect-othertime-op' ), 'othertime' ) . "\n"; |
1748 | | - # Add custom dropdown levels (from MediaWiki message) |
1749 | | - foreach ( explode( ',', $scExpiryOptions ) as $option ) { |
1750 | | - if ( strpos( $option, ":" ) === false ) { |
1751 | | - $show = $value = $option; |
1752 | | - } else { |
1753 | | - list( $show, $value ) = explode( ":", $option ); |
1754 | | - } |
1755 | | - $show = htmlspecialchars( $show ); |
1756 | | - $value = htmlspecialchars( $value ); |
1757 | | - $expiryFormOptions .= Xml::option( $show, $value, $expirySelect == $value ) . "\n"; |
1758 | | - } |
1759 | | - # Actually add expiry dropdown to form |
1760 | | - $output .= "<table>"; // expiry table start |
1761 | | - if ( $showProtectOptions && $isAllowed ) { |
1762 | | - $output .= " |
1763 | | - <tr> |
1764 | | - <td class='mw-label'>" . |
1765 | | - Xml::label( wfMsg( 'stabilization-expiry' ), |
1766 | | - 'mwStabilizeExpirySelection' ) . |
1767 | | - "</td> |
1768 | | - <td class='mw-input'>" . |
1769 | | - Xml::tags( 'select', |
1770 | | - array( |
1771 | | - 'id' => 'mwStabilizeExpirySelection', |
1772 | | - 'name' => 'mwStabilizeExpirySelection', |
1773 | | - 'onchange' => 'onFRChangeExpiryDropdown()', |
1774 | | - ) + $disabledAttrib, |
1775 | | - $expiryFormOptions ) . |
1776 | | - "</td> |
1777 | | - </tr>"; |
1778 | | - } |
1779 | | - # Add custom expiry field to form |
1780 | | - $attribs = array( 'id' => 'mwStabilizeExpiryOther', |
1781 | | - 'onkeyup' => 'onFRChangeExpiryField()' ) + $disabledAttrib; |
1782 | | - $output .= " |
1783 | | - <tr> |
1784 | | - <td class='mw-label'>" . |
1785 | | - Xml::label( wfMsg( 'stabilization-othertime' ), 'mwStabilizeExpiryOther' ) . |
1786 | | - '</td> |
1787 | | - <td class="mw-input">' . |
1788 | | - Xml::input( 'mwStabilizeExpiryOther', 50, $expiryOther, $attribs ) . |
1789 | | - '</td> |
1790 | | - </tr>'; |
1791 | | - $output .= "</table>"; // expiry table end |
1792 | | - # Close field set and table row |
1793 | | - $output .= Xml::closeElement( 'fieldset' ); |
1794 | | - $output .= "</td></tr>"; |
1795 | | - |
1796 | | - # Add some javascript for expiry dropdowns |
1797 | | - $wgOut->addScript( |
1798 | | - "<script type=\"text/javascript\"> |
1799 | | - function onFRChangeExpiryDropdown() { |
1800 | | - document.getElementById('mwStabilizeExpiryOther').value = ''; |
1801 | | - } |
1802 | | - function onFRChangeExpiryField() { |
1803 | | - document.getElementById('mwStabilizeExpirySelection').value = 'othertime'; |
1804 | | - } |
1805 | | - </script>" |
1806 | | - ); |
1807 | | - return true; |
1808 | | - } |
1809 | | - |
1810 | | - // Add stability log extract to protection form |
1811 | | - public static function insertStabilityLog( Article $article, OutputPage $out ) { |
1812 | | - if ( !$article->exists() ) { |
1813 | | - return true; // nothing to do |
1814 | | - } else if ( !FlaggedRevs::inReviewNamespace( $article->getTitle() ) ) { |
1815 | | - return true; // not a reviewable page |
1816 | | - } |
1817 | | - # Show relevant lines from the stability log: |
1818 | | - $out->addHTML( Xml::element( 'h2', null, LogPage::logName( 'stable' ) ) ); |
1819 | | - LogEventsList::showLogExtract( $out, 'stable', $article->getTitle()->getPrefixedText() ); |
1820 | | - return true; |
1821 | | - } |
1822 | | - |
1823 | | - // Update stability config from request |
1824 | | - public static function onProtectionSave( Article $article, &$errorMsg ) { |
1825 | | - global $wgUser, $wgRequest; |
1826 | | - if ( !$article->exists() ) { |
1827 | | - return true; // simple custom levels set for action=protect |
1828 | | - } elseif ( !FlaggedRevs::inReviewNamespace( $article->getTitle() ) ) { |
1829 | | - return true; // not a reviewable page |
1830 | | - } elseif ( wfReadOnly() || !$wgUser->isAllowed( 'stablesettings' ) ) { |
1831 | | - return true; // user cannot change anything |
1832 | | - } |
1833 | | - $form = new PageStabilityProtectForm( $wgUser ); |
1834 | | - $form->setPage( $article->getTitle() ); // target page |
1835 | | - $permission = $wgRequest->getVal( 'mwStabilityLevel' ); |
1836 | | - if ( $permission == "none" ) { |
1837 | | - $permission = ''; // 'none' => '' |
1838 | | - } |
1839 | | - $form->setAutoreview( $permission ); // protection level (autoreview restriction) |
1840 | | - $form->setWatchThis( null ); // protection form already has a watch check |
1841 | | - $form->setReasonExtra( $wgRequest->getText( 'mwProtect-reason' ) ); // manual |
1842 | | - $form->setReasonSelection( $wgRequest->getVal( 'wpProtectReasonSelection' ) ); // dropdown |
1843 | | - $form->setExpiryCustom( $wgRequest->getVal( 'mwStabilizeExpiryOther' ) ); // manual |
1844 | | - $form->setExpirySelection( $wgRequest->getVal( 'mwStabilizeExpirySelection' ) ); // dropdown |
1845 | | - $form->ready(); // params all set |
1846 | | - if ( $wgRequest->wasPosted() && $form->isAllowed() ) { |
1847 | | - $status = $form->submit(); |
1848 | | - if ( $status !== true ) { |
1849 | | - $errorMsg = wfMsg( $status ); // some error message |
1850 | | - } |
1851 | | - } |
1852 | | - return true; |
1853 | | - } |
1854 | | - |
1855 | 1011 | public static function getUnitTests( &$files ) { |
1856 | 1012 | $files[] = dirname( __FILE__ ) . '/maintenance/tests/FRInclusionManagerTest.php'; |
1857 | 1013 | $files[] = dirname( __FILE__ ) . '/maintenance/tests/FRUserCountersTest.php'; |
Index: trunk/extensions/FlaggedRevs/presentation/RevisionReviewFormGUI.php |
— | — | @@ -1,392 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * Main review form UI |
5 | | - * |
6 | | - * NOTE: use ONLY for diff-to-stable views and page version views |
7 | | - */ |
8 | | -class RevisionReviewFormGUI { |
9 | | - protected $user, $article, $rev; |
10 | | - protected $refRev = null; |
11 | | - protected $topNotice = ''; |
12 | | - protected $templateIDs = null, $imageSHA1Keys = null; |
13 | | - |
14 | | - /** |
15 | | - * Generates a brief review form for a page |
16 | | - * @param User $user |
17 | | - * @param FlaggedPage $article |
18 | | - * @param Revision $rev |
19 | | - */ |
20 | | - public function __construct( User $user, FlaggedPage $article, Revision $rev ) { |
21 | | - $this->user = $user; |
22 | | - $this->article = $article; |
23 | | - $this->rev = $rev; |
24 | | - } |
25 | | - |
26 | | - /* |
27 | | - * Call this only when the form is shown on a diff: |
28 | | - * (a) Shows the "reject" button |
29 | | - * (b) Default the rating tags to those of $this->rev (if flagged) |
30 | | - * @param Revision $refRev Old revision for diffs ($this->rev is the new rev) |
31 | | - */ |
32 | | - public function setDiffPriorRev( Revision $refRev ) { |
33 | | - $this->refRev = $refRev; |
34 | | - } |
35 | | - |
36 | | - /* |
37 | | - * Add on a notice inside the review box at the top |
38 | | - * @param string $topNotice Text to |
39 | | - */ |
40 | | - public function setTopNotice( $topNotice ) { |
41 | | - $this->topNotice = (string)$topNotice; |
42 | | - } |
43 | | - |
44 | | - /* |
45 | | - * Set the template/file version parameters corresponding to what the user is viewing |
46 | | - * @param string $topNotice Text to |
47 | | - */ |
48 | | - public function setIncludeVersions( array $templateIDs, array $imageSHA1Keys ) { |
49 | | - $this->templateIDs = $templateIDs; |
50 | | - $this->imageSHA1Keys = $imageSHA1Keys; |
51 | | - } |
52 | | - |
53 | | - /** |
54 | | - * Generates a brief review form for a page |
55 | | - * @return array (html string, error string or true) |
56 | | - */ |
57 | | - public function getHtml() { |
58 | | - global $wgOut, $wgLang, $wgParser, $wgEnableParserCache; |
59 | | - $revId = $this->rev->getId(); |
60 | | - if ( $this->rev->isDeleted( Revision::DELETED_TEXT ) ) { |
61 | | - return array( '', 'review_bad_oldid' ); # The revision must be valid and public |
62 | | - } |
63 | | - $article = $this->article; // convenience |
64 | | - |
65 | | - $srev = $article->getStableRev(); |
66 | | - # See if the version being displayed is flagged... |
67 | | - if ( $revId == $article->getStable() ) { |
68 | | - $frev = $srev; // avoid query |
69 | | - } else { |
70 | | - $frev = FlaggedRevision::newFromTitle( $article->getTitle(), $revId ); |
71 | | - } |
72 | | - $oldFlags = $frev |
73 | | - ? $frev->getTags() // existing tags |
74 | | - : FlaggedRevs::quickTags( FR_CHECKED ); // basic tags |
75 | | - $reviewTime = $frev ? $frev->getTimestamp() : ''; // last review of rev |
76 | | - |
77 | | - $priorRevId = $this->refRev ? $this->refRev->getId() : 0; |
78 | | - # If we are reviewing updates to a page, start off with the stable revision's |
79 | | - # flags. Otherwise, we just fill them in with the selected revision's flags. |
80 | | - # @TODO: do we want to carry over info for other diffs? |
81 | | - if ( $srev && $srev->getRevId() == $priorRevId ) { // diff-to-stable |
82 | | - $flags = $srev->getTags(); |
83 | | - # Check if user is allowed to renew the stable version. |
84 | | - # If not, then get the flags for the new revision itself. |
85 | | - if ( !FlaggedRevs::userCanSetFlags( $this->user, $oldFlags ) ) { |
86 | | - $flags = $oldFlags; |
87 | | - } |
88 | | - # Re-review button is need for template/file only review case |
89 | | - $reviewIncludes = ( $srev->getRevId() == $revId && !$article->stableVersionIsSynced() ); |
90 | | - } else { // views |
91 | | - $flags = $oldFlags; |
92 | | - $reviewIncludes = false; // re-review button not needed |
93 | | - } |
94 | | - |
95 | | - # Disable form for unprivileged users |
96 | | - $disabled = array(); |
97 | | - if ( !$article->getTitle()->quickUserCan( 'review' ) || |
98 | | - !$article->getTitle()->quickUserCan( 'edit' ) || |
99 | | - !FlaggedRevs::userCanSetFlags( $this->user, $flags ) ) |
100 | | - { |
101 | | - $disabled = array( 'disabled' => 'disabled' ); |
102 | | - } |
103 | | - |
104 | | - # Begin form... |
105 | | - $reviewTitle = SpecialPage::getTitleFor( 'RevisionReview' ); |
106 | | - $action = $reviewTitle->getLocalUrl( 'action=submit' ); |
107 | | - $params = array( 'method' => 'post', 'action' => $action, 'id' => 'mw-fr-reviewform' ); |
108 | | - $form = Xml::openElement( 'form', $params ); |
109 | | - $form .= Xml::openElement( 'fieldset', |
110 | | - array( 'class' => 'flaggedrevs_reviewform noprint' ) ); |
111 | | - # Add appropriate legend text |
112 | | - $legendMsg = $frev ? 'revreview-reflag' : 'revreview-flag'; |
113 | | - $form .= Xml::openElement( 'legend', array( 'id' => 'mw-fr-reviewformlegend' ) ); |
114 | | - $form .= "<strong>" . wfMsgHtml( $legendMsg ) . "</strong>"; |
115 | | - $form .= Xml::closeElement( 'legend' ) . "\n"; |
116 | | - # Show explanatory text |
117 | | - $form .= $this->topNotice; |
118 | | - # Show possible conflict warning msg... |
119 | | - if ( $priorRevId ) { |
120 | | - list( $u, $ts ) = |
121 | | - FRUserActivity::getUserReviewingDiff( $priorRevId, $this->rev->getId() ); |
122 | | - } else { |
123 | | - list( $u, $ts ) = FRUserActivity::getUserReviewingPage( $this->rev->getPage() ); |
124 | | - } |
125 | | - if ( $u !== null && $u != $this->user->getName() ) { |
126 | | - $msg = $priorRevId ? 'revreview-poss-conflict-c' : 'revreview-poss-conflict-p'; |
127 | | - $form .= '<p><span class="fr-under-review">' . |
128 | | - wfMsgExt( $msg, 'parseinline', |
129 | | - $u, $wgLang->date( $ts, true ), $wgLang->time( $ts, true ) ) . |
130 | | - '</span></p>'; |
131 | | - } |
132 | | - |
133 | | - if ( $disabled ) { |
134 | | - $form .= Xml::openElement( 'div', array( 'class' => 'fr-rating-controls-disabled', |
135 | | - 'id' => 'fr-rating-controls-disabled' ) ); |
136 | | - } else { |
137 | | - $form .= Xml::openElement( 'div', array( 'class' => 'fr-rating-controls', |
138 | | - 'id' => 'fr-rating-controls' ) ); |
139 | | - } |
140 | | - |
141 | | - # Add main checkboxes/selects |
142 | | - $form .= Xml::openElement( 'span', |
143 | | - array( 'id' => 'mw-fr-ratingselects', 'class' => 'fr-rating-options' ) ); |
144 | | - $form .= self::ratingInputs( $this->user, $flags, (bool)$disabled, (bool)$frev ); |
145 | | - $form .= Xml::closeElement( 'span' ); |
146 | | - |
147 | | - # Get template/file version info as needed |
148 | | - list( $templateIDs, $imageSHA1Keys ) = $this->getIncludeVersions(); |
149 | | - # Convert these into flat string params |
150 | | - list( $templateParams, $imageParams, $fileVersion ) = |
151 | | - RevisionReviewForm::getIncludeParams( $article, $templateIDs, $imageSHA1Keys ); |
152 | | - |
153 | | - $form .= Xml::openElement( 'span', array( 'style' => 'white-space: nowrap;' ) ); |
154 | | - # Hide comment input if needed |
155 | | - if ( !$disabled ) { |
156 | | - if ( count( FlaggedRevs::getTags() ) > 1 ) { |
157 | | - $form .= "<br />"; // Don't put too much on one line |
158 | | - } |
159 | | - $form .= "<span id='mw-fr-commentbox' style='clear:both'>" . |
160 | | - Xml::inputLabel( wfMsg( 'revreview-log' ), 'wpReason', 'wpReason', 40, '', |
161 | | - array( 'class' => 'fr-comment-box' ) ) . "   </span>"; |
162 | | - } |
163 | | - # Determine if there will be reject button |
164 | | - $rejectId = $this->rejectRefRevId(); |
165 | | - # Add the submit buttons |
166 | | - $form .= self::submitButtons( $rejectId, $frev, (bool)$disabled, $reviewIncludes ); |
167 | | - # Show stability log if there is anything interesting... |
168 | | - if ( $article->isPageLocked() ) { |
169 | | - $form .= ' ' . FlaggedRevsXML::logToggle( 'revreview-log-toggle-show' ); |
170 | | - } |
171 | | - $form .= Xml::closeElement( 'span' ); |
172 | | - # ..add the actual stability log body here |
173 | | - if ( $article->isPageLocked() ) { |
174 | | - $form .= FlaggedRevsXML::stabilityLogExcerpt( $article ); |
175 | | - } |
176 | | - $form .= Xml::closeElement( 'div' ) . "\n"; |
177 | | - |
178 | | - # Hidden params |
179 | | - $form .= Html::hidden( 'title', $reviewTitle->getPrefixedText() ) . "\n"; |
180 | | - $form .= Html::hidden( 'target', $article->getTitle()->getPrefixedDBKey() ) . "\n"; |
181 | | - $form .= Html::hidden( 'refid', $priorRevId ) . "\n"; |
182 | | - $form .= Html::hidden( 'oldid', $revId ) . "\n"; |
183 | | - $form .= Html::hidden( 'action', 'submit' ) . "\n"; |
184 | | - $form .= Html::hidden( 'wpEditToken', $this->user->editToken() ) . "\n"; |
185 | | - $form .= Html::hidden( 'changetime', $reviewTime, |
186 | | - array( 'id' => 'mw-fr-input-changetime' ) ); // id for JS |
187 | | - # Add review parameters |
188 | | - $form .= Html::hidden( 'templateParams', $templateParams ) . "\n"; |
189 | | - $form .= Html::hidden( 'imageParams', $imageParams ) . "\n"; |
190 | | - $form .= Html::hidden( 'fileVersion', $fileVersion ) . "\n"; |
191 | | - # Special token to discourage fiddling... |
192 | | - $checkCode = RevisionReviewForm::validationKey( |
193 | | - $templateParams, $imageParams, $fileVersion, $revId |
194 | | - ); |
195 | | - $form .= Html::hidden( 'validatedParams', $checkCode ) . "\n"; |
196 | | - |
197 | | - $form .= Xml::closeElement( 'fieldset' ); |
198 | | - $form .= Xml::closeElement( 'form' ); |
199 | | - |
200 | | - return array( $form, true /* ok */ ); |
201 | | - } |
202 | | - |
203 | | - /* |
204 | | - * If the REJECT button should show then get the ID of the last good rev |
205 | | - * @return int |
206 | | - */ |
207 | | - protected function rejectRefRevId() { |
208 | | - if ( $this->refRev ) { |
209 | | - $priorId = $this->refRev->getId(); |
210 | | - if ( $priorId == $this->article->getStable() && $priorId != $this->rev->getId() ) { |
211 | | - if ( $this->rev->getRawText() != $this->refRev->getRawText() ) { |
212 | | - return $priorId; // left rev must be stable and right one newer |
213 | | - } |
214 | | - } |
215 | | - } |
216 | | - return 0; |
217 | | - } |
218 | | - |
219 | | - /** |
220 | | - * @param User $user |
221 | | - * @param array $flags, selected flags |
222 | | - * @param bool $disabled, form disabled |
223 | | - * @param bool $reviewed, rev already reviewed |
224 | | - * @return string |
225 | | - * Generates a main tag inputs (checkboxes/radios/selects) for review form |
226 | | - */ |
227 | | - protected static function ratingInputs( $user, $flags, $disabled, $reviewed ) { |
228 | | - # Get all available tags for this page/user |
229 | | - list( $labels, $minLevels ) = self::ratingFormTags( $user, $flags ); |
230 | | - if ( $labels === false ) { |
231 | | - $disabled = true; // a tag is unsettable |
232 | | - } |
233 | | - # If there are no tags, make one checkbox to approve/unapprove |
234 | | - if ( FlaggedRevs::binaryFlagging() ) { |
235 | | - return ''; |
236 | | - } |
237 | | - $items = array(); |
238 | | - # Build rating form... |
239 | | - if ( $disabled ) { |
240 | | - // Display the value for each tag as text |
241 | | - foreach ( FlaggedRevs::getTags() as $quality ) { |
242 | | - $selected = isset( $flags[$quality] ) ? $flags[$quality] : 0; |
243 | | - $items[] = FlaggedRevs::getTagMsg( $quality ) . ": " . |
244 | | - FlaggedRevs::getTagValueMsg( $quality, $selected ); |
245 | | - } |
246 | | - } else { |
247 | | - $size = count( $labels, 1 ) - count( $labels ); |
248 | | - foreach ( $labels as $quality => $levels ) { |
249 | | - $item = ''; |
250 | | - $numLevels = count( $levels ); |
251 | | - $minLevel = $minLevels[$quality]; |
252 | | - # Determine the level selected by default |
253 | | - if ( !empty( $flags[$quality] ) && isset( $levels[$flags[$quality]] ) ) { |
254 | | - $selected = $flags[$quality]; // valid non-zero value |
255 | | - } else { |
256 | | - $selected = $minLevel; |
257 | | - } |
258 | | - # Show label as needed |
259 | | - if ( !FlaggedRevs::binaryFlagging() ) { |
260 | | - $item .= Xml::tags( 'label', array( 'for' => "wp$quality" ), |
261 | | - FlaggedRevs::getTagMsg( $quality ) ) . ":\n"; |
262 | | - } |
263 | | - # If the sum of qualities of all flags is above 6, use drop down boxes. |
264 | | - # 6 is an arbitrary value choosen according to screen space and usability. |
265 | | - if ( $size > 6 ) { |
266 | | - $attribs = array( 'name' => "wp$quality", 'id' => "wp$quality", |
267 | | - 'onchange' => "FlaggedRevsReview.updateRatingForm()" ); |
268 | | - $item .= Xml::openElement( 'select', $attribs ) . "\n"; |
269 | | - foreach ( $levels as $i => $name ) { |
270 | | - $optionClass = array( 'class' => "fr-rating-option-$i" ); |
271 | | - $item .= Xml::option( FlaggedRevs::getTagMsg( $name ), $i, |
272 | | - ( $i == $selected ), $optionClass ) . "\n"; |
273 | | - } |
274 | | - $item .= Xml::closeElement( 'select' ) . "\n"; |
275 | | - # If there are more than two levels, current user gets radio buttons |
276 | | - } elseif ( $numLevels > 2 ) { |
277 | | - foreach ( $levels as $i => $name ) { |
278 | | - $attribs = array( 'class' => "fr-rating-option-$i", |
279 | | - 'onchange' => "FlaggedRevsReview.updateRatingForm()" ); |
280 | | - $item .= Xml::radioLabel( FlaggedRevs::getTagMsg( $name ), "wp$quality", |
281 | | - $i, "wp$quality" . $i, ( $i == $selected ), $attribs ) . "\n"; |
282 | | - } |
283 | | - # Otherwise make checkboxes (two levels available for current user) |
284 | | - } else if ( $numLevels == 2 ) { |
285 | | - $i = $minLevel; |
286 | | - $attribs = array( 'class' => "fr-rating-option-$i", |
287 | | - 'onchange' => "FlaggedRevsReview.updateRatingForm()" ); |
288 | | - $attribs = $attribs + array( 'value' => $i ); |
289 | | - $item .= Xml::checkLabel( wfMsg( 'revreview-' . $levels[$i] ), |
290 | | - "wp$quality", "wp$quality", ( $selected == $i ), $attribs ) . "\n"; |
291 | | - } |
292 | | - $items[] = $item; |
293 | | - } |
294 | | - } |
295 | | - return implode( '   ', $items ); |
296 | | - } |
297 | | - |
298 | | - protected static function ratingFormTags( $user, $selected ) { |
299 | | - $labels = array(); |
300 | | - $minLevels = array(); |
301 | | - # Build up all levels available to user |
302 | | - foreach ( FlaggedRevs::getDimensions() as $tag => $levels ) { |
303 | | - if ( isset( $selected[$tag] ) && |
304 | | - !FlaggedRevs::userCanSetTag( $user, $tag, $selected[$tag] ) ) |
305 | | - { |
306 | | - return array( false, false ); // form will have to be disabled |
307 | | - } |
308 | | - $labels[$tag] = array(); // applicable tag levels |
309 | | - $minLevels[$tag] = false; // first non-zero level number |
310 | | - foreach ( $levels as $i => $msg ) { |
311 | | - # Some levels may be restricted or not applicable... |
312 | | - if ( !FlaggedRevs::userCanSetTag( $user, $tag, $i ) ) { |
313 | | - continue; // skip this level |
314 | | - } else if ( $i > 0 && !$minLevels[$tag] ) { |
315 | | - $minLevels[$tag] = $i; // first non-zero level number |
316 | | - } |
317 | | - $labels[$tag][$i] = $msg; // set label |
318 | | - } |
319 | | - if ( !$minLevels[$tag] ) { |
320 | | - return array( false, false ); // form will have to be disabled |
321 | | - } |
322 | | - } |
323 | | - return array( $labels, $minLevels ); |
324 | | - } |
325 | | - |
326 | | - /** |
327 | | - * Generates review form submit buttons |
328 | | - * @param int $rejectId left rev ID for "reject" on diffs |
329 | | - * @param FlaggedRevision $frev, the flagged revision, if any |
330 | | - * @param bool $disabled, is the form disabled? |
331 | | - * @param bool $reviewIncludes, force the review button to be usable? |
332 | | - * @return string |
333 | | - */ |
334 | | - protected static function submitButtons( |
335 | | - $rejectId, $frev, $disabled, $reviewIncludes = false |
336 | | - ) { |
337 | | - $disAttrib = array( 'disabled' => 'disabled' ); |
338 | | - # ACCEPT BUTTON: accept a revision |
339 | | - # We may want to re-review to change: |
340 | | - # (a) notes (b) tags (c) pending template/file changes |
341 | | - if ( FlaggedRevs::binaryFlagging() ) { // just the buttons |
342 | | - $applicable = ( !$frev || $reviewIncludes ); // no tags/notes |
343 | | - $needsChange = false; // no state change possible |
344 | | - } else { // buttons + ratings |
345 | | - $applicable = true; // tags might change |
346 | | - $needsChange = ( $frev && !$reviewIncludes ); |
347 | | - } |
348 | | - $s = Xml::submitButton( wfMsgHtml( 'revreview-submit-review' ), |
349 | | - array( |
350 | | - 'name' => 'wpApprove', |
351 | | - 'id' => 'mw-fr-submit-accept', |
352 | | - 'accesskey' => wfMsg( 'revreview-ak-review' ), |
353 | | - 'title' => wfMsg( 'revreview-tt-flag' ) . ' [' . |
354 | | - wfMsg( 'revreview-ak-review' ) . ']' |
355 | | - ) + ( ( $disabled || !$applicable ) ? $disAttrib : array() ) |
356 | | - ); |
357 | | - # REJECT BUTTON: revert from a pending revision to the stable |
358 | | - if ( $rejectId ) { |
359 | | - $s .= ' '; |
360 | | - $s .= Xml::submitButton( wfMsgHtml( 'revreview-submit-reject' ), |
361 | | - array( |
362 | | - 'name' => 'wpReject', |
363 | | - 'id' => 'mw-fr-submit-reject', |
364 | | - 'title' => wfMsg( 'revreview-tt-reject' ), |
365 | | - ) + ( $disabled ? $disAttrib : array() ) |
366 | | - ); |
367 | | - } |
368 | | - # UNACCEPT BUTTON: revoke a revisions acceptance |
369 | | - # Hide if revision is not flagged |
370 | | - $s .= ' '; |
371 | | - $s .= Xml::submitButton( wfMsgHtml( 'revreview-submit-unreview' ), |
372 | | - array( |
373 | | - 'name' => 'wpUnapprove', |
374 | | - 'id' => 'mw-fr-submit-unaccept', |
375 | | - 'title' => wfMsg( 'revreview-tt-unflag' ), |
376 | | - 'style' => $frev ? '' : 'display:none' |
377 | | - ) + ( $disabled ? $disAttrib : array() ) |
378 | | - ); |
379 | | - // Disable buttons unless state changes in some cases (non-JS compatible) |
380 | | - $s .= "<script type=\"text/javascript\"> |
381 | | - var jsReviewNeedsChange = " . (int)$needsChange . "</script>"; |
382 | | - return $s; |
383 | | - } |
384 | | - |
385 | | - protected function getIncludeVersions() { |
386 | | - # Do we need to get inclusion IDs from parser output? |
387 | | - if ( $this->templateIDs === null || $this->imageSHA1Keys === null ) { |
388 | | - list( $this->templateIDs, $this->imageSHA1Keys ) = |
389 | | - RevisionReviewForm::currentIncludeVersions( $this->article, $this->rev ); |
390 | | - } |
391 | | - return array( $this->templateIDs, $this->imageSHA1Keys ); |
392 | | - } |
393 | | -} |
Index: trunk/extensions/FlaggedRevs/presentation/RejectConfirmationFormGUI.php |
— | — | @@ -1,145 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * Reject confirmation review form UI |
5 | | - */ |
6 | | -class RejectConfirmationFormGUI { |
7 | | - protected $form, $oldRev, $newRev; |
8 | | - |
9 | | - public function __construct( RevisionReviewForm $form ) { |
10 | | - $this->form = $form; |
11 | | - $this->newRev = Revision::newFromTitle( $form->getPage(), $form->getOldId() ); |
12 | | - $this->oldRev = Revision::newFromTitle( $form->getPage(), $form->getRefId() ); |
13 | | - } |
14 | | - |
15 | | - /** |
16 | | - * Get the "are you sure you want to reject these changes?" form |
17 | | - * @return array (html string, error string or true) |
18 | | - */ |
19 | | - public function getHtml() { |
20 | | - global $wgLang, $wgContLang; |
21 | | - $status = $this->form->checkTarget(); |
22 | | - if ( $status !== true ) { |
23 | | - return array( '', $status ); // not a reviewable existing page |
24 | | - } |
25 | | - $oldRev = $this->oldRev; // convenience |
26 | | - $newRev = $this->newRev; // convenience |
27 | | - # Do not mess with archived/deleted revisions |
28 | | - if ( !$oldRev || $newRev->isDeleted( Revision::DELETED_TEXT ) ) { |
29 | | - return array( '', 'review_bad_oldid' ); |
30 | | - } elseif ( !$newRev || $newRev->isDeleted( Revision::DELETED_TEXT ) ) { |
31 | | - return array( '', 'review_bad_oldid' ); |
32 | | - } |
33 | | - |
34 | | - $form = '<div class="plainlinks">'; |
35 | | - |
36 | | - $dbr = wfGetDB( DB_SLAVE ); |
37 | | - $res = $dbr->select( 'revision', |
38 | | - Revision::selectFields(), |
39 | | - array( |
40 | | - 'rev_page' => $oldRev->getPage(), |
41 | | - 'rev_id > ' . $dbr->addQuotes( $oldRev->getId() ), |
42 | | - 'rev_id <= ' . $dbr->addQuotes( $newRev->getId() ) |
43 | | - ), |
44 | | - __METHOD__, |
45 | | - array( 'LIMIT' => 251 ) // sanity check |
46 | | - ); |
47 | | - if ( !$dbr->numRows( $res ) ) { |
48 | | - return array( '', 'review_bad_oldid' ); |
49 | | - } elseif ( $dbr->numRows( $res ) > 250 ) { |
50 | | - return array( '', 'review_reject_excessive' ); |
51 | | - } |
52 | | - |
53 | | - $rejectIds = $rejectAuthors = array(); |
54 | | - $contribs = SpecialPage::getTitleFor( 'Contributions' )->getPrefixedText(); |
55 | | - foreach ( $res as $row ) { |
56 | | - $rev = new Revision( $row ); |
57 | | - $rejectIds[] = $rev->getId(); |
58 | | - $rejectAuthors[] = $rev->isDeleted( Revision::DELETED_USER ) |
59 | | - ? wfMsg( 'rev-deleted-user' ) |
60 | | - : "[[{$contribs}/{$rev->getUserText()}|{$rev->getUserText()}]]"; |
61 | | - } |
62 | | - $rejectAuthors = array_values( array_unique( $rejectAuthors ) ); |
63 | | - |
64 | | - // List of revisions being undone... |
65 | | - $form .= wfMsgExt( 'revreview-reject-text-list', 'parseinline', |
66 | | - $wgLang->formatNum( count( $rejectIds ) ) ); |
67 | | - $form .= '<ul>'; |
68 | | - // FIXME: we need a generic revision list class...this is bullshit |
69 | | - $spRevDelete = SpecialPage::getPage( 'RevisionReview' ); |
70 | | - $spRevDelete->skin = $this->form->getUser()->getSkin(); // XXX |
71 | | - $list = new RevDel_RevisionList( $spRevDelete, $oldRev->getTitle(), $rejectIds ); |
72 | | - for ( $list->reset(); $list->current(); $list->next() ) { |
73 | | - $item = $list->current(); |
74 | | - if ( $item->canView() ) { |
75 | | - $form .= $item->getHTML(); |
76 | | - } |
77 | | - } |
78 | | - $form .= '</ul>'; |
79 | | - if ( $newRev->isCurrent() ) { |
80 | | - // Revision this will revert to (when reverting the top X revs)... |
81 | | - $form .= wfMsgExt( 'revreview-reject-text-revto', 'parseinline', |
82 | | - $oldRev->getTitle()->getPrefixedDBKey(), $oldRev->getId(), |
83 | | - $wgLang->timeanddate( $oldRev->getTimestamp(), true ) |
84 | | - ); |
85 | | - } |
86 | | - |
87 | | - $comment = $this->form->getComment(); // convenience |
88 | | - // Determine the default edit summary... |
89 | | - $oldRevAuthor = $oldRev->isDeleted( Revision::DELETED_USER ) |
90 | | - ? wfMsg( 'rev-deleted-user' ) |
91 | | - : $oldRev->getUserText(); |
92 | | - // NOTE: *-cur msg wording not safe for (unlikely) edit auto-merge |
93 | | - $msg = $newRev->isCurrent() |
94 | | - ? 'revreview-reject-summary-cur' |
95 | | - : 'revreview-reject-summary-old'; |
96 | | - $defaultSummary = wfMsgExt( $msg, array( 'parsemag', 'content' ), |
97 | | - $wgContLang->formatNum( count( $rejectIds ) ), |
98 | | - $wgContLang->listToText( $rejectAuthors ), |
99 | | - $oldRev->getId(), |
100 | | - $oldRevAuthor ); |
101 | | - // If the message is too big, then fallback to the shorter one |
102 | | - $colonSeparator = wfMsgForContent( 'colon-separator' ); |
103 | | - $maxLen = 255 - count( $colonSeparator ) - count( $comment ); |
104 | | - if ( strlen( $defaultSummary ) > $maxLen ) { |
105 | | - $msg = $newRev->isCurrent() |
106 | | - ? 'revreview-reject-summary-cur-short' |
107 | | - : 'revreview-reject-summary-old-short'; |
108 | | - $defaultSummary = wfMsgExt( $msg, array( 'parsemag', 'content' ), |
109 | | - $wgContLang->formatNum( count( $rejectIds ) ), |
110 | | - $oldRev->getId(), |
111 | | - $oldRevAuthor ); |
112 | | - } |
113 | | - // Append any review comment... |
114 | | - if ( $comment != '' ) { |
115 | | - if ( $defaultSummary != '' ) { |
116 | | - $defaultSummary .= $colonSeparator; |
117 | | - } |
118 | | - $defaultSummary .= $comment; |
119 | | - } |
120 | | - |
121 | | - $form .= '</div>'; |
122 | | - |
123 | | - $skin = $this->form->getUser()->getSkin(); |
124 | | - $reviewTitle = SpecialPage::getTitleFor( 'RevisionReview' ); |
125 | | - $form .= Xml::openElement( 'form', |
126 | | - array( 'method' => 'POST', 'action' => $reviewTitle->getFullUrl() ) ); |
127 | | - $form .= Html::hidden( 'action', 'reject' ); |
128 | | - $form .= Html::hidden( 'wpReject', 1 ); |
129 | | - $form .= Html::hidden( 'wpRejectConfirm', 1 ); |
130 | | - $form .= Html::hidden( 'oldid', $this->form->getOldId() ); |
131 | | - $form .= Html::hidden( 'refid', $this->form->getRefId() ); |
132 | | - $form .= Html::hidden( 'target', $oldRev->getTitle()->getPrefixedDBKey() ); |
133 | | - $form .= Html::hidden( 'wpEditToken', $this->form->getUser()->editToken() ); |
134 | | - $form .= Html::hidden( 'changetime', $newRev->getTimestamp() ); |
135 | | - $form .= Xml::inputLabel( wfMsg( 'revreview-reject-summary' ), 'wpReason', |
136 | | - 'wpReason', 120, $defaultSummary ) . "<br />"; |
137 | | - $form .= Html::input( 'wpSubmit', wfMsg( 'revreview-reject-confirm' ), 'submit' ); |
138 | | - $form .= ' '; |
139 | | - $form .= $skin->link( $this->form->getPage(), wfMsg( 'revreview-reject-cancel' ), |
140 | | - array( 'onClick' => 'history.back(); return false;' ), |
141 | | - array( 'oldid' => $this->form->getRefId(), 'diff' => $this->form->getOldId() ) ); |
142 | | - $form .= Xml::closeElement( 'form' ); |
143 | | - |
144 | | - return array( $form, true ); |
145 | | - } |
146 | | -} |
Index: trunk/extensions/FlaggedRevs/presentation/FlaggedRevsUI.hooks.php |
— | — | @@ -0,0 +1,848 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Class containing hooked functions for a FlaggedRevs environment |
| 5 | + */ |
| 6 | +class FlaggedRevsUIHooks { |
| 7 | + /* |
| 8 | + * Register FlaggedRevs special pages as needed. |
| 9 | + * Also sets $wgSpecialPages just to be consistent. |
| 10 | + */ |
| 11 | + public static function defineSpecialPages( array &$list ) { |
| 12 | + global $wgSpecialPages, $wgUseTagFilter; |
| 13 | + // Show special pages only if FlaggedRevs is enabled on some namespaces |
| 14 | + if ( !FlaggedRevs::getReviewNamespaces() ) { |
| 15 | + return true; |
| 16 | + } |
| 17 | + $list['RevisionReview'] = $wgSpecialPages['RevisionReview'] = 'RevisionReview'; |
| 18 | + $list['ReviewedVersions'] = $wgSpecialPages['ReviewedVersions'] = 'ReviewedVersions'; |
| 19 | + $list['PendingChanges'] = $wgSpecialPages['PendingChanges'] = 'PendingChanges'; |
| 20 | + // Show tag filtered pending edit page if there are tags |
| 21 | + if ( $wgUseTagFilter && ChangeTags::listDefinedTags() ) { |
| 22 | + $list['ProblemChanges'] = $wgSpecialPages['ProblemChanges'] = 'ProblemChanges'; |
| 23 | + } |
| 24 | + if ( !FlaggedRevs::useOnlyIfProtected() ) { |
| 25 | + $list['ReviewedPages'] = $wgSpecialPages['ReviewedPages'] = 'ReviewedPages'; |
| 26 | + $list['UnreviewedPages'] = $wgSpecialPages['UnreviewedPages'] = 'UnreviewedPages'; |
| 27 | + } |
| 28 | + $list['QualityOversight'] = $wgSpecialPages['QualityOversight'] = 'QualityOversight'; |
| 29 | + $list['ValidationStatistics'] = $wgSpecialPages['ValidationStatistics'] = 'ValidationStatistics'; |
| 30 | + // Protect levels define allowed stability settings |
| 31 | + if ( FlaggedRevs::useProtectionLevels() ) { |
| 32 | + $list['StablePages'] = $wgSpecialPages['StablePages'] = 'StablePages'; |
| 33 | + } else { |
| 34 | + $list['ConfiguredPages'] = $wgSpecialPages['ConfiguredPages'] = 'ConfiguredPages'; |
| 35 | + $list['Stabilization'] = $wgSpecialPages['Stabilization'] = 'Stabilization'; |
| 36 | + } |
| 37 | + return true; |
| 38 | + } |
| 39 | + |
| 40 | + /** |
| 41 | + * Add FlaggedRevs css/js. |
| 42 | + */ |
| 43 | + protected static function injectStyleAndJS() { |
| 44 | + global $wgOut, $wgUser; |
| 45 | + static $loadedModules = false; |
| 46 | + if ( $loadedModules ) { |
| 47 | + return true; // don't double-load |
| 48 | + } |
| 49 | + $loadedModules = true; |
| 50 | + $fa = FlaggedPageView::globalArticleInstance(); |
| 51 | + # Try to only add to relevant pages |
| 52 | + if ( !$fa || !$fa->isReviewable() ) { |
| 53 | + return true; |
| 54 | + } |
| 55 | + # Add main CSS & JS files |
| 56 | + $wgOut->addModuleStyles( 'ext.flaggedRevs.basic' ); |
| 57 | + $wgOut->addModules( 'ext.flaggedRevs.advanced' ); |
| 58 | + # Add review form JS for reviewers |
| 59 | + if ( $wgUser->isAllowed( 'review' ) ) { |
| 60 | + $wgOut->addModules( 'ext.flaggedRevs.review' ); |
| 61 | + } |
| 62 | + return true; |
| 63 | + } |
| 64 | + |
| 65 | + public static function injectGlobalJSVars( array &$globalVars ) { |
| 66 | + # Get the review tags on this wiki |
| 67 | + $rTags = FlaggedRevs::getJSTagParams(); |
| 68 | + $globalVars['wgFlaggedRevsParams'] = $rTags; |
| 69 | + # Get page-specific meta-data |
| 70 | + $fa = FlaggedPageView::globalArticleInstance(); |
| 71 | + # Try to only add to relevant pages |
| 72 | + if ( $fa && $fa->isReviewable() ) { |
| 73 | + $frev = $fa->getStableRev(); |
| 74 | + $stableId = $frev ? $frev->getRevId() : 0; |
| 75 | + } else { |
| 76 | + $stableId = null; |
| 77 | + } |
| 78 | + $globalVars['wgStableRevisionId'] = $stableId; |
| 79 | + $revisionContents = (object) array( |
| 80 | + 'error' => wfMsgHtml( 'revcontents-error' ), |
| 81 | + 'waiting' => wfMsgHtml( 'revcontents-waiting' ) |
| 82 | + ); |
| 83 | + $globalVars['wgRevContents'] = $revisionContents; |
| 84 | + return true; |
| 85 | + } |
| 86 | + |
| 87 | + /** |
| 88 | + * Add FlaggedRevs css for relevant special pages. |
| 89 | + * @param OutputPage $out |
| 90 | + */ |
| 91 | + protected static function injectStyleForSpecial( &$out ) { |
| 92 | + $title = $out->getTitle(); |
| 93 | + if ( $title->getNamespace() !== NS_SPECIAL ) { |
| 94 | + return true; |
| 95 | + } |
| 96 | + $spPages = array( 'UnreviewedPages', 'PendingChanges', 'ProblemChanges', |
| 97 | + 'Watchlist', 'Recentchanges', 'Contributions', 'Recentchangeslinked' ); |
| 98 | + foreach ( $spPages as $key ) { |
| 99 | + if ( $title->isSpecial( $key ) ) { |
| 100 | + $out->addModuleStyles( 'ext.flaggedRevs.basic' ); // CSS only |
| 101 | + break; |
| 102 | + } |
| 103 | + } |
| 104 | + return true; |
| 105 | + } |
| 106 | + |
| 107 | + /* |
| 108 | + * Add tag notice, CSS/JS, and set robots policy |
| 109 | + */ |
| 110 | + public static function onBeforePageDisplay( &$out, &$skin ) { |
| 111 | + if ( $out->isArticleRelated() ) { |
| 112 | + $view = FlaggedPageView::singleton(); |
| 113 | + $view->displayTag(); // show notice bar/icon in subtitle |
| 114 | + $view->setRobotPolicy(); // set indexing policy |
| 115 | + self::injectStyleAndJS(); // full CSS/JS |
| 116 | + } else { |
| 117 | + self::maybeAddBacklogNotice( $out ); // RC/Watchlist notice |
| 118 | + self::injectStyleForSpecial( $out ); // try special page CSS |
| 119 | + } |
| 120 | + return true; |
| 121 | + } |
| 122 | + |
| 123 | + public static function onMediaWikiPerformAction( |
| 124 | + $output, $article, Title $title, $user, $request |
| 125 | + ) { |
| 126 | + $fa = FlaggedPage::getTitleInstance( $title ); |
| 127 | + self::maybeMarkUnderReview( $fa, $request ); |
| 128 | + return true; |
| 129 | + } |
| 130 | + |
| 131 | + // Mark when an unreviewed page is being reviewed |
| 132 | + protected static function maybeMarkUnderReview( FlaggedPage $fa, WebRequest $request ) { |
| 133 | + global $wgUser; |
| 134 | + if ( !$request->getInt( 'reviewing' ) && !$request->getInt( 'rcid' ) ) { |
| 135 | + return true; // not implied by URL |
| 136 | + } |
| 137 | + # Set a key to note when someone is reviewing this. |
| 138 | + # NOTE: diff-to-stable views already handled elsewhere. |
| 139 | + if ( $fa->isReviewable() && !$fa->getStable() // not reviewed yet |
| 140 | + && $fa->getTitle()->userCan( 'review' ) ) |
| 141 | + { |
| 142 | + FRUserActivity::setUserReviewingPage( $wgUser, $fa->getID() ); |
| 143 | + } |
| 144 | + return true; |
| 145 | + } |
| 146 | + |
| 147 | + /** Add user preferences */ |
| 148 | + public static function onGetPreferences( $user, array &$preferences ) { |
| 149 | + // Box or bar UI |
| 150 | + $preferences['flaggedrevssimpleui'] = |
| 151 | + array( |
| 152 | + 'type' => 'radio', |
| 153 | + 'section' => 'flaggedrevs/flaggedrevs-ui', |
| 154 | + 'label-message' => 'flaggedrevs-pref-UI', |
| 155 | + 'options' => array( |
| 156 | + wfMsg( 'flaggedrevs-pref-UI-0' ) => 0, |
| 157 | + wfMsg( 'flaggedrevs-pref-UI-1' ) => 1, |
| 158 | + ), |
| 159 | + ); |
| 160 | + // Default versions... |
| 161 | + $preferences['flaggedrevsstable'] = |
| 162 | + array( |
| 163 | + 'type' => 'toggle', |
| 164 | + 'section' => 'flaggedrevs/flaggedrevs-ui', |
| 165 | + 'label-message' => 'flaggedrevs-prefs-stable', |
| 166 | + ); |
| 167 | + // Review-related rights... |
| 168 | + if ( $user->isAllowed( 'review' ) ) { |
| 169 | + // Watching reviewed pages |
| 170 | + $preferences['flaggedrevswatch'] = |
| 171 | + array( |
| 172 | + 'type' => 'toggle', |
| 173 | + 'section' => 'watchlist/advancedwatchlist', |
| 174 | + 'label-message' => 'flaggedrevs-prefs-watch', |
| 175 | + ); |
| 176 | + // Diff-to-stable on edit |
| 177 | + $preferences['flaggedrevseditdiffs'] = |
| 178 | + array( |
| 179 | + 'type' => 'toggle', |
| 180 | + 'section' => 'editing/advancedediting', |
| 181 | + 'label-message' => 'flaggedrevs-prefs-editdiffs', |
| 182 | + ); |
| 183 | + // Diff-to-stable on draft view |
| 184 | + $preferences['flaggedrevsviewdiffs'] = |
| 185 | + array( |
| 186 | + 'type' => 'toggle', |
| 187 | + 'section' => 'flaggedrevs/flaggedrevs-ui', |
| 188 | + 'label-message' => 'flaggedrevs-prefs-viewdiffs', |
| 189 | + ); |
| 190 | + } |
| 191 | + return true; |
| 192 | + } |
| 193 | + |
| 194 | + public static function logLineLinks( |
| 195 | + $type, $action, $title, $params, &$comment, &$rv, $ts |
| 196 | + ) { |
| 197 | + if ( !$title ) { |
| 198 | + return true; // sanity check |
| 199 | + } |
| 200 | + // Stability log |
| 201 | + if ( $type == 'stable' && FlaggedRevsLog::isStabilityAction( $action ) ) { |
| 202 | + $rv .= FlaggedRevsLogView::stabilityLogLinks( $title, $ts, $params ); |
| 203 | + // Review log |
| 204 | + } elseif ( $type == 'review' && FlaggedRevsLog::isReviewAction( $action ) ) { |
| 205 | + $rv .= FlaggedRevsLogView::reviewLogLinks( $action, $title, $params ); |
| 206 | + } |
| 207 | + return true; |
| 208 | + } |
| 209 | + |
| 210 | + public static function onImagePageFindFile( $imagePage, &$normalFile, &$displayFile ) { |
| 211 | + $view = FlaggedPageView::singleton(); |
| 212 | + $view->imagePageFindFile( $normalFile, $displayFile ); |
| 213 | + return true; |
| 214 | + } |
| 215 | + |
| 216 | + // MonoBook et al: $contentActions is all the tabs |
| 217 | + // Vector et al: $contentActions is all the action tabs...unused |
| 218 | + public static function onSkinTemplateTabs( Skin $skin, array &$contentActions ) { |
| 219 | + if ( $skin instanceof SkinVector ) { |
| 220 | + // *sigh*...skip, dealt with in setNavigation() |
| 221 | + return true; |
| 222 | + } |
| 223 | + // Note: $wgArticle sometimes not set here |
| 224 | + if ( FlaggedPageView::globalArticleInstance() != null ) { |
| 225 | + $view = FlaggedPageView::singleton(); |
| 226 | + $view->setActionTabs( $skin, $contentActions ); |
| 227 | + $view->setViewTabs( $skin, $contentActions, 'flat' ); |
| 228 | + } |
| 229 | + return true; |
| 230 | + } |
| 231 | + |
| 232 | + // Vector et al: $links is all the tabs (2 levels) |
| 233 | + public static function onSkinTemplateNavigation( Skin $skin, array &$links ) { |
| 234 | + // Note: $wgArticle sometimes not set here |
| 235 | + if ( FlaggedPageView::globalArticleInstance() != null ) { |
| 236 | + $view = FlaggedPageView::singleton(); |
| 237 | + $view->setActionTabs( $skin, $links['actions'] ); |
| 238 | + $view->setViewTabs( $skin, $links['views'], 'nav' ); |
| 239 | + } |
| 240 | + return true; |
| 241 | + } |
| 242 | + |
| 243 | + public static function onArticleViewHeader( &$article, &$outputDone, &$useParserCache ) { |
| 244 | + $view = FlaggedPageView::singleton(); |
| 245 | + $view->addStableLink( $outputDone, $useParserCache ); |
| 246 | + $view->setPageContent( $outputDone, $useParserCache ); |
| 247 | + return true; |
| 248 | + } |
| 249 | + |
| 250 | + public static function overrideRedirect( |
| 251 | + Title $title, WebRequest $request, &$ignoreRedirect, &$target, Article &$article |
| 252 | + ) { |
| 253 | + global $wgMemc, $wgParserCacheExpireTime; |
| 254 | + $fa = FlaggedPage::getTitleInstance( $title ); // on $wgTitle |
| 255 | + if ( !$fa->isReviewable() ) { |
| 256 | + return true; // nothing to do |
| 257 | + } |
| 258 | + # Viewing an old reviewed version... |
| 259 | + if ( $request->getVal( 'stableid' ) ) { |
| 260 | + $ignoreRedirect = true; // don't redirect (same as ?oldid=x) |
| 261 | + return true; |
| 262 | + } |
| 263 | + $srev = $fa->getStableRev(); |
| 264 | + $view = FlaggedPageView::singleton(); |
| 265 | + # Check if we are viewing an unsynced stable version... |
| 266 | + if ( $srev && $view->showingStable() && $srev->getRevId() != $article->getLatest() ) { |
| 267 | + # Check the stable redirect properties from the cache... |
| 268 | + $key = wfMemcKey( 'flaggedrevs', 'overrideRedirect', $article->getId() ); |
| 269 | + $tuple = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $article ); |
| 270 | + if ( is_array( $tuple ) ) { // cache hit |
| 271 | + list( $ignoreRedirect, $target ) = $tuple; |
| 272 | + } else { // cache miss; fetch the stable rev text... |
| 273 | + $text = $srev->getRevText(); |
| 274 | + $redirect = $fa->getRedirectURL( Title::newFromRedirectRecurse( $text ) ); |
| 275 | + if ( $redirect ) { |
| 276 | + $target = $redirect; // use stable redirect |
| 277 | + } else { |
| 278 | + $ignoreRedirect = true; // make MW skip redirection |
| 279 | + } |
| 280 | + $data = FlaggedRevs::makeMemcObj( array( $ignoreRedirect, $target ) ); |
| 281 | + $wgMemc->set( $key, $data, $wgParserCacheExpireTime ); // cache results |
| 282 | + } |
| 283 | + $clearEnvironment = (bool)$target; |
| 284 | + # Check if the we are viewing a draft or synced stable version... |
| 285 | + } else { |
| 286 | + # In both cases, we can just let MW use followRedirect() |
| 287 | + # on the draft as normal, avoiding any page text hits. |
| 288 | + $clearEnvironment = $article->isRedirect(); |
| 289 | + } |
| 290 | + # Environment (e.g. $wgTitle) will change in MediaWiki::initializeArticle |
| 291 | + if ( $clearEnvironment ) $view->clear(); |
| 292 | + return true; |
| 293 | + } |
| 294 | + |
| 295 | + public static function addToEditView( &$editPage ) { |
| 296 | + $view = FlaggedPageView::singleton(); |
| 297 | + $view->addToEditView( $editPage ); |
| 298 | + return true; |
| 299 | + } |
| 300 | + |
| 301 | + public static function onBeforeEditButtons( &$editPage, &$buttons ) { |
| 302 | + $view = FlaggedPageView::singleton(); |
| 303 | + $view->changeSaveButton( $editPage, $buttons ); |
| 304 | + return true; |
| 305 | + } |
| 306 | + |
| 307 | + public static function onNoSuchSection( &$editPage, &$s ) { |
| 308 | + $view = FlaggedPageView::singleton(); |
| 309 | + $view->addToNoSuchSection( $editPage, $s ); |
| 310 | + return true; |
| 311 | + } |
| 312 | + |
| 313 | + public static function addToHistView( &$article ) { |
| 314 | + $view = FlaggedPageView::singleton(); |
| 315 | + $view->addToHistView(); |
| 316 | + return true; |
| 317 | + } |
| 318 | + |
| 319 | + public static function onCategoryPageView( &$category ) { |
| 320 | + $view = FlaggedPageView::singleton(); |
| 321 | + $view->addToCategoryView(); |
| 322 | + return true; |
| 323 | + } |
| 324 | + |
| 325 | + public static function onSkinAfterContent( &$data ) { |
| 326 | + global $wgOut; |
| 327 | + if ( $wgOut->isArticleRelated() |
| 328 | + && FlaggedPageView::globalArticleInstance() != null ) |
| 329 | + { |
| 330 | + $view = FlaggedPageView::singleton(); |
| 331 | + $view->addReviewNotes( $data ); |
| 332 | + $view->addReviewForm( $data ); |
| 333 | + $view->addVisibilityLink( $data ); |
| 334 | + } |
| 335 | + return true; |
| 336 | + } |
| 337 | + |
| 338 | + public static function addToHistQuery( HistoryPager $pager, array &$queryInfo ) { |
| 339 | + $flaggedArticle = FlaggedPage::getArticleInstance( $pager->getArticle() ); |
| 340 | + # Non-content pages cannot be validated. Stable version must exist. |
| 341 | + if ( $flaggedArticle->isReviewable() && $flaggedArticle->getStableRev() ) { |
| 342 | + # Highlight flaggedrevs |
| 343 | + $queryInfo['tables'][] = 'flaggedrevs'; |
| 344 | + $queryInfo['fields'][] = 'fr_quality'; |
| 345 | + $queryInfo['fields'][] = 'fr_user'; |
| 346 | + $queryInfo['fields'][] = 'fr_flags'; |
| 347 | + $queryInfo['join_conds']['flaggedrevs'] = array( 'LEFT JOIN', |
| 348 | + "fr_page_id = rev_page AND fr_rev_id = rev_id" ); |
| 349 | + # Find reviewer name. Sanity check that no extensions added a `user` query. |
| 350 | + if ( !in_array( 'user', $queryInfo['tables'] ) ) { |
| 351 | + $queryInfo['tables'][] = 'user'; |
| 352 | + $queryInfo['fields'][] = 'user_name AS reviewer'; |
| 353 | + $queryInfo['join_conds']['user'] = array( 'LEFT JOIN', "user_id = fr_user" ); |
| 354 | + } |
| 355 | + } |
| 356 | + return true; |
| 357 | + } |
| 358 | + |
| 359 | + public static function addToFileHistQuery( |
| 360 | + File $file, array &$tables, array &$fields, &$conds, array &$opts, array &$join_conds |
| 361 | + ) { |
| 362 | + if ( !$file->isLocal() ) { |
| 363 | + return true; // local files only |
| 364 | + } |
| 365 | + $flaggedArticle = FlaggedPage::getTitleInstance( $file->getTitle() ); |
| 366 | + # Non-content pages cannot be validated. Stable version must exist. |
| 367 | + if ( $flaggedArticle->isReviewable() && $flaggedArticle->getStableRev() ) { |
| 368 | + $tables[] = 'flaggedrevs'; |
| 369 | + $fields[] = 'MAX(fr_quality) AS fr_quality'; |
| 370 | + # Avoid duplicate rows due to multiple revs with the same sha-1 key |
| 371 | + |
| 372 | + # This is a stupid hack to get all the field names in our GROUP BY |
| 373 | + # clause. Postgres yells at you for not including all of the selected |
| 374 | + # columns, so grab the full list, unset the two we actually want to |
| 375 | + # order by, then append the rest of them to our two. It would be |
| 376 | + # REALLY nice if we handled this automagically in makeSelectOptions() |
| 377 | + # or something *sigh* |
| 378 | + $groupBy = OldLocalFile::selectFields(); |
| 379 | + unset( $groupBy[ array_search( 'oi_name', $groupBy ) ] ); |
| 380 | + unset( $groupBy[ array_search( 'oi_timestamp', $groupBy ) ] ); |
| 381 | + $opts['GROUP BY'] = 'oi_name,oi_timestamp,' . implode( ',', $groupBy ); |
| 382 | + |
| 383 | + $join_conds['flaggedrevs'] = array( 'LEFT JOIN', |
| 384 | + 'oi_sha1 = fr_img_sha1 AND oi_timestamp = fr_img_timestamp' ); |
| 385 | + } |
| 386 | + return true; |
| 387 | + } |
| 388 | + |
| 389 | + public static function addToContribsQuery( $pager, array &$queryInfo ) { |
| 390 | + # Highlight flaggedrevs |
| 391 | + $queryInfo['tables'][] = 'flaggedrevs'; |
| 392 | + $queryInfo['fields'][] = 'fr_quality'; |
| 393 | + $queryInfo['join_conds']['flaggedrevs'] = array( 'LEFT JOIN', |
| 394 | + "fr_page_id = rev_page AND fr_rev_id = rev_id" ); |
| 395 | + # Highlight unchecked content |
| 396 | + $queryInfo['tables'][] = 'flaggedpages'; |
| 397 | + $queryInfo['fields'][] = 'fp_stable'; |
| 398 | + $queryInfo['fields'][] = 'fp_pending_since'; |
| 399 | + $queryInfo['join_conds']['flaggedpages'] = array( 'LEFT JOIN', "fp_page_id = rev_page" ); |
| 400 | + return true; |
| 401 | + } |
| 402 | + |
| 403 | + public static function addToRCQuery( |
| 404 | + &$conds, array &$tables, array &$join_conds, $opts, &$query_opts, &$select |
| 405 | + ) { |
| 406 | + $tables[] = 'flaggedpages'; |
| 407 | + $join_conds['flaggedpages'] = array( 'LEFT JOIN', 'fp_page_id = rc_cur_id' ); |
| 408 | + if ( is_array( $select ) ) { // RCL |
| 409 | + $select[] = 'fp_stable'; |
| 410 | + $select[] = 'fp_pending_since'; |
| 411 | + } |
| 412 | + return true; |
| 413 | + } |
| 414 | + |
| 415 | + public static function addToWatchlistQuery( |
| 416 | + &$conds, array &$tables, array &$join_conds, array &$fields |
| 417 | + ) { |
| 418 | + global $wgUser; |
| 419 | + if ( $wgUser->isAllowed( 'review' ) ) { |
| 420 | + $fields[] = 'fp_stable'; |
| 421 | + $fields[] = 'fp_pending_since'; |
| 422 | + $tables[] = 'flaggedpages'; |
| 423 | + $join_conds['flaggedpages'] = array( 'LEFT JOIN', 'fp_page_id = rc_cur_id' ); |
| 424 | + } |
| 425 | + return true; |
| 426 | + } |
| 427 | + |
| 428 | + public static function addToHistLine( HistoryPager $history, $row, &$s, &$liClasses ) { |
| 429 | + $fa = FlaggedPage::getArticleInstance( $history->getArticle() ); |
| 430 | + if ( !$fa->isReviewable() ) { |
| 431 | + return true; // nothing to do here |
| 432 | + } |
| 433 | + # Fetch and process cache the stable revision |
| 434 | + if ( !isset( $history->fr_stableRevId ) ) { |
| 435 | + $srev = $fa->getStableRev(); |
| 436 | + $history->fr_stableRevId = $srev ? $srev->getRevId() : null; |
| 437 | + $history->fr_stableRevUTS = $srev ? // bug 15515 |
| 438 | + wfTimestamp( TS_UNIX, $srev->getRevTimestamp() ) : null; |
| 439 | + $history->fr_pendingRevs = false; |
| 440 | + } |
| 441 | + if ( !$history->fr_stableRevId ) { |
| 442 | + return true; // nothing to do here |
| 443 | + } |
| 444 | + $title = $history->getArticle()->getTitle(); |
| 445 | + $revId = (int)$row->rev_id; |
| 446 | + // Pending revision: highlight and add diff link |
| 447 | + $link = $class = ''; |
| 448 | + if ( wfTimestamp( TS_UNIX, $row->rev_timestamp ) > $history->fr_stableRevUTS ) { |
| 449 | + $class = 'flaggedrevs-pending'; |
| 450 | + $link = wfMsgExt( 'revreview-hist-pending-difflink', 'parseinline', |
| 451 | + $title->getPrefixedText(), $history->fr_stableRevId, $revId ); |
| 452 | + $link = '<span class="plainlinks">' . $link . '</span>'; |
| 453 | + $history->fr_pendingRevs = true; // pending rev shown above stable |
| 454 | + // Reviewed revision: highlight and add link |
| 455 | + } elseif ( isset( $row->fr_quality ) ) { |
| 456 | + if ( !( $row->rev_deleted & Revision::DELETED_TEXT ) ) { |
| 457 | + # Add link to stable version of *this* rev, if any |
| 458 | + list( $link, $class ) = self::markHistoryRow( $title, $row ); |
| 459 | + # Space out and demark the stable revision |
| 460 | + if ( $revId == $history->fr_stableRevId && $history->fr_pendingRevs ) { |
| 461 | + $liClasses[] = 'fr-hist-stable-margin'; |
| 462 | + } |
| 463 | + } |
| 464 | + } |
| 465 | + # Style the row as needed |
| 466 | + if ( $class ) $s = "<span class='$class'>$s</span>"; |
| 467 | + # Add stable old version link |
| 468 | + if ( $link ) $s .= " <small>$link</small>"; |
| 469 | + return true; |
| 470 | + } |
| 471 | + |
| 472 | + /** |
| 473 | + * Make stable version link and return the css |
| 474 | + * @param Title $title |
| 475 | + * @param Row $row, from history page |
| 476 | + * @return array (string,string) |
| 477 | + */ |
| 478 | + protected static function markHistoryRow( Title $title, $row ) { |
| 479 | + if ( !isset( $row->fr_quality ) ) { |
| 480 | + return array( "", "" ); // not reviewed |
| 481 | + } |
| 482 | + $liCss = FlaggedRevsXML::getQualityColor( $row->fr_quality ); |
| 483 | + $flags = explode( ',', $row->fr_flags ); |
| 484 | + if ( in_array( 'auto', $flags ) ) { |
| 485 | + $msg = ( $row->fr_quality >= 1 ) |
| 486 | + ? 'revreview-hist-quality-auto' |
| 487 | + : 'revreview-hist-basic-auto'; |
| 488 | + $css = ( $row->fr_quality >= 1 ) |
| 489 | + ? 'fr-hist-quality-auto' |
| 490 | + : 'fr-hist-basic-auto'; |
| 491 | + } else { |
| 492 | + $msg = ( $row->fr_quality >= 1 ) |
| 493 | + ? 'revreview-hist-quality-user' |
| 494 | + : 'revreview-hist-basic-user'; |
| 495 | + $css = ( $row->fr_quality >= 1 ) |
| 496 | + ? 'fr-hist-quality-user' |
| 497 | + : 'fr-hist-basic-user'; |
| 498 | + } |
| 499 | + $name = isset( $row->reviewer ) ? |
| 500 | + $row->reviewer : User::whoIs( $row->fr_user ); |
| 501 | + $link = wfMsgExt( $msg, 'parseinline', $title->getPrefixedDBkey(), $row->rev_id, $name ); |
| 502 | + $link = "<span class='$css plainlinks'>[$link]</span>"; |
| 503 | + return array( $link, $liCss ); |
| 504 | + } |
| 505 | + |
| 506 | + public static function addToFileHistLine( $hist, File $file, &$s, &$rowClass ) { |
| 507 | + if ( !$file->isVisible() ) { |
| 508 | + return true; // Don't bother showing notice for deleted revs |
| 509 | + } |
| 510 | + # Quality level for old versions selected all at once. |
| 511 | + # Commons queries cannot be done all at once... |
| 512 | + if ( !$file->isOld() || !$file->isLocal() ) { |
| 513 | + $dbr = wfGetDB( DB_SLAVE ); |
| 514 | + $quality = $dbr->selectField( 'flaggedrevs', 'fr_quality', |
| 515 | + array( 'fr_img_sha1' => $file->getSha1(), |
| 516 | + 'fr_img_timestamp' => $dbr->timestamp( $file->getTimestamp() ) ), |
| 517 | + __METHOD__ |
| 518 | + ); |
| 519 | + } else { |
| 520 | + $quality = is_null( $file->quality ) ? false : $file->quality; |
| 521 | + } |
| 522 | + # If reviewed, class the line |
| 523 | + if ( $quality !== false ) { |
| 524 | + $rowClass = FlaggedRevsXML::getQualityColor( $quality ); |
| 525 | + } |
| 526 | + return true; |
| 527 | + } |
| 528 | + |
| 529 | + public static function addToContribsLine( $contribs, &$ret, $row ) { |
| 530 | + $namespaces = FlaggedRevs::getReviewNamespaces(); |
| 531 | + if ( !in_array( $row->page_namespace, $namespaces ) ) { |
| 532 | + // do nothing |
| 533 | + } elseif ( isset( $row->fr_quality ) ) { |
| 534 | + $ret = '<span class="' . FlaggedRevsXML::getQualityColor( $row->fr_quality ) . |
| 535 | + '">' . $ret . '</span>'; |
| 536 | + } elseif ( isset( $row->fp_pending_since ) |
| 537 | + && $row->rev_timestamp >= $row->fp_pending_since ) // bug 15515 |
| 538 | + { |
| 539 | + $ret = '<span class="flaggedrevs-pending">' . $ret . '</span>'; |
| 540 | + } elseif ( !isset( $row->fp_stable ) ) { |
| 541 | + $ret = '<span class="flaggedrevs-unreviewed">' . $ret . '</span>'; |
| 542 | + } |
| 543 | + return true; |
| 544 | + } |
| 545 | + |
| 546 | + public static function addToChangeListLine( &$list, &$articlelink, &$s, RecentChange &$rc ) { |
| 547 | + global $wgUser; |
| 548 | + $title = $rc->getTitle(); // convenience |
| 549 | + if ( !FlaggedRevs::inReviewNamespace( $title ) |
| 550 | + || empty( $rc->mAttribs['rc_this_oldid'] ) // rev, not log |
| 551 | + || !array_key_exists( 'fp_stable', $rc->mAttribs ) ) |
| 552 | + { |
| 553 | + return true; // confirm that page is in reviewable namespace |
| 554 | + } |
| 555 | + $rlink = ''; |
| 556 | + // page is not reviewed |
| 557 | + if ( $rc->mAttribs['fp_stable'] == null ) { |
| 558 | + // Is this a config were pages start off reviewable? |
| 559 | + // Hide notice from non-reviewers due to vandalism concerns (bug 24002). |
| 560 | + if ( !FlaggedRevs::useOnlyIfProtected() && $wgUser->isAllowed( 'review' ) ) { |
| 561 | + $rlink = wfMsgHtml( 'revreview-unreviewedpage' ); |
| 562 | + $css = 'flaggedrevs-unreviewed'; |
| 563 | + } |
| 564 | + // page is reviewed and has pending edits (use timestamps; bug 15515) |
| 565 | + } elseif ( isset( $rc->mAttribs['fp_pending_since'] ) && |
| 566 | + $rc->mAttribs['rc_timestamp'] >= $rc->mAttribs['fp_pending_since'] ) |
| 567 | + { |
| 568 | + $rlink = $list->skin->link( |
| 569 | + $title, |
| 570 | + wfMsgHtml( 'revreview-reviewlink' ), |
| 571 | + array( 'title' => wfMsg( 'revreview-reviewlink-title' ) ), |
| 572 | + array( 'oldid' => $rc->mAttribs['fp_stable'], 'diff' => 'cur' ) |
| 573 | + ); |
| 574 | + $css = 'flaggedrevs-pending'; |
| 575 | + } |
| 576 | + if ( $rlink != '' ) { |
| 577 | + $articlelink .= " <span class=\"mw-fr-reviewlink $css\">[$rlink]</span>"; |
| 578 | + } |
| 579 | + return true; |
| 580 | + } |
| 581 | + |
| 582 | + public static function injectPostEditURLParams( $article, &$sectionAnchor, &$extraQuery ) { |
| 583 | + // Note: $wgArticle sometimes not set here |
| 584 | + if ( FlaggedPageView::globalArticleInstance() != null ) { |
| 585 | + $view = FlaggedPageView::singleton(); |
| 586 | + $view->injectPostEditURLParams( $sectionAnchor, $extraQuery ); |
| 587 | + } |
| 588 | + return true; |
| 589 | + } |
| 590 | + |
| 591 | + // diff=review param (bug 16923) |
| 592 | + public static function checkDiffUrl( $titleObj, &$mOldid, &$mNewid, $old, $new ) { |
| 593 | + if ( $new === 'review' && isset( $titleObj ) ) { |
| 594 | + $frev = FlaggedRevision::newFromStable( $titleObj ); |
| 595 | + if ( $frev ) { |
| 596 | + $mOldid = $frev->getRevId(); // stable |
| 597 | + $mNewid = 0; // cur |
| 598 | + } |
| 599 | + } |
| 600 | + return true; |
| 601 | + } |
| 602 | + |
| 603 | + public static function onDiffViewHeader( $diff, $oldRev, $newRev ) { |
| 604 | + self::injectStyleAndJS(); |
| 605 | + $view = FlaggedPageView::singleton(); |
| 606 | + $view->setViewFlags( $diff, $oldRev, $newRev ); |
| 607 | + $view->addToDiffView( $diff, $oldRev, $newRev ); |
| 608 | + return true; |
| 609 | + } |
| 610 | + |
| 611 | + /* |
| 612 | + * If an article is reviewable, get custom article contents from the FlaggedPageView |
| 613 | + */ |
| 614 | + public static function onArticleContentOnDiff( $diffEngine, $out ) { |
| 615 | + $fa = FlaggedPage::getTitleInstance( $out->getTitle() ); |
| 616 | + if ( !$fa->isReviewable() ) { |
| 617 | + return true; // nothing to do |
| 618 | + } |
| 619 | + $view = FlaggedPageView::singleton(); |
| 620 | + $view->addCustomContentHtml( $out, $diffEngine->getNewid() ); |
| 621 | + return false; |
| 622 | + } |
| 623 | + |
| 624 | + public static function addRevisionIDField( $editPage, $out ) { |
| 625 | + $view = FlaggedPageView::singleton(); |
| 626 | + $view->addRevisionIDField( $editPage, $out ); |
| 627 | + return true; |
| 628 | + } |
| 629 | + |
| 630 | + public static function addReviewCheck( $editPage, &$checkboxes, &$tabindex ) { |
| 631 | + $view = FlaggedPageView::singleton(); |
| 632 | + $view->addReviewCheck( $editPage, $checkboxes, $tabindex ); |
| 633 | + return true; |
| 634 | + } |
| 635 | + |
| 636 | + protected static function maybeAddBacklogNotice( OutputPage &$out ) { |
| 637 | + global $wgUser; |
| 638 | + if ( !$wgUser->isAllowed( 'review' ) ) { |
| 639 | + return true; // not relevant to user |
| 640 | + } |
| 641 | + $namespaces = FlaggedRevs::getReviewNamespaces(); |
| 642 | + $watchlist = SpecialPage::getTitleFor( 'Watchlist' ); |
| 643 | + # Add notice to watchlist about pending changes... |
| 644 | + if ( $out->getTitle()->equals( $watchlist ) && $namespaces ) { |
| 645 | + $dbr = wfGetDB( DB_SLAVE, 'watchlist' ); // consistency with watchlist |
| 646 | + $watchedOutdated = (bool)$dbr->selectField( |
| 647 | + array( 'watchlist', 'page', 'flaggedpages' ), |
| 648 | + '1', // existence |
| 649 | + array( 'wl_user' => $wgUser->getId(), // this user |
| 650 | + 'wl_namespace' => $namespaces, // reviewable |
| 651 | + 'wl_namespace = page_namespace', |
| 652 | + 'wl_title = page_title', |
| 653 | + 'fp_page_id = page_id', |
| 654 | + 'fp_pending_since IS NOT NULL', // edits pending |
| 655 | + ), __METHOD__ |
| 656 | + ); |
| 657 | + # Give a notice if pages on the users's wachlist have pending edits |
| 658 | + if ( $watchedOutdated ) { |
| 659 | + $css = 'plainlinks fr-watchlist-pending-notice'; |
| 660 | + $out->prependHTML( "<div id='mw-fr-watchlist-pending-notice' class='$css'>" . |
| 661 | + wfMsgExt( 'flaggedrevs-watched-pending', 'parseinline' ) . "</div>" ); |
| 662 | + } |
| 663 | + } |
| 664 | + return true; |
| 665 | + } |
| 666 | + |
| 667 | + // Add selector of review "protection" options |
| 668 | + // Code stolen from Stabilization (which was stolen from ProtectionForm) |
| 669 | + public static function onProtectionForm( Article $article, &$output ) { |
| 670 | + global $wgUser, $wgOut, $wgRequest, $wgLang; |
| 671 | + if ( !$article->exists() ) { |
| 672 | + return true; // nothing to do |
| 673 | + } elseif ( !FlaggedRevs::inReviewNamespace( $article->getTitle() ) ) { |
| 674 | + return true; // not a reviewable page |
| 675 | + } |
| 676 | + $form = new PageStabilityProtectForm( $wgUser ); |
| 677 | + $form->setPage( $article->getTitle() ); |
| 678 | + # Can the user actually do anything? |
| 679 | + $isAllowed = $form->isAllowed(); |
| 680 | + $disabledAttrib = $isAllowed ? |
| 681 | + array() : array( 'disabled' => 'disabled' ); |
| 682 | + |
| 683 | + # Get the current config/expiry |
| 684 | + $config = FlaggedPageConfig::getStabilitySettings( $article->getTitle(), FR_MASTER ); |
| 685 | + $oldExpirySelect = ( $config['expiry'] == 'infinity' ) ? 'infinite' : 'existing'; |
| 686 | + |
| 687 | + # Load requested restriction level, default to current level... |
| 688 | + $restriction = $wgRequest->getVal( 'mwStabilityLevel', |
| 689 | + FlaggedPageConfig::getProtectionLevel( $config ) ); |
| 690 | + # Load the requested expiry time (dropdown) |
| 691 | + $expirySelect = $wgRequest->getVal( 'mwStabilizeExpirySelection', $oldExpirySelect ); |
| 692 | + # Load the requested expiry time (field) |
| 693 | + $expiryOther = $wgRequest->getVal( 'mwStabilizeExpiryOther', '' ); |
| 694 | + if ( $expiryOther != '' ) $expirySelect = 'othertime'; // mutual exclusion |
| 695 | + |
| 696 | + # Add an extra row to the protection fieldset tables. |
| 697 | + # Includes restriction dropdown and expiry dropdown & field. |
| 698 | + $output .= "<tr><td>"; |
| 699 | + $output .= Xml::openElement( 'fieldset' ); |
| 700 | + $legendMsg = wfMsgExt( 'flaggedrevs-protect-legend', 'parseinline' ); |
| 701 | + $output .= "<legend>{$legendMsg}</legend>"; |
| 702 | + # Add a "no restrictions" level |
| 703 | + $effectiveLevels = FlaggedRevs::getRestrictionLevels(); |
| 704 | + array_unshift( $effectiveLevels, "none" ); |
| 705 | + # Show all restriction levels in a <select>... |
| 706 | + $attribs = array( |
| 707 | + 'id' => 'mwStabilityLevel', |
| 708 | + 'name' => 'mwStabilityLevel', |
| 709 | + 'size' => count( $effectiveLevels ), |
| 710 | + ) + $disabledAttrib; |
| 711 | + $output .= Xml::openElement( 'select', $attribs ); |
| 712 | + foreach ( $effectiveLevels as $limit ) { |
| 713 | + if ( $limit == 'none' ) { |
| 714 | + $label = wfMsg( 'flaggedrevs-protect-none' ); |
| 715 | + } else { |
| 716 | + $label = wfMsg( 'flaggedrevs-protect-' . $limit ); |
| 717 | + } |
| 718 | + // Default to the key itself if no UI message |
| 719 | + if ( wfEmptyMsg( 'flaggedrevs-protect-' . $limit, $label ) ) { |
| 720 | + $label = 'flaggedrevs-protect-' . $limit; |
| 721 | + } |
| 722 | + $output .= Xml::option( $label, $limit, $limit == $restriction ); |
| 723 | + } |
| 724 | + $output .= Xml::closeElement( 'select' ); |
| 725 | + |
| 726 | + # Get expiry dropdown <select>... |
| 727 | + $scExpiryOptions = wfMsgForContent( 'protect-expiry-options' ); |
| 728 | + $showProtectOptions = ( $scExpiryOptions !== '-' && $isAllowed ); |
| 729 | + # Add the current expiry as an option |
| 730 | + $expiryFormOptions = ''; |
| 731 | + if ( $config['expiry'] != 'infinity' ) { |
| 732 | + $timestamp = $wgLang->timeanddate( $config['expiry'] ); |
| 733 | + $d = $wgLang->date( $config['expiry'] ); |
| 734 | + $t = $wgLang->time( $config['expiry'] ); |
| 735 | + $expiryFormOptions .= |
| 736 | + Xml::option( |
| 737 | + wfMsg( 'protect-existing-expiry', $timestamp, $d, $t ), |
| 738 | + 'existing', |
| 739 | + $expirySelect == 'existing' |
| 740 | + ) . "\n"; |
| 741 | + } |
| 742 | + $expiryFormOptions .= Xml::option( wfMsg( 'protect-othertime-op' ), 'othertime' ) . "\n"; |
| 743 | + # Add custom dropdown levels (from MediaWiki message) |
| 744 | + foreach ( explode( ',', $scExpiryOptions ) as $option ) { |
| 745 | + if ( strpos( $option, ":" ) === false ) { |
| 746 | + $show = $value = $option; |
| 747 | + } else { |
| 748 | + list( $show, $value ) = explode( ":", $option ); |
| 749 | + } |
| 750 | + $show = htmlspecialchars( $show ); |
| 751 | + $value = htmlspecialchars( $value ); |
| 752 | + $expiryFormOptions .= Xml::option( $show, $value, $expirySelect == $value ) . "\n"; |
| 753 | + } |
| 754 | + # Actually add expiry dropdown to form |
| 755 | + $output .= "<table>"; // expiry table start |
| 756 | + if ( $showProtectOptions && $isAllowed ) { |
| 757 | + $output .= " |
| 758 | + <tr> |
| 759 | + <td class='mw-label'>" . |
| 760 | + Xml::label( wfMsg( 'stabilization-expiry' ), |
| 761 | + 'mwStabilizeExpirySelection' ) . |
| 762 | + "</td> |
| 763 | + <td class='mw-input'>" . |
| 764 | + Xml::tags( 'select', |
| 765 | + array( |
| 766 | + 'id' => 'mwStabilizeExpirySelection', |
| 767 | + 'name' => 'mwStabilizeExpirySelection', |
| 768 | + 'onchange' => 'onFRChangeExpiryDropdown()', |
| 769 | + ) + $disabledAttrib, |
| 770 | + $expiryFormOptions ) . |
| 771 | + "</td> |
| 772 | + </tr>"; |
| 773 | + } |
| 774 | + # Add custom expiry field to form |
| 775 | + $attribs = array( 'id' => 'mwStabilizeExpiryOther', |
| 776 | + 'onkeyup' => 'onFRChangeExpiryField()' ) + $disabledAttrib; |
| 777 | + $output .= " |
| 778 | + <tr> |
| 779 | + <td class='mw-label'>" . |
| 780 | + Xml::label( wfMsg( 'stabilization-othertime' ), 'mwStabilizeExpiryOther' ) . |
| 781 | + '</td> |
| 782 | + <td class="mw-input">' . |
| 783 | + Xml::input( 'mwStabilizeExpiryOther', 50, $expiryOther, $attribs ) . |
| 784 | + '</td> |
| 785 | + </tr>'; |
| 786 | + $output .= "</table>"; // expiry table end |
| 787 | + # Close field set and table row |
| 788 | + $output .= Xml::closeElement( 'fieldset' ); |
| 789 | + $output .= "</td></tr>"; |
| 790 | + |
| 791 | + # Add some javascript for expiry dropdowns |
| 792 | + $wgOut->addScript( |
| 793 | + "<script type=\"text/javascript\"> |
| 794 | + function onFRChangeExpiryDropdown() { |
| 795 | + document.getElementById('mwStabilizeExpiryOther').value = ''; |
| 796 | + } |
| 797 | + function onFRChangeExpiryField() { |
| 798 | + document.getElementById('mwStabilizeExpirySelection').value = 'othertime'; |
| 799 | + } |
| 800 | + </script>" |
| 801 | + ); |
| 802 | + return true; |
| 803 | + } |
| 804 | + |
| 805 | + // Add stability log extract to protection form |
| 806 | + public static function insertStabilityLog( Article $article, OutputPage $out ) { |
| 807 | + if ( !$article->exists() ) { |
| 808 | + return true; // nothing to do |
| 809 | + } else if ( !FlaggedRevs::inReviewNamespace( $article->getTitle() ) ) { |
| 810 | + return true; // not a reviewable page |
| 811 | + } |
| 812 | + # Show relevant lines from the stability log: |
| 813 | + $out->addHTML( Xml::element( 'h2', null, LogPage::logName( 'stable' ) ) ); |
| 814 | + LogEventsList::showLogExtract( $out, 'stable', $article->getTitle()->getPrefixedText() ); |
| 815 | + return true; |
| 816 | + } |
| 817 | + |
| 818 | + // Update stability config from request |
| 819 | + public static function onProtectionSave( Article $article, &$errorMsg ) { |
| 820 | + global $wgUser, $wgRequest; |
| 821 | + if ( !$article->exists() ) { |
| 822 | + return true; // simple custom levels set for action=protect |
| 823 | + } elseif ( !FlaggedRevs::inReviewNamespace( $article->getTitle() ) ) { |
| 824 | + return true; // not a reviewable page |
| 825 | + } elseif ( wfReadOnly() || !$wgUser->isAllowed( 'stablesettings' ) ) { |
| 826 | + return true; // user cannot change anything |
| 827 | + } |
| 828 | + $form = new PageStabilityProtectForm( $wgUser ); |
| 829 | + $form->setPage( $article->getTitle() ); // target page |
| 830 | + $permission = $wgRequest->getVal( 'mwStabilityLevel' ); |
| 831 | + if ( $permission == "none" ) { |
| 832 | + $permission = ''; // 'none' => '' |
| 833 | + } |
| 834 | + $form->setAutoreview( $permission ); // protection level (autoreview restriction) |
| 835 | + $form->setWatchThis( null ); // protection form already has a watch check |
| 836 | + $form->setReasonExtra( $wgRequest->getText( 'mwProtect-reason' ) ); // manual |
| 837 | + $form->setReasonSelection( $wgRequest->getVal( 'wpProtectReasonSelection' ) ); // dropdown |
| 838 | + $form->setExpiryCustom( $wgRequest->getVal( 'mwStabilizeExpiryOther' ) ); // manual |
| 839 | + $form->setExpirySelection( $wgRequest->getVal( 'mwStabilizeExpirySelection' ) ); // dropdown |
| 840 | + $form->ready(); // params all set |
| 841 | + if ( $wgRequest->wasPosted() && $form->isAllowed() ) { |
| 842 | + $status = $form->submit(); |
| 843 | + if ( $status !== true ) { |
| 844 | + $errorMsg = wfMsg( $status ); // some error message |
| 845 | + } |
| 846 | + } |
| 847 | + return true; |
| 848 | + } |
| 849 | +} |
Property changes on: trunk/extensions/FlaggedRevs/presentation/FlaggedRevsUI.hooks.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 850 | + native |
Index: trunk/extensions/FlaggedRevs/presentation/specialpages/actions/RevisionReview_body.php |
— | — | @@ -84,7 +84,7 @@ |
85 | 85 | } |
86 | 86 | // Use confirmation screen for reject... |
87 | 87 | if ( $form->getAction() == 'reject' && !$wgRequest->getBool( 'wpRejectConfirm' ) ) { |
88 | | - $rejectForm = new RejectConfirmationFormGUI( $form ); |
| 88 | + $rejectForm = new RejectConfirmationFormUI( $form ); |
89 | 89 | list( $html, $status ) = $rejectForm->getHtml(); |
90 | 90 | // Success... |
91 | 91 | if ( $status === true ) { |
Index: trunk/extensions/FlaggedRevs/presentation/FlaggedPageView.php |
— | — | @@ -1070,7 +1070,7 @@ |
1071 | 1071 | } |
1072 | 1072 | # Build the review form as needed |
1073 | 1073 | if ( $rev && ( !$this->diffRevs || $this->isReviewableDiff ) ) { |
1074 | | - $form = new RevisionReviewFormGUI( $wgUser, $this->article, $rev ); |
| 1074 | + $form = new RevisionReviewFormUI( $wgUser, $this->article, $rev ); |
1075 | 1075 | # Default tags and existence of "reject" button depend on context |
1076 | 1076 | if ( $this->diffRevs ) { |
1077 | 1077 | $form->setDiffPriorRev( $this->diffRevs['old'] ); |
Index: trunk/extensions/FlaggedRevs/presentation/RevisionReviewFormUI.php |
— | — | @@ -0,0 +1,392 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Main review form UI |
| 5 | + * |
| 6 | + * NOTE: use ONLY for diff-to-stable views and page version views |
| 7 | + */ |
| 8 | +class RevisionReviewFormUI { |
| 9 | + protected $user, $article, $rev; |
| 10 | + protected $refRev = null; |
| 11 | + protected $topNotice = ''; |
| 12 | + protected $templateIDs = null, $imageSHA1Keys = null; |
| 13 | + |
| 14 | + /** |
| 15 | + * Generates a brief review form for a page |
| 16 | + * @param User $user |
| 17 | + * @param FlaggedPage $article |
| 18 | + * @param Revision $rev |
| 19 | + */ |
| 20 | + public function __construct( User $user, FlaggedPage $article, Revision $rev ) { |
| 21 | + $this->user = $user; |
| 22 | + $this->article = $article; |
| 23 | + $this->rev = $rev; |
| 24 | + } |
| 25 | + |
| 26 | + /* |
| 27 | + * Call this only when the form is shown on a diff: |
| 28 | + * (a) Shows the "reject" button |
| 29 | + * (b) Default the rating tags to those of $this->rev (if flagged) |
| 30 | + * @param Revision $refRev Old revision for diffs ($this->rev is the new rev) |
| 31 | + */ |
| 32 | + public function setDiffPriorRev( Revision $refRev ) { |
| 33 | + $this->refRev = $refRev; |
| 34 | + } |
| 35 | + |
| 36 | + /* |
| 37 | + * Add on a notice inside the review box at the top |
| 38 | + * @param string $topNotice Text to |
| 39 | + */ |
| 40 | + public function setTopNotice( $topNotice ) { |
| 41 | + $this->topNotice = (string)$topNotice; |
| 42 | + } |
| 43 | + |
| 44 | + /* |
| 45 | + * Set the template/file version parameters corresponding to what the user is viewing |
| 46 | + * @param string $topNotice Text to |
| 47 | + */ |
| 48 | + public function setIncludeVersions( array $templateIDs, array $imageSHA1Keys ) { |
| 49 | + $this->templateIDs = $templateIDs; |
| 50 | + $this->imageSHA1Keys = $imageSHA1Keys; |
| 51 | + } |
| 52 | + |
| 53 | + /** |
| 54 | + * Generates a brief review form for a page |
| 55 | + * @return array (html string, error string or true) |
| 56 | + */ |
| 57 | + public function getHtml() { |
| 58 | + global $wgOut, $wgLang, $wgParser, $wgEnableParserCache; |
| 59 | + $revId = $this->rev->getId(); |
| 60 | + if ( $this->rev->isDeleted( Revision::DELETED_TEXT ) ) { |
| 61 | + return array( '', 'review_bad_oldid' ); # The revision must be valid and public |
| 62 | + } |
| 63 | + $article = $this->article; // convenience |
| 64 | + |
| 65 | + $srev = $article->getStableRev(); |
| 66 | + # See if the version being displayed is flagged... |
| 67 | + if ( $revId == $article->getStable() ) { |
| 68 | + $frev = $srev; // avoid query |
| 69 | + } else { |
| 70 | + $frev = FlaggedRevision::newFromTitle( $article->getTitle(), $revId ); |
| 71 | + } |
| 72 | + $oldFlags = $frev |
| 73 | + ? $frev->getTags() // existing tags |
| 74 | + : FlaggedRevs::quickTags( FR_CHECKED ); // basic tags |
| 75 | + $reviewTime = $frev ? $frev->getTimestamp() : ''; // last review of rev |
| 76 | + |
| 77 | + $priorRevId = $this->refRev ? $this->refRev->getId() : 0; |
| 78 | + # If we are reviewing updates to a page, start off with the stable revision's |
| 79 | + # flags. Otherwise, we just fill them in with the selected revision's flags. |
| 80 | + # @TODO: do we want to carry over info for other diffs? |
| 81 | + if ( $srev && $srev->getRevId() == $priorRevId ) { // diff-to-stable |
| 82 | + $flags = $srev->getTags(); |
| 83 | + # Check if user is allowed to renew the stable version. |
| 84 | + # If not, then get the flags for the new revision itself. |
| 85 | + if ( !FlaggedRevs::userCanSetFlags( $this->user, $oldFlags ) ) { |
| 86 | + $flags = $oldFlags; |
| 87 | + } |
| 88 | + # Re-review button is need for template/file only review case |
| 89 | + $reviewIncludes = ( $srev->getRevId() == $revId && !$article->stableVersionIsSynced() ); |
| 90 | + } else { // views |
| 91 | + $flags = $oldFlags; |
| 92 | + $reviewIncludes = false; // re-review button not needed |
| 93 | + } |
| 94 | + |
| 95 | + # Disable form for unprivileged users |
| 96 | + $disabled = array(); |
| 97 | + if ( !$article->getTitle()->quickUserCan( 'review' ) || |
| 98 | + !$article->getTitle()->quickUserCan( 'edit' ) || |
| 99 | + !FlaggedRevs::userCanSetFlags( $this->user, $flags ) ) |
| 100 | + { |
| 101 | + $disabled = array( 'disabled' => 'disabled' ); |
| 102 | + } |
| 103 | + |
| 104 | + # Begin form... |
| 105 | + $reviewTitle = SpecialPage::getTitleFor( 'RevisionReview' ); |
| 106 | + $action = $reviewTitle->getLocalUrl( 'action=submit' ); |
| 107 | + $params = array( 'method' => 'post', 'action' => $action, 'id' => 'mw-fr-reviewform' ); |
| 108 | + $form = Xml::openElement( 'form', $params ); |
| 109 | + $form .= Xml::openElement( 'fieldset', |
| 110 | + array( 'class' => 'flaggedrevs_reviewform noprint' ) ); |
| 111 | + # Add appropriate legend text |
| 112 | + $legendMsg = $frev ? 'revreview-reflag' : 'revreview-flag'; |
| 113 | + $form .= Xml::openElement( 'legend', array( 'id' => 'mw-fr-reviewformlegend' ) ); |
| 114 | + $form .= "<strong>" . wfMsgHtml( $legendMsg ) . "</strong>"; |
| 115 | + $form .= Xml::closeElement( 'legend' ) . "\n"; |
| 116 | + # Show explanatory text |
| 117 | + $form .= $this->topNotice; |
| 118 | + # Show possible conflict warning msg... |
| 119 | + if ( $priorRevId ) { |
| 120 | + list( $u, $ts ) = |
| 121 | + FRUserActivity::getUserReviewingDiff( $priorRevId, $this->rev->getId() ); |
| 122 | + } else { |
| 123 | + list( $u, $ts ) = FRUserActivity::getUserReviewingPage( $this->rev->getPage() ); |
| 124 | + } |
| 125 | + if ( $u !== null && $u != $this->user->getName() ) { |
| 126 | + $msg = $priorRevId ? 'revreview-poss-conflict-c' : 'revreview-poss-conflict-p'; |
| 127 | + $form .= '<p><span class="fr-under-review">' . |
| 128 | + wfMsgExt( $msg, 'parseinline', |
| 129 | + $u, $wgLang->date( $ts, true ), $wgLang->time( $ts, true ) ) . |
| 130 | + '</span></p>'; |
| 131 | + } |
| 132 | + |
| 133 | + if ( $disabled ) { |
| 134 | + $form .= Xml::openElement( 'div', array( 'class' => 'fr-rating-controls-disabled', |
| 135 | + 'id' => 'fr-rating-controls-disabled' ) ); |
| 136 | + } else { |
| 137 | + $form .= Xml::openElement( 'div', array( 'class' => 'fr-rating-controls', |
| 138 | + 'id' => 'fr-rating-controls' ) ); |
| 139 | + } |
| 140 | + |
| 141 | + # Add main checkboxes/selects |
| 142 | + $form .= Xml::openElement( 'span', |
| 143 | + array( 'id' => 'mw-fr-ratingselects', 'class' => 'fr-rating-options' ) ); |
| 144 | + $form .= self::ratingInputs( $this->user, $flags, (bool)$disabled, (bool)$frev ); |
| 145 | + $form .= Xml::closeElement( 'span' ); |
| 146 | + |
| 147 | + # Get template/file version info as needed |
| 148 | + list( $templateIDs, $imageSHA1Keys ) = $this->getIncludeVersions(); |
| 149 | + # Convert these into flat string params |
| 150 | + list( $templateParams, $imageParams, $fileVersion ) = |
| 151 | + RevisionReviewForm::getIncludeParams( $article, $templateIDs, $imageSHA1Keys ); |
| 152 | + |
| 153 | + $form .= Xml::openElement( 'span', array( 'style' => 'white-space: nowrap;' ) ); |
| 154 | + # Hide comment input if needed |
| 155 | + if ( !$disabled ) { |
| 156 | + if ( count( FlaggedRevs::getTags() ) > 1 ) { |
| 157 | + $form .= "<br />"; // Don't put too much on one line |
| 158 | + } |
| 159 | + $form .= "<span id='mw-fr-commentbox' style='clear:both'>" . |
| 160 | + Xml::inputLabel( wfMsg( 'revreview-log' ), 'wpReason', 'wpReason', 40, '', |
| 161 | + array( 'class' => 'fr-comment-box' ) ) . "   </span>"; |
| 162 | + } |
| 163 | + # Determine if there will be reject button |
| 164 | + $rejectId = $this->rejectRefRevId(); |
| 165 | + # Add the submit buttons |
| 166 | + $form .= self::submitButtons( $rejectId, $frev, (bool)$disabled, $reviewIncludes ); |
| 167 | + # Show stability log if there is anything interesting... |
| 168 | + if ( $article->isPageLocked() ) { |
| 169 | + $form .= ' ' . FlaggedRevsXML::logToggle( 'revreview-log-toggle-show' ); |
| 170 | + } |
| 171 | + $form .= Xml::closeElement( 'span' ); |
| 172 | + # ..add the actual stability log body here |
| 173 | + if ( $article->isPageLocked() ) { |
| 174 | + $form .= FlaggedRevsXML::stabilityLogExcerpt( $article ); |
| 175 | + } |
| 176 | + $form .= Xml::closeElement( 'div' ) . "\n"; |
| 177 | + |
| 178 | + # Hidden params |
| 179 | + $form .= Html::hidden( 'title', $reviewTitle->getPrefixedText() ) . "\n"; |
| 180 | + $form .= Html::hidden( 'target', $article->getTitle()->getPrefixedDBKey() ) . "\n"; |
| 181 | + $form .= Html::hidden( 'refid', $priorRevId ) . "\n"; |
| 182 | + $form .= Html::hidden( 'oldid', $revId ) . "\n"; |
| 183 | + $form .= Html::hidden( 'action', 'submit' ) . "\n"; |
| 184 | + $form .= Html::hidden( 'wpEditToken', $this->user->editToken() ) . "\n"; |
| 185 | + $form .= Html::hidden( 'changetime', $reviewTime, |
| 186 | + array( 'id' => 'mw-fr-input-changetime' ) ); // id for JS |
| 187 | + # Add review parameters |
| 188 | + $form .= Html::hidden( 'templateParams', $templateParams ) . "\n"; |
| 189 | + $form .= Html::hidden( 'imageParams', $imageParams ) . "\n"; |
| 190 | + $form .= Html::hidden( 'fileVersion', $fileVersion ) . "\n"; |
| 191 | + # Special token to discourage fiddling... |
| 192 | + $checkCode = RevisionReviewForm::validationKey( |
| 193 | + $templateParams, $imageParams, $fileVersion, $revId |
| 194 | + ); |
| 195 | + $form .= Html::hidden( 'validatedParams', $checkCode ) . "\n"; |
| 196 | + |
| 197 | + $form .= Xml::closeElement( 'fieldset' ); |
| 198 | + $form .= Xml::closeElement( 'form' ); |
| 199 | + |
| 200 | + return array( $form, true /* ok */ ); |
| 201 | + } |
| 202 | + |
| 203 | + /* |
| 204 | + * If the REJECT button should show then get the ID of the last good rev |
| 205 | + * @return int |
| 206 | + */ |
| 207 | + protected function rejectRefRevId() { |
| 208 | + if ( $this->refRev ) { |
| 209 | + $priorId = $this->refRev->getId(); |
| 210 | + if ( $priorId == $this->article->getStable() && $priorId != $this->rev->getId() ) { |
| 211 | + if ( $this->rev->getRawText() != $this->refRev->getRawText() ) { |
| 212 | + return $priorId; // left rev must be stable and right one newer |
| 213 | + } |
| 214 | + } |
| 215 | + } |
| 216 | + return 0; |
| 217 | + } |
| 218 | + |
| 219 | + /** |
| 220 | + * @param User $user |
| 221 | + * @param array $flags, selected flags |
| 222 | + * @param bool $disabled, form disabled |
| 223 | + * @param bool $reviewed, rev already reviewed |
| 224 | + * @return string |
| 225 | + * Generates a main tag inputs (checkboxes/radios/selects) for review form |
| 226 | + */ |
| 227 | + protected static function ratingInputs( $user, $flags, $disabled, $reviewed ) { |
| 228 | + # Get all available tags for this page/user |
| 229 | + list( $labels, $minLevels ) = self::ratingFormTags( $user, $flags ); |
| 230 | + if ( $labels === false ) { |
| 231 | + $disabled = true; // a tag is unsettable |
| 232 | + } |
| 233 | + # If there are no tags, make one checkbox to approve/unapprove |
| 234 | + if ( FlaggedRevs::binaryFlagging() ) { |
| 235 | + return ''; |
| 236 | + } |
| 237 | + $items = array(); |
| 238 | + # Build rating form... |
| 239 | + if ( $disabled ) { |
| 240 | + // Display the value for each tag as text |
| 241 | + foreach ( FlaggedRevs::getTags() as $quality ) { |
| 242 | + $selected = isset( $flags[$quality] ) ? $flags[$quality] : 0; |
| 243 | + $items[] = FlaggedRevs::getTagMsg( $quality ) . ": " . |
| 244 | + FlaggedRevs::getTagValueMsg( $quality, $selected ); |
| 245 | + } |
| 246 | + } else { |
| 247 | + $size = count( $labels, 1 ) - count( $labels ); |
| 248 | + foreach ( $labels as $quality => $levels ) { |
| 249 | + $item = ''; |
| 250 | + $numLevels = count( $levels ); |
| 251 | + $minLevel = $minLevels[$quality]; |
| 252 | + # Determine the level selected by default |
| 253 | + if ( !empty( $flags[$quality] ) && isset( $levels[$flags[$quality]] ) ) { |
| 254 | + $selected = $flags[$quality]; // valid non-zero value |
| 255 | + } else { |
| 256 | + $selected = $minLevel; |
| 257 | + } |
| 258 | + # Show label as needed |
| 259 | + if ( !FlaggedRevs::binaryFlagging() ) { |
| 260 | + $item .= Xml::tags( 'label', array( 'for' => "wp$quality" ), |
| 261 | + FlaggedRevs::getTagMsg( $quality ) ) . ":\n"; |
| 262 | + } |
| 263 | + # If the sum of qualities of all flags is above 6, use drop down boxes. |
| 264 | + # 6 is an arbitrary value choosen according to screen space and usability. |
| 265 | + if ( $size > 6 ) { |
| 266 | + $attribs = array( 'name' => "wp$quality", 'id' => "wp$quality", |
| 267 | + 'onchange' => "FlaggedRevsReview.updateRatingForm()" ); |
| 268 | + $item .= Xml::openElement( 'select', $attribs ) . "\n"; |
| 269 | + foreach ( $levels as $i => $name ) { |
| 270 | + $optionClass = array( 'class' => "fr-rating-option-$i" ); |
| 271 | + $item .= Xml::option( FlaggedRevs::getTagMsg( $name ), $i, |
| 272 | + ( $i == $selected ), $optionClass ) . "\n"; |
| 273 | + } |
| 274 | + $item .= Xml::closeElement( 'select' ) . "\n"; |
| 275 | + # If there are more than two levels, current user gets radio buttons |
| 276 | + } elseif ( $numLevels > 2 ) { |
| 277 | + foreach ( $levels as $i => $name ) { |
| 278 | + $attribs = array( 'class' => "fr-rating-option-$i", |
| 279 | + 'onchange' => "FlaggedRevsReview.updateRatingForm()" ); |
| 280 | + $item .= Xml::radioLabel( FlaggedRevs::getTagMsg( $name ), "wp$quality", |
| 281 | + $i, "wp$quality" . $i, ( $i == $selected ), $attribs ) . "\n"; |
| 282 | + } |
| 283 | + # Otherwise make checkboxes (two levels available for current user) |
| 284 | + } else if ( $numLevels == 2 ) { |
| 285 | + $i = $minLevel; |
| 286 | + $attribs = array( 'class' => "fr-rating-option-$i", |
| 287 | + 'onchange' => "FlaggedRevsReview.updateRatingForm()" ); |
| 288 | + $attribs = $attribs + array( 'value' => $i ); |
| 289 | + $item .= Xml::checkLabel( wfMsg( 'revreview-' . $levels[$i] ), |
| 290 | + "wp$quality", "wp$quality", ( $selected == $i ), $attribs ) . "\n"; |
| 291 | + } |
| 292 | + $items[] = $item; |
| 293 | + } |
| 294 | + } |
| 295 | + return implode( '   ', $items ); |
| 296 | + } |
| 297 | + |
| 298 | + protected static function ratingFormTags( $user, $selected ) { |
| 299 | + $labels = array(); |
| 300 | + $minLevels = array(); |
| 301 | + # Build up all levels available to user |
| 302 | + foreach ( FlaggedRevs::getDimensions() as $tag => $levels ) { |
| 303 | + if ( isset( $selected[$tag] ) && |
| 304 | + !FlaggedRevs::userCanSetTag( $user, $tag, $selected[$tag] ) ) |
| 305 | + { |
| 306 | + return array( false, false ); // form will have to be disabled |
| 307 | + } |
| 308 | + $labels[$tag] = array(); // applicable tag levels |
| 309 | + $minLevels[$tag] = false; // first non-zero level number |
| 310 | + foreach ( $levels as $i => $msg ) { |
| 311 | + # Some levels may be restricted or not applicable... |
| 312 | + if ( !FlaggedRevs::userCanSetTag( $user, $tag, $i ) ) { |
| 313 | + continue; // skip this level |
| 314 | + } else if ( $i > 0 && !$minLevels[$tag] ) { |
| 315 | + $minLevels[$tag] = $i; // first non-zero level number |
| 316 | + } |
| 317 | + $labels[$tag][$i] = $msg; // set label |
| 318 | + } |
| 319 | + if ( !$minLevels[$tag] ) { |
| 320 | + return array( false, false ); // form will have to be disabled |
| 321 | + } |
| 322 | + } |
| 323 | + return array( $labels, $minLevels ); |
| 324 | + } |
| 325 | + |
| 326 | + /** |
| 327 | + * Generates review form submit buttons |
| 328 | + * @param int $rejectId left rev ID for "reject" on diffs |
| 329 | + * @param FlaggedRevision $frev, the flagged revision, if any |
| 330 | + * @param bool $disabled, is the form disabled? |
| 331 | + * @param bool $reviewIncludes, force the review button to be usable? |
| 332 | + * @return string |
| 333 | + */ |
| 334 | + protected static function submitButtons( |
| 335 | + $rejectId, $frev, $disabled, $reviewIncludes = false |
| 336 | + ) { |
| 337 | + $disAttrib = array( 'disabled' => 'disabled' ); |
| 338 | + # ACCEPT BUTTON: accept a revision |
| 339 | + # We may want to re-review to change: |
| 340 | + # (a) notes (b) tags (c) pending template/file changes |
| 341 | + if ( FlaggedRevs::binaryFlagging() ) { // just the buttons |
| 342 | + $applicable = ( !$frev || $reviewIncludes ); // no tags/notes |
| 343 | + $needsChange = false; // no state change possible |
| 344 | + } else { // buttons + ratings |
| 345 | + $applicable = true; // tags might change |
| 346 | + $needsChange = ( $frev && !$reviewIncludes ); |
| 347 | + } |
| 348 | + $s = Xml::submitButton( wfMsgHtml( 'revreview-submit-review' ), |
| 349 | + array( |
| 350 | + 'name' => 'wpApprove', |
| 351 | + 'id' => 'mw-fr-submit-accept', |
| 352 | + 'accesskey' => wfMsg( 'revreview-ak-review' ), |
| 353 | + 'title' => wfMsg( 'revreview-tt-flag' ) . ' [' . |
| 354 | + wfMsg( 'revreview-ak-review' ) . ']' |
| 355 | + ) + ( ( $disabled || !$applicable ) ? $disAttrib : array() ) |
| 356 | + ); |
| 357 | + # REJECT BUTTON: revert from a pending revision to the stable |
| 358 | + if ( $rejectId ) { |
| 359 | + $s .= ' '; |
| 360 | + $s .= Xml::submitButton( wfMsgHtml( 'revreview-submit-reject' ), |
| 361 | + array( |
| 362 | + 'name' => 'wpReject', |
| 363 | + 'id' => 'mw-fr-submit-reject', |
| 364 | + 'title' => wfMsg( 'revreview-tt-reject' ), |
| 365 | + ) + ( $disabled ? $disAttrib : array() ) |
| 366 | + ); |
| 367 | + } |
| 368 | + # UNACCEPT BUTTON: revoke a revisions acceptance |
| 369 | + # Hide if revision is not flagged |
| 370 | + $s .= ' '; |
| 371 | + $s .= Xml::submitButton( wfMsgHtml( 'revreview-submit-unreview' ), |
| 372 | + array( |
| 373 | + 'name' => 'wpUnapprove', |
| 374 | + 'id' => 'mw-fr-submit-unaccept', |
| 375 | + 'title' => wfMsg( 'revreview-tt-unflag' ), |
| 376 | + 'style' => $frev ? '' : 'display:none' |
| 377 | + ) + ( $disabled ? $disAttrib : array() ) |
| 378 | + ); |
| 379 | + // Disable buttons unless state changes in some cases (non-JS compatible) |
| 380 | + $s .= "<script type=\"text/javascript\"> |
| 381 | + var jsReviewNeedsChange = " . (int)$needsChange . "</script>"; |
| 382 | + return $s; |
| 383 | + } |
| 384 | + |
| 385 | + protected function getIncludeVersions() { |
| 386 | + # Do we need to get inclusion IDs from parser output? |
| 387 | + if ( $this->templateIDs === null || $this->imageSHA1Keys === null ) { |
| 388 | + list( $this->templateIDs, $this->imageSHA1Keys ) = |
| 389 | + RevisionReviewForm::currentIncludeVersions( $this->article, $this->rev ); |
| 390 | + } |
| 391 | + return array( $this->templateIDs, $this->imageSHA1Keys ); |
| 392 | + } |
| 393 | +} |
Property changes on: trunk/extensions/FlaggedRevs/presentation/RevisionReviewFormUI.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 394 | + native |
Index: trunk/extensions/FlaggedRevs/presentation/RejectConfirmationFormUI.php |
— | — | @@ -0,0 +1,145 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Reject confirmation review form UI |
| 5 | + */ |
| 6 | +class RejectConfirmationFormUI { |
| 7 | + protected $form, $oldRev, $newRev; |
| 8 | + |
| 9 | + public function __construct( RevisionReviewForm $form ) { |
| 10 | + $this->form = $form; |
| 11 | + $this->newRev = Revision::newFromTitle( $form->getPage(), $form->getOldId() ); |
| 12 | + $this->oldRev = Revision::newFromTitle( $form->getPage(), $form->getRefId() ); |
| 13 | + } |
| 14 | + |
| 15 | + /** |
| 16 | + * Get the "are you sure you want to reject these changes?" form |
| 17 | + * @return array (html string, error string or true) |
| 18 | + */ |
| 19 | + public function getHtml() { |
| 20 | + global $wgLang, $wgContLang; |
| 21 | + $status = $this->form->checkTarget(); |
| 22 | + if ( $status !== true ) { |
| 23 | + return array( '', $status ); // not a reviewable existing page |
| 24 | + } |
| 25 | + $oldRev = $this->oldRev; // convenience |
| 26 | + $newRev = $this->newRev; // convenience |
| 27 | + # Do not mess with archived/deleted revisions |
| 28 | + if ( !$oldRev || $newRev->isDeleted( Revision::DELETED_TEXT ) ) { |
| 29 | + return array( '', 'review_bad_oldid' ); |
| 30 | + } elseif ( !$newRev || $newRev->isDeleted( Revision::DELETED_TEXT ) ) { |
| 31 | + return array( '', 'review_bad_oldid' ); |
| 32 | + } |
| 33 | + |
| 34 | + $form = '<div class="plainlinks">'; |
| 35 | + |
| 36 | + $dbr = wfGetDB( DB_SLAVE ); |
| 37 | + $res = $dbr->select( 'revision', |
| 38 | + Revision::selectFields(), |
| 39 | + array( |
| 40 | + 'rev_page' => $oldRev->getPage(), |
| 41 | + 'rev_id > ' . $dbr->addQuotes( $oldRev->getId() ), |
| 42 | + 'rev_id <= ' . $dbr->addQuotes( $newRev->getId() ) |
| 43 | + ), |
| 44 | + __METHOD__, |
| 45 | + array( 'LIMIT' => 251 ) // sanity check |
| 46 | + ); |
| 47 | + if ( !$dbr->numRows( $res ) ) { |
| 48 | + return array( '', 'review_bad_oldid' ); |
| 49 | + } elseif ( $dbr->numRows( $res ) > 250 ) { |
| 50 | + return array( '', 'review_reject_excessive' ); |
| 51 | + } |
| 52 | + |
| 53 | + $rejectIds = $rejectAuthors = array(); |
| 54 | + $contribs = SpecialPage::getTitleFor( 'Contributions' )->getPrefixedText(); |
| 55 | + foreach ( $res as $row ) { |
| 56 | + $rev = new Revision( $row ); |
| 57 | + $rejectIds[] = $rev->getId(); |
| 58 | + $rejectAuthors[] = $rev->isDeleted( Revision::DELETED_USER ) |
| 59 | + ? wfMsg( 'rev-deleted-user' ) |
| 60 | + : "[[{$contribs}/{$rev->getUserText()}|{$rev->getUserText()}]]"; |
| 61 | + } |
| 62 | + $rejectAuthors = array_values( array_unique( $rejectAuthors ) ); |
| 63 | + |
| 64 | + // List of revisions being undone... |
| 65 | + $form .= wfMsgExt( 'revreview-reject-text-list', 'parseinline', |
| 66 | + $wgLang->formatNum( count( $rejectIds ) ) ); |
| 67 | + $form .= '<ul>'; |
| 68 | + // FIXME: we need a generic revision list class...this is bullshit |
| 69 | + $spRevDelete = SpecialPage::getPage( 'RevisionReview' ); |
| 70 | + $spRevDelete->skin = $this->form->getUser()->getSkin(); // XXX |
| 71 | + $list = new RevDel_RevisionList( $spRevDelete, $oldRev->getTitle(), $rejectIds ); |
| 72 | + for ( $list->reset(); $list->current(); $list->next() ) { |
| 73 | + $item = $list->current(); |
| 74 | + if ( $item->canView() ) { |
| 75 | + $form .= $item->getHTML(); |
| 76 | + } |
| 77 | + } |
| 78 | + $form .= '</ul>'; |
| 79 | + if ( $newRev->isCurrent() ) { |
| 80 | + // Revision this will revert to (when reverting the top X revs)... |
| 81 | + $form .= wfMsgExt( 'revreview-reject-text-revto', 'parseinline', |
| 82 | + $oldRev->getTitle()->getPrefixedDBKey(), $oldRev->getId(), |
| 83 | + $wgLang->timeanddate( $oldRev->getTimestamp(), true ) |
| 84 | + ); |
| 85 | + } |
| 86 | + |
| 87 | + $comment = $this->form->getComment(); // convenience |
| 88 | + // Determine the default edit summary... |
| 89 | + $oldRevAuthor = $oldRev->isDeleted( Revision::DELETED_USER ) |
| 90 | + ? wfMsg( 'rev-deleted-user' ) |
| 91 | + : $oldRev->getUserText(); |
| 92 | + // NOTE: *-cur msg wording not safe for (unlikely) edit auto-merge |
| 93 | + $msg = $newRev->isCurrent() |
| 94 | + ? 'revreview-reject-summary-cur' |
| 95 | + : 'revreview-reject-summary-old'; |
| 96 | + $defaultSummary = wfMsgExt( $msg, array( 'parsemag', 'content' ), |
| 97 | + $wgContLang->formatNum( count( $rejectIds ) ), |
| 98 | + $wgContLang->listToText( $rejectAuthors ), |
| 99 | + $oldRev->getId(), |
| 100 | + $oldRevAuthor ); |
| 101 | + // If the message is too big, then fallback to the shorter one |
| 102 | + $colonSeparator = wfMsgForContent( 'colon-separator' ); |
| 103 | + $maxLen = 255 - count( $colonSeparator ) - count( $comment ); |
| 104 | + if ( strlen( $defaultSummary ) > $maxLen ) { |
| 105 | + $msg = $newRev->isCurrent() |
| 106 | + ? 'revreview-reject-summary-cur-short' |
| 107 | + : 'revreview-reject-summary-old-short'; |
| 108 | + $defaultSummary = wfMsgExt( $msg, array( 'parsemag', 'content' ), |
| 109 | + $wgContLang->formatNum( count( $rejectIds ) ), |
| 110 | + $oldRev->getId(), |
| 111 | + $oldRevAuthor ); |
| 112 | + } |
| 113 | + // Append any review comment... |
| 114 | + if ( $comment != '' ) { |
| 115 | + if ( $defaultSummary != '' ) { |
| 116 | + $defaultSummary .= $colonSeparator; |
| 117 | + } |
| 118 | + $defaultSummary .= $comment; |
| 119 | + } |
| 120 | + |
| 121 | + $form .= '</div>'; |
| 122 | + |
| 123 | + $skin = $this->form->getUser()->getSkin(); |
| 124 | + $reviewTitle = SpecialPage::getTitleFor( 'RevisionReview' ); |
| 125 | + $form .= Xml::openElement( 'form', |
| 126 | + array( 'method' => 'POST', 'action' => $reviewTitle->getFullUrl() ) ); |
| 127 | + $form .= Html::hidden( 'action', 'reject' ); |
| 128 | + $form .= Html::hidden( 'wpReject', 1 ); |
| 129 | + $form .= Html::hidden( 'wpRejectConfirm', 1 ); |
| 130 | + $form .= Html::hidden( 'oldid', $this->form->getOldId() ); |
| 131 | + $form .= Html::hidden( 'refid', $this->form->getRefId() ); |
| 132 | + $form .= Html::hidden( 'target', $oldRev->getTitle()->getPrefixedDBKey() ); |
| 133 | + $form .= Html::hidden( 'wpEditToken', $this->form->getUser()->editToken() ); |
| 134 | + $form .= Html::hidden( 'changetime', $newRev->getTimestamp() ); |
| 135 | + $form .= Xml::inputLabel( wfMsg( 'revreview-reject-summary' ), 'wpReason', |
| 136 | + 'wpReason', 120, $defaultSummary ) . "<br />"; |
| 137 | + $form .= Html::input( 'wpSubmit', wfMsg( 'revreview-reject-confirm' ), 'submit' ); |
| 138 | + $form .= ' '; |
| 139 | + $form .= $skin->link( $this->form->getPage(), wfMsg( 'revreview-reject-cancel' ), |
| 140 | + array( 'onClick' => 'history.back(); return false;' ), |
| 141 | + array( 'oldid' => $this->form->getRefId(), 'diff' => $this->form->getOldId() ) ); |
| 142 | + $form .= Xml::closeElement( 'form' ); |
| 143 | + |
| 144 | + return array( $form, true ); |
| 145 | + } |
| 146 | +} |
Property changes on: trunk/extensions/FlaggedRevs/presentation/RejectConfirmationFormUI.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 147 | + native |