36 private $watchlistModule =
null;
37 private $linkToSections =
false;
52 parent::__construct( $main, $action );
53 $this->parser = $parser;
71 $feedClasses = $config->get( MainConfigNames::FeedClasses );
77 if ( !$config->get( MainConfigNames::Feed ) ) {
81 if ( !isset( $feedClasses[$params[
'feedformat']] ) ) {
86 $endTime =
wfTimestamp( TS_MW, time() - (
int)$params[
'hours'] * 60 * 60 );
92 'siprop' =>
'general',
93 'list' =>
'watchlist',
94 'wlprop' =>
'title|user|comment|timestamp|ids|loginfo',
97 'wllimit' => min( 50, $this->
getConfig()->
get( MainConfigNames::FeedLimit ) )
100 if ( $params[
'wlowner'] !==
null ) {
101 $fauxReqArr[
'wlowner'] = $params[
'wlowner'];
103 if ( $params[
'wltoken'] !==
null ) {
104 $fauxReqArr[
'wltoken'] = $params[
'wltoken'];
106 if ( $params[
'wlexcludeuser'] !==
null ) {
107 $fauxReqArr[
'wlexcludeuser'] = $params[
'wlexcludeuser'];
109 if ( $params[
'wlshow'] !==
null ) {
110 $fauxReqArr[
'wlshow'] = ParamValidator::implodeMultiValue( $params[
'wlshow'] );
112 if ( $params[
'wltype'] !==
null ) {
113 $fauxReqArr[
'wltype'] = ParamValidator::implodeMultiValue( $params[
'wltype'] );
118 if ( $params[
'linktosections'] ) {
119 $this->linkToSections =
true;
123 if ( $params[
'allrev'] ) {
124 $fauxReqArr[
'wlallrev'] =
'';
129 $module =
new ApiMain( $fauxReq );
132 $data = $module->getResult()->getResultData( [
'query',
'watchlist' ] );
133 foreach ( (array)$data as $key => $info ) {
134 if ( ApiResult::isMetadataKey( $key ) ) {
137 $feedItem = $this->createFeedItem( $info );
139 $feedItems[] = $feedItem;
143 $msg = $this->
msg(
'watchlist' )->inContentLanguage()->text();
145 $feedTitle = $this->
getConfig()->get( MainConfigNames::Sitename ) .
' - ' . $msg .
146 ' [' . $this->
getConfig()->get( MainConfigNames::LanguageCode ) .
']';
149 $feed =
new $feedClasses[$params[
'feedformat']] (
151 htmlspecialchars( $msg ),
156 }
catch ( Exception $e ) {
158 $this->
getMain()->setCacheMaxAge( 0 );
161 $feedTitle = $this->
getConfig()->get( MainConfigNames::Sitename ) .
' - Error - ' .
162 $this->
msg(
'watchlist' )->inContentLanguage()->text() .
163 ' [' . $this->
getConfig()->get( MainConfigNames::LanguageCode ) .
']';
166 $feedFormat = $params[
'feedformat'] ??
'rss';
167 $msg = $this->
msg(
'watchlist' )->inContentLanguage()->escaped();
168 $feed =
new $feedClasses[$feedFormat] ( $feedTitle, $msg, $feedUrl );
171 foreach ( $e->getStatusValue()->getErrors() as $error ) {
173 $msg = ApiMessage::create( $error )
175 $errorTitle = $this->
msg(
'api-feed-error-title', $msg->getApiCode() );
176 $errorText = $msg->text();
177 $feedItems[] =
new FeedItem( $errorTitle, $errorText,
'',
'',
'' );
181 $errorCode =
'internal_api_error';
182 $errorTitle = $this->
msg(
'api-feed-error-title', $errorCode );
183 $errorText = $e->getMessage();
184 $feedItems[] =
new FeedItem( $errorTitle, $errorText,
'',
'',
'' );
195 private function createFeedItem( $info ) {
196 if ( !isset( $info[
'title'] ) ) {
201 $titleStr = $info[
'title'];
207 if ( isset( $info[
'pageid'] ) ) {
209 $curidParam = [
'curid' => $info[
'pageid'] ];
215 if ( isset( $info[
'revid'] ) ) {
216 if ( $info[
'revid'] === 0 && isset( $info[
'logid'] ) ) {
218 $titleUrl = $logTitle->getFullURL( [
'logid' => $info[
'logid'] ] );
220 $titleUrl =
$title->getFullURL( [
'diff' => $info[
'revid'] ] );
223 $titleUrl =
$title->getFullURL( $curidParam );
225 $comment = $info[
'comment'] ??
null;
231 if ( $this->linkToSections && $comment !==
null &&
232 preg_match(
'!(.*)/\*\s*(.*?)\s*\*/(.*)!', $comment,
$matches )
234 $titleUrl .= $this->parser->guessSectionNameFromWikiText(
$matches[ 2 ] );
237 $timestamp = $info[
'timestamp'];
239 if ( isset( $info[
'user'] ) ) {
240 $user = $info[
'user'];
241 $completeText =
"$comment ($user)";
244 $completeText = (string)$comment;
247 return new FeedItem( $titleStr, $completeText, $titleUrl, $timestamp, $user );
250 private function getWatchlistModule() {
251 if ( $this->watchlistModule ===
null ) {
252 $this->watchlistModule = $this->
getMain()->getModuleManager()->getModule(
'query' )
253 ->getModuleManager()->getModule(
'watchlist' );
256 return $this->watchlistModule;
260 $feedFormatNames = array_keys( $this->
getConfig()->
get( MainConfigNames::FeedClasses ) );
263 ParamValidator::PARAM_DEFAULT =>
'rss',
264 ParamValidator::PARAM_TYPE => $feedFormatNames
267 ParamValidator::PARAM_DEFAULT => 24,
268 ParamValidator::PARAM_TYPE =>
'integer',
269 IntegerDef::PARAM_MIN => 1,
270 IntegerDef::PARAM_MAX => 72,
272 'linktosections' =>
false,
276 'allrev' =>
'allrev',
277 'owner' =>
'wlowner',
278 'token' =>
'wltoken',
281 'excludeuser' =>
'wlexcludeuser',
285 $wlparams = $this->getWatchlistModule()->getAllowedParams( $flags );
286 foreach ( $copyParams as $from => $to ) {
287 $p = $wlparams[$from];
288 if ( !is_array( $p ) ) {
289 $p = [ ParamValidator::PARAM_DEFAULT => $p ];
294 if ( isset( $p[ParamValidator::PARAM_TYPE] ) && is_array( $p[ParamValidator::PARAM_TYPE] ) &&
297 foreach ( $p[ParamValidator::PARAM_TYPE] as $v ) {
306 foreach ( $copyParams as $to ) {
316 'action=feedwatchlist'
317 =>
'apihelp-feedwatchlist-example-default',
318 'action=feedwatchlist&allrev=&hours=6'
319 =>
'apihelp-feedwatchlist-example-all6hrs',
324 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Watchlist_feed';
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
This abstract class implements many basic API functions, and is the base of all API classes.
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
getMain()
Get the main module.
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, this is an array mapping those values to $msg...
getResult()
Get the result object.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
This action allows users to get their watchlist items in RSS/Atom formats.
getAllowedParams( $flags=0)
__construct(ApiMain $main, $action, Parser $parser)
getExamplesMessages()
Returns usage examples for this module.
getHelpUrls()
Return links to more detailed help pages about the module.
getCustomPrinter()
This module uses a custom feed wrapper printer.
execute()
Make a nested call to the API to request watchlist items in the last $hours.
This is the main API class, used for both external and internal processing.
Exception used to abort API execution with an error.
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
WebRequest clone which takes values from a provided array.
A base class for outputting syndication feeds (e.g.
A class containing constants representing the names of configuration variables.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
static newFromID( $id, $flags=0)
Create a new Title from an article ID.
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.