MediaWiki REL1_35
LogEventsList.php
Go to the documentation of this file.
1<?php
30
32 public const NO_ACTION_LINK = 1;
33 public const NO_EXTRA_USER_LINKS = 2;
34 public const USE_CHECKBOXES = 4;
35
36 public $flags;
37
42 protected $mDefaultQuery;
43
47 protected $showTagEditUI;
48
52 protected $allowedActions = null;
53
58
60 private $hookRunner;
61
72 public function __construct( $context, $linkRenderer = null, $flags = 0 ) {
73 if ( $context instanceof IContextSource ) {
74 $this->setContext( $context );
75 } else {
76 // Old parameters, $context should be a Skin object
77 $this->setContext( $context->getContext() );
78 }
79
80 $this->flags = $flags;
81 $this->showTagEditUI = ChangeTags::showTagEditingUI( $this->getUser() );
82 if ( $linkRenderer instanceof LinkRenderer ) {
83 $this->linkRenderer = $linkRenderer;
84 }
85 $this->hookRunner = Hooks::runner();
86 }
87
92 protected function getLinkRenderer() {
93 if ( $this->linkRenderer !== null ) {
94 return $this->linkRenderer;
95 } else {
96 return MediaWikiServices::getInstance()->getLinkRenderer();
97 }
98 }
99
116 public function showOptions( $types = [], $user = '', $page = '', $pattern = false, $year = 0,
117 $month = 0, $day = 0, $filter = null, $tagFilter = '', $action = null
118 ) {
119 // For B/C, we take strings, but make sure they are converted...
120 $types = ( $types === '' ) ? [] : (array)$types;
121
122 $formDescriptor = [];
123
124 // Basic selectors
125 $formDescriptor['type'] = $this->getTypeMenuDesc( $types );
126 $formDescriptor['user'] = $this->getUserInputDesc( $user );
127 $formDescriptor['page'] = $this->getTitleInputDesc( $page );
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 );
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 // Title pattern, if allowed
149 if ( !$this->getConfig()->get( 'MiserMode' ) ) {
150 $formDescriptor['pattern'] = $this->getTitlePatternDesc( $pattern );
151 }
152
153 // Date menu
154 $formDescriptor['date'] = [
155 'type' => 'date',
156 'label-message' => 'date',
157 'default' => $year && $month && $day ? sprintf( "%04d-%02d-%02d", $year, $month, $day ) : '',
158 ];
159
160 // Tag filter
161 $formDescriptor['tagfilter'] = [
162 'type' => 'tagfilter',
163 'name' => 'tagfilter',
164 'label-raw' => $this->msg( 'tag-filter' )->parse(),
165 ];
166
167 // Filter links
168 if ( $filter ) {
169 $formDescriptor['filters'] = $this->getFiltersDesc( $filter );
170 }
171
172 // Action filter
173 if (
174 $action !== null &&
175 $this->allowedActions !== null &&
176 count( $this->allowedActions ) > 0
177 ) {
178 $formDescriptor['subtype'] = $this->getActionSelectorDesc( $types, $action );
179 }
180
181 $context = new DerivativeContext( $this->getContext() );
182 $context->setTitle( SpecialPage::getTitleFor( 'Log' ) ); // Remove subpage
183 $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $context );
184 $htmlForm
185 ->setSubmitText( $this->msg( 'logeventslist-submit' )->text() )
186 ->setMethod( 'get' )
187 ->setWrapperLegendMsg( 'log' );
188
189 // TODO This will should be removed at some point. See T199495.
190 if ( isset( $extraInputsString ) ) {
191 $htmlForm->addFooterText( Html::rawElement(
192 'div',
193 null,
194 $extraInputsString
195 ) );
196 }
197
198 $htmlForm->prepareForm()->displayForm( false );
199 }
200
205 private function getFiltersDesc( $filter ) {
206 $optionsMsg = [];
207 $default = [];
208 foreach ( $filter as $type => $val ) {
209 $optionsMsg["logeventslist-{$type}-log"] = $type;
210
211 if ( $val === false ) {
212 $default[] = $type;
213 }
214 }
215 return [
216 'class' => 'HTMLMultiSelectField',
217 'label-message' => 'logeventslist-more-filters',
218 'flatlist' => true,
219 'options-messages' => $optionsMsg,
220 'default' => $default,
221 ];
222 }
223
228 private function getTypeMenuDesc( $queryTypes ) {
229 $queryType = count( $queryTypes ) == 1 ? $queryTypes[0] : '';
230
231 $typesByName = []; // Temporary array
232 // First pass to load the log names
233 foreach ( LogPage::validTypes() as $type ) {
234 $page = new LogPage( $type );
235 $restriction = $page->getRestriction();
236 if ( MediaWikiServices::getInstance()
238 ->userHasRight( $this->getUser(), $restriction )
239 ) {
240 $typesByName[$type] = $page->getName()->text();
241 }
242 }
243
244 // Second pass to sort by name
245 asort( $typesByName );
246
247 // Always put "All public logs" on top
248 $public = $typesByName[''];
249 unset( $typesByName[''] );
250 $typesByName = [ '' => $public ] + $typesByName;
251
252 return [
253 'class' => 'HTMLSelectField',
254 'name' => 'type',
255 'options' => array_flip( $typesByName ),
256 'default' => $queryType,
257 ];
258 }
259
264 private function getUserInputDesc( $user ) {
265 return [
266 'class' => 'HTMLUserTextField',
267 'label-message' => 'specialloguserlabel',
268 'name' => 'user',
269 'default' => $user,
270 ];
271 }
272
277 private function getTitleInputDesc( $title ) {
278 return [
279 'class' => 'HTMLTitleTextField',
280 'label-message' => 'speciallogtitlelabel',
281 'name' => 'page',
282 'required' => false
283 ];
284 }
285
290 private function getTitlePatternDesc( $pattern ) {
291 return [
292 'type' => 'check',
293 'label-message' => 'log-title-wildcard',
294 'name' => 'pattern',
295 ];
296 }
297
302 private function getExtraInputsDesc( $types ) {
303 if ( count( $types ) == 1 ) {
304 if ( $types[0] == 'suppress' ) {
305 return [
306 'type' => 'text',
307 'label-message' => 'revdelete-offender',
308 'name' => 'offender',
309 ];
310 } else {
311 // Allow extensions to add their own extra inputs
312 // This could be an array or string. See T199495.
313 $input = ''; // Deprecated
314 $formDescriptor = [];
315 $this->hookRunner->onLogEventsListGetExtraInputs( $types[0], $this, $input, $formDescriptor );
316
317 return empty( $formDescriptor ) ? $input : $formDescriptor;
318 }
319 }
320
321 return [];
322 }
323
330 private function getActionSelectorDesc( $types, $action ) {
331 $actionOptions = [];
332 $actionOptions[ 'log-action-filter-all' ] = '';
333
334 foreach ( $this->allowedActions as $value ) {
335 $msgKey = 'log-action-filter-' . $types[0] . '-' . $value;
336 $actionOptions[ $msgKey ] = $value;
337 }
338
339 return [
340 'class' => 'HTMLSelectField',
341 'name' => 'subtype',
342 'options-messages' => $actionOptions,
343 'default' => $action,
344 'label' => $this->msg( 'log-action-filter-' . $types[0] )->text(),
345 ];
346 }
347
354 public function setAllowedActions( $actions ) {
355 $this->allowedActions = $actions;
356 }
357
361 public function beginLogEventsList() {
362 return "<ul>\n";
363 }
364
368 public function endLogEventsList() {
369 return "</ul>\n";
370 }
371
376 public function logLine( $row ) {
377 $entry = DatabaseLogEntry::newFromRow( $row );
378 $formatter = LogFormatter::newFromEntry( $entry );
379 $formatter->setContext( $this->getContext() );
380 $formatter->setLinkRenderer( $this->getLinkRenderer() );
381 $formatter->setShowUserToolLinks( !( $this->flags & self::NO_EXTRA_USER_LINKS ) );
382
383 $time = htmlspecialchars( $this->getLanguage()->userTimeAndDate(
384 $entry->getTimestamp(), $this->getUser() ) );
385
386 $action = $formatter->getActionText();
387
388 if ( $this->flags & self::NO_ACTION_LINK ) {
389 $revert = '';
390 } else {
391 $revert = $formatter->getActionLinks();
392 if ( $revert != '' ) {
393 $revert = '<span class="mw-logevent-actionlink">' . $revert . '</span>';
394 }
395 }
396
397 $comment = $formatter->getComment();
398
399 // Some user can hide log items and have review links
400 $del = $this->getShowHideLinks( $row );
401
402 // Any tags...
403 list( $tagDisplay, $newClasses ) = ChangeTags::formatSummaryRow(
404 $row->ts_tags,
405 'logevent',
406 $this->getContext()
407 );
408 $classes = array_merge(
409 [ 'mw-logline-' . $entry->getType() ],
410 $newClasses
411 );
412 $attribs = [
413 'data-mw-logid' => $entry->getId(),
414 'data-mw-logaction' => $entry->getFullType(),
415 ];
416 $ret = "$del $time $action $comment $revert $tagDisplay";
417
418 // Let extensions add data
419 $this->hookRunner->onLogEventsListLineEnding( $this, $ret, $entry, $classes, $attribs );
420 $attribs = array_filter( $attribs,
421 [ Sanitizer::class, 'isReservedDataAttribute' ],
422 ARRAY_FILTER_USE_KEY
423 );
424 $attribs['class'] = implode( ' ', $classes );
425
426 return Html::rawElement( 'li', $attribs, $ret ) . "\n";
427 }
428
433 private function getShowHideLinks( $row ) {
434 // We don't want to see the links and
435 if ( $this->flags == self::NO_ACTION_LINK ) {
436 return '';
437 }
438
439 $user = $this->getUser();
440
441 // If change tag editing is available to this user, return the checkbox
442 if ( $this->flags & self::USE_CHECKBOXES && $this->showTagEditUI ) {
443 return Xml::check(
444 'showhiderevisions',
445 false,
446 [ 'name' => 'ids[' . $row->log_id . ']' ]
447 );
448 }
449
450 // no one can hide items from the suppress log.
451 if ( $row->log_type == 'suppress' ) {
452 return '';
453 }
454
455 $del = '';
456 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
457 // Don't show useless checkbox to people who cannot hide log entries
458 if ( $permissionManager->userHasRight( $user, 'deletedhistory' ) ) {
459 $canHide = $permissionManager->userHasRight( $user, 'deletelogentry' );
460 $canViewSuppressedOnly = $permissionManager->userHasRight( $user, 'viewsuppressed' ) &&
461 !$permissionManager->userHasRight( $user, 'suppressrevision' );
462 $entryIsSuppressed = self::isDeleted( $row, LogPage::DELETED_RESTRICTED );
463 $canViewThisSuppressedEntry = $canViewSuppressedOnly && $entryIsSuppressed;
464 if ( $row->log_deleted || $canHide ) {
465 // Show checkboxes instead of links.
466 if ( $canHide && $this->flags & self::USE_CHECKBOXES && !$canViewThisSuppressedEntry ) {
467 // If event was hidden from sysops
468 if ( !self::userCan( $row, LogPage::DELETED_RESTRICTED, $user ) ) {
469 $del = Xml::check( 'deleterevisions', false, [ 'disabled' => 'disabled' ] );
470 } else {
471 $del = Xml::check(
472 'showhiderevisions',
473 false,
474 [ 'name' => 'ids[' . $row->log_id . ']' ]
475 );
476 }
477 } else {
478 // If event was hidden from sysops
479 if ( !self::userCan( $row, LogPage::DELETED_RESTRICTED, $user ) ) {
480 $del = Linker::revDeleteLinkDisabled( $canHide );
481 } else {
482 $query = [
483 'target' => SpecialPage::getTitleFor( 'Log', $row->log_type )->getPrefixedDBkey(),
484 'type' => 'logging',
485 'ids' => $row->log_id,
486 ];
488 $query,
489 $entryIsSuppressed,
490 $canHide && !$canViewThisSuppressedEntry
491 );
492 }
493 }
494 }
495 }
496
497 return $del;
498 }
499
507 public static function typeAction( $row, $type, $action, $right = '' ) {
508 if ( $right !== '' ) {
509 wfDeprecated( __METHOD__ . ' with a right specified', '1.35' );
510 }
511 $match = is_array( $type ) ?
512 in_array( $row->log_type, $type ) : $row->log_type == $type;
513 if ( $match ) {
514 $match = is_array( $action ) ?
515 in_array( $row->log_action, $action ) : $row->log_action == $action;
516 if ( $match && $right ) {
517 global $wgUser;
518 $match = MediaWikiServices::getInstance()
519 ->getPermissionManager()
520 ->userHasRight( $wgUser, $right );
521 }
522 }
523
524 return $match;
525 }
526
536 public static function userCan( $row, $field, User $user = null ) {
537 if ( !$user ) {
538 wfDeprecated( __METHOD__ . ' without passing a $user parameter', '1.35' );
539 global $wgUser;
540 $user = $wgUser;
541 }
542 return self::userCanBitfield( $row->log_deleted, $field, $user ) &&
543 self::userCanViewLogType( $row->log_type, $user );
544 }
545
555 public static function userCanBitfield( $bitfield, $field, User $user = null ) {
556 if ( $bitfield & $field ) {
557 if ( $user === null ) {
558 wfDeprecated( __METHOD__ . ' without passing a $user parameter', '1.35' );
559 global $wgUser;
560 $user = $wgUser;
561 }
562 if ( $bitfield & LogPage::DELETED_RESTRICTED ) {
563 $permissions = [ 'suppressrevision', 'viewsuppressed' ];
564 } else {
565 $permissions = [ 'deletedhistory' ];
566 }
567 $permissionlist = implode( ', ', $permissions );
568 wfDebug( "Checking for $permissionlist due to $field match on $bitfield" );
569 return MediaWikiServices::getInstance()
570 ->getPermissionManager()
571 ->userHasAnyRight( $user, ...$permissions );
572 }
573 return true;
574 }
575
584 public static function userCanViewLogType( $type, User $user = null ) {
585 if ( $user === null ) {
586 wfDeprecated( __METHOD__ . ' without passing a $user parameter', '1.35' );
587 global $wgUser;
588 $user = $wgUser;
589 }
590 $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()->get( 'LogRestrictions' );
591 if ( isset( $logRestrictions[$type] ) && !MediaWikiServices::getInstance()
593 ->userHasRight( $user, $logRestrictions[$type] )
594 ) {
595 return false;
596 }
597 return true;
598 }
599
605 public static function isDeleted( $row, $field ) {
606 return ( $row->log_deleted & $field ) == $field;
607 }
608
634 public static function showLogExtract(
635 &$out, $types = [], $page = '', $user = '', $param = []
636 ) {
637 $defaultParameters = [
638 'lim' => 25,
639 'conds' => [],
640 'showIfEmpty' => true,
641 'msgKey' => [ '' ],
642 'wrap' => "$1",
643 'flags' => 0,
644 'useRequestParams' => false,
645 'useMaster' => false,
646 'extraUrlParams' => false,
647 ];
648 # The + operator appends elements of remaining keys from the right
649 # handed array to the left handed, whereas duplicated keys are NOT overwritten.
650 $param += $defaultParameters;
651 # Convert $param array to individual variables
652 $lim = $param['lim'];
653 $conds = $param['conds'];
654 $showIfEmpty = $param['showIfEmpty'];
655 $msgKey = $param['msgKey'];
656 $wrap = $param['wrap'];
657 $flags = $param['flags'];
658 $extraUrlParams = $param['extraUrlParams'];
659
660 $useRequestParams = $param['useRequestParams'];
661 // @phan-suppress-next-line PhanRedundantCondition
662 if ( !is_array( $msgKey ) ) {
663 $msgKey = [ $msgKey ];
664 }
665
666 if ( $out instanceof OutputPage ) {
667 $context = $out->getContext();
668 } else {
669 $context = RequestContext::getMain();
670 }
671
672 // FIXME: Figure out how to inject this
673 $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
674
675 # Insert list of top 50 (or top $lim) items
676 $loglist = new LogEventsList( $context, $linkRenderer, $flags );
677 $pager = new LogPager( $loglist, $types, $user, $page, '', $conds );
678 if ( !$useRequestParams ) {
679 # Reset vars that may have been taken from the request
680 $pager->mLimit = 50;
681 $pager->mDefaultLimit = 50;
682 $pager->mOffset = "";
683 $pager->mIsBackwards = false;
684 }
685
686 if ( $param['useMaster'] ) {
687 $pager->mDb = wfGetDB( DB_MASTER );
688 }
689 if ( isset( $param['offset'] ) ) { # Tell pager to ignore WebRequest offset
690 $pager->setOffset( $param['offset'] );
691 }
692
693 // @phan-suppress-next-line PhanSuspiciousValueComparison
694 if ( $lim > 0 ) {
695 $pager->mLimit = $lim;
696 }
697 // Fetch the log rows and build the HTML if needed
698 $logBody = $pager->getBody();
699 $numRows = $pager->getNumRows();
700
701 $s = '';
702
703 if ( $logBody ) {
704 if ( $msgKey[0] ) {
705 $dir = $context->getLanguage()->getDir();
706 $lang = $context->getLanguage()->getHtmlCode();
707
708 $s = Xml::openElement( 'div', [
709 'class' => "warningbox mw-warning-with-logexcerpt mw-content-$dir",
710 'dir' => $dir,
711 'lang' => $lang,
712 ] );
713
714 // @phan-suppress-next-line PhanSuspiciousValueComparison
715 if ( count( $msgKey ) == 1 ) {
716 $s .= $context->msg( $msgKey[0] )->parseAsBlock();
717 } else { // Process additional arguments
718 $args = $msgKey;
719 array_shift( $args );
720 $s .= $context->msg( $msgKey[0], $args )->parseAsBlock();
721 }
722 }
723 $s .= $loglist->beginLogEventsList() .
724 $logBody .
725 $loglist->endLogEventsList();
726 // add styles for change tags
727 $context->getOutput()->addModuleStyles( 'mediawiki.interface.helpers.styles' );
728 } elseif ( $showIfEmpty ) {
729 $s = Html::rawElement( 'div', [ 'class' => 'mw-warning-logempty' ],
730 $context->msg( 'logempty' )->parse() );
731 }
732
733 if ( $numRows > $pager->mLimit ) { # Show "Full log" link
734 $urlParam = [];
735 if ( $page instanceof Title ) {
736 $urlParam['page'] = $page->getPrefixedDBkey();
737 } elseif ( $page != '' ) {
738 $urlParam['page'] = $page;
739 }
740
741 if ( $user != '' ) {
742 $urlParam['user'] = $user;
743 }
744
745 if ( !is_array( $types ) ) { # Make it an array, if it isn't
746 $types = [ $types ];
747 }
748
749 # If there is exactly one log type, we can link to Special:Log?type=foo
750 if ( count( $types ) == 1 ) {
751 $urlParam['type'] = $types[0];
752 }
753
754 // @phan-suppress-next-line PhanSuspiciousValueComparison
755 if ( $extraUrlParams !== false ) {
756 $urlParam = array_merge( $urlParam, $extraUrlParams );
757 }
758
759 $s .= $linkRenderer->makeKnownLink(
760 SpecialPage::getTitleFor( 'Log' ),
761 $context->msg( 'log-fulllog' )->text(),
762 [],
763 $urlParam
764 );
765 }
766
767 if ( $logBody && $msgKey[0] ) {
768 $s .= '</div>';
769 }
770
771 // @phan-suppress-next-line PhanSuspiciousValueComparison
772 if ( $wrap != '' ) { // Wrap message in html
773 $s = str_replace( '$1', $s, $wrap );
774 }
775
776 /* hook can return false, if we don't want the message to be emitted (Wikia BugId:7093) */
777 if ( Hooks::runner()->onLogEventsListShowLogExtract( $s, $types, $page, $user, $param ) ) {
778 // $out can be either an OutputPage object or a String-by-reference
779 if ( $out instanceof OutputPage ) {
780 $out->addHTML( $s );
781 } else {
782 $out = $s;
783 }
784 }
785
786 return $numRows;
787 }
788
797 public static function getExcludeClause( $db, $audience = 'public', User $user = null ) {
798 global $wgLogRestrictions;
799
800 if ( $audience != 'public' && $user === null ) {
802 __METHOD__ .
803 ' using a non-public audience without passing a $user parameter',
804 '1.35'
805 );
806 global $wgUser;
807 $user = $wgUser;
808 }
809
810 // Reset the array, clears extra "where" clauses when $par is used
811 $hiddenLogs = [];
812
813 // Don't show private logs to unprivileged users
814 foreach ( $wgLogRestrictions as $logType => $right ) {
815 if ( $audience == 'public' || !MediaWikiServices::getInstance()
817 ->userHasRight( $user, $right )
818 ) {
819 $hiddenLogs[] = $logType;
820 }
821 }
822 if ( count( $hiddenLogs ) == 1 ) {
823 return 'log_type != ' . $db->addQuotes( $hiddenLogs[0] );
824 } elseif ( $hiddenLogs ) {
825 return 'log_type NOT IN (' . $db->makeList( $hiddenLogs ) . ')';
826 }
827
828 return false;
829 }
830}
getPermissionManager()
getUser()
$wgLogRestrictions
This restricts log access to those who have a certain right Users without this will not see it in the...
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that $function is deprecated.
getContext()
static formatSummaryRow( $tags, $page, MessageLocalizer $localizer=null)
Creates HTML for the given tags.
static showTagEditingUI(User $user)
Indicate whether change tag editing UI is relevant.
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
setContext(IContextSource $context)
An IContextSource implementation which will inherit context from another source but allow individual ...
static revDeleteLinkDisabled( $delete=true)
Creates a dead (show/hide) link for deleting revisions/log entries.
Definition Linker.php:2285
static revDeleteLink( $query=[], $restricted=false, $delete=true)
Creates a (show/hide) link for deleting revisions/log entries.
Definition Linker.php:2263
LinkRenderer null $linkRenderer
static typeAction( $row, $type, $action, $right='')
const NO_EXTRA_USER_LINKS
getTitlePatternDesc( $pattern)
static getExcludeClause( $db, $audience='public', User $user=null)
SQL clause to skip forbidden log types for this user.
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.
getExtraInputsDesc( $types)
getTitleInputDesc( $title)
HookRunner $hookRunner
static userCan( $row, $field, User $user=null)
Determine if the current user is allowed to view a particular field of this log row,...
__construct( $context, $linkRenderer=null, $flags=0)
The first two parameters used to be $skin and $out, but now only a context is needed,...
getFiltersDesc( $filter)
setAllowedActions( $actions)
Sets the action types allowed for log filtering To one action type may correspond several log_actions...
getTypeMenuDesc( $queryTypes)
static userCanViewLogType( $type, User $user=null)
Determine if the current user is allowed to view a particular field of this log row,...
getActionSelectorDesc( $types, $action)
Drop down menu for selection of actions that can be used to filter the log.
static userCanBitfield( $bitfield, $field, User $user=null)
Determine if the current user is allowed to view a particular field of this log row,...
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:37
const DELETED_RESTRICTED
Definition LogPage.php:41
static validTypes()
Get the list of valid log types.
Definition LogPage.php:203
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Class that generates HTML links for pages.
MediaWikiServices is the service locator for the application scope of MediaWiki.
This is one of the Core classes and should be read at least once by any new developers.
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,...
Represents a title within MediaWiki.
Definition Title.php:42
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:60
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Interface for objects which can provide a MediaWiki context on request.
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:38
if( $line===false) $args
Definition mcc.php:124
const DB_MASTER
Definition defines.php:29
if(!isset( $args[0])) $lang