MediaWiki REL1_34
SpecialExpandTemplates.php
Go to the documentation of this file.
1<?php
25
33
35 protected $generateXML;
36
39
41 protected $removeComments;
42
44 protected $removeNowiki;
45
47 const MAX_INCLUDE_SIZE = 50000000;
48
49 function __construct() {
50 parent::__construct( 'ExpandTemplates' );
51 }
52
57 function execute( $subpage ) {
58 $this->setHeaders();
59 $this->addHelpLink( 'Help:ExpandTemplates' );
60
61 $request = $this->getRequest();
62 $titleStr = $request->getText( 'wpContextTitle' );
63 $title = Title::newFromText( $titleStr );
64
65 if ( !$title ) {
66 $title = $this->getPageTitle();
67 }
68 $input = $request->getText( 'wpInput' );
69 $this->generateXML = $request->getBool( 'wpGenerateXml' );
70 $this->generateRawHtml = $request->getBool( 'wpGenerateRawHtml' );
71
72 if ( strlen( $input ) ) {
73 $this->removeComments = $request->getBool( 'wpRemoveComments', false );
74 $this->removeNowiki = $request->getBool( 'wpRemoveNowiki', false );
75 $options = ParserOptions::newFromContext( $this->getContext() );
76 $options->setRemoveComments( $this->removeComments );
77 $options->setTidy( true );
78 $options->setMaxIncludeSize( self::MAX_INCLUDE_SIZE );
79
80 $parser = MediaWikiServices::getInstance()->getParser();
81 if ( $this->generateXML ) {
82 $parser->startExternalParse( $title, $options, Parser::OT_PREPROCESS );
83 $dom = $parser->preprocessToDom( $input );
84
85 if ( method_exists( $dom, 'saveXML' ) ) {
86 // @phan-suppress-next-line PhanUndeclaredMethod
87 $xml = $dom->saveXML();
88 } else {
89 // @phan-suppress-next-line PhanUndeclaredMethod
90 $xml = $dom->__toString();
91 }
92 }
93
94 $output = $parser->preprocess( $input, $title, $options );
95 } else {
96 $this->removeComments = $request->getBool( 'wpRemoveComments', true );
97 $this->removeNowiki = $request->getBool( 'wpRemoveNowiki', false );
98 $output = false;
99 }
100
101 $out = $this->getOutput();
102
103 $this->makeForm( $titleStr, $input );
104
105 if ( $output !== false ) {
106 if ( $this->generateXML && strlen( $output ) > 0 ) {
107 $out->addHTML( $this->makeOutput( $xml, 'expand_templates_xml_output' ) );
108 }
109
110 $tmp = $this->makeOutput( $output );
111
112 if ( $this->removeNowiki ) {
113 $tmp = preg_replace(
114 [ '_&lt;nowiki&gt;_', '_&lt;/nowiki&gt;_', '_&lt;nowiki */&gt;_' ],
115 '',
116 $tmp
117 );
118 }
119
120 $config = $this->getConfig();
121 if ( MWTidy::isEnabled() && $options->getTidy() ) {
122 $tmp = MWTidy::tidy( $tmp );
123 } else {
124 wfDeprecated( 'disabling tidy', '1.33' );
125 }
126
127 $out->addHTML( $tmp );
128
129 $pout = $this->generateHtml( $title, $output );
130 $rawhtml = $pout->getText();
131 if ( $this->generateRawHtml && strlen( $rawhtml ) > 0 ) {
132 $out->addHTML( $this->makeOutput( $rawhtml, 'expand_templates_html_output' ) );
133 }
134
135 $this->showHtmlPreview( $title, $pout, $out );
136 }
137 }
138
147 public function onSubmitInput( array $values ) {
148 $status = Status::newGood();
149 if ( !strlen( $values['input'] ) ) {
150 $status = Status::newFatal( 'expand_templates_input_missing' );
151 }
152 return $status;
153 }
154
161 private function makeForm( $title, $input ) {
162 $fields = [
163 'contexttitle' => [
164 'type' => 'text',
165 'label' => $this->msg( 'expand_templates_title' )->plain(),
166 'name' => 'wpContextTitle',
167 'id' => 'contexttitle',
168 'size' => 60,
169 'default' => $title,
170 'autofocus' => true,
171 ],
172 'input' => [
173 'type' => 'textarea',
174 'name' => 'wpInput',
175 'label' => $this->msg( 'expand_templates_input' )->text(),
176 'rows' => 10,
177 'default' => $input,
178 'id' => 'input',
179 'useeditfont' => true,
180 ],
181 'removecomments' => [
182 'type' => 'check',
183 'label' => $this->msg( 'expand_templates_remove_comments' )->text(),
184 'name' => 'wpRemoveComments',
185 'id' => 'removecomments',
186 'default' => $this->removeComments,
187 ],
188 'removenowiki' => [
189 'type' => 'check',
190 'label' => $this->msg( 'expand_templates_remove_nowiki' )->text(),
191 'name' => 'wpRemoveNowiki',
192 'id' => 'removenowiki',
193 'default' => $this->removeNowiki,
194 ],
195 'generate_xml' => [
196 'type' => 'check',
197 'label' => $this->msg( 'expand_templates_generate_xml' )->text(),
198 'name' => 'wpGenerateXml',
199 'id' => 'generate_xml',
200 'default' => $this->generateXML,
201 ],
202 'generate_rawhtml' => [
203 'type' => 'check',
204 'label' => $this->msg( 'expand_templates_generate_rawhtml' )->text(),
205 'name' => 'wpGenerateRawHtml',
206 'id' => 'generate_rawhtml',
207 'default' => $this->generateRawHtml,
208 ],
209 ];
210
211 $form = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
212 $form
213 ->setSubmitTextMsg( 'expand_templates_ok' )
214 ->setWrapperLegendMsg( 'expandtemplates' )
215 ->setHeaderText( $this->msg( 'expand_templates_intro' )->parse() )
216 ->setSubmitCallback( [ $this, 'onSubmitInput' ] )
217 ->showAlways();
218 }
219
227 private function makeOutput( $output, $heading = 'expand_templates_output' ) {
228 $out = "<h2>" . $this->msg( $heading )->escaped() . "</h2>\n";
229 $out .= Xml::textarea(
230 'output',
231 $output,
232 10,
233 10,
234 [
235 'id' => 'output',
236 'readonly' => 'readonly',
237 'class' => 'mw-editfont-' . $this->getUser()->getOption( 'editfont' )
238 ]
239 );
240
241 return $out;
242 }
243
251 private function generateHtml( Title $title, $text ) {
252 $popts = ParserOptions::newFromContext( $this->getContext() );
253 $popts->setTargetLanguage( $title->getPageLanguage() );
254 return MediaWikiServices::getInstance()->getParser()->parse( $text, $title, $popts );
255 }
256
264 private function showHtmlPreview( Title $title, ParserOutput $pout, OutputPage $out ) {
265 $lang = $title->getPageViewLanguage();
266 $out->addHTML( "<h2>" . $this->msg( 'expand_templates_preview' )->escaped() . "</h2>\n" );
267
268 if ( $this->getConfig()->get( 'RawHtml' ) ) {
269 $request = $this->getRequest();
270 $user = $this->getUser();
271
272 // To prevent cross-site scripting attacks, don't show the preview if raw HTML is
273 // allowed and a valid edit token is not provided (T73111). However, MediaWiki
274 // does not currently provide logged-out users with CSRF protection; in that case,
275 // do not show the preview unless anonymous editing is allowed.
276 if ( $user->isAnon() && !MediaWikiServices::getInstance()
277 ->getPermissionManager()
278 ->userHasRight( $user, 'edit' )
279 ) {
280 $error = [ 'expand_templates_preview_fail_html_anon' ];
281 } elseif ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ), '', $request ) ) {
282 $error = [ 'expand_templates_preview_fail_html' ];
283 } else {
284 $error = false;
285 }
286
287 if ( $error ) {
288 $out->wrapWikiMsg( "<div class='previewnote errorbox'>\n$1\n</div>", $error );
289 return;
290 }
291 }
292
293 $out->addHTML( Html::openElement( 'div', [
294 'class' => 'mw-content-' . $lang->getDir(),
295 'dir' => $lang->getDir(),
296 'lang' => $lang->getHtmlCode(),
297 ] ) );
298 $out->addParserOutputContent( $pout );
299 $out->addHTML( Html::closeElement( 'div' ) );
300 $out->setCategoryLinks( $pout->getCategories() );
301 }
302
303 protected function getGroupName() {
304 return 'wiki';
305 }
306}
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
static tidy( $text)
Interface with Remex tidy.
Definition MWTidy.php:42
static isEnabled()
Definition MWTidy.php:54
MediaWikiServices is the service locator for the application scope of MediaWiki.
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.
wrapWikiMsg( $wrap)
This function takes a number of message/argument specifications, wraps them in some overall structure...
A special page that expands submitted templates, parser functions, and variables, allowing easier deb...
bool $generateRawHtml
Whether or not to show the raw HTML code.
bool $removeComments
Whether or not to remove comments in the expanded wikitext.
onSubmitInput(array $values)
Callback for the HTMLForm used in self::makeForm.
bool $generateXML
Whether or not to show the XML parse tree.
makeForm( $title, $input)
Generate a form allowing users to enter information.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
showHtmlPreview(Title $title, ParserOutput $pout, OutputPage $out)
Wraps the provided html code in a div and outputs it to the page.
generateHtml(Title $title, $text)
Renders the supplied wikitext as html.
makeOutput( $output, $heading='expand_templates_output')
Generate a nice little box with a heading for output.
execute( $subpage)
Show the special page.
bool $removeNowiki
Whether or not to remove <nowiki> tags in the expanded wikitext.
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.
Represents a title within MediaWiki.
Definition Title.php:42
if(!isset( $args[0])) $lang