MediaWiki  master
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 
44 
46  private $tidy;
47 
53  public function __construct(
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  $config = $this->getConfig();
125 
126  $tmp = $this->tidy->tidy( $tmp );
127 
128  $out->addHTML( $tmp );
129 
130  $pout = $this->generateHtml( $title, $output );
131  $rawhtml = $pout->getText();
132  if ( $generateRawHtml && strlen( $rawhtml ) > 0 ) {
133  // @phan-suppress-next-line SecurityCheck-DoubleEscaped Wanted here to display the html
134  $out->addHTML( $this->makeOutput( $rawhtml, 'expand_templates_html_output' ) );
135  }
136 
137  $this->showHtmlPreview( $title, $pout, $out );
138  } else {
139  $this->makeForm();
140  }
141  }
142 
151  public function onSubmitInput( array $values ) {
152  $status = Status::newGood();
153  if ( !strlen( $values['Input'] ) ) {
154  $status = Status::newFatal( 'expand_templates_input_missing' );
155  }
156  return $status;
157  }
158 
162  private function makeForm() {
163  $fields = [
164  'ContextTitle' => [
165  'type' => 'text',
166  'label' => $this->msg( 'expand_templates_title' )->plain(),
167  'id' => 'contexttitle',
168  'size' => 60,
169  'autofocus' => true,
170  ],
171  'Input' => [
172  'type' => 'textarea',
173  'label' => $this->msg( 'expand_templates_input' )->text(),
174  'rows' => 10,
175  'id' => 'input',
176  'useeditfont' => true,
177  ],
178  'RemoveComments' => [
179  'type' => 'check',
180  'label' => $this->msg( 'expand_templates_remove_comments' )->text(),
181  'id' => 'removecomments',
182  'default' => true,
183  ],
184  'RemoveNowiki' => [
185  'type' => 'check',
186  'label' => $this->msg( 'expand_templates_remove_nowiki' )->text(),
187  'id' => 'removenowiki',
188  ],
189  'GenerateXml' => [
190  'type' => 'check',
191  'label' => $this->msg( 'expand_templates_generate_xml' )->text(),
192  'id' => 'generate_xml',
193  ],
194  'GenerateRawHtml' => [
195  'type' => 'check',
196  'label' => $this->msg( 'expand_templates_generate_rawhtml' )->text(),
197  'id' => 'generate_rawhtml',
198  ],
199  ];
200 
201  $form = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
202  $form
203  ->setSubmitTextMsg( 'expand_templates_ok' )
204  ->setWrapperLegendMsg( 'expandtemplates' )
205  ->setHeaderText( $this->msg( 'expand_templates_intro' )->parse() )
206  ->setSubmitCallback( [ $this, 'onSubmitInput' ] )
207  ->showAlways();
208  }
209 
217  private function makeOutput( $output, $heading = 'expand_templates_output' ) {
218  $out = "<h2>" . $this->msg( $heading )->escaped() . "</h2>\n";
219  $out .= Xml::textarea(
220  'output',
221  $output,
222  10,
223  10,
224  [
225  'id' => 'output',
226  'readonly' => 'readonly',
227  'class' => 'mw-editfont-' . $this->userOptionsLookup->getOption( $this->getUser(), 'editfont' )
228  ]
229  );
230 
231  return $out;
232  }
233 
241  private function generateHtml( Title $title, $text ) {
242  $popts = ParserOptions::newFromContext( $this->getContext() );
243  $popts->setTargetLanguage( $title->getPageLanguage() );
244  return $this->parser->parse( $text, $title, $popts );
245  }
246 
254  private function showHtmlPreview( Title $title, ParserOutput $pout, OutputPage $out ) {
255  $lang = $title->getPageViewLanguage();
256  $out->addHTML( "<h2>" . $this->msg( 'expand_templates_preview' )->escaped() . "</h2>\n" );
257 
258  if ( $this->getConfig()->get( MainConfigNames::RawHtml ) ) {
259  $request = $this->getRequest();
260  $user = $this->getUser();
261 
262  // To prevent cross-site scripting attacks, don't show the preview if raw HTML is
263  // allowed and a valid edit token is not provided (T73111). However, MediaWiki
264  // does not currently provide logged-out users with CSRF protection; in that case,
265  // do not show the preview unless anonymous editing is allowed.
266  if ( $user->isAnon() && !$this->getAuthority()->isAllowed( 'edit' ) ) {
267  $error = [ 'expand_templates_preview_fail_html_anon' ];
268  } elseif ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ), '', $request ) ) {
269  $error = [ 'expand_templates_preview_fail_html' ];
270  } else {
271  $error = false;
272  }
273 
274  if ( $error ) {
275  $out->addHTML(
277  $out->msg( $error )->parse(),
278  '',
279  'previewnote'
280  )
281  );
282  return;
283  }
284  }
285 
286  $out->addHTML( Html::openElement( 'div', [
287  'class' => 'mw-content-' . $lang->getDir(),
288  'dir' => $lang->getDir(),
289  'lang' => $lang->getHtmlCode(),
290  ] ) );
291  $out->addParserOutputContent( $pout );
292  $out->addHTML( Html::closeElement( 'div' ) );
293  $out->setCategoryLinks( $pout->getCategories() );
294  }
295 
296  protected function getGroupName() {
297  return 'wiki';
298  }
299 }
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
static factory( $displayFormat, $descriptor, IContextSource $context, $messagePrefix='')
Construct a HTMLForm object for given display type.
Definition: HTMLForm.php:338
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:256
static errorBox( $html, $heading='', $className='')
Return an error box.
Definition: Html.php:788
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:320
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.
Definition: OutputPage.php:52
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.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition: Parser.php:95
const OT_PREPROCESS
Definition: Parser.php:131
A special page that expands submitted templates, parser functions, and variables, allowing easier deb...
makeForm()
Generate a form allowing users to enter information.
__construct(Parser $parser, UserOptionsLookup $userOptionsLookup, TidyDriverBase $tidy)
UserOptionsLookup $userOptionsLookup
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...
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.
Parent class for all special pages.
Definition: SpecialPage.php:44
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.
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
Represents a title within MediaWiki.
Definition: Title.php:48
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:369
static textarea( $name, $content, $cols=40, $rows=5, $attribs=[])
Shortcut for creating textareas.
Definition: Xml.php:654
if(!isset( $args[0])) $lang