Merge branch '11000' into v11_filepage

This commit is contained in:
Fred Tempez 2021-06-04 18:28:12 +02:00
commit 5fbaeec1ae
15 changed files with 516 additions and 236 deletions

View File

@ -1,11 +1,17 @@
# Changelog
## version 10.6.03
- Correction :
- Module actualités (news), version 3.3, le flux RSS affiche l'ensemble des articles plutôt que ceux de la page courante.
## Version 11.0.00
- Modifications :
- Installation : livraison des fichiers de thème du site de test dans une archive. Désormais, le dossier site ne contiendra que les fichiers de sécurité htaccess. Cette procédure permettra de ne plus différencier les archives d'installation et de mise à jour.
- Mises à jour : les mises à jour s'effectueront à partir de la forge plutôt que sur le site.
- Gestion multi-langues
- Traduction rédigée dans une langue européenne
- Traduction automatique dans une langue européenne
- Traduction selon la langue navigateur
- Configuration du site :
- Activation et désactivation de la déconnexion automatique empêchant plusieurs sessions avec le même compte.
- Suppression de l'option articles par pages.
- Suppression de l'option de backup individuel des fichiers de données, pour l'activer manuellement, créez un fichier vide .backup dans site/data
- Nouvelle option permettant de transférer les fichiers de sauvegarde automatiques dans le gestionnaire de fichiers.
## version 10.6.03
- Correction :

View File

