DB error log
[lhc/web/wiklou.git] / includes / Block.php
1 <?php
2 # Blocks and bans object
3 #
4 #TODO: This could be used everywhere, but it isn't.
5 #
6 # All the functions in this class assume the object is either explicitly
7 # loaded or filled. It is not load-on-demand. There are no accessors.
8 #
9 # To use delete(), you only need to fill $mAddress
10
11 # Globals used: $wgBlockCache, $wgAutoblockExpiry
12
13 class Block
14 {
15 /* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry;
16 /* private */ var $mNetworkBits, $mIntegerAddr;
17
18 function Block( $address = '', $user = '', $by = 0, $reason = '',
19 $timestamp = '' , $auto = 0, $expiry = '' )
20 {
21 $this->mAddress = $address;
22 $this->mUser = $user;
23 $this->mBy = $by;
24 $this->mReason = $reason;
25 $this->mTimestamp = $timestamp;
26 $this->mAuto = $auto;
27 $this->mExpiry = $expiry;
28
29 $this->initialiseRange();
30 }
31
32 /*static*/ function newFromDB( $address, $user = 0, $killExpired = true )
33 {
34 $ban = new Block();
35 $ban->load( $address, $user, $killExpired );
36 return $ban;
37 }
38
39 function clear()
40 {
41 $mAddress = $mReason = $mTimestamp = '';
42 $mUser = $mBy = 0;
43 }
44
45 # Get a ban from the DB, with either the given address or the given username
46 function load( $address = "", $user = 0, $killExpired = true )
47 {
48 $fname = 'Block::load';
49 $ret = false;
50 $killed = false;
51
52 if ( 0 == $user && $address=="" ) {
53 $sql = "SELECT * from ipblocks";
54 } elseif ($address=="") {
55 $sql = "SELECT * FROM ipblocks WHERE ipb_user={$user}";
56 } elseif ($user=="") {
57 $sql = "SELECT * FROM ipblocks WHERE ipb_address='" . wfStrencode( $address ) . "'";
58 } else {
59 $sql = "SELECT * FROM ipblocks WHERE (ipb_address='" . wfStrencode( $address ) .
60 "' OR ipb_user={$user})";
61 }
62
63 $res = wfQuery( $sql, DB_READ, $fname );
64 if ( 0 == wfNumRows( $res ) ) {
65 # User is not blocked
66 $this->clear();
67 } else {
68 # Get first block
69 $row = wfFetchObject( $res );
70 $this->initFromRow( $row );
71
72 if ( $killExpired ) {
73 # If requested, delete expired rows
74 do {
75 $killed = $this->deleteIfExpired();
76 if ( $killed ) {
77 $row = wfFetchObject( $res );
78 if ( $row ) {
79 $this->initFromRow( $row );
80 }
81 }
82 } while ( $killed && $row );
83
84 # If there were any left after the killing finished, return true
85 if ( !$row ) {
86 $ret = false;
87 $this->clear();
88 } else {
89 $ret = true;
90 }
91 } else {
92 $ret = true;
93 }
94 }
95 wfFreeResult( $res );
96 return $ret;
97 }
98
99 function initFromRow( $row )
100 {
101 $this->mAddress = $row->ipb_address;
102 $this->mReason = $row->ipb_reason;
103 $this->mTimestamp = $row->ipb_timestamp;
104 $this->mUser = $row->ipb_user;
105 $this->mBy = $row->ipb_by;
106 $this->mAuto = $row->ipb_auto;
107 $this->mId = $row->ipb_id;
108 $this->mExpiry = $row->ipb_expiry;
109
110 $this->initialiseRange();
111 }
112
113 function initialiseRange()
114 {
115 if ( $this->mUser == 0 ) {
116 $rangeParts = explode( '/', $this->mAddress );
117 if ( count( $rangeParts ) == 2 ) {
118 $this->mNetworkBits = $rangeParts[1];
119 } else {
120 $this->mNetworkBits = 32;
121 }
122 $this->mIntegerAddr = ip2long( $rangeParts[0] );
123 } else {
124 $this->mNetworkBits = false;
125 $this->mIntegerAddr = false;
126 }
127 }
128
129 # Callback with a Block object for every block
130 /*static*/ function enumBlocks( $callback, $tag, $killExpired = true )
131 {
132 $sql = 'SELECT * FROM ipblocks ORDER BY ipb_timestamp DESC';
133 $res = wfQuery( $sql, DB_READ, 'Block::enumBans' );
134 $block = new Block();
135
136 while ( $row = wfFetchObject( $res ) ) {
137 $block->initFromRow( $row );
138 if ( $killExpired ) {
139 if ( !$block->deleteIfExpired() ) {
140 $callback( $block, $tag );
141 }
142 } else {
143 $callback( $block, $tag );
144 }
145 }
146 wfFreeResult( $res );
147 }
148
149 function delete()
150 {
151 $fname = 'Block::delete';
152 if ( $this->mAddress == "" ) {
153 $sql = "DELETE FROM ipblocks WHERE ipb_id={$this->mId}";
154 } else {
155 $sql = "DELETE FROM ipblocks WHERE ipb_address='" .
156 wfStrencode( $this->mAddress ) . "'";
157 }
158 wfQuery( $sql, DB_WRITE, 'Block::delete' );
159
160 $this->clearCache();
161 }
162
163 function insert()
164 {
165 $sql = 'INSERT INTO ipblocks ' .
166 '(ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto, ipb_expiry )' .
167 "VALUES ('" . wfStrencode( $this->mAddress ) . "', {$this->mUser}, {$this->mBy}, '" .
168 wfStrencode( $this->mReason ) . "','{$this->mTimestamp}', {$this->mAuto}, '{$this->mExpiry}')";
169 wfQuery( $sql, DB_WRITE, 'Block::insert' );
170
171 $this->clearCache();
172 }
173
174 function deleteIfExpired()
175 {
176 if ( $this->isExpired() ) {
177 $this->delete();
178 return true;
179 } else {
180 return false;
181 }
182 }
183
184 function isExpired()
185 {
186 if ( !$this->mExpiry ) {
187 return false;
188 } else {
189 return wfTimestampNow() > $this->mExpiry;
190 }
191 }
192
193 function isValid()
194 {
195 return $this->mAddress != '';
196 }
197
198 function updateTimestamp()
199 {
200 if ( $this->mAuto ) {
201 $this->mTimestamp = wfTimestampNow();
202 $this->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
203
204 wfQuery( 'UPDATE ipblocks SET ' .
205 "ipb_timestamp='" . $this->mTimestamp . "', " .
206 "ipb_expiry='" . $this->mExpiry . "' " .
207 "WHERE ipb_address='" . wfStrencode( $this->mAddress ) . "'", DB_WRITE, 'Block::updateTimestamp' );
208
209 $this->clearCache();
210 }
211 }
212
213 /* private */ function clearCache()
214 {
215 global $wgBlockCache;
216 if ( is_object( $wgBlockCache ) ) {
217 $wgBlockCache->clear();
218 }
219 }
220
221 function getIntegerAddr()
222 {
223 return $this->mIntegerAddr;
224 }
225
226 function getNetworkBits()
227 {
228 return $this->mNetworkBits;
229 }
230
231 /* static */ function getAutoblockExpiry( $timestamp )
232 {
233 global $wgAutoblockExpiry;
234 return wfUnix2Timestamp( wfTimestamp2Unix( $timestamp ) + $wgAutoblockExpiry );
235 }
236
237 /* static */ function normaliseRange( $range )
238 {
239 $parts = explode( '/', $range );
240 if ( count( $parts ) == 2 ) {
241 $shift = 32 - $parts[1];
242 $ipint = ip2long( $parts[0] );
243 $ipint = $ipint >> $shift << $shift;
244 $newip = long2ip( $ipint );
245 $range = "$newip/{$parts[1]}";
246 }
247 return $range;
248 }
249
250 }
251 ?>