Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Translate currency names #13068

Merged
merged 6 commits into from Jul 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,10 @@ The Product Changelog at **[matomo.org/changelog](https://matomo.org/changelog)*

## Matomo 3.6.0

### New Features

* Custom currencies can now be added using the `currencies[]` configuration key.

### New APIs

* Added new event `API.addGlossaryItems` which lets you add items to the glossary.
Expand Down
3 changes: 3 additions & 0 deletions config/global.ini.php
Expand Up @@ -232,6 +232,9 @@
; The only time that the browser will still trigger archiving is when requesting a custom date range that is not pre-processed yet
browser_archiving_disabled_enforce = 0

; Add custom currencies to Sites Manager.
currencies[BTC] = Bitcoin

; By default, users can create Segments which are to be processed in Real-time.
; Setting this to 0 will force all newly created Custom Segments to be "Pre-processed (faster, requires archive.php cron)"
; This can be useful if you want to prevent users from adding much load on the server.
Expand Down
7 changes: 7 additions & 0 deletions core/Intl/Data/Provider/CurrencyDataProvider.php
Expand Up @@ -8,6 +8,8 @@

namespace Piwik\Intl\Data\Provider;

use Piwik\Config;

/**
* Provides currency data.
*/
Expand All @@ -26,6 +28,11 @@ public function getCurrencyList()
{
if ($this->currencyList === null) {
$this->currencyList = require __DIR__ . '/../Resources/currencies.php';

$custom = Config::getInstance()->General['currencies'];
foreach ($custom as $code => $name) {
$this->currencyList[$code] = array($code, $name);
}
}

return $this->currencyList;
Expand Down
14 changes: 5 additions & 9 deletions core/Intl/Data/Resources/currencies.php
Expand Up @@ -34,10 +34,9 @@
'BHD' => array('.د.ب', 'Bahraini dinar'),
'BDT' => array('৳', 'Bangladeshi taka'),
'BBD' => array('$', 'Barbadian dollar'),
'BYR' => array('Br', 'Belarusian ruble'),
'BYN' => array('Br', 'Belarusian ruble'),
'BZD' => array('$', 'Belize dollar'),
'BMD' => array('$', 'Bermudian dollar'),
'BTC' => array('BTC', 'Bitcoin'),
'BTN' => array('Nu.', 'Bhutanese ngultrum'),
'BOB' => array('Bs.', 'Bolivian boliviano'),
'BAM' => array('KM', 'Bosnia Herzegovina mark'),
Expand All @@ -62,7 +61,6 @@
'XPF' => array('F', 'CFP franc'),
'CUC' => array('$', 'Cuban convertible peso'),
'CUP' => array('$', 'Cuban peso'),
'CMG' => array('ƒ', 'Curaçao and Sint Maarten guilder'),
'CZK' => array('Kč', 'Czech koruna'),
'DKK' => array('kr', 'Danish krone'),
'DJF' => array('Fr', 'Djiboutian franc'),
Expand Down Expand Up @@ -103,14 +101,13 @@
'LSL' => array('L', 'Lesotho loti'),
'LRD' => array('$', 'Liberian dollar'),
'LYD' => array('ل.د', 'Libyan dinar'),
'LTL' => array('Lt', 'Lithuanian litas'),
'MOP' => array('P', 'Macanese pataca'),
'MKD' => array('ден', 'Macedonian denar'),
'MGA' => array('Ar', 'Malagasy ariary'),
'MWK' => array('MK', 'Malawian kwacha'),
'MYR' => array('RM', 'Malaysian ringgit'),
'MVR' => array('ރ.', 'Maldivian rufiyaa'),
'MRO' => array('UM', 'Mauritanian ouguiya'),
'MRU' => array('UM', 'Mauritanian ouguiya'),
'MUR' => array('₨', 'Mauritian rupee'),
'MXN' => array('$', 'Mexican peso'),
'MDL' => array('L', 'Moldovan leu'),
Expand Down Expand Up @@ -140,9 +137,9 @@
'RUB' => array('руб.', 'Russian ruble'),
'RWF' => array('Fr', 'Rwandan franc'),
'SHP' => array('£', 'Saint Helena pound'),
'SVC' => array('', 'Salvadoran colón'),
'SSP' => array('£', 'South Sudanese pound'),
'WST' => array('T', 'Samoan tala'),
'STD' => array('Db', 'São Tomé and Príncipe dobra'),
'STN' => array('Db', 'São Tomé and Príncipe dobra'),
'SAR' => array('ر.س', 'Saudi riyal'),
'RSD' => array('дин. or din.', 'Serbian dinar'),
'SCR' => array('₨', 'Seychellois rupee'),
Expand All @@ -166,7 +163,7 @@
'TTD' => array('$', 'Trinidad and Tobago dollar'),
'TND' => array('د.ت', 'Tunisian dinar'),
'TRY' => array('TL', 'Turkish lira'),
'TMM' => array('m', 'Turkmenistani manat'),
'TMT' => array('m', 'Turkmenistani manat'),
'UGX' => array('Sh', 'Ugandan shilling'),
'UAH' => array('₴', 'Ukrainian hryvnia'),
'AED' => array('د.إ', 'United Arab Emirates dirham'),
Expand All @@ -179,5 +176,4 @@
'XOF' => array('Fr', 'West African CFA franc'),
'YER' => array('﷼', 'Yemeni rial'),
'ZMW' => array('ZK', 'Zambian kwacha'),
'ZWL' => array('$', 'Zimbabwean dollar'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you check if removing/changing such currencies might break Matomo if a site had one of those chosen beofre? If so, we maybe should provide an update script to update all sites using one of the changed/removed currencies...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. If a site is configured to use a removed currency, the 3-letter ISO code will be used as both the full and short name.

When editing a site with a removed currency, the user will get an error message instructing her to select another code: The currency "XXX" is not valid. Please enter a valid currency symbol (eg. USD, EUR, etc.). Alternatively, the admin can add the legacy currency to config.inc.php.

As always, changing the currency of a site will not convert the historic values, so data before/after the change will not be comparable. Fixing this is a separate issue.

);
4 changes: 4 additions & 0 deletions core/MetricsFormatter.php
Expand Up @@ -65,6 +65,10 @@ public static function getCurrencySymbol($idSite)
return Site::getCurrencySymbolFor($idSite);
}

/**
* @deprecated Use Piwik\Intl\Data\Provider\CurrencyDataProvider instead.
* @see \Piwik\Intl\Data\Provider\CurrencyDataProvider::getCurrencyList()
*/
public static function getCurrencyList()
{
return Site::getCurrencyList();
Expand Down
11 changes: 6 additions & 5 deletions core/Site.php
Expand Up @@ -586,14 +586,15 @@ public static function getCurrencyFor($idsite)
*/
public static function getCurrencySymbolFor($idsite)
{
$currency = self::getCurrencyFor($idsite);
$symbols = self::getCurrencyList();
$currencyCode = self::getCurrencyFor($idsite);
$key = 'Intl_CurrencySymbol_' . $currencyCode;
$symbol = Piwik::translate($key);

if (isset($symbols[$currency])) {
return $symbols[$currency][0];
if ($key === $symbol) {
return $currencyCode;
}

return '';
return $symbol;
}


Expand Down
67 changes: 67 additions & 0 deletions plugins/Intl/Commands/GenerateIntl.php
Expand Up @@ -65,6 +65,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
$aliasesData = json_decode($aliasesData, true);
$aliasesData = $aliasesData['supplemental']['metadata']['alias']['languageAlias'];

$this->checkCurrencies($output);

$writePath = Filesystem::getPathToPiwikRoot() . '/plugins/Intl/lang/%s.json';

foreach ($piwikLanguages AS $langCode) {
Expand Down Expand Up @@ -97,6 +99,7 @@ protected function execute(InputInterface $input, OutputInterface $output)

$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);
Expand All @@ -109,6 +112,39 @@ protected function execute(InputInterface $input, OutputInterface $output)
}
}

protected function checkCurrencies(OutputInterface $output)
{
$currencyDataUrl = 'https://raw.githubusercontent.com/unicode-cldr/cldr-core/master/supplemental/currencyData.json';

$currencyData = Http::fetchRemoteFile(sprintf($currencyDataUrl, '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)
{
$languageDataUrl = 'https://raw.githubusercontent.com/unicode-cldr/cldr-localenames-full/master/main/%s/languages.json';
Expand Down Expand Up @@ -366,6 +402,8 @@ protected function fetchTimeZoneData(OutputInterface $output, $langCode, $reques
$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);
}
Expand Down Expand Up @@ -460,6 +498,35 @@ protected function fetchUnitData(OutputInterface $output, $langCode, $requestLan
}
}

protected function fetchCurrencyData(OutputInterface $output, $langCode, $requestLangCode, &$translations)
{
$currenciesUrl = 'https://raw.githubusercontent.com/unicode-cldr/cldr-numbers-full/master/main/%s/currencies.json';

try {
$currencyData = Http::fetchRemoteFile(sprintf($currenciesUrl, $requestLangCode));
$currencyData = json_decode($currencyData, true);
$currencyData = $currencyData['main'][$requestLangCode]['numbers']['currencies'];

$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);
Expand Down