From 56195efaa10e10d67d5f7e85029d64df52a0f7aa Mon Sep 17 00:00:00 2001 From: Amir Sarabadani Date: Sun, 25 Sep 2016 01:09:10 +0330 Subject: Introduce InterwikiLookupAdapter on top of SiteLookup This adapter assumes the db name (Interwiki wiki id) equals global ids. Bug: T135146 Change-Id: I387dc2ff3f5564fcedde835dec66781d8e9424fd --- includes/interwiki/InterwikiLookupAdapter.php | 175 ++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 includes/interwiki/InterwikiLookupAdapter.php (limited to 'includes/interwiki') diff --git a/includes/interwiki/InterwikiLookupAdapter.php b/includes/interwiki/InterwikiLookupAdapter.php new file mode 100644 index 000000000000..a17bdd9b2e00 --- /dev/null +++ b/includes/interwiki/InterwikiLookupAdapter.php @@ -0,0 +1,175 @@ +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 string[] List of prefixes + */ + public function getAllPrefixes( $local = null ) { + if ( $local === null ) { + return array_keys( $this->getInterwikiMap() ); + } + $res = []; + foreach ( $this->getInterwikiMap() as $interwikiId => $interwiki ) { + if ( $interwiki->isLocal() === $local ) { + $res[] = $interwikiId; + } + } + 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; + } +} -- cgit v1.2.3