X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiQueryDeletedrevs.php;h=8540190f1edbc1c6b5d9d21e0e4dc9c25a1c5ea1;hb=4ec93f15d6146d5881c7754ce7d3202d758b326d;hp=b68a8682c580c67bd037fc96f2ec0b2c02cb877a;hpb=dae4c94d893057345f62a3d498fb85c0a54de5a6;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiQueryDeletedrevs.php b/includes/api/ApiQueryDeletedrevs.php index b68a8682c5..8540190f1e 100644 --- a/includes/api/ApiQueryDeletedrevs.php +++ b/includes/api/ApiQueryDeletedrevs.php @@ -1,9 +1,5 @@ .@gmail.com" * * This program is free software; you can redistribute it and/or modify @@ -24,6 +20,9 @@ * @file */ +use MediaWiki\MediaWikiServices; +use MediaWiki\Storage\NameTableAccessException; + /** * Query module to enumerate all deleted revisions. * @@ -44,6 +43,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase { $user = $this->getUser(); $db = $this->getDB(); + $commentStore = CommentStore::getStore(); $params = $this->extractRequestParams( false ); $prop = array_flip( $params['prop'] ); $fld_parentid = isset( $prop['parentid'] ); @@ -113,19 +113,25 @@ class ApiQueryDeletedrevs extends ApiQueryBase { $this->addFieldsIf( 'ar_parent_id', $fld_parentid ); $this->addFieldsIf( 'ar_rev_id', $fld_revid ); - $this->addFieldsIf( 'ar_user_text', $fld_user ); - $this->addFieldsIf( 'ar_user', $fld_userid ); - $this->addFieldsIf( 'ar_comment', $fld_comment || $fld_parsedcomment ); + if ( $fld_user || $fld_userid ) { + $actorQuery = ActorMigration::newMigration()->getJoin( 'ar_user' ); + $this->addTables( $actorQuery['tables'] ); + $this->addFields( $actorQuery['fields'] ); + $this->addJoinConds( $actorQuery['joins'] ); + } $this->addFieldsIf( 'ar_minor_edit', $fld_minor ); $this->addFieldsIf( 'ar_len', $fld_len ); $this->addFieldsIf( 'ar_sha1', $fld_sha1 ); + if ( $fld_comment || $fld_parsedcomment ) { + $commentQuery = $commentStore->getJoin( 'ar_comment' ); + $this->addTables( $commentQuery['tables'] ); + $this->addFields( $commentQuery['fields'] ); + $this->addJoinConds( $commentQuery['joins'] ); + } + if ( $fld_tags ) { - $this->addTables( 'tag_summary' ); - $this->addJoinConds( - [ 'tag_summary' => [ 'LEFT JOIN', [ 'ar_rev_id=ts_rev_id' ] ] ] - ); - $this->addFields( 'ts_tags' ); + $this->addFields( [ 'ts_tags' => ChangeTags::makeTagSummarySubquery( 'archive' ) ] ); } if ( !is_null( $params['tag'] ) ) { @@ -133,21 +139,21 @@ class ApiQueryDeletedrevs extends ApiQueryBase { $this->addJoinConds( [ 'change_tag' => [ 'INNER JOIN', [ 'ar_rev_id=ct_rev_id' ] ] ] ); - $this->addWhereFld( 'ct_tag', $params['tag'] ); + $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore(); + try { + $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) ); + } catch ( NameTableAccessException $exception ) { + // Return nothing. + $this->addWhere( '1=0' ); + } } if ( $fld_content ) { - // Modern MediaWiki has the content for deleted revs in the 'text' - // table using fields old_text and old_flags. But revisions deleted - // pre-1.5 store the content in the 'archive' table directly using - // fields ar_text and ar_flags, and no corresponding 'text' row. So - // we have to LEFT JOIN and fetch all four fields, plus ar_text_id - // to be able to tell the difference. $this->addTables( 'text' ); $this->addJoinConds( [ 'text' => [ 'LEFT JOIN', [ 'ar_text_id=old_id' ] ] ] ); - $this->addFields( [ 'ar_text', 'ar_flags', 'ar_text_id', 'old_text', 'old_flags' ] ); + $this->addFields( [ 'ar_text_id', 'old_text', 'old_flags' ] ); // This also means stricter restrictions $this->checkUserRightsAny( [ 'deletedtext', 'undelete' ] ); @@ -196,10 +202,19 @@ class ApiQueryDeletedrevs extends ApiQueryBase { } if ( !is_null( $params['user'] ) ) { - $this->addWhereFld( 'ar_user_text', $params['user'] ); + // Don't query by user ID here, it might be able to use the ar_usertext_timestamp index. + $actorQuery = ActorMigration::newMigration() + ->getWhere( $db, 'ar_user', User::newFromName( $params['user'], false ), false ); + $this->addTables( $actorQuery['tables'] ); + $this->addJoinConds( $actorQuery['joins'] ); + $this->addWhere( $actorQuery['conds'] ); } elseif ( !is_null( $params['excludeuser'] ) ) { - $this->addWhere( 'ar_user_text != ' . - $db->addQuotes( $params['excludeuser'] ) ); + // Here there's no chance of using ar_usertext_timestamp. + $actorQuery = ActorMigration::newMigration() + ->getWhere( $db, 'ar_user', User::newFromName( $params['excludeuser'], false ) ); + $this->addTables( $actorQuery['tables'] ); + $this->addJoinConds( $actorQuery['joins'] ); + $this->addWhere( 'NOT(' . $actorQuery['conds'] . ')' ); } if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) { @@ -248,10 +263,6 @@ class ApiQueryDeletedrevs extends ApiQueryBase { } $this->addOption( 'LIMIT', $limit + 1 ); - $this->addOption( - 'USE INDEX', - [ 'archive' => ( $mode == 'user' ? 'ar_usertext_timestamp' : 'name_title_timestamp' ) ] - ); if ( $mode == 'all' ) { if ( $params['unique'] ) { // @todo Does this work on non-MySQL? @@ -322,12 +333,13 @@ class ApiQueryDeletedrevs extends ApiQueryBase { $anyHidden = true; } if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_COMMENT, $user ) ) { + $comment = $commentStore->getComment( 'ar_comment', $row )->text; if ( $fld_comment ) { - $rev['comment'] = $row->ar_comment; + $rev['comment'] = $comment; } if ( $fld_parsedcomment ) { $title = Title::makeTitle( $row->ar_namespace, $row->ar_title ); - $rev['parsedcomment'] = Linker::formatComment( $row->ar_comment, $title ); + $rev['parsedcomment'] = Linker::formatComment( $comment, $title ); } } } @@ -357,12 +369,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase { $anyHidden = true; } if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_TEXT, $user ) ) { - if ( isset( $row->ar_text ) && !$row->ar_text_id ) { - // Pre-1.5 ar_text row (if condition from Revision::newFromArchiveRow) - ApiResult::setContentValue( $rev, 'text', Revision::getRevisionText( $row, 'ar_' ) ); - } else { - ApiResult::setContentValue( $rev, 'text', Revision::getRevisionText( $row ) ); - } + ApiResult::setContentValue( $rev, 'text', Revision::getRevisionText( $row ) ); } }