12010 Gestion des langues de l'UI : base de données dans data/ - gestion du catalogue et traduction manuelle des dialogues

This commit is contained in:
Fred Tempez 2022-12-28 16:20:55 +01:00
parent 29d505a262
commit 432defa7ca
7 changed files with 154 additions and 95 deletions

View File

@ -221,7 +221,8 @@ class common
'locale' => '', 'locale' => '',
'page' => '', 'page' => '',
'theme' => '', 'theme' => '',
'user' => '' 'user' => '',
'languages' => '',
]; ];
public static $fontsWebSafe = [ public static $fontsWebSafe = [

View File

@ -332,7 +332,8 @@ class init extends common
'backgroundBlockColor' => 'rgba(236, 239, 241, 1)', 'backgroundBlockColor' => 'rgba(236, 239, 241, 1)',
'borderBlockColor' => 'rgba(190, 202, 209, 1)' 'borderBlockColor' => 'rgba(190, 202, 209, 1)'
], ],
'blacklist' => [] 'blacklist' => [],
'languages'=> [],
]; ];
public static $defaultDataI18n = [ public static $defaultDataI18n = [
'en_EN' => [ 'en_EN' => [

View File

@ -20,7 +20,7 @@ class translate extends common
'index' => self::GROUP_ADMIN, 'index' => self::GROUP_ADMIN,
'copy' => self::GROUP_ADMIN, 'copy' => self::GROUP_ADMIN,
'add' => self::GROUP_ADMIN, // Ajouter une langue de contenu 'add' => self::GROUP_ADMIN, // Ajouter une langue de contenu
'ui' => self::GROUP_ADMIN, // Éditer une langue de l'UI 'edit' => self::GROUP_ADMIN, // Éditer une langue de l'UI
'locale' => self::GROUP_ADMIN, // Éditer une langue de contenu 'locale' => self::GROUP_ADMIN, // Éditer une langue de contenu
'delete' => self::GROUP_ADMIN, // Effacer une langue de contenu ou de l'interface 'delete' => self::GROUP_ADMIN, // Effacer une langue de contenu ou de l'interface
'content' => self::GROUP_VISITOR, 'content' => self::GROUP_VISITOR,
@ -40,6 +40,8 @@ class translate extends common
// Liste des langues installées // Liste des langues installées
public static $languagesUiInstalled = []; public static $languagesUiInstalled = [];
public static $languagesInstalled = []; public static $languagesInstalled = [];
public static $languagesStore = [];
public static $dialogues = [];
// Liste des langues cibles // Liste des langues cibles
public static $languagesTarget = []; public static $languagesTarget = [];
@ -59,6 +61,7 @@ class translate extends common
*/ */
public function update() public function update()
{ {
$lang = $this->getUrl(2);
// Jeton incorrect ou URl avec le code langue incorrecte // Jeton incorrect ou URl avec le code langue incorrecte
if ( if (
$this->getUrl(3) !== $_SESSION['csrf'] $this->getUrl(3) !== $_SESSION['csrf']
@ -72,20 +75,23 @@ class translate extends common
} }
// Upload et sauver le fichier de langue // Upload et sauver le fichier de langue
$response = helper::getUrlContents(common::ZWII_UI_URL . $this->getUrl(2) . '.json'); $response = json_decode(helper::getUrlContents(common::ZWII_UI_URL . $lang . '.json'), true);
if ($response !== false) { if ($response !== false) {
$response = file_put_contents(self::I18N_DIR . $this->getUrl(2) . '.json', $response); $response = file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
// Régénère le descripteur // Mettre à jour le descripteur
unlink(self::I18N_DIR . 'enum.json'); $enumsStore = json_decode(helper::getUrlContents(common::ZWII_UI_URL . 'enum.json'), true);
$this->getUiLanguages(); $enums = $this->getData(['languages']);
$enums = array_merge($enums, [
$lang => $enumsStore[$lang]
]);
$response = (bool) $response && $this->setData(['languages', $enums]);
} }
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'translate', 'redirect' => helper::baseUrl() . 'translate',
'notification' => is_int($response) ? helper::translate('Copie terminée avec succès') : 'Copie terminée avec des erreurs', 'notification' => $response ? helper::translate('Copie terminée avec succès') : 'Copie terminée avec des erreurs',
'state' => is_int($response) 'state' => $response
]); ]);
} }
@ -157,7 +163,6 @@ class translate extends common
public function index() public function index()
{ {
// Préparation du formulaire // Préparation du formulaire
// ------------------------- // -------------------------
@ -173,8 +178,7 @@ class translate extends common
$messageLocale = ''; $messageLocale = '';
} }
self::$languagesInstalled[] = [ self::$languagesInstalled[] = [
template::flag($key, '20 %'), template::flag($key, '20 %') . ' ' . $value . ' (' . $key . ')',
$value . ' (' . $key . ')',
$messageLocale, $messageLocale,
template::button('translateContentLanguageLocaleEdit' . $key, [ template::button('translateContentLanguageLocaleEdit' . $key, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/locale/' . $key, 'href' => helper::baseUrl() . $this->getUrl(0) . '/locale/' . $key,
@ -206,20 +210,22 @@ class translate extends common
// Langues installées // Langues installées
$installedUI = $this->getUiLanguages(); $installedUI = $this->getUiLanguages();
// Récupérer la liste des langues disponibles en ligne // Langues disponibles en ligne
$storeUI = json_decode(helper::getUrlContents(common::ZWII_UI_URL . '/enum.json'), true); $storeUI = json_decode(helper::getUrlContents(common::ZWII_UI_URL . 'enum.json'), true);
// Construction du tableau à partir des langues disponibles dans le store // Construction du tableau à partir des langues disponibles dans le store
foreach ($storeUI as $file => $value) { foreach ($installedUI as $file => $value) {
// La langue est-elle référencée ? // La langue est-elle référencée ?
if (array_key_exists(basename($file, '.json'), $installedUI)) { if (array_key_exists(basename($file, '.json'), $installedUI)) {
// La langue est déjà installée // La langue est déjà installée
self::$languagesUiInstalled[$file] = [ self::$languagesUiInstalled[$file] = [
template::flag($file, '20 %'), template::flag($file, '20 %') . ' ' . self::$languages[$file],
self::$languages[$file], $value['version'],
self::$i18nUI === $file ? helper::translate('Interface') : '', helper::dateUTF8('%d/%m/%Y', $value['date']),
//self::$i18nUI === $file ? helper::translate('Interface') : '',
'',
template::button('translateContentLanguageUIEdit' . $file, [ template::button('translateContentLanguageUIEdit' . $file, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/ui/' . $file, 'href' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $file,
'value' => template::ico('pencil'), 'value' => template::ico('pencil'),
'help' => 'Éditer', 'help' => 'Éditer',
'disabled' => 'fr_FR' === $file 'disabled' => 'fr_FR' === $file
@ -242,22 +248,24 @@ class translate extends common
'help' => 'Supprimer', 'help' => 'Supprimer',
]), ]),
]; ];
} else { }
// La langue n'est pas installée // Construction du tableau à partir des langues disponibles dans le store
self::$languagesUiInstalled[$file] = [ foreach ($storeUI as $file => $value) {
template::flag($file, '20 %'), // La langue est-elle installée ?
self::$languages[$file], if (array_key_exists($file, $installedUI) === false) {
self::$i18nUI === $file ? helper::translate('Interface') : '', self::$languagesStore[$file] = [
'', template::flag($file, '20 %') . ' ' . self::$languages[$file],
'', $value['version'],
template::button('translateContentLanguageUIDownload' . $file, [ helper::dateUTF8('%d/%m/%Y', $value['date']),
'class' => 'buttonGreen', '',
'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file . '/' . $_SESSION['csrf'], template::button('translateContentLanguageUIDownload' . $file, [
'value' => template::ico('shopping-basket'), 'class' => 'buttonGreen',
'help' => 'Installer', 'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file . '/' . $_SESSION['csrf'],
]), 'value' => template::ico('shopping-basket'),
'' 'help' => 'Installer',
]; ])
];
}
} }
} }
@ -431,11 +439,12 @@ class translate extends common
/** /**
* Edition de la langue de l'interface * Edition de la langue de l'interface
*/ */
public function ui() public function edit()
{ {
$lang = $this->getUrl(2);
// Jeton incorrect ou URl avec le code langue incorrecte // Jeton incorrect ou URl avec le code langue incorrecte
if ( if (
!array_key_exists($this->getUrl(2), self::$languages) !array_key_exists($lang, self::$languages)
) { ) {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
@ -447,18 +456,27 @@ class translate extends common
// Soumission du formulaire // Soumission du formulaire
if ($this->isPost()) { if ($this->isPost()) {
$data = json_decode(file_get_contents(self::I18N_DIR . $this->getUrl(2) . '.json'), true); // Sauvegarder les champs de la langue
$data = json_decode(file_get_contents(self::I18N_DIR . $lang . '.json'), true);
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
$data[$key] = $this->getInput('translateString' . array_search($key, array_keys($data)), false, null); $target = $this->getInput('translateString' . array_search($key, array_keys($data)));
if (empty($target) === false) {
$data[$key] = $target;
}
} }
file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
file_put_contents(self::I18N_DIR . $this->getUrl(2) . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); // Mettre à jour le descripteur
$this->setData(['languages', $lang, [
'version' => $this->getInput('translateEditVersion'),
'date' => $this->getInput('translateEditDate', helper::FILTER_DATETIME),
]]);
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'notification' => helper::translate('Modifications enregistrées'), 'notification' => helper::translate('Modifications enregistrées'),
'redirect' => helper::baseUrl() . 'translate', 'redirect' => helper::baseUrl() . 'translate',
'state' => true 'state' => true,
]); ]);
} }
@ -476,7 +494,7 @@ class translate extends common
$data[$key] = ''; $data[$key] = '';
} }
} }
file_put_contents(self::I18N_DIR . $this->getUrl(2) . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
// Tableau des chaines à traduire dans la langue sélectionnée // Tableau des chaines à traduire dans la langue sélectionnée
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
@ -489,16 +507,18 @@ class translate extends common
// Liste des pages // Liste des pages
self::$pages = $pagination['pages']; self::$pages = $pagination['pages'];
// Articles en fonction de la pagination // Articles en fonction de la pagination
for ($i = $pagination['first']; $i < $pagination['last']; $i++) { for ($i = $pagination['first']; $i < $pagination['last']; $i++) {
self::$languagesUiInstalled[$i] = $dialogues[$i]; self::$dialogues[$i] = $dialogues[$i];
} }
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'title' => helper::translate('Éditer les dialogues') . '&nbsp;' . template::flag($this->getUrl(2), '20 %'), 'title' => helper::translate('Éditer les dialogues') . '&nbsp;' . template::flag($lang, '20 %'),
'view' => 'ui' 'view' => 'edit',
'vendor' => [
'flatpickr',
],
]); ]);
} }
@ -540,14 +560,14 @@ class translate extends common
if (file_exists(self::I18N_DIR . $lang . '.json') === true) { if (file_exists(self::I18N_DIR . $lang . '.json') === true) {
$success = unlink(self::I18N_DIR . $lang . '.json'); $success = unlink(self::I18N_DIR . $lang . '.json');
} }
// Effacer la langue dans la base
$this->deleteData(['languages', $lang]);
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'translate', 'redirect' => helper::baseUrl() . 'translate',
'notification' => $success ? helper::translate('Traduction supprimée') : helper::translate('Erreur inconnue'), 'notification' => $success ? helper::translate('Traduction supprimée') : helper::translate('Erreur inconnue'),
'state' => $success 'state' => $success
]); ]);
unlink(self::I18N_DIR . 'enum.json');
$this->getUiLanguages();
break; break;
default: default:
# Do nothing # Do nothing
@ -583,10 +603,10 @@ class translate extends common
*/ */
private function getUiLanguages() private function getUiLanguages()
{ {
$enums = json_decode(helper::getUrlContents(self::I18N_DIR . '/enum.json'), true); $enums = $this->getData(['languages']);
// Générer une énumération absente // Générer une énumération absente
if (is_array($enums) === false) { if (empty($enums) ) {
if (is_dir(self::I18N_DIR) === false) { if (is_dir(self::I18N_DIR) === false) {
mkdir(self::I18N_DIR); mkdir(self::I18N_DIR);
} }
@ -596,17 +616,16 @@ class translate extends common
chdir($dir); chdir($dir);
$enums = []; $enums = [];
foreach ($files as $file => $value) { foreach ($files as $file => $value) {
if (basename($value, '.json') === 'enum.json') { if (basename($value, '.json') === 'enum') {
continue; continue;
} }
$enums[basename($value, '.json')] = [ $enums[basename($value, '.json')] = [
'version' => 1.0, 'version' => "?",
'date' => 1672052400 'date' => 1672052400
]; ];
} }
file_put_contents(self::I18N_DIR . 'enum.json', json_encode($enums)); $this->setData(['languages', $enums]);
} }
return ($enums); return ($enums);
} }
} }

