MediaWiki REL1_39
CoreMagicVariables.php
Go to the documentation of this file.
1<?php
26use Psr\Log\LoggerInterface;
27use Wikimedia\Timestamp\ConvertibleTimestamp;
28
36 private const MAX_TTS = 900;
37
51 public static function expand(
52 // Fundamental options
53 Parser $parser,
54 string $id,
55 // Context passed over from the parser
56 ConvertibleTimestamp $ts,
57 NamespaceInfo $nsInfo,
58 ServiceOptions $svcOptions,
59 LoggerInterface $logger
60 ): ?string {
61 $pageLang = $parser->getFunctionLang();
62 $title = $parser->getTitle();
63
64 switch ( $id ) {
65 case '!':
66 return '|';
67 case '=':
68 return '=';
69 case 'currentmonth':
70 return $pageLang->formatNumNoSeparators( $ts->format( 'm' ) );
71 case 'currentmonth1':
72 return $pageLang->formatNumNoSeparators( $ts->format( 'n' ) );
73 case 'currentmonthname':
74 return $pageLang->getMonthName( (int)$ts->format( 'n' ) );
75 case 'currentmonthnamegen':
76 return $pageLang->getMonthNameGen( (int)$ts->format( 'n' ) );
77 case 'currentmonthabbrev':
78 return $pageLang->getMonthAbbreviation( (int)$ts->format( 'n' ) );
79 case 'currentday':
80 return $pageLang->formatNumNoSeparators( $ts->format( 'j' ) );
81 case 'currentday2':
82 return $pageLang->formatNumNoSeparators( $ts->format( 'd' ) );
83 case 'localmonth':
84 return $pageLang->formatNumNoSeparators( self::makeTsLocal( $svcOptions, $ts )->format( 'm' ) );
85 case 'localmonth1':
86 return $pageLang->formatNumNoSeparators( self::makeTsLocal( $svcOptions, $ts )->format( 'n' ) );
87 case 'localmonthname':
88 return $pageLang->getMonthName( (int)self::makeTsLocal( $svcOptions, $ts )->format( 'n' ) );
89 case 'localmonthnamegen':
90 return $pageLang->getMonthNameGen( (int)self::makeTsLocal( $svcOptions, $ts )->format( 'n' ) );
91 case 'localmonthabbrev':
92 return $pageLang->getMonthAbbreviation( (int)self::makeTsLocal( $svcOptions, $ts )->format( 'n' ) );
93 case 'localday':
94 return $pageLang->formatNumNoSeparators( self::makeTsLocal( $svcOptions, $ts )->format( 'j' ) );
95 case 'localday2':
96 return $pageLang->formatNumNoSeparators( self::makeTsLocal( $svcOptions, $ts )->format( 'd' ) );
97 case 'pagename':
98 return wfEscapeWikiText( $title->getText() );
99 case 'pagenamee':
100 return wfEscapeWikiText( $title->getPartialURL() );
101 case 'fullpagename':
102 return wfEscapeWikiText( $title->getPrefixedText() );
103 case 'fullpagenamee':
104 return wfEscapeWikiText( $title->getPrefixedURL() );
105 case 'subpagename':
106 return wfEscapeWikiText( $title->getSubpageText() );
107 case 'subpagenamee':
108 return wfEscapeWikiText( $title->getSubpageUrlForm() );
109 case 'rootpagename':
110 return wfEscapeWikiText( $title->getRootText() );
111 case 'rootpagenamee':
112 return wfEscapeWikiText( wfUrlencode( str_replace(
113 ' ',
114 '_',
115 $title->getRootText()
116 ) ) );
117 case 'basepagename':
118 return wfEscapeWikiText( $title->getBaseText() );
119 case 'basepagenamee':
120 return wfEscapeWikiText( wfUrlencode( str_replace(
121 ' ',
122 '_',
123 $title->getBaseText()
124 ) ) );
125 case 'talkpagename':
126 if ( $title->canHaveTalkPage() ) {
127 $talkPage = $title->getTalkPage();
128 return wfEscapeWikiText( $talkPage->getPrefixedText() );
129 }
130 return '';
131 case 'talkpagenamee':
132 if ( $title->canHaveTalkPage() ) {
133 $talkPage = $title->getTalkPage();
134 return wfEscapeWikiText( $talkPage->getPrefixedURL() );
135 }
136 return '';
137 case 'subjectpagename':
138 $subjPage = $title->getSubjectPage();
139 return wfEscapeWikiText( $subjPage->getPrefixedText() );
140 case 'subjectpagenamee':
141 $subjPage = $title->getSubjectPage();
142 return wfEscapeWikiText( $subjPage->getPrefixedURL() );
143 case 'pageid': // requested in T25427
144 // Inform the edit saving system that getting the canonical output
145 // after page insertion requires a parse that used that exact page ID
146 self::setOutputFlag( $parser, $logger, ParserOutputFlags::VARY_PAGE_ID, '{{PAGEID}} used' );
147 $value = $title->getArticleID();
148 if ( !$value ) {
149 $value = $parser->getOptions()->getSpeculativePageId();
150 if ( $value ) {
151 $parser->getOutput()->setSpeculativePageIdUsed( $value );
152 }
153 }
154 return (string)$value;
155 case 'revisionid':
156 $namespace = $title->getNamespace();
157 if (
158 $svcOptions->get( MainConfigNames::MiserMode ) &&
159 !$parser->getOptions()->getInterfaceMessage() &&
160 // @TODO: disallow this variable on all namespaces
161 $nsInfo->isSubject( $namespace )
162 ) {
163 // Use a stub result instead of the actual revision ID in order to avoid
164 // double parses on page save but still allow preview detection (T137900)
165 if ( $parser->getRevisionId() || $parser->getOptions()->getSpeculativeRevId() ) {
166 return '-';
167 } else {
168 self::setOutputFlag(
169 $parser,
170 $logger,
171 ParserOutputFlags::VARY_REVISION_EXISTS,
172 '{{REVISIONID}} used'
173 );
174 return '';
175 }
176 } else {
177 // Inform the edit saving system that getting the canonical output after
178 // revision insertion requires a parse that used that exact revision ID
179 self::setOutputFlag( $parser, $logger, ParserOutputFlags::VARY_REVISION_ID, '{{REVISIONID}} used' );
180 $value = $parser->getRevisionId();
181 if ( $value === 0 ) {
182 $rev = $parser->getRevisionRecordObject();
183 $value = $rev ? $rev->getId() : $value;
184 }
185 if ( !$value ) {
186 $value = $parser->getOptions()->getSpeculativeRevId();
187 if ( $value ) {
188 $parser->getOutput()->setSpeculativeRevIdUsed( $value );
189 }
190 }
191 return (string)$value;
192 }
193 case 'revisionday':
194 return strval( (int)self::getRevisionTimestampSubstring(
195 $parser, $logger, 6, 2, self::MAX_TTS, $id
196 ) );
197 case 'revisionday2':
198 return self::getRevisionTimestampSubstring(
199 $parser, $logger, 6, 2, self::MAX_TTS, $id
200 );
201 case 'revisionmonth':
202 return self::getRevisionTimestampSubstring(
203 $parser, $logger, 4, 2, self::MAX_TTS, $id
204 );
205 case 'revisionmonth1':
206 return strval( (int)self::getRevisionTimestampSubstring(
207 $parser, $logger, 4, 2, self::MAX_TTS, $id
208 ) );
209 case 'revisionyear':
210 return self::getRevisionTimestampSubstring(
211 $parser, $logger, 0, 4, self::MAX_TTS, $id
212 );
213 case 'revisiontimestamp':
214 return self::getRevisionTimestampSubstring(
215 $parser, $logger, 0, 14, self::MAX_TTS, $id
216 );
217 case 'revisionuser':
218 // Inform the edit saving system that getting the canonical output after
219 // revision insertion requires a parse that used the actual user ID
220 self::setOutputFlag( $parser, $logger, ParserOutputFlags::VARY_USER, '{{REVISIONUSER}} used' );
221 // Note that getRevisionUser() can return null; we need to
222 // be sure to cast this to (an empty) string, since 'null'
223 // means "magic variable not handled here".
224 return (string)$parser->getRevisionUser();
225 case 'revisionsize':
226 return (string)$parser->getRevisionSize();
227 case 'namespace':
228 return str_replace( '_', ' ',
229 $parser->getContentLanguage()->getNsText( $title->getNamespace() ) );
230 case 'namespacee':
231 return wfUrlencode( $parser->getContentLanguage()->getNsText( $title->getNamespace() ) );
232 case 'namespacenumber':
233 return (string)$title->getNamespace();
234 case 'talkspace':
235 return $title->canHaveTalkPage()
236 ? str_replace( '_', ' ', $title->getTalkNsText() )
237 : '';
238 case 'talkspacee':
239 return $title->canHaveTalkPage()
240 ? wfUrlencode( $title->getTalkNsText() )
241 : '';
242 case 'subjectspace':
243 return str_replace( '_', ' ', $title->getSubjectNsText() );
244 case 'subjectspacee':
245 return ( wfUrlencode( $title->getSubjectNsText() ) );
246 case 'currentdayname':
247 return $pageLang->getWeekdayName( (int)$ts->format( 'w' ) + 1 );
248 case 'currentyear':
249 return $pageLang->formatNumNoSeparators( $ts->format( 'Y' ) );
250 case 'currenttime':
251 return $pageLang->time( $ts->getTimestamp( TS_MW ), false, false );
252 case 'currenthour':
253 return $pageLang->formatNumNoSeparators( $ts->format( 'H' ) );
254 case 'currentweek':
255 // @bug T6594 PHP5 has it zero padded, PHP4 does not, cast to
256 // int to remove the padding
257 return $pageLang->formatNum( (int)$ts->format( 'W' ) );
258 case 'currentdow':
259 return $pageLang->formatNum( $ts->format( 'w' ) );
260 case 'localdayname':
261 return $pageLang->getWeekdayName(
262 (int)self::makeTsLocal( $svcOptions, $ts )->format( 'w' ) + 1
263 );
264 case 'localyear':
265 return $pageLang->formatNumNoSeparators( self::makeTsLocal( $svcOptions, $ts )->format( 'Y' ) );
266 case 'localtime':
267 return $pageLang->time(
268 self::makeTsLocal( $svcOptions, $ts )->format( 'YmdHis' ),
269 false,
270 false
271 );
272 case 'localhour':
273 return $pageLang->formatNumNoSeparators( self::makeTsLocal( $svcOptions, $ts )->format( 'H' ) );
274 case 'localweek':
275 // @bug T6594 PHP5 has it zero padded, PHP4 does not, cast to
276 // int to remove the padding
277 return $pageLang->formatNum( (int)self::makeTsLocal( $svcOptions, $ts )->format( 'W' ) );
278 case 'localdow':
279 return $pageLang->formatNum( self::makeTsLocal( $svcOptions, $ts )->format( 'w' ) );
280 case 'numberofarticles':
281 return $pageLang->formatNum( SiteStats::articles() );
282 case 'numberoffiles':
283 return $pageLang->formatNum( SiteStats::images() );
284 case 'numberofusers':
285 return $pageLang->formatNum( SiteStats::users() );
286 case 'numberofactiveusers':
287 return $pageLang->formatNum( SiteStats::activeUsers() );
288 case 'numberofpages':
289 return $pageLang->formatNum( SiteStats::pages() );
290 case 'numberofadmins':
291 return $pageLang->formatNum( SiteStats::numberingroup( 'sysop' ) );
292 case 'numberofedits':
293 return $pageLang->formatNum( SiteStats::edits() );
294 case 'currenttimestamp':
295 return $ts->getTimestamp( TS_MW );
296 case 'localtimestamp':
297 return self::makeTsLocal( $svcOptions, $ts )->format( 'YmdHis' );
298 case 'currentversion':
300 case 'articlepath':
301 return (string)$svcOptions->get( MainConfigNames::ArticlePath );
302 case 'sitename':
303 return (string)$svcOptions->get( MainConfigNames::Sitename );
304 case 'server':
305 return (string)$svcOptions->get( MainConfigNames::Server );
306 case 'servername':
307 return (string)$svcOptions->get( MainConfigNames::ServerName );
308 case 'scriptpath':
309 return (string)$svcOptions->get( MainConfigNames::ScriptPath );
310 case 'stylepath':
311 return (string)$svcOptions->get( MainConfigNames::StylePath );
312 case 'directionmark':
313 return $pageLang->getDirMark();
314 case 'contentlanguage':
315 return $parser->getContentLanguage()->getCode();
316 case 'pagelanguage':
317 return $pageLang->getCode();
318 case 'cascadingsources':
319 return CoreParserFunctions::cascadingsources( $parser );
320 default:
321 // This is not one of the core magic variables
322 return null;
323 }
324 }
325
333 private static function makeTsLocal( $svcOptions, $ts ) {
334 $localtimezone = $svcOptions->get( MainConfigNames::Localtimezone );
335 $ts->setTimezone( $localtimezone );
336 return $ts;
337 }
338
348 private static function getRevisionTimestampSubstring(
349 Parser $parser,
350 LoggerInterface $logger,
351 int $start,
352 int $len,
353 int $mtts,
354 string $variable
355 ): string {
356 // Get the timezone-adjusted timestamp to be used for this revision
357 $resNow = substr( $parser->getRevisionTimestamp(), $start, $len );
358 // Possibly set vary-revision if there is not yet an associated revision
359 if ( !$parser->getRevisionRecordObject() ) {
360 // Get the timezone-adjusted timestamp $mtts seconds in the future.
361 // This future is relative to the current time and not that of the
362 // parser options. The rendered timestamp can be compared to that
363 // of the timestamp specified by the parser options.
364 $resThen = substr(
365 $parser->getContentLanguage()->userAdjust( wfTimestamp( TS_MW, time() + $mtts ), '' ),
366 $start,
367 $len
368 );
369
370 if ( $resNow !== $resThen ) {
371 // Inform the edit saving system that getting the canonical output after
372 // revision insertion requires a parse that used an actual revision timestamp
373 self::setOutputFlag( $parser, $logger, ParserOutputFlags::VARY_REVISION_TIMESTAMP, "$variable used" );
374 }
375 }
376
377 return $resNow;
378 }
379
388 private static function setOutputFlag(
389 Parser $parser,
390 LoggerInterface $logger,
391 string $flag,
392 string $reason
393 ): void {
394 $parser->getOutput()->setOutputFlag( $flag );
395 $name = $parser->getTitle()->getPrefixedText();
396 // This code was moved from Parser::setOutputFlag and used __METHOD__
397 // originally; we've hard-coded that output here so that our refactor
398 // doesn't change the messages in the logs.
399 $logger->debug( "Parser::setOutputFlag: set $flag flag on '$name'; $reason" );
400 }
401}
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Expansions of core magic variables, used by the parser.
static expand(Parser $parser, string $id, ConvertibleTimestamp $ts, NamespaceInfo $nsInfo, ServiceOptions $svcOptions, LoggerInterface $logger)
Expand the magic variable given by $index.
A class for passing options to services.
A class containing constants representing the names of configuration variables.
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
isSubject( $index)
Is the given namespace is a subject (non-talk) namespace?
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:96
getOptions()
Definition Parser.php:1126
getRevisionUser()
Get the name of the user that edited the last revision.
Definition Parser.php:6106
getRevisionSize()
Get the size of the revision.
Definition Parser.php:6130
getTitle()
Definition Parser.php:1037
getContentLanguage()
Get the content language that this Parser is using.
Definition Parser.php:1248
getOutput()
Definition Parser.php:1118
getRevisionId()
Get the ID of the revision we are parsing.
Definition Parser.php:6013
getRevisionRecordObject()
Get the revision record object for $this->mRevisionId.
Definition Parser.php:6023
static articles()
static images()
static edits()
Definition SiteStats.php:95
static users()
static pages()
static numberingroup( $group)
Find the number of users in a given user group.
static activeUsers()
static getVersion( $flags='', $lang=null)
Return a string of the MediaWiki version with Git revision if available.