MediaWiki  REL1_20
ApiFeedWatchlist.php
Go to the documentation of this file.
00001 <?php
00034 class ApiFeedWatchlist extends ApiBase {
00035 
00036         public function __construct( $main, $action ) {
00037                 parent::__construct( $main, $action );
00038         }
00039 
00045         public function getCustomPrinter() {
00046                 return new ApiFormatFeedWrapper( $this->getMain() );
00047         }
00048 
00049         private $linkToDiffs = false;
00050 
00055         public function execute() {
00056                 global $wgFeed, $wgFeedClasses, $wgFeedLimit, $wgSitename, $wgLanguageCode;
00057 
00058                 try {
00059                         $params = $this->extractRequestParams();
00060 
00061                         if( !$wgFeed ) {
00062                                 $this->dieUsage( 'Syndication feeds are not available', 'feed-unavailable' );
00063                         }
00064 
00065                         if( !isset( $wgFeedClasses[ $params['feedformat'] ] ) ) {
00066                                 $this->dieUsage( 'Invalid subscription feed type', 'feed-invalid' );
00067                         }
00068                         if ( !is_null( $params['wlexcludeuser'] ) ) {
00069                                 $fauxReqArr['wlexcludeuser'] = $params['wlexcludeuser'];
00070                         }
00071 
00072                         // limit to the number of hours going from now back
00073                         $endTime = wfTimestamp( TS_MW, time() - intval( $params['hours'] * 60 * 60 ) );
00074 
00075                         // Prepare parameters for nested request
00076                         $fauxReqArr = array(
00077                                 'action' => 'query',
00078                                 'meta' => 'siteinfo',
00079                                 'siprop' => 'general',
00080                                 'list' => 'watchlist',
00081                                 'wlprop' => 'title|user|comment|timestamp',
00082                                 'wldir' => 'older', // reverse order - from newest to oldest
00083                                 'wlend' => $endTime, // stop at this time
00084                                 'wllimit' => ( 50 > $wgFeedLimit ) ? $wgFeedLimit : 50
00085                         );
00086 
00087                         if ( !is_null( $params['wlowner'] ) ) {
00088                                 $fauxReqArr['wlowner'] = $params['wlowner'];
00089                         }
00090                         if ( !is_null( $params['wltoken'] ) ) {
00091                                 $fauxReqArr['wltoken'] = $params['wltoken'];
00092                         }
00093 
00094                         // Support linking to diffs instead of article
00095                         if ( $params['linktodiffs'] ) {
00096                                 $this->linkToDiffs = true;
00097                                 $fauxReqArr['wlprop'] .= '|ids';
00098                         }
00099 
00100                         // Check for 'allrev' parameter, and if found, show all revisions to each page on wl.
00101                         if ( $params['allrev'] ) {
00102                                 $fauxReqArr['wlallrev'] = '';
00103                         }
00104 
00105                         // Create the request
00106                         $fauxReq = new FauxRequest( $fauxReqArr );
00107 
00108                         // Execute
00109                         $module = new ApiMain( $fauxReq );
00110                         $module->execute();
00111 
00112                         // Get data array
00113                         $data = $module->getResultData();
00114 
00115                         $feedItems = array();
00116                         foreach ( (array)$data['query']['watchlist'] as $info ) {
00117                                 $feedItems[] = $this->createFeedItem( $info );
00118                         }
00119 
00120                         $msg = wfMessage( 'watchlist' )->inContentLanguage()->text();
00121 
00122                         $feedTitle = $wgSitename . ' - ' . $msg . ' [' . $wgLanguageCode . ']';
00123                         $feedUrl = SpecialPage::getTitleFor( 'Watchlist' )->getFullURL();
00124 
00125                         $feed = new $wgFeedClasses[$params['feedformat']] ( $feedTitle, htmlspecialchars( $msg ), $feedUrl );
00126 
00127                         ApiFormatFeedWrapper::setResult( $this->getResult(), $feed, $feedItems );
00128 
00129                 } catch ( Exception $e ) {
00130 
00131                         // Error results should not be cached
00132                         $this->getMain()->setCacheMaxAge( 0 );
00133 
00134                         $feedTitle = $wgSitename . ' - Error - ' . wfMessage( 'watchlist' )->inContentLanguage()->text() . ' [' . $wgLanguageCode . ']';
00135                         $feedUrl = SpecialPage::getTitleFor( 'Watchlist' )->getFullURL();
00136 
00137                         $feedFormat = isset( $params['feedformat'] ) ? $params['feedformat'] : 'rss';
00138                         $msg = wfMessage( 'watchlist' )->inContentLanguage()->escaped();
00139                         $feed = new $wgFeedClasses[$feedFormat] ( $feedTitle, $msg, $feedUrl );
00140 
00141                         if ( $e instanceof UsageException ) {
00142                                 $errorCode = $e->getCodeString();
00143                         } else {
00144                                 // Something is seriously wrong
00145                                 $errorCode = 'internal_api_error';
00146                         }
00147 
00148                         $errorText = $e->getMessage();
00149                         $feedItems[] = new FeedItem( "Error ($errorCode)", $errorText, '', '', '' );
00150                         ApiFormatFeedWrapper::setResult( $this->getResult(), $feed, $feedItems );
00151                 }
00152         }
00153 
00158         private function createFeedItem( $info ) {
00159                 $titleStr = $info['title'];
00160                 $title = Title::newFromText( $titleStr );
00161                 if ( $this->linkToDiffs && isset( $info['revid'] ) ) {
00162                         $titleUrl = $title->getFullURL( array( 'diff' => $info['revid'] ) );
00163                 } else {
00164                         $titleUrl = $title->getFullURL();
00165                 }
00166                 $comment = isset( $info['comment'] ) ? $info['comment'] : null;
00167                 $timestamp = $info['timestamp'];
00168                 $user = $info['user'];
00169 
00170                 $completeText = "$comment ($user)";
00171 
00172                 return new FeedItem( $titleStr, $completeText, $titleUrl, $timestamp, $user );
00173         }
00174 
00175         public function getAllowedParams() {
00176                 global $wgFeedClasses;
00177                 $feedFormatNames = array_keys( $wgFeedClasses );
00178                 return array (
00179                         'feedformat' => array(
00180                                 ApiBase::PARAM_DFLT => 'rss',
00181                                 ApiBase::PARAM_TYPE => $feedFormatNames
00182                         ),
00183                         'hours' => array(
00184                                 ApiBase::PARAM_DFLT => 24,
00185                                 ApiBase::PARAM_TYPE => 'integer',
00186                                 ApiBase::PARAM_MIN => 1,
00187                                 ApiBase::PARAM_MAX => 72,
00188                         ),
00189                         'allrev' => false,
00190                         'wlowner' => array(
00191                                 ApiBase::PARAM_TYPE => 'user'
00192                         ),
00193                         'wltoken' => array(
00194                                 ApiBase::PARAM_TYPE => 'string'
00195                         ),
00196                         'wlexcludeuser' => array(
00197                                 ApiBase::PARAM_TYPE => 'user'
00198                         ),
00199                         'linktodiffs' => false,
00200                 );
00201         }
00202 
00203         public function getParamDescription() {
00204                 return array(
00205                         'feedformat' => 'The format of the feed',
00206                         'hours'      => 'List pages modified within this many hours from now',
00207                         'allrev'     => 'Include multiple revisions of the same page within given timeframe',
00208                         'wlowner'    => "The user whose watchlist you want (must be accompanied by {$this->getModulePrefix()}wltoken if it's not you)",
00209                         'wltoken'    => 'Security token that requested user set in their preferences',
00210                         'wlexcludeuser' => 'A user whose edits should not be shown in the watchlist',
00211                         'linktodiffs' => 'Link to change differences instead of article pages',
00212                 );
00213         }
00214 
00215         public function getDescription() {
00216                 return 'Returns a watchlist feed';
00217         }
00218 
00219         public function getPossibleErrors() {
00220                 return array_merge( parent::getPossibleErrors(), array(
00221                         array( 'code' => 'feed-unavailable', 'info' => 'Syndication feeds are not available' ),
00222                         array( 'code' => 'feed-invalid', 'info' => 'Invalid subscription feed type' ),
00223                 ) );
00224         }
00225 
00226         public function getExamples() {
00227                 return array(
00228                         'api.php?action=feedwatchlist',
00229                         'api.php?action=feedwatchlist&allrev=&linktodiffs=&hours=6'
00230                 );
00231         }
00232 
00233         public function getHelpUrls() {
00234                 return 'https://www.mediawiki.org/wiki/API:Watchlist_feed';
00235         }
00236 
00237         public function getVersion() {
00238                 return __CLASS__ . ': $Id$';
00239         }
00240 }