]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/Interwiki.php
MediaWiki 1.17.4
[autoinstalls/mediawiki.git] / includes / Interwiki.php
1 <?php
2 /**
3  * @file
4  * Interwiki table entry
5  */
6
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
11  * schema updates etc, which aren't wiki-related)
12  */
13 class Interwiki {
14
15         // Cache - removes oldest entry when it hits limit
16         protected static $smCache = array();
17         const CACHE_LIMIT = 100; // 0 means unlimited, any other value is max number of entries.
18
19         protected $mPrefix, $mURL, $mAPI, $mWikiID, $mLocal, $mTrans;
20
21         public function __construct( $prefix = null, $url = '', $api = '', $wikiId = '', $local = 0, $trans = 0 ) {
22                 $this->mPrefix = $prefix;
23                 $this->mURL = $url;
24                 $this->mAPI = $api;
25                 $this->mWikiID = $wikiId;
26                 $this->mLocal = $local;
27                 $this->mTrans = $trans;
28         }
29
30         /**
31          * Check whether an interwiki prefix exists
32          *
33          * @param $prefix String: interwiki prefix to use
34          * @return Boolean: whether it exists
35          */
36         static public function isValidInterwiki( $prefix ) {
37                 $result = self::fetch( $prefix );
38                 return (bool)$result;
39         }
40
41         /**
42          * Fetch an Interwiki object
43          *
44          * @param $prefix String: interwiki prefix to use
45          * @return Interwiki Object, or null if not valid
46          */
47         static public function fetch( $prefix ) {
48                 global $wgContLang;
49                 if( $prefix == '' ) {
50                         return null;
51                 }
52                 $prefix = $wgContLang->lc( $prefix );
53                 if( isset( self::$smCache[$prefix] ) ) {
54                         return self::$smCache[$prefix];
55                 }
56                 global $wgInterwikiCache;
57                 if( $wgInterwikiCache ) {
58                         $iw = Interwiki::getInterwikiCached( $prefix );
59                 } else {
60                         $iw = Interwiki::load( $prefix );
61                         if( !$iw ) {
62                                 $iw = false;
63                         }
64                 }
65                 if( self::CACHE_LIMIT && count( self::$smCache ) >= self::CACHE_LIMIT ) {
66                         reset( self::$smCache );
67                         unset( self::$smCache[key( self::$smCache )] );
68                 }
69                 self::$smCache[$prefix] = $iw;
70                 return $iw;
71         }
72
73         /**
74          * Fetch interwiki prefix data from local cache in constant database.
75          *
76          * @note More logic is explained in DefaultSettings.
77          *
78          * @param $prefix String: interwiki prefix
79          * @return Interwiki object
80          */
81         protected static function getInterwikiCached( $prefix ) {
82                 $value = self::getInterwikiCacheEntry( $prefix );
83
84                 $s = new Interwiki( $prefix );
85                 if ( $value != '' ) {
86                         // Split values
87                         list( $local, $url ) = explode( ' ', $value, 2 );
88                         $s->mURL = $url;
89                         $s->mLocal = (int)$local;
90                 } else {
91                         $s = false;
92                 }
93                 return $s;
94         }
95
96         /**
97          * Get entry from interwiki cache
98          *
99          * @note More logic is explained in DefaultSettings.
100          *
101          * @param $prefix String: database key
102          * @return String: the entry
103          */
104         protected static function getInterwikiCacheEntry( $prefix ) {
105                 global $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite;
106                 static $db, $site;
107
108                 wfDebug( __METHOD__ . "( $prefix )\n" );
109                 if( !$db ) {
110                         $db = CdbReader::open( $wgInterwikiCache );
111                 }
112                 /* Resolve site name */
113                 if( $wgInterwikiScopes >= 3 && !$site ) {
114                         $site = $db->get( '__sites:' . wfWikiID() );
115                         if ( $site == '' ) {
116                                 $site = $wgInterwikiFallbackSite;
117                         }
118                 }
119
120                 $value = $db->get( wfMemcKey( $prefix ) );
121                 // Site level
122                 if ( $value == '' && $wgInterwikiScopes >= 3 ) {
123                         $value = $db->get( "_{$site}:{$prefix}" );
124                 }
125                 // Global Level
126                 if ( $value == '' && $wgInterwikiScopes >= 2 ) {
127                         $value = $db->get( "__global:{$prefix}" );
128                 }
129                 if ( $value == 'undef' ) {
130                         $value = '';
131                 }
132
133                 return $value;
134         }
135
136         /**
137          * Load the interwiki, trying first memcached then the DB
138          *
139          * @param $prefix The interwiki prefix
140          * @return Boolean: the prefix is valid
141          */
142         protected static function load( $prefix ) {
143                 global $wgMemc, $wgInterwikiExpiry;
144                 $key = wfMemcKey( 'interwiki', $prefix );
145                 $mc = $wgMemc->get( $key );
146
147                 if( $mc && is_array( $mc ) ) { // is_array is hack for old keys
148                         $iw = Interwiki::loadFromArray( $mc );
149                         if( $iw ) {
150                                 return $iw;
151                         }
152                 }
153
154                 $db = wfGetDB( DB_SLAVE );
155
156                 $row = $db->fetchRow( $db->select( 'interwiki', '*', array( 'iw_prefix' => $prefix ),
157                         __METHOD__ ) );
158                 $iw = Interwiki::loadFromArray( $row );
159                 if ( $iw ) {
160                         $mc = array(
161                                 'iw_url' => $iw->mURL,
162                                 'iw_api' => $iw->mAPI,
163                                 'iw_local' => $iw->mLocal,
164                                 'iw_trans' => $iw->mTrans
165                         );
166                         $wgMemc->add( $key, $mc, $wgInterwikiExpiry );
167                         return $iw;
168                 }
169
170                 return false;
171         }
172
173         /**
174          * Fill in member variables from an array (e.g. memcached result, Database::fetchRow, etc)
175          *
176          * @param $mc Associative array: row from the interwiki table
177          * @return Boolean: whether everything was there
178          */
179         protected static function loadFromArray( $mc ) {
180                 if( isset( $mc['iw_url'] ) && isset( $mc['iw_local'] ) && isset( $mc['iw_trans'] ) ) {
181                         $iw = new Interwiki();
182                         $iw->mURL = $mc['iw_url'];
183                         $iw->mLocal = $mc['iw_local'];
184                         $iw->mTrans = $mc['iw_trans'];
185                         $iw->mAPI = isset( $mc['iw_api'] ) ? $mc['iw_api'] : '';
186                         $iw->mWikiID = isset( $mc['iw_wikiid'] ) ? $mc['iw_wikiid'] : '';
187
188                         return $iw;
189                 }
190                 return false;
191         }
192
193         /**
194          * Get the URL for a particular title (or with $1 if no title given)
195          *
196          * @param $title String: what text to put for the article name
197          * @return String: the URL
198          */
199         public function getURL( $title = null ) {
200                 $url = $this->mURL;
201                 if( $title != null ) {
202                         $url = str_replace( "$1", $title, $url );
203                 }
204                 return $url;
205         }
206
207         /**
208          * Get the API URL for this wiki
209          *
210          * @return String: the URL
211          */
212         public function getAPI() {
213                 return $this->mAPI;
214         }
215
216         /**
217          * Get the DB name for this wiki
218          *
219          * @return String: the DB name
220          */
221         public function getWikiID() {
222                 return $this->mWikiID;
223         }
224
225         /**
226          * Is this a local link from a sister project, or is
227          * it something outside, like Google
228          *
229          * @return Boolean
230          */
231         public function isLocal() {
232                 return $this->mLocal;
233         }
234
235         /**
236          * Can pages from this wiki be transcluded?
237          * Still requires $wgEnableScaryTransclusion
238          *
239          * @return Boolean
240          */
241         public function isTranscludable() {
242                 return $this->mTrans;
243         }
244
245         /**
246          * Get the name for the interwiki site
247          *
248          * @return String
249          */
250         public function getName() {
251                 $key = 'interwiki-name-' . $this->mPrefix;
252                 $msg = wfMsgForContent( $key );
253                 return wfEmptyMsg( $key, $msg ) ? '' : $msg;
254         }
255
256         /**
257          * Get a description for this interwiki
258          *
259          * @return String
260          */
261         public function getDescription() {
262                 $key = 'interwiki-desc-' . $this->mPrefix;
263                 $msg = wfMsgForContent( $key );
264                 return wfEmptyMsg( $key, $msg ) ? '' : $msg;
265         }
266 }