ProtectLogFormatter.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <?php
  2. /**
  3. * Formatter for protect log entries.
  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. * @license GPL-2.0-or-later
  22. * @since 1.26
  23. */
  24. use MediaWiki\MediaWikiServices;
  25. /**
  26. * This class formats protect log entries.
  27. *
  28. * @since 1.26
  29. */
  30. class ProtectLogFormatter extends LogFormatter {
  31. public function getPreloadTitles() {
  32. $subtype = $this->entry->getSubtype();
  33. if ( $subtype === 'move_prot' ) {
  34. $params = $this->extractParameters();
  35. return [ Title::newFromText( $params[3] ) ];
  36. }
  37. return [];
  38. }
  39. protected function getMessageKey() {
  40. $key = parent::getMessageKey();
  41. $params = $this->extractParameters();
  42. if ( isset( $params[4] ) && $params[4] ) {
  43. // Messages: logentry-protect-protect-cascade, logentry-protect-modify-cascade
  44. $key .= '-cascade';
  45. }
  46. return $key;
  47. }
  48. protected function getMessageParameters() {
  49. $params = parent::getMessageParameters();
  50. $subtype = $this->entry->getSubtype();
  51. if ( $subtype === 'protect' || $subtype === 'modify' ) {
  52. $rawParams = $this->entry->getParameters();
  53. if ( isset( $rawParams['details'] ) ) {
  54. $params[3] = $this->createProtectDescription( $rawParams['details'] );
  55. } elseif ( isset( $params[3] ) ) {
  56. // Old way of Restrictions and expiries
  57. $params[3] = $this->context->getLanguage()->getDirMark() . $params[3];
  58. } else {
  59. // Very old way (nothing set)
  60. $params[3] = '';
  61. }
  62. // Cascading flag
  63. if ( isset( $params[4] ) ) {
  64. // handled in getMessageKey
  65. unset( $params[4] );
  66. }
  67. } elseif ( $subtype === 'move_prot' ) {
  68. $oldname = $this->makePageLink( Title::newFromText( $params[3] ), [ 'redirect' => 'no' ] );
  69. $params[3] = Message::rawParam( $oldname );
  70. }
  71. return $params;
  72. }
  73. public function getActionLinks() {
  74. $linkRenderer = $this->getLinkRenderer();
  75. $subtype = $this->entry->getSubtype();
  76. if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) // Action is hidden
  77. || $subtype === 'move_prot' // the move log entry has the right action link
  78. ) {
  79. return '';
  80. }
  81. // Show history link for all changes after the protection
  82. $title = $this->entry->getTarget();
  83. $links = [
  84. $linkRenderer->makeLink( $title,
  85. $this->msg( 'hist' )->text(),
  86. [],
  87. [
  88. 'action' => 'history',
  89. 'offset' => $this->entry->getTimestamp(),
  90. ]
  91. )
  92. ];
  93. // Show change protection link
  94. if ( MediaWikiServices::getInstance()
  95. ->getPermissionManager()
  96. ->userHasRight( $this->context->getUser(), 'protect' )
  97. ) {
  98. $links[] = $linkRenderer->makeKnownLink(
  99. $title,
  100. $this->msg( 'protect_change' )->text(),
  101. [],
  102. [ 'action' => 'protect' ]
  103. );
  104. }
  105. return $this->msg( 'parentheses' )->rawParams(
  106. $this->context->getLanguage()->pipeList( $links ) )->escaped();
  107. }
  108. protected function getParametersForApi() {
  109. $entry = $this->entry;
  110. $subtype = $this->entry->getSubtype();
  111. $params = $entry->getParameters();
  112. $map = [];
  113. if ( $subtype === 'protect' || $subtype === 'modify' ) {
  114. $map = [
  115. '4::description',
  116. '5:bool:cascade',
  117. 'details' => ':array:details',
  118. ];
  119. } elseif ( $subtype === 'move_prot' ) {
  120. $map = [
  121. '4:title:oldtitle',
  122. '4::oldtitle' => '4:title:oldtitle',
  123. ];
  124. }
  125. foreach ( $map as $index => $key ) {
  126. if ( isset( $params[$index] ) ) {
  127. $params[$key] = $params[$index];
  128. unset( $params[$index] );
  129. }
  130. }
  131. // Change string to explicit boolean
  132. if ( isset( $params['5:bool:cascade'] ) && is_string( $params['5:bool:cascade'] ) ) {
  133. $params['5:bool:cascade'] = $params['5:bool:cascade'] === 'cascade';
  134. }
  135. return $params;
  136. }
  137. public function formatParametersForApi() {
  138. $ret = parent::formatParametersForApi();
  139. if ( isset( $ret['details'] ) && is_array( $ret['details'] ) ) {
  140. $contLang = MediaWikiServices::getInstance()->getContentLanguage();
  141. foreach ( $ret['details'] as &$detail ) {
  142. if ( isset( $detail['expiry'] ) ) {
  143. $detail['expiry'] = $contLang->
  144. formatExpiry( $detail['expiry'], TS_ISO_8601, 'infinite' );
  145. }
  146. }
  147. }
  148. return $ret;
  149. }
  150. /**
  151. * Create the protect description to show in the log formatter
  152. *
  153. * @param array $details
  154. * @return string
  155. */
  156. public function createProtectDescription( array $details ) {
  157. $protectDescription = '';
  158. foreach ( $details as $param ) {
  159. $expiryText = $this->formatExpiry( $param['expiry'] );
  160. // Messages: restriction-edit, restriction-move, restriction-create,
  161. // restriction-upload
  162. $action = $this->context->msg( 'restriction-' . $param['type'] )->escaped();
  163. $protectionLevel = $param['level'];
  164. // Messages: protect-level-autoconfirmed, protect-level-sysop
  165. $message = $this->context->msg( 'protect-level-' . $protectionLevel );
  166. if ( $message->isDisabled() ) {
  167. // Require "$1" permission
  168. $restrictions = $this->context->msg( "protect-fallback", $protectionLevel )->parse();
  169. } else {
  170. $restrictions = $message->escaped();
  171. }
  172. if ( $protectDescription !== '' ) {
  173. $protectDescription .= $this->context->msg( 'word-separator' )->escaped();
  174. }
  175. $protectDescription .= $this->context->msg( 'protect-summary-desc' )
  176. ->params( $action, $restrictions, $expiryText )->escaped();
  177. }
  178. return $protectDescription;
  179. }
  180. private function formatExpiry( $expiry ) {
  181. if ( wfIsInfinity( $expiry ) ) {
  182. return $this->context->msg( 'protect-expiry-indefinite' )->text();
  183. }
  184. $lang = $this->context->getLanguage();
  185. $user = $this->context->getUser();
  186. return $this->context->msg(
  187. 'protect-expiring-local',
  188. $lang->userTimeAndDate( $expiry, $user ),
  189. $lang->userDate( $expiry, $user ),
  190. $lang->userTime( $expiry, $user )
  191. )->text();
  192. }
  193. }