43 parent::__construct( $query, $moduleName,
'wl' );
51 $this->
run( $resultPageSet );
67 private function run( $resultPageSet =
null ) {
75 if ( $params[
'prop'] !==
null && $resultPageSet ===
null ) {
76 $prop = array_flip( $params[
'prop'] );
78 $this->fld_ids = isset( $prop[
'ids'] );
79 $this->fld_title = isset( $prop[
'title'] );
80 $this->fld_flags = isset( $prop[
'flags'] );
81 $this->fld_user = isset( $prop[
'user'] );
82 $this->fld_userid = isset( $prop[
'userid'] );
83 $this->fld_comment = isset( $prop[
'comment'] );
84 $this->fld_parsedcomment = isset( $prop[
'parsedcomment'] );
85 $this->fld_timestamp = isset( $prop[
'timestamp'] );
86 $this->fld_sizes = isset( $prop[
'sizes'] );
87 $this->fld_patrol = isset( $prop[
'patrol'] );
88 $this->fld_notificationtimestamp = isset( $prop[
'notificationtimestamp'] );
89 $this->fld_loginfo = isset( $prop[
'loginfo'] );
90 $this->fld_tags = isset( $prop[
'tags'] );
91 $this->fld_expiry = isset( $prop[
'expiry'] );
93 if ( $this->fld_patrol && !$user->useRCPatrol() && !$user->useNPPatrol() ) {
94 $this->
dieWithError(
'apierror-permissiondenied-patrolflag',
'patrol' );
97 if ( $this->fld_comment || $this->fld_parsedcomment ) {
103 'dir' => $params[
'dir'] ===
'older'
108 if ( $resultPageSet ===
null ) {
111 $options[
'usedInGenerator'] =
true;
114 if ( $params[
'start'] ) {
115 $options[
'start'] = $params[
'start'];
117 if ( $params[
'end'] ) {
118 $options[
'end'] = $params[
'end'];
122 if ( $params[
'continue'] !==
null ) {
123 $cont = explode(
'|', $params[
'continue'] );
125 $continueTimestamp = $cont[0];
126 $continueId = (int)$cont[1];
128 $startFrom = [ $continueTimestamp, $continueId ];
131 if ( $wlowner !== $user ) {
132 $options[
'watchlistOwner'] = $wlowner;
133 $options[
'watchlistOwnerToken'] = $params[
'token'];
136 if ( $params[
'namespace'] !==
null ) {
137 $options[
'namespaceIds'] = $params[
'namespace'];
140 if ( $params[
'allrev'] ) {
141 $options[
'allRevisions'] =
true;
144 if ( $params[
'show'] !==
null ) {
145 $show = array_flip( $params[
'show'] );
156 if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
157 $this->
dieWithError(
'apierror-permissiondenied-patrolflag',
'permissiondenied' );
161 $options[
'filters'] = array_keys( $show );
164 if ( $params[
'type'] !==
null ) {
168 $options[
'rcTypes'] = $rcTypes;
170 }
catch ( Exception $e ) {
176 if ( $params[
'user'] !==
null ) {
177 $options[
'onlyByUser'] = $params[
'user'];
179 if ( $params[
'excludeuser'] !==
null ) {
180 $options[
'notByUser'] = $params[
'excludeuser'];
183 $options[
'limit'] = $params[
'limit'];
185 $this->
getHookRunner()->onApiQueryWatchlistPrepareWatchedItemQueryServiceOptions(
186 $this, $params, $options );
189 $services = MediaWikiServices::getInstance();
190 $watchedItemQuery = $services->getWatchedItemQueryService();
191 $items = $watchedItemQuery->getWatchedItemsWithRecentChangeInfo( $wlowner, $options, $startFrom );
194 if ( $items !== [] && $resultPageSet ===
null && $this->fld_title &&
195 $services->getContentLanguage()->needsGenderDistinction()
197 $nsInfo = $services->getNamespaceInfo();
199 foreach ( $items as list( $watchedItem, $recentChangeInfo ) ) {
201 $linkTarget = $watchedItem->getLinkTarget();
202 if ( $nsInfo->hasGenderDistinction( $linkTarget->getNamespace() ) ) {
203 $usernames[] = $linkTarget->getText();
206 if ( $usernames !== [] ) {
207 $services->getGenderCache()->doQuery( $usernames, __METHOD__ );
211 foreach ( $items as list( $watchedItem, $recentChangeInfo ) ) {
213 if ( $resultPageSet ===
null ) {
217 $startFrom = [ $recentChangeInfo[
'rc_timestamp'], $recentChangeInfo[
'rc_id'] ];
220 } elseif ( $params[
'allrev'] ) {
221 $ids[] = (int)$recentChangeInfo[
'rc_this_oldid'];
223 $ids[] = (int)$recentChangeInfo[
'rc_cur_id'];
227 if ( $startFrom !==
null ) {
231 if ( $resultPageSet ===
null ) {
236 } elseif ( $params[
'allrev'] ) {
237 $resultPageSet->populateFromRevisionIDs( $ids );
239 $resultPageSet->populateFromPageIDs( $ids );
245 if ( $this->fld_flags ) {
248 if ( $this->fld_user || $this->fld_userid || $this->fld_loginfo ) {
251 if ( $this->fld_user || $this->fld_loginfo ) {
254 if ( $this->fld_comment || $this->fld_parsedcomment ) {
257 if ( $this->fld_patrol ) {
261 if ( $this->fld_sizes ) {
264 if ( $this->fld_loginfo ) {
267 if ( $this->fld_tags ) {
270 return $includeFields;
297 $type = (int)$recentChangeInfo[
'rc_type'];
302 if ( $this->fld_title || $this->fld_ids ) {
305 $vals[
'actionhidden'] =
true;
310 $recentChangeInfo[
'rc_deleted'],
315 if ( $this->fld_title ) {
318 if ( $this->fld_ids ) {
319 $vals[
'pageid'] = (int)$recentChangeInfo[
'rc_cur_id'];
320 $vals[
'revid'] = (int)$recentChangeInfo[
'rc_this_oldid'];
321 $vals[
'old_revid'] = (int)$recentChangeInfo[
'rc_last_oldid'];
327 if ( $this->fld_user || $this->fld_userid ) {
328 if ( $recentChangeInfo[
'rc_deleted'] & RevisionRecord::DELETED_USER ) {
329 $vals[
'userhidden'] =
true;
332 if ( RevisionRecord::userCanBitfield(
333 $recentChangeInfo[
'rc_deleted'],
334 RevisionRecord::DELETED_USER,
337 if ( $this->fld_userid ) {
338 $vals[
'userid'] = (int)$recentChangeInfo[
'rc_user'];
340 $vals[
'user'] = (int)$recentChangeInfo[
'rc_user'];
343 if ( $this->fld_user ) {
344 $vals[
'user'] = $recentChangeInfo[
'rc_user_text'];
347 $vals[
'anon'] = $recentChangeInfo[
'rc_user'] == 0;
352 if ( $this->fld_flags ) {
353 $vals[
'bot'] = (bool)$recentChangeInfo[
'rc_bot'];
354 $vals[
'new'] = $recentChangeInfo[
'rc_type'] ==
RC_NEW;
355 $vals[
'minor'] = (bool)$recentChangeInfo[
'rc_minor'];
359 if ( $this->fld_sizes ) {
360 $vals[
'oldlen'] = (int)$recentChangeInfo[
'rc_old_len'];
361 $vals[
'newlen'] = (int)$recentChangeInfo[
'rc_new_len'];
365 if ( $this->fld_timestamp ) {
366 $vals[
'timestamp'] =
wfTimestamp( TS_ISO_8601, $recentChangeInfo[
'rc_timestamp'] );
369 if ( $this->fld_notificationtimestamp ) {
376 if ( $this->fld_comment || $this->fld_parsedcomment ) {
377 if ( $recentChangeInfo[
'rc_deleted'] & RevisionRecord::DELETED_COMMENT ) {
378 $vals[
'commenthidden'] =
true;
381 if ( RevisionRecord::userCanBitfield(
382 $recentChangeInfo[
'rc_deleted'],
383 RevisionRecord::DELETED_COMMENT,
386 $comment = $this->commentStore->getComment(
'rc_comment', $recentChangeInfo )->text;
387 if ( $this->fld_comment ) {
388 $vals[
'comment'] = $comment;
391 if ( $this->fld_parsedcomment ) {
398 if ( $this->fld_patrol ) {
404 if ( $this->fld_loginfo && $recentChangeInfo[
'rc_type'] ==
RC_LOG ) {
406 $vals[
'actionhidden'] =
true;
410 $recentChangeInfo[
'rc_deleted'],
414 $vals[
'logid'] = (int)$recentChangeInfo[
'rc_logid'];
415 $vals[
'logtype'] = $recentChangeInfo[
'rc_log_type'];
416 $vals[
'logaction'] = $recentChangeInfo[
'rc_log_action'];
419 $vals[
'logparams'] = $logFormatter->formatParametersForApi();
420 $vals[
'logdisplay'] = $logFormatter->getActionText();
424 if ( $this->fld_tags ) {
425 if ( $recentChangeInfo[
'rc_tags'] ) {
426 $tags = explode(
',', $recentChangeInfo[
'rc_tags'] );
428 $vals[
'tags'] = $tags;
434 if ( $this->fld_expiry ) {
436 $expiry = $watchedItem->
getExpiry( TS_ISO_8601 );
437 $vals[
'expiry'] = ( $expiry ===
null ? false : $expiry );
440 if ( $anyHidden && ( $recentChangeInfo[
'rc_deleted'] & RevisionRecord::DELETED_RESTRICTED ) ) {
441 $vals[
'suppressed'] =
true;
444 $this->
getHookRunner()->onApiQueryWatchlistExtractOutputData(
445 $this, $watchedItem, $recentChangeInfo, $vals );
465 UserDef::PARAM_ALLOWED_USER_TYPES => [
'name',
'ip',
'id',
'interwiki' ],
469 UserDef::PARAM_ALLOWED_USER_TYPES => [
'name',
'ip',
'id',
'interwiki' ],
501 'notificationtimestamp',
532 UserDef::PARAM_ALLOWED_USER_TYPES => [
'name' ],
546 'action=query&list=watchlist'
547 =>
'apihelp-query+watchlist-example-simple',
548 'action=query&list=watchlist&wlprop=ids|title|timestamp|user|comment'
549 =>
'apihelp-query+watchlist-example-props',
550 'action=query&list=watchlist&wlprop=ids|title|timestamp|user|comment|expiry'
551 =>
'apihelp-query+watchlist-example-expiry',
552 'action=query&list=watchlist&wlallrev=&wlprop=ids|title|timestamp|user|comment'
553 =>
'apihelp-query+watchlist-example-allrev',
554 'action=query&generator=watchlist&prop=info'
555 =>
'apihelp-query+watchlist-example-generator',
556 'action=query&generator=watchlist&gwlallrev=&prop=revisions&rvprop=timestamp|user'
557 =>
'apihelp-query+watchlist-example-generator-rev',
558 'action=query&list=watchlist&wlowner=Example&wltoken=123ABC'
559 =>
'apihelp-query+watchlist-example-wlowner',
564 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Watchlist';