MediaWiki master
ApiExpandTemplates.php
Go to the documentation of this file.
1<?php
23namespace MediaWiki\Api;
24
32
41 private RevisionStore $revisionStore;
42 private ParserFactory $parserFactory;
43
44 public function __construct(
45 ApiMain $main,
46 string $action,
47 RevisionStore $revisionStore,
48 ParserFactory $parserFactory
49 ) {
50 parent::__construct( $main, $action );
51 $this->revisionStore = $revisionStore;
52 $this->parserFactory = $parserFactory;
53 }
54
55 public function execute() {
56 // Cache may vary on the user because ParserOptions gets data from it
57 $this->getMain()->setCacheMode( 'anon-public-user-private' );
58
59 // Get parameters
60 $params = $this->extractRequestParams();
61 $this->requireMaxOneParameter( $params, 'prop', 'generatexml' );
62
63 $title = $params['title'];
64 if ( $title === null ) {
65 $titleProvided = false;
66 // A title is needed for parsing, so arbitrarily choose one
67 $title = 'API';
68 } else {
69 $titleProvided = true;
70 }
71
72 if ( $params['prop'] === null ) {
73 $this->addDeprecation(
74 [ 'apiwarn-deprecation-missingparam', 'prop' ], 'action=expandtemplates&!prop'
75 );
76 $prop = [];
77 } else {
78 $prop = array_fill_keys( $params['prop'], true );
79 }
80
81 $titleObj = Title::newFromText( $title );
82 if ( !$titleObj || $titleObj->isExternal() ) {
83 $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
84 }
85
86 // Get title and revision ID for parser
87 $revid = $params['revid'];
88 if ( $revid !== null ) {
89 $rev = $this->revisionStore->getRevisionById( $revid );
90 if ( !$rev ) {
91 $this->dieWithError( [ 'apierror-nosuchrevid', $revid ] );
92 }
93 $pTitleObj = $titleObj;
94 $titleObj = Title::newFromPageIdentity( $rev->getPage() );
95 if ( $titleProvided && !$titleObj->equals( $pTitleObj ) ) {
96 $this->addWarning( [ 'apierror-revwrongpage', $rev->getId(),
97 wfEscapeWikiText( $pTitleObj->getPrefixedText() ) ] );
98 }
99 }
100
101 $result = $this->getResult();
102
103 // Parse text
104 $options = ParserOptions::newFromContext( $this->getContext() );
105
106 if ( $params['includecomments'] ) {
107 $options->setRemoveComments( false );
108 }
109
110 $reset = null;
111 $suppressCache = false;
112 $this->getHookRunner()->onApiMakeParserOptions(
113 $options, $titleObj, $params, $this, $reset, $suppressCache );
114
115 $retval = [];
116
117 if ( isset( $prop['parsetree'] ) || $params['generatexml'] ) {
118 $parser = $this->parserFactory->getInstance();
119 $parser->startExternalParse( $titleObj, $options, Parser::OT_PREPROCESS );
120 $dom = $parser->preprocessToDom( $params['text'] );
121 // @phan-suppress-next-line PhanUndeclaredMethodInCallable
122 if ( is_callable( [ $dom, 'saveXML' ] ) ) {
123 // @phan-suppress-next-line PhanUndeclaredMethod
124 $xml = $dom->saveXML();
125 } else {
126 // @phan-suppress-next-line PhanUndeclaredMethod
127 $xml = $dom->__toString();
128 }
129 if ( isset( $prop['parsetree'] ) ) {
130 unset( $prop['parsetree'] );
131 $retval['parsetree'] = $xml;
132 } else {
133 // the old way
134 $result->addValue( null, 'parsetree', $xml );
135 $result->addValue( null, ApiResult::META_BC_SUBELEMENTS, [ 'parsetree' ] );
136 }
137 }
138
139 // if they didn't want any output except (probably) the parse tree,
140 // then don't bother actually fully expanding it
141 if ( $prop || $params['prop'] === null ) {
142 $parser = $this->parserFactory->getInstance();
143 $parser->startExternalParse( $titleObj, $options, Parser::OT_PREPROCESS );
144 $frame = $parser->getPreprocessor()->newFrame();
145 $wikitext = $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 = $parser->getOutput();
151 if ( isset( $prop['categories'] ) ) {
152 $categories = $p_output->getCategoryNames();
153 if ( $categories ) {
154 $defaultSortKey = $p_output->getPageProperty( 'defaultsort' ) ?? '';
155 $categories_result = [];
156 foreach ( $categories as $category ) {
157 $entry = [
158 // Note that ::getCategorySortKey() returns
159 // the empty string '' to mean
160 // "use the default sort key"
161 'sortkey' => $p_output->getCategorySortKey( $category ) ?: $defaultSortKey,
162 ];
163 ApiResult::setContentValue( $entry, 'category', $category );
164 $categories_result[] = $entry;
165 }
166 ApiResult::setIndexedTagName( $categories_result, 'category' );
167 $retval['categories'] = $categories_result;
168 }
169 }
170 if ( isset( $prop['properties'] ) ) {
171 $properties = $p_output->getPageProperties();
172 if ( $properties ) {
173 ApiResult::setArrayType( $properties, 'BCkvp', 'name' );
174 ApiResult::setIndexedTagName( $properties, 'property' );
175 $retval['properties'] = $properties;
176 }
177 }
178 if ( isset( $prop['volatile'] ) ) {
179 $retval['volatile'] = $frame->isVolatile();
180 }
181 if ( isset( $prop['ttl'] ) && $frame->getTTL() !== null ) {
182 $retval['ttl'] = $frame->getTTL();
183 }
184 if ( isset( $prop['wikitext'] ) ) {
185 $retval['wikitext'] = $wikitext;
186 }
187 if ( isset( $prop['modules'] ) ) {
188 $retval['modules'] = array_values( array_unique( $p_output->getModules() ) );
189 // Deprecated since 1.32 (T188689)
190 $retval['modulescripts'] = [];
191 $retval['modulestyles'] = array_values( array_unique( $p_output->getModuleStyles() ) );
192 }
193 if ( isset( $prop['jsconfigvars'] ) ) {
194 $showStrategyKeys = (bool)( $params['showstrategykeys'] );
195 $retval['jsconfigvars'] =
196 ApiResult::addMetadataToResultVars( $p_output->getJsConfigVars( $showStrategyKeys ) );
197 }
198 if ( isset( $prop['encodedjsconfigvars'] ) ) {
199 $retval['encodedjsconfigvars'] = FormatJson::encode(
200 $p_output->getJsConfigVars(), false, FormatJson::ALL_OK
201 );
202 $retval[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars';
203 }
204 if ( isset( $prop['modules'] ) &&
205 !isset( $prop['jsconfigvars'] ) && !isset( $prop['encodedjsconfigvars'] ) ) {
206 $this->addWarning( 'apiwarn-moduleswithoutvars' );
207 }
208 }
209 }
210 ApiResult::setSubelementsList( $retval, [ 'wikitext', 'parsetree' ] );
211 $result->addValue( null, $this->getModuleName(), $retval );
212 }
213
214 public function getAllowedParams() {
215 return [
216 'title' => null,
217 'text' => [
218 ParamValidator::PARAM_TYPE => 'text',
219 ParamValidator::PARAM_REQUIRED => true,
220 ],
221 'revid' => [
222 ParamValidator::PARAM_TYPE => 'integer',
223 ],
224 'prop' => [
225 ParamValidator::PARAM_TYPE => [
226 'wikitext',
227 'categories',
228 'properties',
229 'volatile',
230 'ttl',
231 'modules',
232 'jsconfigvars',
233 'encodedjsconfigvars',
234 'parsetree',
235 ],
236 ParamValidator::PARAM_ISMULTI => true,
238 ],
239 'includecomments' => false,
240 'showstrategykeys' => false,
241 'generatexml' => [
242 ParamValidator::PARAM_TYPE => 'boolean',
243 ParamValidator::PARAM_DEPRECATED => true,
244 ],
245 ];
246 }
247
248 protected function getExamplesMessages() {
249 return [
250 'action=expandtemplates&text={{Project:Sandbox}}'
251 => 'apihelp-expandtemplates-example-simple',
252 ];
253 }
254
255 public function getHelpUrls() {
256 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Expandtemplates';
257 }
258}
259
261class_alias( ApiExpandTemplates::class, 'ApiExpandTemplates' );
wfEscapeWikiText( $input)
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:75
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1522
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:557
getHookRunner()
Get an ApiHookRunner for running core API hooks.
Definition ApiBase.php:781
getMain()
Get the main module.
Definition ApiBase.php:575
getResult()
Get the result object.
Definition ApiBase.php:696
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, or 'string' with PARAM_ISMULTI,...
Definition ApiBase.php:221
requireMaxOneParameter( $params,... $required)
Dies if more than one parameter from a certain set of parameters are set and not false.
Definition ApiBase.php:1011
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition ApiBase.php:1440
addDeprecation( $msg, $feature, $data=[])
Add a deprecation warning for this module.
Definition ApiBase.php:1454
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:837
API module that functions as a shortcut to the wikitext preprocessor.
getHelpUrls()
Return links to more detailed help pages about the module.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
getExamplesMessages()
Returns usage examples for this module.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
__construct(ApiMain $main, string $action, RevisionStore $revisionStore, ParserFactory $parserFactory)
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:79
static addMetadataToResultVars( $vars, $forceHash=true)
Add the correct metadata to an array of vars we want to export through the API.
const META_BC_SUBELEMENTS
Key for the 'BC subelements' metadata item.
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
const META_SUBELEMENTS
Key for the 'subelements' metadata item.
Definition ApiResult.php:88
static setArrayType(array &$arr, $type, $kvpKeyName=null)
Set the array data type.
static setContentValue(array &$arr, $name, $value, $flags=0)
Add an output value to the array by name and mark as META_CONTENT.
static setSubelementsList(array &$arr, $names)
Causes the elements with the specified names to be output as subelements rather than attributes.
JSON formatter wrapper class.
Set options of the Parser.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:147
Service for looking up page revisions.
Represents a title within MediaWiki.
Definition Title.php:78
Service for formatting and validating API parameters.