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 BlockUtils $blockUtils;
44 private UserFactory $userFactory;
45 private HookRunner $hookRunner;
46
48 private $target;
49
51 private $targetType;
52
54 private $block;
55
57 private $performer;
58
60 private $reason;
61
63 private $tags = [];
64
76 public function __construct(
77 BlockPermissionCheckerFactory $blockPermissionCheckerFactory,
78 DatabaseBlockStore $blockStore,
79 BlockUtils $blockUtils,
80 UserFactory $userFactory,
81 HookContainer $hookContainer,
82 $target,
83 Authority $performer,
84 string $reason,
85 array $tags = []
86 ) {
87 // Process dependencies
88 $this->blockPermissionChecker = $blockPermissionCheckerFactory
90 $target,
91 $performer
92 );
93 $this->blockStore = $blockStore;
94 $this->blockUtils = $blockUtils;
95 $this->userFactory = $userFactory;
96 $this->hookRunner = new HookRunner( $hookContainer );
97
98 // Process params
99 [ $this->target, $this->targetType ] = $this->blockUtils->parseBlockTarget( $target );
100 if (
101 $this->targetType === AbstractBlock::TYPE_AUTO &&
102 is_numeric( $this->target )
103 ) {
104 // Needed, because BlockUtils::parseBlockTarget will strip the # from autoblocks.
105 $this->target = '#' . $this->target;
106 }
107 $this->block = $this->blockStore->newFromTarget( $this->target );
108 $this->performer = $performer;
109 $this->reason = $reason;
110 $this->tags = $tags;
111 }
112
118 public function unblock(): Status {
119 $status = Status::newGood();
120
121 $basePermissionCheckResult = $this->blockPermissionChecker->checkBasePermissions(
122 $this->block instanceof DatabaseBlock && $this->block->getHideName()
123 );
124 if ( $basePermissionCheckResult !== true ) {
125 return $status->fatal( $basePermissionCheckResult );
126 }
127
128 $blockPermissionCheckResult = $this->blockPermissionChecker->checkBlockPermissions();
129 if ( $blockPermissionCheckResult !== true ) {
130 return $status->fatal( $blockPermissionCheckResult );
131 }
132
133 if ( count( $this->tags ) !== 0 ) {
134 $status->merge(
136 $this->tags,
137 $this->performer
138 )
139 );
140 }
141
142 if ( !$status->isOK() ) {
143 return $status;
144 }
145 return $this->unblockUnsafe();
146 }
147
154 public function unblockUnsafe(): Status {
155 $status = Status::newGood();
156
157 if ( $this->block === null ) {
158 return $status->fatal( 'ipb_cant_unblock', $this->target );
159 }
160
161 if (
162 $this->block->getType() === AbstractBlock::TYPE_RANGE &&
163 $this->targetType === AbstractBlock::TYPE_IP
164 ) {
165 return $status->fatal( 'ipb_blocked_as_range', $this->target, $this->block->getTargetName() );
166 }
167
168 $denyReason = [ 'hookaborted' ];
169 $legacyUser = $this->userFactory->newFromAuthority( $this->performer );
170 if ( !$this->hookRunner->onUnblockUser( $this->block, $legacyUser, $denyReason ) ) {
171 foreach ( $denyReason as $key ) {
172 $status->fatal( $key );
173 }
174 return $status;
175 }
176
177 $deleteBlockStatus = $this->blockStore->deleteBlock( $this->block );
178 if ( !$deleteBlockStatus ) {
179 return $status->fatal( 'ipb_cant_unblock', $this->block->getTargetName() );
180 }
181
182 $this->hookRunner->onUnblockUserComplete( $this->block, $legacyUser );
183
184 // Unset _deleted fields as needed
185 $user = $this->block->getTargetUserIdentity();
186 if ( $this->block->getHideName() && $user ) {
187 $id = $user->getId();
188 RevisionDeleteUser::unsuppressUserName( $user->getName(), $id );
189 }
190
191 $this->log();
192
193 $status->setResult( $status->isOK(), $this->block );
194 return $status;
195 }
196
200 private function log() {
201 // Redact IP for autoblocks
202 if ( $this->block->getType() === DatabaseBlock::TYPE_AUTO ) {
203 $page = TitleValue::tryNew( NS_USER, '#' . $this->block->getId() );
204 } else {
205 $page = TitleValue::tryNew( NS_USER, $this->block->getTargetName() );
206 }
207
208 $logEntry = new ManualLogEntry( 'block', 'unblock' );
209
210 if ( $page !== null ) {
211 $logEntry->setTarget( $page );
212 }
213 $logEntry->setComment( $this->reason );
214 $logEntry->setPerformer( $this->performer->getUser() );
215 $logEntry->addTags( $this->tags );
216 $logEntry->setRelations( [ 'ipb_id' => $this->block->getId() ] );
217 $logId = $logEntry->insert();
218 $logEntry->publish( $logId );
219 }
220
221}
const NS_USER
Definition Defines.php:67
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...
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.