MediaWiki REL1_37
ApiExpandTemplates.php
Go to the documentation of this file.
1<?php
24
35
37 private $parser;
38
45 public function __construct(
46 ApiMain $main,
47 $action,
50 ) {
51 parent::__construct( $main, $action );
52 $this->revisionStore = $revisionStore;
53 $this->parser = $parser;
54 }
55
56 public function execute() {
57 // Cache may vary on the user because ParserOptions gets data from it
58 $this->getMain()->setCacheMode( 'anon-public-user-private' );
59
60 // Get parameters
61 $params = $this->extractRequestParams();
62 $this->requireMaxOneParameter( $params, 'prop', 'generatexml' );
63
64 $title = $params['title'];
65 if ( $title === null ) {
66 $titleProvided = false;
67 // A title is needed for parsing, so arbitrarily choose one
68 $title = 'API';
69 } else {
70 $titleProvided = true;
71 }
72
73 if ( $params['prop'] === null ) {
74 $this->addDeprecation(
75 [ 'apiwarn-deprecation-missingparam', 'prop' ], 'action=expandtemplates&!prop'
76 );
77 $prop = [];
78 } else {
79 $prop = array_fill_keys( $params['prop'], true );
80 }
81
82 $titleObj = Title::newFromText( $title );
83 if ( !$titleObj || $titleObj->isExternal() ) {
84 $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
85 }
86
87 // Get title and revision ID for parser
88 $revid = $params['revid'];
89 if ( $revid !== null ) {
90 $rev = $this->revisionStore->getRevisionById( $revid );
91 if ( !$rev ) {
92 $this->dieWithError( [ 'apierror-nosuchrevid', $revid ] );
93 }
94 $pTitleObj = $titleObj;
95 $titleObj = Title::newFromLinkTarget( $rev->getPageAsLinkTarget() );
96 if ( $titleProvided ) {
97 if ( !$titleObj->equals( $pTitleObj ) ) {
98 $this->addWarning( [ 'apierror-revwrongpage', $rev->getId(),
99 wfEscapeWikiText( $pTitleObj->getPrefixedText() ) ] );
100 }
101 }
102 }
103
104 $result = $this->getResult();
105
106 // Parse text
107 $options = ParserOptions::newFromContext( $this->getContext() );
108
109 if ( $params['includecomments'] ) {
110 $options->setRemoveComments( false );
111 }
112
113 $reset = null;
114 $suppressCache = false;
115 $this->getHookRunner()->onApiMakeParserOptions(
116 $options, $titleObj, $params, $this, $reset, $suppressCache );
117
118 $retval = [];
119
120 if ( isset( $prop['parsetree'] ) || $params['generatexml'] ) {
121 $this->parser->startExternalParse( $titleObj, $options, Parser::OT_PREPROCESS );
122 $dom = $this->parser->preprocessToDom( $params['text'] );
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->getProperties();
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 $retval['jsconfigvars'] =
190 ApiResult::addMetadataToResultVars( $p_output->getJsConfigVars() );
191 }
192 if ( isset( $prop['encodedjsconfigvars'] ) ) {
193 $retval['encodedjsconfigvars'] = FormatJson::encode(
194 $p_output->getJsConfigVars(), false, FormatJson::ALL_OK
195 );
196 $retval[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars';
197 }
198 if ( isset( $prop['modules'] ) &&
199 !isset( $prop['jsconfigvars'] ) && !isset( $prop['encodedjsconfigvars'] ) ) {
200 $this->addWarning( 'apiwarn-moduleswithoutvars' );
201 }
202 }
203 }
204 ApiResult::setSubelementsList( $retval, [ 'wikitext', 'parsetree' ] );
205 $result->addValue( null, $this->getModuleName(), $retval );
206 }
207
208 public function getAllowedParams() {
209 return [
210 'title' => null,
211 'text' => [
212 ApiBase::PARAM_TYPE => 'text',
214 ],
215 'revid' => [
216 ApiBase::PARAM_TYPE => 'integer',
217 ],
218 'prop' => [
220 'wikitext',
221 'categories',
222 'properties',
223 'volatile',
224 'ttl',
225 'modules',
226 'jsconfigvars',
227 'encodedjsconfigvars',
228 'parsetree',
229 ],
232 ],
233 'includecomments' => false,
234 'generatexml' => [
235 ApiBase::PARAM_TYPE => 'boolean',
237 ],
238 ];
239 }
240
241 protected function getExamplesMessages() {
242 return [
243 'action=expandtemplates&text={{Project:Sandbox}}'
244 => 'apihelp-expandtemplates-example-simple',
245 ];
246 }
247
248 public function getHelpUrls() {
249 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Parsing_wikitext#expandtemplates';
250 }
251}
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:55
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1436
const PARAM_REQUIRED
Definition ApiBase.php:105
const PARAM_DEPRECATED
Definition ApiBase.php:101
getMain()
Get the main module.
Definition ApiBase.php:513
const PARAM_TYPE
Definition ApiBase.php:81
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:195
addDeprecation( $msg, $feature, $data=[])
Add a deprecation warning for this module.
Definition ApiBase.php:1368
requireMaxOneParameter( $params,... $required)
Die if more than one of a certain set of parameters is set and not false.
Definition ApiBase.php:936
getResult()
Get the result object.
Definition ApiBase.php:628
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:764
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition ApiBase.php:1354
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:497
getHookRunner()
Get an ApiHookRunner for running core API hooks.
Definition ApiBase.php:710
const PARAM_ISMULTI
Definition ApiBase.php:77
API module that functions as a shortcut to the wikitext preprocessor.
getExamplesMessages()
Returns usage examples for this module.
RevisionStore $revisionStore
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:49
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:91
const OT_PREPROCESS
Definition Parser.php:127