MediaWiki REL1_35
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 private const MAX_INCLUDE_SIZE = 50000000;
48
49 public function __construct() {
50 parent::__construct( 'ExpandTemplates' );
51 }
52
57 public 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->setMaxIncludeSize( self::MAX_INCLUDE_SIZE );
78
79 $parser = MediaWikiServices::getInstance()->getParser();
80 if ( $this->generateXML ) {
81 $parser->startExternalParse( $title, $options, Parser::OT_PREPROCESS );
82 $dom = $parser->preprocessToDom( $input );
83
84 if ( method_exists( $dom, 'saveXML' ) ) {
85 // @phan-suppress-next-line PhanUndeclaredMethod
86 $xml = $dom->saveXML();
87 } else {
88 // @phan-suppress-next-line PhanUndeclaredMethod
89 $xml = $dom->__toString();
90 }
91 }
92
93 $output = $parser->preprocess( $input, $title, $options );
94 } else {
95 $this->removeComments = $request->getBool( 'wpRemoveComments', true );
96 $this->removeNowiki = $request->getBool( 'wpRemoveNowiki', false );
97 $output = false;
98 }
99
100 $out = $this->getOutput();
101
102 $this->makeForm( $titleStr, $input );
103
104 if ( $output !== false ) {
105 if ( $this->generateXML && strlen( $output ) > 0 ) {
106 $out->addHTML( $this->makeOutput( $xml, 'expand_templates_xml_output' ) );
107 }
108
109 $tmp = $this->makeOutput( $output );
110
111 if ( $this->removeNowiki ) {
112 $tmp = preg_replace(
113 [ '_&lt;nowiki&gt;_', '_&lt;/nowiki&gt;_', '_&lt;nowiki */&gt;_' ],
114 '',
115 $tmp
116 );
117 }
118
119 $config = $this->getConfig();
120
121 $tmp = MWTidy::tidy( $tmp );
122
123 $out->addHTML( $tmp );
124
125 $pout = $this->generateHtml( $title, $output );
126 $rawhtml = $pout->getText();
127 if ( $this->generateRawHtml && strlen( $rawhtml ) > 0 ) {
128 $out->addHTML( $this->makeOutput( $rawhtml, 'expand_templates_html_output' ) );
129 }
130
131 $this->showHtmlPreview( $title, $pout, $out );
132 }
133 }
134
143 public function onSubmitInput( array $values ) {
144 $status = Status::newGood();
145 if ( !strlen( $values['input'] ) ) {
146 $status = Status::newFatal( 'expand_templates_input_missing' );
147 }
148 return $status;
149 }
150
157 private function makeForm( $title, $input ) {
158 $fields = [
159 'contexttitle' => [
160 'type' => 'text',
161 'label' => $this->msg( 'expand_templates_title' )->plain(),
162 'name' => 'wpContextTitle',
163 'id' => 'contexttitle',
164 'size' => 60,
165 'default' => $title,
166 'autofocus' => true,
167 ],
168 'input' => [
169 'type' => 'textarea',
170 'name' => 'wpInput',
171 'label' => $this->msg( 'expand_templates_input' )->text(),
172 'rows' => 10,
173 'default' => $input,
174 'id' => 'input',
175 'useeditfont' => true,
176 ],
177 'removecomments' => [
178 'type' => 'check',
179 'label' => $this->msg( 'expand_templates_remove_comments' )->text(),
180 'name' => 'wpRemoveComments',
181 'id' => 'removecomments',
182 'default' => $this->removeComments,
183 ],
184 'removenowiki' => [
185 'type' => 'check',
186 'label' => $this->msg( 'expand_templates_remove_nowiki' )->text(),
187 'name' => 'wpRemoveNowiki',
188 'id' => 'removenowiki',
189 'default' => $this->removeNowiki,
190 ],
191 'generate_xml' => [
192 'type' => 'check',
193 'label' => $this->msg( 'expand_templates_generate_xml' )->text(),
194 'name' => 'wpGenerateXml',
195 'id' => 'generate_xml',
196 'default' => $this->generateXML,
197 ],
198 'generate_rawhtml' => [
199 'type' => 'check',
200 'label' => $this->msg( 'expand_templates_generate_rawhtml' )->text(),
201 'name' => 'wpGenerateRawHtml',
202 'id' => 'generate_rawhtml',
203 'default' => $this->generateRawHtml,
204 ],
205 ];
206
207 $form = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
208 $form
209 ->setSubmitTextMsg( 'expand_templates_ok' )
210 ->setWrapperLegendMsg( 'expandtemplates' )
211 ->setHeaderText( $this->msg( 'expand_templates_intro' )->parse() )
212 ->setSubmitCallback( [ $this, 'onSubmitInput' ] )
213 ->showAlways();
214 }
215
223 private function makeOutput( $output, $heading = 'expand_templates_output' ) {
224 $out = "<h2>" . $this->msg( $heading )->escaped() . "</h2>\n";
225 $out .= Xml::textarea(
226 'output',
227 $output,
228 10,
229 10,
230 [
231 'id' => 'output',
232 'readonly' => 'readonly',
233 'class' => 'mw-editfont-' . $this->getUser()->getOption( 'editfont' )
234 ]
235 );
236
237 return $out;
238 }
239
247 private function generateHtml( Title $title, $text ) {
248 $popts = ParserOptions::newFromContext( $this->getContext() );
249 $popts->setTargetLanguage( $title->getPageLanguage() );
250 return MediaWikiServices::getInstance()->getParser()->parse( $text, $title, $popts );
251 }
252
260 private function showHtmlPreview( Title $title, ParserOutput $pout, OutputPage $out ) {
261 $lang = $title->getPageViewLanguage();
262 $out->addHTML( "<h2>" . $this->msg( 'expand_templates_preview' )->escaped() . "</h2>\n" );
263
264 if ( $this->getConfig()->get( 'RawHtml' ) ) {
265 $request = $this->getRequest();
266 $user = $this->getUser();
267
268 // To prevent cross-site scripting attacks, don't show the preview if raw HTML is
269 // allowed and a valid edit token is not provided (T73111). However, MediaWiki
270 // does not currently provide logged-out users with CSRF protection; in that case,
271 // do not show the preview unless anonymous editing is allowed.
272 if ( $user->isAnon() && !MediaWikiServices::getInstance()
273 ->getPermissionManager()
274 ->userHasRight( $user, 'edit' )
275 ) {
276 $error = [ 'expand_templates_preview_fail_html_anon' ];
277 } elseif ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ), '', $request ) ) {
278 $error = [ 'expand_templates_preview_fail_html' ];
279 } else {
280 $error = false;
281 }
282
283 if ( $error ) {
284 $out->wrapWikiMsg( "<div class='previewnote errorbox'>\n$1\n</div>", $error );
285 return;
286 }
287 }
288
289 $out->addHTML( Html::openElement( 'div', [
290 'class' => 'mw-content-' . $lang->getDir(),
291 'dir' => $lang->getDir(),
292 'lang' => $lang->getHtmlCode(),
293 ] ) );
294 $out->addParserOutputContent( $pout );
295 $out->addHTML( Html::closeElement( 'div' ) );
296 $out->setCategoryLinks( $pout->getCategories() );
297 }
298
299 protected function getGroupName() {
300 return 'wiki';
301 }
302}
static tidy( $text)
Interface with Remex tidy.
Definition MWTidy.php:42
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.
wrapWikiMsg( $wrap,... $msgSpecs)
This function takes a number of message/argument specifications, wraps them in some overall structure...
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.
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