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