MediaWiki  REL1_22
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         $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&timestamp=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 }