Two blocking features: IP range blocks, and expiry times configurable block-by-block.

Possible issue: uses strtotime(), which is very handy but in English
This commit is contained in:
Tim Starling 2004-02-14 12:37:25 +00:00
parent ca6782aefa
commit e2f98922df
14 changed files with 388 additions and 134 deletions

View file

@ -122,4 +122,11 @@ Watchlist:
stores: HTML string
cleared by: nothing, expiry time $wgWLCacheTimeout (1 hour)
note: emergency optimisation only
IP blocks:
key: $wgDBname:ipblocks
ex: wikidb:ipblocks
stores: array of arrays, for the BlockCache class
cleared by: BlockCache:clear()
... more to come ...

View file

@ -8,12 +8,15 @@
#
# To use delete(), you only need to fill $mAddress
# Globals used: $wgIPBlockCache, $wgAutoblockExpiry
class Block
{
var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId;
/* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry;
/* private */ var $mNetworkBits, $mIntegerAddr;
function Block( $address = "", $user = "", $by = 0, $reason = "",
$timestamp = "" , $auto = 0)
$timestamp = "" , $auto = 0, $expiry = "" )
{
$this->mAddress = $address;
$this->mUser = $user;
@ -21,21 +24,27 @@ class Block
$this->mReason = $reason;
$this->mTimestamp = $timestamp;
$this->mAuto = $auto;
}
$this->mExpiry = $expiry;
/*static*/ function newFromDB( $address, $user = 0, $killExpired = true ) {
$this->initialiseRange();
}
/*static*/ function newFromDB( $address, $user = 0, $killExpired = true )
{
$ban = new Block();
$ban->load( $address, $user, $killExpired );
return $ban;
}
function clear() {
function clear()
{
$mAddress = $mReason = $mTimestamp = "";
$mUser = $mBy = 0;
}
# Get a ban from the DB, with either the given address or the given username
function load( $address, $user = 0, $killExpired = true ) {
function load( $address, $user = 0, $killExpired = true )
{
$fname = "Block::load";
$ret = false;
$killed = false;
@ -83,7 +92,8 @@ class Block
return $ret;
}
function initFromRow( $row ) {
function initFromRow( $row )
{
$this->mAddress = $row->ipb_address;
$this->mReason = $row->ipb_reason;
$this->mTimestamp = $row->ipb_timestamp;
@ -91,10 +101,30 @@ class Block
$this->mBy = $row->ipb_by;
$this->mAuto = $row->ipb_auto;
$this->mId = $row->ipb_id;
$this->mExpiry = $row->ipb_expiry;
$this->initialiseRange();
}
function initialiseRange()
{
if ( $this->mUser == 0 ) {
$rangeParts = explode( "/", $this->mAddress );
if ( count( $rangeParts ) == 2 ) {
$this->mNetworkBits = $rangeParts[1];
} else {
$this->mNetworkBits = 32;
}
$this->mIntegerAddr = ip2long( $rangeParts[0] );
} else {
$this->mNetworkBits = false;
$this->mIntegerAddr = false;
}
}
# Callback with a Block object for every block
/*static*/ function enumBlocks( $callback, $tag, $killExpired = true ) {
/*static*/ function enumBlocks( $callback, $tag, $killExpired = true )
{
$sql = "SELECT * FROM ipblocks ORDER BY ipb_timestamp DESC";
$res = wfQuery( $sql, DB_READ, "Block::enumBans" );
$block = new Block();
@ -112,7 +142,8 @@ class Block
wfFreeResult( $res );
}
function delete() {
function delete()
{
$fname = "Block::delete";
if ( $this->mAddress == "" ) {
$sql = "DELETE FROM ipblocks WHERE ipb_id={$this->mId}";
@ -121,17 +152,23 @@ class Block
wfStrencode( $this->mAddress ) . "'";
}
wfQuery( $sql, DB_WRITE, "Block::delete" );
$this->clearCache();
}
function insert() {
function insert()
{
$sql = "INSERT INTO ipblocks
(ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto )
(ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto, ipb_expiry )
VALUES ('" . wfStrencode( $this->mAddress ) . "', {$this->mUser}, {$this->mBy}, '" .
wfStrencode( $this->mReason ) . "','{$this->mTimestamp}', {$this->mAuto})";
wfStrencode( $this->mReason ) . "','{$this->mTimestamp}', {$this->mAuto}, '{$this->mExpiry}')";
wfQuery( $sql, DB_WRITE, "Block::insert" );
$this->clearCache();
}
function deleteIfExpired() {
function deleteIfExpired()
{
if ( $this->isExpired() ) {
$this->delete();
return true;
@ -140,31 +177,64 @@ class Block
}
}
function isExpired() {
global $wgIPBlockExpiration, $wgUserBlockExpiration;
$period = $this->mUser ? $wgUserBlockExpiration : $wgIPBlockExpiration;
# Period==0 means no expiry
if ( !$period ) {
return false;
}
$expiry = wfTimestamp2Unix( $this->mTimestamp ) + $period;
$now = wfTimestamp2Unix( wfTimestampNow() );
if ( $now > $expiry ) {
return true;
} else {
return false;
}
function isExpired()
{
return wfTimestampNow() > $this->mExpiry;
}
function isValid() {
function isValid()
{
return $this->mAddress != "";
}
function updateTimestamp() {
wfQuery( "UPDATE ipblocks SET ipb_timestamp='" . wfTimestampNow() .
"' WHERE ipb_address='" . wfStrencode( $this->mAddress ) . "'", DB_WRITE, "Block::updateTimestamp" );
$this->mTimestamp = wfTimestampNow();
$this->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
wfQuery( "UPDATE ipblocks SET " .
"ipb_timestamp='" . $this->mTimestamp . "', " .
"ipb_expiry='" . $this->mExpiry . "' " .
"WHERE ipb_address='" . wfStrencode( $this->mAddress ) . "'", DB_WRITE, "Block::updateTimestamp" );
$this->clearCache();
}
/* private */ function clearCache()
{
global $wgBlockCache;
if ( is_object( $wgBlockCache ) ) {
$wgBlockCache->clear();
}
}
function getIntegerAddr()
{
return $this->mIntegerAddr;
}
function getNetworkBits()
{
return $this->mNetworkBits;
}
/* static */ function getAutoblockExpiry( $timestamp )
{
global $wgAutoblockExpiry;
return wfUnix2Timestamp( wfTimestamp2Unix( $timestamp ) + $wgAutoblockExpiry );
}
/* static */ function normaliseRange( $range )
{
$parts = explode( "/", $range );
if ( count( $parts ) == 2 ) {
$shift = 32 - $parts[1];
$ipint = ip2long( $parts[0] );
$ipint = $ipint >> $shift << $shift;
$newip = long2ip( $ipint );
$range = "$newip/{$parts[1]}";
}
return $range;
}
}

115
includes/BlockCache.php Normal file
View file

@ -0,0 +1,115 @@
<?
# Object for fast lookup of IP blocks
# Represents a memcached value, and in some sense, the entire ipblocks table
class BlockCache
{
var $mData = false, $mMemcKey;
function BlockCache( $deferLoad = false, $dbName = "" )
{
global $wgDBname;
if ( $dbName == "" ) {
$dbName = $wgDBname;
}
$this->mMemcKey = "$dbName:ipblocks";
if ( !$deferLoad ) {
$this->load();
}
}
function load()
{
global $wgUseMemCached, $wgMemc;
if ( $this->mData === false) {
$this->mData = array();
$saveMemc = false;
# Try memcached
if ( $wgUseMemCached ) {
$this->mData = $wgMemc->get( $this->mMemcKey );
if ( !$this->mData ) {
$saveMemc = true;
}
}
if ( $this->mData === false || is_null( $this->mData ) ) {
# Load from DB
$this->mData = array();
Block::enumBlocks( "wfBlockCacheInsert", "" ); # Calls $this->insert()
}
if ( $saveMemc ) {
$wgMemc->set( $this->mMemcKey, $this->mData, 0 );
}
}
}
function insert( &$block )
{
if ( $block->mUser == 0 ) {
$nb = $block->getNetworkBits();
$ipint = $block->getIntegerAddr();
$index = $ipint >> ( 32 - $nb );
if ( !array_key_exists( $nb, $this->mData ) ) {
$this->mData[$nb] = array();
}
$this->mData[$nb][$index] = 1;
}
}
function get( $ip )
{
$this->load();
$ipint = ip2long( $ip );
$blocked = false;
foreach ( $this->mData as $networkBits => $blockInts ) {
if ( array_key_exists( $ipint >> ( 32 - $networkBits ), $blockInts ) ) {
$blocked = true;
break;
}
}
if ( $blocked ) {
# Clear low order bits
if ( $networkBits != 32 ) {
$ip .= "/$networkBits";
$ip = Block::normaliseRange( $ip );
}
$block = new Block();
$block->load( $ip );
} else {
$block = false;
}
return $block;
}
function clear()
{
global $wgUseMemCached, $wgMemc;
$this->mData = false;
if ( $wgUseMemCached ) {
$wgMemc->delete( $this->mMemcKey );
}
}
function clearLocal()
{
$this->mData = false;
}
}
function wfBlockCacheInsert( $block, $tag )
{
global $wgBlockCache;
$wgBlockCache->insert( $block );
}

View file

@ -113,17 +113,10 @@ $wgWhitelistEdit = false;
$wgWhitelistRead = false;
$wgWhitelistAccount = array ( "user" => 1, "sysop" => 1, "developer" => 1 );
$wgSysopUserBans = false; # Allow sysops to ban logged-in users
$wgIPBlockExpiration = 86400; # IP blocks expire after this many seconds, 0=infinite
$wgUserBlockExpiration = 0; # As above, but for logged-in users
# User agent/range blocking
# Blocks all users using a particular user agent, possibly restricted to a
# set of IP ranges. Note: you can't block all user agents by leaving
# $wgBadUserAgents blank. That would block nothing.
$wgBadRanges = false; # e.g. array(array("1.2.3.0", "1.2.3.255"))
$wgBadUserAgents = false; # e.g. array("OfflineExplorer/1.0")
$wgRangeBlockUser = 0; # The block is attributed to this user ID
$wgRangeBlockReason = ""; # This reason is given (should be in wfMsg, obviously)
$wgSysopRangeBans = false; # Allow sysops to ban IP ranges
$wgDefaultBlockExpiry = "24 hours"; # default expiry time
# strtotime format, or "infinite" for an infinite block
$wgAutoblockExpiry = 86400; # Number of seconds before autoblock entries expire
# Client-side caching:
$wgCachePages = true; # Allow client-side caching of pages

View file

@ -48,6 +48,7 @@ include_once( "Block.php" );
include_once( "SearchEngine.php" );
include_once( "DifferenceEngine.php" );
include_once( "MessageCache.php" );
include_once( "BlockCache.php" );
wfProfileOut( "$fname-includes" );
wfProfileIn( "$fname-memcached" );
@ -56,6 +57,21 @@ global $wgArticle, $wgDeferredUpdateList, $wgLinkCache;
global $wgMemc, $wgMagicWords, $wgMwRedir, $wgDebugLogFile;
global $wgMessageCache, $wgUseMemCached, $wgUseDatabaseMessages;
global $wgMsgCacheExpiry, $wgDBname, $wgCommandLineMode;
global $wgBlockCache;
# Useful debug output
if ( function_exists( "getallheaders" ) ) {
wfDebug( "\nStart request\n" );
wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" );
$headers = getallheaders();
foreach ($headers as $name => $value) {
wfDebug( "$name: $value\n" );
}
wfDebug( "\n" );
} else {
wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" );
}
class MemCachedClientforWiki extends memcached {
function _debugprint( $text ) {
@ -134,6 +150,7 @@ if( !$wgCommandLineMode && isset( $_COOKIE[ini_get("session.name")] ) ) {
User::SetupSession();
}
$wgBlockCache = new BlockCache( true );
$wgUser = User::loadFromSession();
$wgDeferredUpdateList = array();
$wgLinkCache = new LinkCache();

View file

@ -8,7 +8,7 @@ function wfSpecialBlockip()
$wgOut->sysopRequired();
return;
}
$fields = array( "wpBlockAddress", "wpBlockReason" );
$fields = array( "wpBlockAddress", "wpBlockReason", "wpBlockExpiry" );
wfCleanFormFields( $fields );
$ipb = new IPBlockForm();
@ -21,16 +21,24 @@ class IPBlockForm {
function showForm( $err )
{
global $wgOut, $wgUser, $wgLang;
global $ip, $wpBlockAddress, $wpBlockReason;
global $wgOut, $wgUser, $wgLang, $wgDefaultBlockExpiry;
global $ip, $wpBlockAddress, $wpBlockExpiry, $wpBlockReason;
$wgOut->setPagetitle( wfMsg( "blockip" ) );
$wgOut->addWikiText( wfMsg( "blockiptext" ) );
if ( ! $wpBlockAddress ) { $wpBlockAddress = $ip; }
$ipa = wfMsg( "ipaddress" );
$reason = wfMsg( "ipbreason" );
$ipbs = wfMsg( "ipbsubmit" );
if ( ! $wpBlockAddress ) {
$wpBlockAddress = $ip;
}
if ( is_null( $wpBlockExpiry ) || $wpBlockExpiry === "" ) {
$wpBlockExpiry = $wgDefaultBlockExpiry;
}
$mIpaddress = wfMsg( "ipaddress" );
$mIpbexpiry = wfMsg( "ipbexpiry" );
$mIpbreason = wfMsg( "ipbreason" );
$mIpbsubmit = wfMsg( "ipbsubmit" );
$action = wfLocalUrlE( $wgLang->specialPage( "Blockip" ),
"action=submit" );
@ -38,19 +46,28 @@ class IPBlockForm {
$wgOut->setSubtitle( wfMsg( "formerror" ) );
$wgOut->addHTML( "<p><font color='red' size='+1'>{$err}</font>\n" );
}
$scBlockAddress = htmlspecialchars( $wpBlockAddress );
$scBlockExpiry = htmlspecialchars( $wpBlockExpiry );
$scBlockReason = htmlspecialchars( $wpBlockReason );
$wgOut->addHTML( "<p>
<form id=\"blockip\" method=\"post\" action=\"{$action}\">
<table border=0><tr>
<td align=\"right\">{$ipa}:</td>
<td align=\"right\">{$mIpaddress}:</td>
<td align=\"left\">
<input tabindex=1 type=text size=20 name=\"wpBlockAddress\" value=\"{$wpBlockAddress}\">
<input tabindex=1 type=text size=20 name=\"wpBlockAddress\" value=\"{$scBlockAddress}\">
</td></tr><tr>
<td align=\"right\">{$reason}:</td>
<td align=\"right\">{$mIpbexpiry}:</td>
<td align=\"left\">
<input tabindex=2 type=text size=40 name=\"wpBlockReason\" value=\"{$wpBlockReason}\">
<input tabindex=2 type=text size=20 name=\"wpBlockExpiry\" value=\"{$scBlockExpiry}\">
</td></tr><tr>
<td align=\"right\">{$mIpbreason}:</td>
<td align=\"left\">
<input tabindex=3 type=text size=40 name=\"wpBlockReason\" value=\"{$scBlockReason}\">
</td></tr><tr>
<td>&nbsp;</td><td align=\"left\">
<input tabindex=3 type=submit name=\"wpBlock\" value=\"{$ipbs}\">
<input tabindex=4 type=submit name=\"wpBlock\" value=\"{$mIpbsubmit}\">
</td></tr></table>
</form>\n" );
@ -59,25 +76,54 @@ class IPBlockForm {
function doSubmit()
{
global $wgOut, $wgUser, $wgLang;
global $ip, $wpBlockAddress, $wpBlockReason, $wgSysopUserBans;
global $ip, $wpBlockAddress, $wpBlockReason, $wpBlockExpiry;
global $wgSysopUserBans, $wgSysopRangeBans;
$userId = 0;
$wpBlockAddress = trim( $wpBlockAddress );
$rxIP = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if ( ! preg_match( "/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/",
$wpBlockAddress ) )
{
if ( $wgSysopUserBans ) {
$userId = User::idFromName( $wpBlockAddress );
if ( $userId == 0 ) {
$this->showForm( wfMsg( "badipaddress" ) );
# Check for invalid specifications
if ( ! preg_match( "/^$rxIP$/", $wpBlockAddress ) ) {
if ( preg_match( "/^($rxIP)\\/(\\d{1,2})$/", $wpBlockAddress, $matches ) ) {
if ( $wgSysopRangeBans ) {
if ( $matches[2] > 31 || $matches[2] < 1 ) {
$this->showForm( wfMsg( "ip_range_invalid" ) );
}
$wpBlockAddress = Block::normaliseRange( $wpBlockAddress );
} else {
# Range block illegal
$this->showForm( wfMsg( "range_block_disabled" ) );
return;
}
} else {
$this->showForm( wfMsg( "badipaddress" ) );
return;
}
# Username block
if ( $wgSysopUserBans ) {
$userId = User::idFromName( $wpBlockAddress );
if ( $userId == 0 ) {
$this->showForm( wfMsg( "nosuchuser", htmlspecialchars( $wpBlockAddress ) ) );
return;
}
} else {
$this->showForm( wfMsg( "badipaddress" ) );
return;
}
}
}
if ( $wpBlockExpiry == "infinite" || $wpBlockExpiry == "indefinite" ) {
$expiry = 0;
} else {
# Convert GNU-style date, returns -1 on error
$expiry = strtotime( $wpBlockExpiry );
}
if ( $expiry < 0 ) {
$this->showForm( wfMsg( "ipb_expiry_invalid" ) );
return;
}
$expiry = wfUnix2Timestamp( $expiry );
if ( "" == $wpBlockReason ) {
$this->showForm( wfMsg( "noblockreason" ) );
return;
@ -85,13 +131,14 @@ class IPBlockForm {
# Create block
# Note: for a user block, ipb_address is only for display purposes
$ban = new Block( $wpBlockAddress, $userId, $wgUser->getID(),
wfStrencode( $wpBlockReason ), wfTimestampNow(), 0 );
wfStrencode( $wpBlockReason ), wfTimestampNow(), 0, $expiry );
$ban->insert();
# Make log entry
$log = new LogPage( wfMsg( "blocklogpage" ), wfMsg( "blocklogtext" ) );
$action = wfMsg( "blocklogentry", $wpBlockAddress );
$action = wfMsg( "blocklogentry", $wpBlockAddress, $wpBlockExpiry );
$log->addEntry( $action, $wpBlockReason );
# Report to the user

View file

@ -117,9 +117,15 @@ function wfAddRow( $block, $tag ) {
$name = User::whoIs( $block->mBy );
$ulink = $sk->makeKnownLink( $wgLang->getNsText( Namespace::getUser() ). ":{$name}", $name );
$d = $wgLang->timeanddate( $block->mTimestamp, true );
$line = wfMsg( "blocklistline", $d, $ulink, $addr );
$formattedTime = $wgLang->timeanddate( $block->mTimestamp, true );
if ( $block->mExpiry === "" ) {
$formattedExpiry = "indefinite";
} else {
$formattedExpiry = $wgLang->timeanddate( $block->mExpiry, true );
}
$line = wfMsg( "blocklistline", $formattedTime, $ulink, $addr, $formattedExpiry );
$wgOut->addHTML( "<li>{$line}" );

View file

@ -94,45 +94,29 @@ class User {
/* private */ function getBlockedStatus()
{
global $wgBadRanges, $wgBadUserAgents, $wgRangeBlockUser, $wgRangeBlockReason, $wgIP;
global $wgIP, $wgBlockCache;
if ( -1 != $this->mBlockedby ) { return; }
$this->mBlockedby = 0;
# Range/user-agent blocking
$fBlock = false; # Mmmm, Hungarian
if ( ( !is_array( $wgBadUserAgents ) ||
array_key_exists( getenv( "HTTP_USER_AGENT" ), $wgBadUserAgents ) ) &&
is_array( $wgBadRanges ) )
{
$iIp = ip2long( $wgIP );
foreach ( $wgBadRanges as $range ) {
$start = ip2long( $range[0] );
$end = ip2long( $range[1] );
if ( $iIp >= $start && $iIp <= $end ) {
$fBlock = true;
break;
}
# User blocking
if ( $this->mId ) {
$block = new Block();
if ( $block->load( $wgIP , $this->mId ) ) {
$this->mBlockedby = $block->mBy;
$this->mBlockreason = $block->mReason;
}
}
if ( $fBlock ) {
$this->mBlockedby = $wgRangeBlockUser;
$this->mBlockreason = $wgRangeBlockReason;
return;
# IP/range blocking
if ( !$this->mBlockedby ) {
$block = $wgBlockCache->get( $wgIP );
if ( $block !== false ) {
$this->mBlockedby = $block->mBy;
$this->mBlockreason = $block->mReason;
}
}
# User/IP blocking
$block = new Block();
if ( !$block->load( $wgIP , $this->mId ) ) {
wfDebug( $wgIP ." is not blocked\n" );
$this->mBlockedby = 0;
return;
}
$this->mBlockedby = $block->mBy;
$this->mBlockreason = $block->mReason;
}
function isBlocked()
@ -626,6 +610,7 @@ class User {
$ipblock->mReason = wfMsg( "autoblocker", $this->getName(), $userblock->mReason );
$ipblock->mTimestamp = wfTimestampNow();
$ipblock->mAuto = 1;
$ipblock->mExpiry = Block::getAutoblockExpiry( $ipblock->mTimestamp );
# Insert it
$ipblock->insert();

View file

@ -643,11 +643,6 @@ The reason given is this:<br>''$2''<p>You may contact $1 or one of the other
Note that you may not use the \"email this user\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]].
Your IP address is $3. Please include this address in any queries you make.
==Note to AOL users==
Due to continuing acts of vandalism by one particular AOL user, Wikipedia often blocks AOL proxies. Unfortunately, a single proxy server may be used by a large number of AOL users, and hence innocent AOL users are often inadvertently blocked. We apologise for any inconvenience caused.
If this happens to you, please email an administrator, using an AOL email address. Be sure to include the IP address given above.
",
"whitelistedittitle" => "Login required to edit",
"whitelistedittext" => "You have to [[Special:Userlogin|login]] to edit articles.",
@ -1208,9 +1203,10 @@ accordance with [[$wgMetaNamespace:Policy|policy]].
Fill in a specific reason below (for example, citing particular
pages that were vandalized).",
"ipaddress" => "IP Address/username",
"ipbexpiry" => "Expiry",
"ipbreason" => "Reason",
"ipbsubmit" => "Block this user",
"badipaddress" => "No user exists by that name",
"badipaddress" => "Invalid IP address",
"noblockreason" => "You must supply a reason for the block.",
"blockipsuccesssub" => "Block succeeded",
"blockipsuccesstext" => "\"$1\" has been blocked.
@ -1221,17 +1217,20 @@ to a previously blocked IP address or username.",
"ipusubmit" => "Unblock this address",
"ipusuccess" => "\"$1\" unblocked",
"ipblocklist" => "List of blocked IP addresses and usernames",
"blocklistline" => "$1, $2 blocked $3",
"blocklistline" => "$1, $2 blocked $3 (expires $4)",
"blocklink" => "block",
"unblocklink" => "unblock",
"contribslink" => "contribs",
"autoblocker" => "Autoblocked because you share an IP address with \"$1\". Reason \"$2\".",
"blocklogpage" => "Block_log",
"blocklogentry" => 'blocked "$1"',
"blocklogentry" => 'blocked "$1" with an expiry time of $2',
"blocklogtext" => "This is a log of user blocking and unblocking actions. Automatically
blocked IP addresses are not be listed. See the [[Special:Ipblocklist|IP block list]] for
the list of currently operational bans and blocks.",
"unblocklogentry" => 'unblocked "$1"',
"range_block_disabled" => "The sysop ability to create range blocks is disabled.",
"ipb_expiry_invalid" => "Expiry time invalid.",
"ip_range_invalid" => "Invalid IP range.\n",
# Developer tools
#

View file

@ -74,8 +74,7 @@ function initialiseMessages( $overwrite = false) {
$doInsert = true;
if ( $overwrite ) {
$sql = "DELETE FROM cur WHERE cur_namespace=$ns AND cur_title='$title'";
wfQuery( $sql, DB_WRITE, $fname );
wfQuery( "DELETE FROM cur WHERE cur_namespace=$ns AND cur_title='$title'", DB_WRITE, $fname );
} else {
if (array_key_exists($title, $exists)) {
$doInsert = false;
@ -112,7 +111,11 @@ function initialiseMessages( $overwrite = false) {
}
print "Done\n";
print "Writing...";
wfQuery( $sql, DB_WRITE, $fname );
if ( !$first ) {
wfQuery( $sql, DB_WRITE, $fname );
}
print "Done\n";
$navText .= "</table>";

View file

@ -0,0 +1,8 @@
-- Adds the ipb_expiry field to ipblocks
ALTER TABLE ipblocks ADD ipb_expiry char(14) binary NOT NULL default '';
-- All IP blocks have one day expiry
UPDATE ipblocks SET ipb_expiry = date_format(date_add(ipb_timestamp,INTERVAL 1 DAY),"%Y%m%d%H%i%s") WHERE ipb_user = 0;
-- Null string is fine for user blocks, since this indicates infinity

View file

@ -126,6 +126,7 @@ CREATE TABLE ipblocks (
ipb_reason tinyblob NOT NULL default '',
ipb_timestamp char(14) binary NOT NULL default '',
ipb_auto tinyint(1) NOT NULL default '0',
ipb_expiry char(14) binary NOT NULL default '',
UNIQUE KEY ipb_id (ipb_id)
) TYPE=MyISAM PACK_KEYS=1;

View file

@ -154,13 +154,29 @@ function update_passwords() {
function do_ipblocks_update() {
global $wgDatabase;
if ( $wgDatabase->fieldExists( "ipblocks", "ipb_id" ) ) {
echo "...ipblocks table is up to date.\n";
} else {
echo "Updating ipblocks table... ";
dbsource( "maintenance/archives/patch-ipblocks.sql", $wgDatabase );
echo "ok\n";
$do1 = $do2 = false;
if ( !$wgDatabase->fieldExists( "ipblocks", "ipb_id" ) ) {
$do1 = true;
}
if ( !$wgDatabase->fieldExists( "ipblocks", "ipb_expiry" ) ) {
$do2 = true;
}
if ( $do1 || $do2 ) {
echo "Updating ipblocks table... ";
if ( $do1 ) {
dbsource( "maintenance/archives/patch-ipblocks.sql", $wgDatabase );
}
if ( $do2 ) {
dbsource( "maintenance/archives/patch-ipb_expiry.sql", $wgDatabase );
}
echo "ok\n";
} else {
echo "...ipblocks is up to date.\n";
}
}

View file

@ -16,19 +16,6 @@ include_once( "Setup.php" );
wfProfileIn( "main-misc-setup" );
OutputPage::setEncodings(); # Not really used yet
# Useful debug output
if ( function_exists( "getallheaders" ) ) {
wfDebug( "\nStart request\n" );
wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" );
$headers = getallheaders();
foreach ($headers as $name => $value) {
wfDebug( "$name: $value\n" );
}
wfDebug( "\n" );
} else {
wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" );
}
# Query string fields
#
global $action, $title, $search, $go, $target, $printable;