@ -29,7 +29,7 @@ body {
}
@media (min-width: 769px) {
@media screen and (min-width: 769px) {
body {
/*margin:0px 10px;*/
margin: 0;
@ -41,7 +41,7 @@ body {
/**
* Petits écrans inférieurs à 768px de largeur, on supprime les marges
*/
@media (max-width: 768px) {
@media screen and (max-width: 768px) {
body {
margin: 0px;
}
@ -65,7 +65,7 @@ body {
@media (max-width: 768px) {
@media screen and (max-width: 768px) {
.siteContainer {
display: flex;
flex-direction: column;
@ -237,12 +237,12 @@ td>.col12 {
}
/* Tableau sur les écrans de petites tailles */
@media (max-width: 768px) {
@media screen and (max-width: 768px) {
.table thead {
font-size: 0.8em;
}
}
@media (max-width: 668px) {
@media screen and (max-width: 668px) {
.table thead {
display:none;
}
@ -408,7 +408,7 @@ td>.col12 {
background-color: rgba(255, 255, 255, 1);
}
@media (min-width: 769px) {
@media screen and (min-width: 769px) {
#bar #barLeft {
float: left;
}
@ -419,7 +419,7 @@ td>.col12 {
}
}
@media (max-width: 768px) {
@media screen and (max-width: 768px) {
#bar {
text-align: center;
padding: 0 1;
@ -455,7 +455,7 @@ td>.col12 {
overflow: hidden;
}
/* Dans theme.css
@media (min-width:768px) {
@media screen and (min-width:768px) {
#site {
margin: 20px auto;
}
@ -464,7 +464,7 @@ td>.col12 {
/* Bannière */
@media (min-width:768px) {
@media screen and (min-width:768px) {
body>header {
margin: 0;
/*-10px;*/
@ -598,13 +598,13 @@ nav::before {
display: flex;
}
@media (min-width: 769px) {
@media screen and (min-width: 769px) {
nav #menu {
display: block;
}
}
@media (max-width: 768px) {
@media screen and (max-width: 768px) {
body>nav {
margin: 0;
}
@ -691,41 +691,66 @@ li .menuSideChild {
/* Container des drapeaux */
#i18nContainer {
z-index: 100;
#i18nContainerNav, #i18nContainerSite {
position: relative ;
float: right;
width: auto;
height: auto;
margin-top: -25px;
}
#i18nContainer ul {
#i18nContainerNav ul, #i18nContainerSite ul {
list-style: none;
}
#i18nContainer li {
#i18nContainerNav li, #i18nContainerSite li {
display: inline-block;
position: relative;
}
#i18nContainer img {
width: 80%;
#i18nFlag {
width: 70%;
}
#i18nFlagSelected {
width: 100%;
}
/*
* Position du bloc dans le site sur les petits écrans
*/
#i18nContainer img {
margin: 2px;
#i18nContainerNav {
display: block;
}
#i18nContainerSite {
display: none;
}
@media screen and (max-width:1024px){
#i18nContainerNav {
display: none;
}
#i18nContainerSite {
display: block;
margin-top: -10px;
}
#i18nFlag {
width: 100%;
padding: 5px;
}
#i18nFlagSelected {
width: 130%;
padding: 5px;
}
}
/* Corps */
@media (min-width:768px) {
@media screen and (min-width:768px) {
section {
padding: 20px;
}
@ -822,7 +847,7 @@ footer #footerbody>div {
}
/* Conserve le pied de page sur une ligne */
@media (max-width: 768px) {
@media screen and (max-width: 768px) {
body>footer {
margin: 0;
}
@ -1031,6 +1056,7 @@ footer #footerSocials .zwiico-github:hover {
user-select: none;
}
/* Lightbox */
.lightbox {
background: #FFF;
@ -1367,7 +1393,7 @@ input[type='checkbox']:disabled+label:before {
display: inline-block;
}
@media (min-width: 769px) {
@media screen and (min-width: 769px) {
.col1 {
width: 8.33333333%;
}
@ -1556,7 +1582,7 @@ th.col12 {
}
/* Tableau sur les écrans de très petites tailles */
@media (max-width: 480px){
@media screen and (max-width: 480px){
.table tr{
display: block;
margin-bottom: 10px;
@ -1710,3 +1736,7 @@ th.col12 {
border-radius: 5px;
z-index: 30;
}
.helpDisplayButton {
cursor: pointer;
}

View File

@ -18,17 +18,19 @@ class config extends common {
public static $actions = [
'backup' => self::GROUP_ADMIN,
'copyBackups'=> self::GROUP_ADMIN,
'configMetaImage' => self::GROUP_ADMIN,
'generateFiles' => self::GROUP_ADMIN,
'index' => self::GROUP_ADMIN,
'advanced' => self::GROUP_ADMIN,
'manage' => self::GROUP_ADMIN,
'restore' => self::GROUP_ADMIN,
'updateBaseUrl' => self::GROUP_ADMIN,
'script' => self::GROUP_ADMIN,
'logReset' => self::GROUP_ADMIN,
'logDownload'=> self::GROUP_ADMIN,
'blacklistReset' => self::GROUP_ADMIN,
'blacklistDownload' => self::GROUP_ADMIN
'blacklistDownload' => self::GROUP_ADMIN,
];
public static $timezones = [
@ -191,7 +193,7 @@ class config extends common {
$this->addOutput([
'notification' => $successSitemap ? 'Le sitemap a été mis à jour' : 'Echec d\'écriture, le site map n\'a pas été mis à jour',
'redirect' => helper::baseUrl() . 'config/advanced',
'state' => $successSitemap
'state' => $successSitemap
]);
}
@ -265,11 +267,11 @@ class config extends common {
/**
* Procédure d'importation
*/
public function manage() {
public function restore() {
// Soumission du formulaire
if($this->isPost()) {
//if ($this->getInput('configManageImportFile'))
$fileZip = $this->getInput('configManageImportFile');
//if ($this->getInput('configRestoreImportFile'))
$fileZip = $this->getInput('configRestoreImportFile');
$file_parts = pathinfo($fileZip);
$folder = date('Y-m-d-h-i-s', time());
$zip = new ZipArchive();
@ -277,7 +279,7 @@ class config extends common {
// Valeurs en sortie erreur
$this->addOutput([
'notification' => 'Le fichier n\'est pas une archive valide',
'redirect' => helper::baseUrl() . 'config/manage',
'redirect' => helper::baseUrl() . 'config/restore',
'state' => false
]);
}
@ -286,7 +288,7 @@ class config extends common {
// Valeurs en sortie erreur
$this->addOutput([
'notification' => 'Impossible de lire l\'archive',
'redirect' => helper::baseUrl() . 'config/manage',
'redirect' => helper::baseUrl() . 'config/restore',
'state' => false
]);
}
@ -311,21 +313,21 @@ class config extends common {
// V10 valide
$version = '10';
// Option active, les users sont stockées
if ($this->getInput('configManageImportUser', helper::FILTER_BOOLEAN) === true ) {
if ($this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN) === true ) {
$users = $this->getData(['user']);
}
} else { // Version invalide
// Valeurs en sortie erreur
$this->addOutput([
'notification' => 'Cette archive n\'est pas une sauvegarde valide',
'redirect' => helper::baseUrl() . 'config/manage',
'redirect' => helper::baseUrl() . 'config/restore',
'state' => false
]);
}
// Préserver les comptes des utilisateurs d'une version 9 si option cochée
// Positionnement d'une variable de session lue au constructeurs
if ($version === '9') {
$_SESSION['KEEP_USERS'] = $this->getInput('configManageImportUser', helper::FILTER_BOOLEAN);
$_SESSION['KEEP_USERS'] = $this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN);
}
// Extraire le zip ou 'site/'
$success = $zip->extractTo( 'site/' );
@ -335,13 +337,13 @@ class config extends common {
// Restaurer les users originaux d'une v10 si option cochée
if (!empty($users) &&
$version === '10' &&
$this->getInput('configManageImportUser', helper::FILTER_BOOLEAN) === true) {
$this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN) === true) {
$this->setData(['user',$users]);
}
// Message de notification
$notification = $success === true ? 'Restauration réalisée avec succès' : 'Erreur inconnue';
$redirect = $this->getInput('configManageImportUser', helper::FILTER_BOOLEAN) === true ? helper::baseUrl() . 'config/manage' : helper::baseUrl() . 'user/login/';
$redirect = $this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN) === true ? helper::baseUrl() . 'config/restore' : helper::baseUrl() . 'user/login/';
// Valeurs en sortie erreur
$this->addOutput([
'notification' => $notification,
@ -353,7 +355,7 @@ class config extends common {
// Valeurs en sortie
$this->addOutput([
'title' => 'Restaurer',
'view' => 'manage'
'view' => 'restore'
]);
}
@ -399,6 +401,7 @@ class config extends common {
'title' => $this->getInput('configTitle', helper::FILTER_STRING_SHORT, true)
]
]);
$this->setData(['config', 'i18n', 'enabled', $this->getInput('configI18n',helper::FILTER_BOOLEAN) ]);
// Générer robots.txt et sitemap
$this->generateFiles();
// Valeurs en sortie
@ -428,6 +431,11 @@ class config extends common {
$this->getInput('configAdvancedAutoUpdate', helper::FILTER_BOOLEAN) === true) {
$this->setData(['core','lastAutoUpdate',0]);
}
// Eviter déconnexion automatique après son activation
if ( $this->getData(['config','autoDisconnect']) === false
AND $this->getInput('configAdvancedAutoDisconnect',helper::FILTER_BOOLEAN) === true ) {
$this->setData(['user',$this->getuser('id'),'accessCsrf',$_SESSION['csrf']]);
}
// Sauvegarder
$this->setData([
'config',
@ -455,6 +463,7 @@ class config extends common {
'proxyUrl' => $this->getInput('configAdvancedProxyUrl'),
'proxyPort' => $this->getInput('configAdvancedProxyPort',helper::FILTER_INT),
'captchaStrong' => $this->getInput('configAdvancedCaptchaStrong',helper::FILTER_BOOLEAN),
'autoDisconnect' => $this->getInput('configAdvancedAutoDisconnect',helper::FILTER_BOOLEAN),
'smtp' => [
'enable' => $this->getInput('configAdvancedSmtpEnable',helper::FILTER_BOOLEAN),
'host' => $this->getInput('configAdvancedSmtpHost',helper::FILTER_STRING_SHORT),
@ -612,7 +621,7 @@ class config extends common {
// Valeurs en sortie
$this->addOutput([
'notification' => $success ? $c3. ' conversion' . ($c3 > 1 ? 's' : '') . ' effectuée' . ($c3 > 1 ? 's' : '') : 'Aucune conversion',
'redirect' => helper::baseUrl() . 'config/manage',
'redirect' => helper::baseUrl() . 'config/restore',
'state' => $success ? true : false
]);
}
@ -729,6 +738,23 @@ class config extends common {
}
}
/**
* Récupération des backups auto dans le gestionnaire de fichiers
*/
public function copyBackups() {
// Créer le répertoire manquant
if (!is_dir(self::FILE_DIR.'source/backup')) {
mkdir(self::FILE_DIR.'source/backup');
}
$this->custom_copy(self::BACKUP_DIR, self::FILE_DIR . 'source/backup' );
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config/advanced',
'notification' => 'Copie terminée',
'state' => true
]);
}
/**
* Fonction de parcours des données de module
@ -750,4 +776,31 @@ class config extends common {
}
return $newArray;
}
/*
* Copie récursive de dossiers
*
*/
private function custom_copy($src, $dst) {
// open the source directory
$dir = opendir($src);
// Make the destination directory if not exist
if (!is_dir($dst)) {
mkdir($dst);
}
// Loop through the files in source directory
while( $file = readdir($dir) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ){
// Recursively calling custom copy function
// for sub directory
$this -> custom_copy($src . '/' . $file, $dst . '/' . $file);
}
else {
copy($src . '/' . $file, $dst . '/' . $file);
}
}
}
closedir($dir);
}
}

View File

@ -27,24 +27,26 @@
<div class="col12">
<div class="block">
<h4>Maintenance</h4>
<div class="col3">
<?php echo template::checkbox('configAdvancedMaintenance', true, 'Site en maintenance', [
'checked' => $this->getData(['config', 'maintenance'])
<div class="row">
<div class="col4">
<?php echo template::checkbox('configAdvancedMaintenance', true, 'Site en maintenance', [
'checked' => $this->getData(['config', 'maintenance'])
]); ?>
</div>
<div class="col3">
<?php echo template::button('configBackupButton', [
'href' => helper::baseUrl() . 'config/backup',
'value' => 'Sauvegarder',
'ico' => 'download-cloud'
]); ?>
</div>
<div class="col3 offset1">
<?php echo template::button('configRestoreButton', [
'href' => helper::baseUrl() . 'config/restore',
'value' => 'Restaurer',
'ico' => 'upload-cloud'
]); ?>
</div>
<div class="col3 offset1">
<?php echo template::button('configManageButton', [
'href' => helper::baseUrl() . 'config/backup',
'value' => 'Sauvegarder',
'ico' => 'download'
]); ?>
</div>
<div class="col3 offset1">
<?php echo template::button('configManageButton', [
'href' => helper::baseUrl() . 'config/manage',
'value' => 'Restaurer',
'ico' => 'upload'
]); ?>
</div>
</div>
</div>
@ -53,7 +55,6 @@
<div class="col12">
<div class="block">
<h4>Réglages</h4>
<?php $error = helper::urlGetContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version');?>
<div class="row">
<div class="col4">
<?php echo template::file('configAdvancedFavicon', [
@ -80,38 +81,48 @@
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::checkbox('configAdvancedCookieConsent', true, 'Consentement aux cookies', [
'checked' => $this->getData(['config', 'cookieConsent'])
<div class="col6">
<?php echo template::checkbox('configAdvancedCookieConsent', true, 'Message de consentement aux cookies', [
'checked' => $this->getData(['config', 'cookieConsent']),
'help' => 'Activation obligatoire selon les lois françaises sauf si vous utilisez votre propre système de consentement.'
]); ?>
</div>
<div class="col4">
<?php echo template::checkbox('configAdvancedCaptchaStrong', true, 'Captcha renforcé', [
'checked' => $this->getData(['config','captchaStrong']),
'help' => 'Option recommandée pour sécuriser la connexion. S\'applique à tous les captchas du site. Le captcha simple se limite à une addition de nombres de 0 à 10. Le captcha renforcé utilise quatre opérations de nombres de 0 à 20.'
]); ?>
</div>
<div class="col4">
<?php echo template::checkbox('rewrite', true, 'Réécriture d\'URL', [
<div class="col6">
<?php echo template::checkbox('rewrite', true, 'URL intelligentes', [
'checked' => helper::checkRewrite(),
'help' => 'Vérifiez d\'abord que votre serveur l\'autorise : ce n\'est pas le cas chez Free.'
'help' => 'Vérifiez d\'abord que votre serveur autorise l\'URL rewriting (ce qui n\'est pas le cas chez Free).'
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::checkbox('configAdvancedAutoBackup', true, 'Sauvegarde quotidienne', [
'checked' => $this->getData(['config', 'autoBackup']),
'help' => '<p>Une archive contenant le dossier /site/data est copiée dans le dossier \'site/backup\'. La sauvegarde est conservée pendant 30 jours.</p><p>Les fichiers du site ne sont pas sauvegardés automatiquement.</p>'
<div class="col6">
<?php echo template::checkbox('configAdvancedCaptchaStrong', true, 'Captcha complexe', [
'checked' => $this->getData(['config','captchaStrong']),
'help' => 'Option recommandée pour sécuriser la connexion. S\'applique à tous les captchas du site. Le captcha simple se limite à une addition de nombres de 0 à 10. Le captcha complexe utilise quatre opérations de nombres de 0 à 20. Activation recommandée.'
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('configAdvancedAutoDisconnect', true, 'Déconnexion automatique de la session', [
'checked' => $this->getData(['config','autoDisconnect']),
'help' => 'Déconnecte les sessions ouvertes précédemment sur d\'autres navigateurs ou terminaux. Activation recommandée.'
]); ?>
</div>
<div class="col4">
<?php echo template::checkbox('configAdvancedFileBackup', true, 'Copie de sauvegarde', [
'checked' => file_exists('site/data/.backup'),
'help' => '<p>Un fichier .backup.json est généré à chaque édition ou effacement d\'une donnée. La désactivation entraîne la suppression de ces fichiers.</p>'
</div>
<div class="row">
<div class="col6">
<?php echo template::checkbox('configAdvancedAutoBackup', true, 'Sauvegarde automatique quotidienne du site', [
'checked' => $this->getData(['config', 'autoBackup']),
'help' => 'Une archive contenant le dossier /site/data est copiée dans le dossier \'site/backup\'. La sauvegarde est conservée pendant 30 jours.</p><p>Les fichiers du site ne sont pas sauvegardés automatiquement. Activation recommandée.'
]); ?>
</div>
<div class="col3">
<?php echo template::button('configBackupCopyButton', [
'href' => helper::baseUrl() . 'config/copyBackups',
'value' => 'Backups Auto &#10140; FileManager'
]); ?>
</div>
</div>
</div>
</div>
@ -119,30 +130,30 @@
<div class="row">
<div class="col12">
<div class="block">
<h4>Mise à jour automatisée</h4>
<h4>Mises à jour automatisée</h4>
<?php $updateError = helper::urlGetContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version');?>
<div class="row">
<div class="col4">
<?php echo template::checkbox('configAdvancedAutoUpdate', true, 'Mise à jour en ligne', [
<?php echo template::checkbox('configAdvancedAutoUpdate', true, 'Rechercher une mise à jour en ligne', [
'checked' => $this->getData(['config', 'autoUpdate']),
'help' => 'Vérifie une fois par jour l\'existence d\'une mise à jour.',
'disabled' => !$error
'help' => 'La vérification est quotidienne. Option désactivée si la configuration du serveur ne le permet pas.',
'disabled' => !$updateError
]); ?>
</div>
<div class="col4 ">
<?php echo template::checkbox('configAdvancedAutoUpdateHtaccess', true, 'Préserver htaccess', [
<div class="col4">
<?php echo template::checkbox('configAdvancedAutoUpdateHtaccess', true, 'Préserver le fichier htaccess racine', [
'checked' => $this->getData(['config', 'autoUpdateHtaccess']),
'help' => 'Lors d\'une mise à jour automatique, conserve le fichier htaccess de la racine du site.',
'disabled' => !$error
'disabled' => !$updateError
]); ?>
</div>
<div class="col4 ">
<div class="col4">
<?php echo template::button('configAdvancedUpdateForced', [
'ico' => 'download-cloud',
'href' => helper::baseUrl() . 'install/update',
'value' => 'Mise à jour manuelle',
'class' => 'buttonRed',
'disabled' => !$error
'disabled' => !$updateError
]); ?>
</div>
</div>
@ -320,7 +331,7 @@
</div>
</div>
<div class="row">
<div class="col3">
<div class="col6">
<?php echo template::checkbox('configAdvancedConnectCaptcha', true, 'Captcha à la connexion', [
'checked' => $this->getData(['config', 'connect','captcha'])
]); ?>

View File

@ -18,7 +18,7 @@
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètre</h4>
<h4>Paramètres de la sauvegarde</h4>
<div class="row">
<div class="col12">
<?php echo template::checkbox('configBackupOption', true, 'Inclure le contenu du gestionnaire de fichiers', [

View File

@ -62,6 +62,21 @@
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Langues étrangères</h4>
<div class="row">
<div class="col12">
<?php echo template::checkbox('configI18n', true, 'Activer la gestion des langues étrangères', [
'checked' => $this->getData(['config', 'i18n', 'enabled']),
'help'=> 'Une nouvelle icône apparaîtra dans la barre d\'administration. Consultez l\'aide de la page concernée pour en apprendre plus.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
@ -101,7 +116,7 @@
<?php echo template::select('configSearchPageId', array_merge(['none' => 'Aucune'] , helper::arrayCollumn($pages, 'title', 'SORT_ASC') ) , [
'label' => 'Recherche dans le site',
'selected' => $this->getData(['locale', 'searchPageId']),
'help' => 'Sélectionner la page "Recherche" ou une page contenant le module "Recherche". Une option du pied de page ajoute un lien discret vers cette page.'
'help' => 'Sélectionnez une page contenant le module \'Recherche\'. Une option du pied de page ajoute un lien discret vers cette page.'
]); ?>
</div>
</div>
@ -131,6 +146,7 @@
]); ?>
</div>
</div>
<p>Lorsque les langues étrangères sont activées, il convient d'adapter les pages spéciales.</p>
</div>
</div>
</div>

View File

@ -1,7 +1,7 @@
<?php echo template::formOpen('configManageForm'); ?>
<?php echo template::formOpen('configRestoreForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('configManageBack', [
<?php echo template::button('configRestoreBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'config/advanced',
'ico' => 'left',
@ -9,7 +9,7 @@
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('configManageSubmit',[
<?php echo template::submit('configRestoreSubmit',[
'value' => 'Restaurer'
]); ?>
</div>
@ -17,18 +17,18 @@
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètres</h4>
<h4>Archive à restaurer</h4>
<div class="row">
<div class="col10 offset1">
<div class="row">
<?php echo template::file('configManageImportFile', [
<?php echo template::file('configRestoreImportFile', [
'label' => 'Sélectionnez une archive au format ZIP',
'type' => 2,
'help' => 'L\'archive a été déposée dans le gestionnaire de fichiers. Les archives inférieures à la version 9 ne sont pas acceptées.'
]); ?>
</div>
<div class="row">
<?php echo template::checkbox('configManageImportUser', true, 'Préserver les comptes des utilisateurs déjà installés', [
<?php echo template::checkbox('configRestoreImportUser', true, 'Préserver les comptes des utilisateurs déjà installés', [
'checked' => true
]); ?>
</div>
@ -40,7 +40,7 @@
<div class="row">
<div class="col12">
<div class="block">
<h4>Conversion des URL <?php echo template::help('Conversion des URL des ressources multimédia après le transfert d\'une archive entre deux sites aux adresses différentes.');?></h4>
<h4>Conversion après la restauration<?php echo template::help('Conversion des URL des ressources multimédia entre deux sites aux arborescences différentes.');?></h4>
<div class="row">
<div class="col4 offset1">
<?php
@ -54,23 +54,22 @@
$baseUrlValue = str_replace('?','',$this->getData(['core', 'baseUrl']));
$buttonClass = helper::baseUrl(false,false) !== $baseUrlValue ? '' : 'disabled';
}
echo template::text('configManageBaseURLToConvert', [
echo template::text('configRestoreBaseURLToConvert', [
'label' => 'Dossier de l\'archive' ,
'value' => $baseUrlValue,
'readonly' => true,
'help' => 'Dossier de base du site stockée dans la sauvegarde.'
'help' => 'Le dossier de base du site est stockée dans la sauvegarde.'
]); ?>
</div>
<div class="col4">
<?php echo template::text('configManageCurrentURL', [
<?php echo template::text('configRestoreCurrentURL', [
'label' => 'Dossier du site actuel',
'value' => helper::baseUrl(false,false),
'readonly' => true,
'help' => 'Dossier du base site actuel.'
'readonly' => true
]); ?>
</div>
<div class="col2 verticalAlignMiddle">
<?php echo template::button('configManageUpdateBaseURLButton', [
<?php echo template::button('configRestoreUpdateBaseURLButton', [
'href' => helper::baseUrl() . 'config/updateBaseUrl',
'class' => $buttonClass,
'value' => 'convertir'

View File

@ -80,7 +80,7 @@ class init extends common {
],
'module' => [],
'user' => [],
'translate' => [
'i18n' => [
'scriptGoogle' => false,
'showCredits' => false,
'autoDetect' => false,

View File

@ -17,10 +17,77 @@ class translate extends common {
public static $actions = [
/*'config' => self::GROUP_MODERATOR,*/
'index' => self::GROUP_MODERATOR,
'index' => self::GROUP_ADMIN,
'copy' => self::GROUP_ADMIN,
'language' => self::GROUP_VISITOR
];
public static $translateOptions = [];
// Liste des langues installées
public static $languagesInstalled = [];
// Liste des langues cibles
public static $languagesTarget = [];
// Activation du bouton de copie
public static $siteTranslate = true;
/**
* Configuration avancée des langues
*/
public function copy() {
// Soumission du formulaire
if ($this->isPost()) {
// Initialisation
$success = false;
$copyFrom = $this->getInput('translateFormCopySource');
$toCreate = $this->getInput('translateFormCopyTarget');
if ($copyFrom !== $toCreate) {
// Création du dossier
if (is_dir(self::DATA_DIR . $toCreate) === false ) { // Si le dossier est déjà créé
$success = mkdir (self::DATA_DIR . $toCreate);
} else {
$success = true;
}
// Copier les données par défaut avec gestion des erreurs
$success = (copy (self::DATA_DIR . $copyFrom . '/locale.json', self::DATA_DIR . $toCreate . '/locale.json') === true && $success === true) ? true : false;
$success = (copy (self::DATA_DIR . $copyFrom . '/module.json', self::DATA_DIR . $toCreate . '/module.json') === true && $success === true) ? true : false;
$success = (copy (self::DATA_DIR . $copyFrom . '/page.json', self::DATA_DIR . $toCreate . '/page.json') === true && $success === true) ? true : false;
// Enregistrer la langue
if ($success) {
$this->setData(['config', 'i18n', $toCreate, 'site' ]);
$notification = 'Données ' . self::$i18nList[$copyFrom] . ' copiées vers ' . self::$i18nList[$toCreate];
} else {
$notification = "Quelque chose n\'a pas fonctionné, vérifiez les permissions.";
}
} else {
$success = false;
$notification = 'Les langues doivent être différentes.';
}
// Valeurs en sortie
$this->addOutput([
'notification' => $notification,
'title' => 'Utilitaire de copie',
'view' => 'index',
'state' => $success
]);
}
// Tableau des langues installées
foreach (self::$i18nList as $key => $value) {
if ($this->getData(['config','i18n', $key]) === 'site') {
self::$languagesTarget[$key] = $value;
}
}
// Langues cibles fr en plus
self::$languagesInstalled = array_merge(['fr' => 'Français (fr)'],self::$languagesTarget);
// Valeurs en sortie
$this->addOutput([
'title' => 'Utilitaire de copie',
'view' => 'copy'
]);
}
/**
* Configuration
*/
@ -28,19 +95,26 @@ class translate extends common {
// Soumission du formulaire
if($this->isPost()) {
// Edtion des langues
// Désactivation du script Google
if ($this->getInput('translateScriptGoogle', helper::FILTER_BOOLEAN) === false) {
setrawcookie('googtrans', '/fr/fr', time() + 3600, helper::baseUrl(false,false));
$_SESSION['googtrans'] = '/fr/fr';
}
$script = $this->getInput('translateScriptGoogle', helper::FILTER_BOOLEAN);
// Edition des langues
foreach (self::$i18nList as $keyi18n => $value) {
if ($keyi18n === 'fr') {continue;}
// Effacement d'une langue installée (dossier plus option désactivée précédemment)
// Effacement d'une langue installée
if ( is_dir( self::DATA_DIR . $keyi18n ) === true
AND $this->getInput('translateSiteFlag' . strtoupper($keyi18n) , helper::FILTER_BOOLEAN) === false )
AND $this->getInput('translate' . strtoupper($keyi18n)) === 'delete')
{
$this->removeDir( self::DATA_DIR . $keyi18n);
}
// Installation d'une langue
if ( $this->getInput('translateSiteFlag' . strtoupper($keyi18n) , helper::FILTER_BOOLEAN) === true )
if ( $this->getInput('translate' . strtoupper($keyi18n)) === 'site'
AND is_dir(self::DATA_DIR . $keyi18n) === false )
{
// Créer le dossier
// Créer les données absentes
if (is_dir( self::DATA_DIR . $keyi18n ) === false ) {
mkdir( self::DATA_DIR . $keyi18n);
}
@ -58,29 +132,27 @@ class translate extends common {
$e->save();
}
}
// Active le script si une langue est en trad auto
if ($script === false
AND $this->getInput('translate'. strtoupper($keyi18n)) === 'script') {
$script = true;
}
}
// Enregistrement des données
$this->setData(['config','translate', [
'scriptGoogle' => $this->getInput('translateScriptGoogle', helper::FILTER_BOOLEAN),
'showCredits' => $this->getInput('translateCredits', helper::FILTER_BOOLEAN) ? $this->getInput('translateCredits', helper::FILTER_BOOLEAN) : false,
'autoDetect' => $this->getInput('translateAutoDetect', helper::FILTER_BOOLEAN),
'admin' => $this->getInput('translateAdmin', helper::FILTER_BOOLEAN),
'scriptFR' => $this->getInput('translateScriptFlagFR', helper::FILTER_BOOLEAN),
'scriptDE' => $this->getInput('translateScriptFlagDE', helper::FILTER_BOOLEAN),
'scriptEN' => $this->getInput('translateScriptFlagEN', helper::FILTER_BOOLEAN),
'scriptES' => $this->getInput('translateScriptFlagES', helper::FILTER_BOOLEAN),
'scriptIT' => $this->getInput('translateScriptFlagIT', helper::FILTER_BOOLEAN),
'scriptNL' => $this->getInput('translateScriptFlagNL', helper::FILTER_BOOLEAN),
'scriptPT' => $this->getInput('translateScriptFlagPT', helper::FILTER_BOOLEAN),
'site' => $this->getInput('translateSite', helper::FILTER_BOOLEAN),
'siteFR' => $this->getInput('translateSiteFlagFR', helper::FILTER_BOOLEAN),
'siteDE' => $this->getInput('translateSiteFlagDE', helper::FILTER_BOOLEAN),
'siteEN' => $this->getInput('translateSiteFlagEN', helper::FILTER_BOOLEAN),
'siteES' => $this->getInput('translateSiteFlagES', helper::FILTER_BOOLEAN),
'siteIT' => $this->getInput('translateSiteFlagIT', helper::FILTER_BOOLEAN),
'siteNL' => $this->getInput('translateSiteFlagNL', helper::FILTER_BOOLEAN),
'sitePT' => $this->getInput('translateSiteFlagPT', helper::FILTER_BOOLEAN)
$this->setData(['config','i18n', [
'enabled' => $this->getData(['config', 'i18n', 'enabled']),
'scriptGoogle' => $script,
'showCredits' => $this->getInput('translateScriptGoogle', helper::FILTER_BOOLEAN) ? $this->getInput('translateCredits', helper::FILTER_BOOLEAN) : false,
'autoDetect' => $this->getInput('translateScriptGoogle', helper::FILTER_BOOLEAN) ? $this->getInput('translateAutoDetect', helper::FILTER_BOOLEAN) : false,
'admin' => $this->getInput('translateScriptGoogle', helper::FILTER_BOOLEAN) ? $this->getInput('translateAdmin', helper::FILTER_BOOLEAN) : false,
'fr' => $this->getInput('translateFR'),
'de' => $this->getInput('translateDE'),
'en' => $this->getInput('translateEN'),
'es' => $this->getInput('translateES'),
'it' => $this->getInput('translateIT'),
'nl' => $this->getInput('translateNL'),
'pt' => $this->getInput('translatePT')
]]);
// Valeurs en sortie
$this->addOutput([
@ -89,22 +161,54 @@ class translate extends common {
'state' => true
]);
}
// Modification des options de suppression de la langue installée.
foreach (self::$i18nList as $key => $value) {
if ($this->getData(['config','i18n',$key]) === 'site') {
self::$translateOptions [$key] = [
'none' => 'Drapeau masqué',
'script' => 'Traduction automatique',
'site' => 'Traduction rédigée',
'delete' => 'Supprimer la traduction'
];
self::$siteTranslate = $key !== 'fr' ? false : true;
} else {
self::$translateOptions [$key] = [
'none' => 'Drapeau masqué',
'script' => 'Traduction automatique',
'site' => 'Traduction rédigée'
];
}
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Paramètres',
'title' => 'Gestion des langues',
'view' => 'index'
]);
}
/*
* Traitement du changement de langues
*/
/*
* Traitement du changement de langue
* Fonction utilisée par le noyau
*/
public function language() {
// Transmettre le choix au noyau
setcookie('ZWII_USER_I18N', $this->getUrl(2), time() + 3600, helper::baseUrl(false, false) , '', helper::isHttps(), true);
// Valeurs en sortie sans post
// Activation du drapeau
if ( $this->getInput('ZWII_I18N_' . strtoupper($this->getUrl(3))) !== $this->getUrl(2) ) {
// Nettoyer et stocker le choix de l'utilisateur
helper::deleteCookie('ZWII_I18N_SITE');
helper::deleteCookie('ZWII_I18N_SCRIPT');
// Sélectionner
setcookie('ZWII_I18N_' . strtoupper($this->getUrl(3)) , $this->getUrl(2), time() + 3600, helper::baseUrl(false, false) , '', helper::isHttps(), true);
// Désactivation du drapeau, langue FR par défaut
} else {
setcookie('ZWII_I18N_SITE' , 'fr', time() + 3600, helper::baseUrl(false, false) , '', helper::isHttps(), true);
helper::deleteCookie('ZWII_I18N_SCRIPT');
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(3)
'redirect' => helper::baseUrl()
]);
}
}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,34 @@
<?php echo template::formOpen('translateFormCopy'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('translateFormCopyBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'translate',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('translateFormCopySubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Copie de site (traductions rédigées)</h4>
<div class="row">
<div class="col6">
<?php echo template::select('translateFormCopySource', $module::$languagesInstalled, [
'label' => 'Pages et les modules de'
]); ?>
</div>
<div class="col6">
<?php echo template::select('translateFormCopyTarget', $module::$languagesTarget, [
'label' => 'Vers'
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1 @@
<h3>A VENIR</h3>

View File

@ -8,85 +8,127 @@
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<div class="col2">
<?php echo template::button('configAdvancedHelp', [
'class' => 'buttonHelp',
'ico' => 'help',
'value' => 'Aide'
]); ?>
</div>
<div class="col3 offset3">
<?php echo template::button('configAdvancedButton', [
'href' => helper::baseUrl() . 'translate/copy',
'value' => 'Utilitaire de copie',
'ico' => 'cog-alt',
'disabled' => $module::$siteTranslate
]); ?>
</div>
<div class="col2">
<?php echo template::submit('translateFormSubmit'); ?>
</div>
</div>
<!-- Aide à propos de la configuration du site, view advanced -->
<div class="helpDisplayContent">
<?php echo file_get_contents( 'core/module/config/view/advanced/advanced.help.html') ;?>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Traduction automatique
<span class="helpDisplayButton">
<?php echo template::ico('help', 'left');?>
</span>
</h4>
<div class="row">
<div class="col6">
<?php echo template::checkbox('translateScriptGoogle', true, 'Active le script de traduction automatique', [
'checked' => $this->getData(['config','i18n', 'scriptGoogle']),
'help' => 'Le script Google Translate assure la traduction automatique du site.'
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('translateAutoDetect', true, 'Détection automatique de la langue du navigateur', [
'checked' => $this->getData(['config','i18n', 'autoDetect']),
'class' => 'translateGoogleScriptOption',
'help' => 'Détecte la langue du navigateur, dans ce mode il n\'est pas nécessaire d\'afficher les drapeaux.'
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::checkbox('translateCredits', true, 'Afficher les crédits du script Google', [
'checked' => $this->getData(['config','i18n', 'showCredits']),
'class' => 'translateGoogleScriptOption',
'help' => 'Option recommandée pour le respect du droit d\'auteur'
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('translateAdmin', true, 'Traduction en mode connecté', [
'checked' => $this->getData(['config','i18n', 'admin']),
'class' => 'translateGoogleScriptOption',
'help' => 'Traduit le site et l\'interface de ZwiiCMS quand un utilisateur est connecté'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Langues supportées</h4>
<div class="block" id="flagsWrapper">
<h4>Mode de traduction et affichage des drapeaux</h4>
<div class="row">
<div class="col4 offset4">
<?php echo template::select('translateFR', ['none'=>'Drapeau masqué','site'=>'Drapeau affiché'], [
'label' => 'Français',
'selected' => $this->getData(['config', 'i18n' , 'fr'])
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<b>Traduction automatique :</b>
<div class="col12">
<?php echo template::checkbox('translateScriptFlagDE', true, 'Allemand', [
'checked' => $this->getData(['config','translate', 'scriptDE'])
]); ?>
</div>
<div class="col12">
<?php echo template::checkbox('translateScriptFlagEN', true, 'Anglais', [
'checked' => $this->getData(['config','translate', 'scriptEN'])
<div class="col8 offset2">
<?php echo template::select('translateDE', $module::$translateOptions['de'], [
'label' => 'Allemand',
'class' => 'translateFlagSelect',
'selected' => $this->getData(['config', 'i18n' , 'de'])
]); ?>
</div>
<div class="col12">
<?php echo template::checkbox('translateScriptFlagES', true, 'Espagnol', [
'checked' => $this->getData(['config','translate', 'scriptES'])
]); ?>
</div>
<div class="col12">
<?php echo template::checkbox('translateScriptFlagIT', true, 'Italien', [
'checked' => $this->getData(['config','translate', 'scriptIT'])
<div class="col8 offset2">
<?php echo template::select('translateEN', $module::$translateOptions['en'], [
'label' => 'Anglais',
'class' => 'translateFlagSelect',
'selected' => $this->getData(['config', 'i18n' , 'en'])
]); ?>
</div>
<div class="col12">
<?php echo template::checkbox('translateScriptFlagNL', true, 'Néerlandais', [
'checked' => $this->getData(['config','translate', 'scriptNL'])
<div class="col8 offset2">
<?php echo template::select('translateES', $module::$translateOptions['es'], [
'label' => 'Espagnol',
'class' => 'translateFlagSelect',
'selected' => $this->getData(['config', 'i18n' , 'es'])
]); ?>
</div>
<div class="col12">
<?php echo template::checkbox('translateScriptFlagPT', true, 'Portugais', [
'checked' => $this->getData(['config','translate', 'scriptPT'])
]); ?>
</div>
<div class="col12">
<?php echo template::checkbox('translateAutoDetect', true, 'Détection automatique', [
'checked' => $this->getData(['config','translate', 'autoDetect']),
'help' => 'Détecte la langue du navigateur.'
]); ?>
</div>
</div>
<div class="col6">
<b>Traduction rédigée :</b>
<div class="col12">
<?php echo template::checkbox('translateSiteFlagEN', true, 'Anglais', [
'checked' => $this->getData(['config', 'translate', 'siteEN'])
<div class="col8 offset2">
<?php echo template::select('translateIT', $module::$translateOptions['it'], [
'label' => 'Italien',
'class' => 'translateFlagSelect',
'selected' => $this->getData(['config', 'i18n' , 'it'])
]); ?>
</div>
<div class="col12">
<?php echo template::checkbox('translateSiteFlagDE', true, 'Allemand', [
'checked' => $this->getData(['config', 'translate', 'siteDE'])
]); ?>
</div>
<div class="col12">
<?php echo template::checkbox('translateSiteFlagES', true, 'Espagnol', [
'checked' => $this->getData(['config', 'translate', 'siteES'])
]); ?>
</div>
<div class="col12">
<?php echo template::checkbox('translateSiteFlagIT', true, 'Italien', [
'checked' => $this->getData(['config', 'translate', 'siteIT'])
<div class="col8 offset2">
<?php echo template::select('translateNL', $module::$translateOptions['nl'], [
'label' => 'Néerlandais',
'class' => 'translateFlagSelect',
'selected' => $this->getData(['config', 'i18n' , 'nl'])
]); ?>
</div>
<div class="col12">
<?php echo template::checkbox('translateSiteFlagNL', true, 'Néerlandais', [
'checked' => $this->getData(['config', 'translate', 'siteNL'])
]); ?>
</div>
<div class="col12">
<?php echo template::checkbox('translateSiteFlagPT', true, 'Portugais', [
'checked' => $this->getData(['config', 'translate', 'sitePT'])
<div class="col8 offset2">
<?php echo template::select('translatePT', $module::$translateOptions['pt'], [
'label' => 'Portugais',
'class' => 'translateFlagSelect',
'selected' => $this->getData(['config', 'i18n' , 'pt'])
]); ?>
</div>
</div>
@ -94,31 +136,14 @@
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètres de traduction automatique</h4>
<div class="row">
<div class="col4">
<?php echo template::checkbox('translateScriptGoogle', true, 'Active le script de traduction automatique', [
'checked' => $this->getData(['config','translate', 'scriptGoogle'])
]); ?>
</div>
<div class="col4">
<?php echo template::checkbox('translateAdmin', true, 'Mode connexion', [
'checked' => $this->getData(['config','translate', 'admin']),
'help' => 'Traduction automatique du site et de l\'interface du CMS'
]); ?>
</div>
<div class="col4">
<?php echo template::checkbox('translateCredits', true, 'Afficher les crédits du script Google', [
'checked' => $this->getData(['config','translate', 'showCredits']),
'help' => 'Option vivement recommandée pour le respect du droit d\'auteur'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="col10 helpDisplayContent">
<p>Vous avez le choix entre une traduction automatique réalisée avec le script Google Traduction ou une traduction rédigée. La traduction automatique offre deux possibilités, la détection automatique de la langue du navigateur même celle-ci n'est pas
matérialisée par un drapeau. Le clic sur un drapeau forcera la traduction dans cette langue, pour cela sélectionnez le drapeau puis l'option de "Traduction automatique".
La traduction automatique est réalisée à partir du site en version française.</p>
<p>Avec l'option "Traduction rédigée", une nouveau sité est généré, seule la page d'accueil est crée, il faut alors rédiger les pages dans la langue sélectionnée.
Il est possible de copier les pages et les modules d'une langue vers une autre à l'aide de l'utilitaire de copie.
Quand un drapeau est masqué, la traduction est effacée, pensez à sauvegarder.
Afficher le drapeau français pour revenir à la traduction dans la langue originale.</p>
</div>
<?php echo template::formClose(); ?>

View File

@ -199,20 +199,20 @@ class search extends common {
// Traduction du mot clé si le script Google Trad est actif
// Le multi langue est sélectionné
if ( $this->getData(['config','translate','scriptGoogle']) === true
if ( $this->getData(['config','i18n','scriptGoogle']) === true
AND
// et la traduction de la langue courante est automatique
( isset($_COOKIE['googtrans'])
AND ( $this->getData(['config','translate', substr($_COOKIE['googtrans'],4,2)]) === 'script'
AND ( $this->getData(['config','i18n', substr($_COOKIE['googtrans'],4,2)]) === 'script'
// Ou traduction automatique
OR $this->getData(['config','translate','autoDetect']) === true )
OR $this->getData(['config','i18n','autoDetect']) === true )
)
// Cas des pages d'administration
// Pas connecté
AND ( $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
// Ou connecté avec option active
OR ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
AND $this->getData(['config','translate','admin']) === true
AND $this->getData(['config','i18n','admin']) === true
)
)
AND !isset($_COOKIE['ZWII_I18N_SITE'])