Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
ReverseInterwikiLookup
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
4 / 4
13
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 lookup
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
5
 getPrefixTable
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
5
 getDomain
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace MediaWiki\Extension\ReadingLists;
4
5use MediaWiki\Interwiki\InterwikiLookup;
6use MediaWiki\Languages\LanguageNameUtils;
7
8/**
9 * Service for turning domain names into interwiki prefixes.
10 * Assumes a domain name structure somewhat similar to Wikimedia.
11 */
12class ReverseInterwikiLookup implements ReverseInterwikiLookupInterface {
13
14    /** @var InterwikiLookup */
15    private $interwikiLookup;
16
17    /** @var LanguageNameUtils */
18    private $languageNameUtils;
19
20    /** @var string */
21    private $ownDomain;
22
23    /** @var string[] domain name => iw prefix */
24    private $prefixTable;
25
26    /**
27     * @param InterwikiLookup $interwikiLookup
28     * @param LanguageNameUtils $languageNameUtils
29     * @param string $ownDomain
30     */
31    public function __construct(
32        InterwikiLookup $interwikiLookup,
33        LanguageNameUtils $languageNameUtils,
34        $ownDomain
35    ) {
36        $this->interwikiLookup = $interwikiLookup;
37        $this->languageNameUtils = $languageNameUtils;
38        $this->ownDomain = $this->getDomain( $ownDomain );
39    }
40
41    /**
42     * @inheritDoc
43     */
44    public function lookup( $domain ) {
45        $prefixTable = $this->getPrefixTable();
46        $domain = $this->getDomain( $domain );
47
48        if ( $domain === $this->ownDomain ) {
49            return '';
50        }
51
52        if ( array_key_exists( $domain, $prefixTable ) ) {
53            return $prefixTable[$domain];
54        }
55
56        $domainParts = explode( '.', $domain );
57        $targetLang = $domainParts[0];
58        if ( !$this->languageNameUtils->isValidCode( $targetLang ) ) {
59            return null;
60        }
61        $ownDomainParts = explode( '.', $this->ownDomain );
62        $intermediateDomainParts = $domainParts;
63        array_splice( $intermediateDomainParts, 0, 1, $ownDomainParts[0] );
64        $intermediateDomain = implode( '.', $intermediateDomainParts );
65        if ( array_key_exists( $intermediateDomain, $prefixTable ) ) {
66            return [ $prefixTable[$intermediateDomain], $targetLang ];
67        }
68
69        return null;
70    }
71
72    /**
73     * Gets (and caches) interwiki data from the core database.
74     * @return string[] Domain name => interwiki prefix
75     */
76    protected function getPrefixTable() {
77        if ( $this->prefixTable === null ) {
78            $this->prefixTable = [];
79            $iwData = $this->interwikiLookup->getAllPrefixes( true );
80            foreach ( $iwData as $iwRow ) {
81                $url = wfParseUrl( $iwRow['iw_url'] );
82                if ( !$url || !$url['host'] ) {
83                    continue;
84                }
85                $this->prefixTable[$url['host']] = $iwRow['iw_prefix'];
86            }
87        }
88        return $this->prefixTable;
89    }
90
91    /**
92     * Get the domain part of a domain or URL.
93     * @param string $domainOrUrl
94     * @return string
95     */
96    protected function getDomain( $domainOrUrl ) {
97        $parts = wfParseUrl( $domainOrUrl );
98        if ( empty( $parts['host'] ) ) {
99            // assume it's just a bare domain name
100            return $domainOrUrl;
101        }
102        return $parts['host'];
103    }
104
105}