MediaWiki master
ApiExpandTemplates.php
Go to the documentation of this file.
1<?php
9namespace MediaWiki\Api;
10
18
27
28 public function __construct(
29 ApiMain $main,
30 string $action,
31 private readonly RevisionStore $revisionStore,
32 private readonly ParserFactory $parserFactory,
33 ) {
34 parent::__construct( $main, $action );
35 }
36
37 public function execute() {
38 // Cache may vary on the user because ParserOptions gets data from it
39 $this->getMain()->setCacheMode( 'anon-public-user-private' );
40
41 // Get parameters
42 $params = $this->extractRequestParams();
43 $this->requireMaxOneParameter( $params, 'prop', 'generatexml' );
44
45 $title = $params['title'];
46 if ( $title === null ) {
47 $titleProvided = false;
48 // A title is needed for parsing, so arbitrarily choose one
49 $title = 'API';
50 } else {
51 $titleProvided = true;
52 }
53
54 if ( $params['prop'] === null ) {
55 $this->addDeprecation(
56 [ 'apiwarn-deprecation-missingparam', 'prop' ], 'action=expandtemplates&!prop'
57 );
58 $prop = [];
59 } else {
60 $prop = array_fill_keys( $params['prop'], true );
61 }
62
63 $titleObj = Title::newFromText( $title );
64 if ( !$titleObj || $titleObj->isExternal() ) {
65 $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
66 }
67
68 // Get title and revision ID for parser
69 $revid = $params['revid'];
70 if ( $revid !== null ) {
71 $rev = $this->revisionStore->getRevisionById( $revid );
72 if ( !$rev ) {
73 $this->dieWithError( [ 'apierror-nosuchrevid', $revid ] );
74 }
75 $pTitleObj = $titleObj;
76 $titleObj = Title::newFromPageIdentity( $rev->getPage() );
77 if ( $titleProvided && !$titleObj->equals( $pTitleObj ) ) {
78 $this->addWarning( [ 'apierror-revwrongpage', $rev->getId(),
79 wfEscapeWikiText( $pTitleObj->getPrefixedText() ) ] );
80 }
81 }
82
83 $result = $this->getResult();
84
85 // Parse text
86 $options = ParserOptions::newFromContext( $this->getContext() );
87
88 if ( $params['includecomments'] ) {
89 $options->setRemoveComments( false );
90 }
91
92 $reset = null;
93 $suppressCache = false;
94 $this->getHookRunner()->onApiMakeParserOptions(
95 $options, $titleObj, $params, $this, $reset, $suppressCache );
96
97 $retval = [];
98
99 if ( isset( $prop['parsetree'] ) || $params['generatexml'] ) {
100 $parser = $this->parserFactory->getInstance();
101 $parser->startExternalParse( $titleObj, $options, Parser::OT_PREPROCESS );
102 $dom = $parser->preprocessToDom( $params['text'] );
103 if ( is_callable( [ $dom, 'saveXML' ] ) ) {
104 // @phan-suppress-next-line PhanUndeclaredMethod
105 $xml = $dom->saveXML();
106 } else {
107 // @phan-suppress-next-line PhanUndeclaredMethod
108 $xml = $dom->__toString();
109 }
110 if ( isset( $prop['parsetree'] ) ) {
111 unset( $prop['parsetree'] );
112 $retval['parsetree'] = $xml;
113 } else {
114 // the old way
115 $result->addValue( null, 'parsetree', $xml );
116 $result->addValue( null, ApiResult::META_BC_SUBELEMENTS, [ 'parsetree' ] );
117 }
118 }
119
120 // if they didn't want any output except (probably) the parse tree,
121 // then don't bother actually fully expanding it
122 if ( $prop || $params['prop'] === null ) {
123 $parser = $this->parserFactory->getInstance();
124 $parser->startExternalParse( $titleObj, $options, Parser::OT_PREPROCESS );
125 $frame = $parser->getPreprocessor()->newFrame();
126 $wikitext = $parser->preprocess( $params['text'], $titleObj, $options, $revid, $frame );
127 if ( $params['prop'] === null ) {
128 // the old way
129 ApiResult::setContentValue( $retval, 'wikitext', $wikitext );
130 } else {
131 $p_output = $parser->getOutput();
132 if ( isset( $prop['categories'] ) ) {
133 $categories = $p_output->getCategoryNames();
134 if ( $categories ) {
135 $defaultSortKey = $p_output->getPageProperty( 'defaultsort' ) ?? '';
136 $categories_result = [];
137 foreach ( $categories as $category ) {
138 $entry = [
139 // Note that ::getCategorySortKey() returns
140 // the empty string '' to mean
141 // "use the default sort key"
142 'sortkey' => $p_output->getCategorySortKey( $category ) ?: $defaultSortKey,
143 ];
144 ApiResult::setContentValue( $entry, 'category', $category );
145 $categories_result[] = $entry;
146 }
147 ApiResult::setIndexedTagName( $categories_result, 'category' );
148 $retval['categories'] = $categories_result;
149 }
150 }
151 if ( isset( $prop['properties'] ) ) {
152 $properties = $p_output->getPageProperties();
153 if ( $properties ) {
154 ApiResult::setArrayType( $properties, 'BCkvp', 'name' );
155 ApiResult::setIndexedTagName( $properties, 'property' );
156 $retval['properties'] = $properties;
157 }
158 }
159 if ( isset( $prop['volatile'] ) ) {
160 $retval['volatile'] = $frame->isVolatile();
161 }
162 if ( isset( $prop['ttl'] ) && $p_output->hasReducedExpiry() ) {
163 $retval['ttl'] = $p_output->getCacheExpiry();
164 }
165 if ( isset( $prop['wikitext'] ) ) {
166 $retval['wikitext'] = $wikitext;
167 }
168 if ( isset( $prop['modules'] ) ) {
169 $retval['modules'] = array_values( array_unique( $p_output->getModules() ) );
170 // Deprecated since 1.32 (T188689)
171 $retval['modulescripts'] = [];
172 $retval['modulestyles'] = array_values( array_unique( $p_output->getModuleStyles() ) );
173 }
174 if ( isset( $prop['jsconfigvars'] ) ) {
175 $showStrategyKeys = (bool)( $params['showstrategykeys'] );
176 $retval['jsconfigvars'] =
177 ApiResult::addMetadataToResultVars( $p_output->getJsConfigVars( $showStrategyKeys ) );
178 }
179 if ( isset( $prop['encodedjsconfigvars'] ) ) {
180 $retval['encodedjsconfigvars'] = FormatJson::encode(
181 $p_output->getJsConfigVars(), false, FormatJson::ALL_OK
182 );
183 $retval[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars';
184 }
185 if ( isset( $prop['modules'] ) &&
186 !isset( $prop['jsconfigvars'] ) && !isset( $prop['encodedjsconfigvars'] ) ) {
187 $this->addWarning( 'apiwarn-moduleswithoutvars' );
188 }
189 }
190 }
191 ApiResult::setSubelementsList( $retval, [ 'wikitext', 'parsetree' ] );
192 $result->addValue( null, $this->getModuleName(), $retval );
193 }
194
196 public function getAllowedParams() {
197 return [
198 'title' => null,
199 'text' => [
200 ParamValidator::PARAM_TYPE => 'text',
201 ParamValidator::PARAM_REQUIRED => true,
202 ],
203 'revid' => [
204 ParamValidator::PARAM_TYPE => 'integer',
205 ],
206 'prop' => [
207 ParamValidator::PARAM_TYPE => [
208 'wikitext',
209 'categories',
210 'properties',
211 'volatile',
212 'ttl',
213 'modules',
214 'jsconfigvars',
215 'encodedjsconfigvars',
216 'parsetree',
217 ],
218 ParamValidator::PARAM_ISMULTI => true,
220 ],
221 'includecomments' => false,
222 'showstrategykeys' => false,
223 'generatexml' => [
224 ParamValidator::PARAM_TYPE => 'boolean',
225 ParamValidator::PARAM_DEPRECATED => true,
226 ],
227 ];
228 }
229
231 protected function getExamplesMessages() {
232 return [
233 'action=expandtemplates&text={{Project:Sandbox}}'
234 => 'apihelp-expandtemplates-example-simple',
235 ];
236 }
237
239 public function getHelpUrls() {
240 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Expandtemplates';
241 }
242}
243
245class_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:60
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:206
requireMaxOneParameter( $params,... $required)
Dies if more than one parameter from a certain set of parameters are set and not false.
Definition ApiBase.php:1012
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition ApiBase.php:1439
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.1.25, returning boolean false is deprecated...
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
__construct(ApiMain $main, string $action, private readonly RevisionStore $revisionStore, private readonly ParserFactory $parserFactory,)
getExamplesMessages()
Returns usage examples for this module.Return value has query strings as keys, with values being eith...
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:66
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:84
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:134
Service for looking up page revisions.
Represents a title within MediaWiki.
Definition Title.php:69
Service for formatting and validating API parameters.