48 protected $allowedActions =
null;
68 public function __construct( $context, $linkRenderer =
null, $flags = 0 ) {
75 $this->hookRunner = Hooks::runner();
83 if ( $this->linkRenderer !==
null ) {
84 return $this->linkRenderer;
86 return MediaWikiServices::getInstance()->getLinkRenderer();
106 public function showOptions( $types = [], $user =
'', $page =
'', $pattern =
false, $year = 0,
107 $month = 0, $day = 0, $filter =
null, $tagFilter =
'', $action =
null
110 $types = ( $types ===
'' ) ? [] : (array)$types;
112 $formDescriptor = [];
125 is_array( $extraInputsDescriptor ) &&
126 !empty( $extraInputsDescriptor )
128 $formDescriptor[
'extra' ] = $extraInputsDescriptor;
130 is_string( $extraInputsDescriptor ) &&
131 $extraInputsDescriptor !==
''
134 $extraInputsString = $extraInputsDescriptor;
135 wfDeprecated(
'$input in LogEventsListGetExtraInputs hook',
'1.32' );
139 if ( !$this->
getConfig()->
get(
'MiserMode' ) ) {
144 $formDescriptor[
'date'] = [
146 'label-message' =>
'date',
147 'default' => $year && $month && $day ? sprintf(
"%04d-%02d-%02d", $year, $month, $day ) :
'',
151 $formDescriptor[
'tagfilter'] = [
152 'type' =>
'tagfilter',
153 'name' =>
'tagfilter',
154 'label-message' =>
'tag-filter',
165 $this->allowedActions !==
null &&
166 count( $this->allowedActions ) > 0
173 $htmlForm = HTMLForm::factory(
'ooui', $formDescriptor,
$context );
175 ->setSubmitTextMsg(
'logeventslist-submit' )
177 ->setWrapperLegendMsg(
'log' );
180 if ( isset( $extraInputsString ) ) {
181 $htmlForm->addFooterText( Html::rawElement(
188 $htmlForm->prepareForm()->displayForm(
false );
198 foreach ( $filter as
$type => $val ) {
199 $optionsMsg[
"logeventslist-{$type}-log"] =
$type;
201 if ( $val ===
false ) {
206 'class' => HTMLMultiSelectField::class,
207 'label-message' =>
'logeventslist-more-filters',
209 'options-messages' => $optionsMsg,
210 'default' => $default,
219 $queryType = count( $queryTypes ) == 1 ? $queryTypes[0] :
'';
225 $restriction = $page->getRestriction();
226 if ( $this->
getAuthority()->isAllowed( $restriction ) ) {
227 $typesByName[
$type] = $page->getName()->text();
232 asort( $typesByName );
235 $public = $typesByName[
''];
236 unset( $typesByName[
''] );
237 $typesByName = [
'' => $public ] + $typesByName;
240 'class' => HTMLSelectField::class,
242 'options' => array_flip( $typesByName ),
243 'default' => $queryType,
253 'class' => HTMLUserTextField::class,
254 'label-message' =>
'specialloguserlabel',
266 'class' => HTMLTitleTextField::class,
267 'label-message' =>
'speciallogtitlelabel',
280 'label-message' =>
'log-title-wildcard',
290 if ( count( $types ) == 1 ) {
291 if ( $types[0] ==
'suppress' ) {
294 'label-message' =>
'revdelete-offender',
295 'name' =>
'offender',
301 $formDescriptor = [];
302 $this->hookRunner->onLogEventsListGetExtraInputs( $types[0], $this, $input, $formDescriptor );
304 return empty( $formDescriptor ) ? $input : $formDescriptor;
319 $actionOptions[
'log-action-filter-all' ] =
'';
321 foreach ( $this->allowedActions as $value ) {
322 $msgKey =
'log-action-filter-' . $types[0] .
'-' . $value;
323 $actionOptions[ $msgKey ] = $value;
327 'class' => HTMLSelectField::class,
329 'options-messages' => $actionOptions,
330 'default' => $action,
331 'label' => $this->
msg(
'log-action-filter-' . $types[0] )->text(),
342 $this->allowedActions = $actions;
349 return "<ul class='mw-logevent-loglines'>\n";
364 $entry = DatabaseLogEntry::newFromRow( $row );
366 $formatter->setContext( $this->
getContext() );
368 $formatter->setShowUserToolLinks( !( $this->flags & self::NO_EXTRA_USER_LINKS ) );
371 $entry->getTimestamp(),
379 [
'logid' => $entry->getId() ]
382 $action = $formatter->getActionText();
384 if ( $this->flags & self::NO_ACTION_LINK ) {
387 $revert = $formatter->getActionLinks();
388 if ( $revert !=
'' ) {
389 $revert =
'<span class="mw-logevent-actionlink">' . $revert .
'</span>';
393 $comment = $formatter->getComment();
404 $classes = array_merge(
405 [
'mw-logline-' . $entry->getType() ],
409 'data-mw-logid' => $entry->getId(),
410 'data-mw-logaction' => $entry->getFullType(),
412 $ret =
"$del $timeLink $action $comment $revert $tagDisplay";
415 $this->hookRunner->onLogEventsListLineEnding( $this, $ret, $entry, $classes, $attribs );
416 $attribs = array_filter( $attribs,
417 [ Sanitizer::class,
'isReservedDataAttribute' ],
420 $attribs[
'class'] = $classes;
422 return Html::rawElement(
'li', $attribs, $ret ) .
"\n";
431 if ( $this->flags == self::NO_ACTION_LINK ) {
438 if ( $this->flags & self::USE_CHECKBOXES && $this->showTagEditUI ) {
442 [
'name' =>
'ids[' . $row->log_id .
']' ]
447 if ( $row->log_type ==
'suppress' ) {
453 if ( $this->
getAuthority()->isAllowed(
'deletedhistory' ) ) {
454 $canHide = $this->
getAuthority()->isAllowed(
'deletelogentry' );
455 $canViewSuppressedOnly = $this->
getAuthority()->isAllowed(
'viewsuppressed' ) &&
456 !$this->
getAuthority()->isAllowed(
'suppressrevision' );
458 $canViewThisSuppressedEntry = $canViewSuppressedOnly && $entryIsSuppressed;
459 if ( $row->log_deleted || $canHide ) {
461 if ( $canHide && $this->flags & self::USE_CHECKBOXES && !$canViewThisSuppressedEntry ) {
464 $del = Xml::check(
'deleterevisions',
false, [
'disabled' =>
'disabled' ] );
469 [
'name' =>
'ids[' . $row->log_id .
']' ]
480 'ids' => $row->log_id,
485 $canHide && !$canViewThisSuppressedEntry
502 $match = is_array(
$type ) ?
503 in_array( $row->log_type,
$type ) : $row->log_type ==
$type;
505 $match = is_array( $action ) ?
506 in_array( $row->log_action, $action ) : $row->log_action == $action;
522 return self::userCanBitfield( $row->log_deleted, $field, $performer ) &&
523 self::userCanViewLogType( $row->log_type, $performer );
536 if ( $bitfield & $field ) {
538 return $performer->
isAllowedAny(
'suppressrevision',
'viewsuppressed' );
540 return $performer->
isAllowed(
'deletedhistory' );
555 $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()->get(
'LogRestrictions' );
569 return ( $row->log_deleted & $field ) == $field;
598 &$out, $types = [], $page =
'', $user =
'', $param = []
600 $defaultParameters = [
603 'showIfEmpty' =>
true,
607 'useRequestParams' =>
false,
608 'useMaster' =>
false,
609 'extraUrlParams' =>
false,
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'];
621 $extraUrlParams = $param[
'extraUrlParams'];
623 $useRequestParams = $param[
'useRequestParams'];
625 if ( !is_array( $msgKey ) ) {
626 $msgKey = [ $msgKey ];
632 $context = RequestContext::getMain();
635 $services = MediaWikiServices::getInstance();
639 # Insert list of top 50 (or top $lim) items
654 $services->getLinkBatchFactory(),
655 $services->getDBLoadBalancer(),
656 $services->getActorNormalization()
658 if ( !$useRequestParams ) {
659 # Reset vars that may have been taken from the request
661 $pager->mDefaultLimit = 50;
662 $pager->mOffset =
"";
663 $pager->mIsBackwards =
false;
666 if ( $param[
'useMaster'] ) {
670 if ( isset( $param[
'offset'] ) ) { # Tell pager to ignore
WebRequest offset
671 $pager->setOffset( $param[
'offset'] );
676 $pager->mLimit = $lim;
679 $logBody = $pager->getBody();
680 $numRows = $pager->getNumRows();
689 $s = Xml::openElement(
'div', [
690 'class' =>
"warningbox mw-warning-with-logexcerpt mw-content-$dir",
696 if ( count( $msgKey ) == 1 ) {
700 array_shift(
$args );
704 $s .= $loglist->beginLogEventsList() .
706 $loglist->endLogEventsList();
709 } elseif ( $showIfEmpty ) {
710 $s = Html::rawElement(
'div', [
'class' =>
'mw-warning-logempty' ],
715 $titleFormatter = MediaWikiServices::getInstance()->getTitleFormatter();
716 $pageName = $titleFormatter->getPrefixedDBkey( $page );
717 } elseif ( $page !=
'' ) {
723 if ( $numRows > $pager->mLimit ) { # Show
"Full log" link
726 $urlParam[
'page'] = $pageName;
730 $urlParam[
'user'] = $user;
733 if ( !is_array( $types ) ) { # Make it an array,
if it isn
't
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];
742 // @phan-suppress-next-line PhanSuspiciousValueComparison
743 if ( $extraUrlParams !== false ) {
744 $urlParam = array_merge( $urlParam, $extraUrlParams );
747 $s .= $linkRenderer->makeKnownLink(
748 SpecialPage::getTitleFor( 'Log
' ),
749 $context->msg( 'log-fulllog
' )->text(),
755 if ( $logBody && $msgKey[0] ) {
759 // @phan-suppress-next-line PhanSuspiciousValueComparison
760 if ( $wrap != '' ) { // Wrap message in html
761 $s = str_replace( '$1
', $s, $wrap );
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 ) ) {
789 if ( $audience !=
'public' && $performer ===
null ) {
790 throw new InvalidArgumentException(
791 'A User object must be given when checking for a user audience.'
800 if ( $audience ==
'public' || !$performer->isAllowed( $right )
802 $hiddenLogs[] = $logType;
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 ) .
')';
$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.
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
const NO_EXTRA_USER_LINKS
getTitlePatternDesc( $pattern)
static typeAction( $row, $type, $action)
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)
__construct( $context, $linkRenderer=null, $flags=0)
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,...
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,...
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...
msg( $key,... $params)
This is the method for getting translated interface messages.
foreach( $mmfl['setupFiles'] as $fileName) if($queue) if(empty( $mmfl['quiet'])) $s
if(!isset( $args[0])) $lang