Index: trunk/phase3/includes/MagicWord.php |
— | — | @@ -0,0 +1,111 @@ |
| 2 | +<? |
| 3 | + |
| 4 | +# This class encapsulates "magic words" such as #redirect, __NOTOC__, etc. |
| 5 | +# Usage: |
| 6 | +# if (MagicWord::get( MAG_REDIRECT )->match( $text ) ) |
| 7 | +# |
| 8 | +# Possible future improvements: |
| 9 | +# * Simultaneous searching for a number of magic words |
| 10 | +# * $wgMagicWords in shared memory |
| 11 | +# |
| 12 | +# Please avoid reading the data out of one of these objects and then writing |
| 13 | +# special case code. If possible, add another match()-like function here. |
| 14 | + |
| 15 | +/*private*/ $wgMagicFound = false; |
| 16 | + |
| 17 | +class MagicWord { |
| 18 | + /*private*/ var $mId, $mSynonyms, $mCaseSensitive, $mRegex; |
| 19 | + /*private*/ var $mRegexStart, $mBaseRegex; |
| 20 | + |
| 21 | + function MagicWord($id = 0, $syn = "", $cs = false) |
| 22 | + { |
| 23 | + $this->mId = $id; |
| 24 | + $this->mSynonyms = (array)$syn; |
| 25 | + $this->mCaseSensitive = $cs; |
| 26 | + $this->mRegex = ""; |
| 27 | + $this->mRegexStart = ""; |
| 28 | + } |
| 29 | + |
| 30 | + /*static*/ function &get( $id ) |
| 31 | + { |
| 32 | + global $wgMagicWords; |
| 33 | + |
| 34 | + if (!array_key_exists( $id, $wgMagicWords ) ) { |
| 35 | + $mw = new MagicWord(); |
| 36 | + $mw->load( $id ); |
| 37 | + $wgMagicWords[$id] = $mw; |
| 38 | + } |
| 39 | + return $wgMagicWords[$id]; |
| 40 | + } |
| 41 | + |
| 42 | + function load( $id ) |
| 43 | + { |
| 44 | + global $wgLang; |
| 45 | + |
| 46 | + $this->mId = $id; |
| 47 | + $wgLang->getMagic( $this ); |
| 48 | + } |
| 49 | + |
| 50 | + /* private */ function initRegex() |
| 51 | + { |
| 52 | + $escSyn = array_map( "preg_quote", $this->mSynonyms ); |
| 53 | + $this->mBaseRegex = implode( "|", $escSyn ); |
| 54 | + $case = $this->mCaseSensitive ? "" : "i"; |
| 55 | + $this->mRegex = "/{$this->mBaseRegex}/{$case}"; |
| 56 | + $this->mRegexStart = "/^{$this->mBaseRegex}/{$case}"; |
| 57 | + } |
| 58 | + |
| 59 | + function getRegex() |
| 60 | + { |
| 61 | + if ($this->mRegex == "" ) { |
| 62 | + $this->initRegex(); |
| 63 | + } |
| 64 | + return $this->mRegex; |
| 65 | + } |
| 66 | + |
| 67 | + function getRegexStart() |
| 68 | + { |
| 69 | + if ($this->mRegex == "" ) { |
| 70 | + $this->initRegex(); |
| 71 | + } |
| 72 | + return $this->mRegexStart; |
| 73 | + } |
| 74 | + |
| 75 | + function getBaseRegex() |
| 76 | + { |
| 77 | + if ($this->mRegex == "") { |
| 78 | + $this->initRegex(); |
| 79 | + } |
| 80 | + return $this->mBaseRegex; |
| 81 | + } |
| 82 | + |
| 83 | + function match( $text ) { |
| 84 | + return preg_match( $this->getRegex(), $text ); |
| 85 | + } |
| 86 | + |
| 87 | + function matchStart( $text ) |
| 88 | + { |
| 89 | + return preg_match( $this->getRegexStart(), $text ); |
| 90 | + } |
| 91 | + |
| 92 | + function matchAndRemove( &$text ) |
| 93 | + { |
| 94 | + global $wgMagicFound; |
| 95 | + $wgMagicFound = false; |
| 96 | + $text = preg_replace_callback( $this->getRegex(), "pregRemoveAndRecord", $text ); |
| 97 | + return $wgMagicFound; |
| 98 | + } |
| 99 | + |
| 100 | + function replace( $replacement, $subject ) |
| 101 | + { |
| 102 | + return preg_replace( $this->getRegex(), $replacement, $subject ); |
| 103 | + } |
| 104 | +} |
| 105 | + |
| 106 | +/*private*/ function pregRemoveAndRecord( $match ) |
| 107 | +{ |
| 108 | + global $wgMagicFound; |
| 109 | + $wgMagicFound = true; |
| 110 | + return ""; |
| 111 | +} |
| 112 | + |
Property changes on: trunk/phase3/includes/MagicWord.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 113 | + native |
Added: svn:keywords |
2 | 114 | + Author Date Id Revision |
Index: trunk/phase3/includes/Article.php |
— | — | @@ -102,7 +102,7 @@ |
103 | 103 | |
104 | 104 | function loadContent( $noredir = false ) |
105 | 105 | { |
106 | | - global $wgOut, $wgTitle; |
| 106 | + global $wgOut, $wgTitle, $wgMwRedir; |
107 | 107 | global $oldid, $redirect; # From query |
108 | 108 | |
109 | 109 | if ( $this->mContentLoaded ) return; |
— | — | @@ -130,9 +130,8 @@ |
131 | 131 | |
132 | 132 | # If we got a redirect, follow it (unless we've been told |
133 | 133 | # not to by either the function parameter or the query |
134 | | - |
135 | 134 | if ( ( "no" != $redirect ) && ( false == $noredir ) && |
136 | | - ( preg_match( "/^#redirect/i", $s->cur_text ) ) ) { |
| 135 | + ( $wgMwRedir->matchStart( $s->cur_text ) ) ) { |
137 | 136 | if ( preg_match( "/\\[\\[([^\\]\\|]+)[\\]\\|]/", |
138 | 137 | $s->cur_text, $m ) ) { |
139 | 138 | $rt = Title::newFromText( $m[1] ); |
— | — | @@ -204,10 +203,10 @@ |
205 | 204 | |
206 | 205 | function isCountable( $text ) |
207 | 206 | { |
208 | | - global $wgTitle, $wgUseCommaCount; |
209 | | - |
| 207 | + global $wgTitle, $wgUseCommaCount, $wgMwRedir; |
| 208 | + |
210 | 209 | if ( 0 != $wgTitle->getNamespace() ) { return 0; } |
211 | | - if ( preg_match( "/^#redirect/i", $text ) ) { return 0; } |
| 210 | + if ( $wgMwRedir->matchStart( $text ) ) { return 0; } |
212 | 211 | $token = ($wgUseCommaCount ? "," : "[[" ); |
213 | 212 | if ( false === strstr( $text, $token ) ) { return 0; } |
214 | 213 | return 1; |
— | — | @@ -331,13 +330,13 @@ |
332 | 331 | |
333 | 332 | /* private */ function insertNewArticle( $text, $summary, $isminor, $watchthis ) |
334 | 333 | { |
335 | | - global $wgOut, $wgUser, $wgTitle, $wgLinkCache; |
| 334 | + global $wgOut, $wgUser, $wgTitle, $wgLinkCache, $wgMwRedir; |
336 | 335 | $fname = "Article::insertNewArticle"; |
337 | 336 | |
338 | 337 | $ns = $wgTitle->getNamespace(); |
339 | 338 | $ttl = $wgTitle->getDBkey(); |
340 | 339 | $text = $this->preSaveTransform( $text ); |
341 | | - if ( preg_match( "/^#redirect/i", $text ) ) { $redir = 1; } |
| 340 | + if ( $wgMwRedir->matchStart( $text ) ) { $redir = 1; } |
342 | 341 | else { $redir = 0; } |
343 | 342 | |
344 | 343 | $now = wfTimestampNow(); |
— | — | @@ -381,7 +380,7 @@ |
382 | 381 | function updateArticle( $text, $summary, $minor, $watchthis, $section="" ) |
383 | 382 | { |
384 | 383 | global $wgOut, $wgUser, $wgTitle, $wgLinkCache; |
385 | | - global $wgDBtransactions; |
| 384 | + global $wgDBtransactions, $wgMwRedir; |
386 | 385 | $fname = "Article::updateArticle"; |
387 | 386 | |
388 | 387 | $this->loadLastEdit(); |
— | — | @@ -403,7 +402,7 @@ |
404 | 403 | } |
405 | 404 | if ( $this->mMinorEdit ) { $me1 = 1; } else { $me1 = 0; } |
406 | 405 | if ( $minor ) { $me2 = 1; } else { $me2 = 0; } |
407 | | - if ( preg_match( "/^(#redirect[^\\n]+)/i", $text, $m ) ) { |
| 406 | + if ( preg_match( "/^((" . $wgMwRedir->getBaseRegex() . ")[^\\n]+)/i", $text, $m ) ) { |
408 | 407 | $redir = 1; |
409 | 408 | $text = $m[1] . "\n"; # Remove all content but redirect |
410 | 409 | } |
— | — | @@ -498,6 +497,7 @@ |
499 | 498 | function showArticle( $text, $subtitle ) |
500 | 499 | { |
501 | 500 | global $wgOut, $wgTitle, $wgUser, $wgLinkCache, $wgUseBetterLinksUpdate; |
| 501 | + global $wgMwRedir; |
502 | 502 | |
503 | 503 | $wgLinkCache = new LinkCache(); |
504 | 504 | |
— | — | @@ -511,7 +511,7 @@ |
512 | 512 | $wgOut->addWikiText( $text ); |
513 | 513 | |
514 | 514 | $this->editUpdates( $text ); |
515 | | - if( preg_match( "/^#redirect/i", $text ) ) |
| 515 | + if( $wgMwRedir->matchStart( $text ) ) |
516 | 516 | $r = "redirect=no"; |
517 | 517 | else |
518 | 518 | $r = ""; |
Index: trunk/phase3/includes/Setup.php |
— | — | @@ -16,13 +16,12 @@ |
17 | 17 | include_once( "$IP/LinkCache.php" ); |
18 | 18 | include_once( "$IP/Title.php" ); |
19 | 19 | include_once( "$IP/Article.php" ); |
| 20 | +include_once( "$IP/MagicWord.php" ); |
20 | 21 | include_once( "$IP/MemCachedClient.inc.php" ); |
21 | 22 | |
22 | | -wfDebug( "\n\n" ); |
23 | | - |
24 | 23 | global $wgUser, $wgLang, $wgOut, $wgTitle; |
25 | 24 | global $wgArticle, $wgDeferredUpdateList, $wgLinkCache; |
26 | | -global $wgMemc; |
| 25 | +global $wgMemc, $wgMagicWords, $wgMwRedir; |
27 | 26 | |
28 | 27 | class MemCachedClientforWiki extends MemCachedClient { |
29 | 28 | function _debug( $text ) { |
— | — | @@ -39,6 +38,8 @@ |
40 | 39 | include_once( "$IP/Language.php" ); |
41 | 40 | |
42 | 41 | $wgOut = new OutputPage(); |
| 42 | +wfDebug( "\n\n" ); |
| 43 | + |
43 | 44 | $wgLangClass = "Language" . ucfirst( $wgLanguageCode ); |
44 | 45 | if( ! class_exists( $wgLangClass ) ) { |
45 | 46 | include_once( "$IP/LanguageUtf8.php" ); |
— | — | @@ -49,5 +50,6 @@ |
50 | 51 | $wgUser = User::loadFromSession(); |
51 | 52 | $wgDeferredUpdateList = array(); |
52 | 53 | $wgLinkCache = new LinkCache(); |
53 | | - |
| 54 | +$wgMagicWords = array(); |
| 55 | +$wgMwRedir =& MagicWord::get( MAG_REDIRECT ); |
54 | 56 | ?> |
Index: trunk/phase3/includes/OutputPage.php |
— | — | @@ -1109,23 +1109,37 @@ |
1110 | 1110 | /* As with sigs, use server's local time -- |
1111 | 1111 | ensure this is appropriate for your audience! */ |
1112 | 1112 | $v = date( "m" ); |
1113 | | - $text = str_replace( "{{CURRENTMONTH}}", $v, $text ); |
| 1113 | + $mw =& MagicWord::get( MAG_CURRENTMONTH ); |
| 1114 | + $text = $mw->replace( $v, $text ); |
| 1115 | + |
1114 | 1116 | $v = $wgLang->getMonthName( date( "n" ) ); |
1115 | | - $text = str_replace( "{{CURRENTMONTHNAME}}", $v, $text ); |
| 1117 | + $mw =& MagicWord::get( MAG_CURRENTMONTHNAME ); |
| 1118 | + $text = $mw->replace( $v, $text ); |
| 1119 | + |
1116 | 1120 | $v = $wgLang->getMonthNameGen( date( "n" ) ); |
1117 | | - $text = str_replace( "{{CURRENTMONTHNAMEGEN}}", $v, $text ); |
| 1121 | + $mw =& MagicWord::get( MAG_CURRENTMONTHNAMEGEN ); |
| 1122 | + $text = $mw->replace( $v, $text ); |
| 1123 | + |
1118 | 1124 | $v = date( "j" ); |
1119 | | - $text = str_replace( "{{CURRENTDAY}}", $v, $text ); |
| 1125 | + $mw = MagicWord::get( MAG_CURRENTDAY ); |
| 1126 | + $text = $mw->replace( $v, $text ); |
| 1127 | + |
1120 | 1128 | $v = $wgLang->getWeekdayName( date( "w" )+1 ); |
1121 | | - $text = str_replace( "{{CURRENTDAYNAME}}", $v, $text ); |
| 1129 | + $mw =& MagicWord::get( MAG_CURRENTDAYNAME ); |
| 1130 | + $text = $mw->replace( $v, $text ); |
| 1131 | + |
1122 | 1132 | $v = date( "Y" ); |
1123 | | - $text = str_replace( "{{CURRENTYEAR}}", $v, $text ); |
| 1133 | + $mw =& MagicWord::get( MAG_CURRENTYEAR ); |
| 1134 | + $text = $mw->replace( $v, $text ); |
| 1135 | + |
1124 | 1136 | $v = $wgLang->time( wfTimestampNow(), false ); |
1125 | | - $text = str_replace( "{{CURRENTTIME}}", $v, $text ); |
| 1137 | + $mw =& MagicWord::get( MAG_CURRENTTIME ); |
| 1138 | + $text = $mw->replace( $v, $text ); |
1126 | 1139 | |
1127 | | - if ( false !== strstr( $text, "{{NUMBEROFARTICLES}}" ) ) { |
| 1140 | + $mw =& MagicWord::get( MAG_NUMBEROFARTICLES ); |
| 1141 | + if ( $mw->match( $text ) ) { |
1128 | 1142 | $v = wfNumberOfArticles(); |
1129 | | - $text = str_replace( "{{NUMBEROFARTICLES}}", $v, $text ); |
| 1143 | + $text = $mw->replace( $v, $text ); |
1130 | 1144 | } |
1131 | 1145 | wfProfileOut(); |
1132 | 1146 | return $text; |
— | — | @@ -1262,10 +1276,8 @@ |
1263 | 1277 | } |
1264 | 1278 | # if the string __NOTOC__ (not case-sensitive) occurs in the HTML, do not |
1265 | 1279 | # add TOC |
1266 | | - if(preg_match("/__NOTOC__/i",$text)) { |
1267 | | - $text=preg_replace("/__NOTOC__/i","",$text); |
1268 | | - $st=0; |
1269 | | - } |
| 1280 | + $mw =& MagicWord::get( MAG_NOTOC ); |
| 1281 | + $st = ! $mw->matchAndRemove( $text ); |
1270 | 1282 | |
1271 | 1283 | # never add the TOC to the Main Page. This is an entry page that should not |
1272 | 1284 | # be more than 1-2 screens large anyway |
Index: trunk/phase3/languages/Language.php |
— | — | @@ -1,5 +1,37 @@ |
2 | 2 | <? |
3 | 3 | |
| 4 | +#-------------------------------------------------------------------------- |
| 5 | +# Constants |
| 6 | +#-------------------------------------------------------------------------- |
| 7 | + |
| 8 | +# Namespaces |
| 9 | +define("NS_SPECIAL", -1); |
| 10 | +define("NS_MAIN", 0); |
| 11 | +define("NS_TALK", 1); |
| 12 | +define("NS_USER", 2); |
| 13 | +define("NS_USER_TALK", 3); |
| 14 | +define("NS_WP", 4); |
| 15 | +define("NS_WP_TALK", 5); |
| 16 | +define("NS_IMAGE", 6); |
| 17 | +define("NS_IMAGE_TALK", 7); |
| 18 | + |
| 19 | +# Magic words |
| 20 | +define("MAG_REDIRECT", 0); |
| 21 | +define("MAG_NOTOC", 1); |
| 22 | +define("MAG_START", 2); |
| 23 | +define("MAG_CURRENTMONTH", 3); |
| 24 | +define("MAG_CURRENTMONTHNAME", 4); |
| 25 | +define("MAG_CURRENTDAY", 5); |
| 26 | +define("MAG_CURRENTDAYNAME", 6); |
| 27 | +define("MAG_CURRENTYEAR", 7); |
| 28 | +define("MAG_CURRENTTIME", 8); |
| 29 | +define("MAG_NUMBEROFARTICLES", 9); |
| 30 | +define("MAG_CURRENTMONTHNAMEGEN", 10); |
| 31 | + |
| 32 | +#-------------------------------------------------------------------------- |
| 33 | +# Language-specific text |
| 34 | +#-------------------------------------------------------------------------- |
| 35 | + |
4 | 36 | # NOTE: To turn off "Current Events" in the sidebar, |
5 | 37 | # set "currentevents" => "-" |
6 | 38 | |
— | — | @@ -240,6 +272,21 @@ |
241 | 273 | "Sep", "Oct", "Nov", "Dec" |
242 | 274 | ); |
243 | 275 | |
| 276 | +/* private */ $wgMagicWordsEn = array( |
| 277 | +# ID CASE SYNONYMS |
| 278 | + MAG_REDIRECT => array( 0, "#redirect" ), |
| 279 | + MAG_NOTOC => array( 0, "__NOTOC__" ), |
| 280 | + MAG_START => array( 0, "__START__" ), |
| 281 | + MAG_CURRENTMONTH => array( 1, "{{CURRENTMONTH}}" ), |
| 282 | + MAG_CURRENTMONTHNAME => array( 1, "{{CURRENTMONTHNAME}}" ), |
| 283 | + MAG_CURRENTDAY => array( 1, "{{CURRENTDAY}}" ), |
| 284 | + MAG_CURRENTDAYNAME => array( 1, "{{CURRENTDAYNAME}}" ), |
| 285 | + MAG_CURRENTYEAR => array( 1, "{{CURRENTYEAR}}" ), |
| 286 | + MAG_CURRENTTIME => array( 1, "{{CURRENTTIME}}" ), |
| 287 | + MAG_NUMBEROFARTICLES => array( 1, "{{NUMBEROFARTICLES}}" ), |
| 288 | + MAG_CURRENTMONTHNAMEGEN => array( 1, "{{CURRENTMONTHNAMEGEN}}"), |
| 289 | +); |
| 290 | + |
244 | 291 | # All special pages have to be listed here: a description of "" |
245 | 292 | # will make them not show up on the "Special Pages" page, which |
246 | 293 | # is the right thing for some of them (such as the "targeted" ones). |
— | — | @@ -1144,6 +1191,10 @@ |
1145 | 1192 | |
1146 | 1193 | ); |
1147 | 1194 | |
| 1195 | +#-------------------------------------------------------------------------- |
| 1196 | +# Internationalisation code |
| 1197 | +#-------------------------------------------------------------------------- |
| 1198 | + |
1148 | 1199 | class Language { |
1149 | 1200 | |
1150 | 1201 | function getDefaultUserOptions () { |
— | — | @@ -1494,6 +1545,21 @@ |
1495 | 1546 | |
1496 | 1547 | # For right-to-left language support |
1497 | 1548 | function isRTL() { return false; } |
| 1549 | + |
| 1550 | + function getMagicWords() |
| 1551 | + { |
| 1552 | + global $wgMagicWordsEn; |
| 1553 | + return $wgMagicWordsEn; |
| 1554 | + } |
| 1555 | + |
| 1556 | + # Fill a MagicWord object with data from here |
| 1557 | + function getMagic( &$mw ) |
| 1558 | + { |
| 1559 | + $raw = $this->getMagicWords(); # don't worry, it's reference counted not deep copy |
| 1560 | + $rawEntry = $raw[$mw->mId]; |
| 1561 | + $mw->mCaseSensitive = $rawEntry[0]; |
| 1562 | + $mw->mSynonyms = array_slice( $rawEntry, 1 ); |
| 1563 | + } |
1498 | 1564 | } |
1499 | 1565 | |
1500 | 1566 | global $IP; |