Index: trunk/extensions/FlaggedRevs/FlaggedRevs.php |
— | — | @@ -286,7 +286,7 @@ |
287 | 287 | $wgAvailableRights[] = 'stablesettings'; |
288 | 288 | |
289 | 289 | # Bump this number every time you change flaggedrevs.css/flaggedrevs.js |
290 | | -$wgFlaggedRevStyleVersion = 62; |
| 290 | +$wgFlaggedRevStyleVersion = 63; |
291 | 291 | |
292 | 292 | $wgExtensionFunctions[] = 'efLoadFlaggedRevs'; |
293 | 293 | |
Index: trunk/extensions/FlaggedRevs/language/FlaggedRevs.i18n.php |
— | — | @@ -16,6 +16,7 @@ |
17 | 17 | */ |
18 | 18 | |
19 | 19 | $messages['en'] = array( |
| 20 | + 'action-review' => 'review revisions', |
20 | 21 | 'editor' => 'Editor', |
21 | 22 | 'flaggedrevs' => 'Flagged Revisions', |
22 | 23 | 'flaggedrevs-backlog' => 'There is currently a backlog of [[Special:OldReviewedPages|pending edits]] to reviewed pages. \'\'\'Your attention is needed!\'\'\'', |
— | — | @@ -75,7 +76,7 @@ |
76 | 77 | New [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} changes] may have been made.', |
77 | 78 | 'revreview-basic-same' => 'This is the [[{{MediaWiki:Validationpage}}|stable version]], [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} sighted] on <i>$2</i>.', |
78 | 79 | 'revreview-basic-source' => 'A [{{fullurl:{{FULLPAGENAMEE}}|stableid=$1}} sighted version] of this page, [{{fullurl:{{#Special:Log}}|type=review&page={{FULLPAGENAMEE}}}} approved] on <i>$2</i>, was based off this revision.', |
79 | | - 'revreview-blocked' => 'You cannot review this revision because your account is currently blocked ([$1 details])', |
| 80 | + 'revreview-failed' => "'''Unable to review this revision.''' The submission is incomplete or otherwise invalid.", |
80 | 81 | 'revreview-changed' => '\'\'\'The requested action could not be performed on this revision of [[:$1|$1]].\'\'\' |
81 | 82 | |
82 | 83 | A template or file may have been requested when no specific version was specified. |
— | — | @@ -96,6 +97,7 @@ |
97 | 98 | 'revreview-edited' => '\'\'\'Changes will go into the [[{{MediaWiki:Validationpage}}|stable version]] once an authorised user reviews them.\'\'\' |
98 | 99 | The \'\'draft\'\', shown below, contains [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&diffonly=0}} $2 suggested {{PLURAL:$2|change|changes}}].', |
99 | 100 | 'revreview-flag' => 'Review this revision', |
| 101 | + 'revreview-unflag' => 'Unreview this revision', |
100 | 102 | 'revreview-invalid' => '\'\'\'Invalid target:\'\'\' no [[{{MediaWiki:Validationpage}}|reviewed]] revision corresponds to the given ID.', |
101 | 103 | 'revreview-legend' => 'Rate revision content', |
102 | 104 | 'revreview-log' => 'Comment:', |
— | — | @@ -153,9 +155,9 @@ |
154 | 156 | 'revreview-style-3' => 'Concise', |
155 | 157 | 'revreview-style-4' => 'Featured', |
156 | 158 | 'revreview-submit' => 'Submit', |
| 159 | + 'revreview-submit-review' => 'Mark reviewed', |
| 160 | + 'revreview-submit-unreview' => 'Mark unreviewed', |
157 | 161 | 'revreview-submitting' => 'Submitting...', |
158 | | - 'revreview-finished' => 'Review complete!', |
159 | | - 'revreview-failed' => 'Review failed!', |
160 | 162 | 'revreview-successful' => '\'\'\'Revision of [[:$1|$1]] successfully flagged. ([{{fullurl:{{#Special:ReviewedVersions}}|page=$2}} view stable versions])\'\'\'', |
161 | 163 | 'revreview-successful2' => '\'\'\'Revision of [[:$1|$1]] successfully unflagged.\'\'\'', |
162 | 164 | 'revreview-text' => '\'\'[[{{MediaWiki:Validationpage}}|Stable versions]] are the default page content for viewers rather than the newest revision.\'\'', |
— | — | @@ -226,7 +228,7 @@ |
227 | 229 | |
228 | 230 | 'log-show-hide-review' => '$1 review log', |
229 | 231 | |
230 | | - 'revreview-tt-review' => 'Review this page', |
| 232 | + 'revreview-tt-review' => 'Apply this status to this revision', |
231 | 233 | 'validationpage' => '{{ns:help}}:Page validation', |
232 | 234 | ); |
233 | 235 | |
Index: trunk/extensions/FlaggedRevs/specialpages/RevisionReview_body.php |
— | — | @@ -82,7 +82,8 @@ |
83 | 83 | $this->fileVersion = $wgRequest->getVal( 'fileVersion' ); |
84 | 84 | $this->validatedParams = $wgRequest->getVal( 'validatedParams' ); |
85 | 85 | # Special token to discourage fiddling... |
86 | | - $k = self::validationKey( $this->templateParams, $this->imageParams, $this->fileVersion, $this->oldid ); |
| 86 | + $k = self::validationKey( $this->templateParams, $this->imageParams, |
| 87 | + $this->fileVersion, $this->oldid ); |
87 | 88 | if( $this->validatedParams !== $k ) { |
88 | 89 | $wgOut->permissionRequired( 'badaccess-group0' ); |
89 | 90 | return; |
— | — | @@ -155,19 +156,8 @@ |
156 | 157 | public static function AjaxReview( /*$args...*/ ) { |
157 | 158 | global $wgUser; |
158 | 159 | $args = func_get_args(); |
159 | | - // Basic permission check |
160 | | - if( $wgUser->isAllowed( 'review' ) ) { |
161 | | - if( $wgUser->isBlocked() ) { |
162 | | - $blocklist = SpecialPage::getTitleFor( 'Ipblocklist' ); |
163 | | - $blocklog = $blocklist->getFullUrl( 'ip=' . urlencode('#'.$wgUser->getBlockId()) ); |
164 | | - return '<err#><h2>'.wfMsgHtml('blockedtitle').'</h2>'. |
165 | | - wfMsgExt('revreview-blocked','parseinline',$blocklog); |
166 | | - } |
167 | | - } else { |
168 | | - return '<err#>'; |
169 | | - } |
170 | 160 | if( wfReadOnly() ) { |
171 | | - return '<err#>'; |
| 161 | + return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' ); |
172 | 162 | } |
173 | 163 | $tags = FlaggedRevs::getDimensions(); |
174 | 164 | // Make review interface object |
— | — | @@ -177,7 +167,7 @@ |
178 | 168 | foreach( $args as $x => $arg ) { |
179 | 169 | $set = explode('|',$arg,2); |
180 | 170 | if( count($set) != 2 ) { |
181 | | - return '<err#>'; |
| 171 | + return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' ); |
182 | 172 | } |
183 | 173 | list($par,$val) = $set; |
184 | 174 | switch( $par ) |
— | — | @@ -185,13 +175,13 @@ |
186 | 176 | case "target": |
187 | 177 | $form->page = Title::newFromUrl( $val ); |
188 | 178 | if( is_null($form->page) || !FlaggedRevs::isPageReviewable( $form->page ) ) { |
189 | | - return '<err#>'; |
| 179 | + return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' ); |
190 | 180 | } |
191 | 181 | break; |
192 | 182 | case "oldid": |
193 | 183 | $form->oldid = intval( $val ); |
194 | 184 | if( !$form->oldid ) { |
195 | | - return '<err#>'; |
| 185 | + return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' ); |
196 | 186 | } |
197 | 187 | break; |
198 | 188 | case "rcid": |
— | — | @@ -220,7 +210,7 @@ |
221 | 211 | break; |
222 | 212 | case "wpEditToken": |
223 | 213 | if( !$wgUser->matchEditToken( $val ) ) { |
224 | | - return '<err#>'; |
| 214 | + return '<err#>' . wfMsgExt( 'sessionfailure', 'parseinline' ); |
225 | 215 | } |
226 | 216 | break; |
227 | 217 | default: |
— | — | @@ -234,33 +224,45 @@ |
235 | 225 | break; |
236 | 226 | } |
237 | 227 | } |
| 228 | + // No page? |
| 229 | + if( !$form->page ) { |
| 230 | + return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' ); |
| 231 | + } |
| 232 | + // Basic permission check |
| 233 | + $permErrors = $form->page->getUserPermissionsErrors( 'review', $wgUser ); |
| 234 | + if( !$permErrors ) { |
| 235 | + // User must be able to edit this page |
| 236 | + $permErrors = $form->page->getUserPermissionsErrors( 'edit', $wgUser ); |
| 237 | + } |
| 238 | + if( $permErrors ) { |
| 239 | + global $wgOut; |
| 240 | + return '<err#>' . $wgOut->parse( |
| 241 | + $wgOut->formatPermissionsErrorMessage( $permErrors, 'review' ) |
| 242 | + ); |
| 243 | + } |
238 | 244 | // Missing params? |
239 | 245 | if( count($form->dims) != count($tags) ) { |
240 | | - return '<err#>'; |
| 246 | + return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' ); |
241 | 247 | } |
242 | 248 | // Incomplete review? |
243 | 249 | if( !$form->oldid || is_null($form->page) ) { |
244 | | - return '<err#>'; |
| 250 | + return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' ); |
245 | 251 | } |
246 | 252 | if( $form->unapprovedTags && $form->unapprovedTags < count( FlaggedRevs::getDimensions() ) ) { |
247 | | - return '<err#>'; |
| 253 | + return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' ); |
248 | 254 | } |
249 | 255 | // Doesn't match up? |
250 | 256 | $k = self::validationKey( $form->templateParams, $form->imageParams, $form->fileVersion, $form->oldid ); |
251 | 257 | if( $form->validatedParams !== $k ) { |
252 | | - return '<err#>'; |
| 258 | + return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' ); |
253 | 259 | } |
254 | | - // User must be able to edit this page |
255 | | - if( !$form->page->quickUserCan('edit') ) { |
256 | | - return '<err#>'; |
257 | | - } |
258 | 260 | $fa = FlaggedArticle::getTitleInstance( $form->page ); |
259 | 261 | $form->config = $fa->getVisibilitySettings(); |
260 | 262 | # Get the revision's current flags, if any |
261 | 263 | $form->oflags = FlaggedRevs::getRevisionTags( $form->page, $form->oldid ); |
262 | 264 | # Check tag permissions |
263 | 265 | if( !self::userCanSetFlags($form->dims,$form->oflags,$form->config) ) { |
264 | | - return '<err#>'; |
| 266 | + return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' ); |
265 | 267 | } |
266 | 268 | list($approved,$status) = $form->submit(); |
267 | 269 | if( $status === true ) { |
— | — | @@ -270,7 +272,7 @@ |
271 | 273 | } elseif( $approved ) { |
272 | 274 | return '<err#>' . wfMsg( 'revreview-revnotfound' ); |
273 | 275 | } else { // hmmm? |
274 | | - return '<err#>'; |
| 276 | + return '<err#>' . wfMsgExt( 'revreview-failed', 'parseinline' ); |
275 | 277 | } |
276 | 278 | } |
277 | 279 | |
— | — | @@ -312,7 +314,8 @@ |
313 | 315 | for( $i=0; $i < $x; $i++ ) { |
314 | 316 | $formradios[$tag][] = array( "revreview-$tag-$i", "wp$tag", $i ); |
315 | 317 | } |
316 | | - $form .= '<td><strong>' . wfMsgHtml( "revreview-$tag" ) . '</strong></td><td width=\'20\'></td>'; |
| 318 | + $form .= '<td><strong>' . wfMsgHtml( "revreview-$tag" ) . |
| 319 | + '</strong></td><td width=\'20\'></td>'; |
317 | 320 | } |
318 | 321 | $hidden = array( |
319 | 322 | Xml::hidden( 'wpEditToken', $wgUser->editToken() ), |
— | — | @@ -395,7 +398,9 @@ |
396 | 399 | # If all values are set to zero, this has been unapproved |
397 | 400 | $approved = $this->isApproval(); |
398 | 401 | # Double-check permissions |
399 | | - if( !$this->page->quickUserCan('edit') || !self::userCanSetFlags($this->dims,$this->oflags,$this->config) ) { |
| 402 | + if( !$this->page->quickUserCan('edit') |
| 403 | + || !self::userCanSetFlags($this->dims,$this->oflags,$this->config) ) |
| 404 | + { |
400 | 405 | return array($approved,false); |
401 | 406 | } |
402 | 407 | # We can only approve actual revisions... |
Index: trunk/extensions/FlaggedRevs/FlaggedRevsXML.php |
— | — | @@ -161,7 +161,8 @@ |
162 | 162 | } |
163 | 163 | $levelmarker = $level * 20 + 20; |
164 | 164 | if( $prettyBox ) { |
165 | | - $tag .= "<tr><td class='fr-text' valign='middle'>" . wfMsgHtml("revreview-$quality") . |
| 165 | + $tag .= "<tr><td class='fr-text' valign='middle'>" . |
| 166 | + wfMsgHtml("revreview-$quality") . |
166 | 167 | "</td><td class='fr-value$levelmarker' valign='middle'>" . |
167 | 168 | $encValueText . "</td></tr>\n"; |
168 | 169 | } else { |
— | — | @@ -237,7 +238,11 @@ |
238 | 239 | $box .= "</td><td></td></tr></table>"; |
239 | 240 | return $box; |
240 | 241 | } |
241 | | - |
| 242 | + |
| 243 | + /** |
| 244 | + * @returns string |
| 245 | + * Generates (+/-) JS toggle HTML |
| 246 | + */ |
242 | 247 | public static function ratingToggle() { |
243 | 248 | return "<a id='mw-revisiontoggle' class='flaggedrevs_toggle' style='display:none;'" . |
244 | 249 | " onclick='FlaggedRevs.toggleRevRatings()' title='" . |
— | — | @@ -249,81 +254,118 @@ |
250 | 255 | * @param array $flags, selected flags |
251 | 256 | * @param array $config, page config |
252 | 257 | * @param bool $disabled, form disabled |
| 258 | + * @param bool $reviewed, rev already reviewed |
253 | 259 | * @returns string |
254 | 260 | * Generates a main tag inputs (checkboxes/radios/selects) for review form |
255 | 261 | */ |
256 | | - public static function ratingInputs( $flags, $config, $disabled ) { |
| 262 | + public static function ratingInputs( $flags, $config, $disabled, $reviewed ) { |
257 | 263 | $form = ''; |
258 | | - $toggle = $disabled ? array( 'disabled' => "disabled" ) : array(); |
259 | | - $size = count(FlaggedRevs::getDimensions(),1) - count(FlaggedRevs::getDimensions()); |
260 | | - # Loop through all different flag types |
261 | | - foreach( FlaggedRevs::getDimensions() as $quality => $levels ) { |
262 | | - $label = array(); // applicable tag levels |
263 | | - $minLevel = 1; // first non-zero level number |
264 | | - # Get current flag values or default if none |
265 | | - $selected = ( isset($flags[$quality]) && $flags[$quality] > 0 ) ? |
266 | | - $flags[$quality] : 1; |
267 | | - # Disabled form? Set the selected item label |
268 | | - if( $disabled ) { |
269 | | - $label[$selected] = $levels[$selected]; |
270 | | - # Collect all quality levels of a flag current user can set |
271 | | - } else { |
272 | | - foreach( $levels as $i => $name ) { |
273 | | - # Some levels may be restricted or not applicable... |
274 | | - if( !RevisionReview::userCan($quality,$i,$config) ) { |
275 | | - if( $selected == $i ) $selected++; // bump default |
276 | | - continue; // skip this level |
277 | | - } else if( $i > 0 ) { |
278 | | - $minLevel = $i; // first non-zero level number |
279 | | - } |
280 | | - $label[$i] = $name; |
281 | | - } |
| 264 | + # Get all available tags for this page/user |
| 265 | + list($labels,$minLevels) = self::ratingFormTags( $flags, $config ); |
| 266 | + if( $labels === false ) { |
| 267 | + $disabled = true; // a tag is unsettable |
| 268 | + } |
| 269 | + $dimensions = FlaggedRevs::getDimensions(); |
| 270 | + $tags = array_keys($dimensions); |
| 271 | + # If there are no tags, make one checkbox to approve/unapprove |
| 272 | + if( FlaggedRevs::binaryFlagging() ) { |
| 273 | + $inputName = empty($tags) ? 'wpApprove' : "wp{$tags[0]}"; |
| 274 | + return Xml::hidden( $inputName, $reviewed ? 0 : 1, |
| 275 | + array('id' => 'mw-reviewstate') ); |
| 276 | + } |
| 277 | + $items = array(); |
| 278 | + # Build rating form... |
| 279 | + if( $disabled ) { |
| 280 | + // Display the value for each tag as text |
| 281 | + foreach( $dimensions as $quality => $levels ) { |
| 282 | + $selected = isset($flags[$quality]) ? $flags[$quality] : 0; |
| 283 | + $items[] = "<b>" . FlaggedRevs::getTagMsg( $quality ) . ":</b> " . |
| 284 | + FlaggedRevs::getTagValueMsg( $quality, $selected ); |
282 | 285 | } |
283 | | - $numLevels = count( $label ); |
284 | | - $form .= Xml::openElement( 'span', array('class' => 'fr-rating-options') ) . "\n"; |
285 | | - $form .= "<b>" . Xml::tags( 'label', array( 'for' => "wp$quality" ), |
286 | | - FlaggedRevs::getTagMsg( $quality ) ) . ":</b>\n"; |
287 | | - # If the sum of qualities of all flags is above 6, use drop down boxes |
288 | | - # 6 is an arbitrary value choosen according to screen space and usability |
289 | | - if( $size > 6 ) { |
290 | | - $attribs = array( 'name' => "wp$quality", 'id' => "wp$quality", |
291 | | - 'onchange' => "FlaggedRevs.updateRatingForm()" ) + $toggle; |
292 | | - $form .= Xml::openElement( 'select', $attribs ); |
293 | | - foreach( $label as $i => $name ) { |
294 | | - $optionClass = array( 'class' => "fr-rating-option-$i" ); |
295 | | - $form .= Xml::option( FlaggedRevs::getTagMsg($name), $i, ($i == $selected), |
296 | | - $optionClass )."\n"; |
| 286 | + } else { |
| 287 | + $size = count($labels,1) - count($labels); |
| 288 | + foreach( $labels as $quality => $levels ) { |
| 289 | + $item = ''; |
| 290 | + $numLevels = count( $levels ); |
| 291 | + $minLevel = $minLevels[$quality]; |
| 292 | + # Determine the level selected by default |
| 293 | + if( !empty($flags[$quality]) && isset($levels[$flags[$quality]]) ) { |
| 294 | + $selected = $flags[$quality]; // valid non-zero value |
| 295 | + } else { |
| 296 | + $selected = $minLevel; |
297 | 297 | } |
298 | | - $form .= Xml::closeElement('select')."\n"; |
299 | | - # If there are more than two levels, current user gets radio buttons |
300 | | - } elseif( $numLevels > 2 ) { |
301 | | - foreach( $label as $i => $name ) { |
| 298 | + # Show label as needed |
| 299 | + if( !FlaggedRevs::binaryFlagging() ) { |
| 300 | + $item .= "<b>" . Xml::tags( 'label', array( 'for' => "wp$quality" ), |
| 301 | + FlaggedRevs::getTagMsg( $quality ) ) . ":</b>\n"; |
| 302 | + } |
| 303 | + # If the sum of qualities of all flags is above 6, use drop down boxes. |
| 304 | + # 6 is an arbitrary value choosen according to screen space and usability. |
| 305 | + if( $size > 6 ) { |
| 306 | + $attribs = array( 'name' => "wp$quality", 'id' => "wp$quality", |
| 307 | + 'onchange' => "FlaggedRevs.updateRatingForm()" ); |
| 308 | + $item .= Xml::openElement( 'select', $attribs ); |
| 309 | + foreach( $levels as $i => $name ) { |
| 310 | + $optionClass = array( 'class' => "fr-rating-option-$i" ); |
| 311 | + $item .= Xml::option( FlaggedRevs::getTagMsg($name), $i, |
| 312 | + ($i == $selected), $optionClass )."\n"; |
| 313 | + } |
| 314 | + $item .= Xml::closeElement('select')."\n"; |
| 315 | + # If there are more than two levels, current user gets radio buttons |
| 316 | + } elseif( $numLevels > 2 ) { |
| 317 | + foreach( $levels as $i => $name ) { |
| 318 | + $attribs = array( 'class' => "fr-rating-option-$i", |
| 319 | + 'onchange' => "FlaggedRevs.updateRatingForm()" ); |
| 320 | + $item .= Xml::radioLabel( FlaggedRevs::getTagMsg($name), "wp$quality", |
| 321 | + $i, "wp$quality".$i, ($i == $selected), $attribs ) . "\n"; |
| 322 | + } |
| 323 | + # Otherwise make checkboxes (two levels available for current user) |
| 324 | + } else if( $numLevels == 2 ) { |
| 325 | + $i = $minLevel; |
302 | 326 | $attribs = array( 'class' => "fr-rating-option-$i", |
303 | 327 | 'onchange' => "FlaggedRevs.updateRatingForm()" ); |
304 | | - $form .= Xml::radioLabel( FlaggedRevs::getTagMsg($name), "wp$quality", $i, |
305 | | - "wp$quality".$i, ($i == $selected), $attribs ) . "\n"; |
| 328 | + $attribs = $attribs + array('value' => $i); |
| 329 | + $item .= Xml::checkLabel( wfMsg( 'revreview-'.$levels[$i] ), |
| 330 | + "wp$quality", "wp$quality", ($selected == $i), $attribs ) . "\n"; |
306 | 331 | } |
307 | | - # Otherwise make checkboxes (two levels available for current user) |
308 | | - } else { |
309 | | - # If disable, use the current flags; if none, then use the min flag. |
310 | | - $i = $disabled ? $selected : $minLevel; |
311 | | - $attribs = array( 'class' => "fr-rating-option-$i", |
312 | | - 'onchange' => "FlaggedRevs.updateRatingForm()" ); |
313 | | - $attribs = $attribs + $toggle + array('value' => $minLevel); |
314 | | - $form .= Xml::checkLabel( wfMsg( "revreview-{$label[$i]}" ), "wp$quality", |
315 | | - "wp$quality", ($selected == $i), $attribs ) . "\n"; |
| 332 | + $items[] = $item; |
316 | 333 | } |
317 | | - $form .= Xml::closeElement( 'span' ); |
318 | 334 | } |
319 | | - # If there were none, make one checkbox to approve/unapprove |
320 | | - if( FlaggedRevs::dimensionsEmpty() ) { |
321 | | - $form .= Xml::openElement( 'span', array('class' => 'fr-rating-options') ) . "\n"; |
322 | | - $form .= Xml::checkLabel( wfMsg( "revreview-approved" ), "wpApprove", "wpApprove", 1 ) . "\n"; |
323 | | - $form .= Xml::closeElement( 'span' ); |
324 | | - } |
| 335 | + # Wrap visible controls in a span |
| 336 | + $form = Xml::openElement( 'span', array('class' => 'fr-rating-options') ) . "\n"; |
| 337 | + $form .= implode( ' ', $items ); |
| 338 | + $form .= Xml::closeElement( 'span' ) . "\n"; |
325 | 339 | return $form; |
326 | 340 | } |
327 | | - |
| 341 | + |
| 342 | + protected static function ratingFormTags( $selected, $config ) { |
| 343 | + $labels = array(); |
| 344 | + $minLevels = array(); |
| 345 | + # Build up all levels available to user |
| 346 | + foreach( FlaggedRevs::getDimensions() as $tag => $levels ) { |
| 347 | + if( isset($selected[$tag]) && |
| 348 | + !RevisionReview::userCan($tag,$selected[$tag],$config) ) |
| 349 | + { |
| 350 | + return array(false,false); // form will have to be disabled |
| 351 | + } |
| 352 | + $labels[$tag] = array(); // applicable tag levels |
| 353 | + $minLevels[$tag] = false; // first non-zero level number |
| 354 | + foreach( $levels as $i => $msg ) { |
| 355 | + # Some levels may be restricted or not applicable... |
| 356 | + if( !RevisionReview::userCan($tag,$i,$config) ) { |
| 357 | + continue; // skip this level |
| 358 | + } else if( $i > 0 && !$minLevels[$tag] ) { |
| 359 | + $minLevels[$tag] = $i; // first non-zero level number |
| 360 | + } |
| 361 | + $labels[$tag][$i] = $msg; // set label |
| 362 | + } |
| 363 | + if( !$minLevels[$tag] ) { |
| 364 | + return array(false,false); // form will have to be disabled |
| 365 | + } |
| 366 | + } |
| 367 | + return array($labels,$minLevels); |
| 368 | + } |
| 369 | + |
328 | 370 | /* |
329 | 371 | * @param FlaggedArticle $flaggedArticle |
330 | 372 | * @returns string |
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php |
— | — | @@ -30,7 +30,7 @@ |
31 | 31 | } |
32 | 32 | |
33 | 33 | public static function injectGlobalJSVars( &$globalVars ) { |
34 | | - global $wgJsMimeType; |
| 34 | + global $wgUser; |
35 | 35 | $fa = FlaggedArticleView::globalArticleInstance(); |
36 | 36 | # Try to only add to relevant pages |
37 | 37 | if( !$fa || !$fa->isReviewable(true) ) { |
— | — | @@ -41,16 +41,21 @@ |
42 | 42 | # Get page-specific meta-data |
43 | 43 | $frev = $fa->getStableRev(); |
44 | 44 | $stableId = $frev ? $frev->getRevId() : 0; |
45 | | - $ajaxReview = (object) array( |
46 | | - 'sendingMsg' => wfMsgHtml('revreview-submitting'), |
47 | | - 'sentMsgOk' => wfMsgHtml('revreview-finished'), |
48 | | - 'sentMsgBad' => wfMsgHtml('revreview-failed'), |
| 45 | + $ajaxReview = (object) array( |
| 46 | + 'sendMsg' => wfMsgHtml('revreview-submit'), |
| 47 | + 'flagMsg' => wfMsgHtml('revreview-submit-review'), |
| 48 | + 'unflagMsg' => wfMsgHtml('revreview-submit-unreview'), |
| 49 | + 'flagLegMsg' => wfMsgHtml('revreview-flag'), |
| 50 | + 'unflagLegMsg' => wfMsgHtml('revreview-unflag'), |
| 51 | + 'sendingMsg' => wfMsgHtml('revreview-submitting'), |
49 | 52 | 'actioncomplete' => wfMsgHtml('actioncomplete'), |
50 | | - 'actionfailed' => wfMsgHtml('actionfailed') |
| 53 | + 'actionfailed' => wfMsgHtml('actionfailed') |
51 | 54 | ); |
52 | 55 | $globalVars['wgFlaggedRevsParams'] = $rTags; |
53 | 56 | $globalVars['wgStableRevisionId'] = $stableId; |
54 | | - $globalVars['wgAjaxReview'] = $ajaxReview; |
| 57 | + if( $wgUser->isAllowed('review') ) { |
| 58 | + $globalVars['wgAjaxReview'] = $ajaxReview; // language for AJAX form |
| 59 | + } |
55 | 60 | return true; |
56 | 61 | } |
57 | 62 | |
Index: trunk/extensions/FlaggedRevs/flaggedrevs.js |
— | — | @@ -42,6 +42,7 @@ |
43 | 43 | for( tag in wgFlaggedRevsParams.tags ) { |
44 | 44 | var controlName = "wp" + tag; |
45 | 45 | var levels = document.getElementsByName(controlName); |
| 46 | + if( !levels.size ) continue; |
46 | 47 | var selectedlevel = 0; // default |
47 | 48 | |
48 | 49 | if( levels[0].nodeName == 'SELECT' ) { |
— | — | @@ -83,8 +84,10 @@ |
84 | 85 | notebox.style.display = quality ? 'inline' : 'none'; |
85 | 86 | } |
86 | 87 | // If only a few levels are zero, don't show submit link |
87 | | - var submit = document.getElementById('submitreview'); |
88 | | - submit.disabled = ( somezero && !allzero ) ? 'disabled' : ''; |
| 88 | + var submit = document.getElementById('mw-submitreview'); |
| 89 | + if( submit ) { |
| 90 | + submit.disabled = ( somezero && !allzero ) ? 'disabled' : ''; |
| 91 | + } |
89 | 92 | // Clear note box data if not shown |
90 | 93 | var notes = document.getElementById('wpNotes'); |
91 | 94 | if( notes ) { |
— | — | @@ -104,9 +107,12 @@ |
105 | 108 | // These should have been initialized in the generated js |
106 | 109 | if( typeof wgAjaxReview === "undefined" || !wgAjaxReview ) { |
107 | 110 | wgAjaxReview = { |
| 111 | + sendMsg: "Submit", |
108 | 112 | sendingMsg: "Submitting...", |
109 | | - sentMsgOk: "Review complete!", |
110 | | - sentMsgBad: "Review failed!", |
| 113 | + flagMsg: "Mark reviewed", |
| 114 | + unflagMsg: "Mark unreviewed", |
| 115 | + titleFlagMsg: "revreview-tt-review", |
| 116 | + titleUnflagMsg: "revreview-tt-unreview", |
111 | 117 | actioncomplete: "Action complete", |
112 | 118 | actionfailed: "Action failed" |
113 | 119 | }; |
— | — | @@ -180,7 +186,7 @@ |
181 | 187 | |
182 | 188 | wgAjaxReview.unlockForm = function() { |
183 | 189 | var form = document.getElementById("mw-reviewform"); |
184 | | - var submit = document.getElementById("submitreview"); |
| 190 | + var submit = document.getElementById("mw-submitreview"); |
185 | 191 | var notes = document.getElementById("wpNotes"); |
186 | 192 | var reason = document.getElementById("wpReason"); |
187 | 193 | if( !form || !submit ) { |
— | — | @@ -219,19 +225,49 @@ |
220 | 226 | if( wgAjaxReview.timeoutID ) { |
221 | 227 | window.clearTimeout(wgAjaxReview.timeoutID); |
222 | 228 | } |
223 | | - var submit = document.getElementById("submitreview"); |
| 229 | + var submit = document.getElementById("mw-submitreview"); |
| 230 | + var binaryState = document.getElementById("mw-reviewstate"); |
| 231 | + var legend = document.getElementById("mw-reviewformlegend"); |
| 232 | + var diffNotice = document.getElementById("mw-difftostable"); |
| 233 | + // On success... |
224 | 234 | if( response.indexOf('<suc#>') == 0 ) { |
225 | 235 | document.title = wgAjaxReview.actioncomplete; |
226 | | - if( submit ) submit.value = wgAjaxReview.sentMsgOk; |
| 236 | + if( submit ) { |
| 237 | + // If flagging is just binary, flip the form |
| 238 | + if( binaryState ) { |
| 239 | + binaryState.value = (binaryState.value ==1 ) ? 0 : 1; |
| 240 | + // Revision was unflagged - switch to flagging form |
| 241 | + if( binaryState.value == 1 ) { |
| 242 | + legend.innerHTML = '<strong>'+wgAjaxReview.flagLegMsg+'</strong>'; |
| 243 | + submit.value = wgAjaxReview.flagMsg; |
| 244 | + // Revision was flagged - switch to unflagging form |
| 245 | + } else { |
| 246 | + legend.innerHTML = '<strong>'+wgAjaxReview.unflagLegMsg+'</strong>'; |
| 247 | + submit.value = wgAjaxReview.unflagMsg; |
| 248 | + } |
| 249 | + } else { |
| 250 | + submit.value = wgAjaxReview.sendMsg; // back to normal |
| 251 | + } |
| 252 | + } |
| 253 | + // Hide "review this" box on diffs |
| 254 | + if( diffNotice ) diffNotice.style.display = 'none'; |
| 255 | + // On failure... |
227 | 256 | } else { |
228 | 257 | document.title = wgAjaxReview.actionfailed; |
229 | | - if( submit ) submit.value = wgAjaxReview.sentMsgBad; |
| 258 | + if( submit ) { |
| 259 | + if( binaryState ) { |
| 260 | + submit.value = binaryState.value ? |
| 261 | + wgAjaxReview.flagMsg : wgAjaxReview.unflagMsg; // back to normal |
| 262 | + } else { |
| 263 | + submit.value = wgAjaxReview.sendMsg; |
| 264 | + } |
| 265 | + } |
230 | 266 | } |
231 | 267 | wgAjaxReview.unlockForm(); |
232 | 268 | }; |
233 | 269 | |
234 | 270 | wgAjaxReview.onLoad = function() { |
235 | | - var submit = document.getElementById("submitreview"); |
| 271 | + var submit = document.getElementById("mw-submitreview"); |
236 | 272 | if( submit ) { |
237 | 273 | submit.onclick = wgAjaxReview.ajaxCall; |
238 | 274 | } |
Index: trunk/extensions/FlaggedRevs/FlaggedArticleView.php |
— | — | @@ -1048,7 +1048,8 @@ |
1049 | 1049 | $dbr = wfGetDB( DB_SLAVE ); |
1050 | 1050 | // Get templates where the current and stable are not the same revision |
1051 | 1051 | $ret = $dbr->select( array('flaggedtemplates','page','flaggedpages'), |
1052 | | - array( 'ft_namespace', 'ft_title', 'fp_stable','ft_tmp_rev_id', 'page_latest' ), |
| 1052 | + array( 'ft_namespace', 'ft_title', 'fp_stable', |
| 1053 | + 'ft_tmp_rev_id','page_latest' ), |
1053 | 1054 | array( 'ft_rev_id' => $frev->getRevId(), |
1054 | 1055 | 'page_namespace = ft_namespace', |
1055 | 1056 | 'page_title = ft_title' ), |
— | — | @@ -1065,11 +1066,13 @@ |
1066 | 1067 | $row->fp_stable : $row->ft_tmp_rev_id; |
1067 | 1068 | // compare to current |
1068 | 1069 | if( $revIdDraft > $revIdStable ) { |
1069 | | - $tmpChanges[] = $skin->makeKnownLinkObj( $title, $title->getPrefixedText(), |
| 1070 | + $tmpChanges[] = $skin->makeKnownLinkObj( $title, |
| 1071 | + $title->getPrefixedText(), |
1070 | 1072 | "diff=cur&oldid={$revIdStable}" ); |
1071 | 1073 | } |
1072 | 1074 | } |
1073 | | - $wgMemc->set( $key, FlaggedRevs::makeMemcObj($tmpChanges), $wgParserCacheExpireTime ); |
| 1075 | + $wgMemc->set( $key, FlaggedRevs::makeMemcObj($tmpChanges), |
| 1076 | + $wgParserCacheExpireTime ); |
1074 | 1077 | } |
1075 | 1078 | # Add set to list |
1076 | 1079 | if( $tmpChanges ) |
— | — | @@ -1086,15 +1089,18 @@ |
1087 | 1090 | if( $imgChanges === false ) { |
1088 | 1091 | $dbr = wfGetDB( DB_SLAVE ); |
1089 | 1092 | // Get images where the current and stable are not the same revision |
1090 | | - $ret = $dbr->select( array('flaggedimages','page','image','flaggedpages','flaggedrevs'), |
| 1093 | + $ret = $dbr->select( |
| 1094 | + array( 'flaggedimages','page','image','flaggedpages','flaggedrevs' ), |
1091 | 1095 | array( 'fi_name', 'fi_img_timestamp', 'fr_img_timestamp' ), |
1092 | 1096 | array( 'fi_rev_id' => $frev->getRevId() ), |
1093 | 1097 | __METHOD__, |
1094 | 1098 | array(), /* OPTIONS */ |
1095 | | - array( 'page' => array('LEFT JOIN','page_namespace = '. NS_FILE .' AND page_title = fi_name'), |
| 1099 | + array( 'page' => array('LEFT JOIN', |
| 1100 | + 'page_namespace = '. NS_FILE .' AND page_title = fi_name'), |
1096 | 1101 | 'image' => array('LEFT JOIN','img_name = fi_name'), |
1097 | 1102 | 'flaggedpages' => array('LEFT JOIN','fp_page_id = page_id'), |
1098 | | - 'flaggedrevs' => array('LEFT JOIN','fr_page_id = fp_page_id AND fr_rev_id = fp_stable') ) |
| 1103 | + 'flaggedrevs' => array('LEFT JOIN', |
| 1104 | + 'fr_page_id = fp_page_id AND fr_rev_id = fp_stable') ) |
1099 | 1105 | ); |
1100 | 1106 | $imgChanges = array(); |
1101 | 1107 | while( $row = $dbr->fetchObject( $ret ) ) { |
— | — | @@ -1320,6 +1326,9 @@ |
1321 | 1327 | public function addQuickReview( &$data, $top = false, $hide = false ) { |
1322 | 1328 | global $wgOut, $wgUser, $wgRequest; |
1323 | 1329 | $this->load(); |
| 1330 | + if( $wgOut->isPrintable() ) { |
| 1331 | + return false; // Must be on non-printable output |
| 1332 | + } |
1324 | 1333 | # Get the revision being displayed |
1325 | 1334 | $id = $wgOut->getRevisionId(); |
1326 | 1335 | if( !$id ) { |
— | — | @@ -1332,13 +1341,13 @@ |
1333 | 1342 | } else { |
1334 | 1343 | $rev = Revision::newFromTitle( $this->article->getTitle(), $id ); |
1335 | 1344 | } |
1336 | | - # Must be a valid non-printable output and revision must be public |
1337 | | - if( $wgOut->isPrintable() || !$rev || $rev->isDeleted(Revision::DELETED_TEXT) ) { |
| 1345 | + # The revision must be valid and public |
| 1346 | + if( !$rev || $rev->isDeleted(Revision::DELETED_TEXT) ) { |
1338 | 1347 | return false; |
1339 | 1348 | } |
1340 | 1349 | $useCurrent = false; |
1341 | 1350 | if( !isset($wgOut->mTemplateIds) || !isset($wgOut->fr_ImageSHA1Keys) ) { |
1342 | | - $useCurrent = true; |
| 1351 | + $useCurrent = true; // we need to get Ids from parser output |
1343 | 1352 | } |
1344 | 1353 | $skin = $wgUser->getSkin(); |
1345 | 1354 | |
— | — | @@ -1346,7 +1355,10 @@ |
1347 | 1356 | # Variable for sites with no flags, otherwise discarded |
1348 | 1357 | $approve = $wgRequest->getBool('wpApprove'); |
1349 | 1358 | # See if the version being displayed is flagged... |
1350 | | - $oldFlags = $this->article->getFlagsForRevision( $id ); |
| 1359 | + $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $id ); |
| 1360 | + $oldFlags = $frev |
| 1361 | + ? $frev->getTags() // existing tags |
| 1362 | + : FlaggedRevision::expandRevisionTags(''); // unset tags |
1351 | 1363 | # If we are reviewing updates to a page, start off with the stable revision's |
1352 | 1364 | # flags. Otherwise, we just fill them in with the selected revision's flags. |
1353 | 1365 | if( $this->isDiffFromStable ) { |
— | — | @@ -1359,11 +1371,12 @@ |
1360 | 1372 | } |
1361 | 1373 | $reviewNotes = $srev->getComment(); |
1362 | 1374 | } else { |
1363 | | - $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $id ); |
1364 | 1375 | $flags = $oldFlags; |
1365 | | - $reviewNotes = $frev ? $frev->getComment() : ""; // pre-fill notes |
| 1376 | + // Get existing notes to pre-fill field |
| 1377 | + $reviewNotes = $frev ? $frev->getComment() : ""; |
1366 | 1378 | } |
1367 | 1379 | |
| 1380 | + # Begin form... |
1368 | 1381 | $reviewTitle = SpecialPage::getTitleFor( 'RevisionReview' ); |
1369 | 1382 | $action = $reviewTitle->getLocalUrl( 'action=submit' ); |
1370 | 1383 | $params = array( 'method' => 'post', 'action' => $action, 'id' => 'mw-reviewform' ); |
— | — | @@ -1371,16 +1384,22 @@ |
1372 | 1385 | $params['class'] = 'fr-hiddenform'; |
1373 | 1386 | } |
1374 | 1387 | $form = Xml::openElement( 'form', $params ); |
1375 | | - $form .= Xml::openElement( 'fieldset', array('class' => 'flaggedrevs_reviewform noprint') ); |
1376 | | - $form .= "<legend><strong>" . wfMsgHtml( 'revreview-flag', $id ) . "</strong></legend>\n"; |
1377 | | - |
| 1388 | + $form .= Xml::openElement( 'fieldset', |
| 1389 | + array('class' => 'flaggedrevs_reviewform noprint') ); |
| 1390 | + # Add appropriate legend text |
| 1391 | + $legendMsg = ( FlaggedRevs::binaryFlagging() && $frev ) |
| 1392 | + ? 'revreview-unflag' |
| 1393 | + : 'revreview-flag'; |
| 1394 | + $form .= Xml::openElement( 'legend', array('id' => 'mw-reviewformlegend') ); |
| 1395 | + $form .= "<strong>" . wfMsgHtml( $legendMsg ) . "</strong>"; |
| 1396 | + $form .= Xml::closeElement( 'legend' ) . "\n"; |
1378 | 1397 | # Show explanatory text |
1379 | 1398 | if( !FlaggedRevs::lowProfileUI() ) { |
1380 | 1399 | $msg = FlaggedRevs::showStableByDefault() ? 'revreview-text' : 'revreview-text2'; |
1381 | 1400 | $form .= wfMsgExt( $msg, array('parse') ); |
1382 | 1401 | } |
1383 | 1402 | |
1384 | | - # Current user has too few rights to change at least one flag, thus entire form disabled |
| 1403 | + # Disable form for unprivileged users |
1385 | 1404 | $uneditable = !$this->article->getTitle()->quickUserCan('edit'); |
1386 | 1405 | $disabled = !RevisionReview::userCanSetFlags( $flags ) || $uneditable; |
1387 | 1406 | if( $disabled ) { |
— | — | @@ -1392,11 +1411,12 @@ |
1393 | 1412 | 'id' => 'fr-rating-controls') ); |
1394 | 1413 | $toggle = array(); |
1395 | 1414 | } |
| 1415 | + |
1396 | 1416 | # Add main checkboxes/selects |
1397 | 1417 | $form .= Xml::openElement( 'span', array('id' => 'mw-ratingselects') ); |
1398 | | - $form .= FlaggedRevsXML::ratingInputs( $flags, $config, $disabled ); |
| 1418 | + $form .= FlaggedRevsXML::ratingInputs( $flags, $config, $disabled, (bool)$frev ); |
1399 | 1419 | $form .= Xml::closeElement( 'span' ); |
1400 | | - |
| 1420 | + # Add review notes input |
1401 | 1421 | if( FlaggedRevs::allowComments() && $wgUser->isAllowed( 'validate' ) ) { |
1402 | 1422 | $form .= "<div id='mw-notebox'>\n"; |
1403 | 1423 | $form .= "<p>".wfMsgHtml( 'revreview-notes' ) . "</p>\n"; |
— | — | @@ -1406,6 +1426,7 @@ |
1407 | 1427 | Xml::closeElement('textarea') . "\n"; |
1408 | 1428 | $form .= "</div>\n"; |
1409 | 1429 | } |
| 1430 | + |
1410 | 1431 | # Get versions of templates/files used |
1411 | 1432 | $imageParams = $templateParams = $fileVersion = ''; |
1412 | 1433 | if( $useCurrent ) { |
— | — | @@ -1433,7 +1454,7 @@ |
1434 | 1455 | FlaggedRevs::getIncludeParams( $this->article, $templateIDs, $imageSHA1Keys ); |
1435 | 1456 | |
1436 | 1457 | $form .= Xml::openElement( 'span', array('style' => 'white-space: nowrap;') ); |
1437 | | - # Hide comment if needed |
| 1458 | + # Hide comment input if needed |
1438 | 1459 | if( !$disabled ) { |
1439 | 1460 | if( count(FlaggedRevs::getDimensions()) > 1 ) |
1440 | 1461 | $form .= "<br />"; // Don't put too much on one line |
— | — | @@ -1441,25 +1462,27 @@ |
1442 | 1463 | Xml::inputLabel( wfMsg('revreview-log'), 'wpReason', 'wpReason', 40, '', |
1443 | 1464 | array('class' => 'fr-comment-box') ) . " </span>"; |
1444 | 1465 | } |
1445 | | - $form .= Xml::submitButton( wfMsg('revreview-submit'), |
| 1466 | + # Add the submit button |
| 1467 | + if( FlaggedRevs::binaryFlagging() ) { |
| 1468 | + $submitMsg = $frev |
| 1469 | + ? 'revreview-submit-unreview' |
| 1470 | + : 'revreview-submit-review'; |
| 1471 | + $titleMsg = $frev |
| 1472 | + ? 'revreview-tt-unreview' |
| 1473 | + : 'revreview-tt-review'; |
| 1474 | + } else { |
| 1475 | + $submitMsg = 'revreview-submit'; |
| 1476 | + $titleMsg = 'revreview-tt-review'; |
| 1477 | + } |
| 1478 | + $form .= Xml::submitButton( wfMsg($submitMsg), |
1446 | 1479 | array( |
1447 | | - 'id' => 'submitreview', 'accesskey' => wfMsg('revreview-ak-review'), |
1448 | | - 'title' => wfMsg('revreview-tt-review').' ['.wfMsg('revreview-ak-review').']' |
| 1480 | + 'id' => 'mw-submitreview', 'accesskey' => wfMsg('revreview-ak-review'), |
| 1481 | + 'title' => wfMsg($titleMsg).' ['.wfMsg('revreview-ak-review').']' |
1449 | 1482 | ) + $toggle |
1450 | 1483 | ); |
| 1484 | + |
1451 | 1485 | $form .= Xml::closeElement( 'span' ); |
1452 | | - |
1453 | 1486 | $form .= Xml::closeElement( 'div' ) . "\n"; |
1454 | | - |
1455 | | - # Show stability log if there is anything interesting... |
1456 | | - if( $this->article->isPageLocked() ) { |
1457 | | - $loglist = new LogEventsList( $wgUser->getSkin(), $wgOut, LogEventsList::NO_ACTION_LINK ); |
1458 | | - $pager = new LogPager( $loglist, 'stable', '', $this->article->getTitle()->getPrefixedDBKey() ); |
1459 | | - $pager->mLimit = 1; // top item |
1460 | | - if( ($logBody = $pager->getBody()) ) { |
1461 | | - $form .= "<div><ul style='list-style:none; margin: 0;'>$logBody</ul></div>"; |
1462 | | - } |
1463 | | - } |
1464 | 1487 | |
1465 | 1488 | # Hidden params |
1466 | 1489 | $form .= Xml::hidden( 'title', $reviewTitle->getPrefixedText() ) . "\n"; |