MediaWiki master
UnblockUser.php
Go to the documentation of this file.
1<?php
2
8namespace MediaWiki\Block;
9
20
27 private BlockPermissionChecker $blockPermissionChecker;
28 private DatabaseBlockStore $blockStore;
29 private BlockTargetFactory $blockTargetFactory;
30 private UserFactory $userFactory;
31 private HookRunner $hookRunner;
32
34 private $target;
35
36 private ?DatabaseBlock $block;
37
38 private ?DatabaseBlock $blockToRemove = null;
39
41 private $performer;
42
44 private $reason;
45
47 private $tags = [];
48
61 public function __construct(
62 BlockPermissionCheckerFactory $blockPermissionCheckerFactory,
63 DatabaseBlockStore $blockStore,
64 BlockTargetFactory $blockTargetFactory,
65 UserFactory $userFactory,
66 HookContainer $hookContainer,
67 ?DatabaseBlock $blockToRemove,
68 $target,
69 Authority $performer,
70 string $reason,
71 array $tags = []
72 ) {
73 // Process dependencies
74 $this->blockStore = $blockStore;
75 $this->blockTargetFactory = $blockTargetFactory;
76 $this->userFactory = $userFactory;
77 $this->hookRunner = new HookRunner( $hookContainer );
78
79 // Process params
80 if ( $blockToRemove !== null ) {
81 $this->blockToRemove = $blockToRemove;
82 $this->target = $blockToRemove->getTarget();
83 } elseif ( $target instanceof BlockTarget ) {
84 $this->target = $target;
85 } else {
86 // TODO: deprecate (T382106)
87 $this->target = $this->blockTargetFactory->newFromLegacyUnion( $target );
88 }
89
90 $this->blockPermissionChecker = $blockPermissionCheckerFactory
91 ->newChecker(
92 $performer
93 );
94
95 $this->performer = $performer;
96 $this->reason = $reason;
97 $this->tags = $tags;
98 }
99
103 public function unblock(): Status {
104 $status = Status::newGood();
105
106 $this->block = $this->getBlockToRemove( $status );
107 if ( !$status->isOK() ) {
108 return $status;
109 }
110
111 $blockPermissionCheckResult = $this->blockPermissionChecker->checkBlockPermissions( $this->target );
112 if ( $blockPermissionCheckResult !== true ) {
113 return $status->fatal( $blockPermissionCheckResult );
114 }
115
116 $basePermissionCheckResult = $this->blockPermissionChecker->checkBasePermissions(
117 $this->block instanceof DatabaseBlock && $this->block->getHideName()
118 );
119
120 if ( $basePermissionCheckResult !== true ) {
121 return $status->fatal( $basePermissionCheckResult );
122 }
123
124 if ( count( $this->tags ) !== 0 ) {
125 $status->merge(
126 ChangeTags::canAddTagsAccompanyingChange(
127 $this->tags,
128 $this->performer
129 )
130 );
131 }
132
133 if ( !$status->isOK() ) {
134 return $status;
135 }
136
137 return $this->unblockUnsafe();
138 }
139
146 public function unblockUnsafe(): Status {
147 $status = Status::newGood();
148
149 $this->block ??= $this->getBlockToRemove( $status );
150 if ( !$status->isOK() ) {
151 return $status;
152 }
153
154 if ( $this->block === null ) {
155 return $status->fatal( 'ipb_cant_unblock', $this->target->toString() );
156 }
157
158 if (
159 $this->block->getType() === AbstractBlock::TYPE_RANGE &&
160 $this->target->getType() === AbstractBlock::TYPE_IP
161 ) {
162 return $status->fatal( 'ipb_blocked_as_range', $this->target->toString(), $this->block->getTargetName() );
163 }
164
165 $denyReason = [ 'hookaborted' ];
166 $legacyUser = $this->userFactory->newFromAuthority( $this->performer );
167 if ( !$this->hookRunner->onUnblockUser( $this->block, $legacyUser, $denyReason ) ) {
168 foreach ( $denyReason as $key ) {
169 $status->fatal( $key );
170 }
171 return $status;
172 }
173
174 $deleteBlockStatus = $this->blockStore->deleteBlock( $this->block );
175 if ( !$deleteBlockStatus ) {
176 return $status->fatal( 'ipb_cant_unblock', $this->block->getTargetName() );
177 }
178
179 $this->hookRunner->onUnblockUserComplete( $this->block, $legacyUser );
180
181 // Unset _deleted fields as needed
182 $user = $this->block->getTargetUserIdentity();
183 if ( $this->block->getHideName() && $user ) {
184 $id = $user->getId();
185 RevisionDeleteUser::unsuppressUserName( $user->getName(), $id );
186 }
187
188 $this->log();
189
190 $status->setResult( $status->isOK(), $this->block );
191 return $status;
192 }
193
197 private function log() {
198 $page = $this->block->getRedactedTarget()->getLogPage();
199 $logEntry = new ManualLogEntry( 'block', 'unblock' );
200
201 $logEntry->setTarget( $page );
202 $logEntry->setComment( $this->reason );
203 $logEntry->setPerformer( $this->performer->getUser() );
204 $logEntry->addTags( $this->tags );
205 $logEntry->setRelations( [ 'ipb_id' => $this->block->getId() ] );
206 // Save the ID to log_params, since MW 1.44
207 $logEntry->addParameter( 'blockId', $this->block->getId() );
208 $logId = $logEntry->insert();
209 $logEntry->publish( $logId );
210 }
211
212 private function getBlockToRemove( Status $status ): ?DatabaseBlock {
213 if ( $this->blockToRemove !== null ) {
214 return $this->blockToRemove;
215 }
216
217 $activeBlocks = $this->blockStore->newListFromTarget(
218 $this->target, null, false, DatabaseBlockStore::AUTO_SPECIFIED );
219 if ( !$activeBlocks ) {
220 $status->fatal( 'ipb_cant_unblock', $this->target->toString() );
221 return null;
222 }
223
224 if ( count( $activeBlocks ) > 1 ) {
225 $status->fatal( 'ipb_cant_unblock_multiple_blocks',
226 count( $activeBlocks ), Message::listParam(
227 // @phan-suppress-next-line PhanTypeMismatchArgument
228 array_map(
229 static function ( $block ) {
230 return $block->getId();
231 }, $activeBlocks )
232 )
233 );
234 }
235
236 return $activeBlocks[0];
237 }
238}
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:69
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.
Recent changes tagging.
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:144
Backend functions for suppressing and unsuppressing all references to a given user,...
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:44
Create User objects.
This interface represents the authority associated with the current execution context,...
Definition Authority.php:23
Interface for objects representing user identity.