3 * Copyright © 2008 Roan Kattouw <roan.kattouw@gmail.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
23 namespace MediaWiki\Api
;
25 use MediaWiki\Cache\GenderCache
;
26 use MediaWiki\Language\Language
;
27 use MediaWiki\ParamValidator\TypeDef\UserDef
;
28 use MediaWiki\Title\NamespaceInfo
;
29 use MediaWiki\Title\Title
;
30 use MediaWiki\Title\TitleValue
;
31 use MediaWiki\Watchlist\WatchedItemQueryService
;
32 use MediaWiki\Watchlist\WatchedItemStore
;
33 use Wikimedia\ParamValidator\ParamValidator
;
34 use Wikimedia\ParamValidator\TypeDef\IntegerDef
;
37 * This query action allows clients to retrieve a list of pages
38 * on the logged-in user's watchlist.
42 class ApiQueryWatchlistRaw
extends ApiQueryGeneratorBase
{
44 private WatchedItemQueryService
$watchedItemQueryService;
45 private Language
$contentLanguage;
46 private NamespaceInfo
$namespaceInfo;
47 private GenderCache
$genderCache;
49 public function __construct(
52 WatchedItemQueryService
$watchedItemQueryService,
53 Language
$contentLanguage,
54 NamespaceInfo
$namespaceInfo,
55 GenderCache
$genderCache
57 parent
::__construct( $query, $moduleName, 'wr' );
58 $this->watchedItemQueryService
= $watchedItemQueryService;
59 $this->contentLanguage
= $contentLanguage;
60 $this->namespaceInfo
= $namespaceInfo;
61 $this->genderCache
= $genderCache;
64 public function execute() {
68 public function executeGenerator( $resultPageSet ) {
69 $this->run( $resultPageSet );
73 * @param ApiPageSet|null $resultPageSet
76 private function run( $resultPageSet = null ) {
77 $params = $this->extractRequestParams();
79 $user = $this->getWatchlistUser( $params );
81 $prop = array_fill_keys( (array)$params['prop'], true );
82 $show = array_fill_keys( (array)$params['show'], true );
83 if ( isset( $show[WatchedItemQueryService
::FILTER_CHANGED
] )
84 && isset( $show[WatchedItemQueryService
::FILTER_NOT_CHANGED
] )
86 $this->dieWithError( 'apierror-show' );
90 if ( $params['namespace'] ) {
91 $options['namespaceIds'] = $params['namespace'];
93 if ( isset( $show[WatchedItemQueryService
::FILTER_CHANGED
] ) ) {
94 $options['filter'] = WatchedItemQueryService
::FILTER_CHANGED
;
96 if ( isset( $show[WatchedItemQueryService
::FILTER_NOT_CHANGED
] ) ) {
97 $options['filter'] = WatchedItemQueryService
::FILTER_NOT_CHANGED
;
100 if ( isset( $params['continue'] ) ) {
101 $cont = $this->parseContinueParamOrDie( $params['continue'], [ 'int', 'string' ] );
102 $options['startFrom'] = TitleValue
::tryNew( $cont[0], $cont[1] );
103 $this->dieContinueUsageIf( !$options['startFrom'] );
106 if ( isset( $params['fromtitle'] ) ) {
107 $options['from'] = $this->parsePrefixedTitlePart( $params['fromtitle'] );
110 if ( isset( $params['totitle'] ) ) {
111 $options['until'] = $this->parsePrefixedTitlePart( $params['totitle'] );
114 $options['sort'] = WatchedItemStore
::SORT_ASC
;
115 if ( $params['dir'] === 'descending' ) {
116 $options['sort'] = WatchedItemStore
::SORT_DESC
;
118 $options['limit'] = $params['limit'] +
1;
122 $items = $this->watchedItemQueryService
->getWatchedItemsForUser( $user, $options );
124 // Get gender information
125 if ( $items !== [] && $resultPageSet === null &&
126 $this->contentLanguage
->needsGenderDistinction()
129 foreach ( $items as $item ) {
130 $linkTarget = $item->getTarget();
131 if ( $this->namespaceInfo
->hasGenderDistinction( $linkTarget->getNamespace() ) ) {
132 $usernames[] = $linkTarget->getText();
135 if ( $usernames !== [] ) {
136 $this->genderCache
->doQuery( $usernames, __METHOD__
);
140 foreach ( $items as $item ) {
141 $ns = $item->getTarget()->getNamespace();
142 $dbKey = $item->getTarget()->getDBkey();
143 if ( ++
$count > $params['limit'] ) {
144 // We've reached the one extra which shows that there are
145 // additional pages to be had. Stop here...
146 $this->setContinueEnumParameter( 'continue', $ns . '|' . $dbKey );
149 $t = Title
::makeTitle( $ns, $dbKey );
151 if ( $resultPageSet === null ) {
153 ApiQueryBase
::addTitleInfo( $vals, $t );
154 if ( isset( $prop['changed'] ) && $item->getNotificationTimestamp() !== null ) {
155 $vals['changed'] = wfTimestamp( TS_ISO_8601
, $item->getNotificationTimestamp() );
157 $fit = $this->getResult()->addValue( $this->getModuleName(), null, $vals );
159 $this->setContinueEnumParameter( 'continue', $ns . '|' . $dbKey );
166 if ( $resultPageSet === null ) {
167 $this->getResult()->addIndexedTagName( $this->getModuleName(), 'wr' );
169 $resultPageSet->populateFromTitles( $titles );
173 public function getAllowedParams() {
176 ApiBase
::PARAM_HELP_MSG
=> 'api-help-param-continue',
179 ParamValidator
::PARAM_ISMULTI
=> true,
180 ParamValidator
::PARAM_TYPE
=> 'namespace'
183 ParamValidator
::PARAM_DEFAULT
=> 10,
184 ParamValidator
::PARAM_TYPE
=> 'limit',
185 IntegerDef
::PARAM_MIN
=> 1,
186 IntegerDef
::PARAM_MAX
=> ApiBase
::LIMIT_BIG1
,
187 IntegerDef
::PARAM_MAX2
=> ApiBase
::LIMIT_BIG2
190 ParamValidator
::PARAM_ISMULTI
=> true,
191 ParamValidator
::PARAM_TYPE
=> [
194 ApiBase
::PARAM_HELP_MSG_PER_VALUE
=> [],
197 ParamValidator
::PARAM_ISMULTI
=> true,
198 ParamValidator
::PARAM_TYPE
=> [
199 WatchedItemQueryService
::FILTER_CHANGED
,
200 WatchedItemQueryService
::FILTER_NOT_CHANGED
204 ParamValidator
::PARAM_TYPE
=> 'user',
205 UserDef
::PARAM_ALLOWED_USER_TYPES
=> [ 'name' ],
208 ParamValidator
::PARAM_TYPE
=> 'string',
209 ParamValidator
::PARAM_SENSITIVE
=> true,
212 ParamValidator
::PARAM_DEFAULT
=> 'ascending',
213 ParamValidator
::PARAM_TYPE
=> [
219 ParamValidator
::PARAM_TYPE
=> 'string'
222 ParamValidator
::PARAM_TYPE
=> 'string'
227 protected function getExamplesMessages() {
229 'action=query&list=watchlistraw'
230 => 'apihelp-query+watchlistraw-example-simple',
231 'action=query&generator=watchlistraw&gwrshow=changed&prop=info'
232 => 'apihelp-query+watchlistraw-example-generator',
236 public function getHelpUrls() {
237 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Watchlistraw';
241 /** @deprecated class alias since 1.43 */
242 class_alias( ApiQueryWatchlistRaw
::class, 'ApiQueryWatchlistRaw' );