MediaWiki fundraising/REL1_35
SignatureValidator.php
Go to the documentation of this file.
1<?php
21namespace MediaWiki\Preferences;
22
23use Html;
29use SpecialPage;
30use Title;
31use User;
33
38
40 private $user;
42 private $localizer;
44 private $popts;
45
47 $this->user = $user;
48 $this->localizer = $localizer;
49 $this->popts = $popts;
50 }
51
57 public function validateSignature( string $signature ) {
58 $pstSignature = $this->applyPreSaveTransform( $signature );
59 if ( $pstSignature === false ) {
60 // Return early because the rest of the validation uses wikitext parsing, which requires
61 // the pre-save transform to be applied first, and we just found out that the result of the
62 // pre-save transform would require *another* pre-save transform, which is crazy
63 if ( $this->localizer ) {
64 return [ $this->localizer->msg( 'badsigsubst' )->parse() ];
65 }
66 return true;
67 }
68
69 $pstWasApplied = false;
70 if ( $pstSignature !== $signature ) {
71 $pstWasApplied = true;
72 $signature = $pstSignature;
73 }
74
75 $errors = $this->localizer ? [] : false;
76
77 $lintErrors = $this->checkLintErrors( $signature );
78 if ( $lintErrors ) {
79 $config = MediaWikiServices::getInstance()->getMainConfig();
80 $allowedLintErrors = $config->get( 'SignatureAllowedLintErrors' );
81 $messages = '';
82
83 foreach ( $lintErrors as $error ) {
84 if ( in_array( $error['type'], $allowedLintErrors, true ) ) {
85 continue;
86 }
87 if ( !$this->localizer ) {
88 $errors = true;
89 break;
90 }
91
92 $details = $this->getLintErrorDetails( $error );
93 $location = $this->getLintErrorLocation( $error );
94 // Messages used here:
95 // * linter-pager-bogus-image-options-details
96 // * linter-pager-deletable-table-tag-details
97 // * linter-pager-html5-misnesting-details
98 // * linter-pager-misc-tidy-replacement-issues-details
99 // * linter-pager-misnested-tag-details
100 // * linter-pager-missing-end-tag-details
101 // * linter-pager-multi-colon-escape-details
102 // * linter-pager-multiline-html-table-in-list-details
103 // * linter-pager-multiple-unclosed-formatting-tags-details
104 // * linter-pager-obsolete-tag-details
105 // * linter-pager-pwrap-bug-workaround-details
106 // * linter-pager-self-closed-tag-details
107 // * linter-pager-stripped-tag-details
108 // * linter-pager-tidy-font-bug-details
109 // * linter-pager-tidy-whitespace-bug-details
110 // * linter-pager-unclosed-quotes-in-heading-details
111 $label = $this->localizer->msg( "linter-pager-{$error['type']}-details" )->parse();
112 $docsLink = new \OOUI\ButtonWidget( [
113 'href' =>
114 "https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Lint_errors/{$error['type']}",
115 'target' => '_blank',
116 'label' => $this->localizer->msg( 'prefs-signature-error-details' )->text(),
117 ] );
118
119 // If pre-save transform was applied (i.e., the signature has 'subst:' syntax),
120 // error locations will be incorrect, because Parsoid can't expand templates.
121 // Don't display them.
122 $encLocation = $pstWasApplied ? null : json_encode( $location );
123
124 $messages .= Html::rawElement(
125 'li',
126 [ 'data-mw-lint-error-location' => $encLocation ],
127 $label . $this->localizer->msg( 'colon-separator' )->escaped() .
128 $details . ' ' . $docsLink
129 );
130 }
131
132 if ( $messages && $this->localizer ) {
133 $errors[] = $this->localizer->msg( 'badsightml' )->parse() .
134 Html::rawElement( 'ul', [], $messages );
135 }
136 }
137
138 if ( !$this->checkUserLinks( $signature ) ) {
139 if ( $this->localizer ) {
140 $userText = wfEscapeWikiText( $this->user->getName() );
141 $linkWikitext = $this->localizer->msg( 'signature', $userText, $userText )->inContentLanguage()->text();
142 $errors[] = $this->localizer->msg( 'badsiglinks', wfEscapeWikiText( $linkWikitext ) )->parse();
143 } else {
144 $errors = true;
145 }
146 }
147
148 return $errors;
149 }
150
156 protected function applyPreSaveTransform( string $signature ) {
157 // This may be called by the Parser when it's displaying a signature, so we need a new instance
158 $parser = MediaWikiServices::getInstance()->getParser()->getFreshParser();
159
160 $pstSignature = $parser->preSaveTransform(
161 $signature,
162 SpecialPage::getTitleFor( 'Preferences' ),
163 $this->user,
164 $this->popts
165 );
166
167 // The signature wikitext contains another '~~~~' or similar (T230652)
168 if ( $parser->getOutput()->getFlag( 'user-signature' ) ) {
169 return false;
170 }
171
172 // The signature wikitext contains '{{subst:...}}' markup that produces another subst (T230652)
173 $pstPstSignature = $parser->preSaveTransform(
174 $pstSignature,
175 SpecialPage::getTitleFor( 'Preferences' ),
176 $this->user,
177 $this->popts
178 );
179 if ( $pstPstSignature !== $pstSignature ) {
180 return false;
181 }
182
183 return $pstSignature;
184 }
185
190 protected function checkLintErrors( string $signature ) : array {
191 // Real check for mismatched HTML tags in the *output*.
192 // This has to use Parsoid because PHP Parser doesn't produce this information,
193 // it just fixes up the result quietly.
194
195 // This request is not cached, but that's okay, because $signature is short (other code checks
196 // the length against $wgMaxSigChars).
197
198 $config = MediaWikiServices::getInstance()->getMainConfig();
199 $vrsConfig = $config->get( 'VirtualRestConfig' );
200 if ( isset( $vrsConfig['modules']['parsoid'] ) ) {
201 $params = $vrsConfig['modules']['parsoid'];
202 if ( isset( $vrsConfig['global'] ) ) {
203 $params = array_merge( $vrsConfig['global'], $params );
204 }
205 $parsoidVrs = new ParsoidVirtualRESTService( $params );
206
207 $vrsClient = new VirtualRESTServiceClient( new MultiHttpClient( [] ) );
208 $vrsClient->mount( '/parsoid/', $parsoidVrs );
209
210 $request = [
211 'method' => 'POST',
212 'url' => '/parsoid/local/v3/transform/wikitext/to/lint',
213 'body' => [
214 'wikitext' => $signature,
215 ],
216 'headers' => [
217 // Are both of these are really needed?
218 'User-Agent' => 'MediaWiki/' . MW_VERSION,
219 'Api-User-Agent' => 'MediaWiki/' . MW_VERSION,
220 ],
221 ];
222
223 $response = $vrsClient->run( $request );
224 if ( $response['code'] === 200 ) {
225 $json = json_decode( $response['body'], true );
226 // $json is an array of error objects
227 if ( $json ) {
228 return $json;
229 }
230 }
231 }
232
233 return [];
234 }
235
240 protected function checkUserLinks( string $signature ) : bool {
241 // This may be called by the Parser when it's displaying a signature, so we need a new instance
242 $parser = MediaWikiServices::getInstance()->getParser()->getFreshParser();
243
244 // Check for required links. This one's easier to do with the PHP Parser.
245 $pout = $parser->parse(
246 $signature,
247 SpecialPage::getTitleFor( 'Preferences' ),
248 $this->popts
249 );
250
251 // Checking user or talk links is easy
252 $links = $pout->getLinks();
253 $username = $this->user->getName();
254 if (
255 isset( $links[ NS_USER ][ strtr( $username, ' ', '_' ) ] ) ||
256 isset( $links[ NS_USER_TALK ][ strtr( $username, ' ', '_' ) ] )
257 ) {
258 return true;
259 }
260
261 // Checking the contributions link is harder, because the special page name and the username in
262 // the "subpage parameter" are not normalized for us.
263 $splinks = $pout->getLinksSpecial();
264 $specialPageFactory = MediaWikiServices::getInstance()->getSpecialPageFactory();
265 foreach ( $splinks as $dbkey => $unused ) {
266 list( $name, $subpage ) = $specialPageFactory->resolveAlias( $dbkey );
267 if ( $name === 'Contributions' && $subpage ) {
268 $userTitle = Title::makeTitleSafe( NS_USER, $subpage );
269 if ( $userTitle && $userTitle->getText() === $username ) {
270 return true;
271 }
272 }
273 }
274
275 return false;
276 }
277
278 // Adapted from the Linter extension
279 private function getLintErrorLocation( array $lintError ) : array {
280 return array_slice( $lintError['dsr'], 0, 2 );
281 }
282
283 // Adapted from the Linter extension
284 private function getLintErrorDetails( array $lintError ) : string {
285 [ 'type' => $type, 'params' => $params ] = $lintError;
286
287 if ( $type === 'bogus-image-options' && isset( $params['items'] ) ) {
288 $list = array_map( function ( $in ) {
289 return Html::element( 'code', [], $in );
290 }, $params['items'] );
291 return implode(
292 $this->localizer->msg( 'comma-separator' )->escaped(),
293 $list
294 );
295 } elseif ( $type === 'pwrap-bug-workaround' &&
296 isset( $params['root'] ) &&
297 isset( $params['child'] ) ) {
298 return Html::element( 'code', [],
299 $params['root'] . " > " . $params['child'] );
300 } elseif ( $type === 'tidy-whitespace-bug' &&
301 isset( $params['node'] ) &&
302 isset( $params['sibling'] ) ) {
303 return Html::element( 'code', [],
304 $params['node'] . " + " . $params['sibling'] );
305 } elseif ( $type === 'multi-colon-escape' &&
306 isset( $params['href'] ) ) {
307 return Html::element( 'code', [], $params['href'] );
308 } elseif ( $type === 'multiline-html-table-in-list' ) {
309 /* ancestor and name will be set */
310 return Html::element( 'code', [],
311 $params['ancestorName'] . " > " . $params['name'] );
312 } elseif ( $type === 'misc-tidy-replacement-issues' ) {
313 /* There will be a 'subtype' param to disambiguate */
314 return Html::element( 'code', [], $params['subtype'] );
315 } elseif ( isset( $params['name'] ) ) {
316 return Html::element( 'code', [], $params['name'] );
317 }
318
319 return '';
320 }
321
322}
const MW_VERSION
The running version of MediaWiki.
Definition Defines.php:40
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
return[ 'abap'=> true, 'abl'=> true, 'abnf'=> true, 'aconf'=> true, 'actionscript'=> true, 'actionscript3'=> true, 'ada'=> true, 'ada2005'=> true, 'ada95'=> true, 'adl'=> true, 'agda'=> true, 'aheui'=> true, 'ahk'=> true, 'alloy'=> true, 'ambienttalk'=> true, 'ambienttalk/2'=> true, 'ampl'=> true, 'antlr'=> true, 'antlr-actionscript'=> true, 'antlr-as'=> true, 'antlr-c#'=> true, 'antlr-cpp'=> true, 'antlr-csharp'=> true, 'antlr-java'=> true, 'antlr-objc'=> true, 'antlr-perl'=> true, 'antlr-python'=> true, 'antlr-rb'=> true, 'antlr-ruby'=> true, 'apache'=> true, 'apacheconf'=> true, 'apl'=> true, 'applescript'=> true, 'arduino'=> true, 'arexx'=> true, 'arrow'=> true, 'as'=> true, 'as3'=> true, 'asm'=> true, 'aspectj'=> true, 'aspx-cs'=> true, 'aspx-vb'=> true, 'asy'=> true, 'asymptote'=> true, 'at'=> true, 'augeas'=> true, 'autohotkey'=> true, 'autoit'=> true, 'awk'=> true, 'b3d'=> true, 'bare'=> true, 'basemake'=> true, 'bash'=> true, 'basic'=> true, 'bat'=> true, 'batch'=> true, 'bbcbasic'=> true, 'bbcode'=> true, 'bc'=> true, 'befunge'=> true, 'bf'=> true, 'bib'=> true, 'bibtex'=> true, 'blitzbasic'=> true, 'blitzmax'=> true, 'bmax'=> true, 'bnf'=> true, 'boa'=> true, 'boo'=> true, 'boogie'=> true, 'bplus'=> true, 'brainfuck'=> true, 'bro'=> true, 'bsdmake'=> true, 'bst'=> true, 'bst-pybtex'=> true, 'bugs'=> true, 'c'=> true, 'c#'=> true, 'c++'=> true, 'c++-objdumb'=> true, 'c-objdump'=> true, 'ca65'=> true, 'cadl'=> true, 'camkes'=> true, 'capdl'=> true, 'capnp'=> true, 'cbmbas'=> true, 'ceylon'=> true, 'cf3'=> true, 'cfc'=> true, 'cfengine3'=> true, 'cfg'=> true, 'cfm'=> true, 'cfs'=> true, 'chai'=> true, 'chaiscript'=> true, 'chapel'=> true, 'charmci'=> true, 'cheetah'=> true, 'chpl'=> true, 'cirru'=> true, 'cl'=> true, 'clay'=> true, 'clean'=> true, 'clipper'=> true, 'clj'=> true, 'cljs'=> true, 'clojure'=> true, 'clojurescript'=> true, 'cmake'=> true, 'cobol'=> true, 'cobolfree'=> true, 'coffee'=> true, 'coffee-script'=> true, 'coffeescript'=> true, 'common-lisp'=> true, 'componentpascal'=> true, 'console'=> true, 'control'=> true, 'coq'=> true, 'cp'=> true, 'cpp'=> true, 'cpp-objdump'=> true, 'cpsa'=> true, 'cr'=> true, 'crmsh'=> true, 'croc'=> true, 'cry'=> true, 'cryptol'=> true, 'crystal'=> true, 'csh'=> true, 'csharp'=> true, 'csound'=> true, 'csound-csd'=> true, 'csound-document'=> true, 'csound-orc'=> true, 'csound-sco'=> true, 'csound-score'=> true, 'css'=> true, 'css+django'=> true, 'css+erb'=> true, 'css+genshi'=> true, 'css+genshitext'=> true, 'css+jinja'=> true, 'css+lasso'=> true, 'css+mako'=> true, 'css+mozpreproc'=> true, 'css+myghty'=> true, 'css+php'=> true, 'css+ruby'=> true, 'css+smarty'=> true, 'cu'=> true, 'cucumber'=> true, 'cuda'=> true, 'cxx-objdump'=> true, 'cypher'=> true, 'cython'=> true, 'd'=> true, 'd-objdump'=> true, 'dart'=> true, 'dasm16'=> true, 'debcontrol'=> true, 'debsources'=> true, 'delphi'=> true, 'devicetree'=> true, 'dg'=> true, 'diff'=> true, 'django'=> true, 'dmesg'=> true, 'do'=> true, 'docker'=> true, 'dockerfile'=> true, 'dosbatch'=> true, 'doscon'=> true, 'dosini'=> true, 'dpatch'=> true, 'dtd'=> true, 'dts'=> true, 'duby'=> true, 'duel'=> true, 'dylan'=> true, 'dylan-console'=> true, 'dylan-lid'=> true, 'dylan-repl'=> true, 'earl-grey'=> true, 'earlgrey'=> true, 'easytrieve'=> true, 'ebnf'=> true, 'ec'=> true, 'ecl'=> true, 'eg'=> true, 'eiffel'=> true, 'elisp'=> true, 'elixir'=> true, 'elm'=> true, 'emacs'=> true, 'emacs-lisp'=> true, 'email'=> true, 'eml'=> true, 'erb'=> true, 'erl'=> true, 'erlang'=> true, 'evoque'=> true, 'ex'=> true, 'execline'=> true, 'exs'=> true, 'extempore'=> true, 'ezhil'=> true, 'f#'=> true, 'factor'=> true, 'fan'=> true, 'fancy'=> true, 'felix'=> true, 'fennel'=> true, 'fish'=> true, 'fishshell'=> true, 'flatline'=> true, 'flo'=> true, 'floscript'=> true, 'flx'=> true, 'fnl'=> true, 'forth'=> true, 'fortran'=> true, 'fortranfixed'=> true, 'foxpro'=> true, 'freefem'=> true, 'fsharp'=> true, 'fstar'=> true, 'fy'=> true, 'gap'=> true, 'gas'=> true, 'gawk'=> true, 'gd'=> true, 'gdscript'=> true, 'genshi'=> true, 'genshitext'=> true, 'gherkin'=> true, 'glsl'=> true, 'gnuplot'=> true, 'go'=> true, 'golo'=> true, 'gooddata-cl'=> true, 'gosu'=> true, 'groff'=> true, 'groovy'=> true, 'gst'=> true, 'haml'=> true, 'handlebars'=> true, 'haskell'=> true, 'haxe'=> true, 'haxeml'=> true, 'hexdump'=> true, 'hlsl'=> true, 'hs'=> true, 'hsa'=> true, 'hsail'=> true, 'hspec'=> true, 'html'=> true, 'html+cheetah'=> true, 'html+django'=> true, 'html+erb'=> true, 'html+evoque'=> true, 'html+genshi'=> true, 'html+handlebars'=> true, 'html+jinja'=> true, 'html+kid'=> true, 'html+lasso'=> true, 'html+mako'=> true, 'html+myghty'=> true, 'html+ng2'=> true, 'html+php'=> true, 'html+ruby'=> true, 'html+smarty'=> true, 'html+spitfire'=> true, 'html+twig'=> true, 'html+velocity'=> true, 'htmlcheetah'=> true, 'htmldjango'=> true, 'http'=> true, 'hx'=> true, 'hxml'=> true, 'hxsl'=> true, 'hy'=> true, 'hybris'=> true, 'hylang'=> true, 'i6'=> true, 'i6t'=> true, 'i7'=> true, 'icon'=> true, 'idl'=> true, 'idl4'=> true, 'idr'=> true, 'idris'=> true, 'iex'=> true, 'igor'=> true, 'igorpro'=> true, 'ik'=> true, 'inform6'=> true, 'inform7'=> true, 'ini'=> true, 'io'=> true, 'ioke'=> true, 'irb'=> true, 'irc'=> true, 'isabelle'=> true, 'j'=> true, 'jade'=> true, 'jags'=> true, 'jasmin'=> true, 'jasminxt'=> true, 'java'=> true, 'javascript'=> true, 'javascript+cheetah'=> true, 'javascript+django'=> true, 'javascript+erb'=> true, 'javascript+genshi'=> true, 'javascript+genshitext'=> true, 'javascript+jinja'=> true, 'javascript+lasso'=> true, 'javascript+mako'=> true, 'javascript+mozpreproc'=> true, 'javascript+myghty'=> true, 'javascript+php'=> true, 'javascript+ruby'=> true, 'javascript+smarty'=> true, 'javascript+spitfire'=> true, 'jbst'=> true, 'jcl'=> true, 'jinja'=> true, 'jl'=> true, 'jlcon'=> true, 'jproperties'=> true, 'js'=> true, 'js+cheetah'=> true, 'js+django'=> true, 'js+erb'=> true, 'js+genshi'=> true, 'js+genshitext'=> true, 'js+jinja'=> true, 'js+lasso'=> true, 'js+mako'=> true, 'js+myghty'=> true, 'js+php'=> true, 'js+ruby'=> true, 'js+smarty'=> true, 'js+spitfire'=> true, 'jsgf'=> true, 'json'=> true, 'json-ld'=> true, 'json-object'=> true, 'jsonld'=> true, 'jsonml+bst'=> true, 'jsp'=> true, 'julia'=> true, 'juttle'=> true, 'kal'=> true, 'kconfig'=> true, 'kernel-config'=> true, 'kid'=> true, 'kmsg'=> true, 'koka'=> true, 'kotlin'=> true, 'ksh'=> true, 'lagda'=> true, 'lasso'=> true, 'lassoscript'=> true, 'latex'=> true, 'lcry'=> true, 'lcryptol'=> true, 'lean'=> true, 'less'=> true, 'lhaskell'=> true, 'lhs'=> true, 'lid'=> true, 'lidr'=> true, 'lidris'=> true, 'lighttpd'=> true, 'lighty'=> true, 'limbo'=> true, 'linux-config'=> true, 'liquid'=> true, 'lisp'=> true, 'literate-agda'=> true, 'literate-cryptol'=> true, 'literate-haskell'=> true, 'literate-idris'=> true, 'live-script'=> true, 'livescript'=> true, 'llvm'=> true, 'llvm-mir'=> true, 'llvm-mir-body'=> true, 'logos'=> true, 'logtalk'=> true, 'lsl'=> true, 'lua'=> true, 'm2'=> true, 'make'=> true, 'makefile'=> true, 'mako'=> true, 'man'=> true, 'maql'=> true, 'mask'=> true, 'mason'=> true, 'mathematica'=> true, 'matlab'=> true, 'matlabsession'=> true, 'mawk'=> true, 'md'=> true, 'menuconfig'=> true, 'mf'=> true, 'mime'=> true, 'minid'=> true, 'miniscript'=> true, 'mma'=> true, 'modelica'=> true, 'modula2'=> true, 'moin'=> true, 'monkey'=> true, 'monte'=> true, 'moo'=> true, 'moocode'=> true, 'moon'=> true, 'moonscript'=> true, 'mosel'=> true, 'mozhashpreproc'=> true, 'mozpercentpreproc'=> true, 'mq4'=> true, 'mq5'=> true, 'mql'=> true, 'mql4'=> true, 'mql5'=> true, 'ms'=> true, 'msc'=> true, 'mscgen'=> true, 'mupad'=> true, 'mxml'=> true, 'myghty'=> true, 'mysql'=> true, 'nasm'=> true, 'nawk'=> true, 'nb'=> true, 'ncl'=> true, 'nemerle'=> true, 'nesc'=> true, 'newlisp'=> true, 'newspeak'=> true, 'ng2'=> true, 'nginx'=> true, 'nim'=> true, 'nimrod'=> true, 'nit'=> true, 'nix'=> true, 'nixos'=> true, 'notmuch'=> true, 'nroff'=> true, 'nsh'=> true, 'nsi'=> true, 'nsis'=> true, 'numpy'=> true, 'nusmv'=> true, 'obj-c'=> true, 'obj-c++'=> true, 'obj-j'=> true, 'objc'=> true, 'objc++'=> true, 'objdump'=> true, 'objdump-nasm'=> true, 'objective-c'=> true, 'objective-c++'=> true, 'objective-j'=> true, 'objectivec'=> true, 'objectivec++'=> true, 'objectivej'=> true, 'objectpascal'=> true, 'objj'=> true, 'ocaml'=> true, 'octave'=> true, 'odin'=> true, 'ooc'=> true, 'opa'=> true, 'openbugs'=> true, 'openedge'=> true, 'pacmanconf'=> true, 'pan'=> true, 'parasail'=> true, 'pas'=> true, 'pascal'=> true, 'pawn'=> true, 'pcmk'=> true, 'peg'=> true, 'perl'=> true, 'perl6'=> true, 'php'=> true, 'php3'=> true, 'php4'=> true, 'php5'=> true, 'pig'=> true, 'pike'=> true, 'pkgconfig'=> true, 'pl'=> true, 'pl6'=> true, 'plpgsql'=> true, 'po'=> true, 'pointless'=> true, 'pony'=> true, 'posh'=> true, 'postgres'=> true, 'postgres-console'=> true, 'postgresql'=> true, 'postgresql-console'=> true, 'postscr'=> true, 'postscript'=> true, 'pot'=> true, 'pov'=> true, 'powershell'=> true, 'praat'=> true, 'progress'=> true, 'prolog'=> true, 'promql'=> true, 'properties'=> true, 'proto'=> true, 'protobuf'=> true, 'ps1'=> true, 'ps1con'=> true, 'psm1'=> true, 'psql'=> true, 'psysh'=> true, 'pug'=> true, 'puppet'=> true, 'py'=> true, 'py2'=> true, 'py2tb'=> true, 'py3'=> true, 'py3tb'=> true, 'pycon'=> true, 'pypy'=> true, 'pypylog'=> true, 'pyrex'=> true, 'pytb'=> true, 'python'=> true, 'python2'=> true, 'python3'=> true, 'pyx'=> true, 'qbasic'=> true, 'qbs'=> true, 'qml'=> true, 'qvt'=> true, 'qvto'=> true, 'r'=> true, 'racket'=> true, 'ragel'=> true, 'ragel-c'=> true, 'ragel-cpp'=> true, 'ragel-d'=> true, 'ragel-em'=> true, 'ragel-java'=> true, 'ragel-objc'=> true, 'ragel-rb'=> true, 'ragel-ruby'=> true, 'raku'=> true, 'raw'=> true, 'rb'=> true, 'rbcon'=> true, 'rconsole'=> true, 'rd'=> true, 'reason'=> true, 'reasonml'=> true, 'rebol'=> true, 'red'=> true, 'red/system'=> true, 'redcode'=> true, 'registry'=> true, 'resource'=> true, 'resourcebundle'=> true, 'rest'=> true, 'restructuredtext'=> true, 'rexx'=> true, 'rhtml'=> true, 'ride'=> true, 'rkt'=> true, 'rnc'=> true, 'rng-compact'=> true, 'roboconf-graph'=> true, 'roboconf-instances'=> true, 'robotframework'=> true, 'rout'=> true, 'rql'=> true, 'rs'=> true, 'rsl'=> true, 'rst'=> true, 'rts'=> true, 'ruby'=> true, 'rust'=> true, 's'=> true, 'sage'=> true, 'salt'=> true, 'sarl'=> true, 'sas'=> true, 'sass'=> true, 'sbatch'=> true, 'sc'=> true, 'scala'=> true, 'scaml'=> true, 'scd'=> true, 'scdoc'=> true, 'scheme'=> true, 'scilab'=> true, 'scm'=> true, 'scss'=> true, 'sgf'=> true, 'sh'=> true, 'shell'=> true, 'shell-session'=> true, 'shen'=> true, 'shex'=> true, 'shexc'=> true, 'sieve'=> true, 'silver'=> true, 'singularity'=> true, 'slash'=> true, 'slim'=> true, 'sls'=> true, 'slurm'=> true, 'smali'=> true, 'smalltalk'=> true, 'smarty'=> true, 'sml'=> true, 'snobol'=> true, 'snowball'=> true, 'solidity'=> true, 'sources.list'=> true, 'sourceslist'=> true, 'sp'=> true, 'sparql'=> true, 'spec'=> true, 'spitfire'=> true, 'splus'=> true, 'sql'=> true, 'sqlite3'=> true, 'squeak'=> true, 'squid'=> true, 'squid.conf'=> true, 'squidconf'=> true, 'ssp'=> true, 'st'=> true, 'stan'=> true, 'stata'=> true, 'supercollider'=> true, 'sv'=> true, 'swift'=> true, 'swig'=> true, 'systemverilog'=> true, 't-sql'=> true, 'tads3'=> true, 'tap'=> true, 'tasm'=> true, 'tcl'=> true, 'tcsh'=> true, 'tcshcon'=> true, 'tea'=> true, 'teraterm'=> true, 'teratermmacro'=> true, 'termcap'=> true, 'terminfo'=> true, 'terraform'=> true, 'tex'=> true, 'text'=> true, 'tf'=> true, 'thrift'=> true, 'tid'=> true, 'tnt'=> true, 'todotxt'=> true, 'toml'=> true, 'trac-wiki'=> true, 'trafficscript'=> true, 'treetop'=> true, 'ts'=> true, 'tsql'=> true, 'ttl'=> true, 'turtle'=> true, 'twig'=> true, 'typescript'=> true, 'typoscript'=> true, 'typoscriptcssdata'=> true, 'typoscripthtmldata'=> true, 'ucode'=> true, 'udiff'=> true, 'unicon'=> true, 'urbiscript'=> true, 'usd'=> true, 'usda'=> true, 'v'=> true, 'vala'=> true, 'vapi'=> true, 'vb.net'=> true, 'vbnet'=> true, 'vbscript'=> true, 'vcl'=> true, 'vclsnippet'=> true, 'vclsnippets'=> true, 'vctreestatus'=> true, 'velocity'=> true, 'verilog'=> true, 'vfp'=> true, 'vgl'=> true, 'vhdl'=> true, 'vim'=> true, 'wdiff'=> true, 'webidl'=> true, 'whiley'=> true, 'winbatch'=> true, 'winbugs'=> true, 'x10'=> true, 'xbase'=> true, 'xml'=> true, 'xml+cheetah'=> true, 'xml+django'=> true, 'xml+erb'=> true, 'xml+evoque'=> true, 'xml+genshi'=> true, 'xml+jinja'=> true, 'xml+kid'=> true, 'xml+lasso'=> true, 'xml+mako'=> true, 'xml+myghty'=> true, 'xml+php'=> true, 'xml+ruby'=> true, 'xml+smarty'=> true, 'xml+spitfire'=> true, 'xml+velocity'=> true, 'xorg.conf'=> true, 'xq'=> true, 'xql'=> true, 'xqm'=> true, 'xquery'=> true, 'xqy'=> true, 'xslt'=> true, 'xten'=> true, 'xtend'=> true, 'xul+mozpreproc'=> true, 'yaml'=> true, 'yaml+jinja'=> true, 'yang'=> true, 'zeek'=> true, 'zephir'=> true, 'zig'=> true, 'zsh'=> true,]
This class is a collection of static functions that serve two purposes:
Definition Html.php:49
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition Html.php:231
MediaWikiServices is the service locator for the application scope of MediaWiki.
static getInstance()
Returns the global default instance of the top level service locator.
__construct(User $user, ?MessageLocalizer $localizer, ParserOptions $popts)
Class to handle multiple HTTP requests.
Set options of the Parser.
Virtual HTTP service client for Parsoid.
Parent class for all special pages.
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.
Definition Title.php:42
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:60
Virtual HTTP service client loosely styled after a Virtual File System.
const NS_USER
Definition Defines.php:72
const NS_USER_TALK
Definition Defines.php:73
Interface for localizing messages in MediaWiki.