<?php
# See title.doc
-/* private static */ $title_interwiki_cache = array();
+$wgTitleInterwikiCache = array();
# Title class
#
# 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 );
$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 {
# 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 "";
$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 = "" ) {
# 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 ) ) ) {
}
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()
#
/* private */ function secureAndSplit()
{
- global $wgLang, $wgLocalInterwiki;
+ global $wgLang, $wgLocalInterwiki, $wgCapitalLinks;
$fname = "Title::secureAndSplit";
wfProfileIn( $fname );
# 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;
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;
}
# 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 );
# 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";
}
# 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;
+ }
+
}
?>