36use Wikimedia\Timestamp\TimestampFormat as TS;
108 private $linkRenderer;
111 private $contentLanguage;
114 private $commentFormatter;
117 private $userEditTracker;
132 $this->context = RequestContext::getMain();
147 $this->linkRenderer = $linkRenderer;
155 if ( $this->linkRenderer !==
null ) {
156 return $this->linkRenderer;
158 wfDeprecated( static::class .
" without all required services",
'1.42' );
169 $this->contentLanguage = $contentLanguage;
177 if ( $this->contentLanguage === null ) {
178 wfDeprecated( static::class .
" without all required services",
'1.42' );
181 return $this->contentLanguage;
190 $this->commentFormatter = $commentFormatter;
198 if ( $this->commentFormatter === null ) {
199 wfDeprecated( static::class .
" without all required services",
'1.42' );
202 return $this->commentFormatter;
211 $this->userEditTracker = $userEditTracker;
219 if ( $this->userEditTracker === null ) {
220 wfDeprecated( static::class .
" without all required services",
'1.42' );
221 $this->userEditTracker = MediaWikiServices::getInstance()->getUserEditTracker();
223 return $this->userEditTracker;
233 $this->audience = ( $audience == self::FOR_THIS_USER )
234 ? self::FOR_THIS_USER
245 $logRestrictions = $this->context->getConfig()->get( MainConfigNames::LogRestrictions );
246 $type = $this->entry->getType();
247 return !isset( $logRestrictions[$type] )
248 || $this->context->getAuthority()->isAllowed( $logRestrictions[$type] );
257 if ( $this->audience == self::FOR_THIS_USER ) {
258 return LogEventsList::userCanBitfield(
259 $this->entry->getDeleted(), $field, $this->context->getAuthority() ) &&
260 self::canViewLogType();
262 return !$this->entry->isDeleted( $field ) && self::canViewLogType();
273 $this->linkFlood = $value;
285 $this->plaintext =
true;
286 $text = $this->getActionText();
287 $this->plaintext =
false;
299 $actionComment = $this->getIRCActionText();
300 $comment = $this->entry->getComment();
302 if ( $comment !=
'' ) {
303 if ( $actionComment ==
'' ) {
304 $actionComment = $comment;
306 $actionComment .=
wfMessage(
'colon-separator' )->inContentLanguage()->text() . $comment;
310 return $actionComment;
321 $this->plaintext =
true;
322 $this->irctext =
true;
324 $entry = $this->entry;
325 $parameters = $entry->getParameters();
328 $target = $entry->getTarget()->getPrefixedText();
330 $contLang = $this->getContentLanguage();
331 switch ( $entry->getType() ) {
333 switch ( $entry->getSubtype() ) {
335 $movesource = $parameters[
'4::target'];
337 ->rawParams( $target, $movesource )->inContentLanguage()->escaped();
340 $movesource = $parameters[
'4::target'];
342 ->rawParams( $target, $movesource )->inContentLanguage()->escaped();
344 case 'move-noredirect':
346 case 'move_redir-noredirect':
352 switch ( $entry->getSubtype() ) {
355 ->rawParams( $target )->inContentLanguage()->escaped();
359 ->rawParams( $target )->inContentLanguage()->escaped();
367 if ( $entry->getSubtype() ===
'patrol' ) {
368 $diffLink = htmlspecialchars(
369 wfMessage(
'patrol-log-diff', $parameters[
'4::curid'] )
370 ->inContentLanguage()->text() );
371 $text =
wfMessage(
'patrol-log-line', $diffLink,
"[[$target]]",
"" )
372 ->inContentLanguage()->text();
379 switch ( $entry->getSubtype() ) {
382 ->rawParams( $target .
' ' . $parameters[
'4::description'] )
383 ->inContentLanguage()
387 $text =
wfMessage(
'unprotectedarticle' )
388 ->rawParams( $target )->inContentLanguage()->escaped();
391 $text =
wfMessage(
'modifiedarticleprotection' )
392 ->rawParams( $target .
' ' . $parameters[
'4::description'] )
393 ->inContentLanguage()
397 $text =
wfMessage(
'movedarticleprotection' )
398 ->rawParams( $target, $parameters[
'4::oldtitle'] )->inContentLanguage()->escaped();
404 switch ( $entry->getSubtype() ) {
407 $text =
wfMessage(
'newuserlog-create-entry' )
408 ->inContentLanguage()->escaped();
412 $text =
wfMessage(
'newuserlog-create2-entry' )
413 ->rawParams( $target )->inContentLanguage()->escaped();
416 $text =
wfMessage(
'newuserlog-autocreate-entry' )
417 ->inContentLanguage()->escaped();
423 switch ( $entry->getSubtype() ) {
426 ->rawParams( $target )->inContentLanguage()->escaped();
431 ->rawParams( $target )->inContentLanguage()->escaped();
437 if ( count( $parameters[
'4::oldgroups'] ) ) {
438 $oldgroups = implode(
', ', $parameters[
'4::oldgroups'] );
440 $oldgroups =
wfMessage(
'rightsnone' )->inContentLanguage()->escaped();
442 if ( count( $parameters[
'5::newgroups'] ) ) {
443 $newgroups = implode(
', ', $parameters[
'5::newgroups'] );
445 $newgroups =
wfMessage(
'rightsnone' )->inContentLanguage()->escaped();
447 switch ( $entry->getSubtype() ) {
450 ->rawParams( $target, $oldgroups, $newgroups )->inContentLanguage()->escaped();
453 $text =
wfMessage(
'rightslogentry-autopromote' )
454 ->rawParams( $target, $oldgroups, $newgroups )->inContentLanguage()->escaped();
460 switch ( $entry->getSubtype() ) {
462 $text =
wfMessage(
'pagemerge-logentry' )
463 ->rawParams( $target, $parameters[
'4::dest'], $parameters[
'5::mergepoint'] )
464 ->inContentLanguage()->escaped();
474 switch ( $entry->getSubtype() ) {
478 if ( $entry->isLegacy() ) {
479 $rawDuration = $parameters[0];
480 $rawFlags = $parameters[1] ??
'';
482 $rawDuration = $parameters[
'5::duration'];
483 $rawFlags = $parameters[
'6::flags'];
485 $duration = $contLang->translateBlockExpiry(
488 (
int)
wfTimestamp( TS::UNIX, $entry->getTimestamp() )
490 $flags = BlockLogFormatter::formatBlockFlags( $rawFlags, $contLang );
492 ->rawParams( $target, $duration, $flags )->inContentLanguage()->escaped();
496 ->rawParams( $target )->inContentLanguage()->escaped();
499 $duration = $contLang->translateBlockExpiry(
500 $parameters[
'5::duration'],
502 (
int)
wfTimestamp( TS::UNIX, $entry->getTimestamp() )
504 $flags = BlockLogFormatter::formatBlockFlags( $parameters[
'6::flags'],
507 ->rawParams( $target, $duration, $flags )->inContentLanguage()->escaped();
513 switch ( $entry->getSubtype() ) {
515 $text =
wfMessage(
'import-logentry-upload' )
516 ->rawParams( $target )->inContentLanguage()->escaped();
519 $text =
wfMessage(
'import-logentry-interwiki' )
520 ->rawParams( $target )->inContentLanguage()->escaped();
528 $this->plaintext =
false;
529 $this->irctext =
false;
531 return $text ?? $this->getPlainActionText();
542 if ( $this->canView( LogPage::DELETED_ACTION ) ) {
543 $element = $this->getActionMessage();
544 if ( $element instanceof
Message ) {
545 $element = $this->plaintext ? $element->text() : $element->escaped();
547 if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) ) {
548 $element = $this->styleRestrictedElement( $element );
551 $sep = $this->msg(
'word-separator' );
552 $sep = $this->plaintext ? $sep->text() : $sep->escaped();
553 $performer = $this->getPerformerElement();
554 $element = $performer . $sep . $this->getRestrictedElement(
'rev-deleted-event' );
567 $message = $this->msg( $this->getMessageKey() );
568 $message->params( $this->getMessageParameters() );
582 $type = $this->entry->getType();
583 $subtype = $this->entry->getSubtype();
585 return "logentry-$type-$subtype";
606 $entry = $this->entry;
609 if ( $entry->isLegacy() ) {
610 foreach ( $entry->getParameters() as $index => $value ) {
611 $params[$index + 3] = $value;
616 foreach ( $entry->getParameters() as $key => $value ) {
617 if ( !str_contains( $key,
':' ) ) {
620 [ $index, $type, ] = explode(
':', $key, 3 );
621 if ( ctype_digit( $index ) ) {
622 $params[(int)$index - 1] = $this->formatParameterValue( $type, $value );
630 if ( count( $params ) ) {
631 $max = max( array_keys( $params ) );
633 for ( $i = 3; $i < $max; $i++ ) {
634 if ( !isset( $params[$i] ) ) {
662 if ( $this->parsedParameters !==
null ) {
663 return $this->parsedParameters;
666 $entry = $this->entry;
667 $params = $this->extractParameters();
668 $params[0] = Message::rawParam( $this->getPerformerElement() );
669 $params[1] = $this->canView( LogPage::DELETED_USER ) ? $entry->getPerformerIdentity()->getName() :
'';
670 $params[2] = Message::rawParam( $this->makePageLink( $entry->getTarget() ) );
675 $this->parsedParameters = $params;
676 return $this->parsedParameters;
707 $saveLinkFlood = $this->linkFlood;
709 switch ( strtolower( trim( $type ) ) ) {
712 $value = Message::plaintextParam( $value );
715 $value = $this->context->getLanguage()->commaList( $value );
718 $value = $this->msg( $value )->text();
721 $value = $this->msg( $value )->inContentLanguage()->text();
724 $value = Message::numParam( $value );
727 $user = User::newFromName( $value );
728 $value = $user->getName();
731 $this->setShowUserToolLinks(
false );
733 $user = User::newFromName( $value );
736 $value = $this->msg(
'empty-username' )->text();
738 $value = Message::rawParam( $this->makeUserLink( $user ) );
739 $this->setShowUserToolLinks( $saveLinkFlood );
743 $title = Title::newFromText( $value );
744 $value = $title->getPrefixedText();
747 $title = Title::newFromText( $value );
748 $value = Message::rawParam( $this->makePageLink( $title ) );
770 if ( !$title instanceof
Title ) {
771 $msg = $this->msg(
'invalidtitle' )->text();
772 if ( $this->plaintext ) {
775 return Html::element(
'span', [
'class' =>
'mw-invalidtitle' ], $msg );
779 if ( $this->plaintext ) {
780 $link =
'[[' . $title->getPrefixedText() .
']]';
782 $html = $html !==
null ?
new HtmlArmor( $html ) : $html;
783 $link = $this->getLinkRenderer()->makeLink( $title, $html, [], $parameters );
796 if ( $this->canView( LogPage::DELETED_USER ) ) {
797 $performerIdentity = $this->entry->getPerformerIdentity();
798 $element = $this->makeUserLink( $performerIdentity );
799 if ( $this->entry->isDeleted( LogPage::DELETED_USER ) ) {
800 $element = $this->styleRestrictedElement( $element );
803 $element = $this->getRestrictedElement(
'rev-deleted-user' );
815 if ( $this->canView( LogPage::DELETED_COMMENT ) ) {
816 $comment = $this->getCommentFormatter()
817 ->formatBlock( $this->entry->getComment(),
null,
false, $this->getCommentWikiId() );
819 $element = ltrim( $comment );
820 if ( $this->entry->isDeleted( LogPage::DELETED_COMMENT ) ) {
821 $element = $this->styleRestrictedElement( $element );
824 $element = $this->getRestrictedElement(
'rev-deleted-comment' );
854 if ( $this->plaintext ) {
855 return $this->msg( $message )->text();
858 return $this->styleRestrictedElement( $this->msg( $message )->escaped() );
867 if ( $this->plaintext ) {
870 $attribs = [
'class' => [
'history-deleted' ] ];
871 if ( $this->entry->isDeleted( LogPage::DELETED_RESTRICTED ) ) {
872 $attribs[
'class'][] =
'mw-history-suppressed';
875 return Html::rawElement(
'span', $attribs, $content );
886 protected function msg( $key, ...$params ) {
887 return $this->context->msg( $key, ...$params );
897 if ( $this->plaintext ) {
900 $element = Linker::userLink(
904 if ( $this->linkFlood ) {
905 $editCount = $this->getUserEditTracker()->getUserEditCount( $user );
907 $element .= Linker::userToolLinks(
937 return $this->getMessageParameters();
947 if ( LogEntryBase::containsUnsafeParams( $this->entry->getParameters() ) ) {
951 return $this->entry->getParameters();
971 foreach ( $this->getParametersForApi() as $key => $value ) {
972 $vals = explode(
':', $key, 3 );
973 if ( count( $vals ) !== 3 ) {
974 $logParams[$key] = $value;
977 $logParams += $this->formatParameterValueForApi( $vals[2], $vals[1], $value );
979 ApiResult::setIndexedTagName( $logParams,
'param' );
980 ApiResult::setArrayType( $logParams,
'assoc' );
995 $type = strtolower( trim( $type ) );
998 $value = (bool)$value;
1002 if ( is_int( $value ) || ctype_digit( (
string)$value ) ) {
1003 $value = (int)$value;
1005 $value = (float)$value;
1012 if ( is_array( $value ) ) {
1013 ApiResult::setArrayType( $value, $type );
1023 $msg = $this->msg( $value );
1024 if ( $type ===
'msg-content' ) {
1025 $msg->inContentLanguage();
1028 $value[
"{$name}_key"] = $msg->getKey();
1029 if ( $msg->getParams() ) {
1030 $value[
"{$name}_params"] = $msg->getParams();
1032 $value[
"{$name}_text"] = $msg->text();
1037 $title = Title::newFromText( $value );
1039 $title = SpecialPage::getTitleFor(
'Badtitle', $value );
1042 ApiQueryBase::addTitleInfo( $value, $title,
"{$name}_" );
1047 $user = User::newFromName( $value );
1049 $value = $user->getName();
1058 return [ $name => $value ];
1063class_alias( LogFormatter::class,
'LogFormatter' );
wfTimestamp( $outputtype=TS::UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
if(!defined('MW_SETUP_CALLBACK'))
Group all the pieces relevant to the context of a request into one instance.
static newFromRow( $row, string|false $wikiId=WikiAwareEntity::LOCAL)
Constructs new LogEntry from database result row.
A class containing constants representing the names of configuration variables.
Parent class for all special pages.
Interface for objects which can provide a MediaWiki context on request.