MediaWiki REL1_39
ApiExpandTemplates.php
Go to the documentation of this file.
1<?php
25
35 private $revisionStore;
36
38 private $parser;
39
46 public function __construct(
47 ApiMain $main,
48 $action,
49 RevisionStore $revisionStore,
50 Parser $parser
51 ) {
52 parent::__construct( $main, $action );
53 $this->revisionStore = $revisionStore;
54 $this->parser = $parser;
55 }
56
57 public function execute() {
58 // Cache may vary on the user because ParserOptions gets data from it
59 $this->getMain()->setCacheMode( 'anon-public-user-private' );
60
61 // Get parameters
62 $params = $this->extractRequestParams();
63 $this->requireMaxOneParameter( $params, 'prop', 'generatexml' );
64
65 $title = $params['title'];
66 if ( $title === null ) {
67 $titleProvided = false;
68 // A title is needed for parsing, so arbitrarily choose one
69 $title = 'API';
70 } else {
71 $titleProvided = true;
72 }
73
74 if ( $params['prop'] === null ) {
75 $this->addDeprecation(
76 [ 'apiwarn-deprecation-missingparam', 'prop' ], 'action=expandtemplates&!prop'
77 );
78 $prop = [];
79 } else {
80 $prop = array_fill_keys( $params['prop'], true );
81 }
82
83 $titleObj = Title::newFromText( $title );
84 if ( !$titleObj || $titleObj->isExternal() ) {
85 $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
86 }
87
88 // Get title and revision ID for parser
89 $revid = $params['revid'];
90 if ( $revid !== null ) {
91 $rev = $this->revisionStore->getRevisionById( $revid );
92 if ( !$rev ) {
93 $this->dieWithError( [ 'apierror-nosuchrevid', $revid ] );
94 }
95 $pTitleObj = $titleObj;
96 $titleObj = Title::newFromLinkTarget( $rev->getPageAsLinkTarget() );
97 if ( $titleProvided && !$titleObj->equals( $pTitleObj ) ) {
98 $this->addWarning( [ 'apierror-revwrongpage', $rev->getId(),
99 wfEscapeWikiText( $pTitleObj->getPrefixedText() ) ] );
100 }
101 }
102
103 $result = $this->getResult();
104
105 // Parse text
106 $options = ParserOptions::newFromContext( $this->getContext() );
107
108 if ( $params['includecomments'] ) {
109 $options->setRemoveComments( false );
110 }
111
112 $reset = null;
113 $suppressCache = false;
114 $this->getHookRunner()->onApiMakeParserOptions(
115 $options, $titleObj, $params, $this, $reset, $suppressCache );
116
117 $retval = [];
118
119 if ( isset( $prop['parsetree'] ) || $params['generatexml'] ) {
120 $this->parser->startExternalParse( $titleObj, $options, Parser::OT_PREPROCESS );
121 $dom = $this->parser->preprocessToDom( $params['text'] );
122 // @phan-suppress-next-line PhanUndeclaredMethodInCallable
123 if ( is_callable( [ $dom, 'saveXML' ] ) ) {
124 // @phan-suppress-next-line PhanUndeclaredMethod
125 $xml = $dom->saveXML();
126 } else {
127 // @phan-suppress-next-line PhanUndeclaredMethod
128 $xml = $dom->__toString();
129 }
130 if ( isset( $prop['parsetree'] ) ) {
131 unset( $prop['parsetree'] );
132 $retval['parsetree'] = $xml;
133 } else {
134 // the old way
135 $result->addValue( null, 'parsetree', $xml );
136 $result->addValue( null, ApiResult::META_BC_SUBELEMENTS, [ 'parsetree' ] );
137 }
138 }
139
140 // if they didn't want any output except (probably) the parse tree,
141 // then don't bother actually fully expanding it
142 if ( $prop || $params['prop'] === null ) {
143 $this->parser->startExternalParse( $titleObj, $options, Parser::OT_PREPROCESS );
144 $frame = $this->parser->getPreprocessor()->newFrame();
145 $wikitext = $this->parser->preprocess( $params['text'], $titleObj, $options, $revid, $frame );
146 if ( $params['prop'] === null ) {
147 // the old way
148 ApiResult::setContentValue( $retval, 'wikitext', $wikitext );
149 } else {
150 $p_output = $this->parser->getOutput();
151 if ( isset( $prop['categories'] ) ) {
152 $categories = $p_output->getCategories();
153 if ( $categories ) {
154 $categories_result = [];
155 foreach ( $categories as $category => $sortkey ) {
156 $entry = [];
157 $entry['sortkey'] = $sortkey;
158 ApiResult::setContentValue( $entry, 'category', (string)$category );
159 $categories_result[] = $entry;
160 }
161 ApiResult::setIndexedTagName( $categories_result, 'category' );
162 $retval['categories'] = $categories_result;
163 }
164 }
165 if ( isset( $prop['properties'] ) ) {
166 $properties = $p_output->getPageProperties();
167 if ( $properties ) {
168 ApiResult::setArrayType( $properties, 'BCkvp', 'name' );
169 ApiResult::setIndexedTagName( $properties, 'property' );
170 $retval['properties'] = $properties;
171 }
172 }
173 if ( isset( $prop['volatile'] ) ) {
174 $retval['volatile'] = $frame->isVolatile();
175 }
176 if ( isset( $prop['ttl'] ) && $frame->getTTL() !== null ) {
177 $retval['ttl'] = $frame->getTTL();
178 }
179 if ( isset( $prop['wikitext'] ) ) {
180 $retval['wikitext'] = $wikitext;
181 }
182 if ( isset( $prop['modules'] ) ) {
183 $retval['modules'] = array_values( array_unique( $p_output->getModules() ) );
184 // Deprecated since 1.32 (T188689)
185 $retval['modulescripts'] = [];
186 $retval['modulestyles'] = array_values( array_unique( $p_output->getModuleStyles() ) );
187 }
188 if ( isset( $prop['jsconfigvars'] ) ) {
189 $showStrategyKeys = (bool)( $params['showstrategykeys'] );
190 $retval['jsconfigvars'] =
191 ApiResult::addMetadataToResultVars( $p_output->getJsConfigVars( $showStrategyKeys ) );
192 }
193 if ( isset( $prop['encodedjsconfigvars'] ) ) {
194 $retval['encodedjsconfigvars'] = FormatJson::encode(
195 $p_output->getJsConfigVars(), false, FormatJson::ALL_OK
196 );
197 $retval[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars';
198 }
199 if ( isset( $prop['modules'] ) &&
200 !isset( $prop['jsconfigvars'] ) && !isset( $prop['encodedjsconfigvars'] ) ) {
201 $this->addWarning( 'apiwarn-moduleswithoutvars' );
202 }
203 }
204 }
205 ApiResult::setSubelementsList( $retval, [ 'wikitext', 'parsetree' ] );
206 $result->addValue( null, $this->getModuleName(), $retval );
207 }
208
209 public function getAllowedParams() {
210 return [
211 'title' => null,
212 'text' => [
213 ParamValidator::PARAM_TYPE => 'text',
214 ParamValidator::PARAM_REQUIRED => true,
215 ],
216 'revid' => [
217 ParamValidator::PARAM_TYPE => 'integer',
218 ],
219 'prop' => [
220 ParamValidator::PARAM_TYPE => [
221 'wikitext',
222 'categories',
223 'properties',
224 'volatile',
225 'ttl',
226 'modules',
227 'jsconfigvars',
228 'encodedjsconfigvars',
229 'parsetree',
230 ],
231 ParamValidator::PARAM_ISMULTI => true,
233 ],
234 'includecomments' => false,
235 'showstrategykeys' => false,
236 'generatexml' => [
237 ParamValidator::PARAM_TYPE => 'boolean',
238 ParamValidator::PARAM_DEPRECATED => true,
239 ],
240 ];
241 }
242
243 protected function getExamplesMessages() {
244 return [
245 'action=expandtemplates&text={{Project:Sandbox}}'
246 => 'apihelp-expandtemplates-example-simple',
247 ];
248 }
249
250 public function getHelpUrls() {
251 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Parsing_wikitext#expandtemplates';
252 }
253}
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:56
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1454
getMain()
Get the main module.
Definition ApiBase.php:514
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, this is an array mapping those values to $msg...
Definition ApiBase.php:196
addDeprecation( $msg, $feature, $data=[])
Add a deprecation warning for this module.
Definition ApiBase.php:1386
requireMaxOneParameter( $params,... $required)
Die if more than one of a certain set of parameters is set and not false.
Definition ApiBase.php:938
getResult()
Get the result object.
Definition ApiBase.php:629
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:765
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition ApiBase.php:1372
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:498
getHookRunner()
Get an ApiHookRunner for running core API hooks.
Definition ApiBase.php:711
API module that functions as a shortcut to the wikitext preprocessor.
getExamplesMessages()
Returns usage examples for this module.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
__construct(ApiMain $main, $action, RevisionStore $revisionStore, Parser $parser)
getHelpUrls()
Return links to more detailed help pages about the module.
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:52
getContext()
Get the base IContextSource object.
Service for looking up page revisions.
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
Service for formatting and validating API parameters.