match( $text ) ) # # Possible future improvements: # * Simultaneous searching for a number of magic words # * $wgMagicWords in shared memory # # Please avoid reading the data out of one of these objects and then writing # special case code. If possible, add another match()-like function here. /*private*/ $wgMagicFound = false; define("MAG_REDIRECT", 0); define("MAG_NOTOC", 1); define("MAG_START", 2); define("MAG_CURRENTMONTH", 3); define("MAG_CURRENTMONTHNAME", 4); define("MAG_CURRENTDAY", 5); define("MAG_CURRENTDAYNAME", 6); define("MAG_CURRENTYEAR", 7); define("MAG_CURRENTTIME", 8); define("MAG_NUMBEROFARTICLES", 9); define("MAG_CURRENTMONTHNAMEGEN", 10); define("MAG_MSG", 11); define("MAG_SUBST", 12); define("MAG_MSGNW", 13); define("MAG_NOEDITSECTION", 14); define("MAG_END", 15); define("MAG_IMG_THUMBNAIL", 16); define("MAG_IMG_RIGHT", 17); define("MAG_IMG_LEFT", 18); define("MAG_IMG_NONE", 19); define("MAG_IMG_WIDTH", 20); define("MAG_IMG_CENTER", 21); define("MAG_INT", 22); define("MAG_FORCETOC", 23); define("MAG_SITENAME", 24); define("MAG_NS", 25); define("MAG_LOCALURL", 26); define("MAG_LOCALURLE", 27); define("MAG_SERVER", 28); define("MAG_IMG_FRAMED", 29); define("MAG_PAGENAME", 30); define("MAG_NAMESPACE", 31); define("MAG_TOC", 32); $wgVariableIDs = array( MAG_CURRENTMONTH, MAG_CURRENTMONTHNAME, MAG_CURRENTDAY, MAG_CURRENTDAYNAME, MAG_CURRENTYEAR, MAG_CURRENTTIME, MAG_NUMBEROFARTICLES, MAG_CURRENTMONTHNAMEGEN, MAG_SITENAME, MAG_SERVER, MAG_PAGENAME, MAG_NAMESPACE ); class MagicWord { /*private*/ var $mId, $mSynonyms, $mCaseSensitive, $mRegex; /*private*/ var $mRegexStart, $mBaseRegex, $mVariableRegex; /*private*/ var $mModified; function MagicWord($id = 0, $syn = "", $cs = false) { $this->mId = $id; $this->mSynonyms = (array)$syn; $this->mCaseSensitive = $cs; $this->mRegex = ""; $this->mRegexStart = ""; $this->mVariableRegex = ""; $this->mVariableStartToEndRegex = ""; $this->mModified = false; } # Factory: creates an object representing an ID /*static*/ function &get( $id ) { global $wgMagicWords; if ( !is_array( $wgMagicWords ) ) { wfDebugDieBacktrace( "Incorrect initialisation order, \$wgMagicWords does not exist\n" ); } if (!array_key_exists( $id, $wgMagicWords ) ) { $mw = new MagicWord(); $mw->load( $id ); $wgMagicWords[$id] = $mw; } return $wgMagicWords[$id]; } # Initialises this object with an ID function load( $id ) { global $wgLang; $this->mId = $id; $wgLang->getMagic( $this ); } # Preliminary initialisation /* private */ function initRegex() { $variableClass = Title::legalChars(); $escSyn = array_map( "preg_quote", $this->mSynonyms ); $this->mBaseRegex = implode( "|", $escSyn ); $case = $this->mCaseSensitive ? "" : "i"; $this->mRegex = "/{$this->mBaseRegex}/{$case}"; $this->mRegexStart = "/^{$this->mBaseRegex}/{$case}"; $this->mVariableRegex = str_replace( "\\$1", "([$variableClass]*?)", $this->mRegex ); $this->mVariableStartToEndRegex = str_replace( "\\$1", "([$variableClass]*?)", "/^({$this->mBaseRegex})$/{$case}" ); } # Gets a regex representing matching the word function getRegex() { if ($this->mRegex == "" ) { $this->initRegex(); } return $this->mRegex; } # Gets a regex matching the word, if it is at the # string start function getRegexStart() { if ($this->mRegex == "" ) { $this->initRegex(); } return $this->mRegexStart; } # regex without the slashes and what not function getBaseRegex() { if ($this->mRegex == "") { $this->initRegex(); } return $this->mBaseRegex; } # Returns true if the text contains the word function match( $text ) { return preg_match( $this->getRegex(), $text ); } # Returns true if the text starts with the word function matchStart( $text ) { return preg_match( $this->getRegexStart(), $text ); } # Returns NULL if there's no match, the value of $1 otherwise # The return code is the matched string, if there's no variable # part in the regex and the matched variable part ($1) if there # is one. function matchVariableStartToEnd( $text ) { $matchcount = preg_match( $this->getVariableStartToEndRegex(), $text, $matches ); if ( $matchcount == 0 ) { return NULL; } elseif ( count($matches) == 1 ) { return $matches[0]; } else { return $matches[1]; } } # Returns true if the text matches the word, and alters the # input string, removing all instances of the word function matchAndRemove( &$text ) { global $wgMagicFound; $wgMagicFound = false; $text = preg_replace_callback( $this->getRegex(), "pregRemoveAndRecord", $text ); return $wgMagicFound; } function matchStartAndRemove( &$text ) { global $wgMagicFound; $wgMagicFound = false; $text = preg_replace_callback( $this->getRegexStart(), "pregRemoveAndRecord", $text ); return $wgMagicFound; } # Replaces the word with something else function replace( $replacement, $subject ) { $res = preg_replace( $this->getRegex(), $replacement, $subject ); $this->mModified = !($res === $subject); return $res; } # Variable handling: {{SUBST:xxx}} style words # Calls back a function to determine what to replace xxx with # Input word must contain $1 function substituteCallback( $text, $callback ) { $regex = $this->getVariableRegex(); $res = preg_replace_callback( $this->getVariableRegex(), $callback, $text ); $this->mModified = !($res === $text); return $res; } # Matches the word, where $1 is a wildcard function getVariableRegex() { if ( $this->mVariableRegex == "" ) { $this->initRegex(); } return $this->mVariableRegex; } # Matches the entire string, where $1 is a wildcard function getVariableStartToEndRegex() { if ( $this->mVariableStartToEndRegex == "" ) { $this->initRegex(); } return $this->mVariableStartToEndRegex; } # Accesses the synonym list directly function getSynonym( $i ) { return $this->mSynonyms[$i]; } # Returns true if the last call to replace() or substituteCallback() # returned a modified text, otherwise false. function getWasModified(){ return $this->mModified; } # $magicarr is an associative array of (magic word ID => replacement) # This method uses the php feature to do several replacements at the same time, # thereby gaining some efficiency. The result is placed in the out variable # $result. The return value is true if something was replaced. /* static */ function replaceMultiple( $magicarr, $subject, &$result ){ $search = array(); $replace = array(); foreach( $magicarr as $id => $replacement ){ $mw = MagicWord::get( $id ); $search[] = $mw->getRegex(); $replace[] = $replacement; } $result = preg_replace( $search, $replace, $subject ); return !($result === $subject); } # Adds all the synonyms of this MagicWord to an array, to allow quick lookup in a list of magic words function addToArray( &$array, $value ) { foreach ( $this->mSynonyms as $syn ) { $array[$syn] = $value; } } } # Used in matchAndRemove() /*private*/ function pregRemoveAndRecord( $match ) { global $wgMagicFound; $wgMagicFound = true; return ""; } ?>