Merge pull request #26375 from nextcloud/techdebt/noid/symfony-component-translation-pluralization-rules-is-deprecated
"Symfony\Component\Translation\PluralizationRules" is deprecated
This commit is contained in:
commit
012f791c8f
|
@ -48,6 +48,11 @@ foreach ($directories as $dir) {
|
||||||
$content = file_get_contents($file->getPathname());
|
$content = file_get_contents($file->getPathname());
|
||||||
$json = json_decode($content, true);
|
$json = json_decode($content, true);
|
||||||
|
|
||||||
|
$translations = json_encode($json['translations']);
|
||||||
|
if (strpos($translations, '|') !== false) {
|
||||||
|
$errors[] = $file->getPathname() . "\n" . ' ' . 'Contains a | in the translations' . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||||
$errors[] = $file->getPathname() . "\n" . ' ' . json_last_error_msg() . "\n";
|
$errors[] = $file->getPathname() . "\n" . ' ' . json_last_error_msg() . "\n";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace OC\L10N;
|
||||||
use OCP\IL10N;
|
use OCP\IL10N;
|
||||||
use OCP\L10N\IFactory;
|
use OCP\L10N\IFactory;
|
||||||
use Punic\Calendar;
|
use Punic\Calendar;
|
||||||
use Symfony\Component\Translation\PluralizationRules;
|
use Symfony\Component\Translation\IdentityTranslator;
|
||||||
|
|
||||||
class L10N implements IL10N {
|
class L10N implements IL10N {
|
||||||
|
|
||||||
|
@ -48,11 +48,8 @@ class L10N implements IL10N {
|
||||||
/** @var string Locale of this object */
|
/** @var string Locale of this object */
|
||||||
protected $locale;
|
protected $locale;
|
||||||
|
|
||||||
/** @var string Plural forms (string) */
|
/** @var IdentityTranslator */
|
||||||
private $pluralFormString = 'nplurals=2; plural=(n != 1);';
|
private $identityTranslator;
|
||||||
|
|
||||||
/** @var string Plural forms (function) */
|
|
||||||
private $pluralFormFunction = null;
|
|
||||||
|
|
||||||
/** @var string[] */
|
/** @var string[] */
|
||||||
private $translations = [];
|
private $translations = [];
|
||||||
|
@ -214,20 +211,16 @@ class L10N implements IL10N {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returnsed function accepts the argument $n
|
* @internal
|
||||||
*
|
* @return IdentityTranslator
|
||||||
* Called by \OC_L10N_String
|
|
||||||
* @return \Closure the plural form function
|
|
||||||
*/
|
*/
|
||||||
public function getPluralFormFunction(): \Closure {
|
public function getIdentityTranslator(): IdentityTranslator {
|
||||||
if (\is_null($this->pluralFormFunction)) {
|
if (\is_null($this->identityTranslator)) {
|
||||||
$lang = $this->getLanguageCode();
|
$this->identityTranslator = new IdentityTranslator();
|
||||||
$this->pluralFormFunction = function ($n) use ($lang) {
|
$this->identityTranslator->setLocale($this->getLocaleCode());
|
||||||
return PluralizationRules::get($n, $lang);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->pluralFormFunction;
|
return $this->identityTranslator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -242,9 +235,6 @@ class L10N implements IL10N {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($json['pluralForm'])) {
|
|
||||||
$this->pluralFormString = $json['pluralForm'];
|
|
||||||
}
|
|
||||||
$this->translations = array_merge($this->translations, $json['translations']);
|
$this->translations = array_merge($this->translations, $json['translations']);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
namespace OC\L10N;
|
namespace OC\L10N;
|
||||||
|
|
||||||
class L10NString implements \JsonSerializable {
|
class L10NString implements \JsonSerializable {
|
||||||
/** @var \OC\L10N\L10N */
|
/** @var L10N */
|
||||||
protected $l10n;
|
protected $l10n;
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
|
@ -45,37 +45,44 @@ class L10NString implements \JsonSerializable {
|
||||||
protected $count;
|
protected $count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \OC\L10N\L10N $l10n
|
* @param L10N $l10n
|
||||||
* @param string|string[] $text
|
* @param string|string[] $text
|
||||||
* @param array $parameters
|
* @param array $parameters
|
||||||
* @param int $count
|
* @param int $count
|
||||||
*/
|
*/
|
||||||
public function __construct(\OC\L10N\L10N $l10n, $text, $parameters, $count = 1) {
|
public function __construct(L10N $l10n, $text, array $parameters, int $count = 1) {
|
||||||
$this->l10n = $l10n;
|
$this->l10n = $l10n;
|
||||||
$this->text = $text;
|
$this->text = $text;
|
||||||
$this->parameters = $parameters;
|
$this->parameters = $parameters;
|
||||||
$this->count = $count;
|
$this->count = $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function __toString(): string {
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString() {
|
|
||||||
$translations = $this->l10n->getTranslations();
|
$translations = $this->l10n->getTranslations();
|
||||||
|
$identityTranslator = $this->l10n->getIdentityTranslator();
|
||||||
|
|
||||||
$text = $this->text;
|
// Use the indexed version as per \Symfony\Contracts\Translation\TranslatorInterface
|
||||||
|
$identity = $this->text;
|
||||||
if (array_key_exists($this->text, $translations)) {
|
if (array_key_exists($this->text, $translations)) {
|
||||||
if (is_array($translations[$this->text])) {
|
$identity = $translations[$this->text];
|
||||||
$fn = $this->l10n->getPluralFormFunction();
|
|
||||||
$id = $fn($this->count);
|
|
||||||
$text = $translations[$this->text][$id];
|
|
||||||
} else {
|
|
||||||
$text = $translations[$this->text];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace %n first (won't interfere with vsprintf)
|
if (is_array($identity)) {
|
||||||
$text = str_replace('%n', (string)$this->count, $text);
|
$pipeCheck = implode('', $identity);
|
||||||
|
if (strpos($pipeCheck, '|') !== false) {
|
||||||
|
return 'Can not use pipe character in translations';
|
||||||
|
}
|
||||||
|
|
||||||
|
$identity = implode('|', $identity);
|
||||||
|
} elseif (strpos($identity, '|') !== false) {
|
||||||
|
return 'Can not use pipe character in translations';
|
||||||
|
}
|
||||||
|
|
||||||
|
$identity = str_replace('%n', '%count%', $identity);
|
||||||
|
|
||||||
|
// $count as %count% as per \Symfony\Contracts\Translation\TranslatorInterface
|
||||||
|
$text = $identityTranslator->trans($identity, ['%count%' => $this->count]);
|
||||||
|
|
||||||
return vsprintf($text, $this->parameters);
|
return vsprintf($text, $this->parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -441,7 +441,7 @@ class Manager implements IManager {
|
||||||
$date->setTime(0, 0, 0);
|
$date->setTime(0, 0, 0);
|
||||||
$date->add(new \DateInterval('P' . $defaultExpireDays . 'D'));
|
$date->add(new \DateInterval('P' . $defaultExpireDays . 'D'));
|
||||||
if ($date < $expirationDate) {
|
if ($date < $expirationDate) {
|
||||||
$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$defaultExpireDays]);
|
$message = $this->l->n('Can’t set expiration date more than %n day in the future', 'Can’t set expiration date more than %n days in the future', $defaultExpireDays);
|
||||||
throw new GenericShareException($message, $message, 404);
|
throw new GenericShareException($message, $message, 404);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -517,7 +517,7 @@ class Manager implements IManager {
|
||||||
$date->setTime(0, 0, 0);
|
$date->setTime(0, 0, 0);
|
||||||
$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
|
$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
|
||||||
if ($date < $expirationDate) {
|
if ($date < $expirationDate) {
|
||||||
$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
|
$message = $this->l->n('Can’t set expiration date more than %n day in the future', 'Can’t set expiration date more than %n days in the future', $this->shareApiLinkDefaultExpireDays());
|
||||||
throw new GenericShareException($message, $message, 404);
|
throw new GenericShareException($message, $message, 404);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"_%n file_::_%n files_": ["%n Datei", "%n Dateien"]
|
"_%n file_::_%n files_": ["%n Datei", "%n Dateien"],
|
||||||
|
"Ordered placeholders one %s two %s": "Placeholder one %s two %s",
|
||||||
|
"Reordered placeholders one %s two %s": "Placeholder two %2$s one %1$s",
|
||||||
|
"Reordered placeholders one %1$s two %2$s": "Placeholder two %2$s one %1$s"
|
||||||
},
|
},
|
||||||
"pluralForm" : "nplurals=2; plural=(n != 1);"
|
"pluralForm" : "nplurals=2; plural=(n != 1);"
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,27 @@ class L10nTest extends TestCase {
|
||||||
$this->assertEquals('5 oken', (string)$l->n('%n window', '%n windows', 5));
|
$this->assertEquals('5 oken', (string)$l->n('%n window', '%n windows', 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function dataPlaceholders(): array {
|
||||||
|
return [
|
||||||
|
['Ordered placeholders one %s two %s', 'Placeholder one 1 two 2'],
|
||||||
|
['Reordered placeholders one %s two %s', 'Placeholder two 2 one 1'],
|
||||||
|
['Reordered placeholders one %1$s two %2$s', 'Placeholder two 2 one 1'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataPlaceholders
|
||||||
|
*
|
||||||
|
* @param $string
|
||||||
|
* @param $expected
|
||||||
|
*/
|
||||||
|
public function testPlaceholders($string, $expected): void {
|
||||||
|
$transFile = \OC::$SERVERROOT.'/tests/data/l10n/de.json';
|
||||||
|
$l = new L10N($this->getFactory(), 'test', 'de', 'de_AT', [$transFile]);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $l->t($string, ['1', '2']));
|
||||||
|
}
|
||||||
|
|
||||||
public function localizationData() {
|
public function localizationData() {
|
||||||
return [
|
return [
|
||||||
// timestamp as string
|
// timestamp as string
|
||||||
|
|
|
@ -126,6 +126,10 @@ class ManagerTest extends \Test\TestCase {
|
||||||
->willReturnCallback(function ($text, $parameters = []) {
|
->willReturnCallback(function ($text, $parameters = []) {
|
||||||
return vsprintf($text, $parameters);
|
return vsprintf($text, $parameters);
|
||||||
});
|
});
|
||||||
|
$this->l->method('n')
|
||||||
|
->willReturnCallback(function ($singular, $plural, $count, $parameters = []) {
|
||||||
|
return vsprintf(str_replace('%n', $count, ($count === 1) ? $singular : $plural), $parameters);
|
||||||
|
});
|
||||||
|
|
||||||
$this->factory = new DummyFactory(\OC::$server);
|
$this->factory = new DummyFactory(\OC::$server);
|
||||||
|
|
||||||
|
@ -1957,7 +1961,7 @@ class ManagerTest extends \Test\TestCase {
|
||||||
$data = [];
|
$data = [];
|
||||||
|
|
||||||
// No exclude groups
|
// No exclude groups
|
||||||
$data[] = ['no', null, null, null, false];
|
$data[] = ['no', null, null, [], false];
|
||||||
|
|
||||||
// empty exclude list, user no groups
|
// empty exclude list, user no groups
|
||||||
$data[] = ['yes', '', json_encode(['']), [], false];
|
$data[] = ['yes', '', json_encode(['']), [], false];
|
||||||
|
|
Loading…
Reference in New Issue