Use 'email' instead of 'e-mail' in API texts.
[lhc/web/wiklou.git] / includes / api / ApiSetNotificationTimestamp.php
1 <?php
2
3 /**
4 * API for MediaWiki 1.14+
5 *
6 * Created on Jun 18, 2012
7 *
8 * Copyright © 2012 Brad Jorsch
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 * http://www.gnu.org/copyleft/gpl.html
24 *
25 * @file
26 */
27
28 /**
29 * API interface for setting the wl_notificationtimestamp field
30 * @ingroup API
31 */
32 class ApiSetNotificationTimestamp extends ApiBase {
33
34 private $mPageSet;
35
36 public function execute() {
37 $user = $this->getUser();
38
39 if ( $user->isAnon() ) {
40 $this->dieUsage( 'Anonymous users cannot use watchlist change notifications', 'notloggedin' );
41 }
42
43 $params = $this->extractRequestParams();
44 $this->requireMaxOneParameter( $params, 'timestamp', 'torevid', 'newerthanrevid' );
45
46 $pageSet = $this->getPageSet();
47 $args = array_merge( array( $params, 'entirewatchlist' ), array_keys( $pageSet->getAllowedParams() ) );
48 call_user_func_array( array( $this, 'requireOnlyOneParameter' ), $args );
49
50 $dbw = wfGetDB( DB_MASTER, 'api' );
51
52 $timestamp = null;
53 if ( isset( $params['timestamp'] ) ) {
54 $timestamp = $dbw->timestamp( $params['timestamp'] );
55 }
56
57 if ( !$params['entirewatchlist'] ) {
58 $pageSet->execute();
59 }
60
61 if ( isset( $params['torevid'] ) ) {
62 if ( $params['entirewatchlist'] || $pageSet->getGoodTitleCount() > 1 ) {
63 $this->dieUsage( 'torevid may only be used with a single page', 'multpages' );
64 }
65 $title = reset( $pageSet->getGoodTitles() );
66 $timestamp = Revision::getTimestampFromId( $title, $params['torevid'] );
67 if ( $timestamp ) {
68 $timestamp = $dbw->timestamp( $timestamp );
69 } else {
70 $timestamp = null;
71 }
72 } elseif ( isset( $params['newerthanrevid'] ) ) {
73 if ( $params['entirewatchlist'] || $pageSet->getGoodTitleCount() > 1 ) {
74 $this->dieUsage( 'newerthanrevid may only be used with a single page', 'multpages' );
75 }
76 $title = reset( $pageSet->getGoodTitles() );
77 $revid = $title->getNextRevisionID( $params['newerthanrevid'] );
78 if ( $revid ) {
79 $timestamp = $dbw->timestamp( Revision::getTimestampFromId( $title, $revid ) );
80 } else {
81 $timestamp = null;
82 }
83 }
84
85 $apiResult = $this->getResult();
86 $result = array();
87 if ( $params['entirewatchlist'] ) {
88 // Entire watchlist mode: Just update the thing and return a success indicator
89 $dbw->update( 'watchlist', array( 'wl_notificationtimestamp' => $timestamp ),
90 array( 'wl_user' => $user->getID() ),
91 __METHOD__
92 );
93
94 $result['notificationtimestamp'] = ( is_null( $timestamp ) ? '' : wfTimestamp( TS_ISO_8601, $timestamp ) );
95 } else {
96 // First, log the invalid titles
97 foreach ( $pageSet->getInvalidTitles() as $title ) {
98 $r = array();
99 $r['title'] = $title;
100 $r['invalid'] = '';
101 $result[] = $r;
102 }
103 foreach ( $pageSet->getMissingPageIDs() as $p ) {
104 $page = array();
105 $page['pageid'] = $p;
106 $page['missing'] = '';
107 $page['notwatched'] = '';
108 $result[] = $page;
109 }
110 foreach ( $pageSet->getMissingRevisionIDs() as $r ) {
111 $rev = array();
112 $rev['revid'] = $r;
113 $rev['missing'] = '';
114 $rev['notwatched'] = '';
115 $result[] = $rev;
116 }
117
118 // Now process the valid titles
119 $lb = new LinkBatch( $pageSet->getTitles() );
120 $dbw->update( 'watchlist', array( 'wl_notificationtimestamp' => $timestamp ),
121 array( 'wl_user' => $user->getID(), $lb->constructSet( 'wl', $dbw ) ),
122 __METHOD__
123 );
124
125 // Query the results of our update
126 $timestamps = array();
127 $res = $dbw->select( 'watchlist', array( 'wl_namespace', 'wl_title', 'wl_notificationtimestamp' ),
128 array( 'wl_user' => $user->getID(), $lb->constructSet( 'wl', $dbw ) ),
129 __METHOD__
130 );
131 foreach ( $res as $row ) {
132 $timestamps[$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp;
133 }
134
135 // Now, put the valid titles into the result
136 foreach ( $pageSet->getTitles() as $title ) {
137 $ns = $title->getNamespace();
138 $dbkey = $title->getDBkey();
139 $r = array(
140 'ns' => intval( $ns ),
141 'title' => $title->getPrefixedText(),
142 );
143 if ( !$title->exists() ) {
144 $r['missing'] = '';
145 }
146 if ( isset( $timestamps[$ns] ) && array_key_exists( $dbkey, $timestamps[$ns] ) ) {
147 $r['notificationtimestamp'] = '';
148 if ( $timestamps[$ns][$dbkey] !== null ) {
149 $r['notificationtimestamp'] = wfTimestamp( TS_ISO_8601, $timestamps[$ns][$dbkey] );
150 }
151 } else {
152 $r['notwatched'] = '';
153 }
154 $result[] = $r;
155 }
156
157 $apiResult->setIndexedTagName( $result, 'page' );
158 }
159 $apiResult->addValue( null, $this->getModuleName(), $result );
160 }
161
162 /**
163 * Get a cached instance of an ApiPageSet object
164 * @return ApiPageSet
165 */
166 private function getPageSet() {
167 if ( !isset( $this->mPageSet ) ) {
168 $this->mPageSet = new ApiPageSet( $this );
169 }
170 return $this->mPageSet;
171 }
172
173 public function mustBePosted() {
174 return true;
175 }
176
177 public function isWriteMode() {
178 return true;
179 }
180
181 public function needsToken() {
182 return true;
183 }
184
185 public function getTokenSalt() {
186 return '';
187 }
188
189 public function getAllowedParams( $flags = 0 ) {
190 $result = array(
191 'entirewatchlist' => array(
192 ApiBase::PARAM_TYPE => 'boolean'
193 ),
194 'token' => null,
195 'timestamp' => array(
196 ApiBase::PARAM_TYPE => 'timestamp'
197 ),
198 'torevid' => array(
199 ApiBase::PARAM_TYPE => 'integer'
200 ),
201 'newerthanrevid' => array(
202 ApiBase::PARAM_TYPE => 'integer'
203 ),
204 );
205 if ( $flags ) {
206 $result += $this->getPageSet()->getFinalParams( $flags );
207 }
208 return $result;
209
210 }
211
212 public function getParamDescription() {
213 return $this->getPageSet()->getParamDescription() + array(
214 'entirewatchlist' => 'Work on all watched pages',
215 'timestamp' => 'Timestamp to which to set the notification timestamp',
216 'torevid' => 'Revision to set the notification timestamp to (one page only)',
217 'newerthanrevid' => 'Revision to set the notification timestamp newer than (one page only)',
218 'token' => 'A token previously acquired via prop=info',
219 );
220 }
221
222 public function getResultProperties() {
223 return array(
224 ApiBase::PROP_LIST => true,
225 ApiBase::PROP_ROOT => array(
226 'notificationtimestamp' => array(
227 ApiBase::PROP_TYPE => 'timestamp',
228 ApiBase::PROP_NULLABLE => true
229 )
230 ),
231 '' => array(
232 'ns' => array(
233 ApiBase::PROP_TYPE => 'namespace',
234 ApiBase::PROP_NULLABLE => true
235 ),
236 'title' => array(
237 ApiBase::PROP_TYPE => 'string',
238 ApiBase::PROP_NULLABLE => true
239 ),
240 'pageid' => array(
241 ApiBase::PROP_TYPE => 'integer',
242 ApiBase::PROP_NULLABLE => true
243 ),
244 'revid' => array(
245 ApiBase::PROP_TYPE => 'integer',
246 ApiBase::PROP_NULLABLE => true
247 ),
248 'invalid' => 'boolean',
249 'missing' => 'boolean',
250 'notwatched' => 'boolean',
251 'notificationtimestamp' => array(
252 ApiBase::PROP_TYPE => 'timestamp',
253 ApiBase::PROP_NULLABLE => true
254 )
255 )
256 );
257 }
258
259 public function getDescription() {
260 return array( 'Update the notification timestamp for watched pages.',
261 'This affects the highlighting of changed pages in the watchlist and history,',
262 'and the sending of email when the "E-mail me when a page on my watchlist is',
263 'changed" preference is enabled.'
264 );
265 }
266
267 public function getPossibleErrors() {
268 $ps = $this->getPageSet();
269 return array_merge(
270 parent::getPossibleErrors(),
271 $ps->getPossibleErrors(),
272 $this->getRequireMaxOneParameterErrorMessages(
273 array( 'timestamp', 'torevid', 'newerthanrevid' ) ),
274 $this->getRequireOnlyOneParameterErrorMessages(
275 array_merge( array( 'entirewatchlist' ), array_keys( $ps->getFinalParams() ) ) ),
276 array(
277 array( 'code' => 'notloggedin', 'info' => 'Anonymous users cannot use watchlist change notifications' ),
278 array( 'code' => 'multpages', 'info' => 'torevid may only be used with a single page' ),
279 array( 'code' => 'multpages', 'info' => 'newerthanrevid may only be used with a single page' ),
280 )
281 );
282 }
283
284 public function getExamples() {
285 return array(
286 'api.php?action=setnotificationtimestamp&entirewatchlist=&token=ABC123' => 'Reset the notification status for the entire watchlist',
287 'api.php?action=setnotificationtimestamp&titles=Main_page&token=ABC123' => 'Reset the notification status for "Main page"',
288 'api.php?action=setnotificationtimestamp&titles=Main_page&timestamp=2012-01-01T00:00:00Z&token=ABC123' => 'Set the notification timestamp for "Main page" so all edits since 1 January 2012 are unviewed',
289 );
290 }
291
292 public function getHelpUrls() {
293 return 'https://www.mediawiki.org/wiki/API:SetNotificationTimestamp';
294 }
295 }