00001 <?php
00012 class Interwiki {
00013
00014
00015 protected static $smCache = array();
00016 const CACHE_LIMIT = 100;
00017
00018 protected $mPrefix, $mURL, $mLocal, $mTrans;
00019
00020 function __construct( $prefix = null, $url = '', $local = 0, $trans = 0 )
00021 {
00022 $this->mPrefix = $prefix;
00023 $this->mURL = $url;
00024 $this->mLocal = $local;
00025 $this->mTrans = $trans;
00026 }
00027
00034 static public function isValidInterwiki( $prefix ){
00035 $result = self::fetch( $prefix );
00036 return (bool)$result;
00037 }
00038
00045 static public function fetch( $prefix ) {
00046 global $wgContLang;
00047 if( $prefix == '' ) {
00048 return null;
00049 }
00050 $prefix = $wgContLang->lc( $prefix );
00051 if( isset( self::$smCache[$prefix] ) ){
00052 return self::$smCache[$prefix];
00053 }
00054 global $wgInterwikiCache;
00055 if ($wgInterwikiCache) {
00056 $iw = Interwiki::getInterwikiCached( $prefix );
00057 } else {
00058 $iw = Interwiki::load( $prefix );
00059 if( !$iw ){
00060 $iw = false;
00061 }
00062 }
00063 if( self::CACHE_LIMIT && count( self::$smCache ) >= self::CACHE_LIMIT ){
00064 reset( self::$smCache );
00065 unset( self::$smCache[ key( self::$smCache ) ] );
00066 }
00067 self::$smCache[$prefix] = $iw;
00068 return $iw;
00069 }
00070
00079 protected static function getInterwikiCached( $prefix ) {
00080 $value = self::getInterwikiCacheEntry( $prefix );
00081
00082 $s = new Interwiki( $prefix );
00083 if ( $value != '' ) {
00084
00085 list( $local, $url ) = explode( ' ', $value, 2 );
00086 $s->mURL = $url;
00087 $s->mLocal = (int)$local;
00088 }else{
00089 $s = false;
00090 }
00091 return $s;
00092 }
00093
00102 protected static function getInterwikiCacheEntry( $prefix ){
00103 global $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite;
00104 static $db, $site;
00105
00106 wfDebug( __METHOD__ . "( $prefix )\n" );
00107 if( !$db ){
00108 $db = dba_open( $wgInterwikiCache, 'r', 'cdb' );
00109 }
00110
00111 if( $wgInterwikiScopes>=3 && !$site ) {
00112 $site = dba_fetch( '__sites:' . wfWikiID(), $db );
00113 if ( $site == "" ){
00114 $site = $wgInterwikiFallbackSite;
00115 }
00116 }
00117
00118 $value = dba_fetch( wfMemcKey( $prefix ), $db );
00119
00120 if ( $value == '' && $wgInterwikiScopes >= 3 ) {
00121 $value = dba_fetch( "_{$site}:{$prefix}", $db );
00122 }
00123
00124 if ( $value == '' && $wgInterwikiScopes >= 2 ) {
00125 $value = dba_fetch( "__global:{$prefix}", $db );
00126 }
00127 if ( $value == 'undef' )
00128 $value = '';
00129
00130 return $value;
00131 }
00132
00141 protected static function load( $prefix ) {
00142 global $wgMemc, $wgInterwikiExpiry;
00143 $key = wfMemcKey( 'interwiki', $prefix );
00144 $mc = $wgMemc->get( $key );
00145 $iw = false;
00146 if( $mc && is_array( $mc ) ){
00147 $iw = Interwiki::loadFromArray( $mc );
00148 if( $iw ){
00149 return $iw;
00150 }
00151 }
00152
00153 $db = wfGetDB( DB_SLAVE );
00154
00155 $row = $db->fetchRow( $db->select( 'interwiki', '*', array( 'iw_prefix' => $prefix ),
00156 __METHOD__ ) );
00157 $iw = Interwiki::loadFromArray( $row );
00158 if ( $iw ) {
00159 $mc = array( 'iw_url' => $iw->mURL, 'iw_local' => $iw->mLocal, 'iw_trans' => $iw->mTrans );
00160 $wgMemc->add( $key, $mc, $wgInterwikiExpiry );
00161 return $iw;
00162 }
00163
00164 return false;
00165 }
00166
00174 protected static function loadFromArray( $mc ) {
00175 if( isset( $mc['iw_url'] ) && isset( $mc['iw_local'] ) && isset( $mc['iw_trans'] ) ){
00176 $iw = new Interwiki();
00177 $iw->mURL = $mc['iw_url'];
00178 $iw->mLocal = $mc['iw_local'];
00179 $iw->mTrans = $mc['iw_trans'];
00180 return $iw;
00181 }
00182 return false;
00183 }
00184
00191 function getURL( $title = null ){
00192 $url = $this->mURL;
00193 if( $title != null ){
00194 $url = str_replace( "$1", $title, $url );
00195 }
00196 return $url;
00197 }
00198
00199 function isLocal(){
00200 return $this->mLocal;
00201 }
00202
00203 function isTranscludable(){
00204 return $this->mTrans;
00205 }
00206
00207 }