accidentially removed the test for
[lhc/web/wiklou.git] / includes / Title.php
index 3de57d4..255cc15 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 # See title.doc
 
-/* private static */ $title_interwiki_cache = array();
+$wgTitleInterwikiCache = array();
 
 # Title class
 # 
@@ -55,25 +55,15 @@ class Title {
        # From text, such as what you would find in a link
        /* static */ function newFromText( $text, $defaultNamespace = 0 )
        {       
-               static $trans;
                $fname = "Title::newFromText";
                wfProfileIn( $fname );
-               
-               # Note - mixing latin1 named entities and unicode numbered
-               # ones will result in a bad link.
-               if( !isset( $trans ) ) {
-                       global $wgInputEncoding;
-                       $trans = array_flip( get_html_translation_table( HTML_ENTITIES ) );
-                       if( strcasecmp( "utf-8", $wgInputEncoding ) == 0 ) {
-                           $trans = array_map( "utf8_encode", $trans );
-                       }
-               }
 
                if( is_object( $text ) ) {
                        wfDebugDieBacktrace( "Called with object instead of string." );
                }
-               $text = strtr( $text, $trans );
-               
+               global $wgInputEncoding;
+               $text = do_html_entity_decode( $text, ENT_COMPAT, $wgInputEncoding );
+
                $text = wfMungeToUtf8( $text );
                
                
@@ -82,9 +72,12 @@ class Title {
 
                $t = new Title();
                $t->mDbkeyform = str_replace( " ", "_", $text );
-        $t->mDefaultNamespace = $defaultNamespace;
-        
+               $t->mDefaultNamespace = $defaultNamespace;
+
                wfProfileOut( $fname );
+               if ( !is_object( $t ) ) {
+                       var_dump( debug_backtrace() );
+               }
                if( $t->secureAndSplit() ) {
                        return $t;
                } else {
@@ -235,19 +228,22 @@ class Title {
        # The URL contains $1, which is replaced by the title
        function getInterwikiLink( $key )
        {       
-               global $wgMemc, $wgDBname, $title_interwiki_cache;
+               global $wgMemc, $wgDBname, $wgInterwikiExpiry;
+               static $wgTitleInterwikiCache = array();
+
                $k = "$wgDBname:interwiki:$key";
 
-               if( array_key_exists( $k, $title_interwiki_cache ) )
-                       return $title_interwiki_cache[$k]->iw_url;
+               if( array_key_exists( $k, $wgTitleInterwikiCache ) )
+                       return $wgTitleInterwikiCache[$k]->iw_url;
 
                $s = $wgMemc->get( $k ); 
-               if( $s ) { 
-                       $title_interwiki_cache[$k] = $s;
+               # Ignore old keys with no iw_local
+               if( $s && isset( $s->iw_local ) ) { 
+                       $wgTitleInterwikiCache[$k] = $s;
                        return $s->iw_url;
                }
                $dkey = wfStrencode( $key );
-               $query = "SELECT iw_url FROM interwiki WHERE iw_prefix='$dkey'";
+               $query = "SELECT iw_url,iw_local FROM interwiki WHERE iw_prefix='$dkey'";
                $res = wfQuery( $query, DB_READ, "Title::getInterwikiLink" );
                if(!$res) return "";
                
@@ -256,11 +252,24 @@ class Title {
                        $s = (object)false;
                        $s->iw_url = "";
                }
-               $wgMemc->set( $k, $s );
-               $title_interwiki_cache[$k] = $s;
+               $wgMemc->set( $k, $s, $wgInterwikiExpiry );
+               $wgTitleInterwikiCache[$k] = $s;
                return $s->iw_url;
        }
-       
+
+       function isLocal() {
+               global $wgTitleInterwikiCache, $wgDBname;
+
+               if ( $this->mInterwiki != "" ) {
+                       # Make sure key is loaded into cache
+                       $this->getInterwikiLink( $this->mInterwiki );
+                       $k = "$wgDBname:interwiki:" . $this->mInterwiki;
+                       return (bool)($wgTitleInterwikiCache[$k]->iw_local);
+               } else {
+                       return true;
+               }
+       }
+
        # Update the cur_touched field for an array of title objects
        # Inefficient unless the IDs are already loaded into the link cache
        /* static */ function touchArray( $titles, $timestamp = "" ) {
@@ -477,12 +486,20 @@ class Title {
        # Can $wgUser edit this page?
        function userCanEdit()
        {
-               global $wgUser;
 
                if ( -1 == $this->mNamespace ) { return false; }
                # if ( 0 == $this->getArticleID() ) { return false; }
                if ( $this->mDbkeyform == "_" ) { return false; }
-
+               //if ( $this->isCssJsSubpage() and !$this->userCanEditCssJsSubpage() ) { return false; }
+               # protect css/js subpages of user pages
+               # XXX: this might be better using restrictions
+               # XXX: Find a way to work around the php bug that prevents using $this->userCanEditCssJsSubpage() from working
+               global $wgUser;
+               if( Namespace::getUser() == $this->mNamespace
+                       and preg_match("/\\.(css|js)$/", $this->mTextform )
+                       and !$wgUser->isSysop()
+                       and !preg_match("/^".preg_quote($wgUser->getName(), '/')."/", $this->mTextform) )
+               { return false; }
                $ur = $wgUser->getRights();
                foreach ( $this->getRestrictions() as $r ) {
                        if ( "" != $r && ( ! in_array( $r, $ur ) ) ) {
@@ -491,6 +508,39 @@ class Title {
                }
                return true;
        }
+       
+       function userCanRead() {
+               global $wgUser;
+               global $wgWhitelistRead;
+               
+               if( 0 != $wgUser->getID() ) return true;
+               if( !is_array( $wgWhitelistRead ) ) return true;
+               
+               $name = $this->getPrefixedText();
+               if( in_array( $name, $wgWhitelistRead ) ) return true;
+               
+               # Compatibility with old settings
+               if( $this->getNamespace() == NS_ARTICLE ) {
+                       if( in_array( ":" . $name, $wgWhitelistRead ) ) return true;
+               }
+               return false;
+       }
+       
+       function isCssJsSubpage() {
+               return ( Namespace::getUser() == $this->mNamespace and preg_match("/\\.(css|js)$/", $this->mTextform ) );
+       }
+       function isCssSubpage() {
+               return ( Namespace::getUser() == $this->mNamespace and preg_match("/\\.css$/", $this->mTextform ) );
+       }
+       function isJsSubpage() {
+               return ( Namespace::getUser() == $this->mNamespace and preg_match("/\\.js$/", $this->mTextform ) );
+       }
+       function userCanEditCssJsSubpage() {
+               # protect css/js subpages of user pages
+               # XXX: this might be better using restrictions
+               global $wgUser;
+               return ( $wgUser->isSysop() or preg_match("/^".preg_quote($wgUser->getName())."/", $this->mTextform) );
+       }
 
        # Accessor/initialisation for mRestrictions
        function getRestrictions()
@@ -578,7 +628,7 @@ class Title {
        #
        /* private */ function secureAndSplit()
        {
-               global $wgLang, $wgLocalInterwiki;
+               global $wgLang, $wgLocalInterwiki, $wgCapitalLinks;
                $fname = "Title::secureAndSplit";
                wfProfileIn( $fname );
                
@@ -597,13 +647,8 @@ class Title {
                # Clean up whitespace
                #
                $t = preg_replace( "/[\\s_]+/", "_", $this->mDbkeyform );
-               if ( "_" == @$t{0} ) { 
-                       $t = substr( $t, 1 ); 
-               }
-               $l = strlen( $t );
-               if ( $l && ( "_" == $t{$l-1} ) ) { 
-                       $t = substr( $t, 0, $l-1 ); 
-               }
+               $t = preg_replace( '/^_*(.*?)_*$/', '$1', $t );
+
                if ( "" == $t ) {
                        wfProfileOut( $fname );
                        return false;
@@ -626,7 +671,12 @@ class Title {
                        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 ( $ns = $wgLang->getNsIndex( strtolower( $p ) )) {
+                               $lowerNs = strtolower( $p );
+                               if ( $ns = Namespace::getCanonicalIndex( $lowerNs ) ) {
+                                       # Canonical namespace
+                                       $t = $m[2];
+                                       $this->mNamespace = $ns;
+                               } elseif ( $ns = $wgLang->getNsIndex( $lowerNs )) {
                                        # Ordinary namespace
                                        $t = $m[2];
                                        $this->mNamespace = $ns;
@@ -672,8 +722,10 @@ class Title {
                }
 
                # Initial capital letter
-               if( $this->mInterwiki == "") $t = $wgLang->ucfirst( $r );
-
+               if( $wgCapitalLinks && $this->mInterwiki == "") {
+                       $t = $wgLang->ucfirst( $r );
+               }
+               
                # Fill fields
                $this->mDbkeyform = $t;
                $this->mUrlform = wfUrlencode( $t );
@@ -748,14 +800,14 @@ class Title {
        # Returns true on success, message name on failure
        # auth indicates whether wgUser's permissions should be checked
        function moveTo( &$nt, $auth = true ) {
-               $fname = "Title::move";
-               $oldid = $this->getArticleID();
-               $newid = $nt->getArticleID();
-
                if( !$this or !$nt ) {
                        return "badtitletext";
                }
 
+               $fname = "Title::move";
+               $oldid = $this->getArticleID();
+               $newid = $nt->getArticleID();
+
                if ( strlen( $nt->getDBkey() ) < 1 ) {
                        return "articleexists";
                }
@@ -1043,5 +1095,50 @@ class Title {
                # Return true if there was no history
                return $row === false;
        }
+       
+       # Create a redirect, fails if the title already exists, does not notify RC
+       # Returns success
+       function createRedirect( $dest, $comment ) {
+               global $wgUser;
+               if ( $this->getArticleID() ) {
+                       return false;
+               }
+               
+               $now = wfTimestampNow();
+               $won = wfInvertTimestamp( $now );
+
+               wfInsertArray( 'cur', array(
+                       'cur_namespace' => $this->getNamespace(),
+                       'cur_title' => $this->getDBkey(),
+                       'cur_comment' => $comment,
+                       'cur_user' => $wgUser->getID(),
+                       'cur_user_text' => $wgUser->getName(),
+                       'cur_timestamp' => $now,
+                       'inverse_timestamp' => $won,
+                       'cur_touched' => $now,
+                       'cur_is_redirect' => 1,
+                       'cur_is_new' => 1,
+                       'cur_text' => "#REDIRECT [[" . $dest->getPrefixedText() . "]]\n" 
+               ));
+               $newid = wfInsertId();
+               $this->resetArticleID( $newid );
+               
+               # Link table
+               if ( $dest->getArticleID() ) {
+                       wfInsertArray( 'links', array(
+                               'l_to' => $dest->getArticleID(),
+                               'l_from' => $newid
+                       ));
+               } else {
+                       wfInsertArray( 'brokenlinks', array( 
+                               'bl_to' => $dest->getPrefixedDBkey(),
+                               'bl_from' => $newid
+                       ));
+               }
+
+               Article::onArticleCreate( $this );
+               return true;
+       }
+       
 }
 ?>