}
function getQueryInfo() {
- list( $tables, $index, $userCond, $join_cond ) = $this->getUserCond();
-
- $user = $this->getUser();
- $conds = array_merge( $userCond, $this->getNamespaceCond() );
-
- // Paranoia: avoid brute force searches (T19342)
- if ( !$user->isAllowed( 'deletedhistory' ) ) {
- $conds[] = $this->mDb->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0';
- } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
- $conds[] = $this->mDb->bitAnd( 'rev_deleted', Revision::SUPPRESSED_USER ) .
- ' != ' . Revision::SUPPRESSED_USER;
- }
-
- # Don't include orphaned revisions
- $join_cond['page'] = Revision::pageJoinCond();
- # Get the current user name for accounts
- $join_cond['user'] = Revision::userJoinCond();
-
- $options = [];
- if ( $index ) {
- $options['USE INDEX'] = [ 'revision' => $index ];
- }
-
+ $revQuery = Revision::getQueryInfo( [ 'page', 'user' ] );
$queryInfo = [
- 'tables' => $tables,
- 'fields' => array_merge(
- Revision::selectFields(),
- Revision::selectUserFields(),
- [ 'page_namespace', 'page_title', 'page_is_new',
- 'page_latest', 'page_is_redirect', 'page_len' ]
- ),
- 'conds' => $conds,
- 'options' => $options,
- 'join_conds' => $join_cond
+ 'tables' => $revQuery['tables'],
+ 'fields' => array_merge( $revQuery['fields'], [ 'page_is_new' ] ),
+ 'conds' => [],
+ 'options' => [],
+ 'join_conds' => $revQuery['joins'],
];
- // For IPv6, we use ipc_rev_timestamp on ip_changes as the index field,
- // which will be referenced when parsing the results of a query.
- if ( self::isQueryableRange( $this->target ) ) {
- $queryInfo['fields'][] = 'ipc_rev_timestamp';
- }
-
- ChangeTags::modifyDisplayQuery(
- $queryInfo['tables'],
- $queryInfo['fields'],
- $queryInfo['conds'],
- $queryInfo['join_conds'],
- $queryInfo['options'],
- $this->tagFilter
- );
-
- // Avoid PHP 7.1 warning from passing $this by reference
- $pager = $this;
- Hooks::run( 'ContribsPager::getQueryInfo', [ &$pager, &$queryInfo ] );
-
- return $queryInfo;
- }
-
- function getUserCond() {
- $condition = [];
- $join_conds = [];
- $tables = [ 'revision', 'page', 'user' ];
- $index = false;
if ( $this->contribs == 'newbie' ) {
$max = $this->mDb->selectField( 'user', 'max(user_id)', false, __METHOD__ );
- $condition[] = 'rev_user >' . (int)( $max - $max / 100 );
+ $queryInfo['conds'][] = 'rev_user >' . (int)( $max - $max / 100 );
# ignore local groups with the bot right
# @todo FIXME: Global groups may have 'bot' rights
$groupsWithBotPermission = User::getGroupsWithPermission( 'bot' );
if ( count( $groupsWithBotPermission ) ) {
- $tables[] = 'user_groups';
- $condition[] = 'ug_group IS NULL';
- $join_conds['user_groups'] = [
+ $queryInfo['tables'][] = 'user_groups';
+ $queryInfo['conds'][] = 'ug_group IS NULL';
+ $queryInfo['join_conds']['user_groups'] = [
'LEFT JOIN', [
'ug_user = rev_user',
'ug_group' => $groupsWithBotPermission,
// (T140537) Disallow looking too far in the past for 'newbies' queries. If the user requested
// a timestamp offset far in the past such that there are no edits by users with user_ids in
// the range, we would end up scanning all revisions from that offset until start of time.
- $condition[] = 'rev_timestamp > ' .
+ $queryInfo['conds'][] = 'rev_timestamp > ' .
$this->mDb->addQuotes( $this->mDb->timestamp( wfTimestamp() - 30 * 24 * 60 * 60 ) );
} else {
$uid = User::idFromName( $this->target );
if ( $uid ) {
- $condition['rev_user'] = $uid;
- $index = 'user_timestamp';
+ $queryInfo['conds']['rev_user'] = $uid;
+ $queryInfo['options']['USE INDEX']['revision'] = 'user_timestamp';
} else {
$ipRangeConds = $this->getIpRangeConds( $this->mDb, $this->target );
if ( $ipRangeConds ) {
- $tables[] = 'ip_changes';
- $join_conds['ip_changes'] = [
+ $queryInfo['tables'][] = 'ip_changes';
+ $queryInfo['join_conds']['ip_changes'] = [
'LEFT JOIN', [ 'ipc_rev_id = rev_id' ]
];
- $condition[] = $ipRangeConds;
+ $queryInfo['conds'][] = $ipRangeConds;
} else {
- $condition['rev_user_text'] = $this->target;
- $index = 'usertext_timestamp';
+ $queryInfo['conds']['rev_user_text'] = $this->target;
+ $queryInfo['options']['USE INDEX']['revision'] = 'usertext_timestamp';
}
}
}
if ( $this->deletedOnly ) {
- $condition[] = 'rev_deleted != 0';
+ $queryInfo['conds'][] = 'rev_deleted != 0';
}
if ( $this->topOnly ) {
- $condition[] = 'rev_id = page_latest';
+ $queryInfo['conds'][] = 'rev_id = page_latest';
}
if ( $this->newOnly ) {
- $condition[] = 'rev_parent_id = 0';
+ $queryInfo['conds'][] = 'rev_parent_id = 0';
}
if ( $this->hideMinor ) {
- $condition[] = 'rev_minor_edit = 0';
+ $queryInfo['conds'][] = 'rev_minor_edit = 0';
+ }
+
+ $user = $this->getUser();
+ $queryInfo['conds'] = array_merge( $queryInfo['conds'], $this->getNamespaceCond() );
+
+ // Paranoia: avoid brute force searches (T19342)
+ if ( !$user->isAllowed( 'deletedhistory' ) ) {
+ $queryInfo['conds'][] = $this->mDb->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0';
+ } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
+ $queryInfo['conds'][] = $this->mDb->bitAnd( 'rev_deleted', Revision::SUPPRESSED_USER ) .
+ ' != ' . Revision::SUPPRESSED_USER;
+ }
+
+ // For IPv6, we use ipc_rev_timestamp on ip_changes as the index field,
+ // which will be referenced when parsing the results of a query.
+ if ( self::isQueryableRange( $this->target ) ) {
+ $queryInfo['fields'][] = 'ipc_rev_timestamp';
}
- return [ $tables, $index, $condition, $join_conds ];
+ ChangeTags::modifyDisplayQuery(
+ $queryInfo['tables'],
+ $queryInfo['fields'],
+ $queryInfo['conds'],
+ $queryInfo['join_conds'],
+ $queryInfo['options'],
+ $this->tagFilter
+ );
+
+ // Avoid PHP 7.1 warning from passing $this by reference
+ $pager = $this;
+ Hooks::run( 'ContribsPager::getQueryInfo', [ &$pager, &$queryInfo ] );
+
+ return $queryInfo;
}
function getNamespaceCond() {
* @return string Name of field
*/
public function getIndexField() {
- if ( self::isQueryableRange( $this->target ) ) {
+ if ( $this->isQueryableRange( $this->target ) ) {
return 'ipc_rev_timestamp';
} else {
return 'rev_timestamp';
$parentRevIds = [];
$this->mParentLens = [];
$batch = new LinkBatch();
+ $isIpRange = $this->isQueryableRange( $this->target );
# Give some pointers to make (last) links
foreach ( $this->mResult as $row ) {
if ( isset( $row->rev_parent_id ) && $row->rev_parent_id ) {
if ( $this->contribs === 'newbie' ) { // multiple users
$batch->add( NS_USER, $row->user_name );
$batch->add( NS_USER_TALK, $row->user_name );
+ } elseif ( $isIpRange ) {
+ // If this is an IP range, batch the IP's talk page
+ $batch->add( NS_USER_TALK, $row->rev_user_text );
}
$batch->add( $row->page_namespace, $row->page_title );
}
# When querying for an IP range, we want to always show user and user talk links.
$userlink = '';
if ( ( $this->contribs == 'newbie' && !$rev->isDeleted( Revision::DELETED_USER ) )
- || self::isQueryableRange( $this->target ) ) {
+ || $this->isQueryableRange( $this->target ) ) {
$userlink = ' . . ' . $lang->getDirMark()
. Linker::userLink( $rev->getUser(), $rev->getUserText() );
$userlink .= ' ' . $this->msg( 'parentheses' )->rawParams(