MediaWiki  master
LogEventsList.php
Go to the documentation of this file.
1 <?php
34 
36  public const NO_ACTION_LINK = 1;
37  public const NO_EXTRA_USER_LINKS = 2;
38  public const USE_CHECKBOXES = 4;
39 
40  public $flags;
41 
45  protected $showTagEditUI;
46 
50  protected $allowedActions = null;
51 
55  private $linkRenderer;
56 
58  private $hookRunner;
59 
70  public function __construct( $context, $linkRenderer = null, $flags = 0 ) {
71  $this->setContext( $context );
72  $this->flags = $flags;
73  $this->showTagEditUI = ChangeTags::showTagEditingUI( $this->getAuthority() );
74  if ( $linkRenderer instanceof LinkRenderer ) {
75  $this->linkRenderer = $linkRenderer;
76  }
77  $this->hookRunner = new HookRunner( MediaWikiServices::getInstance()->getHookContainer() );
78  }
79 
84  protected function getLinkRenderer() {
85  if ( $this->linkRenderer !== null ) {
86  return $this->linkRenderer;
87  } else {
88  return MediaWikiServices::getInstance()->getLinkRenderer();
89  }
90  }
91 
110  public function showOptions( $types = [], $user = '', $page = '', $pattern = false, $year = 0,
111  $month = 0, $day = 0, $filter = null, $tagFilter = '', $action = null, $extras = [],
112  $tagInvert = false
113  ) {
114  // For B/C, we take strings, but make sure they are converted...
115  $types = ( $types === '' ) ? [] : (array)$types;
116 
117  $formDescriptor = [];
118 
119  // Basic selectors
120  $formDescriptor['type'] = $this->getTypeMenuDesc( $types );
121  $formDescriptor['user'] = $this->getUserInputDesc( $user );
122  $formDescriptor['page'] = $this->getTitleInputDesc( $page );
123 
124  // Title pattern, if allowed
125  if ( !$this->getConfig()->get( MainConfigNames::MiserMode ) ) {
126  $formDescriptor['pattern'] = $this->getTitlePatternDesc( $pattern );
127  }
128 
129  // Add extra inputs if any
130  // This could either be a form descriptor array or a string with raw HTML.
131  // We need it to work in both cases and show a deprecation warning if it
132  // is a string. See T199495.
133  $extraInputsDescriptor = $this->getExtraInputsDesc( $types, $extras );
134  if (
135  is_array( $extraInputsDescriptor ) &&
136  !empty( $extraInputsDescriptor )
137  ) {
138  $formDescriptor[ 'extra' ] = $extraInputsDescriptor;
139  } elseif (
140  is_string( $extraInputsDescriptor ) &&
141  $extraInputsDescriptor !== ''
142  ) {
143  // We'll add this to the footer of the form later
144  $extraInputsString = $extraInputsDescriptor;
145  wfDeprecated( '$input in LogEventsListGetExtraInputs hook', '1.32' );
146  }
147 
148  // Date menu
149  $formDescriptor['date'] = [
150  'type' => 'date',
151  'label-message' => 'date',
152  'default' => $year && $month && $day ? sprintf( "%04d-%02d-%02d", $year, $month, $day ) : '',
153  ];
154 
155  // Tag filter
156  $formDescriptor['tagfilter'] = [
157  'type' => 'tagfilter',
158  'name' => 'tagfilter',
159  'label-message' => 'tag-filter',
160  'default' => $tagFilter,
161  ];
162  $formDescriptor['tagInvert'] = [
163  'type' => 'check',
164  'name' => 'tagInvert',
165  'label-message' => 'invert',
166  'hide-if' => [ '===', 'tagfilter', '' ],
167  'default' => $tagInvert,
168  ];
169 
170  // Filter links
171  if ( $filter ) {
172  $formDescriptor['filters'] = $this->getFiltersDesc( $filter );
173  }
174 
175  // Action filter
176  if (
177  $action !== null &&
178  $this->allowedActions !== null &&
179  count( $this->allowedActions ) > 0
180  ) {
181  $formDescriptor['subtype'] = $this->getActionSelectorDesc( $types, $action );
182  }
183 
184  $context = new DerivativeContext( $this->getContext() );
185  $context->setTitle( SpecialPage::getTitleFor( 'Log' ) ); // Remove subpage
186  $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $context );
187  $htmlForm
188  ->setSubmitTextMsg( 'logeventslist-submit' )
189  ->setMethod( 'GET' )
190  ->setWrapperLegendMsg( 'log' )
191  // T321154
192  ->setFormIdentifier( 'logeventslist' );
193 
194  // TODO This will should be removed at some point. See T199495.
195  if ( isset( $extraInputsString ) ) {
196  $htmlForm->addFooterText( Html::rawElement(
197  'div',
198  [],
199  $extraInputsString
200  ) );
201  }
202 
203  $htmlForm->prepareForm()->displayForm( false );
204  }
205 
210  private function getFiltersDesc( $filter ) {
211  $optionsMsg = [];
212  $default = [];
213  foreach ( $filter as $type => $val ) {
214  $optionsMsg["logeventslist-{$type}-log"] = $type;
215 
216  if ( $val === false ) {
217  $default[] = $type;
218  }
219  }
220  return [
221  'class' => HTMLMultiSelectField::class,
222  'label-message' => 'logeventslist-more-filters',
223  'flatlist' => true,
224  'options-messages' => $optionsMsg,
225  'default' => $default,
226  ];
227  }
228 
233  private function getTypeMenuDesc( $queryTypes ) {
234  $queryType = count( $queryTypes ) == 1 ? $queryTypes[0] : '';
235 
236  $typesByName = []; // Temporary array
237  // First pass to load the log names
238  foreach ( LogPage::validTypes() as $type ) {
239  $page = new LogPage( $type );
240  $restriction = $page->getRestriction();
241  if ( $this->getAuthority()->isAllowed( $restriction ) ) {
242  $typesByName[$type] = $page->getName()->text();
243  }
244  }
245 
246  // Second pass to sort by name
247  asort( $typesByName );
248 
249  // Always put "All public logs" on top
250  $public = $typesByName[''];
251  unset( $typesByName[''] );
252  $typesByName = [ '' => $public ] + $typesByName;
253 
254  return [
255  'class' => HTMLSelectField::class,
256  'name' => 'type',
257  'options' => array_flip( $typesByName ),
258  'default' => $queryType,
259  ];
260  }
261 
266  private function getUserInputDesc( $user ) {
267  return [
268  'class' => HTMLUserTextField::class,
269  'label-message' => 'specialloguserlabel',
270  'name' => 'user',
271  'default' => $user,
272  ];
273  }
274 
279  private function getTitleInputDesc( $page ) {
280  if ( $page instanceof PageReference ) {
281  $titleFormatter = MediaWikiServices::getInstance()->getTitleFormatter();
282  $page = $titleFormatter->getPrefixedText( $page );
283  }
284  return [
285  'class' => HTMLTitleTextField::class,
286  'label-message' => 'speciallogtitlelabel',
287  'name' => 'page',
288  'required' => false,
289  'default' => $page,
290  ];
291  }
292 
297  private function getTitlePatternDesc( $pattern ) {
298  return [
299  'type' => 'check',
300  'label-message' => 'log-title-wildcard',
301  'name' => 'pattern',
302  'default' => $pattern,
303  ];
304  }
305 
311  private function getExtraInputsDesc( $types, $extras ) {
312  if ( count( $types ) == 1 ) {
313  if ( $types[0] == 'suppress' ) {
314  return [
315  'type' => 'text',
316  'label-message' => 'revdelete-offender',
317  'name' => 'offender',
318  'default' => $extras['offender'] ?? '',
319  ];
320  } else {
321  // Allow extensions to add their own extra inputs
322  // This could be an array or string. See T199495.
323  $input = ''; // Deprecated
324  $formDescriptor = [];
325  $this->hookRunner->onLogEventsListGetExtraInputs( $types[0], $this, $input, $formDescriptor );
326 
327  return empty( $formDescriptor ) ? $input : $formDescriptor;
328  }
329  }
330 
331  return [];
332  }
333 
340  private function getActionSelectorDesc( $types, $action ) {
341  $actionOptions = [];
342  $actionOptions[ 'log-action-filter-all' ] = '';
343 
344  foreach ( $this->allowedActions as $value ) {
345  $msgKey = 'log-action-filter-' . $types[0] . '-' . $value;
346  $actionOptions[ $msgKey ] = $value;
347  }
348 
349  return [
350  'class' => HTMLSelectField::class,
351  'name' => 'subtype',
352  'options-messages' => $actionOptions,
353  'default' => $action,
354  'label' => $this->msg( 'log-action-filter-' . $types[0] )->text(),
355  ];
356  }
357 
364  public function setAllowedActions( $actions ) {
365  $this->allowedActions = $actions;
366  }
367 
371  public function beginLogEventsList() {
372  return "<ul class='mw-logevent-loglines'>\n";
373  }
374 
378  public function endLogEventsList() {
379  return "</ul>\n";
380  }
381 
386  public function logLine( $row ) {
387  $entry = DatabaseLogEntry::newFromRow( $row );
388  $formatter = LogFormatter::newFromEntry( $entry );
389  $formatter->setContext( $this->getContext() );
390  $formatter->setLinkRenderer( $this->getLinkRenderer() );
391  $formatter->setShowUserToolLinks( !( $this->flags & self::NO_EXTRA_USER_LINKS ) );
392 
393  $time = $this->getLanguage()->userTimeAndDate(
394  $entry->getTimestamp(),
395  $this->getUser()
396  );
397  // Link the time text to the specific log entry, see T207562
398  $timeLink = $this->getLinkRenderer()->makeKnownLink(
400  $time,
401  [],
402  [ 'logid' => $entry->getId() ]
403  );
404 
405  $action = $formatter->getActionText();
406 
407  if ( $this->flags & self::NO_ACTION_LINK ) {
408  $revert = '';
409  } else {
410  $revert = $formatter->getActionLinks();
411  if ( $revert != '' ) {
412  $revert = '<span class="mw-logevent-actionlink">' . $revert . '</span>';
413  }
414  }
415 
416  $comment = $formatter->getComment();
417 
418  // Some user can hide log items and have review links
419  $del = $this->getShowHideLinks( $row );
420 
421  // Any tags...
422  [ $tagDisplay, $newClasses ] = ChangeTags::formatSummaryRow(
423  $row->ts_tags,
424  'logevent',
425  $this->getContext()
426  );
427  $classes = array_merge(
428  [ 'mw-logline-' . $entry->getType() ],
429  $newClasses
430  );
431  $attribs = [
432  'data-mw-logid' => $entry->getId(),
433  'data-mw-logaction' => $entry->getFullType(),
434  ];
435  $ret = "$del $timeLink $action $comment $revert $tagDisplay";
436 
437  // Let extensions add data
438  $this->hookRunner->onLogEventsListLineEnding( $this, $ret, $entry, $classes, $attribs );
439  $attribs = array_filter( $attribs,
440  [ Sanitizer::class, 'isReservedDataAttribute' ],
441  ARRAY_FILTER_USE_KEY
442  );
443  $attribs['class'] = $classes;
444 
445  return Html::rawElement( 'li', $attribs, $ret ) . "\n";
446  }
447 
452  private function getShowHideLinks( $row ) {
453  // We don't want to see the links and
454  if ( $this->flags == self::NO_ACTION_LINK ) {
455  return '';
456  }
457 
458  // If change tag editing is available to this user, return the checkbox
459  if ( $this->flags & self::USE_CHECKBOXES && $this->showTagEditUI ) {
460  return Xml::check(
461  'showhiderevisions',
462  false,
463  [ 'name' => 'ids[' . $row->log_id . ']' ]
464  );
465  }
466 
467  // no one can hide items from the suppress log.
468  if ( $row->log_type == 'suppress' ) {
469  return '';
470  }
471 
472  $del = '';
473  $authority = $this->getAuthority();
474  // Don't show useless checkbox to people who cannot hide log entries
475  if ( $authority->isAllowed( 'deletedhistory' ) ) {
476  $canHide = $authority->isAllowed( 'deletelogentry' );
477  $canViewSuppressedOnly = $authority->isAllowed( 'viewsuppressed' ) &&
478  !$authority->isAllowed( 'suppressrevision' );
479  $entryIsSuppressed = self::isDeleted( $row, LogPage::DELETED_RESTRICTED );
480  $canViewThisSuppressedEntry = $canViewSuppressedOnly && $entryIsSuppressed;
481  if ( $row->log_deleted || $canHide ) {
482  // Show checkboxes instead of links.
483  if ( $canHide && $this->flags & self::USE_CHECKBOXES && !$canViewThisSuppressedEntry ) {
484  // If event was hidden from sysops
485  if ( !self::userCan( $row, LogPage::DELETED_RESTRICTED, $authority ) ) {
486  $del = Xml::check( 'deleterevisions', false, [ 'disabled' => 'disabled' ] );
487  } else {
488  $del = Xml::check(
489  'showhiderevisions',
490  false,
491  [ 'name' => 'ids[' . $row->log_id . ']' ]
492  );
493  }
494  } else {
495  // If event was hidden from sysops
496  if ( !self::userCan( $row, LogPage::DELETED_RESTRICTED, $authority ) ) {
497  $del = Linker::revDeleteLinkDisabled( $canHide );
498  } else {
499  $query = [
500  'target' => SpecialPage::getTitleFor( 'Log', $row->log_type )->getPrefixedDBkey(),
501  'type' => 'logging',
502  'ids' => $row->log_id,
503  ];
504  $del = Linker::revDeleteLink(
505  $query,
506  $entryIsSuppressed,
507  $canHide && !$canViewThisSuppressedEntry
508  );
509  }
510  }
511  }
512  }
513 
514  return $del;
515  }
516 
523  public static function typeAction( $row, $type, $action ) {
524  $match = is_array( $type ) ?
525  in_array( $row->log_type, $type ) : $row->log_type == $type;
526  if ( $match ) {
527  $match = is_array( $action ) ?
528  in_array( $row->log_action, $action ) : $row->log_action == $action;
529  }
530 
531  return $match;
532  }
533 
543  public static function userCan( $row, $field, Authority $performer ) {
544  return self::userCanBitfield( $row->log_deleted, $field, $performer ) &&
545  self::userCanViewLogType( $row->log_type, $performer );
546  }
547 
557  public static function userCanBitfield( $bitfield, $field, Authority $performer ) {
558  if ( $bitfield & $field ) {
559  if ( $bitfield & LogPage::DELETED_RESTRICTED ) {
560  return $performer->isAllowedAny( 'suppressrevision', 'viewsuppressed' );
561  } else {
562  return $performer->isAllowed( 'deletedhistory' );
563  }
564  }
565  return true;
566  }
567 
576  public static function userCanViewLogType( $type, Authority $performer ) {
577  $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::LogRestrictions );
578  if ( isset( $logRestrictions[$type] ) && !$performer->isAllowed( $logRestrictions[$type] )
579  ) {
580  return false;
581  }
582  return true;
583  }
584 
590  public static function isDeleted( $row, $field ) {
591  return ( $row->log_deleted & $field ) == $field;
592  }
593 
619  public static function showLogExtract(
620  &$out, $types = [], $page = '', $user = '', $param = []
621  ) {
622  $defaultParameters = [
623  'lim' => 25,
624  'conds' => [],
625  'showIfEmpty' => true,
626  'msgKey' => [ '' ],
627  'wrap' => "$1",
628  'flags' => 0,
629  'useRequestParams' => false,
630  'useMaster' => false,
631  'extraUrlParams' => false,
632  ];
633  # The + operator appends elements of remaining keys from the right
634  # handed array to the left handed, whereas duplicated keys are NOT overwritten.
635  $param += $defaultParameters;
636  # Convert $param array to individual variables
637  $lim = $param['lim'];
638  $conds = $param['conds'];
639  $showIfEmpty = $param['showIfEmpty'];
640  $msgKey = $param['msgKey'];
641  $wrap = $param['wrap'];
642  $flags = $param['flags'];
643  $extraUrlParams = $param['extraUrlParams'];
644 
645  $useRequestParams = $param['useRequestParams'];
646  // @phan-suppress-next-line PhanRedundantCondition
647  if ( !is_array( $msgKey ) ) {
648  $msgKey = [ $msgKey ];
649  }
650 
651  if ( $out instanceof OutputPage ) {
652  $context = $out->getContext();
653  } else {
654  $context = RequestContext::getMain();
655  }
656 
657  $services = MediaWikiServices::getInstance();
658  // FIXME: Figure out how to inject this
659  $linkRenderer = $services->getLinkRenderer();
660 
661  # Insert list of top 50 (or top $lim) items
662  $loglist = new LogEventsList( $context, $linkRenderer, $flags );
663  $pager = new LogPager(
664  $loglist,
665  $types,
666  $user,
667  $page,
668  false,
669  $conds,
670  false,
671  false,
672  false,
673  '',
674  '',
675  0,
676  $services->getLinkBatchFactory(),
677  $services->getActorNormalization()
678  );
679  // @phan-suppress-next-line PhanImpossibleCondition
680  if ( !$useRequestParams ) {
681  # Reset vars that may have been taken from the request
682  $pager->mLimit = 50;
683  $pager->mDefaultLimit = 50;
684  $pager->mOffset = "";
685  $pager->mIsBackwards = false;
686  }
687 
688  // @phan-suppress-next-line PhanImpossibleCondition
689  if ( $param['useMaster'] ) {
690  $pager->mDb = wfGetDB( DB_PRIMARY );
691  }
692  // @phan-suppress-next-line PhanImpossibleCondition
693  if ( isset( $param['offset'] ) ) { # Tell pager to ignore WebRequest offset
694  $pager->setOffset( $param['offset'] );
695  }
696 
697  // @phan-suppress-next-line PhanSuspiciousValueComparison
698  if ( $lim > 0 ) {
699  $pager->mLimit = $lim;
700  }
701  // Fetch the log rows and build the HTML if needed
702  $logBody = $pager->getBody();
703  $numRows = $pager->getNumRows();
704 
705  $s = '';
706 
707  if ( $logBody ) {
708  if ( $msgKey[0] ) {
709  // @phan-suppress-next-line PhanParamTooFewUnpack Non-emptiness checked above
710  $msg = $context->msg( ...$msgKey );
711  if ( $page instanceof PageReference ) {
712  $msg->page( $page );
713  }
714  $s .= $msg->parseAsBlock();
715  }
716  $s .= $loglist->beginLogEventsList() .
717  $logBody .
718  $loglist->endLogEventsList();
719  // add styles for change tags
720  $context->getOutput()->addModuleStyles( 'mediawiki.interface.helpers.styles' );
721  // @phan-suppress-next-line PhanRedundantCondition
722  } elseif ( $showIfEmpty ) {
723  $s = Html::rawElement( 'div', [ 'class' => 'mw-warning-logempty' ],
724  $context->msg( 'logempty' )->parse() );
725  }
726 
727  if ( $page instanceof PageReference ) {
728  $titleFormatter = MediaWikiServices::getInstance()->getTitleFormatter();
729  $pageName = $titleFormatter->getPrefixedDBkey( $page );
730  } elseif ( $page != '' ) {
731  $pageName = $page;
732  } else {
733  $pageName = null;
734  }
735 
736  if ( $numRows > $pager->mLimit ) { # Show "Full log" link
737  $urlParam = [];
738  if ( $pageName ) {
739  $urlParam['page'] = $pageName;
740  }
741 
742  if ( $user != '' ) {
743  $urlParam['user'] = $user;
744  }
745 
746  if ( !is_array( $types ) ) { # Make it an array, if it isn't
747  $types = [ $types ];
748  }
749 
750  # If there is exactly one log type, we can link to Special:Log?type=foo
751  if ( count( $types ) == 1 ) {
752  $urlParam['type'] = $types[0];
753  }
754 
755  // @phan-suppress-next-line PhanSuspiciousValueComparison
756  if ( $extraUrlParams !== false ) {
757  $urlParam = array_merge( $urlParam, $extraUrlParams );
758  }
759 
760  $s .= $linkRenderer->makeKnownLink(
761  SpecialPage::getTitleFor( 'Log' ),
762  $context->msg( 'log-fulllog' )->text(),
763  [],
764  $urlParam
765  );
766  }
767 
768  if ( $logBody && $msgKey[0] ) {
769  // TODO: The condition above is weird. Should this be done in any other cases?
770  // Or is it always true in practice?
771 
772  // Mark as interface language (T60685)
773  $dir = $context->getLanguage()->getDir();
774  $lang = $context->getLanguage()->getHtmlCode();
775  $s = Html::rawElement( 'div', [
776  'class' => "mw-content-$dir",
777  'dir' => $dir,
778  'lang' => $lang,
779  ], $s );
780 
781  // Wrap in warning box
782  $s = Html::warningBox(
783  $s,
784  'mw-warning-with-logexcerpt'
785  );
786  }
787 
788  // @phan-suppress-next-line PhanSuspiciousValueComparison, PhanRedundantCondition
789  if ( $wrap != '' ) { // Wrap message in html
790  $s = str_replace( '$1', $s, $wrap );
791  }
792 
793  /* hook can return false, if we don't want the message to be emitted (Wikia BugId:7093) */
794  $hookRunner = new HookRunner( $services->getHookContainer() );
795  if ( $hookRunner->onLogEventsListShowLogExtract( $s, $types, $pageName, $user, $param ) ) {
796  // $out can be either an OutputPage object or a String-by-reference
797  if ( $out instanceof OutputPage ) {
798  $out->addHTML( $s );
799  } else {
800  $out = $s;
801  }
802  }
803 
804  return $numRows;
805  }
806 
816  public static function getExcludeClause( $db, $audience = 'public', Authority $performer = null ) {
817  $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::LogRestrictions );
818 
819  if ( $audience != 'public' && $performer === null ) {
820  throw new InvalidArgumentException(
821  'A User object must be given when checking for a user audience.'
822  );
823  }
824 
825  // Reset the array, clears extra "where" clauses when $par is used
826  $hiddenLogs = [];
827 
828  // Don't show private logs to unprivileged users
829  foreach ( $logRestrictions as $logType => $right ) {
830  if ( $audience == 'public' || !$performer->isAllowed( $right )
831  ) {
832  $hiddenLogs[] = $logType;
833  }
834  }
835  if ( count( $hiddenLogs ) == 1 ) {
836  return 'log_type != ' . $db->addQuotes( $hiddenLogs[0] );
837  } elseif ( $hiddenLogs ) {
838  return 'log_type NOT IN (' . $db->makeList( $hiddenLogs ) . ')';
839  }
840 
841  return false;
842  }
843 }
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
static showTagEditingUI(Authority $performer)
Indicate whether change tag editing UI is relevant.
static formatSummaryRow( $tags, $unused, MessageLocalizer $localizer=null)
Creates HTML for the given tags.
Definition: ChangeTags.php:162
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
getContext()
Get the base IContextSource object.
setContext(IContextSource $context)
static newFromRow( $row)
Constructs new LogEntry from database result row.
An IContextSource implementation which will inherit context from another source but allow individual ...
static factory( $displayFormat, $descriptor, IContextSource $context, $messagePrefix='')
Construct a HTMLForm object for given display type.
Definition: HTMLForm.php:354
const NO_EXTRA_USER_LINKS
static typeAction( $row, $type, $action)
showOptions( $types=[], $user='', $page='', $pattern=false, $year=0, $month=0, $day=0, $filter=null, $tagFilter='', $action=null, $extras=[], $tagInvert=false)
Show options for the log list.
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
static getExcludeClause( $db, $audience='public', Authority $performer=null)
SQL clause to skip forbidden log types for this user.
static userCan( $row, $field, Authority $performer)
Determine if the current user is allowed to view a particular field of this log row,...
static userCanBitfield( $bitfield, $field, Authority $performer)
Determine if the current user is allowed to view a particular field of this log row,...
__construct( $context, $linkRenderer=null, $flags=0)
const NO_ACTION_LINK
setAllowedActions( $actions)
Sets the action types allowed for log filtering To one action type may correspond several log_actions...
array $allowedActions
static userCanViewLogType( $type, Authority $performer)
Determine if the current user is allowed to view a particular field of this log row,...
const USE_CHECKBOXES
static isDeleted( $row, $field)
static newFromEntry(LogEntry $entry)
Constructs a new formatter suitable for given entry.
Class to simplify the use of log pages.
Definition: LogPage.php:41
const DELETED_RESTRICTED
Definition: LogPage.php:45
static validTypes()
Get the list of valid log types.
Definition: LogPage.php:209
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:565
onLogEventsListShowLogExtract(&$s, $types, $page, $user, $param)
This hook is called before the string is added to OutputPage.
This class is a collection of static functions that serve two purposes:
Definition: Html.php:55
Class that generates HTML for internal links.
Some internal bits split of from Skin.php.
Definition: Linker.php:67
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
This is one of the Core classes and should be read at least once by any new developers.
Definition: OutputPage.php:60
static getMain()
Get the RequestContext object associated with the main request.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
static getTitleValueFor( $name, $subpage=false, $fragment='')
Get a localised TitleValue object for a specified special page name.
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Definition: WebRequest.php:50
static check( $name, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox.
Definition: Xml.php:330
Interface for objects (potentially) representing a page that can be viewable and linked to on a wiki.
This interface represents the authority associated the current execution context, such as a web reque...
Definition: Authority.php:37
isAllowed(string $permission)
Checks whether this authority has the given permission in general.
isAllowedAny(... $permissions)
Checks whether this authority has any of the given permissions in general.
const DB_PRIMARY
Definition: defines.php:28