88 if ( $this->linkRenderer !==
null ) {
91 return MediaWikiServices::getInstance()->getLinkRenderer();
111 public function showOptions( $types = [], $user =
'', $page =
'', $pattern =
false, $year = 0,
112 $month = 0, $day = 0,
$filter =
null, $tagFilter =
'', $action =
null
115 $types = ( $types ===
'' ) ? [] : (array)$types;
117 $formDescriptor = [];
130 is_array( $extraInputsDescriptor ) &&
131 !empty( $extraInputsDescriptor )
133 $formDescriptor[
'extra' ] = $extraInputsDescriptor;
135 is_string( $extraInputsDescriptor ) &&
136 $extraInputsDescriptor !==
''
139 $extraInputsString = $extraInputsDescriptor;
140 wfDeprecated(
'$input in LogEventsListGetExtraInputs hook',
'1.32' );
144 if ( !$this->
getConfig()->
get(
'MiserMode' ) ) {
149 $formDescriptor[
'date'] = [
151 'label-message' =>
'date',
152 'default' => $year && $month && $day ? sprintf(
"%04d-%02d-%02d", $year, $month, $day ) :
'',
156 $formDescriptor[
'tagfilter'] = [
157 'type' =>
'tagfilter',
158 'name' =>
'tagfilter',
159 'label-raw' => $this->
msg(
'tag-filter' )->parse(),
170 $this->allowedActions !==
null &&
171 count( $this->allowedActions ) > 0
180 ->setSubmitText( $this->
msg(
'logeventslist-submit' )->text() )
182 ->setWrapperLegendMsg(
'log' );
185 if ( isset( $extraInputsString ) ) {
186 $htmlForm->addFooterText( Html::rawElement(
193 $htmlForm->prepareForm()->displayForm(
false );
204 $message = $this->
msg(
"logeventslist-{$type}-log" );
206 if ( !$message->exists() ) {
207 $message = $this->
msg(
"log-show-hide-{$type}" )->params( $this->
msg(
'show' )->text() );
209 $options[ $message->text() ] =
$type;
211 if ( $val ===
false ) {
216 'class' =>
'HTMLMultiSelectField',
217 'label-message' =>
'logeventslist-more-filters',
219 'options' => $options,
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 Hooks::run(
'LogEventsListGetExtraInputs', [ $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;
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 Hooks::run(
'LogEventsListLineEnding', [ $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 $match = is_array(
$type ) ?
509 in_array( $row->log_type,
$type ) : $row->log_type ==
$type;
511 $match = is_array( $action ) ?
512 in_array( $row->log_action, $action ) : $row->log_action == $action;
513 if ( $match && $right ) {
515 $match = MediaWikiServices::getInstance()
516 ->getPermissionManager()
517 ->userHasRight( $wgUser, $right );
533 public static function userCan( $row, $field,
User $user =
null ) {
548 if ( $bitfield & $field ) {
549 if ( $user ===
null ) {
554 $permissions = [
'suppressrevision',
'viewsuppressed' ];
556 $permissions = [
'deletedhistory' ];
558 $permissionlist = implode(
', ', $permissions );
559 wfDebug(
"Checking for $permissionlist due to $field match on $bitfield\n" );
560 return MediaWikiServices::getInstance()
561 ->getPermissionManager()
562 ->userHasAnyRight( $user, ...$permissions );
576 if ( $user ===
null ) {
580 $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()->get(
'LogRestrictions' );
581 if ( isset( $logRestrictions[
$type] ) && !MediaWikiServices::getInstance()
583 ->userHasRight( $user, $logRestrictions[
$type] )
596 return ( $row->log_deleted & $field ) == $field;
625 &$out, $types = [], $page =
'', $user =
'', $param = []
627 $defaultParameters = [
630 'showIfEmpty' =>
true,
634 'useRequestParams' =>
false,
635 'useMaster' =>
false,
636 'extraUrlParams' =>
false,
638 # The + operator appends elements of remaining keys from the right
639 # handed array to the left handed, whereas duplicated keys are NOT overwritten.
640 $param += $defaultParameters;
641 # Convert $param array to individual variables
642 $lim = $param[
'lim'];
643 $conds = $param[
'conds'];
644 $showIfEmpty = $param[
'showIfEmpty'];
645 $msgKey = $param[
'msgKey'];
646 $wrap = $param[
'wrap'];
648 $extraUrlParams = $param[
'extraUrlParams'];
650 $useRequestParams = $param[
'useRequestParams'];
651 if ( !is_array( $msgKey ) ) {
652 $msgKey = [ $msgKey ];
655 if ( $out instanceof OutputPage ) {
662 $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
664 # Insert list of top 50 (or top $lim) items
666 $pager =
new LogPager( $loglist, $types, $user, $page,
'', $conds );
667 if ( !$useRequestParams ) {
668 # Reset vars that may have been taken from the request
670 $pager->mDefaultLimit = 50;
671 $pager->mOffset =
"";
672 $pager->mIsBackwards =
false;
675 if ( $param[
'useMaster'] ) {
678 if ( isset( $param[
'offset'] ) ) { # Tell pager to ignore
WebRequest offset
679 $pager->setOffset( $param[
'offset'] );
683 $pager->mLimit = $lim;
686 $logBody = $pager->getBody();
687 $numRows = $pager->getNumRows();
697 'class' =>
"mw-warning-with-logexcerpt mw-content-$dir",
702 if ( count( $msgKey ) == 1 ) {
706 array_shift(
$args );
710 $s .= $loglist->beginLogEventsList() .
712 $loglist->endLogEventsList();
715 } elseif ( $showIfEmpty ) {
716 $s = Html::rawElement(
'div', [
'class' =>
'mw-warning-logempty' ],
720 if ( $numRows > $pager->mLimit ) { # Show
"Full log" link
722 if ( $page instanceof
Title ) {
723 $urlParam[
'page'] = $page->getPrefixedDBkey();
724 } elseif ( $page !=
'' ) {
725 $urlParam[
'page'] = $page;
729 $urlParam[
'user'] = $user;
732 if ( !is_array( $types ) ) { # Make it an array,
if it isn
't
736 # If there is exactly one log type, we can link to Special:Log?type=foo
737 if ( count( $types ) == 1 ) {
738 $urlParam['type
'] = $types[0];
741 if ( $extraUrlParams !== false ) {
742 $urlParam = array_merge( $urlParam, $extraUrlParams );
745 $s .= $linkRenderer->makeKnownLink(
746 SpecialPage::getTitleFor( 'Log
' ),
747 $context->msg( 'log-fulllog
' )->text(),
753 if ( $logBody && $msgKey[0] ) {
757 if ( $wrap != '' ) { // Wrap message in html
758 $s = str_replace( '$1
', $s, $wrap );
761 /* hook can return false, if we don't want the message to be emitted (Wikia BugId:7093) */
762 if (
Hooks::run(
'LogEventsListShowLogExtract', [ &
$s, $types, $page, $user, $param ] ) ) {
764 if ( $out instanceof OutputPage ) {
785 if ( $audience !=
'public' && $user ===
null ) {
795 if ( $audience ==
'public' || !MediaWikiServices::getInstance()
797 ->userHasRight( $user, $right )
799 $hiddenLogs[] = $logType;
802 if ( count( $hiddenLogs ) == 1 ) {
803 return 'log_type != ' . $db->addQuotes( $hiddenLogs[0] );
804 } elseif ( $hiddenLogs ) {
805 return 'log_type NOT IN (' . $db->makeList( $hiddenLogs ) .
')';