Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
74.00% covered (warning)
74.00%
37 / 50
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
LanguageNames
75.51% covered (warning)
75.51%
37 / 49
0.00% covered (danger)
0.00%
0 / 2
24.30
0.00% covered (danger)
0.00%
0 / 1
 getNames
59.26% covered (warning)
59.26%
16 / 27
0.00% covered (danger)
0.00%
0 / 1
21.74
 loadLanguage
95.45% covered (success)
95.45%
21 / 22
0.00% covered (danger)
0.00%
0 / 1
7
1<?php
2
3namespace MediaWiki\Extension\CLDR;
4
5use InvalidArgumentException;
6use MediaWiki\Languages\LanguageNameUtils;
7use MediaWiki\MainConfigNames;
8use MediaWiki\MediaWikiServices;
9
10/**
11 * A class for querying translated language names from CLDR data.
12 *
13 * @author Niklas Laxström
14 * @author Ryan Kaldari
15 * @copyright Copyright © 2007-2011
16 * @license GPL-2.0-or-later
17 */
18class LanguageNames {
19
20    /** @var array */
21    private static $cache = [];
22
23    /**
24     * Missing entries fall back to the language's name for itself
25     */
26    public const FALLBACK_NATIVE = 0;
27    /**
28     * Missing entries are sought in the MediaWiki fallback chain
29     */
30    public const FALLBACK_NORMAL = 1;
31    /**
32     * Only include languages supported by core MediaWiki localisation.
33     * Corresponds to LanguageNameUtils::SUPPORTED.
34     */
35    public const LIST_MW_SUPPORTED = 0;
36    /**
37     * Only include languages in LIST_MW_SUPPORTED, plus anything defined in wgExtraLanguageNames.
38     * Corresponds to LanguageNameUtils::DEFINED.
39     */
40    public const LIST_MW = 1;
41    /**
42     * All languages in the CLDR data, including languages unknown to MediaWiki.
43     */
44    public const LIST_MW_AND_CLDR = 2;
45
46    /**
47     * Get localized language names for a particular language, using fallback languages for missing
48     * items.
49     *
50     * @param string $code
51     * @param int $fbMethod
52     * @param int $list
53     * @return array an associative array of language codes and localized language names
54     */
55    public static function getNames( $code, $fbMethod = self::FALLBACK_NATIVE,
56        $list = self::LIST_MW
57    ) {
58        $xx = self::loadLanguage( $code );
59
60        $services = MediaWikiServices::getInstance();
61        $config = $services->getMainConfig();
62        if ( !$config->get( MainConfigNames::UsePigLatinVariant ) ) {
63            // Suppress Pig Latin unless explicitly enabled.
64            unset( $xx['en-x-piglatin'] );
65        }
66
67        $native = $services->getLanguageNameUtils()
68            ->getLanguageNames(
69                LanguageNameUtils::AUTONYMS,
70                $list === self::LIST_MW_SUPPORTED ? LanguageNameUtils::SUPPORTED : LanguageNameUtils::DEFINED
71            );
72
73        if ( $fbMethod === self::FALLBACK_NATIVE ) {
74            $names = array_merge( $native, $xx );
75        } elseif ( $fbMethod === self::FALLBACK_NORMAL ) {
76            // Load missing language names from fallback languages
77            $fb = $xx;
78
79            $fallbacks = $services->getLanguageFallback()->getAll( $code );
80            foreach ( $fallbacks as $fallback ) {
81                // Overwrite the things in fallback with what we have already
82                $fb = array_merge( self::loadLanguage( $fallback ), $fb );
83            }
84
85            /* Add native names for codes that are not in cldr */
86            $names = array_merge( $native, $fb );
87
88            /* As a last resort, try the native name in Names.php */
89            if ( !isset( $names[$code] ) && isset( $native[$code] ) ) {
90                $names[$code] = $native[$code];
91            }
92        } else {
93            throw new InvalidArgumentException( "Invalid value for 2:\$fallback in " . __METHOD__ );
94        }
95
96        switch ( $list ) {
97            case self::LIST_MW:
98                /** @noinspection PhpMissingBreakStatementInspection */
99            case self::LIST_MW_SUPPORTED:
100                /* Remove entries that are not in fb */
101                $names = array_intersect_key( $names, $native );
102                /* And fall to the return */
103            case self::LIST_MW_AND_CLDR:
104                return $names;
105            default:
106                throw new InvalidArgumentException( "Invalid value for 3:\$list in " . __METHOD__ );
107        }
108    }
109
110    /**
111     * Load currency names localized for a particular language. Helper function for getNames.
112     *
113     * @param string $code The language to return the list in
114     * @return array an associative array of language codes and localized language names
115     */
116    private static function loadLanguage( $code ) {
117        if ( isset( self::$cache[$code] ) ) {
118            return self::$cache[$code];
119        }
120
121        self::$cache[$code] = [];
122
123        $langNameUtils = MediaWikiServices::getInstance()->getLanguageNameUtils();
124
125        if ( !$langNameUtils->isValidBuiltInCode( $code ) ) {
126            return [];
127        }
128
129        /* Load override for wrong or missing entries in cldr */
130        $override = __DIR__ . '/../LocalNames/' .
131            $langNameUtils->getFileName( 'LocalNames', $code, '.php' );
132        if ( file_exists( $override ) ) {
133            $languageNames = false;
134            require $override;
135            // @phan-suppress-next-line PhanImpossibleCondition
136            if ( is_array( $languageNames ) ) {
137                self::$cache[$code] = $languageNames;
138            }
139        }
140
141        $filename = __DIR__ . '/../CldrMain/' .
142            $langNameUtils->getFileName( 'CldrMain', $code, '.php' );
143        if ( file_exists( $filename ) ) {
144            $languageNames = false;
145            require $filename;
146            // @phan-suppress-next-line PhanImpossibleCondition
147            if ( is_array( $languageNames ) ) {
148                self::$cache[$code] += $languageNames;
149            }
150        } else {
151            wfDebug( __METHOD__ . ": Unable to load language names for $filename\n" );
152        }
153
154        return self::$cache[$code];
155    }
156}
157
158class_alias( LanguageNames::class, 'LanguageNames' );