[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' });
});
});
/**
* 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/';
// Numéro de version
const ZWII_VERSION = '10.0.04.dev';
const ZWII_VERSION = '10.0.06.dev';
public static $actions = [];
public static $coreModuleIds = [
@ -46,13 +46,31 @@ class common {
'search',
'sitemap',
'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 = [
'config',
'core',
'module',
'page',
'module',
'user',
'theme'
];
@ -128,9 +146,13 @@ class common {
self::GROUP_ADMIN => 'Administrateur'
];
public static $timezone;
public static $i18nBackEnd = 'fr';
public static $i18nFrontEnd = 'fr';
private $url = '';
private $user = [];
/**
* Constructeur commun
*/
@ -152,16 +174,37 @@ class common {
}
// Installation fraîche, initialisation des modules manquants
// La langue d'installation par défaut est fr
foreach (self::$dataStage as $stageId) {
$folder = $this->dirData ($stageId, 'fr');
if (file_exists($folder . $stageId .'.json') === false) {
$this->iniData($stageId);
$this->iniData($stageId,'fr');
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
$this->update();
@ -274,11 +317,9 @@ class common {
* Supprime des données
* @param array $keys Clé(s) des données
*/
public function deleteData($keys) {
// Langue et chemin pour page et module
$lang='fr';
public function deleteData($keys) {
//Retourne une chaine contenant le dossier à créer
$folder = $this->dirData ($keys[0],$lang);
$folder = $this->dirData ($keys[0],$this->geti18n());
// Constructeur
$db = new \Prowebcraft\JsonDb([
'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
@ -347,10 +400,10 @@ class common {
* @return mixed
*/
public function getData($keys = null) {
$lang = 'fr';
if (count($keys) >= 1) {
//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
$db = new \Prowebcraft\JsonDb([
'name' => $keys[0] . '.json',
@ -519,7 +572,7 @@ class common {
* Convertit un fichier de données data.json puis le renomme
*/
public function importData() {
$lang = 'fr';
// Trois tentatives de lecture
for($i = 0; $i < 3; $i++) {
$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.'theme.json',self::DATA_DIR.'imported_theme.json');
// Dossier de langues
if (!file_exists(self::DATA_DIR . '/' . $lang)) {
mkdir (self::DATA_DIR . '/' . $lang);
if (!file_exists(self::DATA_DIR . '/' . $this->geti18n())) {
mkdir (self::DATA_DIR . '/' . $this->geti18n());
}
// Ecriture des données
$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
@ -795,11 +870,9 @@ class common {
* @param array $keys Clé(s) des données
*/
public function setData($keys = NULL) {
// Langue et chemin pour page et module
$lang='fr';
//Retourne une chaine contenant le dossier à créer
$folder = $this->dirData ($keys[0],$lang);
$folder = $this->dirData ($keys[0],$this->geti18n());
// Constructeur
$db = new \Prowebcraft\JsonDb([
'name' => $keys[0] . '.json',
@ -839,14 +912,11 @@ class common {
* @param array $module : nom du module à générer
* choix valides : core config user theme page module
*/
public function iniData($module) {
public function iniData($module, $lang = 'fr') {
// Tableau avec les données vierges
require_once('core/module/install/ressource/defaultdata.php');
// Langue
$lang='fr';
// Stockage dans un sous-dossier localisé
// Le dossier de langue existe t-il ?
if (!file_exists(self::DATA_DIR . '/' . $lang)) {
@ -1022,6 +1092,7 @@ class common {
}
// Version 10.0.00
if($this->getData(['core', 'dataVersion']) < 10000) {
$this->setData(['config','i18n','fr']);
$this->setData(['core', 'dataVersion', 10000]);
//$this->saveData();
}
@ -2086,6 +2157,7 @@ class layout extends common {
* Affiche le copyright
*/
public function showCopyright() {
// Ouverture Bloc copyright
$items = '<div id="footerCopyright">';
$items .= '<span id="footerFontCopyright">';
@ -2133,8 +2205,10 @@ class layout extends common {
strip_tags(str_replace('/', '_', $this->getUrl())) .
'" data-tippy-content="Connexion à l\'administration" rel="nofollow">Connexion</a></span>';
}
// Fermeture du bloc copyright
$items .= '</span></div>';
$items .= '</span></div>';
$items .= $this->geti18n();
echo $items;
}
@ -2503,6 +2577,23 @@ class layout extends common {
// Items de gauche
$leftItems = '';
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 .= '<option value="">Choisissez une page</option>';
$leftItems .= '<optgroup label="Pages orphelines">';
@ -2568,6 +2659,7 @@ class layout extends common {
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() . '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>';
// Mise à jour automatique
if(helper::checkNewVersion() ) {

View File

@ -313,7 +313,7 @@ td > .col12 {
line-height: 45px;
}
#bar li {
#bar li, form {
display: inline;
}
@ -331,11 +331,15 @@ td > .col12 {
#bar a:active {
background: #111112;
}
#bar select {
width: 250px;
#bar select{
border: 0;
}
#bar #barSelectPage {
width: 200px;
}
#bar #barSelectLanguage {
width: 170px;
}
@media (min-width: 769px) {
#bar #barLeft {
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',
'title' => 'Zwii, votre site en quelques clics !',
'itemsperPage' => 10,
'legalPageId' => ''
'legalPageId' => '',
'i18n' => 'fr'
],
'core' => [
'dataVersion' => 0,