View File

@ -0,0 +1,58 @@
<?php echo template::formOpen('translateUIForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('translateUIFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'translate',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('translateUIFormSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>
<?php echo helper::translate('Paramètres'); ?>
</h4>
<div class="row">
<div class="col6">
<?php echo template::text('translateEditVersion', [
'label' => 'Version n°',
'value' => $this->getData(['languages', $this->getUrl(2), 'version'])
]); ?>
</div>
<div class="col6">
<?php echo template::date('translateEditDate', [
'label' => 'Date de publication',
'value' => $this->getData(['languages', $this->getUrl(2), 'date'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<div class="row">
<?php foreach ($module::$dialogues as $key => $value) : ?>
<div class="col6">
<?php echo sprintf('%g -', $key); ?>
<?php echo $value['source']; ?>
</div>
<div class="col6">
<?php echo template::text('translateString' . $key, [
'label' => '',
'value' => $value['target']
]); ?>
</div>
<?php endforeach; ?>
</div>
<?php echo $module::$pages; ?>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -48,9 +48,24 @@
<div id="uiContainer" class="tabContent"> <div id="uiContainer" class="tabContent">
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<?php if ($module::$languagesUiInstalled) : ?> <div class="block">
<?php echo template::table([1, 2, 6, 1, 1, 1, 1], $module::$languagesUiInstalled, ['Langues', '', '', '', '', '', '']); ?> <h4><?php echo helper::translate('Langues installées'); ?>
<?php endif; ?> </h4>
<?php if ($module::$languagesUiInstalled) : ?>
<?php echo template::table([2, 1, 1, 4, 1, 1, 1, 1], $module::$languagesUiInstalled, ['Langues', 'Version', 'Date', '', '', '', '', '']); ?>
<?php endif; ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Catalogue'); ?>
</h4>
<?php if ($module::$languagesStore) : ?>
<?php echo template::table([2, 1, 2, 6, 1], $module::$languagesStore, ['Langues', 'Version', 'Date', '', '']); ?>
<?php endif; ?>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -58,7 +73,7 @@
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<?php if ($module::$languagesInstalled) : ?> <?php if ($module::$languagesInstalled) : ?>
<?php echo template::table([1, 4, 5, 1, 1], $module::$languagesInstalled, ['Langues', '', '', '', '']); ?> <?php echo template::table([2, 4, 4, 1, 1], $module::$languagesInstalled, ['Langues', '', '', '', '']); ?>
<?php endif; ?> <?php endif; ?>
</div> </div>
</div> </div>

View File

@ -1,35 +0,0 @@
<?php echo template::formOpen('translateUIForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('translateUIFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'translate',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('translateUIFormSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<div class="row">
<?php foreach ($module::$languagesUiInstalled as $key => $value) : ?>
<div class="col6">
<?php echo sprintf('%g -', $key); ?>
<?php echo $value['source']; ?>
</div>
<div class="col6">
<?php echo template::text('translateString' . array_search($value['target'], array_keys($module::$languagesUiInstalled)), [
'label' => '',
'value' => $value['target']
]); ?>
</div>
<?php endforeach; ?>
</div>
<?php echo $module::$pages; ?>
</div>
</div>
</div>
<?php echo template::formClose(); ?>