MediaWiki  master
SpecialExpandTemplates.php
Go to the documentation of this file.
1 <?php
26 
34 
36  protected $generateXML;
37 
39  protected $generateRawHtml;
40 
42  protected $removeComments;
43 
45  protected $removeNowiki;
46 
48  private const MAX_INCLUDE_SIZE = 50000000;
49 
51  private $parser;
52 
55 
57  private $tidy;
58 
64  public function __construct(
68  ) {
69  parent::__construct( 'ExpandTemplates' );
70  $this->parser = $parser;
71  $this->userOptionsLookup = $userOptionsLookup;
72  $this->tidy = $tidy;
73  }
74 
79  public function execute( $subpage ) {
80  $this->setHeaders();
81  $this->addHelpLink( 'Help:ExpandTemplates' );
82 
83  $request = $this->getRequest();
84  $titleStr = $request->getText( 'wpContextTitle' );
85  $title = Title::newFromText( $titleStr );
86 
87  if ( !$title ) {
88  $title = $this->getPageTitle();
89  }
90  $input = $request->getText( 'wpInput' );
91  $this->generateXML = $request->getBool( 'wpGenerateXml' );
92  $this->generateRawHtml = $request->getBool( 'wpGenerateRawHtml' );
93 
94  if ( strlen( $input ) ) {
95  $this->removeComments = $request->getBool( 'wpRemoveComments', false );
96  $this->removeNowiki = $request->getBool( 'wpRemoveNowiki', false );
97  $options = ParserOptions::newFromContext( $this->getContext() );
98  $options->setRemoveComments( $this->removeComments );
99  $options->setMaxIncludeSize( self::MAX_INCLUDE_SIZE );
100 
101  if ( $this->generateXML ) {
102  $this->parser->startExternalParse( $title, $options, Parser::OT_PREPROCESS );
103  $dom = $this->parser->preprocessToDom( $input );
104 
105  if ( method_exists( $dom, 'saveXML' ) ) {
106  // @phan-suppress-next-line PhanUndeclaredMethod
107  $xml = $dom->saveXML();
108  } else {
109  // @phan-suppress-next-line PhanUndeclaredMethod
110  $xml = $dom->__toString();
111  }
112  }
113 
114  $output = $this->parser->preprocess( $input, $title, $options );
115  } else {
116  $this->removeComments = $request->getBool( 'wpRemoveComments', true );
117  $this->removeNowiki = $request->getBool( 'wpRemoveNowiki', false );
118  $output = false;
119  }
120 
121  $out = $this->getOutput();
122 
123  $this->makeForm( $titleStr, $input );
124 
125  if ( $output !== false ) {
126  if ( $this->generateXML && strlen( $output ) > 0 ) {
127  $out->addHTML( $this->makeOutput( $xml, 'expand_templates_xml_output' ) );
128  }
129 
130  $tmp = $this->makeOutput( $output );
131 
132  if ( $this->removeNowiki ) {
133  $tmp = preg_replace(
134  [ '_&lt;nowiki&gt;_', '_&lt;/nowiki&gt;_', '_&lt;nowiki */&gt;_' ],
135  '',
136  $tmp
137  );
138  }
139 
140  $config = $this->getConfig();
141 
142  $tmp = $this->tidy->tidy( $tmp );
143 
144  $out->addHTML( $tmp );
145 
146  $pout = $this->generateHtml( $title, $output );
147  $rawhtml = $pout->getText();
148  if ( $this->generateRawHtml && strlen( $rawhtml ) > 0 ) {
149  // @phan-suppress-next-line SecurityCheck-DoubleEscaped Wanted here to display the html
150  $out->addHTML( $this->makeOutput( $rawhtml, 'expand_templates_html_output' ) );
151  }
152 
153  $this->showHtmlPreview( $title, $pout, $out );
154  }
155  }
156 
165  public function onSubmitInput( array $values ) {
166  $status = Status::newGood();
167  if ( !strlen( $values['input'] ) ) {
168  $status = Status::newFatal( 'expand_templates_input_missing' );
169  }
170  return $status;
171  }
172 
179  private function makeForm( $title, $input ) {
180  $fields = [
181  'contexttitle' => [
182  'type' => 'text',
183  'label' => $this->msg( 'expand_templates_title' )->plain(),
184  'name' => 'wpContextTitle',
185  'id' => 'contexttitle',
186  'size' => 60,
187  'default' => $title,
188  'autofocus' => true,
189  ],
190  'input' => [
191  'type' => 'textarea',
192  'name' => 'wpInput',
193  'label' => $this->msg( 'expand_templates_input' )->text(),
194  'rows' => 10,
195  'default' => $input,
196  'id' => 'input',
197  'useeditfont' => true,
198  ],
199  'removecomments' => [
200  'type' => 'check',
201  'label' => $this->msg( 'expand_templates_remove_comments' )->text(),
202  'name' => 'wpRemoveComments',
203  'id' => 'removecomments',
204  'default' => $this->removeComments,
205  ],
206  'removenowiki' => [
207  'type' => 'check',
208  'label' => $this->msg( 'expand_templates_remove_nowiki' )->text(),
209  'name' => 'wpRemoveNowiki',
210  'id' => 'removenowiki',
211  'default' => $this->removeNowiki,
212  ],
213  'generate_xml' => [
214  'type' => 'check',
215  'label' => $this->msg( 'expand_templates_generate_xml' )->text(),
216  'name' => 'wpGenerateXml',
217  'id' => 'generate_xml',
218  'default' => $this->generateXML,
219  ],
220  'generate_rawhtml' => [
221  'type' => 'check',
222  'label' => $this->msg( 'expand_templates_generate_rawhtml' )->text(),
223  'name' => 'wpGenerateRawHtml',
224  'id' => 'generate_rawhtml',
225  'default' => $this->generateRawHtml,
226  ],
227  ];
228 
229  $form = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
230  $form
231  ->setSubmitTextMsg( 'expand_templates_ok' )
232  ->setWrapperLegendMsg( 'expandtemplates' )
233  ->setHeaderText( $this->msg( 'expand_templates_intro' )->parse() )
234  ->setSubmitCallback( [ $this, 'onSubmitInput' ] )
235  ->showAlways();
236  }
237 
245  private function makeOutput( $output, $heading = 'expand_templates_output' ) {
246  $out = "<h2>" . $this->msg( $heading )->escaped() . "</h2>\n";
247  $out .= Xml::textarea(
248  'output',
249  $output,
250  10,
251  10,
252  [
253  'id' => 'output',
254  'readonly' => 'readonly',
255  'class' => 'mw-editfont-' . $this->userOptionsLookup->getOption( $this->getUser(), 'editfont' )
256  ]
257  );
258 
259  return $out;
260  }
261 
269  private function generateHtml( Title $title, $text ) {
270  $popts = ParserOptions::newFromContext( $this->getContext() );
271  $popts->setTargetLanguage( $title->getPageLanguage() );
272  return $this->parser->parse( $text, $title, $popts );
273  }
274 
282  private function showHtmlPreview( Title $title, ParserOutput $pout, OutputPage $out ) {
283  $lang = $title->getPageViewLanguage();
284  $out->addHTML( "<h2>" . $this->msg( 'expand_templates_preview' )->escaped() . "</h2>\n" );
285 
286  if ( $this->getConfig()->get( 'RawHtml' ) ) {
287  $request = $this->getRequest();
288  $user = $this->getUser();
289 
290  // To prevent cross-site scripting attacks, don't show the preview if raw HTML is
291  // allowed and a valid edit token is not provided (T73111). However, MediaWiki
292  // does not currently provide logged-out users with CSRF protection; in that case,
293  // do not show the preview unless anonymous editing is allowed.
294  if ( $user->isAnon() && !$this->getAuthority()->isAllowed( 'edit' ) ) {
295  $error = [ 'expand_templates_preview_fail_html_anon' ];
296  } elseif ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ), '', $request ) ) {
297  $error = [ 'expand_templates_preview_fail_html' ];
298  } else {
299  $error = false;
300  }
301 
302  if ( $error ) {
303  $out->wrapWikiMsg( "<div class='previewnote errorbox'>\n$1\n</div>", $error );
304  return;
305  }
306  }
307 
308  $out->addHTML( Html::openElement( 'div', [
309  'class' => 'mw-content-' . $lang->getDir(),
310  'dir' => $lang->getDir(),
311  'lang' => $lang->getHtmlCode(),
312  ] ) );
313  $out->addParserOutputContent( $pout );
314  $out->addHTML( Html::closeElement( 'div' ) );
315  $out->setCategoryLinks( $pout->getCategories() );
316  }
317 
318  protected function getGroupName() {
319  return 'wiki';
320  }
321 }
SpecialPage\getPageTitle
getPageTitle( $subpage=false)
Get a self-referential title object.
Definition: SpecialPage.php:743
SpecialPage\msg
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
Definition: SpecialPage.php:911
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:363
ParserOutput
Definition: ParserOutput.php:31
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:789
SpecialExpandTemplates\$generateRawHtml
bool $generateRawHtml
Whether or not to show the raw HTML code.
Definition: SpecialExpandTemplates.php:39
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
SpecialExpandTemplates\showHtmlPreview
showHtmlPreview(Title $title, ParserOutput $pout, OutputPage $out)
Wraps the provided html code in a div and outputs it to the page.
Definition: SpecialExpandTemplates.php:282
Xml\textarea
static textarea( $name, $content, $cols=40, $rows=5, $attribs=[])
Shortcut for creating textareas.
Definition: Xml.php:648
SpecialExpandTemplates\execute
execute( $subpage)
Show the special page.
Definition: SpecialExpandTemplates.php:79
SpecialExpandTemplates\$parser
Parser $parser
Definition: SpecialExpandTemplates.php:47
OutputPage\addHTML
addHTML( $text)
Append $text to the body HTML.
Definition: OutputPage.php:1617
SpecialExpandTemplates\makeOutput
makeOutput( $output, $heading='expand_templates_output')
Generate a nice little box with a heading for output.
Definition: SpecialExpandTemplates.php:245
Html\closeElement
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:318
OutputPage\addParserOutputContent
addParserOutputContent(ParserOutput $parserOutput, $poOptions=[])
Add the HTML and enhancements for it (like ResourceLoader modules) associated with a ParserOutput obj...
Definition: OutputPage.php:1989
SpecialPage\addHelpLink
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Definition: SpecialPage.php:947
SpecialPage\getConfig
getConfig()
Shortcut to get main config object.
Definition: SpecialPage.php:877
SpecialExpandTemplates\$userOptionsLookup
UserOptionsLookup $userOptionsLookup
Definition: SpecialExpandTemplates.php:54
SpecialExpandTemplates\__construct
__construct(Parser $parser, UserOptionsLookup $userOptionsLookup, TidyDriverBase $tidy)
Definition: SpecialExpandTemplates.php:64
$title
$title
Definition: testCompression.php:38
SpecialPage\setHeaders
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
Definition: SpecialPage.php:617
SpecialPage\getUser
getUser()
Shortcut to get the User executing this instance.
Definition: SpecialPage.php:799
SpecialExpandTemplates\getGroupName
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Definition: SpecialExpandTemplates.php:318
OutputPage
This is one of the Core classes and should be read at least once by any new developers.
Definition: OutputPage.php:50
SpecialPage\getContext
getContext()
Gets the context this SpecialPage is executed in.
Definition: SpecialPage.php:763
MediaWiki\Tidy\TidyDriverBase
Base class for HTML cleanup utilities.
Definition: TidyDriverBase.php:8
SpecialExpandTemplates
A special page that expands submitted templates, parser functions, and variables, allowing easier deb...
Definition: SpecialExpandTemplates.php:33
OutputPage\wrapWikiMsg
wrapWikiMsg( $wrap,... $msgSpecs)
This function takes a number of message/argument specifications, wraps them in some overall structure...
Definition: OutputPage.php:4116
ParserOptions\newFromContext
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
Definition: ParserOptions.php:1156
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
SpecialPage
Parent class for all special pages.
Definition: SpecialPage.php:43
SpecialExpandTemplates\$removeNowiki
bool $removeNowiki
Whether or not to remove <nowiki> tags in the expanded wikitext.
Definition: SpecialExpandTemplates.php:45
SpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: SpecialPage.php:779
SpecialExpandTemplates\makeForm
makeForm( $title, $input)
Generate a form allowing users to enter information.
Definition: SpecialExpandTemplates.php:179
Parser
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition: Parser.php:87
MediaWiki\User\UserOptionsLookup
Provides access to user options.
Definition: UserOptionsLookup.php:29
Parser\OT_PREPROCESS
const OT_PREPROCESS
Definition: Parser.php:121
OutputPage\setCategoryLinks
setCategoryLinks(array $categories)
Reset the category links (but not the category list) and add $categories.
Definition: OutputPage.php:1450
SpecialExpandTemplates\generateHtml
generateHtml(Title $title, $text)
Renders the supplied wikitext as html.
Definition: SpecialExpandTemplates.php:269
Title
Represents a title within MediaWiki.
Definition: Title.php:46
SpecialExpandTemplates\$generateXML
bool $generateXML
Whether or not to show the XML parse tree.
Definition: SpecialExpandTemplates.php:36
SpecialExpandTemplates\onSubmitInput
onSubmitInput(array $values)
Callback for the HTMLForm used in self::makeForm.
Definition: SpecialExpandTemplates.php:165
ParserOutput\getCategories
& getCategories()
Definition: ParserOutput.php:582
Html\openElement
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:254
SpecialExpandTemplates\$removeComments
bool $removeComments
Whether or not to remove comments in the expanded wikitext.
Definition: SpecialExpandTemplates.php:42
HTMLForm\factory
static factory( $displayFormat,... $arguments)
Construct a HTMLForm object for given display type.
Definition: HTMLForm.php:322
SpecialExpandTemplates\$tidy
TidyDriverBase $tidy
Definition: SpecialExpandTemplates.php:57