MediaWiki  master
LogEventsList.php
Go to the documentation of this file.
1 <?php
33 
35  public const NO_ACTION_LINK = 1;
36  public const NO_EXTRA_USER_LINKS = 2;
37  public const USE_CHECKBOXES = 4;
38 
39  public $flags;
40 
44  protected $showTagEditUI;
45 
49  protected $allowedActions = null;
50 
54  private $linkRenderer;
55 
57  private $hookRunner;
58 
69  public function __construct( $context, $linkRenderer = null, $flags = 0 ) {
70  $this->setContext( $context );
71  $this->flags = $flags;
72  $this->showTagEditUI = ChangeTags::showTagEditingUI( $this->getAuthority() );
73  if ( $linkRenderer instanceof LinkRenderer ) {
74  $this->linkRenderer = $linkRenderer;
75  }
76  $this->hookRunner = Hooks::runner();
77  }
78 
83  protected function getLinkRenderer() {
84  if ( $this->linkRenderer !== null ) {
85  return $this->linkRenderer;
86  } else {
87  return MediaWikiServices::getInstance()->getLinkRenderer();
88  }
89  }
90 
107  public function showOptions( $types = [], $user = '', $page = '', $pattern = false, $year = 0,
108  $month = 0, $day = 0, $filter = null, $tagFilter = '', $action = null
109  ) {
110  // For B/C, we take strings, but make sure they are converted...
111  $types = ( $types === '' ) ? [] : (array)$types;
112 
113  $formDescriptor = [];
114 
115  // Basic selectors
116  $formDescriptor['type'] = $this->getTypeMenuDesc( $types );
117  $formDescriptor['user'] = $this->getUserInputDesc( $user );
118  $formDescriptor['page'] = $this->getTitleInputDesc( $page );
119 
120  // Add extra inputs if any
121  // This could either be a form descriptor array or a string with raw HTML.
122  // We need it to work in both cases and show a deprecation warning if it
123  // is a string. See T199495.
124  $extraInputsDescriptor = $this->getExtraInputsDesc( $types );
125  if (
126  is_array( $extraInputsDescriptor ) &&
127  !empty( $extraInputsDescriptor )
128  ) {
129  $formDescriptor[ 'extra' ] = $extraInputsDescriptor;
130  } elseif (
131  is_string( $extraInputsDescriptor ) &&
132  $extraInputsDescriptor !== ''
133  ) {
134  // We'll add this to the footer of the form later
135  $extraInputsString = $extraInputsDescriptor;
136  wfDeprecated( '$input in LogEventsListGetExtraInputs hook', '1.32' );
137  }
138 
139  // Title pattern, if allowed
140  if ( !$this->getConfig()->get( MainConfigNames::MiserMode ) ) {
141  $formDescriptor['pattern'] = $this->getTitlePatternDesc( $pattern );
142  }
143 
144  // Date menu
145  $formDescriptor['date'] = [
146  'type' => 'date',
147  'label-message' => 'date',
148  'default' => $year && $month && $day ? sprintf( "%04d-%02d-%02d", $year, $month, $day ) : '',
149  ];
150 
151  // Tag filter
152  $formDescriptor['tagfilter'] = [
153  'type' => 'tagfilter',
154  'name' => 'tagfilter',
155  'label-message' => 'tag-filter',
156  ];
157 
158  // Filter links
159  if ( $filter ) {
160  $formDescriptor['filters'] = $this->getFiltersDesc( $filter );
161  }
162 
163  // Action filter
164  if (
165  $action !== null &&
166  $this->allowedActions !== null &&
167  count( $this->allowedActions ) > 0
168  ) {
169  $formDescriptor['subtype'] = $this->getActionSelectorDesc( $types, $action );
170  }
171 
172  $context = new DerivativeContext( $this->getContext() );
173  $context->setTitle( SpecialPage::getTitleFor( 'Log' ) ); // Remove subpage
174  $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $context );
175  $htmlForm
176  ->setSubmitTextMsg( 'logeventslist-submit' )
177  ->setMethod( 'get' )
178  ->setWrapperLegendMsg( 'log' );
179 
180  // TODO This will should be removed at some point. See T199495.
181  if ( isset( $extraInputsString ) ) {
182  $htmlForm->addFooterText( Html::rawElement(
183  'div',
184  [],
185  $extraInputsString
186  ) );
187  }
188 
189  $htmlForm->prepareForm()->displayForm( false );
190  }
191 
196  private function getFiltersDesc( $filter ) {
197  $optionsMsg = [];
198  $default = [];
199  foreach ( $filter as $type => $val ) {
200  $optionsMsg["logeventslist-{$type}-log"] = $type;
201 
202  if ( $val === false ) {
203  $default[] = $type;
204  }
205  }
206  return [
207  'class' => HTMLMultiSelectField::class,
208  'label-message' => 'logeventslist-more-filters',
209  'flatlist' => true,
210  'options-messages' => $optionsMsg,
211  'default' => $default,
212  ];
213  }
214 
219  private function getTypeMenuDesc( $queryTypes ) {
220  $queryType = count( $queryTypes ) == 1 ? $queryTypes[0] : '';
221 
222  $typesByName = []; // Temporary array
223  // First pass to load the log names
224  foreach ( LogPage::validTypes() as $type ) {
225  $page = new LogPage( $type );
226  $restriction = $page->getRestriction();
227  if ( $this->getAuthority()->isAllowed( $restriction ) ) {
228  $typesByName[$type] = $page->getName()->text();
229  }
230  }
231 
232  // Second pass to sort by name
233  asort( $typesByName );
234 
235  // Always put "All public logs" on top
236  $public = $typesByName[''];
237  unset( $typesByName[''] );
238  $typesByName = [ '' => $public ] + $typesByName;
239 
240  return [
241  'class' => HTMLSelectField::class,
242  'name' => 'type',
243  'options' => array_flip( $typesByName ),
244  'default' => $queryType,
245  ];
246  }
247 
252  private function getUserInputDesc( $user ) {
253  return [
254  'class' => HTMLUserTextField::class,
255  'label-message' => 'specialloguserlabel',
256  'name' => 'user',
257  'default' => $user,
258  ];
259  }
260 
265  private function getTitleInputDesc( $page ) {
266  return [
267  'class' => HTMLTitleTextField::class,
268  'label-message' => 'speciallogtitlelabel',
269  'name' => 'page',
270  'required' => false
271  ];
272  }
273 
278  private function getTitlePatternDesc( $pattern ) {
279  return [
280  'type' => 'check',
281  'label-message' => 'log-title-wildcard',
282  'name' => 'pattern',
283  ];
284  }
285 
290  private function getExtraInputsDesc( $types ) {
291  if ( count( $types ) == 1 ) {
292  if ( $types[0] == 'suppress' ) {
293  return [
294  'type' => 'text',
295  'label-message' => 'revdelete-offender',
296  'name' => 'offender',
297  ];
298  } else {
299  // Allow extensions to add their own extra inputs
300  // This could be an array or string. See T199495.
301  $input = ''; // Deprecated
302  $formDescriptor = [];
303  $this->hookRunner->onLogEventsListGetExtraInputs( $types[0], $this, $input, $formDescriptor );
304 
305  return empty( $formDescriptor ) ? $input : $formDescriptor;
306  }
307  }
308 
309  return [];
310  }
311 
318  private function getActionSelectorDesc( $types, $action ) {
319  $actionOptions = [];
320  $actionOptions[ 'log-action-filter-all' ] = '';
321 
322  foreach ( $this->allowedActions as $value ) {
323  $msgKey = 'log-action-filter-' . $types[0] . '-' . $value;
324  $actionOptions[ $msgKey ] = $value;
325  }
326 
327  return [
328  'class' => HTMLSelectField::class,
329  'name' => 'subtype',
330  'options-messages' => $actionOptions,
331  'default' => $action,
332  'label' => $this->msg( 'log-action-filter-' . $types[0] )->text(),
333  ];
334  }
335 
342  public function setAllowedActions( $actions ) {
343  $this->allowedActions = $actions;
344  }
345 
349  public function beginLogEventsList() {
350  return "<ul class='mw-logevent-loglines'>\n";
351  }
352 
356  public function endLogEventsList() {
357  return "</ul>\n";
358  }
359 
364  public function logLine( $row ) {
365  $entry = DatabaseLogEntry::newFromRow( $row );
366  $formatter = LogFormatter::newFromEntry( $entry );
367  $formatter->setContext( $this->getContext() );
368  $formatter->setLinkRenderer( $this->getLinkRenderer() );
369  $formatter->setShowUserToolLinks( !( $this->flags & self::NO_EXTRA_USER_LINKS ) );
370 
371  $time = $this->getLanguage()->userTimeAndDate(
372  $entry->getTimestamp(),
373  $this->getUser()
374  );
375  // Link the time text to the specific log entry, see T207562
376  $timeLink = $this->getLinkRenderer()->makeKnownLink(
378  $time,
379  [],
380  [ 'logid' => $entry->getId() ]
381  );
382 
383  $action = $formatter->getActionText();
384 
385  if ( $this->flags & self::NO_ACTION_LINK ) {
386  $revert = '';
387  } else {
388  $revert = $formatter->getActionLinks();
389  if ( $revert != '' ) {
390  $revert = '<span class="mw-logevent-actionlink">' . $revert . '</span>';
391  }
392  }
393 
394  $comment = $formatter->getComment();
395 
396  // Some user can hide log items and have review links
397  $del = $this->getShowHideLinks( $row );
398 
399  // Any tags...
400  list( $tagDisplay, $newClasses ) = ChangeTags::formatSummaryRow(
401  $row->ts_tags,
402  'logevent',
403  $this->getContext()
404  );
405  $classes = array_merge(
406  [ 'mw-logline-' . $entry->getType() ],
407  $newClasses
408  );
409  $attribs = [
410  'data-mw-logid' => $entry->getId(),
411  'data-mw-logaction' => $entry->getFullType(),
412  ];
413  $ret = "$del $timeLink $action $comment $revert $tagDisplay";
414 
415  // Let extensions add data
416  $this->hookRunner->onLogEventsListLineEnding( $this, $ret, $entry, $classes, $attribs );
417  $attribs = array_filter( $attribs,
418  [ Sanitizer::class, 'isReservedDataAttribute' ],
419  ARRAY_FILTER_USE_KEY
420  );
421  $attribs['class'] = $classes;
422 
423  return Html::rawElement( 'li', $attribs, $ret ) . "\n";
424  }
425 
430  private function getShowHideLinks( $row ) {
431  // We don't want to see the links and
432  if ( $this->flags == self::NO_ACTION_LINK ) {
433  return '';
434  }
435 
436  // If change tag editing is available to this user, return the checkbox
437  if ( $this->flags & self::USE_CHECKBOXES && $this->showTagEditUI ) {
438  return Xml::check(
439  'showhiderevisions',
440  false,
441  [ 'name' => 'ids[' . $row->log_id . ']' ]
442  );
443  }
444 
445  // no one can hide items from the suppress log.
446  if ( $row->log_type == 'suppress' ) {
447  return '';
448  }
449 
450  $del = '';
451  $authority = $this->getAuthority();
452  // Don't show useless checkbox to people who cannot hide log entries
453  if ( $authority->isAllowed( 'deletedhistory' ) ) {
454  $canHide = $authority->isAllowed( 'deletelogentry' );
455  $canViewSuppressedOnly = $authority->isAllowed( 'viewsuppressed' ) &&
456  !$authority->isAllowed( 'suppressrevision' );
457  $entryIsSuppressed = self::isDeleted( $row, LogPage::DELETED_RESTRICTED );
458  $canViewThisSuppressedEntry = $canViewSuppressedOnly && $entryIsSuppressed;
459  if ( $row->log_deleted || $canHide ) {
460  // Show checkboxes instead of links.
461  if ( $canHide && $this->flags & self::USE_CHECKBOXES && !$canViewThisSuppressedEntry ) {
462  // If event was hidden from sysops
463  if ( !self::userCan( $row, LogPage::DELETED_RESTRICTED, $authority ) ) {
464  $del = Xml::check( 'deleterevisions', false, [ 'disabled' => 'disabled' ] );
465  } else {
466  $del = Xml::check(
467  'showhiderevisions',
468  false,
469  [ 'name' => 'ids[' . $row->log_id . ']' ]
470  );
471  }
472  } else {
473  // If event was hidden from sysops
474  if ( !self::userCan( $row, LogPage::DELETED_RESTRICTED, $authority ) ) {
475  $del = Linker::revDeleteLinkDisabled( $canHide );
476  } else {
477  $query = [
478  'target' => SpecialPage::getTitleFor( 'Log', $row->log_type )->getPrefixedDBkey(),
479  'type' => 'logging',
480  'ids' => $row->log_id,
481  ];
482  $del = Linker::revDeleteLink(
483  $query,
484  $entryIsSuppressed,
485  $canHide && !$canViewThisSuppressedEntry
486  );
487  }
488  }
489  }
490  }
491 
492  return $del;
493  }
494 
501  public static function typeAction( $row, $type, $action ) {
502  $match = is_array( $type ) ?
503  in_array( $row->log_type, $type ) : $row->log_type == $type;
504  if ( $match ) {
505  $match = is_array( $action ) ?
506  in_array( $row->log_action, $action ) : $row->log_action == $action;
507  }
508 
509  return $match;
510  }
511 
521  public static function userCan( $row, $field, Authority $performer ) {
522  return self::userCanBitfield( $row->log_deleted, $field, $performer ) &&
523  self::userCanViewLogType( $row->log_type, $performer );
524  }
525 
535  public static function userCanBitfield( $bitfield, $field, Authority $performer ) {
536  if ( $bitfield & $field ) {
537  if ( $bitfield & LogPage::DELETED_RESTRICTED ) {
538  return $performer->isAllowedAny( 'suppressrevision', 'viewsuppressed' );
539  } else {
540  return $performer->isAllowed( 'deletedhistory' );
541  }
542  }
543  return true;
544  }
545 
554  public static function userCanViewLogType( $type, Authority $performer ) {
555  $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::LogRestrictions );
556  if ( isset( $logRestrictions[$type] ) && !$performer->isAllowed( $logRestrictions[$type] )
557  ) {
558  return false;
559  }
560  return true;
561  }
562 
568  public static function isDeleted( $row, $field ) {
569  return ( $row->log_deleted & $field ) == $field;
570  }
571 
597  public static function showLogExtract(
598  &$out, $types = [], $page = '', $user = '', $param = []
599  ) {
600  $defaultParameters = [
601  'lim' => 25,
602  'conds' => [],
603  'showIfEmpty' => true,
604  'msgKey' => [ '' ],
605  'wrap' => "$1",
606  'flags' => 0,
607  'useRequestParams' => false,
608  'useMaster' => false,
609  'extraUrlParams' => false,
610  ];
611  # The + operator appends elements of remaining keys from the right
612  # handed array to the left handed, whereas duplicated keys are NOT overwritten.
613  $param += $defaultParameters;
614  # Convert $param array to individual variables
615  $lim = $param['lim'];
616  $conds = $param['conds'];
617  $showIfEmpty = $param['showIfEmpty'];
618  $msgKey = $param['msgKey'];
619  $wrap = $param['wrap'];
620  $flags = $param['flags'];
621  $extraUrlParams = $param['extraUrlParams'];
622 
623  $useRequestParams = $param['useRequestParams'];
624  // @phan-suppress-next-line PhanRedundantCondition
625  if ( !is_array( $msgKey ) ) {
626  $msgKey = [ $msgKey ];
627  }
628 
629  if ( $out instanceof OutputPage ) {
630  $context = $out->getContext();
631  } else {
633  }
634 
635  $services = MediaWikiServices::getInstance();
636  // FIXME: Figure out how to inject this
637  $linkRenderer = $services->getLinkRenderer();
638 
639  # Insert list of top 50 (or top $lim) items
640  $loglist = new LogEventsList( $context, $linkRenderer, $flags );
641  $pager = new LogPager(
642  $loglist,
643  $types,
644  $user,
645  $page,
646  false,
647  $conds,
648  false,
649  false,
650  false,
651  '',
652  '',
653  0,
654  $services->getLinkBatchFactory(),
655  $services->getDBLoadBalancer(),
656  $services->getActorNormalization()
657  );
658  if ( !$useRequestParams ) {
659  # Reset vars that may have been taken from the request
660  $pager->mLimit = 50;
661  $pager->mDefaultLimit = 50;
662  $pager->mOffset = "";
663  $pager->mIsBackwards = false;
664  }
665 
666  if ( $param['useMaster'] ) {
667  $pager->mDb = wfGetDB( DB_PRIMARY );
668  }
669  // @phan-suppress-next-line PhanImpossibleCondition
670  if ( isset( $param['offset'] ) ) { # Tell pager to ignore WebRequest offset
671  $pager->setOffset( $param['offset'] );
672  }
673 
674  // @phan-suppress-next-line PhanSuspiciousValueComparison
675  if ( $lim > 0 ) {
676  $pager->mLimit = $lim;
677  }
678  // Fetch the log rows and build the HTML if needed
679  $logBody = $pager->getBody();
680  $numRows = $pager->getNumRows();
681 
682  $s = '';
683 
684  if ( $logBody ) {
685  if ( $msgKey[0] ) {
686  $msg = $context->msg( ...$msgKey );
687  if ( $page instanceof PageReference ) {
688  $msg->page( $page );
689  }
690  $s .= $msg->parseAsBlock();
691  }
692  $s .= $loglist->beginLogEventsList() .
693  $logBody .
694  $loglist->endLogEventsList();
695  // add styles for change tags
696  $context->getOutput()->addModuleStyles( 'mediawiki.interface.helpers.styles' );
697  } elseif ( $showIfEmpty ) {
698  $s = Html::rawElement( 'div', [ 'class' => 'mw-warning-logempty' ],
699  $context->msg( 'logempty' )->parse() );
700  }
701 
702  if ( $page instanceof PageReference ) {
703  $titleFormatter = MediaWikiServices::getInstance()->getTitleFormatter();
704  $pageName = $titleFormatter->getPrefixedDBkey( $page );
705  } elseif ( $page != '' ) {
706  $pageName = $page;
707  } else {
708  $pageName = null;
709  }
710 
711  if ( $numRows > $pager->mLimit ) { # Show "Full log" link
712  $urlParam = [];
713  if ( $pageName ) {
714  $urlParam['page'] = $pageName;
715  }
716 
717  if ( $user != '' ) {
718  $urlParam['user'] = $user;
719  }
720 
721  if ( !is_array( $types ) ) { # Make it an array, if it isn't
722  $types = [ $types ];
723  }
724 
725  # If there is exactly one log type, we can link to Special:Log?type=foo
726  if ( count( $types ) == 1 ) {
727  $urlParam['type'] = $types[0];
728  }
729 
730  // @phan-suppress-next-line PhanSuspiciousValueComparison
731  if ( $extraUrlParams !== false ) {
732  $urlParam = array_merge( $urlParam, $extraUrlParams );
733  }
734 
735  $s .= $linkRenderer->makeKnownLink(
736  SpecialPage::getTitleFor( 'Log' ),
737  $context->msg( 'log-fulllog' )->text(),
738  [],
739  $urlParam
740  );
741  }
742 
743  if ( $logBody && $msgKey[0] ) {
744  // TODO: The condition above is weird. Should this be done in any other cases?
745  // Or is it always true in practice?
746 
747  // Mark as interface language (T60685)
748  $dir = $context->getLanguage()->getDir();
749  $lang = $context->getLanguage()->getHtmlCode();
750  $s = Html::rawElement( 'div', [
751  'class' => "mw-content-$dir",
752  'dir' => $dir,
753  'lang' => $lang,
754  ], $s );
755 
756  // Wrap in warning box
757  $s = Html::warningBox(
758  $s,
759  'mw-warning-with-logexcerpt'
760  );
761  }
762 
763  // @phan-suppress-next-line PhanSuspiciousValueComparison
764  if ( $wrap != '' ) { // Wrap message in html
765  $s = str_replace( '$1', $s, $wrap );
766  }
767 
768  /* hook can return false, if we don't want the message to be emitted (Wikia BugId:7093) */
769  if ( Hooks::runner()->onLogEventsListShowLogExtract( $s, $types, $pageName, $user, $param ) ) {
770  // $out can be either an OutputPage object or a String-by-reference
771  if ( $out instanceof OutputPage ) {
772  $out->addHTML( $s );
773  } else {
774  $out = $s;
775  }
776  }
777 
778  return $numRows;
779  }
780 
790  public static function getExcludeClause( $db, $audience = 'public', Authority $performer = null ) {
791  $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::LogRestrictions );
792 
793  if ( $audience != 'public' && $performer === null ) {
794  throw new InvalidArgumentException(
795  'A User object must be given when checking for a user audience.'
796  );
797  }
798 
799  // Reset the array, clears extra "where" clauses when $par is used
800  $hiddenLogs = [];
801 
802  // Don't show private logs to unprivileged users
803  foreach ( $logRestrictions as $logType => $right ) {
804  if ( $audience == 'public' || !$performer->isAllowed( $right )
805  ) {
806  $hiddenLogs[] = $logType;
807  }
808  }
809  if ( count( $hiddenLogs ) == 1 ) {
810  return 'log_type != ' . $db->addQuotes( $hiddenLogs[0] );
811  } elseif ( $hiddenLogs ) {
812  return 'log_type NOT IN (' . $db->makeList( $hiddenLogs ) . ')';
813  }
814 
815  return false;
816  }
817 }
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, $page, MessageLocalizer $localizer=null)
Creates HTML for the given tags.
Definition: ChangeTags.php:182
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()
IContextSource $context
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:344
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:173
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:214
static revDeleteLinkDisabled( $delete=true)
Creates a dead (show/hide) link for deleting revisions/log entries.
Definition: Linker.php:2188
static revDeleteLink( $query=[], $restricted=false, $delete=true)
Creates a (show/hide) link for deleting revisions/log entries.
Definition: Linker.php:2164
LinkRenderer null $linkRenderer
const NO_EXTRA_USER_LINKS
getTitlePatternDesc( $pattern)
static typeAction( $row, $type, $action)
getShowHideLinks( $row)
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
showOptions( $types=[], $user='', $page='', $pattern=false, $year=0, $month=0, $day=0, $filter=null, $tagFilter='', $action=null)
Show options for the log list.
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,...
getExtraInputsDesc( $types)
HookRunner $hookRunner
__construct( $context, $linkRenderer=null, $flags=0)
const NO_ACTION_LINK
getFiltersDesc( $filter)
setAllowedActions( $actions)
Sets the action types allowed for log filtering To one action type may correspond several log_actions...
getTypeMenuDesc( $queryTypes)
array $allowedActions
getTitleInputDesc( $page)
getActionSelectorDesc( $types, $action)
Drop down menu for selection of actions that can be used to filter the log.
static userCanViewLogType( $type, Authority $performer)
Determine if the current user is allowed to view a particular field of this log row,...
const USE_CHECKBOXES
getUserInputDesc( $user)
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:39
const DELETED_RESTRICTED
Definition: LogPage.php:43
static validTypes()
Get the list of valid log types.
Definition: LogPage.php:207
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:561
Class that generates HTML anchor link elements for pages.
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:54
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:43
static check( $name, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox.
Definition: Xml.php:332
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.
msg( $key,... $params)
This is the method for getting translated interface messages.
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:39
foreach( $mmfl['setupFiles'] as $fileName) if( $queue) if(empty( $mmfl['quiet'])) $s
const DB_PRIMARY
Definition: defines.php:28