52 protected $allowedActions =
null;
72 public function __construct( $context, $linkRenderer =
null, $flags = 0 ) {
85 $this->hookRunner = Hooks::runner();
93 if ( $this->linkRenderer !==
null ) {
94 return $this->linkRenderer;
96 return MediaWikiServices::getInstance()->getLinkRenderer();
116 public function showOptions( $types = [], $user =
'', $page =
'', $pattern =
false, $year = 0,
117 $month = 0, $day = 0, $filter =
null, $tagFilter =
'', $action =
null
120 $types = ( $types ===
'' ) ? [] : (array)$types;
122 $formDescriptor = [];
135 is_array( $extraInputsDescriptor ) &&
136 !empty( $extraInputsDescriptor )
138 $formDescriptor[
'extra' ] = $extraInputsDescriptor;
140 is_string( $extraInputsDescriptor ) &&
141 $extraInputsDescriptor !==
''
144 $extraInputsString = $extraInputsDescriptor;
145 wfDeprecated(
'$input in LogEventsListGetExtraInputs hook',
'1.32' );
149 if ( !$this->
getConfig()->
get(
'MiserMode' ) ) {
154 $formDescriptor[
'date'] = [
156 'label-message' =>
'date',
157 'default' => $year && $month && $day ? sprintf(
"%04d-%02d-%02d", $year, $month, $day ) :
'',
161 $formDescriptor[
'tagfilter'] = [
162 'type' =>
'tagfilter',
163 'name' =>
'tagfilter',
164 'label-raw' => $this->
msg(
'tag-filter' )->parse(),
175 $this->allowedActions !==
null &&
176 count( $this->allowedActions ) > 0
183 $htmlForm = HTMLForm::factory(
'ooui', $formDescriptor,
$context );
185 ->setSubmitText( $this->
msg(
'logeventslist-submit' )->text() )
187 ->setWrapperLegendMsg(
'log' );
190 if ( isset( $extraInputsString ) ) {
191 $htmlForm->addFooterText( Html::rawElement(
198 $htmlForm->prepareForm()->displayForm(
false );
208 foreach ( $filter as
$type => $val ) {
209 $optionsMsg[
"logeventslist-{$type}-log"] =
$type;
211 if ( $val ===
false ) {
216 'class' =>
'HTMLMultiSelectField',
217 'label-message' =>
'logeventslist-more-filters',
219 'options-messages' => $optionsMsg,
220 'default' => $default,
229 $queryType = count( $queryTypes ) == 1 ? $queryTypes[0] :
'';
235 $restriction = $page->getRestriction();
236 if ( MediaWikiServices::getInstance()
238 ->userHasRight( $this->
getUser(), $restriction )
240 $typesByName[
$type] = $page->getName()->text();
245 asort( $typesByName );
248 $public = $typesByName[
''];
249 unset( $typesByName[
''] );
250 $typesByName = [
'' => $public ] + $typesByName;
253 'class' =>
'HTMLSelectField',
255 'options' => array_flip( $typesByName ),
256 'default' => $queryType,
266 'class' =>
'HTMLUserTextField',
267 'label-message' =>
'specialloguserlabel',
279 'class' =>
'HTMLTitleTextField',
280 'label-message' =>
'speciallogtitlelabel',
293 'label-message' =>
'log-title-wildcard',
303 if ( count( $types ) == 1 ) {
304 if ( $types[0] ==
'suppress' ) {
307 'label-message' =>
'revdelete-offender',
308 'name' =>
'offender',
314 $formDescriptor = [];
315 $this->hookRunner->onLogEventsListGetExtraInputs( $types[0], $this, $input, $formDescriptor );
317 return empty( $formDescriptor ) ? $input : $formDescriptor;
332 $actionOptions[
'log-action-filter-all' ] =
'';
334 foreach ( $this->allowedActions as $value ) {
335 $msgKey =
'log-action-filter-' . $types[0] .
'-' . $value;
336 $actionOptions[ $msgKey ] = $value;
340 'class' =>
'HTMLSelectField',
342 'options-messages' => $actionOptions,
343 'default' => $action,
344 'label' => $this->
msg(
'log-action-filter-' . $types[0] )->text(),
355 $this->allowedActions = $actions;
377 $entry = DatabaseLogEntry::newFromRow( $row );
379 $formatter->setContext( $this->
getContext() );
381 $formatter->setShowUserToolLinks( !( $this->flags & self::NO_EXTRA_USER_LINKS ) );
383 $time = htmlspecialchars( $this->
getLanguage()->userTimeAndDate(
384 $entry->getTimestamp(), $this->getUser() ) );
386 $action = $formatter->getActionText();
388 if ( $this->flags & self::NO_ACTION_LINK ) {
391 $revert = $formatter->getActionLinks();
392 if ( $revert !=
'' ) {
393 $revert =
'<span class="mw-logevent-actionlink">' . $revert .
'</span>';
397 $comment = $formatter->getComment();
408 $classes = array_merge(
409 [
'mw-logline-' . $entry->getType() ],
413 'data-mw-logid' => $entry->getId(),
414 'data-mw-logaction' => $entry->getFullType(),
416 $ret =
"$del $time $action $comment $revert $tagDisplay";
419 $this->hookRunner->onLogEventsListLineEnding( $this, $ret, $entry, $classes, $attribs );
420 $attribs = array_filter( $attribs,
421 [ Sanitizer::class,
'isReservedDataAttribute' ],
424 $attribs[
'class'] = implode(
' ', $classes );
426 return Html::rawElement(
'li', $attribs, $ret ) .
"\n";
435 if ( $this->flags == self::NO_ACTION_LINK ) {
442 if ( $this->flags & self::USE_CHECKBOXES && $this->showTagEditUI ) {
446 [
'name' =>
'ids[' . $row->log_id .
']' ]
451 if ( $row->log_type ==
'suppress' ) {
456 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
458 if ( $permissionManager->userHasRight( $user,
'deletedhistory' ) ) {
459 $canHide = $permissionManager->userHasRight( $user,
'deletelogentry' );
460 $canViewSuppressedOnly = $permissionManager->userHasRight( $user,
'viewsuppressed' ) &&
461 !$permissionManager->userHasRight( $user,
'suppressrevision' );
463 $canViewThisSuppressedEntry = $canViewSuppressedOnly && $entryIsSuppressed;
464 if ( $row->log_deleted || $canHide ) {
466 if ( $canHide && $this->flags & self::USE_CHECKBOXES && !$canViewThisSuppressedEntry ) {
469 $del = Xml::check(
'deleterevisions',
false, [
'disabled' =>
'disabled' ] );
474 [
'name' =>
'ids[' . $row->log_id .
']' ]
485 'ids' => $row->log_id,
490 $canHide && !$canViewThisSuppressedEntry
508 if ( $right !==
'' ) {
509 wfDeprecated( __METHOD__ .
' with a right specified',
'1.35' );
511 $match = is_array(
$type ) ?
512 in_array( $row->log_type,
$type ) : $row->log_type ==
$type;
514 $match = is_array( $action ) ?
515 in_array( $row->log_action, $action ) : $row->log_action == $action;
516 if ( $match && $right ) {
518 $match = MediaWikiServices::getInstance()
519 ->getPermissionManager()
520 ->userHasRight( $wgUser, $right );
536 public static function userCan( $row, $field,
User $user =
null ) {
538 wfDeprecated( __METHOD__ .
' without passing a $user parameter',
'1.35' );
542 return self::userCanBitfield( $row->log_deleted, $field, $user ) &&
543 self::userCanViewLogType( $row->log_type, $user );
556 if ( $bitfield & $field ) {
557 if ( $user ===
null ) {
558 wfDeprecated( __METHOD__ .
' without passing a $user parameter',
'1.35' );
563 $permissions = [
'suppressrevision',
'viewsuppressed' ];
565 $permissions = [
'deletedhistory' ];
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 );
585 if ( $user ===
null ) {
586 wfDeprecated( __METHOD__ .
' without passing a $user parameter',
'1.35' );
590 $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()->get(
'LogRestrictions' );
591 if ( isset( $logRestrictions[
$type] ) && !MediaWikiServices::getInstance()
593 ->userHasRight( $user, $logRestrictions[
$type] )
606 return ( $row->log_deleted & $field ) == $field;
635 &$out, $types = [], $page =
'', $user =
'', $param = []
637 $defaultParameters = [
640 'showIfEmpty' =>
true,
644 'useRequestParams' =>
false,
645 'useMaster' =>
false,
646 'extraUrlParams' =>
false,
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'];
658 $extraUrlParams = $param[
'extraUrlParams'];
660 $useRequestParams = $param[
'useRequestParams'];
662 if ( !is_array( $msgKey ) ) {
663 $msgKey = [ $msgKey ];
669 $context = RequestContext::getMain();
673 $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
675 # Insert list of top 50 (or top $lim) items
677 $pager =
new LogPager( $loglist, $types, $user, $page,
'', $conds );
678 if ( !$useRequestParams ) {
679 # Reset vars that may have been taken from the request
681 $pager->mDefaultLimit = 50;
682 $pager->mOffset =
"";
683 $pager->mIsBackwards =
false;
686 if ( $param[
'useMaster'] ) {
689 if ( isset( $param[
'offset'] ) ) { # Tell pager to ignore
WebRequest offset
690 $pager->setOffset( $param[
'offset'] );
695 $pager->mLimit = $lim;
698 $logBody = $pager->getBody();
699 $numRows = $pager->getNumRows();
708 $s = Xml::openElement(
'div', [
709 'class' =>
"warningbox mw-warning-with-logexcerpt mw-content-$dir",
715 if ( count( $msgKey ) == 1 ) {
719 array_shift(
$args );
723 $s .= $loglist->beginLogEventsList() .
725 $loglist->endLogEventsList();
728 } elseif ( $showIfEmpty ) {
729 $s = Html::rawElement(
'div', [
'class' =>
'mw-warning-logempty' ],
733 if ( $numRows > $pager->mLimit ) { # Show
"Full log" link
735 if ( $page instanceof
Title ) {
736 $urlParam[
'page'] = $page->getPrefixedDBkey();
737 } elseif ( $page !=
'' ) {
738 $urlParam[
'page'] = $page;
742 $urlParam[
'user'] = $user;
745 if ( !is_array( $types ) ) { # Make it an array,
if it isn
't
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];
754 // @phan-suppress-next-line PhanSuspiciousValueComparison
755 if ( $extraUrlParams !== false ) {
756 $urlParam = array_merge( $urlParam, $extraUrlParams );
759 $s .= $linkRenderer->makeKnownLink(
760 SpecialPage::getTitleFor( 'Log
' ),
761 $context->msg( 'log-fulllog
' )->text(),
767 if ( $logBody && $msgKey[0] ) {
771 // @phan-suppress-next-line PhanSuspiciousValueComparison
772 if ( $wrap != '' ) { // Wrap message in html
773 $s = str_replace( '$1
', $s, $wrap );
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 ) ) {
800 if ( $audience !=
'public' && $user ===
null ) {
803 ' using a non-public audience without passing a $user parameter',
815 if ( $audience ==
'public' || !MediaWikiServices::getInstance()
817 ->userHasRight( $user, $right )
819 $hiddenLogs[] = $logType;
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 ) .
')';
$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.
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()
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.
static revDeleteLink( $query=[], $restricted=false, $delete=true)
Creates a (show/hide) link for deleting revisions/log entries.
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.
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)
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,...
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,...
static isDeleted( $row, $field)
Class to simplify the use of log pages.
static validTypes()
Get the list of valid log types.
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.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
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.
if(!isset( $args[0])) $lang