MediaWiki REL1_37
ProtectedPagesPager.php
Go to the documentation of this file.
1<?php
25
27
28 public $mConds;
30
33
36
38 private $userCache;
39
57 public function __construct(
58 $form,
59 $conds,
60 $type,
61 $level,
64 $size,
70 ILoadBalancer $loadBalancer,
73 ) {
74 // Set database before parent constructor to avoid setting it there with wfGetDB
75 $this->mDb = $loadBalancer->getConnectionRef( ILoadBalancer::DB_REPLICA );
76 parent::__construct( $form->getContext(), $linkRenderer );
77 $this->mConds = $conds;
78 $this->type = $type ?: 'edit';
79 $this->level = $level;
80 $this->namespace = $namespace;
81 $this->sizetype = $sizetype;
82 $this->size = intval( $size );
83 $this->indefonly = (bool)$indefonly;
84 $this->cascadeonly = (bool)$cascadeonly;
85 $this->noredirect = (bool)$noredirect;
86 $this->linkBatchFactory = $linkBatchFactory;
87 $this->commentStore = $commentStore;
88 $this->userCache = $userCache;
89 }
90
91 public function preprocessResults( $result ) {
92 # Do a link batch query
93 $lb = $this->linkBatchFactory->newLinkBatch();
94 $userids = [];
95
96 foreach ( $result as $row ) {
97 $lb->add( $row->page_namespace, $row->page_title );
98 if ( $row->actor_user !== null ) {
99 $userids[] = $row->actor_user;
100 }
101 }
102
103 // fill LinkBatch with user page and user talk
104 if ( count( $userids ) ) {
105 $this->userCache->doQuery( $userids, [], __METHOD__ );
106 foreach ( $userids as $userid ) {
107 $name = $this->userCache->getProp( $userid, 'name' );
108 if ( $name !== false ) {
109 $lb->add( NS_USER, $name );
110 $lb->add( NS_USER_TALK, $name );
111 }
112 }
113 }
114
115 $lb->execute();
116 }
117
118 protected function getFieldNames() {
119 static $headers = null;
120
121 if ( $headers == [] ) {
122 $headers = [
123 'log_timestamp' => 'protectedpages-timestamp',
124 'pr_page' => 'protectedpages-page',
125 'pr_expiry' => 'protectedpages-expiry',
126 'actor_user' => 'protectedpages-performer',
127 'pr_params' => 'protectedpages-params',
128 'log_comment' => 'protectedpages-reason',
129 ];
130 foreach ( $headers as $key => $val ) {
131 $headers[$key] = $this->msg( $val )->text();
132 }
133 }
134
135 return $headers;
136 }
137
144 public function formatValue( $field, $value ) {
146 $row = $this->mCurrentRow;
148
149 switch ( $field ) {
150 case 'log_timestamp':
151 // when timestamp is null, this is a old protection row
152 if ( $value === null ) {
153 $formatted = Html::rawElement(
154 'span',
155 [ 'class' => 'mw-protectedpages-unknown' ],
156 $this->msg( 'protectedpages-unknown-timestamp' )->escaped()
157 );
158 } else {
159 $formatted = htmlspecialchars( $this->getLanguage()->userTimeAndDate(
160 $value, $this->getUser() ) );
161 }
162 break;
163
164 case 'pr_page':
165 $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
166 if ( !$title ) {
167 $formatted = Html::element(
168 'span',
169 [ 'class' => 'mw-invalidtitle' ],
171 $this->getContext(),
172 $row->page_namespace,
173 $row->page_title
174 )
175 );
176 } else {
177 $formatted = $linkRenderer->makeLink( $title );
178 }
179 if ( $row->page_len !== null ) {
180 $formatted .= $this->getLanguage()->getDirMark() .
181 ' ' . Html::rawElement(
182 'span',
183 [ 'class' => 'mw-protectedpages-length' ],
184 Linker::formatRevisionSize( $row->page_len )
185 );
186 }
187 break;
188
189 case 'pr_expiry':
190 $formatted = htmlspecialchars( $this->getLanguage()->formatExpiry(
191 $value, /* User preference timezone */true, 'infinity', $this->getUser() ) );
192 $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
193 if ( $title && $this->getAuthority()->isAllowed( 'protect' ) ) {
194 $changeProtection = $linkRenderer->makeKnownLink(
195 $title,
196 $this->msg( 'protect_change' )->text(),
197 [],
198 [ 'action' => 'unprotect' ]
199 );
200 $formatted .= ' ' . Html::rawElement(
201 'span',
202 [ 'class' => 'mw-protectedpages-actions' ],
203 $this->msg( 'parentheses' )->rawParams( $changeProtection )->escaped()
204 );
205 }
206 break;
207
208 case 'actor_user':
209 // when timestamp is null, this is a old protection row
210 if ( $row->log_timestamp === null ) {
211 $formatted = Html::rawElement(
212 'span',
213 [ 'class' => 'mw-protectedpages-unknown' ],
214 $this->msg( 'protectedpages-unknown-performer' )->escaped()
215 );
216 } else {
217 $username = $row->actor_name;
218 if ( LogEventsList::userCanBitfield(
219 $row->log_deleted,
221 $this->getUser()
222 ) ) {
223 $formatted = Linker::userLink( $value, $username )
224 . Linker::userToolLinks( $value, $username );
225 } else {
226 $formatted = $this->msg( 'rev-deleted-user' )->escaped();
227 }
228 if ( LogEventsList::isDeleted( $row, LogPage::DELETED_USER ) ) {
229 $formatted = '<span class="history-deleted">' . $formatted . '</span>';
230 }
231 }
232 break;
233
234 case 'pr_params':
235 $params = [];
236 // Messages: restriction-level-sysop, restriction-level-autoconfirmed
237 $params[] = $this->msg( 'restriction-level-' . $row->pr_level )->escaped();
238 if ( $row->pr_cascade ) {
239 $params[] = $this->msg( 'protect-summary-cascade' )->escaped();
240 }
241 $formatted = $this->getLanguage()->commaList( $params );
242 break;
243
244 case 'log_comment':
245 // when timestamp is null, this is an old protection row
246 if ( $row->log_timestamp === null ) {
247 $formatted = Html::rawElement(
248 'span',
249 [ 'class' => 'mw-protectedpages-unknown' ],
250 $this->msg( 'protectedpages-unknown-reason' )->escaped()
251 );
252 } else {
253 if ( LogEventsList::userCanBitfield(
254 $row->log_deleted,
256 $this->getUser()
257 ) ) {
258 $value = $this->commentStore->getComment( 'log_comment', $row )->text;
259 $formatted = Linker::formatComment( $value ?? '' );
260 } else {
261 $formatted = $this->msg( 'rev-deleted-comment' )->escaped();
262 }
263 if ( LogEventsList::isDeleted( $row, LogPage::DELETED_COMMENT ) ) {
264 $formatted = '<span class="history-deleted">' . $formatted . '</span>';
265 }
266 }
267 break;
268
269 default:
270 throw new MWException( "Unknown field '$field'" );
271 }
272
273 return $formatted;
274 }
275
276 public function getQueryInfo() {
277 $dbr = $this->getDatabase();
278 $conds = $this->mConds;
279 $conds[] = 'pr_expiry > ' . $dbr->addQuotes( $dbr->timestamp() ) .
280 ' OR pr_expiry IS NULL';
281 $conds[] = 'page_id=pr_page';
282 $conds[] = 'pr_type=' . $dbr->addQuotes( $this->type );
283
284 if ( $this->sizetype == 'min' ) {
285 $conds[] = 'page_len>=' . $this->size;
286 } elseif ( $this->sizetype == 'max' ) {
287 $conds[] = 'page_len<=' . $this->size;
288 }
289
290 if ( $this->indefonly ) {
291 $infinity = $dbr->addQuotes( $dbr->getInfinity() );
292 $conds[] = "pr_expiry = $infinity OR pr_expiry IS NULL";
293 }
294 if ( $this->cascadeonly ) {
295 $conds[] = 'pr_cascade = 1';
296 }
297 if ( $this->noredirect ) {
298 $conds[] = 'page_is_redirect = 0';
299 }
300
301 if ( $this->level ) {
302 $conds[] = 'pr_level=' . $dbr->addQuotes( $this->level );
303 }
304 if ( $this->namespace !== null ) {
305 $conds[] = 'page_namespace=' . $dbr->addQuotes( $this->namespace );
306 }
307
308 $commentQuery = $this->commentStore->getJoin( 'log_comment' );
309
310 return [
311 'tables' => [
312 'page', 'page_restrictions', 'log_search',
313 'logparen' => [ 'logging', 'actor' ] + $commentQuery['tables'],
314 ],
315 'fields' => [
316 'pr_id',
317 'page_namespace',
318 'page_title',
319 'page_len',
320 'pr_type',
321 'pr_level',
322 'pr_expiry',
323 'pr_cascade',
324 'log_timestamp',
325 'log_deleted',
326 'actor_name',
327 'actor_user'
328 ] + $commentQuery['fields'],
329 'conds' => $conds,
330 'join_conds' => [
331 'log_search' => [
332 'LEFT JOIN', [
333 'ls_field' => 'pr_id', 'ls_value = ' . $dbr->buildStringCast( 'pr_id' )
334 ]
335 ],
336 'logparen' => [
337 'LEFT JOIN', [
338 'ls_log_id = log_id'
339 ]
340 ],
341 'actor' => [
342 'JOIN', [
343 'actor_id=log_actor'
344 ]
345 ]
346 ] + $commentQuery['joins']
347 ];
348 }
349
350 protected function getTableClass() {
351 return parent::getTableClass() . ' mw-protectedpages';
352 }
353
354 public function getIndexField() {
355 return 'pr_id';
356 }
357
358 public function getDefaultSort() {
359 return 'pr_id';
360 }
361
362 protected function isFieldSortable( $field ) {
363 // no index for sorting exists
364 return false;
365 }
366}
const NS_USER
Definition Defines.php:66
const NS_USER_TALK
Definition Defines.php:67
Handle database storage of comments such as edit summaries and log reasons.
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
getContext()
Get the base IContextSource object.
getDatabase()
Get the Database object in use.
LinkRenderer $linkRenderer
static userLink( $userId, $userName, $altUserName=false)
Make user link (or user contributions for unregistered users)
Definition Linker.php:1064
static getInvalidTitleDescription(IContextSource $context, $namespace, $title)
Get a message saying that an invalid title was encountered.
Definition Linker.php:185
static formatRevisionSize( $size)
Definition Linker.php:1820
static userToolLinks( $userId, $userText, $redContribsWhenNoEdits=false, $flags=0, $edits=null, $useParentheses=true)
Generate standard user tool links (talk, contributions, block link, etc.)
Definition Linker.php:1109
static formatComment( $comment, $title=null, $local=false, $wikiId=null)
This function is called by all recent changes variants, by the page history, and by the user contribu...
Definition Linker.php:1372
const DELETED_USER
Definition LogPage.php:41
const DELETED_COMMENT
Definition LogPage.php:40
MediaWiki exception.
Class that generates HTML links for pages.
makeKnownLink( $target, $text=null, array $extraAttribs=[], array $query=[])
makeLink( $target, $text=null, array $extraAttribs=[], array $query=[])
getTableClass()
TablePager relies on mw-datatable for styling, see T214208.
getFieldNames()
An array mapping database field names to a textual description of the field name, for use in the tabl...
preprocessResults( $result)
Pre-process results; useful for performing batch existence checks, etc.
LinkBatchFactory $linkBatchFactory
getQueryInfo()
Provides all parameters needed for the main paged query.
formatValue( $field, $value)
getDefaultSort()
The database field name used as a default sort order.
__construct( $form, $conds, $type, $level, $namespace, $sizetype, $size, $indefonly, $cascadeonly, $noredirect, LinkRenderer $linkRenderer, LinkBatchFactory $linkBatchFactory, ILoadBalancer $loadBalancer, CommentStore $commentStore, UserCache $userCache)
getIndexField()
Returns the name of the index field.If the pager supports multiple orders, it may return an array of ...
isFieldSortable( $field)
Return true if the named field should be sortable by the UI, false otherwise.
Table-based display with a user-selectable sort order.
stdClass $mCurrentRow
Database cluster connection, tracking, load balancing, and transaction manager interface.
getConnectionRef( $i, $groups=[], $domain=false, $flags=0)
Get a live database handle reference for a server index.