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