[10.0.06] Gestion de langues en test

This commit is contained in:
fredtempez 2019-08-23 09:46:11 +02:00
parent 1e1b86365d
commit 60688117f6
6 changed files with 297 additions and 28 deletions

View File

@ -376,3 +376,14 @@ $(document).ready(function(){
$("#navfixedconnected .navLevel2").css({ 'pointer-events' : 'none' }); $("#navfixedconnected .navLevel2").css({ 'pointer-events' : 'none' });
}); });
}); });
/**
* Traitement du changement de langue
*/
$(document).ready(function(){
$("#barSelectLanguage").change(function(){
this.form.submit();
});
});

View File

@ -35,7 +35,7 @@ class common {
const TEMP_DIR = 'site/tmp/'; const TEMP_DIR = 'site/tmp/';
// Numéro de version // Numéro de version
const ZWII_VERSION = '10.0.04.dev'; const ZWII_VERSION = '10.0.06.dev';
public static $actions = []; public static $actions = [];
public static $coreModuleIds = [ public static $coreModuleIds = [
@ -46,13 +46,31 @@ class common {
'search', 'search',
'sitemap', 'sitemap',
'theme', 'theme',
'user' 'user',
'i18n'
];
public static $i18nList = [
'de' => 'Allemand (de)' ,
'en' => 'Anglais (en)',
'bg' => 'Bulgare (bg)',
'da' => 'Danois (da)',
'es' => 'Espagnol (es)',
'fi' => 'Finois (fi)',
'fr' => 'Français (fr)',
'is' => 'Islandais (is)',
'it' => 'Italien (it)',
'nl' => 'Néerlandais (nl)',
'no' => 'Norvégien (no)' ,
'pt' => 'Portugais (pt)',
'sv' => 'Suédois (sv)',
'ro' => 'Roumain (ro)',
'cz' => 'Tchèque (cz)'
]; ];
public static $dataStage = [ public static $dataStage = [
'config', 'config',
'core', 'core',
'module',
'page', 'page',
'module',
'user', 'user',
'theme' 'theme'
]; ];
@ -128,9 +146,13 @@ class common {
self::GROUP_ADMIN => 'Administrateur' self::GROUP_ADMIN => 'Administrateur'
]; ];
public static $timezone; public static $timezone;
public static $i18nBackEnd = 'fr';
public static $i18nFrontEnd = 'fr';
private $url = ''; private $url = '';
private $user = []; private $user = [];
/** /**
* Constructeur commun * Constructeur commun
*/ */
@ -152,16 +174,37 @@ class common {
} }
// Installation fraîche, initialisation des modules manquants // Installation fraîche, initialisation des modules manquants
// La langue d'installation par défaut est fr
foreach (self::$dataStage as $stageId) { foreach (self::$dataStage as $stageId) {
$folder = $this->dirData ($stageId, 'fr'); $folder = $this->dirData ($stageId, 'fr');
if (file_exists($folder . $stageId .'.json') === false) { if (file_exists($folder . $stageId .'.json') === false) {
$this->iniData($stageId); $this->iniData($stageId,'fr');
common::$coreNotices [] = $stageId ; common::$coreNotices [] = $stageId ;
// Prévoir une notification ici
} }
} }
// 1 Langue sélectionnée par l'utilisateur prioritaire
if (isset($_COOKIE['ZWII_USER_I18N'])) {
$i18nPOST = $_COOKIE['ZWII_USER_I18N'];
} else {
$i18nPOST = '';
}
// 2 Langue du navigateur
$i18nHTTP = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
// 3 Langue du backend
//$i18nBackEnd = $this->getData('config','i18n');
$i18nBackEnd = 'fr';
// Détermine la langue
common::$i18nFrontEnd = $i18nPOST === '' ? $i18nHTTP : $i18nPOST;
// !! Vérifier si l'anglais est bien installée sinon fr
if ($this->geti18n() !== 'fr') {
common::$i18nFrontEnd = key_exists(common::$i18nFrontEnd, self::$i18nList) ? common::$i18nFrontEnd : 'en';
}
// Sauvegarder la sélection
//setcookie('ZWII_USER_I18N',common::$i18nFrontEnd,strtotime("+1 year"), helper::baseUrl(false, false));
$this->seti18N(common::$i18nFrontEnd);
// Mise à jour des données core // Mise à jour des données core
$this->update(); $this->update();
@ -274,11 +317,9 @@ class common {
* Supprime des données * Supprime des données
* @param array $keys Clé(s) des données * @param array $keys Clé(s) des données
*/ */
public function deleteData($keys) { public function deleteData($keys) {
// Langue et chemin pour page et module
$lang='fr';
//Retourne une chaine contenant le dossier à créer //Retourne une chaine contenant le dossier à créer
$folder = $this->dirData ($keys[0],$lang); $folder = $this->dirData ($keys[0],$this->geti18n());
// Constructeur // Constructeur
$db = new \Prowebcraft\JsonDb([ $db = new \Prowebcraft\JsonDb([
'name' => $keys[0] . '.json', 'name' => $keys[0] . '.json',
@ -317,6 +358,18 @@ class common {
} }
} }
public function geti18n() {
// Choix de la langue
return (common::$i18nFrontEnd);
}
public function seti18n($lan = 'fr') {
// Sauvegarder la sélection
setcookie('ZWII_USER_I18N',$lan,strtotime("+1 year"), helper::baseUrl(false, false));
}
/** /**
* Récupérer une copie d'écran du site Web pour le tag image si le fichier n'existe pas * Récupérer une copie d'écran du site Web pour le tag image si le fichier n'existe pas
@ -347,10 +400,10 @@ class common {
* @return mixed * @return mixed
*/ */
public function getData($keys = null) { public function getData($keys = null) {
$lang = 'fr';
if (count($keys) >= 1) { if (count($keys) >= 1) {
//Retourne une chaine contenant le dossier à créer //Retourne une chaine contenant le dossier à créer
$folder = $this->dirData ($keys[0],$lang); $folder = $this->dirData ($keys[0],$this->geti18n());
// Constructeur du module de sauvegarde // Constructeur du module de sauvegarde
$db = new \Prowebcraft\JsonDb([ $db = new \Prowebcraft\JsonDb([
'name' => $keys[0] . '.json', 'name' => $keys[0] . '.json',
@ -519,7 +572,7 @@ class common {
* Convertit un fichier de données data.json puis le renomme * Convertit un fichier de données data.json puis le renomme
*/ */
public function importData() { public function importData() {
$lang = 'fr';
// Trois tentatives de lecture // Trois tentatives de lecture
for($i = 0; $i < 3; $i++) { for($i = 0; $i < 3; $i++) {
$tempData=json_decode(file_get_contents(self::DATA_DIR.'core.json'), true); $tempData=json_decode(file_get_contents(self::DATA_DIR.'core.json'), true);
@ -537,8 +590,8 @@ class common {
rename (self::DATA_DIR.'core.json',self::DATA_DIR.'imported_core.json'); rename (self::DATA_DIR.'core.json',self::DATA_DIR.'imported_core.json');
rename (self::DATA_DIR.'theme.json',self::DATA_DIR.'imported_theme.json'); rename (self::DATA_DIR.'theme.json',self::DATA_DIR.'imported_theme.json');
// Dossier de langues // Dossier de langues
if (!file_exists(self::DATA_DIR . '/' . $lang)) { if (!file_exists(self::DATA_DIR . '/' . $this->geti18n())) {
mkdir (self::DATA_DIR . '/' . $lang); mkdir (self::DATA_DIR . '/' . $this->geti18n());
} }
// Ecriture des données // Ecriture des données
$this->setData(['config',$tempData['config']]); $this->setData(['config',$tempData['config']]);
@ -744,6 +797,28 @@ class common {
} }
/**
* Retourne la liste les langues installées
* @return array liste de dossiers
* @param bool true la première contient une indication de sélection - false la liste est neutre
* @return array liste des pages installées sous la forme "fr" -> "Français"
* La fonction vérifie l'existence du dossier et des deux fichiers de configuration
*/
public function i18nList ($emptyLine = false) {
$listLanguages = $emptyLine === true ? [''=>'Sélectionner'] : [];
$tempData = array_diff(scandir(self::DATA_DIR), array('..', '.'));
foreach ($tempData as $item) {
if (is_dir(self::DATA_DIR . $item) === true) {
if (is_file(self::DATA_DIR . $item . '/' . 'page.json') === true &&
is_file(self::DATA_DIR . $item . '/' . 'module.json') === true ) {
$listLanguages [$item] = self::$i18nList [$item];
}
}
}
return $listLanguages;
}
/** /**
* Envoi un mail * Envoi un mail
@ -795,11 +870,9 @@ class common {
* @param array $keys Clé(s) des données * @param array $keys Clé(s) des données
*/ */
public function setData($keys = NULL) { public function setData($keys = NULL) {
// Langue et chemin pour page et module
$lang='fr';
//Retourne une chaine contenant le dossier à créer //Retourne une chaine contenant le dossier à créer
$folder = $this->dirData ($keys[0],$lang); $folder = $this->dirData ($keys[0],$this->geti18n());
// Constructeur // Constructeur
$db = new \Prowebcraft\JsonDb([ $db = new \Prowebcraft\JsonDb([
'name' => $keys[0] . '.json', 'name' => $keys[0] . '.json',
@ -839,14 +912,11 @@ class common {
* @param array $module : nom du module à générer * @param array $module : nom du module à générer
* choix valides : core config user theme page module * choix valides : core config user theme page module
*/ */
public function iniData($module) { public function iniData($module, $lang = 'fr') {
// Tableau avec les données vierges // Tableau avec les données vierges
require_once('core/module/install/ressource/defaultdata.php'); require_once('core/module/install/ressource/defaultdata.php');
// Langue
$lang='fr';
// Stockage dans un sous-dossier localisé // Stockage dans un sous-dossier localisé
// Le dossier de langue existe t-il ? // Le dossier de langue existe t-il ?
if (!file_exists(self::DATA_DIR . '/' . $lang)) { if (!file_exists(self::DATA_DIR . '/' . $lang)) {
@ -1022,6 +1092,7 @@ class common {
} }
// Version 10.0.00 // Version 10.0.00
if($this->getData(['core', 'dataVersion']) < 10000) { if($this->getData(['core', 'dataVersion']) < 10000) {
$this->setData(['config','i18n','fr']);
$this->setData(['core', 'dataVersion', 10000]); $this->setData(['core', 'dataVersion', 10000]);
//$this->saveData(); //$this->saveData();
} }
@ -2086,6 +2157,7 @@ class layout extends common {
* Affiche le copyright * Affiche le copyright
*/ */
public function showCopyright() { public function showCopyright() {
// Ouverture Bloc copyright // Ouverture Bloc copyright
$items = '<div id="footerCopyright">'; $items = '<div id="footerCopyright">';
$items .= '<span id="footerFontCopyright">'; $items .= '<span id="footerFontCopyright">';
@ -2133,8 +2205,10 @@ class layout extends common {
strip_tags(str_replace('/', '_', $this->getUrl())) . strip_tags(str_replace('/', '_', $this->getUrl())) .
'" data-tippy-content="Connexion à l\'administration" rel="nofollow">Connexion</a></span>'; '" data-tippy-content="Connexion à l\'administration" rel="nofollow">Connexion</a></span>';
} }
// Fermeture du bloc copyright // Fermeture du bloc copyright
$items .= '</span></div>'; $items .= '</span></div>';
$items .= $this->geti18n();
echo $items; echo $items;
} }
@ -2503,6 +2577,23 @@ class layout extends common {
// Items de gauche // Items de gauche
$leftItems = ''; $leftItems = '';
if($this->getUser('group') >= self::GROUP_MODERATOR) { if($this->getUser('group') >= self::GROUP_MODERATOR) {
// ne pas afficher la barre de langue pour une seule
// Sélection des langues installées
echo $this->geti18n();
if (sizeof($this->i18nList()) > 1) {
$leftItems .= '<li><form method="POST" action="' . helper::baseUrl(true) . 'i18n" id="barFormSelectLanguage">';
$leftItems .= '<select id="barSelectLanguage" name="i18nSelect" >';
foreach ($this->i18nList() as $itemKey => $item) {
$leftItems .= '<option ';
$leftItems .= 'value="' . $itemKey .'"';
if ($this->geti18n() === $itemKey) {
$leftItems .= ' selected ';
}
$leftItems .= ' >' . $item . '</option>';
}
}
$leftItems .= '</select></form></li>';
$leftItems .= '&nbsp;';
$leftItems .= '<li><select id="barSelectPage">'; $leftItems .= '<li><select id="barSelectPage">';
$leftItems .= '<option value="">Choisissez une page</option>'; $leftItems .= '<option value="">Choisissez une page</option>';
$leftItems .= '<optgroup label="Pages orphelines">'; $leftItems .= '<optgroup label="Pages orphelines">';
@ -2568,6 +2659,7 @@ class layout extends common {
if($this->getUser('group') >= self::GROUP_ADMIN) { if($this->getUser('group') >= self::GROUP_ADMIN) {
$rightItems .= '<li><a href="' . helper::baseUrl() . 'user" data-tippy-content="Configurer les utilisateurs">' . template::ico('users') . '</a></li>'; $rightItems .= '<li><a href="' . helper::baseUrl() . 'user" data-tippy-content="Configurer les utilisateurs">' . template::ico('users') . '</a></li>';
$rightItems .= '<li><a href="' . helper::baseUrl() . 'theme" data-tippy-content="Personnaliser le thème">' . template::ico('brush') . '</a></li>'; $rightItems .= '<li><a href="' . helper::baseUrl() . 'theme" data-tippy-content="Personnaliser le thème">' . template::ico('brush') . '</a></li>';
$rightItems .= '<li><a href="' . helper::baseUrl() . 'i18n" data-tippy-content="Internationalisation">' . template::ico('flag') . '</a></li>';
$rightItems .= '<li><a href="' . helper::baseUrl() . 'config" data-tippy-content="Configurer le site">' . template::ico('cog-alt') . '</a></li>'; $rightItems .= '<li><a href="' . helper::baseUrl() . 'config" data-tippy-content="Configurer le site">' . template::ico('cog-alt') . '</a></li>';
// Mise à jour automatique // Mise à jour automatique
if(helper::checkNewVersion() ) { if(helper::checkNewVersion() ) {

View File

@ -313,7 +313,7 @@ td > .col12 {
line-height: 45px; line-height: 45px;
} }
#bar li { #bar li, form {
display: inline; display: inline;
} }
@ -331,11 +331,15 @@ td > .col12 {
#bar a:active { #bar a:active {
background: #111112; background: #111112;
} }
#bar select { #bar select{
width: 250px;
border: 0; border: 0;
} }
#bar #barSelectPage {
width: 200px;
}
#bar #barSelectLanguage {
width: 170px;
}
@media (min-width: 769px) { @media (min-width: 769px) {
#bar #barLeft { #bar #barLeft {
float: left; float: left;

106
core/module/i18n/i18n.php Normal file
View File

@ -0,0 +1,106 @@
<?php
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2019, Frédéric Tempez
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
*/
class i18n extends common {
public static $actions = [
'index' => self::GROUP_MODERATOR
];
/**
* Configuration
*/
public function index() {
// Traitement du changement de langue
if (isset($_POST['i18nSelect'])) {
$this->seti18n($_POST['i18nSelect']);
// Valeurs en sortie sans post
$this->addOutput([
'redirect' => helper::baseUrl(false),
'notification' => 'Langue modifiée',
'state' => true
]);
}
// Retour du formulaire
if($this->isPost()) {
// Et faire un backup
// Fonction à révoir dans core.php
// Récupérer les données du formulaire
$create = $this->getInput('i18nLanguageAdd');
$remove = $this->getInput('i18nLanguageRemove');
$copyFrom = $this->getInput('i18nLanguageCopyFrom');
$notification = '';
$success = array ('create' => false,'remove'=> false);
// Mode Création
if (!empty ($create)) {
// Mode création de langue
// La langue est déja créée ?
if (is_dir(self::DATA_DIR . $create) === false) {
$copyFrom = $copyFrom === '' ? 'core/module/i18n/ressource/' : self::DATA_DIR . $copyFrom . '/';
// Créer le dossier
$success ['create'] = mkdir (self::DATA_DIR . $create);
// Copier les données par défaut
$success ['create'] = (copy ($copyFrom . 'module.json', self::DATA_DIR . $create . '/module.json') === true && $success ['create'] === true) ? true : false;
$success ['create'] = (copy ($copyFrom . 'page.json', self::DATA_DIR . $create . '/page.json') === true && $success ['create'] === true) ? true : false;
}
// Valeurs en sortie
$notification = $success['create'] === true ? self::$i18nList[$create] . ' installée' : self::$i18nList[$create] . ' déjà installée' ;
}
// Mode effacement
if (!empty ($remove)) {
// La langue est celle par défaut : effacement bloqué
// Une notification existe déjà, insérer un séparateur
if ($notification) {
$notification .= ' | ';
}
if ( $remove !== $this->getData(['i18n','frontend'])) {
// Le dossier existe ?
if (is_dir(self::DATA_DIR . $remove) === true) {
$success ['remove'] = unlink (self::DATA_DIR . $remove . '/module.json');
$success ['remove'] = (unlink (self::DATA_DIR . $remove . '/page.json') && $success ['remove'] === true) ? true : false ;
$success ['remove'] = (rmdir (self::DATA_DIR . $remove) === true && $success ['remove'] === true) ? true : false ;;
}
// Valeurs en sortie
$notification .= $success['remove'] === true ? self::$i18nList[$remove] .' effacée' : self::$i18nList[$remove] . ' n\'existe pas' ;
} else {
// Valeurs en sortie
$success ['remove'] = false;
$notification .= self::$i18nList[$remove] . ' est active, effacement impossible';
}
}
$this->addOutput([
'notification' => $notification,
'title' => 'Internationalisation',
'view' => 'index',
'state' => $success ['create'] || $success ['remove']
]);
} else {
// Valeurs en sortie sans post
$this->addOutput([
'title' => 'Internationalisation',
'view' => 'index'
]);
}
}
}

View File

@ -0,0 +1,55 @@
<?php echo template::formOpen('i18nForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('configBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(false),
'ico' => 'home',
'value' => 'Accueil'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('configSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col8">
<div class="block">
<h4>Ajouter une localisation</h4>
<div class="row">
<div class="col5">
<?php echo template::select('i18nLanguageCopyFrom', $this->i18nList(true), [
'label' => 'Copier à partir ',
'help' => 'Pour démarrer sans copie des pages te des modules d\'une langue existante, ne rien sélectionner',
'selected' => -1
]); ?>
</div>
<div class="col1">
<?php echo template::ico('right-big'); ?>
</div>
<div class="col5">
<?php
$available = array ('' => 'Sélectionner');
$available = array_merge ($available, self::$i18nList);
echo template::select('i18nLanguageAdd', $available, [
'label' => 'vers'
]); ?>
</div>
</div>
</div>
</div>
<div class="col4">
<div class="block">
<h4>Supprimer une localisation</h4>
<div class="row">
<?php echo template::select('i18nLanguageRemove', $this->i18nList(true), [
'label' => 'Localisations installées',
'help' => 'La suppression d\'une langue entraîne l\'effacement des pages et des modules',
'selected' => -1
]); ?>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -21,7 +21,8 @@ class initdata extends common {
'timezone' => 'Europe/Paris', 'timezone' => 'Europe/Paris',
'title' => 'Zwii, votre site en quelques clics !', 'title' => 'Zwii, votre site en quelques clics !',
'itemsperPage' => 10, 'itemsperPage' => 10,
'legalPageId' => '' 'legalPageId' => '',
'i18n' => 'fr'
], ],
'core' => [ 'core' => [
'dataVersion' => 0, 'dataVersion' => 0,