MediaWiki REL1_34
SpecialUnblock.php
Go to the documentation of this file.
1<?php
26
33
34 protected $target;
35 protected $type;
36 protected $block;
37
38 public function __construct() {
39 parent::__construct( 'Unblock', 'block' );
40 }
41
42 public function doesWrites() {
43 return true;
44 }
45
46 public function execute( $par ) {
47 $this->checkPermissions();
48 $this->checkReadOnly();
49
50 list( $this->target, $this->type ) = SpecialBlock::getTargetAndType( $par, $this->getRequest() );
51 $this->block = DatabaseBlock::newFromTarget( $this->target );
52 if ( $this->target instanceof User ) {
53 # Set the 'relevant user' in the skin, so it displays links like Contributions,
54 # User logs, UserRights, etc.
55 $this->getSkin()->setRelevantUser( $this->target );
56 }
57
58 $this->setHeaders();
59 $this->outputHeader();
60 $this->addHelpLink( 'Help:Blocking users' );
61
62 $out = $this->getOutput();
63 $out->setPageTitle( $this->msg( 'unblockip' ) );
64 $out->addModules( [ 'mediawiki.userSuggest' ] );
65
66 $form = HTMLForm::factory( 'ooui', $this->getFields(), $this->getContext() );
67 $form->setWrapperLegendMsg( 'unblockip' );
68 $form->setSubmitCallback( [ __CLASS__, 'processUIUnblock' ] );
69 $form->setSubmitTextMsg( 'ipusubmit' );
70 $form->addPreText( $this->msg( 'unblockiptext' )->parseAsBlock() );
71
72 if ( $form->show() ) {
73 switch ( $this->type ) {
74 case DatabaseBlock::TYPE_IP:
75 $out->addWikiMsg( 'unblocked-ip', wfEscapeWikiText( $this->target ) );
76 break;
77 case DatabaseBlock::TYPE_USER:
78 $out->addWikiMsg( 'unblocked', wfEscapeWikiText( $this->target ) );
79 break;
80 case DatabaseBlock::TYPE_RANGE:
81 $out->addWikiMsg( 'unblocked-range', wfEscapeWikiText( $this->target ) );
82 break;
83 case DatabaseBlock::TYPE_ID:
84 case DatabaseBlock::TYPE_AUTO:
85 $out->addWikiMsg( 'unblocked-id', wfEscapeWikiText( $this->target ) );
86 break;
87 }
88 }
89 }
90
91 protected function getFields() {
92 $fields = [
93 'Target' => [
94 'type' => 'text',
95 'label-message' => 'ipaddressorusername',
96 'autofocus' => true,
97 'size' => '45',
98 'required' => true,
99 'cssclass' => 'mw-autocomplete-user', // used by mediawiki.userSuggest
100 ],
101 'Name' => [
102 'type' => 'info',
103 'label-message' => 'ipaddressorusername',
104 ],
105 'Reason' => [
106 'type' => 'text',
107 'label-message' => 'ipbreason',
108 ]
109 ];
110
111 if ( $this->block instanceof DatabaseBlock ) {
112 list( $target, $type ) = $this->block->getTargetAndType();
113
114 # Autoblocks are logged as "autoblock #123 because the IP was recently used by
115 # User:Foo, and we've just got any block, auto or not, that applies to a target
116 # the user has specified. Someone could be fishing to connect IPs to autoblocks,
117 # so don't show any distinction between unblocked IPs and autoblocked IPs
118 if ( $type == DatabaseBlock::TYPE_AUTO && $this->type == DatabaseBlock::TYPE_IP ) {
119 $fields['Target']['default'] = $this->target;
120 unset( $fields['Name'] );
121 } else {
122 $fields['Target']['default'] = $target;
123 $fields['Target']['type'] = 'hidden';
124 switch ( $type ) {
125 case DatabaseBlock::TYPE_IP:
126 $fields['Name']['default'] = $this->getLinkRenderer()->makeKnownLink(
127 SpecialPage::getTitleFor( 'Contributions', $target->getName() ),
128 $target->getName()
129 );
130 $fields['Name']['raw'] = true;
131 break;
132 case DatabaseBlock::TYPE_USER:
133 $fields['Name']['default'] = $this->getLinkRenderer()->makeLink(
134 $target->getUserPage(),
135 $target->getName()
136 );
137 $fields['Name']['raw'] = true;
138 break;
139
140 case DatabaseBlock::TYPE_RANGE:
141 $fields['Name']['default'] = $target;
142 break;
143
144 case DatabaseBlock::TYPE_AUTO:
145 $fields['Name']['default'] = $this->block->getRedactedName();
146 $fields['Name']['raw'] = true;
147 # Don't expose the real target of the autoblock
148 $fields['Target']['default'] = "#{$this->target}";
149 break;
150 }
151 // target is hidden, so the reason is the first element
152 $fields['Target']['autofocus'] = false;
153 $fields['Reason']['autofocus'] = true;
154 }
155 } else {
156 $fields['Target']['default'] = $this->target;
157 unset( $fields['Name'] );
158 }
159
160 return $fields;
161 }
162
169 public static function processUIUnblock( array $data, HTMLForm $form ) {
170 return self::processUnblock( $data, $form->getContext() );
171 }
172
184 public static function processUnblock( array $data, IContextSource $context ) {
185 $performer = $context->getUser();
186 $target = $data['Target'];
187 $block = DatabaseBlock::newFromTarget( $data['Target'] );
188
189 if ( !$block instanceof DatabaseBlock ) {
190 return [ [ 'ipb_cant_unblock', $target ] ];
191 }
192
193 # T17810: blocked admins should have limited access here. This
194 # won't allow sysops to remove autoblocks on themselves, but they
195 # should have ipblock-exempt anyway
196 $status = SpecialBlock::checkUnblockSelf( $target, $performer );
197 if ( $status !== true ) {
198 throw new ErrorPageError( 'badaccess', $status );
199 }
200
201 # If the specified IP is a single address, and the block is a range block, don't
202 # unblock the whole range.
203 list( $target, $type ) = SpecialBlock::getTargetAndType( $target );
204 if ( $block->getType() == DatabaseBlock::TYPE_RANGE && $type == DatabaseBlock::TYPE_IP ) {
205 $range = $block->getTarget();
206
207 return [ [ 'ipb_blocked_as_range', $target, $range ] ];
208 }
209
210 # If the name was hidden and the blocking user cannot hide
211 # names, then don't allow any block removals...
212 if ( !MediaWikiServices::getInstance()
213 ->getPermissionManager()
214 ->userHasRight( $performer, 'hideuser' ) && $block->getHideName()
215 ) {
216 return [ 'unblock-hideuser' ];
217 }
218
219 $reason = [ 'hookaborted' ];
220 if ( !Hooks::run( 'UnblockUser', [ &$block, &$performer, &$reason ] ) ) {
221 return $reason;
222 }
223
224 # Delete block
225 if ( !$block->delete() ) {
226 return [ [ 'ipb_cant_unblock', htmlspecialchars( $block->getTarget() ) ] ];
227 }
228
229 Hooks::run( 'UnblockUserComplete', [ $block, $performer ] );
230
231 # Unset _deleted fields as needed
232 if ( $block->getHideName() ) {
233 # Something is deeply FUBAR if this is not a User object, but who knows?
234 $id = $block->getTarget() instanceof User
235 ? $block->getTarget()->getId()
236 : User::idFromName( $block->getTarget() );
237
238 RevisionDeleteUser::unsuppressUserName( $block->getTarget(), $id );
239 }
240
241 # Redact the name (IP address) for autoblocks
242 if ( $block->getType() == DatabaseBlock::TYPE_AUTO ) {
243 $page = Title::makeTitle( NS_USER, '#' . $block->getId() );
244 } else {
245 $page = $block->getTarget() instanceof User
246 ? $block->getTarget()->getUserPage()
247 : Title::makeTitle( NS_USER, $block->getTarget() );
248 }
249
250 # Make log entry
251 $logEntry = new ManualLogEntry( 'block', 'unblock' );
252 $logEntry->setTarget( $page );
253 $logEntry->setComment( $data['Reason'] );
254 $logEntry->setPerformer( $performer );
255 if ( isset( $data['Tags'] ) ) {
256 $logEntry->addTags( $data['Tags'] );
257 }
258 $logEntry->setRelations( [ 'ipb_id' => $block->getId() ] );
259 $logId = $logEntry->insert();
260 $logEntry->publish( $logId );
261
262 return true;
263 }
264
273 public function prefixSearchSubpages( $search, $limit, $offset ) {
274 $user = User::newFromName( $search );
275 if ( !$user ) {
276 // No prefix suggestion for invalid user
277 return [];
278 }
279 // Autocomplete subpage as user list - public to allow caching
280 return UserNamePrefixSearch::search( 'public', $search, $limit, $offset );
281 }
282
283 protected function getGroupName() {
284 return 'users';
285 }
286}
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
A DatabaseBlock (unlike a SystemBlock) is stored in the database, may give rise to autoblocks and may...
MediaWikiServices is the service locator for the application scope of MediaWiki.
static getTargetAndType( $par, WebRequest $request=null)
Determine the target of the block, and the type of target.
Parent class for all special pages.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getOutput()
Get the OutputPage being used for this instance.
getSkin()
Shortcut to get the skin being used for this instance.
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getRequest()
Get the WebRequest being used for this instance.
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
A special page for unblocking users.
doesWrites()
Indicates whether this special page may perform database writes.
execute( $par)
Default execute method Checks user permissions.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:51