MediaWiki REL1_39
SpecialExpandTemplates.php
Go to the documentation of this file.
1<?php
27
35
37 private const MAX_INCLUDE_SIZE = 50000000;
38
40 private $parser;
41
43 private $userOptionsLookup;
44
46 private $tidy;
47
53 public function __construct(
54 Parser $parser,
55 UserOptionsLookup $userOptionsLookup,
56 TidyDriverBase $tidy
57 ) {
58 parent::__construct( 'ExpandTemplates' );
59 $this->parser = $parser;
60 $this->userOptionsLookup = $userOptionsLookup;
61 $this->tidy = $tidy;
62 }
63
68 public function execute( $subpage ) {
69 $this->setHeaders();
70 $this->addHelpLink( 'Help:ExpandTemplates' );
71
72 $request = $this->getRequest();
73 $input = $request->getText( 'wpInput' );
74
75 if ( strlen( $input ) ) {
76 $removeComments = $request->getBool( 'wpRemoveComments', false );
77 $removeNowiki = $request->getBool( 'wpRemoveNowiki', false );
78 $generateXML = $request->getBool( 'wpGenerateXml' );
79 $generateRawHtml = $request->getBool( 'wpGenerateRawHtml' );
80
81 $options = ParserOptions::newFromContext( $this->getContext() );
82 $options->setRemoveComments( $removeComments );
83 $options->setMaxIncludeSize( self::MAX_INCLUDE_SIZE );
84
85 $titleStr = $request->getText( 'wpContextTitle' );
86 $title = Title::newFromText( $titleStr );
87 if ( !$title ) {
88 $title = $this->getPageTitle();
89 $options->setTargetLanguage( $this->getContentLanguage() );
90 }
91
92 if ( $generateXML ) {
93 $this->parser->startExternalParse( $title, $options, Parser::OT_PREPROCESS );
94 $dom = $this->parser->preprocessToDom( $input );
95
96 if ( method_exists( $dom, 'saveXML' ) ) {
97 // @phan-suppress-next-line PhanUndeclaredMethod
98 $xml = $dom->saveXML();
99 } else {
100 // @phan-suppress-next-line PhanUndeclaredMethod
101 $xml = $dom->__toString();
102 }
103 }
104
105 $output = $this->parser->preprocess( $input, $title, $options );
106 $this->makeForm();
107
108 $out = $this->getOutput();
109 if ( $generateXML && strlen( $output ) > 0 ) {
110 // @phan-suppress-next-line PhanPossiblyUndeclaredVariable xml is set when used
111 $out->addHTML( $this->makeOutput( $xml, 'expand_templates_xml_output' ) );
112 }
113
114 $tmp = $this->makeOutput( $output );
115
116 if ( $removeNowiki ) {
117 $tmp = preg_replace(
118 [ '_&lt;nowiki&gt;_', '_&lt;/nowiki&gt;_', '_&lt;nowiki */&gt;_' ],
119 '',
120 $tmp
121 );
122 }
123
124 $tmp = $this->tidy->tidy( $tmp );
125
126 $out->addHTML( $tmp );
127
128 $pout = $this->generateHtml( $title, $output );
129 $rawhtml = $pout->getText();
130 if ( $generateRawHtml && strlen( $rawhtml ) > 0 ) {
131 // @phan-suppress-next-line SecurityCheck-DoubleEscaped Wanted here to display the html
132 $out->addHTML( $this->makeOutput( $rawhtml, 'expand_templates_html_output' ) );
133 }
134
135 $this->showHtmlPreview( $title, $pout, $out );
136 } else {
137 $this->makeForm();
138 }
139 }
140
149 public function onSubmitInput( array $values ) {
150 $status = Status::newGood();
151 if ( !strlen( $values['Input'] ) ) {
152 $status = Status::newFatal( 'expand_templates_input_missing' );
153 }
154 return $status;
155 }
156
160 private function makeForm() {
161 $fields = [
162 'ContextTitle' => [
163 'type' => 'text',
164 'label' => $this->msg( 'expand_templates_title' )->plain(),
165 'id' => 'contexttitle',
166 'size' => 60,
167 'autofocus' => true,
168 ],
169 'Input' => [
170 'type' => 'textarea',
171 'label' => $this->msg( 'expand_templates_input' )->text(),
172 'rows' => 10,
173 'id' => 'input',
174 'useeditfont' => true,
175 ],
176 'RemoveComments' => [
177 'type' => 'check',
178 'label' => $this->msg( 'expand_templates_remove_comments' )->text(),
179 'id' => 'removecomments',
180 'default' => true,
181 ],
182 'RemoveNowiki' => [
183 'type' => 'check',
184 'label' => $this->msg( 'expand_templates_remove_nowiki' )->text(),
185 'id' => 'removenowiki',
186 ],
187 'GenerateXml' => [
188 'type' => 'check',
189 'label' => $this->msg( 'expand_templates_generate_xml' )->text(),
190 'id' => 'generate_xml',
191 ],
192 'GenerateRawHtml' => [
193 'type' => 'check',
194 'label' => $this->msg( 'expand_templates_generate_rawhtml' )->text(),
195 'id' => 'generate_rawhtml',
196 ],
197 ];
198
199 $form = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
200 $form
201 ->setSubmitTextMsg( 'expand_templates_ok' )
202 ->setWrapperLegendMsg( 'expandtemplates' )
203 ->setHeaderText( $this->msg( 'expand_templates_intro' )->parse() )
204 ->setSubmitCallback( [ $this, 'onSubmitInput' ] )
205 ->showAlways();
206 }
207
215 private function makeOutput( $output, $heading = 'expand_templates_output' ) {
216 $out = "<h2>" . $this->msg( $heading )->escaped() . "</h2>\n";
217 $out .= Xml::textarea(
218 'output',
219 $output,
220 10,
221 10,
222 [
223 'id' => 'output',
224 'readonly' => 'readonly',
225 'class' => 'mw-editfont-' . $this->userOptionsLookup->getOption( $this->getUser(), 'editfont' )
226 ]
227 );
228
229 return $out;
230 }
231
239 private function generateHtml( Title $title, $text ) {
240 $popts = ParserOptions::newFromContext( $this->getContext() );
241 $popts->setTargetLanguage( $title->getPageLanguage() );
242 return $this->parser->parse( $text, $title, $popts );
243 }
244
252 private function showHtmlPreview( Title $title, ParserOutput $pout, OutputPage $out ) {
253 $lang = $title->getPageViewLanguage();
254 $out->addHTML( "<h2>" . $this->msg( 'expand_templates_preview' )->escaped() . "</h2>\n" );
255
256 if ( $this->getConfig()->get( MainConfigNames::RawHtml ) ) {
257 $request = $this->getRequest();
258 $user = $this->getUser();
259
260 // To prevent cross-site scripting attacks, don't show the preview if raw HTML is
261 // allowed and a valid edit token is not provided (T73111). However, MediaWiki
262 // does not currently provide logged-out users with CSRF protection; in that case,
263 // do not show the preview unless anonymous editing is allowed.
264 if ( $user->isAnon() && !$this->getAuthority()->isAllowed( 'edit' ) ) {
265 $error = [ 'expand_templates_preview_fail_html_anon' ];
266 } elseif ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ), '', $request ) ) {
267 $error = [ 'expand_templates_preview_fail_html' ];
268 } else {
269 $error = false;
270 }
271
272 if ( $error ) {
273 $out->addHTML(
274 Html::errorBox(
275 $out->msg( $error )->parse(),
276 '',
277 'previewnote'
278 )
279 );
280 return;
281 }
282 }
283
284 $out->addHTML( Html::openElement( 'div', [
285 'class' => 'mw-content-' . $lang->getDir(),
286 'dir' => $lang->getDir(),
287 'lang' => $lang->getHtmlCode(),
288 ] ) );
289 $out->addParserOutputContent( $pout );
290 $out->addHTML( Html::closeElement( 'div' ) );
291 $out->setCategoryLinks( $pout->getCategories() );
292 }
293
294 protected function getGroupName() {
295 return 'wiki';
296 }
297}
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
A class containing constants representing the names of configuration variables.
Base class for HTML cleanup utilities.
Provides access to user options.
This is one of the Core classes and should be read at least once by any new developers.
setCategoryLinks(array $categories)
Reset the category links (but not the category list) and add $categories.
addParserOutputContent(ParserOutput $parserOutput, $poOptions=[])
Add the HTML and enhancements for it (like ResourceLoader modules) associated with a ParserOutput obj...
addHTML( $text)
Append $text to the body HTML.
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
getText( $options=[])
Get the output HTML.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:96
const OT_PREPROCESS
Definition Parser.php:132
A special page that expands submitted templates, parser functions, and variables, allowing easier deb...
__construct(Parser $parser, UserOptionsLookup $userOptionsLookup, TidyDriverBase $tidy)
onSubmitInput(array $values)
Callback for the HTMLForm used in self::makeForm.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
execute( $subpage)
Show the special page.
Parent class for all special pages.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getOutput()
Get the OutputPage being used for this instance.
getUser()
Shortcut to get the User executing this instance.
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getConfig()
Shortcut to get main config object.
getRequest()
Get the WebRequest being used for this instance.
getPageTitle( $subpage=false)
Get a self-referential title object.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
getContentLanguage()
Shortcut to get content language.
Represents a title within MediaWiki.
Definition Title.php:49
static textarea( $name, $content, $cols=40, $rows=5, $attribs=[])
Shortcut for creating textareas.
Definition Xml.php:654
if(!isset( $args[0])) $lang