4 * API for MediaWiki 1.14+
6 * Created on Jun 18, 2012
8 * Copyright © 2012 Brad Jorsch
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.
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.
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
29 * API interface for setting the wl_notificationtimestamp field
32 class ApiSetNotificationTimestamp
extends ApiBase
{
36 public function execute() {
37 $user = $this->getUser();
39 if ( $user->isAnon() ) {
40 $this->dieUsage( 'Anonymous users cannot use watchlist change notifications', 'notloggedin' );
42 if ( !$user->isAllowed( 'editmywatchlist' ) ) {
43 $this->dieUsage( 'You don\'t have permission to edit your watchlist', 'permissiondenied' );
46 $params = $this->extractRequestParams();
47 $this->requireMaxOneParameter( $params, 'timestamp', 'torevid', 'newerthanrevid' );
49 $pageSet = $this->getPageSet();
50 if ( $params['entirewatchlist'] && $pageSet->getDataSource() !== null ) {
51 $this->dieUsage( "Cannot use 'entirewatchlist' at the same time as '{$pageSet->getDataSource()}'", 'multisource' );
54 $dbw = wfGetDB( DB_MASTER
, 'api' );
57 if ( isset( $params['timestamp'] ) ) {
58 $timestamp = $dbw->timestamp( $params['timestamp'] );
61 if ( !$params['entirewatchlist'] ) {
65 if ( isset( $params['torevid'] ) ) {
66 if ( $params['entirewatchlist'] ||
$pageSet->getGoodTitleCount() > 1 ) {
67 $this->dieUsage( 'torevid may only be used with a single page', 'multpages' );
69 $title = reset( $pageSet->getGoodTitles() );
70 $timestamp = Revision
::getTimestampFromId( $title, $params['torevid'] );
72 $timestamp = $dbw->timestamp( $timestamp );
76 } elseif ( isset( $params['newerthanrevid'] ) ) {
77 if ( $params['entirewatchlist'] ||
$pageSet->getGoodTitleCount() > 1 ) {
78 $this->dieUsage( 'newerthanrevid may only be used with a single page', 'multpages' );
80 $title = reset( $pageSet->getGoodTitles() );
81 $revid = $title->getNextRevisionID( $params['newerthanrevid'] );
83 $timestamp = $dbw->timestamp( Revision
::getTimestampFromId( $title, $revid ) );
89 $apiResult = $this->getResult();
91 if ( $params['entirewatchlist'] ) {
92 // Entire watchlist mode: Just update the thing and return a success indicator
93 $dbw->update( 'watchlist', array( 'wl_notificationtimestamp' => $timestamp ),
94 array( 'wl_user' => $user->getID() ),
98 $result['notificationtimestamp'] = ( is_null( $timestamp ) ?
'' : wfTimestamp( TS_ISO_8601
, $timestamp ) );
100 // First, log the invalid titles
101 foreach ( $pageSet->getInvalidTitles() as $title ) {
103 $r['title'] = $title;
107 foreach ( $pageSet->getMissingPageIDs() as $p ) {
109 $page['pageid'] = $p;
110 $page['missing'] = '';
111 $page['notwatched'] = '';
114 foreach ( $pageSet->getMissingRevisionIDs() as $r ) {
117 $rev['missing'] = '';
118 $rev['notwatched'] = '';
122 // Now process the valid titles
123 $lb = new LinkBatch( $pageSet->getTitles() );
124 $dbw->update( 'watchlist', array( 'wl_notificationtimestamp' => $timestamp ),
125 array( 'wl_user' => $user->getID(), $lb->constructSet( 'wl', $dbw ) ),
129 // Query the results of our update
130 $timestamps = array();
131 $res = $dbw->select( 'watchlist', array( 'wl_namespace', 'wl_title', 'wl_notificationtimestamp' ),
132 array( 'wl_user' => $user->getID(), $lb->constructSet( 'wl', $dbw ) ),
135 foreach ( $res as $row ) {
136 $timestamps[$row->wl_namespace
][$row->wl_title
] = $row->wl_notificationtimestamp
;
139 // Now, put the valid titles into the result
140 /** @var $title Title */
141 foreach ( $pageSet->getTitles() as $title ) {
142 $ns = $title->getNamespace();
143 $dbkey = $title->getDBkey();
145 'ns' => intval( $ns ),
146 'title' => $title->getPrefixedText(),
148 if ( !$title->exists() ) {
151 if ( isset( $timestamps[$ns] ) && array_key_exists( $dbkey, $timestamps[$ns] ) ) {
152 $r['notificationtimestamp'] = '';
153 if ( $timestamps[$ns][$dbkey] !== null ) {
154 $r['notificationtimestamp'] = wfTimestamp( TS_ISO_8601
, $timestamps[$ns][$dbkey] );
157 $r['notwatched'] = '';
162 $apiResult->setIndexedTagName( $result, 'page' );
164 $apiResult->addValue( null, $this->getModuleName(), $result );
168 * Get a cached instance of an ApiPageSet object
171 private function getPageSet() {
172 if ( !isset( $this->mPageSet
) ) {
173 $this->mPageSet
= new ApiPageSet( $this );
176 return $this->mPageSet
;
179 public function mustBePosted() {
183 public function isWriteMode() {
187 public function needsToken() {
191 public function getTokenSalt() {
195 public function getAllowedParams( $flags = 0 ) {
197 'entirewatchlist' => array(
198 ApiBase
::PARAM_TYPE
=> 'boolean'
201 'timestamp' => array(
202 ApiBase
::PARAM_TYPE
=> 'timestamp'
205 ApiBase
::PARAM_TYPE
=> 'integer'
207 'newerthanrevid' => array(
208 ApiBase
::PARAM_TYPE
=> 'integer'
212 $result +
= $this->getPageSet()->getFinalParams( $flags );
218 public function getParamDescription() {
219 return $this->getPageSet()->getFinalParamDescription() +
array(
220 'entirewatchlist' => 'Work on all watched pages',
221 'timestamp' => 'Timestamp to which to set the notification timestamp',
222 'torevid' => 'Revision to set the notification timestamp to (one page only)',
223 'newerthanrevid' => 'Revision to set the notification timestamp newer than (one page only)',
224 'token' => 'A token previously acquired via prop=info',
228 public function getResultProperties() {
230 ApiBase
::PROP_LIST
=> true,
231 ApiBase
::PROP_ROOT
=> array(
232 'notificationtimestamp' => array(
233 ApiBase
::PROP_TYPE
=> 'timestamp',
234 ApiBase
::PROP_NULLABLE
=> true
239 ApiBase
::PROP_TYPE
=> 'namespace',
240 ApiBase
::PROP_NULLABLE
=> true
243 ApiBase
::PROP_TYPE
=> 'string',
244 ApiBase
::PROP_NULLABLE
=> true
247 ApiBase
::PROP_TYPE
=> 'integer',
248 ApiBase
::PROP_NULLABLE
=> true
251 ApiBase
::PROP_TYPE
=> 'integer',
252 ApiBase
::PROP_NULLABLE
=> true
254 'invalid' => 'boolean',
255 'missing' => 'boolean',
256 'notwatched' => 'boolean',
257 'notificationtimestamp' => array(
258 ApiBase
::PROP_TYPE
=> 'timestamp',
259 ApiBase
::PROP_NULLABLE
=> true
265 public function getDescription() {
266 return array( 'Update the notification timestamp for watched pages.',
267 'This affects the highlighting of changed pages in the watchlist and history,',
268 'and the sending of email when the "Email me when a page on my watchlist is',
269 'changed" preference is enabled.'
273 public function getPossibleErrors() {
274 $ps = $this->getPageSet();
277 parent
::getPossibleErrors(),
278 $ps->getFinalPossibleErrors(),
279 $this->getRequireMaxOneParameterErrorMessages(
280 array( 'timestamp', 'torevid', 'newerthanrevid' ) ),
281 $this->getRequireOnlyOneParameterErrorMessages(
282 array_merge( array( 'entirewatchlist' ), array_keys( $ps->getFinalParams() ) ) ),
284 array( 'code' => 'notloggedin', 'info' => 'Anonymous users cannot use watchlist change notifications' ),
285 array( 'code' => 'multpages', 'info' => 'torevid may only be used with a single page' ),
286 array( 'code' => 'multpages', 'info' => 'newerthanrevid may only be used with a single page' ),
291 public function getExamples() {
293 'api.php?action=setnotificationtimestamp&entirewatchlist=&token=123ABC' => 'Reset the notification status for the entire watchlist',
294 'api.php?action=setnotificationtimestamp&titles=Main_page&token=123ABC' => 'Reset the notification status for "Main page"',
295 'api.php?action=setnotificationtimestamp&titles=Main_page×tamp=2012-01-01T00:00:00Z&token=123ABC' => 'Set the notification timestamp for "Main page" so all edits since 1 January 2012 are unviewed',
299 public function getHelpUrls() {
300 return 'https://www.mediawiki.org/wiki/API:SetNotificationTimestamp';