MediaWiki  master
CoreTagHooks.php
Go to the documentation of this file.
1 <?php
25 
30 class CoreTagHooks {
36  public static function register( $parser ) {
37  global $wgRawHtml;
38  $parser->setHook( 'pre', [ __CLASS__, 'pre' ] );
39  $parser->setHook( 'nowiki', [ __CLASS__, 'nowiki' ] );
40  $parser->setHook( 'gallery', [ __CLASS__, 'gallery' ] );
41  $parser->setHook( 'indicator', [ __CLASS__, 'indicator' ] );
42  $parser->setHook( 'langconvert', [ __CLASS__, 'langconvert' ] );
43  if ( $wgRawHtml ) {
44  $parser->setHook( 'html', [ __CLASS__, 'html' ] );
45  }
46  }
47 
59  public static function pre( ?string $content, array $attribs, Parser $parser ): string {
60  // Backwards-compatibility hack
61  $content = StringUtils::delimiterReplace( '<nowiki>', '</nowiki>', '$1', $content ?? '', 'i' );
62 
63  $attribs = Sanitizer::validateTagAttributes( $attribs, 'pre' );
64  // We need to let both '"' and '&' through,
65  // for strip markers and entities respectively.
66  $content = str_replace(
67  [ '>', '<' ],
68  [ '&gt;', '&lt;' ],
69  $content
70  );
71  // @phan-suppress-next-line SecurityCheck-XSS
72  return Html::rawElement( 'pre', $attribs, $content );
73  }
74 
92  public static function html( ?string $content, array $attributes, Parser $parser ) {
93  global $wgRawHtml;
94  if ( $wgRawHtml ) {
95  if ( $parser->getOptions()->getAllowUnsafeRawHtml() ) {
96  return [ $content ?? '', 'markerType' => 'nowiki' ];
97  } else {
98  // In a system message where raw html is
99  // not allowed (but it is allowed in other
100  // contexts).
101  return Html::rawElement(
102  'span',
103  [ 'class' => 'error' ],
104  // Using ->text() not ->parse() as
105  // a paranoia measure against a loop.
106  wfMessage( 'rawhtml-notallowed' )->escaped()
107  );
108  }
109  } else {
110  throw new MWException( '<html> extension tag encountered unexpectedly' );
111  }
112  }
113 
131  public static function nowiki( ?string $content, array $attributes, Parser $parser ): array {
132  $content = strtr( $content ?? '', [
133  // lang converter
134  '-{' => '-&#123;',
135  '}-' => '&#125;-',
136  // html tags
137  '<' => '&lt;',
138  '>' => '&gt;'
139  // Note: Both '"' and '&' are not converted.
140  // This allows strip markers and entities through.
141  ] );
142  return [ $content, 'markerType' => 'nowiki' ];
143  }
144 
161  public static function gallery( ?string $content, array $attributes, Parser $parser ): string {
162  // @phan-suppress-next-line SecurityCheck-XSS
163  return $parser->renderImageGallery( $content ?? '', $attributes );
164  }
165 
178  public static function indicator( ?string $content, array $attributes, Parser $parser, PPFrame $frame ): string {
179  if ( !isset( $attributes['name'] ) || trim( $attributes['name'] ) === '' ) {
180  return '<span class="error">' .
181  wfMessage( 'invalid-indicator-name' )->inContentLanguage()->parse() .
182  '</span>';
183  }
184 
185  $parser->getOutput()->setIndicator(
186  trim( $attributes['name'] ),
187  Parser::stripOuterParagraph( $parser->recursiveTagParseFully( $content ?? '', $frame ) )
188  );
189 
190  return '';
191  }
192 
204  public static function langconvert( ?string $content, array $attributes, Parser $parser, PPFrame $frame ): string {
205  if ( isset( $attributes['from'] ) && isset( $attributes['to'] ) ) {
206  $fromArg = trim( $attributes['from'] );
207  $toArg = trim( $attributes['to'] );
208  $fromLangCode = explode( '-', $fromArg )[0];
209  if ( $fromLangCode && $fromLangCode === explode( '-', $toArg )[0] ) {
210  $lang = MediaWikiServices::getInstance()->getLanguageFactory()
211  ->getLanguage( $fromLangCode );
212  $converter = MediaWikiServices::getInstance()->getLanguageConverterFactory()
213  ->getLanguageConverter( $lang );
214 
215  # ensure that variants are available,
216  # and the variants are valid BCP 47 codes
217  if ( $converter->hasVariants()
218  && strcasecmp( $fromArg, LanguageCode::bcp47( $fromArg ) ) === 0
219  && strcasecmp( $toArg, LanguageCode::bcp47( $toArg ) ) === 0
220  ) {
221  $toVariant = $converter->validateVariant( $toArg );
222 
223  if ( $toVariant ) {
224  // @phan-suppress-next-line SecurityCheck-XSS
225  return $converter->autoConvert(
226  $parser->recursiveTagParse( $content ?? '', $frame ),
227  $toVariant
228  );
229  }
230  }
231  }
232  }
233 
234  return Html::rawElement(
235  'span',
236  [ 'class' => 'error' ],
237  wfMessage( 'invalid-langconvert-attrs' )->inContentLanguage()->parse()
238  );
239  }
240 
241 }
CoreTagHooks\nowiki
static nowiki(?string $content, array $attributes, Parser $parser)
Core parser tag hook function for 'nowiki'.
Definition: CoreTagHooks.php:131
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:191
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
CoreTagHooks
Various tag hooks, registered in every Parser.
Definition: CoreTagHooks.php:30
Parser\recursiveTagParseFully
recursiveTagParseFully( $text, $frame=false)
Fully parse wikitext to fully parsed HTML.
Definition: Parser.php:876
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1182
CoreTagHooks\html
static html(?string $content, array $attributes, Parser $parser)
Core parser tag hook function for 'html', used only when $wgRawHtml is enabled.
Definition: CoreTagHooks.php:92
CoreTagHooks\gallery
static gallery(?string $content, array $attributes, Parser $parser)
Core parser tag hook function for 'gallery'.
Definition: CoreTagHooks.php:161
Parser\getOptions
getOptions()
Definition: Parser.php:1098
$wgRawHtml
$wgRawHtml
Allow raw, unchecked HTML in "<html>...</html>" sections.
Definition: DefaultSettings.php:4983
MWException
MediaWiki exception.
Definition: MWException.php:29
CoreTagHooks\indicator
static indicator(?string $content, array $attributes, Parser $parser, PPFrame $frame)
XML-style tag for page status indicators: icons (or short text snippets) usually displayed in the top...
Definition: CoreTagHooks.php:178
CoreTagHooks\pre
static pre(?string $content, array $attribs, Parser $parser)
Core parser tag hook function for 'pre'.
Definition: CoreTagHooks.php:59
Parser\recursiveTagParse
recursiveTagParse( $text, $frame=false)
Half-parse wikitext to half-parsed HTML.
Definition: Parser.php:852
$content
$content
Definition: router.php:76
Sanitizer\validateTagAttributes
static validateTagAttributes( $attribs, $element)
Take an array of attribute names and values and normalize or discard illegal values for the given ele...
Definition: Sanitizer.php:391
PPFrame
Definition: PPFrame.php:28
Parser\renderImageGallery
renderImageGallery( $text, array $params)
Renders an image gallery from a text with one line per image.
Definition: Parser.php:5030
Parser
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition: Parser.php:91
Parser\stripOuterParagraph
static stripOuterParagraph( $html)
Strip outer.
Definition: Parser.php:6337
LanguageCode\bcp47
static bcp47( $code)
Get the normalised IETF language tag See unit test for examples.
Definition: LanguageCode.php:175
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:210
Parser\getOutput
getOutput()
Definition: Parser.php:1090
StringUtils\delimiterReplace
static delimiterReplace( $startDelim, $endDelim, $replace, $subject, $flags='')
Perform an operation equivalent to preg_replace() with flags.
Definition: StringUtils.php:248
CoreTagHooks\langconvert
static langconvert(?string $content, array $attributes, Parser $parser, PPFrame $frame)
Returns content converted into the requested language variant, using LanguageConverter.
Definition: CoreTagHooks.php:204