r69456 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r69455‎ | r69456 | r69457 >
Date:00:34, 17 July 2010
Author:soxred93
Status:deferred
Tags:
Comment:
Updating to current code: The CheckUSer special page API is working for User->IP, and CheckUserLog is split to a unique special page.
Modified paths:
  • /branches/new-checkuser/CheckUser.alias.php (modified) (history)
  • /branches/new-checkuser/CheckUser.body.php (added) (history)
  • /branches/new-checkuser/CheckUser.i18n.en.php (modified) (history)
  • /branches/new-checkuser/CheckUser.pager.php (added) (history)
  • /branches/new-checkuser/CheckUser.php (modified) (history)
  • /branches/new-checkuser/CheckUserApi.php (modified) (history)
  • /branches/new-checkuser/SpecialCheckUser.php (modified) (history)
  • /branches/new-checkuser/SpecialCheckUserLog.php (added) (history)

Diff [purge]

Index: branches/new-checkuser/CheckUser.i18n.en.php
@@ -77,12 +77,12 @@
7878 'checkuser-ipeditcount' => '~$1 from all users',
7979 'checkuser-log-subpage' => 'Log',
8080 'checkuser-log-return' => 'Return to CheckUser main form',
81 - 'checkuser-log-userips' => '$1 got IP addresses for $2',
82 - 'checkuser-log-ipedits' => '$1 got edits for $2',
83 - 'checkuser-log-ipusers' => '$1 got users for $2',
84 - 'checkuser-log-ipedits-xff' => '$1 got edits for XFF $2',
85 - 'checkuser-log-ipusers-xff' => '$1 got users for XFF $2',
86 - 'checkuser-log-useredits' => '$1 got edits for $2',
 81+ 'checkuser-log-user2ip' => '$1 got IP addresses for $2',
 82+ 'checkuser-log-ip2edits' => '$1 got edits for $2',
 83+ 'checkuser-log-ip2user' => '$1 got users for $2',
 84+ 'checkuser-log-ip2edits-xff' => '$1 got edits for XFF $2',
 85+ 'checkuser-log-ip2user-xff' => '$1 got users for XFF $2',
 86+ 'checkuser-log-user2edits' => '$1 got edits for $2',
8787
8888 'checkuser-autocreate-action' => 'was automatically created',
8989 'checkuser-email-action' => 'sent an email to user "$1"',
@@ -106,4 +106,5 @@
107107 'checkuser-last' => 'Last use',
108108 'checkuser-blockinfo' => 'Block info',
109109 'checkuser-expires' => 'Expires',
 110+ 'checkuser-limit' => 'Results to show:',
