MediaWiki REL1_41
CoreMagicVariables.php
Go to the documentation of this file.
1<?php
27use Psr\Log\LoggerInterface;
28use Wikimedia\Timestamp\ConvertibleTimestamp;
29
37 private const CACHE_TTL_BY_ID = [
38 'currenttime' => 3600,
39 'localtime' => 3600,
40 'numberofarticles' => 3600,
41 'numberoffiles' => 3600,
42 'numberofedits' => 3600,
43 'numberofusers' => 3600,
44 'numberofactiveusers' => 3600,
45 'numberofpages' => 3600,
46 'currentversion' => 86400,
47 'currenttimestamp' => 3600,
48 'localtimestamp' => 3600,
49 'pagesinnamespace' => 3600,
50 'numberofadmins' => 3600,
51 'numberingroup' => 3600,
52 ];
53
55 private const DEADLINE_DATE_SPEC_BY_UNIT = [
56 'Y' => 'first day of January next year midnight',
57 'M' => 'first day of next month midnight',
58 'D' => 'next day midnight',
59 // Note that this relative datetime specifier does not zero out
60 // minutes/seconds, but we will do so manually in
61 // ::applyUnitTimestampDeadline() when given the unit 'H'
62 'H' => 'next hour'
63 ];
65 private const DEADLINE_TTL_CLOCK_FUDGE = 1;
67 private const DEADLINE_TTL_STAGGER_MAX = 15;
69 private const MIN_DEADLINE_TTL = 15;
70
83 public static function expand(
84 // Fundamental options
85 Parser $parser,
86 string $id,
87 // Context passed over from the parser
88 ConvertibleTimestamp $ts,
89 ServiceOptions $svcOptions,
90 LoggerInterface $logger
91 ): ?string {
92 $pageLang = $parser->getTargetLanguage();
93
94 $cacheTTL = self::CACHE_TTL_BY_ID[$id] ?? -1;
95 if ( $cacheTTL > -1 ) {
96 $parser->getOutput()->updateCacheExpiry( $cacheTTL );
97 }
98
99 switch ( $id ) {
100 case '!':
101 return '|';
102 case '=':
103 return '=';
104 case 'currentmonth':
105 self::applyUnitTimestampDeadline( $parser, $ts, 'M' );
106
107 return $pageLang->formatNumNoSeparators( $ts->format( 'm' ) );
108 case 'currentmonth1':
109 self::applyUnitTimestampDeadline( $parser, $ts, 'M' );
110
111 return $pageLang->formatNumNoSeparators( $ts->format( 'n' ) );
112 case 'currentmonthname':
113 self::applyUnitTimestampDeadline( $parser, $ts, 'M' );
114
115 return $pageLang->getMonthName( (int)$ts->format( 'n' ) );
116 case 'currentmonthnamegen':
117 self::applyUnitTimestampDeadline( $parser, $ts, 'M' );
118
119 return $pageLang->getMonthNameGen( (int)$ts->format( 'n' ) );
120 case 'currentmonthabbrev':
121 self::applyUnitTimestampDeadline( $parser, $ts, 'M' );
122
123 return $pageLang->getMonthAbbreviation( (int)$ts->format( 'n' ) );
124 case 'currentday':
125 self::applyUnitTimestampDeadline( $parser, $ts, 'D' );
126
127 return $pageLang->formatNumNoSeparators( $ts->format( 'j' ) );
128 case 'currentday2':
129 self::applyUnitTimestampDeadline( $parser, $ts, 'D' );
130
131 return $pageLang->formatNumNoSeparators( $ts->format( 'd' ) );
132 case 'localmonth':
133 $localTs = self::makeTsLocal( $svcOptions, $ts );
134 self::applyUnitTimestampDeadline( $parser, $localTs, 'M' );
135
136 return $pageLang->formatNumNoSeparators( $localTs->format( 'm' ) );
137 case 'localmonth1':
138 $localTs = self::makeTsLocal( $svcOptions, $ts );
139 self::applyUnitTimestampDeadline( $parser, $localTs, 'M' );
140
141 return $pageLang->formatNumNoSeparators( $localTs->format( 'n' ) );
142 case 'localmonthname':
143 $localTs = self::makeTsLocal( $svcOptions, $ts );
144 self::applyUnitTimestampDeadline( $parser, $localTs, 'M' );
145
146 return $pageLang->getMonthName( (int)$localTs->format( 'n' ) );
147 case 'localmonthnamegen':
148 $localTs = self::makeTsLocal( $svcOptions, $ts );
149 self::applyUnitTimestampDeadline( $parser, $localTs, 'M' );
150
151 return $pageLang->getMonthNameGen( (int)$localTs->format( 'n' ) );
152 case 'localmonthabbrev':
153 $localTs = self::makeTsLocal( $svcOptions, $ts );
154 self::applyUnitTimestampDeadline( $parser, $localTs, 'M' );
155
156 return $pageLang->getMonthAbbreviation( (int)$localTs->format( 'n' ) );
157 case 'localday':
158 $localTs = self::makeTsLocal( $svcOptions, $ts );
159 self::applyUnitTimestampDeadline( $parser, $localTs, 'D' );
160
161 return $pageLang->formatNumNoSeparators( $localTs->format( 'j' ) );
162 case 'localday2':
163 $localTs = self::makeTsLocal( $svcOptions, $ts );
164 self::applyUnitTimestampDeadline( $parser, $localTs, 'D' );
165
166 return $pageLang->formatNumNoSeparators( $localTs->format( 'd' ) );
167 case 'pagename':
168 case 'pagenamee':
169 case 'fullpagename':
170 case 'fullpagenamee':
171 case 'subpagename':
172 case 'subpagenamee':
173 case 'rootpagename':
174 case 'rootpagenamee':
175 case 'basepagename':
176 case 'basepagenamee':
177 case 'talkpagename':
178 case 'talkpagenamee':
179 case 'subjectpagename':
180 case 'subjectpagenamee':
181 case 'pageid':
182 case 'revisionid':
183 case 'revisionuser':
184 case 'revisionday':
185 case 'revisionday2':
186 case 'revisionmonth':
187 case 'revisionmonth1':
188 case 'revisionyear':
189 case 'revisiontimestamp':
190 case 'namespace':
191 case 'namespacee':
192 case 'namespacenumber':
193 case 'talkspace':
194 case 'talkspacee':
195 case 'subjectspace':
196 case 'subjectspacee':
197 case 'cascadingsources':
198 # First argument of the corresponding parser function
199 # (second argument of the PHP implementation) is
200 # "title".
201
202 # Note that for many of these {{FOO}} is subtly different
203 # from {{FOO:{{PAGENAME}}}}, so we can't pass $title here
204 # we have to explicitly use the "no arguments" form of the
205 # parser function by passing `null` to indicate a missing
206 # argument (which then defaults to the current page title).
207 return CoreParserFunctions::$id( $parser, null );
208 case 'revisionsize':
209 return (string)$parser->getRevisionSize();
210 case 'currentdayname':
211 self::applyUnitTimestampDeadline( $parser, $ts, 'D' );
212
213 return $pageLang->getWeekdayName( (int)$ts->format( 'w' ) + 1 );
214 case 'currentyear':
215 self::applyUnitTimestampDeadline( $parser, $ts, 'Y' );
216
217 return $pageLang->formatNumNoSeparators( $ts->format( 'Y' ) );
218 case 'currenttime':
219 return $pageLang->time( $ts->getTimestamp( TS_MW ), false, false );
220 case 'currenthour':
221 self::applyUnitTimestampDeadline( $parser, $ts, 'H' );
222
223 return $pageLang->formatNumNoSeparators( $ts->format( 'H' ) );
224 case 'currentweek':
225 self::applyUnitTimestampDeadline( $parser, $ts, 'D' );
226 // @bug T6594 PHP5 has it zero padded, PHP4 does not, cast to
227 // int to remove the padding
228 return $pageLang->formatNum( (int)$ts->format( 'W' ) );
229 case 'currentdow':
230 self::applyUnitTimestampDeadline( $parser, $ts, 'D' );
231
232 return $pageLang->formatNum( $ts->format( 'w' ) );
233 case 'localdayname':
234 $localTs = self::makeTsLocal( $svcOptions, $ts );
235 self::applyUnitTimestampDeadline( $parser, $localTs, 'D' );
236
237 return $pageLang->getWeekdayName( (int)$localTs->format( 'w' ) + 1 );
238 case 'localyear':
239 $localTs = self::makeTsLocal( $svcOptions, $ts );
240 self::applyUnitTimestampDeadline( $parser, $localTs, 'Y' );
241
242 return $pageLang->formatNumNoSeparators( $localTs->format( 'Y' ) );
243 case 'localtime':
244 $localTs = self::makeTsLocal( $svcOptions, $ts );
245
246 return $pageLang->time(
247 $localTs->format( 'YmdHis' ),
248 false,
249 false
250 );
251 case 'localhour':
252 $localTs = self::makeTsLocal( $svcOptions, $ts );
253 self::applyUnitTimestampDeadline( $parser, $localTs, 'H' );
254
255 return $pageLang->formatNumNoSeparators( $localTs->format( 'H' ) );
256 case 'localweek':
257 $localTs = self::makeTsLocal( $svcOptions, $ts );
258 self::applyUnitTimestampDeadline( $parser, $localTs, 'D' );
259 // @bug T6594 PHP5 has it zero padded, PHP4 does not, cast to
260 // int to remove the padding
261 return $pageLang->formatNum( (int)$localTs->format( 'W' ) );
262 case 'localdow':
263 $localTs = self::makeTsLocal( $svcOptions, $ts );
264 self::applyUnitTimestampDeadline( $parser, $localTs, 'D' );
265
266 return $pageLang->formatNum( $localTs->format( 'w' ) );
267 case 'numberofarticles':
268 case 'numberoffiles':
269 case 'numberofusers':
270 case 'numberofactiveusers':
271 case 'numberofpages':
272 case 'numberofadmins':
273 case 'numberofedits':
274 # second argument is 'raw'; magic variables are "not raw"
275 return CoreParserFunctions::$id( $parser, null );
276 case 'currenttimestamp':
277 return $ts->getTimestamp( TS_MW );
278 case 'localtimestamp':
279 $localTs = self::makeTsLocal( $svcOptions, $ts );
280
281 return $localTs->format( 'YmdHis' );
282 case 'currentversion':
283 return SpecialVersion::getVersion();
284 case 'articlepath':
285 return (string)$svcOptions->get( MainConfigNames::ArticlePath );
286 case 'sitename':
287 return (string)$svcOptions->get( MainConfigNames::Sitename );
288 case 'server':
289 return (string)$svcOptions->get( MainConfigNames::Server );
290 case 'servername':
291 return (string)$svcOptions->get( MainConfigNames::ServerName );
292 case 'scriptpath':
293 return (string)$svcOptions->get( MainConfigNames::ScriptPath );
294 case 'stylepath':
295 return (string)$svcOptions->get( MainConfigNames::StylePath );
296 case 'directionmark':
297 return $pageLang->getDirMark();
298 case 'contentlanguage':
299 return $parser->getContentLanguage()->getCode();
300 case 'pagelanguage':
301 return $pageLang->getCode();
302 default:
303 // This is not one of the core magic variables
304 return null;
305 }
306 }
307
315 private static function makeTsLocal( $svcOptions, $ts ) {
316 $localtimezone = $svcOptions->get( MainConfigNames::Localtimezone );
317 $ts->setTimezone( $localtimezone );
318 return $ts;
319 }
320
328 private static function applyUnitTimestampDeadline(
329 Parser $parser,
330 ConvertibleTimestamp $ts,
331 string $unit
332 ) {
333 $tsUnix = (int)$ts->getTimestamp( TS_UNIX );
334
335 $date = new DateTime( "@$tsUnix" );
336 $date->setTimezone( $ts->getTimezone() );
337 $date->modify( self::DEADLINE_DATE_SPEC_BY_UNIT[$unit] );
338 if ( $unit === 'H' ) {
339 // Zero out the minutes/seconds
340 $date->setTime( intval( $date->format( 'H' ), 10 ), 0, 0 );
341 } else {
342 $date->setTime( 0, 0, 0 );
343 }
344 $deadlineUnix = (int)$date->format( 'U' );
345
346 $ttl = max( $deadlineUnix - $tsUnix, self::MIN_DEADLINE_TTL );
347 $ttl += self::DEADLINE_TTL_CLOCK_FUDGE;
348 $ttl += ( $deadlineUnix % self::DEADLINE_TTL_STAGGER_MAX );
349
350 $parser->getOutput()->updateCacheExpiry( $ttl );
351 }
352}
Expansions of core magic variables, used by the parser.
static expand(Parser $parser, string $id, ConvertibleTimestamp $ts, 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.
Give information about the version of MediaWiki, PHP, the DB and extensions.
Library for creating and parsing MW-style timestamps.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:115
getRevisionSize()
Get the size of the revision.
Definition Parser.php:6038
getContentLanguage()
Get the content language that this Parser is using.
Definition Parser.php:1189
getOutput()
Definition Parser.php:1051