getMain() ); } /** * Format the rows (generated by SpecialRecentchanges or SpecialRecentchangeslinked) * as an RSS/Atom feed. */ public function execute() { $config = $this->getConfig(); $this->params = $this->extractRequestParams(); if ( !$config->get( 'Feed' ) ) { $this->dieWithError( 'feed-unavailable' ); } $feedClasses = $config->get( 'FeedClasses' ); if ( !isset( $feedClasses[$this->params['feedformat']] ) ) { $this->dieWithError( 'feed-invalid' ); } $this->getMain()->setCacheMode( 'public' ); if ( !$this->getMain()->getParameter( 'smaxage' ) ) { // T65249: This page gets hit a lot, cache at least 15 seconds. $this->getMain()->setCacheMaxAge( 15 ); } $feedFormat = $this->params['feedformat']; $specialClass = $this->params['target'] !== null ? SpecialRecentChangesLinked::class : SpecialRecentChanges::class; $formatter = $this->getFeedObject( $feedFormat, $specialClass ); // Parameters are passed via the request in the context… :( $context = new DerivativeContext( $this ); $context->setRequest( new DerivativeRequest( $this->getRequest(), $this->params, $this->getRequest()->wasPosted() ) ); // The row-getting functionality should be factored out of ChangesListSpecialPage too… $rc = new $specialClass(); $rc->setContext( $context ); $rows = $rc->getRows(); $feedItems = $rows ? ChangesFeed::buildItems( $rows ) : []; ApiFormatFeedWrapper::setResult( $this->getResult(), $formatter, $feedItems ); } /** * Return a ChannelFeed object. * * @param string $feedFormat Feed's format (either 'rss' or 'atom') * @param string $specialClass Relevant special page name (either 'SpecialRecentChanges' or * 'SpecialRecentChangesLinked') * @return ChannelFeed */ public function getFeedObject( $feedFormat, $specialClass ) { if ( $specialClass === SpecialRecentChangesLinked::class ) { $title = Title::newFromText( $this->params['target'] ); if ( !$title ) { $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $this->params['target'] ) ] ); } $feed = new ChangesFeed( $feedFormat ); $feedObj = $feed->getFeedObject( $this->msg( 'recentchangeslinked-title', $title->getPrefixedText() ) ->inContentLanguage()->text(), $this->msg( 'recentchangeslinked-feed' )->inContentLanguage()->text(), SpecialPage::getTitleFor( 'Recentchangeslinked' )->getFullURL() ); } else { $feed = new ChangesFeed( $feedFormat ); $feedObj = $feed->getFeedObject( $this->msg( 'recentchanges' )->inContentLanguage()->text(), $this->msg( 'recentchanges-feed-description' )->inContentLanguage()->text(), SpecialPage::getTitleFor( 'Recentchanges' )->getFullURL() ); } return $feedObj; } public function getAllowedParams() { $config = $this->getConfig(); $feedFormatNames = array_keys( $config->get( 'FeedClasses' ) ); $ret = [ 'feedformat' => [ ApiBase::PARAM_DFLT => 'rss', ApiBase::PARAM_TYPE => $feedFormatNames, ], 'namespace' => [ ApiBase::PARAM_TYPE => 'namespace', ], 'invert' => false, 'associated' => false, 'days' => [ ApiBase::PARAM_DFLT => 7, ApiBase::PARAM_MIN => 1, ApiBase::PARAM_TYPE => 'integer', ], 'limit' => [ ApiBase::PARAM_DFLT => 50, ApiBase::PARAM_MIN => 1, ApiBase::PARAM_MAX => $config->get( 'FeedLimit' ), ApiBase::PARAM_TYPE => 'integer', ], 'from' => [ ApiBase::PARAM_TYPE => 'timestamp', ], 'hideminor' => false, 'hidebots' => false, 'hideanons' => false, 'hideliu' => false, 'hidepatrolled' => false, 'hidemyself' => false, 'hidecategorization' => false, 'tagfilter' => [ ApiBase::PARAM_TYPE => 'string', ], 'target' => [ ApiBase::PARAM_TYPE => 'string', ], 'showlinkedto' => false, ]; return $ret; } protected function getExamplesMessages() { return [ 'action=feedrecentchanges' => 'apihelp-feedrecentchanges-example-simple', 'action=feedrecentchanges&days=30' => 'apihelp-feedrecentchanges-example-30days', ]; } }