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