(bug 17831) Go ahead and hide where the username appears as needed. Also, don't let...
authorAaron Schulz <aaron@users.mediawiki.org>
Fri, 20 Mar 2009 20:19:38 +0000 (20:19 +0000)
committerAaron Schulz <aaron@users.mediawiki.org>
Fri, 20 Mar 2009 20:19:38 +0000 (20:19 +0000)
includes/specials/SpecialBlockip.php
languages/messages/MessagesEn.php

index 5baec02..56f0ece 100644 (file)
@@ -394,6 +394,16 @@ class IPBlockForm {
                        return array('ipb_expiry_invalid');
                }
                
+               if( $this->BlockHideName ) {
+                       if( !$userId ) {
+                               // IP users should not be hidden
+                               $this->BlockHideName = false;
+                       } else if( $expiry !== 'infinity' ) {
+                               // Bad expiry.
+                               return array('ipb_expiry_temp');
+                       }
+               }
+               
                if( $this->BlockHideName && $expiry != 'infinity' ) {
                        // Bad expiry.
                        return array('ipb_expiry_temp');
@@ -410,10 +420,12 @@ class IPBlockForm {
                # Should this be privately logged?
                $suppressLog = (bool)$this->BlockHideName;
                if ( wfRunHooks('BlockIp', array(&$block, &$wgUser)) ) {
-
+                       # Try to insert block. Is there a conflicting block?
                        if ( !$block->insert() ) {
+                               # Show form unless the user is already aware of this...
                                if ( !$this->BlockReblock ) {
                                        return array( 'ipb_already_blocked' );
+                               # Otherwise, try to update the block...
                                } else {
                                        # This returns direct blocks before autoblocks/rangeblocks, since we should
                                        # be sure the user is blocked by now it should work for our purposes
@@ -421,16 +433,31 @@ class IPBlockForm {
                                        if( $block->equals( $currentBlock ) ) {
                                                return array( 'ipb_already_blocked' );
                                        }
-                                       $suppressLog = $suppressLog || (bool)$currentBlock->mHideName;
+                                       # If the name was hidden and the blocking user cannot hide
+                                       # names, then don't allow any block changes...
+                                       if( $currentBlock->mHideName && !$wgUser->isAllowed('hideuser') ) {
+                                               return array( 'hookaborted' );
+                                       }
                                        $currentBlock->delete();
                                        $block->insert();
+                                       # If hiding/unhiding a name, this should go in the private logs
+                                       $suppressLog = $suppressLog || (bool)$currentBlock->mHideName;
                                        $log_action = 'reblock';
+                                       # Unset _deleted fields if requested
+                                       if( $currentBlock->mHideName && !$this->BlockHideName ) {
+                                               $this->unsuppressUserName( $this->BlockAddress, $userId );
+                                       }
                                }
                        } else {
                                $log_action = 'block';
                        }
                        wfRunHooks('BlockIpComplete', array($block, $wgUser));
 
+                       # Set *_deleted fields if requested
+                       if( $this->BlockHideName ) {
+                               $this->suppressUserName( $this->BlockAddress, $userId );
+                       }
+
                        if ( $this->BlockWatchUser &&
                                # Only show watch link when this is no range block
                                $block->mRangeStart == $block->mRangeEnd) {
@@ -454,9 +481,57 @@ class IPBlockForm {
 
                        # Report to the user
                        return array();
-               }
-               else
+               } else {
                        return array('hookaborted');
+               }
+       }
+       
+       private function suppressUserName( $name, $userId ) {
+               $op = '|'; // bitwise OR
+               return $this->setUsernameBitfields( $name, $userId, $op );
+       }
+       
+       private function unsuppressUserName( $name, $userId ) {
+               $op = '&'; // bitwise AND
+               return $this->setUsernameBitfields( $name, $userId, $op );
+       }
+       
+       private function setUsernameBitfields( $name, $userId, $op ) {
+               if( $op !== '|' && $op !== '&' )
+                       return false; // sanity check
+               // Typically, the user should have a handful of edits.
+               // Disallow hiding users with many edits for performance.
+               if( User::edits($userId) > 3000 ) {
+                       return false;
+               }
+               $dbw = wfGetDB( DB_MASTER );
+               $delUser = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+               # To suppress, we OR the current bitfields with Revision::DELETED_USER
+               # to put a 1 in the username *_deleted bit. To unsuppress we AND the
+               # current bitfields with the inverse of Revision::DELETED_USER. The
+               # username bit is made to 0 (x & 0 = 0), while others are unchanged (x & 1 = x).
+               # The same goes for the sysop-restricted *_deleted bit.
+               if( $op == '&' ) $delUser = "~{$delUser}";
+               # Hide name from live edits
+               $dbw->update( 'revision', array("rev_deleted = rev_deleted $op $delUser"),
+                       array('rev_user' => $userId), __METHOD__ );
+               # Hide name from deleted edits
+               $dbw->update( 'archive', array("ar_deleted = ar_deleted $op $delUser"),
+                       array('ar_user_text' => $userId), __METHOD__ );
+               # Hide name from logs
+               $dbw->update( 'logging', array("log_deleted = log_deleted $op $delUser"),
+                       array('log_user' => $userId), __METHOD__ );
+               # Hide name from RC
+               $dbw->update( 'recentchanges', array("rc_deleted = rc_deleted $op $delUser"),
+                       array('rc_user_text' => $name), __METHOD__ );
+               # Hide name from live images
+               $dbw->update( 'oldimage', array("oi_deleted = oi_deleted $op $delUser"),
+                       array('oi_user_text' => $name), __METHOD__ );
+               # Hide name from deleted images
+               $dbw->update( 'filearchive', array("fa_deleted = fa_deleted $op $delUser"),
+                       array('fa_user_text' => $name), __METHOD__ );
+               # Done!
+               return true;
        }
 
        /**
index d192818..93bdb5d 100644 (file)
@@ -2631,7 +2631,7 @@ Fill in a specific reason below (for example, citing particular pages that were
 'ipboptions'                      => '2 hours:2 hours,1 day:1 day,3 days:3 days,1 week:1 week,2 weeks:2 weeks,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year,infinite:infinite', # display1:time1,display2:time2,...
 'ipbotheroption'                  => 'other',
 'ipbotherreason'                  => 'Other/additional reason:',
-'ipbhidename'                     => 'Hide username from the block log, active block list and user list',
+'ipbhidename'                     => 'Hide username from edits and lists',
 'ipbwatchuser'                    => "Watch this user's user and talk pages",
 'ipballowusertalk'                => 'Allow this user to edit own talk page while blocked',
 'ipb-change-block'                => 'Re-block the user with these settings',