MediaWiki  master
DatabaseBlockStore.php
Go to the documentation of this file.
1 <?php
23 namespace MediaWiki\Block;
24 
26 use CommentStore;
27 use DeferredUpdates;
28 use InvalidArgumentException;
35 use MWException;
36 use Psr\Log\LoggerInterface;
37 use ReadOnlyMode;
38 use Wikimedia\Assert\Assert;
41 
48 
50  private $options;
51 
55  public const CONSTRUCTOR_OPTIONS = [
56  'PutIPinRC',
57  'BlockDisablesLogin',
58  ];
59 
61  private $logger;
62 
65 
68 
70  private $commentStore;
71 
73  private $hookRunner;
74 
76  private $loadBalancer;
77 
79  private $readOnlyMode;
80 
82  private $userFactory;
83 
95  public function __construct(
97  LoggerInterface $logger,
101  HookContainer $hookContainer,
105  ) {
106  $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
107 
108  $this->options = $options;
109  $this->logger = $logger;
110  $this->actorStoreFactory = $actorStoreFactory;
111  $this->blockRestrictionStore = $blockRestrictionStore;
112  $this->commentStore = $commentStore;
113  $this->hookRunner = new HookRunner( $hookContainer );
114  $this->loadBalancer = $loadBalancer;
115  $this->readOnlyMode = $readOnlyMode;
116  $this->userFactory = $userFactory;
117  }
118 
124  public function purgeExpiredBlocks() {
125  if ( $this->readOnlyMode->isReadOnly() ) {
126  return;
127  }
128 
129  $dbw = $this->loadBalancer->getConnectionRef( DB_PRIMARY );
131 
133  $dbw,
134  __METHOD__,
135  static function ( IDatabase $dbw, $fname ) use ( $blockRestrictionStore ) {
136  $ids = $dbw->selectFieldValues(
137  'ipblocks',
138  'ipb_id',
139  [ 'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ],
140  $fname
141  );
142  if ( $ids ) {
144  $dbw->delete( 'ipblocks', [ 'ipb_id' => $ids ], $fname );
145  }
146  }
147  ) );
148  }
149 
157  private function checkDatabaseDomain( ?IDatabase $db, $expectedWiki ) {
158  if ( $db ) {
159  $dbDomain = $db->getDomainID();
160  $storeDomain = $this->loadBalancer->resolveDomainID( $expectedWiki );
161  if ( $dbDomain !== $storeDomain ) {
162  throw new InvalidArgumentException(
163  "DB connection domain '$dbDomain' does not match '$storeDomain'"
164  );
165  }
166  } else {
167  if ( $expectedWiki !== UserIdentity::LOCAL ) {
168  throw new InvalidArgumentException(
169  "Must provide a database connection for wiki '$expectedWiki'."
170  );
171  }
172  }
173  }
174 
186  public function insertBlock(
187  DatabaseBlock $block,
188  IDatabase $database = null
189  ) {
190  if ( !$block->getBlocker() || $block->getBlocker()->getName() === '' ) {
191  throw new MWException( 'Cannot insert a block without a blocker set' );
192  }
193 
194  $this->checkDatabaseDomain( $database, $block->getBlocker()->getWikiId() );
195 
196  $this->logger->debug( 'Inserting block; timestamp ' . $block->getTimestamp() );
197 
198  // TODO T258866 - consider passing the database
199  $this->purgeExpiredBlocks();
200 
201  $dbw = $database ?: $this->loadBalancer->getConnectionRef( DB_PRIMARY );
202  $row = $this->getArrayForDatabaseBlock( $block, $dbw );
203 
204  $dbw->insert( 'ipblocks', $row, __METHOD__, [ 'IGNORE' ] );
205  $affected = $dbw->affectedRows();
206 
207  if ( $affected ) {
208  $block->setId( $dbw->insertId() );
209  if ( $block->getRawRestrictions() ) {
210  $this->blockRestrictionStore->insert( $block->getRawRestrictions() );
211  }
212  }
213 
214  // Don't collide with expired blocks.
215  // Do this after trying to insert to avoid locking.
216  if ( !$affected ) {
217  // T96428: The ipb_address index uses a prefix on a field, so
218  // use a standard SELECT + DELETE to avoid annoying gap locks.
219  $ids = $dbw->selectFieldValues(
220  'ipblocks',
221  'ipb_id',
222  [
223  'ipb_address' => $row['ipb_address'],
224  'ipb_user' => $row['ipb_user'],
225  'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() )
226  ],
227  __METHOD__
228  );
229  if ( $ids ) {
230  $dbw->delete( 'ipblocks', [ 'ipb_id' => $ids ], __METHOD__ );
231  $this->blockRestrictionStore->deleteByBlockId( $ids );
232  $dbw->insert( 'ipblocks', $row, __METHOD__, [ 'IGNORE' ] );
233  $affected = $dbw->affectedRows();
234  $block->setId( $dbw->insertId() );
235  if ( $block->getRawRestrictions() ) {
236  $this->blockRestrictionStore->insert( $block->getRawRestrictions() );
237  }
238  }
239  }
240 
241  if ( $affected ) {
242  $autoBlockIds = $this->doRetroactiveAutoblock( $block );
243 
244  if ( $this->options->get( 'BlockDisablesLogin' ) ) {
245  $targetUserIdentity = $block->getTargetUserIdentity();
246  if ( $targetUserIdentity ) {
247  $targetUser = $this->userFactory->newFromUserIdentity( $targetUserIdentity );
248  // Change user login token to force them to be logged out.
249  $targetUser->setToken();
250  $targetUser->saveSettings();
251  }
252  }
253 
254  return [ 'id' => $block->getId(), 'autoIds' => $autoBlockIds ];
255  }
256 
257  return false;
258  }
259 
268  public function updateBlock( DatabaseBlock $block ) {
269  $this->logger->debug( 'Updating block; timestamp ' . $block->getTimestamp() );
270 
271  // We could allow cross-wiki updates here, just like we do in insertBlock().
272  Assert::parameter(
273  $block->getBlocker()->getWikiId() === UserIdentity::LOCAL,
274  '$block->getBlocker()',
275  'must belong to the local wiki.'
276  );
277 
278  $dbw = $this->loadBalancer->getConnectionRef( DB_PRIMARY );
279  $row = $this->getArrayForDatabaseBlock( $block, $dbw );
280  $dbw->startAtomic( __METHOD__ );
281 
282  $result = $dbw->update(
283  'ipblocks',
284  $row,
285  [ 'ipb_id' => $block->getId() ],
286  __METHOD__
287  );
288 
289  // Only update the restrictions if they have been modified.
290  $restrictions = $block->getRawRestrictions();
291  if ( $restrictions !== null ) {
292  // An empty array should remove all of the restrictions.
293  if ( empty( $restrictions ) ) {
294  $success = $this->blockRestrictionStore->deleteByBlockId( $block->getId() );
295  } else {
296  $success = $this->blockRestrictionStore->update( $restrictions );
297  }
298  // Update the result. The first false is the result, otherwise, true.
299  $result = $result && $success;
300  }
301 
302  if ( $block->isAutoblocking() ) {
303  // update corresponding autoblock(s) (T50813)
304  $dbw->update(
305  'ipblocks',
306  $this->getArrayForAutoblockUpdate( $block ),
307  [ 'ipb_parent_block_id' => $block->getId() ],
308  __METHOD__
309  );
310 
311  // Only update the restrictions if they have been modified.
312  if ( $restrictions !== null ) {
313  $this->blockRestrictionStore->updateByParentBlockId(
314  $block->getId(),
315  $restrictions
316  );
317  }
318  } else {
319  // autoblock no longer required, delete corresponding autoblock(s)
320  $this->blockRestrictionStore->deleteByParentBlockId( $block->getId() );
321  $dbw->delete(
322  'ipblocks',
323  [ 'ipb_parent_block_id' => $block->getId() ],
324  __METHOD__
325  );
326  }
327 
328  $dbw->endAtomic( __METHOD__ );
329 
330  if ( $result ) {
331  $autoBlockIds = $this->doRetroactiveAutoblock( $block );
332  return [ 'id' => $block->getId(), 'autoIds' => $autoBlockIds ];
333  }
334 
335  return false;
336  }
337 
345  public function deleteBlock( DatabaseBlock $block ): bool {
346  if ( $this->readOnlyMode->isReadOnly() ) {
347  return false;
348  }
349 
350  $blockId = $block->getId();
351 
352  if ( !$blockId ) {
353  throw new MWException(
354  __METHOD__ . " requires that a block id be set\n"
355  );
356  }
357  $dbw = $this->loadBalancer->getConnectionRef( DB_PRIMARY );
358 
359  $this->blockRestrictionStore->deleteByParentBlockId( $blockId );
360  $dbw->delete(
361  'ipblocks',
362  [ 'ipb_parent_block_id' => $blockId ],
363  __METHOD__
364  );
365 
366  $this->blockRestrictionStore->deleteByBlockId( $blockId );
367  $dbw->delete(
368  'ipblocks',
369  [ 'ipb_id' => $blockId ],
370  __METHOD__
371  );
372 
373  return $dbw->affectedRows() > 0;
374  }
375 
384  private function getArrayForDatabaseBlock(
385  DatabaseBlock $block,
386  IDatabase $dbw
387  ): array {
388  $expiry = $dbw->encodeExpiry( $block->getExpiry() );
389 
390  if ( $block->getTargetUserIdentity() ) {
391  $userId = $block->getTargetUserIdentity()->getId();
392  } else {
393  $userId = 0;
394  }
395  if ( !$block->getBlocker() ) {
396  throw new \RuntimeException( __METHOD__ . ': this block does not have a blocker' );
397  }
398  // DatabaseBlockStore supports inserting cross-wiki blocks by passing non-local IDatabase and blocker.
399  $blockerActor = $this->actorStoreFactory
400  ->getActorStore( $dbw->getDomainID() )
401  ->acquireActorId( $block->getBlocker(), $dbw );
402 
403  $blockArray = [
404  'ipb_address' => $block->getTargetName(),
405  'ipb_user' => $userId,
406  'ipb_by_actor' => $blockerActor,
407  'ipb_timestamp' => $dbw->timestamp( $block->getTimestamp() ),
408  'ipb_auto' => $block->getType() === AbstractBlock::TYPE_AUTO,
409  'ipb_anon_only' => !$block->isHardblock(),
410  'ipb_create_account' => $block->isCreateAccountBlocked(),
411  'ipb_enable_autoblock' => $block->isAutoblocking(),
412  'ipb_expiry' => $expiry,
413  'ipb_range_start' => $block->getRangeStart(),
414  'ipb_range_end' => $block->getRangeEnd(),
415  'ipb_deleted' => intval( $block->getHideName() ), // typecast required for SQLite
416  'ipb_block_email' => $block->isEmailBlocked(),
417  'ipb_allow_usertalk' => $block->isUsertalkEditAllowed(),
418  'ipb_parent_block_id' => $block->getParentBlockId(),
419  'ipb_sitewide' => $block->isSitewide(),
420  ];
421  $commentArray = $this->commentStore->insert(
422  $dbw,
423  'ipb_reason',
424  $block->getReasonComment()
425  );
426 
427  $combinedArray = $blockArray + $commentArray;
428  return $combinedArray;
429  }
430 
437  private function getArrayForAutoblockUpdate( DatabaseBlock $block ): array {
438  if ( !$block->getBlocker() ) {
439  throw new \RuntimeException( __METHOD__ . ': this block does not have a blocker' );
440  }
441  $dbw = $this->loadBalancer->getConnectionRef( DB_PRIMARY );
442  $blockerActor = $this->actorStoreFactory
443  ->getActorNormalization()
444  ->acquireActorId( $block->getBlocker(), $dbw );
445  $blockArray = [
446  'ipb_by_actor' => $blockerActor,
447  'ipb_create_account' => $block->isCreateAccountBlocked(),
448  'ipb_deleted' => (int)$block->getHideName(), // typecast required for SQLite
449  'ipb_allow_usertalk' => $block->isUsertalkEditAllowed(),
450  'ipb_sitewide' => $block->isSitewide(),
451  ];
452 
453  $commentArray = $this->commentStore->insert(
454  $dbw,
455  'ipb_reason',
456  $block->getReasonComment()
457  );
458 
459  $combinedArray = $blockArray + $commentArray;
460  return $combinedArray;
461  }
462 
470  private function doRetroactiveAutoblock( DatabaseBlock $block ): array {
471  $autoBlockIds = [];
472  // If autoblock is enabled, autoblock the LAST IP(s) used
473  if ( $block->isAutoblocking() && $block->getType() == AbstractBlock::TYPE_USER ) {
474  $this->logger->debug(
475  'Doing retroactive autoblocks for ' . $block->getTargetName()
476  );
477 
478  $hookAutoBlocked = [];
479  $continue = $this->hookRunner->onPerformRetroactiveAutoblock(
480  $block,
481  $hookAutoBlocked
482  );
483 
484  if ( $continue ) {
485  $coreAutoBlocked = $this->performRetroactiveAutoblock( $block );
486  $autoBlockIds = array_merge( $hookAutoBlocked, $coreAutoBlocked );
487  } else {
488  $autoBlockIds = $hookAutoBlocked;
489  }
490  }
491  return $autoBlockIds;
492  }
493 
501  private function performRetroactiveAutoblock( DatabaseBlock $block ): array {
502  if ( !$this->options->get( 'PutIPinRC' ) ) {
503  // No IPs in the recent changes table to autoblock
504  return [];
505  }
506 
507  $type = $block->getType();
508  if ( $type !== AbstractBlock::TYPE_USER ) {
509  // Autoblocks only apply to users
510  return [];
511  }
512 
513  $dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
514 
515  $targetUser = $block->getTargetUserIdentity();
516  $actor = $targetUser ? $this->actorStoreFactory->getActorNormalization()->findActorId(
517  $targetUser,
518  $dbr
519  ) : null;
520 
521  if ( !$actor ) {
522  $this->logger->debug( 'No actor found to retroactively autoblock' );
523  return [];
524  }
525 
526  $rcIp = $dbr->selectField(
527  [ 'recentchanges' ],
528  'rc_ip',
529  [ 'rc_actor' => $actor ],
530  __METHOD__,
531  [ 'ORDER BY' => 'rc_timestamp DESC' ]
532  );
533 
534  if ( !$rcIp ) {
535  $this->logger->debug( 'No IP found to retroactively autoblock' );
536  return [];
537  }
538 
539  $id = $block->doAutoblock( $rcIp );
540  if ( !$id ) {
541  return [];
542  }
543  return [ $id ];
544  }
545 
546 }
MediaWiki\Block\DatabaseBlockStore\$hookRunner
HookRunner $hookRunner
Definition: DatabaseBlockStore.php:73
MediaWiki\Block\DatabaseBlockStore\$blockRestrictionStore
BlockRestrictionStore $blockRestrictionStore
Definition: DatabaseBlockStore.php:67
MediaWiki\Block
Definition: AbstractBlock.php:21
MediaWiki\Block\DatabaseBlockStore\$logger
LoggerInterface $logger
Definition: DatabaseBlockStore.php:61
MediaWiki\Block\AbstractBlock\getTargetName
getTargetName()
Definition: AbstractBlock.php:359
if
if(ini_get( 'mbstring.func_overload')) if(!defined('MW_ENTRY_POINT'))
Pre-config setup: Before loading LocalSettings.php.
Definition: Setup.php:88
AutoCommitUpdate
Deferrable Update for closure/callback updates that should use auto-commit mode.
Definition: AutoCommitUpdate.php:9
MediaWiki\Block\DatabaseBlockStore\performRetroactiveAutoblock
performRetroactiveAutoblock(DatabaseBlock $block)
Actually retroactively autoblocks the last IP used by the user (if it is a user) blocked by this bloc...
Definition: DatabaseBlockStore.php:501
MediaWiki\Block\DatabaseBlock\getRangeStart
getRangeStart()
Get the IP address at the start of the range in Hex form.
Definition: DatabaseBlock.php:728
ReadOnlyMode
A service class for fetching the wiki's current read-only mode.
Definition: ReadOnlyMode.php:11
Wikimedia\Rdbms\IDatabase\encodeExpiry
encodeExpiry( $expiry)
Encode an expiry time into the DBMS dependent format.
MediaWiki\Block\DatabaseBlock\getType
getType()
Get the type of target for this particular block.int|null AbstractBlock::TYPE_ constant,...
Definition: DatabaseBlock.php:1006
DeferredUpdates\addUpdate
static addUpdate(DeferrableUpdate $update, $stage=self::POSTSEND)
Add an update to the pending update queue for execution at the appropriate time.
Definition: DeferredUpdates.php:119
MediaWiki\Block\AbstractBlock\isCreateAccountBlocked
isCreateAccountBlocked( $x=null)
Get or set the flag indicating whether this block blocks the target from creating an account.
Definition: AbstractBlock.php:210
MediaWiki\Block\DatabaseBlock\getBlocker
getBlocker()
Get the user who implemented this block.
Definition: DatabaseBlock.php:1195
MediaWiki\Block\DatabaseBlockStore\$loadBalancer
ILoadBalancer $loadBalancer
Definition: DatabaseBlockStore.php:76
MediaWiki\Block\DatabaseBlockStore\getArrayForDatabaseBlock
getArrayForDatabaseBlock(DatabaseBlock $block, IDatabase $dbw)
Get an array suitable for passing to $dbw->insert() or $dbw->update()
Definition: DatabaseBlockStore.php:384
CommentStore
Handle database storage of comments such as edit summaries and log reasons.
Definition: CommentStore.php:42
MediaWiki\Block\DatabaseBlockStore\__construct
__construct(ServiceOptions $options, LoggerInterface $logger, ActorStoreFactory $actorStoreFactory, BlockRestrictionStore $blockRestrictionStore, CommentStore $commentStore, HookContainer $hookContainer, ILoadBalancer $loadBalancer, ReadOnlyMode $readOnlyMode, UserFactory $userFactory)
Definition: DatabaseBlockStore.php:95
MediaWiki\Block\DatabaseBlockStore\purgeExpiredBlocks
purgeExpiredBlocks()
Delete expired blocks from the ipblocks table.
Definition: DatabaseBlockStore.php:124
MediaWiki\Block\DatabaseBlockStore\$commentStore
CommentStore $commentStore
Definition: DatabaseBlockStore.php:70
$success
$success
Definition: NoLocalSettings.php:42
MediaWiki\Block\DatabaseBlockStore
Definition: DatabaseBlockStore.php:47
MediaWiki\User\ActorStoreFactory
Definition: ActorStoreFactory.php:35
MediaWiki\Block\DatabaseBlock\getRawRestrictions
getRawRestrictions()
Get restrictions without loading from database if not yet loaded.
Definition: DatabaseBlock.php:1045
MediaWiki\User\UserIdentity
Interface for objects representing user identity.
Definition: UserIdentity.php:39
MediaWiki\Block\DatabaseBlockStore\$options
ServiceOptions $options
Definition: DatabaseBlockStore.php:50
MediaWiki\Block\DatabaseBlockStore\updateBlock
updateBlock(DatabaseBlock $block)
Update a block in the DB with new parameters.
Definition: DatabaseBlockStore.php:268
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
$dbr
$dbr
Definition: testCompression.php:54
MediaWiki\Block\DatabaseBlockStore\$actorStoreFactory
ActorStoreFactory $actorStoreFactory
Definition: DatabaseBlockStore.php:64
MediaWiki\Block\DatabaseBlock
A DatabaseBlock (unlike a SystemBlock) is stored in the database, may give rise to autoblocks and may...
Definition: DatabaseBlock.php:52
Wikimedia\Rdbms\IDatabase\timestamp
timestamp( $ts=0)
Convert a timestamp in one of the formats accepted by ConvertibleTimestamp to the format used for ins...
MWException
MediaWiki exception.
Definition: MWException.php:29
MediaWiki\Config\ServiceOptions
A class for passing options to services.
Definition: ServiceOptions.php:27
MediaWiki\Block\DatabaseBlockStore\CONSTRUCTOR_OPTIONS
const CONSTRUCTOR_OPTIONS
Definition: DatabaseBlockStore.php:55
DeferredUpdates
Class for managing the deferral of updates within the scope of a PHP script invocation.
Definition: DeferredUpdates.php:82
MediaWiki\Block\DatabaseBlockStore\doRetroactiveAutoblock
doRetroactiveAutoblock(DatabaseBlock $block)
Handles retroactively autoblocking the last IP used by the user (if it is a user) blocked by an auto ...
Definition: DatabaseBlockStore.php:470
MediaWiki\Block\AbstractBlock\isEmailBlocked
isEmailBlocked( $x=null)
Get or set the flag indicating whether this block blocks the target from sending emails.
Definition: AbstractBlock.php:223
MediaWiki\Block\AbstractBlock\getReasonComment
getReasonComment()
Get the reason for creating the block.
Definition: AbstractBlock.php:154
MediaWiki\Block\DatabaseBlock\getRangeEnd
getRangeEnd()
Get the IP address at the end of the range in Hex form.
Definition: DatabaseBlock.php:747
MediaWiki\Block\DatabaseBlockStore\getArrayForAutoblockUpdate
getArrayForAutoblockUpdate(DatabaseBlock $block)
Get an array suitable for autoblock updates.
Definition: DatabaseBlockStore.php:437
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
MediaWiki\Block\AbstractBlock\isSitewide
isSitewide( $x=null)
Indicates that the block is a sitewide block.
Definition: AbstractBlock.php:197
MediaWiki\Block\DatabaseBlock\isAutoblocking
isAutoblocking( $x=null)
Definition: DatabaseBlock.php:824
MediaWiki\Block\DatabaseBlock\getParentBlockId
getParentBlockId()
Definition: DatabaseBlock.php:802
DB_PRIMARY
const DB_PRIMARY
Definition: defines.php:27
Wikimedia\Rdbms\IDatabase\getDomainID
getDomainID()
Return the currently selected domain ID.
MediaWiki\Block\DatabaseBlockStore\insertBlock
insertBlock(DatabaseBlock $block, IDatabase $database=null)
Insert a block into the block table.
Definition: DatabaseBlockStore.php:186
MediaWiki\Block\AbstractBlock\getExpiry
getExpiry()
Get the block expiry time.
Definition: AbstractBlock.php:385
MediaWiki\Block\Block\TYPE_AUTO
const TYPE_AUTO
Definition: Block.php:44
MediaWiki\Block\Block\TYPE_USER
const TYPE_USER
Definition: Block.php:41
MediaWiki\Block\AbstractBlock\getTimestamp
getTimestamp()
Get the timestamp indicating when the block was created.
Definition: AbstractBlock.php:406
MediaWiki\Block\DatabaseBlock\getId
getId()
Get the block ID.int|null
Definition: DatabaseBlock.php:775
MediaWiki\Block\DatabaseBlock\setId
setId( $blockId)
Set the block ID.
Definition: DatabaseBlock.php:786
Wikimedia\Rdbms\IDatabase\addQuotes
addQuotes( $s)
Escape and quote a raw value string for use in a SQL query.
MediaWiki\Block\DatabaseBlockStore\checkDatabaseDomain
checkDatabaseDomain(?IDatabase $db, $expectedWiki)
Throws an exception if the given database connection does not match the given wiki ID.
Definition: DatabaseBlockStore.php:157
Wikimedia\Rdbms\IDatabase\selectFieldValues
selectFieldValues( $table, $var, $cond='', $fname=__METHOD__, $options=[], $join_conds=[])
A SELECT wrapper which returns a list of single field values from result rows.
MediaWiki\Block\BlockRestrictionStore\deleteByBlockId
deleteByBlockId( $blockId)
Delete the restrictions by block ID.
Definition: BlockRestrictionStore.php:264
MediaWiki\Block\DatabaseBlock\doAutoblock
doAutoblock( $autoblockIP)
Autoblocks the given IP, referring to this block.
Definition: DatabaseBlock.php:615
MediaWiki\Block\AbstractBlock\getTargetUserIdentity
getTargetUserIdentity()
Definition: AbstractBlock.php:351
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:45
MediaWiki\Block\AbstractBlock\getHideName
getHideName()
Get whether the block hides the target's username.
Definition: AbstractBlock.php:174
MediaWiki\HookContainer\HookRunner
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:558
MediaWiki\Block\DatabaseBlockStore\deleteBlock
deleteBlock(DatabaseBlock $block)
Delete a DatabaseBlock from the database.
Definition: DatabaseBlockStore.php:345
MediaWiki\Block\DatabaseBlockStore\$readOnlyMode
ReadOnlyMode $readOnlyMode
Definition: DatabaseBlockStore.php:79
MediaWiki\Block\DatabaseBlockStore\$userFactory
UserFactory $userFactory
Definition: DatabaseBlockStore.php:82
MediaWiki\Block\DatabaseBlock\isHardblock
isHardblock( $x=null)
Get/set whether the block is a hardblock (affects logged-in users on a given IP/range)
Definition: DatabaseBlock.php:811
MediaWiki\User\UserFactory
Creates User objects.
Definition: UserFactory.php:41
MediaWiki\Block\AbstractBlock\isUsertalkEditAllowed
isUsertalkEditAllowed( $x=null)
Get or set the flag indicating whether this block blocks the target from editing their own user talk ...
Definition: AbstractBlock.php:236
Wikimedia\Rdbms\IDatabase\delete
delete( $table, $conds, $fname=__METHOD__)
Delete all rows in a table that match a condition.
Wikimedia\Rdbms\ILoadBalancer
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: ILoadBalancer.php:81
MediaWiki\Config\ServiceOptions\assertRequiredOptions
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
Definition: ServiceOptions.php:71
MediaWiki\Block\BlockRestrictionStore
Definition: BlockRestrictionStore.php:35
$type
$type
Definition: testCompression.php:52