MediaWiki  master
ProtectedPagesPager.php
Go to the documentation of this file.
1 <?php
25 
27 
28  public $mConds;
30 
33 
35  private $commentStore;
36 
38  private $userCache;
39 
57  public function __construct(
58  $form,
59  $conds,
60  $type,
61  $level,
62  $namespace,
63  $sizetype,
64  $size,
65  $indefonly,
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;
147  $linkRenderer = $this->getLinkRenderer();
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;
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  }
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 {
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  }
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 }
ProtectedPagesPager\$level
$level
Definition: ProtectedPagesPager.php:29
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:1068
ProtectedPagesPager\isFieldSortable
isFieldSortable( $field)
Return true if the named field should be sortable by the UI, false otherwise.
Definition: ProtectedPagesPager.php:362
ProtectedPagesPager\formatValue
formatValue( $field, $value)
Definition: ProtectedPagesPager.php:144
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:354
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:1113
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:545
IndexPager\getDatabase
getDatabase()
Get the Database object in use.
Definition: IndexPager.php:244
ProtectedPagesPager\$userCache
UserCache $userCache
Definition: ProtectedPagesPager.php:38
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:276
ProtectedPagesPager\getDefaultSort
getDefaultSort()
The database field name used as a default sort order.
Definition: ProtectedPagesPager.php:358
ProtectedPagesPager\$type
$type
Definition: ProtectedPagesPager.php:29
ProtectedPagesPager\getTableClass
getTableClass()
TablePager relies on mw-datatable for styling, see T214208.
Definition: ProtectedPagesPager.php:350
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:189
ContextSource\getUser
getUser()
Definition: ContextSource.php:136
ProtectedPagesPager\$namespace
$namespace
Definition: ProtectedPagesPager.php:29
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:91
$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:29
LogPage\DELETED_COMMENT
const DELETED_COMMENT
Definition: LogPage.php:40
ProtectedPagesPager\$cascadeonly
$cascadeonly
Definition: ProtectedPagesPager.php:29
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:35
ProtectedPagesPager\$linkBatchFactory
LinkBatchFactory $linkBatchFactory
Definition: ProtectedPagesPager.php:32
$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:229
ProtectedPagesPager\$indefonly
$indefonly
Definition: ProtectedPagesPager.php:29
Title\makeTitleSafe
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:706
ContextSource\getAuthority
getAuthority()
Definition: ContextSource.php:144
ProtectedPagesPager\__construct
__construct( $form, $conds, $type, $level, $namespace, $sizetype, $size, $indefonly, $cascadeonly, $noredirect, LinkRenderer $linkRenderer, LinkBatchFactory $linkBatchFactory, ILoadBalancer $loadBalancer, CommentStore $commentStore, UserCache $userCache)
Definition: ProtectedPagesPager.php:57
Linker\formatRevisionSize
static formatRevisionSize( $size)
Definition: Linker.php:1822
IndexPager\getLinkRenderer
getLinkRenderer()
Definition: IndexPager.php:980
NS_USER
const NS_USER
Definition: Defines.php:66
Linker\formatComment
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:1376
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:118
ProtectedPagesPager\$noredirect
$noredirect
Definition: ProtectedPagesPager.php:29
LogEventsList\isDeleted
static isDeleted( $row, $field)
Definition: LogEventsList.php:578
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:28
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:232
MediaWiki\Linker\LinkRenderer\makeLink
makeLink( $target, $text=null, array $extraAttribs=[], array $query=[])
Definition: LinkRenderer.php:162
ProtectedPagesPager
Definition: ProtectedPagesPager.php:26
Wikimedia\Rdbms\ILoadBalancer
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: ILoadBalancer.php:81
ProtectedPagesPager\$sizetype
$sizetype
Definition: ProtectedPagesPager.php:29