MediaWiki REL1_31
MagicWord.php
Go to the documentation of this file.
1<?php
59class MagicWord {
63 public $mId;
64
66 public $mSynonyms;
67
70
72 private $mRegex = '';
73
75 private $mRegexStart = '';
76
78 private $mRegexStartToEnd = '';
79
81 private $mBaseRegex = '';
82
84 private $mVariableRegex = '';
85
88
90 private $mModified = false;
91
93 private $mFound = false;
94
96 public static $mVariableIDsInitialised = false;
97
99 public static $mVariableIDs = [
100 '!',
101 'currentmonth',
102 'currentmonth1',
103 'currentmonthname',
104 'currentmonthnamegen',
105 'currentmonthabbrev',
106 'currentday',
107 'currentday2',
108 'currentdayname',
109 'currentyear',
110 'currenttime',
111 'currenthour',
112 'localmonth',
113 'localmonth1',
114 'localmonthname',
115 'localmonthnamegen',
116 'localmonthabbrev',
117 'localday',
118 'localday2',
119 'localdayname',
120 'localyear',
121 'localtime',
122 'localhour',
123 'numberofarticles',
124 'numberoffiles',
125 'numberofedits',
126 'articlepath',
127 'pageid',
128 'sitename',
129 'server',
130 'servername',
131 'scriptpath',
132 'stylepath',
133 'pagename',
134 'pagenamee',
135 'fullpagename',
136 'fullpagenamee',
137 'namespace',
138 'namespacee',
139 'namespacenumber',
140 'currentweek',
141 'currentdow',
142 'localweek',
143 'localdow',
144 'revisionid',
145 'revisionday',
146 'revisionday2',
147 'revisionmonth',
148 'revisionmonth1',
149 'revisionyear',
150 'revisiontimestamp',
151 'revisionuser',
152 'revisionsize',
153 'subpagename',
154 'subpagenamee',
155 'talkspace',
156 'talkspacee',
157 'subjectspace',
158 'subjectspacee',
159 'talkpagename',
160 'talkpagenamee',
161 'subjectpagename',
162 'subjectpagenamee',
163 'numberofusers',
164 'numberofactiveusers',
165 'numberofpages',
166 'currentversion',
167 'rootpagename',
168 'rootpagenamee',
169 'basepagename',
170 'basepagenamee',
171 'currenttimestamp',
172 'localtimestamp',
173 'directionmark',
174 'contentlanguage',
175 'pagelanguage',
176 'numberofadmins',
177 'cascadingsources',
178 ];
179
183 public static $mCacheTTLs = [
184 'currentmonth' => 86400,
185 'currentmonth1' => 86400,
186 'currentmonthname' => 86400,
187 'currentmonthnamegen' => 86400,
188 'currentmonthabbrev' => 86400,
189 'currentday' => 3600,
190 'currentday2' => 3600,
191 'currentdayname' => 3600,
192 'currentyear' => 86400,
193 'currenttime' => 3600,
194 'currenthour' => 3600,
195 'localmonth' => 86400,
196 'localmonth1' => 86400,
197 'localmonthname' => 86400,
198 'localmonthnamegen' => 86400,
199 'localmonthabbrev' => 86400,
200 'localday' => 3600,
201 'localday2' => 3600,
202 'localdayname' => 3600,
203 'localyear' => 86400,
204 'localtime' => 3600,
205 'localhour' => 3600,
206 'numberofarticles' => 3600,
207 'numberoffiles' => 3600,
208 'numberofedits' => 3600,
209 'currentweek' => 3600,
210 'currentdow' => 3600,
211 'localweek' => 3600,
212 'localdow' => 3600,
213 'numberofusers' => 3600,
214 'numberofactiveusers' => 3600,
215 'numberofpages' => 3600,
216 'currentversion' => 86400,
217 'currenttimestamp' => 3600,
218 'localtimestamp' => 3600,
219 'pagesinnamespace' => 3600,
220 'numberofadmins' => 3600,
221 'numberingroup' => 3600,
222 ];
223
225 public static $mDoubleUnderscoreIDs = [
226 'notoc',
227 'nogallery',
228 'forcetoc',
229 'toc',
230 'noeditsection',
231 'newsectionlink',
232 'nonewsectionlink',
233 'hiddencat',
234 'index',
235 'noindex',
236 'staticredirect',
237 'notitleconvert',
238 'nocontentconvert',
239 ];
240
242 public static $mSubstIDs = [
243 'subst',
244 'safesubst',
245 ];
246
248 public static $mObjects = [];
249
251 public static $mDoubleUnderscoreArray = null;
252
264 public function __construct( $id = null, $syn = [], $cs = false ) {
265 $this->mId = $id;
266 $this->mSynonyms = (array)$syn;
267 $this->mCaseSensitive = $cs;
268 }
269
277 public static function &get( $id ) {
278 if ( !isset( self::$mObjects[$id] ) ) {
279 $mw = new MagicWord();
280 $mw->load( $id );
281 self::$mObjects[$id] = $mw;
282 }
283 return self::$mObjects[$id];
284 }
285
291 public static function getVariableIDs() {
292 if ( !self::$mVariableIDsInitialised ) {
293 # Get variable IDs
294 Hooks::run( 'MagicWordwgVariableIDs', [ &self::$mVariableIDs ] );
295 self::$mVariableIDsInitialised = true;
296 }
297 return self::$mVariableIDs;
298 }
299
304 public static function getSubstIDs() {
305 return self::$mSubstIDs;
306 }
307
314 public static function getCacheTTL( $id ) {
315 if ( array_key_exists( $id, self::$mCacheTTLs ) ) {
316 return self::$mCacheTTLs[$id];
317 } else {
318 return -1;
319 }
320 }
321
327 public static function getDoubleUnderscoreArray() {
328 if ( is_null( self::$mDoubleUnderscoreArray ) ) {
329 Hooks::run( 'GetDoubleUnderscoreIDs', [ &self::$mDoubleUnderscoreIDs ] );
330 self::$mDoubleUnderscoreArray = new MagicWordArray( self::$mDoubleUnderscoreIDs );
331 }
333 }
334
339 public static function clearCache() {
340 self::$mObjects = [];
341 }
342
349 public function load( $id ) {
351 $this->mId = $id;
352 $wgContLang->getMagic( $this );
353 if ( !$this->mSynonyms ) {
354 $this->mSynonyms = [ 'brionmademeputthishere' ];
355 throw new MWException( "Error: invalid magic word '$id'" );
356 }
357 }
358
363 public function initRegex() {
364 // Sort the synonyms by length, descending, so that the longest synonym
365 // matches in precedence to the shortest
366 $synonyms = $this->mSynonyms;
367 usort( $synonyms, [ $this, 'compareStringLength' ] );
368
369 $escSyn = [];
370 foreach ( $synonyms as $synonym ) {
371 // In case a magic word contains /, like that's going to happen;)
372 $escSyn[] = preg_quote( $synonym, '/' );
373 }
374 $this->mBaseRegex = implode( '|', $escSyn );
375
376 $case = $this->mCaseSensitive ? '' : 'iu';
377 $this->mRegex = "/{$this->mBaseRegex}/{$case}";
378 $this->mRegexStart = "/^(?:{$this->mBaseRegex})/{$case}";
379 $this->mRegexStartToEnd = "/^(?:{$this->mBaseRegex})$/{$case}";
380 $this->mVariableRegex = str_replace( "\\$1", "(.*?)", $this->mRegex );
381 $this->mVariableStartToEndRegex = str_replace( "\\$1", "(.*?)",
382 "/^(?:{$this->mBaseRegex})$/{$case}" );
383 }
384
395 public function compareStringLength( $s1, $s2 ) {
396 $l1 = strlen( $s1 );
397 $l2 = strlen( $s2 );
398 if ( $l1 < $l2 ) {
399 return 1;
400 } elseif ( $l1 > $l2 ) {
401 return -1;
402 } else {
403 return 0;
404 }
405 }
406
412 public function getRegex() {
413 if ( $this->mRegex == '' ) {
414 $this->initRegex();
415 }
416 return $this->mRegex;
417 }
418
426 public function getRegexCase() {
427 if ( $this->mRegex === '' ) {
428 $this->initRegex();
429 }
430
431 return $this->mCaseSensitive ? '' : 'iu';
432 }
433
439 public function getRegexStart() {
440 if ( $this->mRegex == '' ) {
441 $this->initRegex();
442 }
443 return $this->mRegexStart;
444 }
445
452 public function getRegexStartToEnd() {
453 if ( $this->mRegexStartToEnd == '' ) {
454 $this->initRegex();
455 }
457 }
458
464 public function getBaseRegex() {
465 if ( $this->mRegex == '' ) {
466 $this->initRegex();
467 }
468 return $this->mBaseRegex;
469 }
470
478 public function match( $text ) {
479 return (bool)preg_match( $this->getRegex(), $text );
480 }
481
489 public function matchStart( $text ) {
490 return (bool)preg_match( $this->getRegexStart(), $text );
491 }
492
501 public function matchStartToEnd( $text ) {
502 return (bool)preg_match( $this->getRegexStartToEnd(), $text );
503 }
504
515 public function matchVariableStartToEnd( $text ) {
516 $matches = [];
517 $matchcount = preg_match( $this->getVariableStartToEndRegex(), $text, $matches );
518 if ( $matchcount == 0 ) {
519 return null;
520 } else {
521 # multiple matched parts (variable match); some will be empty because of
522 # synonyms. The variable will be the second non-empty one so remove any
523 # blank elements and re-sort the indices.
524 # See also T8526
525
526 $matches = array_values( array_filter( $matches ) );
527
528 if ( count( $matches ) == 1 ) {
529 return $matches[0];
530 } else {
531 return $matches[1];
532 }
533 }
534 }
535
544 public function matchAndRemove( &$text ) {
545 $this->mFound = false;
546 $text = preg_replace_callback(
547 $this->getRegex(),
548 [ $this, 'pregRemoveAndRecord' ],
549 $text
550 );
551
552 return $this->mFound;
553 }
554
559 public function matchStartAndRemove( &$text ) {
560 $this->mFound = false;
561 $text = preg_replace_callback(
562 $this->getRegexStart(),
563 [ $this, 'pregRemoveAndRecord' ],
564 $text
565 );
566
567 return $this->mFound;
568 }
569
575 public function pregRemoveAndRecord() {
576 $this->mFound = true;
577 return '';
578 }
579
589 public function replace( $replacement, $subject, $limit = -1 ) {
590 $res = preg_replace(
591 $this->getRegex(),
593 $subject,
594 $limit
595 );
596 $this->mModified = $res !== $subject;
597 return $res;
598 }
599
610 public function substituteCallback( $text, $callback ) {
611 $res = preg_replace_callback( $this->getVariableRegex(), $callback, $text );
612 $this->mModified = $res !== $text;
613 return $res;
614 }
615
621 public function getVariableRegex() {
622 if ( $this->mVariableRegex == '' ) {
623 $this->initRegex();
624 }
626 }
627
633 public function getVariableStartToEndRegex() {
634 if ( $this->mVariableStartToEndRegex == '' ) {
635 $this->initRegex();
636 }
638 }
639
647 public function getSynonym( $i ) {
648 return $this->mSynonyms[$i];
649 }
650
654 public function getSynonyms() {
655 return $this->mSynonyms;
656 }
657
664 public function getWasModified() {
665 return $this->mModified;
666 }
667
675 public function addToArray( &$array, $value ) {
677 foreach ( $this->mSynonyms as $syn ) {
678 $array[$wgContLang->lc( $syn )] = $value;
679 }
680 }
681
685 public function isCaseSensitive() {
687 }
688
692 public function getId() {
693 return $this->mId;
694 }
695}
MediaWiki exception.
Class for handling an array of magic words.
This class encapsulates "magic words" such as "#redirect", NOTOC, etc.
Definition MagicWord.php:59
getVariableRegex()
Matches the word, where $1 is a wildcard.
compareStringLength( $s1, $s2)
A comparison function that returns -1, 0 or 1 depending on whether the first string is longer,...
initRegex()
Preliminary initialisation.
getWasModified()
Returns true if the last call to replace() or substituteCallback() returned a modified text,...
static array $mCacheTTLs
Array of caching hints for ParserCache [ string => int ].
static string[] $mDoubleUnderscoreIDs
string $mBaseRegex
Definition MagicWord.php:81
replace( $replacement, $subject, $limit=-1)
Replaces the word with something else.
getVariableStartToEndRegex()
Matches the entire string, where $1 is a wildcard.
static string[] $mVariableIDs
Definition MagicWord.php:99
static bool $mVariableIDsInitialised
Definition MagicWord.php:96
getRegexStartToEnd()
Gets a regex matching the word from start to end of a string.
static array $mObjects
[ string => MagicWord ]
static clearCache()
Clear the self::$mObjects variable For use in parser tests.
bool $mCaseSensitive
Definition MagicWord.php:69
bool $mModified
Definition MagicWord.php:90
isCaseSensitive()
string $mRegexStartToEnd
Definition MagicWord.php:78
substituteCallback( $text, $callback)
Variable handling: {{SUBST:xxx}} style words Calls back a function to determine what to replace xxx w...
__construct( $id=null, $syn=[], $cs=false)
#-
string $mRegex
Definition MagicWord.php:72
getBaseRegex()
regex without the slashes and what not
string $mVariableRegex
Definition MagicWord.php:84
static getCacheTTL( $id)
Allow external reads of TTL array.
matchStartAndRemove(&$text)
static getVariableIDs()
Get an array of parser variable IDs.
getRegexStart()
Gets a regex matching the word, if it is at the string start.
string[] $mSynonyms
Definition MagicWord.php:66
matchStart( $text)
Returns true if the text starts with the word.
getSynonym( $i)
Accesses the synonym list directly.
static MagicWordArray $mDoubleUnderscoreArray
getRegex()
Gets a regex representing matching the word.
load( $id)
Initialises this object with an ID.
matchVariableStartToEnd( $text)
Returns NULL if there's no match, the value of $1 otherwise The return code is the matched string,...
getRegexCase()
Gets the regexp case modifier to use, i.e.
static string[] $mSubstIDs
bool $mFound
Definition MagicWord.php:93
addToArray(&$array, $value)
Adds all the synonyms of this MagicWord to an array, to allow quick lookup in a list of magic words.
matchStartToEnd( $text)
Returns true if the text matched the word.
string $mVariableStartToEndRegex
Definition MagicWord.php:87
string $mId
#-
Definition MagicWord.php:63
static getDoubleUnderscoreArray()
Get a MagicWordArray of double-underscore entities.
match( $text)
Returns true if the text contains the word.
static getSubstIDs()
Get an array of parser substitution modifier IDs.
pregRemoveAndRecord()
Used in matchAndRemove()
string $mRegexStart
Definition MagicWord.php:75
matchAndRemove(&$text)
Returns true if the text matches the word, and alters the input string, removing all instances of the...
static escapeRegexReplacement( $string)
Escape a string to make it suitable for inclusion in a preg_replace() replacement parameter.
$res
Definition database.txt:21
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the local content language as $wgContLang
Definition design.txt:57
when a variable name is used in a it is silently declared as a new local masking the global
Definition design.txt:95
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
the array() calling protocol came about after MediaWiki 1.4rc1.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition injection.txt:37