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