r85166 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r85165‎ | r85166 | r85167 >
Date:23:13, 1 April 2011
Author:happy-melon
Status:resolved (Comments)
Tags:
Comment:
Follow-up r85025: fix the you're-trying-to-block-yourself-you-twit warning, and make it an actual checkbox confirmation. Also use said confirmation for reblocks, and HideUser (bug 18678). Mark a static function from HTMLForm which is called from SpecialBlock as explicitly public.
Modified paths:
  • /trunk/phase3/includes/HTMLForm.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialBlock.php (modified) (history)
  • /trunk/phase3/languages/messages/MessagesEn.php (modified) (history)
  • /trunk/phase3/maintenance/language/messages.inc (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/language/messages.inc
@@ -2070,10 +2070,12 @@
20712071 'ipbwatchuser',
20722072 'ipb-disableusertalk',
20732073 'ipb-change-block',
 2074+ 'ipb-confirm',
20742075 'badipaddress',
20752076 'blockipsuccesssub',
20762077 'blockipsuccesstext',
20772078 'ipb-blockingself',
 2079+ 'ipb-confirmhideuser',
20782080 'ipb-edit-dropdown',
20792081 'ipb-unblock-addr',
20802082 'ipb-unblock',
Index: trunk/phase3/includes/HTMLForm.php
@@ -522,7 +522,7 @@
523523 * @param $errors Array of message keys/values
524524 * @return String HTML, a <ul> list of errors
525525 */
526 - static function formatErrors( $errors ) {
 526+ public static function formatErrors( $errors ) {
527527 $errorstr = '';
528528
529529 foreach ( $errors as $error ) {
Index: trunk/phase3/includes/specials/SpecialBlock.php
@@ -40,8 +40,17 @@
4141 /// @var Block::TYPE_ constant
4242 protected $type;
4343
 44+ /// @var User|String the previous block target
 45+ protected $previousTarget;
 46+
 47+ /// @var Bool whether the previous submission of the form asked for HideUser
 48+ protected $requestedHideUser;
 49+
4450 /// @var Bool
4551 protected $alreadyBlocked;
 52+
 53+ /// @var Array
 54+ protected $preErrors = array();
4655
4756 public function __construct() {
4857 parent::__construct( 'Block', 'block' );
@@ -71,6 +80,9 @@
7281 $wgUser->getSkin()->setRelevantUser( $this->target );
7382 }
7483
 84+ list( $this->previousTarget, /*...*/ ) = Block::parseTarget( $wgRequest->getVal( 'wpPreviousTarget' ) );
 85+ $this->requestedHideUser = $wgRequest->getBool( 'wpHideUser' );
 86+
7587 # bug 15810: blocked admins should have limited access here
7688 $status = self::checkUnblockSelf( $this->target );
7789 if ( $status !== true ) {
@@ -81,7 +93,7 @@
8294 $wgOut->addModules( 'mediawiki.special', 'mediawiki.special.block' );
8395
8496 $fields = self::getFormFields();
85 - $this->alreadyBlocked = $this->maybeAlterFormDefaults( $fields );
 97+ $this->maybeAlterFormDefaults( $fields );
8698
8799 $form = new HTMLForm( $fields );
88100 $form->setTitle( $this->getTitle() );
@@ -94,6 +106,7 @@
95107 $form->setSubmitText( $t );
96108
97109 $this->doPreText( $form );
 110+ $this->doHeadertext( $form );
98111 $this->doPostText( $form );
99112
100113 if( $form->show() ){
@@ -183,11 +196,20 @@
184197 'default' => false,
185198 );
186199
187 - $a['AlreadyBlocked'] = array(
 200+ # This is basically a copy of the Target field, but the user can't change it, so we
 201+ # can see if the warnings we maybe showed to the user before still apply
 202+ $a['PreviousTarget'] = array(
188203 'type' => 'hidden',
189204 'default' => false,
190205 );
191206
 207+ # We'll turn this into a checkbox if we need to
 208+ $a['Confirm'] = array(
 209+ 'type' => 'hidden',
 210+ 'default' => '',
 211+ 'label-message' => 'ipb-confirm',
 212+ );
 213+
192214 return $a;
193215 }
194216
@@ -199,8 +221,14 @@
200222 * already blocked)
201223 */
202224 protected function maybeAlterFormDefaults( &$fields ){
 225+ global $wgRequest, $wgUser;
 226+
 227+ # This will be overwritten by request data
203228 $fields['Target']['default'] = (string)$this->target;
204229
 230+ # This won't be
 231+ $fields['PreviousTarget']['default'] = (string)$this->target;
 232+
205233 $block = Block::newFromTarget( $this->target );
206234
207235 if( $block instanceof Block && !$block->mAuto # The block exists and isn't an autoblock
@@ -221,17 +249,41 @@
222250 $fields['DisableUTEdit']['default'] = $block->prevents( 'editownusertalk' );
223251 }
224252 $fields['Reason']['default'] = $block->mReason;
225 - $fields['AlreadyBlocked']['default'] = htmlspecialchars( $block->getTarget() );
226253
 254+ if( $wgRequest->wasPosted() ){
 255+ # Ok, so we got a POST submission asking us to reblock a user. So show the
 256+ # confirm checkbox; the user will only see it if they haven't previously
 257+ $fields['Confirm']['type'] = 'check';
 258+ } else {
 259+ # We got a target, but it wasn't a POST request, so the user must have gone
 260+ # to a link like [[Special:Block/User]]. We don't need to show the checkbox
 261+ # as long as they go ahead and block *that* user
 262+ $fields['Confirm']['default'] = 1;
 263+ }
 264+
227265 if( $block->mExpiry == 'infinity' ) {
228266 $fields['Expiry']['default'] = 'indefinite';
229267 } else {
230268 $fields['Expiry']['default'] = wfTimestamp( TS_RFC2822, $block->mExpiry );
231269 }
232270
233 - return true;
 271+ $this->alreadyBlocked = true;
 272+ $this->preErrors[] = array( 'ipb-needreblock', (string)$block->getTarget() );
234273 }
235 - return false;
 274+
 275+ # We always need confirmation to do HideUser
 276+ if( $this->requestedHideUser ){
 277+ $fields['Confirm']['type'] = 'check';
 278+ unset( $fields['Confirm']['default'] );
 279+ $this->preErrors[] = 'ipb-confirmhideuser';
 280+ }
 281+
 282+ # Or if the user is trying to block themselves
 283+ if( (string)$this->target === $wgUser->getName() ){
 284+ $fields['Confirm']['type'] = 'check';
 285+ unset( $fields['Confirm']['default'] );
 286+ $this->preErrors[] = 'ipb-blockingself';
 287+ }
236288 }
237289
238290 /**
@@ -265,17 +317,25 @@
266318 $form->addPreText( $s );
267319 }
268320 }
 321+ }
269322
270 - # Username/IP is blocked already locally
271 - if( $this->alreadyBlocked ) {
272 - $form->addPreText( Html::rawElement(
273 - 'div',
274 - array( 'class' => 'mw-ipb-needreblock', ),
275 - wfMsgExt(
276 - 'ipb-needreblock',
277 - array( 'parseinline' ),
278 - $this->target
279 - ) ) );
 323+ /**
 324+ * Add header text inside the form, just underneath where the errors would go
 325+ * @param $form HTMLForm
 326+ * @return void
 327+ */
 328+ protected function doHeaderText( HTMLForm &$form ){
 329+ global $wgRequest;
 330+ # Don't need to do anything if the form has been posted
 331+ if( !$wgRequest->wasPosted() && $this->preErrors ){
 332+ $s = HTMLForm::formatErrors( $this->preErrors );
 333+ if( $s ){
 334+ $form->addHeaderText( Html::rawElement(
 335+ 'div',
 336+ array( 'class' => 'error' ),
 337+ $s
 338+ ) );
 339+ }
280340 }
281341 }
282342
@@ -481,6 +541,10 @@
482542 // Handled by field validator callback
483543 // self::validateTargetField( $data['Target'] );
484544
 545+ # This might have been a hidden field or a checkbox, so interesting data
 546+ # can come from it
 547+ $data['Confirm'] = !in_array( $data['Confirm'], array( '', '0', null, false ), true );
 548+
485549 list( $target, $type ) = self::getTargetAndType( $data['Target'] );
486550 if( $type == Block::TYPE_USER ){
487551 $user = $target;
@@ -490,8 +554,7 @@
491555 # Give admins a heads-up before they go and block themselves. Much messier
492556 # to do this for IPs, but it's pretty unlikely they'd ever get the 'block'
493557 # permission anyway, although the code does allow for it
494 - if( $target === $wgUser->getName()
495 - && $data['AlreadyBlocked'] != htmlspecialchars( $wgUser->getName() ) )
 558+ if( $target === $wgUser->getName() && ( $data['PreviousTarget'] != $data['Target'] || !$data['Confirm'] ) )
496559 {
497560 return array( 'ipb-blockingself' );
498561 }
@@ -544,6 +607,9 @@
545608 # Typically, the user should have a handful of edits.
546609 # Disallow hiding users with many edits for performance.
547610 return array( 'ipb_hide_invalid' );
 611+
 612+ } elseif( !$data['Confirm'] ){
 613+ return array( 'ipb-confirmhideuser' );
548614 }
549615 }
550616
@@ -568,7 +634,7 @@
569635 $status = $block->insert();
570636 if( !$status ) {
571637 # Show form unless the user is already aware of this...
572 - if( $data['AlreadyBlocked'] != htmlspecialchars( $block->getTarget() ) ) {
 638+ if( ( $data['PreviousTarget'] != htmlspecialchars( $block->getTarget() ) ) || !$data['Confirm'] ) {
573639 return array( array( 'ipb_already_blocked', $block->getTarget() ) );
574640 # Otherwise, try to update the block...
575641 } else {
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -3056,11 +3056,13 @@
30573057 'ipbwatchuser' => "Watch this user's user and talk pages",
30583058 'ipb-disableusertalk' => 'Prevent this user from editing their own talk page while blocked',
30593059 'ipb-change-block' => 'Re-block the user with these settings',
 3060+'ipb-confirm' => 'Confirm block',
30603061 'badipaddress' => 'Invalid IP address',
30613062 'blockipsuccesssub' => 'Block succeeded',
30623063 'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] has been blocked.<br />
30633064 See [[Special:IPBlockList|IP block list]] to review blocks.',
30643065 'ipb-blockingself' => 'You are about to block yourself! Are you sure you want to do that?',
 3066+'ipb-confirmhideuser' => 'You are about to block a user with "hide user" enabled. This will suppress the user\'s name in all lists and log entries. Are you sure you want to do that?',
30653067 'ipb-edit-dropdown' => 'Edit block reasons',
30663068 'ipb-unblock-addr' => 'Unblock $1',
30673069 'ipb-unblock' => 'Unblock a username or IP address',
@@ -3126,13 +3128,10 @@
31273129 'ipb_expiry_temp' => 'Hidden username blocks must be permanent.',
31283130 'ipb_hide_invalid' => 'Unable to suppress this account; it may have too many edits.',
31293131 'ipb_already_blocked' => '"$1" is already blocked',
3130 -'ipb-needreblock' => '== Already blocked ==
3131 -$1 is already blocked.
3132 -Do you want to change the settings?',
 3132+'ipb-needreblock' => '$1 is already blocked. Do you want to change the settings?',
31333133 'ipb-otherblocks-header' => 'Other {{PLURAL:$1|block|blocks}}',
31343134 'unblock-hideuser' => 'You cannot unblock this user, as their username has been hidden.',
3135 -'ipb_cant_unblock' => 'Error: Block ID $1 not found.
3136 -It may have been unblocked already.',
 3135+'ipb_cant_unblock' => 'Error: Block ID $1 not found. It may have been unblocked already.',
31373136 'ipb_blocked_as_range' => 'Error: The IP address $1 is not blocked directly and cannot be unblocked.
31383137 It is, however, blocked as part of the range $2, which can be unblocked.',
31393138 'ip_range_invalid' => 'Invalid IP range.',

Sign-offs

UserFlagDate
Werdnainspected17:55, 15 July 2011

Follow-up revisions

RevisionCommit summaryAuthorDate
r85618Various fixes for PHPUnit tests:...pcopp14:54, 7 April 2011
r94235Followup r85025, r85166, r93233: use strict comparison per CR comment, becaus...catrope10:33, 11 August 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r85025(bug 23408) give admins a warning before letting them block themselves. Also...happy-melon18:00, 30 March 2011

Comments

#Comment by Aaron Schulz (talk | contribs)   19:04, 18 June 2011
$data['PreviousTarget'] != htmlspecialchars( $block->getTarget() )

I can't quite tell why htmlspecialchars is needed here.

#Comment by Werdna (talk | contribs)   17:55, 15 July 2011

Looks good other than the double escaping (which you've compensated for).

#Comment by Catrope (talk | contribs)   10:24, 11 August 2011

Comment from the future? Double-escaping wasn't fixed until r93233 :D

Status & tagging log