X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiQueryDeletedrevs.php;h=2ca93f55ed48a0a1fd066f676158243a5776ff85;hb=63dbc0aba243c7dcaa820220c2cb1aa2cc91eca1;hp=f738c507ccc3e820da886bd29063906999b6cf05;hpb=719d7a2f030994213de3eadde5e20fe54c8159cf;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiQueryDeletedrevs.php b/includes/api/ApiQueryDeletedrevs.php index f738c507cc..2ca93f55ed 100644 --- a/includes/api/ApiQueryDeletedrevs.php +++ b/includes/api/ApiQueryDeletedrevs.php @@ -106,7 +106,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase { } $this->addTables( 'archive' ); - $this->addFields( array( 'ar_title', 'ar_namespace', 'ar_timestamp', 'ar_deleted' ) ); + $this->addFields( array( 'ar_title', 'ar_namespace', 'ar_timestamp', 'ar_deleted', 'ar_id' ) ); $this->addFieldsIf( 'ar_parent_id', $fld_parentid ); $this->addFieldsIf( 'ar_rev_id', $fld_revid ); @@ -214,19 +214,33 @@ class ApiQueryDeletedrevs extends ApiQueryBase { } } - if ( !is_null( $params['continue'] ) && ( $mode == 'all' || $mode == 'revs' ) ) { + if ( !is_null( $params['continue'] ) ) { $cont = explode( '|', $params['continue'] ); - $this->dieContinueUsageIf( count( $cont ) != 3 ); - $ns = intval( $cont[0] ); - $this->dieContinueUsageIf( strval( $ns ) !== $cont[0] ); - $title = $db->addQuotes( $cont[1] ); - $ts = $db->addQuotes( $db->timestamp( $cont[2] ) ); $op = ( $dir == 'newer' ? '>' : '<' ); - $this->addWhere( "ar_namespace $op $ns OR " . - "(ar_namespace = $ns AND " . - "(ar_title $op $title OR " . - "(ar_title = $title AND " . - "ar_timestamp $op= $ts)))" ); + if ( $mode == 'all' || $mode == 'revs' ) { + $this->dieContinueUsageIf( count( $cont ) != 4 ); + $ns = intval( $cont[0] ); + $this->dieContinueUsageIf( strval( $ns ) !== $cont[0] ); + $title = $db->addQuotes( $cont[1] ); + $ts = $db->addQuotes( $db->timestamp( $cont[2] ) ); + $ar_id = (int)$cont[3]; + $this->dieContinueUsageIf( strval( $ar_id ) !== $cont[3] ); + $this->addWhere( "ar_namespace $op $ns OR " . + "(ar_namespace = $ns AND " . + "(ar_title $op $title OR " . + "(ar_title = $title AND " . + "(ar_timestamp $op $ts OR " . + "(ar_timestamp = $ts AND " . + "ar_id $op= $ar_id)))))" ); + } else { + $this->dieContinueUsageIf( count( $cont ) != 2 ); + $ts = $db->addQuotes( $db->timestamp( $cont[0] ) ); + $ar_id = (int)$cont[1]; + $this->dieContinueUsageIf( strval( $ar_id ) !== $cont[1] ); + $this->addWhere( "ar_timestamp $op $ts OR " . + "(ar_timestamp = $ts AND " . + "ar_id $op= $ar_id)" ); + } } $this->addOption( 'LIMIT', $limit + 1 ); @@ -236,12 +250,14 @@ class ApiQueryDeletedrevs extends ApiQueryBase { ); if ( $mode == 'all' ) { if ( $params['unique'] ) { + // @todo Does this work on non-MySQL? $this->addOption( 'GROUP BY', 'ar_title' ); } else { $sort = ( $dir == 'newer' ? '' : ' DESC' ); $this->addOption( 'ORDER BY', array( 'ar_title' . $sort, - 'ar_timestamp' . $sort + 'ar_timestamp' . $sort, + 'ar_id' . $sort, ) ); } } else { @@ -251,6 +267,8 @@ class ApiQueryDeletedrevs extends ApiQueryBase { $this->addWhereRange( 'ar_title', $dir, null, null ); } $this->addTimestampWhereRange( 'ar_timestamp', $dir, $params['start'], $params['end'] ); + // Include in ORDER BY for uniqueness + $this->addWhereRange( 'ar_id', $dir, null, null ); } $res = $this->select( __METHOD__ ); $pageMap = array(); // Maps ns&title to (fake) pageid @@ -260,10 +278,11 @@ class ApiQueryDeletedrevs extends ApiQueryBase { if ( ++$count > $limit ) { // We've had enough if ( $mode == 'all' || $mode == 'revs' ) { - $this->setContinueEnumParameter( 'continue', intval( $row->ar_namespace ) . '|' . - $row->ar_title . '|' . $row->ar_timestamp ); + $this->setContinueEnumParameter( 'continue', + "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id" + ); } else { - $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ar_timestamp ) ); + $this->setContinueEnumParameter( 'continue', "$row->ar_timestamp|$row->ar_id" ); } break; } @@ -371,10 +390,11 @@ class ApiQueryDeletedrevs extends ApiQueryBase { } if ( !$fit ) { if ( $mode == 'all' || $mode == 'revs' ) { - $this->setContinueEnumParameter( 'continue', intval( $row->ar_namespace ) . '|' . - $row->ar_title . '|' . $row->ar_timestamp ); + $this->setContinueEnumParameter( 'continue', + "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id" + ); } else { - $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ar_timestamp ) ); + $this->setContinueEnumParameter( 'continue', "$row->ar_timestamp|$row->ar_id" ); } break; } @@ -468,7 +488,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase { 'namespace' => 'Only list pages in this namespace (3)', 'user' => 'Only list revisions by this user', 'excludeuser' => 'Don\'t list revisions by this user', - 'continue' => 'When more results are available, use this to continue (1, 3)', + 'continue' => 'When more results are available, use this to continue', 'unique' => 'List only one revision for each page (3)', 'tag' => 'Only list revisions tagged with this tag', ); @@ -494,8 +514,8 @@ class ApiQueryDeletedrevs extends ApiQueryBase { 'Operates in three modes:', ' 1) List deleted revisions for the given title(s), sorted by timestamp.', ' 2) List deleted contributions for the given user, sorted by timestamp (no titles specified).', - " 3) List all deleted revisions in the given namespace, sorted by title and timestamp', - ' (no titles specified, {$p}user not set).", + ' 3) List all deleted revisions in the given namespace, sorted by title and timestamp', + " (no titles specified, {$p}user not set).", 'Certain parameters only apply to some modes and are ignored in others.', 'For instance, a parameter marked (1) only applies to mode 1 and is ignored in modes 2 and 3.', );