68 private $objectCacheExpiry;
78 private $interwikiScopes;
83 private $fallbackSite;
88 private $thisSite =
null;
94 private $loadBalancer;
122 $this->contLang = $contLang;
123 $this->objectCache = $objectCache;
124 $this->hookRunner =
new HookRunner( $hookContainer );
125 $this->loadBalancer = $loadBalancer;
126 $this->objectCacheExpiry = $objectCacheExpiry;
127 if ( is_array( $interwikiData ) ) {
128 $this->data = $interwikiData;
129 } elseif ( $interwikiData ) {
131 'Setting $wgInterwikiCache to a CDB path is no longer supported' );
133 $this->interwikiScopes = $interwikiScopes;
134 $this->fallbackSite = $fallbackSite;
144 $result = $this->
fetch( $prefix );
146 return (
bool)$result;
156 if ( $prefix ==
'' ) {
160 $prefix = $this->contLang->lc( $prefix );
162 return $this->localCache->getWithSetCallback(
164 function () use ( $prefix ) {
165 if ( $this->data !==
null ) {
166 $iw = $this->fetchPregenerated( $prefix );
168 $iw = $this->load( $prefix );
184 $this->localCache->clear();
192 $this->localCache->clear( $prefix );
194 $key = $this->objectCache->makeKey(
'interwiki', $prefix );
195 $this->objectCache->delete( $key );
206 private function fetchPregenerated( $prefix ) {
207 $value = $this->getPregeneratedEntry( $prefix );
211 list( $local, $url ) = explode(
' ', $value, 2 );
212 return new Interwiki( $prefix, $url,
'',
'', (
int)$local );
226 private function getPregeneratedEntry( $prefix ) {
227 wfDebug( __METHOD__ .
"( $prefix )" );
232 if ( $this->interwikiScopes >= 3 && !$this->thisSite ) {
233 $this->thisSite = $this->data[
'__sites:' . $wikiId] ?? $this->fallbackSite;
236 $value = $this->data[$wikiId .
':' . $prefix] ??
false;
238 if ( $value ===
false && $this->interwikiScopes >= 3 ) {
239 $value = $this->data[
"_{$this->thisSite}:{$prefix}"] ??
false;
242 if ( $value ===
false && $this->interwikiScopes >= 2 ) {
243 $value = $this->data[
"__global:{$prefix}"] ??
false;
255 private function load( $prefix ) {
257 if ( !$this->hookRunner->onInterwikiLoadPrefix( $prefix, $iwData ) ) {
258 return $this->loadFromArray( $iwData );
261 if ( is_array( $iwData ) ) {
262 $iw = $this->loadFromArray( $iwData );
269 $iwData = $this->objectCache->getWithSetCallback(
270 $this->objectCache->makeKey(
'interwiki', $prefix ),
271 $this->objectCacheExpiry,
272 function ( $oldValue, &$ttl, array &$setOpts ) use ( $prefix, $fname ) {
277 $row =
$dbr->selectRow(
279 self::selectFields(),
280 [
'iw_prefix' => $prefix ],
284 return $row ? (array)$row :
'!NONEXISTENT';
288 if ( is_array( $iwData ) ) {
289 return $this->loadFromArray( $iwData ) ?:
false;
301 private function loadFromArray( $mc ) {
302 if ( isset( $mc[
'iw_url'] ) ) {
303 $url = $mc[
'iw_url'];
304 $local = $mc[
'iw_local'] ?? 0;
305 $trans = $mc[
'iw_trans'] ?? 0;
306 $api = $mc[
'iw_api'] ??
'';
307 $wikiId = $mc[
'iw_wikiid'] ??
'';
309 return new Interwiki(
null, $url, $api, $wikiId, $local, $trans );
321 private function getAllPrefixesPregenerated( $local ) {
328 if ( $this->interwikiScopes >= 3 && !$this->thisSite ) {
329 $this->thisSite = $this->data[
'__sites:' . $wikiId] ?? $this->fallbackSite;
335 if ( $this->interwikiScopes >= 2 ) {
336 $sources[] =
'__global';
339 if ( $this->interwikiScopes >= 3 ) {
340 $sources[] =
'_' . $this->thisSite;
342 $sources[] = $wikiId;
344 foreach ( $sources as
$source ) {
345 $list = $this->data[
'__list:' .
$source] ??
'';
346 foreach ( explode(
' ', $list ) as $iw_prefix ) {
347 $row = $this->data[
"{$source}:{$iw_prefix}"] ??
null;
352 list( $iw_local, $iw_url ) = explode(
' ', $row );
354 if ( $local !==
null && $local != $iw_local ) {
358 $data[$iw_prefix] = [
359 'iw_prefix' => $iw_prefix,
361 'iw_local' => $iw_local,
366 return array_values( $data );
383 array $allPrefixes,
int $scope = 1, ?
string $thisSite =
null
386 $wikiId = WikiMap::getCurrentWikiId();
387 $keyPrefix = ( $scope >= 2 ) ?
'__global' : $wikiId;
388 if ( $scope >= 3 && $thisSite ) {
389 $result[
"__sites:$wikiId" ] = $thisSite;
390 $keyPrefix =
"_$thisSite";
393 foreach ( $allPrefixes as $iwInfo ) {
394 $prefix = $iwInfo[
'iw_prefix'];
395 $result[
"$keyPrefix:$prefix"] = implode(
' ', [
396 $iwInfo[
'iw_local'] ?? 0, $iwInfo[
'iw_url']
400 $result[
"__list:$keyPrefix"] = implode(
' ', $list );
401 $result[
"__list:__sites"] = $wikiId;
411 private function getAllPrefixesDB( $local ) {
412 $db = $this->loadBalancer->getConnectionRef(
DB_REPLICA );
416 if ( $local !==
null ) {
417 $where[
'iw_local'] = (int)$local;
420 $res = $db->select(
'interwiki',
421 self::selectFields(),
422 $where, __METHOD__, [
'ORDER BY' =>
'iw_prefix' ]
426 foreach (
$res as $row ) {
427 $retval[] = (array)$row;
440 if ( $this->data !==
null ) {
441 return $this->getAllPrefixesPregenerated( $local );
444 return $this->getAllPrefixesDB( $local );
452 private static function selectFields() {
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.