MediaWiki REL1_37
LogEventsList.php
Go to the documentation of this file.
1<?php
32
34 public const NO_ACTION_LINK = 1;
35 public const NO_EXTRA_USER_LINKS = 2;
36 public const USE_CHECKBOXES = 4;
37
38 public $flags;
39
43 protected $showTagEditUI;
44
48 protected $allowedActions = null;
49
54
56 private $hookRunner;
57
68 public function __construct( $context, $linkRenderer = null, $flags = 0 ) {
69 $this->setContext( $context );
70 $this->flags = $flags;
71 $this->showTagEditUI = ChangeTags::showTagEditingUI( $this->getAuthority() );
72 if ( $linkRenderer instanceof LinkRenderer ) {
73 $this->linkRenderer = $linkRenderer;
74 }
75 $this->hookRunner = Hooks::runner();
76 }
77
82 protected function getLinkRenderer() {
83 if ( $this->linkRenderer !== null ) {
84 return $this->linkRenderer;
85 } else {
86 return MediaWikiServices::getInstance()->getLinkRenderer();
87 }
88 }
89
106 public function showOptions( $types = [], $user = '', $page = '', $pattern = false, $year = 0,
107 $month = 0, $day = 0, $filter = null, $tagFilter = '', $action = null
108 ) {
109 // For B/C, we take strings, but make sure they are converted...
110 $types = ( $types === '' ) ? [] : (array)$types;
111
112 $formDescriptor = [];
113
114 // Basic selectors
115 $formDescriptor['type'] = $this->getTypeMenuDesc( $types );
116 $formDescriptor['user'] = $this->getUserInputDesc( $user );
117 $formDescriptor['page'] = $this->getTitleInputDesc( $page );
118
119 // Add extra inputs if any
120 // This could either be a form descriptor array or a string with raw HTML.
121 // We need it to work in both cases and show a deprecation warning if it
122 // is a string. See T199495.
123 $extraInputsDescriptor = $this->getExtraInputsDesc( $types );
124 if (
125 is_array( $extraInputsDescriptor ) &&
126 !empty( $extraInputsDescriptor )
127 ) {
128 $formDescriptor[ 'extra' ] = $extraInputsDescriptor;
129 } elseif (
130 is_string( $extraInputsDescriptor ) &&
131 $extraInputsDescriptor !== ''
132 ) {
133 // We'll add this to the footer of the form later
134 $extraInputsString = $extraInputsDescriptor;
135 wfDeprecated( '$input in LogEventsListGetExtraInputs hook', '1.32' );
136 }
137
138 // Title pattern, if allowed
139 if ( !$this->getConfig()->get( 'MiserMode' ) ) {
140 $formDescriptor['pattern'] = $this->getTitlePatternDesc( $pattern );
141 }
142
143 // Date menu
144 $formDescriptor['date'] = [
145 'type' => 'date',
146 'label-message' => 'date',
147 'default' => $year && $month && $day ? sprintf( "%04d-%02d-%02d", $year, $month, $day ) : '',
148 ];
149
150 // Tag filter
151 $formDescriptor['tagfilter'] = [
152 'type' => 'tagfilter',
153 'name' => 'tagfilter',
154 'label-message' => 'tag-filter',
155 ];
156
157 // Filter links
158 if ( $filter ) {
159 $formDescriptor['filters'] = $this->getFiltersDesc( $filter );
160 }
161
162 // Action filter
163 if (
164 $action !== null &&
165 $this->allowedActions !== null &&
166 count( $this->allowedActions ) > 0
167 ) {
168 $formDescriptor['subtype'] = $this->getActionSelectorDesc( $types, $action );
169 }
170
171 $context = new DerivativeContext( $this->getContext() );
172 $context->setTitle( SpecialPage::getTitleFor( 'Log' ) ); // Remove subpage
173 $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $context );
174 $htmlForm
175 ->setSubmitTextMsg( 'logeventslist-submit' )
176 ->setMethod( 'get' )
177 ->setWrapperLegendMsg( 'log' );
178
179 // TODO This will should be removed at some point. See T199495.
180 if ( isset( $extraInputsString ) ) {
181 $htmlForm->addFooterText( Html::rawElement(
182 'div',
183 null,
184 $extraInputsString
185 ) );
186 }
187
188 $htmlForm->prepareForm()->displayForm( false );
189 }
190
195 private function getFiltersDesc( $filter ) {
196 $optionsMsg = [];
197 $default = [];
198 foreach ( $filter as $type => $val ) {
199 $optionsMsg["logeventslist-{$type}-log"] = $type;
200
201 if ( $val === false ) {
202 $default[] = $type;
203 }
204 }
205 return [
206 'class' => HTMLMultiSelectField::class,
207 'label-message' => 'logeventslist-more-filters',
208 'flatlist' => true,
209 'options-messages' => $optionsMsg,
210 'default' => $default,
211 ];
212 }
213
218 private function getTypeMenuDesc( $queryTypes ) {
219 $queryType = count( $queryTypes ) == 1 ? $queryTypes[0] : '';
220
221 $typesByName = []; // Temporary array
222 // First pass to load the log names
223 foreach ( LogPage::validTypes() as $type ) {
224 $page = new LogPage( $type );
225 $restriction = $page->getRestriction();
226 if ( $this->getAuthority()->isAllowed( $restriction ) ) {
227 $typesByName[$type] = $page->getName()->text();
228 }
229 }
230
231 // Second pass to sort by name
232 asort( $typesByName );
233
234 // Always put "All public logs" on top
235 $public = $typesByName[''];
236 unset( $typesByName[''] );
237 $typesByName = [ '' => $public ] + $typesByName;
238
239 return [
240 'class' => HTMLSelectField::class,
241 'name' => 'type',
242 'options' => array_flip( $typesByName ),
243 'default' => $queryType,
244 ];
245 }
246
251 private function getUserInputDesc( $user ) {
252 return [
253 'class' => HTMLUserTextField::class,
254 'label-message' => 'specialloguserlabel',
255 'name' => 'user',
256 'default' => $user,
257 ];
258 }
259
264 private function getTitleInputDesc( $page ) {
265 return [
266 'class' => HTMLTitleTextField::class,
267 'label-message' => 'speciallogtitlelabel',
268 'name' => 'page',
269 'required' => false
270 ];
271 }
272
277 private function getTitlePatternDesc( $pattern ) {
278 return [
279 'type' => 'check',
280 'label-message' => 'log-title-wildcard',
281 'name' => 'pattern',
282 ];
283 }
284
289 private function getExtraInputsDesc( $types ) {
290 if ( count( $types ) == 1 ) {
291 if ( $types[0] == 'suppress' ) {
292 return [
293 'type' => 'text',
294 'label-message' => 'revdelete-offender',
295 'name' => 'offender',
296 ];
297 } else {
298 // Allow extensions to add their own extra inputs
299 // This could be an array or string. See T199495.
300 $input = ''; // Deprecated
301 $formDescriptor = [];
302 $this->hookRunner->onLogEventsListGetExtraInputs( $types[0], $this, $input, $formDescriptor );
303
304 return empty( $formDescriptor ) ? $input : $formDescriptor;
305 }
306 }
307
308 return [];
309 }
310
317 private function getActionSelectorDesc( $types, $action ) {
318 $actionOptions = [];
319 $actionOptions[ 'log-action-filter-all' ] = '';
320
321 foreach ( $this->allowedActions as $value ) {
322 $msgKey = 'log-action-filter-' . $types[0] . '-' . $value;
323 $actionOptions[ $msgKey ] = $value;
324 }
325
326 return [
327 'class' => HTMLSelectField::class,
328 'name' => 'subtype',
329 'options-messages' => $actionOptions,
330 'default' => $action,
331 'label' => $this->msg( 'log-action-filter-' . $types[0] )->text(),
332 ];
333 }
334
341 public function setAllowedActions( $actions ) {
342 $this->allowedActions = $actions;
343 }
344
348 public function beginLogEventsList() {
349 return "<ul class='mw-logevent-loglines'>\n";
350 }
351
355 public function endLogEventsList() {
356 return "</ul>\n";
357 }
358
363 public function logLine( $row ) {
364 $entry = DatabaseLogEntry::newFromRow( $row );
365 $formatter = LogFormatter::newFromEntry( $entry );
366 $formatter->setContext( $this->getContext() );
367 $formatter->setLinkRenderer( $this->getLinkRenderer() );
368 $formatter->setShowUserToolLinks( !( $this->flags & self::NO_EXTRA_USER_LINKS ) );
369
370 $time = $this->getLanguage()->userTimeAndDate(
371 $entry->getTimestamp(),
372 $this->getUser()
373 );
374 // Link the time text to the specific log entry, see T207562
375 $timeLink = $this->getLinkRenderer()->makeKnownLink(
377 $time,
378 [],
379 [ 'logid' => $entry->getId() ]
380 );
381
382 $action = $formatter->getActionText();
383
384 if ( $this->flags & self::NO_ACTION_LINK ) {
385 $revert = '';
386 } else {
387 $revert = $formatter->getActionLinks();
388 if ( $revert != '' ) {
389 $revert = '<span class="mw-logevent-actionlink">' . $revert . '</span>';
390 }
391 }
392
393 $comment = $formatter->getComment();
394
395 // Some user can hide log items and have review links
396 $del = $this->getShowHideLinks( $row );
397
398 // Any tags...
399 list( $tagDisplay, $newClasses ) = ChangeTags::formatSummaryRow(
400 $row->ts_tags,
401 'logevent',
402 $this->getContext()
403 );
404 $classes = array_merge(
405 [ 'mw-logline-' . $entry->getType() ],
406 $newClasses
407 );
408 $attribs = [
409 'data-mw-logid' => $entry->getId(),
410 'data-mw-logaction' => $entry->getFullType(),
411 ];
412 $ret = "$del $timeLink $action $comment $revert $tagDisplay";
413
414 // Let extensions add data
415 $this->hookRunner->onLogEventsListLineEnding( $this, $ret, $entry, $classes, $attribs );
416 $attribs = array_filter( $attribs,
417 [ Sanitizer::class, 'isReservedDataAttribute' ],
418 ARRAY_FILTER_USE_KEY
419 );
420 $attribs['class'] = $classes;
421
422 return Html::rawElement( 'li', $attribs, $ret ) . "\n";
423 }
424
429 private function getShowHideLinks( $row ) {
430 // We don't want to see the links and
431 if ( $this->flags == self::NO_ACTION_LINK ) {
432 return '';
433 }
434
435 $user = $this->getUser();
436
437 // If change tag editing is available to this user, return the checkbox
438 if ( $this->flags & self::USE_CHECKBOXES && $this->showTagEditUI ) {
439 return Xml::check(
440 'showhiderevisions',
441 false,
442 [ 'name' => 'ids[' . $row->log_id . ']' ]
443 );
444 }
445
446 // no one can hide items from the suppress log.
447 if ( $row->log_type == 'suppress' ) {
448 return '';
449 }
450
451 $del = '';
452 // Don't show useless checkbox to people who cannot hide log entries
453 if ( $this->getAuthority()->isAllowed( 'deletedhistory' ) ) {
454 $canHide = $this->getAuthority()->isAllowed( 'deletelogentry' );
455 $canViewSuppressedOnly = $this->getAuthority()->isAllowed( 'viewsuppressed' ) &&
456 !$this->getAuthority()->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, $user ) ) {
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, $user ) ) {
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 ];
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( '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 {
632 $context = RequestContext::getMain();
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 '',
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 $dir = $context->getLanguage()->getDir();
687 $lang = $context->getLanguage()->getHtmlCode();
688
689 $s = Xml::openElement( 'div', [
690 'class' => "warningbox mw-warning-with-logexcerpt mw-content-$dir",
691 'dir' => $dir,
692 'lang' => $lang,
693 ] );
694
695 // @phan-suppress-next-line PhanSuspiciousValueComparison
696 if ( count( $msgKey ) == 1 ) {
697 $s .= $context->msg( $msgKey[0] )->parseAsBlock();
698 } else { // Process additional arguments
699 $args = $msgKey;
700 array_shift( $args );
701 $s .= $context->msg( $msgKey[0], $args )->parseAsBlock();
702 }
703 }
704 $s .= $loglist->beginLogEventsList() .
705 $logBody .
706 $loglist->endLogEventsList();
707 // add styles for change tags
708 $context->getOutput()->addModuleStyles( 'mediawiki.interface.helpers.styles' );
709 } elseif ( $showIfEmpty ) {
710 $s = Html::rawElement( 'div', [ 'class' => 'mw-warning-logempty' ],
711 $context->msg( 'logempty' )->parse() );
712 }
713
714 if ( $page instanceof PageReference ) {
715 $titleFormatter = MediaWikiServices::getInstance()->getTitleFormatter();
716 $pageName = $titleFormatter->getPrefixedDBkey( $page );
717 } elseif ( $page != '' ) {
718 $pageName = $page;
719 } else {
720 $pageName = null;
721 }
722
723 if ( $numRows > $pager->mLimit ) { # Show "Full log" link
724 $urlParam = [];
725 if ( $pageName ) {
726 $urlParam['page'] = $pageName;
727 }
728
729 if ( $user != '' ) {
730 $urlParam['user'] = $user;
731 }
732
733 if ( !is_array( $types ) ) { # Make it an array, if it isn't
734 $types = [ $types ];
735 }
736
737 # If there is exactly one log type, we can link to Special:Log?type=foo
738 if ( count( $types ) == 1 ) {
739 $urlParam['type'] = $types[0];
740 }
741
742 // @phan-suppress-next-line PhanSuspiciousValueComparison
743 if ( $extraUrlParams !== false ) {
744 $urlParam = array_merge( $urlParam, $extraUrlParams );
745 }
746
747 $s .= $linkRenderer->makeKnownLink(
748 SpecialPage::getTitleFor( 'Log' ),
749 $context->msg( 'log-fulllog' )->text(),
750 [],
751 $urlParam
752 );
753 }
754
755 if ( $logBody && $msgKey[0] ) {
756 $s .= '</div>';
757 }
758
759 // @phan-suppress-next-line PhanSuspiciousValueComparison
760 if ( $wrap != '' ) { // Wrap message in html
761 $s = str_replace( '$1', $s, $wrap );
762 }
763
764 /* hook can return false, if we don't want the message to be emitted (Wikia BugId:7093) */
765 if ( Hooks::runner()->onLogEventsListShowLogExtract( $s, $types, $pageName, $user, $param ) ) {
766 // $out can be either an OutputPage object or a String-by-reference
767 if ( $out instanceof OutputPage ) {
768 $out->addHTML( $s );
769 } else {
770 $out = $s;
771 }
772 }
773
774 return $numRows;
775 }
776
786 public static function getExcludeClause( $db, $audience = 'public', Authority $performer = null ) {
787 global $wgLogRestrictions;
788
789 if ( $audience != 'public' && $performer === null ) {
790 throw new InvalidArgumentException(
791 'A User object must be given when checking for a user audience.'
792 );
793 }
794
795 // Reset the array, clears extra "where" clauses when $par is used
796 $hiddenLogs = [];
797
798 // Don't show private logs to unprivileged users
799 foreach ( $wgLogRestrictions as $logType => $right ) {
800 if ( $audience == 'public' || !$performer->isAllowed( $right )
801 ) {
802 $hiddenLogs[] = $logType;
803 }
804 }
805 if ( count( $hiddenLogs ) == 1 ) {
806 return 'log_type != ' . $db->addQuotes( $hiddenLogs[0] );
807 } elseif ( $hiddenLogs ) {
808 return 'log_type NOT IN (' . $db->makeList( $hiddenLogs ) . ')';
809 }
810
811 return false;
812 }
813}
getAuthority()
$wgLogRestrictions
This restricts log access to those who have a certain right Users without this will not see it in the...
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.
getContext()
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.
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:2436
static revDeleteLink( $query=[], $restricted=false, $delete=true)
Creates a (show/hide) link for deleting revisions/log entries.
Definition Linker.php:2412
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)
getFiltersDesc( $filter)
setAllowedActions( $actions)
Sets the action types allowed for log filtering To one action type may correspond several log_actions...
getTypeMenuDesc( $queryTypes)
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,...
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:38
const DELETED_RESTRICTED
Definition LogPage.php:42
static validTypes()
Get the list of valid log types.
Definition LogPage.php:206
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,...
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...
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:38
if( $line===false) $args
Definition mcc.php:124
foreach( $mmfl['setupFiles'] as $fileName) if($queue) if(empty( $mmfl['quiet'])) $s
const DB_PRIMARY
Definition defines.php:27
if(!isset( $args[0])) $lang