Internationalisation of "magic words" such as #redirect
authorTim Starling <tstarling@users.mediawiki.org>
Sun, 31 Aug 2003 09:46:37 +0000 (09:46 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Sun, 31 Aug 2003 09:46:37 +0000 (09:46 +0000)
includes/Article.php
includes/MagicWord.php [new file with mode: 0644]
includes/OutputPage.php
includes/Setup.php
languages/Language.php

index 626a9b3..116a8ef 100644 (file)
@@ -102,7 +102,7 @@ class Article {
 
        function loadContent( $noredir = false )
        {
-               global $wgOut, $wgTitle;
+               global $wgOut, $wgTitle, $wgMwRedir;
                global $oldid, $redirect; # From query
 
                if ( $this->mContentLoaded ) return;
@@ -130,9 +130,8 @@ class Article {
 
                        # If we got a redirect, follow it (unless we've been told
                        # not to by either the function parameter or the query
-
                        if ( ( "no" != $redirect ) && ( false == $noredir ) &&
-                         ( preg_match( "/^#redirect/i", $s->cur_text ) ) ) {
+                         ( $wgMwRedir->matchStart( $s->cur_text ) ) ) {
                                if ( preg_match( "/\\[\\[([^\\]\\|]+)[\\]\\|]/",
                                  $s->cur_text, $m ) ) {
                                        $rt = Title::newFromText( $m[1] );
@@ -204,10 +203,10 @@ class Article {
 
        function isCountable( $text )
        {
-               global $wgTitle, $wgUseCommaCount;
-
+               global $wgTitle, $wgUseCommaCount, $wgMwRedir;
+               
                if ( 0 != $wgTitle->getNamespace() ) { return 0; }
-               if ( preg_match( "/^#redirect/i", $text ) ) { return 0; }
+               if ( $wgMwRedir->matchStart( $text ) ) { return 0; }
                $token = ($wgUseCommaCount ? "," : "[[" );
                if ( false === strstr( $text, $token ) ) { return 0; }
                return 1;
@@ -331,13 +330,13 @@ class Article {
 
        /* private */ function insertNewArticle( $text, $summary, $isminor, $watchthis )
        {
-               global $wgOut, $wgUser, $wgTitle, $wgLinkCache;
+               global $wgOut, $wgUser, $wgTitle, $wgLinkCache, $wgMwRedir;
                $fname = "Article::insertNewArticle";
 
                $ns = $wgTitle->getNamespace();
                $ttl = $wgTitle->getDBkey();
                $text = $this->preSaveTransform( $text );
-               if ( preg_match( "/^#redirect/i", $text ) ) { $redir = 1; }
+               if ( $wgMwRedir->matchStart( $text ) ) { $redir = 1; }
                else { $redir = 0; }
 
                $now = wfTimestampNow();
@@ -381,7 +380,7 @@ class Article {
        function updateArticle( $text, $summary, $minor, $watchthis, $section="" )
        {
                global $wgOut, $wgUser, $wgTitle, $wgLinkCache;
-               global $wgDBtransactions;
+               global $wgDBtransactions, $wgMwRedir;
                $fname = "Article::updateArticle";
 
                $this->loadLastEdit();
@@ -403,7 +402,7 @@ class Article {
                }
                if ( $this->mMinorEdit ) { $me1 = 1; } else { $me1 = 0; }
                if ( $minor ) { $me2 = 1; } else { $me2 = 0; }          
-               if ( preg_match( "/^(#redirect[^\\n]+)/i", $text, $m ) ) {
+               if ( preg_match( "/^((" . $wgMwRedir->getBaseRegex() . ")[^\\n]+)/i", $text, $m ) ) {
                        $redir = 1;
                        $text = $m[1] . "\n"; # Remove all content but redirect
                }
@@ -498,6 +497,7 @@ class Article {
        function showArticle( $text, $subtitle )
        {
                global $wgOut, $wgTitle, $wgUser, $wgLinkCache, $wgUseBetterLinksUpdate;
+               global $wgMwRedir;
 
                $wgLinkCache = new LinkCache();
 
@@ -511,7 +511,7 @@ class Article {
                $wgOut->addWikiText( $text );
 
                $this->editUpdates( $text );
-               if( preg_match( "/^#redirect/i", $text ) )
+               if( $wgMwRedir->matchStart( $text ) )
                        $r = "redirect=no";
                else
                        $r = "";
diff --git a/includes/MagicWord.php b/includes/MagicWord.php
new file mode 100644 (file)
index 0000000..fd1e878
--- /dev/null
@@ -0,0 +1,111 @@
+<?
+
+# This class encapsulates "magic words" such as #redirect, __NOTOC__, etc.
+# Usage:
+#     if (MagicWord::get( MAG_REDIRECT )->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;
+
+class MagicWord {
+       /*private*/ var $mId, $mSynonyms, $mCaseSensitive, $mRegex;
+       /*private*/ var $mRegexStart, $mBaseRegex;
+       
+       function MagicWord($id = 0, $syn = "", $cs = false) 
+       {
+               $this->mId = $id;
+               $this->mSynonyms = (array)$syn;
+               $this->mCaseSensitive = $cs;
+               $this->mRegex = "";
+               $this->mRegexStart = "";
+       }
+
+       /*static*/ function &get( $id )
+       {
+               global $wgMagicWords;
+               
+               if (!array_key_exists( $id, $wgMagicWords ) ) {
+                       $mw = new MagicWord();
+                       $mw->load( $id );
+                       $wgMagicWords[$id] = $mw;
+               }
+               return $wgMagicWords[$id];
+       }
+       
+       function load( $id )
+       {
+               global $wgLang;
+               
+               $this->mId = $id;
+               $wgLang->getMagic( $this );
+       }
+       
+       /* private */ function initRegex()
+       {
+               $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}";
+       }
+       
+       function getRegex()
+       {
+               if ($this->mRegex == "" ) {
+                       $this->initRegex();
+               }
+               return $this->mRegex;
+       }
+
+       function getRegexStart()
+       {
+               if ($this->mRegex == "" ) {
+                       $this->initRegex();
+               }
+               return $this->mRegexStart;
+       }
+       
+       function getBaseRegex()
+       {
+               if ($this->mRegex == "") {
+                       $this->initRegex();
+               }
+               return $this->mBaseRegex;
+       }
+               
+       function match( $text ) {
+               return preg_match( $this->getRegex(), $text );
+       }
+
+       function matchStart( $text ) 
+       {
+               return preg_match( $this->getRegexStart(), $text );
+       }
+
+       function matchAndRemove( &$text )
+       {
+               global $wgMagicFound;
+               $wgMagicFound = false;
+               $text = preg_replace_callback( $this->getRegex(), "pregRemoveAndRecord", $text );
+               return $wgMagicFound;
+       }
+
+       function replace( $replacement, $subject )
+       {
+               return preg_replace( $this->getRegex(), $replacement, $subject );
+       }
+}
+
+/*private*/ function pregRemoveAndRecord( $match )
+{
+       global $wgMagicFound;
+       $wgMagicFound = true;
+       return "";
+}
+
index 0cec21b..378e563 100644 (file)
@@ -1109,23 +1109,37 @@ return $r ;
                /* As with sigs, use server's local time --
                   ensure this is appropriate for your audience! */
                $v = date( "m" );
-               $text = str_replace( "{{CURRENTMONTH}}", $v, $text );
+               $mw =& MagicWord::get( MAG_CURRENTMONTH );
+               $text = $mw->replace( $v, $text );
+               
                $v = $wgLang->getMonthName( date( "n" ) );
-               $text = str_replace( "{{CURRENTMONTHNAME}}", $v, $text );
+               $mw =& MagicWord::get( MAG_CURRENTMONTHNAME );
+               $text = $mw->replace( $v, $text );
+               
                $v = $wgLang->getMonthNameGen( date( "n" ) );
-               $text = str_replace( "{{CURRENTMONTHNAMEGEN}}", $v, $text );
+               $mw =& MagicWord::get( MAG_CURRENTMONTHNAMEGEN );
+               $text = $mw->replace( $v, $text );
+               
                $v = date( "j" );
-               $text = str_replace( "{{CURRENTDAY}}", $v, $text );
+               $mw = MagicWord::get( MAG_CURRENTDAY );
+               $text = $mw->replace( $v, $text );
+               
                $v = $wgLang->getWeekdayName( date( "w" )+1 );
-               $text = str_replace( "{{CURRENTDAYNAME}}", $v, $text );
+               $mw =& MagicWord::get( MAG_CURRENTDAYNAME );
+               $text = $mw->replace( $v, $text );
+               
                $v = date( "Y" );
-               $text = str_replace( "{{CURRENTYEAR}}", $v, $text );
+               $mw =& MagicWord::get( MAG_CURRENTYEAR );
+               $text = $mw->replace( $v, $text );
+       
                $v = $wgLang->time( wfTimestampNow(), false );
-               $text = str_replace( "{{CURRENTTIME}}", $v, $text );
+               $mw =& MagicWord::get( MAG_CURRENTTIME );
+               $text = $mw->replace( $v, $text );
 
-               if ( false !== strstr( $text, "{{NUMBEROFARTICLES}}" ) ) {
+               $mw =& MagicWord::get( MAG_NUMBEROFARTICLES );
+               if ( $mw->match( $text ) ) {
                        $v = wfNumberOfArticles();
-                       $text = str_replace( "{{NUMBEROFARTICLES}}", $v, $text );
+                       $text = $mw->replace( $v, $text );
                }
                wfProfileOut();
                return $text;
@@ -1262,10 +1276,8 @@ return $r ;
                }
                # if the string __NOTOC__ (not case-sensitive) occurs in the HTML, do not 
                # add TOC
-               if(preg_match("/__NOTOC__/i",$text)) { 
-                       $text=preg_replace("/__NOTOC__/i","",$text);
-                       $st=0; 
-               }
+               $mw =& MagicWord::get( MAG_NOTOC );
+               $st = ! $mw->matchAndRemove( $text );
 
                # never add the TOC to the Main Page. This is an entry page that should not
                # be more than 1-2 screens large anyway
index 039d72c..c0cc05e 100644 (file)
@@ -16,13 +16,12 @@ include_once( "$IP/User.php" );
 include_once( "$IP/LinkCache.php" );
 include_once( "$IP/Title.php" );
 include_once( "$IP/Article.php" );
+include_once( "$IP/MagicWord.php" );
 include_once( "$IP/MemCachedClient.inc.php" );
 
-wfDebug( "\n\n" );
-
 global $wgUser, $wgLang, $wgOut, $wgTitle;
 global $wgArticle, $wgDeferredUpdateList, $wgLinkCache;
-global $wgMemc;
+global $wgMemc, $wgMagicWords, $wgMwRedir;
 
 class MemCachedClientforWiki extends MemCachedClient {
        function _debug( $text ) {
@@ -39,6 +38,8 @@ if( $wgUseMemCached ) {
 include_once( "$IP/Language.php" );
 
 $wgOut = new OutputPage();
+wfDebug( "\n\n" );
+
 $wgLangClass = "Language" . ucfirst( $wgLanguageCode );
 if( ! class_exists( $wgLangClass ) ) {
        include_once( "$IP/LanguageUtf8.php" );
@@ -49,5 +50,6 @@ $wgLang = new $wgLangClass();
 $wgUser = User::loadFromSession();
 $wgDeferredUpdateList = array();
 $wgLinkCache = new LinkCache();
-
+$wgMagicWords = array();
+$wgMwRedir =& MagicWord::get( MAG_REDIRECT );
 ?>
index f93afd2..25e179a 100644 (file)
@@ -1,5 +1,37 @@
 <?
 
+#--------------------------------------------------------------------------
+# Constants
+#--------------------------------------------------------------------------
+
+# Namespaces
+define("NS_SPECIAL", -1);
+define("NS_MAIN", 0);
+define("NS_TALK", 1);
+define("NS_USER", 2);
+define("NS_USER_TALK", 3);
+define("NS_WP", 4);
+define("NS_WP_TALK", 5);
+define("NS_IMAGE", 6);
+define("NS_IMAGE_TALK", 7);
+
+# Magic words
+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);
+
+#--------------------------------------------------------------------------
+# Language-specific text
+#--------------------------------------------------------------------------
+
 # NOTE: To turn off "Current Events" in the sidebar,
 # set "currentevents" => "-"
 
@@ -240,6 +272,21 @@ this</a> (alternative: like this<a href=\"\" class=\"internal\">?</a>).",
        "Sep", "Oct", "Nov", "Dec"
 );
 
+/* private */ $wgMagicWordsEn = array(
+#   ID                                 CASE  SYNONYMS
+    MAG_REDIRECT             => array( 0,    "#redirect"              ),
+    MAG_NOTOC                => array( 0,    "__NOTOC__"              ),
+    MAG_START                => array( 0,    "__START__"              ),
+    MAG_CURRENTMONTH         => array( 1,    "{{CURRENTMONTH}}"       ),
+    MAG_CURRENTMONTHNAME     => array( 1,    "{{CURRENTMONTHNAME}}"   ),
+    MAG_CURRENTDAY           => array( 1,    "{{CURRENTDAY}}"         ),   
+    MAG_CURRENTDAYNAME       => array( 1,    "{{CURRENTDAYNAME}}"     ),
+    MAG_CURRENTYEAR          => array( 1,    "{{CURRENTYEAR}}"        ),
+    MAG_CURRENTTIME          => array( 1,    "{{CURRENTTIME}}"        ),
+    MAG_NUMBEROFARTICLES     => array( 1,    "{{NUMBEROFARTICLES}}"   ),
+    MAG_CURRENTMONTHNAMEGEN  => array( 1,    "{{CURRENTMONTHNAMEGEN}}"),
+);
+       
 # All special pages have to be listed here: a description of ""
 # will make them not show up on the "Special Pages" page, which
 # is the right thing for some of them (such as the "targeted" ones).
@@ -1144,6 +1191,10 @@ title. Please merge them manually.",
 
 );
 
+#--------------------------------------------------------------------------
+# Internationalisation code
+#--------------------------------------------------------------------------
+
 class Language {
 
        function getDefaultUserOptions () {
@@ -1494,6 +1545,21 @@ class Language {
 
        # For right-to-left language support
        function isRTL() { return false; }
+
+       function getMagicWords() 
+       {
+               global $wgMagicWordsEn;
+               return $wgMagicWordsEn;
+       }
+
+       # Fill a MagicWord object with data from here
+       function getMagic( &$mw )
+       {
+               $raw = $this->getMagicWords(); # don't worry, it's reference counted not deep copy
+               $rawEntry = $raw[$mw->mId];
+               $mw->mCaseSensitive = $rawEntry[0];
+               $mw->mSynonyms = array_slice( $rawEntry, 1 );
+       }
 }
 
 global $IP;