MediaWiki  1.34.0
WikiMap.php
Go to the documentation of this file.
1 <?php
25 
29 class WikiMap {
30 
37  public static function getWiki( $wikiID ) {
38  $wikiReference = self::getWikiReferenceFromWgConf( $wikiID );
39  if ( $wikiReference ) {
40  return $wikiReference;
41  }
42 
43  // Try sites, if $wgConf failed
44  return self::getWikiWikiReferenceFromSites( $wikiID );
45  }
46 
51  private static function getWikiReferenceFromWgConf( $wikiID ) {
52  global $wgConf;
53 
54  $wgConf->loadFullData();
55 
56  list( $major, $minor ) = $wgConf->siteFromDB( $wikiID );
57  if ( $major === null ) {
58  return null;
59  }
60  $server = $wgConf->get( 'wgServer', $wikiID, $major,
61  [ 'lang' => $minor, 'site' => $major ] );
62 
63  $canonicalServer = $wgConf->get( 'wgCanonicalServer', $wikiID, $major,
64  [ 'lang' => $minor, 'site' => $major ] );
65  if ( $canonicalServer === false || $canonicalServer === null ) {
66  $canonicalServer = $server;
67  }
68 
69  $path = $wgConf->get( 'wgArticlePath', $wikiID, $major,
70  [ 'lang' => $minor, 'site' => $major ] );
71 
72  // If we don't have a canonical server or a path containing $1, the
73  // WikiReference isn't going to function properly. Just return null in
74  // that case.
75  if ( !is_string( $canonicalServer ) || !is_string( $path ) || strpos( $path, '$1' ) === false ) {
76  return null;
77  }
78 
79  return new WikiReference( $canonicalServer, $path, $server );
80  }
81 
86  private static function getWikiWikiReferenceFromSites( $wikiID ) {
87  $siteLookup = MediaWikiServices::getInstance()->getSiteLookup();
88  $site = $siteLookup->getSite( $wikiID );
89 
90  if ( !$site instanceof MediaWikiSite ) {
91  // Abort if not a MediaWikiSite, as this is about Wikis
92  return null;
93  }
94 
95  $urlParts = wfParseUrl( $site->getPageUrl() );
96  if ( $urlParts === false || !isset( $urlParts['path'] ) || !isset( $urlParts['host'] ) ) {
97  // We can't create a meaningful WikiReference without URLs
98  return null;
99  }
100 
101  // XXX: Check whether path contains a $1?
102  $path = $urlParts['path'];
103  if ( isset( $urlParts['query'] ) ) {
104  $path .= '?' . $urlParts['query'];
105  }
106 
107  $canonicalServer = $urlParts['scheme'] ?? 'http';
108  $canonicalServer .= '://' . $urlParts['host'];
109 
110  return new WikiReference( $canonicalServer, $path );
111  }
112 
120  public static function getWikiName( $wikiID ) {
121  $wiki = self::getWiki( $wikiID );
122 
123  if ( $wiki ) {
124  return $wiki->getDisplayName();
125  }
126  return $wikiID;
127  }
128 
137  public static function foreignUserLink( $wikiID, $user, $text = null ) {
138  return self::makeForeignLink( $wikiID, "User:$user", $text );
139  }
140 
149  public static function makeForeignLink( $wikiID, $page, $text = null ) {
150  if ( !$text ) {
151  $text = $page;
152  }
153 
154  $url = self::getForeignURL( $wikiID, $page );
155  if ( $url === false ) {
156  return false;
157  }
158 
159  return Linker::makeExternalLink( $url, $text );
160  }
161 
171  public static function getForeignURL( $wikiID, $page, $fragmentId = null ) {
172  $wiki = self::getWiki( $wikiID );
173 
174  if ( $wiki ) {
175  return $wiki->getFullUrl( $page, $fragmentId );
176  }
177 
178  return false;
179  }
180 
187  public static function getCanonicalServerInfoForAllWikis() {
188  $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
189 
190  return $cache->getWithSetCallback(
191  $cache->makeGlobalKey( 'wikimap', 'canonical-urls' ),
192  $cache::TTL_DAY,
193  function () {
195 
196  $infoMap = [];
197  // Make sure at least the current wiki is set, for simple configurations.
198  // This also makes it the first in the map, which is useful for common cases.
199  $wikiId = self::getWikiIdFromDbDomain( self::getCurrentWikiDbDomain() );
200  $infoMap[$wikiId] = [
201  'url' => $wgCanonicalServer,
202  'parts' => wfParseUrl( $wgCanonicalServer )
203  ];
204 
205  foreach ( $wgLocalDatabases as $wikiId ) {
206  $wikiReference = self::getWiki( $wikiId );
207  if ( $wikiReference ) {
208  $url = $wikiReference->getCanonicalServer();
209  $infoMap[$wikiId] = [ 'url' => $url, 'parts' => wfParseUrl( $url ) ];
210  }
211  }
212 
213  return $infoMap;
214  }
215  );
216  }
217 
223  public static function getWikiFromUrl( $url ) {
224  global $wgCanonicalServer;
225 
226  if ( strpos( $url, "$wgCanonicalServer/" ) === 0 ) {
227  // Optimisation: Handle the the common case.
228  // (Duplicates self::getCanonicalServerInfoForAllWikis)
229  return self::getWikiIdFromDbDomain( self::getCurrentWikiDbDomain() );
230  }
231 
232  $urlPartsCheck = wfParseUrl( $url );
233  if ( $urlPartsCheck === false ) {
234  return false;
235  }
236 
237  static $relevantKeys = [ 'host' => 1, 'port' => 1 ];
238  $urlPartsCheck = array_intersect_key( $urlPartsCheck, $relevantKeys );
239 
240  foreach ( self::getCanonicalServerInfoForAllWikis() as $wikiId => $info ) {
241  $urlParts = $info['parts'];
242  if ( $urlParts === false ) {
243  continue; // sanity
244  }
245 
246  $urlParts = array_intersect_key( $urlParts, $relevantKeys );
247  if ( $urlParts == $urlPartsCheck ) {
248  return $wikiId;
249  }
250  }
251 
252  return false;
253  }
254 
268  public static function getWikiIdFromDbDomain( $domain ) {
269  $domain = DatabaseDomain::newFromId( $domain );
270  // Since the schema was not always part of the wiki ID, try to maintain backwards
271  // compatibility with some common cases. Assume that if the DB domain schema is just
272  // the installer default then it is probably the case that the schema is the same for
273  // all wikis in the farm. Historically, any wiki farm had to make the database/prefix
274  // combination unique per wiki. Ommit the schema if it does not seem wiki specific.
275  if ( !in_array( $domain->getSchema(), [ null, 'mediawiki' ], true ) ) {
276  // This means a site admin may have specifically taylored the schemas.
277  // Domain IDs might use the form <DB>-<project>- or <DB>-<project>-<language>_,
278  // meaning that the schema portion must be accounted for to disambiguate wikis.
279  return "{$domain->getDatabase()}-{$domain->getSchema()}-{$domain->getTablePrefix()}";
280  }
281  // Note that if this wiki ID is passed a a domain ID to LoadBalancer, then it can
282  // handle the schema by assuming the generic "mediawiki" schema if needed.
283  return strlen( $domain->getTablePrefix() )
284  ? "{$domain->getDatabase()}-{$domain->getTablePrefix()}"
285  : (string)$domain->getDatabase();
286  }
287 
292  public static function getCurrentWikiDbDomain() {
294  // Avoid invoking LBFactory to avoid any chance of recursion
295  return new DatabaseDomain( $wgDBname, $wgDBmwschema, (string)$wgDBprefix );
296  }
297 
303  public static function isCurrentWikiDbDomain( $domain ) {
304  return self::getCurrentWikiDbDomain()->equals( $domain );
305  }
306 
312  public static function isCurrentWikiId( $wikiId ) {
313  return ( self::getWikiIdFromDbDomain( self::getCurrentWikiDbDomain() ) === $wikiId );
314  }
315 }
$wgConf
$wgConf
wgConf hold the site configuration.
Definition: DefaultSettings.php:59
WikiMap\isCurrentWikiDbDomain
static isCurrentWikiDbDomain( $domain)
Definition: WikiMap.php:303
WikiMap\foreignUserLink
static foreignUserLink( $wikiID, $user, $text=null)
Convenience to get a link to a user page on a foreign wiki.
Definition: WikiMap.php:137
$wgLocalDatabases
string[] $wgLocalDatabases
Other wikis on this site, can be administered from a single developer account.
Definition: DefaultSettings.php:2168
WikiMap\getCurrentWikiDbDomain
static getCurrentWikiDbDomain()
Definition: WikiMap.php:292
$wgDBname
$wgDBname
Current wiki database name.
Definition: DefaultSettings.php:1893
WikiMap\isCurrentWikiId
static isCurrentWikiId( $wikiId)
Definition: WikiMap.php:312
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:117
true
return true
Definition: router.php:92
WikiMap\getWikiFromUrl
static getWikiFromUrl( $url)
Definition: WikiMap.php:223
WikiMap\getForeignURL
static getForeignURL( $wikiID, $page, $fragmentId=null)
Convenience to get a url to a page on a foreign wiki.
Definition: WikiMap.php:171
$wgDBmwschema
$wgDBmwschema
Current wiki database schema name.
Definition: DefaultSettings.php:1903
$wgDBprefix
$wgDBprefix
Current wiki database table name prefix.
Definition: DefaultSettings.php:1913
wfParseUrl
wfParseUrl( $url)
parse_url() work-alike, but non-broken.
Definition: GlobalFunctions.php:793
WikiMap\getWikiIdFromDbDomain
static getWikiIdFromDbDomain( $domain)
Get the wiki ID of a database domain.
Definition: WikiMap.php:268
WikiMap\getWiki
static getWiki( $wikiID)
Get a WikiReference object for $wikiID.
Definition: WikiMap.php:37
Linker\makeExternalLink
static makeExternalLink( $url, $text, $escape=true, $linktype='', $attribs=[], $title=null)
Make an external link.
Definition: Linker.php:848
$wgCanonicalServer
$wgCanonicalServer
Canonical URL of the server, to use in IRC feeds and notification e-mails.
Definition: DefaultSettings.php:114
WikiMap\getWikiReferenceFromWgConf
static getWikiReferenceFromWgConf( $wikiID)
Definition: WikiMap.php:51
WikiMap\getWikiWikiReferenceFromSites
static getWikiWikiReferenceFromSites( $wikiID)
Definition: WikiMap.php:86
WikiMap\makeForeignLink
static makeForeignLink( $wikiID, $page, $text=null)
Convenience to get a link to a page on a foreign wiki.
Definition: WikiMap.php:149
WikiMap
Helper tools for dealing with other locally-hosted wikis.
Definition: WikiMap.php:29
$cache
$cache
Definition: mcc.php:33
WikiReference
Reference to a locally-hosted wiki.
Definition: WikiReference.php:26
$path
$path
Definition: NoLocalSettings.php:25
MediaWikiSite
Class representing a MediaWiki site.
Definition: MediaWikiSite.php:38
Wikimedia\Rdbms\DatabaseDomain
Class to handle database/schema/prefix specifications for IDatabase.
Definition: DatabaseDomain.php:40
WikiMap\getWikiName
static getWikiName( $wikiID)
Convenience to get the wiki's display name.
Definition: WikiMap.php:120
WikiMap\getCanonicalServerInfoForAllWikis
static getCanonicalServerInfoForAllWikis()
Get canonical server info for all local wikis in the map that have one.
Definition: WikiMap.php:187