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