MediaWiki REL1_34
ApiFeedContributions.php
Go to the documentation of this file.
1<?php
28
33
36
38 private $titleParser;
39
45 public function getCustomPrinter() {
46 return new ApiFormatFeedWrapper( $this->getMain() );
47 }
48
49 public function execute() {
50 $this->revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
51 $this->titleParser = MediaWikiServices::getInstance()->getTitleParser();
52
53 $params = $this->extractRequestParams();
54
55 $config = $this->getConfig();
56 if ( !$config->get( 'Feed' ) ) {
57 $this->dieWithError( 'feed-unavailable' );
58 }
59
60 $feedClasses = $config->get( 'FeedClasses' );
61 if ( !isset( $feedClasses[$params['feedformat']] ) ) {
62 $this->dieWithError( 'feed-invalid' );
63 }
64
65 if ( $params['showsizediff'] && $this->getConfig()->get( 'MiserMode' ) ) {
66 $this->dieWithError( 'apierror-sizediffdisabled' );
67 }
68
69 $msg = wfMessage( 'Contributions' )->inContentLanguage()->text();
70 $feedTitle = $config->get( 'Sitename' ) . ' - ' . $msg .
71 ' [' . $config->get( 'LanguageCode' ) . ']';
72 $feedUrl = SpecialPage::getTitleFor( 'Contributions', $params['user'] )->getFullURL();
73
74 try {
75 $target = $this->titleParser
76 ->parseTitle( $params['user'], NS_USER )
77 ->getText();
78 } catch ( MalformedTitleException $e ) {
79 $this->dieWithError(
80 [ 'apierror-baduser', 'user', wfEscapeWikiText( $params['user'] ) ],
81 'baduser_' . $this->encodeParamName( 'user' )
82 );
83 }
84
85 $feed = new $feedClasses[$params['feedformat']] (
86 $feedTitle,
87 htmlspecialchars( $msg ),
88 $feedUrl
89 );
90
91 // Convert year/month parameters to end parameter
92 $params['start'] = '';
93 $params['end'] = '';
94 $params = ContribsPager::processDateFilter( $params );
95
96 $pager = new ContribsPager( $this->getContext(), [
97 'target' => $target,
98 'namespace' => $params['namespace'],
99 'start' => $params['start'],
100 'end' => $params['end'],
101 'tagFilter' => $params['tagfilter'],
102 'deletedOnly' => $params['deletedonly'],
103 'topOnly' => $params['toponly'],
104 'newOnly' => $params['newonly'],
105 'hideMinor' => $params['hideminor'],
106 'showSizeDiff' => $params['showsizediff'],
107 ] );
108
109 $feedLimit = $this->getConfig()->get( 'FeedLimit' );
110 if ( $pager->getLimit() > $feedLimit ) {
111 $pager->setLimit( $feedLimit );
112 }
113
114 $feedItems = [];
115 if ( $pager->getNumRows() > 0 ) {
116 $count = 0;
117 $limit = $pager->getLimit();
118 foreach ( $pager->mResult as $row ) {
119 // ContribsPager selects one more row for navigation, skip that row
120 if ( ++$count > $limit ) {
121 break;
122 }
123 $item = $this->feedItem( $row );
124 if ( $item !== null ) {
125 $feedItems[] = $item;
126 }
127 }
128 }
129
130 ApiFormatFeedWrapper::setResult( $this->getResult(), $feed, $feedItems );
131 }
132
133 protected function feedItem( $row ) {
134 // This hook is the api contributions equivalent to the
135 // ContributionsLineEnding hook. Hook implementers may cancel
136 // the hook to signal the user is not allowed to read this item.
137 $feedItem = null;
138 $hookResult = Hooks::run(
139 'ApiFeedContributions::feedItem',
140 [ $row, $this->getContext(), &$feedItem ]
141 );
142 // Hook returned a valid feed item
143 if ( $feedItem instanceof FeedItem ) {
144 return $feedItem;
145 // Hook was canceled and did not return a valid feed item
146 } elseif ( !$hookResult ) {
147 return null;
148 }
149
150 // Hook completed and did not return a valid feed item
151 $title = Title::makeTitle( (int)$row->page_namespace, $row->page_title );
152 $user = $this->getUser();
153
154 if ( $title && $this->getPermissionManager()->userCan( 'read', $user, $title ) ) {
155 $date = $row->rev_timestamp;
156 $comments = $title->getTalkPage()->getFullURL();
157 $revision = $this->revisionStore->newRevisionFromRow( $row );
158
159 return new FeedItem(
160 $title->getPrefixedText(),
161 $this->feedItemDesc( $revision ),
162 $title->getFullURL( [ 'diff' => $revision->getId() ] ),
163 $date,
164 $this->feedItemAuthor( $revision ),
165 $comments
166 );
167 }
168
169 return null;
170 }
171
177 protected function feedItemAuthor( RevisionRecord $revision ) {
178 $user = $revision->getUser();
179 return $user ? $user->getName() : '';
180 }
181
187 protected function feedItemDesc( RevisionRecord $revision ) {
188 $msg = wfMessage( 'colon-separator' )->inContentLanguage()->text();
189 try {
190 $content = $revision->getContent( SlotRecord::MAIN );
191 } catch ( RevisionAccessException $e ) {
192 $content = null;
193 }
194
195 if ( $content instanceof TextContent ) {
196 // only textual content has a "source view".
197 $html = nl2br( htmlspecialchars( $content->getText() ) );
198 } else {
199 // XXX: we could get an HTML representation of the content via getParserOutput, but that may
200 // contain JS magic and generally may not be suitable for inclusion in a feed.
201 // Perhaps Content should have a getDescriptiveHtml method and/or a getSourceText method.
202 // Compare also FeedUtils::formatDiffRow.
203 $html = '';
204 }
205
206 $comment = $revision->getComment();
207
208 return '<p>' . htmlspecialchars( $this->feedItemAuthor( $revision ) ) . $msg .
209 htmlspecialchars( FeedItem::stripComment( $comment ? $comment->text : '' ) ) .
210 "</p>\n<hr />\n<div>" . $html . '</div>';
211 }
212
213 public function getAllowedParams() {
214 $feedFormatNames = array_keys( $this->getConfig()->get( 'FeedClasses' ) );
215
216 $ret = [
217 'feedformat' => [
218 ApiBase::PARAM_DFLT => 'rss',
219 ApiBase::PARAM_TYPE => $feedFormatNames
220 ],
221 'user' => [
222 ApiBase::PARAM_TYPE => 'user',
224 ],
225 'namespace' => [
226 ApiBase::PARAM_TYPE => 'namespace'
227 ],
228 'year' => [
229 ApiBase::PARAM_TYPE => 'integer'
230 ],
231 'month' => [
232 ApiBase::PARAM_TYPE => 'integer'
233 ],
234 'tagfilter' => [
238 ],
239 'deletedonly' => false,
240 'toponly' => false,
241 'newonly' => false,
242 'hideminor' => false,
243 'showsizediff' => [
244 ApiBase::PARAM_DFLT => false,
245 ],
246 ];
247
248 if ( $this->getConfig()->get( 'MiserMode' ) ) {
249 $ret['showsizediff'][ApiBase::PARAM_HELP_MSG] = 'api-help-param-disabled-in-miser-mode';
250 }
251
252 return $ret;
253 }
254
255 protected function getExamplesMessages() {
256 return [
257 'action=feedcontributions&user=Example'
258 => 'apihelp-feedcontributions-example-simple',
259 ];
260 }
261}
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:42
const PARAM_REQUIRED
(boolean) Is the parameter required?
Definition ApiBase.php:118
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
Definition ApiBase.php:739
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
Definition ApiBase.php:2014
getMain()
Get the main module.
Definition ApiBase.php:536
const PARAM_TYPE
(string|string[]) Either an array of allowed value strings, or a string type as described below.
Definition ApiBase.php:94
const PARAM_DFLT
(null|boolean|integer|string) Default value of the parameter.
Definition ApiBase.php:55
getPermissionManager()
Obtain a PermissionManager instance that subclasses may use in their authorization checks.
Definition ApiBase.php:710
getResult()
Get the result object.
Definition ApiBase.php:640
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:761
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition ApiBase.php:131
const PARAM_ISMULTI
(boolean) Accept multiple pipe-separated values for this parameter (e.g.
Definition ApiBase.php:58
feedItemDesc(RevisionRecord $revision)
feedItemAuthor(RevisionRecord $revision)
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
getCustomPrinter()
This module uses a custom feed wrapper printer.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getExamplesMessages()
Returns usage examples for this module.
This printer is used to wrap an instance of the Feed class.
static setResult( $result, $feed, $feedItems)
Call this method to initialize output data.
static listDefinedTags()
Basically lists defined tags which count even if they aren't applied to anything.
getContext()
Get the base IContextSource object.
static processDateFilter(array $opts)
Set up date filter options, given request data.
A base class for outputting syndication feeds (e.g.
Definition FeedItem.php:33
static stripComment( $text)
Quickie hack... strip out wikilinks to more legible form from the comment.
Definition FeedItem.php:218
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Exception representing a failure to look up a revision.
Page revision base class.
getComment( $audience=self::FOR_PUBLIC, User $user=null)
Fetch revision comment, if it's available to the specified audience.
getContent( $role, $audience=self::FOR_PUBLIC, User $user=null)
Returns the Content of the given slot of this revision.
getUser( $audience=self::FOR_PUBLIC, User $user=null)
Fetch revision's author's user identity, if it's available to the specified audience.
Service for looking up page revisions.
Value object representing a content slot associated with a page revision.
Content object implementation for representing flat text.
const NS_USER
Definition Defines.php:71
A title parser service for MediaWiki.
$content
Definition router.php:78