Merge "Move up devunt's name to Developers"
[lhc/web/wiklou.git] / includes / api / ApiFeedRecentChanges.php
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 * @since 1.23
20 */
21
22 /**
23 * Recent changes feed.
24 *
25 * @ingroup API
26 */
27 class ApiFeedRecentChanges extends ApiBase {
28
29 private $params;
30
31 /**
32 * This module uses a custom feed wrapper printer.
33 *
34 * @return ApiFormatFeedWrapper
35 */
36 public function getCustomPrinter() {
37 return new ApiFormatFeedWrapper( $this->getMain() );
38 }
39
40 /**
41 * Format the rows (generated by SpecialRecentchanges or SpecialRecentchangeslinked)
42 * as an RSS/Atom feed.
43 */
44 public function execute() {
45 $config = $this->getConfig();
46
47 $this->params = $this->extractRequestParams();
48
49 if ( !$config->get( 'Feed' ) ) {
50 $this->dieUsage( 'Syndication feeds are not available', 'feed-unavailable' );
51 }
52
53 $feedClasses = $config->get( 'FeedClasses' );
54 if ( !isset( $feedClasses[$this->params['feedformat']] ) ) {
55 $this->dieUsage( 'Invalid subscription feed type', 'feed-invalid' );
56 }
57
58 $this->getMain()->setCacheMode( 'public' );
59 if ( !$this->getMain()->getParameter( 'smaxage' ) ) {
60 // bug 63249: This page gets hit a lot, cache at least 15 seconds.
61 $this->getMain()->setCacheMaxAge( 15 );
62 }
63
64 $feedFormat = $this->params['feedformat'];
65 $specialClass = $this->params['target'] !== null
66 ? 'SpecialRecentchangeslinked'
67 : 'SpecialRecentchanges';
68
69 $formatter = $this->getFeedObject( $feedFormat, $specialClass );
70
71 // Parameters are passed via the request in the context… :(
72 $context = new DerivativeContext( $this );
73 $context->setRequest( new DerivativeRequest(
74 $this->getRequest(),
75 $this->params,
76 $this->getRequest()->wasPosted()
77 ) );
78
79 // The row-getting functionality should be factored out of ChangesListSpecialPage too…
80 $rc = new $specialClass();
81 $rc->setContext( $context );
82 $rows = $rc->getRows();
83
84 $feedItems = $rows ? ChangesFeed::buildItems( $rows ) : [];
85
86 ApiFormatFeedWrapper::setResult( $this->getResult(), $formatter, $feedItems );
87 }
88
89 /**
90 * Return a ChannelFeed object.
91 *
92 * @param string $feedFormat Feed's format (either 'rss' or 'atom')
93 * @param string $specialClass Relevant special page name (either 'SpecialRecentchanges' or
94 * 'SpecialRecentchangeslinked')
95 * @return ChannelFeed
96 */
97 public function getFeedObject( $feedFormat, $specialClass ) {
98 if ( $specialClass === 'SpecialRecentchangeslinked' ) {
99 $title = Title::newFromText( $this->params['target'] );
100 if ( !$title ) {
101 $this->dieUsageMsg( [ 'invalidtitle', $this->params['target'] ] );
102 }
103
104 $feed = new ChangesFeed( $feedFormat, false );
105 $feedObj = $feed->getFeedObject(
106 $this->msg( 'recentchangeslinked-title', $title->getPrefixedText() )
107 ->inContentLanguage()->text(),
108 $this->msg( 'recentchangeslinked-feed' )->inContentLanguage()->text(),
109 SpecialPage::getTitleFor( 'Recentchangeslinked' )->getFullURL()
110 );
111 } else {
112 $feed = new ChangesFeed( $feedFormat, 'rcfeed' );
113 $feedObj = $feed->getFeedObject(
114 $this->msg( 'recentchanges' )->inContentLanguage()->text(),
115 $this->msg( 'recentchanges-feed-description' )->inContentLanguage()->text(),
116 SpecialPage::getTitleFor( 'Recentchanges' )->getFullURL()
117 );
118 }
119
120 return $feedObj;
121 }
122
123 public function getAllowedParams() {
124 $config = $this->getConfig();
125 $feedFormatNames = array_keys( $config->get( 'FeedClasses' ) );
126
127 $ret = [
128 'feedformat' => [
129 ApiBase::PARAM_DFLT => 'rss',
130 ApiBase::PARAM_TYPE => $feedFormatNames,
131 ],
132
133 'namespace' => [
134 ApiBase::PARAM_TYPE => 'namespace',
135 ],
136 'invert' => false,
137 'associated' => false,
138
139 'days' => [
140 ApiBase::PARAM_DFLT => 7,
141 ApiBase::PARAM_MIN => 1,
142 ApiBase::PARAM_TYPE => 'integer',
143 ],
144 'limit' => [
145 ApiBase::PARAM_DFLT => 50,
146 ApiBase::PARAM_MIN => 1,
147 ApiBase::PARAM_MAX => $config->get( 'FeedLimit' ),
148 ApiBase::PARAM_TYPE => 'integer',
149 ],
150 'from' => [
151 ApiBase::PARAM_TYPE => 'timestamp',
152 ],
153
154 'hideminor' => false,
155 'hidebots' => false,
156 'hideanons' => false,
157 'hideliu' => false,
158 'hidepatrolled' => false,
159 'hidemyself' => false,
160 'hidecategorization' => false,
161
162 'tagfilter' => [
163 ApiBase::PARAM_TYPE => 'string',
164 ],
165
166 'target' => [
167 ApiBase::PARAM_TYPE => 'string',
168 ],
169 'showlinkedto' => false,
170 ];
171
172 if ( $config->get( 'AllowCategorizedRecentChanges' ) ) {
173 $ret += [
174 'categories' => [
175 ApiBase::PARAM_TYPE => 'string',
176 ApiBase::PARAM_ISMULTI => true,
177 ],
178 'categories_any' => false,
179 ];
180 }
181
182 return $ret;
183 }
184
185 protected function getExamplesMessages() {
186 return [
187 'action=feedrecentchanges'
188 => 'apihelp-feedrecentchanges-example-simple',
189 'action=feedrecentchanges&days=30'
190 => 'apihelp-feedrecentchanges-example-30days',
191 ];
192 }
193 }