From 844e7c83e46b0dc2c111caf4ff4358005ddf43a8 Mon Sep 17 00:00:00 2001 From: Robin Pepermans Date: Tue, 19 Jul 2011 12:30:18 +0000 Subject: [PATCH] (bug 19838) API does not use interwiki cache. Patch by Beau; modified to work with current code. --- CREDITS | 3 + RELEASE-NOTES-1.19 | 1 + includes/api/ApiQuerySiteinfo.php | 37 +++++----- includes/interwiki/Interwiki.php | 119 ++++++++++++++++++++++++++++++ maintenance/dumpInterwiki.php | 16 +++- 5 files changed, 156 insertions(+), 20 deletions(-) diff --git a/CREDITS b/CREDITS index 7c29b108af..8aa0c78be0 100644 --- a/CREDITS +++ b/CREDITS @@ -158,6 +158,9 @@ following names for their contribution to the product. * Yuvaraj Pandian T * Zachary Hauri +== Patch Contributors == +* Beau + == Translators == * Anders Wegge Jakobsen * Hk kng diff --git a/RELEASE-NOTES-1.19 b/RELEASE-NOTES-1.19 index 53e6c34fad..deba302291 100644 --- a/RELEASE-NOTES-1.19 +++ b/RELEASE-NOTES-1.19 @@ -15,6 +15,7 @@ production. === New features in 1.19 === === Bug fixes in 1.19 === +* (bug 19838) API does not use interwiki cache. === API changes in 1.19 === diff --git a/includes/api/ApiQuerySiteinfo.php b/includes/api/ApiQuerySiteinfo.php index 20d1f6562b..3491b90800 100644 --- a/includes/api/ApiQuerySiteinfo.php +++ b/includes/api/ApiQuerySiteinfo.php @@ -256,37 +256,36 @@ class ApiQuerySiteinfo extends ApiQueryBase { } protected function appendInterwikiMap( $property, $filter ) { - $this->resetQueryParams(); - $this->addTables( 'interwiki' ); - $this->addFields( array( 'iw_prefix', 'iw_local', 'iw_url', 'iw_wikiid', 'iw_api' ) ); - + $local = null; if ( $filter === 'local' ) { - $this->addWhere( 'iw_local = 1' ); + $local = 1; } elseif ( $filter === '!local' ) { - $this->addWhere( 'iw_local = 0' ); + $local = 0; } elseif ( $filter ) { ApiBase::dieDebug( __METHOD__, "Unknown filter=$filter" ); } - $this->addOption( 'ORDER BY', 'iw_prefix' ); - - $res = $this->select( __METHOD__ ); - + $getPrefixes = Interwiki::getAllPrefixes( $local ); $data = array(); $langNames = Language::getLanguageNames(); - foreach ( $res as $row ) { + foreach ( $getPrefixes as $row ) { + $prefix = $row['iw_prefix']; $val = array(); - $val['prefix'] = $row->iw_prefix; - if ( $row->iw_local == '1' ) { + $val['prefix'] = $prefix; + if ( $row['iw_local'] == '1' ) { $val['local'] = ''; } - // $val['trans'] = intval( $row->iw_trans ); // should this be exposed? - if ( isset( $langNames[$row->iw_prefix] ) ) { - $val['language'] = $langNames[$row->iw_prefix]; + // $val['trans'] = intval( $row['iw_trans'] ); // should this be exposed? + if ( isset( $langNames[$prefix] ) ) { + $val['language'] = $langNames[$prefix]; + } + $val['url'] = wfExpandUrl( $row['iw_url'] ); + if( isset( $row['iw_wikiid'] ) ) { + $val['wikiid'] = $row['iw_wikiid']; + } + if( isset( $row['iw_api'] ) ) { + $val['api'] = $row['iw_api']; } - $val['url'] = wfExpandUrl( $row->iw_url ); - $val['wikiid'] = $row->iw_wikiid; - $val['api'] = $row->iw_api; $data[] = $val; } diff --git a/includes/interwiki/Interwiki.php b/includes/interwiki/Interwiki.php index 71bd9725a0..94cca10a6f 100644 --- a/includes/interwiki/Interwiki.php +++ b/includes/interwiki/Interwiki.php @@ -198,6 +198,125 @@ class Interwiki { return false; } + /** + * Fetch all interwiki prefixes from interwiki cache + * + * @param $local If set, limits output to local/non-local interwikis + * @return Array List of prefixes + * @since 1.19 + * @static + */ + protected static function getAllPrefixesCached( $local ) { + global $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite; + static $db, $site; + + wfDebug( __METHOD__ . "()\n" ); + if( !$db ) { + $db = CdbReader::open( $wgInterwikiCache ); + } + /* Resolve site name */ + if( $wgInterwikiScopes >= 3 && !$site ) { + $site = $db->get( '__sites:' . wfWikiID() ); + if ( $site == '' ) { + $site = $wgInterwikiFallbackSite; + } + } + + // List of interwiki sources + $sources = array(); + // Global Level + if ( $wgInterwikiScopes >= 2 ) { + $sources[] = '__global'; + } + // Site level + if ( $wgInterwikiScopes >= 3 ) { + $sources[] = '_' . $site; + } + $sources[] = wfWikiID(); + + $data = array(); + + foreach( $sources as $source ) { + $list = $db->get( "__list:{$source}" ); + foreach ( explode( ' ', $list ) as $iw_prefix ) { + $row = $db->get( "{$source}:{$iw_prefix}" ); + if( !$row ) { + continue; + } + + list( $iw_local, $iw_url ) = explode( ' ', $row ); + + if ( isset( $local ) && $local != $iw_local ) { + continue; + } + + $data[$iw_prefix] = array( + 'iw_prefix' => $iw_prefix, + 'iw_url' => $iw_url, + 'iw_local' => $iw_local, + ); + } + } + + ksort( $data ); + + return array_values( $data ); + } + + /** + * Fetch all interwiki prefixes from DB + * + * @param $local If set, limits output to local/non-local interwikis + * @return Array List of prefixes + * @since 1.19 + * @static + */ + protected static function getAllPrefixesDb( $local ) { + $db = wfGetDB( DB_SLAVE ); + + $where = array(); + + if ( isset($local) ) { + if ( $local == 1 ) { + $where['iw_local'] = 1; + } + elseif ( $local == 0 ) { + $where['iw_local'] = 0; + } + } + + $res = $db->select( 'interwiki', + array( 'iw_prefix', 'iw_url', 'iw_api', 'iw_wikiid', 'iw_local', 'iw_trans' ), + $where, __METHOD__, array( 'ORDER BY' => 'iw_prefix' ) + ); + + $data = array(); + while( $row = $db->fetchRow($res) ) { + $data[] = $row; + } + $db->freeResult( $res ); + + return $data; + } + + /** + * Returns all interwiki prefixes + * + * @param $local If set, limits output to local/non-local interwikis + * @return Array List of prefixes + * @since 1.19 + * @static + */ + public static function getAllPrefixes( $local ) { + global $wgInterwikiCache; + + if ( $wgInterwikiCache ) { + return self::getAllPrefixesCached( $local ); + } else { + return self::getAllPrefixesDb( $local ); + } + } + /** * Get the URL for a particular title (or with $1 if no title given) * diff --git a/maintenance/dumpInterwiki.php b/maintenance/dumpInterwiki.php index b4f8e82fab..254ebb50b0 100644 --- a/maintenance/dumpInterwiki.php +++ b/maintenance/dumpInterwiki.php @@ -118,7 +118,7 @@ class DumpInterwiki extends Maintenance { $this->error( "m:Interwiki_map not found", true ); } - # Global iterwiki map + # Global interwiki map foreach ( $lines as $line ) { if ( preg_match( '/^\|\s*(.*?)\s*\|\|\s*(.*?)\s*$/', $line, $matches ) ) { $prefix = $wgContLang->lc( $matches[1] ); @@ -195,6 +195,17 @@ class DumpInterwiki extends Maintenance { foreach ( $extraLinks as $link ) { $this->makeLink( $link, "__global" ); } + + # List prefixes for each source + foreach ( $this->prefixLists as $source => $hash ) { + $list = array_keys( $hash ); + sort( $list ); + if ( $this->dbFile ) { + $this->dbFile->set( "__list:{$source}", implode( ' ', $list ) ); + } else { + print "__list:{$source} " . implode( ' ', $list ) . "\n"; + } + } } # ------------------------------------------------------------------------------------------ @@ -229,6 +240,9 @@ class DumpInterwiki extends Maintenance { } else { $this->output( "{$source}:{$entry['iw_prefix']} {$entry['iw_url']} {$entry['iw_local']}\n" ); } + + # Add to list of prefixes + $this->prefixLists[$source][$entry['iw_prefix']] = 1; } } -- 2.20.1