MediaWiki  master
MagicWord.php
Go to the documentation of this file.
1 <?php
25 
60 class MagicWord {
64  public $mId;
65 
67  public $mSynonyms;
68 
71 
73  private $mRegex = '';
74 
76  private $mRegexStart = '';
77 
79  private $mRegexStartToEnd = '';
80 
82  private $mBaseRegex = '';
83 
85  private $mVariableRegex = '';
86 
89 
91  private $mModified = false;
92 
94  private $mFound = false;
95 
97  private $contLang;
98 
111  public function __construct( $id = null, $syn = [], $cs = false, Language $contLang = null ) {
112  $this->mId = $id;
113  $this->mSynonyms = (array)$syn;
114  $this->mCaseSensitive = $cs;
115  $this->contLang = $contLang ?: MediaWikiServices::getInstance()->getContentLanguage();
116  }
117 
124  public function load( $id ) {
125  $this->mId = $id;
126  $this->contLang->getMagic( $this );
127  if ( !$this->mSynonyms ) {
128  $this->mSynonyms = [ 'brionmademeputthishere' ];
129  throw new MWException( "Error: invalid magic word '$id'" );
130  }
131  }
132 
137  public function initRegex() {
138  // Sort the synonyms by length, descending, so that the longest synonym
139  // matches in precedence to the shortest
140  $synonyms = $this->mSynonyms;
141  usort( $synonyms, [ $this, 'compareStringLength' ] );
142 
143  $escSyn = [];
144  foreach ( $synonyms as $synonym ) {
145  // In case a magic word contains /, like that's going to happen;)
146  $escSyn[] = preg_quote( $synonym, '/' );
147  }
148  $this->mBaseRegex = implode( '|', $escSyn );
149 
150  $case = $this->mCaseSensitive ? '' : 'iu';
151  $this->mRegex = "/{$this->mBaseRegex}/{$case}";
152  $this->mRegexStart = "/^(?:{$this->mBaseRegex})/{$case}";
153  $this->mRegexStartToEnd = "/^(?:{$this->mBaseRegex})$/{$case}";
154  $this->mVariableRegex = str_replace( "\\$1", "(.*?)", $this->mRegex );
155  $this->mVariableStartToEndRegex = str_replace( "\\$1", "(.*?)",
156  "/^(?:{$this->mBaseRegex})$/{$case}" );
157  }
158 
169  public function compareStringLength( $s1, $s2 ) {
170  $l1 = strlen( $s1 );
171  $l2 = strlen( $s2 );
172  return $l2 <=> $l1; // descending
173  }
174 
180  public function getRegex() {
181  if ( $this->mRegex == '' ) {
182  $this->initRegex();
183  }
184  return $this->mRegex;
185  }
186 
194  public function getRegexCase() {
195  if ( $this->mRegex === '' ) {
196  $this->initRegex();
197  }
198 
199  return $this->mCaseSensitive ? '' : 'iu';
200  }
201 
207  public function getRegexStart() {
208  if ( $this->mRegex == '' ) {
209  $this->initRegex();
210  }
211  return $this->mRegexStart;
212  }
213 
220  public function getRegexStartToEnd() {
221  if ( $this->mRegexStartToEnd == '' ) {
222  $this->initRegex();
223  }
225  }
226 
232  public function getBaseRegex() {
233  if ( $this->mRegex == '' ) {
234  $this->initRegex();
235  }
236  return $this->mBaseRegex;
237  }
238 
246  public function match( $text ) {
247  return (bool)preg_match( $this->getRegex(), $text );
248  }
249 
257  public function matchStart( $text ) {
258  return (bool)preg_match( $this->getRegexStart(), $text );
259  }
260 
269  public function matchStartToEnd( $text ) {
270  return (bool)preg_match( $this->getRegexStartToEnd(), $text );
271  }
272 
283  public function matchVariableStartToEnd( $text ) {
284  $matches = [];
285  $matchcount = preg_match( $this->getVariableStartToEndRegex(), $text, $matches );
286  if ( $matchcount == 0 ) {
287  return null;
288  } else {
289  # multiple matched parts (variable match); some will be empty because of
290  # synonyms. The variable will be the second non-empty one so remove any
291  # blank elements and re-sort the indices.
292  # See also T8526
293 
294  $matches = array_values( array_filter( $matches ) );
295 
296  if ( count( $matches ) == 1 ) {
297  return $matches[0];
298  } else {
299  return $matches[1];
300  }
301  }
302  }
303 
312  public function matchAndRemove( &$text ) {
313  $this->mFound = false;
314  $text = preg_replace_callback(
315  $this->getRegex(),
316  [ $this, 'pregRemoveAndRecord' ],
317  $text
318  );
319 
320  return $this->mFound;
321  }
322 
327  public function matchStartAndRemove( &$text ) {
328  $this->mFound = false;
329  $text = preg_replace_callback(
330  $this->getRegexStart(),
331  [ $this, 'pregRemoveAndRecord' ],
332  $text
333  );
334 
335  return $this->mFound;
336  }
337 
343  public function pregRemoveAndRecord() {
344  $this->mFound = true;
345  return '';
346  }
347 
357  public function replace( $replacement, $subject, $limit = -1 ) {
358  $res = preg_replace(
359  $this->getRegex(),
360  StringUtils::escapeRegexReplacement( $replacement ),
361  $subject,
362  $limit
363  );
364  $this->mModified = $res !== $subject;
365  return $res;
366  }
367 
378  public function substituteCallback( $text, $callback ) {
379  $res = preg_replace_callback( $this->getVariableRegex(), $callback, $text );
380  $this->mModified = $res !== $text;
381  return $res;
382  }
383 
389  public function getVariableRegex() {
390  if ( $this->mVariableRegex == '' ) {
391  $this->initRegex();
392  }
393  return $this->mVariableRegex;
394  }
395 
401  public function getVariableStartToEndRegex() {
402  if ( $this->mVariableStartToEndRegex == '' ) {
403  $this->initRegex();
404  }
406  }
407 
415  public function getSynonym( $i ) {
416  return $this->mSynonyms[$i];
417  }
418 
422  public function getSynonyms() {
423  return $this->mSynonyms;
424  }
425 
432  public function getWasModified() {
433  return $this->mModified;
434  }
435 
443  public function addToArray( &$array, $value ) {
444  foreach ( $this->mSynonyms as $syn ) {
445  $array[$this->contLang->lc( $syn )] = $value;
446  }
447  }
448 
452  public function isCaseSensitive() {
453  return $this->mCaseSensitive;
454  }
455 
459  public function getId() {
460  return $this->mId;
461  }
462 }
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:157
MagicWord\$contLang
Language $contLang
Definition: MagicWord.php:97
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:378
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:283
MagicWord\getSynonyms
getSynonyms()
Definition: MagicWord.php:422
MagicWord\load
load( $id)
Initialises this object with an ID.
Definition: MagicWord.php:124
MagicWord\isCaseSensitive
isCaseSensitive()
Definition: MagicWord.php:452
MagicWord\getRegexStartToEnd
getRegexStartToEnd()
Gets a regex matching the word from start to end of a string.
Definition: MagicWord.php:220
MagicWord\$mRegex
string $mRegex
Definition: MagicWord.php:73
StringUtils\escapeRegexReplacement
static escapeRegexReplacement( $string)
Escape a string to make it suitable for inclusion in a preg_replace() replacement parameter.
Definition: StringUtils.php:314
MagicWord\getRegex
getRegex()
Gets a regex representing matching the word.
Definition: MagicWord.php:180
MagicWord\$mRegexStartToEnd
string $mRegexStartToEnd
Definition: MagicWord.php:79
MagicWord\__construct
__construct( $id=null, $syn=[], $cs=false, Language $contLang=null)
#-
Definition: MagicWord.php:111
MagicWord\getId
getId()
Definition: MagicWord.php:459
MagicWord\$mBaseRegex
string $mBaseRegex
Definition: MagicWord.php:82
$res
$res
Definition: testCompression.php:57
MagicWord\$mSynonyms
string[] $mSynonyms
Definition: MagicWord.php:67
MagicWord\initRegex
initRegex()
Preliminary initialisation.
Definition: MagicWord.php:137
MagicWord\replace
replace( $replacement, $subject, $limit=-1)
Replaces the word with something else.
Definition: MagicWord.php:357
MagicWord\matchStartToEnd
matchStartToEnd( $text)
Returns true if the text matched the word.
Definition: MagicWord.php:269
MagicWord\$mId
string $mId
#-
Definition: MagicWord.php:64
MWException
MediaWiki exception.
Definition: MWException.php:29
$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:432
MagicWord\$mVariableStartToEndRegex
string $mVariableStartToEndRegex
Definition: MagicWord.php:88
MagicWord\$mModified
bool $mModified
Definition: MagicWord.php:91
MagicWord\$mFound
bool $mFound
Definition: MagicWord.php:94
MagicWord\pregRemoveAndRecord
pregRemoveAndRecord()
Used in matchAndRemove()
Definition: MagicWord.php:343
MagicWord
This class encapsulates "magic words" such as "#redirect", NOTOC, etc.
Definition: MagicWord.php:60
MagicWord\getRegexStart
getRegexStart()
Gets a regex matching the word, if it is at the string start.
Definition: MagicWord.php:207
MagicWord\getBaseRegex
getBaseRegex()
regex without the slashes and what not
Definition: MagicWord.php:232
MagicWord\matchStartAndRemove
matchStartAndRemove(&$text)
Definition: MagicWord.php:327
MagicWord\getVariableRegex
getVariableRegex()
Matches the word, where $1 is a wildcard.
Definition: MagicWord.php:389
MagicWord\$mCaseSensitive
bool $mCaseSensitive
Definition: MagicWord.php:70
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:443
MagicWord\$mRegexStart
string $mRegexStart
Definition: MagicWord.php:76
MagicWord\$mVariableRegex
string $mVariableRegex
Definition: MagicWord.php:85
MagicWord\matchStart
matchStart( $text)
Returns true if the text starts with the word.
Definition: MagicWord.php:257
MagicWord\getRegexCase
getRegexCase()
Gets the regexp case modifier to use, i.e.
Definition: MagicWord.php:194
MagicWord\getVariableStartToEndRegex
getVariableStartToEndRegex()
Matches the entire string, where $1 is a wildcard.
Definition: MagicWord.php:401
MagicWord\getSynonym
getSynonym( $i)
Accesses the synonym list directly.
Definition: MagicWord.php:415
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:169
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:312
MagicWord\match
match( $text)
Returns true if the text contains the word.
Definition: MagicWord.php:246
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:41