Merge "mediawiki.api.upload: Use this.defaults.parameters instead of all-custom params"
[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 $config = $this->getConfig();
44
45 $this->params = $this->extractRequestParams();
46
47 if ( !$config->get( 'Feed' ) ) {
48 $this->dieUsage( 'Syndication feeds are not available', 'feed-unavailable' );
49 }
50
51 $feedClasses = $config->get( 'FeedClasses' );
52 if ( !isset( $feedClasses[$this->params['feedformat']] ) ) {
53 $this->dieUsage( 'Invalid subscription feed type', 'feed-invalid' );
54 }
55
56 $this->getMain()->setCacheMode( 'public' );
57 if ( !$this->getMain()->getParameter( 'smaxage' ) ) {
58 // bug 63249: This page gets hit a lot, cache at least 15 seconds.
59 $this->getMain()->setCacheMaxAge( 15 );
60 }
61
62 $feedFormat = $this->params['feedformat'];
63 $specialClass = $this->params['target'] !== null
64 ? 'SpecialRecentchangeslinked'
65 : 'SpecialRecentchanges';
66
67 $formatter = $this->getFeedObject( $feedFormat, $specialClass );
68
69 // Parameters are passed via the request in the context… :(
70 $context = new DerivativeContext( $this );
71 $context->setRequest( new DerivativeRequest(
72 $this->getRequest(),
73 $this->params,
74 $this->getRequest()->wasPosted()
75 ) );
76
77 // The row-getting functionality should be factored out of ChangesListSpecialPage too…
78 $rc = new $specialClass();
79 $rc->setContext( $context );
80 $rows = $rc->getRows();
81
82 $feedItems = $rows ? ChangesFeed::buildItems( $rows ) : array();
83
84 ApiFormatFeedWrapper::setResult( $this->getResult(), $formatter, $feedItems );
85 }
86
87 /**
88 * Return a ChannelFeed object.
89 *
90 * @param string $feedFormat Feed's format (either 'rss' or 'atom')
91 * @param string $specialClass Relevant special page name (either 'SpecialRecentchanges' or
92 * 'SpecialRecentchangeslinked')
93 * @return ChannelFeed
94 */
95 public function getFeedObject( $feedFormat, $specialClass ) {
96 if ( $specialClass === 'SpecialRecentchangeslinked' ) {
97 $title = Title::newFromText( $this->params['target'] );
98 if ( !$title ) {
99 $this->dieUsageMsg( array( 'invalidtitle', $this->params['target'] ) );
100 }
101
102 $feed = new ChangesFeed( $feedFormat, false );
103 $feedObj = $feed->getFeedObject(
104 $this->msg( 'recentchangeslinked-title', $title->getPrefixedText() )
105 ->inContentLanguage()->text(),
106 $this->msg( 'recentchangeslinked-feed' )->inContentLanguage()->text(),
107 SpecialPage::getTitleFor( 'Recentchangeslinked' )->getFullURL()
108 );
109 } else {
110 $feed = new ChangesFeed( $feedFormat, 'rcfeed' );
111 $feedObj = $feed->getFeedObject(
112 $this->msg( 'recentchanges' )->inContentLanguage()->text(),
113 $this->msg( 'recentchanges-feed-description' )->inContentLanguage()->text(),
114 SpecialPage::getTitleFor( 'Recentchanges' )->getFullURL()
115 );
116 }
117
118 return $feedObj;
119 }
120
121 public function getAllowedParams() {
122 $config = $this->getConfig();
123 $feedFormatNames = array_keys( $config->get( 'FeedClasses' ) );
124
125 $ret = array(
126 'feedformat' => array(
127 ApiBase::PARAM_DFLT => 'rss',
128 ApiBase::PARAM_TYPE => $feedFormatNames,
129 ),
130
131 'namespace' => array(
132 ApiBase::PARAM_TYPE => 'namespace',
133 ),
134 'invert' => false,
135 'associated' => false,
136
137 'days' => array(
138 ApiBase::PARAM_DFLT => 7,
139 ApiBase::PARAM_MIN => 1,
140 ApiBase::PARAM_TYPE => 'integer',
141 ),
142 'limit' => array(
143 ApiBase::PARAM_DFLT => 50,
144 ApiBase::PARAM_MIN => 1,
145 ApiBase::PARAM_MAX => $config->get( 'FeedLimit' ),
146 ApiBase::PARAM_TYPE => 'integer',
147 ),
148 'from' => array(
149 ApiBase::PARAM_TYPE => 'timestamp',
150 ),
151
152 'hideminor' => false,
153 'hidebots' => false,
154 'hideanons' => false,
155 'hideliu' => false,
156 'hidepatrolled' => false,
157 'hidemyself' => false,
158
159 'tagfilter' => array(
160 ApiBase::PARAM_TYPE => 'string',
161 ),
162
163 'target' => array(
164 ApiBase::PARAM_TYPE => 'string',
165 ),
166 'showlinkedto' => false,
167 );
168
169 if ( $config->get( 'AllowCategorizedRecentChanges' ) ) {
170 $ret += array(
171 'categories' => array(
172 ApiBase::PARAM_TYPE => 'string',
173 ApiBase::PARAM_ISMULTI => true,
174 ),
175 'categories_any' => false,
176 );
177 }
178
179 return $ret;
180 }
181
182 protected function getExamplesMessages() {
183 return array(
184 'action=feedrecentchanges'
185 => 'apihelp-feedrecentchanges-example-simple',
186 'action=feedrecentchanges&days=30'
187 => 'apihelp-feedrecentchanges-example-30days',
188 );
189 }
190 }