Don't complain about empty log file... I thought this had already been fixed
[lhc/web/wiklou.git] / includes / Title.php
index 0df3f6c..7c840b9 100644 (file)
@@ -1,12 +1,14 @@
 <?
 # See title.doc
-global $IP;
-include_once( "$IP/Interwiki.php" );
+
+/* private static */ $title_html_translation_table = array_flip( get_html_translation_table( HTML_ENTITIES ) );
+/* private static */ $title_interwiki_cache = array();
 
 class Title {
        /* private */ var $mTextform, $mUrlform, $mDbkeyform;
        /* private */ var $mNamespace, $mInterwiki, $mFragment;
        /* private */ var $mArticleID, $mRestrictions, $mRestrictionsLoaded;
+       /* private */ var $mPrefixedText;
 
        /* private */ function Title()
        {
@@ -24,16 +26,22 @@ class Title {
        {
                $t = new Title();
                $t->mDbkeyform = $key;
-               $t->secureAndSplit();
-               return $t;
+               if( $t->secureAndSplit() )
+                       return $t;
+               else
+                       return NULL;
        }
-
+       
        function newFromText( $text )
-       {
+       {       
+               global $title_html_translation_table;
+               $fname = "Title::newFromText";
+               wfProfileIn( $fname );
+               
                # Note - mixing latin1 named entities and unicode numbered
                # ones will result in a bad link.
-               $trans = get_html_translation_table( HTML_ENTITIES );
-               $trans = array_flip( $trans );
+               $trans =& $title_html_translation_table;
+
                $text = strtr( $text, $trans );
                
                $text = wfMungeToUtf8( $text );
@@ -42,13 +50,17 @@ class Title {
 
                $t = new Title();
                $t->mDbkeyform = str_replace( " ", "_", $text );
-               $t->secureAndSplit();
-               return $t;
+               wfProfileOut( $fname );
+               if( $t->secureAndSplit() ) {
+                       return $t;
+               } else {
+                       return NULL;
+               }
        }
 
        function newFromURL( $url )
        {
-               global $wgLang, $wgServer, $HTTP_SERVER_VARS;
+               global $wgLang, $wgServer;
                
                $t = new Title();
                $s = urldecode( $url ); # This is technically wrong, as anything
@@ -58,14 +70,33 @@ class Title {
                
                # For links that came from outside, check for alternate/legacy
                # character encoding.
-               if( strncmp($wgServer, $HTTP_SERVER_VARS["HTTP_REFERER"], strlen( $wgServer ) ) )
+               wfDebug( "Refer: {$_SERVER['HTTP_REFERER']}\n" );
+               wfDebug( "Servr: $wgServer\n" );
+               if( empty( $_SERVER["HTTP_REFERER"] ) ||
+                       strncmp($wgServer, $_SERVER["HTTP_REFERER"], strlen( $wgServer ) ) )
                        $s = $wgLang->checkTitleEncoding( $s );
                
                $t->mDbkeyform = str_replace( " ", "_", $s );
-               $t->secureAndSplit();
-               return $t;
+               if( $t->secureAndSplit() ) {
+                       return $t;
+               } else {
+                       return NULL;
+               }
+       }
+
+       function nameOf( $id )
+       {
+               $sql = "SELECT cur_namespace,cur_title FROM cur WHERE " .
+                 "cur_id={$id}";
+               $res = wfQuery( $sql, DB_READ, "Article::nameOf" );
+               if ( 0 == wfNumRows( $res ) ) { return NULL; }
+
+               $s = wfFetchObject( $res );
+               $n = Title::makeName( $s->cur_namespace, $s->cur_title );
+               return $n;
        }
 
+
        function legalChars()
        {
                global $wgInputEncoding;
@@ -80,12 +111,34 @@ class Title {
        }
 
        function getInterwikiLink( $key )
-       {
-               global $wgValidInterwikis;
+       {       
+               # Performance note: It would probably be a good idea to 
+               # get/set/fetch the entire $title_interwiki_cache with memcache 
+               # here, reducing some overhead for the repeated memcache accesses. 
+               # Popular pages often has many interwiki links anyways.
+
+               global $wgMemc, $wgDBname, $title_interwiki_cache;
+               $k = "$wgDBname:interwiki:$key";
 
-               if ( array_key_exists( $key, $wgValidInterwikis ) ) {
-                       return $wgValidInterwikis[$key];
-               } else return "";
+               if( array_key_exists( $k, $title_interwiki_cache ) )
+                       return $title_interwiki_cache[$k]->iw_url;
+
+               $s = $wgMemc->get( $k ); 
+               if( $s !== false ) return $s->iw_url;
+               
+               $dkey = wfStrencode( $key );
+               $query = "SELECT iw_url FROM interwiki WHERE iw_prefix='$dkey'";
+               $res = wfQuery( $query, DB_READ, "Title::getInterwikiLink" );
+               if(!$res) return "";
+               
+               $s = wfFetchObject( $res );
+               if(!$s) {
+                       $s = (object)false;
+                       $s->iw_url = "";
+               }
+               $wgMemc->set( $k, $s );
+               $title_interwiki_cache[$k] = $s;                
+               return $s->iw_url;
        }
 
        function getText() { return $this->mTextform; }
@@ -135,8 +188,11 @@ class Title {
        {
                $t = new Title();
                $t->mDbkeyform = Title::makeName( $ns, $title );
-               $t->secureAndSplit();
-               return $t;
+               if( $t->secureAndSplit() ) {
+                       return $t;
+               } else {
+                       return NULL;
+               }
        }
 
        function getPrefixedDBkey()
@@ -148,9 +204,13 @@ class Title {
 
        function getPrefixedText()
        {
-               $s = $this->prefix( $this->mTextform );
-               $s = str_replace( "_", " ", $s );
-               return $s;
+          # TEST THIS @@@
+               if ( empty( $this->mPrefixedText ) ) {
+                       $s = $this->prefix( $this->mTextform );
+                       $s = str_replace( "_", " ", $s );
+                       $this->mPrefixedText = $s;
+               }
+               return $this->mPrefixedText;
        }
 
        function getPrefixedURL()
@@ -169,12 +229,12 @@ class Title {
 
        function getFullURL()
        {
-               global $wgLang, $wgArticlePath, $wgValidInterwikis;
+               global $wgLang, $wgArticlePath;
 
                if ( "" == $this->mInterwiki ) {
                        $p = $wgArticlePath;
                } else {
-                       $p = $wgValidInterwikis[$this->mInterwiki];
+                       $p = $this->getInterwikiLink( $this->mInterwiki );
                }
                $n = $wgLang->getNsText( $this->mNamespace );
                if ( "" != $n ) { $n .= ":"; }
@@ -194,7 +254,13 @@ class Title {
 
                return $s;
        }
-
+       
+       # For the title field in <a> tags
+       function getEscapedText()
+       {
+               return wfEscapeHTML( $this->getPrefixedText() );
+       }
+       
        function isExternal() { return ( "" != $this->mInterwiki ); }
 
        function isProtected()
@@ -256,14 +322,24 @@ class Title {
                }
                return $this->mRestrictions;
        }
+       
+       function isDeleted() {
+               $ns = $this->getNamespace();
+               $t = wfStrencode( $this->getDBkey() );
+               $sql = "SELECT COUNT(*) AS n FROM archive WHERE ar_namespace=$ns AND ar_title='$t'";
+               if( $res = wfQuery( $sql, DB_READ ) ) {
+                       $s = wfFetchObject( $res );
+                       return $s->n;
+               }
+               return 0;
+       }
 
        function getArticleID()
        {
                global $wgLinkCache;
 
                if ( -1 != $this->mArticleID ) { return $this->mArticleID; }
-               $this->mArticleID = $wgLinkCache->addLink(
-                 $this->getPrefixedDBkey() );
+               $this->mArticleID = $wgLinkCache->addLinkObj( $this );
                return $this->mArticleID;
        }
 
@@ -277,6 +353,14 @@ class Title {
                $this->mRestrictionsLoaded = false;
                $this->mRestrictions = array();
        }
+       
+       function invalidateCache() {
+               $now = wfTimestampNow();
+               $ns = $this->getNamespace();
+               $ti = wfStrencode( $this->getDBkey() );
+               $sql = "UPDATE cur SET cur_touched='$now' WHERE cur_namespace=$ns AND cur_title='$ti'";
+               return wfQuery( $sql, DB_WRITE, "Title::invalidateCache" );
+       }
 
        /* private */ function prefix( $name )
        {
@@ -296,65 +380,64 @@ class Title {
     # and uses undersocres, but not otherwise munged.  This function
     # removes illegal characters, splits off the winterwiki and
     # namespace prefixes, sets the other forms, and canonicalizes
-    # everything.  This one function is really at the core of
-       # Wiki--don't mess with it unless you're really sure you know
-       # what you're doing.
+    # everything.      
        #
        /* private */ function secureAndSplit()
        {
-               global $wgLang, $wgValidInterwikis, $wgLocalInterwiki;
+               global $wgLang, $wgLocalInterwiki;
+               $fname = "Title::secureAndSplit";
+               wfProfileIn( $fname );
+               
+               static $imgpre = false;
+               static $rxTc = false;
+
+               # Initialisation
+               if ( $imgpre === false ) {
+                       $imgpre = ":" . $wgLang->getNsText( Namespace::getImage() ) . ":";
+                       $rxTc = "/[^" . Title::legalChars() . "]/";
+               }
 
-               $validNamespaces = $wgLang->getNamespaces();
-               unset( $validNamespaces[0] );
 
                $this->mInterwiki = $this->mFragment = "";
                $this->mNamespace = 0;
 
                $t = preg_replace( "/[\\s_]+/", "_", $this->mDbkeyform );
-               if ( "_" == $t{0} ) { $t = substr( $t, 1 ); }
+               if ( "_" == $t{0} ) { 
+                       $t = substr( $t, 1 ); 
+               }
                $l = strlen( $t );
-               if ( $l && ( "_" == $t{$l-1} ) ) { $t = substr( $t, 0, $l-1 ); }
-               if ( "" == $t ) { $t = "_"; }
+               if ( $l && ( "_" == $t{$l-1} ) ) { 
+                       $t = substr( $t, 0, $l-1 ); 
+               }
+               if ( "" == $t ) {
+                       wfProfileOut( $fname );
+                       return false;
+               }
 
                $this->mDbkeyform = $t;
                $done = false;
 
-               $imgpre = ":" . $wgLang->getNsText( Namespace::getImage() ) . ":";
                if ( 0 == strncasecmp( $imgpre, $t, strlen( $imgpre ) ) ) {
                        $t = substr( $t, 1 );
                }
                if ( ":" == $t{0} ) {
                        $r = substr( $t, 1 );
                } else {
-                       if ( preg_match( "/^((?:i|x|[a-z]{2,3})(?:-[a-z0-9]+)?|[A-Za-z0-9_\\x80-\\xff]+):(.*)$/", $t, $m ) ) {
+                       if ( preg_match( "/^((?:i|x|[a-z]{2,3})(?:-[a-z0-9]+)?|[A-Za-z0-9_\\x80-\\xff]+):_*(.*)$/", $t, $m ) ) {
                                #$p = strtolower( $m[1] );
                                $p = $m[1];
-                               if ( array_key_exists( $p, $wgValidInterwikis ) ) {
+                               if ( $ns = $wgLang->getNsIndex( strtolower( $p ) )) {
+                                       $t = $m[2];
+                                       $this->mNamespace = $ns;
+                               } elseif ( $this->getInterwikiLink( $p ) ) {
                                        $t = $m[2];
                                        $this->mInterwiki = $p;
 
-                                       if ( preg_match( "/^([A-Za-z0-9_\\x80-\\xff]+):(.*)$/",
-                                         $t, $m ) ) {
-                                               $p = strtolower( $m[1] );
-                                       } else {
+                                       if ( !preg_match( "/^([A-Za-z0-9_\\x80-\\xff]+):(.*)$/", $t, $m ) ) {
                                                $done = true;
-                                       }
-                                       if($this->mInterwiki != $wgLocalInterwiki)
+                                       } elseif($this->mInterwiki != $wgLocalInterwiki) {
                                                $done = true;
-                               }
-                               if ( ! $done ) {
-                                       if ( $ns = $wgLang->getNsIndex( str_replace( " ", "_", $p ))) {
-                                               $t = $m[2];
-                                               $this->mNamespace = $ns;
                                        }
-                               #       foreach ( $validNamespaces as $ns ) {
-                               #               if ( 0 == strcasecmp( $p, $ns ) ) {
-                               #                       $t = $m[2];
-                               #                       $this->mNamespace = $wgLang->getNsIndex(
-                               #                         str_replace( " ", "_", $p ) );
-                               #                       break;
-                               #               }
-                               #       }
                                }
                        }
                        $r = $t;
@@ -374,13 +457,23 @@ class Title {
                }
                # Strip illegal characters.
                #
-               $tc = Title::legalChars();
-               $t = preg_replace( "/[^{$tc}]/", "", $r );
+               $t = preg_replace( $rxTc, "", $r );
 
                if( $this->mInterwiki == "") $t = $wgLang->ucfirst( $t );
                $this->mDbkeyform = $t;
                $this->mUrlform = wfUrlencode( $t );
                $this->mTextform = str_replace( "_", " ", $t );
+               
+               wfProfileOut( $fname );
+               return true;
+       }
+       
+       function getTalkPage() {
+               return Title::makeTitle( Namespace::getTalk( $this->getNamespace() ), $this->getDBkey() );
+       }
+       
+       function getSubjectPage() {
+               return Title::makeTitle( Namespace::getSubject( $this->getNamespace() ), $this->getDBkey() );
        }
 }
 ?>