* @static
* @access public
*/
- function newFromText( $text, $defaultNamespace = NS_MAIN ) {
+ public static function newFromText( $text, $defaultNamespace = NS_MAIN ) {
$fname = 'Title::newFromText';
if( is_object( $text ) ) {
*/
$filteredText = Sanitizer::decodeCharReferences( $text );
- $t =& new Title();
+ $t = new Title();
$t->mDbkeyform = str_replace( ' ', '_', $filteredText );
$t->mDefaultNamespace = $defaultNamespace;
* @static
* @access public
*/
- function &makeTitle( $ns, $title ) {
- $t =& new Title();
+ public static function &makeTitle( $ns, $title ) {
+ $t = new Title();
$t->mInterwiki = '';
$t->mFragment = '';
$t->mNamespace = intval( $ns );
}
/**
- * Create a new Title frrom a namespace index and a DB key.
+ * Create a new Title from a namespace index and a DB key.
* The parameters will be checked for validity, which is a bit slower
* than makeTitle() but safer for user-provided data.
*
* @static
* @access public
*/
- function makeTitleSafe( $ns, $title ) {
+ public static function makeTitleSafe( $ns, $title ) {
$t = new Title();
$t->mDbkeyform = Title::makeName( $ns, $title );
if( $t->secureAndSplit() ) {
* @return Title the new object
* @access public
*/
- function newMainPage() {
+ public static function newMainPage() {
return Title::newFromText( wfMsgForContent( 'mainpage' ) );
}
* @static
* @access public
*/
- function newFromRedirect( $text ) {
- global $wgMwRedir;
+ public static function newFromRedirect( $text ) {
+ $mwRedir = MagicWord::get( 'redirect' );
$rt = NULL;
- if ( $wgMwRedir->matchStart( $text ) ) {
+ if ( $mwRedir->matchStart( $text ) ) {
if ( preg_match( '/\[{2}(.*?)(?:\||\]{2})/', $text, $m ) ) {
# categories are escaped using : for example one can enter:
# #REDIRECT [[:Category:Music]]. Need to remove it.
$rt = Title::newFromText( $m[1] );
# Disallow redirects to Special:Userlogout
- if ( !is_null($rt) && $rt->getNamespace() == NS_SPECIAL && preg_match( '/^Userlogout/i', $rt->getText() ) ) {
+ if ( !is_null($rt) && $rt->isSpecial( 'Userlogout' ) ) {
$rt = NULL;
}
}
* @static
* @access public
*/
- function legalChars() {
+ public static function legalChars() {
global $wgLegalTitleChars;
return $wgLegalTitleChars;
}
$lc = SearchEngine::legalSearchChars() . '&#;';
$t = $wgContLang->stripForSearch( $title );
$t = preg_replace( "/[^{$lc}]+/", ' ', $t );
- $t = strtolower( $t );
+ $t = $wgContLang->lc( $t );
# Handle 's, s'
$t = preg_replace( "/([{$lc}]+)'s( |$)/", "\\1 \\1's ", $t );
* @param string $title the DB key form the title
* @return string the prefixed form of the title
*/
- /* static */ function makeName( $ns, $title ) {
+ public static function makeName( $ns, $title ) {
global $wgContLang;
$n = $wgContLang->getNsText( $ns );
* @access public
*/
function getInterwikiLink( $key ) {
- global $wgMemc, $wgDBname, $wgInterwikiExpiry;
- global $wgInterwikiCache;
+ global $wgMemc, $wgInterwikiExpiry;
+ global $wgInterwikiCache, $wgContLang;
$fname = 'Title::getInterwikiLink';
- $key = strtolower( $key );
+ $key = $wgContLang->lc( $key );
- $k = $wgDBname.':interwiki:'.$key;
+ $k = wfMemcKey( 'interwiki', $key );
if( array_key_exists( $k, Title::$interwikiCache ) ) {
return Title::$interwikiCache[$k]->iw_url;
}
* @access public
*/
function getInterwikiCached( $key ) {
- global $wgDBname, $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite;
+ global $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite;
static $db, $site;
if (!$db)
$db=dba_open($wgInterwikiCache,'r','cdb');
/* Resolve site name */
if ($wgInterwikiScopes>=3 and !$site) {
- $site = dba_fetch("__sites:{$wgDBname}", $db);
+ $site = dba_fetch('__sites:' . wfWikiID(), $db);
if ($site=="")
$site = $wgInterwikiFallbackSite;
}
- $value = dba_fetch("{$wgDBname}:{$key}", $db);
+ $value = dba_fetch( wfMemcKey( $key ), $db);
if ($value=='' and $wgInterwikiScopes>=3) {
/* try site-level */
$value = dba_fetch("_{$site}:{$key}", $db);
$s->iw_url=$url;
$s->iw_local=(int)$local;
}
- Title::$interwikiCache[$wgDBname.':interwiki:'.$key] = $s;
+ Title::$interwikiCache[wfMemcKey( 'interwiki', $key )] = $s;
return $s->iw_url;
}
/**
* @access public
*/
function isLocal() {
- global $wgDBname;
-
if ( $this->mInterwiki != '' ) {
# Make sure key is loaded into cache
$this->getInterwikiLink( $this->mInterwiki );
- $k = $wgDBname.':interwiki:' . $this->mInterwiki;
+ $k = wfMemcKey( 'interwiki', $this->mInterwiki );
return (bool)(Title::$interwikiCache[$k]->iw_local);
} else {
return true;
* @access public
*/
function isTrans() {
- global $wgDBname;
-
if ($this->mInterwiki == '')
return false;
# Make sure key is loaded into cache
$this->getInterwikiLink( $this->mInterwiki );
- $k = $wgDBname.':interwiki:' . $this->mInterwiki;
+ $k = wfMemcKey( 'interwiki', $this->mInterwiki );
return (bool)(Title::$interwikiCache[$k]->iw_trans);
}
foreach ( $titles as $title ) {
if ( $wgUseFileCache ) {
- $cm = new CacheManager($title);
+ $cm = new HTMLFileCache($title);
@unlink($cm->fileCacheName());
}
*
* @param string $query an optional query string, not used
* for interwiki links
+ * @param string $variant language variant of url (for sr, zh..)
* @return string the URL
* @access public
*/
- function getFullURL( $query = '' ) {
+ function getFullURL( $query = '', $variant = false ) {
global $wgContLang, $wgServer, $wgRequest;
if ( '' == $this->mInterwiki ) {
- $url = $this->getLocalUrl( $query );
+ $url = $this->getLocalUrl( $query, $variant );
// Ugly quick hack to avoid duplicate prefixes (bug 4571 etc)
// Correct fix would be to move the prepending elsewhere.
* with action=render, $wgServer is prepended.
* @param string $query an optional query string; if not specified,
* $wgArticlePath will be used.
+ * @param string $variant language variant of url (for sr, zh..)
* @return string the URL
* @access public
*/
- function getLocalURL( $query = '' ) {
+ function getLocalURL( $query = '', $variant = false ) {
global $wgArticlePath, $wgScript, $wgServer, $wgRequest;
+ global $wgVariantArticlePath, $wgContLang, $wgUser;
+
+ // internal links should point to same variant as current page (only anonymous users)
+ if($variant == false && $wgContLang->hasVariants() && !$wgUser->isLoggedIn()){
+ $pref = $wgContLang->getPreferredVariant(false);
+ if($pref != $wgContLang->getCode())
+ $variant = $pref;
+ }
if ( $this->isExternal() ) {
$url = $this->getFullURL();
} else {
$dbkey = wfUrlencode( $this->getPrefixedDBkey() );
if ( $query == '' ) {
- $url = str_replace( '$1', $dbkey, $wgArticlePath );
+ if($variant!=false && $wgContLang->hasVariants()){
+ if($wgVariantArticlePath==false)
+ $variantArticlePath = "$wgScript?title=$1&variant=$2"; // default
+ else
+ $variantArticlePath = $wgVariantArticlePath;
+
+ $url = str_replace( '$2', urlencode( $variant ), $variantArticlePath );
+ $url = str_replace( '$1', $dbkey, $url );
+
+ }
+ else
+ $url = str_replace( '$1', $dbkey, $wgArticlePath );
} else {
global $wgActionPaths;
$url = false;
* internal hostname for the server from the exposed one.
*
* @param string $query an optional query string
+ * @param string $variant language variant of url (for sr, zh..)
* @return string the URL
* @access public
*/
- function getInternalURL( $query = '' ) {
+ function getInternalURL( $query = '', $variant = false ) {
global $wgInternalServer;
- $url = $wgInternalServer . $this->getLocalURL( $query );
+ $url = $wgInternalServer . $this->getLocalURL( $query, $variant );
wfRunHooks( 'GetInternalURL', array( &$this, &$url, $query ) );
return $url;
}
if( $action == 'create' ) {
if( ( $this->isTalkPage() && !$wgUser->isAllowed( 'createtalk' ) ) ||
( !$this->isTalkPage() && !$wgUser->isAllowed( 'createpage' ) ) ) {
+ wfProfileOut( $fname );
return false;
}
}
return $this->userCan('edit');
}
+ /**
+ * Can $wgUser create this page?
+ * @return boolean
+ * @access public
+ */
+ function userCanCreate() {
+ return $this->userCan('create');
+ }
+
/**
* Can $wgUser move this page?
* @return boolean
} else {
global $wgWhitelistRead;
- /** If anon users can create an account,
- they need to reach the login page first! */
- if( $wgUser->isAllowed( 'createaccount' )
- && $this->getNamespace() == NS_SPECIAL
+ /**
+ * Always grant access to the login page.
+ * Even anons need to be able to log in.
+ */
+ if( $this->getNamespace() == NS_SPECIAL
&& $this->getText() == 'Userlogin' ) {
return true;
}
* Check that the corresponding skin exists
*/
function isValidCssJsSubpage() {
- global $wgValidSkinNames;
- return( $this->isCssJsSubpage() && array_key_exists( $this->getSkinFromCssJsSubpage(), $wgValidSkinNames ) );
+ if ( $this->isCssJsSubpage() ) {
+ $skinNames = Skin::getSkinNames();
+ return array_key_exists( $this->getSkinFromCssJsSubpage(), $skinNames );
+ } else {
+ return false;
+ }
}
/**
* Trim down a .css or .js subpage title to get the corresponding skin name
);
if ($wgUseFileCache) {
- $cache = new CacheManager($this);
+ $cache = new HTMLFileCache($this);
@unlink($cache->fileCacheName());
}
do {
if ( preg_match( "/^(.+?)_*:_*(.*)$/S", $t, $m ) ) {
$p = $m[1];
- $lowerNs = strtolower( $p );
+ $lowerNs = $wgContLang->lc( $p );
if ( $ns = Namespace::getCanonicalIndex( $lowerNs ) ) {
# Canonical namespace
$t = $m[2];
# Interwiki link
$t = $m[2];
- $this->mInterwiki = strtolower( $p );
+ $this->mInterwiki = $wgContLang->lc( $p );
# Redundant interwiki prefix to the local wiki
if ( 0 == strcasecmp( $this->mInterwiki, $wgLocalInterwiki ) ) {
* @access public
*/
function getSquidURLs() {
- return array(
+ global $wgContLang;
+
+ $urls = array(
$this->getInternalURL(),
$this->getInternalURL( 'action=history' )
);
+
+ // purge variant urls as well
+ if($wgContLang->hasVariants()){
+ $variants = $wgContLang->getVariants();
+ foreach($variants as $vCode){
+ if($vCode==$wgContLang->getCode()) continue; // we don't want default variant
+ $urls[] = $this->getInternalURL('',$vCode);
+ }
+ }
+
+ return $urls;
}
function purgeSquid() {
* @private
*/
function moveOverExistingRedirect( &$nt, $reason = '' ) {
- global $wgUseSquid, $wgMwRedir;
+ global $wgUseSquid;
$fname = 'Title::moveOverExistingRedirect';
$comment = wfMsgForContent( '1movedto2', $this->getPrefixedText(), $nt->getPrefixedText() );
$linkCache->clearLink( $nt->getPrefixedDBkey() );
# Recreate the redirect, this time in the other direction.
- $redirectText = $wgMwRedir->getSynonym( 0 ) . ' [[' . $nt->getPrefixedText() . "]]\n";
+ $mwRedir = MagicWord::get( 'redirect' );
+ $redirectText = $mwRedir->getSynonym( 0 ) . ' [[' . $nt->getPrefixedText() . "]]\n";
$redirectArticle = new Article( $this );
$newid = $redirectArticle->insertOn( $dbw );
$redirectRevision = new Revision( array(
*/
function moveToNewTitle( &$nt, $reason = '' ) {
global $wgUseSquid;
- global $wgMwRedir;
$fname = 'MovePageForm::moveToNewTitle';
$comment = wfMsgForContent( '1movedto2', $this->getPrefixedText(), $nt->getPrefixedText() );
if ( $reason ) {
$linkCache->clearLink( $nt->getPrefixedDBkey() );
# Insert redirect
- $redirectText = $wgMwRedir->getSynonym( 0 ) . ' [[' . $nt->getPrefixedText() . "]]\n";
+ $mwRedir = MagicWord::get( 'redirect' );
+ $redirectText = $mwRedir->getSynonym( 0 ) . ' [[' . $nt->getPrefixedText() . "]]\n";
$redirectArticle = new Article( $this );
$newid = $redirectArticle->insertOn( $dbw );
$redirectRevision = new Revision( array(
if ( !$obj || 0 == $obj->page_is_redirect ) {
# Not a redirect
+ wfDebug( __METHOD__ . ": not a redirect\n" );
return false;
}
$text = Revision::getRevisionText( $obj );
# Does the redirect point to the source?
+ # Or is it a broken self-redirect, usually caused by namespace collisions?
if ( preg_match( "/\\[\\[\\s*([^\\]\\|]*)]]/", $text, $m ) ) {
$redirTitle = Title::newFromText( $m[1] );
if( !is_object( $redirTitle ) ||
- $redirTitle->getPrefixedDBkey() != $this->getPrefixedDBkey() ) {
+ ( $redirTitle->getPrefixedDBkey() != $this->getPrefixedDBkey() &&
+ $redirTitle->getPrefixedDBkey() != $nt->getPrefixedDBkey() ) ) {
+ wfDebug( __METHOD__ . ": redirect points to other page\n" );
return false;
}
} else {
# Fail safe
+ wfDebug( __METHOD__ . ": failsafe\n" );
return false;
}
$stack[$parent] = array();
} else {
$nt = Title::newFromText($parent);
- $stack[$parent] = $nt->getParentCategoryTree( $children + array($parent => 1) );
+ if ( $nt ) {
+ $stack[$parent] = $nt->getParentCategoryTree( $children + array($parent => 1) );
+ }
}
}
return $stack;
/**
* Get the revision ID of the previous revision
*
- * @param integer $revId Revision ID. Get the revision that was before this one.
- * @param string $timestamp The timestamp of the current revision, if known
+ * @param integer $revision Revision ID. Get the revision that was before this one.
* @return interger $oldrevision|false
*/
- function getPreviousRevisionID( $revId, $timestamp = false ) {
+ function getPreviousRevisionID( $revision ) {
+ $dbr =& wfGetDB( DB_SLAVE );
return $dbr->selectField( 'revision', 'rev_id',
'rev_page=' . intval( $this->getArticleId() ) .
' AND rev_id<' . intval( $revision ) . ' ORDER BY rev_id DESC' );
}
}
+ /**
+ * Get the last touched timestamp
+ */
+ function getTouched() {
+ $dbr =& wfGetDB( DB_SLAVE );
+ $touched = $dbr->selectField( 'page', 'page_touched',
+ array(
+ 'page_namespace' => $this->getNamespace(),
+ 'page_title' => $this->getDBkey()
+ ), __METHOD__
+ );
+ return $touched;
+ }
+
+ /**
+ * Get a cached value from a global cache that is invalidated when this page changes
+ * @param string $key the key
+ * @param callback $callback A callback function which generates the value on cache miss
+ *
+ * @deprecated use DependencyWrapper
+ */
+ function getRelatedCache( $memc, $key, $expiry, $callback, $params = array() ) {
+ return DependencyWrapper::getValueFromCache( $memc, $key, $expiry, $callback,
+ $params, new TitleDependency( $this ) );
+ }
+
function trackbackURL() {
global $wgTitle, $wgScriptPath, $wgServer;
* @return string
*/
function getNamespaceKey() {
+ global $wgContLang;
switch ($this->getNamespace()) {
case NS_MAIN:
case NS_TALK:
case NS_CATEGORY_TALK:
return 'nstab-category';
default:
- return 'nstab-' . strtolower( $this->getSubjectNsText() );
+ return 'nstab-' . $wgContLang->lc( $this->getSubjectNsText() );
+ }
+ }
+
+ /**
+ * Returns true if this title resolves to the named special page
+ * @param string $name The special page name
+ * @access public
+ */
+ function isSpecial( $name ) {
+ if ( $this->getNamespace() == NS_SPECIAL ) {
+ list( $thisName, $subpage ) = SpecialPage::resolveAliasWithSubpage( $this->getDBkey() );
+ if ( $name == $thisName ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * If the Title refers to a special page alias which is not the local default,
+ * returns a new Title which points to the local default. Otherwise, returns $this.
+ */
+ function fixSpecialName() {
+ if ( $this->getNamespace() == NS_SPECIAL ) {
+ $canonicalName = SpecialPage::resolveAlias( $this->mDbkeyform );
+ if ( $canonicalName ) {
+ $localName = SpecialPage::getLocalNameFor( $canonicalName );
+ if ( $localName != $this->mDbkeyform ) {
+ return Title::makeTitle( NS_SPECIAL, $localName );
+ }
+ }
}
+ return $this;
}
}
?>