loadFullData(); list( $major, $minor ) = $wgConf->siteFromDB( $wikiID ); if ( $major === null ) { return null; } $server = $wgConf->get( 'wgServer', $wikiID, $major, [ 'lang' => $minor, 'site' => $major ] ); $canonicalServer = $wgConf->get( 'wgCanonicalServer', $wikiID, $major, [ 'lang' => $minor, 'site' => $major ] ); if ( $canonicalServer === false || $canonicalServer === null ) { $canonicalServer = $server; } $path = $wgConf->get( 'wgArticlePath', $wikiID, $major, [ 'lang' => $minor, 'site' => $major ] ); // If we don't have a canonical server or a path containing $1, the // WikiReference isn't going to function properly. Just return null in // that case. if ( !is_string( $canonicalServer ) || !is_string( $path ) || strpos( $path, '$1' ) === false ) { return null; } return new WikiReference( $canonicalServer, $path, $server ); } /** * @param string $wikiID * @return WikiReference|null WikiReference object or null if the wiki was not found */ private static function getWikiWikiReferenceFromSites( $wikiID ) { $siteLookup = MediaWikiServices::getInstance()->getSiteLookup(); $site = $siteLookup->getSite( $wikiID ); if ( !$site instanceof MediaWikiSite ) { // Abort if not a MediaWikiSite, as this is about Wikis return null; } $urlParts = wfParseUrl( $site->getPageUrl() ); if ( $urlParts === false || !isset( $urlParts['path'] ) || !isset( $urlParts['host'] ) ) { // We can't create a meaningful WikiReference without URLs return null; } // XXX: Check whether path contains a $1? $path = $urlParts['path']; if ( isset( $urlParts['query'] ) ) { $path .= '?' . $urlParts['query']; } $canonicalServer = isset( $urlParts['scheme'] ) ? $urlParts['scheme'] : 'http'; $canonicalServer .= '://' . $urlParts['host']; return new WikiReference( $canonicalServer, $path ); } /** * Convenience to get the wiki's display name * * @todo We can give more info than just the wiki id! * @param string $wikiID Wiki'd id (generally database name) * @return string|int Wiki's name or $wiki_id if the wiki was not found */ public static function getWikiName( $wikiID ) { $wiki = self::getWiki( $wikiID ); if ( $wiki ) { return $wiki->getDisplayName(); } return $wikiID; } /** * Convenience to get a link to a user page on a foreign wiki * * @param string $wikiID Wiki'd id (generally database name) * @param string $user User name (must be normalised before calling this function!) * @param string $text Link's text; optional, default to "User:$user" * @return string HTML link or false if the wiki was not found */ public static function foreignUserLink( $wikiID, $user, $text = null ) { return self::makeForeignLink( $wikiID, "User:$user", $text ); } /** * Convenience to get a link to a page on a foreign wiki * * @param string $wikiID Wiki'd id (generally database name) * @param string $page Page name (must be normalised before calling this function!) * @param string $text Link's text; optional, default to $page * @return string|false HTML link or false if the wiki was not found */ public static function makeForeignLink( $wikiID, $page, $text = null ) { if ( !$text ) { $text = $page; } $url = self::getForeignURL( $wikiID, $page ); if ( $url === false ) { return false; } return Linker::makeExternalLink( $url, $text ); } /** * Convenience to get a url to a page on a foreign wiki * * @param string $wikiID Wiki'd id (generally database name) * @param string $page Page name (must be normalised before calling this function!) * @param string|null $fragmentId * * @return string|bool URL or false if the wiki was not found */ public static function getForeignURL( $wikiID, $page, $fragmentId = null ) { $wiki = self::getWiki( $wikiID ); if ( $wiki ) { return $wiki->getFullUrl( $page, $fragmentId ); } return false; } /** * Get canonical server info for all local wikis in the map that have one * * @return array Map of (local wiki ID => map of (url,parts)) * @since 1.30 */ public static function getCanonicalServerInfoForAllWikis() { $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache(); return $cache->getWithSetCallback( $cache->makeGlobalKey( 'wikimap', 'canonical-urls' ), $cache::TTL_DAY, function () { global $wgLocalDatabases, $wgCanonicalServer; $infoMap = []; // Make sure at least the current wiki is set, for simple configurations. // This also makes it the first in the map, which is useful for common cases. $infoMap[wfWikiID()] = [ 'url' => $wgCanonicalServer, 'parts' => wfParseUrl( $wgCanonicalServer ) ]; foreach ( $wgLocalDatabases as $wikiId ) { $wikiReference = self::getWiki( $wikiId ); if ( $wikiReference ) { $url = $wikiReference->getCanonicalServer(); $infoMap[$wikiId] = [ 'url' => $url, 'parts' => wfParseUrl( $url ) ]; } } return $infoMap; } ); } /** * @param string $url * @return bool|string Wiki ID or false * @since 1.30 */ public static function getWikiFromUrl( $url ) { $urlPartsCheck = wfParseUrl( $url ); if ( $urlPartsCheck === false ) { return false; } $urlPartsCheck = array_intersect_key( $urlPartsCheck, [ 'host' => 1, 'port' => 1 ] ); foreach ( self::getCanonicalServerInfoForAllWikis() as $wikiId => $info ) { $urlParts = $info['parts']; if ( $urlParts === false ) { continue; // sanity } $urlParts = array_intersect_key( $urlParts, [ 'host' => 1, 'port' => 1 ] ); if ( $urlParts == $urlPartsCheck ) { return $wikiId; } } return false; } /** * Get the wiki ID of a database domain * * This is like DatabaseDomain::getId() without encoding (for legacy reasons) * * @param string|DatabaseDomain $domain * @return string */ public static function getWikiIdFromDomain( $domain ) { if ( !( $domain instanceof DatabaseDomain ) ) { $domain = DatabaseDomain::newFromId( $domain ); } return strlen( $domain->getTablePrefix() ) ? "{$domain->getDatabase()}-{$domain->getTablePrefix()}" : $domain->getDatabase(); } /** * @param DatabaseDomain|string $domain * @return bool Whether $domain has the same DB/prefix as the current wiki * @since 1.33 */ public static function isCurrentWikiDbDomain( $domain ) { $domain = DatabaseDomain::newFromId( $domain ); $curDomain = self::getCurrentWikiDbDomain(); if ( !in_array( $curDomain->getSchema(), [ null, 'mediawiki' ], true ) ) { // Include the schema if it is set and is not the default placeholder. // This means a site admin may have specifically taylored the schemas. // Domain IDs might use the form --, meaning that // the schema portion must be accounted for to disambiguate wikis. return $curDomain->equals( $domain ); } return ( $curDomain->getDatabase() === $domain->getDatabase() && $curDomain->getTablePrefix() === $domain->getTablePrefix() ); } /** * @return DatabaseDomain Database domain of the current wiki * @since 1.33 */ public static function getCurrentWikiDbDomain() { global $wgDBname, $wgDBmwschema, $wgDBprefix; // Avoid invoking LBFactory to avoid any chance of recursion return new DatabaseDomain( $wgDBname, $wgDBmwschema, (string)$wgDBprefix ); } }