ChangesFeed.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. /**
  3. * Feed for list of changes.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. * http://www.gnu.org/copyleft/gpl.html
  19. *
  20. * @file
  21. */
  22. use MediaWiki\MediaWikiServices;
  23. use MediaWiki\Revision\RevisionRecord;
  24. /**
  25. * Feed to Special:RecentChanges and Special:RecentChangesLinked.
  26. *
  27. * @ingroup Feed
  28. */
  29. class ChangesFeed {
  30. private $format;
  31. /**
  32. * @param string $format Feed's format (either 'rss' or 'atom')
  33. */
  34. public function __construct( $format ) {
  35. $this->format = $format;
  36. }
  37. /**
  38. * Get a ChannelFeed subclass object to use
  39. *
  40. * @param string $title Feed's title
  41. * @param string $description Feed's description
  42. * @param string $url Url of origin page
  43. * @return ChannelFeed|bool ChannelFeed subclass or false on failure
  44. */
  45. public function getFeedObject( $title, $description, $url ) {
  46. global $wgSitename, $wgLanguageCode, $wgFeedClasses;
  47. if ( !isset( $wgFeedClasses[$this->format] ) ) {
  48. return false;
  49. }
  50. if ( !array_key_exists( $this->format, $wgFeedClasses ) ) {
  51. // falling back to atom
  52. $this->format = 'atom';
  53. }
  54. $feedTitle = "$wgSitename - {$title} [$wgLanguageCode]";
  55. return new $wgFeedClasses[$this->format](
  56. $feedTitle, htmlspecialchars( $description ), $url );
  57. }
  58. /**
  59. * Generate the feed items given a row from the database.
  60. * @param object $rows IDatabase resource with recentchanges rows
  61. * @return array
  62. */
  63. public static function buildItems( $rows ) {
  64. $items = [];
  65. # Merge adjacent edits by one user
  66. $sorted = [];
  67. $n = 0;
  68. foreach ( $rows as $obj ) {
  69. if ( $obj->rc_type == RC_EXTERNAL ) {
  70. continue;
  71. }
  72. if ( $n > 0 &&
  73. $obj->rc_type == RC_EDIT &&
  74. $obj->rc_namespace >= 0 &&
  75. $obj->rc_cur_id == $sorted[$n - 1]->rc_cur_id &&
  76. $obj->rc_user_text == $sorted[$n - 1]->rc_user_text ) {
  77. $sorted[$n - 1]->rc_last_oldid = $obj->rc_last_oldid;
  78. } else {
  79. $sorted[$n] = $obj;
  80. $n++;
  81. }
  82. }
  83. $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
  84. foreach ( $sorted as $obj ) {
  85. $title = Title::makeTitle( $obj->rc_namespace, $obj->rc_title );
  86. $talkpage = $nsInfo->hasTalkNamespace( $obj->rc_namespace ) && $title->isValid()
  87. ? $title->getTalkPage()->getFullURL()
  88. : '';
  89. // Skip items with deleted content (avoids partially complete/inconsistent output)
  90. if ( $obj->rc_deleted ) {
  91. continue;
  92. }
  93. if ( $obj->rc_this_oldid ) {
  94. $url = $title->getFullURL( [
  95. 'diff' => $obj->rc_this_oldid,
  96. 'oldid' => $obj->rc_last_oldid,
  97. ] );
  98. } else {
  99. // log entry or something like that.
  100. $url = $title->getFullURL();
  101. }
  102. $items[] = new FeedItem(
  103. $title->getPrefixedText(),
  104. FeedUtils::formatDiff( $obj ),
  105. $url,
  106. $obj->rc_timestamp,
  107. ( $obj->rc_deleted & RevisionRecord::DELETED_USER )
  108. ? wfMessage( 'rev-deleted-user' )->escaped() : $obj->rc_user_text,
  109. $talkpage
  110. );
  111. }
  112. return $items;
  113. }
  114. }