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 ) {
350 global $wgContLang;
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 ) {
676 global $wgContLang;
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
the array() calling protocol came about after MediaWiki 1.4rc1.