Merge "Selenium: replace UserLoginPage with BlankPage where possible"
[lhc/web/wiklou.git] / includes / interwiki / InterwikiLookupAdapter.php
1 <?php
2
3 namespace MediaWiki\Interwiki;
4
5 /**
6 * InterwikiLookupAdapter on top of SiteLookup
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * http://www.gnu.org/copyleft/gpl.html
22 *
23 * @file
24 *
25 * @since 1.29
26 * @ingroup InterwikiLookup
27 *
28 * @license GPL-2.0-or-later
29 */
30
31 use Interwiki;
32 use Site;
33 use SiteLookup;
34 use MediaWikiSite;
35
36 class InterwikiLookupAdapter implements InterwikiLookup {
37
38 /**
39 * @var SiteLookup
40 */
41 private $siteLookup;
42
43 /**
44 * @var Interwiki[]|null associative array mapping interwiki prefixes to Interwiki objects
45 */
46 private $interwikiMap;
47
48 function __construct(
49 SiteLookup $siteLookup,
50 array $interwikiMap = null
51 ) {
52 $this->siteLookup = $siteLookup;
53 $this->interwikiMap = $interwikiMap;
54 }
55
56 /**
57 * See InterwikiLookup::isValidInterwiki
58 * It loads the whole interwiki map.
59 *
60 * @param string $prefix Interwiki prefix to use
61 * @return bool Whether it exists
62 */
63 public function isValidInterwiki( $prefix ) {
64 return array_key_exists( $prefix, $this->getInterwikiMap() );
65 }
66
67 /**
68 * See InterwikiLookup::fetch
69 * It loads the whole interwiki map.
70 *
71 * @param string $prefix Interwiki prefix to use
72 * @return Interwiki|null|bool
73 */
74 public function fetch( $prefix ) {
75 if ( $prefix == '' ) {
76 return null;
77 }
78
79 if ( !$this->isValidInterwiki( $prefix ) ) {
80 return false;
81 }
82
83 return $this->interwikiMap[$prefix];
84 }
85
86 /**
87 * See InterwikiLookup::getAllPrefixes
88 *
89 * @param string|null $local If set, limits output to local/non-local interwikis
90 * @return array[] interwiki rows
91 */
92 public function getAllPrefixes( $local = null ) {
93 $res = [];
94 foreach ( $this->getInterwikiMap() as $interwikiId => $interwiki ) {
95 if ( $local === null || $interwiki->isLocal() === $local ) {
96 $res[] = [
97 'iw_prefix' => $interwikiId,
98 'iw_url' => $interwiki->getURL(),
99 'iw_api' => $interwiki->getAPI(),
100 'iw_wikiid' => $interwiki->getWikiID(),
101 'iw_local' => $interwiki->isLocal(),
102 'iw_trans' => $interwiki->isTranscludable(),
103 ];
104 }
105 }
106 return $res;
107 }
108
109 /**
110 * See InterwikiLookup::invalidateCache
111 *
112 * @param string $prefix
113 */
114 public function invalidateCache( $prefix ) {
115 if ( !isset( $this->interwikiMap[$prefix] ) ) {
116 return;
117 }
118 $globalId = $this->interwikiMap[$prefix]->getWikiID();
119 unset( $this->interwikiMap[$prefix] );
120
121 // Reload the interwiki
122 $site = $this->siteLookup->getSites()->getSite( $globalId );
123 $interwikis = $this->getSiteInterwikis( $site );
124 $this->interwikiMap = array_merge( $this->interwikiMap, [ $interwikis[$prefix] ] );
125 }
126
127 /**
128 * Load interwiki map to use as cache
129 */
130 private function loadInterwikiMap() {
131 $interwikiMap = [];
132 $siteList = $this->siteLookup->getSites();
133 foreach ( $siteList as $site ) {
134 $interwikis = $this->getSiteInterwikis( $site );
135 $interwikiMap = array_merge( $interwikiMap, $interwikis );
136 }
137 $this->interwikiMap = $interwikiMap;
138 }
139
140 /**
141 * Get interwikiMap attribute, load if needed.
142 *
143 * @return Interwiki[]
144 */
145 private function getInterwikiMap() {
146 if ( $this->interwikiMap === null ) {
147 $this->loadInterwikiMap();
148 }
149 return $this->interwikiMap;
150 }
151
152 /**
153 * Load interwikis for the given site
154 *
155 * @param Site $site
156 * @return Interwiki[]
157 */
158 private function getSiteInterwikis( Site $site ) {
159 $interwikis = [];
160 foreach ( $site->getInterwikiIds() as $interwiki ) {
161 $url = $site->getPageUrl();
162 if ( $site instanceof MediaWikiSite ) {
163 $path = $site->getFileUrl( 'api.php' );
164 } else {
165 $path = '';
166 }
167 $local = $site->getSource() === 'local';
168 // TODO: How to adapt trans?
169 $interwikis[$interwiki] = new Interwiki(
170 $interwiki,
171 $url,
172 $path,
173 $site->getGlobalId(),
174 $local
175 );
176 }
177 return $interwikis;
178 }
179 }