Merge "Add support for PHP7 random_bytes in favor of mcrypt_create_iv"
[lhc/web/wiklou.git] / includes / logging / BlockLogFormatter.php
1 <?php
2 /**
3 * Formatter for block 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 http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
22 * @since 1.25
23 */
24
25 use MediaWiki\MediaWikiServices;
26
27 /**
28 * This class formats block log entries.
29 *
30 * @since 1.25
31 */
32 class BlockLogFormatter extends LogFormatter {
33 protected function getMessageParameters() {
34 $params = parent::getMessageParameters();
35
36 $title = $this->entry->getTarget();
37 if ( substr( $title->getText(), 0, 1 ) === '#' ) {
38 // autoblock - no user link possible
39 $params[2] = $title->getText();
40 $params[3] = ''; // no user name for gender use
41 } else {
42 // Create a user link for the blocked
43 $username = $title->getText();
44 // @todo Store the user identifier in the parameters
45 // to make this faster for future log entries
46 $targetUser = User::newFromName( $username, false );
47 $params[2] = Message::rawParam( $this->makeUserLink( $targetUser, Linker::TOOL_LINKS_NOBLOCK ) );
48 $params[3] = $username; // plain user name for gender use
49 }
50
51 $subtype = $this->entry->getSubtype();
52 if ( $subtype === 'block' || $subtype === 'reblock' ) {
53 if ( !isset( $params[4] ) ) {
54 // Very old log entry without duration: means infinite
55 $params[4] = 'infinite';
56 }
57 // Localize the duration, and add a tooltip
58 // in English to help visitors from other wikis.
59 // The lrm is needed to make sure that the number
60 // is shown on the correct side of the tooltip text.
61 $durationTooltip = '&lrm;' . htmlspecialchars( $params[4] );
62 $params[4] = Message::rawParam(
63 "<span class='blockExpiry' title='$durationTooltip'>" .
64 $this->context->getLanguage()->translateBlockExpiry(
65 $params[4],
66 $this->context->getUser(),
67 wfTimestamp( TS_UNIX, $this->entry->getTimestamp() )
68 ) .
69 '</span>'
70 );
71 $params[5] = isset( $params[5] ) ?
72 self::formatBlockFlags( $params[5], $this->context->getLanguage() ) : '';
73 }
74
75 return $params;
76 }
77
78 protected function extractParameters() {
79 $params = parent::extractParameters();
80 // Legacy log params returning the params in index 3 and 4, moved to 4 and 5
81 if ( $this->entry->isLegacy() && isset( $params[3] ) ) {
82 if ( isset( $params[4] ) ) {
83 $params[5] = $params[4];
84 }
85 $params[4] = $params[3];
86 $params[3] = '';
87 }
88 return $params;
89 }
90
91 public function getPreloadTitles() {
92 $title = $this->entry->getTarget();
93 // Preload user page for non-autoblocks
94 if ( substr( $title->getText(), 0, 1 ) !== '#' ) {
95 return [ $title->getTalkPage() ];
96 }
97 return [];
98 }
99
100 public function getActionLinks() {
101 $subtype = $this->entry->getSubtype();
102 $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
103 if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) // Action is hidden
104 || !( $subtype === 'block' || $subtype === 'reblock' )
105 || !$this->context->getUser()->isAllowed( 'block' )
106 ) {
107 return '';
108 }
109
110 // Show unblock/change block link
111 $title = $this->entry->getTarget();
112 $links = [
113 $linkRenderer->makeKnownLink(
114 SpecialPage::getTitleFor( 'Unblock', $title->getDBkey() ),
115 $this->msg( 'unblocklink' )->text()
116 ),
117 $linkRenderer->makeKnownLink(
118 SpecialPage::getTitleFor( 'Block', $title->getDBkey() ),
119 $this->msg( 'change-blocklink' )->text()
120 )
121 ];
122
123 return $this->msg( 'parentheses' )->rawParams(
124 $this->context->getLanguage()->pipeList( $links ) )->escaped();
125 }
126
127 /**
128 * Convert a comma-delimited list of block log flags
129 * into a more readable (and translated) form
130 *
131 * @param string $flags Flags to format
132 * @param Language $lang
133 * @return string
134 */
135 public static function formatBlockFlags( $flags, $lang ) {
136 $flags = trim( $flags );
137 if ( $flags === '' ) {
138 return ''; // nothing to do
139 }
140 $flags = explode( ',', $flags );
141 $flagsCount = count( $flags );
142
143 for ( $i = 0; $i < $flagsCount; $i++ ) {
144 $flags[$i] = self::formatBlockFlag( $flags[$i], $lang );
145 }
146
147 return wfMessage( 'parentheses' )->inLanguage( $lang )
148 ->rawParams( $lang->commaList( $flags ) )->escaped();
149 }
150
151 /**
152 * Translate a block log flag if possible
153 *
154 * @param int $flag Flag to translate
155 * @param Language $lang Language object to use
156 * @return string
157 */
158 public static function formatBlockFlag( $flag, $lang ) {
159 static $messages = [];
160
161 if ( !isset( $messages[$flag] ) ) {
162 $messages[$flag] = htmlspecialchars( $flag ); // Fallback
163
164 // For grepping. The following core messages can be used here:
165 // * block-log-flags-angry-autoblock
166 // * block-log-flags-anononly
167 // * block-log-flags-hiddenname
168 // * block-log-flags-noautoblock
169 // * block-log-flags-nocreate
170 // * block-log-flags-noemail
171 // * block-log-flags-nousertalk
172 $msg = wfMessage( 'block-log-flags-' . $flag )->inLanguage( $lang );
173
174 if ( $msg->exists() ) {
175 $messages[$flag] = $msg->escaped();
176 }
177 }
178
179 return $messages[$flag];
180 }
181
182 protected function getParametersForApi() {
183 $entry = $this->entry;
184 $params = $entry->getParameters();
185
186 static $map = [
187 // While this looks wrong to be starting at 5 rather than 4, it's
188 // because getMessageParameters uses $4 for its own purposes.
189 '5::duration',
190 '6:array:flags',
191 '6::flags' => '6:array:flags',
192 ];
193 foreach ( $map as $index => $key ) {
194 if ( isset( $params[$index] ) ) {
195 $params[$key] = $params[$index];
196 unset( $params[$index] );
197 }
198 }
199
200 $subtype = $entry->getSubtype();
201 if ( $subtype === 'block' || $subtype === 'reblock' ) {
202 // Defaults for old log entries missing some fields
203 $params += [
204 '5::duration' => 'infinite',
205 '6:array:flags' => [],
206 ];
207
208 if ( !is_array( $params['6:array:flags'] ) ) {
209 $params['6:array:flags'] = $params['6:array:flags'] === ''
210 ? []
211 : explode( ',', $params['6:array:flags'] );
212 }
213
214 if ( !wfIsInfinity( $params['5::duration'] ) ) {
215 $ts = wfTimestamp( TS_UNIX, $entry->getTimestamp() );
216 $expiry = strtotime( $params['5::duration'], $ts );
217 if ( $expiry !== false && $expiry > 0 ) {
218 $params[':timestamp:expiry'] = $expiry;
219 }
220 }
221 }
222
223 return $params;
224 }
225
226 public function formatParametersForApi() {
227 $ret = parent::formatParametersForApi();
228 if ( isset( $ret['flags'] ) ) {
229 ApiResult::setIndexedTagName( $ret['flags'], 'f' );
230 }
231 return $ret;
232 }
233
234 }