MediaWiki
REL1_23
|
00001 <?php 00002 00032 class ApiSetNotificationTimestamp extends ApiBase { 00033 00034 private $mPageSet; 00035 00036 public function execute() { 00037 $user = $this->getUser(); 00038 00039 if ( $user->isAnon() ) { 00040 $this->dieUsage( 'Anonymous users cannot use watchlist change notifications', 'notloggedin' ); 00041 } 00042 if ( !$user->isAllowed( 'editmywatchlist' ) ) { 00043 $this->dieUsage( 'You don\'t have permission to edit your watchlist', 'permissiondenied' ); 00044 } 00045 00046 $params = $this->extractRequestParams(); 00047 $this->requireMaxOneParameter( $params, 'timestamp', 'torevid', 'newerthanrevid' ); 00048 00049 $pageSet = $this->getPageSet(); 00050 if ( $params['entirewatchlist'] && $pageSet->getDataSource() !== null ) { 00051 $this->dieUsage( 00052 "Cannot use 'entirewatchlist' at the same time as '{$pageSet->getDataSource()}'", 00053 'multisource' 00054 ); 00055 } 00056 00057 $dbw = wfGetDB( DB_MASTER, 'api' ); 00058 00059 $timestamp = null; 00060 if ( isset( $params['timestamp'] ) ) { 00061 $timestamp = $dbw->timestamp( $params['timestamp'] ); 00062 } 00063 00064 if ( !$params['entirewatchlist'] ) { 00065 $pageSet->execute(); 00066 } 00067 00068 if ( isset( $params['torevid'] ) ) { 00069 if ( $params['entirewatchlist'] || $pageSet->getGoodTitleCount() > 1 ) { 00070 $this->dieUsage( 'torevid may only be used with a single page', 'multpages' ); 00071 } 00072 $title = reset( $pageSet->getGoodTitles() ); 00073 $timestamp = Revision::getTimestampFromId( $title, $params['torevid'] ); 00074 if ( $timestamp ) { 00075 $timestamp = $dbw->timestamp( $timestamp ); 00076 } else { 00077 $timestamp = null; 00078 } 00079 } elseif ( isset( $params['newerthanrevid'] ) ) { 00080 if ( $params['entirewatchlist'] || $pageSet->getGoodTitleCount() > 1 ) { 00081 $this->dieUsage( 'newerthanrevid may only be used with a single page', 'multpages' ); 00082 } 00083 $title = reset( $pageSet->getGoodTitles() ); 00084 $revid = $title->getNextRevisionID( $params['newerthanrevid'] ); 00085 if ( $revid ) { 00086 $timestamp = $dbw->timestamp( Revision::getTimestampFromId( $title, $revid ) ); 00087 } else { 00088 $timestamp = null; 00089 } 00090 } 00091 00092 $apiResult = $this->getResult(); 00093 $result = array(); 00094 if ( $params['entirewatchlist'] ) { 00095 // Entire watchlist mode: Just update the thing and return a success indicator 00096 $dbw->update( 'watchlist', array( 'wl_notificationtimestamp' => $timestamp ), 00097 array( 'wl_user' => $user->getID() ), 00098 __METHOD__ 00099 ); 00100 00101 $result['notificationtimestamp'] = is_null( $timestamp ) 00102 ? '' 00103 : wfTimestamp( TS_ISO_8601, $timestamp ); 00104 } else { 00105 // First, log the invalid titles 00106 foreach ( $pageSet->getInvalidTitles() as $title ) { 00107 $r = array(); 00108 $r['title'] = $title; 00109 $r['invalid'] = ''; 00110 $result[] = $r; 00111 } 00112 foreach ( $pageSet->getMissingPageIDs() as $p ) { 00113 $page = array(); 00114 $page['pageid'] = $p; 00115 $page['missing'] = ''; 00116 $page['notwatched'] = ''; 00117 $result[] = $page; 00118 } 00119 foreach ( $pageSet->getMissingRevisionIDs() as $r ) { 00120 $rev = array(); 00121 $rev['revid'] = $r; 00122 $rev['missing'] = ''; 00123 $rev['notwatched'] = ''; 00124 $result[] = $rev; 00125 } 00126 00127 // Now process the valid titles 00128 $lb = new LinkBatch( $pageSet->getTitles() ); 00129 $dbw->update( 'watchlist', array( 'wl_notificationtimestamp' => $timestamp ), 00130 array( 'wl_user' => $user->getID(), $lb->constructSet( 'wl', $dbw ) ), 00131 __METHOD__ 00132 ); 00133 00134 // Query the results of our update 00135 $timestamps = array(); 00136 $res = $dbw->select( 00137 'watchlist', 00138 array( 'wl_namespace', 'wl_title', 'wl_notificationtimestamp' ), 00139 array( 'wl_user' => $user->getID(), $lb->constructSet( 'wl', $dbw ) ), 00140 __METHOD__ 00141 ); 00142 foreach ( $res as $row ) { 00143 $timestamps[$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp; 00144 } 00145 00146 // Now, put the valid titles into the result 00148 foreach ( $pageSet->getTitles() as $title ) { 00149 $ns = $title->getNamespace(); 00150 $dbkey = $title->getDBkey(); 00151 $r = array( 00152 'ns' => intval( $ns ), 00153 'title' => $title->getPrefixedText(), 00154 ); 00155 if ( !$title->exists() ) { 00156 $r['missing'] = ''; 00157 } 00158 if ( isset( $timestamps[$ns] ) && array_key_exists( $dbkey, $timestamps[$ns] ) ) { 00159 $r['notificationtimestamp'] = ''; 00160 if ( $timestamps[$ns][$dbkey] !== null ) { 00161 $r['notificationtimestamp'] = wfTimestamp( TS_ISO_8601, $timestamps[$ns][$dbkey] ); 00162 } 00163 } else { 00164 $r['notwatched'] = ''; 00165 } 00166 $result[] = $r; 00167 } 00168 00169 $apiResult->setIndexedTagName( $result, 'page' ); 00170 } 00171 $apiResult->addValue( null, $this->getModuleName(), $result ); 00172 } 00173 00178 private function getPageSet() { 00179 if ( !isset( $this->mPageSet ) ) { 00180 $this->mPageSet = new ApiPageSet( $this ); 00181 } 00182 00183 return $this->mPageSet; 00184 } 00185 00186 public function mustBePosted() { 00187 return true; 00188 } 00189 00190 public function isWriteMode() { 00191 return true; 00192 } 00193 00194 public function needsToken() { 00195 return true; 00196 } 00197 00198 public function getTokenSalt() { 00199 return ''; 00200 } 00201 00202 public function getAllowedParams( $flags = 0 ) { 00203 $result = array( 00204 'entirewatchlist' => array( 00205 ApiBase::PARAM_TYPE => 'boolean' 00206 ), 00207 'token' => null, 00208 'timestamp' => array( 00209 ApiBase::PARAM_TYPE => 'timestamp' 00210 ), 00211 'torevid' => array( 00212 ApiBase::PARAM_TYPE => 'integer' 00213 ), 00214 'newerthanrevid' => array( 00215 ApiBase::PARAM_TYPE => 'integer' 00216 ), 00217 ); 00218 if ( $flags ) { 00219 $result += $this->getPageSet()->getFinalParams( $flags ); 00220 } 00221 00222 return $result; 00223 } 00224 00225 public function getParamDescription() { 00226 return $this->getPageSet()->getFinalParamDescription() + array( 00227 'entirewatchlist' => 'Work on all watched pages', 00228 'timestamp' => 'Timestamp to which to set the notification timestamp', 00229 'torevid' => 'Revision to set the notification timestamp to (one page only)', 00230 'newerthanrevid' => 'Revision to set the notification timestamp newer than (one page only)', 00231 'token' => 'A token previously acquired via prop=info', 00232 ); 00233 } 00234 00235 public function getResultProperties() { 00236 return array( 00237 ApiBase::PROP_LIST => true, 00238 ApiBase::PROP_ROOT => array( 00239 'notificationtimestamp' => array( 00240 ApiBase::PROP_TYPE => 'timestamp', 00241 ApiBase::PROP_NULLABLE => true 00242 ) 00243 ), 00244 '' => array( 00245 'ns' => array( 00246 ApiBase::PROP_TYPE => 'namespace', 00247 ApiBase::PROP_NULLABLE => true 00248 ), 00249 'title' => array( 00250 ApiBase::PROP_TYPE => 'string', 00251 ApiBase::PROP_NULLABLE => true 00252 ), 00253 'pageid' => array( 00254 ApiBase::PROP_TYPE => 'integer', 00255 ApiBase::PROP_NULLABLE => true 00256 ), 00257 'revid' => array( 00258 ApiBase::PROP_TYPE => 'integer', 00259 ApiBase::PROP_NULLABLE => true 00260 ), 00261 'invalid' => 'boolean', 00262 'missing' => 'boolean', 00263 'notwatched' => 'boolean', 00264 'notificationtimestamp' => array( 00265 ApiBase::PROP_TYPE => 'timestamp', 00266 ApiBase::PROP_NULLABLE => true 00267 ) 00268 ) 00269 ); 00270 } 00271 00272 public function getDescription() { 00273 return array( 'Update the notification timestamp for watched pages.', 00274 'This affects the highlighting of changed pages in the watchlist and history,', 00275 'and the sending of email when the "Email me when a page on my watchlist is', 00276 'changed" preference is enabled.' 00277 ); 00278 } 00279 00280 public function getPossibleErrors() { 00281 $ps = $this->getPageSet(); 00282 00283 return array_merge( 00284 parent::getPossibleErrors(), 00285 $ps->getFinalPossibleErrors(), 00286 $this->getRequireMaxOneParameterErrorMessages( 00287 array( 'timestamp', 'torevid', 'newerthanrevid' ) ), 00288 $this->getRequireOnlyOneParameterErrorMessages( 00289 array_merge( array( 'entirewatchlist' ), array_keys( $ps->getFinalParams() ) ) ), 00290 array( 00291 array( 'code' => 'notloggedin', 'info' 00292 => 'Anonymous users cannot use watchlist change notifications' ), 00293 array( 'code' => 'multpages', 'info' => 'torevid may only be used with a single page' ), 00294 array( 'code' => 'multpages', 'info' => 'newerthanrevid may only be used with a single page' ), 00295 ) 00296 ); 00297 } 00298 00299 public function getExamples() { 00300 return array( 00301 'api.php?action=setnotificationtimestamp&entirewatchlist=&token=123ABC' 00302 => 'Reset the notification status for the entire watchlist', 00303 'api.php?action=setnotificationtimestamp&titles=Main_page&token=123ABC' 00304 => 'Reset the notification status for "Main page"', 00305 'api.php?action=setnotificationtimestamp&titles=Main_page&' . 00306 'timestamp=2012-01-01T00:00:00Z&token=123ABC' 00307 => 'Set the notification timestamp for "Main page" so all edits ' . 00308 'since 1 January 2012 are unviewed', 00309 ); 00310 } 00311 00312 public function getHelpUrls() { 00313 return 'https://www.mediawiki.org/wiki/API:SetNotificationTimestamp'; 00314 } 00315 }