diff options
author | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
---|---|---|
committer | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
commit | fc7369835258467bf97eb64f184b93691f9a9fd5 (patch) | |
tree | daabd60089d2dd76d9f5fb416b005fbe159c799d /www/wiki/includes/interwiki |
first commit
Diffstat (limited to 'www/wiki/includes/interwiki')
-rw-r--r-- | www/wiki/includes/interwiki/ClassicInterwikiLookup.php | 452 | ||||
-rw-r--r-- | www/wiki/includes/interwiki/Interwiki.php | 185 | ||||
-rw-r--r-- | www/wiki/includes/interwiki/InterwikiLookup.php | 74 | ||||
-rw-r--r-- | www/wiki/includes/interwiki/InterwikiLookupAdapter.php | 178 | ||||
-rw-r--r-- | www/wiki/includes/interwiki/NullInterwikiLookup.php | 57 |
5 files changed, 946 insertions, 0 deletions
diff --git a/www/wiki/includes/interwiki/ClassicInterwikiLookup.php b/www/wiki/includes/interwiki/ClassicInterwikiLookup.php new file mode 100644 index 00000000..d5103da9 --- /dev/null +++ b/www/wiki/includes/interwiki/ClassicInterwikiLookup.php @@ -0,0 +1,452 @@ +<?php +/** + * InterwikiLookup implementing the "classic" interwiki storage (hardcoded up to MW 1.26). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + */ + +namespace MediaWiki\Interwiki; + +use Cdb\Exception as CdbException; +use Cdb\Reader as CdbReader; +use Hooks; +use Interwiki; +use Language; +use MapCacheLRU; +use WANObjectCache; +use Wikimedia\Rdbms\Database; + +/** + * InterwikiLookup implementing the "classic" interwiki storage (hardcoded up to MW 1.26). + * + * This implements two levels of caching (in-process array and a WANObjectCache) + * and tree storage backends (SQL, CDB, and plain PHP arrays). + * + * All information is loaded on creation when called by $this->fetch( $prefix ). + * All work is done on replica DB, because this should *never* change (except during + * schema updates etc, which aren't wiki-related) + * + * @since 1.28 + */ +class ClassicInterwikiLookup implements InterwikiLookup { + + /** + * @var MapCacheLRU + */ + private $localCache; + + /** + * @var Language + */ + private $contentLanguage; + + /** + * @var WANObjectCache + */ + private $objectCache; + + /** + * @var int + */ + private $objectCacheExpiry; + + /** + * @var bool|array|string + */ + private $cdbData; + + /** + * @var int + */ + private $interwikiScopes; + + /** + * @var string + */ + private $fallbackSite; + + /** + * @var CdbReader|null + */ + private $cdbReader = null; + + /** + * @var string|null + */ + private $thisSite = null; + + /** + * @param Language $contentLanguage Language object used to convert prefixes to lower case + * @param WANObjectCache $objectCache Cache for interwiki info retrieved from the database + * @param int $objectCacheExpiry Expiry time for $objectCache, in seconds + * @param bool|array|string $cdbData The path of a CDB file, or + * an array resembling the contents of a CDB file, + * or false to use the database. + * @param int $interwikiScopes Specify number of domains to check for messages: + * - 1: Just local wiki level + * - 2: wiki and global levels + * - 3: site level as well as wiki and global levels + * @param string $fallbackSite The code to assume for the local site, + */ + function __construct( + Language $contentLanguage, + WANObjectCache $objectCache, + $objectCacheExpiry, + $cdbData, + $interwikiScopes, + $fallbackSite + ) { + $this->localCache = new MapCacheLRU( 100 ); + + $this->contentLanguage = $contentLanguage; + $this->objectCache = $objectCache; + $this->objectCacheExpiry = $objectCacheExpiry; + $this->cdbData = $cdbData; + $this->interwikiScopes = $interwikiScopes; + $this->fallbackSite = $fallbackSite; + } + + /** + * Check whether an interwiki prefix exists + * + * @param string $prefix Interwiki prefix to use + * @return bool Whether it exists + */ + public function isValidInterwiki( $prefix ) { + $result = $this->fetch( $prefix ); + + return (bool)$result; + } + + /** + * Fetch an Interwiki object + * + * @param string $prefix Interwiki prefix to use + * @return Interwiki|null|bool + */ + public function fetch( $prefix ) { + if ( $prefix == '' ) { + return null; + } + + $prefix = $this->contentLanguage->lc( $prefix ); + if ( $this->localCache->has( $prefix ) ) { + return $this->localCache->get( $prefix ); + } + + if ( $this->cdbData ) { + $iw = $this->getInterwikiCached( $prefix ); + } else { + $iw = $this->load( $prefix ); + if ( !$iw ) { + $iw = false; + } + } + $this->localCache->set( $prefix, $iw ); + + return $iw; + } + + /** + * Resets locally cached Interwiki objects. This is intended for use during testing only. + * This does not invalidate entries in the persistent cache, as invalidateCache() does. + * @since 1.27 + */ + public function resetLocalCache() { + $this->localCache->clear(); + } + + /** + * Purge the in-process and object cache for an interwiki prefix + * @param string $prefix + */ + public function invalidateCache( $prefix ) { + $this->localCache->clear( $prefix ); + + $key = $this->objectCache->makeKey( 'interwiki', $prefix ); + $this->objectCache->delete( $key ); + } + + /** + * Fetch interwiki prefix data from local cache in constant database. + * + * @note More logic is explained in DefaultSettings. + * + * @param string $prefix Interwiki prefix + * @return Interwiki|false + */ + private function getInterwikiCached( $prefix ) { + $value = $this->getInterwikiCacheEntry( $prefix ); + + if ( $value ) { + // Split values + list( $local, $url ) = explode( ' ', $value, 2 ); + return new Interwiki( $prefix, $url, '', '', (int)$local ); + } else { + return false; + } + } + + /** + * Get entry from interwiki cache + * + * @note More logic is explained in DefaultSettings. + * + * @param string $prefix Database key + * @return bool|string The interwiki entry or false if not found + */ + private function getInterwikiCacheEntry( $prefix ) { + wfDebug( __METHOD__ . "( $prefix )\n" ); + $value = false; + try { + // Resolve site name + if ( $this->interwikiScopes >= 3 && !$this->thisSite ) { + $this->thisSite = $this->getCacheValue( '__sites:' . wfWikiID() ); + if ( $this->thisSite == '' ) { + $this->thisSite = $this->fallbackSite; + } + } + + $value = $this->getCacheValue( wfWikiID() . ':' . $prefix ); + // Site level + if ( $value == '' && $this->interwikiScopes >= 3 ) { + $value = $this->getCacheValue( "_{$this->thisSite}:{$prefix}" ); + } + // Global Level + if ( $value == '' && $this->interwikiScopes >= 2 ) { + $value = $this->getCacheValue( "__global:{$prefix}" ); + } + if ( $value == 'undef' ) { + $value = ''; + } + } catch ( CdbException $e ) { + wfDebug( __METHOD__ . ": CdbException caught, error message was " + . $e->getMessage() ); + } + + return $value; + } + + private function getCacheValue( $key ) { + if ( $this->cdbReader === null ) { + if ( is_string( $this->cdbData ) ) { + $this->cdbReader = \Cdb\Reader::open( $this->cdbData ); + } elseif ( is_array( $this->cdbData ) ) { + $this->cdbReader = new \Cdb\Reader\Hash( $this->cdbData ); + } else { + $this->cdbReader = false; + } + } + + if ( $this->cdbReader ) { + return $this->cdbReader->get( $key ); + } else { + return false; + } + } + + /** + * Load the interwiki, trying first memcached then the DB + * + * @param string $prefix The interwiki prefix + * @return Interwiki|bool Interwiki if $prefix is valid, otherwise false + */ + private function load( $prefix ) { + $iwData = []; + if ( !Hooks::run( 'InterwikiLoadPrefix', [ $prefix, &$iwData ] ) ) { + return $this->loadFromArray( $iwData ); + } + + if ( is_array( $iwData ) ) { + $iw = $this->loadFromArray( $iwData ); + if ( $iw ) { + return $iw; // handled by hook + } + } + + $iwData = $this->objectCache->getWithSetCallback( + $this->objectCache->makeKey( 'interwiki', $prefix ), + $this->objectCacheExpiry, + function ( $oldValue, &$ttl, array &$setOpts ) use ( $prefix ) { + $dbr = wfGetDB( DB_REPLICA ); // TODO: inject LoadBalancer + + $setOpts += Database::getCacheSetOptions( $dbr ); + + $row = $dbr->selectRow( + 'interwiki', + self::selectFields(), + [ 'iw_prefix' => $prefix ], + __METHOD__ + ); + + return $row ? (array)$row : '!NONEXISTENT'; + } + ); + + if ( is_array( $iwData ) ) { + return $this->loadFromArray( $iwData ) ?: false; + } + + return false; + } + + /** + * Fill in member variables from an array (e.g. memcached result, Database::fetchRow, etc) + * + * @param array $mc Associative array: row from the interwiki table + * @return Interwiki|bool Interwiki object or false if $mc['iw_url'] is not set + */ + private function loadFromArray( $mc ) { + if ( isset( $mc['iw_url'] ) ) { + $url = $mc['iw_url']; + $local = isset( $mc['iw_local'] ) ? $mc['iw_local'] : 0; + $trans = isset( $mc['iw_trans'] ) ? $mc['iw_trans'] : 0; + $api = isset( $mc['iw_api'] ) ? $mc['iw_api'] : ''; + $wikiId = isset( $mc['iw_wikiid'] ) ? $mc['iw_wikiid'] : ''; + + return new Interwiki( null, $url, $api, $wikiId, $local, $trans ); + } + + return false; + } + + /** + * Fetch all interwiki prefixes from interwiki cache + * + * @param null|string $local If not null, limits output to local/non-local interwikis + * @return array List of prefixes, where each row is an associative array + */ + private function getAllPrefixesCached( $local ) { + wfDebug( __METHOD__ . "()\n" ); + $data = []; + try { + /* Resolve site name */ + if ( $this->interwikiScopes >= 3 && !$this->thisSite ) { + $site = $this->getCacheValue( '__sites:' . wfWikiID() ); + + if ( $site == '' ) { + $this->thisSite = $this->fallbackSite; + } else { + $this->thisSite = $site; + } + } + + // List of interwiki sources + $sources = []; + // Global Level + if ( $this->interwikiScopes >= 2 ) { + $sources[] = '__global'; + } + // Site level + if ( $this->interwikiScopes >= 3 ) { + $sources[] = '_' . $this->thisSite; + } + $sources[] = wfWikiID(); + + foreach ( $sources as $source ) { + $list = $this->getCacheValue( '__list:' . $source ); + foreach ( explode( ' ', $list ) as $iw_prefix ) { + $row = $this->getCacheValue( "{$source}:{$iw_prefix}" ); + if ( !$row ) { + continue; + } + + list( $iw_local, $iw_url ) = explode( ' ', $row ); + + if ( $local !== null && $local != $iw_local ) { + continue; + } + + $data[$iw_prefix] = [ + 'iw_prefix' => $iw_prefix, + 'iw_url' => $iw_url, + 'iw_local' => $iw_local, + ]; + } + } + } catch ( CdbException $e ) { + wfDebug( __METHOD__ . ": CdbException caught, error message was " + . $e->getMessage() ); + } + + return array_values( $data ); + } + + /** + * Fetch all interwiki prefixes from DB + * + * @param string|null $local If not null, limits output to local/non-local interwikis + * @return array[] Interwiki rows + */ + private function getAllPrefixesDB( $local ) { + $db = wfGetDB( DB_REPLICA ); // TODO: inject DB LoadBalancer + + $where = []; + + if ( $local !== null ) { + if ( $local == 1 ) { + $where['iw_local'] = 1; + } elseif ( $local == 0 ) { + $where['iw_local'] = 0; + } + } + + $res = $db->select( 'interwiki', + self::selectFields(), + $where, __METHOD__, [ 'ORDER BY' => 'iw_prefix' ] + ); + + $retval = []; + foreach ( $res as $row ) { + $retval[] = (array)$row; + } + + return $retval; + } + + /** + * Returns all interwiki prefixes + * + * @param string|null $local If set, limits output to local/non-local interwikis + * @return array[] Interwiki rows, where each row is an associative array + */ + public function getAllPrefixes( $local = null ) { + if ( $this->cdbData ) { + return $this->getAllPrefixesCached( $local ); + } + + return $this->getAllPrefixesDB( $local ); + } + + /** + * Return the list of interwiki fields that should be selected to create + * a new Interwiki object. + * @return string[] + */ + private static function selectFields() { + return [ + 'iw_prefix', + 'iw_url', + 'iw_api', + 'iw_wikiid', + 'iw_local', + 'iw_trans' + ]; + } + +} diff --git a/www/wiki/includes/interwiki/Interwiki.php b/www/wiki/includes/interwiki/Interwiki.php new file mode 100644 index 00000000..5a996d9d --- /dev/null +++ b/www/wiki/includes/interwiki/Interwiki.php @@ -0,0 +1,185 @@ +<?php +/** + * Interwiki table entry. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + */ +use MediaWiki\MediaWikiServices; + +/** + * Value object for representing interwiki records. + */ +class Interwiki { + + /** @var string The interwiki prefix, (e.g. "Meatball", or the language prefix "de") */ + protected $mPrefix; + + /** @var string The URL of the wiki, with "$1" as a placeholder for an article name. */ + protected $mURL; + + /** @var string The URL of the file api.php */ + protected $mAPI; + + /** @var string The name of the database (for a connection to be established + * with wfGetLB( 'wikiid' )) + */ + protected $mWikiID; + + /** @var bool Whether the wiki is in this project */ + protected $mLocal; + + /** @var bool Whether interwiki transclusions are allowed */ + protected $mTrans; + + public function __construct( $prefix = null, $url = '', $api = '', $wikiId = '', $local = 0, + $trans = 0 + ) { + $this->mPrefix = $prefix; + $this->mURL = $url; + $this->mAPI = $api; + $this->mWikiID = $wikiId; + $this->mLocal = (bool)$local; + $this->mTrans = (bool)$trans; + } + + /** + * Check whether an interwiki prefix exists + * + * @deprecated since 1.28, use InterwikiLookup instead + * + * @param string $prefix Interwiki prefix to use + * @return bool Whether it exists + */ + public static function isValidInterwiki( $prefix ) { + return MediaWikiServices::getInstance()->getInterwikiLookup()->isValidInterwiki( $prefix ); + } + + /** + * Fetch an Interwiki object + * + * @deprecated since 1.28, use InterwikiLookup instead + * + * @param string $prefix Interwiki prefix to use + * @return Interwiki|null|bool + */ + public static function fetch( $prefix ) { + return MediaWikiServices::getInstance()->getInterwikiLookup()->fetch( $prefix ); + } + + /** + * Purge the cache (local and persistent) for an interwiki prefix. + * + * @param string $prefix + * @since 1.26 + */ + public static function invalidateCache( $prefix ) { + MediaWikiServices::getInstance()->getInterwikiLookup()->invalidateCache( $prefix ); + } + + /** + * Returns all interwiki prefix definitions. + * + * @deprecated since 1.28, unused. Use InterwikiLookup instead. + * + * @param string|null $local If set, limits output to local/non-local interwikis + * @return array[] List of interwiki rows + * @since 1.19 + */ + public static function getAllPrefixes( $local = null ) { + return MediaWikiServices::getInstance()->getInterwikiLookup()->getAllPrefixes( $local ); + } + + /** + * Get the URL for a particular title (or with $1 if no title given) + * + * @param string $title What text to put for the article name + * @return string The URL + * @note Prior to 1.19 The getURL with an argument was broken. + * If you if you use this arg in an extension that supports MW earlier + * than 1.19 please wfUrlencode and substitute $1 on your own. + */ + public function getURL( $title = null ) { + $url = $this->mURL; + if ( $title !== null ) { + $url = str_replace( "$1", wfUrlencode( $title ), $url ); + } + + return $url; + } + + /** + * Get the API URL for this wiki + * + * @return string The URL + */ + public function getAPI() { + return $this->mAPI; + } + + /** + * Get the DB name for this wiki + * + * @return string The DB name + */ + public function getWikiID() { + return $this->mWikiID; + } + + /** + * Is this a local link from a sister project, or is + * it something outside, like Google + * + * @return bool + */ + public function isLocal() { + return $this->mLocal; + } + + /** + * Can pages from this wiki be transcluded? + * Still requires $wgEnableScaryTransclusion + * + * @return bool + */ + public function isTranscludable() { + return $this->mTrans; + } + + /** + * Get the name for the interwiki site + * + * @return string + */ + public function getName() { + $msg = wfMessage( 'interwiki-name-' . $this->mPrefix )->inContentLanguage(); + + return !$msg->exists() ? '' : $msg->text(); + } + + /** + * Get a description for this interwiki + * + * @return string + */ + public function getDescription() { + $msg = wfMessage( 'interwiki-desc-' . $this->mPrefix )->inContentLanguage(); + + return !$msg->exists() ? '' : $msg->text(); + } + +} diff --git a/www/wiki/includes/interwiki/InterwikiLookup.php b/www/wiki/includes/interwiki/InterwikiLookup.php new file mode 100644 index 00000000..697e39d5 --- /dev/null +++ b/www/wiki/includes/interwiki/InterwikiLookup.php @@ -0,0 +1,74 @@ +<?php +namespace MediaWiki\Interwiki; + +/** + * Service interface for looking up Interwiki records. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + */ +use Interwiki; + +/** + * Service interface for looking up Interwiki records. + * + * @since 1.28 + */ +interface InterwikiLookup { + + /** + * Check whether an interwiki prefix exists + * + * @param string $prefix Interwiki prefix to use + * @return bool Whether it exists + */ + public function isValidInterwiki( $prefix ); + + /** + * Fetch an Interwiki object + * + * @param string $prefix Interwiki prefix to use + * @return Interwiki|null|bool + */ + public function fetch( $prefix ); + + /** + * Returns information about all interwiki prefixes, in the form of rows + * of the interwiki table. Each row may have the following keys: + * + * - iw_prefix: the prefix. Always present. + * - iw_url: the URL to use for linking, with $1 as a placeholder for the target page. + * Always present. + * - iw_api: the URL of the API. Optional. + * - iw_wikiid: the wiki ID (usually the database name for local wikis). Optional. + * - iw_local: whether the wiki is local, and the "magic redirect" mechanism should apply. + * Defaults to false. + * - iw_trans: whether "scary transclusion" is allowed for this site. + * Defaults to false. + * + * @param string|null $local If set, limits output to local/non-local interwikis + * @return array[] interwiki rows. + */ + public function getAllPrefixes( $local = null ); + + /** + * Purge the in-process and persistent object cache for an interwiki prefix + * @param string $prefix + */ + public function invalidateCache( $prefix ); + +} diff --git a/www/wiki/includes/interwiki/InterwikiLookupAdapter.php b/www/wiki/includes/interwiki/InterwikiLookupAdapter.php new file mode 100644 index 00000000..076c37fe --- /dev/null +++ b/www/wiki/includes/interwiki/InterwikiLookupAdapter.php @@ -0,0 +1,178 @@ +<?php +namespace MediaWiki\Interwiki; + +/** + * InterwikiLookupAdapter on top of SiteLookup + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * + * @since 1.29 + * @ingroup InterwikiLookup + * + * @license GNU GPL v2+ + */ + +use Interwiki; +use Site; +use SiteLookup; +use MediaWikiSite; + +class InterwikiLookupAdapter implements InterwikiLookup { + + /** + * @var SiteLookup + */ + private $siteLookup; + + /** + * @var Interwiki[]|null associative array mapping interwiki prefixes to Interwiki objects + */ + private $interwikiMap; + + function __construct( + SiteLookup $siteLookup, + array $interwikiMap = null + ) { + $this->siteLookup = $siteLookup; + $this->interwikiMap = $interwikiMap; + } + + /** + * See InterwikiLookup::isValidInterwiki + * It loads the whole interwiki map. + * + * @param string $prefix Interwiki prefix to use + * @return bool Whether it exists + */ + public function isValidInterwiki( $prefix ) { + return array_key_exists( $prefix, $this->getInterwikiMap() ); + } + + /** + * See InterwikiLookup::fetch + * It loads the whole interwiki map. + * + * @param string $prefix Interwiki prefix to use + * @return Interwiki|null|bool + */ + public function fetch( $prefix ) { + if ( $prefix == '' ) { + return null; + } + + if ( !$this->isValidInterwiki( $prefix ) ) { + return false; + } + + return $this->interwikiMap[$prefix]; + } + + /** + * See InterwikiLookup::getAllPrefixes + * + * @param string|null $local If set, limits output to local/non-local interwikis + * @return array[] interwiki rows + */ + public function getAllPrefixes( $local = null ) { + $res = []; + foreach ( $this->getInterwikiMap() as $interwikiId => $interwiki ) { + if ( $local === null || $interwiki->isLocal() === $local ) { + $res[] = [ + 'iw_prefix' => $interwikiId, + 'iw_url' => $interwiki->getURL(), + 'iw_api' => $interwiki->getAPI(), + 'iw_wikiid' => $interwiki->getWikiID(), + 'iw_local' => $interwiki->isLocal(), + 'iw_trans' => $interwiki->isTranscludable(), + ]; + } + } + return $res; + } + + /** + * See InterwikiLookup::invalidateCache + * + * @param string $prefix + */ + public function invalidateCache( $prefix ) { + if ( !isset( $this->interwikiMap[$prefix] ) ) { + return; + } + $globalId = $this->interwikiMap[$prefix]->getWikiID(); + unset( $this->interwikiMap[$prefix] ); + + // Reload the interwiki + $site = $this->siteLookup->getSites()->getSite( $globalId ); + $interwikis = $this->getSiteInterwikis( $site ); + $this->interwikiMap = array_merge( $this->interwikiMap, [ $interwikis[$prefix] ] ); + } + + /** + * Load interwiki map to use as cache + */ + private function loadInterwikiMap() { + $interwikiMap = []; + $siteList = $this->siteLookup->getSites(); + foreach ( $siteList as $site ) { + $interwikis = $this->getSiteInterwikis( $site ); + $interwikiMap = array_merge( $interwikiMap, $interwikis ); + } + $this->interwikiMap = $interwikiMap; + } + + /** + * Get interwikiMap attribute, load if needed. + * + * @return Interwiki[] + */ + private function getInterwikiMap() { + if ( $this->interwikiMap === null ) { + $this->loadInterwikiMap(); + } + return $this->interwikiMap; + } + + /** + * Load interwikis for the given site + * + * @param Site $site + * @return Interwiki[] + */ + private function getSiteInterwikis( Site $site ) { + $interwikis = []; + foreach ( $site->getInterwikiIds() as $interwiki ) { + $url = $site->getPageUrl(); + if ( $site instanceof MediaWikiSite ) { + $path = $site->getFileUrl( 'api.php' ); + } else { + $path = ''; + } + $local = $site->getSource() === 'local'; + // TODO: How to adapt trans? + $interwikis[$interwiki] = new Interwiki( + $interwiki, + $url, + $path, + $site->getGlobalId(), + $local + ); + } + return $interwikis; + } +} diff --git a/www/wiki/includes/interwiki/NullInterwikiLookup.php b/www/wiki/includes/interwiki/NullInterwikiLookup.php new file mode 100644 index 00000000..09fa1ecd --- /dev/null +++ b/www/wiki/includes/interwiki/NullInterwikiLookup.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright (C) 2018 Kunal Mehta <legoktm@member.fsf.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +namespace MediaWiki\Interwiki; + +/** + * An interwiki lookup that has no data, intended + * for use in the installer. + * + * @since 1.31 + */ +class NullInterwikiLookup implements InterwikiLookup { + + /** + * @inheritDoc + */ + public function isValidInterwiki( $prefix ) { + return false; + } + + /** + * @inheritDoc + */ + public function fetch( $prefix ) { + return false; + } + + /** + * @inheritDoc + */ + public function getAllPrefixes( $local = null ) { + return []; + } + + /** + * @inheritDoc + */ + public function invalidateCache( $prefix ) { + } +} |