110111 );
\ No newline at end of file
Index: branches/new-checkuser/CheckUser.alias.php
@@ -13,6 +13,7 @@
1414 */
1515 $aliases['en'] = array(
1616 'CheckUser' => array( 'CheckUser' ),
 17+ 'CheckUserLog' => array( 'CheckUserLog' ),
1718 );
1819
1920 /** Arabic (العربية) */
Index: branches/new-checkuser/CheckUserApi.php
@@ -56,51 +56,38 @@
5757
5858 public function doUser2IP( &$cuClass, $params, $prop, $limit ) {
5959
60 - $dbParams = $cuClass->doUser2IP( $params, $prop, $limit );
 60+ $result = $cuClass->doUser2IP( $params, $prop, $limit );
6161
6262 $retArray = array();
6363
64 - $dbr = wfGetDB( DB_SLAVE );
65 -
66 - //$dbr->setFlag( DBO_DEBUG );
67 -
68 - $ret = $dbr->select(
69 - $dbParams[0],
70 - $dbParams[1],
71 - $dbParams[2],
72 - __METHOD__,
73 - $dbParams[3]
74 - );
75 -
76 - if ( !$dbr->numRows( $ret ) ) {
77 - return $retArray;
78 - } else {
79 - $counter = 0;
 64+ $counter = 0;
8065
81 - foreach( $ret as $id => $row ) {
82 - $retArray[$counter] = array( 'ip' => $row->cuc_ip );
83 -
84 - if( in_array( 'count', $prop ) || is_null( $prop ) ) $retArray[$counter]['count'] = $row->count;
85 - if( in_array( 'first', $prop ) || is_null( $prop ) ) $retArray[$counter]['first'] = $row->first;
86 - if( in_array( 'last', $prop ) || is_null( $prop ) ) $retArray[$counter]['last'] = $row->last;
87 - if( in_array( 'hex', $prop ) || is_null( $prop ) ) $retArray[$counter]['hex'] = $row->cuc_ip_hex;
88 - if( in_array( 'blockinfo', $prop ) || is_null( $prop ) ) {
89 - $blockinfo = CheckUser::checkBlockInfo( $row->cuc_ip );
90 - if( $blockinfo ) {
91 - $retArray[$counter]['blockinfo']['by'] = $blockinfo->ipb_by_text;
92 - $retArray[$counter]['blockinfo']['reason'] = $blockinfo->ipb_reason;
93 - $retArray[$counter]['blockinfo']['timestamp'] = $blockinfo->ipb_timestamp;
94 - $retArray[$counter]['blockinfo']['expiry'] = $blockinfo->ipb_expiry;
95 - }
 66+ foreach( $result[0] as $id => $row ) {
 67+ $retArray[$counter] = array( 'ip' => $row->cuc_ip );
 68+
 69+ if( in_array( 'count', $prop ) || is_null( $prop ) ) $retArray[$counter]['count'] = $row->count;
 70+ if( in_array( 'first', $prop ) || is_null( $prop ) ) $retArray[$counter]['first'] = $row->first;
 71+ if( in_array( 'last', $prop ) || is_null( $prop ) ) $retArray[$counter]['last'] = $row->last;
 72+ if( in_array( 'hex', $prop ) || is_null( $prop ) ) $retArray[$counter]['hex'] = $row->cuc_ip_hex;
 73+ if( in_array( 'blockinfo', $prop ) || is_null( $prop ) ) {
 74+ $blockinfo = CheckUser::checkBlockInfo( $row->cuc_ip );
 75+ if( $blockinfo ) {
 76+ $retArray[$counter]['blockinfo'] = array();
 77+ $retArray[$counter]['blockinfo']['by'] = $blockinfo->ipb_by_text;
 78+ $retArray[$counter]['blockinfo']['reason'] = $blockinfo->ipb_reason;
 79+ $retArray[$counter]['blockinfo']['timestamp'] = $blockinfo->ipb_timestamp;
 80+ $retArray[$counter]['blockinfo']['expiry'] = $blockinfo->ipb_expiry;
9681 }
97 -
98 - $counter++;
99 -
10082 }
 83+ if( in_array( 'alledits', $prop ) || is_null( $prop ) ) {
 84+ $retArray[$counter]['alledits'] = CheckUser::getAllEdits( $row->cuc_ip_hex, $result[1] );
 85+ }
 86+
 87+ $counter++;
 88+
10189 }
10290
103 - $dbr->freeResult( $ret );
104 -
 91+
10592 return $retArray;
10693 }
10794
@@ -128,13 +115,14 @@
129116 ),
130117 'prop' => array(
131118 ApiBase::PARAM_ISMULTI => true,
132 - ApiBase::PARAM_DFLT => 'count|first|last|blockinfo',
 119+ ApiBase::PARAM_DFLT => 'count|first|last|blockinfo|alledits',
133120 ApiBase::PARAM_TYPE => array(
134121 'count',
135122 'first',
136123 'last',
137124 'hex',
138125 'blockinfo',
 126+ 'alledits',
139127 )
140128 ),
141129 'limit' => array(
Index: branches/new-checkuser/CheckUser.body.php
@@ -0,0 +1,183 @@
 2+<?php
 3+
 4+class CheckUser {
 5+
 6+ var $target;
 7+
 8+ function __construct( $target ) {
 9+ $this->target = $target;
 10+ }
 11+
 12+ function doUser2IP( $params, $prop = array(), $limit = '' ) {
 13+
 14+ $userTitle = Title::newFromText( $this->target, NS_USER );
 15+ if ( !is_null( $userTitle ) ) {
 16+ // normalize the username
 17+ $user = $this->target = $userTitle->getText();
 18+ }
 19+
 20+ # IPs are passed in as a blank string
 21+ if ( !$user ) {
 22+ return array( 'error' => 'nouserspecified' );
 23+ }
 24+
 25+ # Get ID, works better than text as user may have been renamed
 26+ $user_id = User::idFromName( $user );
 27+
 28+ # If user is not IP or nonexistent
 29+ if ( !$user_id ) {
 30+ return array( 'error' => 'nosuchusershort' );
 31+ }
 32+
 33+ # Record check...
 34+ if ( !$this->addLogEntry( 'user2ip', 'user', $user, $params['reason'], $user_id ) ) {
 35+ $retArray['warn'] = 'checkuser-log-fail';
 36+ }
 37+
 38+ $dbr = wfGetDB( DB_SLAVE );
 39+ $time_conds = $this->getTimeConds( $params['period'] );
 40+ # Ordering by the latest timestamp makes a small filesort on the IP list
 41+ $cu_changes = $dbr->tableName( 'cu_changes' );
 42+ $use_index = $dbr->useIndexClause( 'cuc_user_ip_time' );
 43+
 44+ $select = array(
 45+ 'cuc_ip',
 46+ 'cuc_ip_hex',
 47+ 'cuc_user',
 48+ 'COUNT(*) AS count',
 49+ 'MIN(cuc_timestamp) AS first',
 50+ 'MAX(cuc_timestamp) AS last'
 51+ );
 52+
 53+ $opts = array(
 54+ 'GROUP BY' => 'cuc_ip,cuc_ip_hex',
 55+ 'ORDER BY' => 'last DESC',
 56+ 'USE INDEX' => 'cuc_user_ip_time'
 57+ );
 58+
 59+ if( !empty( $limit ) ) $opts['LIMIT'] = $limit;
 60+
 61+ $ret = $dbr->select(
 62+ $cu_changes,
 63+ $select,
 64+ array(
 65+ 'cuc_user' => $user_id,
 66+ $time_conds
 67+ ),
 68+ __METHOD__,
 69+ $opts
 70+ );
 71+
 72+ if( !$ret->numRows() ) {
 73+ return array();
 74+ }
 75+
 76+ return array( $ret, $time_conds );
 77+
 78+ }
 79+
 80+ function doUser2Edits() {
 81+ }
 82+
 83+ function doIP2User() {
 84+ }
 85+
 86+ function doIP2Edits() {
 87+ }
 88+
 89+ protected function addLogEntry( $logType, $targetType, $target, $reason, $targetID = 0 ) {
 90+ global $wgUser;
 91+
 92+ if ( $targetType == 'ip' ) {
 93+ list( $rangeStart, $rangeEnd ) = IP::parseRange( $target );
 94+ $targetHex = $rangeStart;
 95+ if ( $rangeStart == $rangeEnd ) {
 96+ $rangeStart = $rangeEnd = '';
 97+ }
 98+ } else {
 99+ $targetHex = $rangeStart = $rangeEnd = '';
 100+ }
 101+
 102+ $dbw = wfGetDB( DB_MASTER );
 103+ $cul_id = $dbw->nextSequenceValue( 'cu_log_cul_id_seq' );
 104+ $dbw->insert( 'cu_log',
 105+ array(
 106+ 'cul_id' => $cul_id,
 107+ 'cul_timestamp' => $dbw->timestamp(),
 108+ 'cul_user' => $wgUser->getID(),
 109+ 'cul_user_text' => $wgUser->getName(),
 110+ 'cul_reason' => $reason,
 111+ 'cul_type' => $logType,
 112+ 'cul_target_id' => $targetID,
 113+ 'cul_target_text' => $target,
 114+ 'cul_target_hex' => $targetHex,
 115+ 'cul_range_start' => $rangeStart,
 116+ 'cul_range_end' => $rangeEnd,
 117+ ), __METHOD__ );
 118+ return true;
 119+ }
 120+
 121+ function getIPType() {
 122+ }
 123+
 124+ public static function checkBlockInfo( $name ) {
 125+ $dbr = wfGetDB( DB_SLAVE );
 126+
 127+ $ret = $dbr->select(
 128+ 'ipblocks',
 129+ array(
 130+ 'ipb_by_text',
 131+ 'ipb_reason',
 132+ 'ipb_timestamp',
 133+ 'ipb_expiry'
 134+ ),
 135+ array(
 136+ 'ipb_address' => $name
 137+ ),
 138+ __METHOD__
 139+ );
 140+
 141+
 142+ foreach( $ret as $res ) {
 143+ $return = $res;
 144+ break;
 145+ }
 146+
 147+ $dbr->freeResult( $ret );
 148+
 149+ if( isset( $return ) ) return $return;
 150+
 151+ return false;
 152+ }
 153+
 154+ public static function getAllEdits( $hex, $time_conds ) {
 155+ $dbr = wfGetDB( DB_SLAVE );
 156+
 157+ $ipedits = $dbr->estimateRowCount( 'cu_changes', '*',
 158+ array( 'cuc_ip_hex' => $hex, $time_conds ),
 159+ __METHOD__ );
 160+ # If small enough, get a more accurate count
 161+ if ( $ipedits <= 1000 ) {
 162+ $ipedits = $dbr->selectField( 'cu_changes', 'COUNT(*)',
 163+ array( 'cuc_ip_hex' => $hex, $time_conds ),
 164+ __METHOD__ );
 165+ }
 166+
 167+ return $ipedits;
 168+ }
 169+
 170+ protected function getTimeConds( $period ) {
 171+
 172+ if ( !$period ) {
 173+ return '1 = 1';
 174+ }
 175+
 176+ $dbr = wfGetDB( DB_SLAVE );
 177+ $cutoff_unixtime = time() - ( $period * 24 * 3600 );
 178+ $cutoff_unixtime = $cutoff_unixtime - ( $cutoff_unixtime % 86400 );
 179+ $cutoff = $dbr->addQuotes( $dbr->timestamp( $cutoff_unixtime ) );
 180+ return "cuc_timestamp > $cutoff";
 181+ }
 182+
 183+
 184+}
\ No newline at end of file
Index: branches/new-checkuser/CheckUser.pager.php
@@ -0,0 +1,226 @@
 2+<?php
 3+
 4+abstract class CUTablePager extends TablePager {
 5+
 6+ public $mLimitsShown;
 7+ public $mTimeConds;
 8+
 9+ function __construct( $result = array(), $index = 'cuc_ip' ) {
 10+ parent::__construct();
 11+
 12+ $this->mIndexField = $index;
 13+ $this->mResult = $result[0];
 14+ $this->mTimeConds = $result[1];
 15+
 16+ }
 17+
 18+ /* This function normally does a database query to get the results; we need
 19+ * to make a pretend result using a FakeResultWrapper.
 20+ */
 21+ function reallyDoQuery( $offset, $limit, $descending ) {
 22+ global $wgRequest;
 23+
 24+ $result = array();
 25+
 26+ $index = ( $wgRequest->getVal( 'sort' ) ) ? $wgRequest->getVal( 'sort' ) : $this->mIndexField;
 27+
 28+ if ( $descending ) {
 29+ $operator = '>';
 30+
 31+ $obj = new CUSortArray( 'DESC', $index );
 32+ } else {
 33+ $operator = '<';
 34+
 35+ $obj = new CUSortArray( 'ASC', $index );
 36+ }
 37+
 38+ $forNow = array();
 39+
 40+ foreach( $this->mResult as $row ) {
 41+ $row = (array) $row;
 42+
 43+ $forNow[] = $this->fixRowResult( $row );
 44+ }
 45+
 46+ $this->mResult = $forNow;
 47+
 48+ usort( $this->mResult, array( $obj, 'run' ) );
 49+
 50+ $count = 0;
 51+ foreach( $this->mResult as $res ) {
 52+
 53+ if ( $offset != '' ) {
 54+ if ( $descending ) {
 55+ if( $res[$this->mIndexField] > $offset ) continue;
 56+ } else {
 57+ if( $res[$this->mIndexField] < $offset ) continue;
 58+ }
 59+
 60+ }
 61+
 62+ $result[] = $res;
 63+
 64+ $count++;
 65+
 66+ if( $count == $limit ) break;
 67+ }
 68+
 69+ return new FakeResultWrapper( $result );
 70+ }
 71+
 72+ abstract function fixRowResult( $row );
 73+
 74+ function getTitle() {
 75+ return SpecialPage::getTitleFor( 'CheckUser', false );
 76+ }
 77+
 78+ function isFieldSortable( $field ) {
 79+ return true;
 80+ }
 81+
 82+ function getQueryInfo() {
 83+ return '';
 84+ }
 85+
 86+}
 87+
 88+class CUTablePagerUser2IP extends CUTablePager {
 89+
 90+ function fixRowResult( $row ) {
 91+ $row['allusers'] = CheckUser::getAllEdits( $row['cuc_ip_hex'], $this->mTimeConds );
 92+
 93+ $blockinfo = CheckUser::checkBlockInfo( $row['cuc_ip'] );
 94+ $row['blockinfo'] = $blockinfo;
 95+
 96+ if( $blockinfo ) {
 97+ $row['blockinfo'] = array();
 98+
 99+ $row['blockinfo']['by'] = $blockinfo->ipb_by_text;
 100+ $row['blockinfo']['reason'] = $blockinfo->ipb_reason;
 101+ $row['blockinfo']['timestamp'] = $blockinfo->ipb_timestamp;
 102+ $row['blockinfo']['expiry'] = $blockinfo->ipb_expiry;
 103+ }
 104+
 105+ return $row;
 106+ }
 107+
 108+ function formatValue( $field, $value ) {
 109+ global $wgContLang;
 110+
 111+ switch( $field ) {
 112+ case 'cuc_ip':
 113+ return '<a href="' .
 114+ $this->getTitle()->escapeLocalURL( 'user=' . urlencode( $value ) . '&reason=' . urlencode( $reason ) ) . '">' .
 115+ htmlspecialchars( $value ) . '</a>' .
 116+ ' (<a href="' . SpecialPage::getTitleFor( 'Blockip' )->escapeLocalURL( 'ip=' . urlencode( $value ) ) . '">' .
 117+ wfMsgHtml( 'blocklink' ) . '</a>)<br /><small>' .
 118+ wfMsgExt( 'checkuser-toollinks', array( 'parseinline' ), urlencode( $value ) ) . '</small>';
 119+
 120+ break;
 121+ case 'first':
 122+ return $wgContLang->timeanddate( wfTimestamp( TS_MW, $value ), true );
 123+ break;
 124+ case 'last':
 125+ return $wgContLang->timeanddate( wfTimestamp( TS_MW, $value ), true );
 126+ break;
 127+ case 'blockinfo':
 128+ return $this->fixBlockInfo( $value );
 129+ break;
 130+ }
 131+
 132+ return $value;
 133+ }
 134+
 135+ private function fixBlockInfo( $value ) {
 136+ global $wgContLang;
 137+
 138+ if( !$value ) return '';
 139+
 140+ $expirydate = wfMsg( 'checkuser-expires' ) . ' ' . $wgContLang->timeanddate( wfTimestamp( TS_MW, $value['expiry'] ), true );
 141+
 142+ if( !is_numeric( $value['expiry'] ) ) {
 143+ $expirydate = '';
 144+ }
 145+
 146+ return wfMsgExt( 'checkuser-blockedby', 'parseinline', $value['by'], $value['reason'], $wgContLang->timeanddate( wfTimestamp( TS_MW, $value['timestamp'] ), true ), $expirydate );
 147+ }
 148+
 149+ function getCellAttrs( $field, $value ) {
 150+ $retArr = array( 'class' => 'TablePager_col_' . $field );
 151+
 152+ if(
 153+ ( $field == 'first' && $value == $this->mCurrentRow->last ) ||
 154+ ( $field == 'last' && $value == $this->mCurrentRow->first ) ||
 155+ ( $field == 'blockinfo' && !empty( $value ) )
 156+ ) {
 157+ $retArr['style'] = 'background-color: #FFFFCC;';
 158+
 159+ if( $field == 'blockinfo' ) {
 160+ $retArr['style'] .= 'width: 33%;';
 161+ }
 162+ }
 163+
 164+ return $retArr;
 165+ }
 166+
 167+ function getFieldNames() {
 168+ $fields = array(
 169+ $this->getDefaultSort() => wfMsg( 'checkuser-cuc_ip' ),
 170+ 'count' => wfMsg( 'checkuser-count' ),
 171+ 'allusers' => wfMsg( 'checkuser-allusers' ),
 172+ 'first' => wfMsg( 'checkuser-first' ),
 173+ 'last' => wfMsg( 'checkuser-last' ),
 174+ 'blockinfo' => wfMsg( 'checkuser-blockinfo' ),
 175+ );
 176+ return $fields;
 177+ }
 178+
 179+ function getDefaultSort() {
 180+ return 'cuc_ip';
 181+ }
 182+
 183+}
 184+
 185+class CUSortArray {
 186+
 187+ var $dir, $index;
 188+
 189+ function __construct( $dir, $index ) {
 190+ $this->dir = $dir;
 191+ $this->index = $index;
 192+ }
 193+
 194+ function run( $old, $new ) {
 195+ if( $this->index == "blockinfo" ) {
 196+
 197+ if( $this->dir == "DESC" ) {
 198+ return $this->runeval( $old, $new );
 199+ }
 200+ else {
 201+ return $this->runeval( $new, $old );
 202+ }
 203+ }
 204+ else {
 205+ if( $this->dir == "DESC" ) {
 206+ return strnatcmp( $old[$this->index], $new[$this->index] );
 207+ }
 208+ else {
 209+ return strnatcmp( $new[$this->index], $old[$this->index] );
 210+ }
 211+ }
 212+ }
 213+
 214+ function runeval( $old, $new ) {
 215+ $oper = ( $this->dir == "DESC" ) ? -1 : 1;
 216+
 217+ if( !isset( $old[$this->index]['timestamp'] ) ) {
 218+ return -1;
 219+ }
 220+ elseif( !isset( $new[$this->index]['timestamp'] ) ) {
 221+ return 1;
 222+ }
 223+ else {
 224+ return $oper * strnatcmp( $old[$this->index]['timestamp'], $new[$this->index]['timestamp'] );
 225+ }
 226+ }
 227+}
\ No newline at end of file
Index: branches/new-checkuser/CheckUser.php
@@ -44,18 +44,22 @@
4545 $wgHooks['ContributionsToolLinks'][] = 'efLoadCheckUserLink';
4646
4747 $wgAutoloadClasses['SpecialCheckUser'] = $dir . 'SpecialCheckUser.php';
 48+$wgAutoloadClasses['SpecialCheckUserLog'] = $dir . 'SpecialCheckUserLog.php';
4849 $wgAutoloadClasses['CheckUserApi'] = $dir . 'CheckUserApi.php';
4950 $wgAutoloadClasses['CheckUserApiLog'] = $dir . 'CheckUserApiLog.php';
5051 $wgAutoloadClasses['CheckUser'] = $dir . 'CheckUser.body.php';
 52+$wgAutoloadClasses['CUTablePagerUser2IP'] = $dir . 'CheckUser.pager.php';
5153
5254 // Set up the new special page
5355 $wgSpecialPages['CheckUser'] = 'SpecialCheckUser';
5456 $wgSpecialPageGroups['CheckUser'] = 'users';
 57+$wgSpecialPages['CheckUserLog'] = 'SpecialCheckUserLog';
 58+$wgSpecialPageGroups['CheckUserLog'] = 'users';
5559
5660 $wgAPIListModules['checkuser'] = 'CheckUserApi';
5761 $wgAPIListModules['checkuserlog'] = 'CheckUserApiLog';
5862
59 -$wgExtensionMessagesFiles['CheckUser'] = $dir . 'CheckUser.i18n.en.php';
 63+$wgExtensionMessagesFiles['CheckUser'] = $wgExtensionMessagesFiles['CheckUser'] = $dir . 'CheckUser.i18n.en.php';
6064 //FIXME: $wgExtensionMessagesFiles['CheckUser'] = $dir . 'CheckUser.i18n.php';
6165 $wgExtensionAliasesFiles['CheckUser'] = $dir . 'CheckUser.alias.php';
6266
Index: branches/new-checkuser/SpecialCheckUser.php
@@ -48,7 +48,7 @@
4949 } elseif ( $wgCheckUserForceSummary && !strlen( $reason ) ) {
5050 $wgOut->addWikiMsg( 'checkuser-noreason' );
5151 } elseif ( $checktype == 'user2ip' ) {
52 - //$this->doUser2IP( $user, $reason, $period );
 52+ $this->doUser2IP( $user, $reason, $period );
5353 } elseif ( $xff && $checktype == 'subipedits' ) {
5454 $this->doIPEditsRequest( $xff, true, $reason, $period );
5555 } elseif ( $checktype == 'subipedits' ) {
@@ -95,7 +95,7 @@
9696 );
9797 }
9898
99 - $form = Xml::openElement( 'form', array( 'name' => 'checkuserform', 'id' => 'checkuserform', 'action' => $action, 'method' => 'post' ) ) .
 99+ $form = Xml::openElement( 'form', array( 'name' => 'checkuserform', 'id' => 'checkuserform', 'action' => $action, 'method' => 'get' ) ) .
100100 Xml::openElement( 'fieldset' ) . Xml::openElement( 'legend' ) . wfMsgHtml( 'checkuser-query' ) . Xml::closeElement( 'legend') .
101101 Xml::openElement( 'table', array( 'border' => 0, 'cellpadding' => 2 ) ) . Xml::openElement( 'tr' ) .
102102 Xml::openElement( 'td' ) . wfMsgHtml( 'checkuser-target' ) . Xml::closeElement( 'td' ) .
@@ -125,6 +125,8 @@
126126 Xml::closeElement( 'tr' ) . Xml::openElement( 'tr' ) .
127127 $this->getPeriodMenu( $period ) .
128128 Xml::closeElement( 'tr' ) . Xml::openElement( 'tr' ) .
 129+ $this->getLimitMenu() .
 130+ Xml::closeElement( 'tr' ) . Xml::openElement( 'tr' ) .
129131 Xml::openElement( 'td' ) .
130132 Xml::submitButton( wfMsg( 'checkuser-check' ), array( 'id' => 'checkusersubmit', 'name' => 'checkusersubmit' ) ) .
131133 Xml::closeElement( 'td' ) . Xml::closeElement( 'tr' ) . Xml::closeElement( 'table' ) . Xml::closeElement( 'fieldset' ) .
@@ -176,6 +178,22 @@
177179 return $s;
178180 }
179181
 182+ protected function getLimitMenu() {
 183+ global $wgRequest;
 184+
 185+ $currLimit = $wgRequest->getVal( 'limit' );
 186+
 187+ $s = '<td>' . wfMsgHtml( 'checkuser-limit' ) . '</td>';
 188+ $s .= '<td>' . Xml::openElement( 'select', array( 'name' => 'limit', 'id' => 'limit', 'style' => 'margin-top:.2em;' ) );
 189+
 190+ foreach( array( 20, 50, 100, 250, 500, 5000 ) as $limit ) {
 191+ $s .= Xml::option( $limit, $limit, $limit == $currLimit );
 192+ }
 193+
 194+ $s .= Xml::closeElement( 'select' ) . "</td>\n";
 195+ return $s;
 196+ }
 197+
