MediaWiki  master
MagicWord.php
Go to the documentation of this file.
1 <?php
25 
57 class MagicWord {
61  public $mId;
62 
64  public $mSynonyms;
65 
68 
70  private $mRegex = '';
71 
73  private $mRegexStart = '';
74 
76  private $mRegexStartToEnd = '';
77 
79  private $mBaseRegex = '';
80 
82  private $mVariableRegex = '';
83 
86 
88  private $mModified = false;
89 
91  private $mFound = false;
92 
94  private $contLang;
95 
108  public function __construct( $id = null, $syn = [], $cs = false, Language $contLang = null ) {
109  $this->mId = $id;
110  $this->mSynonyms = (array)$syn;
111  $this->mCaseSensitive = $cs;
112  $this->contLang = $contLang ?: MediaWikiServices::getInstance()->getContentLanguage();
113  }
114 
123  public static function get( $id ) {
124  wfDeprecated( __METHOD__, '1.32' );
125  return MediaWikiServices::getInstance()->getMagicWordFactory()->get( $id );
126  }
127 
134  public static function getVariableIDs() {
135  wfDeprecated( __METHOD__, '1.32' );
136  return MediaWikiServices::getInstance()->getMagicWordFactory()->getVariableIDs();
137  }
138 
144  public static function getSubstIDs() {
145  wfDeprecated( __METHOD__, '1.32' );
146  return MediaWikiServices::getInstance()->getMagicWordFactory()->getSubstIDs();
147  }
148 
156  public static function getCacheTTL( $id ) {
157  wfDeprecated( __METHOD__, '1.32' );
158  return MediaWikiServices::getInstance()->getMagicWordFactory()->getCacheTTL( $id );
159  }
160 
167  public static function getDoubleUnderscoreArray() {
168  wfDeprecated( __METHOD__, '1.32' );
169  return MediaWikiServices::getInstance()->getMagicWordFactory()->getDoubleUnderscoreArray();
170  }
171 
178  public function load( $id ) {
179  $this->mId = $id;
180  $this->contLang->getMagic( $this );
181  if ( !$this->mSynonyms ) {
182  $this->mSynonyms = [ 'brionmademeputthishere' ];
183  throw new MWException( "Error: invalid magic word '$id'" );
184  }
185  }
186 
191  public function initRegex() {
192  // Sort the synonyms by length, descending, so that the longest synonym
193  // matches in precedence to the shortest
194  $synonyms = $this->mSynonyms;
195  usort( $synonyms, [ $this, 'compareStringLength' ] );
196 
197  $escSyn = [];
198  foreach ( $synonyms as $synonym ) {
199  // In case a magic word contains /, like that's going to happen;)
200  $escSyn[] = preg_quote( $synonym, '/' );
201  }
202  $this->mBaseRegex = implode( '|', $escSyn );
203 
204  $case = $this->mCaseSensitive ? '' : 'iu';
205  $this->mRegex = "/{$this->mBaseRegex}/{$case}";
206  $this->mRegexStart = "/^(?:{$this->mBaseRegex})/{$case}";
207  $this->mRegexStartToEnd = "/^(?:{$this->mBaseRegex})$/{$case}";
208  $this->mVariableRegex = str_replace( "\\$1", "(.*?)", $this->mRegex );
209  $this->mVariableStartToEndRegex = str_replace( "\\$1", "(.*?)",
210  "/^(?:{$this->mBaseRegex})$/{$case}" );
211  }
212 
223  public function compareStringLength( $s1, $s2 ) {
224  $l1 = strlen( $s1 );
225  $l2 = strlen( $s2 );
226  return $l2 <=> $l1; // descending
227  }
228 
234  public function getRegex() {
235  if ( $this->mRegex == '' ) {
236  $this->initRegex();
237  }
238  return $this->mRegex;
239  }
240 
248  public function getRegexCase() {
249  if ( $this->mRegex === '' ) {
250  $this->initRegex();
251  }
252 
253  return $this->mCaseSensitive ? '' : 'iu';
254  }
255 
261  public function getRegexStart() {
262  if ( $this->mRegex == '' ) {
263  $this->initRegex();
264  }
265  return $this->mRegexStart;
266  }
267 
274  public function getRegexStartToEnd() {
275  if ( $this->mRegexStartToEnd == '' ) {
276  $this->initRegex();
277  }
279  }
280 
286  public function getBaseRegex() {
287  if ( $this->mRegex == '' ) {
288  $this->initRegex();
289  }
290  return $this->mBaseRegex;
291  }
292 
300  public function match( $text ) {
301  return (bool)preg_match( $this->getRegex(), $text );
302  }
303 
311  public function matchStart( $text ) {
312  return (bool)preg_match( $this->getRegexStart(), $text );
313  }
314 
323  public function matchStartToEnd( $text ) {
324  return (bool)preg_match( $this->getRegexStartToEnd(), $text );
325  }
326 
337  public function matchVariableStartToEnd( $text ) {
338  $matches = [];
339  $matchcount = preg_match( $this->getVariableStartToEndRegex(), $text, $matches );
340  if ( $matchcount == 0 ) {
341  return null;
342  } else {
343  # multiple matched parts (variable match); some will be empty because of
344  # synonyms. The variable will be the second non-empty one so remove any
345  # blank elements and re-sort the indices.
346  # See also T8526
347 
348  $matches = array_values( array_filter( $matches ) );
349 
350  if ( count( $matches ) == 1 ) {
351  return $matches[0];
352  } else {
353  return $matches[1];
354  }
355  }
356  }
357 
366  public function matchAndRemove( &$text ) {
367  $this->mFound = false;
368  $text = preg_replace_callback(
369  $this->getRegex(),
370  [ $this, 'pregRemoveAndRecord' ],
371  $text
372  );
373 
374  return $this->mFound;
375  }
376 
381  public function matchStartAndRemove( &$text ) {
382  $this->mFound = false;
383  $text = preg_replace_callback(
384  $this->getRegexStart(),
385  [ $this, 'pregRemoveAndRecord' ],
386  $text
387  );
388 
389  return $this->mFound;
390  }
391 
397  public function pregRemoveAndRecord() {
398  $this->mFound = true;
399  return '';
400  }
401 
411  public function replace( $replacement, $subject, $limit = -1 ) {
412  $res = preg_replace(
413  $this->getRegex(),
414  StringUtils::escapeRegexReplacement( $replacement ),
415  $subject,
416  $limit
417  );
418  $this->mModified = $res !== $subject;
419  return $res;
420  }
421 
432  public function substituteCallback( $text, $callback ) {
433  $res = preg_replace_callback( $this->getVariableRegex(), $callback, $text );
434  $this->mModified = $res !== $text;
435  return $res;
436  }
437 
443  public function getVariableRegex() {
444  if ( $this->mVariableRegex == '' ) {
445  $this->initRegex();
446  }
447  return $this->mVariableRegex;
448  }
449 
455  public function getVariableStartToEndRegex() {
456  if ( $this->mVariableStartToEndRegex == '' ) {
457  $this->initRegex();
458  }
460  }
461 
469  public function getSynonym( $i ) {
470  return $this->mSynonyms[$i];
471  }
472 
476  public function getSynonyms() {
477  return $this->mSynonyms;
478  }
479 
486  public function getWasModified() {
487  return $this->mModified;
488  }
489 
497  public function addToArray( &$array, $value ) {
498  foreach ( $this->mSynonyms as $syn ) {
499  $array[$this->contLang->lc( $syn )] = $value;
500  }
501  }
502 
506  public function isCaseSensitive() {
507  return $this->mCaseSensitive;
508  }
509 
513  public function getId() {
514  return $this->mId;
515  }
516 }
string $mVariableStartToEndRegex
Definition: MagicWord.php:85
static getVariableIDs()
Get an array of parser variable IDs.
Definition: MagicWord.php:134
replace( $replacement, $subject, $limit=-1)
Replaces the word with something else.
Definition: MagicWord.php:411
matchVariableStartToEnd( $text)
Returns NULL if there&#39;s no match, the value of $1 otherwise The return code is the matched string...
Definition: MagicWord.php:337
getRegexStart()
Gets a regex matching the word, if it is at the string start.
Definition: MagicWord.php:261
getRegex()
Gets a regex representing matching the word.
Definition: MagicWord.php:234
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
static escapeRegexReplacement( $string)
Escape a string to make it suitable for inclusion in a preg_replace() replacement parameter...
getBaseRegex()
regex without the slashes and what not
Definition: MagicWord.php:286
$value
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 MediaWikiServices
Definition: injection.txt:23
string [] $mSynonyms
Definition: MagicWord.php:64
string $mRegexStart
Definition: MagicWord.php:73
load( $id)
Initialises this object with an ID.
Definition: MagicWord.php:178
isCaseSensitive()
Definition: MagicWord.php:506
string $mBaseRegex
Definition: MagicWord.php:79
static getDoubleUnderscoreArray()
Get a MagicWordArray of double-underscore entities.
Definition: MagicWord.php:167
string $mId
#-
Definition: MagicWord.php:61
pregRemoveAndRecord()
Used in matchAndRemove()
Definition: MagicWord.php:397
$res
Definition: database.txt:21
Language $contLang
Definition: MagicWord.php:94
match( $text)
Returns true if the text contains the word.
Definition: MagicWord.php:300
string $mRegex
Definition: MagicWord.php:70
getWasModified()
Returns true if the last call to replace() or substituteCallback() returned a modified text...
Definition: MagicWord.php:486
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition: hooks.txt:767
substituteCallback( $text, $callback)
Variable handling: {{SUBST:xxx}} style words Calls back a function to determine what to replace xxx w...
Definition: MagicWord.php:432
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:9
matchStartAndRemove(&$text)
Definition: MagicWord.php:381
getVariableStartToEndRegex()
Matches the entire string, where $1 is a wildcard.
Definition: MagicWord.php:455
static getCacheTTL( $id)
Allow external reads of TTL array.
Definition: MagicWord.php:156
static getSubstIDs()
Get an array of parser substitution modifier IDs.
Definition: MagicWord.php:144
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:35
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:497
__construct( $id=null, $syn=[], $cs=false, Language $contLang=null)
#-
Definition: MagicWord.php:108
string $mRegexStartToEnd
Definition: MagicWord.php:76
matchStartToEnd( $text)
Returns true if the text matched the word.
Definition: MagicWord.php:323
matchStart( $text)
Returns true if the text starts with the word.
Definition: MagicWord.php:311
bool $mFound
Definition: MagicWord.php:91
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
getRegexCase()
Gets the regexp case modifier to use, i.e.
Definition: MagicWord.php:248
initRegex()
Preliminary initialisation.
Definition: MagicWord.php:191
getVariableRegex()
Matches the word, where $1 is a wildcard.
Definition: MagicWord.php:443
bool $mCaseSensitive
Definition: MagicWord.php:67
matchAndRemove(&$text)
Returns true if the text matches the word, and alters the input string, removing all instances of the...
Definition: MagicWord.php:366
compareStringLength( $s1, $s2)
A comparison function that returns -1, 0 or 1 depending on whether the first string is longer...
Definition: MagicWord.php:223
getSynonym( $i)
Accesses the synonym list directly.
Definition: MagicWord.php:469
string $mVariableRegex
Definition: MagicWord.php:82
getRegexStartToEnd()
Gets a regex matching the word from start to end of a string.
Definition: MagicWord.php:274
bool $mModified
Definition: MagicWord.php:88
This class encapsulates "magic words" such as "#redirect", NOTOC, etc.
Definition: MagicWord.php:57
$matches