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 = Hooks::runner();
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->getDBLoadBalancer(),
678  $services->getActorNormalization()
679  );
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  if ( $param['useMaster'] ) {
689  $pager->mDb = wfGetDB( DB_PRIMARY );
690  }
691  // @phan-suppress-next-line PhanImpossibleCondition
692  if ( isset( $param['offset'] ) ) { # Tell pager to ignore WebRequest offset
693  $pager->setOffset( $param['offset'] );
694  }
695 
696  // @phan-suppress-next-line PhanSuspiciousValueComparison
697  if ( $lim > 0 ) {
698  $pager->mLimit = $lim;
699  }
700  // Fetch the log rows and build the HTML if needed
701  $logBody = $pager->getBody();
702  $numRows = $pager->getNumRows();
703 
704  $s = '';
705 
706  if ( $logBody ) {
707  if ( $msgKey[0] ) {
708  // @phan-suppress-next-line PhanParamTooFewUnpack Non-emptiness checked above
709  $msg = $context->msg( ...$msgKey );
710  if ( $page instanceof PageReference ) {
711  $msg->page( $page );
712  }
713  $s .= $msg->parseAsBlock();
714  }
715  $s .= $loglist->beginLogEventsList() .
716  $logBody .
717  $loglist->endLogEventsList();
718  // add styles for change tags
719  $context->getOutput()->addModuleStyles( 'mediawiki.interface.helpers.styles' );
720  } elseif ( $showIfEmpty ) {
721  $s = Html::rawElement( 'div', [ 'class' => 'mw-warning-logempty' ],
722  $context->msg( 'logempty' )->parse() );
723  }
724 
725  if ( $page instanceof PageReference ) {
726  $titleFormatter = MediaWikiServices::getInstance()->getTitleFormatter();
727  $pageName = $titleFormatter->getPrefixedDBkey( $page );
728  } elseif ( $page != '' ) {
729  $pageName = $page;
730  } else {
731  $pageName = null;
732  }
733 
734  if ( $numRows > $pager->mLimit ) { # Show "Full log" link
735  $urlParam = [];
736  if ( $pageName ) {
737  $urlParam['page'] = $pageName;
738  }
739 
740  if ( $user != '' ) {
741  $urlParam['user'] = $user;
742  }
743 
744  if ( !is_array( $types ) ) { # Make it an array, if it isn't
745  $types = [ $types ];
746  }
747 
748  # If there is exactly one log type, we can link to Special:Log?type=foo
749  if ( count( $types ) == 1 ) {
750  $urlParam['type'] = $types[0];
751  }
752 
753  // @phan-suppress-next-line PhanSuspiciousValueComparison
754  if ( $extraUrlParams !== false ) {
755  $urlParam = array_merge( $urlParam, $extraUrlParams );
756  }
757 
758  $s .= $linkRenderer->makeKnownLink(
759  SpecialPage::getTitleFor( 'Log' ),
760  $context->msg( 'log-fulllog' )->text(),
761  [],
762  $urlParam
763  );
764  }
765 
766  if ( $logBody && $msgKey[0] ) {
767  // TODO: The condition above is weird. Should this be done in any other cases?
768  // Or is it always true in practice?
769 
770  // Mark as interface language (T60685)
771  $dir = $context->getLanguage()->getDir();
772  $lang = $context->getLanguage()->getHtmlCode();
773  $s = Html::rawElement( 'div', [
774  'class' => "mw-content-$dir",
775  'dir' => $dir,
776  'lang' => $lang,
777  ], $s );
778 
779  // Wrap in warning box
780  $s = Html::warningBox(
781  $s,
782  'mw-warning-with-logexcerpt'
783  );
784  }
785 
786  // @phan-suppress-next-line PhanSuspiciousValueComparison
787  if ( $wrap != '' ) { // Wrap message in html
788  $s = str_replace( '$1', $s, $wrap );
789  }
790 
791  /* hook can return false, if we don't want the message to be emitted (Wikia BugId:7093) */
792  if ( Hooks::runner()->onLogEventsListShowLogExtract( $s, $types, $pageName, $user, $param ) ) {
793  // $out can be either an OutputPage object or a String-by-reference
794  if ( $out instanceof OutputPage ) {
795  $out->addHTML( $s );
796  } else {
797  $out = $s;
798  }
799  }
800 
801  return $numRows;
802  }
803 
813  public static function getExcludeClause( $db, $audience = 'public', Authority $performer = null ) {
814  $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::LogRestrictions );
815 
816  if ( $audience != 'public' && $performer === null ) {
817  throw new InvalidArgumentException(
818  'A User object must be given when checking for a user audience.'
819  );
820  }
821 
822  // Reset the array, clears extra "where" clauses when $par is used
823  $hiddenLogs = [];
824 
825  // Don't show private logs to unprivileged users
826  foreach ( $logRestrictions as $logType => $right ) {
827  if ( $audience == 'public' || !$performer->isAllowed( $right )
828  ) {
829  $hiddenLogs[] = $logType;
830  }
831  }
832  if ( count( $hiddenLogs ) == 1 ) {
833  return 'log_type != ' . $db->addQuotes( $hiddenLogs[0] );
834  } elseif ( $hiddenLogs ) {
835  return 'log_type NOT IN (' . $db->makeList( $hiddenLogs ) . ')';
836  }
837 
838  return false;
839  }
840 }
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:196
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:350
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
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:40
const DELETED_RESTRICTED
Definition: LogPage.php:44
static validTypes()
Get the list of valid log types.
Definition: LogPage.php:208
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:560
Class that generates HTML anchor link elements for pages.
Some internal bits split of from Skin.php.
Definition: Linker.php:65
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:57
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:47
static check( $name, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox.
Definition: Xml.php:329
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.
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:40
foreach( $mmfl['setupFiles'] as $fileName) if( $queue) if(empty( $mmfl['quiet'])) $s
const DB_PRIMARY
Definition: defines.php:28