MessageCache invalidation improvements
[mediawiki.git] / includes / interwiki / InterwikiLookupAdapter.php
blob60d6f43ddd1313f6e27949a54f7cd581cbf47b21
1 <?php
2 namespace MediaWiki\Interwiki;
4 /**
5 * InterwikiLookupAdapter on top of SiteLookup
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * http://www.gnu.org/copyleft/gpl.html
22 * @file
24 * @since 1.29
25 * @ingroup InterwikiLookup
27 * @license GNU GPL v2+
30 use Interwiki;
31 use Site;
32 use SiteLookup;
33 use MediaWikiSite;
35 class InterwikiLookupAdapter implements InterwikiLookup {
37 /**
38 * @var SiteLookup
40 private $siteLookup;
42 /**
43 * @var Interwiki[]|null associative array mapping interwiki prefixes to Interwiki objects
45 private $interwikiMap;
47 function __construct(
48 SiteLookup $siteLookup,
49 array $interwikiMap = null
50 ) {
51 $this->siteLookup = $siteLookup;
52 $this->interwikiMap = $interwikiMap;
55 /**
56 * See InterwikiLookup::isValidInterwiki
57 * It loads the whole interwiki map.
59 * @param string $prefix Interwiki prefix to use
60 * @return bool Whether it exists
62 public function isValidInterwiki( $prefix ) {
64 return array_key_exists( $prefix, $this->getInterwikiMap() );
67 /**
68 * See InterwikiLookup::fetch
69 * It loads the whole interwiki map.
71 * @param string $prefix Interwiki prefix to use
72 * @return Interwiki|null|bool
74 public function fetch( $prefix ) {
75 if ( $prefix == '' ) {
76 return null;
79 if ( !$this->isValidInterwiki( $prefix ) ) {
80 return false;
83 return $this->interwikiMap[$prefix];
86 /**
87 * See InterwikiLookup::getAllPrefixes
89 * @param string|null $local If set, limits output to local/non-local interwikis
90 * @return string[] List of prefixes
92 public function getAllPrefixes( $local = null ) {
93 if ( $local === null ) {
94 return array_keys( $this->getInterwikiMap() );
96 $res = [];
97 foreach ( $this->getInterwikiMap() as $interwikiId => $interwiki ) {
98 if ( $interwiki->isLocal() === $local ) {
99 $res[] = $interwikiId;
102 return $res;
106 * See InterwikiLookup::invalidateCache
108 * @param string $prefix
110 public function invalidateCache( $prefix ) {
111 if ( !isset( $this->interwikiMap[$prefix] ) ) {
112 return;
114 $globalId = $this->interwikiMap[$prefix]->getWikiID();
115 unset( $this->interwikiMap[$prefix] );
117 // Reload the interwiki
118 $site = $this->siteLookup->getSites()->getSite( $globalId );
119 $interwikis = $this->getSiteInterwikis( $site );
120 $this->interwikiMap = array_merge( $this->interwikiMap, [ $interwikis[$prefix] ] );
124 * Load interwiki map to use as cache
126 private function loadInterwikiMap() {
127 $interwikiMap = [];
128 $siteList = $this->siteLookup->getSites();
129 foreach ( $siteList as $site ) {
130 $interwikis = $this->getSiteInterwikis( $site );
131 $interwikiMap = array_merge( $interwikiMap, $interwikis );
133 $this->interwikiMap = $interwikiMap;
137 * Get interwikiMap attribute, load if needed.
139 * @return Interwiki[]
141 private function getInterwikiMap() {
142 if ( $this->interwikiMap === null ) {
143 $this->loadInterwikiMap();
145 return $this->interwikiMap;
149 * Load interwikis for the given site
151 * @param Site $site
152 * @return Interwiki[]
154 private function getSiteInterwikis( Site $site ) {
155 $interwikis = [];
156 foreach ( $site->getInterwikiIds() as $interwiki ) {
157 $url = $site->getPageUrl();
158 if ( $site instanceof MediaWikiSite ) {
159 $path = $site->getFileUrl( 'api.php' );
160 } else {
161 $path = '';
163 $local = $site->getSource() === 'local';
164 // TODO: How to adapt trans?
165 $interwikis[$interwiki] = new Interwiki(
166 $interwiki,
167 $url,
168 $path,
169 $site->getGlobalId(),
170 $local
173 return $interwikis;