MediaWiki master
UnblockUser.php
Go to the documentation of this file.
1<?php
2
22namespace MediaWiki\Block;
23
24use ChangeTags;
34
41 private BlockPermissionChecker $blockPermissionChecker;
42 private DatabaseBlockStore $blockStore;
43 private BlockTargetFactory $blockTargetFactory;
44 private UserFactory $userFactory;
45 private HookRunner $hookRunner;
46
48 private $target;
49
50 private ?DatabaseBlock $block;
51
52 private ?DatabaseBlock $blockToRemove = null;
53
55 private $performer;
56
58 private $reason;
59
61 private $tags = [];
62
75 public function __construct(
76 BlockPermissionCheckerFactory $blockPermissionCheckerFactory,
77 DatabaseBlockStore $blockStore,
78 BlockTargetFactory $blockTargetFactory,
79 UserFactory $userFactory,
80 HookContainer $hookContainer,
81 ?DatabaseBlock $blockToRemove,
82 $target,
83 Authority $performer,
84 string $reason,
85 array $tags = []
86 ) {
87 // Process dependencies
88 $this->blockStore = $blockStore;
89 $this->blockTargetFactory = $blockTargetFactory;
90 $this->userFactory = $userFactory;
91 $this->hookRunner = new HookRunner( $hookContainer );
92
93 // Process params
94 if ( $blockToRemove !== null ) {
95 $this->blockToRemove = $blockToRemove;
96 $this->target = $blockToRemove->getTarget();
97 } elseif ( $target instanceof BlockTarget ) {
98 $this->target = $target;
99 } else {
100 // TODO: deprecate (T382106)
101 $this->target = $this->blockTargetFactory->newFromLegacyUnion( $target );
102 }
103
104 $this->blockPermissionChecker = $blockPermissionCheckerFactory
105 ->newChecker(
106 $performer
107 );
108
109 $this->performer = $performer;
110 $this->reason = $reason;
111 $this->tags = $tags;
112 }
113
117 public function unblock(): Status {
118 $status = Status::newGood();
119
120 $this->block = $this->getBlockToRemove( $status );
121 if ( !$status->isOK() ) {
122 return $status;
123 }
124
125 $blockPermissionCheckResult = $this->blockPermissionChecker->checkBlockPermissions( $this->target );
126 if ( $blockPermissionCheckResult !== true ) {
127 return $status->fatal( $blockPermissionCheckResult );
128 }
129
130 $basePermissionCheckResult = $this->blockPermissionChecker->checkBasePermissions(
131 $this->block instanceof DatabaseBlock && $this->block->getHideName()
132 );
133
134 if ( $basePermissionCheckResult !== true ) {
135 return $status->fatal( $basePermissionCheckResult );
136 }
137
138 if ( count( $this->tags ) !== 0 ) {
139 $status->merge(
141 $this->tags,
142 $this->performer
143 )
144 );
145 }
146
147 if ( !$status->isOK() ) {
148 return $status;
149 }
150
151 return $this->unblockUnsafe();
152 }
153
160 public function unblockUnsafe(): Status {
161 $status = Status::newGood();
162
163 $this->block ??= $this->getBlockToRemove( $status );
164 if ( !$status->isOK() ) {
165 return $status;
166 }
167
168 if ( $this->block === null ) {
169 return $status->fatal( 'ipb_cant_unblock', $this->target );
170 }
171
172 if (
173 $this->block->getType() === AbstractBlock::TYPE_RANGE &&
174 $this->target->getType() === AbstractBlock::TYPE_IP
175 ) {
176 return $status->fatal( 'ipb_blocked_as_range', $this->target, $this->block->getTargetName() );
177 }
178
179 $denyReason = [ 'hookaborted' ];
180 $legacyUser = $this->userFactory->newFromAuthority( $this->performer );
181 if ( !$this->hookRunner->onUnblockUser( $this->block, $legacyUser, $denyReason ) ) {
182 foreach ( $denyReason as $key ) {
183 $status->fatal( $key );
184 }
185 return $status;
186 }
187
188 $deleteBlockStatus = $this->blockStore->deleteBlock( $this->block );
189 if ( !$deleteBlockStatus ) {
190 return $status->fatal( 'ipb_cant_unblock', $this->block->getTargetName() );
191 }
192
193 $this->hookRunner->onUnblockUserComplete( $this->block, $legacyUser );
194
195 // Unset _deleted fields as needed
196 $user = $this->block->getTargetUserIdentity();
197 if ( $this->block->getHideName() && $user ) {
198 $id = $user->getId();
199 RevisionDeleteUser::unsuppressUserName( $user->getName(), $id );
200 }
201
202 $this->log();
203
204 $status->setResult( $status->isOK(), $this->block );
205 return $status;
206 }
207
211 private function log() {
212 $page = $this->block->getRedactedTarget()->getLogPage();
213 $logEntry = new ManualLogEntry( 'block', 'unblock' );
214
215 $logEntry->setTarget( $page );
216 $logEntry->setComment( $this->reason );
217 $logEntry->setPerformer( $this->performer->getUser() );
218 $logEntry->addTags( $this->tags );
219 $logEntry->setRelations( [ 'ipb_id' => $this->block->getId() ] );
220 // Save the ID to log_params, since MW 1.44
221 $logEntry->addParameter( 'blockId', $this->block->getId() );
222 $logId = $logEntry->insert();
223 $logEntry->publish( $logId );
224 }
225
226 private function getBlockToRemove( Status $status ): ?DatabaseBlock {
227 if ( $this->blockToRemove !== null ) {
228 return $this->blockToRemove;
229 }
230
231 $activeBlocks = $this->blockStore->newListFromTarget( $this->target );
232 if ( !$activeBlocks ) {
233 $status->fatal( 'ipb_cant_unblock', $this->target );
234 return null;
235 }
236
237 if ( count( $activeBlocks ) > 1 ) {
238 $status->fatal( 'ipb_cant_unblock_multiple_blocks',
239 count( $activeBlocks ), Message::listParam(
240 array_map(
241 static function ( $block ) {
242 return $block->getId();
243 }, $activeBlocks )
244 )
245 );
246 }
247
248 return $activeBlocks[0];
249 }
250}
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:81
Recent changes tagging.
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...
getTarget()
Get the target as an object.
Factory for BlockTarget objects.
Base class for block targets.
A DatabaseBlock (unlike a SystemBlock) is stored in the database, may give rise to autoblocks and may...
getId( $wikiId=self::LOCAL)
Get the block ID.?int
Backend class for unblocking users.
__construct(BlockPermissionCheckerFactory $blockPermissionCheckerFactory, DatabaseBlockStore $blockStore, BlockTargetFactory $blockTargetFactory, UserFactory $userFactory, HookContainer $hookContainer, ?DatabaseBlock $blockToRemove, $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...
Class for creating new log entries and inserting them into the database.
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition Message.php:155
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:54
Create User objects.
Backend functions for suppressing and unsuppressing all references to a given user,...
static unsuppressUserName( $name, $userId, ?IDatabase $dbw=null)
This interface represents the authority associated with the current execution context,...
Definition Authority.php:37
Interface for objects representing user identity.