91 $contentHandlerFactory,
100 $this->revisionStore = $revisionStore;
101 $this->changeTagDefStore = $changeTagDefStore;
102 $this->namespaceInfo = $namespaceInfo;
110 $db = $this->
getDB();
116 if (
$params[
'namespace'] === [] ) {
117 if ( $resultPageSet ===
null ) {
127 if (
$params[
'user'] !==
null ) {
131 if ( $mode ==
'user' ) {
132 foreach ( [
'from',
'to',
'prefix',
'excludeuser' ] as $param ) {
133 if (
$params[$param] !==
null ) {
136 [
'apierror-invalidparammix-cannotusewith', $p . $param,
"{$p}user" ],
142 foreach ( [
'start',
'end' ] as $param ) {
143 if (
$params[$param] !==
null ) {
146 [
'apierror-invalidparammix-mustusewith', $p . $param,
"{$p}user" ],
158 $optimizeGenerateTitles =
false;
159 if ( $mode ===
'all' &&
$params[
'generatetitles'] && $resultPageSet !==
null ) {
160 if ( $dir ===
'newer' ) {
161 $optimizeGenerateTitles =
true;
164 $this->
addWarning( [
'apiwarn-alldeletedrevisions-performance', $p ],
'performance' );
168 if ( $resultPageSet ===
null ) {
170 $arQuery = $this->revisionStore->getArchiveQueryInfo();
174 $this->
addFields( [
'ar_title',
'ar_namespace' ] );
178 $this->
addFields( [
'ar_title',
'ar_namespace' ] );
179 if ( $optimizeGenerateTitles ) {
182 $this->
addFields( [
'ar_timestamp',
'ar_rev_id',
'ar_id' ] );
184 if (
$params[
'user'] !==
null ||
$params[
'excludeuser'] !==
null ) {
186 $this->
addJoinConds( [
'actor' =>
'actor_id=ar_actor' ] );
190 if ( $this->fld_tags ) {
194 if (
$params[
'tag'] !==
null ) {
197 [
'change_tag' => [
'JOIN', [
'ar_rev_id=ct_rev_id' ] ] ]
208 if ( ( $this->fld_comment || $this->fld_parsedcomment ) &&
211 $this->
dieWithError(
'apierror-cantview-deleted-comment',
'permissiondenied' );
213 if ( $this->fetchContent &&
214 !$this->
getAuthority()->isAllowedAny(
'deletedtext',
'undelete' )
216 $this->
dieWithError(
'apierror-cantview-deleted-revision-content',
'permissiondenied' );
221 if ( $mode ==
'all' ) {
222 $namespaces =
$params[
'namespace'] ?? $this->namespaceInfo->getValidNamespaces();
230 $isDirNewer = ( $dir ===
'newer' );
231 $after = ( $isDirNewer ?
'>=' :
'<=' );
232 $before = ( $isDirNewer ?
'<=' :
'>=' );
234 foreach ( $namespaces as $ns ) {
235 if (
$params[
'from'] !==
null ) {
240 if (
$params[
'to'] !==
null ) {
245 $titleParts[$fromTitlePart .
'|' . $toTitlePart][] = $ns;
247 if ( count( $titleParts ) === 1 ) {
248 [ $fromTitlePart, $toTitlePart, ] = explode(
'|', key( $titleParts ), 2 );
249 if ( $fromTitlePart !==
'' ) {
250 $this->
addWhere( $db->expr(
'ar_title', $after, $fromTitlePart ) );
252 if ( $toTitlePart !==
'' ) {
253 $this->
addWhere( $db->expr(
'ar_title', $before, $toTitlePart ) );
257 foreach ( $titleParts as $titlePart => $ns ) {
258 [ $fromTitlePart, $toTitlePart, ] = explode(
'|', $titlePart, 2 );
259 $expr = $db->expr(
'ar_namespace',
'=', $ns );
260 if ( $fromTitlePart !==
'' ) {
261 $expr = $expr->and(
'ar_title', $after, $fromTitlePart );
263 if ( $toTitlePart !==
'' ) {
264 $expr = $expr->and(
'ar_title', $before, $toTitlePart );
268 $this->
addWhere( $db->orExpr( $where ) );
272 if ( isset(
$params[
'prefix'] ) ) {
274 foreach ( $namespaces as $ns ) {
276 $titleParts[$prefixTitlePart][] = $ns;
278 if ( count( $titleParts ) === 1 ) {
279 $prefixTitlePart = key( $titleParts );
280 $this->
addWhere( $db->expr(
'ar_title', IExpression::LIKE,
281 new LikeValue( $prefixTitlePart, $db->anyString() )
285 foreach ( $titleParts as $prefixTitlePart => $ns ) {
286 $where[] = $db->expr(
'ar_namespace',
'=', $ns )
287 ->and(
'ar_title', IExpression::LIKE,
288 new LikeValue( $prefixTitlePart, $db->anyString() ) );
290 $this->
addWhere( $db->orExpr( $where ) );
294 if ( $this->
getConfig()->
get( MainConfigNames::MiserMode ) ) {
295 $miser_ns =
$params[
'namespace'];
302 if (
$params[
'user'] !==
null ) {
308 } elseif (
$params[
'excludeuser'] !==
null ) {
309 $this->
addWhere( $db->expr(
'actor_name',
'!=',
$params[
'excludeuser'] ) );
312 if (
$params[
'user'] !==
null ||
$params[
'excludeuser'] !==
null ) {
314 if ( !$this->
getAuthority()->isAllowed(
'deletedhistory' ) ) {
315 $bitmask = RevisionRecord::DELETED_USER;
316 } elseif ( !$this->
getAuthority()->isAllowedAny(
'suppressrevision',
'viewsuppressed' ) ) {
317 $bitmask = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
322 $this->
addWhere( $db->bitAnd(
'ar_deleted', $bitmask ) .
" != $bitmask" );
326 if (
$params[
'continue'] !==
null ) {
327 $op = ( $dir ==
'newer' ?
'>=' :
'<=' );
328 if ( $optimizeGenerateTitles ) {
330 $this->
addWhere( $db->buildComparison( $op, [
331 'ar_namespace' => $cont[0],
332 'ar_title' => $cont[1],
334 } elseif ( $mode ==
'all' ) {
336 $this->
addWhere( $db->buildComparison( $op, [
337 'ar_namespace' => $cont[0],
338 'ar_title' => $cont[1],
339 'ar_timestamp' => $db->timestamp( $cont[2] ),
344 $this->
addWhere( $db->buildComparison( $op, [
345 'ar_timestamp' => $db->timestamp( $cont[0] ),
351 $this->
addOption(
'LIMIT', $this->limit + 1 );
353 $sort = ( $dir ==
'newer' ?
'' :
' DESC' );
355 if ( $optimizeGenerateTitles ) {
357 if (
$params[
'namespace'] ===
null || count( array_unique(
$params[
'namespace'] ) ) > 1 ) {
358 $orderby[] =
"ar_namespace $sort";
360 $orderby[] =
"ar_title $sort";
361 } elseif ( $mode ==
'all' ) {
363 if (
$params[
'namespace'] ===
null || count( array_unique(
$params[
'namespace'] ) ) > 1 ) {
364 $orderby[] =
"ar_namespace $sort";
366 $orderby[] =
"ar_title $sort";
367 $orderby[] =
"ar_timestamp $sort";
368 $orderby[] =
"ar_id $sort";
372 $orderby[] =
"ar_timestamp $sort";
373 $orderby[] =
"ar_id $sort";
375 $this->
addOption(
'ORDER BY', $orderby );
377 $res = $this->
select( __METHOD__ );
379 if ( $resultPageSet ===
null ) {
387 foreach ( $res as $row ) {
388 if ( ++$count > $this->limit ) {
390 if ( $optimizeGenerateTitles ) {
392 } elseif ( $mode ==
'all' ) {
394 "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id"
403 if ( $miser_ns !==
null && !in_array( $row->ar_namespace, $miser_ns ) ) {
407 if ( $resultPageSet !==
null ) {
408 if (
$params[
'generatetitles'] ) {
409 $key =
"{$row->ar_namespace}:{$row->ar_title}";
410 if ( !isset( $generated[$key] ) ) {
411 $generated[$key] = Title::makeTitle( $row->ar_namespace, $row->ar_title );
414 $generated[] = $row->ar_rev_id;
417 $revision = $this->revisionStore->newRevisionFromArchiveRow( $row );
420 if ( !isset( $pageMap[$row->ar_namespace][$row->ar_title] ) ) {
421 $index = $nextIndex++;
422 $pageMap[$row->ar_namespace][$row->ar_title] = $index;
423 $title = Title::newFromLinkTarget( $revision->getPageAsLinkTarget() );
425 'pageid' => $title->getArticleID(),
426 'revisions' => [ $rev ],
428 ApiResult::setIndexedTagName( $a[
'revisions'],
'rev' );
430 $fit = $result->addValue( [
'query', $this->
getModuleName() ], $index, $a );
432 $index = $pageMap[$row->ar_namespace][$row->ar_title];
433 $fit = $result->addValue(
438 if ( $mode ==
'all' ) {
440 "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id"
450 if ( $resultPageSet !==
null ) {
451 if (
$params[
'generatetitles'] ) {
452 $resultPageSet->populateFromTitles( $generated );
454 $resultPageSet->populateFromRevisionIDs( $generated );
457 $result->addIndexedTagName( [
'query', $this->
getModuleName() ],
'page' );
462 $ret = parent::getAllowedParams() + [
464 ParamValidator::PARAM_TYPE =>
'user',
465 UserDef::PARAM_ALLOWED_USER_TYPES => [
'name',
'ip',
'temp',
'id',
'interwiki' ],
468 ParamValidator::PARAM_ISMULTI =>
true,
469 ParamValidator::PARAM_TYPE =>
'namespace',
472 ParamValidator::PARAM_TYPE =>
'timestamp',
476 ParamValidator::PARAM_TYPE =>
'timestamp',
480 ParamValidator::PARAM_TYPE => [
484 ParamValidator::PARAM_DEFAULT =>
'older',
487 'newer' =>
'api-help-paramvalue-direction-newer',
488 'older' =>
'api-help-paramvalue-direction-older',
501 ParamValidator::PARAM_TYPE =>
'user',
502 UserDef::PARAM_ALLOWED_USER_TYPES => [
'name',
'ip',
'temp',
'id',
'interwiki' ],
509 'generatetitles' => [
510 ParamValidator::PARAM_DEFAULT => false
514 if ( $this->
getConfig()->
get( MainConfigNames::MiserMode ) ) {
516 'apihelp-query+alldeletedrevisions-param-miser-user-namespace',
519 'apihelp-query+alldeletedrevisions-param-miser-user-namespace',
528 'action=query&list=alldeletedrevisions&adruser=Example&adrlimit=50'
529 =>
'apihelp-query+alldeletedrevisions-example-user',
530 'action=query&list=alldeletedrevisions&adrdir=newer&adrnamespace=0&adrlimit=50'
531 =>
'apihelp-query+alldeletedrevisions-example-ns-main',
536 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Alldeletedrevisions';
array $params
The job parameters.
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
getParameter( $paramName, $parseLimit=true)
Get a value for the given parameter.
const PARAM_HELP_MSG_INFO
(array) Specify additional information tags for the parameter.
const PARAM_HELP_MSG_APPEND
((string|array|Message)[]) Specify additional i18n messages to append to the normal message for this ...
parseContinueParamOrDie(string $continue, array $types)
Parse the 'continue' parameter in the usual format and validate the types of each part,...
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, or 'string' with PARAM_ISMULTI,...
getResult()
Get the result object.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
getModuleName()
Get the name of the module being executed by this instance.
This class contains a list of pages that the client has requested.
Query module to enumerate all deleted revisions.
getExamplesMessages()
Returns usage examples for this module.
getHelpUrls()
Return links to more detailed help pages about the module.
__construct(ApiQuery $query, $moduleName, RevisionStore $revisionStore, IContentHandlerFactory $contentHandlerFactory, ParserFactory $parserFactory, SlotRoleRegistry $slotRoleRegistry, NameTableStore $changeTagDefStore, NamespaceInfo $namespaceInfo, ContentRenderer $contentRenderer, ContentTransformer $contentTransformer, CommentFormatter $commentFormatter, TempUserCreator $tempUserCreator, UserFactory $userFactory)
run(ApiPageSet $resultPageSet=null)
static addTitleInfo(&$arr, $title, $prefix='')
Add information (title and namespace) about a Title object to a result array.
addFields( $value)
Add a set of fields to select to the internal array.
addOption( $name, $value=null)
Add an option such as LIMIT or USE INDEX.
addTables( $tables, $alias=null)
Add a set of tables to the internal array.
addTimestampWhereRange( $field, $dir, $start, $end, $sort=true)
Add a WHERE clause corresponding to a range, similar to addWhereRange, but converts $start and $end t...
getDB()
Get the Query database connection (read-only)
executeGenderCacheFromResultWrapper(IResultWrapper $res, $fname=__METHOD__, $fieldPrefix='page')
Preprocess the result set to fill the GenderCache with the necessary information before using self::a...
select( $method, $extraQuery=[], array &$hookData=null)
Execute a SELECT query based on the values in the internal arrays.
addJoinConds( $join_conds)
Add a set of JOIN conditions to the internal array.
addWhereFld( $field, $value)
Equivalent to addWhere( [ $field => $value ] )
titlePartToKey( $titlePart, $namespace=NS_MAIN)
Convert an input title or title prefix into a dbkey.
addWhere( $value)
Add a set of WHERE clauses to the internal array.
setContinueEnumParameter( $paramName, $paramValue)
Overridden to set the generator param if in generator mode.
A base class for functions common to producing a list of revisions.
parseParameters( $params)
Parse the parameters into the various instance fields.
extractRevisionInfo(RevisionRecord $revision, $row)
Extract information from the RevisionRecord.
This is the main query class.
A service to render content.
A service to transform content.
A class containing constants representing the names of configuration variables.