(bug 15831) Modern skin RTL support is bugous
[mediawiki.git] / includes / Interwiki.php
bloba705591426c4e7823bf067f12f9cb0450200c1fe
1 <?php
2 /**
3 * @file
4 * Interwiki table entry
5 */
7 /**
8 * The interwiki class
9 * All information is loaded on creation when called by Interwiki::fetch( $prefix ).
10 * All work is done on slave, because this should *never* change (except during schema updates etc, which arent wiki-related)
12 class Interwiki {
14 // Cache - removed in LRU order when it hits limit
15 protected static $smCache = array();
16 const CACHE_LIMIT = 100; // 0 means unlimited, any other value is max number of entries.
18 protected $mPrefix, $mURL, $mLocal, $mTrans;
20 function __construct( $prefix = null, $url = '', $local = 0, $trans = 0 )
22 $this->mPrefix = $prefix;
23 $this->mURL = $url;
24 $this->mLocal = $local;
25 $this->mTrans = $trans;
28 /**
29 * Check whether an interwiki prefix exists
31 * @return bool Whether it exists
32 * @param $prefix string Interwiki prefix to use
34 static public function isValidInterwiki( $prefix ){
35 global $wgContLang;
36 $prefix = $wgContLang->lc( $prefix );
37 if( isset( self::$smCache[$prefix] ) ){
38 return true;
40 global $wgInterwikiCache;
41 if ($wgInterwikiCache) {
42 return Interwiki::isValidInterwikiCached( $key );
44 $iw = new Interwiki;
45 if( !$iw->load( $prefix ) ){
46 return false;
48 if( self::CACHE_LIMIT && count( self::$smCache ) >= self::CACHE_LIMIT ){
49 array_shift( self::$smCache );
51 self::$smCache[$prefix] = &$iw;
52 return true;
55 /**
56 * Fetch an Interwiki object
58 * @return Interwiki Object, or null if not valid
59 * @param $prefix string Interwiki prefix to use
61 static public function fetch( $prefix ) {
62 global $wgContLang;
63 $prefix = $wgContLang->lc( $prefix );
64 if( isset( self::$smCache[$prefix] ) ){
65 return self::$smCache[$prefix];
67 global $wgInterwikiCache;
68 if ($wgInterwikiCache) {
69 return Interwiki::getInterwikiCached( $key );
71 $iw = new Interwiki;
72 if( !$iw->load( $prefix ) ){
73 return false;
75 if( self::CACHE_LIMIT && count( self::$smCache ) >= self::CACHE_LIMIT ){
76 array_shift( self::$smCache );
78 self::$smCache[$prefix] = &$iw;
79 return $iw;
82 /**
83 * Fetch interwiki prefix data from local cache in constant database.
85 * @note More logic is explained in DefaultSettings.
87 * @param $key \type{\string} Database key
88 * @return \type{\Interwiki} An interwiki object
90 protected static function getInterwikiCached( $key ) {
91 global $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite;
92 static $db, $site;
94 if (!$db)
95 $db=dba_open($wgInterwikiCache,'r','cdb');
96 /* Resolve site name */
97 if ($wgInterwikiScopes>=3 and !$site) {
98 $site = dba_fetch('__sites:' . wfWikiID(), $db);
99 if ($site=="")
100 $site = $wgInterwikiFallbackSite;
102 $value = dba_fetch( wfMemcKey( $key ), $db);
103 if ($value=='' and $wgInterwikiScopes>=3) {
104 /* try site-level */
105 $value = dba_fetch("_{$site}:{$key}", $db);
107 if ($value=='' and $wgInterwikiScopes>=2) {
108 /* try globals */
109 $value = dba_fetch("__global:{$key}", $db);
111 if ($value=='undef')
112 $value='';
113 $s = new Interwiki( $key );
114 if ( $value != '' ) {
115 list( $local, $url ) = explode( ' ', $value, 2 );
116 $s->mURL = $url;
117 $s->mLocal = (int)$local;
119 if( self::CACHE_LIMIT && count( self::$smCache ) >= self::CACHE_LIMIT ){
120 array_shift( self::$smCache );
122 self::$smCache[$prefix] = &$s;
123 return $s;
127 * Check whether an interwiki is in the cache
129 * @note More logic is explained in DefaultSettings.
131 * @param $key \type{\string} Database key
132 * @return \type{\bool} Whether it exists
134 protected static function isValidInterwikiCached( $key ) {
135 global $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite;
136 static $db, $site;
138 if (!$db)
139 $db=dba_open($wgInterwikiCache,'r','cdb');
140 /* Resolve site name */
141 if ($wgInterwikiScopes>=3 and !$site) {
142 $site = dba_fetch('__sites:' . wfWikiID(), $db);
143 if ($site=="")
144 $site = $wgInterwikiFallbackSite;
146 $value = dba_fetch( wfMemcKey( $key ), $db);
147 if ($value=='' and $wgInterwikiScopes>=3) {
148 /* try site-level */
149 $value = dba_fetch("_{$site}:{$key}", $db);
151 if ($value=='' and $wgInterwikiScopes>=2) {
152 /* try globals */
153 $value = dba_fetch("__global:{$key}", $db);
155 if ($value=='undef')
156 $value='';
157 if ( $value != '' ) {
158 return true;
159 }else{
160 return false;
165 * Clear all member variables in the current object. Does not clear
166 * the block from the DB.
168 function clear() {
169 $this->mURL = '';
170 $this->mLocal = $this->mTrans = 0;
171 $this->mPrefix = null;
175 * Get the DB object
177 * @return Database
179 function &getDB(){
180 $db = wfGetDB( DB_SLAVE );
181 return $db;
185 * Load interwiki from the DB
187 * @param $prefix The interwiki prefix
188 * @return bool The prefix is valid
191 function load( $prefix ) {
192 global $wgMemc;
193 $key = wfMemcKey( 'interwiki', $prefix );
194 $mc = $wgMemc->get( $key );
195 if( $mc && is_array( $mc ) ){ // is_array is hack for old keys
196 if( $this->loadFromArray( $mc ) ){
197 wfDebug("Succeeded\n");
198 return true;
200 }else{
201 $db =& $this->getDB();
203 $res = $db->resultObject( $db->select( 'interwiki', '*', array( 'iw_prefix' => $prefix ),
204 __METHOD__ ) );
205 if ( $this->loadFromResult( $res ) ) {
206 $mc = array( 'url' => $this->mURL, 'local' => $this->mLocal, 'trans' => $this->mTrans );
207 $wgMemc->add( $key, $mc );
208 return true;
212 # Give up
213 $this->clear();
214 return false;
218 * Fill in member variables from an array (e.g. memcached result)
220 * @return bool Whether everything was there
221 * @param $res ResultWrapper Row from the interwiki table
223 function loadFromArray( $mc ) {
224 if( isset( $mc['url'] ) && isset( $mc['local'] ) && isset( $mc['trans'] ) ){
225 $this->mURL = $mc['url'];
226 $this->mLocal = $mc['local'];
227 $this->mTrans = $mc['trans'];
228 return true;
230 return false;
234 * Fill in member variables from a result wrapper
236 * @return bool Whether there was a row there
237 * @param $res ResultWrapper Row from the interwiki table
239 function loadFromResult( ResultWrapper $res ) {
240 $ret = false;
241 if ( 0 != $res->numRows() ) {
242 # Get first entry
243 $row = $res->fetchObject();
244 $this->initFromRow( $row );
245 $ret = true;
247 $res->free();
248 return $ret;
252 * Given a database row from the interwiki table, initialize
253 * member variables
255 * @param $row ResultWrapper A row from the interwiki table
257 function initFromRow( $row ) {
258 $this->mPrefix = $row->iw_prefix;
259 $this->mURL = $row->iw_url;
260 $this->mLocal = $row->iw_local;
261 $this->mTrans = $row->iw_trans;
264 /**
265 * Get the URL for a particular title (or with $1 if no title given)
267 * @param $title string What text to put for the article name
268 * @return string The URL
270 function getURL( $title = null ){
271 $url = $this->mURL;
272 if( $title != null ){
273 $url = str_replace( "$1", $title, $url );
275 return $url;
278 function isLocal(){
279 return $this->mLocal;
282 function isTranscludable(){
283 return $this->mTrans;