diff -c /var/mw-trunk/source/checkuser/CheckUser_body.php /var/mw-trunk/modified/checkuser/CheckUser_body.php *** /var/mw-trunk/source/checkuser/CheckUser_body.php 2011-10-12 02:16:37.000000000 +0400 --- /var/mw-trunk/modified/checkuser/CheckUser_body.php 2011-10-15 03:10:25.000000000 +0400 *************** *** 21,27 **** } public function execute( $subpage ) { ! global $wgRequest, $wgOut, $wgUser, $wgContLang; $this->setHeaders(); --- 21,27 ---- } public function execute( $subpage ) { ! global $wgRequest, $wgOut, $wgUser, $wgContLang, $wgCheckUserCheckUserAgents; $this->setHeaders(); *************** *** 107,112 **** --- 107,114 ---- $this->doIPUsersRequest( $xff, true, $reason, $period, $tag, $talkTag ); } elseif ( $checktype == 'subipusers' ) { $this->doIPUsersRequest( $ip, false, $reason, $period, $tag, $talkTag ); + } elseif ( $wgCheckUserCheckUserAgents && $checktype == 'subagents' ) { + $this->doAgentUsersRequest( $name, $reason, $period, $tag, $talkTag ); } } # Add CIDR calculation convenience form *************** *** 146,161 **** } protected function showForm( $user, $reason, $checktype, $ip, $xff, $name, $period ) { ! global $wgOut, $wgUser; $action = $this->getTitle()->escapeLocalUrl(); # Fill in requested type if it makes sense ! $encipusers = $encedits = $encuserips = 0; if ( $checktype == 'subipusers' && ( $ip || $xff ) ) { $encipusers = 1; } elseif ( $checktype == 'subuserips' && $name ) { $encuserips = 1; } elseif ( $checktype == 'subedits' ) { $encedits = 1; # Defaults otherwise } elseif ( $ip || $xff ) { $encedits = 1; --- 148,165 ---- } protected function showForm( $user, $reason, $checktype, $ip, $xff, $name, $period ) { ! global $wgOut, $wgUser, $wgCheckUserCheckUserAgents; $action = $this->getTitle()->escapeLocalUrl(); # Fill in requested type if it makes sense ! $encipusers = $encedits = $encagents = $encuserips = 0; if ( $checktype == 'subipusers' && ( $ip || $xff ) ) { $encipusers = 1; } elseif ( $checktype == 'subuserips' && $name ) { $encuserips = 1; } elseif ( $checktype == 'subedits' ) { $encedits = 1; + } elseif ( $checktype == 'subagents' ) { + $encagents = 1; # Defaults otherwise } elseif ( $ip || $xff ) { $encedits = 1; *************** *** 188,193 **** --- 192,204 ---- $form .= '' . Xml::radio( 'checktype', 'subipusers', $encipusers, array( 'id' => 'subipusers' ) ); $form .= ' ' . Xml::label( wfMsg( 'checkuser-users' ), 'subipusers' ) . ''; + + if( $wgCheckUserCheckUserAgents ) { + $form .= '' . + Xml::radio( 'checktype', 'subagents', $encagents, array( 'id' => 'subagents' ) ); + $form .= ' ' . Xml::label( wfMsg( 'checkuser-agents' ), 'subagents' ) . ''; + } + $form .= ''; $form .= Xml::closeElement( 'table' ); $form .= Xml::closeElement( 'td' ); *************** *** 1058,1063 **** --- 1069,1266 ---- for ( $i = ( count( $users_agentsets[$name] ) - 1 ); $i >= 0; $i-- ) { $agent = $users_agentsets[$name][$i]; $s .= '
  • ' . htmlspecialchars( $agent ) . "
  • \n"; + } + $s .= ''; + $s .= ''; + } + $s .= "\n"; + if ( $wgUser->isAllowed( 'block' ) && !$wgUser->isBlocked() ) { + $s .= "
    \n"; + $s .= '' . wfMsgHtml( 'checkuser-massblock' ) . "\n"; + $s .= '

    ' . wfMsgExt( 'checkuser-massblock-text', array( 'parseinline' ) ) . "

    \n"; + $s .= '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '
    ' . Xml::check( 'usetag', false, array( 'id' => 'usetag' ) ) . '' . Xml::label( wfMsgHtml( 'checkuser-blocktag' ), 'usetag' ) . '' . Xml::input( 'tag', 46, $tag, array( 'id' => 'blocktag' ) ) . '
    ' . Xml::check( 'usettag', false, array( 'id' => 'usettag' ) ) . '' . Xml::label( wfMsgHtml( 'checkuser-blocktag-talk' ), 'usettag' ) . '' . Xml::input( 'talktag', 46, $talkTag, array( 'id' => 'talktag' ) ) . '
    '; + $s .= '

    ' . wfMsgHtml( 'checkuser-reason' ) . ' '; + $s .= Xml::input( 'blockreason', 46, '', array( 'maxlength' => '150', 'id' => 'blockreason' ) ); + $s .= ' ' . Xml::submitButton( wfMsgHtml( 'checkuser-massblock-commit' ), + array( 'id' => 'checkuserblocksubmit', 'name' => 'checkuserblock' ) ) . "

    \n"; + $s .= "
    \n"; + } + $s .= ''; + } + + $wgOut->addHTML( $s ); + } + + protected function doAgentUsersRequest( $agent, $reason = '', $period = 0, $tag = '', $talkTag = '' ) { + global $wgUser, $wgOut, $wgLang, $wgCheckUserCheckUserAgents, $wgCheckUserCheckUserAgentsStrict; + if( !$wgCheckUserCheckUserAgents ) return false; + + $dbr = wfGetDB( DB_SLAVE ); + + if( empty($agent) ) return false; + + $logType = 'agentusers'; + + if ( !$this->addLogEntry( $logType, 'agent', $agent, $reason ) ) { + $wgOut->addHTML( '

    ' . wfMsgHtml( 'checkuser-log-fail' ) . '

    ' ); + } + + $time_conds = $this->getTimeConds( $period ); + + $esc = mysql_real_escape_string($agent); + if( $wgCheckUserCheckUserAgentsStrict ) { + $agent_cond = "cuc_agent = '$esc'"; + } else { + $agent = preg_replace("/\*/", "%", $esc); + $agent_cond = "cuc_agent LIKE '$agent'"; + } + + $cu_changes = $dbr->tableName( 'cu_changes' ); + + if ( $period ) { + $count = $dbr->selectField( 'cu_changes', 'COUNT(*)', + array( $agent_cond, $time_conds ), + __METHOD__, + array( 'USE INDEX' => 'cuc_user_ip_time' ) ); + } else { + $count = $dbr->estimateRowCount( 'cu_changes', '*', + array( $agent_cond, $time_conds ), + __METHOD__, + array( 'USE INDEX' => 'cuc_user_ip_time' ) ); + } + + wfSuppressWarnings(); + set_time_limit( 120 ); + wfRestoreWarnings(); + + if ( isset( $count ) && $count > 5000 ) { + $wgOut->addHTML( wfMsgExt( 'checkuser-limited', array( 'parse' ) ) ); + } + + global $wgMemc; + + $use_index = $dbr->useIndexClause( 'cuc_user_ip_time' ); + $sql = "SELECT cuc_user_text, cuc_timestamp, cuc_user, cuc_ip, cuc_agent, cuc_xff + FROM $cu_changes $use_index WHERE $agent_cond AND $time_conds + ORDER BY cuc_timestamp DESC LIMIT 5000"; + $ret = $dbr->query( $sql, __METHOD__ ); + + $users_first = $users_last = $users_edits = $users_ids = array(); + if ( !$dbr->numRows( $ret ) ) { + $s = $this->noMatchesMessage( $ip, !$xfor ) . "\n"; + } else { + global $wgAuth; + while ( ( $row = $dbr->fetchObject( $ret ) ) != false ) { + if ( !array_key_exists( $row->cuc_user_text, $users_edits ) ) { + $users_last[$row->cuc_user_text] = $row->cuc_timestamp; + $users_edits[$row->cuc_user_text] = 0; + $users_ids[$row->cuc_user_text] = $row->cuc_user; + $users_infosets[$row->cuc_user_text] = array(); + $users_agentsets[$row->cuc_user_text] = array(); + } + $users_edits[$row->cuc_user_text] += 1; + $users_first[$row->cuc_user_text] = $row->cuc_timestamp; + + $xff = empty( $row->cuc_xff ) ? null : $row->cuc_xff; + $xff_ip_combo = array( $row->cuc_ip, $xff ); + + if ( !in_array( $xff_ip_combo, $users_infosets[$row->cuc_user_text] ) ) { + $users_infosets[$row->cuc_user_text][] = $xff_ip_combo; + } + + if ( count( $users_agentsets[$row->cuc_user_text] ) < 20 ) { + if ( !in_array( $row->cuc_agent, $users_agentsets[$row->cuc_user_text] ) ) { + $users_agentsets[$row->cuc_user_text][] = $row->cuc_agent; + } + } + } + $dbr->freeResult( $ret ); + + $action = $this->getTitle()->escapeLocalURL( 'action=block' ); + $s = "
    "; + $s .= '