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
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
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
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
substituteCallback( $text, $callback)
Variable handling: {{SUBST:xxx}} style words Calls back a function to determine what to replace xxx w...
Definition: MagicWord.php:432
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
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