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