X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Finterwiki%2FInterwiki.php;h=558e32c11ecf8c77cb608826776d81738063751d;hb=925f65c1400a3f5ec22ea9edc3c07f1d06fa368d;hp=5a0dd36fa8009769c922a291e86de1ca499ea143;hpb=20b4f9d311ba743b88e277907293e5f8f2bb6ee1;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/interwiki/Interwiki.php b/includes/interwiki/Interwiki.php index 5a0dd36fa8..558e32c11e 100644 --- a/includes/interwiki/Interwiki.php +++ b/includes/interwiki/Interwiki.php @@ -19,19 +19,12 @@ * * @file */ -use \Cdb\Exception as CdbException; -use \Cdb\Reader as CdbReader; +use MediaWiki\MediaWikiServices; /** - * The interwiki class - * All information is loaded on creation when called by Interwiki::fetch( $prefix ). - * All work is done on slave, because this should *never* change (except during - * schema updates etc, which aren't wiki-related) + * Value object for representing interwiki records. */ class Interwiki { - // Cache - removes oldest entry when it hits limit - protected static $smCache = []; - const CACHE_LIMIT = 100; // 0 means unlimited, any other value is max number of entries. /** @var string The interwiki prefix, (e.g. "Meatball", or the language prefix "de") */ protected $mPrefix; @@ -67,335 +60,48 @@ class Interwiki { /** * 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 ) { - $result = self::fetch( $prefix ); - - return (bool)$result; + 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 ) { - global $wgContLang; - - if ( $prefix == '' ) { - return null; - } - - $prefix = $wgContLang->lc( $prefix ); - if ( isset( self::$smCache[$prefix] ) ) { - return self::$smCache[$prefix]; - } - - global $wgInterwikiCache; - if ( $wgInterwikiCache ) { - $iw = Interwiki::getInterwikiCached( $prefix ); - } else { - $iw = Interwiki::load( $prefix ); - if ( !$iw ) { - $iw = false; - } - } - - if ( self::CACHE_LIMIT && count( self::$smCache ) >= self::CACHE_LIMIT ) { - reset( self::$smCache ); - unset( self::$smCache[key( self::$smCache )] ); - } - - self::$smCache[$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 static function resetLocalCache() { - static::$smCache = []; + 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 ) { - $cache = ObjectCache::getMainWANInstance(); - $key = wfMemcKey( 'interwiki', $prefix ); - $cache->delete( $key ); - unset( static::$smCache[$prefix] ); - } - - /** - * Fetch interwiki prefix data from local cache in constant database. - * - * @note More logic is explained in DefaultSettings. - * - * @param string $prefix Interwiki prefix - * @return Interwiki - */ - protected static function getInterwikiCached( $prefix ) { - $value = self::getInterwikiCacheEntry( $prefix ); - - $s = new Interwiki( $prefix ); - if ( $value ) { - // Split values - list( $local, $url ) = explode( ' ', $value, 2 ); - $s->mURL = $url; - $s->mLocal = (bool)$local; - } else { - $s = false; - } - - return $s; - } - - /** - * 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 - */ - protected static function getInterwikiCacheEntry( $prefix ) { - global $wgInterwikiScopes, $wgInterwikiFallbackSite; - static $site; - - $value = false; - try { - // Resolve site name - if ( $wgInterwikiScopes >= 3 && !$site ) { - $site = self::getCacheValue( '__sites:' . wfWikiID() ); - if ( $site == '' ) { - $site = $wgInterwikiFallbackSite; - } - } - - $value = self::getCacheValue( wfMemcKey( $prefix ) ); - // Site level - if ( $value == '' && $wgInterwikiScopes >= 3 ) { - $value = self::getCacheValue( "_{$site}:{$prefix}" ); - } - // Global Level - if ( $value == '' && $wgInterwikiScopes >= 2 ) { - $value = self::getCacheValue( "__global:{$prefix}" ); - } - if ( $value == 'undef' ) { - $value = ''; - } - } catch ( CdbException $e ) { - wfDebug( __METHOD__ . ": CdbException caught, error message was " - . $e->getMessage() ); - } - - return $value; - } - - private static function getCacheValue( $key ) { - global $wgInterwikiCache; - static $reader; - if ( $reader === null ) { - $reader = is_array( $wgInterwikiCache ) ? false : CdbReader::open( $wgInterwikiCache ); - } - if ( $reader ) { - return $reader->get( $key ); - } else { - return isset( $wgInterwikiCache[$key] ) ? $wgInterwikiCache[$key] : 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 - */ - protected static function load( $prefix ) { - global $wgInterwikiExpiry; - - $iwData = []; - if ( !Hooks::run( 'InterwikiLoadPrefix', [ $prefix, &$iwData ] ) ) { - return Interwiki::loadFromArray( $iwData ); - } - - if ( is_array( $iwData ) ) { - $iw = Interwiki::loadFromArray( $iwData ); - if ( $iw ) { - return $iw; // handled by hook - } - } - - $iwData = ObjectCache::getMainWANInstance()->getWithSetCallback( - wfMemcKey( 'interwiki', $prefix ), - $wgInterwikiExpiry, - function ( $oldValue, &$ttl, array &$setOpts ) use ( $prefix ) { - $dbr = wfGetDB( DB_SLAVE ); - - $setOpts += Database::getCacheSetOptions( $dbr ); - - $row = $dbr->selectRow( - 'interwiki', - Interwiki::selectFields(), - [ 'iw_prefix' => $prefix ], - __METHOD__ - ); - - return $row ? (array)$row : '!NONEXISTENT'; - } - ); - - if ( is_array( $iwData ) ) { - return Interwiki::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 - */ - protected static function loadFromArray( $mc ) { - if ( isset( $mc['iw_url'] ) ) { - $iw = new Interwiki(); - $iw->mURL = $mc['iw_url']; - $iw->mLocal = isset( $mc['iw_local'] ) ? (bool)$mc['iw_local'] : false; - $iw->mTrans = isset( $mc['iw_trans'] ) ? (bool)$mc['iw_trans'] : false; - $iw->mAPI = isset( $mc['iw_api'] ) ? $mc['iw_api'] : ''; - $iw->mWikiID = isset( $mc['iw_wikiid'] ) ? $mc['iw_wikiid'] : ''; - - return $iw; - } - - 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 - * @since 1.19 - */ - protected static function getAllPrefixesCached( $local ) { - global $wgInterwikiScopes, $wgInterwikiFallbackSite; - static $site; - - wfDebug( __METHOD__ . "()\n" ); - $data = []; - try { - /* Resolve site name */ - if ( $wgInterwikiScopes >= 3 && !$site ) { - $site = self::getCacheValue( '__sites:' . wfWikiID() ); - - if ( $site == '' ) { - $site = $wgInterwikiFallbackSite; - } - } - - // List of interwiki sources - $sources = []; - // Global Level - if ( $wgInterwikiScopes >= 2 ) { - $sources[] = '__global'; - } - // Site level - if ( $wgInterwikiScopes >= 3 ) { - $sources[] = '_' . $site; - } - $sources[] = wfWikiID(); - - foreach ( $sources as $source ) { - $list = self::getCacheValue( '__list:' . $source ); - foreach ( explode( ' ', $list ) as $iw_prefix ) { - $row = self::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() ); - } - - ksort( $data ); - - 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 List of prefixes - * @since 1.19 - */ - protected static function getAllPrefixesDB( $local ) { - $db = wfGetDB( DB_SLAVE ); - - $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; + return MediaWikiServices::getInstance()->getInterwikiLookup()->invalidateCache( $prefix ); } /** * Returns all interwiki prefixes * + * @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 prefixes * @since 1.19 */ public static function getAllPrefixes( $local = null ) { - global $wgInterwikiCache; - - if ( $wgInterwikiCache ) { - return self::getAllPrefixesCached( $local ); - } - - return self::getAllPrefixesDB( $local ); + return MediaWikiServices::getInstance()->getInterwikiLookup()->getAllPrefixes( $local ); } /** @@ -476,19 +182,4 @@ class Interwiki { return !$msg->exists() ? '' : $msg->text(); } - /** - * Return the list of interwiki fields that should be selected to create - * a new Interwiki object. - * @return string[] - */ - public static function selectFields() { - return [ - 'iw_prefix', - 'iw_url', - 'iw_api', - 'iw_wikiid', - 'iw_local', - 'iw_trans' - ]; - } }