IRCColourfulRCFeedFormatter.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. */
  20. use MediaWiki\MediaWikiServices;
  21. /**
  22. * Generates a colourful notification intended for humans on IRC.
  23. *
  24. * @since 1.22
  25. */
  26. class IRCColourfulRCFeedFormatter implements RCFeedFormatter {
  27. /**
  28. * @see RCFeedFormatter::getLine
  29. * @param array $feed
  30. * @param RecentChange $rc
  31. * @param string|null $actionComment
  32. * @return string|null
  33. */
  34. public function getLine( array $feed, RecentChange $rc, $actionComment ) {
  35. global $wgUseRCPatrol, $wgUseNPPatrol, $wgLocalInterwikis,
  36. $wgCanonicalServer, $wgScript;
  37. $attribs = $rc->getAttributes();
  38. if ( $attribs['rc_type'] == RC_CATEGORIZE ) {
  39. // Don't send RC_CATEGORIZE events to IRC feed (T127360)
  40. return null;
  41. }
  42. if ( $attribs['rc_type'] == RC_LOG ) {
  43. // Don't use SpecialPage::getTitleFor, backwards compatibility with
  44. // IRC API which expects "Log".
  45. $titleObj = Title::newFromText( 'Log/' . $attribs['rc_log_type'], NS_SPECIAL );
  46. } else {
  47. $titleObj =& $rc->getTitle();
  48. }
  49. $title = $titleObj->getPrefixedText();
  50. $title = self::cleanupForIRC( $title );
  51. if ( $attribs['rc_type'] == RC_LOG ) {
  52. $url = '';
  53. } else {
  54. $url = $wgCanonicalServer . $wgScript;
  55. if ( $attribs['rc_type'] == RC_NEW ) {
  56. $query = '?oldid=' . $attribs['rc_this_oldid'];
  57. } else {
  58. $query = '?diff=' . $attribs['rc_this_oldid'] . '&oldid=' . $attribs['rc_last_oldid'];
  59. }
  60. if ( $wgUseRCPatrol || ( $attribs['rc_type'] == RC_NEW && $wgUseNPPatrol ) ) {
  61. $query .= '&rcid=' . $attribs['rc_id'];
  62. }
  63. // HACK: We need this hook for WMF's secure server setup
  64. Hooks::run( 'IRCLineURL', [ &$url, &$query, $rc ] );
  65. $url .= $query;
  66. }
  67. if ( $attribs['rc_old_len'] !== null && $attribs['rc_new_len'] !== null ) {
  68. $szdiff = $attribs['rc_new_len'] - $attribs['rc_old_len'];
  69. if ( $szdiff < -500 ) {
  70. $szdiff = "\002$szdiff\002";
  71. } elseif ( $szdiff >= 0 ) {
  72. $szdiff = '+' . $szdiff;
  73. }
  74. // @todo i18n with parentheses in content language?
  75. $szdiff = '(' . $szdiff . ')';
  76. } else {
  77. $szdiff = '';
  78. }
  79. $user = self::cleanupForIRC( $attribs['rc_user_text'] );
  80. if ( $attribs['rc_type'] == RC_LOG ) {
  81. $targetText = $rc->getTitle()->getPrefixedText();
  82. $comment = self::cleanupForIRC( str_replace(
  83. "[[$targetText]]",
  84. "[[\00302$targetText\00310]]",
  85. $actionComment
  86. ) );
  87. $flag = $attribs['rc_log_action'];
  88. } else {
  89. $store = MediaWikiServices::getInstance()->getCommentStore();
  90. $comment = self::cleanupForIRC(
  91. $store->getComment( 'rc_comment', $attribs )->text
  92. );
  93. $flag = '';
  94. if ( !$attribs['rc_patrolled']
  95. && ( $wgUseRCPatrol || $attribs['rc_type'] == RC_NEW && $wgUseNPPatrol )
  96. ) {
  97. $flag .= '!';
  98. }
  99. $flag .= ( $attribs['rc_type'] == RC_NEW ? "N" : "" )
  100. . ( $attribs['rc_minor'] ? "M" : "" ) . ( $attribs['rc_bot'] ? "B" : "" );
  101. }
  102. if ( $feed['add_interwiki_prefix'] === true && $wgLocalInterwikis ) {
  103. // we use the first entry in $wgLocalInterwikis in recent changes feeds
  104. $prefix = $wgLocalInterwikis[0];
  105. } elseif ( $feed['add_interwiki_prefix'] ) {
  106. $prefix = $feed['add_interwiki_prefix'];
  107. } else {
  108. $prefix = false;
  109. }
  110. if ( $prefix !== false ) {
  111. $titleString = "\00314[[\00303$prefix:\00307$title\00314]]";
  112. } else {
  113. $titleString = "\00314[[\00307$title\00314]]";
  114. }
  115. # see http://www.irssi.org/documentation/formats for some colour codes. prefix is \003,
  116. # no colour (\003) switches back to the term default
  117. $fullString = "$titleString\0034 $flag\00310 " .
  118. "\00302$url\003 \0035*\003 \00303$user\003 \0035*\003 $szdiff \00310$comment\003\n";
  119. return $fullString;
  120. }
  121. /**
  122. * Remove newlines, carriage returns and decode html entities
  123. * @param string $text
  124. * @return string
  125. */
  126. public static function cleanupForIRC( $text ) {
  127. return str_replace(
  128. [ "\n", "\r" ],
  129. [ " ", "" ],
  130. Sanitizer::decodeCharReferences( $text )
  131. );
  132. }
  133. }