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