MediaWiki  1.28.1
Block.php
Go to the documentation of this file.
1 <?php
24 
25 class Block {
27  public $mReason;
28 
30  public $mTimestamp;
31 
33  public $mAuto;
34 
36  public $mExpiry;
37 
39  public $mHideName;
40 
43 
45  protected $mId;
46 
48  protected $mFromMaster;
49 
51  protected $mBlockEmail;
52 
54  protected $mDisableUsertalk;
55 
57  protected $mCreateAccount;
58 
60  protected $target;
61 
63  protected $forcedTargetID;
64 
66  protected $type;
67 
69  protected $blocker;
70 
72  protected $isHardblock;
73 
75  protected $isAutoblocking;
76 
77  # TYPE constants
78  const TYPE_USER = 1;
79  const TYPE_IP = 2;
80  const TYPE_RANGE = 3;
81  const TYPE_AUTO = 4;
82  const TYPE_ID = 5;
83 
106  function __construct( $options = [] ) {
107  $defaults = [
108  'address' => '',
109  'user' => null,
110  'by' => null,
111  'reason' => '',
112  'timestamp' => '',
113  'auto' => false,
114  'expiry' => '',
115  'anonOnly' => false,
116  'createAccount' => false,
117  'enableAutoblock' => false,
118  'hideName' => false,
119  'blockEmail' => false,
120  'allowUsertalk' => false,
121  'byText' => '',
122  ];
123 
124  if ( func_num_args() > 1 || !is_array( $options ) ) {
125  $options = array_combine(
126  array_slice( array_keys( $defaults ), 0, func_num_args() ),
127  func_get_args()
128  );
129  wfDeprecated( __METHOD__ . ' with multiple arguments', '1.26' );
130  }
131 
132  $options += $defaults;
133 
134  $this->setTarget( $options['address'] );
135 
136  if ( $this->target instanceof User && $options['user'] ) {
137  # Needed for foreign users
138  $this->forcedTargetID = $options['user'];
139  }
140 
141  if ( $options['by'] ) {
142  # Local user
143  $this->setBlocker( User::newFromId( $options['by'] ) );
144  } else {
145  # Foreign user
146  $this->setBlocker( $options['byText'] );
147  }
148 
149  $this->mReason = $options['reason'];
150  $this->mTimestamp = wfTimestamp( TS_MW, $options['timestamp'] );
151  $this->mExpiry = wfGetDB( DB_REPLICA )->decodeExpiry( $options['expiry'] );
152 
153  # Boolean settings
154  $this->mAuto = (bool)$options['auto'];
155  $this->mHideName = (bool)$options['hideName'];
156  $this->isHardblock( !$options['anonOnly'] );
157  $this->isAutoblocking( (bool)$options['enableAutoblock'] );
158 
159  # Prevention measures
160  $this->prevents( 'sendemail', (bool)$options['blockEmail'] );
161  $this->prevents( 'editownusertalk', !$options['allowUsertalk'] );
162  $this->prevents( 'createaccount', (bool)$options['createAccount'] );
163 
164  $this->mFromMaster = false;
165  }
166 
173  public static function newFromID( $id ) {
174  $dbr = wfGetDB( DB_REPLICA );
175  $res = $dbr->selectRow(
176  'ipblocks',
177  self::selectFields(),
178  [ 'ipb_id' => $id ],
179  __METHOD__
180  );
181  if ( $res ) {
182  return self::newFromRow( $res );
183  } else {
184  return null;
185  }
186  }
187 
193  public static function selectFields() {
194  return [
195  'ipb_id',
196  'ipb_address',
197  'ipb_by',
198  'ipb_by_text',
199  'ipb_reason',
200  'ipb_timestamp',
201  'ipb_auto',
202  'ipb_anon_only',
203  'ipb_create_account',
204  'ipb_enable_autoblock',
205  'ipb_expiry',
206  'ipb_deleted',
207  'ipb_block_email',
208  'ipb_allow_usertalk',
209  'ipb_parent_block_id',
210  ];
211  }
212 
221  public function equals( Block $block ) {
222  return (
223  (string)$this->target == (string)$block->target
224  && $this->type == $block->type
225  && $this->mAuto == $block->mAuto
226  && $this->isHardblock() == $block->isHardblock()
227  && $this->prevents( 'createaccount' ) == $block->prevents( 'createaccount' )
228  && $this->mExpiry == $block->mExpiry
229  && $this->isAutoblocking() == $block->isAutoblocking()
230  && $this->mHideName == $block->mHideName
231  && $this->prevents( 'sendemail' ) == $block->prevents( 'sendemail' )
232  && $this->prevents( 'editownusertalk' ) == $block->prevents( 'editownusertalk' )
233  && $this->mReason == $block->mReason
234  );
235  }
236 
247  protected function newLoad( $vagueTarget = null ) {
248  $db = wfGetDB( $this->mFromMaster ? DB_MASTER : DB_REPLICA );
249 
250  if ( $this->type !== null ) {
251  $conds = [
252  'ipb_address' => [ (string)$this->target ],
253  ];
254  } else {
255  $conds = [ 'ipb_address' => [] ];
256  }
257 
258  # Be aware that the != '' check is explicit, since empty values will be
259  # passed by some callers (bug 29116)
260  if ( $vagueTarget != '' ) {
261  list( $target, $type ) = self::parseTarget( $vagueTarget );
262  switch ( $type ) {
263  case self::TYPE_USER:
264  # Slightly weird, but who are we to argue?
265  $conds['ipb_address'][] = (string)$target;
266  break;
267 
268  case self::TYPE_IP:
269  $conds['ipb_address'][] = (string)$target;
270  $conds[] = self::getRangeCond( IP::toHex( $target ) );
271  $conds = $db->makeList( $conds, LIST_OR );
272  break;
273 
274  case self::TYPE_RANGE:
275  list( $start, $end ) = IP::parseRange( $target );
276  $conds['ipb_address'][] = (string)$target;
277  $conds[] = self::getRangeCond( $start, $end );
278  $conds = $db->makeList( $conds, LIST_OR );
279  break;
280 
281  default:
282  throw new MWException( "Tried to load block with invalid type" );
283  }
284  }
285 
286  $res = $db->select( 'ipblocks', self::selectFields(), $conds, __METHOD__ );
287 
288  # This result could contain a block on the user, a block on the IP, and a russian-doll
289  # set of rangeblocks. We want to choose the most specific one, so keep a leader board.
290  $bestRow = null;
291 
292  # Lower will be better
293  $bestBlockScore = 100;
294 
295  # This is begging for $this = $bestBlock, but that's not allowed in PHP :(
296  $bestBlockPreventsEdit = null;
297 
298  foreach ( $res as $row ) {
299  $block = self::newFromRow( $row );
300 
301  # Don't use expired blocks
302  if ( $block->isExpired() ) {
303  continue;
304  }
305 
306  # Don't use anon only blocks on users
307  if ( $this->type == self::TYPE_USER && !$block->isHardblock() ) {
308  continue;
309  }
310 
311  if ( $block->getType() == self::TYPE_RANGE ) {
312  # This is the number of bits that are allowed to vary in the block, give
313  # or take some floating point errors
314  $end = Wikimedia\base_convert( $block->getRangeEnd(), 16, 10 );
315  $start = Wikimedia\base_convert( $block->getRangeStart(), 16, 10 );
316  $size = log( $end - $start + 1, 2 );
317 
318  # This has the nice property that a /32 block is ranked equally with a
319  # single-IP block, which is exactly what it is...
320  $score = self::TYPE_RANGE - 1 + ( $size / 128 );
321 
322  } else {
323  $score = $block->getType();
324  }
325 
326  if ( $score < $bestBlockScore ) {
327  $bestBlockScore = $score;
328  $bestRow = $row;
329  $bestBlockPreventsEdit = $block->prevents( 'edit' );
330  }
331  }
332 
333  if ( $bestRow !== null ) {
334  $this->initFromRow( $bestRow );
335  $this->prevents( 'edit', $bestBlockPreventsEdit );
336  return true;
337  } else {
338  return false;
339  }
340  }
341 
348  public static function getRangeCond( $start, $end = null ) {
349  if ( $end === null ) {
350  $end = $start;
351  }
352  # Per bug 14634, we want to include relevant active rangeblocks; for
353  # rangeblocks, we want to include larger ranges which enclose the given
354  # range. We know that all blocks must be smaller than $wgBlockCIDRLimit,
355  # so we can improve performance by filtering on a LIKE clause
356  $chunk = self::getIpFragment( $start );
357  $dbr = wfGetDB( DB_REPLICA );
358  $like = $dbr->buildLike( $chunk, $dbr->anyString() );
359 
360  # Fairly hard to make a malicious SQL statement out of hex characters,
361  # but stranger things have happened...
362  $safeStart = $dbr->addQuotes( $start );
363  $safeEnd = $dbr->addQuotes( $end );
364 
365  return $dbr->makeList(
366  [
367  "ipb_range_start $like",
368  "ipb_range_start <= $safeStart",
369  "ipb_range_end >= $safeEnd",
370  ],
371  LIST_AND
372  );
373  }
374 
381  protected static function getIpFragment( $hex ) {
382  global $wgBlockCIDRLimit;
383  if ( substr( $hex, 0, 3 ) == 'v6-' ) {
384  return 'v6-' . substr( substr( $hex, 3 ), 0, floor( $wgBlockCIDRLimit['IPv6'] / 4 ) );
385  } else {
386  return substr( $hex, 0, floor( $wgBlockCIDRLimit['IPv4'] / 4 ) );
387  }
388  }
389 
395  protected function initFromRow( $row ) {
396  $this->setTarget( $row->ipb_address );
397  if ( $row->ipb_by ) { // local user
398  $this->setBlocker( User::newFromId( $row->ipb_by ) );
399  } else { // foreign user
400  $this->setBlocker( $row->ipb_by_text );
401  }
402 
403  $this->mReason = $row->ipb_reason;
404  $this->mTimestamp = wfTimestamp( TS_MW, $row->ipb_timestamp );
405  $this->mAuto = $row->ipb_auto;
406  $this->mHideName = $row->ipb_deleted;
407  $this->mId = (int)$row->ipb_id;
408  $this->mParentBlockId = $row->ipb_parent_block_id;
409 
410  // I wish I didn't have to do this
411  $this->mExpiry = wfGetDB( DB_REPLICA )->decodeExpiry( $row->ipb_expiry );
412 
413  $this->isHardblock( !$row->ipb_anon_only );
414  $this->isAutoblocking( $row->ipb_enable_autoblock );
415 
416  $this->prevents( 'createaccount', $row->ipb_create_account );
417  $this->prevents( 'sendemail', $row->ipb_block_email );
418  $this->prevents( 'editownusertalk', !$row->ipb_allow_usertalk );
419  }
420 
426  public static function newFromRow( $row ) {
427  $block = new Block;
428  $block->initFromRow( $row );
429  return $block;
430  }
431 
438  public function delete() {
439  if ( wfReadOnly() ) {
440  return false;
441  }
442 
443  if ( !$this->getId() ) {
444  throw new MWException( "Block::delete() requires that the mId member be filled\n" );
445  }
446 
447  $dbw = wfGetDB( DB_MASTER );
448  $dbw->delete( 'ipblocks', [ 'ipb_parent_block_id' => $this->getId() ], __METHOD__ );
449  $dbw->delete( 'ipblocks', [ 'ipb_id' => $this->getId() ], __METHOD__ );
450 
451  return $dbw->affectedRows() > 0;
452  }
453 
462  public function insert( $dbw = null ) {
463  global $wgBlockDisablesLogin;
464  wfDebug( "Block::insert; timestamp {$this->mTimestamp}\n" );
465 
466  if ( $dbw === null ) {
467  $dbw = wfGetDB( DB_MASTER );
468  }
469 
470  # Periodic purge via commit hooks
471  if ( mt_rand( 0, 9 ) == 0 ) {
473  }
474 
475  $row = $this->getDatabaseArray();
476  $row['ipb_id'] = $dbw->nextSequenceValue( "ipblocks_ipb_id_seq" );
477 
478  $dbw->insert( 'ipblocks', $row, __METHOD__, [ 'IGNORE' ] );
479  $affected = $dbw->affectedRows();
480  $this->mId = $dbw->insertId();
481 
482  # Don't collide with expired blocks.
483  # Do this after trying to insert to avoid locking.
484  if ( !$affected ) {
485  # T96428: The ipb_address index uses a prefix on a field, so
486  # use a standard SELECT + DELETE to avoid annoying gap locks.
487  $ids = $dbw->selectFieldValues( 'ipblocks',
488  'ipb_id',
489  [
490  'ipb_address' => $row['ipb_address'],
491  'ipb_user' => $row['ipb_user'],
492  'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() )
493  ],
494  __METHOD__
495  );
496  if ( $ids ) {
497  $dbw->delete( 'ipblocks', [ 'ipb_id' => $ids ], __METHOD__ );
498  $dbw->insert( 'ipblocks', $row, __METHOD__, [ 'IGNORE' ] );
499  $affected = $dbw->affectedRows();
500  $this->mId = $dbw->insertId();
501  }
502  }
503 
504  if ( $affected ) {
505  $auto_ipd_ids = $this->doRetroactiveAutoblock();
506 
507  if ( $wgBlockDisablesLogin && $this->target instanceof User ) {
508  // Change user login token to force them to be logged out.
509  $this->target->setToken();
510  $this->target->saveSettings();
511  }
512 
513  return [ 'id' => $this->mId, 'autoIds' => $auto_ipd_ids ];
514  }
515 
516  return false;
517  }
518 
526  public function update() {
527  wfDebug( "Block::update; timestamp {$this->mTimestamp}\n" );
528  $dbw = wfGetDB( DB_MASTER );
529 
530  $dbw->startAtomic( __METHOD__ );
531 
532  $dbw->update(
533  'ipblocks',
534  $this->getDatabaseArray( $dbw ),
535  [ 'ipb_id' => $this->getId() ],
536  __METHOD__
537  );
538 
539  $affected = $dbw->affectedRows();
540 
541  if ( $this->isAutoblocking() ) {
542  // update corresponding autoblock(s) (bug 48813)
543  $dbw->update(
544  'ipblocks',
545  $this->getAutoblockUpdateArray(),
546  [ 'ipb_parent_block_id' => $this->getId() ],
547  __METHOD__
548  );
549  } else {
550  // autoblock no longer required, delete corresponding autoblock(s)
551  $dbw->delete(
552  'ipblocks',
553  [ 'ipb_parent_block_id' => $this->getId() ],
554  __METHOD__
555  );
556  }
557 
558  $dbw->endAtomic( __METHOD__ );
559 
560  if ( $affected ) {
561  $auto_ipd_ids = $this->doRetroactiveAutoblock();
562  return [ 'id' => $this->mId, 'autoIds' => $auto_ipd_ids ];
563  }
564 
565  return false;
566  }
567 
573  protected function getDatabaseArray( $db = null ) {
574  if ( !$db ) {
575  $db = wfGetDB( DB_REPLICA );
576  }
577  $expiry = $db->encodeExpiry( $this->mExpiry );
578 
579  if ( $this->forcedTargetID ) {
580  $uid = $this->forcedTargetID;
581  } else {
582  $uid = $this->target instanceof User ? $this->target->getId() : 0;
583  }
584 
585  $a = [
586  'ipb_address' => (string)$this->target,
587  'ipb_user' => $uid,
588  'ipb_by' => $this->getBy(),
589  'ipb_by_text' => $this->getByName(),
590  'ipb_reason' => $this->mReason,
591  'ipb_timestamp' => $db->timestamp( $this->mTimestamp ),
592  'ipb_auto' => $this->mAuto,
593  'ipb_anon_only' => !$this->isHardblock(),
594  'ipb_create_account' => $this->prevents( 'createaccount' ),
595  'ipb_enable_autoblock' => $this->isAutoblocking(),
596  'ipb_expiry' => $expiry,
597  'ipb_range_start' => $this->getRangeStart(),
598  'ipb_range_end' => $this->getRangeEnd(),
599  'ipb_deleted' => intval( $this->mHideName ), // typecast required for SQLite
600  'ipb_block_email' => $this->prevents( 'sendemail' ),
601  'ipb_allow_usertalk' => !$this->prevents( 'editownusertalk' ),
602  'ipb_parent_block_id' => $this->mParentBlockId
603  ];
604 
605  return $a;
606  }
607 
611  protected function getAutoblockUpdateArray() {
612  return [
613  'ipb_by' => $this->getBy(),
614  'ipb_by_text' => $this->getByName(),
615  'ipb_reason' => $this->mReason,
616  'ipb_create_account' => $this->prevents( 'createaccount' ),
617  'ipb_deleted' => (int)$this->mHideName, // typecast required for SQLite
618  'ipb_allow_usertalk' => !$this->prevents( 'editownusertalk' ),
619  ];
620  }
621 
628  protected function doRetroactiveAutoblock() {
629  $blockIds = [];
630  # If autoblock is enabled, autoblock the LAST IP(s) used
631  if ( $this->isAutoblocking() && $this->getType() == self::TYPE_USER ) {
632  wfDebug( "Doing retroactive autoblocks for " . $this->getTarget() . "\n" );
633 
634  $continue = Hooks::run(
635  'PerformRetroactiveAutoblock', [ $this, &$blockIds ] );
636 
637  if ( $continue ) {
638  self::defaultRetroactiveAutoblock( $this, $blockIds );
639  }
640  }
641  return $blockIds;
642  }
643 
651  protected static function defaultRetroactiveAutoblock( Block $block, array &$blockIds ) {
652  global $wgPutIPinRC;
653 
654  // No IPs are in recentchanges table, so nothing to select
655  if ( !$wgPutIPinRC ) {
656  return;
657  }
658 
659  $dbr = wfGetDB( DB_REPLICA );
660 
661  $options = [ 'ORDER BY' => 'rc_timestamp DESC' ];
662  $conds = [ 'rc_user_text' => (string)$block->getTarget() ];
663 
664  // Just the last IP used.
665  $options['LIMIT'] = 1;
666 
667  $res = $dbr->select( 'recentchanges', [ 'rc_ip' ], $conds,
668  __METHOD__, $options );
669 
670  if ( !$res->numRows() ) {
671  # No results, don't autoblock anything
672  wfDebug( "No IP found to retroactively autoblock\n" );
673  } else {
674  foreach ( $res as $row ) {
675  if ( $row->rc_ip ) {
676  $id = $block->doAutoblock( $row->rc_ip );
677  if ( $id ) {
678  $blockIds[] = $id;
679  }
680  }
681  }
682  }
683  }
684 
692  public static function isWhitelistedFromAutoblocks( $ip ) {
693  // Try to get the autoblock_whitelist from the cache, as it's faster
694  // than getting the msg raw and explode()'ing it.
695  $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
696  $lines = $cache->getWithSetCallback(
697  wfMemcKey( 'ipb', 'autoblock', 'whitelist' ),
698  $cache::TTL_DAY,
699  function ( $curValue, &$ttl, array &$setOpts ) {
701 
702  return explode( "\n",
703  wfMessage( 'autoblock_whitelist' )->inContentLanguage()->plain() );
704  }
705  );
706 
707  wfDebug( "Checking the autoblock whitelist..\n" );
708 
709  foreach ( $lines as $line ) {
710  # List items only
711  if ( substr( $line, 0, 1 ) !== '*' ) {
712  continue;
713  }
714 
715  $wlEntry = substr( $line, 1 );
716  $wlEntry = trim( $wlEntry );
717 
718  wfDebug( "Checking $ip against $wlEntry..." );
719 
720  # Is the IP in this range?
721  if ( IP::isInRange( $ip, $wlEntry ) ) {
722  wfDebug( " IP $ip matches $wlEntry, not autoblocking\n" );
723  return true;
724  } else {
725  wfDebug( " No match\n" );
726  }
727  }
728 
729  return false;
730  }
731 
738  public function doAutoblock( $autoblockIP ) {
739  # If autoblocks are disabled, go away.
740  if ( !$this->isAutoblocking() ) {
741  return false;
742  }
743 
744  # Check for presence on the autoblock whitelist.
745  if ( self::isWhitelistedFromAutoblocks( $autoblockIP ) ) {
746  return false;
747  }
748 
749  # Allow hooks to cancel the autoblock.
750  if ( !Hooks::run( 'AbortAutoblock', [ $autoblockIP, &$this ] ) ) {
751  wfDebug( "Autoblock aborted by hook.\n" );
752  return false;
753  }
754 
755  # It's okay to autoblock. Go ahead and insert/update the block...
756 
757  # Do not add a *new* block if the IP is already blocked.
758  $ipblock = Block::newFromTarget( $autoblockIP );
759  if ( $ipblock ) {
760  # Check if the block is an autoblock and would exceed the user block
761  # if renewed. If so, do nothing, otherwise prolong the block time...
762  if ( $ipblock->mAuto && // @todo Why not compare $ipblock->mExpiry?
763  $this->mExpiry > Block::getAutoblockExpiry( $ipblock->mTimestamp )
764  ) {
765  # Reset block timestamp to now and its expiry to
766  # $wgAutoblockExpiry in the future
767  $ipblock->updateTimestamp();
768  }
769  return false;
770  }
771 
772  # Make a new block object with the desired properties.
773  $autoblock = new Block;
774  wfDebug( "Autoblocking {$this->getTarget()}@" . $autoblockIP . "\n" );
775  $autoblock->setTarget( $autoblockIP );
776  $autoblock->setBlocker( $this->getBlocker() );
777  $autoblock->mReason = wfMessage( 'autoblocker', $this->getTarget(), $this->mReason )
778  ->inContentLanguage()->plain();
780  $autoblock->mTimestamp = $timestamp;
781  $autoblock->mAuto = 1;
782  $autoblock->prevents( 'createaccount', $this->prevents( 'createaccount' ) );
783  # Continue suppressing the name if needed
784  $autoblock->mHideName = $this->mHideName;
785  $autoblock->prevents( 'editownusertalk', $this->prevents( 'editownusertalk' ) );
786  $autoblock->mParentBlockId = $this->mId;
787 
788  if ( $this->mExpiry == 'infinity' ) {
789  # Original block was indefinite, start an autoblock now
790  $autoblock->mExpiry = Block::getAutoblockExpiry( $timestamp );
791  } else {
792  # If the user is already blocked with an expiry date, we don't
793  # want to pile on top of that.
794  $autoblock->mExpiry = min( $this->mExpiry, Block::getAutoblockExpiry( $timestamp ) );
795  }
796 
797  # Insert the block...
798  $status = $autoblock->insert();
799  return $status
800  ? $status['id']
801  : false;
802  }
803 
808  public function deleteIfExpired() {
809 
810  if ( $this->isExpired() ) {
811  wfDebug( "Block::deleteIfExpired() -- deleting\n" );
812  $this->delete();
813  $retVal = true;
814  } else {
815  wfDebug( "Block::deleteIfExpired() -- not expired\n" );
816  $retVal = false;
817  }
818 
819  return $retVal;
820  }
821 
826  public function isExpired() {
828  wfDebug( "Block::isExpired() checking current " . $timestamp . " vs $this->mExpiry\n" );
829 
830  if ( !$this->mExpiry ) {
831  return false;
832  } else {
833  return $timestamp > $this->mExpiry;
834  }
835  }
836 
841  public function isValid() {
842  return $this->getTarget() != null;
843  }
844 
848  public function updateTimestamp() {
849  if ( $this->mAuto ) {
850  $this->mTimestamp = wfTimestamp();
851  $this->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
852 
853  $dbw = wfGetDB( DB_MASTER );
854  $dbw->update( 'ipblocks',
855  [ /* SET */
856  'ipb_timestamp' => $dbw->timestamp( $this->mTimestamp ),
857  'ipb_expiry' => $dbw->timestamp( $this->mExpiry ),
858  ],
859  [ /* WHERE */
860  'ipb_id' => $this->getId(),
861  ],
862  __METHOD__
863  );
864  }
865  }
866 
872  public function getRangeStart() {
873  switch ( $this->type ) {
874  case self::TYPE_USER:
875  return '';
876  case self::TYPE_IP:
877  return IP::toHex( $this->target );
878  case self::TYPE_RANGE:
879  list( $start, /*...*/ ) = IP::parseRange( $this->target );
880  return $start;
881  default:
882  throw new MWException( "Block with invalid type" );
883  }
884  }
885 
891  public function getRangeEnd() {
892  switch ( $this->type ) {
893  case self::TYPE_USER:
894  return '';
895  case self::TYPE_IP:
896  return IP::toHex( $this->target );
897  case self::TYPE_RANGE:
898  list( /*...*/, $end ) = IP::parseRange( $this->target );
899  return $end;
900  default:
901  throw new MWException( "Block with invalid type" );
902  }
903  }
904 
910  public function getBy() {
911  $blocker = $this->getBlocker();
912  return ( $blocker instanceof User )
913  ? $blocker->getId()
914  : 0;
915  }
916 
922  public function getByName() {
923  $blocker = $this->getBlocker();
924  return ( $blocker instanceof User )
925  ? $blocker->getName()
926  : (string)$blocker; // username
927  }
928 
933  public function getId() {
934  return $this->mId;
935  }
936 
943  public function fromMaster( $x = null ) {
944  return wfSetVar( $this->mFromMaster, $x );
945  }
946 
952  public function isHardblock( $x = null ) {
953  wfSetVar( $this->isHardblock, $x );
954 
955  # You can't *not* hardblock a user
956  return $this->getType() == self::TYPE_USER
957  ? true
959  }
960 
965  public function isAutoblocking( $x = null ) {
966  wfSetVar( $this->isAutoblocking, $x );
967 
968  # You can't put an autoblock on an IP or range as we don't have any history to
969  # look over to get more IPs from
970  return $this->getType() == self::TYPE_USER
971  ? $this->isAutoblocking
972  : false;
973  }
974 
982  public function prevents( $action, $x = null ) {
983  global $wgBlockDisablesLogin;
984  $res = null;
985  switch ( $action ) {
986  case 'edit':
987  # For now... <evil laugh>
988  $res = true;
989  break;
990  case 'createaccount':
991  $res = wfSetVar( $this->mCreateAccount, $x );
992  break;
993  case 'sendemail':
994  $res = wfSetVar( $this->mBlockEmail, $x );
995  break;
996  case 'editownusertalk':
997  $res = wfSetVar( $this->mDisableUsertalk, $x );
998  break;
999  case 'read':
1000  $res = false;
1001  break;
1002  }
1003  if ( !$res && $wgBlockDisablesLogin ) {
1004  // If a block would disable login, then it should
1005  // prevent any action that all users cannot do
1006  $anon = new User;
1007  $res = $anon->isAllowed( $action ) ? $res : true;
1008  }
1009 
1010  return $res;
1011  }
1012 
1017  public function getRedactedName() {
1018  if ( $this->mAuto ) {
1019  return Html::rawElement(
1020  'span',
1021  [ 'class' => 'mw-autoblockid' ],
1022  wfMessage( 'autoblockid', $this->mId )
1023  );
1024  } else {
1025  return htmlspecialchars( $this->getTarget() );
1026  }
1027  }
1028 
1035  public static function getAutoblockExpiry( $timestamp ) {
1036  global $wgAutoblockExpiry;
1037 
1038  return wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $timestamp ) + $wgAutoblockExpiry );
1039  }
1040 
1044  public static function purgeExpired() {
1045  if ( wfReadOnly() ) {
1046  return;
1047  }
1048 
1050  wfGetDB( DB_MASTER ),
1051  __METHOD__,
1052  function ( IDatabase $dbw, $fname ) {
1053  $dbw->delete(
1054  'ipblocks',
1055  [ 'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ],
1056  $fname
1057  );
1058  }
1059  ) );
1060  }
1061 
1082  public static function newFromTarget( $specificTarget, $vagueTarget = null, $fromMaster = false ) {
1083 
1084  list( $target, $type ) = self::parseTarget( $specificTarget );
1085  if ( $type == Block::TYPE_ID || $type == Block::TYPE_AUTO ) {
1086  return Block::newFromID( $target );
1087 
1088  } elseif ( $target === null && $vagueTarget == '' ) {
1089  # We're not going to find anything useful here
1090  # Be aware that the == '' check is explicit, since empty values will be
1091  # passed by some callers (bug 29116)
1092  return null;
1093 
1094  } elseif ( in_array(
1095  $type,
1097  ) {
1098  $block = new Block();
1099  $block->fromMaster( $fromMaster );
1100 
1101  if ( $type !== null ) {
1102  $block->setTarget( $target );
1103  }
1104 
1105  if ( $block->newLoad( $vagueTarget ) ) {
1106  return $block;
1107  }
1108  }
1109  return null;
1110  }
1111 
1122  public static function getBlocksForIPList( array $ipChain, $isAnon, $fromMaster = false ) {
1123  if ( !count( $ipChain ) ) {
1124  return [];
1125  }
1126 
1127  $conds = [];
1128  $proxyLookup = MediaWikiServices::getInstance()->getProxyLookup();
1129  foreach ( array_unique( $ipChain ) as $ipaddr ) {
1130  # Discard invalid IP addresses. Since XFF can be spoofed and we do not
1131  # necessarily trust the header given to us, make sure that we are only
1132  # checking for blocks on well-formatted IP addresses (IPv4 and IPv6).
1133  # Do not treat private IP spaces as special as it may be desirable for wikis
1134  # to block those IP ranges in order to stop misbehaving proxies that spoof XFF.
1135  if ( !IP::isValid( $ipaddr ) ) {
1136  continue;
1137  }
1138  # Don't check trusted IPs (includes local squids which will be in every request)
1139  if ( $proxyLookup->isTrustedProxy( $ipaddr ) ) {
1140  continue;
1141  }
1142  # Check both the original IP (to check against single blocks), as well as build
1143  # the clause to check for rangeblocks for the given IP.
1144  $conds['ipb_address'][] = $ipaddr;
1145  $conds[] = self::getRangeCond( IP::toHex( $ipaddr ) );
1146  }
1147 
1148  if ( !count( $conds ) ) {
1149  return [];
1150  }
1151 
1152  if ( $fromMaster ) {
1153  $db = wfGetDB( DB_MASTER );
1154  } else {
1155  $db = wfGetDB( DB_REPLICA );
1156  }
1157  $conds = $db->makeList( $conds, LIST_OR );
1158  if ( !$isAnon ) {
1159  $conds = [ $conds, 'ipb_anon_only' => 0 ];
1160  }
1161  $selectFields = array_merge(
1162  [ 'ipb_range_start', 'ipb_range_end' ],
1164  );
1165  $rows = $db->select( 'ipblocks',
1166  $selectFields,
1167  $conds,
1168  __METHOD__
1169  );
1170 
1171  $blocks = [];
1172  foreach ( $rows as $row ) {
1173  $block = self::newFromRow( $row );
1174  if ( !$block->isExpired() ) {
1175  $blocks[] = $block;
1176  }
1177  }
1178 
1179  return $blocks;
1180  }
1181 
1203  public static function chooseBlock( array $blocks, array $ipChain ) {
1204  if ( !count( $blocks ) ) {
1205  return null;
1206  } elseif ( count( $blocks ) == 1 ) {
1207  return $blocks[0];
1208  }
1209 
1210  // Sort hard blocks before soft ones and secondarily sort blocks
1211  // that disable account creation before those that don't.
1212  usort( $blocks, function ( Block $a, Block $b ) {
1213  $aWeight = (int)$a->isHardblock() . (int)$a->prevents( 'createaccount' );
1214  $bWeight = (int)$b->isHardblock() . (int)$b->prevents( 'createaccount' );
1215  return strcmp( $bWeight, $aWeight ); // highest weight first
1216  } );
1217 
1218  $blocksListExact = [
1219  'hard' => false,
1220  'disable_create' => false,
1221  'other' => false,
1222  'auto' => false
1223  ];
1224  $blocksListRange = [
1225  'hard' => false,
1226  'disable_create' => false,
1227  'other' => false,
1228  'auto' => false
1229  ];
1230  $ipChain = array_reverse( $ipChain );
1231 
1233  foreach ( $blocks as $block ) {
1234  // Stop searching if we have already have a "better" block. This
1235  // is why the order of the blocks matters
1236  if ( !$block->isHardblock() && $blocksListExact['hard'] ) {
1237  break;
1238  } elseif ( !$block->prevents( 'createaccount' ) && $blocksListExact['disable_create'] ) {
1239  break;
1240  }
1241 
1242  foreach ( $ipChain as $checkip ) {
1243  $checkipHex = IP::toHex( $checkip );
1244  if ( (string)$block->getTarget() === $checkip ) {
1245  if ( $block->isHardblock() ) {
1246  $blocksListExact['hard'] = $blocksListExact['hard'] ?: $block;
1247  } elseif ( $block->prevents( 'createaccount' ) ) {
1248  $blocksListExact['disable_create'] = $blocksListExact['disable_create'] ?: $block;
1249  } elseif ( $block->mAuto ) {
1250  $blocksListExact['auto'] = $blocksListExact['auto'] ?: $block;
1251  } else {
1252  $blocksListExact['other'] = $blocksListExact['other'] ?: $block;
1253  }
1254  // We found closest exact match in the ip list, so go to the next Block
1255  break;
1256  } elseif ( array_filter( $blocksListExact ) == []
1257  && $block->getRangeStart() <= $checkipHex
1258  && $block->getRangeEnd() >= $checkipHex
1259  ) {
1260  if ( $block->isHardblock() ) {
1261  $blocksListRange['hard'] = $blocksListRange['hard'] ?: $block;
1262  } elseif ( $block->prevents( 'createaccount' ) ) {
1263  $blocksListRange['disable_create'] = $blocksListRange['disable_create'] ?: $block;
1264  } elseif ( $block->mAuto ) {
1265  $blocksListRange['auto'] = $blocksListRange['auto'] ?: $block;
1266  } else {
1267  $blocksListRange['other'] = $blocksListRange['other'] ?: $block;
1268  }
1269  break;
1270  }
1271  }
1272  }
1273 
1274  if ( array_filter( $blocksListExact ) == [] ) {
1275  $blocksList = &$blocksListRange;
1276  } else {
1277  $blocksList = &$blocksListExact;
1278  }
1279 
1280  $chosenBlock = null;
1281  if ( $blocksList['hard'] ) {
1282  $chosenBlock = $blocksList['hard'];
1283  } elseif ( $blocksList['disable_create'] ) {
1284  $chosenBlock = $blocksList['disable_create'];
1285  } elseif ( $blocksList['other'] ) {
1286  $chosenBlock = $blocksList['other'];
1287  } elseif ( $blocksList['auto'] ) {
1288  $chosenBlock = $blocksList['auto'];
1289  } else {
1290  throw new MWException( "Proxy block found, but couldn't be classified." );
1291  }
1292 
1293  return $chosenBlock;
1294  }
1295 
1305  public static function parseTarget( $target ) {
1306  # We may have been through this before
1307  if ( $target instanceof User ) {
1308  if ( IP::isValid( $target->getName() ) ) {
1309  return [ $target, self::TYPE_IP ];
1310  } else {
1311  return [ $target, self::TYPE_USER ];
1312  }
1313  } elseif ( $target === null ) {
1314  return [ null, null ];
1315  }
1316 
1317  $target = trim( $target );
1318 
1319  if ( IP::isValid( $target ) ) {
1320  # We can still create a User if it's an IP address, but we need to turn
1321  # off validation checking (which would exclude IP addresses)
1322  return [
1325  ];
1326 
1327  } elseif ( IP::isValidBlock( $target ) ) {
1328  # Can't create a User from an IP range
1330  }
1331 
1332  # Consider the possibility that this is not a username at all
1333  # but actually an old subpage (bug #29797)
1334  if ( strpos( $target, '/' ) !== false ) {
1335  # An old subpage, drill down to the user behind it
1336  $target = explode( '/', $target )[0];
1337  }
1338 
1339  $userObj = User::newFromName( $target );
1340  if ( $userObj instanceof User ) {
1341  # Note that since numbers are valid usernames, a $target of "12345" will be
1342  # considered a User. If you want to pass a block ID, prepend a hash "#12345",
1343  # since hash characters are not valid in usernames or titles generally.
1344  return [ $userObj, Block::TYPE_USER ];
1345 
1346  } elseif ( preg_match( '/^#\d+$/', $target ) ) {
1347  # Autoblock reference in the form "#12345"
1348  return [ substr( $target, 1 ), Block::TYPE_AUTO ];
1349 
1350  } else {
1351  # WTF?
1352  return [ null, null ];
1353  }
1354  }
1355 
1360  public function getType() {
1361  return $this->mAuto
1362  ? self::TYPE_AUTO
1363  : $this->type;
1364  }
1365 
1373  public function getTargetAndType() {
1374  return [ $this->getTarget(), $this->getType() ];
1375  }
1376 
1383  public function getTarget() {
1384  return $this->target;
1385  }
1386 
1392  public function getExpiry() {
1393  return $this->mExpiry;
1394  }
1395 
1400  public function setTarget( $target ) {
1401  list( $this->target, $this->type ) = self::parseTarget( $target );
1402  }
1403 
1408  public function getBlocker() {
1409  return $this->blocker;
1410  }
1411 
1416  public function setBlocker( $user ) {
1417  $this->blocker = $user;
1418  }
1419 
1428  $blocker = $this->getBlocker();
1429  if ( $blocker instanceof User ) { // local user
1430  $blockerUserpage = $blocker->getUserPage();
1431  $link = "[[{$blockerUserpage->getPrefixedText()}|{$blockerUserpage->getText()}]]";
1432  } else { // foreign user
1433  $link = $blocker;
1434  }
1435 
1436  $reason = $this->mReason;
1437  if ( $reason == '' ) {
1438  $reason = $context->msg( 'blockednoreason' )->text();
1439  }
1440 
1441  /* $ip returns who *is* being blocked, $intended contains who was meant to be blocked.
1442  * This could be a username, an IP range, or a single IP. */
1443  $intended = $this->getTarget();
1444 
1445  $lang = $context->getLanguage();
1446  return [
1447  $this->mAuto ? 'autoblockedtext' : 'blockedtext',
1448  $link,
1449  $reason,
1450  $context->getRequest()->getIP(),
1451  $this->getByName(),
1452  $this->getId(),
1453  $lang->formatExpiry( $this->mExpiry ),
1454  (string)$intended,
1455  $lang->userTimeAndDate( $this->mTimestamp, $context->getUser() ),
1456  ];
1457  }
1458 }
getBy()
Get the user id of the blocking sysop.
Definition: Block.php:910
static newFromName($name, $validate= 'valid')
Static factory method for creation from username.
Definition: User.php:525
static getRangeCond($start, $end=null)
Get a set of SQL conditions which will select rangeblocks encompassing a given range.
Definition: Block.php:348
bool $isHardblock
Definition: Block.php:72
setBlocker($user)
Set the user who implemented (or will implement) this block.
Definition: Block.php:1416
Interface for objects which can provide a MediaWiki context on request.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
wfGetDB($db, $groups=[], $wiki=false)
Get a Database object.
the array() calling protocol came about after MediaWiki 1.4rc1.
string $mTimestamp
Definition: Block.php:30
either a plain
Definition: hooks.txt:1987
static defaultRetroactiveAutoblock(Block $block, array &$blockIds)
Retroactively autoblocks the last IP used by the user (if it is a user) blocked by this Block...
Definition: Block.php:651
static sanitizeIP($ip)
Convert an IP into a verbose, uppercase, normalized form.
Definition: IP.php:140
$context
Definition: load.php:50
static chooseBlock(array $blocks, array $ipChain)
From a list of multiple blocks, find the most exact and strongest Block.
Definition: Block.php:1203
const TYPE_RANGE
Definition: Block.php:80
static isInRange($addr, $range)
Determine if a given IPv4/IPv6 address is in a given CIDR network.
Definition: IP.php:638
static isWhitelistedFromAutoblocks($ip)
Checks whether a given IP is on the autoblock whitelist.
Definition: Block.php:692
static sanitizeRange($range)
Gets rid of unneeded numbers in quad-dotted/octet IP strings For example, 127.111.113.151/24 -> 127.111.113.0/24.
Definition: IP.php:713
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:189
bool $mFromMaster
Definition: Block.php:48
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
isValid()
Is the block address valid (i.e.
Definition: Block.php:841
static getCacheSetOptions(IDatabase $db1)
Merge the result of getSessionLagStatus() for several DBs using the most pessimistic values to estima...
Definition: Database.php:3039
msg()
Get a Message object with context set.
getType()
Get the type of target for this particular block.
Definition: Block.php:1360
static rawElement($element, $attribs=[], $contents= '')
Returns an HTML element in a string.
Definition: Html.php:209
if(!isset($args[0])) $lang
int $mParentBlockId
Definition: Block.php:42
bool $mDisableUsertalk
Definition: Block.php:54
equals(Block $block)
Check if two blocks are effectively equal.
Definition: Block.php:221
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
Definition: hooks.txt:177
static newFromId($id)
Static factory method for creation from a given user ID.
Definition: User.php:548
const TYPE_IP
Definition: Block.php:79
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:23
__construct($options=[])
Create a new block with specified parameters on a user, IP or IP range.
Definition: Block.php:106
getId()
Get the block ID.
Definition: Block.php:933
when a variable name is used in a it is silently declared as a new local masking the global
Definition: design.txt:93
timestamp($ts=0)
Convert a timestamp in one of the formats accepted by wfTimestamp() to the format used for inserting ...
const DB_MASTER
Definition: defines.php:23
getName()
Get the user name, or the IP of an anonymous user.
Definition: User.php:2108
update()
Update a block in the DB with new parameters.
Definition: Block.php:526
wfDebug($text, $dest= 'all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
const TS_UNIX
Unix time - the number of seconds since 1970-01-01 00:00:00 UTC.
Definition: defines.php:6
getRangeEnd()
Get the IP address at the end of the range in Hex form.
Definition: Block.php:891
usually copyright or history_copyright This message must be in HTML not wikitext & $link
Definition: hooks.txt:2889
getAutoblockUpdateArray()
Definition: Block.php:611
wfTimestamp($outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
deleteIfExpired()
Check if a block has expired.
Definition: Block.php:808
getUser()
Get the User object.
insert($dbw=null)
Insert a block into the block table.
Definition: Block.php:462
delete($table, $conds, $fname=__METHOD__)
DELETE query wrapper.
getExpiry()
Definition: Block.php:1392
wfReadOnly()
Check whether the wiki is in read-only mode.
const LIST_AND
Definition: Defines.php:35
int $type
Block::TYPE_ constant.
Definition: Block.php:66
getTargetAndType()
Get the target and target type for this particular Block.
Definition: Block.php:1373
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock()-offset Set to overwrite offset parameter in $wgRequest set to ''to unsetoffset-wrap String Wrap the message in html(usually something like"&lt
if($limit) $timestamp
static newFromTarget($specificTarget, $vagueTarget=null, $fromMaster=false)
Given a target and the target's type, get an existing Block object if possible.
Definition: Block.php:1082
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context $options
Definition: hooks.txt:1046
getRedactedName()
Get the block name, but with autoblocked IPs hidden as per standard privacy policy.
Definition: Block.php:1017
bool $isAutoblocking
Definition: Block.php:75
static isValid($ip)
Validate an IP address.
Definition: IP.php:113
$res
Definition: database.txt:21
bool $mBlockEmail
Definition: Block.php:51
setTarget($target)
Set the target for this block, and update $this->type accordingly.
Definition: Block.php:1400
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Deferrable Update for closure/callback updates via IDatabase::doAtomicSection()
$cache
Definition: mcc.php:33
int $mId
Definition: Block.php:45
doAutoblock($autoblockIP)
Autoblocks the given IP, referring to this Block.
Definition: Block.php:738
wfDeprecated($function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
const TS_MW
MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS)
Definition: defines.php:11
static parseTarget($target)
From an existing Block, get the target and the type of target.
Definition: Block.php:1305
static purgeExpired()
Purge expired blocks from the ipblocks table.
Definition: Block.php:1044
newLoad($vagueTarget=null)
Load a block from the database which affects the already-set $this->target: 1) A block directly on th...
Definition: Block.php:247
const TYPE_ID
Definition: Block.php:82
static run($event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:131
static toHex($ip)
Return a zero-padded upper case hexadecimal representation of an IP address.
Definition: IP.php:405
const TYPE_AUTO
Definition: Block.php:81
getLanguage()
Get the Language object.
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
static newFromRow($row)
Create a new Block object from a database row.
Definition: Block.php:426
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a local account $user
Definition: hooks.txt:242
const LIST_OR
Definition: Defines.php:38
User string $target
Definition: Block.php:60
doRetroactiveAutoblock()
Retroactively autoblocks the last IP used by the user (if it is a user) blocked by this Block...
Definition: Block.php:628
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
wfSetVar(&$dest, $source, $force=false)
Sets dest to source and returns the original value of dest If source is NULL, it just returns the val...
static getBlocksForIPList(array $ipChain, $isAnon, $fromMaster=false)
Get all blocks that match any IP from an array of IP addresses.
Definition: Block.php:1122
bool $mAuto
Definition: Block.php:33
int $forcedTargetID
Hack for foreign blocking (CentralAuth)
Definition: Block.php:63
This document describes the state of Postgres support in and is fairly well maintained The main code is very well while extensions are very hit and miss it is probably the most supported database after MySQL Much of the work in making MediaWiki database agnostic came about through the work of creating Postgres as and are nearing end of but without copying over all the usage comments General notes on the but these can almost always be programmed around *Although Postgres has a true BOOLEAN type
Definition: postgres.txt:22
updateTimestamp()
Update the timestamp on autoblocks.
Definition: Block.php:848
static addUpdate(DeferrableUpdate $update, $stage=self::POSTSEND)
Add an update to the deferred list to be run later by execute()
$lines
Definition: router.php:67
if(!defined( 'MEDIAWIKI')) $fname
This file is not a valid entry point, perform no further processing unless MEDIAWIKI is defined...
Definition: Setup.php:36
prevents($action, $x=null)
Get/set whether the Block prevents a given action.
Definition: Block.php:982
static getAutoblockExpiry($timestamp)
Get a timestamp of the expiry for autoblocks.
Definition: Block.php:1035
getBlocker()
Get the user who implemented this block.
Definition: Block.php:1408
static parseRange($range)
Given a string range in a number of formats, return the start and end of the range in hexadecimal...
Definition: IP.php:501
getId()
Get the user's ID.
Definition: User.php:2083
getPermissionsError(IContextSource $context)
Get the key and parameters for the corresponding error message.
Definition: Block.php:1427
isAutoblocking($x=null)
Definition: Block.php:965
static selectFields()
Return the list of ipblocks fields that should be selected to create a new block. ...
Definition: Block.php:193
User $blocker
Definition: Block.php:69
$line
Definition: cdb.php:59
getTarget()
Get the target for this particular Block.
Definition: Block.php:1383
getUserPage()
Get this user's personal page title.
Definition: User.php:4151
static newFromID($id)
Load a blocked user from their block id.
Definition: Block.php:173
const TYPE_USER
Definition: Block.php:78
getDatabaseArray($db=null)
Get an array suitable for passing to $dbw->insert() or $dbw->update()
Definition: Block.php:573
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set $status
Definition: hooks.txt:1046
fromMaster($x=null)
Get/set a flag determining whether the master is used for reads.
Definition: Block.php:943
wfMemcKey()
Make a cache key for the local wiki.
const DB_REPLICA
Definition: defines.php:22
addQuotes($s)
Adds quotes and backslashes.
string $mExpiry
Definition: Block.php:36
bool $mHideName
Definition: Block.php:39
isHardblock($x=null)
Get/set whether the Block is a hardblock (affects logged-in users on a given IP/range) ...
Definition: Block.php:952
initFromRow($row)
Given a database row from the ipblocks table, initialize member variables.
Definition: Block.php:395
static isValidBlock($ipblock)
Validate an IP Block (valid address WITH a valid prefix).
Definition: IP.php:126
Definition: Block.php:25
getRangeStart()
Get the IP address at the start of the range in Hex form.
Definition: Block.php:872
getRequest()
Get the WebRequest object.
static getIpFragment($hex)
Get the component of an IP address which is certain to be the same between an IP address and a rangeb...
Definition: Block.php:381
getByName()
Get the username of the blocking sysop.
Definition: Block.php:922
string $mReason
Definition: Block.php:27
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:34
bool $mCreateAccount
Definition: Block.php:57
isExpired()
Has the block expired?
Definition: Block.php:826