MediaWiki  REL1_31
MagicWord.php
Go to the documentation of this file.
1 <?php
59 class 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(),
592  StringUtils::escapeRegexReplacement( $replacement ),
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  }
625  return $this->mVariableRegex;
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() {
686  return $this->mCaseSensitive;
687  }
688 
692  public function getId() {
693  return $this->mId;
694  }
695 }
MagicWordArray
Class for handling an array of magic words.
Definition: MagicWordArray.php:31
array
the array() calling protocol came about after MediaWiki 1.4rc1.
MagicWord\substituteCallback
substituteCallback( $text, $callback)
Variable handling: {{SUBST:xxx}} style words Calls back a function to determine what to replace xxx w...
Definition: MagicWord.php:610
MagicWord\matchVariableStartToEnd
matchVariableStartToEnd( $text)
Returns NULL if there's no match, the value of $1 otherwise The return code is the matched string,...
Definition: MagicWord.php:515
MagicWord\__construct
__construct( $id=null, $syn=[], $cs=false)
#-
Definition: MagicWord.php:264
MagicWord\getSynonyms
getSynonyms()
Definition: MagicWord.php:654
MagicWord\$mVariableIDsInitialised
static bool $mVariableIDsInitialised
Definition: MagicWord.php:96
MagicWord\load
load( $id)
Initialises this object with an ID.
Definition: MagicWord.php:349
MagicWord\isCaseSensitive
isCaseSensitive()
Definition: MagicWord.php:685
MagicWord\getRegexStartToEnd
getRegexStartToEnd()
Gets a regex matching the word from start to end of a string.
Definition: MagicWord.php:452
MagicWord\$mRegex
string $mRegex
Definition: MagicWord.php:72
StringUtils\escapeRegexReplacement
static escapeRegexReplacement( $string)
Escape a string to make it suitable for inclusion in a preg_replace() replacement parameter.
Definition: StringUtils.php:310
MagicWord\getRegex
getRegex()
Gets a regex representing matching the word.
Definition: MagicWord.php:412
MagicWord\$mRegexStartToEnd
string $mRegexStartToEnd
Definition: MagicWord.php:78
$res
$res
Definition: database.txt:21
MagicWord\getId
getId()
Definition: MagicWord.php:692
MagicWord\$mBaseRegex
string $mBaseRegex
Definition: MagicWord.php:81
MagicWord\$mSubstIDs
static string[] $mSubstIDs
Definition: MagicWord.php:242
php
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
MagicWord\$mSynonyms
string[] $mSynonyms
Definition: MagicWord.php:66
MagicWord\initRegex
initRegex()
Preliminary initialisation.
Definition: MagicWord.php:363
MagicWord\replace
replace( $replacement, $subject, $limit=-1)
Replaces the word with something else.
Definition: MagicWord.php:589
MagicWord\matchStartToEnd
matchStartToEnd( $text)
Returns true if the text matched the word.
Definition: MagicWord.php:501
MagicWord\getVariableIDs
static getVariableIDs()
Get an array of parser variable IDs.
Definition: MagicWord.php:291
MagicWord\$mId
string $mId
#-
Definition: MagicWord.php:63
MWException
MediaWiki exception.
Definition: MWException.php:26
MagicWord\getCacheTTL
static getCacheTTL( $id)
Allow external reads of TTL array.
Definition: MagicWord.php:314
MagicWord\$mCacheTTLs
static array $mCacheTTLs
Array of caching hints for ParserCache [ string => int ].
Definition: MagicWord.php:183
$matches
$matches
Definition: NoLocalSettings.php:24
MagicWord\getWasModified
getWasModified()
Returns true if the last call to replace() or substituteCallback() returned a modified text,...
Definition: MagicWord.php:664
MagicWord\$mVariableStartToEndRegex
string $mVariableStartToEndRegex
Definition: MagicWord.php:87
MagicWord\$mModified
bool $mModified
Definition: MagicWord.php:90
MagicWord\$mFound
bool $mFound
Definition: MagicWord.php:93
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:95
MagicWord\pregRemoveAndRecord
pregRemoveAndRecord()
Used in matchAndRemove()
Definition: MagicWord.php:575
MagicWord
This class encapsulates "magic words" such as "#redirect", NOTOC, etc.
Definition: MagicWord.php:59
MagicWord\getRegexStart
getRegexStart()
Gets a regex matching the word, if it is at the string start.
Definition: MagicWord.php:439
MagicWord\getBaseRegex
getBaseRegex()
regex without the slashes and what not
Definition: MagicWord.php:464
MagicWord\clearCache
static clearCache()
Clear the self::$mObjects variable For use in parser tests.
Definition: MagicWord.php:339
$value
$value
Definition: styleTest.css.php:45
MagicWord\matchStartAndRemove
matchStartAndRemove(&$text)
Definition: MagicWord.php:559
MagicWord\getVariableRegex
getVariableRegex()
Matches the word, where $1 is a wildcard.
Definition: MagicWord.php:621
MagicWord\$mDoubleUnderscoreIDs
static string[] $mDoubleUnderscoreIDs
Definition: MagicWord.php:225
MagicWord\$mCaseSensitive
bool $mCaseSensitive
Definition: MagicWord.php:69
MagicWord\addToArray
addToArray(&$array, $value)
Adds all the synonyms of this MagicWord to an array, to allow quick lookup in a list of magic words.
Definition: MagicWord.php:675
MagicWord\getSubstIDs
static getSubstIDs()
Get an array of parser substitution modifier IDs.
Definition: MagicWord.php:304
MagicWord\$mRegexStart
string $mRegexStart
Definition: MagicWord.php:75
MagicWord\$mVariableRegex
string $mVariableRegex
Definition: MagicWord.php:84
as
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
Definition: distributors.txt:22
MagicWord\matchStart
matchStart( $text)
Returns true if the text starts with the word.
Definition: MagicWord.php:489
MagicWord\$mDoubleUnderscoreArray
static MagicWordArray $mDoubleUnderscoreArray
Definition: MagicWord.php:251
MagicWord\getDoubleUnderscoreArray
static getDoubleUnderscoreArray()
Get a MagicWordArray of double-underscore entities.
Definition: MagicWord.php:327
MagicWord\$mVariableIDs
static string[] $mVariableIDs
Definition: MagicWord.php:99
MagicWord\getRegexCase
getRegexCase()
Gets the regexp case modifier to use, i.e.
Definition: MagicWord.php:426
MagicWord\getVariableStartToEndRegex
getVariableStartToEndRegex()
Matches the entire string, where $1 is a wildcard.
Definition: MagicWord.php:633
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:203
MagicWord\getSynonym
getSynonym( $i)
Accesses the synonym list directly.
Definition: MagicWord.php:647
MagicWord\compareStringLength
compareStringLength( $s1, $s2)
A comparison function that returns -1, 0 or 1 depending on whether the first string is longer,...
Definition: MagicWord.php:395
MagicWord\matchAndRemove
matchAndRemove(&$text)
Returns true if the text matches the word, and alters the input string, removing all instances of the...
Definition: MagicWord.php:544
MagicWord\match
match( $text)
Returns true if the text contains the word.
Definition: MagicWord.php:478
MagicWord\$mObjects
static array $mObjects
[ string => MagicWord ]
Definition: MagicWord.php:248
$wgContLang
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 content language as $wgContLang
Definition: design.txt:57