Merge "API: Fix prop=revisions&rvdiffto= without rvprop=content"
[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 /**
30 * This module uses a custom feed wrapper printer.
31 *
32 * @return ApiFormatFeedWrapper
33 */
34 public function getCustomPrinter() {
35 return new ApiFormatFeedWrapper( $this->getMain() );
36 }
37
38 /**
39 * Format the rows (generated by SpecialRecentchanges or SpecialRecentchangeslinked)
40 * as an RSS/Atom feed.
41 */
42 public function execute() {
43 global $wgFeed, $wgFeedClasses;
44
45 $this->params = $this->extractRequestParams();
46
47 if ( !$wgFeed ) {
48 $this->dieUsage( 'Syndication feeds are not available', 'feed-unavailable' );
49 }
50
51 if ( !isset( $wgFeedClasses[$this->params['feedformat']] ) ) {
52 $this->dieUsage( 'Invalid subscription feed type', 'feed-invalid' );
53 }
54
55 $this->getMain()->setCacheMode( 'public' );
56 if ( !$this->getMain()->getParameter( 'smaxage' ) ) {
57 // bug 63249: This page gets hit a lot, cache at least 15 seconds.
58 $this->getMain()->setCacheMaxAge( 15 );
59 }
60
61 $feedFormat = $this->params['feedformat'];
62 $specialClass = $this->params['target'] !== null
63 ? 'SpecialRecentchangeslinked'
64 : 'SpecialRecentchanges';
65
66 $formatter = $this->getFeedObject( $feedFormat, $specialClass );
67
68 // Everything is passed implicitly via $wgRequest… :(
69 // The row-getting functionality should maybe be factored out of ChangesListSpecialPage too…
70 $rc = new $specialClass();
71 $rows = $rc->getRows();
72
73 $feedItems = $rows ? ChangesFeed::buildItems( $rows ) : array();
74
75 ApiFormatFeedWrapper::setResult( $this->getResult(), $formatter, $feedItems );
76 }
77
78 /**
79 * Return a ChannelFeed object.
80 *
81 * @param string $feedFormat Feed's format (either 'rss' or 'atom')
82 * @param string $specialClass Relevant special page name (either 'SpecialRecentchanges' or
83 * 'SpecialRecentchangeslinked')
84 * @return ChannelFeed
85 */
86 public function getFeedObject( $feedFormat, $specialClass ) {
87 if ( $specialClass === 'SpecialRecentchangeslinked' ) {
88 $title = Title::newFromText( $this->params['target'] );
89 if ( !$title ) {
90 $this->dieUsageMsg( array( 'invalidtitle', $this->params['target'] ) );
91 }
92
93 $feed = new ChangesFeed( $feedFormat, false );
94 $feedObj = $feed->getFeedObject(
95 $this->msg( 'recentchangeslinked-title', $title->getPrefixedText() )
96 ->inContentLanguage()->text(),
97 $this->msg( 'recentchangeslinked-feed' )->inContentLanguage()->text(),
98 SpecialPage::getTitleFor( 'Recentchangeslinked' )->getFullURL()
99 );
100 } else {
101 $feed = new ChangesFeed( $feedFormat, 'rcfeed' );
102 $feedObj = $feed->getFeedObject(
103 $this->msg( 'recentchanges' )->inContentLanguage()->text(),
104 $this->msg( 'recentchanges-feed-description' )->inContentLanguage()->text(),
105 SpecialPage::getTitleFor( 'Recentchanges' )->getFullURL()
106 );
107 }
108
109 return $feedObj;
110 }
111
112 public function getAllowedParams() {
113 global $wgFeedClasses, $wgAllowCategorizedRecentChanges, $wgFeedLimit;
114 $feedFormatNames = array_keys( $wgFeedClasses );
115
116 $ret = array(
117 'feedformat' => array(
118 ApiBase::PARAM_DFLT => 'rss',
119 ApiBase::PARAM_TYPE => $feedFormatNames,
120 ),
121
122 'namespace' => array(
123 ApiBase::PARAM_TYPE => 'namespace',
124 ),
125 'invert' => false,
126 'associated' => false,
127
128 'days' => array(
129 ApiBase::PARAM_DFLT => 7,
130 ApiBase::PARAM_MIN => 1,
131 ApiBase::PARAM_TYPE => 'integer',
132 ),
133 'limit' => array(
134 ApiBase::PARAM_DFLT => 50,
135 ApiBase::PARAM_MIN => 1,
136 ApiBase::PARAM_MAX => $wgFeedLimit,
137 ApiBase::PARAM_TYPE => 'integer',
138 ),
139 'from' => array(
140 ApiBase::PARAM_TYPE => 'timestamp',
141 ),
142
143 'hideminor' => false,
144 'hidebots' => false,
145 'hideanons' => false,
146 'hideliu' => false,
147 'hidepatrolled' => false,
148 'hidemyself' => false,
149
150 'tagfilter' => array(
151 ApiBase::PARAM_TYPE => 'string',
152 ),
153
154 'target' => array(
155 ApiBase::PARAM_TYPE => 'string',
156 ),
157 'showlinkedto' => false,
158 );
159
160 if ( $wgAllowCategorizedRecentChanges ) {
161 $ret += array(
162 'categories' => array(
163 ApiBase::PARAM_TYPE => 'string',
164 ApiBase::PARAM_ISMULTI => true,
165 ),
166 'categories_any' => false,
167 );
168 }
169
170 return $ret;
171 }
172
173 public function getParamDescription() {
174 return array(
175 'feedformat' => 'The format of the feed',
176 'namespace' => 'Namespace to limit the results to',
177 'invert' => 'All namespaces but the selected one',
178 'associated' => 'Include associated (talk or main) namespace',
179 'days' => 'Days to limit the results to',
180 'limit' => 'Maximum number of results to return',
181 'from' => 'Show changes since then',
182 'hideminor' => 'Hide minor changes',
183 'hidebots' => 'Hide changes made by bots',
184 'hideanons' => 'Hide changes made by anonymous users',
185 'hideliu' => 'Hide changes made by registered users',
186 'hidepatrolled' => 'Hide patrolled changes',
187 'hidemyself' => 'Hide changes made by yourself',
188 'tagfilter' => 'Filter by tag',
189 'target' => 'Show only changes on pages linked from this page',
190 'showlinkedto' => 'Show changes on pages linked to the selected page instead',
191 'categories' => 'Show only changes on pages in all of these categories',
192 'categories_any' => 'Show only changes on pages in any of the categories instead',
193 );
194 }
195
196 public function getDescription() {
197 return 'Returns a recent changes feed';
198 }
199
200 public function getPossibleErrors() {
201 return array_merge( parent::getPossibleErrors(), array(
202 array( 'code' => 'feed-unavailable', 'info' => 'Syndication feeds are not available' ),
203 array( 'code' => 'feed-invalid', 'info' => 'Invalid subscription feed type' ),
204 ) );
205 }
206
207 public function getExamples() {
208 return array(
209 'api.php?action=feedrecentchanges',
210 'api.php?action=feedrecentchanges&days=30'
211 );
212 }
213 }