(bug 19838) API does not use interwiki cache.
authorRobin Pepermans <robin@users.mediawiki.org>
Tue, 19 Jul 2011 12:30:18 +0000 (12:30 +0000)
committerRobin Pepermans <robin@users.mediawiki.org>
Tue, 19 Jul 2011 12:30:18 +0000 (12:30 +0000)
Patch by Beau; modified to work with current code.

CREDITS
RELEASE-NOTES-1.19
includes/api/ApiQuerySiteinfo.php
includes/interwiki/Interwiki.php
maintenance/dumpInterwiki.php

diff --git a/CREDITS b/CREDITS
index 7c29b10..8aa0c78 100644 (file)
--- 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
index 53e6c34..deba302 100644 (file)
@@ -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 ===
 
index 20d1f65..3491b90 100644 (file)
@@ -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;
                }
index 71bd972..94cca10 100644 (file)
@@ -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)
         *
index b4f8e82..254ebb5 100644 (file)
@@ -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;
        }
 }