MediaWiki  REL1_21
ApiSetNotificationTimestamp.php
Go to the documentation of this file.
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&timestamp=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 }