180198 /**
181199 * Make a quick JS form for admins to calculate block ranges
182200 */
@@ -210,7 +228,7 @@
211229 'period' => $period
212230 ) );
213231
214 - $pager = new CUTablePager( $result );
 232+ $pager = new CUTablePagerUser2IP( $result );
215233
216234 $output =
217235 $pager->getNavigationBar() .
@@ -234,7 +252,7 @@
235253
236254 }
237255
238 -class CUTablePager extends TablePager {
 256+class CUTablePagerOld extends TablePager {
239257
240258 private $mCUSelectParams;
241259 private $mBlockInfo;
@@ -246,6 +264,8 @@
247265 }
248266
249267 function getQueryInfo() {
 268+ $dbr = new wfGetDB( DB_SLAVE );
 269+
250270 $ret = array(
251271 'tables' => $this->mCUSelectParams[0],
252272 'fields' => $this->mCUSelectParams[1],
@@ -271,7 +291,7 @@
272292 //}
273293
274294 function isFieldSortable( $field ) {
275 - return true;
 295+ return in_array( $field, array( 'cuc_ip', 'first', 'last' ) );
276296 }
277297
278298 function getDefaultSort() {
@@ -281,6 +301,8 @@
282302 function formatValue( $name, $value ) {
283303 global $wgContLang;
284304
 305+ var_dump( $this->mCurrentRow );
 306+
285307 switch( $name ) {
286308 case 'cuc_ip':
287309 $value = '<a href="' .
@@ -399,3 +421,6 @@
400422 }
401423
402424 }
 425+
 426+
 427+
Index: branches/new-checkuser/SpecialCheckUserLog.php
@@ -0,0 +1,246 @@
 2+<?php
 3+
 4+class SpecialCheckUserLog extends SpecialPage {
 5+
 6+ function __construct() {
 7+ global $wgUser;
 8+
 9+ parent::__construct( 'CheckUserLog', 'checkuser-log' );
 10+ }
 11+
 12+ function execute( $subpage ) {
 13+ global $wgRequest, $wgOut, $wgUser, $wgCheckUserForceSummary;
 14+
 15+ wfLoadExtensionMessages( 'CheckUserLog' );
 16+
 17+ $this->setHeaders();
 18+
 19+ if ( !$wgUser->isAllowed( 'checkuser-log' ) ) {
 20+ $wgOut->permissionRequired( 'checkuser-log' );
 21+ return;
 22+ }
 23+
 24+ $this->showLog();
 25+ }
 26+
 27+ protected function showLog() {
 28+ global $wgRequest, $wgOut, $wgUser;
 29+
 30+ $type = $wgRequest->getVal( 'cuSearchType' );
 31+ $target = $wgRequest->getVal( 'cuSearch' );
 32+ $year = $wgRequest->getIntOrNull( 'year' );
 33+ $month = $wgRequest->getIntOrNull( 'month' );
 34+ $error = false;
 35+ $dbr = wfGetDB( DB_SLAVE );
 36+ $searchConds = false;
 37+
 38+ $wgOut->setPageTitle( wfMsg( 'checkuser-log' ) );
 39+
 40+ $wgOut->addHTML( $wgUser->getSkin()->makeKnownLinkObj( $this->getTitle(), wfMsgHtml( 'checkuser-log-return' ) ) );
 41+
 42+ if ( $type === null ) {
 43+ $type = 'target';
 44+ } elseif ( $type == 'initiator' ) {
 45+ $user = User::newFromName( $target );
 46+ if ( !$user || !$user->getID() ) {
 47+ $error = 'checkuser-user-nonexistent';
 48+ } else {
 49+ $searchConds = array( 'cul_user' => $user->getID() );
 50+ }
 51+ } else /* target */ {
 52+ $type = 'target';
 53+ // Is it an IP?
 54+ list( $start, $end ) = IP::parseRange( $target );
 55+ if ( $start !== false ) {
 56+ if ( $start == $end ) {
 57+ $searchConds = array( 'cul_target_hex = ' . $dbr->addQuotes( $start ) . ' OR ' .
 58+ '(cul_range_end >= ' . $dbr->addQuotes( $start ) . ' AND ' .
 59+ 'cul_range_start <= ' . $dbr->addQuotes( $end ) . ')'
 60+ );
 61+ } else {
 62+ $searchConds = array(
 63+ '(cul_target_hex >= ' . $dbr->addQuotes( $start ) . ' AND ' .
 64+ 'cul_target_hex <= ' . $dbr->addQuotes( $end ) . ') OR ' .
 65+ '(cul_range_end >= ' . $dbr->addQuotes( $start ) . ' AND ' .
 66+ 'cul_range_start <= ' . $dbr->addQuotes( $end ) . ')'
 67+ );
 68+ }
 69+ } else {
 70+ // Is it a user?
 71+ $user = User::newFromName( $target );
 72+ if ( $user && $user->getID() ) {
 73+ $searchConds = array(
 74+ 'cul_type' => array( 'userips', 'useredits' ),
 75+ 'cul_target_id' => $user->getID(),
 76+ );
 77+ } elseif ( $target ) {
 78+ $error = 'checkuser-user-nonexistent';
 79+ }
 80+ }
 81+ }
 82+
 83+ $searchTypes = array( 'initiator', 'target' );
 84+ $select = "<select name=\"cuSearchType\" style='margin-top:.2em;'>\n";
 85+ foreach ( $searchTypes as $searchType ) {
 86+ if ( $type == $searchType ) {
 87+ $checked = 'selected="selected"';
 88+ } else {
 89+ $checked = '';
 90+ }
 91+ $caption = wfMsgHtml( 'checkuser-search-' . $searchType );
 92+ $select .= "<option value=\"$searchType\" $checked>$caption</option>\n";
 93+ }
 94+ $select .= '</select>';
 95+
 96+ $encTarget = htmlspecialchars( $target );
 97+ $msgSearch = wfMsgHtml( 'checkuser-search' );
 98+ $input = "<input type=\"text\" name=\"cuSearch\" value=\"$encTarget\" size=\"40\"/>";
 99+ $msgSearchForm = wfMsgHtml( 'checkuser-search-form', $select, $input );
 100+ $formAction = $this->getTitle()->escapeLocalUrl();
 101+ $msgSearchSubmit = '&#160;&#160;' . wfMsgHtml( 'checkuser-search-submit' ) . '&#160;&#160;';
 102+
 103+ $s = "<form method='get' action=\"$formAction\">\n" .
 104+ "<fieldset><legend>$msgSearch</legend>\n" .
 105+ "<p>$msgSearchForm</p>\n" .
 106+ "<p>" . $this->getDateMenu( $year, $month ) . "&#160;&#160;&#160;\n" .
 107+ "<input type=\"submit\" name=\"cuSearchSubmit\" value=\"$msgSearchSubmit\"/></p>\n" .
 108+ "</fieldset></form>\n";
 109+ $wgOut->addHTML( $s );
 110+
 111+ if ( $error !== false ) {
 112+ $wgOut->addWikiText( '<div class="errorbox">' . wfMsg( $error ) . '</div>' );
 113+ return;
 114+ }
 115+
 116+ $pager = new CheckUserLogPager( $this, $searchConds, $year, $month );
 117+ $wgOut->addHTML(
 118+ $pager->getNavigationBar() .
 119+ $pager->getBody() .
 120+ $pager->getNavigationBar()
 121+ );
 122+ }
 123+
 124+ /**
 125+ * @return string Formatted HTML
 126+ * @param int $year
 127+ * @param int $month
 128+ */
 129+ protected function getDateMenu( $year, $month ) {
 130+ # Offset overrides year/month selection
 131+ if ( $month && $month !== - 1 ) {
 132+ $encMonth = intval( $month );
 133+ } else {
 134+ $encMonth = '';
 135+ }
 136+ if ( $year ) {
 137+ $encYear = intval( $year );
 138+ } elseif ( $encMonth ) {
 139+ $thisMonth = intval( gmdate( 'n' ) );
 140+ $thisYear = intval( gmdate( 'Y' ) );
 141+ if ( intval( $encMonth ) > $thisMonth ) {
 142+ $thisYear--;
 143+ }
 144+ $encYear = $thisYear;
 145+ } else {
 146+ $encYear = '';
 147+ }
 148+ return Xml::label( wfMsg( 'year' ), 'year' ) . ' ' .
 149+ Xml::input( 'year', 4, $encYear, array( 'id' => 'year', 'maxlength' => 4 ) ) .
 150+ ' ' .
 151+ Xml::label( wfMsg( 'month' ), 'month' ) . ' ' .
 152+ Xml::monthSelector( $encMonth, - 1 );
 153+ }
 154+
 155+}
 156+
 157+class CheckUserLogPager extends ReverseChronologicalPager {
 158+ var $searchConds, $specialPage, $y, $m;
 159+
 160+ function __construct( $specialPage, $searchConds, $y, $m ) {
 161+ parent::__construct();
 162+ /*
 163+ $this->messages = array_map( 'wfMsg',
 164+ array( 'comma-separator', 'checkuser-log-userips', 'checkuser-log-ipedits', 'checkuser-log-ipusers',
 165+ 'checkuser-log-ipedits-xff', 'checkuser-log-ipusers-xff' ) );*/
 166+
 167+ $this->getDateCond( $y, $m );
 168+ $this->searchConds = $searchConds ? $searchConds : array();
 169+ $this->specialPage = $specialPage;
 170+ }
 171+
 172+ function formatRow( $row ) {
 173+ global $wgLang;
 174+
 175+ $skin = $this->getSkin();
 176+
 177+ if ( $row->cul_reason === '' ) {
 178+ $comment = '';
 179+ } else {
 180+ $comment = $skin->commentBlock( $row->cul_reason );
 181+ }
 182+
 183+ $user = $skin->userLink( $row->cul_user, $row->user_name );
 184+
 185+ if ( $row->cul_type == 'userips' || $row->cul_type == 'useredits' ) {
 186+ $target = $skin->userLink( $row->cul_target_id, $row->cul_target_text ) .
 187+ $skin->userToolLinks( $row->cul_target_id, $row->cul_target_text );
 188+ } else {
 189+ $target = $row->cul_target_text;
 190+ }
 191+
 192+ return '<li>' .
 193+ $wgLang->timeanddate( wfTimestamp( TS_MW, $row->cul_timestamp ), true ) .
 194+ wfMsg( 'comma-separator' ) .
 195+ wfMsg(
 196+ 'checkuser-log-' . $row->cul_type,
 197+ $user,
 198+ $target
 199+ ) .
 200+ $comment .
 201+ '</li>';
 202+ }
 203+
 204+ function getStartBody() {
 205+ if ( $this->getNumRows() ) {
 206+ return '<ul>';
 207+ } else {
 208+ return '';
 209+ }
 210+ }
 211+
 212+ function getEndBody() {
 213+ if ( $this->getNumRows() ) {
 214+ return '</ul>';
 215+ } else {
 216+ return '';
 217+ }
 218+ }
 219+
 220+ function getEmptyBody() {
 221+ return '<p>' . wfMsgHtml( 'checkuser-empty' ) . '</p>';
 222+ }
 223+
 224+ function getQueryInfo() {
 225+ $this->searchConds[] = 'user_id = cul_user';
 226+ return array(
 227+ 'tables' => array( 'cu_log', 'user' ),
 228+ 'fields' => $this->selectFields(),
 229+ 'conds' => $this->searchConds
 230+ );
 231+ }
 232+
 233+ function getIndexField() {
 234+ return 'cul_timestamp';
 235+ }
 236+
 237+ function getTitle() {
 238+ return $this->specialPage->getTitle();
 239+ }
 240+
 241+ function selectFields() {
 242+ return array(
 243+ 'cul_id', 'cul_timestamp', 'cul_user', 'cul_reason', 'cul_type',
 244+ 'cul_target_id', 'cul_target_text', 'user_name'
 245+ );
 246+ }
 247+}

Status & tagging log