From: Matt Johnston Date: Mon, 29 Sep 2008 10:08:46 +0000 (+0000) Subject: New format for accessing Interwiki data. Replaced all old ways within core I could... X-Git-Tag: 1.31.0-rc.0~45021 X-Git-Url: https://git.cyclocoop.org/%7B%24admin_url%7Dmembres/%7B%7B%20url_for%28%27vote%27%2C%20idvote=vote.voteid%29%20%7D%7D?a=commitdiff_plain;h=904c84d8d4f44254ea6b6aef1db077a6ac843e90;p=lhc%2Fweb%2Fwiklou.git New format for accessing Interwiki data. Replaced all old ways within core I could find, but should be backwards compatible wherever needed. Also fix the notes in RELEASE-NOTES to state PHP 5.2 recommended as certain classes require it (e.g. ForeignAPIRepo, which uses json_decode) --- diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 483b61b514..b5c92fa263 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -310,7 +310,7 @@ regularly. Below only new and removed languages are listed. == Compatibility == -MediaWiki 1.14 requires PHP 5 (5.1 recommended). PHP 4 is no longer supported. +MediaWiki 1.14 requires PHP 5 (5.2 recommended). PHP 4 is no longer supported. PHP 5.0.x fails on 64-bit systems due to serious bugs with array processing: http://bugs.php.net/bug.php?id=34879 diff --git a/config/index.php b/config/index.php index 785ec21a86..09c195614a 100644 --- a/config/index.php +++ b/config/index.php @@ -1702,7 +1702,7 @@ if ( \$wgCommandLineMode ) { ## you can enable inline LaTeX equations: \$wgUseTeX = false; -\$wgLocalInterwiki = \$wgSitename; +\$wgLocalInterwiki = strtolower( \$wgSitename ); \$wgLanguageCode = \"{$slconf['LanguageCode']}\"; diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index daa3cd8d54..c0fd122097 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -91,6 +91,7 @@ $wgAutoloadLocalClasses = array( 'ImageQueryPage' => 'includes/ImageQueryPage.php', 'IncludableSpecialPage' => 'includes/SpecialPage.php', 'IndexPager' => 'includes/Pager.php', + 'Interwiki' => 'includes/Interwiki.php', 'IP' => 'includes/IP.php', 'Job' => 'includes/JobQueue.php', 'License' => 'includes/Licenses.php', diff --git a/includes/Interwiki.php b/includes/Interwiki.php new file mode 100644 index 0000000000..4fa6b520d3 --- /dev/null +++ b/includes/Interwiki.php @@ -0,0 +1,217 @@ +mPrefix = $prefix; + $this->mURL = $url; + $this->mLocal = $local; + $this->mTrans = $trans; + } + + /** + * Fetch an Interwiki object + * + * @return Interwiki Object, or null if not valid + * @param $prefix string Interwiki prefix to use + */ + static public function fetch( $prefix ) { + if( isset( self::$smCache[$prefix] ) ){ + return self::$smCache[$prefix]; + } + global $wgInterwikiCache; + if ($wgInterwikiCache) { + return Interwiki::getInterwikiCached( $key ); + } + $iw = new Interwiki; + $iw->load( $prefix ); + if( self::CACHE_LIMIT && count( self::$smCache ) >= self::CACHE_LIMIT ){ + array_shift( self::$smCache ); + } + self::$smCache[$prefix] = &$iw; + return $iw; + } + + /** + * Fetch interwiki prefix data from local cache in constant database. + * + * @note More logic is explained in DefaultSettings. + * + * @param $key \type{\string} Database key + * @return \type{\string} URL of interwiki site + */ + protected static function getInterwikiCached( $key ) { + 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:' . wfWikiID(), $db); + if ($site=="") + $site = $wgInterwikiFallbackSite; + } + $value = dba_fetch( wfMemcKey( $key ), $db); + if ($value=='' and $wgInterwikiScopes>=3) { + /* try site-level */ + $value = dba_fetch("_{$site}:{$key}", $db); + } + if ($value=='' and $wgInterwikiScopes>=2) { + /* try globals */ + $value = dba_fetch("__global:{$key}", $db); + } + if ($value=='undef') + $value=''; + $s = new Interwiki( $key ); + if ( $value != '' ) { + list( $local, $url ) = explode( ' ', $value, 2 ); + $s->mURL = $url; + $s->mLocal = (int)$local; + } + if( self::CACHE_LIMIT && count( self::$smCache ) >= self::CACHE_LIMIT ){ + array_shift( self::$smCache ); + } + self::$smCache[$prefix] = &$s; + return $s; + } + + /** + * Clear all member variables in the current object. Does not clear + * the block from the DB. + */ + function clear() { + $this->mURL = ''; + $this->mLocal = $this->mTrans = 0; + $this->mPrefix = null; + } + + /** + * Get the DB object + * + * @return Database + */ + function &getDB(){ + $db = wfGetDB( DB_SLAVE ); + return $db; + } + + /** + * Load interwiki from the DB + * + * @param $prefix The interwiki prefix + * @return bool The prefix is valid + * + */ + function load( $prefix ) { + global $wgMemc; + $key = wfMemcKey( 'interwiki', $prefix ); + $mc = $wgMemc->get( $key ); + if( $mc ){ + if( $this->loadFromArray( $mc ) ){ + wfDebug("Succeeded\n"); + return true; + } + }else{ + $db =& $this->getDB(); + + $res = $db->resultObject( $db->select( 'interwiki', '*', array( 'iw_prefix' => $prefix ), + __METHOD__ ) ); + if ( $this->loadFromResult( $res ) ) { + $mc = array( 'url' => $this->mURL, 'local' => $this->mLocal, 'trans' => $this->mTrans ); + $wgMemc->add( $key, $mc ); + return true; + } + } + + # Give up + $this->clear(); + return false; + } + + /** + * Fill in member variables from an array (e.g. memcached result) + * + * @return bool Whether everything was there + * @param $res ResultWrapper Row from the interwiki table + */ + function loadFromArray( $mc ) { + if( isset( $mc['url'] ) && isset( $mc['local'] ) && isset( $mc['trans'] ) ){ + $this->mURL = $mc['url']; + $this->mLocal = $mc['local']; + $this->mTrans = $mc['trans']; + return true; + } + return false; + } + + /** + * Fill in member variables from a result wrapper + * + * @return bool Whether there was a row there + * @param $res ResultWrapper Row from the interwiki table + */ + function loadFromResult( ResultWrapper $res ) { + $ret = false; + if ( 0 != $res->numRows() ) { + # Get first entry + $row = $res->fetchObject(); + $this->initFromRow( $row ); + $ret = true; + } + $res->free(); + return $ret; + } + + /** + * Given a database row from the interwiki table, initialize + * member variables + * + * @param $row ResultWrapper A row from the interwiki table + */ + function initFromRow( $row ) { + $this->mPrefix = $row->iw_prefix; + $this->mURL = $row->iw_url; + $this->mLocal = $row->iw_local; + $this->mTrans = $row->iw_trans; + } + + /** + * Get the URL for a particular title (or with $1 if no title given) + * + * @param $title string What text to put for the article name + * @return string The URL + */ + function getURL( $title = null ){ + $url = $this->mURL; + if( $title != null ){ + $url = str_replace( "$1", $title, $url ); + } + return $url; + } + + function isLocal(){ + return $this->mLocal; + } + + function isTranscludable(){ + return $this->mTrans; + } + +} diff --git a/includes/Title.php b/includes/Title.php index c328d88950..d3ed52667b 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -404,100 +404,10 @@ class Title { * @return \type{\string} the associated URL, containing "$1", * which should be replaced by an article title * @static (arguably) + * @deprecated See Interwiki class */ public function getInterwikiLink( $key ) { - global $wgMemc, $wgInterwikiExpiry; - global $wgInterwikiCache, $wgContLang; - $fname = 'Title::getInterwikiLink'; - - if ( count( Title::$interwikiCache ) >= self::CACHE_MAX ) { - // Don't use infinite memory - reset( Title::$interwikiCache ); - unset( Title::$interwikiCache[ key( Title::$interwikiCache ) ] ); - } - - $key = $wgContLang->lc( $key ); - - $k = wfMemcKey( 'interwiki', $key ); - if( array_key_exists( $k, Title::$interwikiCache ) ) { - return Title::$interwikiCache[$k]->iw_url; - } - - if ($wgInterwikiCache) { - return Title::getInterwikiCached( $key ); - } - - $s = $wgMemc->get( $k ); - # Ignore old keys with no iw_local - if( $s && isset( $s->iw_local ) && isset($s->iw_trans)) { - Title::$interwikiCache[$k] = $s; - return $s->iw_url; - } - - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'interwiki', - array( 'iw_url', 'iw_local', 'iw_trans' ), - array( 'iw_prefix' => $key ), $fname ); - if( !$res ) { - return ''; - } - - $s = $dbr->fetchObject( $res ); - if( !$s ) { - # Cache non-existence: create a blank object and save it to memcached - $s = (object)false; - $s->iw_url = ''; - $s->iw_local = 0; - $s->iw_trans = 0; - } - $wgMemc->set( $k, $s, $wgInterwikiExpiry ); - Title::$interwikiCache[$k] = $s; - - return $s->iw_url; - } - - /** - * Fetch interwiki prefix data from local cache in constant database. - * - * @note More logic is explained in DefaultSettings. - * - * @param $key \type{\string} Database key - * @return \type{\string} URL of interwiki site - */ - public static function getInterwikiCached( $key ) { - 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:' . wfWikiID(), $db); - if ($site=="") - $site = $wgInterwikiFallbackSite; - } - $value = dba_fetch( wfMemcKey( $key ), $db); - if ($value=='' and $wgInterwikiScopes>=3) { - /* try site-level */ - $value = dba_fetch("_{$site}:{$key}", $db); - } - if ($value=='' and $wgInterwikiScopes>=2) { - /* try globals */ - $value = dba_fetch("__global:{$key}", $db); - } - if ($value=='undef') - $value=''; - $s = (object)false; - $s->iw_url = ''; - $s->iw_local = 0; - $s->iw_trans = 0; - if ($value!='') { - list($local,$url)=explode(' ',$value,2); - $s->iw_url=$url; - $s->iw_local=(int)$local; - } - Title::$interwikiCache[wfMemcKey( 'interwiki', $key )] = $s; - return $s->iw_url; + return Interwiki::fetch( $key )->getURL( ); } /** @@ -509,10 +419,7 @@ class Title { */ public function isLocal() { if ( $this->mInterwiki != '' ) { - # Make sure key is loaded into cache - $this->getInterwikiLink( $this->mInterwiki ); - $k = wfMemcKey( 'interwiki', $this->mInterwiki ); - return (bool)(Title::$interwikiCache[$k]->iw_local); + return Interwiki::fetch( $this->mInterwiki )->isLocal(); } else { return true; } @@ -527,10 +434,8 @@ class Title { public function isTrans() { if ($this->mInterwiki == '') return false; - # Make sure key is loaded into cache - $this->getInterwikiLink( $this->mInterwiki ); - $k = wfMemcKey( 'interwiki', $this->mInterwiki ); - return (bool)(Title::$interwikiCache[$k]->iw_trans); + + return Interwiki::fetch( $this->mInterwiki )->isTranscludable(); } /** @@ -778,7 +683,7 @@ class Title { $url = $wgServer . $url; } } else { - $baseUrl = $this->getInterwikiLink( $this->mInterwiki ); + $baseUrl = Interwiki::fetch( $this->mInterwiki )->getURL( ); $namespace = wfUrlencode( $this->getNsText() ); if ( '' != $namespace ) { @@ -2162,7 +2067,7 @@ class Title { # Ordinary namespace $dbkey = $m[2]; $this->mNamespace = $ns; - } elseif( $this->getInterwikiLink( $p ) ) { + } elseif( new Interwiki( $p ) ) { if( !$firstPass ) { # Can't make a local interwiki link to an interwiki link. # That's just crazy!