Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
Hooks
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 3
306
0.00% covered (danger)
0.00%
0 / 1
 onExtensionFunctions
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
42
 onUserGetAllRights
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 onInterwikiLoadPrefix
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
90
1<?php
2
3namespace MediaWiki\Extension\Interwiki;
4
5use MediaWiki\MediaWikiServices;
6use MediaWiki\Permissions\Hook\UserGetAllRightsHook;
7use MediaWiki\WikiMap\WikiMap;
8
9class Hooks implements UserGetAllRightsHook {
10    /** @var bool */
11    private static $shouldSkipIWCheck = false;
12    /** @var bool */
13    private static $shouldSkipILCheck = false;
14
15    public static function onExtensionFunctions() {
16        global $wgInterwikiViewOnly;
17
18        if ( !$wgInterwikiViewOnly ) {
19            global $wgLogTypes;
20
21            // Set up the new log type - interwiki actions are logged to this new log
22            // TODO: Move this out of an extension function once T200385 is implemented.
23            $wgLogTypes[] = 'interwiki';
24        }
25        // Register the (deprecated) InterwikiLoadPrefix hook only if one
26        // of the wgInterwiki*CentralDB globals is set.
27        global $wgInterwikiCentralDB, $wgInterwikiCentralInterlanguageDB;
28
29        self::$shouldSkipIWCheck = (
30            $wgInterwikiCentralDB === null ||
31            $wgInterwikiCentralDB === WikiMap::getCurrentWikiId()
32        );
33        self::$shouldSkipILCheck = (
34            $wgInterwikiCentralInterlanguageDB === null ||
35            $wgInterwikiCentralInterlanguageDB === WikiMap::getCurrentWikiId()
36        );
37        if ( self::$shouldSkipIWCheck && self::$shouldSkipILCheck ) {
38            // Bail out early if _neither_ $wgInterwiki*CentralDB
39            // global is set; if one or both are set, we gotta register
40            // the InterwikiLoadPrefix hook.
41            return;
42        }
43        // This will trigger a deprecation warning in MW 1.36+
44        MediaWikiServices::getInstance()->getHookContainer()->register(
45            'InterwikiLoadPrefix', 'MediaWiki\Extension\Interwiki\Hooks::onInterwikiLoadPrefix'
46        );
47    }
48
49    /**
50     * @param array &$rights
51     */
52    public function onUserGetAllRights( &$rights ) {
53        global $wgInterwikiViewOnly;
54        if ( !$wgInterwikiViewOnly ) {
55            // New user right, required to modify the interwiki table through Special:Interwiki
56            $rights[] = 'interwiki';
57        }
58    }
59
60    public static function onInterwikiLoadPrefix( $prefix, &$iwData ) {
61        global $wgInterwikiCentralDB, $wgInterwikiCentralInterlanguageDB;
62
63        $services = MediaWikiServices::getInstance();
64        $connectionProvider = $services->getConnectionProvider();
65        $isInterlanguageLink = $services->getLanguageNameUtils()->getLanguageName( $prefix );
66        if ( !$isInterlanguageLink && !self::$shouldSkipIWCheck ) {
67            // Check if prefix exists locally and skip
68            $lookup = $services->getInterwikiLookup();
69            foreach ( $lookup->getAllPrefixes( null ) as $id => $localPrefixInfo ) {
70                if ( $prefix === $localPrefixInfo['iw_prefix'] ) {
71                    return true;
72                }
73            }
74
75            $dbrCentralDB = $connectionProvider->getReplicaDatabase( $wgInterwikiCentralDB ?? false );
76
77            $res = $dbrCentralDB->newSelectQueryBuilder()
78                ->select( '*' )
79                ->from( 'interwiki' )
80                ->where( [ 'iw_prefix' => $prefix ] )
81                ->caller( __METHOD__ )
82                ->fetchRow();
83            if ( !$res ) {
84                return true;
85            }
86            // Explicitly make this an array since it's expected to be one
87            $iwData = (array)$res;
88            // At this point, we can safely return false because we know that we have something
89            return false;
90        } elseif ( $isInterlanguageLink && !self::$shouldSkipILCheck ) {
91            // Global interlanguage link? Whoo!
92            $dbrCentralLangDB = $connectionProvider->getReplicaDatabase( $wgInterwikiCentralInterlanguageDB ?? false );
93
94            $res = $dbrCentralLangDB->newSelectQueryBuilder()
95                ->select( '*' )
96                ->from( 'interwiki' )
97                ->where( [ 'iw_prefix' => $prefix ] )
98                ->caller( __METHOD__ )
99                ->fetchRow();
100            if ( !$res ) {
101                return false;
102            }
103            // Explicitly make this an array since it's expected to be one
104            $iwData = (array)$res;
105            // At this point, we can safely return false because we know that we have something
106            return false;
107        }
108    }
109}