MediaWiki REL1_37
ApiSetNotificationTimestamp.php
Go to the documentation of this file.
1<?php
2
28
34
35 private $mPageSet = null;
36
39
42
45
53 public function __construct(
54 ApiMain $main,
55 $action,
59 ) {
60 parent::__construct( $main, $action );
61
62 $this->loadBalancer = $loadBalancer;
63 $this->revisionStore = $revisionStore;
64 $this->watchedItemStore = $watchedItemStore;
65 }
66
67 public function execute() {
68 $user = $this->getUser();
69
70 if ( !$user->isRegistered() ) {
71 $this->dieWithError( 'watchlistanontext', 'notloggedin' );
72 }
73 $this->checkUserRightsAny( 'editmywatchlist' );
74
75 $params = $this->extractRequestParams();
76 $this->requireMaxOneParameter( $params, 'timestamp', 'torevid', 'newerthanrevid' );
77
78 $continuationManager = new ApiContinuationManager( $this, [], [] );
79 $this->setContinuationManager( $continuationManager );
80
81 $pageSet = $this->getPageSet();
82 if ( $params['entirewatchlist'] && $pageSet->getDataSource() !== null ) {
83 $this->dieWithError(
84 [
85 'apierror-invalidparammix-cannotusewith',
86 $this->encodeParamName( 'entirewatchlist' ),
87 $pageSet->encodeParamName( $pageSet->getDataSource() )
88 ],
89 'multisource'
90 );
91 }
92
93 $dbw = $this->loadBalancer->getConnectionRef( DB_PRIMARY, 'api' );
94
95 $timestamp = null;
96 if ( isset( $params['timestamp'] ) ) {
97 $timestamp = $dbw->timestamp( $params['timestamp'] );
98 }
99
100 if ( !$params['entirewatchlist'] ) {
101 $pageSet->execute();
102 }
103
104 if ( isset( $params['torevid'] ) ) {
105 if ( $params['entirewatchlist'] || $pageSet->getGoodTitleCount() > 1 ) {
106 $this->dieWithError( [ 'apierror-multpages', $this->encodeParamName( 'torevid' ) ] );
107 }
108 $titles = $pageSet->getGoodTitles();
109 $title = reset( $titles );
110 if ( $title ) {
111 // XXX $title isn't actually used, can we just get rid of the previous six lines?
112 $timestamp = $this->revisionStore->getTimestampFromId(
113 $params['torevid'],
114 IDBAccessObject::READ_LATEST
115 );
116 if ( $timestamp ) {
117 $timestamp = $dbw->timestamp( $timestamp );
118 } else {
119 $timestamp = null;
120 }
121 }
122 } elseif ( isset( $params['newerthanrevid'] ) ) {
123 if ( $params['entirewatchlist'] || $pageSet->getGoodTitleCount() > 1 ) {
124 $this->dieWithError( [ 'apierror-multpages', $this->encodeParamName( 'newerthanrevid' ) ] );
125 }
126 $titles = $pageSet->getGoodTitles();
127 $title = reset( $titles );
128 if ( $title ) {
129 $timestamp = null;
130 $currRev = $this->revisionStore->getRevisionById(
131 $params['newerthanrevid'],
132 Title::READ_LATEST
133 );
134 if ( $currRev ) {
135 $nextRev = $this->revisionStore->getNextRevision(
136 $currRev,
137 Title::READ_LATEST
138 );
139 if ( $nextRev ) {
140 $timestamp = $dbw->timestamp( $nextRev->getTimestamp() );
141 }
142 }
143 }
144 }
145
146 $apiResult = $this->getResult();
147 $result = [];
148 if ( $params['entirewatchlist'] ) {
149 // Entire watchlist mode: Just update the thing and return a success indicator
150 $this->watchedItemStore->resetAllNotificationTimestampsForUser( $user, $timestamp );
151
152 $result['notificationtimestamp'] = $timestamp === null
153 ? ''
154 : wfTimestamp( TS_ISO_8601, $timestamp );
155 } else {
156 // First, log the invalid titles
157 foreach ( $pageSet->getInvalidTitlesAndReasons() as $r ) {
158 $r['invalid'] = true;
159 $result[] = $r;
160 }
161 foreach ( $pageSet->getMissingPageIDs() as $p ) {
162 $page = [];
163 $page['pageid'] = $p;
164 $page['missing'] = true;
165 $page['notwatched'] = true;
166 $result[] = $page;
167 }
168 foreach ( $pageSet->getMissingRevisionIDs() as $r ) {
169 $rev = [];
170 $rev['revid'] = $r;
171 $rev['missing'] = true;
172 $rev['notwatched'] = true;
173 $result[] = $rev;
174 }
175
176 if ( $pageSet->getPages() ) {
177 // Now process the valid titles
178 $this->watchedItemStore->setNotificationTimestampsForUser(
179 $user,
180 $timestamp,
181 $pageSet->getPages()
182 );
183
184 // Query the results of our update
185 $timestamps = $this->watchedItemStore->getNotificationTimestampsBatch(
186 $user,
187 $pageSet->getPages()
188 );
189
190 // Now, put the valid titles into the result
192 foreach ( $pageSet->getTitles() as $title ) {
193 $ns = $title->getNamespace();
194 $dbkey = $title->getDBkey();
195 $r = [
196 'ns' => $ns,
197 'title' => $title->getPrefixedText(),
198 ];
199 if ( !$title->exists() ) {
200 $r['missing'] = true;
201 if ( $title->isKnown() ) {
202 $r['known'] = true;
203 }
204 }
205 if ( isset( $timestamps[$ns] ) && array_key_exists( $dbkey, $timestamps[$ns] ) ) {
206 $r['notificationtimestamp'] = '';
207 if ( $timestamps[$ns][$dbkey] !== null ) {
208 $r['notificationtimestamp'] = wfTimestamp( TS_ISO_8601, $timestamps[$ns][$dbkey] );
209 }
210 } else {
211 $r['notwatched'] = true;
212 }
213 $result[] = $r;
214 }
215 }
216
217 ApiResult::setIndexedTagName( $result, 'page' );
218 }
219 $apiResult->addValue( null, $this->getModuleName(), $result );
220
221 $this->setContinuationManager( null );
222 $continuationManager->setContinuationIntoResult( $apiResult );
223 }
224
229 private function getPageSet() {
230 if ( $this->mPageSet === null ) {
231 $this->mPageSet = new ApiPageSet( $this );
232 }
233
234 return $this->mPageSet;
235 }
236
237 public function mustBePosted() {
238 return true;
239 }
240
241 public function isWriteMode() {
242 return true;
243 }
244
245 public function needsToken() {
246 return 'csrf';
247 }
248
249 public function getAllowedParams( $flags = 0 ) {
250 $result = [
251 'entirewatchlist' => [
252 ApiBase::PARAM_TYPE => 'boolean'
253 ],
254 'timestamp' => [
255 ApiBase::PARAM_TYPE => 'timestamp'
256 ],
257 'torevid' => [
258 ApiBase::PARAM_TYPE => 'integer'
259 ],
260 'newerthanrevid' => [
261 ApiBase::PARAM_TYPE => 'integer'
262 ],
263 'continue' => [
264 ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
265 ],
266 ];
267 if ( $flags ) {
268 $result += $this->getPageSet()->getFinalParams( $flags );
269 }
270
271 return $result;
272 }
273
274 protected function getExamplesMessages() {
275 return [
276 'action=setnotificationtimestamp&entirewatchlist=&token=123ABC'
277 => 'apihelp-setnotificationtimestamp-example-all',
278 'action=setnotificationtimestamp&titles=Main_page&token=123ABC'
279 => 'apihelp-setnotificationtimestamp-example-page',
280 'action=setnotificationtimestamp&titles=Main_page&' .
281 'timestamp=2012-01-01T00:00:00Z&token=123ABC'
282 => 'apihelp-setnotificationtimestamp-example-pagetimestamp',
283 'action=setnotificationtimestamp&generator=allpages&gapnamespace=2&token=123ABC'
284 => 'apihelp-setnotificationtimestamp-example-allpages',
285 ];
286 }
287
288 public function getHelpUrls() {
289 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:SetNotificationTimestamp';
290 }
291}
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:55
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1436
checkUserRightsAny( $rights, $user=null)
Helper function for permission-denied errors.
Definition ApiBase.php:1539
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
Definition ApiBase.php:742
const PARAM_TYPE
Definition ApiBase.php:81
requireMaxOneParameter( $params,... $required)
Die if more than one of a certain set of parameters is set and not false.
Definition ApiBase.php:936
setContinuationManager(ApiContinuationManager $manager=null)
Definition ApiBase.php:672
getResult()
Get the result object.
Definition ApiBase.php:628
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:764
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition ApiBase.php:162
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:497
This manages continuation state.
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:49
This class contains a list of pages that the client has requested.
API interface for setting the wl_notificationtimestamp field.
WatchedItemStoreInterface $watchedItemStore
getExamplesMessages()
Returns usage examples for this module.
getPageSet()
Get a cached instance of an ApiPageSet object.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getHelpUrls()
Return links to more detailed help pages about the module.
mustBePosted()
Indicates whether this module must be called with a POST request.
__construct(ApiMain $main, $action, ILoadBalancer $loadBalancer, RevisionStore $revisionStore, WatchedItemStoreInterface $watchedItemStore)
needsToken()
Returns the token type this module requires in order to execute.
isWriteMode()
Indicates whether this module requires write mode.
Service for looking up page revisions.
Represents a title within MediaWiki.
Definition Title.php:48
Database cluster connection, tracking, load balancing, and transaction manager interface.
const DB_PRIMARY
Definition defines.php:27