MediaWiki REL1_40
ApiExpandTemplates.php
Go to the documentation of this file.
1<?php
26
36 private $revisionStore;
37
39 private $parser;
40
47 public function __construct(
48 ApiMain $main,
49 $action,
50 RevisionStore $revisionStore,
51 Parser $parser
52 ) {
53 parent::__construct( $main, $action );
54 $this->revisionStore = $revisionStore;
55 $this->parser = $parser;
56 }
57
58 public function execute() {
59 // Cache may vary on the user because ParserOptions gets data from it
60 $this->getMain()->setCacheMode( 'anon-public-user-private' );
61
62 // Get parameters
63 $params = $this->extractRequestParams();
64 $this->requireMaxOneParameter( $params, 'prop', 'generatexml' );
65
66 $title = $params['title'];
67 if ( $title === null ) {
68 $titleProvided = false;
69 // A title is needed for parsing, so arbitrarily choose one
70 $title = 'API';
71 } else {
72 $titleProvided = true;
73 }
74
75 if ( $params['prop'] === null ) {
76 $this->addDeprecation(
77 [ 'apiwarn-deprecation-missingparam', 'prop' ], 'action=expandtemplates&!prop'
78 );
79 $prop = [];
80 } else {
81 $prop = array_fill_keys( $params['prop'], true );
82 }
83
84 $titleObj = Title::newFromText( $title );
85 if ( !$titleObj || $titleObj->isExternal() ) {
86 $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
87 }
88
89 // Get title and revision ID for parser
90 $revid = $params['revid'];
91 if ( $revid !== null ) {
92 $rev = $this->revisionStore->getRevisionById( $revid );
93 if ( !$rev ) {
94 $this->dieWithError( [ 'apierror-nosuchrevid', $revid ] );
95 }
96 $pTitleObj = $titleObj;
97 $titleObj = Title::newFromLinkTarget( $rev->getPageAsLinkTarget() );
98 if ( $titleProvided && !$titleObj->equals( $pTitleObj ) ) {
99 $this->addWarning( [ 'apierror-revwrongpage', $rev->getId(),
100 wfEscapeWikiText( $pTitleObj->getPrefixedText() ) ] );
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 // @phan-suppress-next-line PhanUndeclaredMethodInCallable
124 if ( is_callable( [ $dom, 'saveXML' ] ) ) {
125 // @phan-suppress-next-line PhanUndeclaredMethod
126 $xml = $dom->saveXML();
127 } else {
128 // @phan-suppress-next-line PhanUndeclaredMethod
129 $xml = $dom->__toString();
130 }
131 if ( isset( $prop['parsetree'] ) ) {
132 unset( $prop['parsetree'] );
133 $retval['parsetree'] = $xml;
134 } else {
135 // the old way
136 $result->addValue( null, 'parsetree', $xml );
137 $result->addValue( null, ApiResult::META_BC_SUBELEMENTS, [ 'parsetree' ] );
138 }
139 }
140
141 // if they didn't want any output except (probably) the parse tree,
142 // then don't bother actually fully expanding it
143 if ( $prop || $params['prop'] === null ) {
144 $this->parser->startExternalParse( $titleObj, $options, Parser::OT_PREPROCESS );
145 $frame = $this->parser->getPreprocessor()->newFrame();
146 $wikitext = $this->parser->preprocess( $params['text'], $titleObj, $options, $revid, $frame );
147 if ( $params['prop'] === null ) {
148 // the old way
149 ApiResult::setContentValue( $retval, 'wikitext', $wikitext );
150 } else {
151 $p_output = $this->parser->getOutput();
152 if ( isset( $prop['categories'] ) ) {
153 $categories = $p_output->getCategories();
154 if ( $categories ) {
155 $categories_result = [];
156 foreach ( $categories as $category => $sortkey ) {
157 $entry = [];
158 $entry['sortkey'] = $sortkey;
159 ApiResult::setContentValue( $entry, 'category', (string)$category );
160 $categories_result[] = $entry;
161 }
162 ApiResult::setIndexedTagName( $categories_result, 'category' );
163 $retval['categories'] = $categories_result;
164 }
165 }
166 if ( isset( $prop['properties'] ) ) {
167 $properties = $p_output->getPageProperties();
168 if ( $properties ) {
169 ApiResult::setArrayType( $properties, 'BCkvp', 'name' );
170 ApiResult::setIndexedTagName( $properties, 'property' );
171 $retval['properties'] = $properties;
172 }
173 }
174 if ( isset( $prop['volatile'] ) ) {
175 $retval['volatile'] = $frame->isVolatile();
176 }
177 if ( isset( $prop['ttl'] ) && $frame->getTTL() !== null ) {
178 $retval['ttl'] = $frame->getTTL();
179 }
180 if ( isset( $prop['wikitext'] ) ) {
181 $retval['wikitext'] = $wikitext;
182 }
183 if ( isset( $prop['modules'] ) ) {
184 $retval['modules'] = array_values( array_unique( $p_output->getModules() ) );
185 // Deprecated since 1.32 (T188689)
186 $retval['modulescripts'] = [];
187 $retval['modulestyles'] = array_values( array_unique( $p_output->getModuleStyles() ) );
188 }
189 if ( isset( $prop['jsconfigvars'] ) ) {
190 $showStrategyKeys = (bool)( $params['showstrategykeys'] );
191 $retval['jsconfigvars'] =
192 ApiResult::addMetadataToResultVars( $p_output->getJsConfigVars( $showStrategyKeys ) );
193 }
194 if ( isset( $prop['encodedjsconfigvars'] ) ) {
195 $retval['encodedjsconfigvars'] = FormatJson::encode(
196 $p_output->getJsConfigVars(), false, FormatJson::ALL_OK
197 );
198 $retval[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars';
199 }
200 if ( isset( $prop['modules'] ) &&
201 !isset( $prop['jsconfigvars'] ) && !isset( $prop['encodedjsconfigvars'] ) ) {
202 $this->addWarning( 'apiwarn-moduleswithoutvars' );
203 }
204 }
205 }
206 ApiResult::setSubelementsList( $retval, [ 'wikitext', 'parsetree' ] );
207 $result->addValue( null, $this->getModuleName(), $retval );
208 }
209
210 public function getAllowedParams() {
211 return [
212 'title' => null,
213 'text' => [
214 ParamValidator::PARAM_TYPE => 'text',
215 ParamValidator::PARAM_REQUIRED => true,
216 ],
217 'revid' => [
218 ParamValidator::PARAM_TYPE => 'integer',
219 ],
220 'prop' => [
221 ParamValidator::PARAM_TYPE => [
222 'wikitext',
223 'categories',
224 'properties',
225 'volatile',
226 'ttl',
227 'modules',
228 'jsconfigvars',
229 'encodedjsconfigvars',
230 'parsetree',
231 ],
232 ParamValidator::PARAM_ISMULTI => true,
234 ],
235 'includecomments' => false,
236 'showstrategykeys' => false,
237 'generatexml' => [
238 ParamValidator::PARAM_TYPE => 'boolean',
239 ParamValidator::PARAM_DEPRECATED => true,
240 ],
241 ];
242 }
243
244 protected function getExamplesMessages() {
245 return [
246 'action=expandtemplates&text={{Project:Sandbox}}'
247 => 'apihelp-expandtemplates-example-simple',
248 ];
249 }
250
251 public function getHelpUrls() {
252 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Expandtemplates';
253 }
254}
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:59
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1460
getMain()
Get the main module.
Definition ApiBase.php:522
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, or 'string' with PARAM_ISMULTI,...
Definition ApiBase.php:204
addDeprecation( $msg, $feature, $data=[])
Add a deprecation warning for this module.
Definition ApiBase.php:1392
requireMaxOneParameter( $params,... $required)
Die if more than one of a certain set of parameters is set and not false.
Definition ApiBase.php:946
getResult()
Get the result object.
Definition ApiBase.php:637
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:773
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition ApiBase.php:1378
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:506
getHookRunner()
Get an ApiHookRunner for running core API hooks.
Definition ApiBase.php:719
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:58
getContext()
Get the base IContextSource object.
Service for looking up page revisions.
Represents a title within MediaWiki.
Definition Title.php:82
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:107
const OT_PREPROCESS
Definition Parser.php:142
Service for formatting and validating API parameters.