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