-
Notifications
You must be signed in to change notification settings - Fork 691
Expand file tree
/
Copy pathLocalization.php
More file actions
134 lines (113 loc) Β· 4.57 KB
/
Localization.php
File metadata and controls
134 lines (113 loc) Β· 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/
namespace craft\helpers;
use Craft;
use craft\i18n\Locale;
use yii\base\InvalidArgumentException;
use yii\i18n\MissingTranslationEvent;
/**
* Class Localization
*
* @author Pixel & Tonic, Inc. <support@pixelandtonic.com>
* @since 3.0.0
*/
class Localization
{
/**
* @var string[][]
*/
private static array $_translations = [];
/**
* Normalizes a language into the correct format (e.g. `en-US`).
*
* @param string $language
* @return string
* @throws InvalidArgumentException if $language is invalid.
*/
public static function normalizeLanguage(string $language): string
{
$language = strtolower(str_replace('_', '-', $language));
$allLanguages = Craft::$app->getI18n()->getAllLocaleIds();
$lcLanguages = array_map('strtolower', $allLanguages);
$allLanguages = array_combine($lcLanguages, $allLanguages);
if (!isset($allLanguages[$language])) {
throw new InvalidArgumentException('Invalid language: ' . $language);
}
return $allLanguages[$language];
}
/**
* Normalizes a user-submitted number for use in code and/or to be saved into the database.
*
* Group symbols are removed (e.g. 1,000,000 => 1000000), and decimals are converted to a periods, if the current
* locale uses something else.
*
* @param mixed $number The number that should be normalized.
* @param string|null $localeId The locale ID that the number is set in
* @return mixed The normalized number.
*/
public static function normalizeNumber(mixed $number, ?string $localeId = null): mixed
{
if (is_string($number)) {
if ($localeId === null) {
$locale = Craft::$app->getFormattingLocale();
} elseif ($localeId === Craft::$app->language) {
$locale = Craft::$app->getLocale();
} else {
$locale = Craft::$app->getI18n()->getLocaleById($localeId);
}
$decimalSymbol = $locale->getNumberSymbol(Locale::SYMBOL_DECIMAL_SEPARATOR);
$groupSymbol = $locale->getNumberSymbol(Locale::SYMBOL_GROUPING_SEPARATOR);
// Remove any group symbols and use a period for the decimal symbol
$number = str_replace([$groupSymbol, $decimalSymbol], ['', '.'], $number);
}
return $number;
}
/**
* Looks for a missing translation string in Yii's core translations.
*
* @param MissingTranslationEvent $event
*/
public static function findMissingTranslation(MissingTranslationEvent $event): void
{
// Look for translation file from most to least specific. So nl_nl.php gets checked before nl.php, for example.
$translationFiles = [];
$parts = explode('_', $event->language);
$totalParts = count($parts);
for ($i = 1; $i <= $totalParts; $i++) {
$translationFiles[] = implode('_', array_slice($parts, 0, $i));
}
$translationFiles = array_reverse($translationFiles);
// First see if we have any cached info.
foreach ($translationFiles as $translationFile) {
// We've loaded the translation file already, just check for the translation.
if (isset(self::$_translations[$translationFile])) {
if (isset(self::$_translations[$translationFile][$event->message])) {
// Found a match... grab it and go.
$event->message = self::$_translations[$translationFile][$event->message];
return;
}
// No translation... just give up.
return;
}
}
// No luck in cache, check the file system.
$frameworkMessagePath = FileHelper::normalizePath(Craft::getAlias('@app/framework/messages'));
foreach ($translationFiles as $translationFile) {
$path = $frameworkMessagePath . DIRECTORY_SEPARATOR . $translationFile . DIRECTORY_SEPARATOR . 'yii.php';
if (is_file($path)) {
// Load it up.
self::$_translations[$translationFile] = include $path;
if (isset(self::$_translations[$translationFile][$event->message])) {
$event->message = self::$_translations[$translationFile][$event->message];
return;
}
} else {
self::$_translations[$translationFile] = [];
}
}
}
}