MediaWiki master
UnblockUser.php
Go to the documentation of this file.
1<?php
2
22namespace MediaWiki\Block;
23
24use ChangeTags;
34
42 private $blockPermissionChecker;
43
45 private $blockStore;
46
48 private $blockUtils;
49
51 private $userFactory;
52
54 private $hookRunner;
55
57 private $target;
58
60 private $targetType;
61
63 private $block;
64
66 private $performer;
67
69 private $reason;
70
72 private $tags = [];
73
85 public function __construct(
86 BlockPermissionCheckerFactory $blockPermissionCheckerFactory,
87 DatabaseBlockStore $blockStore,
88 BlockUtils $blockUtils,
89 UserFactory $userFactory,
90 HookContainer $hookContainer,
91 $target,
92 Authority $performer,
93 string $reason,
94 array $tags = []
95 ) {
96 // Process dependencies
97 $this->blockPermissionChecker = $blockPermissionCheckerFactory
99 $target,
100 $performer
101 );
102 $this->blockStore = $blockStore;
103 $this->blockUtils = $blockUtils;
104 $this->userFactory = $userFactory;
105 $this->hookRunner = new HookRunner( $hookContainer );
106
107 // Process params
108 [ $this->target, $this->targetType ] = $this->blockUtils->parseBlockTarget( $target );
109 if (
110 $this->targetType === AbstractBlock::TYPE_AUTO &&
111 is_numeric( $this->target )
112 ) {
113 // Needed, because BlockUtils::parseBlockTarget will strip the # from autoblocks.
114 $this->target = '#' . $this->target;
115 }
116 $this->block = $this->blockStore->newFromTarget( $this->target );
117 $this->performer = $performer;
118 $this->reason = $reason;
119 $this->tags = $tags;
120 }
121
127 public function unblock(): Status {
128 $status = Status::newGood();
129
130 $basePermissionCheckResult = $this->blockPermissionChecker->checkBasePermissions(
131 $this->block instanceof DatabaseBlock && $this->block->getHideName()
132 );
133 if ( $basePermissionCheckResult !== true ) {
134 return $status->fatal( $basePermissionCheckResult );
135 }
136
137 $blockPermissionCheckResult = $this->blockPermissionChecker->checkBlockPermissions();
138 if ( $blockPermissionCheckResult !== true ) {
139 return $status->fatal( $blockPermissionCheckResult );
140 }
141
142 if ( count( $this->tags ) !== 0 ) {
143 $status->merge(
145 $this->tags,
146 $this->performer
147 )
148 );
149 }
150
151 if ( !$status->isOK() ) {
152 return $status;
153 }
154 return $this->unblockUnsafe();
155 }
156
163 public function unblockUnsafe(): Status {
164 $status = Status::newGood();
165
166 if ( $this->block === null ) {
167 return $status->fatal( 'ipb_cant_unblock', $this->target );
168 }
169
170 if (
171 $this->block->getType() === AbstractBlock::TYPE_RANGE &&
172 $this->targetType === AbstractBlock::TYPE_IP
173 ) {
174 return $status->fatal( 'ipb_blocked_as_range', $this->target, $this->block->getTargetName() );
175 }
176
177 $denyReason = [ 'hookaborted' ];
178 $legacyUser = $this->userFactory->newFromAuthority( $this->performer );
179 if ( !$this->hookRunner->onUnblockUser( $this->block, $legacyUser, $denyReason ) ) {
180 foreach ( $denyReason as $key ) {
181 $status->fatal( $key );
182 }
183 return $status;
184 }
185
186 $deleteBlockStatus = $this->blockStore->deleteBlock( $this->block );
187 if ( !$deleteBlockStatus ) {
188 return $status->fatal( 'ipb_cant_unblock', $this->block->getTargetName() );
189 }
190
191 $this->hookRunner->onUnblockUserComplete( $this->block, $legacyUser );
192
193 // Unset _deleted fields as needed
194 $user = $this->block->getTargetUserIdentity();
195 if ( $this->block->getHideName() && $user ) {
196 $id = $user->getId();
197 RevisionDeleteUser::unsuppressUserName( $user->getName(), $id );
198 }
199
200 $this->log();
201
202 $status->setResult( $status->isOK(), $this->block );
203 return $status;
204 }
205
209 private function log() {
210 // Redact IP for autoblocks
211 if ( $this->block->getType() === DatabaseBlock::TYPE_AUTO ) {
212 $page = TitleValue::tryNew( NS_USER, '#' . $this->block->getId() );
213 } else {
214 $page = TitleValue::tryNew( NS_USER, $this->block->getTargetName() );
215 }
216
217 $logEntry = new ManualLogEntry( 'block', 'unblock' );
218
219 if ( $page !== null ) {
220 $logEntry->setTarget( $page );
221 }
222 $logEntry->setComment( $this->reason );
223 $logEntry->setPerformer( $this->performer->getUser() );
224 $logEntry->addTags( $this->tags );
225 $logEntry->setRelations( [ 'ipb_id' => $this->block->getId() ] );
226 $logId = $logEntry->insert();
227 $logEntry->publish( $logId );
228 }
229
230}
const NS_USER
Definition Defines.php:66
static canAddTagsAccompanyingChange(array $tags, Authority $performer=null, $checkBlock=true)
Is it OK to allow the user to apply all the specified tags at the same time as they edit/make the cha...
Class for creating new log entries and inserting them into the database.
getHideName()
Get whether the block hides the target's username.
Backend class for blocking utils.
A DatabaseBlock (unlike a SystemBlock) is stored in the database, may give rise to autoblocks and may...
Backend class for unblocking users.
__construct(BlockPermissionCheckerFactory $blockPermissionCheckerFactory, DatabaseBlockStore $blockStore, BlockUtils $blockUtils, UserFactory $userFactory, HookContainer $hookContainer, $target, Authority $performer, string $reason, array $tags=[])
unblockUnsafe()
Unblock user without any sort of permission checks.
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:54
Represents the target of a wiki link.
Creates User objects.
Backend functions for suppressing and unsuppressing all references to a given user,...
static unsuppressUserName( $name, $userId, IDatabase $dbw=null)
fatal( $message,... $parameters)
Add an error and set OK to false, indicating that the operation as a whole was fatal.
This interface represents the authority associated with the current execution context,...
Definition Authority.php:37
Interface for objects representing user identity.