Index: trunk/phase3/maintenance/language/messages.inc |
— | — | @@ -2086,15 +2086,20 @@ |
2087 | 2087 | 'unblocked-id', |
2088 | 2088 | 'ipblocklist', |
2089 | 2089 | 'ipblocklist-legend', |
2090 | | - 'ipblocklist-username', |
2091 | | - 'ipblocklist-sh-userblocks', |
2092 | | - 'ipblocklist-sh-tempblocks', |
2093 | | - 'ipblocklist-sh-addressblocks', |
| 2090 | + 'blocklist-userblocks', |
| 2091 | + 'blocklist-tempblocks', |
| 2092 | + 'blocklist-addressblocks', |
| 2093 | + 'blocklist-timestamp', |
| 2094 | + 'blocklist-target', |
| 2095 | + 'blocklist-expiry', |
| 2096 | + 'blocklist-by', |
| 2097 | + 'blocklist-params', |
| 2098 | + 'blocklist-reason', |
2094 | 2099 | 'ipblocklist-summary', |
2095 | 2100 | 'ipblocklist-submit', |
2096 | 2101 | 'ipblocklist-localblock', |
2097 | 2102 | 'ipblocklist-otherblocks', |
2098 | | - 'blocklistline', |
| 2103 | + |
2099 | 2104 | 'infiniteblock', |
2100 | 2105 | 'expiringblock', |
2101 | 2106 | 'anononlyblock', |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -603,8 +603,8 @@ |
604 | 604 | 'FewestrevisionsPage' => 'includes/specials/SpecialFewestrevisions.php', |
605 | 605 | 'FileDuplicateSearchPage' => 'includes/specials/SpecialFileDuplicateSearch.php', |
606 | 606 | 'IPBlockForm' => 'includes/specials/SpecialBlock.php', |
607 | | - 'IPBlocklistPager' => 'includes/specials/SpecialIpblocklist.php', |
608 | | - 'IPUnblockForm' => 'includes/specials/SpecialIpblocklist.php', |
| 607 | + 'BlockListPager' => 'includes/specials/SpecialBlockList.php', |
| 608 | + 'SpecialBlockList' => 'includes/specials/SpecialBlockList.php', |
609 | 609 | 'ImportReporter' => 'includes/specials/SpecialImport.php', |
610 | 610 | 'ImportStreamSource' => 'includes/Import.php', |
611 | 611 | 'ImportStringSource' => 'includes/Import.php', |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -4948,7 +4948,7 @@ |
4949 | 4949 | 'Listusers' => 'users', |
4950 | 4950 | 'Activeusers' => 'users', |
4951 | 4951 | 'Listgrouprights' => 'users', |
4952 | | - 'Ipblocklist' => 'users', |
| 4952 | + 'BlockList' => 'users', |
4953 | 4953 | 'Contributions' => 'users', |
4954 | 4954 | 'Emailuser' => 'users', |
4955 | 4955 | 'Listadmins' => 'users', |
Index: trunk/phase3/includes/specials/SpecialIpblocklist.php |
— | — | @@ -1,383 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * Implements Special:ipblocklist |
5 | | - * |
6 | | - * This program is free software; you can redistribute it and/or modify |
7 | | - * it under the terms of the GNU General Public License as published by |
8 | | - * the Free Software Foundation; either version 2 of the License, or |
9 | | - * (at your option) any later version. |
10 | | - * |
11 | | - * This program is distributed in the hope that it will be useful, |
12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | - * GNU General Public License for more details. |
15 | | - * |
16 | | - * You should have received a copy of the GNU General Public License along |
17 | | - * with this program; if not, write to the Free Software Foundation, Inc., |
18 | | - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
19 | | - * http://www.gnu.org/copyleft/gpl.html |
20 | | - * |
21 | | - * @file |
22 | | - * @ingroup SpecialPage |
23 | | - */ |
24 | | - |
25 | | -/** |
26 | | - * A special page that lists existing blocks and allows users with the 'block' |
27 | | - * permission to remove blocks |
28 | | - * |
29 | | - * @ingroup SpecialPage |
30 | | - */ |
31 | | -class IPUnblockForm extends SpecialPage { |
32 | | - var $ip; |
33 | | - var $hideuserblocks, $hidetempblocks, $hideaddressblocks; |
34 | | - |
35 | | - function __construct() { |
36 | | - parent::__construct( 'Ipblocklist' ); |
37 | | - } |
38 | | - |
39 | | - /** |
40 | | - * Main execution point |
41 | | - * |
42 | | - * @param $ip part of title: Special:Ipblocklist/<ip>. |
43 | | - */ |
44 | | - function execute( $ip ) { |
45 | | - global $wgUser, $wgOut, $wgRequest; |
46 | | - |
47 | | - $this->setHeaders(); |
48 | | - $this->outputHeader(); |
49 | | - |
50 | | - $ip = $wgRequest->getVal( 'ip', $ip ); |
51 | | - $this->ip = trim( $wgRequest->getVal( 'wpUnblockAddress', $ip ) ); |
52 | | - $this->hideuserblocks = $wgRequest->getBool( 'hideuserblocks' ); |
53 | | - $this->hidetempblocks = $wgRequest->getBool( 'hidetempblocks' ); |
54 | | - $this->hideaddressblocks = $wgRequest->getBool( 'hideaddressblocks' ); |
55 | | - |
56 | | - $action = $wgRequest->getText( 'action' ); |
57 | | - |
58 | | - if( $action == 'unblock' || $action == 'submit' && $wgRequest->wasPosted() ) { |
59 | | - # B/C @since 1.18: Unblock interface is now at Special:Unblock |
60 | | - $title = SpecialPage::getTitleFor( 'Unblock', $this->ip ); |
61 | | - $wgOut->redirect( $title->getFullUrl() ); |
62 | | - return; |
63 | | - } else { |
64 | | - # Just show the block list |
65 | | - $this->showList( '' ); |
66 | | - } |
67 | | - } |
68 | | - |
69 | | - function showList( $msg ) { |
70 | | - global $wgOut, $wgUser; |
71 | | - |
72 | | - if ( $msg != '' ) { |
73 | | - $wgOut->setSubtitle( $msg ); |
74 | | - } |
75 | | - |
76 | | - // Purge expired entries on one in every 10 queries |
77 | | - if ( !mt_rand( 0, 10 ) ) { |
78 | | - Block::purgeExpired(); |
79 | | - } |
80 | | - |
81 | | - $conds = array(); |
82 | | - // Is user allowed to see all the blocks? |
83 | | - if ( !$wgUser->isAllowed( 'hideuser' ) ) |
84 | | - $conds['ipb_deleted'] = 0; |
85 | | - if ( $this->ip == '' ) { |
86 | | - // No extra conditions |
87 | | - } elseif ( substr( $this->ip, 0, 1 ) == '#' ) { |
88 | | - $conds['ipb_id'] = substr( $this->ip, 1 ); |
89 | | - // Single IPs |
90 | | - } elseif ( IP::isIPAddress( $this->ip ) && strpos( $this->ip, '/' ) === false ) { |
91 | | - $iaddr = IP::toHex( $this->ip ); |
92 | | - if( $iaddr ) { |
93 | | - # Only scan ranges which start in this /16, this improves search speed |
94 | | - # Blocks should not cross a /16 boundary. |
95 | | - $range = substr( $iaddr, 0, 4 ); |
96 | | - // Fixme -- encapsulate this sort of query-building. |
97 | | - $dbr = wfGetDB( DB_SLAVE ); |
98 | | - $encIp = $dbr->addQuotes( IP::sanitizeIP( $this->ip ) ); |
99 | | - $encAddr = $dbr->addQuotes( $iaddr ); |
100 | | - $conds[] = "(ipb_address = $encIp) OR |
101 | | - (ipb_range_start" . $dbr->buildLike( $range, $dbr->anyString() ) . " AND |
102 | | - ipb_range_start <= $encAddr |
103 | | - AND ipb_range_end >= $encAddr)"; |
104 | | - } else { |
105 | | - $conds['ipb_address'] = IP::sanitizeIP( $this->ip ); |
106 | | - } |
107 | | - $conds['ipb_auto'] = 0; |
108 | | - // IP range |
109 | | - } elseif ( IP::isIPAddress( $this->ip ) ) { |
110 | | - $conds['ipb_address'] = Block::normaliseRange( $this->ip ); |
111 | | - $conds['ipb_auto'] = 0; |
112 | | - } else { |
113 | | - $user = User::newFromName( $this->ip ); |
114 | | - if ( $user && ( $id = $user->getId() ) != 0 ) { |
115 | | - $conds['ipb_user'] = $id; |
116 | | - } else { |
117 | | - // Uh...? |
118 | | - $conds['ipb_address'] = $this->ip; |
119 | | - $conds['ipb_auto'] = 0; |
120 | | - } |
121 | | - } |
122 | | - // Apply filters |
123 | | - if( $this->hideuserblocks ) { |
124 | | - $conds['ipb_user'] = 0; |
125 | | - } |
126 | | - if( $this->hidetempblocks ) { |
127 | | - $conds['ipb_expiry'] = 'infinity'; |
128 | | - } |
129 | | - if( $this->hideaddressblocks ) { |
130 | | - $conds[] = "ipb_user != 0 OR ipb_range_end > ipb_range_start"; |
131 | | - } |
132 | | - |
133 | | - // Search form |
134 | | - $wgOut->addHTML( $this->searchForm() ); |
135 | | - |
136 | | - // Check for other blocks, i.e. global/tor blocks |
137 | | - $otherBlockLink = array(); |
138 | | - wfRunHooks( 'OtherBlockLogLink', array( &$otherBlockLink, $this->ip ) ); |
139 | | - |
140 | | - // Show additional header for the local block only when other blocks exists. |
141 | | - // Not necessary in a standard installation without such extensions enabled |
142 | | - if( count( $otherBlockLink ) ) { |
143 | | - $wgOut->addHTML( |
144 | | - Html::rawElement( 'h2', array(), wfMsg( 'ipblocklist-localblock' ) ) . "\n" |
145 | | - ); |
146 | | - } |
147 | | - $pager = new IPBlocklistPager( $this, $conds ); |
148 | | - if ( $pager->getNumRows() ) { |
149 | | - $wgOut->addHTML( |
150 | | - $pager->getNavigationBar() . |
151 | | - Html::rawElement( 'ul', null, $pager->getBody() ) . |
152 | | - $pager->getNavigationBar() |
153 | | - ); |
154 | | - } elseif ( $this->ip != '') { |
155 | | - $wgOut->addWikiMsg( 'ipblocklist-no-results' ); |
156 | | - } else { |
157 | | - $wgOut->addWikiMsg( 'ipblocklist-empty' ); |
158 | | - } |
159 | | - |
160 | | - if( count( $otherBlockLink ) ) { |
161 | | - $wgOut->addHTML( |
162 | | - Html::rawElement( 'h2', array(), wfMsgExt( 'ipblocklist-otherblocks', 'parseinline', count( $otherBlockLink ) ) ) . "\n" |
163 | | - ); |
164 | | - $list = ''; |
165 | | - foreach( $otherBlockLink as $link ) { |
166 | | - $list .= Html::rawElement( 'li', array(), $link ) . "\n"; |
167 | | - } |
168 | | - $wgOut->addHTML( Html::rawElement( 'ul', array( 'class' => 'mw-ipblocklist-otherblocks' ), $list ) . "\n" ); |
169 | | - } |
170 | | - |
171 | | - } |
172 | | - |
173 | | - function searchForm() { |
174 | | - global $wgScript, $wgLang; |
175 | | - |
176 | | - $showhide = array( wfMsg( 'show' ), wfMsg( 'hide' ) ); |
177 | | - $nondefaults = array(); |
178 | | - if( $this->hideuserblocks ) { |
179 | | - $nondefaults['hideuserblocks'] = $this->hideuserblocks; |
180 | | - } |
181 | | - if( $this->hidetempblocks ) { |
182 | | - $nondefaults['hidetempblocks'] = $this->hidetempblocks; |
183 | | - } |
184 | | - if( $this->hideaddressblocks ) { |
185 | | - $nondefaults['hideaddressblocks'] = $this->hideaddressblocks; |
186 | | - } |
187 | | - $ubLink = $this->makeOptionsLink( $showhide[1-$this->hideuserblocks], |
188 | | - array( 'hideuserblocks' => 1-$this->hideuserblocks ), $nondefaults); |
189 | | - $tbLink = $this->makeOptionsLink( $showhide[1-$this->hidetempblocks], |
190 | | - array( 'hidetempblocks' => 1-$this->hidetempblocks ), $nondefaults); |
191 | | - $sipbLink = $this->makeOptionsLink( $showhide[1-$this->hideaddressblocks], |
192 | | - array( 'hideaddressblocks' => 1-$this->hideaddressblocks ), $nondefaults); |
193 | | - |
194 | | - $links = array(); |
195 | | - $links[] = wfMsgHtml( 'ipblocklist-sh-userblocks', $ubLink ); |
196 | | - $links[] = wfMsgHtml( 'ipblocklist-sh-tempblocks', $tbLink ); |
197 | | - $links[] = wfMsgHtml( 'ipblocklist-sh-addressblocks', $sipbLink ); |
198 | | - $hl = $wgLang->pipeList( $links ); |
199 | | - |
200 | | - return |
201 | | - Html::rawElement( 'form', array( 'action' => $wgScript ), |
202 | | - Html::hidden( 'title', $this->getTitle()->getPrefixedDbKey() ) . |
203 | | - Html::openElement( 'fieldset' ) . |
204 | | - Html::element( 'legend', null, wfMsg( 'ipblocklist-legend' ) ) . |
205 | | - Xml::inputLabel( wfMsg( 'ipblocklist-username' ), 'ip', 'ip', /* size */ false, $this->ip ) . |
206 | | - ' ' . |
207 | | - Xml::submitButton( wfMsg( 'ipblocklist-submit' ) ) . '<br />' . |
208 | | - $hl . |
209 | | - Html::closeElement( 'fieldset' ) |
210 | | - ); |
211 | | - } |
212 | | - |
213 | | - /** |
214 | | - * Makes change an option link which carries all the other options |
215 | | - * |
216 | | - * @param $title see Title |
217 | | - * @param $override Array: special query string options, will override the |
218 | | - * ones in $options |
219 | | - * @param $options Array: query string options |
220 | | - * @param $active Boolean: whether to display the link in bold |
221 | | - */ |
222 | | - function makeOptionsLink( $title, $override, $options, $active = false ) { |
223 | | - global $wgUser; |
224 | | - $sk = $wgUser->getSkin(); |
225 | | - $params = $override + $options; |
226 | | - return $sk->link( $this->getTitle(), htmlspecialchars( $title ), |
227 | | - ( $active ? array( 'style'=>'font-weight: bold;' ) : array() ), $params, array( 'known' ) ); |
228 | | - } |
229 | | - |
230 | | - /** |
231 | | - * Callback function to output a block |
232 | | - * |
233 | | - * @param $block Block |
234 | | - */ |
235 | | - function formatRow( $block ) { |
236 | | - global $wgUser, $wgLang, $wgBlockAllowsUTEdit; |
237 | | - |
238 | | - wfProfileIn( __METHOD__ ); |
239 | | - |
240 | | - static $sk=null, $msg=null; |
241 | | - |
242 | | - if( is_null( $sk ) ) |
243 | | - $sk = $wgUser->getSkin(); |
244 | | - if( is_null( $msg ) ) { |
245 | | - $msg = array(); |
246 | | - $keys = array( 'infiniteblock', 'expiringblock', 'unblocklink', 'change-blocklink', |
247 | | - 'anononlyblock', 'createaccountblock', 'noautoblockblock', 'emailblock', 'blocklist-nousertalk', 'blocklistline' ); |
248 | | - foreach( $keys as $key ) { |
249 | | - $msg[$key] = wfMsgHtml( $key ); |
250 | | - } |
251 | | - } |
252 | | - |
253 | | - # Prepare links to the blocker's user and talk pages |
254 | | - $blocker_id = $block->getBy(); |
255 | | - $blocker_name = $block->getByName(); |
256 | | - $blocker = $sk->userLink( $blocker_id, $blocker_name ); |
257 | | - $blocker .= $sk->userToolLinks( $blocker_id, $blocker_name ); |
258 | | - |
259 | | - # Prepare links to the block target's user and contribs. pages (as applicable, don't do it for autoblocks) |
260 | | - if( $block->mAuto ) { |
261 | | - $target = $block->getRedactedName(); # Hide the IP addresses of auto-blocks; privacy |
262 | | - } else { |
263 | | - $target = $sk->userLink( $block->mUser, $block->mAddress ) |
264 | | - . $sk->userToolLinks( $block->mUser, $block->mAddress, false, Linker::TOOL_LINKS_NOBLOCK ); |
265 | | - } |
266 | | - |
267 | | - $formattedTime = htmlspecialchars( $wgLang->timeanddate( $block->mTimestamp, true ) ); |
268 | | - |
269 | | - $properties = array(); |
270 | | - $properties[] = Block::formatExpiry( $block->mExpiry ); |
271 | | - if ( $block->mAnonOnly ) { |
272 | | - $properties[] = $msg['anononlyblock']; |
273 | | - } |
274 | | - if ( $block->mCreateAccount ) { |
275 | | - $properties[] = $msg['createaccountblock']; |
276 | | - } |
277 | | - if (!$block->mEnableAutoblock && $block->mUser ) { |
278 | | - $properties[] = $msg['noautoblockblock']; |
279 | | - } |
280 | | - |
281 | | - if ( $block->mBlockEmail && $block->mUser ) { |
282 | | - $properties[] = $msg['emailblock']; |
283 | | - } |
284 | | - |
285 | | - if ( !$block->mAllowUsertalk && $wgBlockAllowsUTEdit ) { |
286 | | - $properties[] = $msg['blocklist-nousertalk']; |
287 | | - } |
288 | | - |
289 | | - $properties = $wgLang->commaList( $properties ); |
290 | | - |
291 | | - $line = wfMsgReplaceArgs( $msg['blocklistline'], array( $formattedTime, $blocker, $target, $properties ) ); |
292 | | - |
293 | | - $changeblocklink = ''; |
294 | | - $toolLinks = ''; |
295 | | - if ( $wgUser->isAllowed( 'block' ) ) { |
296 | | - $unblocklink = $sk->link( $this->getTitle(), |
297 | | - $msg['unblocklink'], |
298 | | - array(), |
299 | | - array( 'action' => 'unblock', 'id' => $block->mId ), |
300 | | - 'known' ); |
301 | | - |
302 | | - # Create changeblocklink for all blocks with exception of autoblocks |
303 | | - if( !$block->mAuto ) { |
304 | | - $changeblocklink = wfMsgExt( 'pipe-separator', 'escapenoentities' ) . |
305 | | - $sk->link( SpecialPage::getTitleFor( 'Block', $block->mAddress ), |
306 | | - $msg['change-blocklink'], |
307 | | - array(), array(), 'known' ); |
308 | | - } |
309 | | - $toolLinks = "($unblocklink$changeblocklink)"; |
310 | | - } |
311 | | - |
312 | | - $comment = $sk->commentBlock( htmlspecialchars($block->mReason) ); |
313 | | - |
314 | | - $s = "{$line} $comment"; |
315 | | - if ( $block->mHideName ) |
316 | | - $s = '<span class="history-deleted">' . $s . '</span>'; |
317 | | - |
318 | | - wfProfileOut( __METHOD__ ); |
319 | | - return "<li>$s $toolLinks</li>\n"; |
320 | | - } |
321 | | -} |
322 | | - |
323 | | -/** |
324 | | - * @todo document |
325 | | - * @ingroup Pager |
326 | | - */ |
327 | | -class IPBlocklistPager extends ReverseChronologicalPager { |
328 | | - public $mForm, $mConds; |
329 | | - |
330 | | - function __construct( $form, $conds = array() ) { |
331 | | - $this->mForm = $form; |
332 | | - $this->mConds = $conds; |
333 | | - parent::__construct(); |
334 | | - } |
335 | | - |
336 | | - function getStartBody() { |
337 | | - wfProfileIn( __METHOD__ ); |
338 | | - # Do a link batch query |
339 | | - $this->mResult->seek( 0 ); |
340 | | - $lb = new LinkBatch; |
341 | | - |
342 | | - /* |
343 | | - while ( $row = $this->mResult->fetchObject() ) { |
344 | | - $lb->addObj( Title::makeTitleSafe( NS_USER, $row->user_name ) ); |
345 | | - $lb->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->user_name ) ); |
346 | | - $lb->addObj( Title::makeTitleSafe( NS_USER, $row->ipb_address ) ); |
347 | | - $lb->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->ipb_address ) ); |
348 | | - }*/ |
349 | | - # Faster way |
350 | | - # Usernames and titles are in fact related by a simple substitution of space -> underscore |
351 | | - # The last few lines of Title::secureAndSplit() tell the story. |
352 | | - foreach ( $this->mResult as $row ) { |
353 | | - $name = str_replace( ' ', '_', $row->ipb_by_text ); |
354 | | - $lb->add( NS_USER, $name ); |
355 | | - $lb->add( NS_USER_TALK, $name ); |
356 | | - $name = str_replace( ' ', '_', $row->ipb_address ); |
357 | | - $lb->add( NS_USER, $name ); |
358 | | - $lb->add( NS_USER_TALK, $name ); |
359 | | - } |
360 | | - $lb->execute(); |
361 | | - wfProfileOut( __METHOD__ ); |
362 | | - return ''; |
363 | | - } |
364 | | - |
365 | | - function formatRow( $row ) { |
366 | | - $block = new Block; |
367 | | - $block->initFromRow( $row ); |
368 | | - return $this->mForm->formatRow( $block ); |
369 | | - } |
370 | | - |
371 | | - function getQueryInfo() { |
372 | | - $conds = $this->mConds; |
373 | | - $conds[] = 'ipb_expiry>' . $this->mDb->addQuotes( $this->mDb->timestamp() ); |
374 | | - return array( |
375 | | - 'tables' => 'ipblocks', |
376 | | - 'fields' => '*', |
377 | | - 'conds' => $conds, |
378 | | - ); |
379 | | - } |
380 | | - |
381 | | - function getIndexField() { |
382 | | - return 'ipb_timestamp'; |
383 | | - } |
384 | | -} |
Index: trunk/phase3/includes/specials/SpecialBlockList.php |
— | — | @@ -0,0 +1,424 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Implements Special:BlockList |
| 5 | + * |
| 6 | + * This program is free software; you can redistribute it and/or modify |
| 7 | + * it under the terms of the GNU General Public License as published by |
| 8 | + * the Free Software Foundation; either version 2 of the License, or |
| 9 | + * (at your option) any later version. |
| 10 | + * |
| 11 | + * This program is distributed in the hope that it will be useful, |
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | + * GNU General Public License for more details. |
| 15 | + * |
| 16 | + * You should have received a copy of the GNU General Public License along |
| 17 | + * with this program; if not, write to the Free Software Foundation, Inc., |
| 18 | + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 19 | + * http://www.gnu.org/copyleft/gpl.html |
| 20 | + * |
| 21 | + * @file |
| 22 | + * @ingroup SpecialPage |
| 23 | + */ |
| 24 | + |
| 25 | +/** |
| 26 | + * A special page that lists existing blocks |
| 27 | + * |
| 28 | + * @ingroup SpecialPage |
| 29 | + */ |
| 30 | +class SpecialBlockList extends SpecialPage { |
| 31 | + |
| 32 | + protected $target, $options; |
| 33 | + |
| 34 | + function __construct() { |
| 35 | + parent::__construct( 'BlockList' ); |
| 36 | + } |
| 37 | + |
| 38 | + /** |
| 39 | + * Main execution point |
| 40 | + * |
| 41 | + * @param $par String title fragment |
| 42 | + */ |
| 43 | + public function execute( $par ) { |
| 44 | + global $wgUser, $wgOut, $wgRequest; |
| 45 | + |
| 46 | + $this->setHeaders(); |
| 47 | + $this->outputHeader(); |
| 48 | + $wgOut->setPageTitle( wfMsg( 'ipblocklist' ) ); |
| 49 | + $wgOut->addModuleStyles( 'mediawiki.special' ); |
| 50 | + |
| 51 | + $par = $wgRequest->getVal( 'ip', $par ); |
| 52 | + $this->target = trim( $wgRequest->getVal( 'wpTarget', $par ) ); |
| 53 | + |
| 54 | + $this->options = $wgRequest->getArray( 'wpOptions' ); |
| 55 | + |
| 56 | + $action = $wgRequest->getText( 'action' ); |
| 57 | + |
| 58 | + if( $action == 'unblock' || $action == 'submit' && $wgRequest->wasPosted() ) { |
| 59 | + # B/C @since 1.18: Unblock interface is now at Special:Unblock |
| 60 | + $title = SpecialPage::getTitleFor( 'Unblock', $this->target ); |
| 61 | + $wgOut->redirect( $title->getFullUrl() ); |
| 62 | + return; |
| 63 | + } |
| 64 | + |
| 65 | + # Just show the block list |
| 66 | + $fields = array( |
| 67 | + 'Target' => array( |
| 68 | + 'type' => 'text', |
| 69 | + 'label-message' => 'ipaddressorusername', |
| 70 | + 'tabindex' => '1', |
| 71 | + 'size' => '45', |
| 72 | + ), |
| 73 | + 'Options' => array( |
| 74 | + 'type' => 'multiselect', |
| 75 | + 'options' => array( |
| 76 | + wfMsg( 'blocklist-userblocks' ) => 'userblocks', |
| 77 | + wfMsg( 'blocklist-tempblocks' ) => 'tempblocks', |
| 78 | + wfMsg( 'blocklist-addressblocks' ) => 'addressblocks', |
| 79 | + ), |
| 80 | + 'cssclass' => 'mw-htmlform-multiselect-flatlist', |
| 81 | + ), |
| 82 | + ); |
| 83 | + $form = new HTMLForm( $fields ); |
| 84 | + $form->setTitle( $this->getTitle() ); |
| 85 | + $form->setMethod( 'get' ); |
| 86 | + $form->setWrapperLegend( wfMsg( 'ipblocklist-legend' ) ); |
| 87 | + $form->setSubmitText( wfMsg( 'ipblocklist-submit' ) ); |
| 88 | + $form->prepareForm(); |
| 89 | + |
| 90 | + $form->displayForm( '' ); |
| 91 | + $this->showList(); |
| 92 | + } |
| 93 | + |
| 94 | + /** |
| 95 | + * Get the component of an IP address which is certain to be the same between an IP |
| 96 | + * address and a rangeblock containing that IP address. |
| 97 | + * @todo: should be in IP.php?? |
| 98 | + * @param $ip String |
| 99 | + * @return String |
| 100 | + */ |
| 101 | + protected static function getIpFragment( $ip ){ |
| 102 | + global $wgBlockCIDRLimit; |
| 103 | + if( IP::isIPv4( $ip ) ){ |
| 104 | + $hexAddress = IP::toHex( $ip ); |
| 105 | + return substr( $hexAddress, 0, wfBaseconvert( $wgBlockCIDRLimit['IPv4'], 10, 16 ) ); |
| 106 | + } elseif( IP::isIPv6( $ip ) ) { |
| 107 | + $hexAddress = substr( IP::toHex( $ip ), 2 ); |
| 108 | + return 'v6-' . substr( $hexAddress, 0, wfBaseconvert( $wgBlockCIDRLimit['IPv6'], 10, 16 ) ); |
| 109 | + } else { |
| 110 | + return null; |
| 111 | + } |
| 112 | + } |
| 113 | + |
| 114 | + function showList() { |
| 115 | + global $wgOut, $wgUser; |
| 116 | + |
| 117 | + # Purge expired entries on one in every 10 queries |
| 118 | + if ( !mt_rand( 0, 10 ) ) { |
| 119 | + Block::purgeExpired(); |
| 120 | + } |
| 121 | + |
| 122 | + $conds = array(); |
| 123 | + # Is the user allowed to see hidden blocks? |
| 124 | + if ( !$wgUser->isAllowed( 'hideuser' ) ){ |
| 125 | + $conds['ipb_deleted'] = 0; |
| 126 | + } |
| 127 | + |
| 128 | + if ( $this->target !== '' ){ |
| 129 | + list( $target, $type ) = Block::parseTarget( $this->target ); |
| 130 | + |
| 131 | + switch( $type ){ |
| 132 | + case Block::TYPE_ID: |
| 133 | + $conds['ipb_id'] = $target; |
| 134 | + break; |
| 135 | + |
| 136 | + case Block::TYPE_IP: |
| 137 | + case BLock::TYPE_RANGE: |
| 138 | + list( $start, $end ) = IP::parseRange( $target ); |
| 139 | + # Per bug 14634, we want to include relevant active rangeblocks; for |
| 140 | + # rangeblocks, we want to include larger ranges which enclose the given |
| 141 | + # range. We know that all blocks must be smaller than $wgBlockCIDRLimit, |
| 142 | + # so we can improve performance by filtering on a LIKE clause |
| 143 | + $chunk = self::getIpFragment( $start ); |
| 144 | + $dbr = wfGetDB( DB_SLAVE ); |
| 145 | + $like = $dbr->buildLike( $chunk, $dbr->anyString() ); |
| 146 | + |
| 147 | + # Fairly hard to make a malicious SQL statement out of hex characters, |
| 148 | + # but stranger things have happened... |
| 149 | + $safeStart = $dbr->addQuotes( IP::toHex( $start ) ); |
| 150 | + $safeEnd = $dbr->addQuotes( IP::toHex( $end ) ); |
| 151 | + $safeTarget = $dbr->addQuotes( IP::toHex( $target ) ); |
| 152 | + |
| 153 | + # TODO: abstract this away |
| 154 | + $conds[] = "(ipb_address = $safeTarget) OR |
| 155 | + (ipb_range_start $like AND ipb_range_start <= $safeStart AND ipb_range_end >= $safeEnd)"; |
| 156 | + $conds['ipb_auto'] = 0; |
| 157 | + break; |
| 158 | + |
| 159 | + case Block::TYPE_USER: |
| 160 | + $conds['ipb_address'] = (string)$this->target; |
| 161 | + $conds['ipb_auto'] = 0; |
| 162 | + break; |
| 163 | + } |
| 164 | + } |
| 165 | + |
| 166 | + # Apply filters |
| 167 | + if( in_array( 'userblocks', $this->options ) ) { |
| 168 | + $conds['ipb_user'] = 0; |
| 169 | + } |
| 170 | + if( in_array( 'tempblocks', $this->options ) ) { |
| 171 | + $conds['ipb_expiry'] = 'infinity'; |
| 172 | + } |
| 173 | + if( in_array( 'addressblocks', $this->options ) ) { |
| 174 | + $conds[] = "ipb_user != 0 OR ipb_range_end > ipb_range_start"; |
| 175 | + } |
| 176 | + |
| 177 | + # Check for other blocks, i.e. global/tor blocks |
| 178 | + $otherBlockLink = array(); |
| 179 | + wfRunHooks( 'OtherBlockLogLink', array( &$otherBlockLink, $this->target ) ); |
| 180 | + |
| 181 | + # Show additional header for the local block only when other blocks exists. |
| 182 | + # Not necessary in a standard installation without such extensions enabled |
| 183 | + if( count( $otherBlockLink ) ) { |
| 184 | + $wgOut->addHTML( |
| 185 | + Html::rawElement( 'h2', array(), wfMsg( 'ipblocklist-localblock' ) ) . "\n" |
| 186 | + ); |
| 187 | + } |
| 188 | + |
| 189 | + $pager = new BlockListPager( $this, $conds ); |
| 190 | + if ( $pager->getNumRows() ) { |
| 191 | + $wgOut->addHTML( |
| 192 | + $pager->getNavigationBar() . |
| 193 | + $pager->getBody(). |
| 194 | + $pager->getNavigationBar() |
| 195 | + ); |
| 196 | + |
| 197 | + } elseif ( $this->target ) { |
| 198 | + $wgOut->addWikiMsg( 'ipblocklist-no-results' ); |
| 199 | + |
| 200 | + } else { |
| 201 | + $wgOut->addWikiMsg( 'ipblocklist-empty' ); |
| 202 | + } |
| 203 | + |
| 204 | + if( count( $otherBlockLink ) ) { |
| 205 | + $wgOut->addHTML( |
| 206 | + Html::rawElement( |
| 207 | + 'h2', |
| 208 | + array(), |
| 209 | + wfMsgExt( |
| 210 | + 'ipblocklist-otherblocks', |
| 211 | + 'parseinline', |
| 212 | + count( $otherBlockLink ) |
| 213 | + ) |
| 214 | + ) . "\n" |
| 215 | + ); |
| 216 | + $list = ''; |
| 217 | + foreach( $otherBlockLink as $link ) { |
| 218 | + $list .= Html::rawElement( 'li', array(), $link ) . "\n"; |
| 219 | + } |
| 220 | + $wgOut->addHTML( Html::rawElement( 'ul', array( 'class' => 'mw-ipblocklist-otherblocks' ), $list ) . "\n" ); |
| 221 | + } |
| 222 | + } |
| 223 | +} |
| 224 | + |
| 225 | +class BlockListPager extends TablePager { |
| 226 | + protected $conds; |
| 227 | + protected $page; |
| 228 | + |
| 229 | + function __construct( $page, $conds ) { |
| 230 | + $this->page = $page; |
| 231 | + $this->conds = $conds; |
| 232 | + $this->mDefaultDirection = true; |
| 233 | + parent::__construct(); |
| 234 | + } |
| 235 | + |
| 236 | + function getFieldNames() { |
| 237 | + global $wgUser; |
| 238 | + static $headers = null; |
| 239 | + |
| 240 | + if ( $headers == array() ) { |
| 241 | + $headers = array( |
| 242 | + 'ipb_timestamp' => 'blocklist-timestamp', |
| 243 | + 'ipb_target' => 'blocklist-target', |
| 244 | + 'ipb_expiry' => 'blocklist-expiry', |
| 245 | + 'ipb_by' => 'blocklist-by', |
| 246 | + 'ipb_params' => 'blocklist-params', |
| 247 | + 'ipb_reason' => 'blocklist-reason', |
| 248 | + ); |
| 249 | + $headers = array_map( 'wfMsg', $headers ); |
| 250 | + } |
| 251 | + |
| 252 | + return $headers; |
| 253 | + } |
| 254 | + |
| 255 | + function formatValue( $name, $value ) { |
| 256 | + global $wgOut, $wgLang, $wgUser; |
| 257 | + |
| 258 | + static $sk, $msg; |
| 259 | + if ( empty( $sk ) ) { |
| 260 | + $sk = $wgUser->getSkin(); |
| 261 | + $msg = array( |
| 262 | + 'anononlyblock', |
| 263 | + 'createaccountblock', |
| 264 | + 'noautoblockblock', |
| 265 | + 'emailblock', |
| 266 | + 'blocklist-nousertalk', |
| 267 | + 'unblocklink', |
| 268 | + 'change-blocklink', |
| 269 | + ); |
| 270 | + $msg = array_combine( $msg, array_map( 'wfMessage', $msg ) ); |
| 271 | + } |
| 272 | + |
| 273 | + $row = $this->mCurrentRow; |
| 274 | + $formatted = ''; |
| 275 | + |
| 276 | + switch( $name ) { |
| 277 | + case 'ipb_timestamp': |
| 278 | + $formatted = $wgLang->timeanddate( $value ); |
| 279 | + break; |
| 280 | + |
| 281 | + case 'ipb_target': |
| 282 | + if( $row->ipb_auto ){ |
| 283 | + $formatted = wfMessage( 'autoblockid', $row->ipb_id ); |
| 284 | + } else { |
| 285 | + list( $target, $type ) = Block::parseTarget( $row->ipb_address ); |
| 286 | + switch( $type ){ |
| 287 | + case Block::TYPE_USER: |
| 288 | + case Block::TYPE_IP: |
| 289 | + $formatted = $sk->userLink( $target->getId(), $target ); |
| 290 | + $formatted .= $sk->userToolLinks( |
| 291 | + $target->getId(), |
| 292 | + $target, |
| 293 | + false, |
| 294 | + Linker::TOOL_LINKS_NOBLOCK |
| 295 | + ); |
| 296 | + break; |
| 297 | + case Block::TYPE_RANGE: |
| 298 | + $formatted = htmlspecialchars( $target ); |
| 299 | + } |
| 300 | + } |
| 301 | + break; |
| 302 | + |
| 303 | + case 'ipb_expiry': |
| 304 | + $formatted = $wgLang->timeanddate( $value ); |
| 305 | + if( $wgUser->isAllowed( 'block' ) ){ |
| 306 | + if( $row->ipb_auto ){ |
| 307 | + $links[] = $sk->linkKnown( |
| 308 | + SpecialPage::getTitleFor( 'Unblock' ), |
| 309 | + $msg['unblocklink'], |
| 310 | + array(), |
| 311 | + array( 'wpTarget' => "#{$row->ipb_id}" ) |
| 312 | + ); |
| 313 | + } else { |
| 314 | + $links[] = $sk->linkKnown( |
| 315 | + SpecialPage::getTitleFor( 'Unblock', $row->ipb_address ), |
| 316 | + $msg['unblocklink'] |
| 317 | + ); |
| 318 | + $links[] = $sk->linkKnown( |
| 319 | + SpecialPage::getTitleFor( 'Block', $row->ipb_address ), |
| 320 | + $msg['change-blocklink'] |
| 321 | + ); |
| 322 | + } |
| 323 | + $formatted .= ' ' . Html::rawElement( |
| 324 | + 'span', |
| 325 | + array( 'class' => 'mw-blocklist-actions' ), |
| 326 | + "[{$wgLang->pipeList($links)}]" |
| 327 | + ); |
| 328 | + } |
| 329 | + break; |
| 330 | + |
| 331 | + case 'ipb_by': |
| 332 | + $user = User::newFromId( $value ); |
| 333 | + if( $user instanceof User ){ |
| 334 | + $formatted = $sk->userLink( $user->getId(), $user->getName() ); |
| 335 | + $formatted .= $sk->userToolLinks( $user->getId(), $user->getName() ); |
| 336 | + } |
| 337 | + break; |
| 338 | + |
| 339 | + case 'ipb_reason': |
| 340 | + $formatted = $sk->commentBlock( $value ); |
| 341 | + break; |
| 342 | + |
| 343 | + case 'ipb_params': |
| 344 | + $properties = array(); |
| 345 | + if ( $row->ipb_anon_only ) { |
| 346 | + $properties[] = $msg['anononlyblock']; |
| 347 | + } |
| 348 | + if ( $row->ipb_create_account ) { |
| 349 | + $properties[] = $msg['createaccountblock']; |
| 350 | + } |
| 351 | + if ( !$row->ipb_enable_autoblock ) { |
| 352 | + $properties[] = $msg['noautoblockblock']; |
| 353 | + } |
| 354 | + |
| 355 | + if ( $row->ipb_block_email ) { |
| 356 | + $properties[] = $msg['emailblock']; |
| 357 | + } |
| 358 | + |
| 359 | + if ( !$row->ipb_allow_usertalk ) { |
| 360 | + $properties[] = $msg['blocklist-nousertalk']; |
| 361 | + } |
| 362 | + |
| 363 | + $formatted = $wgLang->commaList( $properties ); |
| 364 | + break; |
| 365 | + |
| 366 | + default: |
| 367 | + $formatted = "Unable to format $name"; |
| 368 | + break; |
| 369 | + } |
| 370 | + |
| 371 | + return $formatted; |
| 372 | + } |
| 373 | + |
| 374 | + function getQueryInfo() { |
| 375 | + $info = array( |
| 376 | + 'tables' => array( 'ipblocks' ), |
| 377 | + 'fields' => array( |
| 378 | + 'ipb_id', |
| 379 | + 'ipb_address', |
| 380 | + 'ipb_by', |
| 381 | + 'ipb_reason', |
| 382 | + 'ipb_timestamp', |
| 383 | + 'ipb_auto', |
| 384 | + 'ipb_anon_only', |
| 385 | + 'ipb_create_account', |
| 386 | + 'ipb_enable_autoblock', |
| 387 | + 'ipb_expiry', |
| 388 | + 'ipb_range_start', |
| 389 | + 'ipb_range_end', |
| 390 | + 'ipb_deleted', |
| 391 | + 'ipb_block_email', |
| 392 | + 'ipb_allow_usertalk', |
| 393 | + ), |
| 394 | + 'conds' => $this->conds, |
| 395 | + ); |
| 396 | + |
| 397 | + global $wgUser; |
| 398 | + # Is the user allowed to see hidden blocks? |
| 399 | + if ( !$wgUser->isAllowed( 'hideuser' ) ){ |
| 400 | + $conds['ipb_deleted'] = 0; |
| 401 | + } |
| 402 | + |
| 403 | + return $info; |
| 404 | + } |
| 405 | + |
| 406 | + public function getTableClass(){ |
| 407 | + return 'TablePager mw-blocklist'; |
| 408 | + } |
| 409 | + |
| 410 | + function getIndexField() { |
| 411 | + return 'ipb_timestamp'; |
| 412 | + } |
| 413 | + |
| 414 | + function getDefaultSort() { |
| 415 | + return 'ipb_timestamp'; |
| 416 | + } |
| 417 | + |
| 418 | + function isFieldSortable( $name ) { |
| 419 | + return false; |
| 420 | + } |
| 421 | + |
| 422 | + function getTitle() { |
| 423 | + return $this->mPage->getTitle(); |
| 424 | + } |
| 425 | +} |
Property changes on: trunk/phase3/includes/specials/SpecialBlockList.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 426 | + native |
Added: svn:keywords |
2 | 427 | + Author Date Id Revision |
Index: trunk/phase3/includes/specials/SpecialBlock.php |
— | — | @@ -308,7 +308,7 @@ |
309 | 309 | |
310 | 310 | # Link to the block list |
311 | 311 | $links[] = $skin->linkKnown( |
312 | | - SpecialPage::getTitleFor( 'Ipblocklist' ), |
| 312 | + SpecialPage::getTitleFor( 'BlockList' ), |
313 | 313 | wfMsg( 'ipb-blocklist' ) |
314 | 314 | ); |
315 | 315 | |
Index: trunk/phase3/includes/SpecialPage.php |
— | — | @@ -138,7 +138,7 @@ |
139 | 139 | # Users and rights |
140 | 140 | 'Block' => 'SpecialBlock', |
141 | 141 | 'Unblock' => 'SpecialUnblock', |
142 | | - 'Ipblocklist' => 'IPUnblockForm', |
| 142 | + 'BlockList' => 'SpecialBlockList', |
143 | 143 | 'Resetpass' => 'SpecialResetpass', |
144 | 144 | 'DeletedContributions' => 'DeletedContributionsPage', |
145 | 145 | 'Preferences' => 'SpecialPreferences', |
Index: trunk/phase3/includes/Pager.php |
— | — | @@ -51,7 +51,7 @@ |
52 | 52 | * |
53 | 53 | * Subclassing the pager to implement concrete functionality should be fairly |
54 | 54 | * simple, please see the examples in HistoryPage.php and |
55 | | - * SpecialIpblocklist.php. You just need to override formatRow(), |
| 55 | + * SpecialBlockList.php. You just need to override formatRow(), |
56 | 56 | * getQueryInfo() and getIndexField(). Don't forget to call the parent |
57 | 57 | * constructor if you override it. |
58 | 58 | * |
Index: trunk/phase3/languages/messages/MessagesEn.php |
— | — | @@ -405,7 +405,7 @@ |
406 | 406 | 'Filepath' => array( 'FilePath' ), |
407 | 407 | 'Import' => array( 'Import' ), |
408 | 408 | 'Invalidateemail' => array( 'InvalidateEmail' ), |
409 | | - 'Ipblocklist' => array( 'BlockList', 'ListBlocks', 'IPBlockList' ), |
| 409 | + 'BlockList' => array( 'BlockList', 'ListBlocks', 'IPBlockList' ), |
410 | 410 | 'LinkSearch' => array( 'LinkSearch' ), |
411 | 411 | 'Listadmins' => array( 'ListAdmins' ), |
412 | 412 | 'Listbots' => array( 'ListBots' ), |
— | — | @@ -1592,7 +1592,7 @@ |
1593 | 1593 | # Suppression log |
1594 | 1594 | 'suppressionlog' => 'Suppression log', |
1595 | 1595 | 'suppressionlogtext' => 'Below is a list of deletions and blocks involving content hidden from administrators. |
1596 | | -See the [[Special:IPBlockList|IP block list]] for the list of currently operational bans and blocks.', |
| 1596 | +See the [[Special:BlockList|IP block list]] for the list of currently operational bans and blocks.', |
1597 | 1597 | |
1598 | 1598 | # Revision move |
1599 | 1599 | 'moverevlogentry' => 'moved {{PLURAL:$3|one revision|$3 revisions}} from $1 to $2', |
— | — | @@ -3072,15 +3072,19 @@ |
3073 | 3073 | 'unblocked-id' => 'Block $1 has been removed', |
3074 | 3074 | 'ipblocklist' => 'Blocked IP addresses and usernames', |
3075 | 3075 | 'ipblocklist-legend' => 'Find a blocked user', |
3076 | | -'ipblocklist-username' => 'Username or IP address:', |
3077 | | -'ipblocklist-sh-userblocks' => '$1 account blocks', |
3078 | | -'ipblocklist-sh-tempblocks' => '$1 temporary blocks', |
3079 | | -'ipblocklist-sh-addressblocks' => '$1 single IP blocks', |
| 3076 | +'blocklist-userblocks' => 'Hide account blocks', |
| 3077 | +'blocklist-tempblocks' => 'Hide temporary blocks', |
| 3078 | +'blocklist-addressblocks' => 'Hide single IP blocks', |
| 3079 | +'blocklist-timestamp' => 'Timestamp', |
| 3080 | +'blocklist-target' => 'Target', |
| 3081 | +'blocklist-expiry' => 'Expires', |
| 3082 | +'blocklist-by' => 'Blocking admin', |
| 3083 | +'blocklist-params' => 'Block parameters', |
| 3084 | +'blocklist-reason' => 'Reason', |
3080 | 3085 | 'ipblocklist-summary' => '', # do not translate or duplicate this message to other languages |
3081 | 3086 | 'ipblocklist-submit' => 'Search', |
3082 | 3087 | 'ipblocklist-localblock' => 'Local block', |
3083 | 3088 | 'ipblocklist-otherblocks' => 'Other {{PLURAL:$1|block|blocks}}', |
3084 | | -'blocklistline' => '$1, $2 blocked $3 ($4)', |
3085 | 3089 | 'infiniteblock' => 'infinite', |
3086 | 3090 | 'expiringblock' => 'expires on $1 at $2', |
3087 | 3091 | 'anononlyblock' => 'anon. only', |
Index: trunk/phase3/resources/mediawiki.special/mediawiki.special.css |
— | — | @@ -37,6 +37,13 @@ |
38 | 38 | font-weight: bold; |
39 | 39 | } |
40 | 40 | |
| 41 | +/**** Special:BlockList ****/ |
| 42 | +table.mw-blocklist span.mw-usertoollinks, |
| 43 | +span.mw-blocklist-actions{ |
| 44 | + white-space: nowrap; |
| 45 | + font-size: 90%; |
| 46 | +} |
| 47 | + |
41 | 48 | /**** Special:Contributions ****/ |
42 | 49 | .mw-uctop { |
43 | 50 | font-weight: bold; |
Index: trunk/extensions/CheckUser/CheckUser_body.php |
— | — | @@ -499,7 +499,7 @@ |
500 | 500 | |
501 | 501 | protected function getIPBlockInfo( $ip ) { |
502 | 502 | static $blocklist; |
503 | | - $blocklist = SpecialPage::getTitleFor( 'Ipblocklist' ); |
| 503 | + $blocklist = SpecialPage::getTitleFor( 'BlockList' ); |
504 | 504 | $block = new Block(); |
505 | 505 | $block->fromMaster( false ); // use slaves |
506 | 506 | if ( $block->load( $ip, 0 ) ) { |
— | — | @@ -1032,7 +1032,7 @@ |
1033 | 1033 | protected function userBlockFlags( $ip, $userId, $user ) { |
1034 | 1034 | static $logs, $blocklist; |
1035 | 1035 | $logs = SpecialPage::getTitleFor( 'Log' ); |
1036 | | - $blocklist = SpecialPage::getTitleFor( 'Ipblocklist' ); |
| 1036 | + $blocklist = SpecialPage::getTitleFor( 'BlockList' ); |
1037 | 1037 | $block = new Block(); |
1038 | 1038 | $block->fromMaster( false ); // use slaves |
1039 | 1039 | $flags = array(); |