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