forked from vergnet/site-accueil-insa
633 lines
31 KiB
PHP
633 lines
31 KiB
PHP
<?php
|
|
/**
|
|
* Matomo - free/libre analytics platform
|
|
*
|
|
* @link https://matomo.org
|
|
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
|
*
|
|
*/
|
|
|
|
namespace Piwik\Plugins\Intl\Commands;
|
|
|
|
use DateTimeZone;
|
|
use Piwik\Container\StaticContainer;
|
|
use Piwik\Development;
|
|
use Piwik\Filesystem;
|
|
use Piwik\Http;
|
|
use Piwik\Plugin\ConsoleCommand;
|
|
use Piwik\Plugins\LanguagesManager\TranslationWriter\Filter\EncodedEntities;
|
|
use Piwik\Plugins\LanguagesManager\TranslationWriter\Filter\UnnecassaryWhitespaces;
|
|
use Piwik\Plugins\LanguagesManager\TranslationWriter\Writer;
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
use Symfony\Component\Console\Input\InputOption;
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
|
|
/**
|
|
* Console Command to generate Intl-data files for Piwik
|
|
*
|
|
* This script uses the master data of unicode-cldr/cldr-localenames-full repository to fetch available translations
|
|
*/
|
|
class GenerateIntl extends ConsoleCommand
|
|
{
|
|
public $CLDRVersion = "39.0.0";
|
|
|
|
public function isEnabled()
|
|
{
|
|
return Development::isEnabled();
|
|
}
|
|
|
|
protected function configure()
|
|
{
|
|
$this->setName('translations:generate-intl-data')
|
|
->addOption('language', 'l', InputOption::VALUE_OPTIONAL, 'language that should be fetched')
|
|
->addOption('cldr-version', '', InputOption::VALUE_OPTIONAL, 'CLDR version to use for update')
|
|
->setDescription('Generates Intl-data for Piwik');
|
|
}
|
|
|
|
protected function transformLangCode($langCode)
|
|
{
|
|
if (substr_count($langCode, '-') == 1) {
|
|
$langCodeParts = explode('-', $langCode, 2);
|
|
return sprintf('%s-%s', $langCodeParts[0], strtoupper($langCodeParts[1]));
|
|
}
|
|
return $langCode;
|
|
}
|
|
|
|
protected function transform($str)
|
|
{
|
|
if (empty($str)) {
|
|
return $str;
|
|
}
|
|
|
|
preg_match_all("~^(.)(.*)$~u", $str, $arr);
|
|
return mb_strtoupper($arr[1][0]).$arr[2][0];
|
|
}
|
|
|
|
protected function execute(InputInterface $input, OutputInterface $output)
|
|
{
|
|
$matomoLanguages = \Piwik\Plugins\LanguagesManager\API::getInstance()->getAvailableLanguages();
|
|
|
|
if ($input->getOption('language')) {
|
|
$matomoLanguages = [$input->getOption('language')];
|
|
}
|
|
|
|
if ($input->getOption('cldr-version')) {
|
|
$this->CLDRVersion = $input->getOption('cldr-version');
|
|
}
|
|
|
|
$aliasesUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-core/supplemental/aliases.json';
|
|
$aliasesData = Http::fetchRemoteFile(sprintf($aliasesUrl, $this->CLDRVersion));
|
|
$aliasesData = json_decode($aliasesData, true);
|
|
$aliasesData = $aliasesData['supplemental']['metadata']['alias']['languageAlias'] ?? [];
|
|
|
|
$this->checkCurrencies($output);
|
|
|
|
foreach ($matomoLanguages AS $langCode) {
|
|
|
|
if ($langCode == 'dev') {
|
|
continue;
|
|
}
|
|
|
|
$requestLangCode = $transformedLangCode = $this->transformLangCode($langCode);
|
|
|
|
if (array_key_exists($requestLangCode, $aliasesData)) {
|
|
$requestLangCode = $aliasesData[$requestLangCode]['_replacement'];
|
|
}
|
|
|
|
// fix some locales
|
|
$localFixes = array(
|
|
'pt' => 'pt-PT',
|
|
'pt-br' => 'pt',
|
|
'zh-cn' => 'zh-Hans',
|
|
'zh-tw' => 'zh-Hant'
|
|
);
|
|
|
|
if (array_key_exists($langCode, $localFixes)) {
|
|
$requestLangCode = $localFixes[$langCode];
|
|
}
|
|
|
|
setlocale(LC_ALL, $langCode);
|
|
|
|
$translations = array();
|
|
|
|
$this->fetchLanguageData($output, $transformedLangCode, $requestLangCode, $translations);
|
|
$this->fetchTerritoryData($output, $transformedLangCode, $requestLangCode, $translations);
|
|
$this->fetchCurrencyData($output, $transformedLangCode, $requestLangCode, $translations);
|
|
$this->fetchCalendarData($output, $transformedLangCode, $requestLangCode, $translations);
|
|
$this->fetchTimeZoneData($output, $transformedLangCode, $requestLangCode, $translations);
|
|
$this->fetchLayoutDirection($output, $transformedLangCode, $requestLangCode, $translations);
|
|
$this->fetchUnitData($output, $transformedLangCode, $requestLangCode, $translations);
|
|
$this->fetchNumberFormattingData($output, $transformedLangCode, $requestLangCode, $translations);
|
|
|
|
// fix missing language name for territory specific languages (like es-AR)
|
|
if (empty($translations['Intl']['OriginalLanguageName']) && strpos($transformedLangCode, '-')) {
|
|
list($language, $territory) = explode('-', $transformedLangCode);
|
|
|
|
if (!empty($translations['Intl']['Language_'.$language])) {
|
|
|
|
$originalName = $this->transform($translations['Intl']['Language_'.$language]);
|
|
|
|
if (!empty($translations['Intl']['Country_'.$territory])) {
|
|
$originalName .= ' (' . $translations['Intl']['Country_'.$territory] . ')';
|
|
} else {
|
|
$originalName .= ' (' . strtoupper($language) . ')';
|
|
}
|
|
|
|
$translations['Intl']['OriginalLanguageName'] = $originalName;
|
|
}
|
|
}
|
|
|
|
ksort($translations['Intl']);
|
|
|
|
$translationWriter = new Writer($langCode, 'Intl');
|
|
$translationWriter->setTranslations($translations);
|
|
$translationWriter->addFilter(new UnnecassaryWhitespaces());
|
|
$translationWriter->addFilter(new EncodedEntities());
|
|
$translationWriter->save();
|
|
}
|
|
}
|
|
|
|
protected function checkCurrencies(OutputInterface $output)
|
|
{
|
|
$currencyDataUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-core/supplemental/currencyData.json';
|
|
|
|
$currencyData = Http::fetchRemoteFile(sprintf($currencyDataUrl, $this->CLDRVersion, 'en'));
|
|
$currencyData = json_decode($currencyData, true);
|
|
$currencyData = $currencyData['supplemental']['currencyData']['region'] ?? [];
|
|
|
|
$cldrCurrencies = array();
|
|
foreach ($currencyData as $region) {
|
|
foreach ($region as $regionCurrencies) {
|
|
foreach ($regionCurrencies as $currencyCode => $validity) {
|
|
if (!isset($validity['_to']) && !isset($validity['_tender'])) {
|
|
$cldrCurrencies[] = $currencyCode;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$file = Filesystem::getPathToPiwikRoot() . '/core/Intl/Data/Resources/currencies.php';
|
|
$matomoCurrencies = array_keys(include $file);
|
|
|
|
$missing = array_diff($cldrCurrencies, $matomoCurrencies);
|
|
$additional = array_diff($matomoCurrencies, $cldrCurrencies);
|
|
|
|
if ($missing) {
|
|
$output->writeln('Warning: Currencies missing from ' . $file . ': ' . implode(', ', $missing));
|
|
}
|
|
if ($additional) {
|
|
$output->writeln('Warning: Unknown currencies in ' . $file . ': ' . implode(', ', $additional));
|
|
}
|
|
}
|
|
|
|
protected function getEnglishLanguageName($code, $alternateCode)
|
|
{
|
|
$languageDataUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-localenames-full/main/%s/languages.json';
|
|
|
|
static $languageData = array();
|
|
|
|
try {
|
|
if (empty($languageData)) {
|
|
$languageData = Http::fetchRemoteFile(sprintf($languageDataUrl, $this->CLDRVersion, 'en'));
|
|
$languageData = json_decode($languageData, true);
|
|
$languageData = $languageData['main']['en']['localeDisplayNames']['languages'] ?? [];
|
|
}
|
|
|
|
if (array_key_exists($code, $languageData) && $languageData[$code] != $code) {
|
|
return $this->transform($languageData[$code]);
|
|
}
|
|
|
|
if (array_key_exists($alternateCode, $languageData) && $languageData[$alternateCode] != $alternateCode) {
|
|
return $this->transform($languageData[$alternateCode]);
|
|
}
|
|
|
|
if (strpos($code, '-')) {
|
|
list($language, $territory) = explode('-', $code);
|
|
|
|
if (!array_key_exists($language, $languageData)) {
|
|
return '';
|
|
}
|
|
|
|
$englishName = $this->transform($languageData[$language]);
|
|
|
|
$territoryDataUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-localenames-full/main/%s/territories.json';
|
|
|
|
try {
|
|
$territoryData = Http::fetchRemoteFile(sprintf($territoryDataUrl, $this->CLDRVersion, 'en'));
|
|
$territoryData = json_decode($territoryData, true);
|
|
$territoryData = $territoryData['main']['en']['localeDisplayNames']['territories'] ?? [];
|
|
|
|
if (array_key_exists($territory, $territoryData)) {
|
|
$englishName .= ' ('.$territoryData[$territory].')';
|
|
} else {
|
|
$englishName .= ' ('.strtoupper($language).')';
|
|
}
|
|
} catch (\Exception $e) {
|
|
$englishName .= ' ('.strtoupper($language).')';
|
|
}
|
|
|
|
return $englishName;
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
protected function fetchLanguageData(OutputInterface $output, $langCode, $requestLangCode, &$translations)
|
|
{
|
|
$languageCodes = array_keys(StaticContainer::get('Piwik\Intl\Data\Provider\LanguageDataProvider')->getLanguageList());
|
|
|
|
$languageDataUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-localenames-full/main/%s/languages.json';
|
|
|
|
try {
|
|
$languageData = Http::fetchRemoteFile(sprintf($languageDataUrl, $this->CLDRVersion, $requestLangCode));
|
|
$languageData = json_decode($languageData, true);
|
|
$languageData = $languageData['main'][$requestLangCode]['localeDisplayNames']['languages'] ?? [];
|
|
|
|
if (empty($languageData)) {
|
|
throw new \Exception();
|
|
}
|
|
|
|
foreach ($languageCodes AS $code) {
|
|
if (!empty($languageData[$code]) && $languageData[$code] != $code) {
|
|
$translations['Intl']['Language_' . $code] = $this->transform($languageData[$code]);
|
|
}
|
|
}
|
|
|
|
if (array_key_exists($langCode, $languageData) && $languageData[$langCode] != $langCode) {
|
|
$translations['Intl']['OriginalLanguageName'] = $this->transform($languageData[$langCode]);
|
|
} else if (array_key_exists($requestLangCode, $languageData) && $languageData[$requestLangCode] != $requestLangCode) {
|
|
$translations['Intl']['OriginalLanguageName'] = $this->transform($languageData[$requestLangCode]);
|
|
}
|
|
$translations['Intl']['EnglishLanguageName'] = $this->getEnglishLanguageName($langCode, $requestLangCode);
|
|
|
|
$output->writeln('Saved language data for ' . $langCode);
|
|
} catch (\Exception $e) {
|
|
$output->writeln('Unable to import language data for ' . $langCode);
|
|
}
|
|
}
|
|
|
|
protected function fetchLayoutDirection(OutputInterface $output, $langCode, $requestLangCode, &$translations)
|
|
{
|
|
$layoutDirectionUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-misc-full/main/%s/layout.json';
|
|
|
|
try {
|
|
$layoutData = Http::fetchRemoteFile(sprintf($layoutDirectionUrl, $this->CLDRVersion, $requestLangCode));
|
|
$layoutData = json_decode($layoutData, true);
|
|
$layoutData = $layoutData['main'][$requestLangCode]['layout']['orientation'] ?? [];
|
|
|
|
if (empty($layoutData)) {
|
|
throw new \Exception();
|
|
}
|
|
|
|
$translations['Intl']['LayoutDirection'] = 'ltr';
|
|
if ($layoutData['characterOrder'] == 'right-to-left') {
|
|
$translations['Intl']['LayoutDirection'] = 'rtl';
|
|
}
|
|
|
|
$output->writeln('Saved language data for ' . $langCode);
|
|
} catch (\Exception $e) {
|
|
$output->writeln('Unable to import language data for ' . $langCode);
|
|
}
|
|
}
|
|
|
|
protected function fetchTerritoryData(OutputInterface $output, $langCode, $requestLangCode, &$translations)
|
|
{
|
|
$territoryDataUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-localenames-full/main/%s/territories.json';
|
|
|
|
$countryCodes = array_keys(StaticContainer::get('Piwik\Intl\Data\Provider\RegionDataProvider')->getCountryList());
|
|
$countryCodes = array_map('strtoupper', $countryCodes);
|
|
|
|
$continentMapping = array(
|
|
"afr" => "002",
|
|
"amc" => "013",
|
|
"amn" => "003",
|
|
"ams" => "005",
|
|
"ant" => "AQ",
|
|
"asi" => "142",
|
|
"eur" => "150",
|
|
"oce" => "009"
|
|
);
|
|
|
|
try {
|
|
$territoryData = Http::fetchRemoteFile(sprintf($territoryDataUrl, $this->CLDRVersion, $requestLangCode));
|
|
$territoryData = json_decode($territoryData, true);
|
|
$territoryData = $territoryData['main'][$requestLangCode]['localeDisplayNames']['territories'] ?? [];
|
|
|
|
if (empty($territoryData)) {
|
|
throw new \Exception();
|
|
}
|
|
|
|
foreach ($countryCodes AS $code) {
|
|
if (!empty($territoryData[$code]) && $territoryData[$code] != $code) {
|
|
$translations['Intl']['Country_' . $code] = $this->transform($territoryData[$code]);
|
|
}
|
|
}
|
|
|
|
foreach ($continentMapping as $shortCode => $code) {
|
|
if (!empty($territoryData[$code]) && $territoryData[$code] != $code) {
|
|
$translations['Intl']['Continent_' . $shortCode] = $this->transform($territoryData[$code]);
|
|
}
|
|
}
|
|
|
|
$output->writeln('Saved territory data for ' . $langCode);
|
|
} catch (\Exception $e) {
|
|
$output->writeln('Unable to import territory data for ' . $langCode);
|
|
}
|
|
}
|
|
|
|
protected function fetchCalendarData(OutputInterface $output, $langCode, $requestLangCode, &$translations)
|
|
{
|
|
$calendarDataUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-dates-full/main/%s/ca-gregorian.json';
|
|
|
|
try {
|
|
$calendarData = Http::fetchRemoteFile(sprintf($calendarDataUrl, $this->CLDRVersion, $requestLangCode));
|
|
$calendarData = json_decode($calendarData, true);
|
|
$calendarData = $calendarData['main'][$requestLangCode]['dates']['calendars']['gregorian'] ?? [];
|
|
|
|
if (empty($calendarData)) {
|
|
throw new \Exception();
|
|
}
|
|
|
|
for ($i = 1; $i <= 12; $i++) {
|
|
$translations['Intl']['Month_Short_' . $i] = $calendarData['months']['format']['abbreviated'][$i];
|
|
$translations['Intl']['Month_Long_' . $i] = $calendarData['months']['format']['wide'][$i];
|
|
$translations['Intl']['Month_Short_StandAlone_' . $i] = $calendarData['months']['stand-alone']['abbreviated'][$i];
|
|
$translations['Intl']['Month_Long_StandAlone_' . $i] = $calendarData['months']['stand-alone']['wide'][$i];
|
|
}
|
|
|
|
$days = array(
|
|
1 => 'mon',
|
|
2 => 'tue',
|
|
3 => 'wed',
|
|
4 => 'thu',
|
|
5 => 'fri',
|
|
6 => 'sat',
|
|
7 => 'sun'
|
|
);
|
|
|
|
foreach ($days AS $nr => $day) {
|
|
$translations['Intl']['Day_Min_' . $nr] = $calendarData['days']['format']['short'][$day];
|
|
$translations['Intl']['Day_Short_' . $nr] = $calendarData['days']['format']['abbreviated'][$day];
|
|
$translations['Intl']['Day_Long_' . $nr] = $calendarData['days']['format']['wide'][$day];
|
|
$translations['Intl']['Day_Min_StandAlone_' . $nr] = $calendarData['days']['stand-alone']['short'][$day];
|
|
$translations['Intl']['Day_Short_StandAlone_' . $nr] = $calendarData['days']['stand-alone']['abbreviated'][$day];
|
|
$translations['Intl']['Day_Long_StandAlone_' . $nr] = $calendarData['days']['stand-alone']['wide'][$day];
|
|
}
|
|
|
|
$translations['Intl']['Time_AM'] = $calendarData['dayPeriods']['format']['wide']['am'];
|
|
$translations['Intl']['Time_PM'] = $calendarData['dayPeriods']['format']['wide']['pm'];
|
|
$translations['Intl']['Format_Time'] = '{time}';
|
|
$translations['Intl']['Format_Time_12'] = $calendarData['dateTimeFormats']['availableFormats']['hms'];
|
|
$translations['Intl']['Format_Time_24'] = $calendarData['dateTimeFormats']['availableFormats']['Hms'];
|
|
$translations['Intl']['Format_Hour_12'] = $calendarData['dateTimeFormats']['availableFormats']['h'];
|
|
$translations['Intl']['Format_Hour_24'] = $calendarData['dateTimeFormats']['availableFormats']['H'];
|
|
$translations['Intl']['Format_Date_Long'] = $calendarData['dateFormats']['full'];
|
|
$translations['Intl']['Format_Date_Day_Month'] = $calendarData['dateTimeFormats']['availableFormats']['MMMEd'];
|
|
$translations['Intl']['Format_Date_Short'] = $calendarData['dateFormats']['medium'];
|
|
$translations['Intl']['Format_Month_Short'] = $calendarData['dateTimeFormats']['availableFormats']['yMMM'];
|
|
$translations['Intl']['Format_Month_Long'] = $this->transformDateFormat($calendarData['dateTimeFormats']['availableFormats']['yMMM'], array('MMM' => 'MMMM', 'LLL' => 'LLLL'));
|
|
if (isset($calendarData['dateTimeFormats']['availableFormats']['yMMMM'])) {
|
|
$translations['Intl']['Format_Month_Long'] = $calendarData['dateTimeFormats']['availableFormats']['yMMMM'];
|
|
}
|
|
$translations['Intl']['Format_Year'] = $calendarData['dateTimeFormats']['availableFormats']['y'];
|
|
|
|
$translations['Intl']['Format_DateTime_Long'] = $calendarData['dateFormats']['full'] . ' {time}';
|
|
$translations['Intl']['Format_DateTime_Short'] = $calendarData['dateFormats']['medium'] . ' {time}';
|
|
|
|
$translations['Intl']['Format_Interval_Long_D'] = $this->transformDateFormat($calendarData['dateTimeFormats']['intervalFormats']['yMMMd']['d'], array('MMMM' => 'MMM', 'LLLL' => 'LLL', 'MMM' => 'MMMM', 'LLL' => 'LLLL'));
|
|
$translations['Intl']['Format_Interval_Long_M'] = $this->transformDateFormat($calendarData['dateTimeFormats']['intervalFormats']['yMMMd']['M'], array('MMMM' => 'MMM', 'LLLL' => 'LLL', 'MMM' => 'MMMM', 'LLL' => 'LLLL'));
|
|
$translations['Intl']['Format_Interval_Long_Y'] = $this->transformDateFormat($calendarData['dateTimeFormats']['intervalFormats']['yMMMd']['y'], array('MMMM' => 'MMM', 'LLLL' => 'LLL', 'MMM' => 'MMMM', 'LLL' => 'LLLL'));
|
|
|
|
if(isset($calendarData['dateTimeFormats']['intervalFormats']['yMMMMd'])) {
|
|
$translations['Intl']['Format_Interval_Long_D'] = $calendarData['dateTimeFormats']['intervalFormats']['yMMMMd']['d'];
|
|
$translations['Intl']['Format_Interval_Long_M'] = $calendarData['dateTimeFormats']['intervalFormats']['yMMMMd']['M'];
|
|
$translations['Intl']['Format_Interval_Long_Y'] = $calendarData['dateTimeFormats']['intervalFormats']['yMMMMd']['y'];
|
|
}
|
|
|
|
$translations['Intl']['Format_Interval_Short_D'] = $calendarData['dateTimeFormats']['intervalFormats']['yMMMd']['d'];
|
|
$translations['Intl']['Format_Interval_Short_M'] = $calendarData['dateTimeFormats']['intervalFormats']['yMMMd']['M'];
|
|
$translations['Intl']['Format_Interval_Short_Y'] = $calendarData['dateTimeFormats']['intervalFormats']['yMMMd']['y'];
|
|
|
|
$output->writeln('Saved calendar data for ' . $langCode);
|
|
} catch (\Exception $e) {
|
|
$output->writeln('Unable to import calendar data for ' . $langCode);
|
|
}
|
|
|
|
$dateFieldsUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-dates-full/main/%s/dateFields.json';
|
|
|
|
try {
|
|
$dateFieldData = Http::fetchRemoteFile(sprintf($dateFieldsUrl, $this->CLDRVersion, $requestLangCode));
|
|
$dateFieldData = json_decode($dateFieldData, true);
|
|
$dateFieldData = $dateFieldData['main'][$requestLangCode]['dates']['fields'] ?? [];
|
|
|
|
if (empty($dateFieldData)) {
|
|
throw new \Exception();
|
|
}
|
|
|
|
$translations['Intl']['PeriodWeek'] = $dateFieldData['week']['displayName'];
|
|
$translations['Intl']['PeriodYear'] = $dateFieldData['year']['displayName'];
|
|
$translations['Intl']['PeriodDay'] = $dateFieldData['day']['displayName'];
|
|
$translations['Intl']['PeriodMonth'] = $dateFieldData['month']['displayName'];
|
|
$translations['Intl']['Year_Short'] = $dateFieldData['year-narrow']['displayName'];
|
|
$translations['Intl']['Today'] = $this->transform($dateFieldData['day']['relative-type-0']);
|
|
$translations['Intl']['Yesterday'] = $this->transform($dateFieldData['day']['relative-type--1']);
|
|
|
|
$output->writeln('Saved date fields for ' . $langCode);
|
|
} catch (\Exception $e) {
|
|
$output->writeln('Unable to import date fields for ' . $langCode);
|
|
}
|
|
}
|
|
|
|
protected function fetchTimeZoneData(OutputInterface $output, $langCode, $requestLangCode, &$translations)
|
|
{
|
|
$timeZoneDataUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-dates-full/main/%s/timeZoneNames.json';
|
|
|
|
try {
|
|
$timeZoneData = Http::fetchRemoteFile(sprintf($timeZoneDataUrl, $this->CLDRVersion, $requestLangCode));
|
|
$timeZoneData = json_decode($timeZoneData, true);
|
|
$timeZoneData = $timeZoneData['main'][$requestLangCode]['dates']['timeZoneNames'] ?? [];
|
|
|
|
if (empty($timeZoneData)) {
|
|
throw new \Exception();
|
|
}
|
|
|
|
$cities = array();
|
|
foreach ($timeZoneData['zone'] as $key1 => $level1) {
|
|
foreach ($level1 as $key2 => $level2) {
|
|
if (isset($level2['exemplarCity'])) {
|
|
$level2 = array($level2);
|
|
}
|
|
foreach ($level2 as $key3 => $level3) {
|
|
if (isset($level3['exemplarCity'])) {
|
|
$timezone = $key1 . '/' . $key2;
|
|
if ($key3) {
|
|
$timezone .= '/' . $key3;
|
|
}
|
|
$cities[$timezone] = $level3['exemplarCity'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ($cities as $timezone => $city) {
|
|
try {
|
|
$zone = new DateTimeZone($timezone);
|
|
} catch (\Exception $e) {
|
|
continue;
|
|
}
|
|
$location = $zone->getLocation();
|
|
if (!isset($location['country_code'])) {
|
|
continue;
|
|
}
|
|
// We only need translations for countries with more than one timezone.
|
|
$timezonesInCountry = DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, $location['country_code']);
|
|
if (count($timezonesInCountry) > 1) {
|
|
$translations['Intl']['Timezone_' . str_replace(array('_', '/'), array('', '_'), $timezone)] = $city;
|
|
}
|
|
}
|
|
|
|
$output->writeln('Saved time zone data for ' . $langCode);
|
|
} catch (\Exception $e) {
|
|
$output->writeln('Unable to import time zone data for ' . $langCode);
|
|
}
|
|
}
|
|
|
|
protected function transformDateFormat($dateFormat, $changes=array())
|
|
{
|
|
if(!empty($changes)) {
|
|
$dateFormat = str_replace(array_keys($changes), array_values($changes), $dateFormat);
|
|
}
|
|
|
|
return $dateFormat;
|
|
}
|
|
|
|
protected function fetchNumberFormattingData(OutputInterface $output, $langCode, $requestLangCode, &$translations)
|
|
{
|
|
$unitsUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-numbers-full/main/%s/numbers.json';
|
|
|
|
try {
|
|
$unitsData = Http::fetchRemoteFile(sprintf($unitsUrl, $this->CLDRVersion, $requestLangCode));
|
|
$unitsData = json_decode($unitsData, true);
|
|
$unitsData = $unitsData['main'][$requestLangCode]['numbers'] ?? [];
|
|
|
|
if (empty($unitsData)) {
|
|
throw new \Exception();
|
|
}
|
|
|
|
$numberingSystem = $unitsData['defaultNumberingSystem'];
|
|
|
|
$translations['Intl']['NumberSymbolDecimal'] = $unitsData['symbols-numberSystem-' . $numberingSystem]['decimal'];
|
|
$translations['Intl']['NumberSymbolGroup'] = $unitsData['symbols-numberSystem-' . $numberingSystem]['group'];
|
|
$translations['Intl']['NumberSymbolPercent'] = $unitsData['symbols-numberSystem-' . $numberingSystem]['percentSign'];
|
|
$translations['Intl']['NumberSymbolPlus'] = $unitsData['symbols-numberSystem-' . $numberingSystem]['plusSign'];
|
|
$translations['Intl']['NumberSymbolMinus'] = $unitsData['symbols-numberSystem-' . $numberingSystem]['minusSign'];
|
|
$translations['Intl']['NumberFormatNumber'] = $unitsData['decimalFormats-numberSystem-' . $numberingSystem]['standard'];
|
|
$translations['Intl']['NumberFormatCurrency'] = $unitsData['currencyFormats-numberSystem-' . $numberingSystem]['standard'];
|
|
$translations['Intl']['NumberFormatPercent'] = $unitsData['percentFormats-numberSystem-' . $numberingSystem]['standard'];
|
|
|
|
$output->writeln('Saved number formatting data for ' . $langCode);
|
|
} catch (\Exception $e) {
|
|
$output->writeln('Unable to import number formatting data for ' . $langCode);
|
|
}
|
|
}
|
|
|
|
protected function fetchUnitData(OutputInterface $output, $langCode, $requestLangCode, &$translations)
|
|
{
|
|
$unitsUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-units-full/main/%s/units.json';
|
|
|
|
try {
|
|
$unitsData = Http::fetchRemoteFile(sprintf($unitsUrl, $this->CLDRVersion, $requestLangCode));
|
|
$unitsData = json_decode($unitsData, true);
|
|
$unitsData = $unitsData['main'][$requestLangCode]['units'] ?? [];
|
|
|
|
if (empty($unitsData)) {
|
|
throw new \Exception();
|
|
}
|
|
|
|
$translations['Intl']['NSeconds'] = $this->replacePlaceHolder($unitsData['long']['duration-second']['unitPattern-count-other']);
|
|
$translations['Intl']['NSecondsShort'] = $this->replacePlaceHolder($unitsData['narrow']['duration-second']['unitPattern-count-other']);
|
|
$translations['Intl']['Seconds'] = $unitsData['long']['duration-second']['displayName'];
|
|
|
|
$translations['Intl']['NMinutes'] = $this->replacePlaceHolder($unitsData['long']['duration-minute']['unitPattern-count-other']);
|
|
|
|
if (isset($unitsData['long']['duration-minute']['unitPattern-count-one'])) {
|
|
$translations['Intl']['OneMinute'] = $this->replacePlaceHolder($unitsData['long']['duration-minute']['unitPattern-count-one'], '1');
|
|
} else {
|
|
$translations['Intl']['OneMinute'] = $this->replacePlaceHolder($unitsData['long']['duration-minute']['unitPattern-count-other'], '1');
|
|
}
|
|
|
|
if (isset($unitsData['short']['duration-minute']['unitPattern-count-one'])) {
|
|
$translations['Intl']['OneMinuteShort'] = $this->replacePlaceHolder($unitsData['short']['duration-minute']['unitPattern-count-one'], '1');
|
|
} else {
|
|
$translations['Intl']['OneMinuteShort'] = $this->replacePlaceHolder($unitsData['short']['duration-minute']['unitPattern-count-other'], '1');
|
|
}
|
|
|
|
$translations['Intl']['NMinutesShort'] = $this->replacePlaceHolder($unitsData['short']['duration-minute']['unitPattern-count-other']);
|
|
|
|
$translations['Intl']['Minutes'] = $unitsData['long']['duration-minute']['displayName'];
|
|
|
|
$translations['Intl']['Hours'] = $unitsData['long']['duration-hour']['displayName'];
|
|
$translations['Intl']['NHoursShort'] = $this->replacePlaceHolder($unitsData['narrow']['duration-hour']['unitPattern-count-other']);
|
|
|
|
$translations['Intl']['NDays'] = $this->replacePlaceHolder($unitsData['long']['duration-day']['unitPattern-count-other']);
|
|
|
|
if (isset($unitsData['short']['duration-day']['unitPattern-count-one'])) {
|
|
$translations['Intl']['OneDay'] = $this->replacePlaceHolder($unitsData['long']['duration-day']['unitPattern-count-one'], '1');
|
|
} else {
|
|
$translations['Intl']['OneDay'] = $this->replacePlaceHolder($unitsData['long']['duration-day']['unitPattern-count-other'], '1');
|
|
}
|
|
|
|
$translations['Intl']['PeriodWeeks'] = $unitsData['long']['duration-week']['displayName'];
|
|
$translations['Intl']['PeriodYears'] = $unitsData['long']['duration-year']['displayName'];
|
|
$translations['Intl']['PeriodDays'] = $unitsData['long']['duration-day']['displayName'];
|
|
$translations['Intl']['PeriodMonths'] = $unitsData['long']['duration-month']['displayName'];
|
|
|
|
|
|
$output->writeln('Saved unit data for ' . $langCode);
|
|
} catch (\Exception $e) {
|
|
$output->writeln('Unable to import unit data for ' . $langCode);
|
|
}
|
|
}
|
|
|
|
protected function fetchCurrencyData(OutputInterface $output, $langCode, $requestLangCode, &$translations)
|
|
{
|
|
$currenciesUrl = 'https://raw.githubusercontent.com/unicode-org/cldr-json/%s/cldr-json/cldr-numbers-full/main/%s/currencies.json';
|
|
|
|
try {
|
|
$currencyData = Http::fetchRemoteFile(sprintf($currenciesUrl, $this->CLDRVersion, $requestLangCode));
|
|
$currencyData = json_decode($currencyData, true);
|
|
$currencyData = $currencyData['main'][$requestLangCode]['numbers']['currencies'] ?? [];
|
|
|
|
if (empty($currencyData)) {
|
|
throw new \Exception();
|
|
}
|
|
|
|
$dataProvider = StaticContainer::get('Piwik\Intl\Data\Provider\CurrencyDataProvider');
|
|
foreach ($dataProvider->getCurrencyList() as $code => $currency) {
|
|
if (isset($currencyData[$code]['displayName'])) {
|
|
$translations['Intl']['Currency_' . $code] = $this->transform($currencyData[$code]['displayName']);
|
|
} else {
|
|
$translations['Intl']['Currency_' . $code] = $currency[1];
|
|
}
|
|
if (isset($currencyData[$code]['symbol'])) {
|
|
$translations['Intl']['CurrencySymbol_' . $code] = $currencyData[$code]['symbol'];
|
|
} else {
|
|
$translations['Intl']['CurrencySymbol_' . $code] = $currency[0];
|
|
}
|
|
}
|
|
|
|
$output->writeln('Saved currency data for ' . $langCode);
|
|
} catch (\Exception $e) {
|
|
$output->writeln('Unable to import currency data for ' . $langCode);
|
|
}
|
|
}
|
|
|
|
protected function replacePlaceHolder($string, $replacement = '%s')
|
|
{
|
|
return str_replace('{0}', $replacement, $string);
|
|
}
|
|
|
|
}
|